Given a stream cipher such as Chacha20, which uses a 64-bit nonce, it would be unsafe to use a random nonce because of the risk of accidental repetition (which if used twice with the same key would be disastrous). In environments where using a simple counter is not an option, consider the following construction:

  • staticKey: 256 bit cryptographically secure pseudorandom key
  • perEncryptionSalt: 128 bit random salt
  • perEncryptionKey: HKDF(staticKey, perEncryptionSalt, info)
  • perEncryptionNonce: 64 bit random nonce

Ciphertext = chacha20(clearText, perEncryptionKey, perEncryptionNonce)

The salt and nonce would be appended to the ciphertext and included in the mac. Given that the key changes with each encryption (and thus would unlikely ever be used in combination with the same nonce), is this construction safe? I'm aware of XChacha20/XSalsa20 and they already solve this problem, but I'm curious nonetheless.

  • 1
    $\begingroup$ Isn't that exactly what XChaCha20 is doing? $\endgroup$
    – Elias
    Commented Jul 10, 2017 at 15:41
  • 2
    $\begingroup$ @Elias I don't know - I haven't studied it. Is it? $\endgroup$
    – hunter
    Commented Jul 10, 2017 at 15:45

1 Answer 1


Without looking at the code I would say your construction is pretty much the same as XChaCha20:

From https://download.libsodium.org/doc/advanced/xchacha20.html

Internally, XChaCha20 works like a block cipher used in counter mode. It uses the HChaCha20 hash function to derive a subkey and a subnonce from the original key and extended nonce, and a dedicated 64-bit block counter to avoid incrementing the nonce after each block.

(emphasis mine)

I'm not sure if this HChaCha20 hash function has any specific properties but using HKDF is probably just fine.

Here is the paper on XSalsa20. It should be possible to adapt the security proof.

  • $\begingroup$ HChaCha20 is cheaper than HKDF and uses the ChaCha20 core. However, using HKDF is sensible in this context. It would be better to use a larger output with HKDF though and take the nonce from the end. $\endgroup$ Commented Aug 17, 2022 at 14:00
  • $\begingroup$ That sounds fishy. Why would you do that? $\endgroup$
    – Elias
    Commented Aug 18, 2022 at 10:12
  • 1
    $\begingroup$ It obviously depends what you're trying to do, but it hides the nonce and saves you from storing it. It's not an unheard of practice. You then increment the nonce afterwards with the same key or rotate the key. $\endgroup$ Commented Aug 18, 2022 at 14:27

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.