Pipes
A pipe starts with a 3-step handshake:
- The client sends an ephemeral public key.
- The server sends a box encrypted to the client's ephemeral key.
- The client sends a box encrypted to the server's ephemeral key, chained from the previous box.
The Noise boxes can contain an initial exchange of plaintext (which could be used to send certificates, or other negotiation data).
After the handshake the chain variable is expanded into two, one for each direction. After this, either side can send Noise bodies.
(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' Client<-Server: noise_box((S',s'), (S,s), C', pad_len, app_data, 2) # outputs cv_h1 Client->Server: noise_box((C',c'), (C,c), S', pad_len, app_data, 4, cv_h1)[DH_LEN:] # outputs cv_h2 # NOTE: C' is omitted since it was already sent cc_client || cc_server = KDF(cv_h2, zeros[CV_LEN], SUITE_NAME || (byte)6, CC_LEN*2) # After this, the following messages can be sent repeatedly in any order: Client->Server: noise_body(cc_client, pad_len, app_data) # updates cc_client Client<-Server: noise_body(cc_server, pad_len, app_data) # updates cc_server
If either endpoint sets its long-term public key equal to its ephemeral public key, it's considered "anonymous". The other endpoint can detect this and skip the redundant DH calculation.
This allows Noise pipes to be "mutually-authenticated", "server-authenticated", "client-authenticated", or "anonymous".
If the underlying connection is closed (e.g. TCP connection close), a Noise party should erase its cipher contexts. If any error is detected, the party should erase its cipher contexts and close the connection.
For a mutually-authenticated pipe, each party performs 3 variable-base ECDH operations. If either side is "anonymous", then this count is reduced to 2 or even 1. (Generating the ephemeral key requires an additional fixed-base operation, which can be optimized to a fraction of the speed of a variable-base operation).
This is the same number of public-key operations performed by CurveCP or SIGMA. Simpler protocols (such as MTI/AO) require 2 DH ops, but lack some of the properties of Noise. MQV/HMQV is particularly efficient at between 1 and 1.5 DH ops, but lacks identity-hiding and is patented.
The handshake adds 1 round-trip before the client can send data.
!!! WORK IN PROGRESS !!!
When used with TCP, each message is prefixed with a little-endian uint32 specifying its length in bytes.