# What is encrypted with the key to give the keystream in CTR mode exactly?

I'm learning how CTR mode and there is something I have trouble understanding. If I understood correctly, two components are encrypted with the key, a nonce and a counter concatenated, and it looks like for example a5b1fe9ac36701ba0000000000000003 : 8 bytes of nonce and 8 bytes of the counter padded with zeros. However, I also read that reusing the nonce produce the same keystream and must be avoided. Why is that, since the counter will differ each time ?

• The counter always starts at zero. So it would be the same. – Maeher Aug 12 '20 at 15:43
• @Maeher It always starts at zero and increments by one for each block, but this small incrementation should change the whole keystream because of the avalanche effect, no ? – Katoptriss Aug 12 '20 at 15:49
• Yes, that's the general idea. – Maarten Bodewes Aug 12 '20 at 15:59

## 1 Answer

The counter is increased for each block in a message. However, it is restarted at zero for the next message. That way only the nonce is required to be different. If you can synchronize the counter over multiple messages then yes, just increasing the counter is secure. However, you would loose the ability to encrypt messages in parallel, and you would somehow need to keep track of the counter when finishing encrypting a message.

Note that the 8 byte nonce and 8 byte counter is just one way to create a unique input for the block cipher. Other schemes / sizes are certainly possible. For instance, you could use the ID of an entity in there to separate those for the same key (a bit for a client & one for the server). Generally however, we keep to a nonce and counter in that order. Domain separation is often performed by using different keys for different purposes.

Beware that it is often up to the user to make sure that the counter doesn't overflow into the nonce. Furthermore, if the nonce is randomized then you should take note of the birthday paradox; it might be a good idea to increase the nonce size compared to the message size. E.g. a 32 bit counter would still leave you with $$16 \cdot 2^{32} = 64\ \text{GiB}$$ message size. That should even be enough for most high bitrate movies, and it would leave you with a full 96 bits for the nonce. The authenticated cipher mode GCM - which uses CTR mode internally - does exactly specify 64 GiB - 32 bytes as maximum message size, so you can guess the nonce and counter size by that alone.

• I see, I misunderstood in the sense that I thought the nonce needed to be different for each block. Thank you. I would have another question : if I were to choose a 16 bytes nonce, does that mean that there would be no counter involved, and that each plaintext block would be XORed with the exact same keystream ? – Katoptriss Aug 12 '20 at 16:25
• - LFSR,counter based nonce + random is missing here How to generate a nonce for ChaCha20 Poly1305? – kelalaka Aug 12 '20 at 18:51
• @Katoptriss No, the combi of nonce & counter needs to be unique. For the 16 byte nonce (number used once) you would expect the nonce to change for each message. However, then there is no counter, so each message can only consist of 16 bytes (or whatever the block size is). CTR mode is one of the reasons why 8 byte block ciphers are not considered helpful, and it may even be a good reason to move to 256 bit block ciphers. – Maarten Bodewes Aug 12 '20 at 20:43
• @kelalaka Not really, because I've not described anything about nonce creation other than that it needs to be unique for each message. Any method of randomization is fine, as long as the values are distributed well and - of course - unique with a high degree of certainty (i.e. large enough). – Maarten Bodewes Aug 12 '20 at 20:45