[noise] Simple 1-RTT protocol

Alexey Ermishkin scratch.net at gmail.com
Sun Jun 11 23:46:56 PDT 2017


I see following disadvantages:
1) Using abstract "version" makes all implementations incompatible by definition
2) No standard way to use IK or Pipes

This reduces the usability to a very limited number of cases where everyone will be able to play in their own sandbox only. I thought of Noise_TLS/Socket/Link/whatever to be a more general purpose transport layer protocol.

My suggestions:
1) We could still use string identifiers instead of version number, this will add compatibility.

2) I don't like the idea of generating multiple sub-messages either. To avoid the necessity of executing multiple handshakes and generating  multiple sub-messages, we could specify the ClientHello message for XX as
 -  List of strings of names of supported protocols
 -  Public key

3) All other protocols (IK) where first message is not a plain public key must always send only a single Noise message during ClientHello.
So it's either of two
 - a  list of protos + public key
 -  protocol name +noise message

As for the name.. NoiseTransport, maybe? 

What do you think?
-----Original Message-----
From: Noise [mailto:noise-bounces at moderncrypto.org] On Behalf Of Trevor Perrin
Sent: Monday, June 12, 2017 4:24 AM
To: noise <noise at moderncrypto.org>
Subject: Re: [noise] Simple 1-RTT protocol

On Sun, Jun 11, 2017 at 1:04 AM, Trevor Perrin <trevp at trevp.net> wrote:
> We've talked about a "NoiseSocket" protocol that would be the default 
> usage for Noise.
[...]
> Here's a simpler proposal:
[...]
>
>  -> ClientHello(client_version: byte, options: bytes[])
>  <- ServerAuth(server_version: byte, server_credentials: bytes[])  -> 
> ClientAuth(client_credentials: bytes[])



We could simplify further:  instead of client_version and server_version, just have a single client version.

If the server supports newer versions the server can communicate this to the client in the server's response payload.  If the client cares, it can open a new session with a higher version.

If the server doesn't support the client's version, the server closes the connection, and the client can try falling back to an older version.

This doesn't allow the client to offer multiple versions simultaneously, but I'm not sure that's worth the complexity.

I'm also not sure "NoiseSocket" is a good name.  It sounds like an API endpoint rather than a protocol, and a simpler name might be better for such a simple construct.  "NoiseLink", maybe?

Anyways, updated sketch:


Protocol messages
==================

Noise_XX:
 -> e
 <- e, ee, s, es
 -> s, es

With names and arguments:

 -> ClientHello(version: byte, cleartext_payload: bytes[])
 <- ServerAuth(server_auth_payload: bytes[])  -> ClientAuth(client_auth_payload: bytes[])

The server_auth_payload and client_auth_payload are good for sending credentials such as certificates.  If the server supports a higher version, it should indicate this in server_auth_payload, so that the client can initiate a new session using a higher version.  Encoding details for this are up to the application.

Parties should ignore any handshake payloads they don't recognize.  If handshake payloads are populated, it should be with an extensible format like Protobufs, JSON, or XML, and parties should ignore any fields they don't recognize.


Message framing
================

ClientHello:
 - 1 byte: version
 - 2 bytes: length of following message
 - <message>

Other messages:
 - 2 bytes: length of following message
 - <message>


Prologue
=========
Since we can't know how applications will use the version field, we should probably bind it:

"NoiseLink" || version


API
====

    descriptor = pair of (version, (DH, Cipher, Hash))
    descriptorList = list of descriptors

InitializeClientSession(descriptor)
InitializeServerSession(descriptorList)

WriteClientHello(cleartext_payload=empty) -> handshake_message
ReadClientHello(handshake_message) -> (version, cleartext_payload)

WriteServerAuth(server_key_pair=empty, server_auth_payload=empty) -> handshake_message
ReadServerAuth(handshake_message) -> (server_pub_key, server_auth_payload)

WriteClientAuth(client_key_pair=empty, client_auth_payload=empty) -> handshake_message
ReadClientAuth(handshake_message) -> (client_pub_key, client_auth_payload)

Write(payload) -> transport_message
Read(transport_message) -> payload


Trevor
_______________________________________________
Noise mailing list
Noise at moderncrypto.org
https://moderncrypto.org/mailman/listinfo/noise



More information about the Noise mailing list