The protocol is designed to be stateless, multiplexed, and adversarially resistant.
Initiates the X25519 Diffie-Hellman key exchange.
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 1 |
Type | 0x48 (b'H') |
| 1 | VLP |
Bincode Blob | Contains ProtocolVersion (u16), Capabilities (u16), SessionID (u64), PublicKey (32 bytes), and AuthTag (16 bytes). |
Every data packet is padded to exactly 1200 bytes to prevent traffic analysis. The payload size is hidden within the encrypted header.
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 1 |
Type | 0x44 (b'D') |
| 1 | 8 |
Session ID | Plaintext. Used by receiver to look up the X25519 Shared Secret. |
| 9 | 22 |
Masked Header | The XOR-obfuscated geometry. |
| 31 | VLP |
Payload | The raw Wirehair droplet data (up to Pkt Size). |
| Varies | VLP |
Padding | Zeros appended to reach exactly 1200 bytes. |
To prevent stream tracking and replay analysis, the 22-byte geometry header is XOR-masked before transmission.
Plaintext Geometry:
| Offset | Type | Field | Description |
|---|---|---|---|
| 0 | u32 |
Stream ID | Multiplexing ID for the specific file. |
| 4 | u64 |
Block ID | Chunk index. Block 0 is the SessionManifest. |
| 12 | u32 |
Seq ID | FEC droplet index. |
| 16 | u32 |
Total Size | Total bytes of the encrypted blob for this Block. |
| 20 | u16 |
Pkt Size | Size of the valid Payload in this UDP packet. |
Masking Algorithm:
- Extract the first 12 bytes of the Payload. This is the Dynamic Nonce.
- Initialize ChaCha20 with the
SharedSecretand theDynamic Nonce. - Encrypt a 22-byte array of zeros
[0u8; 22]to generate the Keystream Mask. - Apply a bitwise XOR between the Plaintext Geometry and the Keystream Mask.
Because the payload is previously encrypted via ChaCha20-Poly1305 (using BlockID as AAD), the first 12 bytes are statistically random and guaranteed to change for every FEC droplet, ensuring the Keystream Mask is highly dynamic.
Each stream starts with a serialized SessionManifest block. Current fields:
filename: Stringfile_size: u64trace_id: u64timestamp: u64
trace_id is propagated through sender/receiver events to support observability and relay tracing.