I understand that NaCl's crypto_stream and crypto_stream_xor don't do any authentication like crypto_secretbox does. Does using them allow listeners to forge crypto_secretbox messages for any key you use them with?

I'm worried about a known plaintext attack. If I use crypto_stream_xor to encrypt a bunch of zeroes, the listener now has the full keystream for whatever nonce I just used. I think they can use the first 32 bytes of that as a crypto_onetimeauth key to forge valid authenticators for crypto_secretbox messages, with whatever plaintext they want (up to the length of the zeroes I encrypted, minus 32).

If that's right, then using crypto_stream_xor seems to break authenticity just as badly as nonce reuse does. The NaCl/libsodium documentation is pretty clear about saying "never reuse a nonce with the same key", but there's nothing in there about "never use crypto_stream_xor with a key that you also use for crypto_secretbox."


1 Answer 1


crypto_secretbox uses the first 32 bytes of XSalsa20 output as the key for Poly1305. Thus you are correct that using crypto_stream_xor on a known plaintext will reveal the authentication-key used by crypto_secretbox, allowing forgeries under that key and nonce.

Not using a key for multiple purposes is a general crypto design principle. Perhaps that's why the authors of NaCl didn't think of explicitly warning about this pitfall.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.