Full deniability
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:
- Full deniability: Handshake using Triple-DH
- Plaintext length hiding
- All Diffie-Hellman (no signatures): Using TLS with ephemeral ECDH requires signatures. Noise relies only on ECDH (no signatures). This yields a simpler and more robust protocol, reduces bandwidth, and avoids creating hard-to-deny evidence of who has communicated with who.
Proposal:
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 |
G is the generator of Curve25519.
Alice has long term authenticating secret a and generates one-time ephemeral secret c.
Bob has long term authenticating secret b and generates one-time ephemeral secret d.
To initiate a session using triple DH.
Alice: compute C = c G and send C to Bob
Bob: compute
D = d G s₁ = \mathrm{hash}(d C)
s₂ = \mathrm{hash}( ∥ s₁)
S₁ = a b G
S₂ = 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.