This specification contains all details of Sphinx packet data structures and algorithms for constructing/unwrapping Sphinx packets.

Please note that this specification is exactly the same as what defined in the Sphinx paper below and what implemented by Nym: https://github.com/nymtech/sphinx.

Therefore, this document covers only an overview of Sphinx packet construction with easy-to-understand diagrams. For more details, please see the executable specification written in Python.

Sphinx Packet Construction

Header Construction

A diagram below describes how a Sphinx header is constructed.

Routing Information Encryption

Routing Information Filler Construction

In the Header Construction diagram, two zero fillers (encrypted; colored) are appended to the EncryptedPaddedFinalRoutingInfo to make it have the same size as EncryptedRoutingInfo (300 bytes).

Also, when constructing a RoutingInfo of $m_3$ (that will be used by $m_2$), the last filler is truncated. And, the remaining filler in the RoutingInfo is encrypted again with a stream key of $m_2$ to build a new EncryptedRoutingInfo (300 bytes).

That is, the filler is for preventing adversaries from distinguishing packets emitted from different mix layers (i.e. packet-layer undistinguishability).

The diagram below shows how fillers can be constructed and encrypted. The zero-filler is a 60-byte x00 byte array.

Untitled

Because an additional XOR is used separately with AES128-CTR for encryption, the truncated filler can be easily recovered when a mix node decrypts a EncryptedRoutingInfo. For example,