<?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: hqc</title><description>Posts tagged hqc.</description><link>https://paragmali.com/</link><language>en-US</language><lastBuildDate>Sat, 25 Jul 2026 08:57:55 GMT</lastBuildDate><atom:link href="https://paragmali.com/tags/hqc/rss.xml" rel="self" type="application/rss+xml"/><item><title>The Hedge and Its Fault Line: How Classic McEliece and HQC Would Break</title><link>https://paragmali.com/blog/the-hedge-and-its-fault-line-how-classic-mceliece-and-hqc-wo/</link><guid isPermaLink="true">https://paragmali.com/blog/the-hedge-and-its-fault-line-how-classic-mceliece-and-hqc-wo/</guid><description>Classic McEliece and HQC hedge post-quantum encryption on syndrome decoding, a problem unrelated to lattices -- and here is where their own math gives way.</description><pubDate>Sat, 18 Jul 2026 00:00:00 GMT</pubDate><content:encoded>
**Classic McEliece and HQC are the post-quantum hedge.** Their security rests on decoding a random-looking error-correcting code, a problem with no known link to the lattices under ML-KEM, so a lattice break would not cost them a single bit. Their own most-likely failure is not exotic: it is information-set decoding, the 60-year-old generic attack that already retired McEliece&apos;s original 1978 *parameters* (at roughly $2^{60}$ operations) without ever touching its binary-Goppa *structure*, and that has moved the security exponent only about 15 to 20 percent in 56 years. The deeper, less-likely threat is a structural distinguisher on the code family; the 2024 syzygy result finally reaches Classic McEliece parameters but is still a distinguisher, not a break. Neither fault line has reached recommended parameters -- which is exactly why holding two unrelated hard problems beats betting everything on one.
&lt;h2&gt;1. A Hedge Against a Single Point of Failure&lt;/h2&gt;
&lt;p&gt;In March 2025, having already chosen a lattice-based encryption standard it had spent eight years vetting, NIST did something that looks, at first glance, like betting against its own decision: it selected a &lt;em&gt;second&lt;/em&gt; key-encapsulation mechanism, built on a bruised-looking idea from 1978, whose entire job is to fail differently [@nist-hqc-announce].&lt;/p&gt;
&lt;p&gt;Classic McEliece and its quasi-cyclic cousin HQC do not rest on lattices, or on factoring, or on discrete logarithms. They rest on the difficulty of decoding a random-looking error-correcting code, a problem so unrelated to the others that if lattice cryptography were shattered tomorrow, these schemes would not lose a single bit of security. That independence is the entire point. It is also the thing that tells you exactly where to look for how they would break.&lt;/p&gt;
&lt;p&gt;Two standardized KEMs now sit on two unrelated hard problems. ML-KEM, standardized as FIPS 203 in August 2024, reduces to Module-LWE, a lattice problem [@nist-fips-203]. HQC, selected in March 2025 as the second KEM after ML-KEM, reduces to quasi-cyclic syndrome decoding, a coding problem [@nist-hqc-announce]. Behind them stands Classic McEliece, the ultra-conservative elder whose one-wayness assumption &quot;has remained remarkably stable, despite half a century of attack papers&quot; [@classic-mceliece-site].&lt;/p&gt;
&lt;p&gt;The reason to hold two problems instead of one is written into recent history: vetted finalists fall. Ward Beullens recovered a Rainbow signing key over a single weekend [@rainbow-eprint-2022-214], and Wouter Castryck and Thomas Decru broke SIKE in an afternoon on one core [@sike-eprint-2022-975]. Each had survived years of scrutiny before one new idea ended it.&lt;/p&gt;

flowchart TD
    LB[&quot;A future break of lattice cryptography&quot;] --&amp;gt; ML[&quot;ML-KEM, built on Module-LWE&quot;]
    ML --&amp;gt; F1[&quot;Lattice-based encryption falls&quot;]
    LB -. no known reduction .-&amp;gt; CB[&quot;HQC and Classic McEliece, built on syndrome decoding&quot;]
    CB --&amp;gt; F2[&quot;Code-based encryption stands&quot;]
&lt;p&gt;This article analyzes only the mathematics: how the algorithms themselves would give way under cryptanalysis. Side-channel leaks, fault injection, random-number failures, and protocol misuse are real, but they attack an implementation, not the problem, and they belong to the companion piece &quot;How the NIST Finalists Broke.&quot;&lt;/p&gt;
&lt;p&gt;Two fault lines belong here. The first is information-set decoding, the generic attack that prices every code-based parameter. The second is a structural distinguisher, an algorithm that would notice the code is not random after all. If a lattice break truly does not touch these schemes, what exactly would? To answer that, you first have to see why the two hard problems are strangers.&lt;/p&gt;
&lt;h2&gt;2. Two Hard Problems, Not One&lt;/h2&gt;
&lt;p&gt;What makes two hard problems &lt;em&gt;independent&lt;/em&gt; enough that betting on both is safer than betting on one? Not that both are hard. Independence means a solution to one buys you nothing against the other. That is a strong claim, and code-based cryptography earns it honestly.&lt;/p&gt;
&lt;p&gt;Start with the problem itself. An error-correcting code adds redundancy so a receiver can repair a noisy message. A parity-check matrix $H$ describes the redundancy: a vector is a valid codeword exactly when $H$ maps it to zero. Feed $H$ a corrupted word instead, and it returns a short fingerprint of the corruption called the syndrome. The attacker&apos;s task is to run that backward.&lt;/p&gt;

Given a parity-check matrix $H$ over $\mathbb{F}_2$ and a syndrome vector $\mathbf{s}$, find the lowest-weight error vector $\mathbf{e}$ satisfying $H\mathbf{e}^{\top} = \mathbf{s}$. Equivalently, find the nearest codeword to a received word. This is the computational problem every code-based scheme rests on.

A binary linear code of length $n$ and dimension $k$ is a $k$-dimensional subspace of $\mathbb{F}_2^n$. A generator matrix $G$ produces codewords as linear combinations of its $k$ rows; a parity-check matrix $H$ satisfies $H\mathbf{c}^{\top} = \mathbf{0}$ for every codeword $\mathbf{c}$. The fraction $k/n$ is the code&apos;s rate, and it turns out to be a security knob, not just an efficiency one.
&lt;p&gt;In 1978, the same year McEliece published his cipher, Elwyn Berlekamp, Robert McEliece, and Henk van Tilborg proved that this decoding problem is NP-complete [@bmvt-1978]. That badge is the strongest worst-case anchor any deployed public-key system has. It is also, we will see in section 12, a promise the schemes cannot fully cash: NP-completeness is a statement about the &lt;em&gt;worst&lt;/em&gt; case, while the deployed schemes rest on the &lt;em&gt;average&lt;/em&gt; case of a &lt;em&gt;specific structured&lt;/em&gt; family, and no reduction bridges the two. Hold that thought; the honest security story lives there.&lt;/p&gt;
&lt;p&gt;The syndrome you are chasing is a concrete object. Here is one small enough to hold in your hand.&lt;/p&gt;
&lt;p&gt;{`&lt;/p&gt;
Parity-check matrix H (4 x 7) over F2, and a weight-2 error e.
&lt;p&gt;H = [
    [1, 0, 0, 1, 0, 1, 1],
    [0, 1, 0, 1, 1, 0, 1],
    [0, 0, 1, 0, 1, 1, 1],
    [1, 1, 0, 0, 1, 0, 0],
]
e = [0, 1, 0, 0, 0, 1, 0]   # Hamming weight 2&lt;/p&gt;
Syndrome s = H . e^T, each entry reduced mod 2.
&lt;p&gt;s = [sum(H[i][j] * e[j] for j in range(len(e))) % 2 for i in range(len(H))]
print(&quot;error weight:&quot;, sum(e))
print(&quot;syndrome s   :&quot;, s)&lt;/p&gt;
The attacker sees only H and s, and must recover the weight-2 e.
Doing that with no trapdoor is information-set decoding.
&lt;p&gt;`}&lt;/p&gt;
&lt;p&gt;Now the independence claim. &lt;a href=&quot;https://paragmali.com/blog/two-standards-one-lattice-how-ml-kem-and-ml-dsa-would-break/&quot; rel=&quot;noopener&quot;&gt;Lattice cryptography&lt;/a&gt;, the subject of Part 6 of this series, rests on problems like Learning With Errors, where you recover a secret from noisy linear equations over a large modulus. Syndrome decoding lives over $\mathbb{F}_2$ and measures noise by Hamming weight, not Euclidean distance. There is &lt;em&gt;no known reduction&lt;/em&gt; in either direction between the two, and &quot;no known reduction&quot; is the exact, non-overstated phrasing: not a proof of independence, but the honest state of decades of trying [@overbeck-sendrier-2009].&lt;/p&gt;
&lt;p&gt;The two worlds do share some &lt;em&gt;tooling&lt;/em&gt;. The fastest modern decoders and the fastest lattice sieves both reduce, deep down, to nearest-neighbor search [@may-ozerov-2015]. That is a shared &lt;em&gt;algorithm&lt;/em&gt;, not a shared &lt;em&gt;assumption&lt;/em&gt;: a faster nearest-neighbor routine nudges both cost estimates, but it does not let a lattice break read out a code secret.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Because syndrome decoding has no known reduction to or from lattice problems, a break of lattice cryptography does not debit code-based cryptography. The hedge is not a slogan. It is the absence of a mathematical bridge between the two assumptions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So the hardness is real and, as far as anyone knows, unrelated to the lattice bet. But hardness alone is not a cipher. Turning &quot;decoding a random code is hard&quot; into public-key encryption took a specific 1978 trick: hiding a code you can secretly decode.&lt;/p&gt;
&lt;h2&gt;3. A Stranger Question: McEliece (1978) and Niederreiter (1986)&lt;/h2&gt;
&lt;p&gt;RSA had appeared in 1977, founding public-key encryption on number theory [@mceliece-comparison]. Robert McEliece, then a staff member at NASA&apos;s Jet Propulsion Laboratory, which Caltech operates for NASA and where coding theory was daily bread for talking to deep-space probes, asked a stranger question the very next year: could you build public-key encryption on &lt;em&gt;coding theory&lt;/em&gt; instead?The 1978 scheme is a JPL publication, not a Caltech academic paper. McEliece worked at JPL through 1978, was a professor at the University of Illinois at Urbana-Champaign from 1978 to 1982, and joined the Caltech electrical-engineering faculty only in 1982 [@caltech-obituary, @wikipedia-mceliece].&lt;/p&gt;
&lt;p&gt;His answer, published in a JPL progress report rather than a cryptography venue, is the oldest public-key encryption scheme whose underlying hardness assumption has never been broken, including against a quantum computer [@mceliece-1978].RSA, a year older, is still classically secure, so McEliece is not the oldest public-key scheme outright. Its narrower and load-bearing claim to seniority is that its hardness assumption has never fallen, and unlike RSA&apos;s factoring assumption it does not fall to Shor&apos;s algorithm either [@bernstein-2010].&lt;/p&gt;
&lt;p&gt;The trick is disguise. Take a binary Goppa code, an algebraic code with a secret description that makes error correction fast. Scramble its generator matrix by multiplying on both sides, $G&apos; = SGP$, where $S$ is an invertible matrix and $P$ a permutation. Publish $G&apos;$, which now looks like the generator of a random code.&lt;/p&gt;
&lt;p&gt;To encrypt a message $\mathbf{m}$, compute $\mathbf{m}G&apos;$ and add a random error vector $\mathbf{e}$ of Hamming weight $t$. Only the holder of $(S, G, P)$ can undo the scramble and run the fast Goppa decoder to strip the $t$ errors; everyone else faces generic decoding of a code that betrays nothing about its structure [@classic-mceliece-site]. McEliece&apos;s original parameters used a $[1024, 524]$ Goppa code correcting $t = 50$ errors [@mceliece-1978].&lt;/p&gt;

An algebraic code, in the alternant family, defined by a Goppa polynomial and a set of support points. It carries a hidden description that permits fast error correction through Patterson&apos;s algorithm.The Goppa and Patterson decoding machinery is summarized here, not derived; a careful modern treatment is the IACR reference &quot;Understanding binary-Goppa decoding&quot; [@cic-goppa-decoding]. Instantiated at a moderate rate and with no exploited automorphisms, it has been the lone survivor of decades of attempts to break the code family underneath McEliece.

flowchart TD
    G[&quot;Secret binary Goppa code, fast decoder&quot;] --&amp;gt; KG[&quot;Scramble it: G&apos; = S G P&quot;]
    KG --&amp;gt; PK[&quot;Publish G&apos; as a random-looking code&quot;]
    M[&quot;Message m&quot;] --&amp;gt; ENC[&quot;Encrypt: c = m G&apos; + e, weight-t error e&quot;]
    PK --&amp;gt; ENC
    ENC --&amp;gt; DEC[&quot;Owner applies S, G, P to peel the disguise&quot;]
    DEC --&amp;gt; FD[&quot;Secret decoder removes e and returns m&quot;]
&lt;p&gt;Eight years later, Harald Niederreiter published the dual: instead of a scrambled generator matrix, publish a scrambled parity-check matrix $H&apos;$, and let the ciphertext be the &lt;em&gt;syndrome&lt;/em&gt; $\mathbf{s} = H&apos;\mathbf{e}^{\top}$ of a low-weight error, with the message encoded into $\mathbf{e}$ [@niederreiter-1986]. With binary Goppa codes the two forms are security-equivalent, but the syndrome form yields smaller ciphertexts, and it is the exact construction Classic McEliece ships today. The object that information-set decoding and the structural distinguishers actually attack is this syndrome form.&lt;/p&gt;
&lt;p&gt;For roughly two decades, none of this mattered to practitioners.McEliece&apos;s public key ran to hundreds of kilobits, against RSA&apos;s hundreds of bits. The scheme was an admired museum piece, correct and elegant and ignored, sidelined by a usability failure rather than a security one. Then in 1994 Peter Shor gave a &lt;a href=&quot;https://paragmali.com/blog/how-q-day-breaks-everything-shors-algorithm-and-the-simultan/&quot; rel=&quot;noopener&quot;&gt;quantum algorithm that factors integers and computes discrete logarithms&lt;/a&gt; efficiently, threatening RSA and elliptic curves, while leaving syndrome decoding with no known handle at all [@bernstein-2010]. Overnight, &quot;impractical&quot; became &quot;quantum-safe,&quot; and the museum piece became an asset.&lt;/p&gt;

The McEliece one-wayness problem &quot;has remained remarkably stable, despite half a century of attack papers.&quot; -- Classic McEliece official documentation [@classic-mceliece-site]
&lt;p&gt;A disguised code and a pile of errors. An attacker who cannot lift the disguise has exactly one other move: decode the public code the hard way. That move has a name, a 1962 origin, and it turns out to set every code-based parameter ever chosen.&lt;/p&gt;
&lt;h2&gt;4. The Two Ways In: Message Recovery and Key Recovery&lt;/h2&gt;
&lt;p&gt;Faced with a McEliece or Niederreiter public key, an attacker has exactly two doors. Everything in the rest of this article walks through one of them, so it is worth naming them cleanly before anyone opens either.&lt;/p&gt;
&lt;p&gt;Door 1 is &lt;strong&gt;message recovery&lt;/strong&gt;. Ignore the hidden structure entirely and decode the public code generically, treating it as the random code it pretends to be. Recover the error vector of one ciphertext and you recover one plaintext. This is information-set decoding, and it works against any linear code with no assumptions at all.&lt;/p&gt;
&lt;p&gt;Door 2 is &lt;strong&gt;key recovery&lt;/strong&gt;. Instead of decoding a message, tear off the disguise: recover the secret algebraic structure of the code from the public key. Succeed once and you can decrypt &lt;em&gt;every&lt;/em&gt; ciphertext ever produced under that key, cheaply, forever. This is the territory of structural and distinguisher attacks.&lt;/p&gt;
&lt;p&gt;The two doors differ not just in method but in severity, and that asymmetry is the argument of the whole article. Door 1 is likely but shallow. It has been open, a crack, for sixty years, and all it does when it widens is force the defender to choose bigger parameters. Door 2 is unlikely but deep. No one has walked through it against a deployed parameter set, but if they did, it would not force a parameter change -- it would end the code family.&lt;/p&gt;

flowchart TD
    PK[&quot;A McEliece or Niederreiter public key&quot;] --&amp;gt; D1[&quot;Door 1: decode the public code generically&quot;]
    PK --&amp;gt; D2[&quot;Door 2: recover the hidden code structure&quot;]
    D1 --&amp;gt; R1[&quot;Information-set decoding, one ciphertext at a time&quot;]
    D2 --&amp;gt; R2[&quot;Structural distinguisher and key recovery, all ciphertexts at once&quot;]
    R1 --&amp;gt; E1[&quot;Effect: forces bigger parameters, an erosion&quot;]
    R2 --&amp;gt; E2[&quot;Effect: ends the whole code family, a collapse&quot;]
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This series analyzes cryptanalysis of the algorithm&apos;s own mathematics. Attacks on implementations -- timing and power side channels, fault injection, weak randomness, and protocol or mode misuse -- are out of scope here and handed to the companion track &quot;How It Breaks in Real Life.&quot; One boundary is worth stating now: for public-key primitives, quantum algorithms count as structural math and are in scope. Shor&apos;s algorithm is fair game, and section 11 shows it misses. Grover&apos;s algorithm is only a generic search discount, not a structural break.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Start with Door 1, because it is the door that has actually moved McEliece&apos;s numbers, and because its six-decade history is a master class in how a hard problem refuses to collapse.&lt;/p&gt;
&lt;h2&gt;5. Information-Set Decoding: The Baseline and the Ruler&lt;/h2&gt;
&lt;p&gt;Long before McEliece, in 1962, Eugene Prange at the Air Force Cambridge Research Laboratories asked how to decode a code by &lt;em&gt;guessing&lt;/em&gt;.Prange published in &lt;em&gt;IRE Transactions on Information Theory&lt;/em&gt;; the IRE merged into the IEEE in 1963, so the same journal now carries an IEEE name [@prange-1962]. His answer is still, six decades later, the conceptual core of the fastest known attack on Classic McEliece.&lt;/p&gt;
&lt;p&gt;The idea is disarmingly simple. To decode a length-$n$ code, pick $k$ of the $n$ coordinate positions and &lt;em&gt;hope&lt;/em&gt; none of the $t$ errors landed on them. If your guess is clean, then within those $k$ coordinates the received word equals the codeword exactly, and a single round of Gaussian elimination reconstructs the message. No search over error patterns, no structure, just linear algebra on a lucky window [@prange-1962].&lt;/p&gt;

A generic decoding attack. Guess a set of $k$ coordinates, called an information set, that you hope contains none of the $t$ errors. Solve linear algebra to reconstruct the message on that window; if the guess was clean, the full error vector falls out. If not, discard and guess again. ISD uses no structural assumption, which is exactly why it, and not any code-specific trick, sets code-based security.
&lt;p&gt;The catch is the hoping. The chance that a random size-$k$ window is completely error-free is the hypergeometric ratio $\binom{n-t}{k}\big/\binom{n}{k}$: the number of ways to place all $k$ chosen coordinates among the $n-t$ clean ones, over the number of ways to choose any $k$. That probability is tiny, and the expected number of iterations is its reciprocal. Each iteration is cheap and uses only polynomial memory, but you need exponentially many of them, giving a running time around $2^{0.057n}$ in one standard convention [@bjmm-2012, @may-ozerov-2015]. Run the numbers yourself and watch the exponent climb.&lt;/p&gt;
&lt;p&gt;{`
// Log of binomial coefficient C(n, k), to stay numerically sane.
function logChoose(n, k) {
  if (k &amp;lt; 0 || k &amp;gt; n) return -Infinity;
  let s = 0;
  for (let i = 0; i &amp;lt; k; i++) s += Math.log(n - i) - Math.log(i + 1);
  return s;
}&lt;/p&gt;
&lt;p&gt;// A Prange iteration succeeds if all t errors avoid the size-k information set,
// i.e. every error lands in the remaining n-k coordinates.
function prange(n, k, t) {
  const logP = logChoose(n - t, k) - logChoose(n, k); // hypergeometric
  return { log2Iters: -logP / Math.LN2 };
}&lt;/p&gt;
&lt;p&gt;for (const [n, k, t] of [[100, 50, 10], [200, 100, 20], [400, 200, 40]]) {
  const r = prange(n, k, t);
  console.log(&quot;n=&quot; + n + &quot; k=&quot; + k + &quot; t=&quot; + t +
    &quot;  expected iterations = 2^&quot; + r.log2Iters.toFixed(1));
}
`}&lt;/p&gt;

flowchart TD
    A[&quot;Pick a random size-k information set I&quot;] --&amp;gt; B[&quot;Gaussian-eliminate H against I&quot;]
    B --&amp;gt; C{&quot;Is I error-free?&quot;}
    C -- no --&amp;gt; A
    C -- yes --&amp;gt; D[&quot;Read the error off by linear algebra, return e&quot;]
&lt;p&gt;Here is the reframe that matters. ISD is not a footnote to code-based cryptography; it &lt;em&gt;is&lt;/em&gt; the ruler. Classic McEliece and HQC do not claim a security level derived from a proof. They quote, as their security level, the measured cost of the best known information-set decoder against their public code [@classic-mceliece-site, @mceliece-comparison]. When cryptographers ask &quot;how strong is mceliece6688128,&quot; they are asking one question: how many operations does the best ISD need?&lt;/p&gt;

The ratio of a code&apos;s dimension $k$ to its length $n$. High rate means little redundancy; low rate means a lot. Structural distinguishers bite hardest as the rate approaches 1, which is why Classic McEliece deliberately fixes a moderate rate. It is a security decision wearing the costume of a design parameter.
&lt;p&gt;Prange&apos;s weakness is obvious in hindsight: he throws away every iteration in which even a single error touches the chosen window, and for realistic $t$ that is almost every iteration. Every improvement for the next fifty-six years is a variation on one move: stop demanding a perfectly clean window. How much faster can that make you? Astonishingly little, and that near-flatness is the quiet foundation on which the whole hedge is built.&lt;/p&gt;
&lt;h2&gt;6. The Evolution of ISD: From Prange to BJMM&lt;/h2&gt;
&lt;p&gt;Six decades, some of the sharpest cryptographers alive, and one relentless goal: shave the exponent. Here is the entire distance they traveled, and it is shorter than you would guess.&lt;/p&gt;
&lt;p&gt;Each generation kept Prange&apos;s skeleton and relaxed his one rigid demand. &lt;strong&gt;Lee and Brickell&lt;/strong&gt; (1988) allowed a few errors to sit inside the information set and paid a small search to find them, so a window no longer had to be perfectly clean [@lee-brickell-1988]. &lt;strong&gt;Stern&lt;/strong&gt; (1989) split the window and looked for collisions between two halves, a birthday-style search that became the template for everything modern, at the cost of exponential memory [@stern-1989].&lt;/p&gt;
&lt;p&gt;Then the modern jumps. &lt;strong&gt;May, Meurer, and Thomae&lt;/strong&gt; (2011) introduced the representation technique, the first real jump in decades [@mmt-2011]. &lt;strong&gt;Becker, Joux, May, and Meurer&lt;/strong&gt; (2012) sharpened it by letting the two halves overlap, exploiting arithmetic over $\mathbb{F}_2$, and reached a headline exponent of $2^{n/20}$ [@bjmm-2012].Over $\mathbb{F}_2$, $1+1=0$: if both halves of a representation put a one in the same position, those ones cancel. Allowing that overlap is exactly what multiplies the number of representations in BJMM [@bjmm-2012]. &lt;strong&gt;May and Ozerov&lt;/strong&gt; (2015) then recast the collision step as approximate nearest-neighbor search [@may-ozerov-2015], and &lt;strong&gt;Both and May&lt;/strong&gt; (2018) pushed the same machinery to high error rates, the live frontier [@both-may-2018].&lt;/p&gt;

The counting trick at the heart of the modern ISD variants. Rather than search for one specific splitting of the target error $\mathbf{e} = \mathbf{e}_1 + \mathbf{e}_2$, notice that there are exponentially *many* valid splittings and design the search so that finding any single one suffices. The abundance of representations lowers the expected cost of finding one.
&lt;p&gt;Why does counting splittings help? Fix the target error $\mathbf{e}$ of weight $w$ and write it as a sum $\mathbf{e} = \mathbf{e}_1 + \mathbf{e}_2$ of two weight-$w/2$ vectors. The same $\mathbf{e}$ can be written that way in about $\binom{w}{w/2}$ different ways. That abundance is the lever: because so many representations of the &lt;em&gt;one&lt;/em&gt; solution exist, the search can impose about $\log_2\binom{w}{w/2}$ extra linear constraints and still expect one representation to survive. Each constraint shrinks the intermediate lists the attacker must build, so more representations buy exponentially smaller lists, and finding a single survivor is enough.&lt;/p&gt;
&lt;p&gt;BJMM&apos;s $1+1=0$ trick widens the lever: it lets $\mathbf{e}_1$ and $\mathbf{e}_2$ carry ones in positions &lt;em&gt;outside&lt;/em&gt; the support of $\mathbf{e}$, where the two ones cancel over $\mathbb{F}_2$, multiplying the representation count from $\binom{w}{w/2}$ to roughly $\binom{w}{w/2}\binom{n-w}{\varepsilon}$ and licensing still more constraints [@bjmm-2012].&lt;/p&gt;
&lt;p&gt;May and Ozerov attack the leftover cost from the other side: the collision step is really a search for two list entries at small Hamming distance, not exact equality, so replacing Stern&apos;s exact-match join with an approximate nearest-neighbor search shaves the exponent again [@may-ozerov-2015].&lt;/p&gt;

flowchart LR
    P[&quot;Prange 1962&quot;] --&amp;gt; LB[&quot;Lee-Brickell 1988&quot;]
    LB --&amp;gt; St[&quot;Stern 1989&quot;]
    St --&amp;gt; MMT[&quot;MMT 2011&quot;]
    MMT --&amp;gt; BJMM[&quot;BJMM 2012&quot;]
    BJMM --&amp;gt; MO[&quot;May-Ozerov 2015&quot;]
    MO --&amp;gt; BM[&quot;Both-May 2018&quot;]
&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;Key idea&lt;/th&gt;
&lt;th&gt;Advertised exponent&lt;/th&gt;
&lt;th&gt;Memory&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Prange&lt;/td&gt;
&lt;td&gt;1962&lt;/td&gt;
&lt;td&gt;a completely clean information set&lt;/td&gt;
&lt;td&gt;$2^{0.057n}$&lt;/td&gt;
&lt;td&gt;polynomial&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lee-Brickell&lt;/td&gt;
&lt;td&gt;1988&lt;/td&gt;
&lt;td&gt;allow $p$ errors inside the set&lt;/td&gt;
&lt;td&gt;below Prange&lt;/td&gt;
&lt;td&gt;polynomial&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stern&lt;/td&gt;
&lt;td&gt;1989&lt;/td&gt;
&lt;td&gt;birthday split of the window&lt;/td&gt;
&lt;td&gt;below Lee-Brickell&lt;/td&gt;
&lt;td&gt;exponential&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MMT&lt;/td&gt;
&lt;td&gt;2011&lt;/td&gt;
&lt;td&gt;representations of the error&lt;/td&gt;
&lt;td&gt;$2^{0.054n}$ (title)&lt;/td&gt;
&lt;td&gt;exponential&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BJMM&lt;/td&gt;
&lt;td&gt;2012&lt;/td&gt;
&lt;td&gt;overlapping halves, $1+1=0$&lt;/td&gt;
&lt;td&gt;$2^{n/20}=2^{0.05n}$ (title)&lt;/td&gt;
&lt;td&gt;exponential&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;May-Ozerov&lt;/td&gt;
&lt;td&gt;2015&lt;/td&gt;
&lt;td&gt;nearest-neighbor search&lt;/td&gt;
&lt;td&gt;$2^{0.0473n}$&lt;/td&gt;
&lt;td&gt;exponential&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Both-May&lt;/td&gt;
&lt;td&gt;2018&lt;/td&gt;
&lt;td&gt;high error-rate frontier&lt;/td&gt;
&lt;td&gt;current best regime&lt;/td&gt;
&lt;td&gt;exponential&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Read the table for its &lt;em&gt;shape&lt;/em&gt;, not a decimal sequence. Across roughly fifty-six years the exponent constant fell only from about $2^{0.057n}$ to about $2^{0.047n}$ [@bjmm-2012, @may-ozerov-2015], an erosion near 15 to 20 percent of the constant, and the running time never left the family $2^{\Theta(n)}$.The nearest-neighbor step that powers May-Ozerov is the same primitive that powers lattice sieving. Shared tooling, not shared hardness: a faster nearest-neighbor routine helps both cost estimates without linking the two assumptions [@may-ozerov-2015]. Worse for the attacker, every post-Stern variant buys its lower &lt;em&gt;time&lt;/em&gt; exponent with exponential &lt;em&gt;memory&lt;/em&gt;, and the real cost of touching that much memory blunts the advantage.&lt;/p&gt;

The headline exponents above are each quoted in that paper&apos;s own decoding-radius and rate convention, and the conventions differ. MMT&apos;s $2^{0.054n}$, BJMM&apos;s $2^{n/20}$, and May-Ozerov&apos;s $2^{0.0473n}$ are not points on one ruler. The specific error to avoid is comparing Prange&apos;s full-distance $2^{0.12n}$ against a half-distance $2^{0.047n}$ and reporting a 2.5-fold improvement; measured in a single convention the gain is closer to 1.2-fold [@may-ozerov-2015, @mceliece-comparison]. The convention-independent fact is the trend&apos;s shape: the constant fell by roughly 15 to 20 percent, and the exponential form never changed.
&lt;p&gt;{`
// Two ISD exponents in one (half-distance) convention.
const cPrange = 0.057;   // Prange, 1962
const cModern = 0.0473;  // May-Ozerov regime, 2015&lt;/p&gt;
&lt;p&gt;for (const n of [3488, 6688, 8192]) {
  const bitsOld = cPrange * n;
  const bitsNew = cModern * n;
  console.log(&quot;n=&quot; + n +
    &quot;  Prange ~ 2^&quot; + bitsOld.toFixed(0) +
    &quot;   modern ~ 2^&quot; + bitsNew.toFixed(0) +
    &quot;   gap = &quot; + (bitsOld - bitsNew).toFixed(0) + &quot; bits&quot;);
}
// The exponent shrinks, but the problem stays firmly exponential.
`}&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Information-set decoding erodes margins; it does not collapse the problem. Fifty-six years of the sharpest attacks moved the exponent constant by roughly 15 to 20 percent and never once changed its exponential form. That is why a code-based parameter set ages slowly and predictably rather than failing overnight.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Real, but incremental. So if ISD only ever crawls, has it actually broken anything? Yes, once, decisively, and the receipt is the single most important fact in this article.&lt;/p&gt;
&lt;h2&gt;7. The Break ISD Already Delivered&lt;/h2&gt;
&lt;p&gt;In 2008, Daniel Bernstein, Tanja Lange, and Christiane Peters did what thirty years of theory had implied but no one had cashed: they recovered plaintexts from McEliece&apos;s &lt;em&gt;original&lt;/em&gt; parameters, the $[1024, 524]$ Goppa code with $t = 50$, at roughly $2^{60}$ operations on real hardware [@blp-2008]. They also wrote down the prescription for restoring security: grow $n$, $k$, and $t$. Nothing more exotic was required.&lt;/p&gt;
&lt;p&gt;This is the receipt, and it must be read precisely, because it is the fact most often garbled. What fell was the &lt;em&gt;parameter set&lt;/em&gt;, the specific numbers McEliece chose in 1978. What did &lt;em&gt;not&lt;/em&gt; fall was the binary-Goppa &lt;em&gt;structure&lt;/em&gt;. The Bernstein-Lange-Peters attack never recovered the secret code; it decoded the public code generically, exactly as Prange would have, only faster. The trapdoor was never lifted.&lt;/p&gt;
&lt;p&gt;So the familiar phrase &quot;unbroken since 1978&quot; is true, but only at the level of the &lt;em&gt;structure&lt;/em&gt; and the &lt;em&gt;assumption&lt;/em&gt;. At the level of the original &lt;em&gt;numbers&lt;/em&gt;, ISD won in 2008, and the field had already moved to larger parameters by then.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The original 1978 parameters were practically broken in 2008, yet the binary-Goppa &lt;em&gt;structure&lt;/em&gt; was never scratched. Information-set decoding simply decoded the public code generically, and the repair was larger keys. So &quot;unbroken since 1978&quot; is a precise claim about the &lt;em&gt;structure&lt;/em&gt;, while the security &lt;em&gt;number&lt;/em&gt; is a moving measurement, the ISD ruler, that has been quietly pushing the parameters upward all along. The scheme is not a static fortress; it is a well-instrumented, slowly-eroding margin.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Just how slowly does the ruler move? The Classic McEliece team runs CryptAttackTester, a computer-checked attack-cost tool, and publishes the bit-operation cost of 1980s-era ISD against current ISD on the same code sizes [@mceliece-comparison, @mceliece-papers-index]. The numbers are almost comically flat.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Problem size $(n, t)$&lt;/th&gt;
&lt;th&gt;1980s ISD&lt;/th&gt;
&lt;th&gt;Current ISD&lt;/th&gt;
&lt;th&gt;Improvement&lt;/th&gt;
&lt;th&gt;Used by&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;$(1024, 50)$&lt;/td&gt;
&lt;td&gt;$2^{70.05}$&lt;/td&gt;
&lt;td&gt;$2^{69.78}$&lt;/td&gt;
&lt;td&gt;0.27 bit&lt;/td&gt;
&lt;td&gt;McEliece&apos;s original 1978 parameters&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$(3488, 64)$&lt;/td&gt;
&lt;td&gt;$2^{156.96}$&lt;/td&gt;
&lt;td&gt;$2^{150.59}$&lt;/td&gt;
&lt;td&gt;6.37 bits&lt;/td&gt;
&lt;td&gt;mceliece348864&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$(6688, 128)$&lt;/td&gt;
&lt;td&gt;$2^{275.41}$&lt;/td&gt;
&lt;td&gt;$2^{257.36}$&lt;/td&gt;
&lt;td&gt;18.05 bits&lt;/td&gt;
&lt;td&gt;mceliece6688128&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Four decades of the world&apos;s best ISD research removed about eighteen bits from a 275-bit problem [@mceliece-comparison]. That is real, and it is a rounding error against the security margin.&lt;/p&gt;
&lt;p&gt;The units matter here. McEliece&apos;s 1978 paper estimated about $2^{65}$ &lt;em&gt;bit operations&lt;/em&gt; for $(1024, 50)$, an underestimate even of the attacks known then, and improved ISD still needs &lt;em&gt;more&lt;/em&gt; than $2^{65}$ bit operations. The fastest software today breaks $(1024, 50)$ in about $2^{60}$ &lt;em&gt;CPU cycles&lt;/em&gt;, each cycle doing many bit operations at once -- the practical Bernstein-Lange-Peters message recovery [@mceliece-comparison]. The $2^{60}$ figure is a coarser unit, not a contradiction of the $2^{65}$ one. This is the thesis made concrete: ISD, not a structural break, has actually moved McEliece&apos;s numbers, and it moves them at a glacial pace.&lt;/p&gt;
&lt;p&gt;So Door 1 erodes; it does not collapse. That should be reassuring, unless the disguise itself, the very thing that makes the public code look random, is quietly leaking. That is Door 2, and it just had its most dramatic decade in forty-seven years.&lt;/p&gt;
&lt;h2&gt;8. The Other Surface: Structural Distinguishers&lt;/h2&gt;
&lt;p&gt;Every McEliece scheme rests on one bet: that a disguised algebraic code is indistinguishable from a random one. History says that bet is broken more often than it is kept, and the wreckage is instructive.&lt;/p&gt;

The temptation is always the same. Binary Goppa keys are huge, so why not swap in a more structured code that decodes faster and packs smaller? Every time someone tries, the extra structure leaks. Niederreiter&apos;s own generalized Reed-Solomon variant was recovered in polynomial time by Sidelnikov and Shestakov in 1992 [@sidelnikov-shestakov-1992]. Sidelnikov&apos;s binary Reed-Muller scheme [@sidelnikov-1994] fell to Minder and Shokrollahi in 2007 [@minder-shokrollahi-2007]. Most algebraic-geometry variants broke too [@overbeck-sendrier-2009].&lt;p&gt;The lesson carries the whole thesis: it is the &lt;em&gt;choice of code family&lt;/em&gt;, not the McEliece idea, that usually dies. Binary Goppa, at moderate rate and with no exploited automorphisms, has been the survivor, consistent with Sendrier&apos;s support-splitting analysis of when a disguised code can be re-identified [@sendrier-2000]. Every structural distinguisher since is, in effect, asking one question: is binary Goppa secretly as leaky as generalized Reed-Solomon?
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;

An algorithm that tells a disguised algebraic public code apart from a truly random linear code of the same size, faster than chance. It is weaker than key recovery, because distinguishing is not decrypting, but it undermines the indistinguishability premise the security argument leans on, and historically it is the first symptom of a code family about to fall.
&lt;p&gt;For thirty years the answer was reassuring. Then the structural front reawakened, each result escaping the previous one&apos;s limit and each reading the same suspicion in a different algebraic language: does the disguise leak a low-degree-polynomial fingerprint?&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;high-rate distinguisher&lt;/strong&gt; of Faugere, Gauthier-Umana, Otmani, Perret, and Tillich (2013) measures the &lt;em&gt;dimension of a solution space&lt;/em&gt; built from the public code [@fgopt-2013, @fgopt-eprint-2010-331]. The accessible restatement is the square-code, or Schur-product, test: square a code by taking all componentwise products of its codewords, and a random code fills the available dimension, while an alternant or Goppa code collapses into an abnormally &lt;em&gt;small&lt;/em&gt; square-code dimension. That collapse is measurable only as the rate approaches 1, safely outside the moderate rate Classic McEliece deliberately fixes, which turns the moderate-rate choice from an efficiency compromise into an active defense.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;quadratic-forms&lt;/strong&gt; approach of Couvreur, Mora, and Tillich (2023) escapes the rate-to-1 limit [@couvreur-mora-tillich-2023]. It builds the whole space of quadratic relations satisfied by Schur products of dual codewords and hunts for &quot;unusually low-rank matrices (rank 2 or 3 ...) which reveal the secret polynomial structure of the code.&quot;&lt;/p&gt;
&lt;p&gt;The mechanism is sharp: a rank-2 quadratic form factors as a product of two linear forms, and those linear forms encode the secret support and multipliers, so finding one low-rank matrix &lt;em&gt;is&lt;/em&gt; extracting a piece of the key. That yields a subexponential distinguisher across a broad range, but its polynomial-time &lt;em&gt;key recovery&lt;/em&gt; is confined to codes whose Goppa degree is small, below $q-1$, the high-rate, small-degree families Classic McEliece does not use.&lt;/p&gt;
&lt;p&gt;Then the &lt;strong&gt;syzygy distinguisher&lt;/strong&gt; of Randriambololona (2024) reads &quot;graded Betti numbers of the homogeneous coordinate ring of a shortening of the dual code&quot; [@randriambololona-2024]. Syzygies are the relations among the code&apos;s defining equations, and the relations among those relations; the graded Betti numbers count them degree by degree and so measure how algebraically &lt;em&gt;regular&lt;/em&gt; the construction is.&lt;/p&gt;
&lt;p&gt;Because a Goppa code comes from evaluating low-degree polynomials at a hidden support, its coordinate ring is unusually regular and its Betti numbers deviate from the random pattern. The computation is subexponential in the error-correcting capability $t$ rather than exponential, and, uniquely, it carries no high-rate restriction, so for the first time it reaches the parameters Classic McEliece actually ships.&lt;/p&gt;
&lt;p&gt;Line the three up and the pattern is exact. All three ask whether the disguise leaks a low-degree-polynomial fingerprint. The 2013 test counts a &lt;em&gt;dimension&lt;/em&gt; and leaks only at high rate; the 2023 test hunts a &lt;em&gt;rank-2 matrix&lt;/em&gt; and leaks the secret itself, but in polynomial time only when the degree is below $q-1$; the 2024 test reads &lt;em&gt;syzygies&lt;/em&gt; and leaks at McEliece&apos;s own rate, subexponentially in $t$. Each escaped the previous limit, and yet not one has turned its leak into key recovery at a deployed parameter set.&lt;/p&gt;

flowchart TD
    A[&quot;2013 high-rate distinguisher&quot;] --&amp;gt; A2[&quot;Bites only as the rate approaches 1, outside McEliece&apos;s moderate rate&quot;]
    A2 --&amp;gt; B[&quot;2023 quadratic-forms distinguisher&quot;]
    B --&amp;gt; B2[&quot;Subexponential over a broad range, with poly-time key recovery only for small-degree high-rate codes McEliece avoids&quot;]
    B2 --&amp;gt; C[&quot;2024 syzygy distinguisher&quot;]
    C --&amp;gt; C2[&quot;Subexponential, reaches Classic McEliece parameters, yet still only a distinguisher&quot;]

&quot;Since its introduction in 1978, this is the first time an analysis [in the CPA model] of the McEliece cryptosystem breaks the exponential barrier.&quot; -- Hugues Randriambololona, &quot;The syzygy distinguisher&quot; [@randriambololona-2024]
&lt;p&gt;That sentence is doing careful work, and it is the aha of this section: the real existential threat to McEliece was never decoding the message. It is the disguise slipping. And the disguise, for the first time in forty-seven years, is showing a seam. But read the boundary exactly.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The 2024 syzygy result reaching Classic McEliece parameters is a distinguisher in the CPA model, not a key-recovery or message-recovery attack. It notices that the public code is not perfectly random; it does not read the secret or decrypt a ciphertext. Reporting it as &quot;McEliece broken&quot; is a category error. What it buys an attacker is a warning and a research direction, not a plaintext.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A warning light, then, not a fire, but the brightest warning light in forty-seven years. With both doors mapped, we can finally look at the two schemes that actually walked through standardization, and see how each is engineered against exactly these threats.&lt;/p&gt;
&lt;h2&gt;9. Classic McEliece: Conservative by Design&lt;/h2&gt;
&lt;p&gt;Some engineers optimize for elegance. The Classic McEliece team optimized for one thing: being boring for as long as possible. The scheme is Niederreiter&apos;s syndrome form instantiated with binary Goppa codes, wrapped into an IND-CCA2 key-encapsulation mechanism by a tight Fujisaki-Okamoto conversion of a one-way PKE. Because the underlying encryption is deterministic and has &lt;em&gt;no&lt;/em&gt; decryption failures for valid ciphertexts, that conversion admits a tight security reduction in both the classical and quantum random-oracle models [@classic-mceliece-site].&lt;/p&gt;
&lt;p&gt;Look at the design through the two doors. Against Door 2, the team fixes a deliberately &lt;em&gt;moderate&lt;/em&gt; rate, sitting well away from the high-rate regime where the 2013 distinguisher operates. Against a whole class of adaptive attacks, the deterministic, failure-free decryption removes the decoding-failure channel entirely, so there is nothing to observe. And against Door 1, the parameters are chosen with what can only be called overkill. The price for all of this is paid in one currency: public-key size.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter set&lt;/th&gt;
&lt;th&gt;Public key (bytes)&lt;/th&gt;
&lt;th&gt;Ciphertext (bytes)&lt;/th&gt;
&lt;th&gt;ISD security&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;mceliece348864&lt;/td&gt;
&lt;td&gt;261,120&lt;/td&gt;
&lt;td&gt;96&lt;/td&gt;
&lt;td&gt;$2^{150.59}$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mceliece460896&lt;/td&gt;
&lt;td&gt;524,160&lt;/td&gt;
&lt;td&gt;156&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mceliece6688128&lt;/td&gt;
&lt;td&gt;1,044,992&lt;/td&gt;
&lt;td&gt;208&lt;/td&gt;
&lt;td&gt;$2^{257.36}$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mceliece6960119&lt;/td&gt;
&lt;td&gt;1,047,319&lt;/td&gt;
&lt;td&gt;194&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mceliece8192128&lt;/td&gt;
&lt;td&gt;1,357,824&lt;/td&gt;
&lt;td&gt;208&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Public keys run from about 261 KB to about 1.36 MB [@mceliece-impl]. That is the number everyone remembers, and it is a genuine deployment problem. But notice the other column, the one nobody talks about: the ciphertexts are 96 to 208 &lt;em&gt;bytes&lt;/em&gt; [@mceliece-impl]. A mceliece6688128 ciphertext is 208 bytes, smaller than ML-KEM-512&apos;s 768-byte ciphertext, while resting on a far longer-studied assumption. For a system that fetches a static public key once and then encapsulates to it many times, that trade is not obviously bad; it is merely unusual.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Classic McEliece was standardized by ISO/IEC in 2026 -- published as Amendment 2 to ISO/IEC 18033-2 [@iso-18033-2-amd2] -- and was &lt;strong&gt;not&lt;/strong&gt; selected by NIST. NIST&apos;s IR 8545 explains why: its public key is very large. Do not describe Classic McEliece as a NIST or FIPS standard [@nist-ir-8545].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A megabyte key is a hard sell for an ephemeral TLS handshake, where a fresh key ships on every connection. That single ergonomic fact is why NIST reached instead for a scheme with kilobyte keys, and, along the way, a different and younger set of assumptions.&lt;/p&gt;
&lt;h2&gt;10. HQC: Quasi-Cyclic and NIST-Selected&lt;/h2&gt;
&lt;p&gt;HQC makes the opposite bet from McEliece at almost every turn, and that is precisely why NIST picked it. Where McEliece hides a decodable code and keeps the decoder secret, HQC does the reverse.&lt;/p&gt;
&lt;p&gt;Its hardness comes from decoding a &lt;em&gt;random&lt;/em&gt; quasi-cyclic code, the quasi-cyclic syndrome-decoding problem, while error correction is handled by a &lt;em&gt;separate, public, fixed&lt;/em&gt; decoder built from concatenated Reed-Muller and Reed-Solomon codes [@hqc-2018, @hqc-decoder-2024]. Nothing about the decoder is secret; the only secret is the noise. The compactness comes from the cyclic structure: one block-row describes an entire circulant block, so the public key is kilobytes rather than megabytes.&lt;/p&gt;

Syndrome decoding restricted to quasi-cyclic codes, whose parity-check matrix is assembled from circulant blocks, so a single row describes a whole block. HQC&apos;s hardness rests on QCSD. The cyclic structure is what shrinks the key to kilobytes, and it is also what hands the attacker the DOOM speedup.
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Instance&lt;/th&gt;
&lt;th&gt;Public key (bytes)&lt;/th&gt;
&lt;th&gt;Ciphertext (bytes)&lt;/th&gt;
&lt;th&gt;NIST level&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;HQC-1&lt;/td&gt;
&lt;td&gt;2,241&lt;/td&gt;
&lt;td&gt;4,433&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HQC-3&lt;/td&gt;
&lt;td&gt;4,514&lt;/td&gt;
&lt;td&gt;8,978&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HQC-5&lt;/td&gt;
&lt;td&gt;7,237&lt;/td&gt;
&lt;td&gt;14,421&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The trade-off against McEliece is exact and opposite [@pqc-hqc-site]. HQC&apos;s public keys are about 2 to 7 KB, against McEliece&apos;s 0.26 to 1.36 MB, but its ciphertexts are about 4 to 14 KB, against McEliece&apos;s 96 to 208 bytes. Small keys, larger ciphertexts. That shape suits ephemeral, per-session handshakes where a fresh public key ships every time.&lt;/p&gt;
&lt;p&gt;The quasi-cyclic structure is not free, and honesty requires naming the surcharge. It is an &lt;em&gt;added&lt;/em&gt; assumption beyond plain syndrome decoding, and it hands the attacker a specific speedup.DOOM, &quot;Decoding One Out of Many,&quot; lets an attacker amortize one decoding across the many cyclic shifts of a quasi-cyclic instance, a speedup of roughly $\sqrt{N}$. It applies to HQC and BIKE and is already priced into their parameters; Classic McEliece, with no cyclic structure, does not pay it [@doom-2011]. Both effects are quantified and folded into HQC&apos;s parameter choices.&lt;/p&gt;
&lt;p&gt;How much security does that structure actually buy, and how do we know? Here HQC and McEliece part company in a way worth stating plainly. The 2025 HQC specification fixes its parameters &quot;so that the minimal workfactor of the best known attack exceeds the security parameter,&quot; which is to say HQC-1, HQC-3, and HQC-5 are built to clear $2^{128}$, $2^{192}$, and $2^{256}$ classical operations by construction rather than by a printed per-instance count [@hqc-spec-2025].&lt;/p&gt;
&lt;p&gt;That workfactor is the cost of the best information-set decoder on the quasi-cyclic problem, of order $2^{c\omega}$ in the error weight $\omega$, divided by the DOOM gain of &quot;approximately $\sqrt{n}$&quot; -- about 7.0, 7.6, and 7.9 bits at HQC&apos;s three block sizes -- and then halved in the exponent for the quantum setting, since &quot;the quantum-safe security is obtained by dividing the security bits by two,&quot; the same Grover discount McEliece applies [@hqc-spec-2025, @bernstein-2010].&lt;/p&gt;
&lt;p&gt;An honest asymmetry hides in that sentence. McEliece quotes a computer-checked number: CryptAttackTester&apos;s &lt;code&gt;isd2&lt;/code&gt; gives $2^{150.59}$ at $(3488, 64)$ and $2^{257.36}$ at $(6688, 128)$ [@mceliece-comparison]. HQC quotes a &lt;em&gt;target&lt;/em&gt; plus an asymptotic formula minus two discounts. No CAT-grade, fully computer-checked concrete count for quasi-cyclic syndrome decoding is published on the same footing, so the widely repeated third-party figures of roughly 145, 194, and 243 bits should not be attributed to the specification. They are estimator output, not a spec claim, and section 12 files the gap as an open problem.&lt;/p&gt;
&lt;p&gt;Why HQC and not its sibling BIKE? Both are quasi-cyclic and both were candidates, but BIKE keeps its QC-MDPC decoder &lt;em&gt;secret&lt;/em&gt;, and a hidden decoder has a key-correlated decoding-failure rate that is genuinely hard to analyze. The mathematical difficulty of pinning that failure rate, the design concern underlying the Guo-Johansson-Stankovski reaction-attack line, weighed against BIKE [@gjs-2016].&lt;/p&gt;
&lt;p&gt;HQC&apos;s &lt;em&gt;public&lt;/em&gt; decoder makes the same failure analysis far cleaner, and NIST&apos;s IR 8545 records this as a deciding factor, along with the reasons Classic McEliece was set aside [@nist-ir-8545]. HQC was announced in March 2025 as the second standardized KEM after ML-KEM, with a draft released for public comment first and the finalized standard expected in roughly two years [@nist-hqc-announce], the outcome of a multi-year public process [@nist-pqc-project].&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;Classic McEliece&lt;/th&gt;
&lt;th&gt;HQC&lt;/th&gt;
&lt;th&gt;BIKE (not selected)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Hard problem&lt;/td&gt;
&lt;td&gt;binary Goppa decoding&lt;/td&gt;
&lt;td&gt;quasi-cyclic syndrome decoding&lt;/td&gt;
&lt;td&gt;QC-MDPC decoding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Decoder hidden?&lt;/td&gt;
&lt;td&gt;yes, secret Goppa decoder&lt;/td&gt;
&lt;td&gt;no, public RM and RS decoder&lt;/td&gt;
&lt;td&gt;yes, secret QC-MDPC decoder&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Public key&lt;/td&gt;
&lt;td&gt;261 KB to 1.36 MB&lt;/td&gt;
&lt;td&gt;2.2 to 7.2 KB&lt;/td&gt;
&lt;td&gt;kilobytes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ciphertext&lt;/td&gt;
&lt;td&gt;96 to 208 B&lt;/td&gt;
&lt;td&gt;4.4 to 14.4 KB&lt;/td&gt;
&lt;td&gt;kilobytes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Decryption failures&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;td&gt;nonzero, cleanly analyzable&lt;/td&gt;
&lt;td&gt;nonzero, harder to analyze&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Standardization&lt;/td&gt;
&lt;td&gt;ISO/IEC track&lt;/td&gt;
&lt;td&gt;NIST-selected, March 2025&lt;/td&gt;
&lt;td&gt;dropped in Round 4&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Two schemes, two unrelated hard problems, both standing. But there is one adversary the entire post-quantum project was built to survive. Does it touch either of them?&lt;/p&gt;
&lt;h2&gt;11. Quantum Cryptanalysis: Why Shor Misses&lt;/h2&gt;
&lt;p&gt;The whole reason we are re-standardizing encryption is a quantum algorithm. So why does that same algorithm do nothing here? The answer is the most reassuring structural result in this article, and it is a &lt;em&gt;positive&lt;/em&gt; one for the defender.&lt;/p&gt;
&lt;p&gt;Shor&apos;s algorithm is not a general-purpose code breaker. It efficiently solves one abstract problem, and factoring and discrete logarithm happen to be instances of it.&lt;/p&gt;

The abstract problem Shor&apos;s algorithm actually solves: given a function that is constant on the cosets of an unknown subgroup and distinct on distinct cosets, find the subgroup. Factoring and discrete logarithm are instances over *abelian* groups, which is why a quantum computer breaks RSA and elliptic curves. Syndrome decoding exposes no such abelian hidden-subgroup structure, so Shor&apos;s algorithm has nothing to grab.
&lt;p&gt;That is the whole story of Shor against codes. General syndrome decoding presents no periodicity, no abelian hidden subgroup, no algebraic handle of the kind Shor&apos;s period-finding needs. There is no known efficient quantum algorithm for decoding a random linear code [@bernstein-2010]. The property that made McEliece impractical in 1978, its refusal to reduce to clean number theory, is exactly the property that makes it quantum-safe in 2025.&lt;/p&gt;
&lt;p&gt;Grover&apos;s algorithm does apply, but only to the &lt;em&gt;search step&lt;/em&gt; inside ISD, and even there it underdelivers. Because ISD is not one big unstructured search, Grover speeds up only its innermost search, so the true quantum speedup is &lt;em&gt;less&lt;/em&gt; than a full square root [@bernstein-2010]. Schemes still set their quantum parameters by the deliberately conservative rule of halving the classical bit-security -- turning an attack near $2^{cn}$ into a budget of about $2^{(c/2)n}$ -- which &lt;em&gt;upper-bounds&lt;/em&gt; Grover&apos;s real benefit rather than measuring it.&lt;/p&gt;
&lt;p&gt;The countermeasure is generic and boring: increase the key size until the halved exponent is large enough again. The &lt;code&gt;mceliece6*&lt;/code&gt; and HQC-5 tiers already fold this discount into their parameters, chosen &quot;for long-term security, including security against multi-target attacks and against quantum attacks&quot; [@mceliece-comparison]. A search discount absorbed by a parameter bump is a cost adjustment, not a structural break.&lt;/p&gt;
&lt;p&gt;One symmetric corollary completes the hedge: just as a lattice break does not touch codes, a hypothetical &lt;em&gt;quantum&lt;/em&gt; attack on lattices would not touch codes either. The two problems share no structure for such an attack to exploit. The independence runs in every direction.&lt;/p&gt;
&lt;p&gt;So Shor misses, Grover only nibbles, and the hedge survives the one adversary it was built for. That is the strong half of the story. Now the honest, humbler half: what do we actually &lt;em&gt;know&lt;/em&gt; about how hard these problems are?&lt;/p&gt;
&lt;h2&gt;12. Theoretical Limits and Open Problems&lt;/h2&gt;
&lt;p&gt;Here is the uncomfortable truth under every code-based security claim, and it is the same truth under every deployed public-key system: we have never &lt;em&gt;proven&lt;/em&gt; the problem is hard. We have only failed, for decades, to solve it. Naming exactly where the proof runs out is the honest security story, and it has three gaps.&lt;/p&gt;
&lt;p&gt;The first gap is &lt;strong&gt;worst-case versus average-case&lt;/strong&gt;. Decoding a general linear code is NP-complete [@bmvt-1978], and that is the strongest worst-case anchor any scheme has. But Classic McEliece and HQC do not rest on the worst case. They rest on the &lt;em&gt;average-case&lt;/em&gt; hardness of a &lt;em&gt;specific structured&lt;/em&gt; family, binary Goppa or random quasi-cyclic, and no reduction connects the NP-complete worst case to that average case. An NP-hardness badge is not a security proof, and pretending otherwise is the most common overstatement in the whole subject.&lt;/p&gt;
&lt;p&gt;The second gap is &lt;strong&gt;asymptotic versus concrete&lt;/strong&gt;. Every ISD exponent is an asymptotic worst-case figure, and the concrete cost at a named parameter set depends on the memory model.This is why the field increasingly trusts a computer-checked bit-operation count over a hand-analyzed asymptotic exponent. A variant with a lower time exponent but exponential memory may cost more in practice than its headline suggests.&lt;/p&gt;
&lt;p&gt;That is why a computer-checked ruler like CryptAttackTester matters more than any single exponent [@mceliece-comparison, @mceliece-papers-index], and it is why the one place HQC&apos;s ruler runs softer than McEliece&apos;s, a workfactor &lt;em&gt;target&lt;/em&gt; and an asymptotic formula rather than a CAT-audited count for quasi-cyclic decoding, is worth flagging as an open item rather than waving through [@hqc-spec-2025].&lt;/p&gt;
&lt;p&gt;The third gap is &lt;strong&gt;distinguisher versus break&lt;/strong&gt;, and the 2024 syzygy result lives exactly inside it: it distinguishes subexponentially, yet it does not recover [@randriambololona-2024]. A subexponential distinguisher that never becomes a recovery is a strange, in-between object, and reasoning about it demands the precision this whole article has insisted on.&lt;/p&gt;

This article studies breaks that have *not* happened to code-based schemes. Its companion, &quot;How the NIST Finalists Broke,&quot; studies breaks that *did* happen to other post-quantum candidates. Rainbow, a multivariate signature finalist, fell to a single idea from Ward Beullens over a weekend [@rainbow-eprint-2022-214]. SIKE, an isogeny KEM, fell to Wouter Castryck and Thomas Decru in an afternoon [@sike-eprint-2022-975]. Both had survived years of review. That is the entire case for a portfolio: a vetted scheme can still fall to one new idea, so you do not stake everything on one hard problem.
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attack&lt;/th&gt;
&lt;th&gt;What it recovers&lt;/th&gt;
&lt;th&gt;Complexity&lt;/th&gt;
&lt;th&gt;Severity&lt;/th&gt;
&lt;th&gt;Status vs deployed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;ISD (message recovery)&lt;/td&gt;
&lt;td&gt;plaintext of one ciphertext&lt;/td&gt;
&lt;td&gt;exponential, best near $2^{0.047n}$&lt;/td&gt;
&lt;td&gt;forces parameter growth&lt;/td&gt;
&lt;td&gt;the ruler; unbroken at recommended sizes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Structural (key recovery)&lt;/td&gt;
&lt;td&gt;the secret code, all ciphertexts&lt;/td&gt;
&lt;td&gt;2013 poly as rate to 1; 2023 and 2024 subexponential&lt;/td&gt;
&lt;td&gt;collapse of the family&lt;/td&gt;
&lt;td&gt;no key or message recovery; 2024 distinguisher reaches parameters&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DOOM (modifier)&lt;/td&gt;
&lt;td&gt;speeds up ISD on QC codes&lt;/td&gt;
&lt;td&gt;about $\sqrt{N}$ factor&lt;/td&gt;
&lt;td&gt;minor discount&lt;/td&gt;
&lt;td&gt;priced into HQC and BIKE&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Read against the thesis, the table is a &lt;em&gt;weighed prediction&lt;/em&gt;, not a scoreboard. Door 1, better ISD, is likely but shallow: it will keep forcing periodic parameter growth, exactly as it did to the 1978 parameters, an erosion that never ends the family.&lt;/p&gt;
&lt;p&gt;Door 2, a distinguisher maturing into key recovery, is unlikely but deep: it would end the family, and the frontier now &lt;em&gt;reaches&lt;/em&gt; Classic McEliece parameters as a distinguisher while remaining short of a recovery. The most-likely fault line is continued ISD erosion; the most-dangerous fault line is the structural road; and neither has broken a deployed parameter set.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The most-likely break is shallow: continued ISD erosion, already seen once at the parameter level, which forces periodic parameter growth. The most-dangerous break is deep: a structural distinguisher maturing into key recovery, which would end the family. Neither has reached a deployed parameter set.&lt;/p&gt;
&lt;/blockquote&gt;

