Noise Protocol primer
When your phone connects to the relay, it has to be sure it reached your relay and not something in between, and nobody on the network should read what passes. The Noise Protocol Framework is a specification for building handshakes that do this. WireGuard uses it with the same cipher suite TrueSeal does. This page explains how it works, assuming no background in protocol design.
Why Noise and not TLS
TLS ties identity to a domain name and checks it through certificate authorities. A TrueSeal device has no domain name and no certificate; its identity is a keypair it made itself, and the relay’s identity is the public key in the app’s Relay Address. Noise starts from keys directly.
Noise also fixes the cipher suite in the protocol name. Both sides agree on it in advance, so there is no negotiation step and no way to talk either side down to a weaker cipher.
Diffie-Hellman
Diffie-Hellman (DH) lets two parties compute the same secret without sending it. With Alice’s keypair (a_priv, a_pub) and Bob’s (b_priv, b_pub):
DH(a_priv, b_pub) == DH(b_priv, a_pub)
Each side uses its own private key and the other’s public key. Someone who sees both public keys can’t compute the result. TrueSeal uses X25519 for DH.
A handshake is a chain of DH results
A Noise handshake is a short exchange of messages, and each step runs one or more DH operations. Every DH result is mixed into a running chaining key with HKDF. When the handshake ends, the chaining key depends on every DH that happened, so both sides derive the same session keys only if each of them held the right private keys at each step.
Static and ephemeral keys
Each side can bring two kinds of keypair:
- A static keypair is long-lived and identifies its owner. The relay’s static key is in your Relay Address. A device’s static key is its X25519 identity key.
- An ephemeral keypair is made for one handshake and thrown away after it.
Patterns differ in which static keys each side sends and which they already know. In NK the initiator sends no static key at all, which is why TrueSeal uses it for pushes.
Forward secrecy
The session keys depend on DH results that involve the ephemeral keys. Once a handshake ends, the ephemeral private keys are gone. Someone who records a session and later steals a static private key can’t recompute that session’s keys, so the recording stays unreadable. With the stolen key they can still pretend to be its owner in new sessions.
In TrueSeal this protects the connection between a device and the relay. The messages inside are sealed to each recipient’s long-lived key, so they don’t gain forward secrecy from Noise.
The handshake hash
Both sides also keep a running hash of every handshake message, sent and received. Each encrypted handshake payload uses that hash as associated data, so if anyone changes, drops or reorders a handshake message, the next decryption fails. At the end, both sides hold the same handshake hash, and it is bound to the session.
The prologue goes into this hash before the first message. Two sides that start with different prologues can’t finish the handshake. In the preview, TrueSeal puts its Transport Version there, once trueseal-noise#25 adds the prologue argument.
After the handshake
The final chaining key splits into two keys, one for each direction. Each direction has its own key and its own message counter used as the nonce, so both sides can send at once, and a message sent one way can’t be replayed back the other way.
The patterns TrueSeal uses
A Noise pattern says what each side knows before it starts, which messages go each way, and which DH runs at each step. TrueSeal uses two: