std only.Expand description
Rotating connection-ID chain (introduced in WIRE v5 / ε; current WIRE v6).
After v4 header protection, the only per-connection cleartext left on the
wire is the outer 8-byte routing ConnId. v5 collapsed the two connection
identifiers (the redundant 32-byte inner session_id is dropped from the
data-plane wire) into this single CID and rotates it on every migration,
closing the stable-CID linkability residual (threat-model §12.5). The v6
anti-fingerprint pass did not touch this construction — it still holds.
§Construction
At session establishment each peer derives two per-direction chain secrets from the initial session secret (mirroring the AEAD / header-protection key layout):
cid_secret_c2s = derive_key_32("phantom-cid-c2s-v1", initial_secret) // client→server
cid_secret_s2c = derive_key_32("phantom-cid-s2c-v1", initial_secret) // server→clientThe CID for migration index i truncates a per-index KDF output to 8 bytes:
CID_i = derive_key_32("phantom-cid-v1", cid_secret ‖ i.to_be_bytes())[0..8]The client stamps its outbound ConnId from the c2s chain (the chain the
server routes on); the server stamps from the s2c chain. So is_server swaps
the outbound/inbound secrets, exactly like HeaderProtector::derive and the
AEAD send/recv keys — one peer’s outbound chain is the other’s inbound chain.
§Properties
- Session-stable, zeroized: the chain secrets are derived once and held
for the session (they do not rotate with the AEAD epoch); they are zeroized
on drop. The index advances on
migrate()(held bySession, not here). - Unguessable / unlinkable:
CID_iis a KDF output truncation, so withoutcid_secretthe CIDs are independent-random to an observer — pre- and post-migration flows cannot be linked. - Not forward-secret (honest caveat): like the HP keys, a session-key
compromise lets an attacker recompute the whole CID chain and link a
recorded flow retroactively. The payload stays forward-secret (AEAD
ratchets). See
docs/plans/wire-v5-cid-collapse-design.md§5.
Structs§
- CidChain
- Per-direction, session-stable rotating-CID chain secrets.
outbound_secretis the chain this peer stamps its outboundConnIdfrom (the peer routes on it);inbound_secretis the chain this peer routes inboundConnIds on. Derived once from the initial session secret; zeroized on drop.
Constants§
- CID_LEN
- Wire width of a routing CID (the outer UDP
ConnId): 8 bytes. - CID_
WINDOW_ LEADING - See
CID_WINDOW_TRAILING. - CID_
WINDOW_ TRAILING - Default demux window — trailing
T(in-flight reordering across a migration boundary) and leadingK(migration lookahead: the sender may have migrated ahead of delivery).(T + K + 1) = 19accepted CIDs per inbound direction.