en un clic
links
// Reticulum's link system — encrypted channels with forward secrecy. Use when working with link establishment, link requests, ECDH, ephemeral keys, forward secrecy, channels, keep-alive, or link timeouts.
// Reticulum's link system — encrypted channels with forward secrecy. Use when working with link establishment, link requests, ECDH, ephemeral keys, forward secrecy, channels, keep-alive, or link timeouts.
Reticulum's cryptographic primitives, identity structure, encryption tokens, and key derivation. Use when working with Ed25519, X25519, identity hashes, HKDF, token format, encryption, signatures, ratchets, or key derivation.
Reticulum's addressing system and destination types. Use when working with destination types (SINGLE, GROUP, PLAIN, LINK), destination hashes, aspect naming, or addressing.
Reticulum's hardware abstraction layer and interface types. Use when working with RNode, AutoInterface, TCP, UDP, I2P, Serial, KISS, BLE interfaces, interface modes, IFAC, bandwidth allocation, or MTU.
Reticulum's packet structure and wire format. Use when working with packet headers, MTU/MDU, packet types, header types (HEADER_1/HEADER_2), packet context flags, IFAC, or binary packet encoding.
Detailed knowledge of Reticulum's announce mechanism for automatic path discovery. Use when working with announce propagation, path discovery, announce bandwidth, announce forwarding, path requests, or announce structure.
Reticulum's resource transfer system for large data over links. Use when working with resource transfers, windowing, hashmaps, segments, compression, file transfers, or resource states.
| name | links |
| description | Reticulum's link system — encrypted channels with forward secrecy. Use when working with link establishment, link requests, ECDH, ephemeral keys, forward secrecy, channels, keep-alive, or link timeouts. |
This skill provides knowledge about Reticulum's link system - encrypted channels with forward secrecy. Invoke when the user mentions link establishment, link request, ECDH, ephemeral keys, forward secrecy, keep-alive, or link timeouts.
Links are abstract encrypted channels between two nodes providing:
Unlike traditional connections, links are not tied to specific interfaces or IP addresses. They're abstract channels identified by link hash.
PENDING = 0x00 # Link request sent, awaiting response
HANDSHAKE = 0x01 # Link proof received, deriving keys
ACTIVE = 0x02 # Link established and operational
STALE = 0x03 # No traffic, final keep-alive sent
CLOSED = 0x04 # Link terminated
PENDING → HANDSHAKE → ACTIVE → STALE → CLOSED
↓ ↓
└──────── CLOSED ──────┘
PENDING: Initial state after sending link request. Waiting for link proof from destination.
HANDSHAKE: Link proof received and validated. Performing ECDH key exchange to derive shared secret.
ACTIVE: Link fully established. Data can be exchanged with encryption and forward secrecy.
STALE: No traffic received for STALE_TIME (720s). Final keep-alive sent. Link will timeout if no response.
CLOSED: Link terminated. Reasons: timeout, explicit close, or error.
ECPUBSIZE = 64 # Public key size (32B encryption + 32B signing)
KEYSIZE = 32 # Symmetric key size (AES-256)
ESTABLISHMENT_TIMEOUT_PER_HOP = 6 # Seconds per hop for establishment
KEEPALIVE = 360 # Keep-alive interval (seconds)
STALE_TIME = 720 # Time before link considered stale (2×KEEPALIVE)
STALE_GRACE = 5 # Grace period before timeout (seconds)
KEEPALIVE_TIMEOUT_FACTOR = 4 # Multiplier for RTT-based timeout
ECPUBSIZE (64 bytes): Combined size of X25519 encryption public key (32B) + Ed25519 signing public key (32B). Sent together in link request.
ESTABLISHMENT_TIMEOUT_PER_HOP (6 seconds): Timeout per hop. For 10-hop path: 10 × 6 = 60 seconds total timeout.
KEEPALIVE (360 seconds): Interval for sending keep-alive packets when link is idle. Ensures both ends know link is alive.
STALE_TIME (720 seconds): After no traffic for this duration, link enters STALE state and sends final keep-alive.
STALE_GRACE (5 seconds): Additional grace period after final keep-alive before declaring timeout.
Link establishment uses exactly 3 packets totaling 297 bytes:
Sent by initiator to destination:
[HEADER 19B][LKi 64B]
Total: 83 bytes
LKi = encryption_public_key (32B) + signing_public_key (32B)
Header (19 bytes):
LKi (64 bytes): Initiator's ephemeral public keys
With optional MTU signalling (+3 bytes): 86 bytes total
Sent by destination back to initiator:
[HEADER 19B][SIGNATURE 64B][LKr 32B]
Total: 115 bytes
SIGNATURE = Ed25519 signature (64B)
LKr = responder encryption public key (32B)
Header (19 bytes):
SIGNATURE (64 bytes): Ed25519 signature of link_id + LKr + responder_sig_pub + signalling_bytes using destination's persistent signing key. The signing public key is not transmitted — the initiator already knows it from the destination's identity.
LKr (32 bytes): Destination's ephemeral X25519 encryption public key
With optional MTU signalling (+3 bytes appended): 118 bytes total
Sent by initiator to measure round-trip time:
[HEADER 19B][ENCRYPTED_DATA 80B]
Total: 99 bytes
Header (19 bytes):
ENCRYPTED_DATA (80 bytes): Encrypted timestamp for RTT calculation
Links use Elliptic Curve Diffie-Hellman on Curve25519:
Li_privLi_pub = X25519(Li_priv, G) where G is generatorLi_pub in link request as part of LKiWhen link proof received:
4. Extract Lr_pub from link proof
5. Perform ECDH: shared_secret = X25519(Li_priv, Lr_pub)
6. Derive link keys via HKDF from shared_secret
Li_pubLr_privLr_pub = X25519(Lr_priv, G)shared_secret = X25519(Lr_priv, Li_pub)Lr_pub in link proofBoth sides now share the same shared_secret without ever transmitting it.
Link ID is SHA-256 hash of entire link request packet:
link_id = SHA256(link_request_packet)[:16] # Truncated to 16 bytes
This hash serves as:
Currently only AES-256-CBC is enabled:
MODE_AES256_CBC = 0x01
ENABLED_MODES = [MODE_AES256_CBC]
Reserved modes for future use:
Links send keep-alive packets when idle to detect timeouts.
# Send keep-alive if no traffic for KEEPALIVE seconds
if time_since_last_traffic >= KEEPALIVE:
send_keepalive()
Keep-alive packet:
keepalive_size = 20 bytes
keepalive_interval = 360 seconds
bits_per_second = (20 * 8) / 360 = 0.44 bits/second
Total cost: ~0.44 bits/second per active link
timeout = (RTT * KEEPALIVE_TIMEOUT_FACTOR) + STALE_GRACE
# Example: RTT = 2 seconds
timeout = (2 * 4) + 5 = 13 seconds
After entering STALE state (no traffic for 720s):
(RTT × 4) + 5 secondsLinks provide forward secrecy through:
If link keys compromised:
Links negotiate MTU during establishment (optional):
# 3-byte MTU signalling
mtu = 512 # Example MTU
mode = 0x01 # MODE_AES256_CBC
# Encode: 21 bits MTU + 3 bits mode
signalling_value = (mtu & 0x1FFFFF) + (((mode << 5) & 0xE0) << 16)
mtu_bytes = struct.pack(">I", signalling_value)[1:] # Last 3 bytes
Appended to link request (LKi + mtu_bytes) and link proof (LKr + signature + mtu_bytes).
Maximum data unit for link packets:
# Calculation from Link.py
MDU = floor((MTU - IFAC_MIN_SIZE - HEADER_MINSIZE - TOKEN_OVERHEAD) / AES_BLOCKSIZE) * AES_BLOCKSIZE - 1
# With MTU=500:
MDU = floor((500 - 1 - 19 - 48) / 16) * 16 - 1
MDU = floor(432 / 16) * 16 - 1
MDU = 27 * 16 - 1
MDU = 432 - 1 = 431 bytes
This is the maximum application data per link packet after encryption overhead.
Time Initiator Network Destination
---- --------- ------- -----------
t=0 Send LinkReq ─────────────────────────────→ Receive
State: PENDING Validate
Generate keys
ECDH
t=RTT/2 ←─────────────────── Send LinkProof
Receive State: ACTIVE
Validate signature
ECDH
Send RTT packet ───────────────────────────→ Receive
State: ACTIVE Measure RTT
t=RTT Link fully established with measured RTT
Total establishment time: ~1 RTT for 3-packet handshake
Link initiator reveals no identifying information:
Transport nodes store link entries:
link_table = {
link_id: hops
}
Entries timeout if not proven within establishment timeout period.
Links provide reliable delivery via:
For detailed protocol specifications:
references/link-establishment.md - Complete 7-step handshake processreferences/key-exchange.md - ECDH shared secret derivation and HKDFreferences/keepalive.md - Watchdog logic and timeout detectionreferences/wire-examples.py - Byte-level link request packet constructionRelated skills:
cryptography-identity - X25519, Ed25519, HKDF detailspackets-wire-format - Packet structure and contextstransport-routing - Link table and multi-hop routingresources - Large data transfer over linksSource References:
https://github.com/markqvist/Reticulum/RNS/Link.py (lines 65-200)https://github.com/markqvist/Reticulum/docs/source/understanding.rst (lines 518-577)