Zhenfei Zhang <zzhang@...> writes: > 2.2.2 Handshake > > To perform the handshake, the client needs to know an identity key digest > for the server, and an ntor onion key (a curve25519 public key) for that > server. Call the ntor onion key "B". > > The client generates a temporary key pair: > x, X = KEYGEN(); > > an NTRU temporary key pair: > * QSSK, QSPK = QSKEYGEN(); > > ================================================================================ > and generates a client-side handshake with contents: > NODEID Server identity digest [ID_LENGTH bytes] > KEYID KEYID(B) [H_LENGTH bytes] > CLIENT_PK X [G_LENGTH bytes] > * QSPK QSPK [QSPK_LENGTH bytes] > ================================================================================ > > The server generates an ephemeral curve25519 keypair: > y, Y = KEYGEN(); > > a ephemeral "parallel" secret for encryption with NTRU: > * PAR_SEC P [H_LENGTH bytes] > > and computes: > * C = ENCRYPT( P | B, QSPK); > > Then it uses its ntor private key 'b' to compute an ECC secret > E = EXP(X,y) | EXP(X,b) | B | X | Y > > and computes: > > * secret_input = E | P | QSPK | ID | PROTOID > #pre secret_input = E | ID | PROTOID > > KEY_SEED = H(secret_input, t_key) > verify = H(secret_input, t_verify) > * auth_input = verify | B | Y | X | C | QSPK > | ID | PROTOID | "Server" > #pre auth_input = verify | B | Y | X | ID | PROTOID | "Server" > > ================================================================================ > The server's handshake reply is: > SERVER_PK Y [G_LENGTH bytes] > AUTH H(auth_input, t_mac) [H_LENGTH bytes] > * QSCIPHER C [QSPK_LENGTH bytes] > ================================================================================ > The client then checks Y is in G^*, and computes > > E = EXP(Y,x) | EXP(B,x) | B | X | Y > * P' = DECRYPT(C, QSSK) > > extract P,B from P' (P' = P|B), verifies B, and computes > > * secret_input = E | P | QSPK | ID | PROTOID > #pre secret_input = E | ID | PROTOID > > KEY_SEED = H(secret_input, t_key) > verify = H(secret_input, t_verify) > * auth_input = verify | B | Y | X | C | ID | PROTOID | "Server" > #pre auth_input = verify | B | Y | X | ID | PROTOID | "Server" > > The client verifies that AUTH == H(auth_input, t_mac). > > Both parties now have a shared value for KEY_SEED. This value will be used > during Key Derivation Function - KDF-RFC5869 (see 5.2.2 tor-spec.txt) >
Hi, I'm trying to understand the hybrid protocol that's described here. The server generates the parallel secret PAR_SEC or P and then computes C = ENCRYPT( P | B | Y, QSPK); The client decrypts C to get P and then uses it combination with the ECC secret E: secret_input = E | P | QSPK | ID | PROTOID So E is secret, P is generated by the server, QSPK ID and PROTOID are all public. So IF ECC is broken and IF the server has been compromised (big IF's!) then everything is known. I guess my point is that the client isnt contributing any secret information to the quantum-safe part of KEY_SEED. Is that OK? -- lukep _______________________________________________ tor-dev mailing list tor-dev@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev