[<<<][^^^][>>>]


Encrypted packet

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 | BLOCK 0 | BLOCK 1  ...   | JUNK |
+-------------------------------------/------\------+---------+----------...---+------+
                                     /        \
                      +-------------------------------------+
                      | MAGIC | NICE | SENDER | RCPT | EPUB |
                      +-------------------------------------+
XDR typeValue
Magic number8-byte, fixed length opaque dataN N C P E 0x00 0x00 0x04
Nicenessunsigned integer1-255, packet niceness level
Sender32-byte, fixed length opaque dataSender node’s id
Recipient32-byte, fixed length opaque dataRecipient node’s id
Exchange public key32-byte, fixed length opaque dataEphemeral curve25519 public key
Signature64-byte, fixed length opaque dataed25519 signature for that packet’s header

Signature is calculated over all previous fields.

All following encryption is done in AEAD mode using ChaCha20-Poly1305 algorithms. Data is splitted on 128 KiB blocks. Each block is encrypted with increasing nonce counter.

Authenticated and encrypted size come after the header:

XDR typeValue
Sizeunsigned hyper integerPayload size.

Then comes the actual payload.

Each node has static exchange and signature keypairs. When node A want to send encrypted packet to node B, it:

  1. generates ephemeral curve25519 keypair
  2. prepares structure for signing
  3. signs that structure using private ed25519 signature key
  4. takes remote node’s exchange public key and performs Diffie-Hellman computation on this remote static public key and private ephemeral one
  5. derive the keys:
    1. initialize BLAKE2Xb XOF with derived ephemeral key and 96-byte output length
    2. feed N N C P E 0x00 0x00 0x04 magic number to XOF
    3. read 32-bytes of "size" AEAD encryption key
    4. read 32-bytes of payload AEAD encryption key
    5. optionally read 32-bytes pad generation key
  6. encrypts size, appends its authenticated ciphertext to the header
  7. encrypts payload, appends its authenticated ciphertext
  8. possibly appends any kind of "junk" noise data to hide real payload’s size from the adversary (generated using XOF with unlimited output length)

[<<<][^^^][>>>]