[noise] New draft: "noh2" branch

Trevor Perrin trevp at trevp.net
Thu Aug 27 00:37:07 PDT 2015


On Wed, Aug 26, 2015 at 5:28 PM, Jason A. Donenfeld <Jason at zx2c4.com> wrote:
>
> FWIW, I prefer master to noh, and I prefer noh to noh2. Noh2 and noh seem to
> add quite a bit of complexity and implementation prescription that I don't
> openly welcome.

I'm still trying to simplify noh2, see if you like revision 1 any better.


> What I dislike: the considerable complexity and abstraction added.


A lot of the complexity from noh got removed in noh2.  Hard to know
what else to cut:

 * If the patterns are confusing we could go back to the original
Noise design that used a single "e, dheX, s, dhsX" pattern for every
message.  But you'd end up with redundant fields and DH ops (e.g. in
brackets) that we currently tailor away:

XX:
 -> e
 <- e, dhee, s, dhse
 -> [e, dhee,] s, dhse

IS:
 -> e, dhes, s, dhss
 <- e, dhee, [s,] dhss

XS:
 -> e, dhes, [e, dhes]
 <- e, dhee, [e, dhee]
 -> s, dhse, [s, dhse]


 * We could write a concrete spec that presents a concrete Noise Pipe
protocol, and then have the general framework in a separate document.
But I'm not sure presenting a long list of concrete steps is that much
better.  For example, I find the pattern easier to deal with then a
list of steps:

 -> e
 <- e, dhee, s, dhse
 -> s, dhse

vs

def WritePipeHandshakeMessage0():
  kernel.MixKey(name + ZERO + preshared_key)
  e = GENERATE_KEYPAIR()
  Write(e.pub)
  Write(payload)

def WritePipeHandshakeMessage1():
  e = GENERATE_KEYPAIR()
  Write(e.pub)
  kernel.MixKey(DH(e, re))
  Write(kernel.Encrypt(s.pub))
  kernel.MixHash(s)
  kernel.MixKey(DH(s, re))
  Write(kernel.Encrypt(payload))

def WritePipeHandshakeMessage2():
  Write(kernel.Encrypt(s.pub))
  kernel.MixHash(s)
  kernel.MixKey(DH(s, re))
  Write(kernel.Encrypt(payload))



>  While
> elegant, in fact I don't want the ability for "parties to alter handshake
> patterns, ciphersets, and transport flags on the fly".

I do think being able to choose whether or not to authenticate, or
execute a 0-RTT handshake, are pretty useful, and the "noh2" design
achieves them at low cost.


> This might make noise
> suitable as a general purpose TLS-rank protocol, but I'm after something
> small, minimal, secure, and easy to produce an audit-able implementation. I
> don't want it to have so many bells and whistles that I need to write it in
> Rust or Haskell to have faith in my code; instead I want to write C that I
> can confidently verify without my eyes bleeding.

I would hope we achieve that to.  I'll try to implement noh2 soon and
see how it goes.


> I also liked the quality of the master branch where all previous bytes were
> in aad for each encryption, which imposed ordering constraints (in addition
> to binding relevant data to the exchange).

I'm not sure what "ordering constraint" means here.  I don't think
there's any way to maliciously reorder handshake messages.


> It also had the nice effect of
> authenticating the prologue, which seems like a nice quality, as I wouldn't
> want an attacker to be able to "break apart" any components of one message
> and put them in a message of another type.

None of the type, length fields need to be in aad, nor does an
explicit nonce.  So I'm not sure what we'd use this for: what data
needs to be authenticated and go in prologue that couldn't just go in
the payload?


Trevor


More information about the Noise mailing list