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