The draft of chacha20 uses a 64-bit nonce, but the final version of chacha20 specification uses a 96-bit nonce.

The #9792 PR adds chacha20 to Bitcoin Core. We can see the function ChaCha20::SetIV(uint64_t iv) is using 64 bits for setting the nonce value. The chacha20.cpp mentions that it follows the chacha20 implementation from here.

Is there any specific reason for bitcoin using a 64-bit nonce? Wouldn't it be better to use a 96-bit nonce as recommended?

1 Answer 1


It doesn't matter. The old version has a 64-bit nonce and 64-bit counter, while the new one replaces it with a 96-bit nonce and 32-bit counter. For our purposes however, they can reasonably both be thought of as a single 128-bit number that should just never repeat.

The ChaCha20 implementation in Bitcoin Core is used as basis for the random number generator, and not (yet) as a stream cypher for encryption, where the nonce/IV and block counter are used for somewhat distinct purposes.

In the RNG, the 256-bit key is randomly generated (using OS and system randomness), and the nonce and counter are both just set to 0. The block counter then increments every time 64 bytes are generated. If we'd switch to a 32-bit counter instead, we'd need to deal with the situation where the counter overflows, and most likely the way to do that would be to increment the nonce when that happens. And all of that is still exactly identical as just thinking of it as a 64-bit nonce and counter with incrementing non-overflowing counter instead.

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.