Full deniability

Remco Bloemen

https://moderncrypto.org/mail-archive/curves/2014/000107.html

Similar to KEA+ http://research.microsoft.com/en-us/um/people/klauter/security_of_kea_ake_protocol.pdf

http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar2.pdf

Noise pipes begin with a Triple Diffie-Hellman key agreement, as sketched above. This key agreement is similar to the variant of “Protocol 1” from Kudla and Paterson, section 5.1 where forward-secrecy is added via a DH between the two ephemeral keys. However, the parties’ identities are encrypted, accomplishing “identity-hiding” in the style of SIGMA-I. Since signatures are not used, Noise offers smaller messages, simpler cryptography, and stronger deniability than SIGMA-I.

Next version:

Proposal:

% sloccount ./Cryptography/{SymmetricKey2,SharedSecretKey,SignatureKey,Hash,Keccak,SpongeWrap}* ./Networking/{MeshCipher,MeshHandshake}*

% sloccount ./Cryptography/{SymmetricKey2,SharedSecretKey,Hash,Keccak,SpongeWrap}* ./Networking/{MeshCipher,MeshHandshake}*

Feature New Old TLS SSH IPSec
Complexity (lines of code) 1639 3447 437,157 44,140 25,075
Handshake round trips 1 1 2 15 3
Handshake overhead (bytes) 148 584 2403 4485
Packet overhead (bytes) 10 10 29—203 33 36

GG is the generator of Curve25519.

Alice has long term authenticating secret aa and generates one-time ephemeral secret cc.

Bob has long term authenticating secret bb and generates one-time ephemeral secret dd.

To initiate a session using triple DH.

Alice: compute C=cGC = c G and send CC to Bob

Bob: compute

D=dGD = d G s1=hash(dC)s_1 = \mathrm{hash}(d C)

s2=hash(s1)s_2 = \mathrm{hash}( ∥ s_1 )

S1=abGS_1 = a b G

S2=abGS_2 = a b G

See: https://whispersystems.org/blog/simplifying-otr-deniability/ See: https://github.com/trevp/noise/wiki/Overview

(A,a) : client’s public key C and private key c (B,b) : server’s public key S and private key s (C,c) : client’s ephemeral public key C’ and private key c’ (D,d) : server’s ephemeral public key D and private key d

Client -> Server : C 56 bytes

key1 = HASH(c * D) = HASH(d * C) key2 = HASH((c * B) || key1) = HASH((b * C) || key1)

Client <- Server : D || Encrypt(key1, B) || Encrypt(key2, data) 56 + 56 bytes

key3 = HASH((a * D) || key2) = HASH()

Client -> Server : Encrypt(key2, A) || Encrypt(key3, data) 56 bytes

Serve -> Client

128 bytes.

(A,a) : client’s public key C and private key c (B,b) : server’s public key S and private key s (C,c) : client’s ephemeral public key C’ and private key c’ (D,d) : server’s ephemeral public key D and private key d

Client -> Server : C 32 bytes

key1 = HASH(c * D) = HASH(d * C)

Client <- Server : D || Encrypt(key1, B) 64 bytes

key2 = HASH((c * B) || key1) = HASH((b * C) || key1) key3 = HASH((a * D) || key2) = HASH()

Client -> Server: Encrypt(key2, A) 32 bytes

Server -> Client

128 bytes.