[noise] Potential redesign?

Trevor Perrin trevp at trevp.net
Thu Mar 19 00:31:32 PDT 2015


On Tue, Mar 17, 2015 at 10:28 PM, Tony Arcieri <bascule at gmail.com> wrote:>
>
> Maybe a list of Noise use cases would be helpful? Some examples:
>
> 1) The TLS use case, i.e. streams, probably running over TCP
> 2) The machine-to-machine asynchronous message protocol use case, maybe TCP,
> UDP, or both and potentially with "introductions" to eliminate round-trips
> 3) The "Axolotl" use case, i.e. humans sending messages to each other on
> smartphones


I don't have a great list, but we can work through some protocols and
see how they'd be rendered in Noise1 (previous) vs Noise2
(descriptors).

---

Noise1 was based on a symmetry between boxes and handshakes:

NoiseBox(s, rs):
 e, dhes, s, dhss

NoisePipe(s):
  -> e
  <- e, dhee, s, dhse
  -> e, dhee, s, dhse

But it's unnecessary to have "e, dhee" in the last message.  So Noise1
(in some versions) omitted sending the final "e" and explained that
you should reuse the previous dhee calculation.  Which was kind of a
hack.  Noise2 doesn't care about the symmetry so can be
straightforward and more efficient:

HandshakeXX(s):
  -> e
  <- e, dhee, s, dhse
  -> s, dhse

You can omit the final message to drop client-auth (in fairness,
Noise1 could do the same):

HandshakeNX():
  -> e
  <- e, dhee, s, dhse

This is close to Tor's Ntor, but Ntor doesn't have identity-hiding, so
a more accurate rendition:

Ntor():
  -> e
  <- e, s, dhee, dhse

The client might have pre-knowledge of server.  For example, CurveCP
and Halite [1] can send initial encrypted data in first message, like:

HandshakeXS(s, rs):
  -> e, dhes
  <- e, dhee
  -> s, dhse

They also defer dhee to the third message, I think for DoS resistance.
(And because they're using Nacl they have to nest the boxes, but we
can use chaining and avoid double-encrypting):

CurveCP_or_Halite(s):
  -> e, dhes
  <- e
  -> dhee, s, dhse

QUIC and maybe TLS 1.3 use pre-knowledge of an ephemeral key for
0-RTT, but then the server can present a fresher ephemeral:

HandshakeNE(s, rs, re):
 -> e, dhee, dhes
 <- e, dhee

Client auth could be added to that in a few ways.  The most
heavyweight construction adds client-auth with both old and new
ephemeral:

HandshakeXE(s, rs, re):
 -> e, dhee, dhes, s, dhse
 <- e, dhee, dhes

TextSecure uses pre-knowledge of an ephemeral "prekey" for a 0-RTT key
agreement with sender authentication, e.g.

BoxXE(s, rs, re):
  e, dhee, dhes, s, dhse


Then the ratchet kicks in and parties take turns introducing DH
ratchet keys and mixing them into the root PRF chain:

 -> e, dhee
 <- e, dhee
 -> e, dhee
 ...

(though there's more to it than that).

DNSCurve is space-constrained so uses straight Nacl, i.e.
static-static key agreement with nonces:

BoxSS(s, rs):
 ndhss


Anyways, I think that's pretty good coverage of a lot of patterns.
(What Noise2 wouldn't have is the ability to negotiate different
patterns on the fly, I guess I'm assuming most systems only need to
choose 1 pattern that fits).

Trevor

[1] https://bitbucket.org/0x0000/halite/raw/332d576a2050f728840df6795eef8b8c71e0f51c/docs/states.text


More information about the Noise mailing list