<div dir="ltr"><div><br></div><div>NoiseSocket specifies a framework for negotiation on top of Noise.  The idea is that each handshake message can contain some "negotiation data" prior to the Noise message.  The initial message's "negotiation data" can advertise the initiator's support for other Noise protocols.</div><div><br></div><div>The first response message tells the initiator whether the responder is accepting the initial protocol, rejecting it, executing a "fallback" to a different protocol that reuses the initial ephemeral, or requesting the initiator to retry a different protocol.  The response message's "negotiation data" and "noise message" fields are populated for these options as follows (Y=populated, n=zero-length):</div><div><br></div><div>                   NEGO.DATA    NOISE.MSG</div><div>Silent Reject          -             -</div><div>Accept                 n             Y</div><div>Explicit Reject        Y             n </div><div>Retry                  Y             n</div><div>Fallback               Y             Y</div><div><br></div><div><br></div><div>Note that the responder only has two ways to switch Noise protocol:</div><div> - Fallback = switch to a protocol that reuses the inital ephemeral </div><div> - Retry ("reinitialization request" in current spec) = ask the initiator to start a new protocol</div><div><br></div><div>That covers most cases.  If the responder accepts the initiator's DH choice, it uses a "fallback" protocol.  If the responder doesn't accept the DH choice, it's simplest to ask the initiator to retry the same pattern with the correct DH.</div><div><br></div><div>However, in some cases it might be more efficient for the server to reject the client's DH choice but simultaneously initiate a new protocol on its own.  For example-</div><div><br></div><div>Client attempts NX_25519:</div><div> -> e</div><div> <- e, ee, s, es</div><div><br></div><div>If the server asks for a retry with NX_448, then we lose a whole round-trip, and the client can't send encrypted data till her 3rd message:</div><div><br></div><div> -> e[25519]</div><div> <- RETRY PLEASE WITH 448</div><div> -> e[448]</div><div> <- e, ee, s, es</div><div> -> ENCRYPTED_TRANSPORT_MESSAGE</div><div><br></div><div>If the server is willing to send its identity in clear, then the client can send some encrypted data on her 2nd message:</div><div><br></div><div> -> e[25519]</div><div> <- RETRY WITH:  e[448], s</div><div> -> e, ee, es, ENCRYPTED_PAYLOAD</div><div><br></div><div>The "reversed" part of that looks like an IN pattern with roles reversed.</div><div><br></div><div>IN:</div><div> -> e, s</div><div> -> e, ee, se</div><div><br></div><div><br></div><div>So for completeness, I wonder if we should extend NoiseSocket so the responder also has a "Reverse" option?</div><div><br></div><div>                   NEGO.DATA    NOISE.MSG</div><div>Silent Reject          -             -</div><div>Accept                 n             Y</div><div>Explicit Reject        Y             n </div><div>Retry                  Y             n</div><div>Fallback               Y             Y</div><div>Reverse                Y             Y</div><div><br></div><div>I'm not sure whether we'd view this as just a role reversal followed by IN, or a "modified" IN, such as:</div><div><br></div><div>INreversed:</div><div> -></div><div> <- e, s</div><div> -> e, ee, es</div><div><br></div><div><br></div><div>Thoughts?</div><div><br></div><div><br></div><div>Trevor</div><div><br></div></div>