[noise] Explicit nonces (for lossy transports)
Jason A. Donenfeld
Jason at zx2c4.com
Tue Jun 13 10:40:53 PDT 2017
Hi Trevor, Jake,
This seems like a big mistake for me, and not a rabbit hole you want to go down.
The only thing Noise needs to specify is that a nonce may only be used
once, but the order of nonces does not matter.
Beyond that, you're going to be wasting a lot of time and duplicating
tons of effort to try to specify an extension document about this. The
reason is that different configurations need different
Generally speaking, if you want a protocol that "works" and does most
things the way you're expecting, then you use TCP. If you have other
use cases and a permissive network then you can use SCTP, or if your
network isn't permissive, you can use SCTP over UDP. However, if you
want a totally custom protocol for something very specific and
particular -- a VPN, a low latency video game, streaming video, real
time video chat, fully-buffered file uploads, broadcast time updates
-- then you pretty much want to design your own layer 4 protocol on
top of UDP. This most certainly shouldn't be the task of a crypto
protocol like Noise, which exists at layer 5, not layer 4.
For example, once you've specified the easy statement about nonces I
mentioned above, you then have to decide how you want to deal with
out-of-order messages. Should you use a simple sliding window as in
appendix C of RFC2401? Should you use a more complex rotating buffer
to avoid bit shifts as in RFC6479? Should you choose any one of the
dozens of other algorithms that have been invented for different
network characteristics? Should each packet also get a timestamp so
that packets which are too old can be discarded, no matter the status
of the out-of-order window? These are all decisions that are probably
best not made inside Noise, but rather by a consumer of Noise who will
actually be able to choose what Noise is being used for.
How should retransmissions happen during the handshake? Should there
be a timeout for every packet, with the most recent one retransmitted?
Should there be a timeout for the entire handshake, with it starting
over from scratch if it is not entirely completed? Should these
timeouts be dynamic to deal with high latency space stations or should
they be static to simplify the state machine? Again, best left up to
the user of Noise.
How should termination be handled? An explicit terminator, or an
implicit timeout? How should chunking and MTU be specified? Should
each message be chunked into smaller records so that they can be
retransmitted individually in the case of ICMP fragmentation-needed?
Or in case of a timeout? Or should messages simply always be below the
smallest allowed MTU for a given layer 1/2/3? Not something you want
to put into Noise, and again best left up to a user of Noise.
So anyway, putting this in Noise seems like a pretty terrible idea and
not the sort of networking brain damage to which you want to expose
yourself, your children, or your kitten. The rabbit hole knows no
bounds, and there are no "right" decisions that can be made for a
one-size-fits-all extension or even a several-sizes-fit-all set of
In fact, that's kind of the beauty of Noise. It specifies the crypto
layer. Using that, you can then very easily fit it to whatever network
layer you want -- TCP, SCTP, UDP custom protocol, CAN bus, I2C, SMS,
twitter, the block chain, and so forth. Noise can work well over
streaming layers or over datagram layers. It can work well over
sequential layers or non-sequential layers. Etc, etc. Noise is really
quite flexible, and fitting for lots of different circumstances.
Therefore, the only thing Noise might possibly need is a mention in
the specification that nonces can be made explicit, so long as they're
only used once. My own reading was that this was already implied --
and indeed every existing Noise library allows for this -- but in case
there's ambiguity, this probably only requires one sentence to
More information about the Noise