⚿ Cryptography

ChaCha20-Poly1305: Modern Authenticated Encryption

ChaCha20-Poly1305 is a modern authenticated encryption construction that combines the ChaCha20 stream cipher with the Poly1305 message authenticator. Designed by Daniel J. Bernstein and standardized in RFC 8439, it delivers confidentiality and integrity together in a single, fast, software-friendly package. It is a first-class cipher suite in TLS and a favored choice on devices without hardware AES acceleration. Understanding how ChaCha20-Poly1305 works illuminates the design of contemporary AEAD schemes.

What AEAD Means

AEAD (Authenticated Encryption with Associated Data) is the property that a cipher provides both:

  • Confidentiality: the plaintext is hidden.
  • Integrity and authenticity: any tampering with the ciphertext, or with unencrypted associated data bound to it, is detected.

The "associated data" part lets you authenticate headers or metadata that must remain readable (like packet routing information) while still binding them to the encrypted payload. AEAD constructions like ChaCha20-Poly1305 and AES-GCM are the modern standard because they prevent entire classes of attacks that arise when encryption and authentication are bolted together incorrectly.

The ChaCha20 Stream Cipher

ChaCha20 is a stream cipher, meaning it generates a pseudorandom keystream that is XORed with the plaintext to encrypt (and XORed with the ciphertext to decrypt). It is built on ARX operations: addition, rotation, and XOR. These are simple, fast on general-purpose CPUs, and inherently constant-time, avoiding the table lookups that expose some ciphers to cache-timing attacks.

ChaCha20 works on a 512-bit internal state arranged as a 4x4 matrix of 32-bit words, comprising:

  • Four fixed constant words
  • Eight words (256 bits) of key
  • One word of block counter
  • Three words (96 bits) of nonce

The core of ChaCha20 is the quarter-round, which mixes four state words using additions, XORs, and rotations. The algorithm applies quarter-rounds in a pattern across columns and diagonals for 20 rounds (hence "ChaCha20"), then adds the original state back to produce a 64-byte keystream block. Incrementing the counter yields successive keystream blocks.

# ChaCha20 quarter-round (operates on state words a, b, c, d)
a += b;  d ^= a;  d <<<= 16
c += d;  b ^= c;  b <<<= 12
a += b;  d ^= a;  d <<<= 8
c += d;  b ^= c;  b <<<= 7

ChaCha20 uses a 256-bit key and a 96-bit nonce, and the 32-bit counter allows a very large amount of keystream per nonce.

The Poly1305 Authenticator

Poly1305 is a one-time message authentication code that produces a 128-bit tag. It evaluates the message as coefficients of a polynomial modulo the prime 2^130 − 5 (which gives the algorithm its name), then adds a secret value modulo 2^128. This design is a Wegman-Carter MAC and is extremely fast.

The critical requirement is that each Poly1305 key must be used only once. In the combined construction, this is handled automatically: the one-time Poly1305 key is derived from ChaCha20 itself.

How the Combined Construction Works

ChaCha20-Poly1305 as an AEAD proceeds in a well-defined sequence:

  1. Derive the one-time MAC key. Run ChaCha20 with the message key and nonce at counter zero, and use the first 32 bytes of the keystream block as the one-time Poly1305 key.
  2. Encrypt the plaintext. Run ChaCha20 starting at counter one to generate keystream, and XOR it with the plaintext to produce the ciphertext.
  3. Authenticate. Compute the Poly1305 tag over the associated data, the ciphertext, and their lengths, using the one-time key from step one.
  4. Output the ciphertext and the 128-bit tag.

Decryption reverses the process and, crucially, verifies the tag before releasing any plaintext. If the tag does not match, the entire message is rejected. This ordering (verify, then decrypt) prevents attackers from exploiting partial decryptions.

The Nonce Reuse Danger

Like all stream ciphers and AEAD modes, ChaCha20-Poly1305 has one absolute rule: never reuse a nonce with the same key. Reusing a nonce is catastrophic in two ways:

  • Keystream reuse lets an attacker XOR two ciphertexts to cancel the keystream and recover relationships between plaintexts.
  • Poly1305 key reuse can allow forgery of authentication tags.

