It seems like the solution is to write a super simple "framing protocol"... which is to say that I can first send a frame length; and on the receiving end simply read until frame length worth of data is consumed... and then apply the crypto_stream cipher on that frame with the correct corresponding nonce.
That sounds like a reasonable solution. ScrambleSuit also has its own protocol header, if that helps: https://gitweb.torproject.org/user/phw/scramblesuit.git/blob/HEAD:/message.p...
Cool. Thanks! I'll take a look.
Also, I'm probably stating the obvious here, but you seem to be using a static key for encryption and decryption. That results in a many time pad, i.e., the same key is used for many plain texts. That's a problem because Tor's TLS handshake is predictable and a censor could observe that multiple independent SaltyStream connections share several bytes in their handshake. You might want to use a key derivation function, as also suggested by the NaCl doc:
NaCl does not make any promises regarding the resistance of crypto_stream to "related-key attacks." It is the caller's responsibility to use proper key-derivation functions.
I wrote this as a sort of rough draft... It is meant to accept a key from the commandline... you know, for testing. So I specified default keys... but really this is just for testing. To be useful at all there'd have to be proper key generation like you are saying and key exchange...
It's OK to use crypto_stream to encode multiple messages with the same key as long as the nonce is different each time :
"""This means that an attacker cannot distinguish this function from a uniform random function. Consequently, if a series of messages is encrypted by crypto_stream_xor with a different nonce for each message, the ciphertexts are indistinguishable from uniform random strings of the same length."""
Cheers
David