Encrypted packets are the only files found in spools, in exchangeable storages and that are synchronized between TCP daemons.
Each encrypted packet has the following header:
+------------ HEADER -------------+ +-------- ENCRYPTED --------+ / \ / \ +--------------------------------------------+------------+----...-----------+------+ | MAGIC | NICE | SENDER | RCPT | EPUB | SIGN | SIZE | MAC | CIPHERTEXT | MAC | JUNK | +-------------------------------------/------\------------+----...-----------+------+ / \ +-------------------------------------+ | MAGIC | NICE | SENDER | RCPT | EPUB | +-------------------------------------+
XDR type | Value | |
---|---|---|
Magic number | 8-byte, fixed length opaque data | N N C P E 0x00 0x00 0x01 |
Niceness | unsigned integer | 1-255, packet niceness level |
Sender | 32-byte, fixed length opaque data | Sender node’s id |
Recipient | 32-byte, fixed length opaque data | Recipient node’s id |
Exchange public key | 32-byte, fixed length opaque data | Ephemeral curve25519 public key |
Signature | 64-byte, fixed length opaque data | ed25519 signature for that packet’s header |
Signature is calculated over all previous fields.
All following encryption is done using Twofish algorithm with 256-bit key in CTR mode of operation with zero initialization vector (because each encrypted packet has ephemeral exchange key). BLAKE2b-256 MAC is appended to the ciphertext.
After the headers comes an encrypted payload size and MAC of that size.
XDR type | Value | |
---|---|---|
Size | unsigned hyper integer | Payload size. |
Next comes the actual encrypted payload with corresponding MAC.
Each node has static exchange and signature keypairs. When node A want to send encrypted packet to node B, it: