<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Parag Mali - tag: aes</title><description>Posts tagged aes.</description><link>https://paragmali.com/</link><language>en-US</language><lastBuildDate>Sun, 19 Jul 2026 05:08:41 GMT</lastBuildDate><atom:link href="https://paragmali.com/tags/aes/rss.xml" rel="self" type="application/rss+xml"/><item><title>How AES Breaks in Real Life: The Attacks That Never Touched the Cipher</title><link>https://paragmali.com/blog/how-aes-breaks-in-real-life-the-attacks-that-never-touched-t/</link><guid isPermaLink="true">https://paragmali.com/blog/how-aes-breaks-in-real-life-the-attacks-that-never-touched-t/</guid><description>AES-the-cipher has never been broken in the field -- its deployments have. KRACK, repeated GCM nonces, and cache timing broke the wrapper, never the block.</description><pubDate>Fri, 17 Jul 2026 00:00:00 GMT</pubDate><content:encoded>
**AES-the-cipher has never been broken in the field. Your AES traffic was decrypted anyway.** The best publicly known attack on the full cipher costs about $2^{126}$ operations for AES-128 -- its own authors say it does &quot;not threaten the practical use of AES in any way&quot; [@biclique-2011]. Yet real Wi-Fi sessions were decrypted, real HTTPS connections were forged, and real AES keys were lifted out of running servers. None of it touched the 128-bit block math. AES is a *permutation*, not a cryptosystem: to protect a message you wrap it in an *implementation*, a *mode*, and a *protocol*, and it was those three wrappers that failed -- a T-table lookup leaked the key through cache timing [@bernstein-2005; @osvik-shamir-tromer-2006]; 184 live HTTPS servers repeated an AES-GCM nonce and weaponized Joux&apos;s 2006 forbidden attack into forgery [@nonce-disrespecting-2016; @joux-2006]; and KRACK&apos;s replayed handshake rewound the AES-CCMP nonce and reused a keystream [@krack-2017]. Every fix changed *how AES is used*, never AES.
&lt;h2&gt;1. AES Is Unbroken. Your AES Traffic Was Decrypted Anyway.&lt;/h2&gt;
&lt;p&gt;The best publicly known attack on the full AES cipher costs roughly $2^{126}$ operations for AES-128 -- a number so far beyond feasible that its own discoverers wrote it does &quot;not threaten the practical use of AES in any way&quot; [@biclique-2011]. To put $2^{126}$ in scale: if every one of the billions of computers on Earth checked a billion keys a second, you would still wait longer than the age of the universe, many times over. By any honest measure, the cipher stands.&lt;/p&gt;
&lt;p&gt;And yet, in the same decade that number was published, attackers decrypted live Wi-Fi sessions, forged authenticated HTTPS connections, and lifted AES keys straight out of running servers -- none of them going anywhere near that $2^{126}$ wall. How does a cipher nobody can break keep producing decrypted traffic and stolen keys?&lt;/p&gt;
&lt;p&gt;The resolution is the thesis of this article, and you can hold it right now: &lt;strong&gt;none of these breaks touched the 128-bit block math.&lt;/strong&gt; AES is a keyed &lt;em&gt;permutation&lt;/em&gt; -- a function that scrambles one 16-byte block into another -- and nothing more. It is not a cryptosystem. To protect a real message you wrap that permutation in three things: an &lt;em&gt;implementation&lt;/em&gt; that computes it on real silicon, a &lt;em&gt;mode&lt;/em&gt; that chains it across a message, and a &lt;em&gt;protocol&lt;/em&gt; that establishes keys and drives the mode. Each wrapper is a new, independent way to fail. And it was the wrappers, every time, that failed.&lt;/p&gt;
&lt;p&gt;That gives you a diagnostic sentence to carry through the rest of this piece. When your encrypted traffic falls, the question is never &quot;was AES broken?&quot; It is: &lt;em&gt;which layer around AES failed -- the implementation, the mode, or the protocol?&lt;/em&gt; By the end you will be able to drop KRACK, the GCM nonce scandal, and tomorrow&apos;s not-yet-published incident into that one question on sight.&lt;/p&gt;

To break AES in the field, you never touch AES. The table lookup leaks, the nonce repeats, the handshake rewinds -- and the 128-bit block math never moves.
&lt;p&gt;This is Part 1 of &lt;em&gt;How It Breaks in Real Life&lt;/em&gt;, a series with a single recurring claim: the primitive&apos;s mathematics almost never caused the break; the deployment did -- the nonce, the padding, key generation, a downgrade, a validation bug, or a deprecated-but-still-live algorithm. AES is the cleanest case, which is why it goes first. Its companion piece, &lt;em&gt;How AES Would Break&lt;/em&gt;, asks what it would take to move the block itself: the key schedule, related-key cryptanalysis, the slow erosion of the security margin. That is the &lt;em&gt;would-break-in-theory&lt;/em&gt; story. This is the &lt;em&gt;did-break-in-the-field&lt;/em&gt; one.&lt;/p&gt;
&lt;p&gt;If the cipher was intact and the block math never moved, then everything that broke was built &lt;em&gt;around&lt;/em&gt; it. To see how &quot;unbroken cipher&quot; and &quot;decrypted traffic&quot; can both be true, you have to go back to what AES actually is -- and, more to the point, what it is not.&lt;/p&gt;
&lt;h2&gt;2. Why a Cipher Is Not a Cryptosystem&lt;/h2&gt;
&lt;p&gt;In October 2000, after a three-year open competition in which the world&apos;s cryptographers were &lt;em&gt;invited to attack&lt;/em&gt; the candidates, NIST selected Joan Daemen and Vincent Rijmen&apos;s Rijndael as the Advanced Encryption Standard [@nist-press-2000]. The choice followed a public evaluation of fifteen submissions narrowed to five finalists, judged on security, performance, and efficiency from servers to smart cards [@nist-aes-dev; @nist-jres-r1-1999; @nist-jres-r2-2001]. That adversarial process is why the core math has held for over two decades -- and why, when things break in the field, the fault lies elsewhere. Winning the competition made Rijndael a &lt;em&gt;cipher&lt;/em&gt;, not a cryptosystem.&lt;/p&gt;
&lt;p&gt;Here is the distinction the whole article turns on. AES, standardized as FIPS 197 in 2001 and editorially refreshed in 2023 with &lt;em&gt;no technical change&lt;/em&gt; to the algorithm, is a keyed &lt;strong&gt;128-bit permutation&lt;/strong&gt; [@fips-197]. It maps one 128-bit block to one 128-bit block under a 128-, 192-, or 256-bit key, and that is &lt;em&gt;all&lt;/em&gt; it does.AES applies 10, 12, or 14 rounds for the 128-, 192-, and 256-bit keys. The round function is identical across all three; key size changes only the round count and the key schedule that feeds it [@fips-197]. It has no notion of a message longer than 16 bytes, no integrity, no session or conversation. Feed it the same block and key twice and you get the same output twice. On its own it cannot safely encrypt a paragraph, let alone a Wi-Fi session.&lt;/p&gt;

A **block cipher** is a keyed permutation on fixed-size blocks -- AES maps one 16-byte block to another under a key. A **mode of operation** (CTR, CCM, GCM, and others) is the wrapper that chains that permutation across an arbitrary-length message and, in authenticated modes, adds integrity. The block cipher is the engine; the mode is the car. You do not drive an engine.
&lt;p&gt;To turn that engine into something that protects real data, you add three wrappers, and each one is a new, independent failure surface:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;an &lt;strong&gt;implementation&lt;/strong&gt; that computes the permutation on a real CPU, and may leak through timing or cache behavior;&lt;/li&gt;
&lt;li&gt;a &lt;strong&gt;&lt;a href=&quot;https://paragmali.com/blog/the-ciphertext-was-unbreakable-the-attacker-rewrote-it-anyw/&quot; rel=&quot;noopener&quot;&gt;mode of operation&lt;/a&gt;&lt;/strong&gt; that chains the permutation across a whole message and, in AEAD modes, adds integrity -- and imposes a contract on how you feed it nonces;&lt;/li&gt;
&lt;li&gt;a &lt;strong&gt;protocol&lt;/strong&gt; that establishes keys and drives the mode, and can mismanage them.&lt;/li&gt;
&lt;/ul&gt;

flowchart TD
    B[&quot;AES 128-bit permutation -- never broken in the field&quot;]
    I[&quot;Implementation layer -- computes the block in code or silicon&quot;]
    M[&quot;Mode layer -- chains the block, adds integrity, imposes a nonce contract&quot;]
    P[&quot;Protocol layer -- establishes keys and drives the mode&quot;]
    B --&amp;gt; I --&amp;gt; M --&amp;gt; P
    I -. break .-&amp;gt; AtkI[&quot;Cache timing leaks the key&quot;]
    M -. break .-&amp;gt; AtkM[&quot;A repeated nonce reuses a keystream&quot;]
    P -. break .-&amp;gt; AtkP[&quot;A replayed handshake rewinds the nonce&quot;]
&lt;p&gt;This map is the lens for everything that follows. The block sits at the center, untouched. The implementation wraps it, the mode wraps that, the protocol wraps that -- and the three field breaks in this article land on the three outer rings, in order, working outward from the silicon.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; AES has a &lt;strong&gt;128-bit block size&lt;/strong&gt; for all three variants; only the &lt;em&gt;key&lt;/em&gt; is 128, 192, or 256 bits. When this article says &quot;the 128-bit block math never moved,&quot; it means the block permutation, not the key. Hold onto a foreshadow: key size will turn out to be irrelevant to every break here. Against nonce reuse and a reinstalled handshake key, AES-256 fails exactly as fast as AES-128; against cache timing it is just as vulnerable, though a longer key takes proportionally more leakage to extract.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;One more piece of honesty before we watch the wrappers fail. The series this article opens says the primitive&apos;s math &lt;em&gt;almost&lt;/em&gt; never causes the break -- &quot;almost,&quot; not &quot;never&quot; -- and the hedge is load-bearing.Every break in this article is independent of key size. That is not a rhetorical flourish; it is a literal property of cache timing, nonce reuse, and handshake replay, none of which involve guessing key bits.&lt;/p&gt;

Some deployed primitives genuinely fell as *math*, not deployment. DES died to brute force because its 56-bit key was too short, which is *why* NIST ran the AES competition in the first place. RC4&apos;s keystream biases were turned into real plaintext recovery against TLS [@alfardan-2013]. MD5 and SHA-1 fell to collision attacks -- the SHAttered project produced the first SHA-1 collision at roughly $2^{63}$ hash computations [@shattered-2017]. Those are real breaks of the primitive&apos;s mathematics. AES is simply not one of them, which is what makes its deployment-versus-primitive split so clean. Never harden &quot;almost never&quot; into &quot;the math never breaks.&quot;
&lt;p&gt;Three wrappers, three contracts, three ways to fail -- none of them the cipher. Before watching each one break in the field, you need to see the contracts up close: what a mode actually promises, what a nonce is, and why the humble table lookup is a loaded gun.&lt;/p&gt;
&lt;h2&gt;3. The Layers Around the Block, and the Contracts They Impose&lt;/h2&gt;
&lt;p&gt;Every one of the three field breaks is the violation of a single, specific promise. If you see the promise clearly now, the break will look obvious later. So here are all three contracts, one per layer, in order.&lt;/p&gt;
&lt;h3&gt;The implementation contract: a lookup should not leak what it looked up&lt;/h3&gt;
&lt;p&gt;Computing AES the naive way -- byte by byte through its S-box and its field multiplications -- is slow in software. So fast implementations fold an entire round into precomputed lookup tables. Four tables of about 1 KB each, conventionally called &lt;code&gt;T0&lt;/code&gt; through &lt;code&gt;T3&lt;/code&gt;, turn each output column of a round into &lt;code&gt;T0[a] XOR T1[b] XOR T2[c] XOR T3[d]&lt;/code&gt;: four reads and three XORs, so a full round is four of those -- sixteen reads in all [@bernstein-2005].&lt;/p&gt;

A set of precomputed lookup tables (typically four tables of 256 four-byte entries, about 4 KB total) that fold AES&apos;s SubBytes, ShiftRows, and MixColumns steps into a handful of table reads per round. It is purely a speed optimization. The block permutation it computes is identical to the slow version -- but *how* it computes it now depends on secret-derived indices.
&lt;p&gt;The hidden assumption is that a table read takes the same time regardless of which entry you read. On a real CPU with a cache hierarchy, that is &lt;em&gt;false&lt;/em&gt;: the first access to a memory line is slow, a cached line is fast, and an attacker can measure the difference. And the indices &lt;code&gt;a, b, c, d&lt;/code&gt; are secret -- state bytes derived from the key XORed with the plaintext. So which table lines get touched, and therefore the timing, depends on the key. The implementation&apos;s contract is that a data-dependent lookup must not leak the data. The cache breaks it for free.&lt;/p&gt;
&lt;h3&gt;The mode contract: never repeat a (key, nonce) pair&lt;/h3&gt;
&lt;p&gt;A mode turns the one-block permutation into something that encrypts messages and detects tampering. Modern modes aim for AEAD.&lt;/p&gt;

Authenticated Encryption with Associated Data: a mode that provides confidentiality *and* integrity at once. It encrypts the plaintext and produces an authentication tag over both the ciphertext and some associated data (headers, sequence numbers) that is authenticated but not encrypted. GCM and CCM are AEAD modes; if the tag does not verify, the receiver rejects the message.
&lt;p&gt;The workhorse construction is counter mode. AES is run on a counter to produce a &lt;em&gt;keystream&lt;/em&gt;, and the keystream is XORed with the plaintext: keystream block $k_i = \mathrm{AES}_K(\text{nonce} \parallel i)$, and ciphertext $C_i = P_i \oplus k_i$. This is elegant and fast and fully parallel. It also carries one absolute obligation.&lt;/p&gt;

A **nonce** is a &quot;number used once.&quot; In counter-based modes the pair (key, nonce) must be **unique for every encryption under that key**. The nonce need not be secret or random -- a counter is fine -- but it must never repeat. This is the single most load-bearing rule in practical symmetric cryptography, and it is the rule every mode-and-protocol break in this article violates.
&lt;p&gt;Watch what happens if you break it. If two messages are encrypted under the same key &lt;em&gt;and the same nonce&lt;/em&gt;, they get the &lt;em&gt;same&lt;/em&gt; keystream. XOR the two ciphertexts and the keystream cancels:&lt;/p&gt;
&lt;p&gt;$$C_1 \oplus C_2 = (P_1 \oplus k) \oplus (P_2 \oplus k) = P_1 \oplus P_2$$&lt;/p&gt;
&lt;p&gt;The key never appears. The attacker who captures two same-nonce ciphertexts learns the XOR of the two plaintexts, and if they know or can guess one, they get the other -- with the cipher fully intact.&lt;/p&gt;

The failure that follows from a repeated (key, nonce) in a counter-based mode: identical keystream for two messages, so $C_1 \oplus C_2 = P_1 \oplus P_2$. The plaintext XOR leaks and the key is never touched. This one mechanic drives *both* the GCM break and the WPA2/CCMP break later in this article.
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; A block cipher in a counter-based mode is a keystream generator. Feed it the same (key, nonce) twice and you get the same keystream, so $C_1 \oplus C_2 = P_1 \oplus P_2$ -- the plaintext XOR leaks and the key is never touched. The nonce-uniqueness contract is the one promise that stops this. Break it and the strongest cipher in the world protects nothing.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You can watch the cancellation happen. Nothing below is real AES -- the toy keystream stands in for AES-CTR output -- but the XOR algebra is exactly the algebra of the real break.&lt;/p&gt;
&lt;p&gt;{`
// Same (key, nonce) =&amp;gt; same keystream for BOTH messages. That is the whole bug.
const keystream = [0x9e, 0x37, 0xb1, 0xa4, 0x55, 0x0c, 0xd2, 0x6f];&lt;/p&gt;
&lt;p&gt;function xorBytes(a, b) {
  const out = [];
  for (let i = 0; i &amp;lt; a.length; i++) out.push(a[i] ^ b[i]);
  return out;
}
const toBytes = (s) =&amp;gt; Array.from(s).map((c) =&amp;gt; c.charCodeAt(0));&lt;/p&gt;
&lt;p&gt;const p1 = toBytes(&quot;ATTACK 0&quot;);
const p2 = toBytes(&quot;defend!!&quot;);&lt;/p&gt;
&lt;p&gt;const c1 = xorBytes(p1, keystream);   // what the attacker sees
const c2 = xorBytes(p2, keystream);   // what the attacker sees&lt;/p&gt;
&lt;p&gt;const leaked = xorBytes(c1, c2);      // C1 ^ C2, computed with NO key
const truth  = xorBytes(p1, p2);      // P1 ^ P2, the secret relationship&lt;/p&gt;
&lt;p&gt;console.log(&quot;C1 ^ C2 =&quot;, leaked.join(&quot;,&quot;));
console.log(&quot;P1 ^ P2 =&quot;, truth.join(&quot;,&quot;));
console.log(&quot;keystream cancelled?&quot;, JSON.stringify(leaked) === JSON.stringify(truth));
// Know one plaintext, recover the other. The cipher stayed perfectly strong.
`}&lt;/p&gt;
&lt;p&gt;GCM adds one more thing to worry about. Its integrity tag is built from a secret authentication subkey derived from the key alone, and &lt;a href=&quot;https://paragmali.com/blog/one-number-used-twice-how-a-repeated-nonce-hands-over-your-p/&quot; rel=&quot;noopener&quot;&gt;a repeated nonce&lt;/a&gt; exposes that subkey to attack as well -- which is how confidentiality loss becomes &lt;em&gt;forgery&lt;/em&gt;. We will pull that thread in the next section.&lt;/p&gt;
&lt;p&gt;Even with perfectly unique nonces, GCM has a budget. With random 96-bit nonces, NIST caps a single key at fewer than $2^{32}$ invocations, because random 96-bit values begin colliding around the birthday bound [@sp-800-38d]. Uniqueness is not just a coding rule; it is a counting problem.&lt;/p&gt;

When AES-GCM came to TLS 1.2, RFC 5288 let the implementation choose part of each record&apos;s nonce -- an &quot;explicit nonce&quot; -- and its own security-considerations text carried a &quot;Counter Reuse&quot; warning that a repeated counter is catastrophic [@rfc-5288]. The contract was not merely implied; it was written down, in the same document that shipped the feature. A decade later, a scan of the live Internet found servers breaking it anyway.
&lt;h3&gt;The protocol contract: install a key once, so its nonce only ever counts up&lt;/h3&gt;
&lt;p&gt;A mode still needs a protocol to establish keys and supply nonces. WPA2&apos;s 4-way handshake derives a fresh Pairwise Transient Key, and AES-CCMP then encrypts each frame with a nonce built from an incrementing packet number; CCM, like GCM, forbids repeating that counter under one key [@sp-800-38c; @ieee-80211i-2004]. The assumption is simple and, on its face, obviously true: a key is installed exactly once, so the packet number only ever counts &lt;em&gt;up&lt;/em&gt; and never rewinds.&lt;/p&gt;
&lt;p&gt;Here are the three contracts side by side. Keep the last column in view -- it is the bill each violation runs up.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;What it is&lt;/th&gt;
&lt;th&gt;The contract it imposes&lt;/th&gt;
&lt;th&gt;What a violation costs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Implementation&lt;/td&gt;
&lt;td&gt;Code or silicon that computes the AES round&lt;/td&gt;
&lt;td&gt;A data-dependent lookup must not leak the data&lt;/td&gt;
&lt;td&gt;Cache/timing side channel recovers the key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mode&lt;/td&gt;
&lt;td&gt;CTR, GCM, CCM chaining the block across a message&lt;/td&gt;
&lt;td&gt;The (key, nonce) pair must be unique per encryption&lt;/td&gt;
&lt;td&gt;Keystream reuse leaks $P_1 \oplus P_2$; in GCM, forgery&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Protocol&lt;/td&gt;
&lt;td&gt;Handshake and key management driving the mode&lt;/td&gt;
&lt;td&gt;A key is installed once, so its nonce only counts up&lt;/td&gt;
&lt;td&gt;A reinstalled key rewinds the nonce, forcing reuse&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Three contracts, each reasonable, each &lt;em&gt;unenforced by the cipher&lt;/em&gt; -- the permutation cannot know whether you fed it a repeated nonce or read a leaky table. Which raises the only question that matters: in the real world, running on real servers and real routers, do these contracts actually hold? They do not. Here is where, when, and how each one broke.&lt;/p&gt;
&lt;h2&gt;4. Three Field Breaks, Three Layers, One Pattern&lt;/h2&gt;
&lt;p&gt;The comfortable belief is &quot;we standardized a strong cipher, so our encrypted traffic is safe.&quot; What follows are three independent refutations of that inference -- one at each layer around the block, ordered by when the field break landed. Read them as a catalog, not a lineage: these are not ciphers that replaced one another but three &lt;em&gt;simultaneous&lt;/em&gt; layers, every real deployment has all three at once, and the chronology is the attacker&apos;s frontier moving &lt;em&gt;outward&lt;/em&gt; as each inner layer hardened.&lt;/p&gt;

timeline
    title From the silicon outward -- one pattern, three layers
    2005-2006 : Implementation layer : Cache timing recovers AES keys (Bernstein, Osvik-Shamir-Tromer)
    2016 : Mode layer : 184 HTTPS servers repeat a GCM nonce (Böck et al., weaponizing Joux 2006)
    2017 : Protocol layer : KRACK rewinds the AES-CCMP nonce (Vanhoef and Piessens)
&lt;h3&gt;Generation 1: the implementation leaked (2005-2006)&lt;/h3&gt;
&lt;p&gt;In 2005, Daniel J. Bernstein did something the FIPS 197 math says is impossible: he recovered a full AES key &lt;em&gt;remotely&lt;/em&gt;, over a network -- without breaking AES at all [@bernstein-2005; @bernstein-index]. The target was a server doing nothing but AES under clean timing conditions, so the demonstration was remote in principle rather than turnkey -- and alarming precisely because it was not purely local. It ran ordinary T-table AES, whose secret-dependent indices left the encryption&apos;s timing faintly correlated with the key; enough samples pinned the key bytes. A year later, Dag Arne Osvik, Adi Shamir, and Eran Tromer formalized the idea into two reusable cache attacks -- &lt;strong&gt;Prime+Probe&lt;/strong&gt; and &lt;strong&gt;Evict+Time&lt;/strong&gt; -- recovering keys with a modest number of encryptions on a shared machine [@osvik-shamir-tromer-2006].&lt;/p&gt;

Recovering a secret from the physical *side effects* of a computation -- its timing, its cache footprint, its power draw -- rather than from the algorithm&apos;s inputs and outputs. A cache-timing attack on T-table AES watches which cache lines the lookups touch; because the touched lines depend on key-derived indices, the access pattern leaks the key.
&lt;p&gt;The mechanism is worth seeing as a chain, because every link is outside the cipher:&lt;/p&gt;

flowchart LR
    K[&quot;Secret index = key byte XOR plaintext byte&quot;] --&amp;gt; L[&quot;Which T-table cache line is touched&quot;]
    L --&amp;gt; M[&quot;Cache hit or miss changes measurable timing&quot;]
    M --&amp;gt; R[&quot;Attacker narrows and then pins the key byte&quot;]
&lt;p&gt;You can feel the leak in miniature. A real CPU caches memory in lines of 64 bytes, so a 256-entry table falls into a handful of cache lines. The attacker never sees the secret index -- only which &lt;em&gt;line&lt;/em&gt; was touched. Watch a single observation cut the keyspace:&lt;/p&gt;
&lt;p&gt;{`
// A CPU caches memory in 64-byte lines, so 256 one-byte table entries fall into
// a few &quot;cache lines.&quot; The attacker sees ONLY which line was touched -- not the index.
const LINE = 64;
const touchedLine = (index) =&amp;gt; Math.floor(index / LINE);&lt;/p&gt;
&lt;p&gt;const secretKeyByte = 0xB7;                   // unknown to the attacker
const plaintextByte = 0x2A;                   // attacker-chosen, known
const realIndex = secretKeyByte ^ plaintextByte;
const observed = touchedLine(realIndex);      // the only thing that leaks&lt;/p&gt;
&lt;p&gt;// Which key bytes are consistent with the observed cache line?
const candidates = [];
for (let k = 0; k &amp;lt; 256; k++) {
  if (touchedLine(k ^ plaintextByte) === observed) candidates.push(k);
}
console.log(&quot;observed cache line:&quot;, observed);
console.log(&quot;key-byte candidates remaining:&quot;, candidates.length, &quot;of 256&quot;);
console.log(&quot;true key byte still in the set?&quot;, candidates.includes(secretKeyByte));
// One measurement: 256 -&amp;gt; 64. Vary the known plaintext, intersect the sets, and the byte falls out.
`}&lt;/p&gt;
&lt;p&gt;The insight is the sharpest edge of the whole thesis, so state it plainly.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Cache timing recovers AES keys in the field -- that is real, and it is the reason &quot;AES is unbroken&quot; does not mean &quot;your key is safe.&quot; But the leak lives in the T-table&apos;s &lt;em&gt;memory-access pattern&lt;/em&gt;, not in the permutation. The table is a speed optimization; swap it for a leak-free implementation and the key stops leaking while the cipher stays byte-for-byte identical. Keys fall, the cipher stands. Keep that distinction sharp -- collapsing it is the reader&apos;s default error.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The fix pointed straight at the next era, and it changed how AES is &lt;em&gt;computed&lt;/em&gt;, never what AES computes. Two responses followed: &lt;strong&gt;constant-time bitsliced software&lt;/strong&gt;, which replaces the tables with data-independent boolean logic so no secret ever indexes memory [@kasper-schwabe-2009]; and, decisively, &lt;strong&gt;hardware AES-NI&lt;/strong&gt;, which executes each round in silicon with no lookup tables and data-independent latency [@intel-aes-ni]. Once AES-NI reached mainstream CPUs in the early 2010s, this surface largely closed -- and the attacker&apos;s frontier moved one ring outward, to the mode.The formalization is due to &lt;strong&gt;Osvik, Shamir, and Tromer&lt;/strong&gt; -- not Biham, a common misattribution [@osvik-shamir-tromer-2006].&lt;/p&gt;
&lt;h3&gt;Generation 2: the mode&apos;s contract was violated (2006, then 2016)&lt;/h3&gt;
&lt;p&gt;In June 2006, Antoine Joux submitted a public comment to NIST with a quietly devastating observation about GCM, now known as the &quot;forbidden attack&quot; [@joux-2006]. GCM, designed by David McGrew and John Viega, authenticates with a &lt;a href=&quot;https://paragmali.com/blog/the-tag-verified-the-cipher-held-the-forgery-went-through-a-/&quot; rel=&quot;noopener&quot;&gt;one-time polynomial MAC&lt;/a&gt; over the field $\mathrm{GF}(2^{128})$, keyed by a secret subkey derived from the encryption key alone [@mcgrew-viega-2004].&lt;/p&gt;

GCM&apos;s authentication secret, computed as $H = \mathrm{AES}_K(0^{128})$ -- the encryption of an all-zero block under the key. Every authentication tag is a polynomial in $H$ evaluated over the ciphertext, masked by $\mathrm{AES}_K(J_0)$ where $J_0$ comes from the nonce. Security depends on $H$ staying secret, which in turn depends on the nonce never repeating.
&lt;p&gt;Joux&apos;s point: if a (key, nonce) pair repeats, the mask $\mathrm{AES}_K(J_0)$ is &lt;em&gt;identical&lt;/em&gt; across the two messages, so the difference of their tags becomes a polynomial equation over $\mathrm{GF}(2^{128})$ whose unknown is $H$. Solve for the roots and you recover $H$; with $H$ in hand, you can forge a valid authentication tag for a message you chose -- universal forgery [@joux-2006]. The confidentiality loss from keystream reuse was already bad; this makes &lt;em&gt;integrity&lt;/em&gt; fall too.&lt;/p&gt;

flowchart TD
    N[&quot;Same (key, nonce) used for two messages&quot;] --&amp;gt; KS[&quot;Identical CTR keystream&quot;]
    KS --&amp;gt; C[&quot;C1 XOR C2 equals P1 XOR P2, confidentiality lost&quot;]
    N --&amp;gt; J[&quot;Identical tag mask AES_K of J0&quot;]
    J --&amp;gt; EQ[&quot;Tag difference becomes a polynomial equation in H over GF(2 to the 128)&quot;]
    EQ --&amp;gt; F[&quot;Roots reveal the subkey H, enabling forgery&quot;]
&lt;p&gt;For ten years this was a footnote -- a warning about a contract nobody, surely, would break. Then, in 2016, Hanno Böck, Aaron Zauner, Sean Devlin, Juraj Somorovsky, and Philipp Jovanovic scanned the Internet and found it broken in the wild [@nonce-disrespecting-2016]. Their paper, &quot;Nonce-Disrespecting Adversaries,&quot; reported &lt;strong&gt;184 live HTTPS servers actually repeating GCM nonces&lt;/strong&gt; -- &quot;which fully breaks the authenticity of the connections&quot; -- among them large corporations, financial institutions, and a credit-card company, plus more than 70,000 servers using random nonces at volume risk.&lt;/p&gt;
&lt;p&gt;They then did the thing Joux only described: they weaponized the repeats into working forgeries and injected content into live sessions. The root cause was mundane and entirely operational -- buggy hardware and firmware nonce generators, and counters that reset. The mode&apos;s assumption failed; AES did exactly what it was told.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; GCM will not stop you from repeating a nonce. Never generate a nonce you might repeat across process restarts, threads, forks, or virtual-machine clones and snapshots. A saved counter that resets to zero on restart is worse than useless -- it guarantees the reuse. AES-256 offers exactly zero protection here: key size is irrelevant to nonce reuse.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Two precisions keep this honest. First, the mechanism is layer-agnostic in the worst way: this is the &lt;em&gt;same keystream-reuse atom&lt;/em&gt; from Section 3, now carrying a forgery payload because GCM&apos;s integrity also leans on the nonce. Second, resist the tempting overstatement.&lt;strong&gt;Precision lock.&lt;/strong&gt; One nonce reuse is &lt;em&gt;already&lt;/em&gt; a break: it immediately leaks $C_1 \oplus C_2 = P_1 \oplus P_2$ and gives one root-finding equation for $H$. But &lt;em&gt;uniquely pinning&lt;/em&gt; $H$ for reliable universal forgery generally needs at least two collisions. Say &quot;one reuse is already catastrophic, and more reuse pins the subkey&quot; -- never &quot;one reuse recovers the key&quot; [@joux-2006]. The evidence for live reuse is the Böck et al. scan, five authors, 184 servers -- not the frequently miscited IBM Domino CVE [@nonce-disrespecting-2016].&lt;/p&gt;
&lt;p&gt;The fixes, once again, changed the &lt;em&gt;usage&lt;/em&gt; and left the cipher alone: nonce-misuse-resistant AES-GCM-SIV, where a repeat leaks only whether two messages were equal [@rfc-8452], and TLS 1.3&apos;s deterministic per-record nonce, which deletes the implementation-chosen &quot;explicit nonce&quot; that RFC 5288 had exposed [@rfc-8446]. As the mode hardened, the frontier moved one final ring outward -- to the protocol.&lt;/p&gt;
&lt;h3&gt;Generation 3: the protocol reused the nonce (2017)&lt;/h3&gt;
&lt;p&gt;WPA2&apos;s 4-way handshake exists to install a fresh key on both sides. The client installs its Pairwise Transient Key after message 3, and AES-CCMP then encrypts every frame with a nonce built from a packet number that only counts up. For reliability, the standard lets message 3 be retransmitted -- and there the trap was set. In 2017, Mathy Vanhoef and Frank Piessens showed that an attacker who captures and &lt;em&gt;replays message 3&lt;/em&gt; forces the client to reinstall a key it is already using, resetting the CCMP packet number and replay counter to their starting values [@krack-2017]. The nonce rewinds. The keystream repeats. This is KRACK: Key Reinstallation Attack.&lt;/p&gt;

Installing a key that is already in use. Because installing a key also initializes its associated nonce or packet-number counter, reinstalling an in-use key *rewinds* that counter to its starting value -- forcing the same (key, nonce) pairs, and therefore the same keystream, to be used again. KRACK triggers this by replaying a handshake message the protocol was willing to accept twice.

sequenceDiagram
    participant C as Client
    participant A as Access Point
    participant M as Attacker
    A-&amp;gt;&amp;gt;C: Message 1 (ANonce)
    C-&amp;gt;&amp;gt;A: Message 2 (SNonce)
    A-&amp;gt;&amp;gt;C: Message 3 (install key)
    Note over C: Installs PTK, packet number starts counting up
    C-&amp;gt;&amp;gt;A: Message 4 (acknowledge)
    M-&amp;gt;&amp;gt;C: Replay Message 3
    Note over C: Reinstalls the same key, packet number resets to start
    Note over C,A: Nonce reused, keystream repeats, frames become decryptable
&lt;p&gt;The insight is the same shape as before, delivered one layer further out: AES-CCMP did &lt;em&gt;exactly what it was told&lt;/em&gt;. The permutation was flawless; the state machine told it to reuse a nonce, and it obeyed. The consequence is keystream reuse -- identical (key, nonce) yields $C_1 \oplus C_2 = P_1 \oplus P_2$ -- so a known-plaintext frame yields the keystream and decrypts the colliding frame.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Scope lock.&lt;/strong&gt; Against AES-CCMP specifically, KRACK forces nonce-reuse &lt;em&gt;decryption and replay&lt;/em&gt; -- not forgery and not AES key recovery. Forgery arises for the TKIP and GCMP cases, not CCMP. The especially devastating all-zero-key variant was an Android and Linux &lt;code&gt;wpa_supplicant&lt;/code&gt; implementation bug that reinstalled an all-zero key, still not a break of AES [@krack-2017].&lt;/p&gt;
&lt;p&gt;The fix was a backwards-compatible patch to the handshake state machine -- refuse to reinstall an in-use key -- shipped across Android, Linux, Apple, Windows, and OpenBSD in 2017 [@krack-2017]. Structurally, the Wi-Fi Alliance announced WPA3 in 2018 [@wifi-wpa3-2018]; its Personal mode swaps WPA2&apos;s pre-shared-key authentication for the SAE (Dragonfly) key exchange and mandates anti-reinstallation checks plus management-frame protection. The 4-way handshake still installs the pairwise key, so KRACK immunity comes from that mandatory hardening -- the same defense WPA2 received as a patch -- not from SAE removing the handshake [@dragonblood-2019]. The protocol changed. AES did not.&lt;/p&gt;
&lt;h3&gt;The pattern, seen all at once&lt;/h3&gt;
&lt;p&gt;Put the three side by side and the shape is unmistakable. Same violated contract in three costumes; same untouched block every time.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Incident&lt;/th&gt;
&lt;th&gt;Year&lt;/th&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Mechanism&lt;/th&gt;
&lt;th&gt;Root cause&lt;/th&gt;
&lt;th&gt;Fix (usage, not cipher)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Bernstein; Osvik-Shamir-Tromer cache timing [@bernstein-2005; @osvik-shamir-tromer-2006]&lt;/td&gt;
&lt;td&gt;2005-2006&lt;/td&gt;
&lt;td&gt;Implementation&lt;/td&gt;
&lt;td&gt;Secret-dependent T-table indices leak via cache/timing&lt;/td&gt;
&lt;td&gt;A data-dependent lookup leaks the data&lt;/td&gt;
&lt;td&gt;Constant-time bitslicing; AES-NI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Joux forbidden attack; Böck et al. scan [@joux-2006; @nonce-disrespecting-2016]&lt;/td&gt;
&lt;td&gt;2006, 2016&lt;/td&gt;
&lt;td&gt;Mode&lt;/td&gt;
&lt;td&gt;Repeated GCM nonce reuses keystream and exposes $H$&lt;/td&gt;
&lt;td&gt;Buggy nonce generators break uniqueness&lt;/td&gt;
&lt;td&gt;AES-GCM-SIV; TLS 1.3 derived nonces&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KRACK [@krack-2017]&lt;/td&gt;
&lt;td&gt;2017&lt;/td&gt;
&lt;td&gt;Protocol&lt;/td&gt;
&lt;td&gt;Replayed message 3 rewinds the CCMP nonce&lt;/td&gt;
&lt;td&gt;State machine reinstalls an in-use key&lt;/td&gt;
&lt;td&gt;Handshake patch; WPA3-SAE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Biclique baseline [@biclique-2011]&lt;/td&gt;
&lt;td&gt;2011&lt;/td&gt;
&lt;td&gt;The cipher itself&lt;/td&gt;
&lt;td&gt;Best single-key attack: $2^{126.1}$ for AES-128&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;None needed -- &quot;no practical impact&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Seen one at a time, these look like three unrelated bugs -- a cache thing, a TLS thing, a Wi-Fi thing. Seen together, they are a single pattern: every time, a contract &lt;em&gt;around&lt;/em&gt; the permutation was violated, real traffic or keys fell, and the 128-bit block math did not move. That pattern is the whole point, and it is worth naming out loud.&lt;/p&gt;
&lt;h2&gt;5. The Fixes Changed How AES Is Used, Never AES&lt;/h2&gt;
&lt;p&gt;Stop treating the three incidents as separate stories. Line them up and one realization collapses the subject: &lt;em&gt;every&lt;/em&gt; field break attacked a layer around the permutation, and &lt;em&gt;every&lt;/em&gt; fix changed how AES is &lt;em&gt;used&lt;/em&gt; -- never AES itself.&lt;/p&gt;
&lt;p&gt;This is not a eureka discovery. It is an engineering discipline, and it is visible only because the same shape repeats three times across 2005, 2016, and 2017. Look at what each fix actually touched:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Implementation.&lt;/strong&gt; Constant-time bitsliced code and hardware AES-NI compute the round with no data-dependent memory access [@kasper-schwabe-2009; @intel-aes-ni]. The tables are gone; the permutation they computed is unchanged.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mode.&lt;/strong&gt; AES-GCM-SIV makes a repeated nonce merely detectable rather than catastrophic -- a repeat leaks only whether two messages were equal, never the subkey $H$ [@rfc-8452]. TLS 1.3 derives each nonce deterministically from the record sequence number, deleting the footgun RFC 5288 had exposed [@rfc-8446]. The nonce plumbing changed; AES did not.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Protocol.&lt;/strong&gt; The KRACK patch forbids reinstalling an in-use key, and WPA3 makes that anti-reinstallation defense mandatory (alongside management-frame protection) while swapping WPA2&apos;s pre-shared-key authentication for the SAE key exchange; the 4-way handshake persists, hardened rather than removed [@krack-2017; @wifi-wpa3-2018; @dragonblood-2019]. The state machine changed; AES did not.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Not one of these altered the block permutation. They hardened wrappers.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The cipher is the fixed point around which everything else evolved. Every field break attacked a layer around the permutation, and every remedy -- constant-time and AES-NI, misuse-resistant AEAD and derived nonces, patched handshakes and WPA3 -- hardened a &lt;em&gt;wrapper&lt;/em&gt;. Soundness requires the weakest of the three layers to hold, and hardening any one of them is an exercise in &lt;em&gt;usage&lt;/em&gt;, not cryptanalysis.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There is a dynamic hiding in the chronology, and it is no coincidence. As AES-NI closed the implementation gap around 2010, the weakest remaining link -- the attacker&apos;s frontier -- moved to the mode, where the 2016 scan found it. As misuse-resistant modes and derived nonces closed that, the frontier moved to the protocol, where KRACK found it in 2017. The layers did not take turns being weak; the attacker simply always works the &lt;em&gt;current&lt;/em&gt; weakest one. That is why &quot;we use a strong cipher&quot; was never the right unit of analysis. The right unit is the weakest wrapper you are still running.&lt;/p&gt;

This article is the *did-break-in-the-field* story. Its companion, *How AES Would Break*, is the *would-break-in-theory* one: the key schedule, related-key attacks such as the Biryukov-Khovratovich results on AES-256 that only exist in a related-key model correct deployments never create [@biryukov-khovratovich-2009], and the slow erosion of the security margin. Different question, different article. And the general craft of constant-time code, fault resistance, and key custody belongs to a third sibling on secure implementation. This piece links out to both rather than re-teaching them, because the point here is narrow and sharp: the wrappers broke, and the wrappers were fixed.
&lt;p&gt;If every fix is a species of &quot;use AES correctly,&quot; then the state of the art is just the catalog of what &quot;correctly&quot; means at each layer in 2026 -- and, tellingly, where even correct-by-the-book still is not quite enough.&lt;/p&gt;
&lt;h2&gt;6. What Correct AES Deployment Looks Like in 2026&lt;/h2&gt;
&lt;p&gt;The modern answer is unglamorous, and that is exactly the point: be sound at all three layers at once, because a hardened mode does nothing for a leaky implementation, and a constant-time implementation does nothing for a protocol that rewinds its nonce. Here is the correct-deployment endpoint, keyed to the three failure loci.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Implementation.&lt;/strong&gt; Use hardware AES -- Intel and AMD AES-NI, or ARMv8&apos;s cryptographic extension -- which runs each round in silicon with no lookup tables and data-independent latency [@intel-aes-ni]. Where the CPU lacks AES instructions, fall back to a &lt;strong&gt;constant-time bitsliced&lt;/strong&gt; software implementation that never lets a secret index memory [@kasper-schwabe-2009]. Mainstream libraries typically make this selection at runtime, preferring hardware AES with a constant-time fallback.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Mode.&lt;/strong&gt; Use a &lt;a href=&quot;https://paragmali.com/blog/the-aead-decision-matrix-seven-ciphers-three-edges-one-choic/&quot; rel=&quot;noopener&quot;&gt;vetted AEAD&lt;/a&gt;, never a hand-rolled chain of primitives. AES-GCM is the performance leader when you can &lt;em&gt;guarantee&lt;/em&gt; nonce uniqueness -- either random 96-bit nonces kept under the NIST budget of fewer than $2^{32}$ invocations per key [@sp-800-38d], or TLS 1.3&apos;s deterministic per-record nonce derived from the sequence number [@rfc-8446]. Where uniqueness cannot be guaranteed, use &lt;strong&gt;AES-GCM-SIV&lt;/strong&gt;, which survives a repeat gracefully [@rfc-8452].&lt;/p&gt;

An authenticated-encryption scheme that does not fail catastrophically when a nonce repeats. In an MRAE scheme such as AES-GCM-SIV, a repeated (nonce, message) pair leaks only the fact that the two plaintexts were identical -- never the keystream across distinct messages, never the subkey $H$. It is the provably strongest guarantee achievable once you admit that nonces sometimes repeat.
&lt;p&gt;&lt;strong&gt;Protocol.&lt;/strong&gt; At the link layer, patch WPA2 against key reinstallation or move to WPA3, which mandates anti-reinstallation checks and management-frame protection to close the defect while still running a 4-way handshake to install the pairwise key [@krack-2017; @wifi-wpa3-2018; @dragonblood-2019]. At the transport layer, prefer TLS 1.3 over 1.2: it deletes the explicit-nonce footgun and the downgrade and renegotiation hazards that made 1.2 fragile [@rfc-8446].&lt;/p&gt;
&lt;p&gt;There is one caveat that keeps this from being a victory lap, and it is a good illustration of how deep the &quot;usage&quot; story goes.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &quot;AES-NI is constant-time by construction&quot; is true by &lt;em&gt;design intent&lt;/em&gt;, but on Ice Lake and later Intel cores, and Armv8.4-A and later, data-operand-independent timing -- including for AES instructions -- is only &lt;em&gt;guaranteed&lt;/em&gt; when the processor&apos;s data-independent-timing mode is explicitly enabled [@intel-doit; @biggers-2023]. A constant-time algorithm is necessary but not sufficient for constant-time execution; part of the guarantee lives below your software, in a mode you now have to request.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The practical upshot is that &quot;constant-time&quot; has quietly become a setting rather than an assumption.On recent Intel cores the mode is called DOITM (Data Operand Independent Timing Mode); on Arm it is the DIT (Data-Independent Timing) processor-state bit. Eric Biggers raised the cross-vendor issue publicly in 2023, and it is the reason security-sensitive code on the newest silicon must ask for timing guarantees rather than inherit them [@biggers-2023; @intel-doit].&lt;/p&gt;
&lt;p&gt;&quot;Use a vetted AEAD, use hardware AES, patch your handshake&quot; is the whole answer for greenfield code. But engineers inherit constraints -- a fixed nonce source, a distributed system that cannot coordinate a counter, a CPU with no AES instructions. So the real question is rarely &quot;what is best.&quot; It is &quot;what are my options, ranked, and exactly when does each one apply?&quot;&lt;/p&gt;
&lt;h2&gt;7. Closing Each Gap: The Competing Defenses&lt;/h2&gt;
&lt;p&gt;At two of the three layers a practitioner actually has a &lt;em&gt;choice&lt;/em&gt;, and the honest framing is a set of trade-offs, not a single winner. Take the two design spaces in turn.&lt;/p&gt;
&lt;h3&gt;The side channel: hardware AES-NI versus software bitslicing&lt;/h3&gt;
&lt;p&gt;These two coexist because they optimize different constraints. Where the CPU has AES instructions, AES-NI is the fastest option and constant-time by construction (subject to the DOIT/DIT caveat from the previous section) [@intel-aes-ni]. Where it does not -- older cores, small embedded parts -- constant-time bitsliced software gives a verifiable timing guarantee at the cost of speed and implementation effort [@kasper-schwabe-2009]. The one option that is never acceptable in security code is the original T-table implementation.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;T-table AES (broken)&lt;/th&gt;
&lt;th&gt;Bitsliced constant-time software&lt;/th&gt;
&lt;th&gt;Hardware AES-NI / ARMv8&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Secret-dependent memory access&lt;/td&gt;
&lt;td&gt;Yes (about 4 KB of tables)&lt;/td&gt;
&lt;td&gt;None (boolean logic)&lt;/td&gt;
&lt;td&gt;None (silicon datapath)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Timing side-channel resistance&lt;/td&gt;
&lt;td&gt;Fails [@bernstein-2005; @osvik-shamir-tromer-2006]&lt;/td&gt;
&lt;td&gt;Constant-time by construction&lt;/td&gt;
&lt;td&gt;Data-independent by design; DOIT/DIT mode needed on Ice Lake+/Armv8.4+ [@intel-doit]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Throughput&lt;/td&gt;
&lt;td&gt;Fast (pre-attack)&lt;/td&gt;
&lt;td&gt;Good when blocks are batched&lt;/td&gt;
&lt;td&gt;Fastest; line-rate AEAD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Block-parallelism needed&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (weak for a single block)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hardware requirement&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;CPU AES instructions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best suited for&lt;/td&gt;
&lt;td&gt;Nothing security-sensitive&lt;/td&gt;
&lt;td&gt;No-AES-NI or verifiable software&lt;/td&gt;
&lt;td&gt;Everything with the instruction&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h3&gt;The nonce: four live strategies&lt;/h3&gt;
&lt;p&gt;This is the design space where the 2016 scan drew blood, so it deserves the careful table. The four options trade nonce size, streaming ability, and misuse tolerance against each other.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;AES-GCM, random 96-bit nonce&lt;/th&gt;
&lt;th&gt;AES-GCM, TLS 1.3 counter nonce&lt;/th&gt;
&lt;th&gt;AES-GCM-SIV (MRAE)&lt;/th&gt;
&lt;th&gt;XChaCha20-Poly1305&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Nonce size&lt;/td&gt;
&lt;td&gt;96-bit&lt;/td&gt;
&lt;td&gt;96-bit (derived)&lt;/td&gt;
&lt;td&gt;96-bit&lt;/td&gt;
&lt;td&gt;192-bit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Passes&lt;/td&gt;
&lt;td&gt;1 (streaming)&lt;/td&gt;
&lt;td&gt;1 (streaming)&lt;/td&gt;
&lt;td&gt;2 (buffered)&lt;/td&gt;
&lt;td&gt;1 (streaming)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;On accidental repeat&lt;/td&gt;
&lt;td&gt;Catastrophic (leaks $P_1 \oplus P_2$; two collisions give $H$ and forgery)&lt;/td&gt;
&lt;td&gt;Structurally prevented per connection&lt;/td&gt;
&lt;td&gt;Graceful (leaks only message equality)&lt;/td&gt;
&lt;td&gt;Catastrophic on a true repeat, but essentially never collides at random&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Safe budget per key&lt;/td&gt;
&lt;td&gt;Under $2^{32}$ messages [@sp-800-38d]&lt;/td&gt;
&lt;td&gt;Per-connection sequence, no reuse if the counter is sound&lt;/td&gt;
&lt;td&gt;Effectively unbounded against misuse&lt;/td&gt;
&lt;td&gt;About $2^{96}$ random nonces before collision risk&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Relative speed&lt;/td&gt;
&lt;td&gt;Fastest (line rate)&lt;/td&gt;
&lt;td&gt;Fastest&lt;/td&gt;
&lt;td&gt;About 0.92 cpb on Broadwell, 14-19% slower than OpenSSL GCM [@gueron-lindell-2015]&lt;/td&gt;
&lt;td&gt;Fast in constant-time software, no AES-NI needed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Primitive&lt;/td&gt;
&lt;td&gt;AES&lt;/td&gt;
&lt;td&gt;AES&lt;/td&gt;
&lt;td&gt;AES&lt;/td&gt;
&lt;td&gt;ChaCha20 (not AES)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Read the table as a decision, not a ranking. If you own a reliable per-connection counter, deterministic-nonce AES-GCM is both fastest and safe -- that is what TLS 1.3 does [@rfc-8446]. If you &lt;em&gt;cannot&lt;/em&gt; guarantee uniqueness -- distributed writers, stateless functions, restart- or clone-prone systems -- AES-GCM-SIV is the provably strongest answer under misuse, at the price of a second pass and a buffered message [@rfc-8452; @rogaway-shrimpton-2006]. And if AES is not mandated and you just want &quot;a random nonce is always safe,&quot; XChaCha20-Poly1305&apos;s 192-bit nonce makes accidental collision astronomically unlikely [@xchacha-draft] -- a different primitive, included as the most common answer to the nonce footgun rather than as an AES deployment.&lt;/p&gt;
&lt;p&gt;Every option here changes &lt;em&gt;how AES is used&lt;/em&gt; -- or swaps AES out entirely -- and each buys its safety with a specific cost: a pass, a throughput hit, a hardware dependency, a different primitive. Which makes the honest way to close the technical arc a question about limits: how little does the attacker actually need, and how much can the defender actually guarantee?&lt;/p&gt;
&lt;h2&gt;8. Theoretical Limits: What Is Provably True on Both Sides&lt;/h2&gt;
&lt;p&gt;The thesis has two sides, and each has its own provable frontier. The surprise is the asymmetry: the cipher side is essentially closed, and all the hard, unavoidable limits live in the deployment.&lt;/p&gt;
&lt;h3&gt;The cipher side: the math that did not break&lt;/h3&gt;
&lt;p&gt;Biclique cryptanalysis is the &lt;em&gt;entire&lt;/em&gt; published erosion of the full-cipher security margin. Bogdanov, Khovratovich, and Rechberger reported the first single-key attacks on the full cipher at $2^{126.1}$, $2^{189.7}$, and $2^{254.4}$ for AES-128, AES-192, and AES-256 -- with no related-key assumption [@biclique-2011]. Against brute force at $2^{128}$, $2^{192}$, and $2^{256}$, that is a gain of at most roughly 1.6 to 2.3 bits: a factor of a few, not a factor that matters.A &quot;bit&quot; of security is a doubling of attacker work, so shaving 2 bits makes the attack about four times faster than brute force -- still astronomically far from feasible.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;AES-128&lt;/th&gt;
&lt;th&gt;AES-192&lt;/th&gt;
&lt;th&gt;AES-256&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Brute-force cost&lt;/td&gt;
&lt;td&gt;$2^{128}$&lt;/td&gt;
&lt;td&gt;$2^{192}$&lt;/td&gt;
&lt;td&gt;$2^{256}$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best known single-key attack (biclique)&lt;/td&gt;
&lt;td&gt;$2^{126.1}$&lt;/td&gt;
&lt;td&gt;$2^{189.7}$&lt;/td&gt;
&lt;td&gt;$2^{254.4}$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Margin removed&lt;/td&gt;
&lt;td&gt;about 1.9 bits&lt;/td&gt;
&lt;td&gt;about 2.3 bits&lt;/td&gt;
&lt;td&gt;about 1.6 bits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Practical threat&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Relevance to the field breaks above&lt;/td&gt;
&lt;td&gt;Zero&lt;/td&gt;
&lt;td&gt;Zero&lt;/td&gt;
&lt;td&gt;Zero&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;There is no proof that any attack on AES &lt;em&gt;must&lt;/em&gt; cost as much as exhaustive search -- concrete block ciphers essentially never come with such a theorem -- so confidence rests on more than two decades of open cryptanalysis since the competition, not on an impossibility result [@fips-197]. But the reading is unambiguous, and the authors said it themselves.&lt;/p&gt;

The best known attacks on the full AES &quot;do not threaten the practical use of AES in any way.&quot; -- Bogdanov, Khovratovich, and Rechberger, 2011 [@biclique-2011]
&lt;p&gt;Notice the defender&apos;s column in the table never moves, and key size is irrelevant to every operational break in the sections above. The cipher side is, for practical purposes, a closed question.&lt;/p&gt;
&lt;h3&gt;The deployment side: where the real limits live&lt;/h3&gt;
&lt;p&gt;Now the asymmetry. Three &lt;em&gt;provable&lt;/em&gt; boundaries constrain real systems, and none of them is about AES&apos;s strength:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;The GCM birthday bound.&lt;/strong&gt; With random 96-bit nonces, collision risk grows by the birthday bound, so NIST caps a single key at fewer than $2^{32}$ invocations [@sp-800-38d]. This is a structural limit of random-nonce GCM, independent of the cipher -- the mathematical reason &quot;just use random nonces at massive scale&quot; eventually fails.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The AEAD trilemma.&lt;/strong&gt; No single scheme is simultaneously single-pass and line-rate, fully nonce-misuse-resistant, &lt;em&gt;and&lt;/em&gt; large-nonce. GCM gives you the first, GCM-SIV the second, XChaCha the third-and-a-half; you cannot have all three at once [@rfc-8452]. And misuse-resistant AE is provably the &lt;em&gt;strongest possible&lt;/em&gt; guarantee once nonces may repeat -- an attacker can always at least detect that the same message was encrypted, and a well-designed SIV scheme leaks nothing more [@rogaway-shrimpton-2006].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ISA-guaranteed whole-machine constant time is impossible in general.&lt;/strong&gt; The instruction set does not, in general, promise data-independent instruction timing, so even AES and XOR instructions may be data-dependent on recent cores unless the timing mode is enabled [@intel-doit; @biggers-2023]. A constant-time &lt;em&gt;algorithm&lt;/em&gt; cannot by itself guarantee constant-time &lt;em&gt;execution&lt;/em&gt;; part of the guarantee lives below the software, and the general craft of getting it right is the subject of the &lt;a href=&quot;https://paragmali.com/blog/correct-constant-time-and-still-owned-a-field-guide-to-side-/&quot; rel=&quot;noopener&quot;&gt;secure-implementation sibling&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The cipher-secure and system-secure claims are different, and the gap between them is &lt;em&gt;inherent&lt;/em&gt;, not accidental. The cipher side has a negligible margin nibble -- under two bits. The deployment side has the real, provable limits: the GCM birthday bound, the single-pass / misuse-resistant / large-nonce trilemma, and the structural impossibility of ISA-guaranteed constant time. Key size buys nothing against any of them.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If the cipher side is closed and the deployment side has hard limits, then the live frontier is wherever those deployment limits are still being hit in the wild. That is not a solved problem. It is an active one.&lt;/p&gt;
&lt;h2&gt;9. Open Problems: Where AES Still Breaks in the Field&lt;/h2&gt;
&lt;p&gt;The cipher side is closed; the deployment side is not. Here are the places the same three-layer pattern is still live -- each an &lt;em&gt;operational&lt;/em&gt; frontier, consistent with the thesis that the weakest link is the wrapper, not the block.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Guaranteeing nonce uniqueness in distributed, multi-writer, restart-prone systems.&lt;/strong&gt; This is the exact gap that produced Generation 2: buggy counters and generators on 184 live servers repeated GCM nonces [@nonce-disrespecting-2016]. The best partial answer, MRAE via AES-GCM-SIV, makes a repeat &lt;em&gt;detectable&lt;/em&gt; rather than catastrophic [@rfc-8452] -- but the single-pass, fully misuse-resistant, large-nonce scheme the trilemma forbids remains unrealized. In a world of stateless functions, cloned VMs, and shared keys across a fleet, &quot;just keep a counter&quot; is still an unsolved systems problem, not a solved one.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cross-VM cache side channels in multi-tenant clouds.&lt;/strong&gt; The 2005-2006 threat model assumed a shared physical machine; virtualization brought it back at scale. Irazoqui, Inci, Eisenbarth, and Sunar recovered AES keys &lt;em&gt;across virtual-machine boundaries&lt;/em&gt; using Flush+Reload with memory deduplication [@irazoqui-2014]. Hardware AES removes the &lt;em&gt;table&lt;/em&gt; channel, which is why AES-NI and constant-time code remain load-bearing in 2026.Even instruction timing can be data-dependent on recent cores unless the timing mode is enabled, so cloud tenancy keeps the Generation-1 question open even for hardware AES [@biggers-2023].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fault and differential-fault attacks.&lt;/strong&gt; Inducing a computation fault -- through voltage glitching, a laser, or rowhammer-style effects -- can recover an AES key from a handful of faulty ciphertexts [@piret-quisquater-2003]. This is again an implementation and hardware failure, not a cipher failure; the depth belongs to the secure-implementation sibling, but it is a live operational locus wherever an attacker has physical or near-physical access.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The long tail of devices without hardware AES.&lt;/strong&gt; Constant-time software is slower than AES-NI, and the performance gap quietly tempts developers back toward leaky tables on the smallest parts [@kasper-schwabe-2009]. On many of those devices the pragmatic answer is to ship a constant-time stream cipher such as ChaCha20 instead of fighting AES&apos;s software side channels [@xchacha-draft].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Formal verification of protocol state machines,&lt;/strong&gt; so the next KRACK is caught before it ships. TLS 1.3 was co-designed with formal analysis and has verified component implementations, such as those in the HACL* library [@hacl-2017]. Wi-Fi&apos;s SAE was &lt;em&gt;not&lt;/em&gt; fully immunized: Dragonblood found downgrade, denial-of-service, and side-channel leaks the authors argue are &quot;inherent to Dragonfly,&quot; and even patched software remained affected by a novel leak [@dragonblood-2019]. The state of the art at the protocol layer is &lt;em&gt;better&lt;/em&gt;, not &lt;em&gt;finished&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Every open problem here is the same sentence in new clothes: a contract around the permutation is hard to keep in the real world. Which means the practical guide almost writes itself -- it is the thesis made operational, each rule routed to the incident it prevents.&lt;/p&gt;
&lt;h2&gt;10. What to Do on Monday&lt;/h2&gt;
&lt;p&gt;Everything above collapses into a short decision procedure and a shorter list of nevers, each rule tied to the incident it prevents.&lt;/p&gt;

flowchart TD
    S[&quot;Deploying AES&quot;] --&amp;gt; Q1{&quot;CPU has AES instructions?&quot;}
    Q1 --&amp;gt;|Yes| HW[&quot;Use AES-NI or ARMv8 crypto, enable timing mode on newest cores&quot;]
    Q1 --&amp;gt;|No| CT[&quot;Use constant-time bitsliced software&quot;]
    HW --&amp;gt; Q2{&quot;Can you guarantee nonce uniqueness?&quot;}
    CT --&amp;gt; Q2
    Q2 --&amp;gt;|Yes| GCM[&quot;AES-GCM with deterministic nonces, TLS 1.3 style&quot;]
    Q2 --&amp;gt;|No| Q3{&quot;Is AES mandated?&quot;}
    Q3 --&amp;gt;|Yes| SIV[&quot;AES-GCM-SIV, misuse-resistant&quot;]
    Q3 --&amp;gt;|No| XC[&quot;XChaCha20-Poly1305, 192-bit nonce&quot;]
&lt;p&gt;The rules behind the tree:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Implementation.&lt;/strong&gt; Use a library that selects AES-NI or ARMv8 crypto at runtime and falls back to constant-time software; never table-based AES in security code; on the newest cores, be aware the data-independent-timing mode may need to be requested [@intel-aes-ni; @intel-doit]. &lt;em&gt;Prevents Generation 1: cache-timing key recovery.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mode and nonce.&lt;/strong&gt; Reliable per-connection counter, as in TLS or QUIC? Use AES-GCM with deterministic nonces [@rfc-8446]. Cannot &lt;em&gt;guarantee&lt;/em&gt; uniqueness across restarts, threads, or clones? Use AES-GCM-SIV [@rfc-8452]. Want &quot;a random nonce is always safe&quot; and AES is not mandated? Use XChaCha20-Poly1305 [@xchacha-draft]. Never hand-roll a mode, and never choose your own explicit GCM nonce. &lt;em&gt;Prevents Generation 2: nonce reuse and forgery.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Protocol.&lt;/strong&gt; Patch WPA2 against key reinstallation or move to WPA3, keep clients updated, and prefer TLS 1.3 over 1.2 [@krack-2017; @rfc-8446]. &lt;em&gt;Prevents Generation 3: handshake-driven nonce rewind.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The single highest-value check you can add to code review is a nonce-reuse detector. It is the exact contract the 184 servers violated, and it fits in a few lines.&lt;/p&gt;
&lt;p&gt;{`
// Scan a stream of (key, nonce) pairs and flag the first repeat.
function findNonceReuse(records) {
  const seen = new Set();
  for (const r of records) {
    const tag = r.key + &quot;|&quot; + r.nonce;
    if (seen.has(tag)) return { reused: true, key: r.key, nonce: r.nonce };
    seen.add(tag);
  }
  return { reused: false };
}&lt;/p&gt;
&lt;p&gt;const stream = [
  { key: &quot;k1&quot;, nonce: &quot;00000001&quot; },
  { key: &quot;k1&quot;, nonce: &quot;00000002&quot; },
  { key: &quot;k1&quot;, nonce: &quot;00000001&quot; },   // counter reset after a restart -- the bug
];&lt;/p&gt;
&lt;p&gt;console.log(findNonceReuse(stream));
// { reused: true, key: &apos;k1&apos;, nonce: &apos;00000001&apos; } -- catch it in review, not in an incident.
`}&lt;/p&gt;
&lt;p&gt;Now hold each pitfall up to the mirror. Every one of these confident sentences reproduces a specific, named incident.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;The confident mistake&lt;/th&gt;
&lt;th&gt;The incident it reproduces&lt;/th&gt;
&lt;th&gt;The fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Table-based AES is fine in security code&lt;/td&gt;
&lt;td&gt;Bernstein; Osvik-Shamir-Tromer cache timing [@bernstein-2005; @osvik-shamir-tromer-2006]&lt;/td&gt;
&lt;td&gt;AES-NI or constant-time software&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Repeating a nonce across restarts, threads, or clones is unlikely to matter&lt;/td&gt;
&lt;td&gt;The 184-server GCM forgery scan [@nonce-disrespecting-2016]&lt;/td&gt;
&lt;td&gt;AES-GCM-SIV or a disciplined counter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AES-256 is safer against these attacks&lt;/td&gt;
&lt;td&gt;Every break here -- key size is irrelevant [@nonce-disrespecting-2016]&lt;/td&gt;
&lt;td&gt;Fix the wrapper, not the key size&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Constant-time source means constant-time execution&lt;/td&gt;
&lt;td&gt;The DOIT/DIT timing caveat [@intel-doit; @biggers-2023]&lt;/td&gt;
&lt;td&gt;Enable the timing mode where required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;An unpatched WPA2 handshake is good enough&lt;/td&gt;
&lt;td&gt;KRACK [@krack-2017]&lt;/td&gt;
&lt;td&gt;Patch WPA2 or deploy WPA3&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

When you review encryption code, find where the nonce comes from and ask exactly one question: can this value repeat across a restart, a fork, a thread, or a clone? If you cannot prove it never repeats, you are reading a latent Generation-2 incident. Reach for AES-GCM-SIV or a 192-bit-nonce AEAD instead of arguing about how improbable a collision seems.
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; 1. AES-NI or ARMv8 crypto, with a constant-time software fallback. 2. A vetted AEAD -- deterministic-nonce AES-GCM where a per-connection counter is reliable, AES-GCM-SIV where uniqueness is hard, XChaCha20-Poly1305 where AES is not mandated. 3. Patched WPA2 or WPA3, and TLS 1.3 over 1.2.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The checklist is short because the lesson is one sentence. Before restating it, clear the handful of confident, wrong sentences that keep this bug alive in design meetings.&lt;/p&gt;
&lt;h2&gt;11. Frequently Asked Questions&lt;/h2&gt;


No. The best publicly known attack on the full cipher, biclique cryptanalysis, costs about $2^{126}$ operations for AES-128 -- a fraction-of-a-bit improvement over brute force with zero practical impact, and its authors say it does &quot;not threaten the practical use of AES in any way&quot; [@biclique-2011]. Every break in this article happened in a layer around the cipher, not in the cipher.


Yes -- via cache-timing side channels [@bernstein-2005; @osvik-shamir-tromer-2006]. But that is *not* a break of the cipher. The T-table implementation&apos;s memory-access pattern leaked the key; the block permutation did not. Swap the leaky tables for a constant-time implementation and the key stops leaking while AES stays byte-for-byte identical. &quot;Unbroken cipher&quot; and &quot;stolen key&quot; are both true at once.


Be precise here. One reuse immediately leaks $P_1 \oplus P_2$ through keystream reuse, and it gives one equation for the GHASH subkey $H$. But *pinning* $H$ for reliable universal forgery generally needs at least two collisions [@joux-2006]. One reuse is already catastrophic -- do not understate it -- but do not say &quot;one reuse recovers the key&quot; either.


No. Every break here is implementation, mode, or protocol; key size provides no protection against cache timing, nonce reuse, or a reinstalled handshake key [@nonce-disrespecting-2016]. For the nonce-reuse and handshake breaks AES-256 fails exactly as fast as AES-128; for cache timing it is just as vulnerable, though a longer key takes proportionally more leakage to extract. If someone proposes AES-256 as the fix for any incident in this article, they have misdiagnosed the layer.


No. Against AES-CCMP, KRACK forces nonce-reuse decryption and replay, not AES key recovery [@krack-2017]. The especially damaging all-zero-key case was an Android and Linux `wpa_supplicant` implementation bug, not a weakness in AES. No block-math weakness is involved, and no AES key is recovered by the attack itself.


No. A padding oracle is a mode-and-validation failure in CBC deployments -- the receiver leaks whether decrypted padding was valid -- and it never touches the AES permutation. It is the same moral as this article (a wrapper broke), in a different deployment, and it is covered in a dedicated padding-oracle sibling. AES itself is not the weak link there either.

&lt;p&gt;Every correction points at the same root: the cipher was never the weak link. Time to say the sentence the whole article was built to earn.&lt;/p&gt;
&lt;h2&gt;12. To Break AES in the Field, You Never Touch AES&lt;/h2&gt;
&lt;p&gt;Return to the paradox we opened with, now resolved. The best attack on the full cipher is a fraction-of-a-bit shave with no practical impact [@biclique-2011] -- and yet Wi-Fi sessions were decrypted, HTTPS connections forged, and keys lifted from running servers, because every one of those breaks happened in a wrapper the cipher knows nothing about. The implementation leaked through cache timing [@bernstein-2005; @osvik-shamir-tromer-2006]. The mode&apos;s nonce contract was violated on 184 live servers, weaponizing Joux&apos;s decade-old forbidden attack into forgery [@nonce-disrespecting-2016; @joux-2006]. The protocol rewound its nonce when a replayed handshake reinstalled a key [@krack-2017]. Three layers, three field breaks, and the 128-bit block math untouched in all three.&lt;/p&gt;
&lt;p&gt;And every fix changed how AES is &lt;em&gt;used&lt;/em&gt;, never AES: constant-time code and AES-NI at the implementation, misuse-resistant AEAD and derived nonces at the mode, patched handshakes and WPA3 at the protocol [@kasper-schwabe-2009; @rfc-8452; @rfc-8446; @wifi-wpa3-2018]. The cipher is the fixed point; the engineering happened all around it.&lt;/p&gt;

A cipher is not a cryptosystem. When your traffic falls, do not ask whether AES broke -- ask which wrapper did: the implementation, the mode, or the protocol.
&lt;p&gt;One last honesty, because the series depends on it. The claim is &quot;almost never,&quot; not &quot;never.&quot; Scoped to AES, the split is pristine -- the block math never fell in deployment. But some deployed primitives genuinely broke as &lt;em&gt;math&lt;/em&gt;: DES&apos;s 56-bit key, RC4&apos;s keystream biases [@alfardan-2013], and the &lt;a href=&quot;https://paragmali.com/blog/the-fingerprint-two-files-shared-a-field-guide-to-cryptograp/&quot; rel=&quot;noopener&quot;&gt;MD5 and SHA-1 collisions&lt;/a&gt; [@shattered-2017]. AES has not joined them, and naming the cases where cryptanalysis won is what keeps the thesis honest rather than triumphant.&lt;/p&gt;
&lt;p&gt;The cipher was never the weak link -- and no bigger key would have saved a single one of these systems. That is why this is Part 1 of a series about how things break &lt;em&gt;in real life&lt;/em&gt;, not a chapter on block-cipher cryptanalysis. The companion piece, &lt;em&gt;How AES Would Break&lt;/em&gt;, takes up the other question: what it would take to move the block itself. This one answered the question that actually decrypts traffic. It was never the cipher. It was the wrapper, every time.&lt;/p&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;how-aes-breaks-in-real-life&quot; keyTerms={[
  { term: &quot;Block cipher vs. mode of operation&quot;, definition: &quot;AES is a keyed permutation on one 16-byte block; a mode (CTR, GCM, CCM) chains it across a whole message and turns it into a cryptosystem.&quot; },
  { term: &quot;Nonce / IV&quot;, definition: &quot;A number used once. Counter-based modes require the (key, nonce) pair to be unique per encryption, or the keystream repeats.&quot; },
  { term: &quot;AEAD&quot;, definition: &quot;Authenticated Encryption with Associated Data: confidentiality and integrity together, with headers authenticated but not encrypted. GCM and CCM are AEAD modes.&quot; },
  { term: &quot;Keystream reuse&quot;, definition: &quot;Identical (key, nonce) yields identical keystream, so the XOR of two ciphertexts equals the XOR of their plaintexts. The key is never touched.&quot; },
  { term: &quot;T-table&quot;, definition: &quot;Precomputed lookup tables that fold an AES round into a few reads. A speed optimization whose secret-dependent indices leak through the cache.&quot; },
  { term: &quot;Cache-timing attack&quot;, definition: &quot;Recovering a secret from the timing or cache footprint of data-dependent memory access, not from the algorithm output.&quot; },
  { term: &quot;GHASH subkey H&quot;, definition: &quot;GCM&apos;s authentication secret, the encryption of an all-zero block under the key. A repeated nonce turns tag differences into equations that reveal it.&quot; },
  { term: &quot;Key reinstallation&quot;, definition: &quot;Installing an already-in-use key, which rewinds its nonce or packet-number counter and forces keystream reuse. The mechanism KRACK exploits.&quot; },
  { term: &quot;MRAE&quot;, definition: &quot;Nonce-misuse-resistant authenticated encryption, such as AES-GCM-SIV, where a repeated nonce leaks only message equality, never the subkey.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>cryptography</category><category>aes</category><category>aes-gcm</category><category>nonce-reuse</category><category>krack</category><category>side-channel-attack</category><category>authenticated-encryption</category><category>tls</category><author>noreply@paragmali.com (Parag Mali)</author></item><item><title>The Fortress and the Afterthought: How AES Would Break at Its Key Schedule</title><link>https://paragmali.com/blog/the-fortress-and-the-afterthought-how-aes-would-break-at-its/</link><guid isPermaLink="true">https://paragmali.com/blog/the-fortress-and-the-afterthought-how-aes-would-break-at-its/</guid><description>AES is not broken -- but if it ever were, the crack would start at its linear key schedule, not its celebrated round function. A structural cryptanalysis tour.</description><pubDate>Fri, 17 Jul 2026 00:00:00 GMT</pubDate><content:encoded>
**AES is not broken -- but if it ever were, the crack would start at its key schedule, not its celebrated round function.** Twenty-five years of single-key cryptanalysis have plateaued near 7 of AES-128&apos;s 10 rounds, which is the wide-trail round function working exactly as designed. The only attacks that reach all rounds faster than brute force either target the linear key schedule directly (related-key attacks: full AES-256 at $2^{99.5}$, full AES-192 at $2^{176}$) or lean on its slow diffusion (the biclique attack: $2^{126.1}$ / $2^{189.7}$ / $2^{254.4}$, a meet-in-the-middle acceleration of brute force, not a pure key-schedule break). The security margin is a living, quantitative measure -- narrow in *rounds reached* under related keys, astronomically wide in *complexity* everywhere -- and the key schedule is where it is thinnest.
&lt;h2&gt;1. The Cipher That Guards the Internet&lt;/h2&gt;
&lt;p&gt;Every time you open a bank app, unlock a laptop, or load a padlocked website, you are trusting AES -- and in twenty-five years of public assault, no one has come close to breaking it in the way that would matter. It underpins TLS sessions [@rfc8446-tls13], the &lt;a href=&quot;https://paragmali.com/blog/bitlocker-on-windows-architecture-attacks-and-the-limits-of-/&quot; rel=&quot;noopener&quot;&gt;full-disk encryption&lt;/a&gt; on laptops and phones, secure messaging, and the tunnels inside most VPNs. So this article does not ask whether AES is broken. It isn&apos;t. It asks a sharper, more honest question: &lt;em&gt;if&lt;/em&gt; it ever broke, where would the very first crack appear -- and the answer is not the part everyone admires.&lt;/p&gt;
&lt;p&gt;The Advanced Encryption Standard was chosen in an open, international contest run by the U.S. National Institute of Standards and Technology between 1997 and 2001, precisely so the world&apos;s cryptanalysts could attack the candidates before one became the standard [@nist-aes-dev]. The winner, Rijndael, has since absorbed a quarter-century of that attention. Textbooks celebrate two of its parts above all: the S-box, a slice of finite-field algebra, and MixColumns, a diffusion layer with a provable mixing guarantee. If you asked most engineers where a future break might begin, they would point at that famous mathematics.&lt;/p&gt;
&lt;p&gt;They would be pointing at the wrong place. The strongest results against full-round AES do not touch the S-box or MixColumns at all. They exploit the humblest component in the design -- the &lt;strong&gt;key schedule&lt;/strong&gt;, the little routine that stretches your 128-, 192-, or 256-bit key into the sequence of round keys the cipher actually uses. It is fast, simple, and almost entirely linear, and it is exactly where every sub-brute-force full-round result lives or leans.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The AES round function is the most-analyzed, most-trusted primitive in symmetric cryptography, and it has held. The key schedule is its least-designed, most-linear component. If AES ever falls, the accumulated evidence says the first crack starts there -- not at the celebrated mathematics, but at the afterthought bolted beside it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That gap between &quot;the best attack we have&quot; and &quot;trying every key&quot; has a name, and it is the ruler this entire article uses.&lt;/p&gt;

The security margin of a cipher is the distance between the best known attack and brute force -- measured two ways at once: how many of the cipher&apos;s rounds an attack can reach out of the total, and how far below the $2^{n}$ cost of exhaustive key search the best full-cipher attack sits. A wide margin means attacks fall far short; a thin margin means they are creeping close. It is a living, quantitative number, not a binary &quot;broken or safe.&quot;
&lt;p&gt;One boundary before we start. This is a structural story -- about the mathematics of the algorithm itself. The attacks that actually steal data in the real world -- &lt;a href=&quot;https://paragmali.com/blog/correct-constant-time-and-still-owned-a-field-guide-to-side-/&quot; rel=&quot;noopener&quot;&gt;cache-timing side channels&lt;/a&gt;, fault injection, repeated GCM nonces, &lt;a href=&quot;https://paragmali.com/blog/they-read-your-plaintext-without-breaking-your-cipher-a-fiel/&quot; rel=&quot;noopener&quot;&gt;padding oracles&lt;/a&gt;, key-reinstallation attacks like KRACK -- never touch the cipher&apos;s math at all. Those belong to this article&apos;s empirical sibling; here, we stay inside the equations.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Everything below analyzes cryptanalysis of AES&apos;s own mathematics: the round function and the key schedule. Side channels, fault and power attacks, implementation bugs, weak random number generators, and protocol or mode misuse are deliberately out of scope, named only to mark the edge. They are the subject of the sibling article in the companion series &lt;em&gt;How It Breaks in Real Life&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To see why the key schedule is the suspect, you first have to see what the designers built -- and what they admitted they left cheap.&lt;/p&gt;
&lt;h2&gt;2. A Cipher Designed Against Its Own Attack&lt;/h2&gt;
&lt;p&gt;By the late 1990s the old standard was dying in public. In 1998 the Electronic Frontier Foundation built a purpose-made machine called Deep Crack and brute-forced a DES key in a matter of days, proving a 56-bit key was no longer enough [@eff-des-cracker].DES had been the U.S. standard since 1977 [@eff-des-cracker]. Deep Crack&apos;s public key recovery in 1998 was the exclamation point on years of warnings, and it set the clock ticking on the AES competition.&lt;/p&gt;
&lt;p&gt;NIST&apos;s response was radical for a spy-adjacent agency: instead of designing a replacement behind closed doors, it announced an open, international contest and invited the world to break the candidates first [@nist-aes-dev]. Fifteen submissions were cut to five finalists -- MARS, RC6, Rijndael, Serpent, and Twofish -- and in October 2000 NIST named the Belgian design Rijndael the winner [@nist-round1] [@nist-press-2000].&lt;/p&gt;
&lt;p&gt;The cipher is &lt;em&gt;Rijndael&lt;/em&gt;, designed by Joan Daemen and Vincent Rijmen (the name blends theirs). &lt;em&gt;AES&lt;/em&gt; is the specific profile NIST standardized: Rijndael restricted to a 128-bit block with 128-, 192-, or 256-bit keys. Cryptanalysts often say &quot;Rijndael&quot; for the general cipher and &quot;AES&quot; for the standard.&lt;/p&gt;
&lt;p&gt;Here is the part of the story that plants this article&apos;s thesis. Daemen and Rijmen did not come to the contest cold. In 1997 they had co-designed an earlier cipher, Square, and -- unusually -- had published the strongest attack against it themselves: the &lt;strong&gt;Square attack&lt;/strong&gt;, a structural technique that tracks a carefully chosen set of inputs through the cipher&apos;s byte operations [@square-fse97]. They arrived at the AES competition already knowing the best way to attack their own architecture, and they engineered Rijndael&apos;s round function specifically to resist it.&lt;/p&gt;
&lt;p&gt;The tool they used was the wide-trail strategy, and it is the reason the round function has held for twenty-five years.&lt;/p&gt;

The wide-trail strategy is a design method that makes differential and linear attack paths (&quot;trails&quot;) provably improbable by guaranteeing many active S-boxes. In AES, MixColumns has a *branch number* of 5, which forces any two consecutive rounds to activate at least 5 of the byte substitutions. Over four rounds this compounds to a provable minimum of 25 active S-boxes -- and since each S-box caps an attacker&apos;s differential probability at $2^{-6}$, no useful high-probability trail can stretch across the cipher [@design-rijndael].
&lt;p&gt;The key schedule got the opposite treatment. Where the round function was engineered against a known attack with a provable bound, the key expansion was designed for speed and simplicity: enough structure to break symmetry between rounds and eliminate equivalent keys, and no more. It is built almost entirely from XOR and word rotation, with only an occasional column of S-box nonlinearity to break symmetry. The designers concentrated their genius on the round function and, by their own account, left the key schedule cheap. Twenty years later, peer-reviewed work put the consequence bluntly.&lt;/p&gt;

&quot;The key schedule is arguably the weakest part of the AES.&quot; -- Gaëtan Leurent and Clara Pernot, EUROCRYPT 2021 [@leurent-pernot-eurocrypt21]
&lt;p&gt;That asymmetry -- a fortress round function bolted to a lightly-built key schedule -- is the seed of everything that follows. The competition worked exactly as intended: Rijndael was chosen after the community failed to break it and the round function proved resilient [@nist-rijndael-report]. But &quot;resilient round function&quot; and &quot;no weak spot anywhere&quot; are different claims, and the next two decades of attacks would find the difference.&lt;/p&gt;
&lt;p&gt;The whole arc, from the contest to the full-round results, fits on one timeline.&lt;/p&gt;

timeline
    title The structural cryptanalysis of AES, 1997 to 2021
    1997 : Square cipher and the Square attack, Rijndael&apos;s ancestor
    2000 : Rijndael wins, round-function attacks reach 6 to 7 rounds
    2001 : FIPS 197 standardizes AES
    2008 : Single-key meet-in-the-middle line begins, still short of full rounds
    2009 : Related-key attacks reach full AES-192 and AES-256
    2011 : Biclique, the only single-key full-round result
    2021 : New key-schedule structure found after 20 years
&lt;p&gt;The designers told us where they concentrated their effort, and where they did not. To understand why that choice matters, open the machine up and look at the four operations inside.&lt;/p&gt;
&lt;h2&gt;3. Where the Strength Is, and Where It Isn&apos;t&lt;/h2&gt;
&lt;p&gt;AES is four operations repeated ten to fourteen times. Three of them are among the most-analyzed primitives in cryptography. The fourth -- the one that stretches your key into round keys -- is the one nobody fortified.&lt;/p&gt;
&lt;p&gt;Each round of AES transforms a 4-by-4 grid of 16 bytes through the same four steps [@fips197]:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SubBytes&lt;/strong&gt; replaces every byte using the S-box, the cipher&apos;s only source of nonlinearity in the data path.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ShiftRows&lt;/strong&gt; rotates the rows of the grid by different offsets, spreading bytes across columns.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MixColumns&lt;/strong&gt; mixes each column through a fixed matrix so that one changed input byte disturbs all four output bytes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AddRoundKey&lt;/strong&gt; XORs in the round key for that round.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;AES-128 runs 10 rounds, AES-192 runs 12, and AES-256 runs 14. The count grows with the key because a longer key means a longer key schedule and more round keys to derive.The original Rijndael also permitted 192- and 256-bit blocks, but AES fixes the block at 128 bits and varies only the key length. Throughout this article, &quot;AES&quot; means that fixed-block profile.&lt;/p&gt;

flowchart TD
    A[&quot;State: 16 bytes in a 4x4 grid&quot;] --&amp;gt; B[&quot;SubBytes: S-box on every byte&quot;]
    B --&amp;gt; C[&quot;ShiftRows: rotate each row&quot;]
    C --&amp;gt; D[&quot;MixColumns: mix each column, branch number 5&quot;]
    D --&amp;gt; E[&quot;AddRoundKey: XOR the round key&quot;]
    E --&amp;gt; F[&quot;Next round&quot;]
&lt;p&gt;Two of these steps are why AES is trusted. The S-box is not an arbitrary lookup table; it is algebra.&lt;/p&gt;

The AES S-box maps each byte to its multiplicative inverse in the finite field $GF(2^8)$ (with zero mapped to zero), followed by a fixed affine transformation over the bits. The inversion supplies strong nonlinearity -- it caps the probability of any input-to-output difference at $2^{-6}$ -- while the affine step destroys the clean algebraic form that a pure inversion would leave behind, blunting algebraic attacks [@fips197] [@design-rijndael].
&lt;p&gt;MixColumns is the diffusion partner. Its matrix is chosen so that changing a single input byte changes all four output bytes of the column.This is the maximum-distance-separable (MDS) property, summarized by a &lt;em&gt;branch number&lt;/em&gt; of 5: the number of nonzero input bytes plus nonzero output bytes of MixColumns is always at least 5. It is what lets four rounds guarantee 25 active S-boxes, and it is unusually strong diffusion for such a cheap operation. Together, SubBytes and MixColumns make the round function mix so thoroughly that after just a couple of rounds every output bit depends on every input bit in a way no attacker has been able to shortcut. This is the fortress.&lt;/p&gt;
&lt;p&gt;Now meet the protagonist. The key schedule -- the routine FIPS 197 calls key expansion -- is what turns your master key into the round keys that AddRoundKey consumes.&lt;/p&gt;

The AES key schedule expands the master key into one round key per round (plus one for the initial whitening). It processes the key in 32-bit words: most new words are simply the XOR of two earlier words, and once per group of words it applies RotWord (a byte rotation), SubWord (the S-box on four bytes), and a round constant Rcon to break symmetry. AES-256 adds one extra SubWord column at the midpoint of each eight-word group -- two nonlinear columns per group rather than one -- but even then the expansion is overwhelmingly linear, XOR and rotation [@fips197].

flowchart LR
    W0[&quot;Word w0 to w3: the master key&quot;] --&amp;gt; N[&quot;Once per group: RotWord, then SubWord, then XOR Rcon&quot;]
    N --&amp;gt; X[&quot;XOR into the next word&quot;]
    W0 --&amp;gt; X
    X --&amp;gt; W1[&quot;Next four words: round key 1&quot;]
    W1 --&amp;gt; Y[&quot;Mostly plain XOR of earlier words&quot;]
    Y --&amp;gt; W2[&quot;Round key 2, and so on&quot;]
&lt;p&gt;Make the contrast visceral. The round function stirs the state with a nonlinear S-box on all 16 bytes and a strong diffusion layer, every single round. The key schedule stirs its state with XOR and rotation, and touches the S-box only four bytes at a time, once or twice per group of words.A 32-bit word is one column of four bytes, and SubWord runs the S-box on all four at once -- so one word and one S-box column mean the same thing here. One mixes with a sledgehammer; the other barely swirls.&lt;/p&gt;
&lt;p&gt;That gap has a consequence worth holding onto: because the expansion is mostly linear, a difference injected into the key propagates through it &lt;em&gt;predictably&lt;/em&gt;. If you know the difference going in, you can compute much of the difference coming out -- no probabilities required. Remember that when we reach the related-key attacks.&lt;/p&gt;
&lt;p&gt;You can watch the slow, predictable diffusion yourself. The demo below injects a one-byte difference into a master key and follows it through the linear backbone of the expansion. Notice that the earliest words stay untouched, and that once the difference appears it propagates in a fixed, fully determined pattern rather than exploding into randomness the way the round function would scramble it.&lt;/p&gt;
&lt;p&gt;{`
// A deliberately simplified model of the AES key-expansion BACKBONE:
// new word = previous word XOR the word four positions back.
// (The real schedule adds one S-box column per group; we skip that
//  nonlinear part to expose why differences travel predictably.)
const Nk = 4;          // 128-bit key = 4 words
const totalWords = 44; // 11 round keys of 4 words each&lt;/p&gt;
&lt;p&gt;function expandBackbone(seed) {
  const w = seed.slice();
  for (let i = Nk; i &amp;lt; totalWords; i++) {
    // linear step only: XOR of two earlier words
    w[i] = w[i - 1] ^ w[i - 4];
  }
  return w;
}&lt;/p&gt;
&lt;p&gt;// Two master keys that differ in exactly ONE word (a single injected difference).
const keyA = [0x00000000, 0x11111111, 0x22222222, 0x33333333];
const keyB = [0x00000000, 0x11111111, 0x22222222, 0x33333333 ^ 0x01000000];&lt;/p&gt;
&lt;p&gt;const a = expandBackbone(keyA);
const b = expandBackbone(keyB);&lt;/p&gt;
&lt;p&gt;let firstTouched = -1, touchedCount = 0;
for (let i = 0; i &amp;lt; a.length; i++) {
  const diff = a[i] ^ b[i];
  if (diff !== 0) {
    touchedCount++;
    if (firstTouched === -1) firstTouched = i;
  }
}
console.log(&quot;Injected a 1-word difference into word 3.&quot;);
console.log(&quot;First word carrying the difference: w&quot; + firstTouched);
console.log(&quot;Words disturbed out of &quot; + totalWords + &quot;: &quot; + touchedCount);
console.log(&quot;The difference is fully determined -- no guessing, no probability.&quot;);
console.log(&quot;A real attacker exploits exactly this predictability.&quot;);
`}&lt;/p&gt;
&lt;p&gt;A fortress bolted to an afterthought. For years, no attacker seemed to notice the afterthought -- they all threw themselves at the fortress. Here is what happened when they did.&lt;/p&gt;
&lt;h2&gt;4. The First Cracks, at Four to Seven Rounds&lt;/h2&gt;
&lt;p&gt;The moment Rijndael became a finalist, the world&apos;s cryptanalysts opened fire. The first attacks worked -- and then hit a wall almost immediately, at a height that has barely moved since.&lt;/p&gt;

A reduced-round attack targets a version of the cipher with fewer than the full number of rounds -- say 6-round AES-128 instead of 10-round. Cryptanalysts study reduced-round variants because they are the natural way to measure the security margin: the highest round count you can break, compared with the full count, is a direct reading of how much cushion remains [@lu-idc-indocrypt08].
&lt;p&gt;The opening salvo was the designers&apos; own weapon, turned up to full power. Integral cryptanalysis -- the generalized Square attack -- does not chase a probabilistic pattern the way classical differential attacks do. It exploits a property that holds with certainty.&lt;/p&gt;

An integral attack feeds the cipher a structured set of plaintexts -- a &quot;Lambda-set&quot; of 256 texts in which one byte takes all 256 possible values and the rest are held constant -- and tracks the whole set at once. Because SubBytes is a bijection, an all-values byte stays all-values; the load-bearing invariant is that after a few rounds the XOR (over $GF(2^8)$) of all 256 intermediate states is provably zero, or &quot;balanced.&quot; A wrong key guess in the final round breaks the balance, so the attacker keeps only guesses that preserve it [@square-fse97].
&lt;p&gt;That balanced sum gives a 3-round distinguisher, which the Square attack extends by wrapping key-guessing rounds around it to break up to 6 rounds of AES at about $2^{72}$ work [@square-fse97]. The invariant is simple enough that a student can implement it in a few lines.&lt;/p&gt;
&lt;p&gt;{`
// A Lambda-set&apos;s active byte takes all 256 values exactly once.
// Claim: after any bijective S-box, the XOR of all outputs is still 0.
// This is the &quot;balance&quot; property the Square attack sieves keys with.&lt;/p&gt;
&lt;p&gt;// Build a toy S-box: a random permutation of 0..255 (a bijection like AES&apos;s).
const sbox = Array.from({length: 256}, (_, i) =&amp;gt; i);
for (let i = 255; i &amp;gt; 0; i--) {
  const j = Math.floor(Math.random() * (i + 1));
  [sbox[i], sbox[j]] = [sbox[j], sbox[i]];
}&lt;/p&gt;
&lt;p&gt;// Active byte: all 256 values. XOR them before and after the S-box.
let xorInput = 0, xorOutput = 0;
for (let v = 0; v &amp;lt; 256; v++) {
  xorInput ^= v;          // XOR of 0..255 is 0 by construction
  xorOutput ^= sbox[v];   // a bijection just permutes those values
}
console.log(&quot;XOR of the active byte (input):  &quot; + xorInput);   // 0
console.log(&quot;XOR after the bijective S-box:   &quot; + xorOutput);  // still 0
console.log(xorOutput === 0 ? &quot;Balanced: the distinguisher holds.&quot; :
                              &quot;Broken balance (won&apos;t happen for a bijection).&quot;);
`}&lt;/p&gt;
&lt;p&gt;The Square attack&apos;s real bottleneck was not the distinguisher but the cost of the final key-guessing summation. In 2000, Niels Ferguson, John Kelsey, David Wagner and colleagues fixed exactly that with the &lt;strong&gt;partial-sums&lt;/strong&gt; technique, reorganizing the summation to reuse intermediate results. It cut the 6-round work to roughly $2^{44}$ and bought one more round, reaching 7-round AES-128 at about $2^{120}$ using almost the entire codebook [@partial-sums-fse00]. The same year, Henri Gilbert and Marine Minier found a different route to the same height: a collision attack on 7 rounds of Rijndael that exploited collisions between partial functions inside the cipher [@gilbert-minier-aes3].&lt;/p&gt;
&lt;p&gt;A third family arrived in parallel and turned differential logic inside out. Impossible-differential cryptanalysis of Rijndael originated with Eli Biham and Nathan Keller in an unpublished report at the Third AES Candidate Conference in 2000.That original Biham-Keller report was never formally published and is not indexed in the usual bibliographic databases, so this article attributes only the &lt;em&gt;origin&lt;/em&gt; of the technique to it and takes every concrete figure from the peer-reviewed successors below. Precision about what is and is not on the record is part of honest cryptanalysis. Instead of a high-probability pattern, it uses one that occurs with probability &lt;em&gt;exactly zero&lt;/em&gt;: AES has a 4-round differential that can never happen, so any key guess that would produce it is provably wrong and can be sieved out.&lt;/p&gt;
&lt;p&gt;Jiqiang Lu, Orr Dunkelman, Nathan Keller and Jongsung Kim formalized and optimized the technique in 2008, as did Behnam Bahrak and Mohammad Reza Aref independently. It gave the best impossible-differential attacks of its era: 7 rounds of AES-128 and AES-192, and 8 rounds of AES-256 [@lu-idc-indocrypt08] [@bahrak-aref-iet08].&lt;/p&gt;
&lt;p&gt;Step back and the pattern is unmistakable. Integral, partial sums, collision, impossible differential -- four different mechanisms, and every one of them targets the round function, and every one of them stalls far below the full 10 rounds. Around seven rounds, they all hit the same ceiling. Some of these are &lt;em&gt;distinguishers&lt;/em&gt; (they tell real AES apart from a random permutation) and some are &lt;em&gt;key recoveries&lt;/em&gt; (they actually extract key bytes), but the reach is the same either way.&lt;/p&gt;
&lt;p&gt;Different attacks, one shared ceiling: about seven rounds. Was that a coincidence -- or was something stopping them?&lt;/p&gt;
&lt;h2&gt;5. Climbing the Round Ladder&lt;/h2&gt;
&lt;p&gt;For fifteen years the single-key attacks improved -- new mechanisms, cleverer bookkeeping, automated search. And still they stalled around seven rounds. The reason they stalled is the whole point of this article.&lt;/p&gt;
&lt;p&gt;The next mechanism traded probability for memory. If the distinguishers of Section 4 were too short, why not &lt;em&gt;store&lt;/em&gt; a description of several middle rounds rather than propagate a pattern through them?&lt;/p&gt;

A meet-in-the-middle attack splits the cipher into two halves and works from both ends toward the middle. The attacker precomputes every possible value of some property in the middle, then, for each key guess, computes the same property from the data and checks for a match. It trades memory for a way around the probability barrier that limits differential and integral attacks -- you look the answer up instead of hoping it appears [@demirci-selcuk-fse08].
&lt;p&gt;In 2008, Hüseyin Demirci and Ali Aydın Selçuk built the first MITM attack on AES, reaching 8 rounds of AES-256 -- past the seven-round wall. But there was a catch that makes the plateau vivid: the precomputed table held on the order of $2^{206}$ entries [@demirci-selcuk-fse08]. That is not a time cost you wait out; it is more storage than exists on Earth. The attack was structurally valid and physically impossible at once -- a memory catastrophe.&lt;/p&gt;
&lt;p&gt;Two years later, Orr Dunkelman, Nathan Keller and Adi Shamir rescued it. Their differential-enumeration technique restricted the precomputed table to only the middle states actually reachable from a chosen truncated differential, and a compact &quot;multiset&quot; representation shrank it further -- collapsing the impossible $2^{206}$ down toward the attack&apos;s own time complexity and turning a physical impossibility into a coherent shortcut for 8-round AES-192 and AES-256 [@dks-asiacrypt10].&lt;/p&gt;
&lt;p&gt;Then, in 2013, Patrick Derbez, Pierre-Alain Fouque and Jérémy Jean treated the search for the best MITM parameters as a computer-search problem, automating the exploration to squeeze out the best single-key numbers anyone has found: 7-round AES-128 with data, time and memory all under $2^{100}$; 8-round AES-192 and AES-256; and 9-round AES-256 [@dfj-eurocrypt13].&lt;/p&gt;
&lt;p&gt;Line the generations up and the shape of the wall becomes concrete.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Generation&lt;/th&gt;
&lt;th&gt;Year&lt;/th&gt;
&lt;th&gt;Rounds reached&lt;/th&gt;
&lt;th&gt;The wall it hit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Integral / Square&lt;/td&gt;
&lt;td&gt;1997-2000&lt;/td&gt;
&lt;td&gt;up to 6&lt;/td&gt;
&lt;td&gt;Cost of the final key-guessing summation [@square-fse97]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Partial sums&lt;/td&gt;
&lt;td&gt;2000&lt;/td&gt;
&lt;td&gt;7 (AES-128)&lt;/td&gt;
&lt;td&gt;Distinguisher still only about 4 rounds long [@partial-sums-fse00]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Impossible differential&lt;/td&gt;
&lt;td&gt;2000-2008&lt;/td&gt;
&lt;td&gt;7-8&lt;/td&gt;
&lt;td&gt;The impossible differential is fixed at 4 rounds [@lu-idc-indocrypt08]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Demirci-Selçuk MITM&lt;/td&gt;
&lt;td&gt;2008&lt;/td&gt;
&lt;td&gt;8 (AES-256)&lt;/td&gt;
&lt;td&gt;A physically impossible $2^{206}$-entry table [@demirci-selcuk-fse08]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Differential-enumeration MITM&lt;/td&gt;
&lt;td&gt;2010&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Memory tamed, but still single-key, still 8 rounds [@dks-asiacrypt10]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Automated MITM&lt;/td&gt;
&lt;td&gt;2013&lt;/td&gt;
&lt;td&gt;7 / 8 / 9&lt;/td&gt;
&lt;td&gt;No long single-key characteristic exists to extend [@dfj-eurocrypt13]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Fifteen years, five mechanisms, and the frontier climbs from six rounds to nine and stops. It is tempting to read that trend line as a slow slide toward a break -- seven rounds today, ten rounds soon. That reading is exactly backwards.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The single-key plateau near seven rounds is not the attackers failing. It is the wide-trail round function succeeding. By provable design there is no long, high-probability characteristic to extend across the round function, so every single-key attack must bolt a few key-guessing rounds onto a short distinguisher -- and runs out of room. The plateau is evidence of strength, and it is precisely what forces every full-round result off the round function and onto the key schedule.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Not every idea in this era survived. The most famous casualty was an algebraic dream.&lt;/p&gt;

In 2002, Nicolas Courtois and Josef Pieprzyk proposed writing AES as a giant system of quadratic equations and solving it with a method they called XSL; a later GF(256) adaptation by Sean Murphy and Matthew Robshaw put the suggested attacks in the range of $2^{87}$ to $2^{100}$ [@xsl-eprint02]. It caused a stir -- an attack that ignored rounds entirely. But the method was heuristic, and its own authors admitted its complexity was &quot;very difficult to evaluate.&quot; In 2005, Carlos Cid and Gaëtan Leurent analyzed XSL carefully and showed it did not work as claimed [@cid-leurent-xsl05]. The S-box&apos;s affine layer and field structure are part of why algebraic attacks have never dented AES.
&lt;p&gt;If the round function cannot be beaten in the ordinary attack model, there are exactly two ways forward, and both leave the round function untouched. The first is to change the rules of engagement.&lt;/p&gt;

In the related-key model, the attacker cannot choose the secret key but *can* obtain encryptions under several keys whose differences it knows -- for example, the real key and the real key XORed with a chosen constant. It is a stronger, more demanding model than the standard single-key setting, and well-designed protocols never grant it. But it is a legitimate measure of a cipher&apos;s structural health, and it is the setting in which AES&apos;s key schedule first cracked [@bk-asiacrypt09].
&lt;p&gt;The escape route through that model runs directly through the key schedule&apos;s linearity: because the expansion is mostly XOR, a difference injected into the key travels through it predictably and can be arranged to &lt;em&gt;cancel&lt;/em&gt; a difference in the data over a few rounds -- a &quot;local collision&quot; that, chained, lets a usable characteristic span the entire cipher for the first time. The second escape gives up on beating brute force outright and instead &lt;em&gt;accelerates&lt;/em&gt; it, with a structure called a biclique that leans on how slowly the key schedule diffuses. We will need one more idea for both roads.&lt;/p&gt;

A distinguisher is an attack that tells the real cipher apart from an idealized random permutation, without necessarily recovering the key. It is weaker than a key recovery, but it still counts as a structural break: an ideal cipher should be indistinguishable from random, so any efficient distinguisher proves the cipher deviates from the ideal. Distinguishers often precede full key-recovery attacks by years [@bkn-crypto09].
&lt;p&gt;Both escapes were walked between 2009 and 2011. Neither one beat the round function. Both went for the key schedule.&lt;/p&gt;

flowchart TD
    S[&quot;AES cryptanalysis&quot;] --&amp;gt; A[&quot;Single-key round-function line&quot;]
    S --&amp;gt; B[&quot;Full-round results&quot;]
    A --&amp;gt; A1[&quot;Integral, partial sums, impossible differential&quot;]
    A1 --&amp;gt; A2[&quot;MITM and automated MITM&quot;]
    A2 --&amp;gt; A3[&quot;Plateau near 7 to 9 rounds: the round function holding&quot;]
    B --&amp;gt; B1[&quot;Related-key: local collisions in the linear key schedule&quot;]
    B --&amp;gt; B2[&quot;Biclique: leans on slow key-schedule diffusion&quot;]
    A3 --&amp;gt; K[&quot;The key schedule&quot;]
    B1 --&amp;gt; K
    B2 --&amp;gt; K
&lt;h2&gt;6. Two Ways Past the Full Cipher&lt;/h2&gt;
&lt;p&gt;In 2009 and 2011, three papers did what nobody had managed in a decade: they reached all the way through AES faster than brute force. Neither road beat the round function. Both went for the key schedule -- one breaking it head-on, one leaning on it.&lt;/p&gt;
&lt;h3&gt;Road one: related-key attacks break the key schedule directly&lt;/h3&gt;
&lt;p&gt;The first road exploits the linearity you watched in Section 3. Because AES-256&apos;s key schedule is so close to linear, a difference injected into the key propagates through it predictably, and it can be arranged to cancel a difference that the round keys introduce into the data.&lt;/p&gt;

A related-key attack queries the cipher under keys whose differences the attacker knows. Its key tool against AES is the *local collision*: a difference introduced into the state by one round key is cancelled by a difference the linear key schedule carries into the very next round key, so the two differences annihilate over a short span. Because the schedule is mostly XOR, these cancellations are cheap to arrange and can be chained into a differential covering the whole cipher [@bk-asiacrypt09].
&lt;p&gt;In 2009, Alex Biryukov, Dmitry Khovratovich and Ivica Nikolić delivered the first full-round result of any kind. They defined a &lt;em&gt;differential q-multicollision&lt;/em&gt; and showed AES-256 admits them in about $q \cdot 2^{67}$ operations, against a provable lower bound of roughly $q \cdot 2^{((q-1)/(q+1)) \cdot 128}$ for an ideal cipher -- a gap wide enough to prove, in their words, that AES-256 &quot;can not model an ideal cipher&quot; [@bkn-crypto09].&lt;/p&gt;
&lt;p&gt;From that they built the first attack on all 14 rounds: a related-key distinguisher working for 1 out of every $2^{35}$ keys using $2^{120}$ data, convertible to a key recovery at $2^{131}$ time and $2^{65}$ memory [@bkn-crypto09]. It was a weak-key-class result -- powerful, but not yet a universal key recovery.&lt;/p&gt;
&lt;p&gt;Months later, Biryukov and Khovratovich closed that gap and extended it. Combining local collisions with the boomerang attack and a trick called boomerang switching -- which buys free middle rounds by reconciling two short differentials where they meet -- they produced a key recovery on the full AES-256 that works for &lt;em&gt;all&lt;/em&gt; keys, at $2^{99.5}$ time and data, using four related keys [@bk-asiacrypt09]. The same machinery gave the first cryptanalysis of the full AES-192, at complexity $2^{176}$ [@bk-asiacrypt09].The paper notes the AES-256 figure improves to $2^{99}$. Two precision points that matter: the attack uses &lt;em&gt;four&lt;/em&gt; related keys, and the $2^{99.5}$ (or $2^{99}$) number belongs to AES-256 alone. The full AES-192 result is $2^{176}$ -- never attach the AES-256 figure to AES-192.&lt;/p&gt;
&lt;p&gt;Sit with what that means, because it inverts a near-universal assumption. AES-256 has more rounds and a longer key than AES-128, and everyone treats it as the stronger choice. Yet under related keys it is &lt;em&gt;weaker&lt;/em&gt;: its longer key schedule is more linear structure to exploit, and no comparable all-keys full-round attack exists against AES-128. This is the thesis in its most literal form -- more key material bought more exploitable structure, and the longer key schedule breaks worse.&lt;/p&gt;

flowchart TD
    A[&quot;Attacker injects a known key difference&quot;] --&amp;gt; B[&quot;Linear key schedule propagates it predictably&quot;]
    B --&amp;gt; C[&quot;Round-key difference cancels the state difference: local collision&quot;]
    C --&amp;gt; D[&quot;Chain local collisions across rounds&quot;]
    D --&amp;gt; E[&quot;Boomerang switching joins two short trails, buys free middle rounds&quot;]
    E --&amp;gt; F[&quot;Characteristic spans full AES-192 and AES-256&quot;]
&lt;h3&gt;Road two: biclique leans on the key schedule&apos;s slow diffusion&lt;/h3&gt;
&lt;p&gt;The second road answers a different question. Related-key attacks need a strong model no protocol grants. Could &lt;em&gt;anything&lt;/em&gt; reach the full cipher in the ordinary single-key model? In 2011, Andrey Bogdanov, Dmitry Khovratovich and Christian Rechberger answered yes -- with an important asterisk.&lt;/p&gt;

A biclique is a meet-in-the-middle structure that lets an attacker test a whole group of keys at nearly the cost of testing one. By precomputing partial encryptions over a few rounds and reusing them across every key in the group, it accelerates exhaustive key search: instead of a full encryption per candidate key, each key costs only the handful of operations that actually differ. It is not a shortcut around the cipher&apos;s mathematics -- it is a faster way to try every key [@biclique-asiacrypt11].
&lt;p&gt;Applied to full AES with no related keys assumed, the biclique attack recovers keys at $2^{126.1}$ for AES-128, $2^{189.7}$ for AES-192, and $2^{254.4}$ for AES-256 [@biclique-asiacrypt11]. Those are the only single-key, full-round results faster than brute force that exist.&lt;/p&gt;
&lt;p&gt;And here is where the savings come from: between neighboring keys in a group, so few round-key and state bytes change that most of the computation can be reused -- and &lt;em&gt;that&lt;/em&gt; is a consequence of the key schedule&apos;s slow diffusion, the same sluggish mixing we watched in Section 3. Where the related-key road exploits the schedule&apos;s linearity, the biclique road exploits its slowness.&lt;/p&gt;
&lt;p&gt;But the honest framing is load-bearing, and this article treats it as non-negotiable.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The biclique attack is a meet-in-the-middle &lt;em&gt;acceleration of exhaustive key search&lt;/em&gt;, not a pure structural break of the key schedule. Its recomputation savings &lt;em&gt;depend on&lt;/em&gt; the key schedule&apos;s slow diffusion, but it does not exploit a mathematical weakness that collapses the cipher. The gain over brute force is about two bits -- a factor of roughly four. Never describe biclique as &quot;breaking&quot; the key schedule the way the related-key attacks do; it &lt;em&gt;leans on&lt;/em&gt; the schedule, and that distinction is the difference between honest analysis and hype.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The authors said as much themselves, and it is the most important sentence in the whole biclique story.&lt;/p&gt;

The biclique attacks on full AES &quot;do not threaten the practical use of AES in any way.&quot; -- Bogdanov, Khovratovich, and Rechberger, ASIACRYPT 2011 [@biclique-asiacrypt11]

flowchart TD
    A[&quot;Partition the key space into groups&quot;] --&amp;gt; B[&quot;Build a biclique over a few rounds per group&quot;]
    B --&amp;gt; C[&quot;Precompute partial encryptions once per group&quot;]
    C --&amp;gt; D[&quot;Neighboring keys differ in few bytes: slow key-schedule diffusion&quot;]
    D --&amp;gt; E[&quot;Reuse precomputation, recompute only what changed&quot;]
    E --&amp;gt; F[&quot;Each key costs less than one full encryption&quot;]
    F --&amp;gt; G[&quot;Full-round key recovery, about a factor of 4 under brute force&quot;]
&lt;p&gt;Put the two roads side by side and the article&apos;s claim stops being rhetoric.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The only two ways anyone has reached full-round AES faster than brute force both run through the key schedule. The related-key attacks break it head-on, chaining local collisions through its linearity to recover keys on full AES-192 and AES-256. The biclique attack leans on it, exploiting its slow diffusion to shave a factor of four off exhaustive search in the single-key model. The celebrated S-box and MixColumns are untouched in both. The crack starts at the part nobody fortified.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Two roads to the full cipher, both paved by the key schedule -- one breaking it, one leaning on it. So where exactly does AES stand today?&lt;/p&gt;
&lt;h2&gt;7. Where AES Stands Today&lt;/h2&gt;
&lt;p&gt;Strip away the drama and put the numbers on one table. That table is the clearest statement of where AES is strong and where it is thin.&lt;/p&gt;
&lt;p&gt;Three ceilings orient everything: brute force costs $2^{128}$, $2^{192}$, and $2^{256}$ for the three key sizes. Every result below is measured against those.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Variant&lt;/th&gt;
&lt;th&gt;Rounds&lt;/th&gt;
&lt;th&gt;Best single-key reduced-round&lt;/th&gt;
&lt;th&gt;Best single-key full-round&lt;/th&gt;
&lt;th&gt;Best related-key full-round&lt;/th&gt;
&lt;th&gt;Brute-force ceiling&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;AES-128&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;7 rounds, under $2^{100}$ [@dfj-eurocrypt13]&lt;/td&gt;
&lt;td&gt;$2^{126.1}$ [@biclique-asiacrypt11]&lt;/td&gt;
&lt;td&gt;none comparable known&lt;/td&gt;
&lt;td&gt;$2^{128}$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AES-192&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;8 rounds, $2^{172}$ [@dfj-eurocrypt13]&lt;/td&gt;
&lt;td&gt;$2^{189.7}$ [@biclique-asiacrypt11]&lt;/td&gt;
&lt;td&gt;$2^{176}$ [@bk-asiacrypt09]&lt;/td&gt;
&lt;td&gt;$2^{192}$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AES-256&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;9 rounds, $2^{203}$ [@dfj-eurocrypt13]&lt;/td&gt;
&lt;td&gt;$2^{254.4}$ [@biclique-asiacrypt11]&lt;/td&gt;
&lt;td&gt;$2^{99.5}$, improved to $2^{99}$ [@bk-asiacrypt09]&lt;/td&gt;
&lt;td&gt;$2^{256}$&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Read the columns and the whole argument snaps into focus. The single-key reduced-round column stalls at 7, 8, and 9 rounds out of 10, 12, and 14 -- and it has not moved since 2013 [@dfj-eurocrypt13]. The single-key full-round column sits about two bits under the ceiling, a factor of roughly four, courtesy of biclique [@biclique-asiacrypt11].Tao and Wu refined the biclique complexities in 2015, nudging the last digits and cutting the attack&apos;s storage requirement, but the headline numbers barely moved -- evidence that the single-key full-round margin has been essentially static for over a decade [@taowu-acisp15] [@wikipedia-aes]. The related-key column is the outlier: $2^{99}$ against a $2^{256}$ ceiling for AES-256 is an enormous complexity gap -- but only in a model real deployments deny.&lt;/p&gt;
&lt;p&gt;The frontier keeps yielding small refinements, and where they land is telling. In 2018, Achiya Bar-On, Orr Dunkelman, Nathan Keller, Eyal Ronen and Adi Shamir cut the best 5-round single-key attack from about $2^{32}$ to under $2^{22}$ -- practical enough to run -- and gave the best practical-data attacks on 7-round AES-192 [@barron-crypto18].&lt;/p&gt;
&lt;p&gt;And in 2021, Gaëtan Leurent and Clara Pernot found that the AES-128 key schedule can be split into four independent parallel computations on 32-bit chunks, up to linear transformation -- a structural fact, in their words, &quot;not described in the literature after more than 20 years&quot; of analysis [@leurent-pernot-eurocrypt21]. Twenty years on, the fresh cryptanalytic advantage still comes from the key schedule.&lt;/p&gt;
&lt;p&gt;So the margin is asymmetric. In &lt;em&gt;rounds reached&lt;/em&gt;, the related-key model gets uncomfortably close to full coverage while the single-key model plateaus a few rounds short. In &lt;em&gt;complexity&lt;/em&gt;, the numbers are astronomically wide everywhere except the related-key AES-256 corner. And even that &quot;best&quot; single-key number is not remotely a threat.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The biclique attack on AES-128 costs $2^{126.1}$ operations. That is faster than the $2^{128}$ brute-force ceiling -- and it is still roughly $10^{38}$ operations, a number with no physical meaning. If every atom-scale computer that could ever be built ran for the age of the universe, it would not make a dent. &quot;Faster than brute force&quot; is a statement about cryptographic bookkeeping, not about feasibility. AES is not close to breakable; it is close to &lt;em&gt;optimal&lt;/em&gt;, and the tiny gap that remains is a ruler, not a wound.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;One table, two full-round winners, one common thread. Line them up as competing methods and the thesis stops being a claim and becomes a pattern.&lt;/p&gt;
&lt;h2&gt;8. Single-Key, Related-Key, and the Common Thread&lt;/h2&gt;
&lt;p&gt;These attack families are not really competitors -- they optimize for different things. Put them on shared axes and you can see exactly what each one buys, what it costs, and what it leans on.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attack family&lt;/th&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Full rounds?&lt;/th&gt;
&lt;th&gt;Best complexity&lt;/th&gt;
&lt;th&gt;Threatens deployed AES?&lt;/th&gt;
&lt;th&gt;Leans on key schedule?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Biclique&lt;/td&gt;
&lt;td&gt;Single-key&lt;/td&gt;
&lt;td&gt;Yes (10/12/14)&lt;/td&gt;
&lt;td&gt;$2^{126.1}$ / $2^{189.7}$ / $2^{254.4}$ [@biclique-asiacrypt11]&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes, via slow diffusion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Related-key boomerang&lt;/td&gt;
&lt;td&gt;Related-key&lt;/td&gt;
&lt;td&gt;Yes (AES-192/256)&lt;/td&gt;
&lt;td&gt;AES-256 $2^{99}$, AES-192 $2^{176}$ [@bk-asiacrypt09]&lt;/td&gt;
&lt;td&gt;No, model denied&lt;/td&gt;
&lt;td&gt;Yes, directly, via linearity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Single-key MITM (DS to DKS to DFJ)&lt;/td&gt;
&lt;td&gt;Single-key&lt;/td&gt;
&lt;td&gt;No (7/8/9)&lt;/td&gt;
&lt;td&gt;7-round AES-128 under $2^{100}$ [@dfj-eurocrypt13]&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Indirectly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Impossible-diff / integral (incl. Bar-On)&lt;/td&gt;
&lt;td&gt;Single-key&lt;/td&gt;
&lt;td&gt;No (7 or fewer)&lt;/td&gt;
&lt;td&gt;5-round under $2^{22}$, practical [@barron-crypto18]&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Increasingly&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The two full-round rows and the two reduced-round rows tell opposite halves of the same story. The reduced-round families cannot cross the wide-trail wall no matter how cleverly they are automated or how practical their data becomes -- they top out short of the full cipher because the round function gives them nothing longer to work with.&lt;/p&gt;
&lt;p&gt;The full-round families cross it only by refusing to fight the round function at all. One changes the model to attack the key schedule&apos;s linearity; the other accepts brute-force complexity and mines the key schedule&apos;s slow diffusion for a discount. Every entry in the &quot;leans on key schedule?&quot; column is a yes or a trending-toward-yes.&lt;/p&gt;

AES-256 has more rounds and a longer key than AES-128 -- and under related keys, that longer, still-linear key schedule is exactly what makes it weaker. More key material, more structure to exploit.
&lt;p&gt;The honest caveat rides along in the table too. Biclique&apos;s &quot;yes&quot; in the last column is an &lt;em&gt;enabling&lt;/em&gt; dependence -- it needs the schedule to diffuse slowly so its precomputation can be reused -- not the structural collapse that the related-key row represents. Reading the two together is the point: the key schedule is the common thread of every full-round result, but it is threaded two different ways, and only one of them is a direct break.&lt;/p&gt;

Not every result fits the key-recovery mould. In 2007, Lars Knudsen and Vincent Rijmen introduced *known-key distinguishers*, where the key is public and the goal is merely to show the cipher behaves less randomly than an ideal permutation would [@known-key-ac07]. It sounds academic, but it broadened what counts as &quot;a break&quot; and seeded the rebound attacks that are genuinely productive against AES-based hash and compression functions -- a reminder that a cipher can be perfectly safe as an encryptor while its internals still leak structure when repurposed.
&lt;p&gt;The pattern is undeniable, but a pattern is not a proof. How close &lt;em&gt;can&lt;/em&gt; cryptanalysis get -- and could we ever prove it can get no closer?&lt;/p&gt;
&lt;h2&gt;9. How Close Can Cryptanalysis Get?&lt;/h2&gt;
&lt;p&gt;Here is the uncomfortable truth that separates cryptography from mathematics: nobody can prove AES is secure. Not &quot;has not proven it yet&quot; -- cannot, even in principle, in the way we mean it for public-key systems.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://paragmali.com/blog/rsa-is-a-trapdoor-not-a-cryptosystem-oaep-pss-and-the-25-yea/&quot; rel=&quot;noopener&quot;&gt;RSA&lt;/a&gt; and &lt;a href=&quot;https://paragmali.com/blog/nobody-broke-the-discrete-log-a-field-guide-to-diffie-hellma/&quot; rel=&quot;noopener&quot;&gt;Diffie-Hellman&lt;/a&gt; rest on the &lt;em&gt;assumed hardness&lt;/em&gt; of a specific, well-studied problem -- integer factoring, or the discrete logarithm -- that the world&apos;s mathematicians have failed to solve efficiently for decades, and some public-key schemes (Rabin, or lattice systems) provably reduce to such problems. Their security is anchored to a famous open question. Block ciphers have no such anchor.&lt;/p&gt;
&lt;p&gt;AES&apos;s security is not reducible to any problem believed hard; it rests entirely on the fact that very smart people have attacked it for twenty-five years and failed. That is strong evidence, but it is not a proof, and it means a future structural break can never be &lt;em&gt;ruled out&lt;/em&gt; -- only measured, as a margin.&lt;/p&gt;
&lt;p&gt;The nearest thing to a proof AES has is a design-level bound, and it is precisely bounded in what it covers.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The wide-trail strategy proves that any differential or linear trail across four AES rounds activates at least 25 S-boxes, capping such a trail&apos;s probability at $2^{-150}$ [@design-rijndael]. That is a real theorem -- and it is exactly why single-key differential and linear attacks fail. But it bounds only &lt;em&gt;trails through the round function&lt;/em&gt;. It says nothing about the key schedule, nothing about related-key differentials, and nothing about meet-in-the-middle accelerations like biclique. The one thing AES can almost prove is the one thing the round function already does well. The key schedule sits outside the theorem.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That gap is the article&apos;s most counterintuitive lesson. Security is not a binary a cipher passes or fails; it is a measured quantity, and the measurement keeps coming back thinnest at the key schedule. Worse for intuition: the AES-256-versus-AES-128 result shows that adding key material can &lt;em&gt;lower&lt;/em&gt; the margin rather than raise it, because a longer linear key schedule is more structure to attack. The one genuine impossibility result we do have points the same way -- Biryukov, Khovratovich and Nikolić proved AES-256 cannot instantiate an ideal cipher, using the very key-schedule structure the related-key attacks ride [@bkn-crypto09].&lt;/p&gt;
&lt;p&gt;What about quantum computers -- surely they change the answer? For AES, structurally, they do not.&lt;/p&gt;
&lt;p&gt;Grover&apos;s halving is the main reason to prefer AES-256 for long-term or post-quantum margin -- not because AES-128 is structurally weaker, but because the larger key leaves a more comfortable margin against a generic quantum speedup.&lt;/p&gt;
&lt;p&gt;Grover&apos;s algorithm gives a generic square-root speedup for key search: $2^{n/2}$ instead of $2^{n}$, so AES-128 drops to roughly $2^{64}$ and AES-256 to roughly $2^{128}$ [@grover-aes-pqcrypto16]. Crucially, that speedup is &lt;em&gt;independent of AES&apos;s internal structure&lt;/em&gt; -- it applies to any cipher, treating AES as a black box. It does not touch the key schedule, the S-box, or MixColumns; it does not care how AES is built.&lt;/p&gt;
&lt;p&gt;That is exactly why Grover sits &lt;em&gt;outside&lt;/em&gt; this article&apos;s thesis: it is a generic key-search discount, not a structural break. And Shor&apos;s algorithm [@shor-siam97], which shatters RSA and &lt;a href=&quot;https://paragmali.com/blog/the-curve-was-hard-the-gap-was-soft-a-field-guide-to-using-e/&quot; rel=&quot;noopener&quot;&gt;elliptic curves&lt;/a&gt;, attacks the hidden-subgroup structure of public-key math and simply does not apply to symmetric ciphers.&lt;/p&gt;

Grover marks one edge of this article&apos;s territory: a generic speedup, not a structural crack, so it is named and set aside. The other edge is the entire world of real-world AES failures -- cache-timing side channels, fault injection, repeated GCM nonces, padding oracles, key-reinstallation attacks like KRACK. None of those touch the cipher&apos;s mathematics; they break the wrapper around it. They are the subject of the companion piece, *How AES Breaks in Real Life: The Attacks That Never Touched the Cipher*. This article is the would-break-in-theory story; that one is the did-break-in-the-field story.
&lt;p&gt;No proof, a thin single-key margin, and a key schedule that keeps yielding fresh structure twenty years on. So what would it actually take to break AES?&lt;/p&gt;
&lt;h2&gt;10. What Would Actually Break AES&lt;/h2&gt;
&lt;p&gt;If you wanted to be the person who genuinely dented AES, here is the to-do list -- and why every item on it has resisted the field&apos;s best for more than a decade.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Close the single-key reduced-round gap.&lt;/strong&gt; The frontier has sat at 7, 8, and 9 rounds since 2013, despite automated search tools purpose-built to push it [@dfj-eurocrypt13]. Nobody has extended the single-key attacks by even one round in over ten years. Either a genuinely new distinguisher is needed, or the round function really does leave nothing longer to exploit.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Migrate the key-schedule attacks into the single-key model.&lt;/strong&gt; The related-key attacks reach the full cipher, but only under a model real protocols deny. Can their key-schedule insight be recast into an attack that needs no related keys? So far, no -- and this is the single most important open question for the thesis. If it ever happened, the crack really would start where this article predicts, in a model that matters.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prove that a nonlinear key schedule would have mattered.&lt;/strong&gt; Would a heavier, nonlinear key expansion have removed both the related-key local collisions and biclique&apos;s recomputation discount? There is strong circumstantial evidence it would: Leurent and Pernot&apos;s 2021 discovery that the AES-128 schedule still splits into four independent 32-bit computations shows the linearity keeps handing attackers structure two decades on [@leurent-pernot-eurocrypt21].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Find a real single-key shortcut on full AES-128.&lt;/strong&gt; Not biclique&apos;s two bits -- an attack meaningfully below $2^{126}$ that reflects a structural weakness rather than an accounting trick. None is known.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Push the new structural distinguishers deeper.&lt;/strong&gt; In 2017, Lorenzo Grassi, Christian Rechberger and Sondre Rønjom found an unexpected structural-differential property of 5-round AES, which Bar-On and colleagues then turned into the best practical 5-round attack [@grassi-eurocrypt17] [@barron-crypto18]. Can such properties reach 6, 7, or more rounds? So far they have not.&lt;/p&gt;

A secret-key distinguisher, like the Grassi-Rechberger-Rønjom 5-round property, does not extract a single key byte -- it only shows the cipher behaves less randomly than it should over a few rounds [@grassi-eurocrypt17]. That sounds harmless. But historically, distinguishers are the early-warning system: they reveal structure years before anyone works out how to convert it into a key recovery, and every family in this article began as a distinguishing property before it became an attack. Watching where new distinguishers appear -- and they keep appearing near the key schedule -- is how you predict where the next real attack will come from.
&lt;p&gt;None of these five is close to solved. The standing challenge is stark: outside the related-key model, and beyond biclique&apos;s two-bit shave, nothing has meaningfully dented full-round single-key AES-128 in the entire history of its public analysis. Which is exactly why, for everyone who actually ships software, the right question is not &quot;when will AES break?&quot; but &quot;what should I do today?&quot;&lt;/p&gt;
&lt;h2&gt;11. What This Means for You&lt;/h2&gt;
&lt;p&gt;Strip all of it down to what changes your decisions. For almost everyone, the answer is: nothing -- and understanding &lt;em&gt;why&lt;/em&gt; nothing changes is the real payoff.&lt;/p&gt;
&lt;p&gt;AES is not broken. Every structural result in this article is astronomically infeasible, the strongest single-key full-round attack shaves a factor of four off a number no machine will ever reach, and the related-key attacks need access that correctly built systems never grant. Keep using AES.&lt;/p&gt;
&lt;p&gt;On key size, choose deliberately rather than superstitiously. AES-128 and AES-256 are both effectively unbreakable in the single-key model your systems actually run in; the related-key paradox that makes AES-256 &quot;weaker&quot; lives entirely in a model deployments deny [@bk-asiacrypt09].&lt;/p&gt;
&lt;p&gt;Prefer AES-256 when you want long-term or post-quantum margin, because Grover&apos;s generic square-root speedup halves the effective key length and a $2^{128}$ quantum margin is more comfortable than $2^{64}$ [@grover-aes-pqcrypto16]. Prefer AES-128 when you want raw speed and a post-Grover margin of $2^{64}$ is ample for your threat model. Both are sound; the choice is about margin, not about one being broken.&lt;/p&gt;
&lt;p&gt;The one pitfall worth internalizing is the related-key boundary.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Related-key attacks only bite if an attacker can influence the &lt;em&gt;relationships&lt;/em&gt; between the keys you use -- for example, by driving AES as a hash or compression function where attacker-known differences flow into the key input, or a home-grown key-derivation scheme that XORs chosen constants into a master key. Use AES as a keyed black box under independent, well-generated keys, and the entire related-key family -- including the full AES-192 and AES-256 results -- simply does not apply. Independent keys are the whole defense.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You can make the margin tangible with a few lines of arithmetic. The calculator below reads the AES-128 single-key margin both ways the article measures it: as rounds reached versus total, and as the best full-round complexity versus the brute-force ceiling.&lt;/p&gt;
&lt;p&gt;{`
// Two ways to feel the margin, using the numbers from this article.
const totalRounds = 10;
const bestSingleKeyRounds = 7;         // best single-key reduced-round (DFJ 2013)
const bruteForceExponent = 128;        // brute-force ceiling for AES-128
const bestFullRoundExponent = 126.1;   // biclique (BKR 2011)&lt;/p&gt;
&lt;p&gt;// 1) Round margin: how many full rounds still resist single-key attack.
const roundMargin = totalRounds - bestSingleKeyRounds;
console.log(&quot;Rounds still beyond the best single-key attack: &quot; + roundMargin +
            &quot; of &quot; + totalRounds);&lt;/p&gt;
&lt;p&gt;// 2) Complexity margin: how much &quot;faster than brute force&quot; biclique really is.
const speedupFactor = Math.pow(2, bruteForceExponent - bestFullRoundExponent);
console.log(&quot;Biclique speedup over brute force: about &quot; +
            speedupFactor.toFixed(1) + &quot;x&quot;);
console.log(&quot;Brute force itself: 2^128, roughly 1 followed by 38 zeros.&quot;);
console.log(&quot;A 3.7x discount on a never-finishable computation is still never-finishable.&quot;);
`}&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This article covered how AES would break &lt;em&gt;in theory&lt;/em&gt; -- the mathematics of the cipher itself. The attacks that actually steal data break the &lt;em&gt;deployment&lt;/em&gt;: the nonce, the padding, the key generation, a downgrade, a validation bug. If you want the field&apos;s real incident history, read the companion piece, &lt;em&gt;How AES Breaks in Real Life: The Attacks That Never Touched the Cipher&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;


No. In twenty-five years of public analysis, no attack has come close to breaking full-round AES in any way that matters. The single strongest single-key result -- the biclique attack -- recovers an AES-128 key in about $2^{126.1}$ operations, a factor of roughly four below brute force and still on the order of $10^{38}$ operations, which is physically meaningless [@biclique-asiacrypt11]. Every other full-round result needs a related-key model that real systems deny. AES is not broken; it is close to optimal.


Only in the related-key model, and only there. AES-256&apos;s longer, still-linear key schedule gives an attacker more structure, which is why a full-round related-key key recovery exists for AES-256 (about $2^{99}$) but no comparable full-round single-key break exists for AES-128 [@bk-asiacrypt09]. In the single-key model your deployments actually use, both are effectively unbreakable, and AES-256 gives you more post-quantum margin. The &quot;paradox&quot; is real cryptanalysis, not a practical warning.


No. Its complexity for AES-128 is $2^{126.1}$ -- roughly $10^{38}$ operations -- and its own authors state the attacks &quot;do not threaten the practical use of AES in any way&quot; [@biclique-asiacrypt11]. Biclique is best understood as a precise *measurement* of the thin single-key margin, not a threat to it. It is a meet-in-the-middle acceleration of brute force, not a structural collapse.


Not structurally. Grover&apos;s algorithm gives a generic square-root speedup for key search -- $2^{n/2}$ instead of $2^{n}$ -- so AES-128 drops to about $2^{64}$ and AES-256 to about $2^{128}$ of quantum security [@grover-aes-pqcrypto16]. That is a black-box discount independent of AES&apos;s internal design, which is why it is not a structural break; use AES-256 if you want the larger margin. Shor&apos;s algorithm [@shor-siam97], which does break RSA and elliptic curves, does not apply to symmetric ciphers at all.


It is this article&apos;s well-motivated thesis, carefully bounded. The related-key attacks break the full cipher by targeting the key schedule&apos;s linearity directly [@bk-asiacrypt09]; the biclique attack leans on the key schedule&apos;s slow diffusion to accelerate brute force [@biclique-asiacrypt11]; and peer-reviewed work in 2021 still calls the key schedule &quot;arguably the weakest part of the AES&quot; [@leurent-pernot-eurocrypt21]. The honest caveat: biclique&apos;s dependence is enabling, not a pure structural break, so this is a synthesized argument, not a claim that every full-round result is a key-schedule attack.


It is an attack in which the adversary obtains encryptions under several keys whose differences it knows [@bk-asiacrypt09]. It cannot happen unless your construction lets an attacker influence the relationships between keys -- which well-designed protocols never do. Use independent, well-generated keys and treat AES as a keyed black box, and the entire related-key family evaporates. It is a statement about a cipher&apos;s structural health, not a common deployment risk.


Because &quot;faster&quot; here means a factor of about four below $2^{128}$ -- the difference between $2^{128}$ and $2^{126.1}$ [@biclique-asiacrypt11]. Both are numbers no computation will ever complete. In cryptography, &quot;faster than brute force&quot; is the technical bar for a result to count at all; it is a bookkeeping threshold, not a statement that the cipher is within reach of any attacker, now or ever.

&lt;p&gt;Return to the question this article opened with: not whether AES is broken, but where the first crack would appear if it ever were. The evidence has answered it.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The AES round function is the most-analyzed, most-trusted primitive in symmetric cryptography, and twenty-five years of single-key attacks have plateaued a few rounds short of it -- the wide-trail design working exactly as intended. Every full-round result faster than brute force lives somewhere else: the related-key attacks break the linear key schedule head-on, reaching full AES-192 and AES-256, and the biclique attack leans on its slow diffusion to shave a factor of four off exhaustive search. The S-box and MixColumns are untouched. If AES ever falls, the evidence says the first crack starts at the key schedule -- the least-designed, most-linear component -- bounded by the honest caveat that biclique leans on the schedule rather than breaking it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;how-aes-would-break&quot; keyTerms={[
  { term: &quot;Security margin&quot;, definition: &quot;The distance between the best known attack and brute force, measured both in rounds reached out of total and in complexity below the 2^n ceiling.&quot; },
  { term: &quot;Wide-trail strategy&quot;, definition: &quot;AES&apos;s round-function design method: MixColumns&apos; branch number of 5 forces at least 25 active S-boxes over four rounds, capping any trail&apos;s probability at 2^-150.&quot; },
  { term: &quot;S-box (SubBytes)&quot;, definition: &quot;Multiplicative inversion in GF(2^8) followed by a fixed affine transformation; AES&apos;s only data-path nonlinearity, with maximum differential probability 2^-6.&quot; },
  { term: &quot;Key schedule&quot;, definition: &quot;The mostly-linear (XOR plus rotation) expansion of the master key into round keys, with one S-box column per group of words; AES&apos;s least-designed component.&quot; },
  { term: &quot;Integral (Square) attack&quot;, definition: &quot;Tracks a Lambda-set of 256 texts so a byte-wise XOR sum is provably zero after a few rounds, sieving wrong key guesses.&quot; },
  { term: &quot;Meet-in-the-middle attack&quot;, definition: &quot;Splits the cipher and matches a precomputed middle property against online computation, trading memory for the probability barrier.&quot; },
  { term: &quot;Related-key attack&quot;, definition: &quot;The attacker queries under keys whose differences it knows; against AES it chains local collisions through the linear key schedule.&quot; },
  { term: &quot;Local collision&quot;, definition: &quot;A state difference introduced by one round key that the linear key schedule cancels in the next, annihilating over a short span.&quot; },
  { term: &quot;Biclique&quot;, definition: &quot;A meet-in-the-middle structure that tests a group of keys at nearly the cost of one, accelerating exhaustive search by leaning on slow key-schedule diffusion.&quot; },
  { term: &quot;Distinguisher&quot;, definition: &quot;An attack that tells the real cipher apart from an ideal random permutation without necessarily recovering the key; a weaker but still structural break.&quot; }
]} questions={[
  { q: &quot;Why do single-key attacks on AES plateau near seven rounds?&quot;, a: &quot;Because the wide-trail round function leaves no long high-probability characteristic to extend; attackers must bolt key-guessing rounds onto a short distinguisher and run out of room. The plateau is the design working.&quot; },
  { q: &quot;Name the only two ways anyone has reached full-round AES faster than brute force, and what each exploits.&quot;, a: &quot;Related-key boomerang attacks (exploiting the key schedule&apos;s linearity via local collisions) and the biclique attack (leaning on the key schedule&apos;s slow diffusion to accelerate exhaustive search).&quot; },
  { q: &quot;Why is AES-256 weaker than AES-128 under related keys?&quot;, a: &quot;Its longer, still-linear key schedule offers more exploitable structure, yielding a full-round related-key recovery near 2^99 with no comparable single-key full-round break on AES-128.&quot; },
  { q: &quot;Why can AES never be proven secure the way RSA can?&quot;, a: &quot;Block ciphers have no security reduction to a problem believed hard, so a structural break can never be ruled out -- only measured as a margin. The wide-trail bound only covers round-function trails, not the key schedule.&quot; },
  { q: &quot;Why is Grover&apos;s algorithm outside this article&apos;s thesis?&quot;, a: &quot;Grover is a generic square-root key-search speedup independent of AES&apos;s internal structure, so it is a black-box discount, not a structural break.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>aes</category><category>cryptanalysis</category><category>key-schedule</category><category>related-key-attacks</category><category>biclique</category><category>block-ciphers</category><category>security-margin</category><author>noreply@paragmali.com (Parag Mali)</author></item><item><title>The Ciphertext Was Unbreakable. The Attacker Rewrote It Anyway: A Field Guide to Block Cipher Modes</title><link>https://paragmali.com/blog/the-ciphertext-was-unbreakable-the-attacker-rewrote-it-anyw/</link><guid isPermaLink="true">https://paragmali.com/blog/the-ciphertext-was-unbreakable-the-attacker-rewrote-it-anyw/</guid><description>Every block cipher mode -- ECB, CBC, CFB, OFB, CTR -- answers only confidentiality, never integrity. A field guide to why, the famous breaks, and the AEAD fix.</description><pubDate>Wed, 08 Jul 2026 21:51:08 GMT</pubDate><content:encoded>
A block cipher only enciphers one fixed-size block. A &quot;mode of operation&quot; is the wrapper that turns it into a scheme for real messages -- and every mode answers only one of two questions: can the attacker *read* it (confidentiality), or can the attacker *change* it (integrity)? The five SP 800-38A modes -- ECB, CBC, CFB, OFB, CTR -- are all malleable, so an attacker who cannot decrypt your ciphertext can still predictably edit the plaintext, and ECB additionally leaks structure outright (the penguin, Adobe&apos;s 153 million passwords). This field guide hands you one lens -- *which question did this mode answer, and was its IV/nonce contract honored?* -- and uses it to walk each mode&apos;s exact contract, a named failure catalog (Vaudenay, BEAST, Lucky Thirteen, POODLE, Sweet32, Efail, GCM nonce reuse), and the fix: authenticated encryption, whose dominant AES instances (GCM equals CTR plus GHASH, CCM equals CTR plus CBC-MAC) are literally these modes plus a MAC. It closes with the 2024-2026 state of the art (IR 8459, the ECB sunset, Ascon, nonce-misuse-resistant AES-GCM-SIV) and a decision guide for using these primitives correctly.
&lt;h2&gt;1. Two Lines of Code&lt;/h2&gt;
&lt;p&gt;A bank encrypts the message &quot;transfer $9&quot; with AES and a 256-bit key and sends the ciphertext across a network an attacker completely controls. He cannot read a single byte of it. AES is unbroken and will stay unbroken. Yet by flipping a few bits he cannot even decrypt, he turns the message into &quot;transfer $9,000,000,&quot; and the receiver accepts the change as authentic. The encryption was never broken. It simply answered the wrong question.&lt;/p&gt;
&lt;p&gt;How can a ciphertext be unreadable and freely editable at once? The trick is not a flaw in AES but a property of the &lt;em&gt;mode&lt;/em&gt; -- the wrapper that stretches a one-block cipher across a longer message. Many modes turn the cipher into a keystream generator and combine it with the plaintext by XOR, so $C = P \oplus \text{keystream}$. Rearrange the algebra: $P = C \oplus \text{keystream}$. An attacker who XORs a chosen delta into the ciphertext XORs exactly that delta into the recovered plaintext. He needs no key, reads nothing, and the receiver decrypts a perfectly well-formed forgery. That is one half of the story: the integrity question was never answered.&lt;/p&gt;
&lt;p&gt;The other half is uglier, because it fails the &lt;em&gt;first&lt;/em&gt; question too. In 2013, attackers exposed roughly 153 million Adobe account records. The passwords were not hashed. They were &lt;em&gt;encrypted&lt;/em&gt;, with 3DES in ECB mode and no salt [@troyhunt-adobe-2013]. ECB enciphers each block independently, so identical passwords produced identical ciphertext. Combined with the unencrypted password hints Adobe stored beside them, enormous numbers of passwords were reconstructed without anyone ever breaking 3DES [@troyhunt-adobe-2013]. The cipher was fine. The mode leaked the plaintext.&lt;/p&gt;
&lt;p&gt;Two stories, one shape. In each, the cipher did exactly what it promised and the attacker still won. That is because a mode of operation answers up to two independent questions, and the five most famous modes answer only one:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Can the attacker read it?&lt;/strong&gt; That is &lt;em&gt;confidentiality&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Can the attacker change it?&lt;/strong&gt; That is &lt;em&gt;integrity&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The five modes standardized for decades -- ECB, CBC, CFB, OFB, CTR -- answer only the first question. ECB answers even that one wrongly. Every named break in this field, past or future, reduces to one diagnostic sentence: &lt;em&gt;which of the two questions did this mode answer, and was its IV/nonce contract honored?&lt;/em&gt; Hold that sentence in your head and the whole subject becomes legible.&lt;/p&gt;

flowchart TD
    Mode[&quot;A block cipher mode of operation&quot;]
    Mode --&amp;gt; C[&quot;Question 1: can the attacker READ it? (confidentiality)&quot;]
    Mode --&amp;gt; I[&quot;Question 2: can the attacker CHANGE it? (integrity)&quot;]
    C --&amp;gt; Cans[&quot;Answered only if the IV or nonce contract is honored&quot;]
    I --&amp;gt; Ians[&quot;Never answered by the five SP 800-38A modes&quot;]
    Cans --&amp;gt; BreakA[&quot;Break type A: violated IV/nonce contract (BEAST, GCM nonce reuse)&quot;]
    Ians --&amp;gt; BreakB[&quot;Break type B: missing integrity answer (Efail, bit-flipping, truncation)&quot;]
&lt;p&gt;This is Part 5 of a field guide for protocol designers. It leans on two earlier parts without re-deriving them: &lt;a href=&quot;https://paragmali.com/blog/secure-against-whom-the-security-definitions-every-protocol-&quot; rel=&quot;noopener&quot;&gt;Part 1&lt;/a&gt; gave us the security definitions this article keeps invoking -- IND-CPA, IND-CCA2, INT-CTXT -- and Part 2 gave us the discipline of generating initialization vectors and nonces. Here we spend those definitions on a single primitive: the block cipher mode.&lt;/p&gt;
&lt;p&gt;If AES was never broken in either story, what actually failed? To answer, you first have to know what a block cipher can and cannot do on its own, and why a mode was mandatory from the very first day it shipped.&lt;/p&gt;
&lt;h2&gt;2. A Cipher That Only Speaks in Blocks&lt;/h2&gt;
&lt;p&gt;A block cipher is smaller than you think. DES (1977) enciphers exactly 64 bits at a time. AES (2001) enciphers exactly 128. Feed it more and it simply refuses. It is a keyed permutation on one fixed-size block and physically cannot accept a message longer than that.&lt;/p&gt;

A keyed, invertible permutation on one fixed-size block of bits, written $E_k : \{0,1\}^n \to \{0,1\}^n$ for a key $k$ and block size $n$ (64 bits for DES, 128 for AES). It maps one $n$-bit input to one $n$-bit output and back. It has no notion of a message, a length, or a stream.
&lt;p&gt;Because real messages are almost never exactly one block long, every use of a block cipher needs a wrapper: a rule for chopping the message into blocks, deciding what each block&apos;s input should be, and stitching the outputs back together. That wrapper is the mode of operation.&lt;/p&gt;

The algorithm that lifts a one-block cipher to messages of arbitrary length. It specifies how plaintext is partitioned, what feeds into each block cipher call, and how the results combine into a ciphertext. The mode -- not the cipher -- decides whether identical plaintext leaks, whether the scheme is parallel, and what the initialization-vector or nonce rule is.
&lt;p&gt;The primitive came first. Horst Feistel&apos;s work at IBM in the early 1970s produced the Feistel network that became DES, a 64-bit keyed permutation blessed as a federal standard in 1977 [@feistel-1973][@fips-46-3]. The 64-bit block chosen here is the exact quantity that dies, 39 years later, to the Sweet32 attack.&lt;/p&gt;
&lt;p&gt;The first wrapper followed almost immediately. In 1976, William Ehrsam, Carl Meyer, John Smith, and Walter Tuchman at IBM filed the patent on Cipher Block Chaining -- the idea of feeding each plaintext block the previous ciphertext block before encryption, so that identical plaintext blocks stop producing identical ciphertext (US Patent 4,074,066, granted 1978) [@cbc-patent-4074066].The patent&apos;s actual title is &quot;Message verification and transmission error detection by block chaining&quot; [@cbc-patent-4074066]. That is historically ironic: CBC as a confidentiality mode provides no message verification -- no integrity -- at all, which is the very gap this article is about.&lt;/p&gt;
&lt;p&gt;Counter mode arrived on paper three years later. Whitfield Diffie and Martin Hellman described encrypting a counter to make a keystream in their 1979 survey &quot;Privacy and Authentication,&quot; turning a block cipher into a parallelizable stream cipher [@diffie-hellman-1979][@rogaway-modes-2011].Counter mode was described &quot;just as early as the basic-four modes,&quot; in Rogaway&apos;s words, &quot;yet for some reason it was not included in the initial batch&quot; [@rogaway-modes-2011]. It waited 22 years for a federal standard. The exact page in Proc. IEEE 67(3) is gated behind IEEE Xplore, so the DOI is the stable handle and Rogaway&apos;s 2011 survey carries the attribution [@diffie-hellman-1979][@rogaway-modes-2011].&lt;/p&gt;
&lt;p&gt;Then the standard fixed the toolkit. In December 1980 the National Bureau of Standards published FIPS 81, &lt;em&gt;DES Modes of Operation&lt;/em&gt;, sanctioning four ways to stretch DES across real traffic: ECB, CBC, CFB, and OFB [@fips-81]. Counter mode was left out. It did not enter a NIST standard until Morris Dworkin&apos;s SP 800-38A re-specified all five modes for the AES era in December 2001, finally adding CTR as the fifth -- 22 years after Diffie and Hellman [@nist-sp-800-38a].&lt;/p&gt;

flowchart LR
    A[&quot;1976: CBC invented at IBM&quot;] --&amp;gt; B[&quot;1979: Counter mode, Diffie-Hellman&quot;]
    B --&amp;gt; C[&quot;1980: FIPS 81 standardizes ECB, CBC, CFB, OFB&quot;]
    C --&amp;gt; D[&quot;1997: BDJR concrete-security proofs&quot;]
    D --&amp;gt; E[&quot;2000-2001: Encrypt-then-MAC proven, SP 800-38A adds CTR&quot;]
    E --&amp;gt; F[&quot;2004-2007: GCM and CCM, CTR plus a MAC&quot;]
    F --&amp;gt; G[&quot;2011-2018: BEAST, Lucky Thirteen, POODLE, Sweet32, Efail&quot;]
    G --&amp;gt; H[&quot;2024-2025: NIST IR 8459, Ascon&quot;]
&lt;p&gt;Here is the load-bearing historical fact. Every one of these five modes is a &lt;em&gt;confidentiality&lt;/em&gt; construction. Integrity -- the second question, &quot;can the attacker change it?&quot; -- was filed under a separate heading called a message authentication code, and in practice it was usually forgotten. FIPS 81 and SP 800-38A specify no integrity mechanism for any of the five [@fips-81][@nist-sp-800-38a]. That separation of concerns, confidentiality here and integrity somewhere else, is the original sin the rest of this story pays for.&lt;/p&gt;
&lt;p&gt;So the toolkit was frozen by 1980 (four modes) and completed by 2001 (a fifth), every one a way to hide data and none a way to protect it from change. The most obvious of the four is also the most broken, and seeing exactly why is the fastest route into the whole subject.&lt;/p&gt;
&lt;h2&gt;3. ECB, and Why &quot;Just Encrypt Each Block&quot; Fails&lt;/h2&gt;
&lt;p&gt;The most obvious wrapper is to apply the one-block permutation to each block on its own: $C_i = E_k(P_i)$. This is Electronic Codebook mode, and it is the design every beginner reinvents in an afternoon. It is also broken in a way you can see with your eyes.&lt;/p&gt;
&lt;p&gt;The flaw is that ECB is &lt;em&gt;deterministic&lt;/em&gt;. It has no initialization vector, no chaining, and no state, so the same plaintext block always encrypts to the same ciphertext block: $P_i = P_j \Rightarrow C_i = C_j$. The plaintext&apos;s block-level structure survives encryption intact. Rogaway&apos;s survey states it flatly: ECB &quot;leak[s] equality of blocks across both block positions and time&quot; and &quot;does not achieve any generally desirable security goal in its own right&quot; [@rogaway-modes-2011].&lt;/p&gt;

flowchart TD
    P1[&quot;Block A: LOVE&quot;] --&amp;gt; C1[&quot;Ciphertext 7a3f&quot;]
    P2[&quot;Block B: HATE&quot;] --&amp;gt; C2[&quot;Ciphertext 9b2e&quot;]
    P3[&quot;Block C: LOVE&quot;] --&amp;gt; C3[&quot;Ciphertext 7a3f&quot;]
    C1 -.-&amp;gt;|&quot;equal blocks leak&quot;| C3
&lt;p&gt;That leak is not a metaphor.The famous &quot;ECB penguin&quot; -- an image of Tux encrypted block-by-block whose outline stays perfectly visible -- is community folklore (the Tux image is by Larry Ewing, 1996) with no research primary. The load-bearing evidence for ECB&apos;s failure is the Adobe 2013 breach and the BDJR theorem, not the meme. In 2013, roughly 153 million Adobe records showed it at scale: passwords encrypted with 3DES in ECB, no salt, so identical passwords produced identical ciphertext and the plaintext structure reconstructed itself without 3DES ever being broken [@troyhunt-adobe-2013].&lt;/p&gt;
&lt;p&gt;Underneath the meme is a theorem. ECB is not IND-CPA.&lt;/p&gt;

The baseline security goal for encryption. An adversary who may request encryptions of any plaintexts it chooses still cannot tell which of two equal-length messages a challenge ciphertext hides. Bellare, Desai, Jokipii, and Rogaway (1997) proved the consequence: any IND-CPA scheme must be randomized or stateful, so a deterministic mode like ECB cannot qualify [@bdjr-1997][@katz-lindell-2020].
&lt;p&gt;The proof is a one-line adversary. Ask the challenger to encrypt a pair of equal blocks $(X, X)$ versus an unequal pair $(X, Y)$ and simply look for a repeated ciphertext block; ECB gives itself away every time [@bdjr-1997]. This is the same reasoning &lt;a href=&quot;https://paragmali.com/blog/secure-against-whom-the-security-definitions-every-protocol-&quot; rel=&quot;noopener&quot;&gt;Part 1&lt;/a&gt; develops in general. ECB is also malleable at block granularity: because blocks are independent, an attacker can cut, paste, and reorder them undetected. It fails both questions at once.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; ECB is deterministic, so identical plaintext blocks become identical ciphertext blocks and structured or repeated data leaks through untouched -- the ECB penguin, and Adobe&apos;s roughly 153 million exposed passwords [@troyhunt-adobe-2013]. Reach for ECB only as a raw one-block building block, never to encrypt a message.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That &quot;never&quot; needs one careful qualifier -- it is easy to overstate.&lt;/p&gt;

The rule is *never ECB for messages* -- multi-block, structured, or low-entropy plaintext. The raw single-block permutation is still a legitimate building block: it is the block operation every other mode calls, and it sits at the core of NIST AES Key Wrap and of CMAC/CBC-MAC. NIST&apos;s SP 800-131A Revision 3, the initial public draft published on October 21, 2024, formalizes this by moving ECB to &quot;legacy use&quot; and disallowing it for encrypting secret data, with legacy (decrypt-only) use retained -- a demotion, not a claim that ECB has no valid use anywhere [@nist-sp-800-131a-r3].
&lt;p&gt;You can watch the determinism happen. The toy below is not a real cipher, but like ECB it transforms each block with the same deterministic function, so a repeated plaintext block produces a repeated ciphertext block:&lt;/p&gt;
&lt;p&gt;{`
// A toy deterministic block transform. Not a real cipher -- the point is
// only that the same input block always yields the same output block.
function toyBlockCipher(block) {
  return block.split(&apos;&apos;).reverse().map(function (c) {
    return String.fromCharCode((c.charCodeAt(0) + 7) % 128);
  }).join(&apos;&apos;);
}&lt;/p&gt;
&lt;p&gt;// ECB: split into 4-char blocks and transform each one independently.
function ecb(message) {
  var out = [];
  for (var i = 0; i &amp;lt; message.length; i += 4) {
    out.push(toyBlockCipher(message.slice(i, i + 4)));
  }
  return out;
}&lt;/p&gt;
&lt;p&gt;var blocks = ecb(&apos;LOVEHATELOVE&apos;); // block 1 and block 3 are identical
console.log(blocks);
console.log(&apos;Block 1 equals block 3? &apos; + (blocks[0] === blocks[2]));
// True. The repeated plaintext block leaks as a repeated ciphertext block,
// with no key required to notice the pattern.
`}&lt;/p&gt;
&lt;p&gt;One clarification before moving on.These five are the SP 800-38A &lt;em&gt;confidentiality-only&lt;/em&gt; modes, not &quot;all block cipher modes.&quot; Disk encryption (XTS-AES, SP 800-38E), authentication (CMAC, SP 800-38B), and authenticated encryption (GCM in SP 800-38D, CCM in SP 800-38C) live in separate NIST publications because they pursue different goals. ECB is the degenerate member of the family, and its failure points straight at the fix.&lt;/p&gt;
&lt;p&gt;BDJR&apos;s theorem is also the cure. To be IND-CPA, encryption must be randomized or stateful. So add an initialization vector, and make each block&apos;s encryption depend on the previous one, so that identical plaintext diverges. That is Cipher Block Chaining -- and the start of a forty-year evolution that improves everything except the one thing that matters.&lt;/p&gt;
&lt;h2&gt;4. From CBC to CTR, Generation by Generation&lt;/h2&gt;
&lt;p&gt;Four modes remain, and they line up as a sequence of fixes -- each one repairing the previous mode&apos;s &lt;em&gt;limitation&lt;/em&gt;, and none of them repairing the missing integrity answer. The field got faster, more flexible, and better specified. It stayed exactly as forgeable as the day it started.&lt;/p&gt;
&lt;h3&gt;CBC: chain the blocks&lt;/h3&gt;
&lt;p&gt;CBC seeds the chain with an initialization vector and feeds each plaintext block the previous ciphertext block before encryption: $C_i = E_k(P_i \oplus C_{i-1})$, with $C_0 = \text{IV}$. Decryption runs $P_i = D_k(C_i) \oplus C_{i-1}$. Because every ciphertext block now depends on all plaintext before it, identical plaintext blocks diverge, and ECB&apos;s pattern leak is gone. With an unpredictable IV, CBC is provably IND-CPA [@bdjr-1997].&lt;/p&gt;

The per-message starting value a mode mixes in so that encrypting the same plaintext twice yields different ciphertext. For CBC and CFB the IV must be *unpredictable* -- indistinguishable from random to an attacker -- not merely fresh, because it is the first value fed into the chain [@nist-sp-800-38a]. Part 2 of this series covers how to generate one.
&lt;p&gt;CBC answered the first question correctly and left the second blank, and even its confidentiality carries three sharp contract edges. This one mode seeded most of the Failure Catalog. It is malleable: a controlled flip in ciphertext block $C_i$ deterministically flips the corresponding bits of plaintext block $P_{i+1}$ while randomizing $P_i$ -- the &quot;flip-and-garble&quot; gadget, an attacker editing a later block without the key [@rogaway-modes-2011].&lt;/p&gt;
&lt;p&gt;The three contract edges follow. It needs padding, and a receiver that reveals whether decrypted padding is valid turns that check into a plaintext-recovering oracle. Its IV must be unpredictable, or a chosen-plaintext attacker can distinguish messages. And with a 64-bit block, its ciphertext blocks start colliding after about $2^{32}$ blocks, leaking $P_i \oplus P_j$. Rogaway&apos;s performance verdict is blunt: CBC encryption is &quot;inherently serial,&quot; and he can &quot;identify no important advantages over CTR mode&quot; [@rogaway-modes-2011].Ciphertext stealing (CBC-CS, standardized in an addendum to SP 800-38A) is the no-expansion variant that avoids padding by borrowing bits from the penultimate block. It is a useful trick, not a new security property -- CBC-CS is still malleable and still needs an unpredictable IV.&lt;/p&gt;
&lt;h3&gt;CFB: a self-synchronizing stream&lt;/h3&gt;
&lt;p&gt;CFB turns the block cipher into a stream by encrypting the &lt;em&gt;previous ciphertext&lt;/em&gt; to produce a keystream, then XORing it with the plaintext: $C_i = P_i \oplus E_k(C_{i-1})$. The cipher never touches the plaintext directly, so there is no padding, the mode can operate on sub-block segments (one byte or even one bit at a time), and it self-synchronizes after lost or inserted segments -- a genuinely useful property for noisy character-oriented links [@rogaway-modes-2011].&lt;/p&gt;
&lt;p&gt;The costs are real. Encryption is still serial, and for a segment size $s \lt n$ the mode makes many more block cipher calls per byte -- Rogaway notes $s = 8$ means &quot;16 times the number of blockcipher calls as CBC,&quot; and $s = 1$ means 128 times [@rogaway-modes-2011].Folklore (and even the loose version of this article&apos;s own scope) sometimes says CFB needs only a &lt;em&gt;unique&lt;/em&gt; IV. The primary source is stricter: SP 800-38A Section 5.3 requires the IV for both CBC and CFB to be &lt;em&gt;unpredictable&lt;/em&gt; [@nist-sp-800-38a]. Treat CFB&apos;s IV exactly like CBC&apos;s.&lt;/p&gt;
&lt;p&gt;CFB&apos;s malleability is the middle case, not a pure bit-flip. Because $P_i = C_i \oplus E_k(C_{i-1})$, flipping a ciphertext bit flips exactly the aligned plaintext bit in the &lt;em&gt;current&lt;/em&gt; block -- but that same altered block is the cipher&apos;s input for the next one, so the &lt;em&gt;following&lt;/em&gt; block decrypts to garbage. Efail (2018) weaponized precisely this: Damian Poddebniak and co-authors built malleability &quot;gadgets&quot; in CFB (OpenPGP&apos;s mode), engineered to absorb the garbled block while keeping the surgical edit, that turned an encrypted email into a plaintext-exfiltration channel with no key recovery and no padding oracle [@efail-2018][@efail-site].&lt;/p&gt;
&lt;h3&gt;OFB: a pre-computable stream&lt;/h3&gt;
&lt;p&gt;OFB makes the keystream independent of the message by feeding back the cipher&apos;s &lt;em&gt;own output&lt;/em&gt; instead of the ciphertext: $O_i = E_k(O_{i-1})$, then $C_i = P_i \oplus O_i$. Because the pad depends only on the key and IV, you can compute it before the plaintext arrives, and a single flipped ciphertext bit corrupts only the corresponding plaintext bit, with no error propagation -- attractive for satellite links and digitized voice [@rogaway-modes-2011].&lt;/p&gt;

A number used once: a value that must never repeat under a given key. OFB and CTR need their nonce only to be *unique*, not unpredictable, so a simple counter is a perfectly good nonce [@nist-sp-800-38a]. Reusing one under the same key is catastrophic for every keystream mode, because it reproduces the exact same pad. Part 2 covers how to source these values safely.
&lt;p&gt;That last point is OFB&apos;s undoing. If a $(\text{key}, \text{IV})$ pair ever repeats, the pad repeats, and $C \oplus C&apos; = P \oplus P&apos;$ leaks the XOR of two plaintexts with no key -- a two-time pad [@rogaway-modes-2011]. OFB is also serial in &lt;em&gt;both&lt;/em&gt; directions, so it cannot use hardware parallelism at all, a strictly worse profile than CTR for the same &quot;stream&quot; benefit. And the original FIPS 81 reduced-feedback variants shortened the keystream cycle dangerously, a hazard SP 800-38A removed by defining OFB with full-block feedback only [@fips-81][@nist-sp-800-38a].&lt;/p&gt;
&lt;h3&gt;CTR: the parallel stream that wins&lt;/h3&gt;
&lt;p&gt;CTR keeps OFB&apos;s &quot;encrypt something to make a pad&quot; idea but replaces the serial feedback chain with an &lt;em&gt;independent&lt;/em&gt; per-block counter: $C_i = P_i \oplus E_k(\text{nonce} ,|, i)$. Because each pad block is a standalone function of its counter, the blocks have no data dependency on one another. CTR is fully parallel on both encryption and decryption, random-access (decrypt block $i$ alone), precomputable, inverse-free, and needs no padding. Rogaway estimates it &quot;encrypting at more than 10 times the speed of CBC&quot; in hardware [@rogaway-modes-2011]. Its contract is the simplest of all: the counter must be &lt;em&gt;unique&lt;/em&gt; per key, and unpredictability is explicitly not required [@bdjr-1997][@rogaway-modes-2011].&lt;/p&gt;

Counter mode is &quot;the best and most modern way to achieve privacy-only encryption&quot; and &quot;an important building block for authenticated-encryption schemes.&quot; -- Phillip Rogaway, 2011
&lt;p&gt;And here is the cliff. CTR is the best answer to the &lt;em&gt;first&lt;/em&gt; question, which is exactly what makes its failure the point of the whole story. It is still malleable, and more transparently so than any other mode: $P = C \oplus \text{keystream}$, so flipping any ciphertext bit flips exactly the corresponding plaintext bit, with no key. The &quot;transfer $9&quot; to &quot;transfer $9,000,000&quot; edit from the opening is a single XOR, and the receiver decrypts a perfectly well-formed message. CTR removed every other excuse -- it is fast, parallel, and clean -- so the blank where integrity should be is the only thing left to see.&lt;/p&gt;

flowchart TD
    subgraph CBC[&quot;CBC: serial chaining&quot;]
        cIV[&quot;IV&quot;] --&amp;gt; cx1[&quot;XOR&quot;]
        cP1[&quot;P1&quot;] --&amp;gt; cx1
        cx1 --&amp;gt; cE1[&quot;E_k&quot;] --&amp;gt; cC1[&quot;C1&quot;]
        cC1 --&amp;gt; cx2[&quot;XOR&quot;]
        cP2[&quot;P2&quot;] --&amp;gt; cx2
        cx2 --&amp;gt; cE2[&quot;E_k&quot;] --&amp;gt; cC2[&quot;C2&quot;]
    end
    subgraph CTR[&quot;CTR: independent counters&quot;]
        tK1[&quot;E_k(nonce, 1)&quot;] --&amp;gt; tx1[&quot;XOR&quot;]
        tP1[&quot;P1&quot;] --&amp;gt; tx1
        tx1 --&amp;gt; tC1[&quot;C1&quot;]
        tK2[&quot;E_k(nonce, 2)&quot;] --&amp;gt; tx2[&quot;XOR&quot;]
        tP2[&quot;P2&quot;] --&amp;gt; tx2
        tx2 --&amp;gt; tC2[&quot;C2&quot;]
    end
&lt;p&gt;Lined up as a reference grid, the five modes and their exact contracts look like this:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;Relation&lt;/th&gt;
&lt;th&gt;IV / nonce contract&lt;/th&gt;
&lt;th&gt;Parallelism&lt;/th&gt;
&lt;th&gt;Malleability&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;ECB&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C_i = E_k(P_i)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;none (the flaw)&lt;/td&gt;
&lt;td&gt;encrypt and decrypt parallel&lt;/td&gt;
&lt;td&gt;block-level: cut, paste, reorder&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CBC&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C_i = E_k(P_i XOR C_{i-1})&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;unpredictable IV&lt;/td&gt;
&lt;td&gt;encrypt serial, decrypt parallel&lt;/td&gt;
&lt;td&gt;flip-and-garble (block-coupled)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CFB&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C_i = P_i XOR E_k(C_{i-1})&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;unpredictable IV&lt;/td&gt;
&lt;td&gt;encrypt serial, decrypt parallel&lt;/td&gt;
&lt;td&gt;surgical bit, next block garbled (middle)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OFB&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C_i = P_i XOR E_k(O_{i-1})&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;unique nonce&lt;/td&gt;
&lt;td&gt;serial both ways&lt;/td&gt;
&lt;td&gt;surgical bitwise&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CTR&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C_i = P_i XOR E_k(counter_i)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;unique nonce (not unpredictable)&lt;/td&gt;
&lt;td&gt;encrypt and decrypt parallel&lt;/td&gt;
&lt;td&gt;surgical bitwise&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The IV and nonce contracts are SP 800-38A&apos;s; the parallelism and malleability columns follow Rogaway&apos;s summary tables [@nist-sp-800-38a][@rogaway-modes-2011].&lt;/p&gt;
&lt;p&gt;That last column deserves its own magnification, because &quot;malleable&quot; is not one behavior. It runs from surgical (edit one plaintext bit and touch nothing else), through a middle case (edit one bit, but wreck the neighboring block), to block-coupled (your controlled edit lands a block &lt;em&gt;later&lt;/em&gt;):&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;Malleability class&lt;/th&gt;
&lt;th&gt;What one flipped ciphertext bit does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;CTR, OFB&lt;/td&gt;
&lt;td&gt;surgical&lt;/td&gt;
&lt;td&gt;flips exactly the aligned plaintext bit, with zero collateral&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CFB&lt;/td&gt;
&lt;td&gt;middle case&lt;/td&gt;
&lt;td&gt;flips the aligned bit in the current block, and fully garbles the next block&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CBC&lt;/td&gt;
&lt;td&gt;block-coupled&lt;/td&gt;
&lt;td&gt;garbles the current block, and flips the aligned bit in the next block&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ECB&lt;/td&gt;
&lt;td&gt;block-level&lt;/td&gt;
&lt;td&gt;no sub-block control, but whole blocks can be cut, pasted, and reordered&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The distinction is operational, not academic: CTR&apos;s surgical malleability is what makes the opening bit-flip a one-line edit, while CFB&apos;s &quot;flip here, garble there&quot; is the exact structure Efail&apos;s exfiltration gadgets were built around [@rogaway-modes-2011][@efail-2018]. Read as an evolution, the same five tell a story of steady improvement on every axis but one:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;Year&lt;/th&gt;
&lt;th&gt;Key idea&lt;/th&gt;
&lt;th&gt;Limitation that drove the next step&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;ECB&lt;/td&gt;
&lt;td&gt;1980&lt;/td&gt;
&lt;td&gt;encrypt each block independently&lt;/td&gt;
&lt;td&gt;deterministic; leaks block equality (not IND-CPA)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CBC&lt;/td&gt;
&lt;td&gt;1976 / 1980&lt;/td&gt;
&lt;td&gt;chain each block with the previous ciphertext&lt;/td&gt;
&lt;td&gt;serial; needs padding; unpredictable IV; 64-bit birthday&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CFB&lt;/td&gt;
&lt;td&gt;1980&lt;/td&gt;
&lt;td&gt;encrypt the previous ciphertext into a keystream&lt;/td&gt;
&lt;td&gt;serial; sub-block sizes multiply cipher calls&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OFB&lt;/td&gt;
&lt;td&gt;1980&lt;/td&gt;
&lt;td&gt;encrypt the feedback into a message-independent pad&lt;/td&gt;
&lt;td&gt;serial both ways; reuse is a two-time pad&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CTR&lt;/td&gt;
&lt;td&gt;1979 / 2001&lt;/td&gt;
&lt;td&gt;encrypt an independent counter&lt;/td&gt;
&lt;td&gt;the best confidentiality mode, yet still no integrity&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Not one of the four evolutions from ECB added integrity. CBC, CFB, OFB, and CTR each improved chaining, padding, error behavior, or parallelism. Every one of them left the second question -- can the attacker change it? -- completely blank.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;One honest caveat: CFB, OFB, and CTR are not a strict quality ladder. They are three parallel answers to CBC&apos;s &quot;turn the block cipher into a stream,&quot; standardized together, with CTR the clear winner [@rogaway-modes-2011]. The linear arrow is a teaching device.&lt;/p&gt;
&lt;p&gt;Line the four up and the pattern is undeniable. The bug was never &quot;which chaining?&quot; It was the blank where the second answer should be. Naming that blank correctly is the pivot the whole field turned on.&lt;/p&gt;
&lt;h2&gt;5. Malleability Is the Real Bug&lt;/h2&gt;
&lt;p&gt;Here is the reframe that organizes the entire subject: confidentiality is not security. A mode that perfectly hides your message while letting an attacker predictably rewrite it has not handed you a weaker guarantee. It has handed you a &lt;em&gt;different&lt;/em&gt; one, and mistaking the two is the single most repeated error in applied cryptography.&lt;/p&gt;

The property that an attacker can transform a ciphertext into a predictable transformation of the underlying plaintext, without knowing the key or the plaintext. A malleable scheme may be perfectly confidential and still let an attacker edit the message. All five SP 800-38A modes are malleable.
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Every one of the five modes answers only confidentiality. The missing integrity answer &lt;em&gt;is&lt;/em&gt; malleability, and malleability is the real bug. The fix is authenticated encryption -- not a faster or cleverer confidentiality mode.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is a provable statement, not a mood. A confidentiality-only mode is not IND-CCA2 and not non-malleable; IND-CPA says nothing about an active attacker who edits ciphertext in transit [@bdjr-1997].&lt;/p&gt;
&lt;p&gt;The mechanism differs per mode, and that difference is your diagnostic. In the pure keystream modes (CTR and OFB) the relation is $P = C \oplus \text{keystream}$, so flipping ciphertext bit $i$ flips plaintext bit $i$ exactly, with no collateral. CFB is the middle case: the flip lands surgically in the current block but garbles the &lt;em&gt;next&lt;/em&gt; one, because CFB feeds each ciphertext block back through the cipher. In CBC the coupling runs the other way -- a flip in $C_i$ predictably edits $P_{i+1}$ while randomizing $P_i$. &lt;a href=&quot;https://paragmali.com/blog/secure-against-whom-the-security-definitions-every-protocol-&quot; rel=&quot;noopener&quot;&gt;Part 1&lt;/a&gt; develops why this is a failure of the &lt;em&gt;goal&lt;/em&gt;, not the construction.&lt;/p&gt;

The stronger targets a confidentiality-only mode provably fails. IND-CCA2 (indistinguishability under adaptive chosen-ciphertext attack) hands the adversary a decryption oracle for any ciphertext but the challenge; non-malleability forbids turning one ciphertext into a predictably related one. Because all five SP 800-38A modes are malleable, none is IND-CCA2. Part 1 of this series formalizes both goals -- here they are exactly what a MAC restores.
&lt;p&gt;You can run the attack from the opening. The demo below encrypts a payment instruction with a toy keystream, then, knowing only the message format, rewrites the amount by XORing a delta into the ciphertext. No key is ever touched:&lt;/p&gt;
&lt;p&gt;{`
// Toy CTR: P = C XOR keystream. Editing C edits P, with no key. NOT real crypto.
function xorBytes(a, b) { return a.map(function (x, i) { return x ^ b[i]; }); }
function toBytes(s) { return Array.from(s).map(function (c) { return c.charCodeAt(0); }); }
function toStr(b) { return b.map(function (x) { return String.fromCharCode(x); }).join(&apos;&apos;); }&lt;/p&gt;
&lt;p&gt;var plaintext = &apos;amount:0000009&apos;;                 // the honest instruction
var keystream = toBytes(&apos;SECRETPADSECRET&apos;).slice(0, plaintext.length);&lt;/p&gt;
&lt;p&gt;// Sender encrypts. The attacker sees only C -- never the key, never the keystream.
var C = xorBytes(toBytes(plaintext), keystream);&lt;/p&gt;
&lt;p&gt;// The attacker knows the fixed message FORMAT and wants this instead:
var target = &apos;amount:9000000&apos;;                    // same length, this is the &quot;9 -&amp;gt; 9,000,000&quot; edit
var delta = xorBytes(toBytes(plaintext), toBytes(target));  // computable from the format alone&lt;/p&gt;
&lt;p&gt;// He XORs the delta straight into the ciphertext.
var forged = xorBytes(C, delta);&lt;/p&gt;
&lt;p&gt;// The receiver decrypts with the real keystream and sees the forgery.
console.log(&apos;Receiver reads: &apos; + toStr(xorBytes(forged, keystream)));  // amount:9000000
console.log(&apos;Keys or keystream used by the attacker: none.&apos;);
`}&lt;/p&gt;
&lt;p&gt;The same edit, drawn as it happens on the wire:&lt;/p&gt;

sequenceDiagram
    participant S as Sender
    participant A as Attacker
    participant R as Receiver
    S-&amp;gt;&amp;gt;A: Ciphertext of a nine-dollar transfer
    Note over A: Cannot read it, AES is unbroken
    Note over A: But P is C XOR keystream, so flipping ciphertext bit i flips plaintext bit i
    A-&amp;gt;&amp;gt;A: XOR a chosen delta into the amount bytes
    A-&amp;gt;&amp;gt;R: Modified ciphertext
    Note over R: Decrypts to a nine-million transfer, perfectly well-formed
    R-&amp;gt;&amp;gt;R: Accepts the forgery as authentic

Confidentiality without integrity is not weaker encryption. It is a different, largely illusory guarantee.
&lt;p&gt;Now turn the lens on the historical record. Every famous break of these modes is one of two diagnoses -- a missing integrity answer, or a violated IV/nonce contract:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Break&lt;/th&gt;
&lt;th&gt;Year&lt;/th&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;Root cause&lt;/th&gt;
&lt;th&gt;Lesson&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Adobe [@troyhunt-adobe-2013]&lt;/td&gt;
&lt;td&gt;2013&lt;/td&gt;
&lt;td&gt;ECB&lt;/td&gt;
&lt;td&gt;confidentiality answered wrongly (determinism)&lt;/td&gt;
&lt;td&gt;never ECB for messages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Padding oracle, Vaudenay [@vaudenay-2002]&lt;/td&gt;
&lt;td&gt;2002&lt;/td&gt;
&lt;td&gt;CBC&lt;/td&gt;
&lt;td&gt;no integrity plus a distinguishable padding check&lt;/td&gt;
&lt;td&gt;verify before decrypting&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BEAST [@bard-2004][@cve-2011-3389]&lt;/td&gt;
&lt;td&gt;2011&lt;/td&gt;
&lt;td&gt;CBC&lt;/td&gt;
&lt;td&gt;violated IV contract (predictable IV)&lt;/td&gt;
&lt;td&gt;IVs must be unpredictable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lucky Thirteen [@lucky-thirteen-2013]&lt;/td&gt;
&lt;td&gt;2013&lt;/td&gt;
&lt;td&gt;CBC&lt;/td&gt;
&lt;td&gt;wrong composition order plus a timing leak&lt;/td&gt;
&lt;td&gt;Encrypt-then-MAC, constant time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;POODLE [@poodle-2014][@cve-2014-3566]&lt;/td&gt;
&lt;td&gt;2014&lt;/td&gt;
&lt;td&gt;CBC (SSL 3.0)&lt;/td&gt;
&lt;td&gt;padding oracle after a downgrade&lt;/td&gt;
&lt;td&gt;retire the mode and the fallback&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sweet32 [@sweet32-2016][@cve-2016-2183]&lt;/td&gt;
&lt;td&gt;2016&lt;/td&gt;
&lt;td&gt;CBC (64-bit)&lt;/td&gt;
&lt;td&gt;block-size birthday bound&lt;/td&gt;
&lt;td&gt;no 64-bit ciphers for bulk&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Efail [@efail-2018]&lt;/td&gt;
&lt;td&gt;2018&lt;/td&gt;
&lt;td&gt;CBC / CFB&lt;/td&gt;
&lt;td&gt;missing integrity (malleability gadget)&lt;/td&gt;
&lt;td&gt;authenticate the ciphertext&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Truncation, Smyth-Pironti [@smyth-pironti-2013]&lt;/td&gt;
&lt;td&gt;2013&lt;/td&gt;
&lt;td&gt;TLS record (any mode)&lt;/td&gt;
&lt;td&gt;missing integrity of length and framing (omission)&lt;/td&gt;
&lt;td&gt;authenticate the end, not just the bytes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GCM nonce reuse [@joux-2006][@nonce-disrespecting-2016]&lt;/td&gt;
&lt;td&gt;2016&lt;/td&gt;
&lt;td&gt;CTR / GCM&lt;/td&gt;
&lt;td&gt;violated nonce contract&lt;/td&gt;
&lt;td&gt;never repeat a (key, nonce)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Most of these breaks edit or leak bytes, but the subtlest one deletes them. Ben Smyth and Alfredo Pironti showed at WOOT 2013 that silently &lt;em&gt;truncating&lt;/em&gt; a TLS stream -- cutting it short at an attacker-chosen point -- changes the meaning a web application infers from a &quot;complete&quot; response, because the record layer authenticated the bytes it carried but never the fact that the message had &lt;em&gt;ended&lt;/em&gt; [@smyth-pironti-2013]. That is an integrity failure of omission, and it is why the fix in Section 10 authenticates length and end-of-stream, not just content. Most of the rest are TLS history, which the &lt;a href=&quot;https://paragmali.com/blog/rotating-every-cipher-schannel-and-the-twenty-year-algorithm&quot; rel=&quot;noopener&quot;&gt;SChannel post&lt;/a&gt; tells from the deployment side.Precision on GCM nonce reuse: one repeated $(\text{key}, \text{nonce})$ &lt;em&gt;immediately&lt;/em&gt; leaks $P_1 \oplus P_2$, but uniquely recovering the GHASH subkey $H$ generally needs two or more collisions. Never say &quot;one reuse leaks $H$&quot; [@joux-2006].The routinely mis-cited CVE-2016-0270 actually names IBM Domino, not OpenSSL, and NVD warns it &quot;has been incorrectly used for GCM nonce reuse issues in other products.&quot; The deployed GCM-nonce forgery is the Nonce-Disrespecting Adversaries paper, whose byline is exactly five authors: Boeck, Zauner, Devlin, Somorovsky, and Jovanovic [@cve-2016-0270][@nonce-disrespecting-2016].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; A bare confidentiality mode lets an attacker edit your plaintext undetected -- bit-for-bit in CTR and OFB, a surgical bit plus a garbled next block in CFB, and block-coupled in CBC. Use an AEAD, or Encrypt-then-MAC and verify the tag &lt;em&gt;before&lt;/em&gt; you decrypt a single byte.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The fix is to add the missing answer, and the order in which you add it turns out to matter. Bellare and Namprempre (2000) and Krawczyk (2001) proved that &lt;strong&gt;Encrypt-then-MAC&lt;/strong&gt; -- encrypt, then MAC the ciphertext, and verify the tag before decrypting -- generically yields both IND-CPA and INT-CTXT, a scheme that is confidential &lt;em&gt;and&lt;/em&gt; unforgeable, while MAC-then-encrypt and encrypt-and-MAC are fragile [@bellare-namprempre-2000][@krawczyk-2001].&lt;/p&gt;

A keyed tag that proves a message was not altered and came from someone holding the key. Anyone with the key can compute the tag over a message; without it, forging a valid tag is infeasible. HMAC, CMAC, and CBC-MAC are common constructions. A MAC supplies the integrity answer a confidentiality mode leaves blank.

SSL and early TLS shipped MAC-then-encrypt. The theory said Encrypt-then-MAC was the safe generic choice. That debate was not settled by proof alone -- it was settled by a decade of breaks (BEAST, Lucky Thirteen, POODLE) that all exploited the MAC-then-encrypt-plus-CBC-padding surface, until TLS 1.3 removed CBC outright and mandated authenticated encryption [@krawczyk-2001][@rfc-8446-tls13].
&lt;p&gt;Better still, fuse the two answers into one primitive.&lt;/p&gt;

A single primitive that provides confidentiality *and* integrity at once, and can also authenticate unencrypted &quot;associated data&quot; such as headers. It answers both questions in one object, so a modified ciphertext is rejected before any plaintext is released.
&lt;p&gt;The punchline binds this whole article together: the dominant &lt;em&gt;AES&lt;/em&gt; AEADs are literally these modes plus a MAC. &lt;strong&gt;GCM equals CTR plus GHASH&lt;/strong&gt;, a polynomial hash over $GF(2^{128})$ [@mcgrew-viega-2004][@nist-sp-800-38d]. &lt;strong&gt;CCM equals CTR plus CBC-MAC&lt;/strong&gt; [@rfc-3610-ccm][@nist-sp-800-38c]. The 1979 counter idea and the 1976 chaining idea, welded into a primitive that finally answers both questions -- the &lt;a href=&quot;https://paragmali.com/blog/the-connection-that-refused-to-downgrade-twenty-five-years-o&quot; rel=&quot;noopener&quot;&gt;SMB 3.1.1 post&lt;/a&gt; shows GCM and CCM running in a real protocol.&lt;/p&gt;

flowchart TD
    P[&quot;Plaintext&quot;] --&amp;gt; CTR[&quot;CTR encryption&quot;]
    CTR --&amp;gt; C[&quot;Ciphertext&quot;]
    C --&amp;gt; M[&quot;MAC over ciphertext and associated data&quot;]
    M --&amp;gt; T[&quot;Authentication tag&quot;]
    C --&amp;gt; W[&quot;Transmit ciphertext plus tag&quot;]
    T --&amp;gt; W
    W --&amp;gt; V{&quot;Tag valid?&quot;}
    V --&amp;gt;|&quot;no&quot;| X[&quot;Reject, decrypt nothing&quot;]
    V --&amp;gt;|&quot;yes&quot;| D[&quot;Decrypt and release plaintext&quot;]
&lt;p&gt;One boundary to keep honest: not every modern AEAD is built from these modes. ChaCha20-Poly1305 (a stream cipher plus Poly1305) and Ascon (a sponge permutation) are first-class AEADs that are deliberately &lt;em&gt;not&lt;/em&gt; SP 800-38A constructions [@rfc-8439-chacha20][@nist-sp-800-232]. The lineage claim is bounded to the AES AEADs.&lt;/p&gt;
&lt;p&gt;With integrity finally bolted on, every entry in the catalog retroactively dies -- a modified ciphertext fails the tag before a byte is decrypted. So the field declared victory and shipped AEAD everywhere. Then it discovered that AEAD did not repeal the IV/nonce contract. It &lt;em&gt;sharpened&lt;/em&gt; it -- which is exactly where the state of the art picks up.&lt;/p&gt;
&lt;h2&gt;6. The Field Is Retiring Confidentiality-Only Modes&lt;/h2&gt;
&lt;p&gt;The modern answer to &quot;which block cipher mode should I use?&quot; is &lt;em&gt;no bare confidentiality mode at all.&lt;/em&gt; It is a choice of AEAD, and between 2024 and 2026 that answer stopped being folklore and became written policy. The tell is what the standards bodies did &lt;em&gt;not&lt;/em&gt; do. Faced with four decades of breaks, nobody proposed a sixth confidentiality mode. Every document below reaches instead for authentication.&lt;/p&gt;
&lt;p&gt;Start with the audit. NIST IR 8459, published in September 2024 by Nicky Mouha and Morris Dworkin, is the first formal review of the entire SP 800-38 series, and it reads less like a specification than a post-mortem: it works through the family mode by mode, documenting why each keeps failing, and its recommendations point at authenticated encryption rather than a patched mode -- down to disallowing ECB for the very job it keeps losing at, encrypting secrets [@nist-ir-8459]. An audit whose answer to &quot;which new mode?&quot; is &quot;stop adding modes&quot; is this whole section in miniature.&lt;/p&gt;
&lt;p&gt;The policy machinery had already started turning. In April 2023 NIST&apos;s Crypto Publication Review Board published its decision to revise SP 800-38A itself, with goals that read like a confession: to &quot;limit the approval of the Electronic Codebook (ECB) mode,&quot; to &quot;provide guidance on the importance of incorporating authentication, where feasible,&quot; to fold in &quot;three variations of ciphertext stealing for Cipher Block Chaining mode,&quot; and -- once a stronger technique exists -- to &quot;consider deprecating the modes in SP 800-38A&quot; [@csrc-sp38a-revision-2023]. The document that defines the five modes is contemplating its own retirement, and names authenticated encryption as the successor it is waiting on.&lt;/p&gt;
&lt;p&gt;SP 800-131A Revision 3 supplies the compliance lever. Its initial public draft of October 21, 2024 disallows ECB for encrypting secret data and relegates it to legacy (decrypt-only) use; the draft&apos;s own phrase is &quot;the retirement of ECB as a confidentiality mode of operation&quot; [@nist-sp-800-131a-r3]. For a FIPS-bound product that is an effective-on-finalization change, not a suggestion.&lt;/p&gt;
&lt;p&gt;Where the field is heading is just as clear from what it &lt;em&gt;standardized&lt;/em&gt;. Ascon, finalized as NIST SP 800-232 in August 2025, is the new AEAD for the constrained, low-power class for which earlier standards specified AES-CCM -- and it is a sponge permutation, pointedly &lt;em&gt;not&lt;/em&gt; an SP 800-38A block cipher mode [@nist-sp-800-232]. &quot;Migrate to AEAD&quot; does not mean &quot;migrate to a mode.&quot; And for the one contract even AEADs still impose, AES-GCM-SIV (RFC 8452, 2019) is the standardized hedge: a nonce-misuse-resistant scheme that degrades gracefully instead of catastrophically when a nonce repeats [@rfc-8452-gcm-siv].&lt;/p&gt;

An AEAD that stays secure even when a nonce is accidentally reused, leaking at most whether two identical messages were sent under the same nonce, instead of collapsing into a two-time pad and forgery. AES-GCM-SIV reaches this by deriving its internal counter from a MAC of the whole message, so a repeat is a mild, bounded leak rather than a catastrophe [@rfc-8452-gcm-siv][@gcm-siv-spec-2017].

AES-GCM-SIV is engineered to be &quot;nonce misuse resistant -- that is, [it does] not fail catastrophically if a nonce is repeated.&quot; -- RFC 8452
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Document&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;NIST IR 8459 [@nist-ir-8459]&lt;/td&gt;
&lt;td&gt;audits the whole SP 800-38 series; steers ECB and secrets toward AEAD&lt;/td&gt;
&lt;td&gt;published, Sept 2024&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Decision to revise SP 800-38A [@csrc-sp38a-revision-2023]&lt;/td&gt;
&lt;td&gt;limit ECB, add CBC ciphertext stealing, urge authentication, weigh deprecation&lt;/td&gt;
&lt;td&gt;published, Apr 2023&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SP 800-131A Rev. 3 [@nist-sp-800-131a-r3]&lt;/td&gt;
&lt;td&gt;moves ECB to legacy (decrypt-only) use; disallowed for encrypting secrets on publication&lt;/td&gt;
&lt;td&gt;draft (Oct 21, 2024 IPD)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ascon (SP 800-232) [@nist-sp-800-232]&lt;/td&gt;
&lt;td&gt;a permutation AEAD for constrained devices, deliberately not a 38A mode&lt;/td&gt;
&lt;td&gt;final, Aug 2025&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AES-GCM-SIV (RFC 8452) [@rfc-8452-gcm-siv]&lt;/td&gt;
&lt;td&gt;a nonce-misuse-resistant AEAD hedge&lt;/td&gt;
&lt;td&gt;published, 2019&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The migration is credible &lt;em&gt;now&lt;/em&gt;, rather than merely aspirational, because the substrate already moved. TLS 1.3 (RFC 8446, 2018) removed every CBC-mode cipher suite and makes AES-GCM its mandatory-to-implement AEAD [@rfc-8446-tls13]; QUIC protects every packet with an AEAD, binding the packet number directly into the AEAD nonce, with no unauthenticated-confidentiality option at all [@rfc-9001-quic-tls].&lt;/p&gt;
&lt;p&gt;The performance objection that once favored CBC also evaporated: with AES-NI and the carry-less multiply instruction PCLMULQDQ, AES-GCM fell from roughly 3.7 cycles per byte in optimized software toward about 1, so the fast path and the safe path are now the same path [@krovetz-rogaway-ae-2011][@gcm-siv-spec-2017]. The 2024-2026 standards are simply retiring the confidentiality-only modes to match a deployment reality that migrated years earlier.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The modern &quot;which mode?&quot; question is really &quot;which AEAD?&quot; The five SP 800-38A confidentiality-only modes now survive as &lt;em&gt;internals&lt;/em&gt; of authenticated encryption and as legacy interoperability options -- not as something you deploy on purpose.&lt;/p&gt;
&lt;/blockquote&gt;

Not every SP 800-38 sibling is a confidentiality mode. SP 800-38G defines FF1 and FF3, *format-preserving* encryption that turns a 16-digit card number into another 16-digit string so it still fits a legacy database column [@nist-sp-800-38g]. Different goal, and it came with its own break: Durak and Vaudenay gave a practical total recovery of FF3 over small domains, a slide attack exploiting the design&apos;s &quot;bad domain separation&quot; in roughly $O(N^{11/6})$ chosen plaintexts [@durak-vaudenay-2017]. NIST responded with FF3-1, shrinking the tweak from 64 to 56 bits and raising the minimum domain to one million [@nist-sp-800-38g-r1]. Signposted here, not surveyed -- it is not one of the five.
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Reach for a vetted AEAD -- AES-GCM or ChaCha20-Poly1305 -- give it a unique nonce per key, cap your messages under the nonce limit, and drop to a raw confidentiality mode only as an Encrypt-then-MAC building block when an AEAD is genuinely unavailable.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The cross-references write themselves: the CBC-to-GCM migration is the story the &lt;a href=&quot;https://paragmali.com/blog/rotating-every-cipher-schannel-and-the-twenty-year-algorithm&quot; rel=&quot;noopener&quot;&gt;SChannel post&lt;/a&gt; tells for Windows TLS, and GCM and CCM running in a shipping protocol is what the &lt;a href=&quot;https://paragmali.com/blog/the-connection-that-refused-to-downgrade-twenty-five-years-o&quot; rel=&quot;noopener&quot;&gt;SMB 3.1.1 post&lt;/a&gt; shows. So the strategic direction is settled: move to AEAD. But &quot;AEAD&quot; is not one thing. The moment you have to &lt;em&gt;ship&lt;/em&gt;, the question sharpens from &quot;which mode?&quot; to &quot;which AEAD, with which parameters, for which platform?&quot; -- and that has a real, defensible answer.&lt;/p&gt;
&lt;h2&gt;7. When You Must Pick a Mode, and Which AEAD&lt;/h2&gt;
&lt;p&gt;Two comparisons matter in practice. The first is the intra-family one folklore gets wrong. The second is the one you actually face when you ship.&lt;/p&gt;
&lt;h3&gt;CBC versus CTR: a choice that changes nothing that matters&lt;/h3&gt;
&lt;p&gt;Both are confidentiality-only, both are malleable, and both are still everywhere. On the merits CTR is superior: fully parallel on encryption and decryption, random-access, and governed by the simplest contract (a unique nonce). CBC survives on forty years of deployment inertia, not on technical advantage -- Rogaway, having surveyed all five modes, reports &quot;no important advantages over CTR mode&quot; for CBC [@rogaway-modes-2011].&lt;/p&gt;
&lt;p&gt;But here is the point most tuning guides miss: swapping CBC for CTR fixes nothing that matters, because neither answers the second question. You trade a serial mode with padding for a parallel mode without it, and you keep every bit of the malleability. If your reason for the swap is security, you are solving the wrong problem.&lt;/p&gt;
&lt;h3&gt;Which AEAD&lt;/h3&gt;
&lt;p&gt;This is the comparison with real stakes, and every option is a defensible answer to a different constraint. AES-GCM is the throughput default on modern CPUs, hardware-accelerated by AES-NI and CLMUL, and brittle exactly where humans err -- a single reused nonce is catastrophic [@nist-sp-800-38d]. ChaCha20-Poly1305 is the software default: constant-time by construction, with no AES hardware and no cache-timing hazard [@rfc-8439-chacha20]. AES-CCM is CTR plus CBC-MAC, two-pass and small-footprint [@rfc-3610-ccm][@nist-sp-800-38c]; those documents define CCM, and its compact profile is why the IEEE wireless standards adopt it -- WPA2 (802.11i) [@krovetz-rogaway-ae-2011] and IEEE 802.15.4 low-power wireless [@rfc-4944][@rfc-9031] both build their link-layer security on it. AES-GCM-SIV is the nonce-misuse-resistant hedge [@rfc-8452-gcm-siv]. Ascon is the lightweight standard for microcontrollers [@nist-sp-800-232].&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;AEAD&lt;/th&gt;
&lt;th&gt;Built from&lt;/th&gt;
&lt;th&gt;Passes&lt;/th&gt;
&lt;th&gt;Constant-time&lt;/th&gt;
&lt;th&gt;Nonce-reuse penalty&lt;/th&gt;
&lt;th&gt;Best fit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;AES-GCM [@nist-sp-800-38d]&lt;/td&gt;
&lt;td&gt;CTR + GHASH&lt;/td&gt;
&lt;td&gt;1, online&lt;/td&gt;
&lt;td&gt;needs AES-NI, CLMUL&lt;/td&gt;
&lt;td&gt;catastrophic (forgery)&lt;/td&gt;
&lt;td&gt;server bulk, TLS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ChaCha20-Poly1305 [@rfc-8439-chacha20]&lt;/td&gt;
&lt;td&gt;stream + Poly1305&lt;/td&gt;
&lt;td&gt;1, online&lt;/td&gt;
&lt;td&gt;by construction (software)&lt;/td&gt;
&lt;td&gt;catastrophic&lt;/td&gt;
&lt;td&gt;mobile, no AES hardware&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AES-CCM [@rfc-3610-ccm]&lt;/td&gt;
&lt;td&gt;CTR + CBC-MAC&lt;/td&gt;
&lt;td&gt;2, not online&lt;/td&gt;
&lt;td&gt;needs AES-NI&lt;/td&gt;
&lt;td&gt;catastrophic&lt;/td&gt;
&lt;td&gt;WPA2, IoT, small code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AES-GCM-SIV [@rfc-8452-gcm-siv]&lt;/td&gt;
&lt;td&gt;POLYVAL-SIV + CTR&lt;/td&gt;
&lt;td&gt;2, not online&lt;/td&gt;
&lt;td&gt;needs AES-NI, CLMUL&lt;/td&gt;
&lt;td&gt;graceful (leak equality)&lt;/td&gt;
&lt;td&gt;nonce-uncertain systems&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ascon [@nist-sp-800-232]&lt;/td&gt;
&lt;td&gt;sponge permutation&lt;/td&gt;
&lt;td&gt;1 (duplex)&lt;/td&gt;
&lt;td&gt;easy to protect&lt;/td&gt;
&lt;td&gt;catastrophic&lt;/td&gt;
&lt;td&gt;microcontrollers, IoT&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The performance folklore is worth correcting too. The cleanest apples-to-apples software measurement, Krovetz and Rogaway at FSE 2011 on an Intel i5 &quot;Clarkdale,&quot; found CCM near 4.2 cycles per byte, GCM near 3.7, OCB near 1.5, and raw CTR near 1.3 [@krovetz-rogaway-ae-2011]. Read that as an &lt;em&gt;ordering&lt;/em&gt; under fixed effort, not a modern absolute: with mature AES-NI and CLMUL, AES-GCM reaches roughly 1 cycle per byte on current x86 [@gcm-siv-spec-2017]. The durable lesson is that hardware, not algorithm choice, moved GCM from 3.7 to 1 -- which is the whole reason CTR-based AEADs won.&lt;/p&gt;

The two non-38A AEADs from Section 5, ChaCha20-Poly1305 and Ascon, sit within a broader research lineage -- OCB, EAX, SIV/AES-SIV, IACBC/IAPM, McOE -- that is real but out of scope here; OCB is the elegant one-pass design that patents kept out of deployment for years [@rfc-7253-ocb].
&lt;p&gt;Every column wins on some axis and loses on another; none is unconditionally best. And the reasons &lt;em&gt;why&lt;/em&gt; no single scheme dominates are not engineering accidents. They are theorems. To use any of these correctly, you have to know the walls they are all pressed against.&lt;/p&gt;
&lt;h2&gt;8. You Cannot Get Integrity From a Confidentiality Mode&lt;/h2&gt;
&lt;p&gt;The two-question frame is not merely good advice. It is a theorem, and it draws a hard line no amount of clever engineering crosses.&lt;/p&gt;
&lt;p&gt;Start with the central impossibility. IND-CPA does not imply IND-CCA2 or non-malleability; BDJR proved ECB is not even IND-CPA and that CBC and CTR &lt;em&gt;are&lt;/em&gt; IND-CPA with proper IVs and nonces, but IND-CPA says nothing about an active attacker editing ciphertext [@bdjr-1997]. Bellare and Namprempre sharpened the target, separating INT-PTXT from INT-CTXT and proving that only Encrypt-then-MAC generically delivers IND-CPA plus INT-CTXT [@bellare-namprempre-2000][@krawczyk-2001].&lt;/p&gt;
&lt;p&gt;The consequence is a lower bound, not a tip: you cannot patch integrity into a bare CTR, CBC, CFB, or OFB mode, because malleability is a property of the confidentiality &lt;em&gt;goal&lt;/em&gt;, not a bug in any &lt;em&gt;construction&lt;/em&gt;. This is the reasoning &lt;a href=&quot;https://paragmali.com/blog/secure-against-whom-the-security-definitions-every-protocol-&quot; rel=&quot;noopener&quot;&gt;Part 1&lt;/a&gt; sets up in full.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; &quot;Confidentiality does not imply integrity&quot; is a theorem, not advice. IND-CPA does not imply IND-CCA2 or non-malleability, so you cannot patch integrity into a bare CTR, CBC, CFB, or OFB mode. It is a property of the goal, not a bug in the construction.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The second wall is the block size.&lt;/p&gt;

The threshold at which collisions among random $n$-bit values become likely: around $2^{n/2}$ of them. For a block cipher it means ciphertext blocks start repeating -- and leaking $P_i \oplus P_j$ -- after roughly $2^{n/2}$ blocks, regardless of key length. This is the ceiling behind Sweet32 and the GCM nonce cap.
&lt;p&gt;Ciphertext-collision leakage grows like $q^2 / 2^n$ in the number of blocks $q$, so security degrades at about $q \approx 2^{n/2}$ blocks: roughly $2^{32}$ blocks (about 32 GiB) for a 64-bit cipher, which is the Sweet32 ceiling, and $2^{64}$ blocks for AES [@bdjr-1997][@sweet32-2016]. A provable ceiling, independent of key size -- doubling the key does not move it.&lt;/p&gt;
&lt;p&gt;GCM inherits its own two ceilings, and conflating them is a common error. Per SP 800-38D, a single message is capped at $2^{39} - 256$ bits (about 64 GiB), and, under random 96-bit nonces, the number of invocations per key must stay below about $2^{32}$ to keep the nonce-collision probability negligible [@nist-sp-800-38d]. One is a length limit; the other is a count limit. They are different numbers that both bite.&lt;/p&gt;
&lt;p&gt;The last wall is the sharpest, because no computational assumption stands behind it. Reusing a $(\text{key}, \text{nonce})$ in any keystream mode leaks $C_1 \oplus C_2 = P_1 \oplus P_2$ -- a two-time pad. You can watch it recover a plaintext with nothing but XOR:&lt;/p&gt;
&lt;p&gt;{`
// Reusing a (key, nonce) reproduces the SAME keystream. That is a two-time pad.
function xorBytes(a, b) { return a.map(function (x, i) { return x ^ b[i]; }); }
function toBytes(s) { return Array.from(s).map(function (c) { return c.charCodeAt(0); }); }
function toStr(b) { return b.map(function (x) { return String.fromCharCode(x); }).join(&apos;&apos;); }&lt;/p&gt;
&lt;p&gt;var p1 = &apos;attack at dawn&apos;;
var p2 = &apos;defend the fort&apos;;
var n = Math.min(p1.length, p2.length);
var ks = toBytes(&apos;REUSEDPADREUSEDPAD&apos;).slice(0, n);   // the SAME pad used twice -- the bug&lt;/p&gt;
&lt;p&gt;var c1 = xorBytes(toBytes(p1).slice(0, n), ks);
var c2 = xorBytes(toBytes(p2).slice(0, n), ks);&lt;/p&gt;
&lt;p&gt;// The attacker never has the key. He XORs the two ciphertexts; the pad cancels:
var leaked = xorBytes(c1, c2);                         // equals p1 XOR p2&lt;/p&gt;
&lt;p&gt;// With a crib -- a good guess at p1 -- he recovers p2 outright:
var crib = toBytes(&apos;attack at dawn&apos;).slice(0, n);
console.log(&apos;Recovered from a crib: &apos; + toStr(xorBytes(leaked, crib)));  // defend the for
`}&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Reusing a $(\text{key}, \text{nonce})$ leaks $P_1 \oplus P_2$ with no computational assumption to fall back on -- no key length saves you. In GCM it is worse: repeated nonces also expose the GHASH subkey $H$ -- uniquely, once two or more collisions accumulate -- enabling universal forgery [@joux-2006][@nist-sp-800-38d].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The core science, then, is closed. &quot;Confidentiality does not imply integrity&quot; is settled, reuse is an information-theoretic floor, and the block-size wall is provable. If the theory is finished, what is left to work on? More than you would guess -- and it is where the modes still bite.&lt;/p&gt;
&lt;h2&gt;9. Where Modes Still Bite&lt;/h2&gt;
&lt;p&gt;The confidentiality-versus-integrity fight is won. The live frontier is one level up: not &quot;is it confidential?&quot; but &quot;how &lt;em&gt;resilient&lt;/em&gt; is the authenticated scheme when humans and hardware misbehave?&quot; Four problems are genuinely open, and one popular worry is not a problem at all.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Make nonce-misuse-resistance the default, not the hedge.&lt;/strong&gt; AES-GCM fails catastrophically on nonce reuse, yet reuse -- from stateless senders, VM clones, restarted counters -- is among the most common real misuses [@nist-sp-800-38d]. AES-GCM-SIV delivers graceful degradation at roughly 1 cycle per byte and up to $2^{50}$ messages per key, &quot;well suited for real world applications that need a nonce-misuse resistant Authenticated Encryption scheme&quot; [@gcm-siv-spec-2017].&lt;/p&gt;
&lt;p&gt;But it is two-pass and offline, and it remains opt-in. The open problem is an AEAD that is online, single-pass, parallel, roughly 1 cycle per byte, &lt;em&gt;and&lt;/em&gt; misuse-resistant at once -- and, harder, getting TLS and KMS libraries to make it the default. NIST IR 8459 flags nonce management across the whole SP 800-38 series as a first-order concern [@nist-ir-8459].&lt;/p&gt;

The property that binds a ciphertext to the single key and context that produced it, so it cannot be made to decrypt validly under a second key. Standard AEAD security says nothing about it, which is why AES-GCM and ChaCha20-Poly1305 lack it -- and why a ciphertext can be crafted to open to two different valid plaintexts under two different keys.
&lt;p&gt;&lt;strong&gt;Key commitment and robustness.&lt;/strong&gt; AES-GCM and ChaCha20-Poly1305 are not key-committing: a single ciphertext can be built to decrypt to valid plaintexts under &lt;em&gt;two&lt;/em&gt; different keys [@key-commitment-2022]. Real systems assume otherwise, so this breaks password-based encryption, message franking, and envelope schemes.&lt;/p&gt;
&lt;p&gt;Partitioning-oracle attacks turned that gap into practical password recovery against Shadowsocks proxies; the same study only &lt;em&gt;surveyed&lt;/em&gt; protocols such as OPAQUE as potentially vulnerable rather than breaking them [@partitioning-oracles-2021]. The &quot;invisible salamanders&quot; attack built AES-GCM ciphertexts that decrypt to valid files under two keys, defeating message franking [@fast-franking-2018], a technique later generalized across file formats [@key-commitment-2022]. A genuine lower bound -- compactly committing AE is provably impossible at AES-GCM&apos;s exact performance profile [@fast-franking-2018] -- meets a cheap upper bound -- committing GCM and GCM-SIV variants at no ciphertext expansion [@committing-ae-2022]. The bounds nearly meet, yet the deployed default still sits on the wrong side.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Constant-time implementation.&lt;/strong&gt; CBC-decrypt-then-MAC timing gave us Lucky Thirteen, and table-based AES and GHASH leak through cache [@lucky-thirteen-2013]. This is effectively solved on hardware with AES-NI and CLMUL, and ChaCha20-Poly1305 is constant-time by design [@rfc-8439-chacha20]. It stays a live hazard on microcontrollers and throughout the legacy CBC base.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The forty-year migration.&lt;/strong&gt; A vast deployed base still runs CBC and 64-bit block ciphers, keeping Sweet32 and padding oracles alive. TLS 1.3 removed CBC-mode cipher suites and mandates AEAD [@rfc-8446-tls13], and IR 8459 audits the whole series [@nist-ir-8459], but embedded firmware, file-format crypto, database encryption, and private protocols lag by years. This is an engineering and logistics problem, not a mathematical one -- and it is the one that keeps the Failure Catalog growing.&lt;/p&gt;

A widespread belief holds that quantum computers break block cipher modes. To first order they do not: Grover&apos;s algorithm gives only a quadratic speedup on key search, so doubling the key (AES-256) restores the margin. The post-quantum churn is in key exchange and signatures, not in symmetric modes or AEADs [@nist-ir-8105].
&lt;p&gt;None of these is a hole in the confidentiality-versus-integrity theory. All are the gap between the ideal AEAD and the one you can install today -- which is exactly the gap a practitioner has to bridge. So here are the rules that bridge it.&lt;/p&gt;
&lt;h2&gt;10. Use X With These Params In Case Y&lt;/h2&gt;
&lt;p&gt;Everything so far collapses into one rule and a short decision tree you can apply without re-deriving a theorem. The rule: use a vetted AEAD, not a raw confidentiality mode [@ferguson-schneier-kohno-2010].&lt;/p&gt;
&lt;p&gt;The decision guide, in priority order:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Default:&lt;/strong&gt; AES-GCM with a 96-bit nonce, unique per key -- prefer a deterministic counter -- and a hard cap of fewer than $2^{32}$ messages per key [@nist-sp-800-38d].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cannot guarantee unique nonces:&lt;/strong&gt; AES-GCM-SIV [@rfc-8452-gcm-siv], or XChaCha20-Poly1305, which widens the RFC 8439 ChaCha20-Poly1305 construction to a 192-bit random nonce [@rfc-8439-chacha20].The 192-bit-nonce XChaCha20 variant is specified in the IRTF draft draft-irtf-cfrg-xchacha, not in RFC 8439, which standardizes only the 96-bit ChaCha20-Poly1305 [@rfc-8439-chacha20]. The wider nonce is exactly what lets you pick nonces at random without tracking a counter.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No fast AES hardware, or you need constant-time software:&lt;/strong&gt; ChaCha20-Poly1305 [@rfc-8439-chacha20].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Constrained or IoT, small code budget:&lt;/strong&gt; Ascon-AEAD128 [@nist-sp-800-232] or AES-CCM [@rfc-3610-ccm].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Need key or context commitment&lt;/strong&gt; (password-based encryption, franking, envelope, rotation): a committing AEAD [@committing-ae-2022].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Must drop to a raw mode&lt;/strong&gt; (interoperability or a FIPS boundary): CTR plus Encrypt-then-MAC (CMAC or HMAC) with a unique nonce, or CBC only with a fresh &lt;em&gt;unpredictable&lt;/em&gt; IV plus Encrypt-then-MAC plus constant-time padding [@nist-sp-800-38a][@bellare-namprempre-2000].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Streaming or large objects:&lt;/strong&gt; do not ship one monolithic AEAD blob you cannot buffer. Split the stream into records, give each a unique per-chunk nonce, and authenticate a sequence number plus an explicit end-of-stream marker, so a dropped, reordered, or truncated record is caught rather than silently accepted. This is the record-protocol pattern DTLS 1.3 uses -- rejecting duplicates through &quot;a sliding receive window&quot; -- and that QUIC uses by binding each packet number into its AEAD nonce; together they close truncation and replay, the two integrity gaps a bare mode cannot see [@smyth-pironti-2013][@rfc-9147-dtls13][@rfc-9001-quic-tls].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Never:&lt;/strong&gt; ECB for messages, a 64-bit block cipher for bulk data, a reused nonce, or &quot;encryption&quot; with no integrity tag.&lt;/li&gt;
&lt;/ol&gt;

flowchart TD
    Start[&quot;Need to encrypt a message&quot;] --&amp;gt; Q1{&quot;Is a vetted AEAD available?&quot;}
    Q1 --&amp;gt;|&quot;no&quot;| Raw[&quot;CTR or CBC plus Encrypt-then-MAC, verify tag first&quot;]
    Q1 --&amp;gt;|&quot;yes&quot;| Q2{&quot;Can you guarantee unique nonces?&quot;}
    Q2 --&amp;gt;|&quot;no&quot;| NMR[&quot;AES-GCM-SIV or XChaCha20-Poly1305 (192-bit nonce)&quot;]
    Q2 --&amp;gt;|&quot;yes&quot;| Q3{&quot;Fast AES hardware present?&quot;}
    Q3 --&amp;gt;|&quot;no&quot;| Chacha[&quot;ChaCha20-Poly1305&quot;]
    Q3 --&amp;gt;|&quot;yes&quot;| Q4{&quot;Constrained device?&quot;}
    Q4 --&amp;gt;|&quot;yes&quot;| Small[&quot;Ascon-AEAD128 or AES-CCM&quot;]
    Q4 --&amp;gt;|&quot;no&quot;| GCM[&quot;AES-GCM, 96-bit nonce, fewer than 2^32 messages per key&quot;]
&lt;p&gt;When you do touch a raw mode, the contract is the whole game. &lt;a href=&quot;https://paragmali.com/blog/predictable-or-repeated-the-only-two-ways-cryptographic-rand&quot; rel=&quot;noopener&quot;&gt;Part 2&lt;/a&gt; covers how to &lt;em&gt;generate&lt;/em&gt; these values; this table says what each mode &lt;em&gt;requires&lt;/em&gt;:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;Requirement&lt;/th&gt;
&lt;th&gt;Consequence of violation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;ECB&lt;/td&gt;
&lt;td&gt;none (and that is the flaw)&lt;/td&gt;
&lt;td&gt;determinism leaks block equality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CBC&lt;/td&gt;
&lt;td&gt;unpredictable and unique IV&lt;/td&gt;
&lt;td&gt;a predictable IV enables BEAST&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CFB&lt;/td&gt;
&lt;td&gt;unpredictable and unique IV&lt;/td&gt;
&lt;td&gt;a predictable IV enables chosen-plaintext distinguishing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OFB&lt;/td&gt;
&lt;td&gt;unique nonce&lt;/td&gt;
&lt;td&gt;reuse is a two-time pad&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CTR&lt;/td&gt;
&lt;td&gt;unique nonce (unpredictability not required)&lt;/td&gt;
&lt;td&gt;reuse is a two-time pad&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Those requirements come straight from SP 800-38A [@nist-sp-800-38a]; the raw bytes that satisfy them come from a CSPRNG, which the &lt;a href=&quot;https://paragmali.com/blog/a-key-is-only-as-unguessable-as-the-dice-that-made-it-inside&quot; rel=&quot;noopener&quot;&gt;Windows CSPRNG post&lt;/a&gt; covers, and the real API calls that wire AES-CBC and AES-GCM together live in the &lt;a href=&quot;https://paragmali.com/blog/cng-architecture-bcrypt-ncrypt-ksps&quot; rel=&quot;noopener&quot;&gt;CNG post&lt;/a&gt;. Finally, every common misuse maps one-to-one to a named break and its fix:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Misuse&lt;/th&gt;
&lt;th&gt;Named break&lt;/th&gt;
&lt;th&gt;Fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;ECB for structured data&lt;/td&gt;
&lt;td&gt;Adobe 2013 [@troyhunt-adobe-2013]&lt;/td&gt;
&lt;td&gt;AEAD over AES&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;static or predictable IV&lt;/td&gt;
&lt;td&gt;BEAST [@cve-2011-3389]&lt;/td&gt;
&lt;td&gt;fresh unpredictable IV, or an AEAD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;reused GCM nonce&lt;/td&gt;
&lt;td&gt;Nonce-Disrespecting Adversaries [@nonce-disrespecting-2016]&lt;/td&gt;
&lt;td&gt;counter nonces, or GCM-SIV / XChaCha&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MAC-then-encrypt or encrypt-and-MAC&lt;/td&gt;
&lt;td&gt;Lucky Thirteen [@lucky-thirteen-2013]&lt;/td&gt;
&lt;td&gt;Encrypt-then-MAC, verify before decrypt&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;no integrity at all&lt;/td&gt;
&lt;td&gt;Efail [@efail-2018]&lt;/td&gt;
&lt;td&gt;an AEAD, or Encrypt-then-MAC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;64-bit block cipher for bulk&lt;/td&gt;
&lt;td&gt;Sweet32 [@sweet32-2016]&lt;/td&gt;
&lt;td&gt;a 128-bit-block AEAD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;truncation with no length integrity&lt;/td&gt;
&lt;td&gt;Truncation, Smyth-Pironti [@smyth-pironti-2013]&lt;/td&gt;
&lt;td&gt;authenticate length and end-of-stream&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

Run `openssl s_client -connect example.com:443 -tls1_3` and read the `Cipher` line: a modern server reports an AEAD such as `TLS_AES_128_GCM_SHA256` or `TLS_CHACHA20_POLY1305_SHA256`. If you instead see a suite with `CBC` in the name, you are looking at a legacy, malleable-mode configuration that belongs on the migration list.
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Read every mode as a building block with an exact IV/nonce contract, and read every break as a missing integrity answer or a violated contract. Default to an AEAD; touch a raw mode only under Encrypt-then-MAC discipline, and only when an AEAD is off the table.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Notice that every rule is the same rule wearing different clothes: pick the primitive that answers &lt;em&gt;both&lt;/em&gt; questions, and honor its IV/nonce contract. The folklore that gets this wrong is dense enough to deserve its own section.&lt;/p&gt;
&lt;h2&gt;11. Misconceptions, Named and Corrected&lt;/h2&gt;
&lt;p&gt;Seven half-truths cause real incidents. Each dissolves under the same two-question lens.&lt;/p&gt;


No. All five SP 800-38A modes are malleable, so an attacker who cannot read your ciphertext can still predictably edit the plaintext -- bit-for-bit in the additive keystream modes CTR and OFB, block-coupled in CBC, and a mix of the two in CFB. Confidentiality and integrity are different guarantees; you need a MAC or an AEAD to get the second one, and encryption alone does not provide it.


Only as a building block, never as a message-encryption mode. The raw single-block permutation is legitimate inside key wrap and CMAC or CBC-MAC. But ECB is deterministic, so the moment your data has any structure or repetition it leaks block equality -- which is why NIST is moving ECB to legacy use [@nist-sp-800-131a-r3]. The rule is &quot;never ECB for messages,&quot; not &quot;ECB has no use anywhere.&quot;


No. A random IV fixes ECB&apos;s determinism, but it adds no integrity -- the mode is still malleable. And the requirement is not uniform: CBC and CFB need an *unpredictable* IV, while CTR and OFB need only a *unique* nonce [@nist-sp-800-38a]. Getting that distinction wrong is exactly what BEAST exploited.


No. Under random 96-bit nonces you must stay below roughly $2^{32}$ invocations per key to keep the nonce-collision probability negligible [@nist-sp-800-38d]. Past that, a repeat becomes likely, and a repeated GCM nonce fails catastrophically. If you cannot count, use AES-GCM-SIV or XChaCha20-Poly1305 instead.


That fixes nothing that matters. Both are confidentiality-only and both are malleable; swapping one for the other trades performance characteristics, not security [@rogaway-modes-2011]. The fix is an AEAD, not a different malleable mode.


Not under nonce reuse. A single repeated $(\text{key}, \text{nonce})$ leaks $P_1 \oplus P_2$, and with two or more collisions it recovers the GHASH subkey $H$, enabling universal forgery -- Joux&apos;s &quot;forbidden attack,&quot; which was later found live on real TLS servers [@joux-2006][@nonce-disrespecting-2016]. GCM is only as strong as its nonce discipline.


Order matters. MAC-then-encrypt and encrypt-and-MAC are fragile and produced Lucky Thirteen and the padding-oracle family [@lucky-thirteen-2013]. The proven-safe generic composition is Encrypt-then-MAC: authenticate the ciphertext and verify the tag *before* you decrypt [@bellare-namprempre-2000].

&lt;p&gt;Every one dissolves into the same sentence -- which is where this started, and where it ends.&lt;/p&gt;
&lt;h2&gt;Two Questions, Forty Years&lt;/h2&gt;
&lt;p&gt;Return to the opening. A ciphertext AES kept perfectly secret, rewritten in transit by an attacker who never read a byte of it, and accepted as authentic -- because the mode answered only the first of two questions. That was not an exotic failure. It was the ordinary shape of every break in this article.&lt;/p&gt;
&lt;p&gt;Run the catalog back through the lens and the pattern is total. Adobe [@troyhunt-adobe-2013], Vaudenay&apos;s padding oracle [@vaudenay-2002], BEAST [@cve-2011-3389], Lucky Thirteen [@lucky-thirteen-2013], POODLE [@cve-2014-3566], Sweet32 [@cve-2016-2183], Efail [@efail-2018], and GCM nonce reuse [@nonce-disrespecting-2016]: in every case, AES or DES did exactly what it promised, and the variable was always &lt;em&gt;which question the design forgot&lt;/em&gt; or &lt;em&gt;which IV/nonce contract it violated&lt;/em&gt;. Not one of these was a cipher break.&lt;/p&gt;
&lt;p&gt;Read that way, the 2024-2026 state of the art is a single move. The field stopped iterating confidentiality modes and standardized the &lt;em&gt;second&lt;/em&gt; answer. Authenticated encryption is the destination -- and its dominant AES instances, GCM and CCM, are literally these very modes plus a MAC, while ChaCha20-Poly1305 and Ascon supply a parallel lineage that is not [@nist-ir-8459][@nist-sp-800-232]. The frontier moved with it: nonce-misuse resistance and key commitment are the properties the deployed defaults still lack.&lt;/p&gt;
&lt;p&gt;The payoff of the field guide is the same as its premise. Master the five not as interchangeable dropdown options but as building blocks with exact contracts, and every break -- past or future -- becomes readable on sight. You do not need to memorize the next CVE. You need one test, and you already have it: &lt;em&gt;which question did this mode answer, and was its IV/nonce contract honored?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;That lens outlives every mode, every cipher, and every standard revision. Which is why this is Part 5 of a field guide to protocol design, not a chapter on five diagrams.&lt;/p&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;block-cipher-modes-ecb-to-ctr&quot; keyTerms={[
  { term: &quot;Block cipher&quot;, definition: &quot;A keyed, invertible permutation on one fixed-size block of bits (64 for DES, 128 for AES).&quot; },
  { term: &quot;Mode of operation&quot;, definition: &quot;The wrapper that lifts a one-block cipher to messages of arbitrary length.&quot; },
  { term: &quot;IND-CPA&quot;, definition: &quot;Indistinguishability under chosen-plaintext attack; it forces secure encryption to be randomized or stateful.&quot; },
  { term: &quot;Initialization Vector (IV)&quot;, definition: &quot;A per-message starting value; it must be unpredictable for CBC and CFB.&quot; },
  { term: &quot;Nonce&quot;, definition: &quot;A number used once per key; CTR and OFB need it unique, not unpredictable.&quot; },
  { term: &quot;Malleability&quot;, definition: &quot;An attacker can turn a ciphertext into a predictable change of the plaintext, with no key.&quot; },
  { term: &quot;Message Authentication Code (MAC)&quot;, definition: &quot;A keyed integrity tag that supplies the answer a confidentiality mode omits.&quot; },
  { term: &quot;AEAD&quot;, definition: &quot;Authenticated Encryption with Associated Data; confidentiality and integrity in one primitive.&quot; },
  { term: &quot;Birthday bound&quot;, definition: &quot;Collisions among n-bit values become likely near 2 to the n over 2; the block-size ceiling.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>block-cipher-modes</category><category>aes</category><category>authenticated-encryption</category><category>aead</category><category>cryptography</category><category>cbc</category><category>ctr</category><category>gcm</category><author>noreply@paragmali.com (Parag Mali)</author></item></channel></rss>