How Tor Circuit Key Exchange Works
This article provides a technical overview of how encryption keys are
negotiated within the Tor network. Tor relies on an incremental
“telescoping” mechanism combined with the ntor handshake
protocol to establish separate, layered encryption keys between a client
and each relay in a circuit. By using ephemeral-static Diffie-Hellman
cryptography, the network ensures that each hop only knows its immediate
predecessor and successor while providing perfect forward secrecy for
all routed traffic.
The Telescoping Circuit Building Process
Tor does not establish all connections simultaneously. Instead, circuits are created incrementally—one relay at a time—in a process called telescoping. A standard Tor circuit consists of three nodes: the Guard (entry) relay, the Middle relay, and the Exit relay.
To initiate a circuit, the client retrieves the public identity keys and onion keys of the relays from the signed network consensus directory. The client then exchanges keys sequentially, using already established encrypted tunnels to negotiate keys with downstream relays.
The ntor Handshake
Modern Tor implementations use the ntor protocol, a
Diffie-Hellman handshake based on Curve25519, to negotiate symmetric
keys. The handshake operates as follows:
- Client Ephemeral Key Generation: The client creates a temporary (ephemeral) Curve25519 key pair.
- Handshake Request (
CREATE2cell): The client sends its ephemeral public key, along with the relay’s identity fingerprint and public onion key, packaged inside aCREATE2cell. - Relay Computation and Response (
CREATED2cell): The relay receives the cell, generates its own ephemeral key pair, and performs a series of scalar multiplications using both the ephemeral keys and its static onion key. The relay produces a shared secret, computes an authentication digest (HMAC), and sends its ephemeral public key and HMAC back inside aCREATED2cell. - Key Derivation: The client verifies the HMAC using the relay’s static public key and the returned ephemeral key. Once verified, both the client and the relay use a Key Derivation Function (KDF)—specifically HKDF-SHA256—to derive separate symmetric forward and backward encryption keys (AES-CTR) and integrity keys.
Step-by-Step Circuit Extension
1. Connecting to the Guard Relay
The client connects directly to the Guard relay via TLS and sends a
CREATE2 cell. After the ntor handshake
completes, the client and Guard share a symmetric key (\(K_1\)).
2. Extending to the Middle Relay
To connect to the Middle relay without revealing its IP address: *
The client generates a new ephemeral key pair for the Middle relay. * It
packages the handshake data into a RELAY_EXTEND2 cell. *
The client encrypts this cell using \(K_1\) and sends it to the Guard relay. *
The Guard decrypts the outer layer, extracts the payload, converts it
into a CREATE2 cell, and forwards it to the Middle relay. *
The Middle relay completes the ntor handshake and returns a
CREATED2 cell to the Guard. * The Guard wraps this response
in a RELAY_EXTENDED2 cell, encrypts it with \(K_1\), and sends it back to the client. *
The client and Middle relay compute a shared symmetric key (\(K_2\)).
3. Extending to the Exit Relay
The process repeats for the Exit relay: * The client encrypts the new
RELAY_EXTEND2 handshake payload first with \(K_2\), then with \(K_1\). * The Guard strips layer \(K_1\) and forwards the payload to the
Middle relay. * The Middle relay strips layer \(K_2\) and sends the resulting
CREATE2 cell to the Exit relay. * The Exit relay responds
back through the Middle and Guard relays to the client. * The client and
Exit relay derive the final shared symmetric key (\(K_3\)).
Layered Encryption and Forward Secrecy
At the end of this process, the client holds three distinct symmetric keys (\(K_1\), \(K_2\), \(K_3\)), while each relay holds only the single key negotiated with the client. When sending data, the client encrypts the payload in three layers (like an onion): first with \(K_3\), then \(K_2\), then \(K_1\).
Because the ephemeral keys used during the ntor
handshake are discarded immediately after key derivation, past session
traffic cannot be decrypted even if a relay’s long-term static identity
keys are compromised in the future.