- Can a structural distinguisher mature into *key recovery* at recommended parameters? The syzygy distinguisher reaches Classic McEliece parameters but does not recover [@randriambololona-2024].
- How much further can ISD erode the exponent? No proven lower bound exists, yet the trend is stubbornly asymptotic-only.
- Is binary Goppa truly indistinguishable from random at deployed rates? Sharpened, not settled, by the 2024 result.
- What is the concrete, computer-checked hardness of QCSD, including the exact DOOM factor for HQC?
- Does quantum computing buy anything beyond the Grover discount against codes? The absence of an abelian hidden-subgroup handle suggests not [@bernstein-2010].
- Can average-case hardness of the structured family be reduced to a worst-case problem? None is known, and the NP-hardness ceiling suggests it may be permanently out of reach.
&lt;p&gt;So we hold two believed-independent hard problems, two watched rulers, and no proofs. Given exactly that, how should you actually &lt;em&gt;deploy&lt;/em&gt; the hedge today?&lt;/p&gt;
&lt;h2&gt;13. Deploying the Hedge Today&lt;/h2&gt;
&lt;p&gt;The theory says &quot;hedge.&quot; The engineering question is &lt;em&gt;how&lt;/em&gt;, and the answer is not &quot;pick one.&quot;&lt;/p&gt;
&lt;p&gt;Choose &lt;strong&gt;Classic McEliece&lt;/strong&gt; when you want the most conservative option on the table: a forty-seven-year track record, byte-sized ciphertexts, and a design with no decryption failures. Its megabyte public key is tolerable precisely when a &lt;em&gt;static&lt;/em&gt; long-term key is fetched or pinned once and reused across many encapsulations, which is also the setting most exposed to &lt;a href=&quot;https://paragmali.com/blog/q-day-has-not-happened-the-incident-already-has-harvest-now-/&quot; rel=&quot;noopener&quot;&gt;harvest-now-decrypt-later&lt;/a&gt; collection [@mceliece-impl].&lt;/p&gt;
&lt;p&gt;Choose &lt;strong&gt;HQC&lt;/strong&gt; when you want the NIST-selected KEM, balanced kilobyte-scale keys and ciphertexts, and general-purpose ergonomics that suit ephemeral, per-session handshakes where a fresh public key ships every time [@pqc-hqc-site]. Classic McEliece is a poor fit there: shipping a fresh quarter-to-1.36-megabyte key on every session is prohibitive, the same key-size objection that kept it out of the NIST selection [@nist-ir-8545]. The deciding factor is usually bandwidth &lt;em&gt;shape&lt;/em&gt;, not a single bit count.&lt;/p&gt;
&lt;p&gt;But the real recommendation is neither scheme alone. It is to deploy in &lt;strong&gt;hybrid&lt;/strong&gt;, and the combiner has a precise, provable shape. Run two independent KEMs and fold both shared secrets into one session key, so that breaking either component alone leaves the session key secure.&lt;/p&gt;
&lt;p&gt;Giacon, Heuer, and Poettering proved that a black-box KEM combiner &quot;yield[s] a new KEM that is (CCA) secure as long as at least one of the ingredient KEMs is,&quot; provided the key-derivation step also binds the component ciphertexts and public keys, the transcript [@kem-combiners-2018]. That proviso is not a formality: a function that hashes only the two secrets and ignores the ciphertexts can lose IND-CCA security, because an attacker who mauls one component&apos;s ciphertext may leave the derived key unchanged, defeating non-malleability.&lt;/p&gt;
&lt;p&gt;The concrete, IND-CCA-preserving instance is &lt;strong&gt;X-Wing&lt;/strong&gt;, which fixes X25519 and ML-KEM-768 and sets the session key to &lt;code&gt;SHA3-256(ss_ML-KEM || ss_X25519 || ct_X25519 || pk_X25519 || XWingLabel)&lt;/code&gt; [@xwing-2024, @xwing-cfrg-draft]. It is proved to be a post-quantum IND-CCA KEM if ML-KEM-768 is one, and a classically IND-CCA KEM if the strong Diffie-Hellman assumption holds for X25519: secure if &lt;em&gt;either&lt;/em&gt; component survives [@xwing-2024]. Notice that it binds the X25519 ciphertext and public key directly but does not re-hash the ML-KEM ciphertext, because ML-KEM&apos;s own transform already folds that ciphertext into its shared secret [@xwing-cfrg-draft].&lt;/p&gt;
&lt;p&gt;Wire the two schemes of this article into that frame by matching NIST security levels. For long-term, harvest-now-sensitive &lt;em&gt;static&lt;/em&gt;-key data, run a level-5 triple hedge, X25519 with ML-KEM-1024 and &lt;code&gt;mceliece6688128&lt;/code&gt; or &lt;code&gt;mceliece8192128&lt;/code&gt;, so that no single break across classical, lattice, or code is fatal; McEliece belongs here specifically because a static key amortizes over many messages while its 208-byte ciphertexts dominate per-message traffic [@mceliece-impl, @nist-ir-8545].&lt;/p&gt;
&lt;p&gt;For &lt;em&gt;ephemeral&lt;/em&gt; per-session handshakes, run X25519 with ML-KEM-768 or ML-KEM-1024 and HQC-3 or HQC-5, or take X-Wing as the baseline and add an HQC leg only where a code-based hedge is mandated [@pqc-hqc-site]. That layered posture is the entire reason NIST standardized a code-based KEM after it already had a lattice one [@nist-ir-8545].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Pick your security level from the current best ISD cost with the Grover discount already applied, which is what the &lt;code&gt;mceliece6*&lt;/code&gt; and HQC-5 tiers do. Then build crypto-agility into the system, so a future ISD improvement or a maturing distinguisher is answered by swapping parameters or primitives, not by a redesign under pressure.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;One boundary carries over from the very first section. Choosing a scheme, or a combiner, with a well-understood &lt;em&gt;mathematical&lt;/em&gt; fault line does not exempt you from the &lt;em&gt;implementation&lt;/em&gt; attacks that fill the companion track: constant-time decoding, protected randomness, and careful failure handling still matter. The combiner itself is a construction, in scope for this article; its constant-time, side-channel-resistant &lt;em&gt;implementation&lt;/em&gt; is not. This article told you where the algorithm would give way. It did not promise your code was written correctly.&lt;/p&gt;
&lt;p&gt;Deploying the hedge well means holding two ideas at once: real confidence in the independence of the bet, and clear eyes about its fault lines. The FAQ tackles the specific confusions that break that balance.&lt;/p&gt;
&lt;h2&gt;14. Frequently Asked Questions&lt;/h2&gt;


No. Improved information-set decoding, in the 2008 Bernstein-Lange-Peters attack, recovered plaintexts from the original $[1024, 524]$, $t = 50$ *parameters* at roughly $2^{60}$ operations, but it never recovered the binary-Goppa *structure* [@blp-2008]. The fix was simply larger parameters, and the trapdoor idea was untouched. &quot;Unbroken since 1978&quot; is a precise claim about the structure, not about the original numbers.


There is no known link. Their hardness, decoding a random-looking code, has no known reduction to or from lattice problems, which is exactly why NIST standardized a code-based KEM alongside the lattice one [@nist-hqc-announce]. The two worlds share some algorithmic tooling, such as nearest-neighbor search, but not an assumption, so a lattice break does not transfer.


No. Decoding a general linear code is NP-complete in the *worst* case [@bmvt-1978], but the deployed schemes rest on the *average-case* hardness of a *specific structured* family, and no reduction bridges the two. Security here is believed and measured, by the cost of the best known ISD, not proven.


No, and it is out of scope here. An attack of that kind targets a reference *implementation* through a side channel; it does not touch the quasi-cyclic syndrome-decoding problem the scheme&apos;s security rests on. Implementation and side-channel attacks are real and important, but they belong to the companion &quot;How It Breaks in Real Life&quot; track, not to a structural analysis.


No. NIST selected HQC in March 2025; Classic McEliece is on the ISO/IEC track [@nist-hqc-announce]. NIST&apos;s IR 8545 explains both why HQC was chosen over BIKE and why Classic McEliece was not selected, the deciding factor against it being its very large public key [@nist-ir-8545].


Only weakly. Shor&apos;s algorithm has no structural handle on syndrome decoding, which exposes no abelian hidden-subgroup problem, so it does not apply. Grover&apos;s algorithm gives at most a quadratic search discount, and against ISD&apos;s structured search even less, absorbed by growing the key size [@bernstein-2010]. No Shor-style collapse of code-based schemes is known.


No. It is the most significant structural result in forty-seven years, subexponential and the first to *reach* Classic McEliece parameters, but it is explicitly a distinguisher in the CPA model, not a key-recovery or message-recovery break of those parameters [@randriambololona-2024]. Calling it &quot;McEliece broken&quot; is a category error.

