[noise] Key exchange and DuplexWrap-like protocols [xpost messaging]
mike at shiftleft.org
Thu Feb 12 15:03:31 PST 2015
Trevor redirected me to here after posting on Messaging. I wonder what you think of the following design for a simpler Noise-like key exchange and messaging protocol. I don’t think it’s entirely novel, but it may be interesting because of its simplicity:
Both sides initialize a DuplexWrap object to the empty state. The handshake is explicitly half-duplex, and every message is exchanged using DuplexWrap’s wrap/unwrap primitives. [foo] means to pass foo to header(), rather than body, so it won’t be transmitted. There need to be length fields and MAC tags in suitable places: on every object would be good enough, but you could omit them in some places. Also, you’d need a few fields to distinguish ciphersuites, which kind of authentication is expected/used, etc. So the following is very rough.
Bob->Alice: g^b, [g^ab], Bob’s cert on g^B, [g^aB]
If Alice has a cert:
Alice->Bob: Alice’s cert on g^A, [g^Ab]
If Alice has a password:
Bob->Alice: salt, maybe some stretcher parameters
or run some PAKE protocol on the same channel. Could be SPEKE or SPAKE2 or whatever. Here’s SPAKE2:
Bob->Alice: salt, g^x M^stretch(password) or Elligator equivalent
Alice->Bob: g^y N^stretch(password) or Elligator equivalent, [g^xy, stretch(password), maybe augmentation]
After the handshake, Alice and Bob will probably want to go to full-duplex mode. To do this, they can clone the DuplexWrap object, and distinguish it with a new header (I think this is secure in DuplexWrap’s model?):
Alice->Bob: [“Alice’s side”]
Bob->Alice: [“Bob’s side”]
For forward secrecy, Alice and Bob can call forget() to prevent rollback. For better forward secrecy, they can create new ephemerals:
Bob->Alice: g^y, [g^xy]
This can easily be extended to a full Axlotl-style ratchet.
So, in summary, strengths:
* You don’t need a separate cipher, MAC, hash and KDF, just the duplex object.
* Easy to add some form of anonymity.
* Easy to analyze since Duplex object is (almost?) a random oracle.
* Easy to add ratchets.
* Automatically resists power analysis because keys rotate as you use them.
* Half-duplex, and going to full-duplex mode is a hack.
* Not standardized.
* Not done yet.
* Can’t support out-of-order delivery.
* Can’t easily recover from lost messages if running on UDP or similar.
More information about the Noise