Start here: what is a stream cipher?
A stream cipher turns a secret key plus a
one-time nonce into a long, random-looking
keystream, then XORs that keystream with your
message to encrypt it. Decryption is the same XOR again, because
x β y β y = x. The whole cipher rests on one equation you'll see
live below:
ciphertext = plaintext β keystream
- Key
- 256-bit secret shared by sender and receiver. Same key both ways.
- Nonce
- "Number used once" β a 96-bit public value that must never repeat under one key.
- Keystream
- The pseudorandom bytes ChaCha20 derives from key + nonce. As long as your message.
- XOR (β)
- Bit-wise exclusive-or: 1 if the two bits differ, else 0. Its own inverse.
The rule in one line: the nonce must never repeat under the same key. Section 4 shows what an attacker does the moment it does.
Encrypt / Decrypt Playground
Here is the whole cipher, one byte per column: your
plaintext XOR the
keystream gives the
ciphertext. Hover or focus a column to
trace one byte through ct = pt β ks.
Keystream Visualizer
Same key, different nonce β completely different keystream
Colour encodes byte value only (low = blue, high = red) so the grid is easy to scan β it carries no cryptographic meaning. The real "is it random?" signal is the avalanche stat below, not any pattern in the hues.
Quarter-Round Stepper
Watch the 4Γ4 state matrix evolve through all 80 quarter-rounds. The four highlighted cells are the words being mixed by the current quarter-round.
Press Initialize Block to build the state matrix from the current key & nonce.
Nonce Reuse Attack Demo
π Crib-drag β recover Message 2 from a guess of Message 1
The keystream is gone, so an attacker who guesses one message instantly recovers the other β no key required. The guess is pre-filled with the real Message 1; edit it and watch the recovery degrade character-by-character.
Learn More
Why ChaCha20?
- Software performance without AES-NI: On devices lacking hardware AES instructions (mobile, IoT, older ARM), ChaCha20 runs 2β3Γ faster than software AES.
- Timing-attack resistance: AES uses S-box table lookups that leak timing information. ChaCha20's ARX design (Add-Rotate-XOR) uses only constant-time operations β no lookup tables.
- Google's choice: Google adopted ChaCha20-Poly1305 for Android TLS and QUIC because most mobile devices lacked AES-NI when the decision was made.
- RFC 8439: Standardizes ChaCha20 and Poly1305 for IETF protocols including TLS 1.3.
ARX Design
ChaCha20 uses only three operations β Add (mod 2Β³Β²), Rotate (bit rotation), and XOR. These are constant-time on virtually all CPUs, making side-channel attacks fundamentally harder.
The 4Γ4 State Matrix
ChaCha20 operates on a 4Γ4 matrix of 32-bit words (512 bits total):
| cccccccc | cccccccc | cccccccc | cccccccc |
| kkkkkkkk | kkkkkkkk | kkkkkkkk | kkkkkkkk |
| kkkkkkkk | kkkkkkkk | kkkkkkkk | kkkkkkkk |
| bbbbbbbb | nnnnnnnn | nnnnnnnn | nnnnnnnn |
- c β Constants: the ASCII of "expand 32-byte k" (
0x61707865 0x3320646e 0x79622d32 0x6b206574) - k β Key: 256 bits (8 words) of secret key material
- b β Block counter: 32-bit counter, incremented per 64-byte block
- n β Nonce: 96 bits (3 words), must be unique per message
Rules for Safe ChaCha20 Usage
- Never reuse a nonce+key pair. This demo's Section D shows exactly why β the keystream cancels, leaking plaintext XORs.
- Prefer XChaCha20 for long-lived keys. Its 192-bit nonce is large enough for random generation without realistic collision risk.
- Always pair with Poly1305 for authentication. ChaCha20 alone provides confidentiality, not integrity. Use ChaCha20-Poly1305 (AEAD) in production.
- Counter overflow at 2Β³Β² blocks = 256 GB per key/nonce. For larger data streams, rotate key/nonce pairs.
Why this matters
AES requires dedicated hardware instructions (AES-NI) to run safely and quickly. On devices without AES-NI β most ARM chips before 2011, many IoT devices, some embedded systems β AES implementations leak timing information that can expose keys. ChaCha20 is immune to this entire class of attack by design. That's why TLS 1.3 supports it as a first-class cipher suite.