|  | @@ -17,7 +17,9 @@ TODO: (very soon)
 | 
	
		
			
				|  |  |        - Copy prose from tor-design to make everything more readable.
 | 
	
		
			
				|  |  |  when do we rotate which keys (tls, link, etc)?
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -0. Notation:
 | 
	
		
			
				|  |  | +0. Preliminaries
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +0.1.  Notation and encoding
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     PK -- a public key.
 | 
	
		
			
				|  |  |     SK -- a private key
 | 
	
	
		
			
				|  | @@ -30,27 +32,79 @@ when do we rotate which keys (tls, link, etc)?
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     All numeric values are encoded in network (big-endian) order.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -   Unless otherwise specified, all symmetric ciphers are AES in counter
 | 
	
		
			
				|  |  | -   mode, with an IV of all 0 bytes.  Asymmetric ciphers are either RSA
 | 
	
		
			
				|  |  | -   with 1024-bit keys and exponents of 65537, or DH where the generator (g)
 | 
	
		
			
				|  |  | -   is 2 and the modulus (p) is the 1024-bit safe prime from rfc2409,
 | 
	
		
			
				|  |  | -   section 6.2, whose hex representation is:
 | 
	
		
			
				|  |  | +   H(m) -- a cryptographic hash of m.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +0.2. Security parameters
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +   Tor uses a stream cipher, a public-key cipher, the Diffie-Hellman
 | 
	
		
			
				|  |  | +   protocol, and and a hash function.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +   KEY_LEN -- the length of the stream cipher's key, in bytes.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +   PK_ENC_LEN -- the length of a public-key encrypted message, in bytes.
 | 
	
		
			
				|  |  | +   PK_PAD_LEN -- the number of bytes added in padding for public-key
 | 
	
		
			
				|  |  | +     encryption, in bytes. (The largest number of bytes that can be encrypted
 | 
	
		
			
				|  |  | +     in a single public-key operation is therefore PK_ENC_LEN-PK_PAD_LEN.)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +   DH_LEN -- the number of bytes used to represent a member of the
 | 
	
		
			
				|  |  | +     Diffie-Hellman group.
 | 
	
		
			
				|  |  | +   DH_SEC_LEN -- the number of bytes used in a Diffie-Hellman private key (x).
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +   HASH_LEN -- the length of the hash function's output, in bytes.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +   CELL_LEN -- The length of a Tor cell, in bytes.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +0.3. Ciphers
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +   For a stream cipher, we use 128-bit AES in counter mode, with an IV of all
 | 
	
		
			
				|  |  | +   0 bytes.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +   For a public-key cipher, we use RSA with 1024-bit keys and a fixed
 | 
	
		
			
				|  |  | +   exponent of 65537.  We use OAEP padding, with SHA1 as its digest
 | 
	
		
			
				|  |  | +   function.   (For OAEP padding, see
 | 
	
		
			
				|  |  | +   ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +   For Diffie-Hellman, we use a generator (g) of 2.  For the modulus (p), the
 | 
	
		
			
				|  |  | +   1024-bit safe prime from rfc2409, (section 6.2) whose hex representation
 | 
	
		
			
				|  |  | +   is:
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |       "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08"
 | 
	
		
			
				|  |  |       "8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B"
 | 
	
		
			
				|  |  |       "302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9"
 | 
	
		
			
				|  |  |       "A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6"
 | 
	
		
			
				|  |  |       "49286651ECE65381FFFFFFFFFFFFFFFF"
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |     As an optimization, implementations SHOULD choose DH private keys (x) of
 | 
	
		
			
				|  |  |     320 bits.  Implementations that do this MUST never use any DH key more
 | 
	
		
			
				|  |  |     than once.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -   All "hashes" are 20-byte SHA1 cryptographic digests.
 | 
	
		
			
				|  |  | +   For a hash function, we use SHA1.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +   KEY_LEN=16.
 | 
	
		
			
				|  |  | +   DH_LEN=128; DH_GROUP_LEN=40.
 | 
	
		
			
				|  |  | +   PK_ENC_LEN=128; PK_PAD_LEN=42.
 | 
	
		
			
				|  |  | +   HASH_LEN=20.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     When we refer to "the hash of a public key", we mean the SHA1 hash of the
 | 
	
		
			
				|  |  |     DER encoding of an ASN.1 RSA public key (as specified in PKCS.1).
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +   All "random" values should be generated with a cryptographically strong
 | 
	
		
			
				|  |  | +   random number generator, unless otherwise noted.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +   The "hybrid encryption" of a byte sequence M with a public key PK is
 | 
	
		
			
				|  |  | +   computed as follows:
 | 
	
		
			
				|  |  | +      1. If M is less than PK_ENC_LEN-PK_PAD_LEN, pad and encrypt M with PK.
 | 
	
		
			
				|  |  | +      2. Otherwise, generate a KEY_LEN byte random key K.
 | 
	
		
			
				|  |  | +         Let M1 = the first PK_ENC_LEN-PK_PAD_LEN-KEY_LEN bytes of M,
 | 
	
		
			
				|  |  | +         and let M2 = the rest of M.
 | 
	
		
			
				|  |  | +         Pad and encrypt K|M1 with PK.  Encrypt M2 with our stream cipher,
 | 
	
		
			
				|  |  | +         using the key K.  Concatenate these encrypted values.
 | 
	
		
			
				|  |  | +   (Note that this "hybrid encryption" approach does not prevent an attacker
 | 
	
		
			
				|  |  | +   from adding or removing bytes to the end of M.)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +0.4. Other parameter values
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +   CELL_LEN=512
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  1. System overview
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     Onion Routing is a distributed overlay network designed to anonymize
 | 
	
	
		
			
				|  | @@ -74,7 +128,7 @@ when do we rotate which keys (tls, link, etc)?
 | 
	
		
			
				|  |  |     support "TLS_DHE_RSA_WITH_AES_128_CBC_SHA" if it is available.
 | 
	
		
			
				|  |  |     Implementations MAY support other ciphersuites, but MUST NOT
 | 
	
		
			
				|  |  |     support any suite without ephemeral keys, symmetric keys of at
 | 
	
		
			
				|  |  | -   least 128 bits, and digests of at least 160 bits.
 | 
	
		
			
				|  |  | +   least KEY_LEN bits, and digests of at least HASH_LEN bits.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     An OP or OR always sends a two-certificate chain, consisting of a
 | 
	
		
			
				|  |  |     certificate using a short-term connection key and a second, self-
 | 
	
	
		
			
				|  | @@ -95,7 +149,7 @@ when do we rotate which keys (tls, link, etc)?
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     Once a TLS connection is established, the two sides send cells
 | 
	
		
			
				|  |  |     (specified below) to one another.  Cells are sent serially.  All
 | 
	
		
			
				|  |  | -   cells are 512 bytes long.  Cells may be sent embedded in TLS
 | 
	
		
			
				|  |  | +   cells are CELL_LEN bytes long.  Cells may be sent embedded in TLS
 | 
	
		
			
				|  |  |     records of any size or divided across TLS records, but the framing
 | 
	
		
			
				|  |  |     of TLS records MUST NOT leak information about the type or contents
 | 
	
		
			
				|  |  |     of the cells.
 | 
	
	
		
			
				|  | @@ -116,8 +170,8 @@ when do we rotate which keys (tls, link, etc)?
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          CircID                                [2 bytes]
 | 
	
		
			
				|  |  |          Command                               [1 byte]
 | 
	
		
			
				|  |  | -        Payload (padded with 0 bytes)         [509 bytes]
 | 
	
		
			
				|  |  | -                                         [Total size: 512 bytes]
 | 
	
		
			
				|  |  | +        Payload (padded with 0 bytes)         [CELL_LEN-3 bytes]
 | 
	
		
			
				|  |  | +                                         [Total size: CELL_LEN bytes]
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     The CircID field determines which circuit, if any, the cell is
 | 
	
		
			
				|  |  |     associated with.
 | 
	
	
		
			
				|  | @@ -168,41 +222,33 @@ when do we rotate which keys (tls, link, etc)?
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     The payload for a CREATE cell is an 'onion skin', which consists
 | 
	
		
			
				|  |  |     of the first step of the DH handshake data (also known as g^x).
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -   The data is encrypted to Bob's PK as follows: Suppose Bob's PK
 | 
	
		
			
				|  |  | -   modulus is L octets long. If the data to be encrypted is shorter
 | 
	
		
			
				|  |  | -   than L-42, then it is encrypted directly (with OAEP padding: see
 | 
	
		
			
				|  |  | -   ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf). If the
 | 
	
		
			
				|  |  | -   data is at least as long as L-42, then a randomly generated 16-byte
 | 
	
		
			
				|  |  | -   symmetric key is prepended to the data, after which the first L-16-42
 | 
	
		
			
				|  |  | -   bytes of the data are encrypted with Bob's PK; and the rest of the
 | 
	
		
			
				|  |  | -   data is encrypted with the symmetric key.
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -   So in this case, the onion skin can be thought of as:
 | 
	
		
			
				|  |  | -       RSA-encrypted:
 | 
	
		
			
				|  |  | -         OAEP padding                  [42 bytes]
 | 
	
		
			
				|  |  | -         Symmetric key                 [16 bytes]
 | 
	
		
			
				|  |  | -         First part of g^x             [70 bytes]
 | 
	
		
			
				|  |  | +   This value is hybrid-encrypted (see 0.3) to Bob's public key, giving
 | 
	
		
			
				|  |  | +   an onion-skin of:
 | 
	
		
			
				|  |  | +       PK-encrypted:
 | 
	
		
			
				|  |  | +         Padding padding               [PK_PAD_LEN bytes]
 | 
	
		
			
				|  |  | +         Symmetric key                 [KEY_LEN bytes]
 | 
	
		
			
				|  |  | +         First part of g^x             [PK_ENC_LEN-PK_PAD_LEN-KEY_LEN bytes]
 | 
	
		
			
				|  |  |         Symmetrically encrypted:
 | 
	
		
			
				|  |  | -         Second part of g^x            [58 bytes]
 | 
	
		
			
				|  |  | +         Second part of g^x            [DH_LEN-(PK_ENC_LEN-PK_PAD_LEN-KEY_LEN)
 | 
	
		
			
				|  |  | +                                           bytes]
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     The relay payload for an EXTEND relay cell consists of:
 | 
	
		
			
				|  |  |           Address                       [4 bytes]
 | 
	
		
			
				|  |  |           Port                          [2 bytes]
 | 
	
		
			
				|  |  | -         Onion skin                    [186 bytes]
 | 
	
		
			
				|  |  | -         Identity fingerprint          [20 bytes]
 | 
	
		
			
				|  |  | +         Onion skin                    [DH_LEN+KEY_LEN+PK_PAD_LEN bytes]
 | 
	
		
			
				|  |  | +         Identity fingerprint          [HASH_LEN bytes]
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     The port and address field denote the IPV4 address and port of the next
 | 
	
		
			
				|  |  | -   onion router in the circuit; the public key hash is the SHA1 hash of the
 | 
	
		
			
				|  |  | -   PKCS#1 ASN1 encoding of the next onion router's identity (signing) key.
 | 
	
		
			
				|  |  | -   (Including this hash allows the extending OR verify that it is indeed
 | 
	
		
			
				|  |  | -   connected to the correct target OR, and prevents certain man-in-the-middle
 | 
	
		
			
				|  |  | -   attacks.)
 | 
	
		
			
				|  |  | +   onion router in the circuit; the public key hash is the hash of the PKCS#1
 | 
	
		
			
				|  |  | +   ASN1 encoding of the next onion router's identity (signing) key.  (See 0.3
 | 
	
		
			
				|  |  | +   above.)  (Including this hash allows the extending OR verify that it is
 | 
	
		
			
				|  |  | +   indeed connected to the correct target OR, and prevents certain
 | 
	
		
			
				|  |  | +   man-in-the-middle attacks.)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     The payload for a CREATED cell, or the relay payload for an
 | 
	
		
			
				|  |  |     EXTENDED cell, contains:
 | 
	
		
			
				|  |  | -         DH data (g^y)                 [128 bytes]
 | 
	
		
			
				|  |  | -         Derivative key data (KH)      [20 bytes]   <see 4.2 below>
 | 
	
		
			
				|  |  | +         DH data (g^y)                 [DH_LEN bytes]
 | 
	
		
			
				|  |  | +         Derivative key data (KH)      [HASH_LEN bytes]   <see 4.2 below>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     The CircID for a CREATE cell is an arbitrarily chosen 2-byte integer,
 | 
	
		
			
				|  |  |     selected by the node (OP or OR) that sends the CREATE cell.  To prevent
 | 
	
	
		
			
				|  | @@ -232,12 +278,12 @@ when do we rotate which keys (tls, link, etc)?
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     A CREATE_FAST cell contains:
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -       Key material (X)    [20 bytes]
 | 
	
		
			
				|  |  | +       Key material (X)    [HASH_LEN bytes]
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     A CREATED_FAST cell contains:
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -       Key material (Y)    [20 bytes]
 | 
	
		
			
				|  |  | -       Derivative key data [20 bytes] (See 4.2 below)
 | 
	
		
			
				|  |  | +       Key material (Y)    [HASH_LEN bytes]
 | 
	
		
			
				|  |  | +       Derivative key data [HASH_LEN bytes] (See 4.2 below)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     The values of X and Y must be generated randomly.
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -251,7 +297,7 @@ when do we rotate which keys (tls, link, etc)?
 | 
	
		
			
				|  |  |     and server MUST verify that the received g^x or g^y value is not degenerate;
 | 
	
		
			
				|  |  |     that is, it must be strictly greater than 1 and strictly less than p-1
 | 
	
		
			
				|  |  |     where p is the DH modulus.  Implementations MUST NOT complete a handshake
 | 
	
		
			
				|  |  | -   with degenerate keys.  Implementions MAY discard other "weak" g^x values.
 | 
	
		
			
				|  |  | +   with degenerate keys.  Implementations MAY discard other "weak" g^x values.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     (Discarding degenerate keys is critical for security; if bad keys are not
 | 
	
		
			
				|  |  |     discarded, an attacker can substitute the server's CREATED cell's g^y with
 | 
	
	
		
			
				|  | @@ -268,12 +314,15 @@ when do we rotate which keys (tls, link, etc)?
 | 
	
		
			
				|  |  |     If CREATE_FAST is used, the client and server base their key material on
 | 
	
		
			
				|  |  |     K0=X|Y.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -   From the base key material K0, they compute 100 bytes of derivative
 | 
	
		
			
				|  |  | -   key data as K = SHA1(K0 | [00]) | SHA1(K0 | [01]) | ... SHA1(K0 |
 | 
	
		
			
				|  |  | -   [04]) where "00" is a single octet whose value is zero, [01] is a
 | 
	
		
			
				|  |  | -   single octet whose value is one, etc.  The first 20 bytes of K form
 | 
	
		
			
				|  |  | -   KH, bytes 21-40 form the forward digest Df, 41-60 form the backward
 | 
	
		
			
				|  |  | -   digest Db, 61-76 form Kf, and 77-92 form Kb.
 | 
	
		
			
				|  |  | +   From the base key material K0, they compute KEY_LEN*2+HASH_LEN*3 bytes of
 | 
	
		
			
				|  |  | +   derivative key data as
 | 
	
		
			
				|  |  | +       K = H(K0 | [00]) | H(K0 | [01]) | H(K0 | [02]) | ...
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +   The first HASH_LEN bytes of K form KH; the next HASH_LEN form the forward
 | 
	
		
			
				|  |  | +   digest Df; the next HASH_LEN 41-60 form the backward digest Db; the next
 | 
	
		
			
				|  |  | +   KEY_LEN 61-76 form Kf, and the final KEY_LEN form Kb.  Excess bytes from K
 | 
	
		
			
				|  |  | +   are discarded.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     KH is used in the handshake response to demonstrate knowledge of the
 | 
	
		
			
				|  |  |     computed shared key. Df is used to seed the integrity-checking hash
 | 
	
	
		
			
				|  | @@ -399,7 +448,7 @@ when do we rotate which keys (tls, link, etc)?
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     Otherwise, if the OR is not at the OP edge of the circuit (that is,
 | 
	
		
			
				|  |  |     either an 'exit node' or a non-edge node), it de/encrypts the payload
 | 
	
		
			
				|  |  | -   with AES/CTR, as follows:
 | 
	
		
			
				|  |  | +   with the stream cipher, as follows:
 | 
	
		
			
				|  |  |          'Forward' relay cell (same direction as CREATE):
 | 
	
		
			
				|  |  |              Use Kf as key; decrypt.
 | 
	
		
			
				|  |  |          'Back' relay cell (opposite direction from CREATE):
 | 
	
	
		
			
				|  | @@ -415,7 +464,7 @@ when do we rotate which keys (tls, link, etc)?
 | 
	
		
			
				|  |  |     sends a DESTROY cell to tear down the circuit.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     When a relay cell arrives at an OP, the OP decrypts the payload
 | 
	
		
			
				|  |  | -   with AES/CTR as follows:
 | 
	
		
			
				|  |  | +   with the stream cipher as follows:
 | 
	
		
			
				|  |  |           OP receives data cell:
 | 
	
		
			
				|  |  |              For I=N...1,
 | 
	
		
			
				|  |  |                  Decrypt with Kb_I.  If the payload is recognized (see
 | 
	
	
		
			
				|  | @@ -438,7 +487,7 @@ when do we rotate which keys (tls, link, etc)?
 | 
	
		
			
				|  |  |           StreamID                [2 bytes]
 | 
	
		
			
				|  |  |           Digest                  [4 bytes]
 | 
	
		
			
				|  |  |           Length                  [2 bytes]
 | 
	
		
			
				|  |  | -         Data                    [498 bytes]
 | 
	
		
			
				|  |  | +         Data                    [CELL_LEN-14 bytes]
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     The relay commands are:
 | 
	
		
			
				|  |  |           1 -- RELAY_BEGIN     [forward]
 | 
	
	
		
			
				|  | @@ -461,7 +510,7 @@ when do we rotate which keys (tls, link, etc)?
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     The 'recognized' field in any unencrypted relay payload is always set
 | 
	
		
			
				|  |  |     to zero; the 'digest' field is computed as the first four bytes of
 | 
	
		
			
				|  |  | -   the running SHA-1 digest of all the bytes that have been destined for
 | 
	
		
			
				|  |  | +   the running digest of all the bytes that have been destined for
 | 
	
		
			
				|  |  |     this hop of the circuit or originated from this hop of the circuit,
 | 
	
		
			
				|  |  |     seeded from Df or Db respectively (obtained in section 4.2 above),
 | 
	
		
			
				|  |  |     and including this RELAY cell's entire payload (taken with the digest
 | 
	
	
		
			
				|  | @@ -763,7 +812,7 @@ The items' formats are as follows:
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     "fingerprint"
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -      A fingerprint (20 byte SHA1 hash of asn1 encoded public key, encoded
 | 
	
		
			
				|  |  | +      A fingerprint (a HASH_LEN-byte of asn1 encoded public key, encoded
 | 
	
		
			
				|  |  |        in hex, with a single space after every 4 characters) for this router's
 | 
	
		
			
				|  |  |        identity key.
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -801,7 +850,7 @@ The items' formats are as follows:
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     "router-signature" NL Signature NL
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -       The "SIGNATURE" object contains a signature of the PKCS1-padded SHA1
 | 
	
		
			
				|  |  | +       The "SIGNATURE" object contains a signature of the PKCS1-padded
 | 
	
		
			
				|  |  |         hash of the entire router descriptor, taken from the beginning of the
 | 
	
		
			
				|  |  |         "router" line, through the newline after the "router-signature" line.
 | 
	
		
			
				|  |  |         The router descriptor is invalid unless the signature is performed
 | 
	
	
		
			
				|  | @@ -909,7 +958,7 @@ descriptors, and a single "directory-signature" item.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      "directory-signature" nickname-of-dirserver NL Signature
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -The signature is computed by computing the SHA-1 hash of the
 | 
	
		
			
				|  |  | +The signature is computed by computing the digest of the
 | 
	
		
			
				|  |  |  directory, from the characters "signed-directory", through the newline
 | 
	
		
			
				|  |  |  after "directory-signature".  This digest is then padded with PKCS.1,
 | 
	
		
			
				|  |  |  and signed with the directory server's signing key.
 | 
	
	
		
			
				|  | @@ -981,6 +1030,8 @@ B.1. ... but which will require backward-incompatible change
 | 
	
		
			
				|  |  |    - Circuit IDs should be longer.
 | 
	
		
			
				|  |  |    - IPv6 everywhere.
 | 
	
		
			
				|  |  |    - Maybe, keys should be longer.
 | 
	
		
			
				|  |  | +    - Maybe, key-length should be adjustable.  How to do this without
 | 
	
		
			
				|  |  | +      making anonymity suck?
 | 
	
		
			
				|  |  |    - Drop backward compatibility.
 | 
	
		
			
				|  |  |    - We should use a 128-bit subgroup of our DH prime.
 | 
	
		
			
				|  |  |    - Handshake should use HMAC.
 |