More details of the rendezvous design

Roger Dingledine arma at
Sun Mar 21 18:40:22 UTC 2004

Here are more details on our rendezvous design. If there are no glaring
holes or problems, we'll add it to the spec and start building.

There are 9 pieces to the rendezvous design:
(1) Bob configures his local IP
(2) Bob makes and publishes the rendezvous service descriptor
(3) Alice gets a y.onion address out of band
(4) Bob establishes each introduction point
(5) Alice establishes a rendezvous point
(6) Alice introduces herself
(7) Bob goes to the rendezvous point
(8) What the rendezvous point does
(9) Alice sends a begin cell

(1) Bob configures his local IP.
He generates a public/private keypair (stored locally), and for each
IP:port service he wants to offer, he configures a virtual port that
maps to it. (Maybe he has a separate directory tree in his datadir for
hidden services, with a config file stored in its root.)

(2) Bob makes and publishes his rendezvous service descriptor.
He chooses a set of n Tor servers to use as introduction points. The
descriptor includes the PK of the service [128 bytes], a freshness
timestamp [4 bytes], the set of padded nicknames [20 bytes each], and
a signature on the hash of the descriptor [128 bytes]. Bob periodically
publishes a fresh service descriptor to each directory server (directory
servers are now also playing the role of serving service descriptors).

(3) Alice gets a y.onion:port address out of band.
y is the base32 of the first 10 bytes of the hash of PK. Port comes in
at step 9 below. Alice picks a directory server, and fetches the service
descriptor that corresponds to y. She verifies its integrity.
(Later we may extend this to x.y.onion:port addresses, where x is some
sort of auth cookie.)

(4) Bob establishes each introduction point.
Bob establishes a Tor circuit which ends at the chosen introduction point,
and sends a relay establish_intro cell, with the hash of his service's
public key (20 bytes).

(5) Alice establishes a rendezvous point.
Alice chooses a Tor server as her rendezvous point, and establishes a
Tor circuit which ends at that server. She generates a random 20-byte
rendezvous cookie, and sends it in a relay establish_rend cell.

(6) Alice introduces herself.
She builds a Tor circuit which ends at the introduction point, and sends
a relay introduce cell, which includes the 20 bytes of H(PK) plus a blob:
  rendezvous cookie [20 bytes]             \
  nickname of rendezvous point [20 bytes]   \ encrypted to PK
  symmetric key [16 bytes]                  /
  g^x part one [72 bytes]                  /
  g^x part two [56 bytes] -- encrypted via AES with symmetric key

(7) Bob goes to the rendezvous point.
He builds a Tor circuit which ends at the server Alice chose, and sends
a relay rendezvous_one cell, which includes:
  rendezvous cookie [20 bytes]
  g^y [128 bytes]
  H(g^(xy) | 0) [20 bytes]

(8) What the rendezvous point does.
The rendezvous point matches the rendezvous cookie to the one Alice
provided, and sends a relay rendezvous_two cell down Alice's circuit,
containing the g^y and H(K). From then on, it has two circuits which
both terminate at it. So each circuit has a layer of encryption that it
does at that node. Thus the rendezvous point simply passes the payload
of relay cells, unchanged, from one circuit to the other and vice versa.
of cells

(9) Alice sends a begin cell.
Clearly Alice does not know the IP she will be connecting to. So she
sends a begin cell with the magic address "", and the port number from
the original y.onion:port address she got. Bob's client figures out which
service she wants (based on the por), and connect()s out to it. [[Should
we find a better way to handle how Alice learns about ports?]]

More information about the tor-dev mailing list