Same key, different nonce → completely different keystream
⚙️ 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.
⚠ Never reuse a nonce with the same key. This demo shows exactly why.
📚 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.