See the following presentation, which presents insecure key exchange protocols (the key exchange from the article is on page 4) while building up to SIGMA: https://www.ietf.org/proceedings/52/slides/ipsec-9.pdf
As you can see, this stuff is hard and you really shouldn't be designing your own. CurveZMQ (basically, DJB's CurveCP over TCP) is probably a better choice if you want a NaCl-based secure channel. CurveZMQ also happens to be pretty well documented if you want to learn about what it takes to design a secure protocol: http://curvezmq.org/page:read-the-docs
[1] https://codesinchaos.wordpress.com/2012/09/09/curvecp-1/
Of course, the more of these features you add, the closer you get to TLS. That being said, without these features (eg, if you need to basically upgrade your whole fleet just to update to a newer NaCl or to add keys as opposed to using a signed certificate mechanism), the advantage starts shifting towards even simpler approaches, such as spiped, which omits all the public-key ceremony in favor of a shared secret key.
- Any rough benchmarks vs. TLS? Or even just back-of-the-envelope math/reasoning behind the claim in the opening paragraph: "without the overhead of TLS".
- Instead of generating 24 PRNG bytes for each message to use as the NaCl nonce, why not use the sequence number each message is assigned anyway?
[1] http://www.zdnet.com/article/openbsd-forks-prunes-fixes-open...
Firstly, the <sub></sub> is being escaped instead of being interpreted as a tag. Also you say that the client and server make a keypair and create a tuple k_(pub,1) || k_(pub,2) || sig. Why would one participant have 2 pubkeys? If you meant it to be one public and one private, why would it include a private key? Is it actually that the client makes k_(pub,1) || client_sig and the server makes k_(pub,2) || server_sig? Also later you reference k_(peer,1) and k_(priv,1) which weren't mentioned previously at any point.
Sorry if I'm misunderstanding anything. I'm gonna read through the Go code to see if I can understand better, this looks really interesting!
Looking at the source, it seems like the initial key exchange keys are sent as a k_(pub,x) || sig tuple where x is 1 for the sender and 2 for the receiver. Similarly, it looks like the shared keys are derived from subslices of k_(pub,x) and k_(priv,3-x).
Is there a particular reason there isn't a single read/write symmetric key that's derived from the entirety of the public and private keys?