A — What is a Nonce?
A1 — The one rule
A nonce (number used once) in AEAD schemes is a per-encryption value that must be unique for every encryption under the same key. It does not need to be secret. AES-GCM uses a 96-bit nonce (12 bytes). The security proof assumes the nonce is never reused — and the rest of this page is what happens when that one rule is broken.
NIST SP 800-38D calls it an Initialization Vector (IV); RFC 5116 calls it a nonce — same concept.
96-BIT NONCE (12 BYTES)
No theory yet — go break it first. Head to Section B, flip the nonce toggle, and watch AES-GCM leak. Then Section C explains the algebra behind what you just saw.
B — See It Break (Live Attack Demo)
Encrypt two messages under AES-GCM and AES-GCM-SIV with the same key. Leave the nonce toggle on to reuse the nonce, then run the attack. Watch AES-GCM leak the plaintext XOR and hand over its authentication key — while AES-GCM-SIV shrugs. Curiosity first: see the break here, then jump to Section C for why it happened.
🔓 AES-GCM Vulnerable
Click "Encrypt Both" to begin
🔒 AES-GCM-SIV Resistant
Click "Encrypt Both" to begin
C — Why It Breaks
You just watched AES-GCM leak. Here is the algebra behind it. Two levels: the first cracks confidentiality (recovering the plaintexts), the second cracks integrity (forging tags). Each turns on one idea — a shared secret term that cancels when you XOR two things together. The animations below show that cancellation happen.
C1 — Level 1: keystream reuse (confidentiality)
AES-GCM encrypts by XORing plaintext with a keystream — a pseudorandom pad derived from (key, nonce, counter). The keystream depends only on the key and nonce, not on the message. So if you reuse a (key, nonce) pair, both messages get XORed with the same pad:
The same keystream (highlighted) sits in both ciphertexts.
Because x ⊕ x = 0, the identical keystream blocks annihilate each other. What's left is C₁ ⊕ C₂ = P₁ ⊕ P₂ — the XOR of the two plaintexts, with no key involved at all. In practice that often recovers both messages (via crib-dragging / known structure). This is exactly the Recovered P₁ ⊕ P₂ you saw in Section B.
C2 — Level 2: authentication-key recovery (integrity)
GHASH — a keyed checksum built from multiply-add in a special number system. GF(2¹²⁸) — arithmetic on 128-bit blocks where "add" is just XOR. The mask — a per-nonce pad AES adds on top of the checksum so the tag looks random.
AES-GCM's tag is that GHASH checksum, keyed by H = E_K(0¹²⁸) (fixed by the key alone), with the mask XORed on top. For a 96-bit nonce:
The mask E_K(nonce ‖ 0³¹1) depends only on (key, nonce) — so, just like the keystream in Level 1, two tags under the same nonce carry the identical mask. XOR the two tags and it cancels:
The same mask (highlighted) sits in both tags.
With the mask gone, what remains is one equation in the single unknown H over GF(2¹²⁸). For two equal-length single blocks it collapses to the closed form tag₁ ⊕ tag₂ = (C₁ ⊕ C₂)·H², solved directly as H = √((tag₁ ⊕ tag₂)·(C₁ ⊕ C₂)⁻¹). (For longer messages it is a higher-degree polynomial whose roots give a small candidate set — Joux's "forbidden attack.") Recover H and you also recover the mask, and then you can forge a valid tag for any ciphertext under that nonce. Not theoretical: a 2016 survey (Böck, Zauner, Devlin et al.) found production HTTPS servers reusing AES-GCM nonces, exposed to exactly this.
One honest detail about the demo. To recover H cleanly the attacker doesn't use your Alice/Mallory messages — it sends two chosen 16-byte probes (forbidden-atk-01 / forbidden-atk-02) under the same reused nonce, because the closed-form solver above needs equal-length single blocks. Those probes are not your messages above; the reused nonce is what's shared. Any two chosen ciphertexts under the repeated nonce would do — real-world attackers pick convenient ones.
D — SIV: Safe by Design
AES-GCM-SIV closes both holes with one idea: make the IV depend on the plaintext, and AES-encrypt the checksum before anyone sees it. Below: the construction, why the tag-cancellation trick dies, and an interactive panel where you can watch plaintext → tag → IV → ciphertext move together.
D0 — The synthetic-IV construction (RFC 8452)
AES-GCM-SIV uses a synthetic IV approach:
- Derive a per-nonce authentication key and encryption key from the master key and nonce
- Hash the plaintext (and AAD) with POLYVAL (a keyed checksum, GHASH's twin in a little-endian-friendly field) — then XOR in the nonce and AES-encrypt the result to produce the tag
- Use that tag (top bit set) as the synthetic IV for AES-CTR encryption
The IV is derived from the plaintext itself. If the same (key, nonce) pair encrypts two different plaintexts, the two IVs differ, so the two keystreams differ — the Level 1 cancellation can never happen. Nonce reuse degrades to leaking only whether two plaintexts were identical.
D1 — Key Derivation
AES-GCM-SIV derives per-nonce keys from the master key. For each counter it AES-encrypts the block counter ‖ nonce (counter is a 32-bit little-endian value; nonce is 96 bits) and keeps the low 8 bytes of the output, concatenating them:
For a 128-bit master key the encryption key uses only counters 2–3 (two blocks).
D2 — POLYVAL Authentication (why the cancel trick dies)
POLYVAL — a keyed checksum, GHASH's twin, defined in RFC 8452 in a little-endian-friendly version of the same GF(2¹²⁸) field (add = XOR).
Its key H is derived per-nonce from (key, nonce). But the decisive difference from AES-GCM is the final step: the POLYVAL result is AES-encrypted before it is output as the tag.
tag = AESKenc(S)
Recall the Level 2 break in Section C: subtracting two tags cancelled the mask and left a clean polynomial in H. Here the attacker only ever sees AESKenc(S) — never POLYVAL's raw output S. XORing two tags now XORs two AES outputs, which linearizes into nothing: the AES pseudorandom permutation shreds the polynomial structure. So even reusing a nonce (which does reuse H) never leaks the authentication key.
D3 — Tag-as-IV, Live: plaintext → tag → IV → ciphertext
SIV's whole safety property is the IV depends on the plaintext. The 128-bit tag (the AES-encrypted POLYVAL result) is the initial AES-CTR counter block — copied verbatim, with the most significant bit of its last byte set to 1 (RFC 8452 §4). That bit is the same one cleared on the tag-generation input, so the tag value can never collide with a CTR counter. Watch all four values move together as you type — the tag changes, so the IV changes, so the very first ciphertext block changes.
Type any message to see how the AES-GCM-SIV tag, derived AES-CTR IV, and first ciphertext block all change togetherCompare against a second message B:
E — When to Use Which
E1 — Comparison Table
| Property | AES-GCM | AES-GCM-SIV |
|---|---|---|
| Standard | NIST SP 800-38D | RFC 8452 |
| Nonce size | 96 bits | 96 bits |
| Nonce reuse consequence | Key recovery + full plaintext XOR | Identical plaintext detection only |
| Performance | ~1 pass | ~2 passes (extra POLYVAL) |
| FIPS approved | Yes | No — an IRTF CFRG spec (RFC 8452), not a NIST mode |
| Hardware acceleration | AES-NI + PCLMULQDQ | AES-NI + PCLMULQDQ |
| Online encryption | Yes | No — must buffer full plaintext |
| Deployed in | TLS 1.3, QUIC, IPsec | Google internal, QUIC experiments |
| Recommendation | ✅ Nonce uniqueness guaranteed | ✅ Nonce uniqueness uncertain |
E2 — Decision Guidance
Scenario 1 — Single server, sequential encryption
AES-GCM with a counter nonce is safe. Nonce uniqueness is easy to guarantee. No need for SIV overhead.
Scenario 2 — Distributed system, multiple encryptors
Coordinating nonces across servers is error-prone. AES-GCM-SIV degrades gracefully on accidental reuse. Use SIV or use random 96-bit nonces with AES-GCM (collision risk is low at < 2³² messages per key).
Scenario 3 — Key wrapping and key storage
AES-GCM-SIV is designed for this — short messages, repeated access to the same key, nonce coordination difficult. Google's Tink library uses it for key wrapping.
E3 — Honest Limitations of AES-GCM-SIV
- Not FIPS-approved — cannot use in FIPS 140-2/3 contexts
- No online encryption — must have full plaintext before starting (not suitable for streaming)
- Two passes over the data — the tag must be computed before encryption can begin, so throughput can approach half that of single-pass AES-GCM on long messages, though hardware-optimized (AES-NI + PCLMULQDQ) implementations narrow the gap
- Not yet widely deployed — operational experience is thin compared to AES-GCM