&lt;p&gt;Every answer points back to one idea: precise language is the difference between &quot;watched&quot; and &quot;broken.&quot;&lt;/p&gt;
&lt;h2&gt;15. The Hedge and Its Fault Line&lt;/h2&gt;
&lt;p&gt;Return to March 2025. NIST, having already crowned a lattice-based encryption standard, standardized a second one on a bruised 1978 idea, and it looked like betting against its own decision. It was not. It was refusing to keep all of encryption&apos;s weight on a single hard problem.&lt;/p&gt;
&lt;p&gt;Everything since has justified that refusal. Code-based cryptography is the diversification bet, and the bet is sound in the one way that matters: a lattice break does not debit it. Shor&apos;s algorithm structurally misses syndrome decoding, and no reduction connects the two assumptions, so the independence is real rather than rhetorical.&lt;/p&gt;
&lt;p&gt;Its own most-likely fault line is not exotic. It is information-set decoding, which has already &quot;broken&quot; McEliece once, at the level of the 1978 &lt;em&gt;parameters&lt;/em&gt;, never the &lt;em&gt;structure&lt;/em&gt;, and which crawls, moving the security exponent only about 15 to 20 percent in fifty-six years [@mceliece-comparison]. Its deeper, less-likely fault line is a structural distinguisher maturing into key recovery, a frontier that in 2024 finally &lt;em&gt;reached&lt;/em&gt; Classic McEliece parameters yet remains a distinguisher, not a break [@randriambololona-2024]. Both fault lines are watched closely. Neither has reached a recommended parameter set.&lt;/p&gt;
&lt;p&gt;That is the shape of the whole argument, and it carries a lesson beyond these two schemes. The deepest security engineering is sometimes not building the strongest single wall. It is declining to bet everything on one wall, however strong, because the history of this field is a history of strong walls falling to a single new idea. Two believed-independent hard problems, each with a slowly-moving, well-instrumented ruler, is a sturdier posture than one problem with a taller number.&lt;/p&gt;
&lt;p&gt;There is a quiet marvel in where this landed. An idea from 1978, dismissed for two decades as an impractical museum piece, too bulky to use, is now the insurance policy on the entire post-quantum transition. It did not have to become strong. It only had to stay different.&lt;/p&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;how-mceliece-and-hqc-would-break&quot; keyTerms={[
  { term: &quot;Syndrome decoding&quot;, definition: &quot;Recovering a low-weight error from its syndrome under a parity-check matrix; NP-complete in the worst case and the basis of code-based security.&quot; },
  { term: &quot;Information-set decoding (ISD)&quot;, definition: &quot;The generic message-recovery attack that prices every code-based parameter; exponential for all known variants and the security ruler.&quot; },
  { term: &quot;Binary Goppa code&quot;, definition: &quot;The moderate-rate algebraic code hidden inside Classic McEliece; the lone survivor of the code-family graveyard.&quot; },
  { term: &quot;Structural distinguisher&quot;, definition: &quot;An algorithm that tells a disguised algebraic code from a random one; weaker than key recovery but the first symptom of a failing code family.&quot; },
  { term: &quot;Quasi-cyclic syndrome decoding (QCSD)&quot;, definition: &quot;HQC&apos;s hardness assumption; circulant structure shrinks keys and also enables the DOOM speedup.&quot; },
  { term: &quot;Representation technique&quot;, definition: &quot;The counting idea behind MMT and BJMM that lowers the ISD exponent by making many valid error splittings, needing only one.&quot; },
  { term: &quot;Hidden-subgroup problem&quot;, definition: &quot;The abelian structure Shor&apos;s algorithm exploits to break RSA and elliptic curves, and which syndrome decoding lacks.&quot; }
]} questions={[
  { q: &quot;Why does a break of lattice cryptography not threaten Classic McEliece or HQC?&quot;, a: &quot;Their security rests on syndrome decoding, which has no known reduction to or from lattice problems, so the two assumptions are independent.&quot; },
  { q: &quot;In what precise sense is Classic McEliece unbroken since 1978?&quot;, a: &quot;The binary-Goppa structure has never been recovered; only the original 1978 parameters fell, to improved ISD in 2008, and the fix was larger parameters.&quot; },
  { q: &quot;What is the difference between the two attack doors?&quot;, a: &quot;Door 1, ISD, recovers one message and forces parameter growth; Door 2, structural key recovery, would recover the secret code and end the family.&quot; },
  { q: &quot;Why does Shor&apos;s algorithm miss code-based cryptography while Grover only weakens it?&quot;, a: &quot;Syndrome decoding exposes no abelian hidden-subgroup structure for Shor to exploit; Grover gives only a quadratic search discount absorbed by larger keys.&quot; },
  { q: &quot;What is the status of the 2024 syzygy distinguisher?&quot;, a: &quot;It is subexponential and reaches Classic McEliece parameters, but it is a CPA-model distinguisher, not a key-recovery or message-recovery break.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>post-quantum-cryptography</category><category>code-based-cryptography</category><category>classic-mceliece</category><category>hqc</category><category>information-set-decoding</category><category>cryptanalysis</category><category>syndrome-decoding</category><category>kem</category><author>noreply@paragmali.com (Parag Mali)</author></item><item><title>One Event, Three Assumptions, Five Answers: A Field Guide to the Post-Quantum Toolkit</title><link>https://paragmali.com/blog/one-event-three-assumptions-five-answers-a-field-guide-to-th/</link><guid isPermaLink="true">https://paragmali.com/blog/one-event-three-assumptions-five-answers-a-field-guide-to-th/</guid><description>A field guide to the five NIST post-quantum primitives -- ML-KEM, ML-DSA, SLH-DSA, FN-DSA, HQC: math intuition, exact sizes, failures, and decision rules.</description><pubDate>Tue, 14 Jul 2026 01:32:13 GMT</pubDate><content:encoded>
Shor&apos;s 1994 algorithm condemned RSA, Diffie-Hellman, and elliptic curves [@shor-1994], and &quot;harvest now, decrypt later&quot; means the clock is already running on today&apos;s traffic. NIST&apos;s answer is not one replacement but a **toolkit**: three finalized standards -- ML-KEM for key exchange, ML-DSA and SLH-DSA for signatures, all published on 2024-08-13 [@fips-203] [@fips-204] [@fips-205] -- and two more still on the way, FN-DSA (Falcon) and HQC, both pre-final [@fips-206-perlner-2025] [@nist-ir-8545]. The five are spread deliberately across lattices, hash functions, and codes so that no single mathematical break takes everything down. There is no free lunch: every choice trades size against speed against how conservative the assumption is. And, tellingly, **nothing in the toolkit has been mathematically broken.** Every real-world failure so far has been an implementation leak -- KyberSlash&apos;s secret-dependent division [@kyberslash-site], Falcon&apos;s floating-point hazard [@fouque-gsnorm-2019] -- while the era&apos;s two famous cryptanalytic breaks, SIKE and Rainbow, hit schemes that never made the cut [@castryck-decru-sidh-2022] [@beullens-rainbow-2022].
&lt;h2&gt;1. Somebody Is Already Saving Your Handshake&lt;/h2&gt;
&lt;p&gt;Right now, somewhere, a machine may be recording this very TLS session -- not to read today, but to decrypt on the afternoon a large quantum computer finally boots. That is not a thriller premise. It is the stated design assumption behind a change that is already shipping in production TLS software, where the default key exchange offered is no longer plain X25519 but a hybrid whose second half is called ML-KEM [@openssl-35-notes]. The strange part is not that the field replaced the math. It is that replacing it took &lt;strong&gt;five&lt;/strong&gt; different algorithms, resting on &lt;strong&gt;three&lt;/strong&gt; unrelated hard problems, to answer a &lt;strong&gt;single&lt;/strong&gt; result published in 1994 -- and that, so far, not one of the five has actually been broken.&lt;/p&gt;
&lt;p&gt;The single result is Shor&apos;s algorithm. In 1994 Peter Shor showed that a large, fault-tolerant quantum computer could factor integers and compute discrete logarithms in polynomial time [@shor-1994]. That one capability condemns essentially every public-key system deployed on the internet: RSA rests on factoring, Diffie-Hellman and elliptic-curve cryptography rest on discrete logarithms. (This series covered those primitives directly in &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;Part 14 on RSA&lt;/a&gt;, &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;Part 15 on elliptic curves&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;Part 18 on Diffie-Hellman&lt;/a&gt;.) The moment a cryptographically relevant quantum computer exists, all three fall together.&lt;/p&gt;

An attack strategy in which an adversary records encrypted traffic today, stores it, and decrypts it years later once a quantum computer becomes available. It means the quantum threat is not purely in the future: any secret that must stay confidential past the arrival of quantum computing is already exposed the moment it crosses the wire.
&lt;p&gt;Harvest now, decrypt later is why this is urgent before any quantum computer exists. If your threat model includes an adversary who can afford disk space and patience, then a session key protecting a 20-year secret is already at risk today [@nist-pqc-project]. That is the reasoning behind migrating key establishment first, and it is why the hybrid X25519MLKEM768 key share now ships as a default key share in OpenSSL 3.5, and was enabled by default in OpenSSH 9.9 before becoming the default key exchange in OpenSSH 10.0 [@openssl-35-notes] [@openssh-99-notes] [@openssh-pq].&lt;/p&gt;
&lt;p&gt;So the threat is one thing, sharp and singular. Why is the answer five things? NIST did not standardize one post-quantum cipher; it assembled a &lt;strong&gt;toolkit&lt;/strong&gt; -- three finalized standards and two more in progress -- and spread it across three unrelated families of hard problem: structured lattices, hash functions, and error-correcting codes. The bet is that a mathematical breakthrough against one family is unlikely to touch the others. To see why the answer is a toolkit, not a single cipher: its parts are older than the threat they answer.&lt;/p&gt;
&lt;h2&gt;2. The Threat, and the Three Old Ideas That Outlived It&lt;/h2&gt;
&lt;p&gt;Here is the twist that makes the whole story make sense: the replacements predate the threat. The oldest members of the toolkit were invented for reasons that had nothing to do with quantum computers, and they turned out to be quantum-safe by accident.&lt;/p&gt;
&lt;p&gt;Robert McEliece published a code-based public-key cryptosystem in 1978, hiding a secret, efficiently decodable error-correcting code (a binary Goppa code) behind a scrambled generator matrix so that an attacker faces the task of decoding a random-looking linear code [@mceliece-1978]. One year later, Ralph Merkle showed how to build digital signatures out of nothing but a hash function, chaining one-time keys under a binary hash tree whose root is the public key [@merkle-thesis-1979]; he polished the construction a decade later as &quot;A Certified Digital Signature&quot; [@merkle-cds-1989]. Both predate Shor by fifteen-plus years. Both are still standing.&lt;/p&gt;
&lt;p&gt;Then, in 1994, the threat arrived. Shor&apos;s quantum algorithm solves factoring and discrete logarithm in polynomial time, condemning RSA, Diffie-Hellman, and elliptic curves the moment a large quantum computer runs it [@shor-1994]. Two years later Lov Grover found a quantum search algorithm with a quadratic speedup [@grover-1996]. Grover is the good news that bounds the damage: a mere square-root speedup means doubling a symmetric key or hash-output length restores the security margin, which is exactly why hash-based signatures are considered the most conservative branch of the toolkit.Shor is catastrophic (exponential to polynomial); Grover is survivable (a square-root factor). The asymmetry is the reason symmetric ciphers and hash functions merely need bigger parameters, while public-key cryptography needed entirely new hard problems.&lt;/p&gt;
&lt;p&gt;Lattices arrived on a separate track, and again for their own reasons. In 1996 Miklos Ajtai proved a startling worst-case-to-average-case reduction: breaking a &lt;em&gt;random&lt;/em&gt; instance of a certain lattice problem is as hard as breaking the &lt;em&gt;worst&lt;/em&gt; case [@ajtai-1996]. That single result promoted lattices from a curiosity to a rigorous foundation. In 1998 Hoffstein, Pipher, and Silverman published NTRU, the first lattice scheme compact and fast enough to consider deploying, working over a small polynomial ring with tiny coefficients [@ntru-1998].NTRU was first announced at the CRYPTO 1996 rump session but formally published at ANTS-III in 1998, so you will see both dates in the literature. Merkle&apos;s hash-tree work has the same two-date character: the 1979 thesis, then the 1989 CRYPTO paper.&lt;/p&gt;
&lt;p&gt;Oded Regev tied the knot in 2005 with Learning With Errors (LWE), a versatile assumption whose hardness reduces (quantumly) to worst-case lattice problems and whose one-sentence intuition -- add noise to linear algebra -- runs through every lattice member of the toolkit [@regev-lwe-2005].&lt;/p&gt;
&lt;p&gt;The last pieces are the mechanisms that make these foundations into safe schemes. The Fujisaki-Okamoto transform (1999) upgrades a weak encryption scheme into a strong one by re-encrypting on decryption and checking consistency [@fo-1999]. The GPV framework (2008) showed how to build lattice hash-and-sign signatures using a trapdoor and discrete-Gaussian sampling [@gpv-2007]. Lyubashevsky&apos;s &quot;Fiat-Shamir with aborts&quot; (2009) offered a rival way to sign, rejecting and restarting whenever a candidate would leak the key [@lyubashevsky-fswa-2009]. Ring-LWE (2010) moved LWE into polynomial rings for compact keys and fast arithmetic [@lpr-ringlwe-2010]. And in 2015, SPHINCS made hash-based signatures &lt;em&gt;stateless&lt;/em&gt;, removing the operational footgun that had kept Merkle&apos;s idea out of ordinary hands [@sphincs-2015].&lt;/p&gt;

timeline
    title Post-quantum foundations predate the 1994 threat
    1978 : McEliece code-based encryption
    1979 : Merkle hash-based signatures
    1994 : Shor algorithm breaks RSA and ECC
    1996 : Grover search : Ajtai hard lattices
    1998 : NTRU ring lattices
    2005 : Regev Learning With Errors
    2008 : GPV lattice hash-and-sign
    2009 : Fiat-Shamir with aborts
    2010 : Ring-LWE efficiency
    2015 : SPHINCS stateless hashing
&lt;p&gt;Read the timeline as three columns hiding in one line. Codes and hashes (1978, 1979) are the ancient, conservative branches. Lattices (1996 to 2010) are the young, efficient branch that took the most theoretical work to make safe. The mechanisms (FO, GPV, Fiat-Shamir-with-aborts) are the connective tissue that turns a hard problem into a usable cipher.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Year&lt;/th&gt;
&lt;th&gt;Who&lt;/th&gt;
&lt;th&gt;Idea&lt;/th&gt;
&lt;th&gt;Why it mattered&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;1978&lt;/td&gt;
&lt;td&gt;McEliece&lt;/td&gt;
&lt;td&gt;Code-based encryption&lt;/td&gt;
&lt;td&gt;Oldest surviving PQC family; ancestor of HQC [@mceliece-1978]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1979&lt;/td&gt;
&lt;td&gt;Merkle&lt;/td&gt;
&lt;td&gt;Hash-based signatures&lt;/td&gt;
&lt;td&gt;Weakest possible assumption; ancestor of SLH-DSA [@merkle-thesis-1979]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1994&lt;/td&gt;
&lt;td&gt;Shor&lt;/td&gt;
&lt;td&gt;Quantum factoring and discrete log&lt;/td&gt;
&lt;td&gt;The single threat the toolkit answers [@shor-1994]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1996&lt;/td&gt;
&lt;td&gt;Ajtai&lt;/td&gt;
&lt;td&gt;Worst-case lattice hardness&lt;/td&gt;
&lt;td&gt;Made lattices a rigorous foundation [@ajtai-1996]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2005&lt;/td&gt;
&lt;td&gt;Regev&lt;/td&gt;
&lt;td&gt;Learning With Errors&lt;/td&gt;
&lt;td&gt;The assumption under ML-KEM and ML-DSA [@regev-lwe-2005]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2015&lt;/td&gt;
&lt;td&gt;Bernstein et al.&lt;/td&gt;
&lt;td&gt;Stateless hash signatures&lt;/td&gt;
&lt;td&gt;Made hash signatures deployable [@sphincs-2015]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Each of these old ideas was quantum-safe. And none was deployable as written. To see why, watch each one walk straight into a different wall.&lt;/p&gt;
&lt;h2&gt;3. Three Walls: Why the Old Ideas Could Not Ship&lt;/h2&gt;
&lt;p&gt;A cipher can be perfectly correct -- decrypting every honest message, verifying every honest signature -- and still be unusable, or worse, still hand over its secret key. The first generation of post-quantum schemes taught that lesson three times, each on a different axis.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The first wall is size.&lt;/strong&gt; McEliece&apos;s cryptosystem has resisted cryptanalysis for more than forty-five years, which is a stronger track record than RSA has. But its public key is an entire generator matrix. In the modern Classic McEliece parameter sets, that means a public key from roughly 261 KB (for the &lt;code&gt;mceliece348864&lt;/code&gt; set) up to about 1.36 MB (for &lt;code&gt;mceliece8192128&lt;/code&gt;) [@classic-mceliece]. A megabyte of key material per connection is a non-starter for a TLS handshake that budgets a few kilobytes. McEliece is not broken; it is simply too big to carry. Its security was never the problem. Its shape was.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The second wall is state.&lt;/strong&gt; Merkle&apos;s hash-tree signatures, engineered into the modern XMSS and LMS schemes and standardized by NIST in SP 800-208, are compact and rest on the most conservative assumption in cryptography [@nist-sp-800-208]. But they are &lt;em&gt;stateful&lt;/em&gt;: the signer must advance a one-time-key index after every signature and must never, ever reuse one.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; NIST SP 800-208 warns that if an attacker obtains two signatures made with the same one-time key, &quot;it would become computationally feasible for that attacker to forge signatures on arbitrary messages&quot; [@nist-sp-800-208]. Restore a virtual machine from a snapshot, clone a key into a backup, or run two signer replicas, and you can silently reuse an index. The math is impeccable; the operational requirement -- perfect, rollback-proof, monotonic state, forever -- is what ordinary systems cannot guarantee.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;The third wall is the subtle one, and it reframes the whole problem: leakage.&lt;/strong&gt; The natural way to sign with a lattice is hash-and-sign in the style of GGH and its NTRU instantiation, NTRUSign: hash the message to a target point, then use your secret &quot;good&quot; basis to round to a nearby lattice point. A verifier checks the point is on the lattice and close to the target. It verifies perfectly. It is also fatally broken.&lt;/p&gt;
&lt;p&gt;In 2006, Phong Nguyen and Oded Regev showed why in a paper with a wonderful title: &quot;Learning a Parallelepiped&quot; [@nguyen-regev-2006]. Every signature is the difference between the hashed target and a lattice point, and those differences are distributed over the &lt;em&gt;fundamental parallelepiped&lt;/em&gt; of the secret basis. Collect a few hundred signatures, and you can reconstruct the shape of that parallelepiped -- which is to say, you can recover the secret key. The signer was leaking the key a little at a time, in the statistical shape of its own outputs, while every individual signature passed verification.&lt;/p&gt;

When the distribution of a scheme&apos;s public outputs (its signatures or its decryption behavior) depends on the secret key, an attacker who collects enough outputs can infer the key -- even though each individual output is valid. The break is statistical, not logical: nothing is forged, yet the key is recovered from the shape of honest data.
&lt;p&gt;Put the three walls side by side and a pattern appears. McEliece fails on size, stateful hashes fail on operational state, and NTRUSign fails on leakage -- three completely different axes. The naive strategy of &quot;pick the oldest unbroken idea and ship it&quot; runs aground because being unbroken is not the same as being safe to deploy. The NTRUSign failure is the sharpest version of the lesson, because it severs two ideas most people treat as one.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Correctness is not security. A scheme can verify every honest signature and still surrender its secret key through the statistical shape of a few hundred outputs. The real design goal is not &quot;find math no one has broken.&quot; It is &quot;make the outputs reveal nothing about the secret.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That reframing is the hinge of the entire toolkit. Once you decide the enemy is any correlation between your public outputs and your private key, the design problem becomes concrete: engineer the transcript, the ciphertext, and the failure behavior so they are provably independent of the secret. That single idea, applied four different ways, is the modern toolkit.&lt;/p&gt;
&lt;h2&gt;4. The Competition: One Fix, Four Times&lt;/h2&gt;
&lt;p&gt;The forcing function was not a single genius. It was an open, adversarial competition. NIST issued its public Call for Proposals in December 2016 and spent the next years pruning dozens of submissions across multiple rounds, documenting the reasoning in status reports as it went [@nistir-8413]. What emerged was not one lineage but four convergent tracks, running inside three unrelated hardness assumptions, each track advancing by fixing the specific flaw that sank its predecessor.&lt;/p&gt;

flowchart LR
    subgraph TA[&quot;Track A -- codes&quot;]
      A1[McEliece 1978] --&amp;gt; A2[Niederreiter] --&amp;gt; A3[QC-MDPC BIKE] --&amp;gt; A4[HQC]
    end
    subgraph TB[&quot;Track B -- hashes&quot;]
      B1[Lamport OTS] --&amp;gt; B2[Merkle WOTS] --&amp;gt; B3[XMSS LMS] --&amp;gt; B4[SPHINCS+]
    end
    subgraph TC[&quot;Track C -- lattice KEM&quot;]
      C1[NTRU] --&amp;gt; C2[LWE] --&amp;gt; C3[Ring-LWE] --&amp;gt; C4[Module-LWE]
    end
    subgraph TD[&quot;Track D -- lattice signatures&quot;]
      D1[GGH NTRUSign] --&amp;gt; D2[GPV Falcon]
      D1 --&amp;gt; D3[Fiat-Shamir Dilithium]
    end
    A4 --&amp;gt; TK[Five toolkit tips]
    B4 --&amp;gt; TK
    C4 --&amp;gt; TK
    D2 --&amp;gt; TK
    D3 --&amp;gt; TK
    P1[SIKE isogeny] -.broke 2022.-&amp;gt; XX[Pruned families]
    P2[Rainbow multivariate] -.broke 2022.-&amp;gt; XX
&lt;p&gt;&lt;strong&gt;Track A, codes, is a war on key size.&lt;/strong&gt; McEliece&apos;s matrix is enormous, so Niederreiter published the &quot;dual&quot; version that sends a compact syndrome instead of a full codeword -- smaller ciphertext, but the public key is still a matrix. Quasi-cyclic MDPC codes then collapsed that key to a few kilobytes by making the matrix reconstructable from a single row, an idea realized in the BIKE scheme [@mdpc-mceliece-2013].&lt;/p&gt;

The hard problem under every code-based scheme: given a random-looking parity-check matrix and a syndrome (the matrix applied to an unknown low-weight error), recover the error. Decoding a general random linear code is NP-hard; a code-based cryptosystem hides a secret, efficiently decodable code so that only the key holder can decode, while an attacker faces the random-code version.
&lt;p&gt;But BIKE walked into a wall of its own. Its iterative bit-flipping decoder occasionally fails, and -- this is the trap -- &lt;em&gt;those failures depend on the secret key&lt;/em&gt;. In 2016 Guo, Johansson, and Stankovski turned that into a full reaction attack: feed the decoder crafted ciphertexts, watch which ones fail, and recover the private key from the pattern of failures [@gjs-mdpc-2016]. The very feature that shrank the key opened a side channel.&lt;/p&gt;

The probability that correct decapsulation fails on an honest ciphertext. For post-quantum KEMs this is not merely a correctness nuisance: if the failure rate is non-negligible and correlated with the secret, each failure leaks information, and enough failures recover the key. DFR is therefore a security parameter, and a good scheme drives it to a cryptographically negligible level with a bound that does not depend on the secret.
&lt;p&gt;HQC is the fix: keep the quasi-cyclic key size, but decode with a &lt;em&gt;public&lt;/em&gt;, fixed code whose failure rate can be bounded analytically and does not depend on the secret. That is precisely why NIST chose HQC over BIKE -- its DFR analysis was judged more mature [@nist-ir-8545].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Track B, hashes, is a war on state&lt;/strong&gt;, and the whole story is the fight against one number: the leaf index. Lamport&apos;s one-time signature signs once per key; Merkle put many one-time keys under a tree so one root signs many messages; XMSS and LMS engineered that into standardized, stateful schemes [@nist-sp-800-208]; and SPHINCS removed the state entirely by choosing a random leaf from a space so vast that collisions are negligible, backed by a few-time signature to absorb the rare clash [@sphincs-2015]. SPHINCS+ then hardened it with tweakable hashes and a tighter few-time scheme called FORS [@sphincs-plus-framework-2019].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Track C, lattice KEMs, is a war over structure.&lt;/strong&gt; NTRU was fast but rested on a heuristic assumption; LWE bought a worst-case hardness reduction but needed a full random matrix as its key; Ring-LWE compressed that matrix to a single polynomial with fast NTT arithmetic [@lpr-ringlwe-2010]; and Module-LWE dialed the ring structure partway back down, trading a sliver of efficiency for a hedge against the possibility that too much algebraic structure helps the attacker [@crystals-kyber].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Track D, lattice signatures, is where the tree forks and both branches survive.&lt;/strong&gt; The GGH/NTRUSign transcript leak forced a choice, and the field kept two answers: GPV hash-and-sign, which samples from a discrete Gaussian whose shape is provably independent of the secret basis (this becomes Falcon), and Fiat-Shamir with aborts, which rejects and restarts until the transcript is key-independent (this becomes Dilithium) [@gpv-2007] [@lyubashevsky-fswa-2009].&lt;/p&gt;
&lt;p&gt;Stare at those four tracks and the same move appears in every one.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Every surviving generation makes the transcript or the failure channel provably independent of the secret. Gaussian sampling and rejection sampling remove the signature-transcript leak; the Fujisaki-Okamoto transform removes the decryption-failure oracle; statelessness removes the operational-state leak; HQC&apos;s public decoder removes BIKE&apos;s secret-dependent failures. The toolkit is not five unrelated tricks. It is one principle instantiated five ways.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The competition also pruned in public, and the prunings are the best argument for the whole strategy.&lt;/p&gt;

Two schemes that had survived years of scrutiny fell in 2022, within months of each other. Ward Beullens broke Rainbow, a multivariate signature finalist, in what his paper title advertised as a weekend on a laptop [@beullens-rainbow-2022]. Then Wouter Castryck and Thomas Decru broke SIKE, an isogeny-based KEM, with a key-recovery attack that runs in about ten minutes on a single core [@castryck-decru-sidh-2022]. Both schemes had strong theory and years of failed attacks behind them. Both were destroyed by a single new idea. And both were *outside* the final toolkit -- Rainbow was not selected, and SIKE advanced to NIST&apos;s fourth round only to be broken before it could be selected. That is the empirical case for diversity in one sentence: no amount of survived cryptanalysis is a proof, so you hedge across unrelated assumptions rather than bet everything on one.
&lt;p&gt;This is the moment to state the honest ending up front -- the argument the rest of the article defends.&lt;/p&gt;

Nothing in the toolkit has been mathematically broken. Every real-world failure so far has been an implementation leak -- and the two famous algorithmic breaks of the era hit schemes that never made the cut.
&lt;p&gt;It helps to see every notable failure of the era in one place, sorted by what actually went wrong. Two of these are implementation leaks in surviving schemes (the math is intact); two are historical breaks of superseded designs; and two are the non-toolkit cryptanalytic breaks that justify the hedge.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Failure&lt;/th&gt;
&lt;th&gt;Scheme&lt;/th&gt;
&lt;th&gt;Root cause&lt;/th&gt;
&lt;th&gt;Lesson&lt;/th&gt;
&lt;th&gt;In the toolkit?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Parallelepiped leak&lt;/td&gt;
&lt;td&gt;GGH / NTRUSign&lt;/td&gt;
&lt;td&gt;Signature distribution depends on the secret basis [@nguyen-regev-2006]&lt;/td&gt;
&lt;td&gt;Make the transcript key-independent&lt;/td&gt;
&lt;td&gt;No -- superseded ancestor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reaction attack&lt;/td&gt;
&lt;td&gt;QC-MDPC / BIKE&lt;/td&gt;
&lt;td&gt;Secret-dependent decoding failures form an oracle [@gjs-mdpc-2016]&lt;/td&gt;
&lt;td&gt;Bound the DFR with a public decoder&lt;/td&gt;
&lt;td&gt;No -- not selected&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SIKE key recovery&lt;/td&gt;
&lt;td&gt;SIDH isogenies&lt;/td&gt;
&lt;td&gt;Torsion-point structure enables recovery [@castryck-decru-sidh-2022]&lt;/td&gt;
&lt;td&gt;A decade unbroken is not a proof&lt;/td&gt;
&lt;td&gt;No -- non-toolkit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rainbow weekend break&lt;/td&gt;
&lt;td&gt;Multivariate&lt;/td&gt;
&lt;td&gt;Structural attack on the oil-and-vinegar map [@beullens-rainbow-2022]&lt;/td&gt;
&lt;td&gt;Diversify assumptions&lt;/td&gt;
&lt;td&gt;No -- non-toolkit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KyberSlash&lt;/td&gt;
&lt;td&gt;ML-KEM (Kyber)&lt;/td&gt;
&lt;td&gt;Secret-dependent division timing [@kyberslash-site]&lt;/td&gt;
&lt;td&gt;Constant-time reduction; math untouched&lt;/td&gt;
&lt;td&gt;Yes -- implementation leak&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gram-Schmidt leak&lt;/td&gt;
&lt;td&gt;FN-DSA (Falcon)&lt;/td&gt;
&lt;td&gt;Floating-point sampler leaks basis norms [@fouque-gsnorm-2019]&lt;/td&gt;
&lt;td&gt;Use a vetted constant-time sampler&lt;/td&gt;
&lt;td&gt;Yes -- implementation hazard&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Notice that the bottom two rows -- the only failures inside the toolkit -- are both in the &quot;implementation&quot; column, never the &quot;math&quot; column. That distinction is the spine of everything that follows. By 2024 the pruned tree had five surviving tips. Three of them became law on a single day.&lt;/p&gt;
&lt;h2&gt;5. Three Standards in One Day&lt;/h2&gt;
&lt;p&gt;On 2024-08-13, NIST published three Federal Information Processing Standards at once: FIPS 203 (ML-KEM) for key encapsulation, FIPS 204 (ML-DSA) and FIPS 205 (SLH-DSA) for signatures [@fips-203] [@fips-204] [@fips-205]. That single date is when post-quantum cryptography crossed from an open competition into the law of the land, the thing an auditor can require and a protocol can mandate.&lt;/p&gt;
&lt;p&gt;Each standard is the hardened descendant of a competition submission, and each carries one defining idea forward.&lt;/p&gt;

A KEM is a three-function object -- key generation, encapsulate, decapsulate -- that lets two parties agree on a random shared secret. Encapsulate takes a public key and returns a ciphertext plus a shared secret; decapsulate takes the ciphertext and the private key and returns the same shared secret. It is the post-quantum replacement for the key-exchange half of Diffie-Hellman, and it composes with a symmetric cipher through the KEM-DEM pattern this series covered in [Part 19 on HPKE](/blog/the-standard-was-boring-that-was-the-point-a-field-guide-to-/). Crucially, a KEM is not a drop-in for a static-static Diffie-Hellman handshake -- a distinction we return to in the limits.
&lt;p&gt;&lt;strong&gt;ML-KEM&lt;/strong&gt; is Module-LWE encryption wrapped in a Fujisaki-Okamoto transform with &lt;em&gt;implicit rejection&lt;/em&gt;, so that an invalid ciphertext yields a pseudo-random shared secret rather than an error -- there is no decapsulation-failure oracle to probe [@fips-203]. &lt;strong&gt;ML-DSA&lt;/strong&gt; is a Fiat-Shamir-with-aborts signature built entirely from uniform integers, chosen deliberately so the implementation needs no floating point and is easy to make constant-time [@fips-204]. &lt;strong&gt;SLH-DSA&lt;/strong&gt; is a stateless hash-based signature whose security rests on nothing but its hash function -- the conservative backstop [@fips-205].&lt;/p&gt;
&lt;p&gt;ML-KEM is the standardized CRYSTALS-Kyber; ML-DSA is Dilithium; SLH-DSA is SPHINCS+. These are the same schemes under new NIST names, with standardization edits (tweaked hashing, encodings, and parameter cleanups), not fresh designs. If you have working knowledge of Kyber, you already understand ML-KEM.&lt;/p&gt;
&lt;p&gt;Two things follow that people routinely get wrong. First, the renaming is not a redesign: &quot;Kyber&quot; and &quot;ML-KEM&quot; are essentially the same scheme [@crystals-kyber]. Second, the toolkit is not finished -- only three of the five are standardized, and the fourth and fifth are genuinely pre-final.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; FN-DSA (Falcon), destined for FIPS 206, was still in development as of this writing, with a final expected around late 2026 or 2027 [@fips-206-perlner-2025]. HQC was only &lt;em&gt;selected&lt;/em&gt; for standardization on 2025-03-11, with a draft FIPS still pending [@nist-ir-8545]. Do not deploy either in production yet. Every FN-DSA and HQC size in this article is pre-final and may change.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The migration is already underway on the finalized three. But a standard is a promise about an interface, not a proof of security. To defend a design in a review, you need what is under each name: the math, the exact sizes, and the specific way each one can still fail.&lt;/p&gt;
&lt;h2&gt;6. The Five Primitives in Depth&lt;/h2&gt;
&lt;p&gt;One workhorse, one default, one backstop, one compact hopeful, one insurance policy. That is the toolkit in five phrases: ML-KEM is the workhorse KEM, ML-DSA the default signature, SLH-DSA the conservative backstop, FN-DSA the compact hopeful, and HQC the non-lattice insurance policy. Three of the five are lattice schemes, so learn the lattice intuition once and reuse it three times.&lt;/p&gt;

LWE is &quot;add noise to linear algebra.&quot; Given a random matrix $A$ and the product $b = A\mathbf{s} + \mathbf{e}$ where $\mathbf{e}$ is small random noise, recovering the secret $\mathbf{s}$ is believed hard, classically and quantumly. Module-LWE is the same idea over a small polynomial ring, arranged as a rank-$k$ module so the security level is set by $k$ rather than by resizing everything. Raising $k$ adds structure-diluting hedge; lowering it saves bytes. ML-KEM and ML-DSA both live here; only the rank and the noise change.
&lt;p&gt;All byte sizes below are exact for the finalized three and explicitly pre-final for FN-DSA and HQC. Cycle counts come from the pqm4 Cortex-M4 benchmark harness unless labeled otherwise [@pqm4-benchmarks].Never compare a Cortex-M4 cycle count against an AVX2 desktop number directly -- they are different machines. HQC&apos;s own figures are measured on an Intel i7-11850H and Falcon&apos;s on an Intel i5-8259U, so those live on a different scale than the M4 numbers used for cross-scheme comparison.&lt;/p&gt;
&lt;h3&gt;6.1 ML-KEM (FIPS 203): the workhorse&lt;/h3&gt;
&lt;p&gt;ML-KEM is the standardization of CRYSTALS-Kyber, finalized as FIPS 203, and it is the only post-quantum primitive deployed at scale today [@fips-203] [@crystals-kyber]. Its security rests on Module-LWE over the ring $R_q = \mathbb{Z}_q[X]/(X^{256}+1)$ with modulus $q = 3329$; the module rank $k \in {2,3,4}$ selects ML-KEM-512, ML-KEM-768, and ML-KEM-1024.&lt;/p&gt;
&lt;p&gt;The scheme has two layers. The inner layer is an IND-CPA encryption scheme over the ring. The outer layer upgrades it to a CCA-secure KEM using the Fujisaki-Okamoto transform.&lt;/p&gt;

The FO transform turns a weak (chosen-plaintext-secure) encryption scheme into a strong (chosen-ciphertext-secure) KEM by re-encrypting on decapsulation and checking the result. The modern twist -- *implicit rejection* -- is that a failed check returns a deterministic pseudo-random shared secret derived from a secret seed $z$, never an error. Because every ciphertext yields a well-formed key, an attacker who submits tampered ciphertexts learns nothing from the response, closing the decapsulation-failure oracle that broke earlier schemes [@fo-1999] [@hhk-fo-2017].

sequenceDiagram
    participant S as Sender
    participant R as Receiver
    R-&amp;gt;&amp;gt;S: public encapsulation key ek
    Note over S: pick random m, derive shared key K and coins r
    S-&amp;gt;&amp;gt;R: ciphertext c that encapsulates m
    Note over R: decrypt c to m-prime, re-derive K-prime and r-prime
    Note over R: re-encrypt m-prime to c-prime and compare
    alt c-prime equals c
        Note over R: return true shared secret K-prime
    else mismatch
        Note over R: return pseudo-random key from secret z, no error
    end
&lt;p&gt;That implicit-rejection branch is the load-bearing idea. It is worth seeing in code just how little a tampered ciphertext reveals.&lt;/p&gt;
&lt;p&gt;{`
// Illustrative only -- NOT production crypto.
// ML-KEM decapsulation never reports &quot;invalid&quot;. On a re-encryption mismatch it
// returns a pseudo-random key derived from a per-key secret z, so a tampered
// ciphertext produces a well-formed but useless key -- no distinguishable signal.&lt;/p&gt;
&lt;p&gt;function toyHash(s) {
  let h = 2166136261 &amp;gt;&amp;gt;&amp;gt; 0;
  for (const c of String(s)) h = Math.imul(h ^ c.charCodeAt(0), 16777619) &amp;gt;&amp;gt;&amp;gt; 0;
  return (h &amp;gt;&amp;gt;&amp;gt; 0).toString(16).padStart(8, &apos;0&apos;);
}&lt;/p&gt;
&lt;p&gt;const z = &apos;per-key-secret-z&apos;; // implicit-rejection secret, never leaves the device&lt;/p&gt;
&lt;p&gt;// Receiver decrypts c to m&apos;, re-encrypts m&apos;, and compares the result to c.
function decapsulate(c, mDecrypted, cReencrypted) {
  if (cReencrypted === c) {
    return toyHash(&apos;real-shared-secret:&apos; + mDecrypted); // the genuine key
  }
  return toyHash(z + &apos;:&apos; + c);                           // pseudo-random reject key
}&lt;/p&gt;
&lt;p&gt;// Honest ciphertext: re-encryption matches, real key returned.
console.log(&apos;honest   :&apos;, decapsulate(&apos;c123&apos;, &apos;m&apos;, &apos;c123&apos;));
// Tampered ciphertext: mismatch -&amp;gt; still a key, still no error.
console.log(&apos;tampered :&apos;, decapsulate(&apos;c999&apos;, &apos;m-garbled&apos;, &apos;c123&apos;));
// The reject key is deterministic per (z, c) and looks like any other key,
// so the attacker cannot tell rejection from success. The oracle is closed.
`}&lt;/p&gt;
&lt;p&gt;The exact bytes are what a protocol actually carries. For ML-KEM the encapsulation key / decapsulation key / ciphertext / shared secret sizes are 800 / 1632 / 768 / 32 for ML-KEM-512, 1184 / 2400 / 1088 / 32 for ML-KEM-768, and 1568 / 3168 / 1568 / 32 for ML-KEM-1024 [@fips-203]. The decryption-failure rates are $2^{-138.8}$, $2^{-164.8}$, and $2^{-174.8}$ respectively -- negligible by design, which as we saw is a security requirement, not a mere nicety [@fips-203]. On Cortex-M4, ML-KEM-768 costs roughly 642k / 659k / 708k cycles for keygen / encapsulate / decapsulate [@pqm4-benchmarks].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Several Kyber implementations divided a &lt;em&gt;secret&lt;/em&gt; numerator by the public modulus $q = 3329$ inside compression, and on many CPUs division time depends on the inputs -- so the timing leaked secret data. That is KyberSlash [@kyberslash-site] [@kyberslash-eprint-2024]. The FIPS 203 mathematics was never in question; the fix is constant-time (Barrett-style) reduction. It is the toolkit&apos;s headline real-world failure, and it is an implementation bug, exactly as the thesis predicts.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The three small prime moduli to remember: $q = 3329$ for ML-KEM, $q = 8380417$ for ML-DSA, and $q = 12289$ for Falcon. KyberSlash lived in the division by 3329.&lt;/p&gt;
&lt;p&gt;ML-KEM excels because it is small, fast, and easy to implement over small integers mod a fixed prime. It is the default post-quantum KEM in shipping software: the X25519MLKEM768 hybrid is a default key share in OpenSSL 3.5, and it was enabled by default in OpenSSH 9.9 before becoming the default key exchange in OpenSSH 10.0 [@openssl-35-notes] [@openssh-99-notes] [@openssh-pq]. Where it is least comfortable is its assumption: Module-LWE is younger and more structured than code- or hash-based hardness, which is the entire reason the field wants a non-lattice KEM in reserve.&lt;/p&gt;
&lt;h3&gt;6.2 ML-DSA (FIPS 204): the default signature&lt;/h3&gt;
&lt;p&gt;ML-DSA is the standardized CRYSTALS-Dilithium, and it is the signature you should reach for by default [@fips-204] [@crystals-dilithium]. It builds on the same Module-LWE ring world as ML-KEM (here with $q = 8380417$), but it signs by a completely different route than the hash-and-sign that leaked in NTRUSign.&lt;/p&gt;

Turn an interactive identification protocol into a signature by replacing the verifier&apos;s challenge with a hash (Fiat-Shamir), then add a rejection step: whenever the candidate signature would correlate with the secret, discard it and restart with fresh randomness. The signatures that survive are, by construction, distributed independently of the secret key. The cost is that signing runs a variable number of attempts [@lyubashevsky-fswa-2009].
&lt;p&gt;The signer commits to a masking vector $\mathbf{y}$, derives a sparse challenge $c$ by hashing the commitment together with the message, and forms $\mathbf{z} = \mathbf{y} + c\mathbf{s}_1$. If $\mathbf{z}$ strays outside a safe range, releasing it would leak the secret, so the signer aborts and tries again.&lt;/p&gt;

flowchart TD
    A[Sample fresh masking vector y] --&amp;gt; B[Derive sparse challenge c by hashing commitment and message]
    B --&amp;gt; C[Form candidate z as y plus c times secret s1]
    C --&amp;gt; D{&quot;Is z inside the safe range?&quot;}
    D -- No, would leak the secret --&amp;gt; A
    D -- Yes --&amp;gt; E[Publish signature challenge, z, hint]
&lt;p&gt;You can watch the loop behave. The number of attempts varies from signature to signature, and every released value stays inside the safe bound -- the mechanism that makes the transcript reveal nothing about the key.&lt;/p&gt;
&lt;p&gt;{`
// Illustrative only -- NOT production crypto.
// Keep sampling a masking value y until z = y + c*s1 lands in a safe range.
// Candidates that would correlate z with the secret are rejected; only
// key-independent z escape. Signing time therefore varies run to run.&lt;/p&gt;
&lt;p&gt;const GAMMA1 = 100;   // masking range
const BETA   = 20;    // how far c*s1 can push z
const secret = 37;    // s1, unknown to the verifier
const c = 1;          // toy sparse challenge
const rand = (n) =&amp;gt; Math.floor(Math.random() * n);&lt;/p&gt;
&lt;p&gt;function signOnce() {
  let attempts = 0;
  while (true) {
    attempts++;
    const y = rand(2 * GAMMA1) - GAMMA1;       // uniform masking
    const z = y + c * secret;
    if (Math.abs(z) &amp;lt; GAMMA1 - BETA) return { z, attempts }; // safe -&amp;gt; release
    // otherwise abort and retry with fresh y
  }
}&lt;/p&gt;
&lt;p&gt;let total = 0, n = 20000, maxAbsZ = 0;
for (let i = 0; i &amp;lt; n; i++) {
  const r = signOnce();
  total += r.attempts;
  maxAbsZ = Math.max(maxAbsZ, Math.abs(r.z));
}
console.log(&apos;avg attempts / signature:&apos;, (total / n).toFixed(2));
console.log(&apos;max |z| ever released   :&apos;, maxAbsZ, &apos;bound is&apos;, GAMMA1 - BETA);
console.log(&apos;variable attempt count is why ML-DSA signing time is not constant&apos;);
`}&lt;/p&gt;
&lt;p&gt;The Dilithium team chose this uniform-integer, rejection-based route deliberately, rather than Falcon&apos;s Gaussian sampler, and they were blunt about why.&lt;/p&gt;

&quot;Gaussian sampling is hard to implement securely and efficiently.&quot; -- the CRYSTALS-Dilithium team, on why ML-DSA uses uniform integers and no floating point [@crystals-dilithium].
&lt;p&gt;The private key / public key / signature sizes are 2560 / 1312 / 2420 for ML-DSA-44, 4032 / 1952 / 3309 for ML-DSA-65, and 4896 / 2592 / 4627 for ML-DSA-87, targeting NIST categories 2, 3, and 5 [@fips-204]. Verification is fast and constant-time; signing is fast but variable-time because of the abort loop, which is the single most important operational fact about the scheme. On Cortex-M4, ML-DSA-65 signing averages near 6.19M cycles but ranges from about 2.92M to 26.0M across a thousand runs [@pqm4-benchmarks].&lt;/p&gt;
&lt;p&gt;FIPS 204 supports both hedged (randomized) and deterministic signing; the hedged mode is the default and is more resilient to fault and bad-randomness mishaps. It also adds a context string of up to 255 bytes so applications can domain-separate their signatures and prevent cross-protocol reuse.&lt;/p&gt;
&lt;p&gt;ML-DSA excels as the general-purpose default: no floating point, easy constant-time code, moderate sizes, fast verification. Its weak spot is the signature-size wall this series flagged for interfaces in &lt;a href=&quot;https://paragmali.com/blog/the-math-held-the-interface-leaked-a-field-guide-to-digital-/&quot; rel=&quot;noopener&quot;&gt;Part 17 on digital signatures&lt;/a&gt; -- a 3309-byte signature is roughly fifty times an Ed25519 signature, and that multiplies through certificate chains.&lt;/p&gt;
&lt;h3&gt;6.3 SLH-DSA (FIPS 205): the conservative backstop&lt;/h3&gt;
&lt;p&gt;SLH-DSA is the standardized SPHINCS+, and it makes the most conservative bet in the toolkit: its security rests on nothing but the properties of its hash function, the same primitives this series covered in &lt;a href=&quot;https://paragmali.com/blog/the-fingerprint-two-files-shared-a-field-guide-to-cryptograp/&quot; rel=&quot;noopener&quot;&gt;Part 10 on cryptographic hashes&lt;/a&gt; [@fips-205] [@sphincs-plus-spec]. If every lattice and code assumption fell tomorrow, a signature that depends only on a hash would still stand.&lt;/p&gt;

SLH-DSA composes three hash-based gadgets. WOTS+ is a one-time signature that signs by revealing points along hash chains. FORS (&quot;Forest Of Random Subsets&quot;) is a *few-time* signature that signs the message digest and tolerates rare index collisions. A hypertree stacks many layers of Merkle trees, each layer&apos;s WOTS+ keys authenticating the roots below, up to one public root. Picking the FORS instance pseudo-randomly from the message removes the state that made XMSS dangerous [@sphincs-plus-framework-2019].

flowchart TD
    M[Message digest] --&amp;gt; R[Randomizer picks a FORS instance pseudo-randomly]
    R --&amp;gt; F[FORS few-time signature over the digest]
    F --&amp;gt; W[WOTS+ one-time key authenticates the FORS root]
    W --&amp;gt; H[Hypertree of Merkle layers, each signs the layer below]
    H --&amp;gt; PK[Single long-lived public root]
&lt;p&gt;The trade is stark. Public keys are tiny (32 to 64 bytes), but signatures are enormous and signing is slow. FIPS 205 defines twelve parameter sets -- three security levels, each with a &quot;small&quot; (&lt;code&gt;s&lt;/code&gt;) and &quot;fast&quot; (&lt;code&gt;f&lt;/code&gt;) variant, over SHA-2 and SHAKE. The public key / signature sizes run 32 / 7856 for 128s, 32 / 17088 for 128f, 48 / 16224 for 192s, 48 / 35664 for 192f, 64 / 29792 for 256s, and 64 / 49856 for 256f [@fips-205]. Signing hashes whole subtrees and costs hundreds of millions to billions of Cortex-M4 cycles, orders of magnitude slower than lattice signing [@pqm4-benchmarks]. The &lt;code&gt;s&lt;/code&gt;/&lt;code&gt;f&lt;/code&gt; knob only trades one pain for the other: smaller signatures mean slower signing.&lt;/p&gt;
&lt;p&gt;That profile makes SLH-DSA the right tool for low-volume, high-assurance signing -- firmware, boot chains, and software-update roots -- where you sign rarely, verify occasionally, and value a rock-bottom assumption over compactness.&lt;/p&gt;

If you can guarantee perfect state, the stateful hash signatures XMSS and LMS (NIST SP 800-208) are markedly smaller than SLH-DSA [@nist-sp-800-208]. The catch is the catch from Section 3: reuse a one-time leaf index and you enable forgery. They are the right call only in a tightly controlled setting -- a hardware security module or a firmware signer that can enforce monotonic, rollback-proof state. For everyone else, SLH-DSA trades bytes for the removal of that footgun, which is usually the better deal.
&lt;h3&gt;6.4 FN-DSA / Falcon: the compact hopeful (pre-final)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Falcon is destined to become FIPS 206, but that document was still in development as of this writing, with a final expected around late 2026 or 2027 [@fips-206-perlner-2025] [@digicert-fndsa]. Every name and size below is pre-final and comes from the Falcon specification, not from a FIPS [@falcon-spec]. Do not ship FN-DSA in production yet.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Falcon instantiates the GPV hash-and-sign framework over NTRU lattices ($q = 12289$, dimension $n = 512$ or $1024$), and it produces the smallest signatures and keys of any standardized-track scheme [@falcon-spec] [@gpv-2007].&lt;/p&gt;

The safe way to do lattice hash-and-sign. A secret trapdoor lets the signer sample a short lattice vector near a hashed target from a discrete Gaussian whose distribution is provably independent of the secret basis. That independence is exactly what NTRUSign lacked -- it closes the parallelepiped leak by construction, rather than hoping the outputs happen not to correlate with the key.

flowchart LR
    M[Message] --&amp;gt; HP[Hash message to a point c in the ring]
    HP --&amp;gt; TS[Use NTRU trapdoor basis to target c]
    TS --&amp;gt; GS[Fast-Fourier Gaussian sampling, the delicate floating-point step]
    GS --&amp;gt; SV[Short vector s1, s2 near the lattice]
    SV --&amp;gt; SIG[Signature is a salt plus compressed s2]
&lt;p&gt;The payoff is compactness. Falcon-512 has an 897-byte public key and a 666-byte signature (roughly RSA-2048&apos;s classical security level, as this series discussed in Part 14, at a fraction of the byte size); Falcon-1024 is 1793 / 1280 [@falcon-spec]. On a desktop i5-8259U the reference code signs about 5948 times per second and verifies about 27933 times per second for Falcon-512 [@falcon-spec]. A Falcon-512 signature is under a third the size of ML-DSA-44&apos;s.&lt;/p&gt;
&lt;p&gt;So why is it the last of the five to standardize? Because the Gaussian sampler runs on floating-point arithmetic, and making floating point constant-time across compilers and CPUs is genuinely hard. Timing or precision leakage of the sampler&apos;s Gram-Schmidt norms can recover the secret key [@fouque-gsnorm-2019]. Mitigations exist -- Pornin&apos;s constant-time integer implementation and isochronous Gaussian sampling among them -- but they are intricate and platform-sensitive [@pornin-ctfalcon-2019] [@howe-isochronous-2019].&lt;/p&gt;
&lt;p&gt;Want concrete evidence that FN-DSA is pre-final? When researchers fetched the expected FIPS 206 Initial Public Draft URL during the source verification for this article, it returned HTTP 404 -- the draft was not yet published. The compact math is done; the standardization and safe-implementation work is not.&lt;/p&gt;
&lt;p&gt;Falcon is the right tool when signature and key bandwidth is the binding constraint &lt;em&gt;and&lt;/em&gt; you can guarantee a vetted constant-time implementation -- and even then, not before FIPS 206 lands. Until it does, prefer ML-DSA.&lt;/p&gt;
&lt;h3&gt;6.5 HQC: the non-lattice insurance policy (pre-final)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; NIST selected HQC on 2025-03-11 as a code-based KEM to stand alongside ML-KEM, with a draft FIPS expected in 2026 and a final around 2027 [@nist-ir-8545]. The parameters below come from the HQC specification and are pre-final [@hqc-spec]. Do not deploy it in production yet.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;HQC (&quot;Hamming Quasi-Cyclic&quot;) is the toolkit&apos;s deliberate non-lattice hedge. Its security rests on the hardness of decoding random quasi-cyclic codes -- syndrome decoding, unrelated to lattices -- so a future lattice break would leave it untouched [@hqc-spec]. It solves the problem that sank BIKE by separating the secret from the decoder: HQC encrypts by adding a low-weight error and decodes with a &lt;em&gt;public&lt;/em&gt;, fixed code (a concatenation of Reed-Muller and Reed-Solomon codes) whose decoding-failure rate can be bounded analytically and does not depend on the secret. That bounded, secret-independent DFR is exactly why NIST preferred it over BIKE [@nist-ir-8545] [@gjs-mdpc-2016].&lt;/p&gt;
&lt;p&gt;The cost is bandwidth. The encapsulation key / decapsulation key / ciphertext / shared secret sizes are 2241 / 2321 / 4433 / 32 for HQC-1, 4514 / 4602 / 8978 / 32 for HQC-3, and 7237 / 7333 / 14421 / 32 for HQC-5 [@hqc-spec]. The ciphertext is roughly four to nine times ML-KEM&apos;s. HQC is the reserve KEM, not the first choice: you carry the extra kilobytes precisely because its assumption is unrelated to everything else in the box.&lt;/p&gt;
&lt;h3&gt;6.6 Tier C: the signposts&lt;/h3&gt;
&lt;p&gt;Four more schemes sit just outside the toolkit and are worth knowing by name.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Classic McEliece&lt;/strong&gt; is the most conservative code-based KEM, unbroken since 1978, but with public keys from roughly 261 KB to over a megabyte [@classic-mceliece]. It was not selected for the FIPS set and is advancing on an ISO track; choose it only where a huge, static, long-lived key is acceptable and maximal conservatism is the goal.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;BIKE&lt;/strong&gt; is the quasi-cyclic KEM that HQC beat out; its secret-dependent decoding-failure rate was judged less mature than HQC&apos;s bounded public decoder, so NIST did not select it [@bike-suite] [@nist-ir-8545].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;XMSS and LMS&lt;/strong&gt; are the standardized stateful hash signatures -- compact, conservative, and safe only where perfect state is guaranteed [@nist-sp-800-208].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CSIDH&lt;/strong&gt; is the one post-quantum candidate for a non-interactive Diffie-Hellman-style shared key, but its quantum security is contested -- subexponential quantum attacks push it toward much larger parameters [@peikert-csieves-2019] -- and its isogeny cousin SIKE was broken in 2022 [@castryck-decru-sidh-2022]. Treat it as research, not deployment.&lt;/p&gt;
&lt;p&gt;Now the exact bytes, all in one place. The table below is the empirical anchor for every trade discussed next -- the literal number of bytes a protocol must carry for each choice.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Primitive&lt;/th&gt;
&lt;th&gt;Param set&lt;/th&gt;
&lt;th&gt;Family&lt;/th&gt;
&lt;th&gt;Public/enc key (B)&lt;/th&gt;
&lt;th&gt;Ciphertext or signature (B)&lt;/th&gt;
&lt;th&gt;NIST cat&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;ML-KEM&lt;/td&gt;
&lt;td&gt;512&lt;/td&gt;
&lt;td&gt;lattice KEM&lt;/td&gt;
&lt;td&gt;800&lt;/td&gt;
&lt;td&gt;768&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Final [@fips-203]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ML-KEM&lt;/td&gt;
&lt;td&gt;768&lt;/td&gt;
&lt;td&gt;lattice KEM&lt;/td&gt;
&lt;td&gt;1184&lt;/td&gt;
&lt;td&gt;1088&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Final [@fips-203]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ML-KEM&lt;/td&gt;
&lt;td&gt;1024&lt;/td&gt;
&lt;td&gt;lattice KEM&lt;/td&gt;
&lt;td&gt;1568&lt;/td&gt;
&lt;td&gt;1568&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Final [@fips-203]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HQC&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;code KEM&lt;/td&gt;
&lt;td&gt;2241&lt;/td&gt;
&lt;td&gt;4433&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Pre-final [@hqc-spec]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HQC&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;code KEM&lt;/td&gt;
&lt;td&gt;4514&lt;/td&gt;
&lt;td&gt;8978&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Pre-final [@hqc-spec]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HQC&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;code KEM&lt;/td&gt;
&lt;td&gt;7237&lt;/td&gt;
&lt;td&gt;14421&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Pre-final [@hqc-spec]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ML-DSA&lt;/td&gt;
&lt;td&gt;44&lt;/td&gt;
&lt;td&gt;lattice sig&lt;/td&gt;
&lt;td&gt;1312&lt;/td&gt;
&lt;td&gt;2420&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Final [@fips-204]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ML-DSA&lt;/td&gt;
&lt;td&gt;65&lt;/td&gt;
&lt;td&gt;lattice sig&lt;/td&gt;
&lt;td&gt;1952&lt;/td&gt;
&lt;td&gt;3309&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Final [@fips-204]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ML-DSA&lt;/td&gt;
&lt;td&gt;87&lt;/td&gt;
&lt;td&gt;lattice sig&lt;/td&gt;
&lt;td&gt;2592&lt;/td&gt;
&lt;td&gt;4627&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Final [@fips-204]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FN-DSA/Falcon&lt;/td&gt;
&lt;td&gt;512&lt;/td&gt;
&lt;td&gt;lattice sig&lt;/td&gt;
&lt;td&gt;897&lt;/td&gt;
&lt;td&gt;666&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Pre-final [@falcon-spec]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FN-DSA/Falcon&lt;/td&gt;
&lt;td&gt;1024&lt;/td&gt;
&lt;td&gt;lattice sig&lt;/td&gt;
&lt;td&gt;1793&lt;/td&gt;
&lt;td&gt;1280&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Pre-final [@falcon-spec]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SLH-DSA&lt;/td&gt;
&lt;td&gt;128s&lt;/td&gt;
&lt;td&gt;hash sig&lt;/td&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;td&gt;7856&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Final [@fips-205]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SLH-DSA&lt;/td&gt;
&lt;td&gt;128f&lt;/td&gt;
&lt;td&gt;hash sig&lt;/td&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;td&gt;17088&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Final [@fips-205]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SLH-DSA&lt;/td&gt;
&lt;td&gt;192s&lt;/td&gt;
&lt;td&gt;hash sig&lt;/td&gt;
&lt;td&gt;48&lt;/td&gt;
&lt;td&gt;16224&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Final [@fips-205]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SLH-DSA&lt;/td&gt;
&lt;td&gt;192f&lt;/td&gt;
&lt;td&gt;hash sig&lt;/td&gt;
&lt;td&gt;48&lt;/td&gt;
&lt;td&gt;35664&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Final [@fips-205]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SLH-DSA&lt;/td&gt;
&lt;td&gt;256s&lt;/td&gt;
&lt;td&gt;hash sig&lt;/td&gt;
&lt;td&gt;64&lt;/td&gt;
&lt;td&gt;29792&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Final [@fips-205]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SLH-DSA&lt;/td&gt;
&lt;td&gt;256f&lt;/td&gt;
&lt;td&gt;hash sig&lt;/td&gt;
&lt;td&gt;64&lt;/td&gt;
&lt;td&gt;49856&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Final [@fips-205]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Two footnotes complete the picture. For the KEMs, the decapsulation (secret) keys are larger than the encapsulation keys -- 1632 / 2400 / 3168 bytes for ML-KEM and 2321 / 4602 / 7333 bytes for HQC -- and both produce a 32-byte shared secret [@fips-203] [@hqc-spec]. For ML-DSA, the private keys are 2560 / 4032 / 4896 bytes [@fips-204]. Now the uncomfortable question: given all five, which do you actually deploy, and what do you give up to get it?&lt;/p&gt;
&lt;h2&gt;7. Choosing Inside the Toolkit&lt;/h2&gt;
&lt;p&gt;There is no universal winner, and looking for one is the wrong frame. In practice you make two decisions -- which KEM, and which signature -- plus one deployment choice about hybrids. Everything else follows from the bytes in the master table and the assumption you are willing to trust.&lt;/p&gt;
&lt;p&gt;The KEM decision is really ML-KEM versus HQC, because the other code-based options are signposts rather than shipping choices.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;ML-KEM-768 (final)&lt;/th&gt;
&lt;th&gt;HQC-3 (pre-final)&lt;/th&gt;
&lt;th&gt;Classic McEliece (signpost)&lt;/th&gt;
&lt;th&gt;BIKE (signpost)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Assumption&lt;/td&gt;
&lt;td&gt;Module-LWE (lattice)&lt;/td&gt;
&lt;td&gt;quasi-cyclic syndrome decoding (code)&lt;/td&gt;
&lt;td&gt;Goppa-code decoding&lt;/td&gt;
&lt;td&gt;QC-MDPC decoding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enc. key&lt;/td&gt;
&lt;td&gt;1184 B&lt;/td&gt;
&lt;td&gt;4514 B&lt;/td&gt;
&lt;td&gt;261 KB to ~1.36 MB&lt;/td&gt;
&lt;td&gt;few KB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ciphertext&lt;/td&gt;
&lt;td&gt;1088 B&lt;/td&gt;
&lt;td&gt;8978 B&lt;/td&gt;
&lt;td&gt;~100 to 200 B&lt;/td&gt;
&lt;td&gt;few KB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best-known attack&lt;/td&gt;
&lt;td&gt;lattice sieving $\approx 2^{0.292\beta}$&lt;/td&gt;
&lt;td&gt;information-set decoding (exp.)&lt;/td&gt;
&lt;td&gt;information-set decoding (exp.)&lt;/td&gt;
&lt;td&gt;ISD, plus a reaction attack given a failure oracle&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DFR&lt;/td&gt;
&lt;td&gt;$2^{-164.8}$&lt;/td&gt;
&lt;td&gt;bounded, secret-independent&lt;/td&gt;
&lt;td&gt;negligible&lt;/td&gt;
&lt;td&gt;secret-dependent (the problem)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maturity&lt;/td&gt;
&lt;td&gt;final and deployed&lt;/td&gt;
&lt;td&gt;selected 2025, pre-final&lt;/td&gt;
&lt;td&gt;ISO track, not in FIPS&lt;/td&gt;
&lt;td&gt;not selected&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best suited for&lt;/td&gt;
&lt;td&gt;default KEM everywhere&lt;/td&gt;
&lt;td&gt;non-lattice diversity backup&lt;/td&gt;
&lt;td&gt;huge static keys, max conservatism&lt;/td&gt;
&lt;td&gt;superseded by HQC&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;ML-KEM wins on size and ubiquity. HQC&apos;s entire reason to exist is that its assumption is unrelated to ML-KEM&apos;s, so a lattice break would not take both down -- and you pay roughly eight times the ciphertext for that insurance [@fips-203] [@hqc-spec] [@nist-ir-8545].&lt;/p&gt;
&lt;p&gt;The signature decision spans three finalists on very different paradigms.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;ML-DSA-65 (final)&lt;/th&gt;
&lt;th&gt;FN-DSA / Falcon-512 (pre-final)&lt;/th&gt;
&lt;th&gt;SLH-DSA-128s (final)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Construction&lt;/td&gt;
&lt;td&gt;Fiat-Shamir with aborts&lt;/td&gt;
&lt;td&gt;GPV hash-and-sign over NTRU&lt;/td&gt;
&lt;td&gt;stateless hash-based&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Assumption&lt;/td&gt;
&lt;td&gt;Module-LWE and Module-SIS&lt;/td&gt;
&lt;td&gt;NTRU and SIS (lattice)&lt;/td&gt;
&lt;td&gt;hash function only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Public key&lt;/td&gt;
&lt;td&gt;1952 B&lt;/td&gt;
&lt;td&gt;897 B&lt;/td&gt;
&lt;td&gt;32 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Signature&lt;/td&gt;
&lt;td&gt;3309 B&lt;/td&gt;
&lt;td&gt;666 B&lt;/td&gt;
&lt;td&gt;7856 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Signing&lt;/td&gt;
&lt;td&gt;fast, variable-time&lt;/td&gt;
&lt;td&gt;fast, floating-point sampler&lt;/td&gt;
&lt;td&gt;very slow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Implementation risk&lt;/td&gt;
&lt;td&gt;low (no floating point)&lt;/td&gt;
&lt;td&gt;high (constant-time floating point is hard)&lt;/td&gt;
&lt;td&gt;low (hashing only)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maturity&lt;/td&gt;
&lt;td&gt;final, the default&lt;/td&gt;
&lt;td&gt;FIPS 206 in development&lt;/td&gt;
&lt;td&gt;final&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best suited for&lt;/td&gt;
&lt;td&gt;general-purpose default&lt;/td&gt;
&lt;td&gt;size-critical, constant-time guaranteed&lt;/td&gt;
&lt;td&gt;firmware and roots, low volume&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;There is no free lunch in that table [@fips-204] [@falcon-spec] [@fips-205]. Falcon is smallest but hardest to implement safely and not yet final; SLH-DSA is the safest to trust but by far the largest and slowest; ML-DSA is the sensible middle and the recommended default.&lt;/p&gt;
&lt;p&gt;To feel the gap, anchor on the classical world this series has used throughout. An Ed25519 signature is 64 bytes; an X25519 public key is 32. Nothing in the post-quantum toolkit comes close, as Part 15 on elliptic curves makes vivid.&lt;/p&gt;
&lt;p&gt;The smallest post-quantum signature, Falcon-512 at 666 bytes, is about ten times larger and carries a floating-point hazard; the most conservative, SLH-DSA-128s at 7856 bytes, is about one hundred and twenty times larger; and the default KEM ciphertext, ML-KEM-768 at 1088 bytes, is about thirty-four times an X25519 share [@falcon-spec] [@fips-205] [@fips-203]. Every column of these tables buys one property -- small size, easy constant-time code, a conservative assumption, or non-lattice diversity -- by giving up another.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; No post-quantum primitive wins on every axis. The five are not a menu awaiting a single winner; they are deliberate coverage of a trade surface, chosen so that whatever your binding constraint -- bytes, speed, assumption conservatism, or implementation safety -- one of them is the defensible answer.&lt;/p&gt;
&lt;/blockquote&gt;

The toolkit is five points on a trade surface, not an arbitrary menu.
&lt;p&gt;One more choice cuts across both decisions: hybrid versus pure. The shipping default, X25519MLKEM768, runs a classical X25519 exchange and a post-quantum ML-KEM-768 encapsulation together and combines both shared secrets, so the session stays secure as long as &lt;em&gt;either&lt;/em&gt; half holds [@openssl-35-notes]. During a migration that is the conservative posture: it defends against a future quantum computer and against an implementation bug in the young post-quantum half at once -- a belt-and-suspenders design, the security-definition thinking of Part 1 made concrete. These trades feel like engineering. Underneath them sits something humbler: we cannot prove any of it is hard.&lt;/p&gt;
&lt;h2&gt;8. What We Cannot Prove&lt;/h2&gt;
&lt;p&gt;Here is the headline most readers do not expect: none of the five rests on an unconditional hardness proof. &quot;Standardized by NIST&quot; does not mean &quot;proven secure.&quot; It means &quot;no efficient attack is known, backed by decades of failed attempts and, for lattices, an unusually strong reduction.&quot; That is a different and more honest claim.&lt;/p&gt;
&lt;p&gt;The lattice story is the one people most often overstate. Ajtai and then Regev proved worst-case-to-average-case reductions: breaking random instances is as hard as breaking the worst case [@ajtai-1996] [@regev-lwe-2005]. That is remarkable, and it is genuinely reassuring.&lt;/p&gt;
&lt;p&gt;But three caveats matter. First, those reductions are cleanest for &lt;em&gt;plain&lt;/em&gt; LWE, while the standards use &lt;em&gt;structured&lt;/em&gt; Module-LWE and NTRU, whose reductions are weaker or looser. Second, the actual parameters are not chosen from the reduction at all; they are sized against the best-known attack, lattice sieving, whose cost is heuristically $\approx 2^{0.292\beta}$ classically and roughly $2^{0.265\beta}$ quantumly under debated memory assumptions [@bdgl-sieving-2015]. Third, at the approximation factors these schemes use, the underlying lattice problems sit in $\mathsf{NP} \cap \mathsf{coNP}$, so they are not NP-hard under standard assumptions [@aharonov-regev-2005]. A genuine super-polynomial lower bound for any of them would prove $\mathsf{P} \neq \mathsf{NP}$ -- which no one can currently do.&lt;/p&gt;
&lt;p&gt;Codes and hashes are no different in kind. General syndrome decoding is NP-hard, but HQC&apos;s security depends on the &lt;em&gt;average-case&lt;/em&gt; hardness of decoding random quasi-cyclic codes, which is an assumption, not a theorem [@hqc-spec]. SLH-DSA reduces tightly to standard properties of its hash function, with no algebraic structure to exploit -- the most conservative bet in the box, but still a bet [@fips-205].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Realize what this means taken together: the security of the entire toolkit is a &lt;em&gt;monitored cryptanalytic bet&lt;/em&gt;, not a proof. The strong lattice reductions do not cover the structured schemes actually deployed; the parameters are justified empirically; and a real hardness proof for any of them would settle the biggest open question in computer science. This is precisely why the field standardized a diversified portfolio and keeps a non-lattice spare. The humility is not a weakness in the design -- it &lt;em&gt;is&lt;/em&gt; the design.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Two results in this area are not assumptions but hard walls, and they pull in opposite directions. The first is Shor&apos;s algorithm itself: no choice of RSA, Diffie-Hellman, or elliptic-curve parameters can ever be post-quantum, because the attack is a capability of the adversary, not a bound you can tune [@shor-1994]. The second constrains the replacements.&lt;/p&gt;

A NIKE lets two parties who know only each other&apos;s long-term public keys compute a shared secret with no interaction -- the static-static magic of Diffie-Hellman, where two published keys silently agree. A KEM does not provide this: encapsulation produces a fresh ciphertext that must be sent, so at least one message is required. There is no efficient, well-trusted post-quantum NIKE (the only candidate, CSIDH, has contested quantum security under subexponential quantum attack [@peikert-csieves-2019]).
&lt;p&gt;That second wall -- KEM is not NIKE -- is why post-quantum migration is not a mechanical find-and-replace. Any protocol that relied on Diffie-Hellman&apos;s non-interactive static-static agreement has to be redesigned around an interactive KEM handshake, as Part 18 on Diffie-Hellman foreshadowed. It is a design-level impossibility, not a tuning problem.&lt;/p&gt;
&lt;p&gt;One more subtlety links two sections: for the FO-transformed KEMs, the decryption-failure rate is a &lt;em&gt;security&lt;/em&gt; bound, not merely a correctness figure. A noticeable, secret-correlated failure rate is an oracle -- the exact mechanism behind the BIKE reaction attack -- which is why ML-KEM specifies rates like $2^{-164.8}$ and HQC insists on an analytically bounded one [@gjs-mdpc-2016].&lt;/p&gt;
&lt;p&gt;Put it all together and the shape of the toolkit becomes inevitable. The theoretically perfect primitive would have elliptic-curve-sized keys and signatures, fast constant-time software with no floating point, a conservative and well-understood assumption, and strong chosen-ciphertext or unforgeability guarantees. No known construction reaches all four corners at once: lattices are small and fast on a young, structured assumption; hashes are conservative but huge; codes offer diversity but cost kilobytes. The five primitives are the field&apos;s best simultaneous coverage of that surface. If we cannot prove hardness, the honest posture is to keep asking what we still cannot do -- and to keep a spare.&lt;/p&gt;
&lt;h2&gt;9. The Frontier the Toolkit Does Not Close&lt;/h2&gt;
&lt;p&gt;A field guide should be honest about what remains open. Seven problems sit on the near horizon, and together they explain why the toolkit is best understood as a monitored bet with an insurance policy attached.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The signature-size wall.&lt;/strong&gt; No post-quantum signature reaches the 64-byte classical world while keeping a conservative assumption &lt;em&gt;and&lt;/em&gt; an easy constant-time implementation. Falcon-512 is 666 bytes but floating-point; ML-DSA-44 is 2420 bytes; SLH-DSA-128s is 7856 bytes and up. Certificate chains, TLS handshakes, DNSSEC responses, and firmware manifests all multiply signature size by depth, so a few-kilobyte signature reshapes protocols. NIST&apos;s ongoing &quot;Additional Digital Signature Schemes&quot; on-ramp is the active response, hunting for small-signature options on different assumptions [@nist-pqc-project].This on-ramp is deliberately looking beyond lattices -- for schemes whose assumptions differ from ML-DSA and Falcon -- so that a future small-signature standard also widens the toolkit&apos;s assumption diversity rather than deepening its lattice exposure.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Constant-time Falcon without floating point.&lt;/strong&gt; Falcon&apos;s fast-Fourier Gaussian sampler is defined over floating-point arithmetic, and a portable, high-precision, provably constant-time sampler is hard to guarantee across compilers and CPUs. This is the chief obstacle to shipping FN-DSA safely and the reason it standardizes last [@pornin-ctfalcon-2019] [@howe-isochronous-2019]. The motivating attack -- key recovery from Gram-Schmidt norm leakage -- is concrete, not hypothetical [@fouque-gsnorm-2019].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Shrinking code-based ciphertexts.&lt;/strong&gt; HQC buys assumption diversity at 4.4 to 14.4 KB ciphertexts, and the smaller-key alternative (BIKE) was set aside precisely because its secret-dependent failure rate is a reaction-attack surface. An open goal is a code-based KEM with McEliece-like conservatism, ML-KEM-like size, and a provable secret-independent DFR [@nist-ir-8545].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Formally verified, side-channel-hardened implementations of all five.&lt;/strong&gt; KyberSlash showed that even widely used reference code can leak through timing [@kyberslash-site]. Machine-checked constant-time implementations of ML-KEM exist, but ML-DSA&apos;s variable-time abort loop and FN-DSA&apos;s floating point are materially harder to verify end to end. The standards are only as safe as the code that runs them.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Is the algebraic structure free?&lt;/strong&gt; Ring-LWE, Module-LWE, and NTRU all add ring structure for compact keys and fast transforms. No attack exploits that structure at the standardized parameters, but there is no proof it is as hard as unstructured LWE -- and all three lattice primitives share the exposure, so a structural breakthrough could touch most of the toolkit at once. The Module-LWE design dilutes structure as a hedge, but the conjecture that it is essentially as hard as plain LWE remains believed and unproven.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Migrating static-static protocols.&lt;/strong&gt; Because a KEM is not a NIKE, any protocol that assumed non-interactive Diffie-Hellman agreement must be redesigned, not reconfigured. Interactive hybrid handshakes cover key establishment well; a practical, trusted post-quantum NIKE does not exist.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The real quantum cost of sieving.&lt;/strong&gt; The quantum sieving exponent near $2^{0.265\beta}$ depends on memory and qRAM models whose real-world cost is uncertain, and NIST&apos;s security categories inherit that uncertainty [@bdgl-sieving-2015]. Conservative defaults -- recommending Category-3 ML-KEM-768 rather than the smaller set -- absorb the doubt, but a settled cost model would tighten every lattice parameter.&lt;/p&gt;
&lt;p&gt;None of that blocks you from shipping the right thing today. Here is exactly what to ship.&lt;/p&gt;
&lt;h2&gt;10. Exact Decision Rules&lt;/h2&gt;
&lt;p&gt;Enough theory. Here are defensible defaults you can carry into a design review, phrased as &quot;use X with these parameters in case Y.&quot;&lt;/p&gt;

flowchart TD
    Q1{&quot;Signing or key exchange?&quot;}
    Q1 -- Key exchange --&amp;gt; K1{&quot;Bandwidth very tight and Category 1 acceptable?&quot;}
    K1 -- Yes --&amp;gt; KEM512[ML-KEM-512 in a hybrid]
    K1 -- No --&amp;gt; K2{&quot;Long-term or Category 5 secret?&quot;}
    K2 -- Yes --&amp;gt; KEM1024[ML-KEM-1024 in a hybrid]
    K2 -- No --&amp;gt; KEM768[ML-KEM-768 hybrid, the default]
    Q1 -- Signing --&amp;gt; S1{&quot;Low-volume firmware or root of trust?&quot;}
    S1 -- Yes --&amp;gt; SLH[SLH-DSA-128s or 128f]
    S1 -- No --&amp;gt; S2{&quot;Is signature size the hard limit?&quot;}
    S2 -- No --&amp;gt; MLDSA[ML-DSA-65, the default]
    S2 -- Yes --&amp;gt; FN[Consider FN-DSA, vetted constant-time only, after FIPS 206]
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Key establishment (TLS, SSH, VPN):&lt;/strong&gt; use &lt;strong&gt;ML-KEM-768 in a hybrid&lt;/strong&gt; (X25519MLKEM768). It is the shipping default and the conservative middle category [@openssl-35-notes] [@openssh-99-notes]. Drop to ML-KEM-512 only under tight bandwidth with Category-1 acceptance; step up to ML-KEM-1024 for Category-5 or long-lived secrets.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;General-purpose signatures:&lt;/strong&gt; use &lt;strong&gt;ML-DSA-65&lt;/strong&gt; (Category 3). No floating point, easy constant-time, moderate sizes [@fips-204].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Firmware, boot, root-of-trust (low volume, maximum conservatism):&lt;/strong&gt; use &lt;strong&gt;SLH-DSA-128s&lt;/strong&gt; for smaller signatures or &lt;strong&gt;128f&lt;/strong&gt; for faster signing. You sign rarely, so absorb the large signature in exchange for a hash-only assumption [@fips-205].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;When signature size is the binding constraint:&lt;/strong&gt; consider &lt;strong&gt;FN-DSA / Falcon&lt;/strong&gt; -- but only with a vetted constant-time implementation, and &lt;strong&gt;not in production until FIPS 206 is final&lt;/strong&gt; [@fips-206-perlner-2025]. Until then, prefer ML-DSA.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;For KEM assumption diversity:&lt;/strong&gt; plan for &lt;strong&gt;HQC&lt;/strong&gt; as a standardized non-lattice backup &lt;strong&gt;once its FIPS lands&lt;/strong&gt;, not today [@nist-ir-8545]. If you need maximal conservatism now and can absorb a huge static key, Classic McEliece is the code-based option outside the FIPS set [@classic-mceliece].&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The single most useful thing you can build is an intuition for how many bytes each choice adds. Run the numbers.&lt;/p&gt;
&lt;p&gt;{`
// Illustrative only. Estimate the extra bytes post-quantum adds versus classical
// X25519 / Ed25519, for a KEM share and for a 3-certificate chain.&lt;/p&gt;
&lt;p&gt;const sizes = {
  &apos;Ed25519&apos;:      { sig: 64,   pk: 32 },
  &apos;ML-DSA-65&apos;:    { sig: 3309, pk: 1952 },
  &apos;Falcon-512&apos;:   { sig: 666,  pk: 897 },
  &apos;SLH-DSA-128s&apos;: { sig: 7856, pk: 32 },
};&lt;/p&gt;
&lt;p&gt;// A chain of 3 certificates, each carrying one signature + one public key.
function chainBytes(name) {
  const s = sizes[name];
  return (s.sig + s.pk) * 3;
}&lt;/p&gt;
&lt;p&gt;for (const n of [&apos;Ed25519&apos;,&apos;ML-DSA-65&apos;,&apos;Falcon-512&apos;,&apos;SLH-DSA-128s&apos;]) {
  console.log(n.padEnd(14), String(chainBytes(n)).padStart(6), &apos;bytes over a 3-cert chain&apos;);
}&lt;/p&gt;
&lt;p&gt;console.log(&apos;---&apos;);
const x25519Share = 32 + 32;            // classical key share, round trip
const mlkemAdds   = 1184 + 1088;        // ML-KEM-768 key + ciphertext
console.log(&apos;KEM share, classical X25519 :&apos;, x25519Share, &apos;bytes&apos;);
console.log(&apos;KEM share, ML-KEM-768 hybrid:&apos;, x25519Share + mlkemAdds, &apos;bytes&apos;);
`}&lt;/p&gt;
&lt;p&gt;Rules pick the primitive; discipline keeps it safe. A short pitfall list, drawn straight from the failure catalog:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Do not divide a secret by the modulus in variable time.&lt;/strong&gt; That was KyberSlash; use constant-time (Barrett) reduction and a library whose constant-time behavior has been tested [@kyberslash-site].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prefer hedged (randomized) signing for ML-DSA, and feed it a good RNG.&lt;/strong&gt; The randomized mode is the default and is more resilient to fault and nonce mishaps [@fips-204].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use context strings&lt;/strong&gt; to domain-separate signatures across applications and prevent cross-protocol reuse [@fips-204].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Keep implicit rejection constant-time.&lt;/strong&gt; Never let a KEM surface a decapsulation failure as a distinguishable error or timing tell.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Do not hand-roll any of these.&lt;/strong&gt; Every primitive has subtle side channels; use standard libraries.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; During migration, run post-quantum alongside classical (X25519MLKEM768) so a break or bug in either half is survivable, and migrate &lt;em&gt;key establishment&lt;/em&gt; before signatures -- harvest-now-decrypt-later already threatens today&apos;s recorded traffic, while forged signatures require an attacker who is present in the future [@openssl-35-notes].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;On availability: the finalized three are production-ready across the toolchain. OpenSSL 3.5 ships X25519MLKEM768 as a default key share, OpenSSH enabled &lt;code&gt;mlkem768x25519-sha256&lt;/code&gt; by default in 9.9 and made it the default in 10.0, and ML-KEM and ML-DSA are broadly available across open-source libraries -- liboqs, BoringSSL, AWS-LC, Microsoft SymCrypt, Bouncy Castle, and pyca/cryptography -- with formally verified ML-KEM through the libcrux line [@openssl-35-notes] [@openssh-pq] [@open-quantum-safe]. FN-DSA and HQC are experimental only until their FIPS documents are final. For a sense of how this looks in real deployments, this blog&apos;s companion posts trace &lt;a href=&quot;https://paragmali.com/blog/post-quantum-cryptography-on-windows-the-thirty-year-migrati/&quot; rel=&quot;noopener&quot;&gt;the post-quantum migration on Windows&lt;/a&gt; and &lt;a href=&quot;https://paragmali.com/blog/the-thirty-year-migration-ships-in-a-pip-install-how-post-qu/&quot; rel=&quot;noopener&quot;&gt;the moment ML-KEM arrived in an ordinary &lt;code&gt;pip install&lt;/code&gt;&lt;/a&gt;. The forthcoming Part 21 on crypto-agility and cryptographic bills of materials covers how to keep these choices swappable as the toolkit evolves.&lt;/p&gt;

Post-quantum migration now has deadlines attached. NIST&apos;s guidance and its IR 8547 transition plan point toward deprecating quantum-vulnerable algorithms by 2035, and comparable government profiles set similar horizons [@nist-pqc-project]. The practical reading is simple: inventory where you use RSA, Diffie-Hellman, and ECC now, because a decade is not long for a full cryptographic transition, and the harvest-now clock started before the standards were even published.

If you have OpenSSL 3.5 or later installed, you can list its post-quantum groups and signature algorithms with `openssl list -kem-algorithms` and `openssl list -signature-algorithms`. Seeing `ML-KEM-768` and `X25519MLKEM768` in that output is the concrete, on-your-own-machine version of this entire article: the migration is not a forecast, it is already in your crypto library [@openssl-35-notes].
&lt;p&gt;The rules above answer &quot;what.&quot; These next answer the questions that come up in review.&lt;/p&gt;
&lt;h2&gt;11. Questions From the Review Room&lt;/h2&gt;


No. There is no cryptanalytic break of any of the five. The only real-world failures are implementation leaks -- KyberSlash&apos;s secret-dependent division timing [@kyberslash-site] and Falcon&apos;s floating-point Gram-Schmidt leakage [@fouque-gsnorm-2019] -- and both are fixed by better code, not new math. The era&apos;s two famous breaks, SIKE and Rainbow, hit schemes that were never selected for the toolkit [@castryck-decru-sidh-2022] [@beullens-rainbow-2022].


Against a classical attacker, yes. Against harvest-now-decrypt-later, not for long-lived secrets: an adversary can record today&apos;s session and decrypt it once a quantum computer arrives, which is why you migrate key establishment first and why hybrids are already shipping [@nist-pqc-project] [@openssl-35-notes].


Not in general. A KEM is not a non-interactive key exchange -- there is no trusted post-quantum static-static agreement -- so protocols that relied on that property must be redesigned around an interactive KEM handshake rather than reconfigured in place.


No. FN-DSA (Falcon) was still in development toward FIPS 206 as of this writing [@fips-206-perlner-2025], and HQC was only selected on 2025-03-11 with a draft FIPS pending [@nist-ir-8545]. Do not ship either in production yet.


Because no single primitive wins on size, speed, assumption conservatism, and maturity at once, and because spreading the toolkit across three unrelated hard problems -- lattices, hashes, and codes -- means one mathematical break cannot take everything down. The 2022 breaks of SIKE and Rainbow, both outside the toolkit, are the empirical argument for that hedge [@nist-ir-8545] [@castryck-decru-sidh-2022].


Essentially yes. ML-KEM (FIPS 203) is the standardized CRYSTALS-Kyber with standardization edits, and the same relationship holds for Dilithium to ML-DSA and SPHINCS+ to SLH-DSA [@fips-203] [@crystals-kyber]. If you learned Kyber, you already know ML-KEM.


No and no. All five primitives run on ordinary classical hardware today [@nist-pqc-project]. Quantum key distribution is a physics-layer technique that uses quantum hardware to exchange keys; post-quantum cryptography is classical software designed to resist quantum *attacks*. They solve related problems by completely different means.

&lt;p&gt;Step back to the shape of the whole thing. One event in 1994 condemned all deployed public-key cryptography [@shor-1994]. The field&apos;s answer was not a single replacement but a portfolio hedged across three unrelated assumptions and tuned to five different binding constraints, three of them already law and two still in progress. The most striking fact remains the quietest one: after a decade of open, adversarial cryptanalysis, nothing in the toolkit has been broken -- only its early code has leaked.&lt;/p&gt;
&lt;p&gt;The real test is still ahead. When the next break comes, and history suggests one eventually will, the entire point of this design is that it lands on one assumption family while the others carry the load. That is not a promise that the math is unbreakable. It is a bet, made in the open, that diversity outlasts any single idea -- and a spare, HQC, waiting in reserve for the day the bet is called.&lt;/p&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;the-post-quantum-toolkit&quot; keyTerms={[
  { term: &quot;ML-KEM (FIPS 203)&quot;, definition: &quot;The standardized Module-LWE key-encapsulation mechanism; the deployed post-quantum KEM, small and fast, secured by FO with implicit rejection.&quot; },
  { term: &quot;ML-DSA (FIPS 204)&quot;, definition: &quot;The default post-quantum signature; a Fiat-Shamir-with-aborts lattice scheme using uniform integers and no floating point.&quot; },
  { term: &quot;SLH-DSA (FIPS 205)&quot;, definition: &quot;The conservative backstop signature; stateless hash-based, resting only on hash-function security, with tiny keys but very large signatures.&quot; },
  { term: &quot;FN-DSA / Falcon&quot;, definition: &quot;Pre-final (FIPS 206 in development). GPV hash-and-sign over NTRU with the smallest signatures, but a hard-to-implement floating-point sampler.&quot; },
  { term: &quot;HQC&quot;, definition: &quot;Pre-final (selected 2025-03-11). A code-based KEM providing non-lattice assumption diversity, with a public decoder and a bounded, secret-independent failure rate.&quot; },
  { term: &quot;Harvest now, decrypt later&quot;, definition: &quot;Recording encrypted traffic today to decrypt once quantum computers exist; the reason key establishment migrates first.&quot; },
  { term: &quot;Fujisaki-Okamoto with implicit rejection&quot;, definition: &quot;The transform giving KEMs chosen-ciphertext security by returning a pseudo-random key on failure, closing the decapsulation-failure oracle.&quot; },
  { term: &quot;Fiat-Shamir with aborts&quot;, definition: &quot;Signing by reject-and-restart so the released transcript is provably independent of the secret key.&quot; },
  { term: &quot;Transcript leakage&quot;, definition: &quot;When public outputs statistically depend on the secret key, so enough valid outputs recover it, as in the NTRUSign parallelepiped break.&quot; },
  { term: &quot;KEM is not NIKE&quot;, definition: &quot;A key-encapsulation mechanism cannot replace non-interactive static-static Diffie-Hellman, so some protocols need redesign, not a drop-in swap.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>post-quantum-cryptography</category><category>ml-kem</category><category>ml-dsa</category><category>slh-dsa</category><category>falcon</category><category>hqc</category><category>lattice-cryptography</category><category>cryptography</category><author>noreply@paragmali.com (Parag Mali)</author></item></channel></rss>