Overview - noiseprotocol/noise_spec GitHub Wiki

Protocols Overview

(This is an informal overview; for a full description, see following pages.)

Boxes

Noise boxes are an authenticated encryption from the sender's ECDH key to the receiver's ECDH key. The sender's public key is transmitted to the intended receiver but is hidden from an eavesdropper by an ephemeral ECDH key. Noise boxes are "one-way" - they can be decrypted by the receiver, but not the sender.

In more detail: Noise boxes consist of an ephemeral public key, followed by the sender's public key encrypted using the ECDH between the ephemeral and receiver keys. Following this, there's a payload encrypted using both the (ephemeral, receiver) ECDH and the (sender, receiver) ECDH:

(A',a') : ephemeral public key A' and private key a'
(A,a)   : sender's public key A and private key a
(B,b)   : receiver's public key B and private key b

'*'           : EC point-scalar multiply
'||'          : concatenation of byte sequences
ENCRYPT(k, m) : authenticated encryption of m with symmetric key k

noise_box((A',a'), (A,a), B, plaintext):
  key1 = HASH(a' * B)
  key2 = HASH((a * B) || key1)
  return A' || ENCRYPT(key1, A) || ENCRYPT(key2, plaintext)

The ephemeral ECDH adds forward-secrecy and identity-hiding for the sender.

Pipes

Noise pipes begin with a handshake based on a "triple-DH" key agreement. The client and server identities (their public keys) are encrypted using intermediate results:

(C,c)   : client's public key C and private key c
(S,s)   : server's public key S and private key s
(C',c') : client's ephemeral public key C' and private key c'
(S',s') : server's ephemeral public key S' and private key s'

Client -> Server : C'

  key1 = HASH(c' * S')
  key2 = HASH((c' * S) || key1)

Client <- Server : S' || Encrypt(key1, S) || Encrypt(key2, optional_plaintext)

  key3 = HASH((c * S') || key2)

Client -> Server : C' || Encrypt(key2, C) || Encrypt(key3, optional_plaintext)

Composing boxes into pipes

The pipe handshake can be implemented as an exchange of Noise boxes. The boxes are extended to support a "chaining variable" (CV) input which is used in deriving secret keys, and a CV output which is based on the box's secret keys. CVs are used to connect the boxes into a pipe handshake. The output from the first box is the input to the second box:

Client -> Server : C'
Client <- Server : noise_box((S',s'), (S,s), C', optional_plaintext)    
# outputs chain_h1 

Client -> Server : noise_box((C',c'), (C,c), S', optional_plaintext, chain_h1)    
# outputs chain_h2

session_key = chain_h2

Crypto Overview

Elliptic curve

Noise ciphersuites can be defined to use any DH or ECDH domain parameters. By default, Noise supports ECDH using Curve25519 and the Goldilocks-448 elliptic curve.

One-pass key exchange for boxes

Noise boxes are a "hybrid" or "KEM/DEM" encryption of a plaintext, where the "KEM" is supplied by a "one-pass key agreement" protocol. The one-pass key agreement is a "one-pass unified model" ECDH, as sketched above.

Two-pass key agreement for pipes

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.

KDF

Key derivation from ECDH results is done using HMAC-SHA2-512 in a manner inspired by HKDF-Expand.

Cipher and MAC

Noise ciphersuites can be defined to use any authentication encryption algorithm. Currently ciphersuites are defined for ChaCha20/Poly1305 and AES-GCM.

Home

Next (Noise properties and protocol comparisons)

⚠️ **GitHub.com Fallback** ⚠️