Nonces do not need to be secret, but they must be unique per key. Common strategies are a monotonic counter or, where more messages are needed than a 96-bit random nonce can safely support, an extended-nonce variant like XChaCha20-Poly1305, which accepts a 192-bit nonce and makes random nonces safe.

ChaCha20-Poly1305 Versus AES-GCM

ChaCha20-Poly1305 and AES-GCM are the two dominant AEAD schemes and are broadly comparable in security. The practical trade-offs:

  • Hardware AES: on CPUs with AES-NI, AES-GCM is typically faster.
  • Software only: on devices without AES acceleration, such as many mobile and embedded processors, ChaCha20-Poly1305 is usually faster and more power-efficient.
  • Side channels: ChaCha20's ARX design is naturally constant-time, whereas naive software AES can leak through cache timing.
  • Nonce robustness: both are sensitive to nonce reuse; extended-nonce ChaCha variants ease nonce management.

Because of these properties, ChaCha20-Poly1305 is a preferred cipher suite in TLS on mobile platforms and in modern secure protocols. It is a strong alternative or complement to AES-based encryption.

Key Takeaways

  • ChaCha20-Poly1305 is an AEAD construction pairing the ChaCha20 stream cipher with the Poly1305 authenticator to provide confidentiality and integrity.
  • ChaCha20 uses ARX operations over a 512-bit state, a 256-bit key, a 96-bit nonce, and 20 rounds, making it fast and naturally constant-time.
  • Poly1305 is a one-time MAC producing a 128-bit tag; its one-time key is safely derived from ChaCha20 for each message.
  • Never reuse a nonce with the same key; consider XChaCha20-Poly1305 with its 192-bit nonce when random nonces are needed.
  • It is an excellent AES-GCM alternative, often faster and safer in software-only environments without AES hardware.
chacha20poly1305authenticated-encryptionaeadcryptography

Frequently asked questions

What is ChaCha20-Poly1305?

ChaCha20-Poly1305 is an authenticated encryption algorithm that combines the ChaCha20 stream cipher for confidentiality with the Poly1305 authenticator for integrity. It encrypts data and produces an authentication tag in one step, protecting against both eavesdropping and tampering, and is widely used in TLS, SSH, and VPNs.

How does ChaCha20-Poly1305 work?

ChaCha20 generates a pseudorandom keystream from a key, nonce, and counter, which is combined with the plaintext to produce ciphertext. Poly1305 then computes a message authentication tag over the ciphertext and any associated data, and the recipient verifies this tag before trusting the message to detect any modification.

Is ChaCha20-Poly1305 better than AES-GCM?

Both are strong authenticated ciphers, but ChaCha20-Poly1305 often performs better and more safely on devices without hardware AES acceleration, such as many mobile phones. AES-GCM is typically faster on hardware with dedicated AES instructions, so protocols like TLS offer both and negotiate the best choice.

Is ChaCha20-Poly1305 secure?

Yes, ChaCha20-Poly1305 is considered highly secure and is standardized for use in TLS and other protocols, with no known practical attacks. Its main requirement is that each nonce must never be reused with the same key, since nonce reuse can break both confidentiality and authentication.

Why does ChaCha20-Poly1305 resist timing attacks?

ChaCha20 and Poly1305 are built from simple additions, rotations, and XOR operations that run in constant time and do not use secret-dependent table lookups. This avoids the cache-timing side channels that can affect naive software implementations of AES, making it safer in pure software.

What is a nonce in ChaCha20-Poly1305 and why does it matter?

A nonce is a number used once that combines with the key to ensure each encryption produces a unique keystream. Reusing a nonce with the same key is catastrophic, as it can expose relationships between plaintexts and allow forgery, so nonces must be unique per message, typically via a counter or random value.

Try it hands-on

K0G is an open toolkit of browser-based security utilities — hashing, encoding, JWT, certificates, crypto and more, all running locally in your browser.

Explore the tools →