Encryption with Stream Ciphers: ChaCha20

While I often use some form of cryptography as a software engineer, I only recently dug deeper, and I found that spending just a bit of time learning some details can yield a lot of useful knowledge. Let’s dig into one facet here, starting with one cipher used for encryption and decryption. I hope this will be a gentle introduction that gives you enough knowledge to explore more cryptography topics further on your own.

Let’s take a look at a common cipher called ChaCha20. It’s symmetric, meaning the two sides must already have a common key. Sometimes asymmetric encryption is used to negotitate this key, like when opening an HTTPS or other TLS connection.

ChaCha is a stream cipher, meaning a securely random stream of data called a keystream is combined with a plaintext message using a mathematical operation like XOR to produce the encrypted message. For a synchronous stream cipher like ChaCha, the keystream has no relation to the data being encrypted.

The ChaCha algorithm produces a keystream from a 32-byte key and an 2-byte nonce. Once we have the keystream, the encryption operation is easy: simply XOR the plaintext message with the keystream. If we have a 100-byte message to encrypt, we’ll use the ChaCha algorithm to get the first 100 bytes of the keystream. We iterate through each byte, taking the XOR of that byte with the corresponding byte from the plaintext message to give us the encrypted message.

We can perform exactly that same operation (with the same key and nonce) again on the encrypted message to get the decrypted message.

The complexity in a stream cipher is in generating a secure key stream from a given key and nonce; the rest is easy. I’ll leave figuring out the math behind generating the key stream as an exercise for the reader 😉.

Standard