<?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: rsa</title><description>Posts tagged rsa.</description><link>https://paragmali.com/</link><language>en-US</language><lastBuildDate>Sun, 19 Jul 2026 05:08:42 GMT</lastBuildDate><atom:link href="https://paragmali.com/tags/rsa/rss.xml" rel="self" type="application/rss+xml"/><item><title>How Q-Day Breaks Everything: Shor&apos;s Algorithm and the Simultaneous Fall of RSA, Diffie-Hellman, and ECC</title><link>https://paragmali.com/blog/how-q-day-breaks-everything-shors-algorithm-and-the-simultan/</link><guid isPermaLink="true">https://paragmali.com/blog/how-q-day-breaks-everything-shors-algorithm-and-the-simultan/</guid><description>RSA, Diffie-Hellman, DSA, and elliptic curves share one abelian period. A single quantum computer running Shor&apos;s algorithm reads it and breaks all four at once.</description><pubDate>Sat, 18 Jul 2026 00:00:00 GMT</pubDate><content:encoded>
RSA, Diffie-Hellman, DSA, and elliptic-curve cryptography look like four independent security systems, but they secretly rest on one structure: a hidden period in a finite abelian group. A single fault-tolerant quantum computer running Shor&apos;s algorithm reads that period directly with the quantum Fourier transform, breaking all four in polynomial time -- and enlarging keys does not help, because Shor scales with the logarithm of the key. Symmetric cryptography (AES, SHA-2/3) survives Q-Day intact because it hides no such period, so it faces only Grover&apos;s quadratic speedup, which doubling the key size neutralizes. No such machine exists in 2026 -- the best hardware runs about one below-threshold logical qubit -- but &quot;harvest now, decrypt later&quot; means the migration to post-quantum cryptography cannot wait for it to arrive.
&lt;h2&gt;1. One Break, Four Falls&lt;/h2&gt;
&lt;p&gt;Four cryptographers, working in four different decades on four different branches of mathematics, built the fortresses that guard almost every secret you have ever sent: a 2048-bit RSA key, a 2048-bit Diffie-Hellman group, a DSA signature, and a 256-bit elliptic curve. They look nothing alike -- different keys, different math, different inventors -- so we deployed them side by side and called it diversity.&lt;/p&gt;
&lt;p&gt;This article is about the afternoon a single machine running a single idea knocks all four down at once, while AES-256 in the field next door barely looks up -- and about why the reason those four fall together is exactly the reason the fifth survives.&lt;/p&gt;
&lt;p&gt;Here is the thesis, stated plainly before any mathematics arrives to defend it: the four are not four problems. They are one. Underneath RSA&apos;s factoring, Diffie-Hellman&apos;s discrete logarithm, DSA&apos;s signatures, and elliptic-curve cryptography&apos;s smaller keys lies a single shared object -- a hidden period in a finite abelian group. A quantum computer running Peter Shor&apos;s 1994 algorithm reads that period more or less in one shot, and when the period falls, all four fortresses built on top of it fall with it [@shor-1994].&lt;/p&gt;
&lt;p&gt;Symmetric cryptography survives for the mirror-image reason: a well-built cipher hides no period at all, so there is nothing for the same machine to read.&lt;/p&gt;
&lt;p&gt;The event has a name.&lt;/p&gt;

Q-Day is the hypothetical day a cryptographically relevant quantum computer first runs Shor&apos;s algorithm at scale against deployed keys, breaking the public-key cryptography (RSA, Diffie-Hellman, DSA, and elliptic-curve schemes) that secures most of the internet. It is a threshold, not a gradual slope: the same machine that cannot break a 2048-bit key at all on Monday can break it in hours once it crosses the fault-tolerance threshold.
&lt;p&gt;Two questions organize everything that follows, and the whole article is their answer: &lt;em&gt;why do these four fall together?&lt;/em&gt; and &lt;em&gt;why not AES?&lt;/em&gt; Hold both in your head. The first is a story about a hidden unity nobody designed on purpose. The second is a story about a boundary so sharp it can be stated as a theorem -- and that same boundary turns out to be the entire design premise of the cryptography we are now scrambling to deploy.&lt;/p&gt;

RSA, Diffie-Hellman, DSA, and elliptic curves were never four independent bets. They are one bet -- that a hidden period in a finite abelian group is hard to find -- made four times in four disguises. Shor&apos;s algorithm collects on all four at once.
&lt;p&gt;One honesty flag, planted here and never lowered: no such machine exists in 2026. Not almost, not in a lab somewhere -- none. The best error-corrected hardware yet demonstrated encodes about one reliable logical qubit [@google-willow-2025], and a real attack needs on the order of a thousand of them holding still for hours. So this is a loaded gun on the table, not a fired one. That gap between a proven algorithm and an unbuilt machine is not a reason to relax; as we will see, it is precisely the deadline.&lt;/p&gt;
&lt;p&gt;The journey runs in seven moves: how the world came to trust just two hard problems, the one quantum trick that matters, the breakthrough that turned factoring into period-finding, the same trick applied three more times, the asymmetry that spares AES, the machine&apos;s true price tag, the limits of the blast radius, and why one proven fact already forces a global migration. To see why one machine breaks four fortresses, you first have to see how the world ended up trusting just two hard problems in the first place.&lt;/p&gt;
&lt;h2&gt;2. Two Problems the Whole World Rested On&lt;/h2&gt;
&lt;p&gt;Rewind to 1976. Two strangers want to agree on a shared secret while an eavesdropper records every bit that passes between them. For millennia this was considered impossible: to share a secret you first had to share a secret. Then Whitfield Diffie and Martin Hellman published a construction that let the two strangers mix public numbers into a private one the eavesdropper could not reconstruct, and modern cryptography was born [@diffie-hellman-1976]. Its security rested on a new assumption -- that one specific arithmetic operation is easy forward and hard backward.&lt;/p&gt;

In a cyclic group generated by an element $g$, exponentiation is easy: given $g$ and $x$, computing $h = g^x$ is fast. The discrete logarithm problem is the reverse: given $g$ and $h$, recover the exponent $x$. In the multiplicative group of integers modulo a large prime -- and, later, in the group of points on an elliptic curve -- recovering $x$ is believed to require super-polynomial classical effort. That belief is the security assumption beneath Diffie-Hellman, DSA, and elliptic-curve cryptography.
&lt;p&gt;A year later, Ron Rivest, Adi Shamir, and Leonard Adleman turned a different one-way asymmetry into a full encryption-and-signature system: multiplying two large primes is easy, but factoring their product back into those primes is hard [@rsa-1978]. &lt;a href=&quot;https://paragmali.com/blog/how-rsa-would-break-why-factoring-is-the-slow-path-and-coppe/&quot; rel=&quot;noopener&quot;&gt;RSA&lt;/a&gt; bet its life on integer factoring; &lt;a href=&quot;https://paragmali.com/blog/nobody-broke-the-discrete-log-a-field-guide-to-diffie-hellma/&quot; rel=&quot;noopener&quot;&gt;Diffie-Hellman&lt;/a&gt; had bet on the discrete logarithm. Two bets, two problems.&lt;/p&gt;
&lt;p&gt;Then the bets consolidated. In 1985 Victor Miller, and independently in 1987 Neal Koblitz, moved the discrete logarithm onto elliptic curves, where the best known classical attacks are far weaker and so the keys can be dramatically smaller for the same classical security [@miller-1986][@koblitz-1987]. &lt;a href=&quot;https://paragmali.com/blog/the-curve-was-hard-the-gap-was-soft-a-field-guide-to-using-e/&quot; rel=&quot;noopener&quot;&gt;Elliptic-curve cryptography&lt;/a&gt; was not a new hard problem -- it was the &lt;em&gt;same&lt;/em&gt; discrete logarithm relocated to a group where classical attackers had less traction.This is the seed of a cruel irony we will harvest in Section 5. ECC&apos;s whole selling point is that it achieves equal classical security with smaller keys, because no sub-exponential attack like index calculus applies to well-chosen curves [@koblitz-1987]. Against a quantum computer, &quot;smaller keys&quot; means &quot;fewer qubits to attack,&quot; so the classical strength inverts into a quantum liability.&lt;/p&gt;
&lt;p&gt;By the 1990s the accounting was stark. Strip away the packaging and essentially &lt;em&gt;all&lt;/em&gt; deployed public-key cryptography reduced to exactly two hard problems: integer factoring and the discrete logarithm. The classical attacks that calibrate their key sizes -- the general number field sieve for factoring, index calculus for finite-field discrete logs, Pollard&apos;s rho for elliptic curves -- are the subject of this series&apos; earlier posts on RSA and the discrete logarithm, and I will not re-derive them here [@bernstein-lange-2017].&lt;/p&gt;
&lt;p&gt;What matters is the structural fact: the entire public-key world put all its eggs in two baskets, and nobody chose those two baskets because they were secretly connected. They looked like independent bets.&lt;/p&gt;

Nobody chose factoring and the discrete logarithm because they were related. They looked like two independent bets. They were the same bet.
&lt;p&gt;While the defense lineage was consolidating, a second, unrelated lineage was quietly assembling the machine that would read both. In 1982 Richard Feynman observed that simulating quantum physics on a classical computer seems to require exponential resources, and proposed turning the problem around: build a computer that &lt;em&gt;is&lt;/em&gt; quantum-mechanical and let physics do the bookkeeping [@feynman-1982]. In 1985 David Deutsch made the idea rigorous, defining the universal quantum computer and the principle that it could simulate any physical process [@deutsch-1985].&lt;/p&gt;
&lt;p&gt;This was pure physics and computability theory. Nobody in 1985 thought it had anything to do with RSA. The two lineages were on tracks that had not yet touched.&lt;/p&gt;

flowchart LR
    subgraph Defense[&quot;Defense lineage -- the fortresses&quot;]
        DH[&quot;1976 Diffie-Hellman: discrete log assumption&quot;]
        RSA[&quot;1977 RSA: integer factoring&quot;]
        ECC[&quot;1985 to 1987 Miller and Koblitz: elliptic curves&quot;]
    end
    subgraph Attack[&quot;Attack lineage -- the machine&quot;]
        FEY[&quot;1982 Feynman: simulate physics with a quantum computer&quot;]
        DEU[&quot;1985 Deutsch: universal quantum computer&quot;]
        SIM[&quot;1994 Simon: period-finding template&quot;]
    end
    DH --&amp;gt; SHOR[&quot;1994 Shor: period-finding topples all four&quot;]
    RSA --&amp;gt; SHOR
    ECC --&amp;gt; SHOR
    FEY --&amp;gt; DEU
    DEU --&amp;gt; SIM
    SIM --&amp;gt; SHOR
    SHOR --&amp;gt; GID[&quot;2021 to 2025 Gidney: concrete qubit bill&quot;]
&lt;p&gt;Two problems, one machine, a decades-long collision course -- and in 1994 a single person connected them. The bridge between the two lineages started as one strange little algorithm about a hidden XOR mask, and to understand how it grew into the break, you have to understand the one quantum trick that makes all of this work.&lt;/p&gt;
&lt;h2&gt;3. The One Trick That Matters&lt;/h2&gt;
&lt;p&gt;Before we can watch four fortresses fall, we have to kill a myth, because the myth predicts the wrong outcome. The popular story says a quantum computer &quot;tries all the keys at once and reads out the winner.&quot; If that were true, it would break AES just as easily as RSA -- every symmetric cipher would fall too, and the entire second half of this article would be wrong. It is not true. A quantum computer does something far stranger and far more specific, and the specificity is the whole point.&lt;/p&gt;
&lt;p&gt;Start with the one genuinely non-classical resource.&lt;/p&gt;

A register of $n$ qubits can occupy a weighted combination of all $2^n$ basis states at once, written $\sum_x \alpha_x |x\rangle$ where each complex number $\alpha_x$ is an amplitude. Applying a function to that register evaluates it on every input simultaneously. But the result is an internal state, not a readable list: when you measure, you get exactly one outcome $x$, drawn at random with probability $|\alpha_x|^2$, and the rest of the superposition vanishes.
&lt;p&gt;This is where the myth breaks. Yes, you can evaluate a function on all $2^n$ inputs at once. No, you cannot read the answers. Measurement hands you a single random input-output pair, which is no better than guessing. Superposition alone buys you nothing. The art -- the entire art of quantum algorithms -- is what you do to the amplitudes &lt;em&gt;before&lt;/em&gt; you measure.&lt;/p&gt;
&lt;p&gt;The tool for that is interference. Amplitudes are complex numbers, and like waves they can add or cancel. If you can arrange the computation so that every path leading to a wrong answer is met by another path of opposite sign, the wrong answers cancel to near-zero amplitude, while the right answers reinforce. Measurement then returns a useful outcome with high probability -- not because you searched, but because you sculpted the wavefunction so that only the structure you care about is left standing.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &quot;A quantum computer tries every key in parallel and reads the winner&quot; is wrong, and the error is not a detail. Parallel evaluation produces a superposition you cannot read; a single measurement collapses it to one random result. Every real quantum speedup comes from interference that cancels wrong answers -- and interference only helps when the problem has structure to exploit. Unstructured problems, like guessing an AES key, expose no such structure, which is exactly why they resist.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So which structure can interference exploit? The most powerful answer known is &lt;em&gt;periodicity&lt;/em&gt;. Suppose a function $f$ is periodic: it repeats with some hidden period $r$, so that $f(x)$ and $f(x + r)$ always agree. Evaluate $f$ over a superposition of all inputs, and the state quietly organizes itself around that period. The instrument that reads it is the quantum Fourier transform.&lt;/p&gt;

The QFT is the quantum analogue of the discrete Fourier transform, applied to the amplitudes of a quantum state rather than to a list of numbers. Fed a state whose amplitudes repeat with a hidden period $r$, it concentrates the total amplitude onto the frequencies that match $r$, so that measuring the transformed state returns a multiple of $1/r$ with high probability. On an $n$-qubit register it runs in about $O(n^2)$ elementary gates [@nielsen-chuang-2010].
&lt;p&gt;Put those pieces together and you have a machine that does exactly one magical thing: it takes a function with a hidden period and hands you that period. Superpose over all inputs, evaluate the function, and the act of computing it entangles the input register with the output so that the input register&apos;s amplitudes now repeat with the function&apos;s period. Apply the QFT, and interference collapses that repeating pattern onto its frequency. Measure, and you read out information about $r$ -- the period no classical observer could see without effectively checking the inputs one by one.&lt;/p&gt;

flowchart TD
    A[&quot;Superpose over all inputs x&quot;] --&amp;gt; B[&quot;Evaluate f(x) into a second register&quot;]
    B --&amp;gt; C[&quot;Measuring or entangling leaves the input register repeating with period r&quot;]
    C --&amp;gt; D[&quot;Quantum Fourier transform concentrates amplitude on multiples of 1 over r&quot;]
    D --&amp;gt; E[&quot;Measure: read a multiple of the hidden frequency&quot;]
    E --&amp;gt; F[&quot;Classical post-processing recovers r&quot;]
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; A quantum computer does not search in parallel and read the winner. It engineers interference so that wrong answers cancel and only a function&apos;s hidden period survives measurement. No period, no exponential speedup -- which is precisely why the same machine that shatters RSA cannot touch a well-built symmetric cipher.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The first person to turn this into a concrete algorithm was Daniel Simon. In 1994 he built a toy problem -- a function that secretly satisfies $f(x) = f(x \oplus s)$ for a hidden bit-string $s$ -- and showed that quantum interference recovers $s$ exponentially faster than any classical method possibly could [@simon-1994].Simon&apos;s algorithm is the direct ancestor Shor read. Its &quot;period&quot; is a hidden XOR mask in a group of bit-strings, which breaks nothing anyone deployed. Shor&apos;s leap was to see the same template hiding inside a problem the entire economy depended on, and to swap Simon&apos;s simple transform for the QFT over the integers modulo $N$ [@simon-1994].&lt;/p&gt;
&lt;p&gt;Simon&apos;s hidden period lived in a toy group and broke nothing real. But it proved the template: encode a secret as the period of a function, then let interference read it. The question that ended an era was the obvious next one -- what &lt;em&gt;real&lt;/em&gt;, deployed, load-bearing problem is secretly period-finding in disguise?&lt;/p&gt;
&lt;h2&gt;4. The Breakthrough: Factoring Is Period-Finding&lt;/h2&gt;
&lt;p&gt;In 1994, at Bell Labs, Peter Shor answered that question with a move so clean it still reads like sleight of hand. Factoring -- the problem RSA stakes its life on -- is secretly a period-finding problem. Watch the reduction before the machinery, because the reduction is the whole trick.&lt;/p&gt;
&lt;p&gt;To factor a large number $N$, pick a random integer $a$ with no common factor with $N$. Now consider the innocent-looking function $f(x) = a^x \bmod N$. Because there are only finitely many residues modulo $N$, this function must eventually repeat, and it repeats with a period: the smallest $r$ for which $a^r \equiv 1 \pmod N$. That period has a name.&lt;/p&gt;

The multiplicative order of $a$ modulo $N$ is the smallest positive integer $r$ such that $a^r \equiv 1 \pmod N$. It is exactly the period of the function $f(x) = a^x \bmod N$. Classically, finding $r$ appears about as hard as factoring $N$ itself. Quantumly, it is the one thing the QFT does well.
&lt;p&gt;Here is why the order cracks the factorization. Suppose $r$ is even. Then $a^r - 1 = (a^{r/2} - 1)(a^{r/2} + 1)$ is divisible by $N$. Unless $a^{r/2} \equiv -1 \pmod N$ (a case you detect and retry), neither factor on the right is a multiple of $N$ by itself, so each shares only &lt;em&gt;part&lt;/em&gt; of $N$&apos;s prime structure. Computing $\gcd(a^{r/2} \pm 1,, N)$ with Euclid&apos;s ancient algorithm then hands you a non-trivial factor. For a random $a$, this works with probability at least one-half, so a couple of tries suffice [@shor-1994].&lt;/p&gt;
&lt;p&gt;Every step in that paragraph is classical arithmetic you can run right now -- except one: finding the order $r$. That single sub-problem is where the quantum computer earns its keep, and it is period-finding exactly as Section 3 described it.&lt;/p&gt;
&lt;p&gt;Superpose over all exponents $x$, compute $a^x \bmod N$ reversibly into a second register (this modular exponentiation is the dominant cost of the whole circuit), and the first register is left repeating with period $r$. Apply the QFT, and amplitude concentrates on multiples of $1/r$; measure, and you get an estimate of some $k/r$. A classical continued-fraction expansion then recovers $r$ from that estimate.&lt;/p&gt;

flowchart TD
    A[&quot;Pick random a in the range 2 to N minus 1&quot;] --&amp;gt; B{&quot;a coprime to N?&quot;}
    B --&amp;gt;|no| Z[&quot;gcd(a, N) is already a factor -- lucky&quot;]
    B --&amp;gt;|yes| C[&quot;Quantum step: find the order r of a mod N by QFT period-finding&quot;]
    C --&amp;gt; D[&quot;Classical step: continued fractions recover r from the measured fraction&quot;]
    D --&amp;gt; E{&quot;r even and a^(r/2) not -1 mod N?&quot;}
    E --&amp;gt;|no| A
    E --&amp;gt;|yes| F[&quot;Classical step: gcd(a^(r/2) +/- 1, N) yields a non-trivial factor&quot;]
&lt;p&gt;You do not need a quantum computer to see the reduction work, because only the order-finding is quantum. Compute the order by brute force on a small $N$, feed it into the same greatest-common-divisor step Shor uses, and a real factor drops out.&lt;/p&gt;
&lt;p&gt;{`
from math import gcd&lt;/p&gt;
&lt;p&gt;def find_order(a, N):
    # multiplicative order of a mod N: smallest r &amp;gt;= 1 with a^r = 1 (mod N)
    x = a % N
    r = 1
    while x != 1:
        x = (x * a) % N
        r += 1
        if r &amp;gt; N:                # safety: a was not coprime to N
            return None
    return r&lt;/p&gt;
&lt;p&gt;def factor_via_order(N, a):
    if gcd(a, N) != 1:
        return gcd(a, N), N // gcd(a, N)     # lucky: a already shares a factor
    r = find_order(a, N)
    if r is None or r % 2 != 0:
        return None                           # r odd -&amp;gt; pick another a and retry
    y = pow(a, r // 2, N)
    if y == N - 1:
        return None                           # a^(r/2) = -1 mod N -&amp;gt; retry
    return gcd(y - 1, N), gcd(y + 1, N)&lt;/p&gt;
&lt;p&gt;for (N, a) in [(15, 7), (21, 2), (2047, 5)]:
    print(&quot;N =&quot;, N, &quot; a =&quot;, a,
          &quot; order r =&quot;, find_order(a, N),
          &quot; factors =&quot;, factor_via_order(N, a))&lt;/p&gt;
N = 15  a = 7  order r = 4  factors = (3, 5)
N = 21  a = 2  order r = 6  factors = (7, 3)
N = 2047 a = 5  order r = 44 factors = (23, 89)
&lt;p&gt;`}&lt;/p&gt;

Add `(3233, 3)` to the list and it factors $3233 = 61 \times 53$ cleanly. Now add `(3233, 2)` and it returns `None`: with $a = 2$ the order is even but $a^{r/2} \equiv -1 \pmod{3233}$, the one case the reduction cannot use, so it must retry with a fresh $a$. That single `None` is the &quot;probability at least one-half&quot; caveat made concrete -- some choices of $a$ simply do not yield a factor, which is exactly why Shor picks $a$ at random and expects to need a couple of attempts.
&lt;p&gt;The classical order search above is exponential in the number of digits -- run it on a 2048-bit $N$ and it never returns. Shor&apos;s contribution is to replace that one line with a quantum circuit that finds the same $r$ in polynomial time.Alexei Kitaev reformulated the quantum step in 1995 as phase estimation on the operator that multiplies by $a$, recovering $r$ from the eigenvalue&apos;s phase. It is mathematically equivalent to Shor&apos;s order-finding and is how most modern textbooks present the algorithm [@kitaev-1995]. How polynomial? The whole circuit is about $O((\log N)^3)$ gates, dominated by the modular exponentiation; the QFT itself is only $O((\log N)^2)$ [@nielsen-chuang-2010].&lt;/p&gt;
&lt;p&gt;One precision point, flagged loudly because it will haunt Sections 7 and 8: that $O((\log N)^3)$ is a &lt;em&gt;circuit size&lt;/em&gt; on a perfect, noiseless, fault-tolerant machine. It counts logical gates, not seconds. The distance between &quot;a polynomial-size circuit exists&quot; and &quot;a machine ran it before lunch&quot; is measured in millions of physical qubits, and we will pay that bill in full later.&lt;/p&gt;
&lt;p&gt;Now the consequence that inverts fifty years of defensive instinct.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Every classical attack on RSA gets exponentially harder as the key grows, so the entire history of the field has been &quot;when the attacker catches up, add bits.&quot; Shor breaks that reflex. Its cost is polynomial in the &lt;em&gt;number of bits&lt;/em&gt; $n = \log N$. Going from RSA-2048 to RSA-4096 roughly doubles $n$, so it multiplies the qubit and gate counts by a small constant -- not the exponential wall classical attackers slam into. The first move everyone reaches for is worthless here.&lt;/p&gt;
&lt;/blockquote&gt;

Shor&apos;s cost grows with the logarithm of the key, not the key. Against this attack, RSA-4096 is not meaningfully safer than RSA-2048 -- it is a rounding error safer.
&lt;p&gt;Factoring was the first fortress to fall. But Shor&apos;s 1994 paper had a second half that almost nobody quotes, and it is the reason Diffie-Hellman, DSA, and elliptic curves fall too -- not by coincidence, but by the same mechanism running one dimension higher.&lt;/p&gt;
&lt;h2&gt;5. The Same Trick, Three More Times&lt;/h2&gt;
&lt;p&gt;If factoring is secretly period-finding, the natural question is: what else is? The answer is the entire argument of this article. Almost everything the deployed public-key world rests on is period-finding in disguise -- and Shor&apos;s own 1994 paper proved the second case himself.&lt;/p&gt;
&lt;p&gt;Recall the discrete logarithm: given $g$ and $h = g^s$ in a cyclic group of order $r$, recover the exponent $s$. Shor&apos;s insight was that $s$ is also hidden inside a periodicity, only now the period lives in two dimensions instead of one. Here is the mechanism in full, because it is the load-bearing step and hand-waving it would cheat you of the aha.&lt;/p&gt;
&lt;p&gt;Define the two-variable function&lt;/p&gt;
&lt;p&gt;$$f(x, y) = g^x , h^y = g^{,x + s y}.$$&lt;/p&gt;
&lt;p&gt;This function takes the same value whenever the exponent $x + s y$ is unchanged modulo $r$. So the set of shifts that leave $f$ invariant -- its hidden period, now a &lt;em&gt;lattice&lt;/em&gt; of vectors rather than a single number -- is&lt;/p&gt;
&lt;p&gt;$$L = {(x, y) \in \mathbb{Z}^2 : x + s y \equiv 0 \pmod{r}}.$$&lt;/p&gt;
&lt;p&gt;That lattice encodes the secret $s$ directly in its slope. To read it, Shor superposes over both exponent registers and applies a two-dimensional QFT. Interference concentrates the amplitude onto the dual frequency vectors $(k_1, k_2)$ satisfying $k_1 + s,k_2 \equiv 0 \pmod{r}$. A single measurement returns one such pair, and whenever $\gcd(k_2, r) = 1$ you solve for the secret in one line of classical arithmetic:&lt;/p&gt;
&lt;p&gt;$$s \equiv -,k_1 , k_2^{-1} \pmod{r}.$$&lt;/p&gt;
&lt;p&gt;Look at what just happened. This is the &lt;em&gt;exact&lt;/em&gt; same period-extraction that factored $N$ in Section 4 -- superpose, evaluate, transform, measure, post-process -- run in two dimensions instead of one [@shor-1994]. The discrete logarithm does not resist Shor any harder than factoring does; it surrenders the secret exponent directly. Finite-field Diffie-Hellman, DSA, and ElGamal all rest on precisely this discrete logarithm, so all three fall in the same stroke.&lt;/p&gt;
&lt;p&gt;Elliptic curves are the same story one more time. The points on an elliptic curve form a finite abelian group under a geometric addition law, and &quot;discrete logarithm&quot; there means recovering the integer $s$ with $Q = sP$ for public points $P$ and $Q$. It is the same $f(x,y)$, the same two-dimensional period, the same 2-D QFT -- only the group operation changes. John Proos and Christof Zalka worked out the elliptic-curve version explicitly in 2003, and with it ECDH, ECDSA, and EdDSA join the list [@proos-zalka-2003].&lt;/p&gt;
&lt;p&gt;Now the unification that turns three coincidences into one sentence.&lt;/p&gt;

Given a finite abelian group $G$ and a function $f$ on $G$ that is constant on the cosets of some hidden subgroup $H$ (and takes different values on different cosets), the abelian hidden subgroup problem is to find $H$. Order-finding, the finite-field discrete logarithm, and the elliptic-curve discrete logarithm are all special cases -- and the QFT with phase estimation solves every abelian instance in polynomial time [@kitaev-1995].
&lt;p&gt;Alexei Kitaev supplied this abstraction in 1995 [@kitaev-1995]. Before it, &quot;Shor breaks RSA&quot; and &quot;Shor breaks Diffie-Hellman&quot; looked like two separate results that happened to use the same author&apos;s trick. After it, they are two instances of a single mathematical fact: &lt;em&gt;the quantum Fourier transform reads a hidden period in any finite abelian group.&lt;/em&gt; Factoring hides its period in one dimension; both discrete logs hide theirs in two; the machine does not care which.&lt;/p&gt;

flowchart TD
    F1[&quot;Integer factoring -- RSA&quot;] --&amp;gt; HSP[&quot;Abelian hidden subgroup problem: f is constant on the cosets of a hidden subgroup&quot;]
    F2[&quot;Finite-field discrete log -- DH and DSA&quot;] --&amp;gt; HSP
    F3[&quot;Elliptic-curve discrete log -- ECDH and ECDSA&quot;] --&amp;gt; HSP
    HSP --&amp;gt; QFT[&quot;Quantum Fourier transform reads the hidden period&quot;]
    QFT --&amp;gt; O1[&quot;RSA falls&quot;]
    QFT --&amp;gt; O2[&quot;Diffie-Hellman and DSA fall&quot;]
    QFT --&amp;gt; O3[&quot;ECDH and ECDSA fall&quot;]
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The four are not four security problems. They are one -- a hidden abelian period -- wearing four disguises. Factoring hides it in one dimension; the two discrete logs hide it in two. One machine, one idea, four falls.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Two precautions before the table. First, &quot;together&quot; means the same machine class and the same breakthrough, not one identical circuit pressing a single button. RSA, a finite field, and an elliptic curve need different arithmetic units compiled into the machine; what they share is that each reduces to the abelian HSP, so one fault-tolerant quantum computer running Shor&apos;s family of circuits dispatches all of them. Second -- and this is the counterintuitive kicker -- the four do not fall in the order their reputations suggest. Elliptic-curve cryptography, the &lt;em&gt;strongest&lt;/em&gt; of the four against classical attack, falls &lt;em&gt;first&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Why? Because ECC&apos;s classical strength is small keys. No sub-exponential attack applies to a well-chosen curve, so a 256-bit elliptic key matches the classical security of a 3072-bit RSA key [@nist-sp800-57]. Against Shor, &quot;fewer bits&quot; simply means &quot;fewer logical qubits to build.&quot;&lt;/p&gt;
&lt;p&gt;Martin Roetteler and colleagues estimated in 2017 that breaking the NIST P-256 curve needs about 2330 logical qubits [@roetteler-2017] -- materially fewer than the roughly 6200 logical qubits (about $3n$) a 2048-bit RSA break requires [@gidney-ekera-2021]. Proos and Zalka had already found the same inversion in 2003: about 1000 qubits for 160-bit ECC versus about 2000 for the security-equivalent 1024-bit RSA [@proos-zalka-2003].Those small keys also pay a purely classical dividend that has nothing to do with quantum computers: at equal classical security an ECC certificate and its handshake messages are a fraction of the size of the RSA equivalent, which trims bandwidth and storage on every connection they protect.&lt;/p&gt;

&quot;ECC is an easier target than RSA.&quot; -- Roetteler, Naehrig, Svore, and Lauter, 2017
&lt;p&gt;The full ledger, with the survivor included so the contrast is unmissable:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Primitive&lt;/th&gt;
&lt;th&gt;Underlying hard problem&lt;/th&gt;
&lt;th&gt;Hidden abelian period?&lt;/th&gt;
&lt;th&gt;Quantum attack&lt;/th&gt;
&lt;th&gt;Do bigger keys help?&lt;/th&gt;
&lt;th&gt;Logical-qubit estimate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;RSA-2048&lt;/td&gt;
&lt;td&gt;Integer factoring&lt;/td&gt;
&lt;td&gt;Yes -- one-dimensional order&lt;/td&gt;
&lt;td&gt;Shor order-finding&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;~6200 (about $3n$) [@gidney-ekera-2021]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Finite-field DH / DSA-2048&lt;/td&gt;
&lt;td&gt;Discrete log modulo a prime&lt;/td&gt;
&lt;td&gt;Yes -- two-dimensional period&lt;/td&gt;
&lt;td&gt;Shor DLP variant&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Comparable to RSA-2048 [@gidney-ekera-2021]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ECDH / ECDSA (P-256)&lt;/td&gt;
&lt;td&gt;Elliptic-curve discrete log&lt;/td&gt;
&lt;td&gt;Yes -- two-dimensional period&lt;/td&gt;
&lt;td&gt;Shor via Proos-Zalka&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;~2330 -- falls first [@roetteler-2017]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AES-256&lt;/td&gt;
&lt;td&gt;None -- unstructured key&lt;/td&gt;
&lt;td&gt;No period at all&lt;/td&gt;
&lt;td&gt;Grover only (quadratic)&lt;/td&gt;
&lt;td&gt;Yes -- doubling suffices&lt;/td&gt;
&lt;td&gt;Not applicable [@bbbv-1997]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Three rows share the &quot;yes&quot; column, and that shared &quot;yes&quot; is the entire vulnerability. One machine, one idea, four falls -- and yet AES-256 in the field next door survives untouched. That survival is not luck, and it is not a gap someone will patch next year. It is the second half of the thesis, and it has a proof.&lt;/p&gt;
&lt;h2&gt;6. Why Symmetric Crypto Only Loses a Square Root&lt;/h2&gt;
&lt;p&gt;Return to &lt;a href=&quot;https://paragmali.com/blog/the-fortress-and-the-afterthought-how-aes-would-break-at-its/&quot; rel=&quot;noopener&quot;&gt;AES-256&lt;/a&gt;, standing untouched in the next field. The same machine that reads RSA&apos;s period in polynomial time barely dents it. The reason is exactly the reason RSA falls: AES hides no period. There is no abelian structure inside a well-designed cipher for the QFT to grab, so the exponential engine has nothing to bite on. What is left is the generic attack that works on &lt;em&gt;any&lt;/em&gt; search problem, structured or not.&lt;/p&gt;

Grover&apos;s algorithm finds a marked item in an unstructured space of $N$ candidates using about $\sqrt{N}$ evaluations of a test function, a quadratic speedup over the roughly $N/2$ a classical search expects [@grover-1996]. For an $n$-bit key there are $N = 2^n$ candidates, so Grover&apos;s query count is about $2^{n/2}$: AES-128 drops to about $2^{64}$ queries, AES-256 to about $2^{128}$.
&lt;p&gt;At a glance that looks alarming -- $2^{64}$ sounds within reach. Hold that thought; it is the most misunderstood number in the field, and we will dismantle it in a moment. First, the structural point, because it is what makes the symmetric world safe by design rather than by luck.&lt;/p&gt;
&lt;p&gt;The quadratic speedup is not a weak version of Shor&apos;s exponential one. It is a &lt;em&gt;different kind&lt;/em&gt; of thing, and its weakness is provable. Bennett, Bernstein, Brassard, and Vazirani proved in 1997 that any quantum algorithm searching an unstructured space needs at least on the order of $\sqrt{N}$ queries -- the $\Omega(\sqrt{N})$ lower bound [@bbbv-1997]. Grover is optimal; you cannot do better against a structureless target.&lt;/p&gt;
&lt;p&gt;This is the single most important bound in the article, because it converts &quot;we do not know a better attack on AES&quot; into &quot;there provably is no better generic attack.&quot; Shor exists because factoring has structure. Grover is the best you can ever do precisely when there is none.&lt;/p&gt;
&lt;p&gt;{`
// Classical brute force is 2^n; Grover&apos;s floor is 2^(n/2).
// This compares EXPONENTS -- it is a query lower bound, not a runtime.
function keyStrength(nBits) {
  return { classical: nBits, grover: nBits / 2 };  // log2 of each cost
}&lt;/p&gt;
&lt;p&gt;for (const n of [128, 192, 256]) {
  const s = keyStrength(n);
  console.log(&quot;AES-&quot; + n + &quot;: classical 2^&quot; + s.classical + &quot; vs Grover floor 2^&quot; + s.grover);
}&lt;/p&gt;
&lt;p&gt;// Doubling the key restores the pre-quantum margin:
const groverAes256 = keyStrength(256).grover;      // 2^128
const classicalAes128 = keyStrength(128).classical; // 2^128
console.log(&quot;AES-256&apos;s Grover floor 2^&quot; + groverAes256 +
            &quot; equals AES-128&apos;s old classical margin 2^&quot; + classicalAes128);
// AES-128: classical 2^128 vs Grover floor 2^64
// AES-256: classical 2^256 vs Grover floor 2^128
`}&lt;/p&gt;
&lt;p&gt;So doubling the key exactly undoes Grover: AES-256&apos;s $2^{128}$ Grover floor restores the $2^{128}$ margin AES-128 used to enjoy classically. But &quot;double the key&quot; undersells how safe AES-128 already is, and here is where the popular $2^{64}$ falls apart.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;That $2^{64}$ is a floor on operations, not a feasible runtime.&lt;/strong&gt; Three facts, each independently decisive, separate the number from any real attack. First, Grover is inherently &lt;em&gt;sequential&lt;/em&gt;: its roughly $2^{n/2}$ iterations must be applied one after another, and each iteration contains a full evaluation of AES as a reversible quantum circuit -- a deep block of gates, not a single step [@grassl-2015]. You cannot collapse the iterations into a shallow parallel circuit.&lt;/p&gt;
&lt;p&gt;Second, it barely parallelizes: split the search across $P$ machines and each one&apos;s work drops by only $\sqrt{P}$, not $P$. Christof Zalka proved this is fundamental -- quantum searching &quot;cannot be parallelized better than by assigning different parts of the search space to independent quantum computers&quot; [@zalka-1999]. Throwing a thousand quantum computers at AES-128 buys a factor of about 31, not 1000.&lt;/p&gt;
&lt;p&gt;Third, and most concrete: real machines have a maximum circuit depth. NIST&apos;s post-quantum call formalized this as MAXDEPTH, with plausible values of ${2^{40}, 2^{64}, 2^{96}}$ serial logical gates -- roughly a year, a decade, and a millennium of continuous computation. Under that constraint, NIST estimated the cost of a Grover key search on AES-128 at about $2^{170}/\text{MAXDEPTH}$ quantum gates, versus $2^{143}$ classical gates -- because &quot;one has to run many smaller instances of the algorithm in parallel, which makes the quantum speedup less dramatic&quot; [@nist-cfp-2016].&lt;/p&gt;
&lt;p&gt;Even with MAXDEPTH at a decade ($2^{64}$), that is about $2^{106}$ gates. Depth-restricted analyses of explicit AES Grover oracles confirm the picture and underpin NIST&apos;s security categories [@jaques-2020]. The clean $2^{64}$ was always a lower bound on abstract queries, never a wall-clock estimate.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Symmetric cryptography survives not by being stronger than RSA but by being structureless: no hidden period, so no Shor, only a provably quadratic nibble -- and even that nibble is a floor on operations under a depth limit, not a runtime. AES-256 is not a nervous hope. It is a proof-backed hedge.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The comparison, side by side:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;Symmetric (AES-256, SHA-384)&lt;/th&gt;
&lt;th&gt;Asymmetric (RSA, DH, DSA, ECC)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Exploitable abelian period?&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best quantum attack&lt;/td&gt;
&lt;td&gt;Grover search&lt;/td&gt;
&lt;td&gt;Shor period-finding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speedup over classical&lt;/td&gt;
&lt;td&gt;Quadratic (square-root)&lt;/td&gt;
&lt;td&gt;Exponential&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Provably optimal attack?&lt;/td&gt;
&lt;td&gt;Yes -- $\Omega(\sqrt{N})$ [@bbbv-1997]&lt;/td&gt;
&lt;td&gt;Not applicable -- structure gives it away&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Effect of doubling the key&lt;/td&gt;
&lt;td&gt;Restores the full margin&lt;/td&gt;
&lt;td&gt;Negligible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Survives Q-Day?&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; For symmetric primitives the fix is boring and effective: prefer AES-256 over AES-128, and SHA-384 or SHA-512 over SHA-256. Because Grover is only quadratic -- and, under a depth limit, far weaker than even that -- doubling the security parameter is not just adequate, it is sufficient with margin to spare [@nist-cfp-2016]. No new mathematics, no migration project. The hard problem is entirely on the public-key side.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;One honest fence marks the edge of that &quot;only Grover&quot; claim.&lt;/p&gt;

There is a model in which symmetric constructions fall exponentially, not quadratically. In the superposition-query (Q2) model, where an attacker can query a secret-keyed device on a superposition of inputs, Kaplan and colleagues showed in 2016 that Simon&apos;s algorithm breaks specific *modes* -- Even-Mansour, CBC-MAC, GMAC -- in polynomial time [@kaplan-2016]. This is real and important, but note what it requires: physical access to a keyed oracle that will accept quantum superpositions as input, an implementation-and-protocol assumption, not a structural weakness of the AES primitive. This article&apos;s contract is structural-only, and under the realistic classical-query model the &quot;symmetric loses just a square root&quot; claim holds. The Q2 mode attacks belong to the sibling post on how cryptography breaks in real life, alongside side channels and fault attacks.
&lt;p&gt;So the break is real, the boundary is sharp, and the algorithm has been proven on paper for thirty years. Only one thing still stands between the mathematics and your ciphertext: a machine that does not yet exist. Building it is where the story turns from algorithms to engineering -- and where the price tag appears.&lt;/p&gt;
&lt;h2&gt;7. From Algorithm to Machine: Fault Tolerance and the Qubit Bill&lt;/h2&gt;
&lt;p&gt;A polynomial-time algorithm is not a polynomial-time afternoon. Shor&apos;s circuit is small on paper, but &quot;on paper&quot; assumes qubits that never make a mistake and never forget. Real qubits do both, constantly. Run a bare Shor circuit on today&apos;s noisy hardware and it dissolves into random noise long before the modular exponentiation finishes. Closing the gap between the proof and the machine is an engineering problem measured in millions of qubits, and it has a structure worth understanding, because that structure is where the cost estimates come from -- and where they are falling.&lt;/p&gt;
&lt;p&gt;Begin with the distinction the whole field turns on.&lt;/p&gt;

A physical qubit is one noisy device -- a superconducting transmon, a trapped ion, a neutral atom -- with an error rate around $10^{-3}$ per operation. A logical qubit is an error-corrected qubit assembled from many physical ones, whose effective error rate can be pushed arbitrarily low by adding more physical qubits, provided each is already below a threshold error rate. Shor&apos;s circuit counts logical qubits and logical gates; the machine must manufacture them out of vastly more physical hardware.
&lt;p&gt;The manufacturing method is quantum error correction, and the workhorse is the surface code.&lt;/p&gt;

The surface code lays physical qubits on a two-dimensional grid and repeatedly measures local parity checks that reveal where errors occurred without measuring -- and thus destroying -- the stored quantum information. Its defining property: the logical error rate falls exponentially as the code distance $d$ (roughly the grid width) grows, as long as physical errors stay below about $1\%$. It is the code behind every concrete Shor resource estimate [@google-willow-2025].
&lt;p&gt;Error correction handles the memory and the easy gates, but Shor also needs &quot;non-Clifford&quot; gates -- the T and Toffoli operations that do the genuinely quantum arithmetic -- and those cannot be done directly on surface-code qubits. They are supplied through a separate factory that distills noisy inputs into clean &quot;magic states.&quot;The modern version of that factory is magic-state cultivation, which reaches logical error rates as low as $2 \times 10^{-9}$ under $10^{-3}$ circuit noise and, in its authors&apos; words, hints that &quot;further magic state distillation may never be needed in practice&quot; -- shaving one of the largest overheads in the whole bill [@magic-state-cultivation-2024]. Stack it all together and you get the fault-tolerance pyramid every estimate rests on.&lt;/p&gt;

flowchart TD
    P[&quot;Thousands of noisy physical qubits, about 1 percent error each&quot;] --&amp;gt; S[&quot;Surface-code patch: parity checks suppress errors exponentially in code distance&quot;]
    S --&amp;gt; L[&quot;One reliable logical qubit&quot;]
    M[&quot;Magic-state cultivation: clean T and Toffoli states&quot;] --&amp;gt; G[&quot;Non-Clifford gates that Shor requires&quot;]
    L --&amp;gt; G
    G --&amp;gt; SHOR[&quot;Fault-tolerant Shor circuit: about 3n logical qubits, billions of gates&quot;]
&lt;p&gt;Now the part that reframes the entire threat. Line up the resource estimates chronologically and hold the hardware assumptions fixed, and you see the price of Q-Day &lt;em&gt;collapsing&lt;/em&gt; -- not because anyone built a better qubit, but because the algorithms kept improving.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Year&lt;/th&gt;
&lt;th&gt;Target&lt;/th&gt;
&lt;th&gt;Qubits&lt;/th&gt;
&lt;th&gt;Runtime&lt;/th&gt;
&lt;th&gt;What changed&lt;/th&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;2003&lt;/td&gt;
&lt;td&gt;160-bit ECC&lt;/td&gt;
&lt;td&gt;~1000 logical&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;First elliptic-curve estimate&lt;/td&gt;
&lt;td&gt;Proos-Zalka [@proos-zalka-2003]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2017&lt;/td&gt;
&lt;td&gt;P-256 ECC&lt;/td&gt;
&lt;td&gt;2330 logical&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Simulation-backed qubit formula&lt;/td&gt;
&lt;td&gt;Roetteler et al. [@roetteler-2017]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2020&lt;/td&gt;
&lt;td&gt;ECC curves&lt;/td&gt;
&lt;td&gt;fewer logical gates&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Optimized ECDLP circuits&lt;/td&gt;
&lt;td&gt;Haner et al. [@haner-2020]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2021&lt;/td&gt;
&lt;td&gt;RSA-2048&lt;/td&gt;
&lt;td&gt;20 million physical&lt;/td&gt;
&lt;td&gt;8 hours&lt;/td&gt;
&lt;td&gt;First full fault-tolerant bill&lt;/td&gt;
&lt;td&gt;Gidney-Ekera [@gidney-ekera-2021]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023&lt;/td&gt;
&lt;td&gt;RSA-2048&lt;/td&gt;
&lt;td&gt;asymptotic&lt;/td&gt;
&lt;td&gt;~$O(n^{3/2})$ gates&lt;/td&gt;
&lt;td&gt;First asymptotic gate win in ~30 years&lt;/td&gt;
&lt;td&gt;Regev [@regev-2023]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2025&lt;/td&gt;
&lt;td&gt;RSA-2048&lt;/td&gt;
&lt;td&gt;under 1 million physical&lt;/td&gt;
&lt;td&gt;under a week&lt;/td&gt;
&lt;td&gt;Better algorithms, same 2019 hardware&lt;/td&gt;
&lt;td&gt;Gidney [@gidney-2025]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Read the last three rows slowly. In 2021 Craig Gidney and Martin Ekera published the first end-to-end physical estimate: about 20 million noisy physical qubits, 8 hours, assuming a surface code with $10^{-3}$ gate error, a microsecond cycle time,A surface-code cycle is one full round of parity measurement across the patch; the estimate assumes roughly one microsecond per round, so an 8-hour run is on the order of tens of billions of rounds. and short-discrete-log refinements from Ekera and Hastad folded in [@gidney-ekera-2021][@ekera-hastad-2017].&lt;/p&gt;
&lt;p&gt;In 2023 Oded Regev found the first asymptotic reduction in Shor&apos;s gate count in three decades -- roughly $O(n^{3/2})$ gates -- though he flagged it as resting on a heuristic and not clearly practical, and its variant trades gate count for extra space whose real-world cost is still unsettled [@regev-2023]. Then in 2025 Gidney returned with a new estimate: fewer than one million physical qubits, under a week -- and, in a line worth pausing on, &lt;em&gt;the same 2019 hardware assumptions he used in the 20-million estimate&lt;/em&gt; [@gidney-2025].&lt;/p&gt;

Twenty million qubits to under one million in six years -- same author, same hardware assumptions, one-twentieth the machine. The mathematics improved, not the metal.
&lt;p&gt;That drop happened with no improvement in the underlying qubits at all: the estimate, not the machine, was the moving part, which means the cost of Q-Day keeps falling on the strength of pure algorithm design, independent of when good hardware arrives. That is the uncomfortable dynamic hiding behind every &quot;quantum is decades away&quot; headline: the target keeps moving toward us on the math axis while we wait for the hardware axis. The algorithm&apos;s price tag is collapsing on its own schedule. So the only question left is the one everyone actually asks -- how close is the machine itself?&lt;/p&gt;
&lt;h2&gt;8. Where the Hardware Actually Is (and Isn&apos;t)&lt;/h2&gt;
&lt;p&gt;State the honesty anchor flatly, because everything downstream depends on it: as of 2026, no cryptographically relevant quantum computer exists. Not &quot;almost,&quot; not &quot;in a classified lab somewhere.&quot; None. The public state of the art is three to four orders of magnitude short of a Shor attack, and it helps to see exactly how short, because the headlines and the reality use the same words to mean different things.&lt;/p&gt;

A CRQC is a quantum computer large and reliable enough to run Shor&apos;s algorithm against real deployed keys -- on the order of a few thousand logical qubits held coherent through billions of gates, which with today&apos;s overheads means roughly a million physical qubits. It is a specific threshold. A 100-qubit noisy processor, however valuable for physics, is not a small CRQC and cannot be scaled into one without error correction.
&lt;p&gt;The state of the art splits cleanly into two regimes, and conflating them is the source of most confusion. The first is &lt;em&gt;fully below-threshold error correction&lt;/em&gt; -- the hard, scalable kind, where adding qubits genuinely drives the error down.&lt;/p&gt;
&lt;p&gt;Google&apos;s Willow is the reference point: a distance-7 surface-code patch, a 7-by-7 array of 49 data qubits totaling 101 physical qubits, encoding exactly &lt;em&gt;one&lt;/em&gt; logical qubit. The logical error is suppressed by a factor $\Lambda = 2.14 \pm 0.02$ for each two-step increase in code distance, and its lifetime beats its best physical qubit by 2.4 times [@google-willow-2025].That $\Lambda$ greater than 1 is the whole result: it is the first convincing demonstration that a real surface code operates &lt;em&gt;below&lt;/em&gt; threshold, so that making the patch bigger makes the logical qubit better rather than worse. The number to remember is the ratio: about 100 physical qubits for one good logical qubit, today [@google-willow-2025]. So the scalable frontier stands at roughly one logical qubit built from about a hundred physical ones.&lt;/p&gt;
&lt;p&gt;The second regime is &lt;em&gt;error detection&lt;/em&gt; at low code distance, and it is where the &quot;tens of logical qubits&quot; headlines come from. A neutral-atom processor from a Harvard, MIT, and QuEra collaboration entangled up to 48 logical qubits using small &lt;code&gt;[[8,3,2]]&lt;/code&gt; code blocks (alongside 40 color-code qubits and a surface-code logical operation scaled across code distances) on up to 280 physical qubits [@bluvstein-2024]. That is a genuine milestone -- but these are transversal, post-selected error-&lt;em&gt;detection&lt;/em&gt; demonstrations, which throw away runs where an error is spotted, not a scalable below-threshold memory that can run for billions of gates.&lt;/p&gt;
&lt;p&gt;On the trapped-ion side, Quantinuum ran a handful of logical qubits with full &lt;em&gt;repeated&lt;/em&gt; error correction: a &lt;code&gt;[[7,1,3]]&lt;/code&gt; code and a &lt;code&gt;[[12,2,4]]&lt;/code&gt; code based on Knill&apos;s C4/C6 scheme (two logical qubits), the first reaching error rates 9.8 to 500 times below the physical rate and the second 4.7 to 800 times below it [@quantinuum-2024].&lt;/p&gt;
&lt;p&gt;Put the three numbers next to the requirement and the chasm is obvious. Fully below-threshold correction reaches about one logical qubit on superconducting hardware and a couple on trapped ions; error detection reaches a few tens on neutral atoms.&lt;/p&gt;
&lt;p&gt;A CRQC needs about 2330 logical qubits for the P-256 curve [@roetteler-2017], or roughly $3n$ -- at least 6200 -- for RSA-2048, backed by fewer than a million physical qubits [@gidney-2025]. Between &quot;48 post-selected logical qubits in a detection demo&quot; and &quot;a few thousand fully corrected logical qubits running Shor for hours&quot; lie three to four orders of magnitude and several unsolved engineering problems.&lt;/p&gt;
&lt;p&gt;When, then? The honest answer is a window, not a date. Expert judgment clusters the arrival of a CRQC in roughly the 2030 to 2035 range with wide uncertainty on both sides. The most-cited proxy, the Global Risk Institute and evolutionQ expert-survey timeline, reports figures on the order of 28 to 49 percent probability within ten years [@quantum-threat-timeline] -- but that number must be quoted with its qualifier: it is a &lt;em&gt;survey of expert opinion&lt;/em&gt;, not a measured or primary-verified quantity, and the defensible claim is the qualitative window, not any single percentage.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The absence of a machine today would be comforting if secrets expired the moment they were sent. They do not. An adversary can record your encrypted traffic now and store it until a CRQC arrives, then decrypt it retroactively. For any data whose confidentiality must outlive the 2030s, &quot;no quantum computer exists yet&quot; provides exactly zero protection. The clock started when the ciphertext was first captured, not when the machine boots.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The gun is loaded and sitting on the table. Its trigger is an engineering trajectory, not a delivered capability, and the timeline is a judgment rather than a promise -- but a judgment that says &quot;sometime in the next decade&quot; is not a judgment you can safely ignore for data that must stay secret into the 2040s. Before we talk about who has to move first, one question decides everything downstream: what, exactly, does this machine &lt;em&gt;not&lt;/em&gt; break?&lt;/p&gt;
&lt;h2&gt;9. What Q-Day Does Not Break&lt;/h2&gt;
&lt;p&gt;The blast radius is bounded, and the boundary is the thesis restated as a theorem: Shor breaks &lt;em&gt;exactly&lt;/em&gt; the abelian-hidden-subgroup primitives, and nothing else structurally. Everything on the safe side of that line survives Q-Day, and a whole field of cryptography was deliberately built there.&lt;/p&gt;
&lt;p&gt;Start the inventory. Symmetric ciphers and hashes survive with only Grover&apos;s quadratic nibble, as Section 6 proved. Hash-based signatures such as SLH-DSA rest on nothing but the preimage and collision resistance of a hash function, so they inherit that same square-root safety and no more [@fips-205]. And the new public-key families -- lattices, codes, isogenies, multivariate systems -- survive because not one of them is an abelian hidden-subgroup problem. The QFT has no period to read.&lt;/p&gt;
&lt;p&gt;The sharpest way to say why is to name the structure lattices actually touch.&lt;/p&gt;

The dihedral group is non-abelian: its elements do not all commute. The hidden subgroup problem over it is the natural non-abelian cousin of the one the QFT dispatches so easily -- but the Fourier machinery that concentrates amplitude so neatly in the abelian case does not do so here. Despite two decades of effort, the best known quantum algorithm is Kuperberg&apos;s, running in sub-exponential but still super-polynomial time $2^{O(\sqrt{\log N})}$ [@kuperberg-2003]. Certain lattice problems relate to it, which is one reason lattice cryptography is believed quantum-resistant.
&lt;p&gt;Notice the symmetry. The abstraction that &lt;em&gt;unifies&lt;/em&gt; the attack -- the abelian HSP -- is the very same abstraction that &lt;em&gt;bounds&lt;/em&gt; it. Cross from abelian to non-abelian structure and the QFT stops working, Shor&apos;s polynomial-time guarantee evaporates, and the best anyone has managed in twenty years is sub-exponential. That single conceptual line is the design premise of post-quantum cryptography.&lt;/p&gt;
&lt;p&gt;But here precision matters more than anywhere else in the article, because the most natural way to summarize this is &lt;em&gt;wrong&lt;/em&gt; and plants a misconception. It is tempting to write that the best quantum attack on lattice schemes is Kuperberg&apos;s sub-exponential algorithm. It is not, for three reasons worth stating explicitly.&lt;/p&gt;
&lt;p&gt;First, the attack that actually sets lattice key sizes is not a hidden-subgroup attack at all. It is lattice sieving -- quantum-accelerated BKZ -- and it is &lt;em&gt;exponential&lt;/em&gt;. Heuristic quantum sieving for the shortest-vector problem runs in about $2^{0.312n + o(n)}$, against the classical $2^{0.384n + o(n)}$ [@laarhoven-2013]. Quantum search shaves the constant in the exponent; it never reaches sub-exponential. Lattice parameters are chosen against that exponential wall.&lt;/p&gt;
&lt;p&gt;Second, the famous link between lattices and the dihedral HSP is a &lt;em&gt;one-directional reduction, not a usable attack&lt;/em&gt;. Regev showed in 2004 that a dihedral-HSP solver &lt;em&gt;by coset sampling&lt;/em&gt; would break the unique shortest-vector problem [@regev-2004] -- but there is no known way to prepare the required dihedral coset states from an actual lattice instance. The implication runs from &quot;hypothetical dihedral solver&quot; to &quot;broken lattice,&quot; not the other way, so you cannot feed a real lattice problem into Kuperberg&apos;s algorithm and get an attack out.&lt;/p&gt;
&lt;p&gt;Third, Kuperberg&apos;s sub-exponential algorithm genuinely is the best known attack -- but for a &lt;em&gt;different&lt;/em&gt; family. Commutative-isogeny schemes like CSIDH are built on an abelian group action, a hidden-shift problem, and there Kuperberg&apos;s algorithm really does set the parameters [@csidh-2018][@kuperberg-2003]. The &quot;Kuperberg&quot; label belongs on a CSIDH row, never on the lattice row. With that fixed, here is the honest ledger of what falls and what stands.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Primitive&lt;/th&gt;
&lt;th&gt;Underlying problem&lt;/th&gt;
&lt;th&gt;Abelian HSP?&lt;/th&gt;
&lt;th&gt;Best known quantum attack&lt;/th&gt;
&lt;th&gt;Verdict&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;RSA / DH / DSA / ECC&lt;/td&gt;
&lt;td&gt;Factoring, discrete log&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Shor -- polynomial&lt;/td&gt;
&lt;td&gt;Broken&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AES-256, SHA-384/512&lt;/td&gt;
&lt;td&gt;Unstructured key or preimage&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Grover -- quadratic (optimal)&lt;/td&gt;
&lt;td&gt;Safe: double the parameter [@bbbv-1997]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SLH-DSA (hash signatures)&lt;/td&gt;
&lt;td&gt;Hash preimage and collision&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Grover -- quadratic&lt;/td&gt;
&lt;td&gt;Safe [@fips-205]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ML-KEM / ML-DSA (lattice)&lt;/td&gt;
&lt;td&gt;Module-LWE&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Exponential lattice sieving $2^{\Theta(n)}$&lt;/td&gt;
&lt;td&gt;Believed safe [@laarhoven-2013]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CSIDH (commutative isogeny)&lt;/td&gt;
&lt;td&gt;Abelian group action, hidden shift&lt;/td&gt;
&lt;td&gt;Group action&lt;/td&gt;
&lt;td&gt;Kuperberg -- sub-exponential&lt;/td&gt;
&lt;td&gt;Sized against Kuperberg [@kuperberg-2003]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The line Shor cannot cross is the line between abelian and non-abelian structure -- and that single line is the entire design premise of post-quantum cryptography. Lattice schemes are not &quot;probably too hard to bother with&quot;; they sit provably on the far side of the abstraction that makes Shor work.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Two counterweights keep this from becoming triumphalism, and they cut in opposite directions.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Nobody has ever proven that factoring or the discrete logarithm is classically hard. Factoring&apos;s decision version sits in NP intersect co-NP and is not believed NP-complete, so Shor exploits &lt;em&gt;special structure&lt;/em&gt;, not raw NP-hardness. That means Shor is &lt;em&gt;the known&lt;/em&gt; structural break -- not a proof that no classical shortcut exists. The public-key world was never standing on proven ground; it was standing on ground nobody had found a way through yet.&lt;/p&gt;
&lt;/blockquote&gt;

In 2022 Wouter Castryck and Thomas Decru broke SIDH, a leading isogeny-based candidate, recovering the key of SIKEp434 in about ten minutes on a single classical core [@castryck-decru-2022]. No quantum computer was involved. Two lessons follow. First, do not conflate &quot;elliptic-curve&quot; with &quot;Shor target&quot;: SIDH is isogeny-based, a different hard problem, and it fell to classical mathematics, not to Q-Day. Second, the post-quantum assumptions are themselves young and unproven, and SIDH is proof that a scheme can be quantum-immune and still catastrophically broken. Note also that SIDH is not CSIDH: one collapsed classically, the other still stands, sized against Kuperberg.
&lt;p&gt;So Shor is a scalpel, not a bomb. It cuts exactly one structure -- the abelian hidden period -- and a whole field of cryptography was engineered to live on the parts it cannot reach. That field exists for exactly one reason, and with every piece now on the table, it is time to name it.&lt;/p&gt;
&lt;h2&gt;10. Why This One Event Is the Whole Reason PQC Exists&lt;/h2&gt;
&lt;p&gt;Assemble the pieces and one sentence follows that you now have every reason to accept. Because RSA, Diffie-Hellman, DSA, and elliptic-curve cryptography share exactly one crack -- the abelian period the QFT reads -- that crack is not four separate vulnerabilities. It is a &lt;em&gt;single point of failure&lt;/em&gt; for nearly the entire deployed public-key world. And a single point of failure of that magnitude does not get patched. It gets routed around, by building a replacement on the far side of the abelian line.&lt;/p&gt;

One shared crack under four fortresses is not four vulnerabilities. It is one -- a single point of failure for nearly all deployed public-key cryptography. Post-quantum cryptography is the world&apos;s response to that one fact.
&lt;p&gt;That response is already machinery, and every gear traces back to Shor. In 2016 NIST opened a public competition to standardize quantum-resistant algorithms [@nist-pqc-project]; on 13 August 2024 it published the first three standards -- FIPS 203 (ML-KEM) for key establishment, FIPS 204 (ML-DSA) for signatures, and FIPS 205 (SLH-DSA) for hash-based signatures [@fips-203][@fips-204][@fips-205].&lt;/p&gt;
&lt;p&gt;The NSA&apos;s CNSA 2.0 suite sets a national-security transition timeline and, tellingly, keeps AES-256 and &lt;a href=&quot;https://paragmali.com/blog/how-sha-2-and-sha-3-would-break-merkle-damgard-collisions-le/&quot; rel=&quot;noopener&quot;&gt;SHA-384/512&lt;/a&gt; on the symmetric side because those need no replacement [@nsa-cnsa-2.0]. And in 2026 the United States made it binding: Executive Order 14412 requires high-value systems to adopt post-quantum key establishment by 31 December 2030 and post-quantum signatures by 31 December 2031 [@eo-14412].&lt;/p&gt;
&lt;p&gt;There is a quiet revival buried in that timeline. The lattice hardness now anchoring ML-KEM and ML-DSA is not new: Miklos Ajtai put worst-case lattice hardness on a rigorous footing in 1996, and NTRU shipped a ring-based lattice cryptosystem in 1998 [@ajtai-1996][@ntru-1998]. Both sat in a niche for two decades. What changed their fortunes was not a new theorem -- it was Shor turning &quot;hardness the quantum Fourier transform cannot read&quot; into the single most valuable property a cryptosystem can have, and a generation of survey work mapping out the lattice, code, hash, and isogeny families that possess it [@bernstein-lange-2017].&lt;/p&gt;
&lt;p&gt;But standards and deadlines only matter if they beat the clock, and the clock is subtle, because it started ticking before the machine exists. Michele Mosca captured the logic in a single inequality.&lt;/p&gt;

Let $X$ be the years your organization needs to migrate to quantum-safe cryptography, $Y$ the years your data must stay confidential, and $Z$ the years until a CRQC exists. If $X + Y &amp;gt; Z$, then data you protect today will still be sensitive when the machine arrives -- so you are already exposed, no matter how far off Q-Day turns out to be [@mosca-2018].

flowchart LR
    X[&quot;X: years to migrate&quot;] --&amp;gt; SUM[&quot;X + Y&quot;]
    Y[&quot;Y: years data must stay secret&quot;] --&amp;gt; SUM
    Z[&quot;Z: years until a CRQC exists&quot;] --&amp;gt; CMP{&quot;X + Y greater than Z?&quot;}
    SUM --&amp;gt; CMP
    CMP --&amp;gt;|yes| EXP[&quot;Already exposed: harvested ciphertext will be readable&quot;]
    CMP --&amp;gt;|no| OK[&quot;Safe, for this data, for now&quot;]
&lt;p&gt;The inequality has teeth because of the harvesting strategy that makes $Z$ irrelevant for confidentiality.&lt;/p&gt;

Harvest-now-decrypt-later is the practice of recording encrypted traffic today and storing it until a quantum computer can decrypt it. It converts a future capability into a present threat: the confidentiality of a long-lived secret is compromised the moment its ciphertext is captured, not the moment Q-Day arrives.
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If an adversary is recording your encrypted traffic now -- and for high-value targets it is safe to assume someone is -- then every secret with a shelf life into the 2030s is effectively in the open already. You cannot un-send the ciphertext. This is the reason the migration cannot wait for proof that a CRQC exists: by the time the proof arrives, the harvested data is decades into its exposure. The empirical side of this -- who is harvesting, what is already at risk, and what the captured traffic looks like -- is the subject of the companion post, &quot;How Q-Day Is Already Breaking Things: Harvest Now, Decrypt Later.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is the hinge of the whole series, so state it without hedging. The post-quantum migration is not a bet on when quantum computers will arrive. It is a response to one already-proven mathematical fact -- that Shor&apos;s algorithm reads the shared abelian period under RSA, Diffie-Hellman, DSA, and ECC -- combined with one strategic fact, that adversaries can harvest today and decrypt later. Neither of those facts depends on a machine booting up. Which means the work starts now, not on Q-Day. So what, concretely, do you do before the machine that does not yet exist finally does?&lt;/p&gt;
&lt;h2&gt;11. What To Do Before Q-Day&lt;/h2&gt;
&lt;p&gt;You cannot buy a cryptographically relevant quantum computer, and you cannot wait for one to appear before acting -- harvest-now-decrypt-later has already seen to that. The good news is that the pre-Q-Day checklist follows directly from the thesis, and every item on it is doable today with shipping standards.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Inventory every use of RSA, DH, DSA, ECDH, and ECDSA.&lt;/strong&gt; Build a cryptographic bill of materials: where each algorithm lives, which keys protect what, and how long each secret must last. This is not busywork. Because all four primitives share one crack, &lt;em&gt;nothing&lt;/em&gt; on that list is safe by virtue of key size, curve choice, or obscurity -- the inventory is the map of your entire exposure.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Triage by secrecy lifetime.&lt;/strong&gt; Run Mosca&apos;s inequality on each data class. Anything whose confidentiality must outlive the CRQC window -- health records, state secrets, long-lived credentials, genomic data -- migrates first, because for that data $X + Y &amp;gt; Z$ already holds [@mosca-2018]. You can compute the gap directly.&lt;/p&gt;
&lt;p&gt;{`
// If migration time X + secrecy lifetime Y exceeds time-to-CRQC Z, you are exposed.
function mosca(X, Y, Z) {
  const exposed = (X + Y) &amp;gt; Z;
  const gap = (X + Y) - Z;   // positive gap = years of exposure
  return { exposed, gap };
}&lt;/p&gt;
&lt;p&gt;const cases = [
  { label: &quot;Long-lived health records&quot;, X: 5, Y: 25, Z: 12 },
  { label: &quot;Short-lived session key&quot;,   X: 2, Y: 1,  Z: 12 },
];
for (const c of cases) {
  const r = mosca(c.X, c.Y, c.Z);
  console.log(c.label + &quot;: X=&quot; + c.X + &quot; Y=&quot; + c.Y + &quot; Z=&quot; + c.Z + &quot; -&amp;gt; &quot; +
    (r.exposed ? &quot;EXPOSED by &quot; + r.gap + &quot; years&quot; : &quot;safe by &quot; + (-r.gap) + &quot; years&quot;));
}
// Long-lived health records: X=5 Y=25 Z=12 -&amp;gt; EXPOSED by 18 years
// Short-lived session key: X=2 Y=1 Z=12 -&amp;gt; safe by 9 years
`}&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Deploy hybrid key establishment now.&lt;/strong&gt; Combine a classical exchange with a lattice one -- for example the &lt;code&gt;X25519MLKEM768&lt;/code&gt; hybrid -- so that a future CRQC cannot decrypt today&apos;s captured sessions, while a flaw in the young post-quantum scheme still leaves the classical layer standing [@fips-203]. Hybrids are the pragmatic answer to &quot;the abelian period is readable&quot; and &quot;the new assumptions are unproven&quot; at the same time.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. Migrate signatures on their own timeline.&lt;/strong&gt; Move to ML-DSA or SLH-DSA, but recognize the urgency differs from confidentiality [@fips-204][@fips-205]. A forged signature requires a CRQC at signing time; there is nothing an adversary can harvest today and forge later. Confidentiality is the harvestable asset, so it leads.&lt;/p&gt;

Harvest-now-decrypt-later threatens *confidentiality*: recorded ciphertext sits waiting for the machine. Signatures are different -- forgery needs a CRQC while the signing key is still trusted, so there is no equivalent of a stored capture that becomes forgeable in hindsight. This is why key establishment carries the earlier deadline in Executive Order 14412 than signatures do. The exception is long-lived roots of trust -- certificate-authority roots, firmware-signing keys valid for a decade or more -- whose validity windows reach into the CRQC era and so deserve early attention.
&lt;p&gt;&lt;strong&gt;5. Take the cheap symmetric hedge.&lt;/strong&gt; Prefer AES-256 over AES-128 and SHA-384 or SHA-512 over SHA-256. As Section 6 established, Grover is only quadratic -- and under a realistic depth limit, far weaker than even that -- so doubling the security parameter is sufficient, not merely hopeful [@bbbv-1997]. This is the one part of the migration that costs almost nothing.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;6. Build crypto-agility.&lt;/strong&gt; Design so the algorithm can be swapped without re-architecting the protocol, so the next transition is a configuration change rather than another decade-long project.&lt;/p&gt;

Crypto-agility is building systems so a cryptographic algorithm can be replaced without redesigning the protocol or application around it. It turns a future migration from a rebuild into a swap.
&lt;p&gt;Crypto-agility is doubly warranted here, because the destination assumptions are young. SIDH&apos;s classical collapse in 2022 is the standing reminder that a scheme can look quantum-safe and still fail for reasons no one anticipated [@castryck-decru-2022]. Agility is how you survive being wrong about the replacement.&lt;/p&gt;
&lt;p&gt;For the details of &lt;em&gt;what&lt;/em&gt; to migrate to -- parameter sets, performance trade-offs, and deployment patterns -- this series&apos; &lt;a href=&quot;https://paragmali.com/blog/one-event-three-assumptions-five-answers-a-field-guide-to-th/&quot; rel=&quot;noopener&quot;&gt;post-quantum-toolkit&lt;/a&gt; and &lt;a href=&quot;https://paragmali.com/blog/you-cannot-rotate-what-you-cannot-see-crypto-agility-and-the/&quot; rel=&quot;noopener&quot;&gt;crypto-agility&lt;/a&gt; installments carry the load, and the implementation-hardening questions (side channels, fault attacks, and the rest) belong to the empirical sibling, per this article&apos;s structural-only contract. None of it waits for the machine. That is the whole point -- and it is why the last few questions people always ask deserve straight, mechanism-grounded answers.&lt;/p&gt;
&lt;h2&gt;12. Sharp Questions, Straight Answers&lt;/h2&gt;


No. The threat to confidentiality is already live through harvest-now-decrypt-later: an adversary records your encrypted traffic today and decrypts it once a CRQC exists [@mosca-2018]. If your data must stay secret into the 2030s, the absence of a machine in 2026 protects nothing -- the ciphertext is already captured, and you cannot un-send it.


No. Symmetric primitives expose no abelian period, so Shor does not apply; they face only Grover&apos;s quadratic speedup, which is provably the best any quantum attacker can do against unstructured search [@bbbv-1997]. And even that is a floor on operations, not a runtime: under NIST&apos;s MAXDEPTH depth limit, an AES-128 key search costs about $2^{170}/\text{MAXDEPTH}$ quantum gates [@nist-cfp-2016]. Prefer AES-256 and SHA-384/512 and the problem is closed.


No, and this is the counterintuitive part. Shor&apos;s cost is polynomial in the number of key bits, so going from RSA-2048 to RSA-4096 buys a small constant, not security [@shor-1994]. Worse for the intuition: elliptic curves use *smaller* keys, so they need *fewer* logical qubits and fall first -- about 2330 logical qubits for P-256 versus roughly 6200 for RSA-2048 [@roetteler-2017][@gidney-ekera-2021].


Same machine class and same breakthrough, not one identical circuit. RSA, a finite field, and an elliptic curve need different arithmetic compiled into the machine, but each reduces to the abelian hidden-subgroup problem, so one CRQC running Shor&apos;s family dispatches all of them [@kitaev-1995]. If anything, elliptic-curve schemes fall a step ahead because they need the fewest qubits [@roetteler-2017].


No -- and this conflation is a common trap. The broken isogeny scheme SIDH was not defeated by Shor at all; Castryck and Decru broke it with classical mathematics in about ten minutes on one core [@castryck-decru-2022]. &quot;Elliptic-curve&quot; is not the same as &quot;Shor target.&quot; Isogeny problems are a different structure, and their risks (as SIDH showed) can be entirely classical.


The migration is not a bet on hardware timing. Mosca&apos;s inequality shows that if migration time plus secrecy lifetime exceeds time-to-CRQC, you are already exposed [@mosca-2018]. Meanwhile the cost estimates keep falling on algorithmic progress alone -- 20 million qubits to under a million in six years, same hardware assumptions [@gidney-ekera-2021][@gidney-2025] -- and the underlying algorithm has been proven for three decades. The proof is not in doubt; only the schedule is.

&lt;p&gt;Step back to the single image the whole article was built to earn. Four cryptographers, four decades, four branches of mathematics -- and one hidden period beneath all of them. RSA, Diffie-Hellman, DSA, and elliptic curves were never four independent bets. They were one bet, that a hidden abelian period is hard to find, made four times in four disguises.&lt;/p&gt;
&lt;p&gt;Shor&apos;s algorithm reads that period with the quantum Fourier transform and collects on all four at once, while AES-256 in the next field survives for the mirror-image reason: it hides no period, so the same machine can do no better than a provably quadratic nibble. That asymmetry -- abelian falls, non-abelian stands -- is not a footnote. It is the exact line post-quantum cryptography was engineered to live behind.&lt;/p&gt;
&lt;p&gt;The shared quantum vulnerability of RSA, Diffie-Hellman, DSA, and elliptic curves is a single point of failure, and that single point is the whole reason post-quantum cryptography exists. The algorithm is proven; the machine is not here yet; and the distance between those two facts is not your safety margin -- it is your deadline.&lt;/p&gt;
&lt;p&gt;The gun is loaded and on the table. No one has fired it, and no one can say precisely when someone will. But the mathematics that makes it fire was settled in 1994, the price of ammunition is falling every year, and some of the secrets it will read are being recorded right now. That is why the work does not start on Q-Day. It starts today.&lt;/p&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;how-q-day-breaks-everything&quot; keyTerms={[
  { term: &quot;Q-Day&quot;, definition: &quot;The day a cryptographically relevant quantum computer first runs Shor&apos;s algorithm against deployed keys, breaking RSA, Diffie-Hellman, DSA, and elliptic-curve cryptography.&quot; },
  { term: &quot;Discrete Logarithm Problem&quot;, definition: &quot;Recovering the exponent x from g and h = g^x in a finite group; the assumption under Diffie-Hellman, DSA, and ECC.&quot; },
  { term: &quot;Superposition&quot;, definition: &quot;A quantum register occupying a weighted combination of all basis states at once; measuring returns just one outcome at random.&quot; },
  { term: &quot;Quantum Fourier Transform&quot;, definition: &quot;The instrument that concentrates a quantum state&apos;s amplitude onto the frequency of a hidden period, so measurement reveals the period.&quot; },
  { term: &quot;Order of a mod N&quot;, definition: &quot;The smallest positive r with a to the r congruent to 1 mod N; the period of a to the x mod N and the key to factoring.&quot; },
  { term: &quot;Abelian Hidden Subgroup Problem&quot;, definition: &quot;Finding a hidden subgroup of a finite abelian group from a function constant on its cosets; solved by the QFT in polynomial time and shared by factoring and both discrete logs.&quot; },
  { term: &quot;Grover&apos;s algorithm&quot;, definition: &quot;A generic unstructured search in about the square root of the space; a quadratic, provably optimal, non-structural speedup.&quot; },
  { term: &quot;Logical vs physical qubit&quot;, definition: &quot;A logical qubit is an error-corrected qubit built from many noisy physical qubits; Shor&apos;s circuit counts logical qubits and gates.&quot; },
  { term: &quot;Surface code&quot;, definition: &quot;A two-dimensional error-correcting code whose logical error falls exponentially with code distance when physical errors stay below about one percent.&quot; },
  { term: &quot;CRQC&quot;, definition: &quot;A cryptographically relevant quantum computer: enough logical qubits held coherent through billions of gates to run Shor against real keys, roughly a million physical qubits today.&quot; },
  { term: &quot;Dihedral (non-abelian) HSP&quot;, definition: &quot;The non-abelian hidden-subgroup problem lattice problems relate to; the best known quantum algorithm is only sub-exponential, which is why lattice cryptography resists Shor.&quot; },
  { term: &quot;Mosca&apos;s inequality&quot;, definition: &quot;If migration time plus data secrecy lifetime exceeds time-to-CRQC, your data is already exposed to harvest-now-decrypt-later.&quot; }
]} questions={[
  { q: &quot;Why does enlarging an RSA or ECC key fail to defend against Shor?&quot;, a: &quot;Shor&apos;s cost is polynomial in the number of key bits, so more bits add only a small constant; ECC&apos;s smaller keys even make it fall first.&quot; },
  { q: &quot;Why does AES-256 survive Q-Day when RSA does not?&quot;, a: &quot;AES hides no abelian period for the QFT to read, so it faces only Grover&apos;s quadratic speedup, which the BBBV bound proves is optimal; doubling the key restores the margin.&quot; },
  { q: &quot;In what sense are RSA, DH, DSA, and ECC the same problem?&quot;, a: &quot;All three underlying problems are instances of the abelian hidden-subgroup problem, which the quantum Fourier transform solves in polynomial time.&quot; },
  { q: &quot;Why is the best quantum attack on ML-KEM exponential rather than Kuperberg&apos;s sub-exponential algorithm?&quot;, a: &quot;Lattice parameters are set by exponential sieving; the lattice-to-dihedral-HSP link is a one-directional reduction, and Kuperberg&apos;s algorithm actually applies to commutative-isogeny schemes like CSIDH.&quot; },
  { q: &quot;Why must migration start before a quantum computer exists?&quot;, a: &quot;Harvest-now-decrypt-later means data captured today can be decrypted after Q-Day, so Mosca&apos;s inequality can already be violated for long-lived secrets.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>quantum-computing</category><category>shors-algorithm</category><category>post-quantum-cryptography</category><category>cryptanalysis</category><category>rsa</category><category>elliptic-curve-cryptography</category><category>diffie-hellman</category><category>hidden-subgroup-problem</category><author>noreply@paragmali.com (Parag Mali)</author></item><item><title>How RSA Breaks in Real Life: ROCA, Bleichenbacher&apos;s Ghosts, FREAK, and the Keys That Shared a Prime</title><link>https://paragmali.com/blog/how-rsa-breaks-in-real-life-roca-bleichenbachers-ghosts-frea/</link><guid isPermaLink="true">https://paragmali.com/blog/how-rsa-breaks-in-real-life-roca-bleichenbachers-ghosts-frea/</guid><description>No one has ever factored a strong, deployed RSA key -- yet ROCA, Bleichenbacher&apos;s oracle, DROWN, and FREAK broke real RSA anyway. The break was never the factoring.</description><pubDate>Fri, 17 Jul 2026 00:00:00 GMT</pubDate><content:encoded>
**No one has ever factored a strong, correctly generated RSA key in the wild.** The public ceiling is RSA-250, an 829-bit *challenge* number that took about 2,700 core-years in 2020 [@rsa250-2020]. And yet real RSA keys, sessions, and signatures fell anyway, at three layers the RSA math depends on but does not control. **Key generation:** the 2008 Debian OpenSSL bug collapsed the keyspace to roughly 32,767 seeds [@cve-2008-0166]; low-entropy devices *shared primes* recoverable with a single `gcd` in 2012 [@factorable-2012]; Infineon&apos;s ROCA library built *structured* primes a Coppersmith lattice factors, forging Estonian eID cards and YubiKey 4 in 2017 [@roca-crocs]. **Padding:** Bleichenbacher&apos;s 1998 oracle decrypts a session from about a million padding-validity answers, recovering no key and factoring nothing [@bleichenbacher-1998], revived by DROWN across roughly a third of HTTPS via SSLv2 in 2016 [@drown-2016] and by ROBOT on Facebook and PayPal in 2017 [@robotattack]. **Negotiation:** FREAK forced a 512-bit export key and factored it for about \$100 in 2015 [@freakattack]. Seven deployed breaks, one pattern. Where three of them ended in a factorization, it was only because the deployment had already produced a *weak* modulus -- the math merely finished the job. Every fix changed how RSA is generated, used, or negotiated -- validated entropy, OAEP and PSS, TLS 1.3 dropping RSA key transport [@rfc8446] -- never RSA itself.
&lt;h2&gt;1. No One Has Ever Factored a Strong RSA Key. Your RSA Keys Broke Anyway.&lt;/h2&gt;
&lt;p&gt;The largest RSA key ever factored in public is a 250-digit, 829-bit challenge number, and cracking it in 2020 took the world&apos;s best number theorists about 2,700 core-years [@rsa250-2020]. No strong, correctly generated RSA key protecting real traffic has ever been factored at all. Hold that fact still for a moment, because the next one refuses to sit beside it.&lt;/p&gt;
&lt;p&gt;In the same era, Estonian national ID cards were forgeable [@roca-crocs], roughly a third of all HTTPS was decryptable [@drown-2016], hundreds of thousands of embedded private keys were recoverable [@factorable-2012], and export-grade sessions were silently man-in-the-middled [@freakattack]. Every one of those was an RSA break. Not one of them was a factored strong modulus. So how does a factoring problem nobody can beat on a strong key keep producing forged signatures, decrypted sessions, and stolen private keys?&lt;/p&gt;
&lt;p&gt;The resolution is the whole argument of this article, and it belongs before the evidence: none of these broke strong RSA. RSA is a trapdoor permutation, and its single security promise is narrow -- that factoring a strong $n = p \cdot q$ is hard [@rsa-1978]. That promise silently depends on three things the mathematics does not control: where the primes came from, how the decrypting party validates padding, and which key strength a protocol will accept. It was those three deployment-owned layers, never the factoring problem, that gave way.&lt;/p&gt;
&lt;p&gt;So carry one diagnostic question through everything that follows. When an RSA key, session, or signature falls, do not ask &quot;did someone factor the modulus?&quot; Ask instead: which layer the math depends on but does not control gave way -- the primes, the padding, or the negotiation? Every break in this article is a non-empty answer to that question, and you will learn to drop ROCA, DROWN, FREAK, and tomorrow&apos;s incident into it on sight.&lt;/p&gt;

To break RSA in the field, you never factor a strong modulus. You take the weak one the deployment already handed you, or the oracle it left open -- and the factoring problem on a strong key stands untouched.
&lt;p&gt;The paradox even has a face. The researcher Nadia Heninger appears at both poles of this story: she recovered weak keys in the field, and she co-holds the public record for factoring a strong one [@factorable-2012, @rsa250-2020]. One person, both ends of the argument -- the weak keys that fall in an afternoon and the strong one that costs millennia of compute.&lt;/p&gt;
&lt;p&gt;This is Part 3 of &lt;em&gt;How It Breaks in Real Life&lt;/em&gt;, a series with one recurring thesis: the primitive&apos;s mathematics almost never caused the break; the deployment did. RSA is one of its cleanest cases. It has a companion piece, &lt;em&gt;How RSA Would Break: Why Factoring Is the Slow Path and Coppersmith Is the Fast One&lt;/em&gt;, which handles the would-break-in-theory math: the Number Field Sieve, Coppersmith&apos;s lattices, and Shor&apos;s algorithm. This article is the did-break-in-the-field frame.&lt;/p&gt;
&lt;p&gt;If no strong modulus was ever factored and the factoring problem never moved, then everything that broke was built around it. To see how &quot;unfactored modulus&quot; and &quot;recovered key&quot; can both be true at once, we have to go back to what RSA actually promises -- and, more importantly, what it silently assumes.&lt;/p&gt;
&lt;h2&gt;2. What RSA Actually Assumes&lt;/h2&gt;
&lt;p&gt;In 1977, Ron Rivest, Adi Shamir, and Leonard Adleman handed the world its first practical public-key cryptosystem: a public modulus $n = p \cdot q$, a public exponent $e$, a private exponent $d$, and a security argument resting on the hardness of factoring $n$ [@rsa-1978]. That assumption is exactly why the core problem has held for five decades. It is also exactly why, when RSA breaks in the field, the fault lies somewhere else. Being a trapdoor permutation made RSA a primitive. It did not make it a safe deployment.&lt;/p&gt;
&lt;p&gt;Start with the single most important distinction in this article. RSA-the-primitive is a keyed permutation over the integers modulo $n$, and its security promise is narrow and conditional. Here is the precise version, because the imprecise version is the source of half the confusion in the subject.&lt;/p&gt;

RSA fixes a modulus $n = p \cdot q$, a public exponent $e$, and a private exponent $d$; encryption is $c = m^e \bmod n$ and decryption is $m = c^d \bmod n$. Its security rests on the assumption that inverting the permutation without $d$ is hard. Factoring $n$ is *sufficient* to invert it -- recover $\phi(n)$, then $d$ -- and remains the best known attack, so breaking RSA is *at most* as hard as factoring. Whether it is *as hard as* factoring, the RSA-problem-versus-factoring equivalence, is an open question [@boneh-1999, @rsa-1978]. The math controls only that hardness, never where $p$ and $q$ come from.
&lt;p&gt;Read that twice, because the direction matters. Factoring is &lt;em&gt;sufficient&lt;/em&gt; to break RSA: if you can factor $n$, you win. But nobody has proved the reverse, that breaking RSA requires factoring. The RSA problem might, in principle, be easier than factoring; we do not know. What we do know is that the best attack anyone has found on the primitive is still factoring, and factoring a strong modulus is where the wall stands.&lt;/p&gt;
&lt;p&gt;Notice the quiet consequence: the field never even needed that unproven shortcut. Every deployed break in this article bypassed both directions entirely. No one factored a strong key, and no one found a clever inversion either. They walked around the math.&lt;/p&gt;
&lt;p&gt;Because the guarantee is only about the &lt;em&gt;difficulty of factoring&lt;/em&gt;, it says nothing about three other things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Where $p$ and $q$ come from.&lt;/strong&gt; They must be large, independent, and drawn from &lt;a href=&quot;https://paragmali.com/blog/predictable-or-repeated-the-only-two-ways-cryptographic-rand/&quot; rel=&quot;noopener&quot;&gt;real entropy&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How the raw permutation is wrapped.&lt;/strong&gt; Textbook RSA is deterministic and malleable, so it must be padded before it is used.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Which key strength a protocol will accept.&lt;/strong&gt; A 512-bit option nobody wants is still a 512-bit option somebody can force.&lt;/li&gt;
&lt;/ol&gt;

Unpadded RSA is deterministic: equal plaintexts always produce equal ciphertexts, so an eavesdropper can recognize repeats and test guesses. It is also *malleable*, because $(m_1^e)(m_2^e) \equiv (m_1 m_2)^e \pmod{n}$: an attacker who multiplies a ciphertext by $s^e$ turns it into an encryption of $m \cdot s$ without knowing $m$. Both properties make raw RSA unusable on its own; it must be wrapped in a padding scheme. That same malleability is the lever every padding-oracle attack pulls.
&lt;p&gt;Those three silences are the structure of the whole article. Picture them as a map: the factoring-hardness assumption sits at the center, and three deployment-owned dependencies surround it. Each is an independent surface an attacker can reach without ever touching the factoring problem.&lt;/p&gt;

flowchart TD
    A[&quot;The one RSA guarantee: factoring a strong modulus is hard&quot;]
    A --&amp;gt; B[&quot;Layer 1: Key generation, where the primes come from&quot;]
    A --&amp;gt; C[&quot;Layer 2: Padding validation, how decryption is checked&quot;]
    A --&amp;gt; D[&quot;Layer 3: Negotiation, which key strength is accepted&quot;]
    B --&amp;gt; E[&quot;Each layer is an independent failure surface reached without factoring&quot;]
    C --&amp;gt; E
    D --&amp;gt; E
&lt;p&gt;Before we watch each dependency fail, three guardrails, because the argument is easy to overstate in exactly three ways.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The whole argument turns on one distinction. Three incidents ahead -- FREAK, ROCA, and shared primes -- &lt;em&gt;do&lt;/em&gt; end in a factorization. That is not a counterexample to the thesis; it is the thesis. In each case the deployment first produced a &lt;em&gt;weak&lt;/em&gt; modulus (a downgrade forced 512 bits, a library constrained the primes, bad entropy made two keys collide), and the math only finished a job the deployment had already set up. The precise, load-bearing claim, kept word-for-word throughout: no strong, correctly generated, deployed modulus has ever been factored in the field. The public ceiling is RSA-250, an 829-bit challenge number [@rsa250-2020].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The series this article belongs to lists a familiar set of culprits: the RNG, the nonce, the padding, the downgrade. RSA answers to most of them, but not the nonce.RSA signing has no secret per-signature nonce whose reuse leaks the key. &lt;a href=&quot;https://paragmali.com/blog/one-number-used-twice-how-a-repeated-nonce-hands-over-your-p/&quot; rel=&quot;noopener&quot;&gt;The nonce-reuse break&lt;/a&gt; -- the reused $k$ behind the 2010 PlayStation 3 and 2013 Android SecureRandom key recoveries [@ps3-epic-fail-2010, @android-securerandom-2013, @bitcoin-android-alert-2013] -- is an (EC)DSA phenomenon, a different primitive. There is no &quot;RSA nonce-reuse break&quot;; when you see one described, it is really an ECDSA story, and it is told in its own article. Two of the three real culprits are RSA&apos;s, and both are downstream of the map above.&lt;/p&gt;

The series says the primitive&apos;s math *almost* never causes the break, and that hedge is load-bearing. Factoring is genuinely real, just slow. It fell RSA-155 (512-bit) in 1999, RSA-768 in 2009, and RSA-250 in 2020 [@rsa155-2000, @rsa768-epfl, @rsa250-2020], every one a public *challenge* number, never a deployed key. And Shor&apos;s algorithm will fall RSA outright on a large quantum computer. None of that is a deployed strong key, and all of it belongs to the companion article, *How RSA Would Break*. State the hedge, and never inflate it into a claim that the mathematics is somehow unbreakable.
&lt;p&gt;One narrow assumption, three silent dependencies, none of them the factoring problem. Before we watch each dependency break in the field, we need to see the contracts up close: what real entropy actually buys, why a padding check is a loaded gun, and why a 512-bit option nobody uses is still a live weapon.&lt;/p&gt;
&lt;h2&gt;3. Three Contracts the Math Cannot Enforce&lt;/h2&gt;
&lt;p&gt;Every field break in this article is the violation of one specific promise -- a promise the RSA math assumes but has no way to enforce. There are exactly three, one per layer of the map, and once you can see the contract, the break becomes obvious. Here they are, side by side.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;The contract it imposes&lt;/th&gt;
&lt;th&gt;Cost of violating it&lt;/th&gt;
&lt;th&gt;Who owns it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Key generation&lt;/td&gt;
&lt;td&gt;Primes are unpredictable and never shared&lt;/td&gt;
&lt;td&gt;Keys become enumerable, colliding, or structurally factorable&lt;/td&gt;
&lt;td&gt;The RNG, the key-generation library, the boot-time entropy source&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Padding validation&lt;/td&gt;
&lt;td&gt;Never reveal whether a decryption was well-padded&lt;/td&gt;
&lt;td&gt;The server becomes a decryption or signing oracle&lt;/td&gt;
&lt;td&gt;The TLS and PKCS#1 implementation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Negotiation&lt;/td&gt;
&lt;td&gt;Never accept a crippled key or a dead protocol&lt;/td&gt;
&lt;td&gt;A strong peer is forced down to a breakable one&lt;/td&gt;
&lt;td&gt;The protocol state machine and its configuration&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;The key-generation contract: the primes must be unpredictable and never shared.&lt;/strong&gt; Two &quot;random&quot; primes are only as unpredictable as the generator that produced them. Starve that generator of entropy, cripple it with a bug, or bias its structure, and the primes come out predictable, colliding, or specially formed -- while every later step still looks textbook-correct.&lt;/p&gt;

A cryptographically secure pseudorandom number generator (CSPRNG) stretches a small secret seed into an unbounded stream of unpredictable bits, and its output is only as unpredictable as that seed. If the seed is starved of real entropy at boot, crippled by a bug that removes entropy, or drawn from a generator that constrains its outputs, the primes it produces become predictable, colliding, or specially formed, even though the arithmetic around them is flawless.

If two moduli $n_1$ and $n_2$ accidentally share one prime, then $\gcd(n_1, n_2) = p$ recovers that prime with a single Euclidean gcd, and one division gives the other factor of each. A batch-GCD computes every pairwise gcd across millions of keys at once with a product-and-remainder tree, in quasi-linear time. It is simultaneously an attack (recover private keys at Internet scale) and a defense (scan your own fleet for collisions).
&lt;p&gt;The hidden assumption behind this contract is quiet but total: enough real entropy reached key generation, and no two keys ever drew the same prime.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The padding contract: never reveal whether padding was valid.&lt;/strong&gt; Textbook RSA is deterministic and malleable, so a real system must wrap the message before exponentiating. For twenty-five years the near-universal wrapper has been PKCS#1 v1.5.&lt;/p&gt;

Before exponentiation the message is wrapped as `00 02 [at least 8 random non-zero bytes] 00 [message]` [@rfc2313]. The leading `00 02` marks an encryption block, the random bytes make equal plaintexts encrypt differently, and the `00` separator marks where the message begins. The attack in this article is on this v1.5 *encryption* format, whose validity check becomes the oracle. PKCS#1 v1.5 *signatures* are a separate construction and are not what these attacks break.
&lt;p&gt;Here is the conceptual pivot the whole subject turns on. In 1998, Daniel Bleichenbacher noticed that the padding &lt;em&gt;check itself&lt;/em&gt; is a leak [@bleichenbacher-1998]. A server that decrypts a ciphertext and then reveals -- by error, timeout, or timing -- whether the result began with the required &lt;code&gt;00 02&lt;/code&gt; bytes has answered a yes/no question about the plaintext. One bit does not sound like much. But raw RSA is malleable, so the attacker can ask the question about a plaintext of their choosing.&lt;/p&gt;

A decrypting party that reveals -- by error message, connection reset, timeout, or response timing -- whether a submitted ciphertext decrypted to validly padded plaintext leaks one bit per query. Feed it enough adaptively chosen ciphertexts and those one-bit answers pin the plaintext down, without ever recovering the private key. This is the single most load-bearing idea in the article.
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Because raw RSA is malleable, an attacker can multiply a ciphertext $c$ by $s^e$ to form $c&apos; = c \cdot s^e \bmod n$, which decrypts to $m \cdot s \bmod n$. A server that reveals whether each such $c&apos;$ was validly padded answers one yes/no question per query about where $m$ lies. About $10^6$ adaptive queries narrow $m$ to a single value: a session decrypted, with no private key recovered and nothing factored. This one mechanic drives Bleichenbacher, DROWN, and ROBOT.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You can feel the mechanic in miniature. The toy below uses an idealized one-bit oracle -- it reports only whether the decryption falls in the bottom half of the range -- and binary-searches the plaintext out of the server without ever touching the key.The oracle recovers no private key and factors nothing; it turns the server into a one-session decryption (or one-message signing) oracle, and the modulus is untouched afterward. Keep two things distinct: the attack is on PKCS#1 v1.5 &lt;em&gt;encryption&lt;/em&gt;, and v1.5 &lt;em&gt;signatures&lt;/em&gt; are a separate scheme it does not break.&lt;/p&gt;
&lt;p&gt;{`
function modpow(b, e, n){ b %= n; let r = 1n; while (e &amp;gt; 0n){ if (e &amp;amp; 1n) r = (r&lt;em&gt;b)%n; b = (b&lt;/em&gt;b)%n; e &amp;gt;&amp;gt;= 1n; } return r; }
const p = 61n, q = 53n, n = p*q;          // toy modulus n = 3233
const e = 17n, d = 2753n;                 // public e, private d
const m = 65n;                            // the secret plaintext
const c = modpow(m, e, n);                // the ciphertext the attacker holds&lt;/p&gt;
&lt;p&gt;// The ONLY leak: does the decryption land in the bottom half of [0, n)?
// An idealized magnitude / MSB oracle -- one bit per query.
const oracle = (ct) =&amp;gt; modpow(ct, d, n) &amp;lt; n / 2n;&lt;/p&gt;
&lt;p&gt;const enc2 = modpow(2n, e, n);            // multiplier that doubles the plaintext (malleability)
const K = 14n, SCALE = 1n &amp;lt;&amp;lt; K;
let loS = 0n, hiS = n * SCALE, ct = c;
for (let i = 0n; i &amp;lt; K; i++){
  const mid = (loS + hiS) / 2n;
  if (oracle(ct)) hiS = mid; else loS = mid;   // read one bit, halve the interval
  ct = (ct * enc2) % n;                          // next query sees 2&lt;em&gt;m, 4&lt;/em&gt;m, ... mod n
}
console.log(&apos;recovered plaintext -&amp;gt;&apos;, (hiS / SCALE).toString());   // -&amp;gt; 65&lt;/p&gt;
&lt;p&gt;// The real PKCS#1 v1.5 oracle asks a different one-bit question: do the top bytes
// equal 00 02? That narrows m onto a union of intervals 2B &amp;lt;= m &amp;lt; 3B rather than a
// &amp;lt; n/2 half -- same principle, different bit. This &amp;lt; n/2 magnitude test is the same
// family of magnitude / most-significant-byte leak Manger&apos;s 2001 attack exploits
// against OAEP -- but his oracle tests x &amp;lt; B = 2^(8(k-1)) (whether the leading octet
// is zero), not x &amp;lt; n/2.
`}&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The negotiation contract: never accept a deliberately crippled key or a dead protocol.&lt;/strong&gt; The math cannot see which key strength a handshake settled on, nor whether the protocol carrying it was retired a decade ago.&lt;/p&gt;

1990s US export regulations capped exportable cryptography at deliberately weak strengths, including 512-bit `RSA_EXPORT` key exchange, and SSLv2 was the era&apos;s now-obsolete protocol [@freakattack, @freak-sp2015]. Both were retired in principle long ago, yet both survived in shipping code and server configurations long enough to become live attack surfaces.
&lt;p&gt;The assumption here is that only a party that &lt;em&gt;wants&lt;/em&gt; export-grade crypto, or &lt;em&gt;wants&lt;/em&gt; SSLv2, will ever get it.&lt;/p&gt;
&lt;p&gt;Three contracts, each reasonable, each unenforced by the math. The factoring problem cannot tell whether you fed it a shared prime, a leaky padding check, or a forced 512-bit key. Which raises the only question that matters: on real smartcards and real servers, do these contracts actually hold? They do not. Here is where, when, and how each one broke.&lt;/p&gt;
&lt;h2&gt;4. Three Deployment Failures, Three Layers, One Pattern&lt;/h2&gt;
&lt;p&gt;The comfortable belief is &quot;we use RSA-2048, so our keys, sessions, and signatures are safe.&quot; What follows are seven independent refutations of that inference: seven deployed field breaks, grouped into three pillars, one per layer the math depends on but does not control. Each pillar runs in chronological order, but read it as a failure catalog, not a lineage of improving designs. They are three simultaneous layers every real deployment must secure at once, and the chronology is simply the attacker&apos;s frontier moving from one unmet obligation to the next as each was patched.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Incident&lt;/th&gt;
&lt;th&gt;Year&lt;/th&gt;
&lt;th&gt;Pillar&lt;/th&gt;
&lt;th&gt;Mechanism&lt;/th&gt;
&lt;th&gt;Modulus&lt;/th&gt;
&lt;th&gt;Recovers key?&lt;/th&gt;
&lt;th&gt;Factors it?&lt;/th&gt;
&lt;th&gt;The fix (changed the deployment)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Debian OpenSSL RNG&lt;/td&gt;
&lt;td&gt;2008&lt;/td&gt;
&lt;td&gt;Key generation&lt;/td&gt;
&lt;td&gt;Seed collapsed to the process ID; keys enumerable&lt;/td&gt;
&lt;td&gt;Weak&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Real entropy; regenerate every key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mining Your Ps and Qs&lt;/td&gt;
&lt;td&gt;2012&lt;/td&gt;
&lt;td&gt;Key generation&lt;/td&gt;
&lt;td&gt;Shared prime; one gcd factors both&lt;/td&gt;
&lt;td&gt;Weak&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes (weak)&lt;/td&gt;
&lt;td&gt;Entropy at boot; batch-GCD scanning&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ROCA&lt;/td&gt;
&lt;td&gt;2017&lt;/td&gt;
&lt;td&gt;Key generation&lt;/td&gt;
&lt;td&gt;Structured primes; Coppersmith lattice&lt;/td&gt;
&lt;td&gt;Weak&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes (weak)&lt;/td&gt;
&lt;td&gt;Fix the library; ROCA detector; regenerate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bleichenbacher&lt;/td&gt;
&lt;td&gt;1998&lt;/td&gt;
&lt;td&gt;Padding&lt;/td&gt;
&lt;td&gt;v1.5 padding-validity oracle&lt;/td&gt;
&lt;td&gt;Strong&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Uniform errors; OAEP; drop RSA transport&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DROWN&lt;/td&gt;
&lt;td&gt;2016&lt;/td&gt;
&lt;td&gt;Padding&lt;/td&gt;
&lt;td&gt;Same oracle via a shared-key SSLv2 endpoint&lt;/td&gt;
&lt;td&gt;Strong&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Disable SSLv2; stop cross-protocol key reuse&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ROBOT&lt;/td&gt;
&lt;td&gt;2017&lt;/td&gt;
&lt;td&gt;Padding&lt;/td&gt;
&lt;td&gt;The 1998 oracle still answering across nine vendors&lt;/td&gt;
&lt;td&gt;Strong&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Constant-time uniform errors; retire RSA encryption&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FREAK&lt;/td&gt;
&lt;td&gt;2015&lt;/td&gt;
&lt;td&gt;Negotiation&lt;/td&gt;
&lt;td&gt;Downgrade to 512-bit &lt;code&gt;RSA_EXPORT&lt;/code&gt;, then factor&lt;/td&gt;
&lt;td&gt;Weak&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes (weak)&lt;/td&gt;
&lt;td&gt;Remove export ciphers; downgrade protection; TLS 1.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RSA-250 (ceiling)&lt;/td&gt;
&lt;td&gt;2020&lt;/td&gt;
&lt;td&gt;Challenge&lt;/td&gt;
&lt;td&gt;GNFS on an 829-bit challenge number&lt;/td&gt;
&lt;td&gt;Strong&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;Yes (challenge)&lt;/td&gt;
&lt;td&gt;Not a field break; the public ceiling, never deployed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Read the two rightmost data columns as the argument in a grid: every row that ends in a factored modulus is a &lt;em&gt;weak&lt;/em&gt; modulus, and every row with a &lt;em&gt;strong&lt;/em&gt; modulus recovers no key and factors nothing. The one strong modulus ever factored, RSA-250, is a challenge number that never protected anything.&lt;/p&gt;

flowchart LR
    Y1998[&quot;1998 Bleichenbacher, padding&quot;] --&amp;gt; Y2008[&quot;2008 Debian RNG, key generation&quot;]
    Y2008 --&amp;gt; Y2012[&quot;2012 shared primes, key generation&quot;]
    Y2012 --&amp;gt; Y2015[&quot;2015 FREAK, negotiation&quot;]
    Y2015 --&amp;gt; Y2016[&quot;2016 DROWN via SSLv2, padding&quot;]
    Y2016 --&amp;gt; Y2017[&quot;2017 ROCA structure, and ROBOT padding&quot;]
    Y2017 --&amp;gt; Y2020[&quot;2020 RSA-250 ceiling, a challenge number&quot;]
&lt;h3&gt;Pillar 1: The primes were weak before the math began&lt;/h3&gt;
&lt;p&gt;All three key-generation breaks share one shape: generation produced a weak modulus, and then -- only then -- arithmetic finished it off. A strong modulus is on none of these paths.&lt;/p&gt;

flowchart TD
    R[&quot;Crippled RNG, Debian 2008&quot;] --&amp;gt; W[&quot;Weak modulus&quot;]
    B[&quot;Starved boot entropy&quot;] --&amp;gt; SP[&quot;Two keys share a prime, 2012&quot;]
    SP --&amp;gt; G[&quot;One gcd recovers the shared prime&quot;]
    G --&amp;gt; W
    ST[&quot;Structured primes, Infineon RSALib, 2017&quot;] --&amp;gt; CO[&quot;Coppersmith lattice factors the key&quot;]
    CO --&amp;gt; W
    W --&amp;gt; F[&quot;The math finishes the job, and a strong modulus is on no path here&quot;]
&lt;p&gt;&lt;strong&gt;Debian OpenSSL, defect 2006, disclosed 2008.&lt;/strong&gt; A well-meaning Debian patch, written to silence a Valgrind warning about uninitialized memory, removed most of the entropy feeding OpenSSL&apos;s PRNG. The change shipped in openssl 0.9.8c-1, and for nearly two years the effective seed collapsed to essentially the process ID, about 32,767 possibilities [@cve-2008-0166, @debian-dsa1571]. Keys stopped being unpredictable and became &lt;em&gt;enumerable&lt;/em&gt;: an attacker could precompute the whole set. No factoring, no oracle, just a keyspace small enough to list.The defect was uploaded as openssl 0.9.8c-1 on 17 September 2006 and disclosed on 13 May 2008 by Luciano Bello [@debian-dsa1571-full]. Field measurement came from Yilek and colleagues at IMC 2009, who watched the fix propagate: 751 vulnerable certificates observed, and a meaningful fraction still vulnerable roughly six months later [@yilek-imc2009].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Mining Your Ps and Qs, 2012.&lt;/strong&gt; Nadia Heninger, Zakir Durumeric, Eric Wustrow, and J. Alex Halderman scanned the entire IPv4 Internet&apos;s TLS and SSH hosts and found something worse than predictability. They found collision. Headless and embedded devices, generating keys at first boot with almost no entropy, sometimes produced moduli that shared a single prime with an unrelated device. A shared prime is fatal, because $\gcd(n_1, n_2) = p$ factors both moduli in the time of one gcd.&lt;/p&gt;
&lt;p&gt;They measured that 5.57% of TLS hosts shared keys, and they remotely recovered the RSA private keys of 0.50% of all TLS hosts through common factors, notifying 54 manufacturers [@factorable-2012]. An independent study the same year, titled &quot;Ron was wrong, Whit is right,&quot; found the same collisions in a different dataset and ruled out a single-vendor fluke [@ron-wrong-2012].&lt;/p&gt;
&lt;p&gt;You can watch both keys fall from one gcd:&lt;/p&gt;
&lt;p&gt;{&lt;code&gt;const gcd = (a, b) =&amp;gt; { while (b) { [a, b] = [b, a % b]; } return a; }; // Two RSA moduli from two different devices. Neither looks weak on its own. // (Shrunk stand-ins; real moduli are hundreds of digits and the gcd costs the same.) const n1 = 63900000000000000000000000000000000000000000002625100000000000000000000000000000000000000000026931n; const n2 = 74700000000000000000000000000000000000000000003196300000000000000000000000000000000000000000034189n; const p = gcd(n1, n2);              // one Euclidean gcd -- the entire attack const q1 = n1 / p, q2 = n2 / p; console.log(&apos;shared prime p =&apos;, p.toString()); console.log(&apos;device 1 recovered:&apos;, p * q1 === n1); console.log(&apos;device 2 recovered:&apos;, p * q2 === n2); console.log(&apos;Both private keys recovered from one gcd. Key size was irrelevant.&apos;);&lt;/code&gt;}&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ROCA, 2017.&lt;/strong&gt; The first two breaks needed bad randomness. ROCA needed none. Matus Nemec, Marek Sys, Petr Svenda, Dusan Klinec, and Vashek Matyas showed that Infineon&apos;s RSALib built its primes in a speed-optimizing but constrained form, $p = k \cdot M + (65537^a \bmod M)$, detectable from the &lt;em&gt;public key alone&lt;/em&gt; and factorable by a Coppersmith-style lattice far faster than general factoring [@roca-ccs2017, @roca-crocs, @cve-2017-15361]. The randomness was fine; the &lt;em&gt;structure&lt;/em&gt; was the flaw, so every key the chip ever generated was affected.The first author is Matus Nemec (not &quot;Miroslav&quot;), and the fifth is Vashek, or Vaclav, Matyas (not &quot;Vladimir&quot;). The affected products were the YubiKey 4 (not the YubiKey 5), Estonian national eID cards, and Infineon-based TPMs. Because the attack keys off structure rather than entropy, it is RNG-independent [@roca-crocs].&lt;/p&gt;

For a monic polynomial of degree $d$ modulo $N$, Coppersmith&apos;s method finds every integer root $x_0$ with $\lvert x_0 \rvert \le N^{1/d}$ in polynomial time, using lattice reduction [@coppersmith-1997]. When a prime is built with a special constrained structure, part of it becomes such a small root, and the method factors $n$ far faster than general-purpose factoring. It is the dormant 1997 engine ROCA revived; the lattice details belong to the companion *How RSA Would Break*.
&lt;p&gt;The cost, from the authors themselves: a 1024-bit key fell in under three CPU-months, about $76 on AWS; a 2048-bit key in under 100 CPU-years, about $40,000; and roughly 760,000 confirmed-vulnerable keys were in the field [@roca-crocs]. Notice what &quot;2048-bit&quot; bought here: nothing. The number that mattered was not the key size but the structure of the primes.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; ROCA factors nominally 2048-bit keys, and a shared prime falls to one gcd, yet both only work because &lt;em&gt;generation&lt;/em&gt; produced a weak key. The factoring problem on a strong modulus never bent; the RNG or the library did. This is the thesis&apos;s sharpest edge, and it is why the weak-versus-strong distinction has to stay explicit: a factored key here is evidence &lt;em&gt;for&lt;/em&gt; the thesis, not against it.&lt;/p&gt;
&lt;/blockquote&gt;

Infineon&apos;s ROCA-vulnerable chips were FIPS 140-2 and Common Criteria EAL5+ certified, and they passed for years. Certification tested the on-chip RNG, not the *structure* of the public keys it produced, so a biased-but-well-randomized generator sailed straight through. This is exactly why the Pillar 1 fix adds post-generation structure and shared-factor tests, not just entropy checks [@roca-crocs].
&lt;h3&gt;Pillar 2: The padding check was an oracle&lt;/h3&gt;
&lt;p&gt;Now the padding pivot from Section 3, shown surviving twenty-five years of patches. Three incidents, one bug, reappearing at a new layer each time an inner defense hardened.&lt;/p&gt;

sequenceDiagram
    participant A as Attacker
    participant S as Server
    Note over S: Holds the private key, reveals only whether padding was valid
    A-&amp;gt;&amp;gt;S: Submit c times s^e mod n
    S-&amp;gt;&amp;gt;A: One bit, padding valid or invalid
    Note over A,S: Each bit narrows the interval that must contain m
    A-&amp;gt;&amp;gt;S: Submit the next adaptively chosen ciphertext
    S-&amp;gt;&amp;gt;A: One more bit
    Note over A,S: After about a million queries m is pinned, key never touched
&lt;p&gt;&lt;strong&gt;Bleichenbacher, 1998.&lt;/strong&gt; The origin. A PKCS#1 v1.5 encryption endpoint that reveals whether a decryption was well-padded becomes an adaptive chosen-ciphertext decryption oracle, and about $10^6$ queries decrypt a captured session. The private key is never recovered and nothing is factored; the attacker simply borrows the server&apos;s decryption ability for one message [@bleichenbacher-1998].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DROWN, 2016.&lt;/strong&gt; Nimrod Aviram and fourteen coauthors, Heninger and Halderman among them, showed the 1998 oracle had a door nobody had closed: a forgotten SSLv2 endpoint. If a modern TLS server shared its RSA key with an old SSLv2 server -- common, because operators reused certificates -- an attacker could run a cross-protocol Bleichenbacher attack through the SSLv2 side, whose export ciphers and an OpenSSL bug made a &quot;special&quot; variant cheap.&lt;/p&gt;
&lt;p&gt;At disclosure in March 2016, 33% of all HTTPS servers, 25% of the top million, and 22% of browser-trusted sites were vulnerable; it fell to about 1.2% by 2019 [@drown-2016].DROWN is not ROBOT. DROWN (2016) reached modern TLS &lt;em&gt;cross-protocol&lt;/em&gt;, through a shared-key SSLv2 endpoint. ROBOT (disclosed December 2017, published at USENIX Security 2018) found the &lt;em&gt;same&lt;/em&gt; oracle still answering &lt;em&gt;directly&lt;/em&gt; on modern TLS stacks. Different years, different vector, the same 1998 bug [@drown-2016, @robotattack].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Nadia Heninger co-authored &lt;em&gt;Mining Your Ps and Qs&lt;/em&gt; (2012, weak keys recovered by gcd) and &lt;em&gt;DROWN&lt;/em&gt; (2016, the oracle re-armed via SSLv2), and she co-holds the &lt;em&gt;RSA-250&lt;/em&gt; factoring record (2020, the slow way a &lt;em&gt;strong&lt;/em&gt; key falls) [@factorable-2012, @drown-2016, @rsa250-2020]. One researcher stands at both poles of the argument. She is not alone: Juraj Somorovsky bridges DROWN and ROBOT, and J. Alex Halderman bridges Mining Your Ps and Qs and DROWN. This is one research community with a shared toolkit of Internet-wide measurement, not rival schools [@robotattack].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;ROBOT, 2017.&lt;/strong&gt; Hanno Bock, Juraj Somorovsky, and Craig Young gave the bug its name, Return Of Bleichenbacher&apos;s Oracle Threat, and showed the nineteen-year-old oracle still live across nine vendors, including F5, Citrix, Radware, Palo Alto Networks, IBM, and Cisco, with vulnerable subdomains on 27 of the top 100 domains, Facebook and PayPal among them [@robot-usenix2018, @robot-eprint, @robotattack]. To prove the point without crossing a line, the team used the oracle to sign a message with Facebook&apos;s private key, and still never recovered that key.&lt;/p&gt;

ROBOT &quot;allows performing RSA decryption and signing operations with the private key of a TLS server&quot; -- and yet recovers no private key at all. Its own recommendation is the entire fix thesis in one line: disable RSA encryption cipher suites entirely.
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Not by error text, not by an alert code, not by a TCP reset, not by a timeout, not by response timing. You cannot make an observable-validity scheme uniformly safe by patching. You replace it (OAEP) or remove it (no RSA key transport).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;All three padding incidents carry the sharpest version of the thesis: the attacker &lt;em&gt;uses&lt;/em&gt; the private key without ever &lt;em&gt;holding&lt;/em&gt; it, and the modulus is untouched at the end. The remedy was never a bigger key. It was uniform, constant-time error handling and, ultimately, retiring RSA encryption in favor of OAEP or &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;forward-secret key exchange&lt;/a&gt;, exactly as ROBOT advised.&lt;/p&gt;
&lt;h3&gt;Pillar 3: The negotiation forced a crippled key&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;FREAK, 2015.&lt;/strong&gt; Benjamin Beurdouche and seven coauthors found a TLS state-machine flaw with a nasty consequence. A man-in-the-middle could force a handshake down to 512-bit &lt;code&gt;RSA_EXPORT&lt;/code&gt; even when neither the client nor the server wanted export-grade crypto. And 512-bit RSA has been factorable since RSA-155 fell in 1999, so the attacker factors the downgraded modulus in hours for about $100 on cloud compute, then impersonates or decrypts the session. At disclosure, 36.7% of browser-trusted HTTPS servers still accepted export RSA [@freak-sp2015, @freak-pdf, @freakattack, @cve-2015-0204, @rsa155-2000].&lt;/p&gt;

sequenceDiagram
    participant C as Client
    participant M as MITM
    participant S as Server
    C-&amp;gt;&amp;gt;M: ClientHello, wants strong RSA
    M-&amp;gt;&amp;gt;S: Forward it but ask for RSA_EXPORT
    S-&amp;gt;&amp;gt;M: ServerKeyExchange with a 512-bit export key
    M-&amp;gt;&amp;gt;C: Inject the 512-bit key as if it were normal
    Note over M: Factor the 512-bit modulus in hours for about 100 dollars
    M-&amp;gt;&amp;gt;C: Impersonate or decrypt the session
&lt;p&gt;The factoring step is feasible here only because a downgrade plus 1990s export policy forced a deliberately weak key. The math finished a job the deployment set up, and it could not have touched a 2048-bit key the same way.The academic paper, &quot;A Messy State of the Union,&quot; has eight authors; never attribute FREAK to a single name [@freak-sp2015]. The freakattack.com credit to Karthikeyan Bhargavan and the miTLS team, with tracking by the University of Michigan, is a separate and separately-true fact [@freakattack]. The fix was, again, a deployment change, not a cryptographic one: remove export ciphers, disable SSLv2, add downgrade protection, and ultimately TLS 1.3 dropping RSA key exchange entirely.&lt;/p&gt;
&lt;p&gt;Three layers, seven field breaks, one shape. Every time, a contract the RSA math depends on but does not control was violated, real keys or sessions or signatures fell, and the factoring problem on a strong modulus did not move. Seen one at a time, each looks like a smartcard bug, a TLS bug, a legacy-protocol bug. Seen together, they are a single pattern, and the pattern is the whole point.&lt;/p&gt;
&lt;h2&gt;5. Every Fix Changed How RSA Is Generated, Used, or Negotiated -- Never RSA&lt;/h2&gt;
&lt;p&gt;Stop treating the seven incidents as separate. Line them up and one realization collapses the subject: every field break attacked a layer the math depends on but does not control -- entropy, then the padding check, then negotiated strength -- and every fix changed how RSA is &lt;em&gt;generated, used, or negotiated&lt;/em&gt;, never the factoring problem.&lt;/p&gt;
&lt;p&gt;The breakthrough here is not a eureka discovery. It is an engineering discipline, visible only because the same shape repeats across a twenty-year drumbeat from 1998 to 2020. Map each fix to its layer and watch none of them touch the primitive:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Key generation&lt;/strong&gt; was answered with validated high-entropy generation plus post-hoc structure and shared-factor testing: FIPS 186-5, batch-GCD scanners, and the ROCA detector [@fips186-5, @factorable-2012, @roca-crocs].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Padding&lt;/strong&gt; was answered with OAEP, uniform constant-time error handling, and, most durably, structurally retiring RSA encryption [@rfc8017, @robotattack].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Negotiation&lt;/strong&gt; was answered by removing export and SSLv2, adding downgrade protection, and TLS 1.3 deleting static RSA key exchange outright [@rfc8446].&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It is worth dwelling on the padding fix that &lt;em&gt;failed&lt;/em&gt;, because its failure is the most instructive event in the whole story. The canonical countermeasure was not hand-waving. TLS 1.2 specified it precisely: on any decryption or padding failure, the server does not signal an error at all. It substitutes a randomly generated premaster secret and proceeds as if nothing were wrong, so the handshake fails uniformly and only later, at the &lt;code&gt;Finished&lt;/code&gt;-message MAC, with no observable difference between valid and invalid padding [@rfc5246]. The RFC even cites Bleichenbacher and the Klima-Pokorny-Rosa version oracle by name.&lt;/p&gt;
&lt;p&gt;It removed exactly one channel, the explicit error message. And the same one bit resurfaced through three more: a forgotten SSLv2 sibling (DROWN), implementation quirks like TCP resets and alert timing (ROBOT), and decryption timing (Marvin) [@drown-2016, @robotattack, @marvin-paper].&lt;/p&gt;
&lt;p&gt;That is the deep lesson. A scheme whose &lt;em&gt;validity is observable&lt;/em&gt; cannot be patched uniformly safe; it can only be structurally replaced. The field kept relearning Bleichenbacher&apos;s single lesson at a new layer each time an inner defense hardened.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Every field break attacked a layer the math depends on but does not control, and every remedy -- validated entropy and structure tests, OAEP and PSS with uniform errors, dead export and SSLv2, TLS 1.3 -- hardened a &lt;em&gt;deployment obligation&lt;/em&gt;. The factoring problem is the fixed point around which everything else evolved. Soundness requires the weakest of three deployment layers to hold, and hardening any one of them is an exercise in &lt;em&gt;usage&lt;/em&gt;, not cryptanalysis.&lt;/p&gt;
&lt;/blockquote&gt;

This is exactly the border with the two companion pieces. The would-break-in-theory math -- the Number Field Sieve, Coppersmith&apos;s lattices, Shor&apos;s algorithm -- belongs to *How RSA Would Break*. The constructive depth of OAEP and PSS, including how to implement the constant-time error path correctly, belongs to [*RSA Done Right*](/blog/rsa-is-a-trapdoor-not-a-cryptosystem-oaep-pss-and-the-25-yea/). This article links out to both rather than re-teaching them, because its job is the pattern across the field, not the internals of any one fix.
&lt;p&gt;If every fix is &quot;generate, use, or negotiate RSA correctly,&quot; then the state of the art is simply the catalog of what &quot;correctly&quot; means at each layer in 2026 -- and where, even now, correct-by-the-book still is not enough.&lt;/p&gt;
&lt;h2&gt;6. What Correct RSA Deployment Looks Like in 2026&lt;/h2&gt;
&lt;p&gt;The modern answer is unglamorous, and that is the point: be sound at all three layers at once, because validated key generation does nothing for a leaky padding check, and a perfect padding scheme does nothing for a forced 512-bit downgrade.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key generation.&lt;/strong&gt; Use validated, high-entropy, structure-checked generation per FIPS 186-5, published February 2023 [@fips186-5]. Guarantee real entropy &lt;em&gt;before&lt;/em&gt; the first key is generated, use 2048-bit or larger moduli, and run continuous fleet hygiene: batch-GCD across your own keys and the ROCA detector against certified black boxes [@factorable-2012, @roca-crocs]. Generation and measurement are complementary -- measurement catches what generation missed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Padding and encryption.&lt;/strong&gt; Use RSA-OAEP for encryption and RSA-PSS for signatures, both from RFC 8017, with constant-time, uniform-error decryption; better still, avoid RSA key transport altogether [@rfc8017].&lt;/p&gt;

OAEP (Optimal Asymmetric Encryption Padding) is a plaintext-aware encryption padding, and PSS is the analogous randomized signature scheme; both are specified in RFC 8017 [@rfc8017]. OAEP removes the Bleichenbacher oracle *as a class*, but only when decryption returns one constant-time, generic error for every failure. OAEP decoding has two internally distinct failure cases -- an integer-out-of-range or wrong leading octet, versus an octet-format or integrity failure -- and if an implementation lets them be distinguishable by code, alert, or timing, OAEP itself becomes a padding oracle: Manger&apos;s 2001 attack then recovers the plaintext in about $\log_2 n$ queries, far fewer than Bleichenbacher&apos;s $10^6$, because the leaked bit is cleaner [@manger-2001]. PSS is not what the padding oracles break; construction depth belongs to *RSA Done Right*.
&lt;p&gt;The one-line takeaway is worth memorizing: OAEP done wrong is Bleichenbacher wearing different padding. Even the fix is a deployment obligation.Marvin (2023, Hubert Kario at Red Hat) is a modern &lt;em&gt;timing&lt;/em&gt; revival of the v1.5 oracle across many libraries. Its existence and authorship are verified, but keep it at mention weight pending venue and peer-review confirmation, rather than leaning on it as a load-bearing result [@marvin-paper, @marvin-iacr-news].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Negotiation.&lt;/strong&gt; Use TLS 1.3, which removes static RSA key exchange entirely: all key exchange is forward-secret (EC)DHE, and RSA survives only as a &lt;em&gt;signature&lt;/em&gt; algorithm, with the rationale spelled out in the RFC&apos;s Appendix E.8, &quot;Attacks on Static RSA&quot; [@rfc8446]. SSLv2, export ciphers, and &lt;code&gt;RSA_EXPORT&lt;/code&gt; are dead. Forward secrecy is the structural win here: with no RSA key transport on the wire, there is no v1.5 decryption for an oracle to be &lt;em&gt;about&lt;/em&gt;. The deployed stacks already reflect this -- mainstream TLS libraries now default to TLS 1.3, and some, like rustls, never implemented the &lt;code&gt;TLS_RSA_*&lt;/code&gt; transport suites at all [@rustls-manual].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; SSLv2, &lt;code&gt;RSA_EXPORT&lt;/code&gt;, and PKCS#1 v1.5 all stayed live in production for a decade or more after retirement, and every one was weaponized as a &lt;em&gt;live&lt;/em&gt; attack surface: DROWN, FREAK, ROBOT. &quot;Harmless legacy&quot; is a contradiction. Retiring RSA key transport is a migration, not a switch: v1.5 is still specified and ubiquitous in S/MIME, JWT and JOSE, hardware security modules, and legacy TLS, and the timing tail persists wherever v1.5 decryption survives [@marvin-paper].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&quot;Validate generation, use OAEP and PSS, drop RSA key transport&quot; is the whole answer for greenfield code. But engineers inherit constraints -- a device that must self-generate keys, a peer that only speaks v1.5, a fleet already in the field -- so the real question is not &quot;what is best&quot; but &quot;what are my options at each layer, ranked, and exactly when does each apply?&quot;&lt;/p&gt;
&lt;h2&gt;7. Competing Approaches: How the Field Closes Each Gap&lt;/h2&gt;
&lt;p&gt;For each of the three loci, the honest picture is competing options with real trade-offs, not a single winner.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pillar&lt;/th&gt;
&lt;th&gt;Option A&lt;/th&gt;
&lt;th&gt;Option B&lt;/th&gt;
&lt;th&gt;Option C&lt;/th&gt;
&lt;th&gt;Main trade-off&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Key generation&lt;/td&gt;
&lt;td&gt;Hardware RNG plus entropy at boot&lt;/td&gt;
&lt;td&gt;Derandomized key generation from a strong seed&lt;/td&gt;
&lt;td&gt;Post-hoc structure and shared-factor testing&lt;/td&gt;
&lt;td&gt;Prevention versus detection; they coexist&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Padding&lt;/td&gt;
&lt;td&gt;OAEP (safe only with one constant-time generic error)&lt;/td&gt;
&lt;td&gt;Hardened uniform-error v1.5 (&lt;code&gt;RFC 5246&lt;/code&gt; random premaster)&lt;/td&gt;
&lt;td&gt;Abandon RSA encryption for (EC)DHE&lt;/td&gt;
&lt;td&gt;Compatibility versus a clean break&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Downgrade&lt;/td&gt;
&lt;td&gt;TLS 1.3 downgrade protection and protocol retirement&lt;/td&gt;
&lt;td&gt;Config hardening (&lt;code&gt;TLS_FALLBACK_SCSV&lt;/code&gt;, disable export and SSLv2)&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;A new protocol versus patching the old one&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Key generation.&lt;/strong&gt; Three approaches coexist. A hardware RNG with guaranteed entropy at boot prevents the Debian and shared-prime failures at the source. Derandomized key generation -- deriving the primes from a single strong seed -- removes the runtime-entropy dependency entirely, at the cost of trusting that seed. And post-hoc structure and shared-factor testing (batch-GCD scanners, the ROCA detector) catches what generation missed [@factorable-2012, @roca-crocs, @fips186-5]. Measurement is the backstop for generation: ROCA and Mining Your Ps and Qs were both &lt;em&gt;discovered&lt;/em&gt; by scanning the field, not by auditing source.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Padding.&lt;/strong&gt; Three options, chosen by how much legacy you must carry. Fix the scheme with OAEP -- but recall Manger, that it is only misuse-safe with one constant-time generic error [@manger-2001]. Or keep v1.5 for compatibility and harden the implementation toward a uniform error, the RFC 5246 random-premaster substitution -- a twenty-five-year losing battle across error text, protocol siblings, implementation quirks, and timing [@rfc5246]. Or abandon RSA encryption for forward-secret (EC)DHE. Different deployments sit under different compatibility constraints, so all three survive in the field [@rfc8017, @robotattack].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Downgrade.&lt;/strong&gt; Two options. TLS 1.3, with built-in downgrade protection and outright protocol and algorithm retirement, is the durable answer. For stacks that cannot move yet, configuration hardening -- &lt;code&gt;TLS_FALLBACK_SCSV&lt;/code&gt;, disabling export ciphers and SSLv2 -- is the interim one [@rfc8446, @drown-2016].&lt;/p&gt;
&lt;p&gt;Notice the convergence. The durable answer to both Pillar 2 and Pillar 3 is the &lt;em&gt;same&lt;/em&gt; move: do not do RSA key transport. The clean surviving split is that RSA-for-signatures (PSS) stays first-class while RSA-for-encryption is retired.&lt;/p&gt;
&lt;p&gt;Every one of these options changes how RSA is generated, used, or negotiated, or drops RSA key transport entirely, and each buys its safety with a specific cost -- a scan, a migration, a compatibility break, a forward-secret handshake. Which means the honest way to close the technical arc is to ask what is &lt;em&gt;provably&lt;/em&gt; true on both sides: how little the attacker needs, and how much the defender can actually guarantee.&lt;/p&gt;
&lt;h2&gt;8. What Is Provably True on Both Sides&lt;/h2&gt;
&lt;p&gt;The thesis has two sides, and each has its own frontier. The surprise is the asymmetry: the &lt;em&gt;math&lt;/em&gt; side is a slow, honest, well-mapped concession, and all the operationally relevant limits live in the &lt;em&gt;deployment&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The math side, the honest concession.&lt;/strong&gt; Factoring is real but slow. The Number Field Sieve runs in heuristic sub-exponential time $L_N[1/3, (64/9)^{1/3}]$, with $(64/9)^{1/3} \approx 1.923$ [@rsa240-2019], and the public record has crept forward for two decades.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Challenge&lt;/th&gt;
&lt;th&gt;Bits&lt;/th&gt;
&lt;th&gt;Year&lt;/th&gt;
&lt;th&gt;Effort&lt;/th&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Deployed strong key factored?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;RSA-155&lt;/td&gt;
&lt;td&gt;512&lt;/td&gt;
&lt;td&gt;1999&lt;/td&gt;
&lt;td&gt;feasible in hours today&lt;/td&gt;
&lt;td&gt;NFS&lt;/td&gt;
&lt;td&gt;Never&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RSA-768&lt;/td&gt;
&lt;td&gt;768&lt;/td&gt;
&lt;td&gt;2009&lt;/td&gt;
&lt;td&gt;~1500 core-years sieving&lt;/td&gt;
&lt;td&gt;NFS&lt;/td&gt;
&lt;td&gt;Never&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RSA-240&lt;/td&gt;
&lt;td&gt;795&lt;/td&gt;
&lt;td&gt;2019&lt;/td&gt;
&lt;td&gt;~900 core-years&lt;/td&gt;
&lt;td&gt;NFS&lt;/td&gt;
&lt;td&gt;Never&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RSA-250&lt;/td&gt;
&lt;td&gt;829&lt;/td&gt;
&lt;td&gt;2020&lt;/td&gt;
&lt;td&gt;~2700 core-years&lt;/td&gt;
&lt;td&gt;GNFS (CADO-NFS)&lt;/td&gt;
&lt;td&gt;Never&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RSA-2048&lt;/td&gt;
&lt;td&gt;2048&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;astronomically out of reach classically&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Never&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Every row is a &lt;em&gt;challenge&lt;/em&gt; number from the old RSA Factoring Challenge, a public target list RSA Laboratories once published [@wiki-rsa-challenge], and none was ever a deployed key [@rsa155-2000, @rsa768-epfl, @rsa768-eprint, @rsa240-2019, @rsa250-2020]. 512-bit is hours, which is exactly why FREAK works; 2048-bit is out of classical reach; and Shor&apos;s algorithm collapses all of it on a quantum computer -- a story the companion &lt;em&gt;How RSA Would Break&lt;/em&gt; owns. Read the rightmost column top to bottom: it says &lt;em&gt;Never&lt;/em&gt; at every row, because no strong, correctly generated, deployed modulus has ever been factored in the field.RSA-250&apos;s roughly 2700 core-years split into about 2450 for sieving and 250 for the matrix step, run on Intel Xeon Gold 6130 cores with CADO-NFS. It is a 250-digit, 829-bit challenge number, and it never protected a deployed system [@rsa250-2020].&lt;/p&gt;
&lt;p&gt;The Heninger through-line closes here. The researcher who recovered weak keys by the thousand in Pillar 1 co-holds &lt;em&gt;this&lt;/em&gt; record -- the slow, honest way a &lt;em&gt;strong&lt;/em&gt; key falls [@rsa250-2020]. That is the entire weak-versus-strong distinction compressed into one career. And note the theory is not even settled in the defender&apos;s favor: there is no proof that factoring requires super-polynomial time, and the RSA-problem-versus-factoring equivalence is itself open [@boneh-1999]. Two-plus decades of open cryptanalysis is an empirical floor, not a theorem -- and it never once mattered in the field.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The deployment side, where the real limits live.&lt;/strong&gt; Here the limits are provable-in-practice, and none is about a strong modulus&apos;s strength.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attack&lt;/th&gt;
&lt;th&gt;Attacked layer&lt;/th&gt;
&lt;th&gt;Worst-case work&lt;/th&gt;
&lt;th&gt;Needs a weak modulus?&lt;/th&gt;
&lt;th&gt;Recovers the private key?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Padding oracle (Bleichenbacher family)&lt;/td&gt;
&lt;td&gt;Padding&lt;/td&gt;
&lt;td&gt;About $10^6$ queries, polynomial&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Batch-GCD shared primes&lt;/td&gt;
&lt;td&gt;Key generation&lt;/td&gt;
&lt;td&gt;One gcd, quasi-linear over the fleet&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ROCA and Coppersmith&lt;/td&gt;
&lt;td&gt;Key generation&lt;/td&gt;
&lt;td&gt;Lattice reduction, polynomial&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FREAK downgrade then factor&lt;/td&gt;
&lt;td&gt;Negotiation&lt;/td&gt;
&lt;td&gt;Hours to factor 512-bit&lt;/td&gt;
&lt;td&gt;Yes (forced)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GNFS on a strong modulus&lt;/td&gt;
&lt;td&gt;The math itself&lt;/td&gt;
&lt;td&gt;Sub-exponential, ~2700 core-years at 829-bit&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Only the challenge key&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Three boundaries, stated outright. First, a padding oracle needs no factoring: its query count is bounded below only by the roughly one-bit-per-conforming-reply information rate, so decryption is &lt;em&gt;many&lt;/em&gt; queries but always polynomial, and you cannot make an observable-validity scheme require exponentially many queries [@bleichenbacher-1998, @manger-2001]. Second, a shared prime is a single gcd away and a structured prime a Coppersmith lattice away -- quasi-linear or polynomial, regardless of key size [@factorable-2012, @roca-crocs]. Third, certification is not structural testing -- the ROCA lesson from Pillar 1, where FIPS 140-2 and CC EAL5+ chips shipped structurally factorable keys for years [@roca-crocs].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The math side is a slow, mapped concession -- an 829-bit public ceiling, and no strong deployed key ever factored. The deployment side holds the &lt;em&gt;real&lt;/em&gt; limits: a padding oracle needs no factoring, a shared prime is one gcd, a structured prime one lattice, a downgrade one forced 512-bit key -- all independent of key size. &quot;Strong-modulus-secure&quot; and &quot;system-secure&quot; are different claims, and the gap between them is inherent, not accidental.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If the math side is a slow, mapped concession and the deployment side has hard, polynomial-cost limits, the practical frontier is obvious: it is wherever those deployment limits are still being hit in the wild. That is not a solved problem. It is an active one.&lt;/p&gt;
&lt;h2&gt;9. Where RSA Still Breaks in the Field&lt;/h2&gt;
&lt;p&gt;The math side is a slow, honest concession. The deployment side is not closed. Here are the places the same three-pillar pattern is still live, each an operational frontier, each consistent with the thesis that the weak link is a layer the math depends on, never the factoring problem.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Entropy on embedded, first-boot, and cloned systems (Pillar 1).&lt;/strong&gt; The exact Debian and shared-prime gap, revived by cloud VM cloning and container images that reproduce identical state at key-generation time [@ristenpart-yilek-2010]. The best partial answer is FIPS 186-5 generation plus fleet batch-GCD, but coverage of cloned and containerized keys is incomplete [@factorable-2012, @fips186-5].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The PKCS#1 v1.5 long tail and timing oracles (Pillar 2).&lt;/strong&gt; v1.5 is still specified and everywhere. Marvin (2023) showed the &lt;em&gt;timing&lt;/em&gt; axis is still open across many libraries, tied to the working impossibility result that an observable-validity scheme cannot be patched uniformly safe, only structurally replaced [@marvin-paper, @marvin-iacr-news, @robotattack].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Protocol and algorithm-retirement lag (Pillar 3).&lt;/strong&gt; How does a dead algorithm -- SSLv2, export RSA, v1.5 -- stay live for a decade or more? DROWN fell from 33% in 2016 to about 1.2% by 2019, and FREAK from 36.7% toward the low single digits: large but incomplete progress [@drown-2016, @freakattack]. This is a socio-technical problem, not a cryptanalytic one.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The next ROCA-class library (Pillar 1).&lt;/strong&gt; Detecting a &lt;em&gt;structurally&lt;/em&gt; biased generator inside certified closed hardware, before it ships millions of keys. The ROCA detector is signature-based, so a genuinely new structure would evade it [@roca-crocs].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Post-quantum signature migration ahead of Shor.&lt;/strong&gt; This is the one future break that &lt;em&gt;is&lt;/em&gt; the math. Key exchange is already forward-secret, but signatures need proactive migration; the mechanics belong to the post-quantum and would-break siblings.&lt;/p&gt;
&lt;p&gt;One boundary is worth fencing so it is never miscounted as a field incident.Wiener&apos;s small-$d$ attack recovers a too-small private exponent $d &amp;lt; \tfrac{1}{3} n^{1/4}$ from the public key by continued fractions (1990) [@wiener-1990], and Hastad&apos;s low-exponent broadcast recovers the same unpadded low-$e$ message sent to $e$ recipients via CRT and an integer $e$-th root (1988) [@hastad-1988]. Both are real, but they are parameter-choice, theoretical breaks -- the canonical argument for randomized padding -- not documented field incidents. They belong to &lt;em&gt;How RSA Would Break&lt;/em&gt;. Parameter-choice attacks on deliberately bad exponents are a different genre from the deployment failures cataloged here.&lt;/p&gt;
&lt;p&gt;Every open problem here is the same sentence in new clothes: a contract the RSA math depends on is hard to keep in the real world. Which means the practical guide writes itself. It is the thesis made operational, each rule routed to the incident it prevents.&lt;/p&gt;
&lt;h2&gt;10. What to Do on Monday&lt;/h2&gt;
&lt;p&gt;Everything above collapses into a short decision procedure and a shorter list of nevers, each rule tied to the incident it prevents.&lt;/p&gt;

flowchart TD
    E{&quot;Real entropy before keygen?&quot;} --&amp;gt;|No| E1[&quot;Stop. Seed first. Never generate at unseeded boot.&quot;]
    E --&amp;gt;|Yes| K[&quot;FIPS 186-5 generation, 2048-bit or larger&quot;]
    K --&amp;gt; SCAN{&quot;Batch-GCD and ROCA detector&quot;}
    SCAN --&amp;gt;|Flagged| REV[&quot;Regenerate and revoke&quot;]
    SCAN --&amp;gt;|Clean| ENC{&quot;Need RSA encryption?&quot;}
    ENC --&amp;gt;|Yes| OAEP[&quot;OAEP, one constant-time generic error&quot;]
    ENC --&amp;gt;|No| DHE[&quot;Prefer (EC)DHE, TLS 1.3&quot;]
    OAEP --&amp;gt; SIG[&quot;Signatures: RSA-PSS, plan PQC&quot;]
    DHE --&amp;gt; SIG
    SIG --&amp;gt; NEG[&quot;Disable SSLv2, export, and RSA_EXPORT, add downgrade protection&quot;]
&lt;p&gt;&lt;strong&gt;Key generation.&lt;/strong&gt; Guarantee real entropy before the first key is generated; follow FIPS 186-5; never generate keys at unseeded first boot; use a 2048-bit minimum with validated generation; and run batch-GCD and the ROCA detector across your keys and CT logs, regenerating or revoking anything flagged. This prevents Debian enumeration, shared primes, and ROCA [@fips186-5, @factorable-2012, @roca-crocs].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Padding and encryption.&lt;/strong&gt; Never use raw PKCS#1 v1.5. If you must do RSA encryption, use OAEP with constant-time, uniform-error handling -- one generic error, per Manger; better still, prefer (EC)DHE forward secrecy and drop RSA key transport, which TLS 1.3 does for you. This prevents Bleichenbacher, DROWN, ROBOT, and Marvin [@rfc8017, @manger-2001, @rfc8446].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Signatures.&lt;/strong&gt; Use RSA-PSS, which is not what the oracles break, and plan the post-quantum signature migration ahead of Shor [@rfc8017].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Negotiation.&lt;/strong&gt; Disable SSLv2, export ciphers, and &lt;code&gt;RSA_EXPORT&lt;/code&gt;; enable downgrade protection; prefer TLS 1.3 over 1.2. This prevents FREAK and DROWN&apos;s SSLv2 channel [@rfc8446, @drown-2016].&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Do this...&lt;/th&gt;
&lt;th&gt;...and you reproduce&lt;/th&gt;
&lt;th&gt;The fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Generate keys at unseeded first boot&lt;/td&gt;
&lt;td&gt;Debian enumeration, shared primes&lt;/td&gt;
&lt;td&gt;Real entropy before keygen; batch-GCD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trust a certified black box as structurally safe&lt;/td&gt;
&lt;td&gt;ROCA&lt;/td&gt;
&lt;td&gt;ROCA detector; regenerate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reveal padding validity by error, reset, timeout, or timing&lt;/td&gt;
&lt;td&gt;Bleichenbacher, DROWN, ROBOT, Marvin&lt;/td&gt;
&lt;td&gt;Uniform constant-time errors; OAEP; drop RSA transport&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reuse one RSA key across protocols&lt;/td&gt;
&lt;td&gt;DROWN, via SSLv2&lt;/td&gt;
&lt;td&gt;Separate keys; disable SSLv2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Leave export ciphers or SSLv2 live&lt;/td&gt;
&lt;td&gt;FREAK, DROWN&lt;/td&gt;
&lt;td&gt;Remove export and SSLv2; downgrade protection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Assume &quot;2048-bit means safe&quot;&lt;/td&gt;
&lt;td&gt;Every non-factoring break&lt;/td&gt;
&lt;td&gt;Secure all three layers, not the key size&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The batch-GCD check is not just an attacker&apos;s tool; it is your fleet audit. Run it against your own moduli:&lt;/p&gt;
&lt;p&gt;{&lt;code&gt;const gcd = (a, b) =&amp;gt; { while (b) { [a, b] = [b, a % b]; } return a; }; // Public moduli scraped from your own devices or CT logs. const fleet = {   &apos;host-a&apos;: 63900000000000000000000000000000000000000000002625100000000000000000000000000000000000000000026931n,   &apos;host-b&apos;: 74700000000000000000000000000000000000000000003196300000000000000000000000000000000000000000034189n,   &apos;host-c&apos;: 35510000000000000000000000000000000000000000001968800000000000000000000000000000000000000000010257n,   &apos;host-d&apos;: 18130000000000000000000000000000000000000000001447800000000000000000000000000000000000000000026649n, }; const names = Object.keys(fleet); let flagged = 0; for (let i = 0; i &amp;lt; names.length; i++) {   for (let j = i + 1; j &amp;lt; names.length; j++) {     const g = gcd(fleet[names[i]], fleet[names[j]]);     if (g &amp;gt; 1n) {       flagged++;       console.log(&apos;WEAK PAIR:&apos;, names[i], &apos;&amp;amp;&apos;, names[j], &apos;-&amp;gt; shared factor&apos;, g.toString());     }   } } console.log(flagged ? (&apos;Regenerate and revoke &apos; + flagged + &apos; compromised pair(s).&apos;) : &apos;No shared factors found.&apos;);&lt;/code&gt;}&lt;/p&gt;

To feed real keys in, extract each modulus first with a one-liner like `openssl x509 -in cert.pem -noout -modulus`, collect them into the list above, and run it. Any pair with a gcd greater than 1 is a compromised pair: regenerate and revoke both, then find out why two devices drew the same prime.
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; One: validated high-entropy, structure-checked key generation (FIPS 186-5) plus fleet batch-GCD and ROCA scans. Two: OAEP for encryption and PSS for signatures with uniform, constant-time errors -- or, better, drop RSA key transport for (EC)DHE. Three: TLS 1.3, with SSLv2, export ciphers, and &lt;code&gt;RSA_EXPORT&lt;/code&gt; disabled.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The checklist is short because the lesson is one sentence. Before restating it, let us clear the handful of confident, wrong sentences that keep these bugs alive in design meetings.&lt;/p&gt;
&lt;h2&gt;11. Misconceptions, Precisely Corrected&lt;/h2&gt;
&lt;p&gt;The paradox survives mostly because a few plausible, wrong statements keep getting repeated. Here they are, corrected, each answer tied back to a catalog entry and the three-pillar thesis.&lt;/p&gt;


Only *weak* keys: 512-bit export keys (FREAK), shared-prime keys, and ROCA-structured keys. The public *challenge* ceiling is the 829-bit RSA-250, which took about 2,700 core-years in 2020. No strong, correctly generated, deployed modulus has ever been factored [@rsa250-2020, @freakattack].


No. It is a decryption or signing *oracle*: the attacker decrypts one session or forges one signature, but the key is never extracted and the modulus is never factored [@robotattack, @bleichenbacher-1998].


No -- it is a different scheme. The padding oracle is on v1.5 *encryption*. PSS signatures, and even v1.5 signatures, are not what falls. Keep the two constructions distinct [@rfc8017].


No. RSA signing has no secret per-signature nonce. The per-signature $k$-reuse break behind the PlayStation 3 and Android incidents is an (EC)DSA phenomenon, told in its own article [@ps3-epic-fail-2010, @bitcoin-android-alert-2013].


Not for padding oracles, shared or structured primes, or downgrade -- those are deployment defects, independent of key size. Size only matters against brute factoring, which is exactly why 512-bit export was fatal and a strong key is not [@factorable-2012, @roca-crocs].


Not necessarily. ROCA&apos;s keys were CC EAL5+ certified; certification tested the RNG, not the public-key *structure*, and roughly 760,000 factorable keys shipped anyway [@roca-crocs].


The primitive, no. But stop using RSA key transport and raw PKCS#1 v1.5, prefer forward-secret (EC)DHE and OAEP or PSS, and plan the post-quantum signature migration ahead of Shor [@rfc8446, @rfc8017].

&lt;p&gt;Every correction points at the same root: the factoring problem was never the weak link. Time to say the sentence the whole article was built to earn.&lt;/p&gt;
&lt;h2&gt;To Break RSA in the Field, You Never Factor a Strong Modulus&lt;/h2&gt;
&lt;p&gt;Return to the opening paradox, now resolved. The public factoring ceiling is an 829-bit challenge number that cost about 2,700 core-years, and no strong deployed key has ever fallen to it [@rsa250-2020]. And yet national ID cards were forgeable, a third of HTTPS was decryptable, embedded keys were recoverable, and sessions were man-in-the-middled -- because every one of those breaks happened at a layer the factoring problem knows nothing about.&lt;/p&gt;
&lt;p&gt;The primes were weak before the math began: Debian, shared primes, ROCA. The padding check was an oracle: Bleichenbacher, DROWN, ROBOT. The negotiation forced a crippled key: FREAK. Three layers, seven deployed field breaks, and the factoring problem on a strong modulus untouched in all of them. RSA-250, the eighth row of the catalog, is the &lt;em&gt;ceiling&lt;/em&gt; -- a strong-but-undeployed challenge number, not a field break.&lt;/p&gt;
&lt;p&gt;Every fix changed how RSA is generated, used, or negotiated -- validated entropy and structure tests, OAEP and PSS and uniform errors, dead export and SSLv2 and TLS 1.3 -- never RSA. And where three incidents did end in a factorization, the deployment had already produced a &lt;em&gt;weak&lt;/em&gt; modulus, so the math merely finished a job it had been handed.&lt;/p&gt;

When your RSA keys fall, don&apos;t ask whether someone factored the modulus. Ask which layer the math depends on but does not control gave way: the primes, the padding, or the negotiation.
&lt;p&gt;One last time, keep the hedge honest: almost never, not never. Factoring is real and fell RSA-512, RSA-768, and RSA-250 as challenge numbers, and Shor&apos;s algorithm is coming for strong keys on a quantum computer -- but that is the story &lt;em&gt;How RSA Would Break&lt;/em&gt; tells, and the constructive OAEP and PSS depth belongs to &lt;em&gt;RSA Done Right&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The factoring problem was never the weak link in the field, and no bigger key would have saved a single one of these deployments. That is why this is Part 3 of a series about how things break &lt;em&gt;in real life&lt;/em&gt;, not a chapter on the Number Field Sieve.&lt;/p&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;how-rsa-breaks-in-real-life&quot; keyTerms={[
  { term: &quot;RSA trapdoor permutation&quot;, definition: &quot;n = p times q with public (n, e) and private d; factoring is sufficient to break RSA and remains the best known attack, while whether inverting RSA is as hard as factoring is an open question.&quot; },
  { term: &quot;Textbook (raw) RSA and malleability&quot;, definition: &quot;Unpadded RSA is deterministic and malleable, so multiplying a ciphertext by s to the e multiplies the plaintext by s; it must be padded before use.&quot; },
  { term: &quot;Entropy and CSPRNG seeding&quot;, definition: &quot;A generator&apos;s output is only as unpredictable as its seed; a starved, crippled, or biased seed yields predictable, enumerable, or colliding primes.&quot; },
  { term: &quot;Shared-factor (batch-GCD) recovery&quot;, definition: &quot;If two moduli share a prime, one gcd factors both; a batch-GCD computes every pairwise gcd across millions of keys at once.&quot; },
  { term: &quot;PKCS#1 v1.5 padding&quot;, definition: &quot;The 00 02 encryption format wrapped around a message; its validity check is what becomes Bleichenbacher&apos;s oracle.&quot; },
  { term: &quot;Padding oracle&quot;, definition: &quot;A decryptor that reveals whether padding was valid leaks one bit per query; enough adaptive queries decrypt a message without the private key.&quot; },
  { term: &quot;Coppersmith&apos;s method&quot;, definition: &quot;Finds small roots of a polynomial modulo N in polynomial time; when primes are structured it factors n far faster than general factoring, the engine behind ROCA.&quot; },
  { term: &quot;Export-grade RSA&quot;, definition: &quot;Deliberately weak 512-bit RSA_EXPORT key exchange and the obsolete SSLv2 protocol, retired in principle but live long enough to power FREAK and DROWN.&quot; },
  { term: &quot;RSA-OAEP and RSA-PSS&quot;, definition: &quot;The modern encryption and signature paddings; OAEP removes the Bleichenbacher oracle only when decryption returns one constant-time generic error, per Manger.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>cryptography</category><category>rsa</category><category>roca</category><category>bleichenbacher</category><category>padding-oracle</category><category>freak</category><category>tls</category><category>key-generation</category><author>noreply@paragmali.com (Parag Mali)</author></item><item><title>How RSA Would Break: Why Factoring Is the Slow Path and Coppersmith Is the Fast One</title><link>https://paragmali.com/blog/how-rsa-would-break-why-factoring-is-the-slow-path-and-coppe/</link><guid isPermaLink="true">https://paragmali.com/blog/how-rsa-would-break-why-factoring-is-the-slow-path-and-coppe/</guid><description>Everyone says you break RSA by factoring the modulus. That is the slowest path. A structural tour of the fast lane, the slow lane, and the quantum one.</description><pubDate>Fri, 17 Jul 2026 00:00:00 GMT</pubDate><content:encoded>
Most people picture an RSA break as someone factoring the modulus. That is the slowest, least-likely path there is: the best classical sieve methods (the quadratic sieve, then the General Number Field Sieve) are sub-exponential, and the record has crawled from 426-bit RSA-129 in 1994 to 829-bit RSA-250 in 2020, still a universe short of a 2048-bit key [@boudot-rsa250-2020]. The fast cracks never factor `N` at all. Coppersmith&apos;s lattice method, Wiener&apos;s small-`d` attack, and their relatives run in polynomial time, but only when a parameter or key-generation choice deviates from the ideal [@boneh-survey-1999]. Against a correctly generated RSA-2048 key with `e = 65537`, a full-size random `d`, and OAEP padding, every one of those preconditions is absent, so the fast lane has no applicable attack. The only structural attack that breaks a well-formed key is Shor&apos;s quantum algorithm, which as of 2026 waits on hardware that does not yet exist [@shor-siam-1997; @gidney-2025].
&lt;h2&gt;1. The break never comes through the front door&lt;/h2&gt;
&lt;p&gt;Ask a room of engineers how RSA breaks, and almost everyone reaches for the same answer: someone factors the modulus. They are describing the slowest, least-likely path there is. The attacks that actually work never touch &lt;code&gt;N&lt;/code&gt; at all, and the one attack that could break a flawlessly generated key has not been built yet, because it needs a computer that does not exist.&lt;/p&gt;
&lt;p&gt;That is the whole argument of this article, and it runs against the common intuition hard enough to be worth stating plainly. RSA&apos;s security is usually explained as &quot;factoring is hard, and your key is a big number nobody can factor.&quot; Both halves are true, and together they still point you at the wrong threat. Factoring your modulus is the one attack a bigger key genuinely slows down, which is exactly why it is the attack that will almost certainly never be the way your key falls.&lt;/p&gt;
&lt;p&gt;Here is the organizing lens for everything that follows: a &lt;strong&gt;two-speed map&lt;/strong&gt; with a third road. The &lt;em&gt;slow lane&lt;/em&gt; attacks the hardness assumption directly by factoring &lt;code&gt;N&lt;/code&gt;. It works on any key, needs no mistake on your part, and is asymptotically glacial.&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;fast lane&lt;/em&gt; ignores &lt;code&gt;N&lt;/code&gt; entirely and attacks the &lt;em&gt;instantiation&lt;/em&gt;, the specific way this key and this message were built. It runs in polynomial time and is genuinely fast, but only when the parameters or the key generation leaked structure they should not have. And the &lt;em&gt;third road&lt;/em&gt;, Shor&apos;s quantum algorithm, reopens the front door itself by changing the machine you compute on, breaking even a perfect key, if and only if someone builds the hardware.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The front door of RSA is bolted, and it opens only at a crawl: factoring is the slow path, not the likely one. The fast cracks come through side windows that a well-generated key never leaves open. And the single attack that opens the front door itself is quantum, on a machine that has not been built.&lt;/p&gt;
&lt;/blockquote&gt;

flowchart TD
    A[&quot;Break RSA-2048&quot;] --&amp;gt; B[&quot;Slow lane: factor N directly&quot;]
    A --&amp;gt; C[&quot;Fast lane: attack the instantiation&quot;]
    A --&amp;gt; D[&quot;Third road: change the machine&quot;]
    B --&amp;gt; B1[&quot;GNFS, sub-exponential, glacial&quot;]
    C --&amp;gt; C1[&quot;Coppersmith, Wiener, polynomial&quot;]
    D --&amp;gt; D1[&quot;Shor, polynomial, needs a quantum computer&quot;]
    B1 --&amp;gt; E{&quot;Beats a correct key?&quot;}
    C1 --&amp;gt; E
    D1 --&amp;gt; E
    E --&amp;gt;|&quot;slow lane, not in practice&quot;| F[&quot;Correct key survives classically&quot;]
    E --&amp;gt;|&quot;fast lane, only with a defect&quot;| F
    E --&amp;gt;|&quot;third road, yes, on hardware that does not exist&quot;| G[&quot;The one real structural threat&quot;]
&lt;p&gt;One boundary before we begin, because it decides what counts as an answer. This is a &lt;em&gt;structural&lt;/em&gt; story about the mathematics of the algorithm itself. The attacks that steal real data most often never touch RSA&apos;s math at all; they break the implementation or the protocol around it. Here we stay inside the equations, where the only question is whether the numbers themselves give way.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This article analyzes cryptanalysis of RSA&apos;s own mathematics. Side channels, fault and power attacks, implementation bugs, weak random-number generators, key-generation library defects such as ROCA, padding oracles such as Bleichenbacher&apos;s, and protocol downgrades such as FREAK are all out of scope. They are how RSA breaks &lt;em&gt;in practice&lt;/em&gt;, and they are covered by the companion article. One exception that belongs to the math: Shor&apos;s quantum algorithm counts as a structural break and is in scope. Grover&apos;s algorithm, a generic search speedup, is only mentioned to mark the edge of the map.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So if factoring is the slow path, what makes the fast one fast, and why does it never touch &lt;code&gt;N&lt;/code&gt;? To see that, start where RSA started: with a bet nobody could prove they would win.&lt;/p&gt;
&lt;h2&gt;2. A wager on a problem no one has proven hard&lt;/h2&gt;
&lt;p&gt;In 1977, three researchers at MIT, Ron Rivest, Adi Shamir, and Leonard Adleman, answered an open call. A year earlier, Whitfield Diffie and Martin Hellman had described what public-key cryptography should do without giving a concrete way to do it: a lock anyone can snap shut but only the keyholder can open [@diffie-hellman-1976]. Rivest, Shamir, and Adleman supplied the lock [@rivest-shamir-adleman-1978].&lt;/p&gt;
&lt;p&gt;That August, Martin Gardner&apos;s Mathematical Games column in &lt;em&gt;Scientific American&lt;/em&gt; handed it to the public as a dare: a 129-digit number to factor, a modest cash prize, and the confident promise that reading the encrypted message would take far longer than any reader would live to see [@gardner-1977; @atkins-rsa129-1995].&lt;/p&gt;
&lt;p&gt;The question worth holding onto is whether that confidence was &lt;em&gt;earned&lt;/em&gt; or merely &lt;em&gt;borrowed&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;RSA itself is almost aggressively simple. Pick two large primes and multiply them into a public modulus $N = pq$. Publish &lt;code&gt;N&lt;/code&gt; and a public exponent &lt;code&gt;e&lt;/code&gt;. To encrypt a message &lt;code&gt;m&lt;/code&gt;, compute $c = m^e \bmod N$; to decrypt, compute $m = c^d \bmod N$, where the private exponent &lt;code&gt;d&lt;/code&gt; is chosen so that $ed \equiv 1 \pmod{\varphi(N)}$ and $\varphi(N) = (p-1)(q-1)$ is Euler&apos;s totient [@rivest-shamir-adleman-1978]. Encryption is a modular exponentiation anyone can perform. Decryption is the same operation with a secret exponent that only the keyholder knows.&lt;/p&gt;
&lt;p&gt;Everything rests on one hinge. To recover &lt;code&gt;d&lt;/code&gt;, the obvious route is to compute $\varphi(N)$, and to compute $\varphi(N)$ you need &lt;code&gt;p&lt;/code&gt; and &lt;code&gt;q&lt;/code&gt;, which means factoring &lt;code&gt;N&lt;/code&gt;. So RSA is &lt;em&gt;believed&lt;/em&gt; to be as hard to break as factoring is hard to do. Read that sentence twice, because the load-bearing word is &quot;believed.&quot; Rivest, Shamir, and Adleman did not prove that breaking RSA requires factoring, and no one has proven it since. RSA is a wager that a specific problem is hard, staked on decades of failed attempts to make it easy rather than on a theorem.&lt;/p&gt;

A function that is easy to compute in the forward direction but hard to invert, unless you hold a secret piece of information (the trapdoor) that makes inversion easy. RSA&apos;s forward direction is modular exponentiation, its trapdoor is the factorization of `N`, and its entire security is the conjecture that without the trapdoor, inversion stays hard.
&lt;p&gt;What makes the RSA story unusually honest is that the field turned this belief into a &lt;em&gt;dated, public experiment&lt;/em&gt;. In March 1991, RSA Security launched the RSA Factoring Challenge: a published list of moduli, cash bounties, and an open invitation to factor them [@wiki-rsa-factoring-challenge]. Every time a challenge number fell, the community learned precisely how far the sharpest available methods and machines could reach in a given year. The result is something most security assumptions never get: a fifty-year measured record of exactly how hard factoring has proven to be in practice.&lt;/p&gt;

timeline
    title Fifty years of RSA cryptanalysis
    1977 : RSA published : Gardner challenge
    1985 : Hastad low-exponent broadcast
    1990 : Wiener small-d attack : Number Field Sieve
    1994 : Shor quantum factoring : RSA-129 factored
    1996 : Coppersmith small-root method
    1999 : Boneh-Durfee small-d lattice : Boneh survey
    2009 : RSA-768 factored
    2020 : RSA-250 factored
    2025 : Shor estimate under one million qubits
&lt;p&gt;That timeline is also a map of everything this article covers, and it splits cleanly into the two speeds. Some entries, the Number Field Sieve, RSA-129, RSA-768, RSA-250, are the slow lane: brute assaults on the factoring problem itself, dated by when a bigger number finally fell. Others, Hastad, Wiener, Coppersmith, Boneh-Durfee, are the fast lane: polynomial-time attacks that never factor anything, dated by when someone noticed a new way for a careless instantiation to give itself away. Only one entry, Shor, belongs to neither lane, because it changes the machine.&lt;/p&gt;

It is worth naming the excluded failures precisely, because they, not the mathematics, are what actually break RSA deployments in the wild: timing and power side channels that leak the private key, fault attacks that corrupt a computation to expose a factor, weak random-number generators that hand out repeated or flawed primes (the ROCA vulnerability), padding oracles such as Bleichenbacher&apos;s that turn a chatty server into a decryption service, and protocol downgrades such as FREAK. Every one is a genuine break, and not one of them factors `N` or attacks RSA&apos;s mathematics. They are implementation and protocol failures, and they belong to the empirical sibling, *How RSA Breaks in Real Life*. This article is about the equations.
&lt;p&gt;If the whole system rests on one unproven assumption, the obvious move is to attack that assumption head-on and just factor &lt;code&gt;N&lt;/code&gt;. Fifty years of the sharpest minds in computational number theory tried exactly that. Here is how far they got.&lt;/p&gt;
&lt;h2&gt;3. The slow lane: attacking factoring head-on&lt;/h2&gt;
&lt;p&gt;The direct attack writes itself: break RSA by factoring the modulus. The punchline is not triumph but frustration. Even the reigning champion algorithm is, at cryptographic sizes, glacial.&lt;/p&gt;
&lt;p&gt;The ladder is a genealogy, and each rung earned its place by beating the one below it. At the bottom sits &lt;strong&gt;trial division&lt;/strong&gt; and Fermat&apos;s method, fully exponential in the size of &lt;code&gt;N&lt;/code&gt; and useless past a few dozen digits. Then come the special-purpose methods: John Pollard&apos;s &lt;strong&gt;&lt;code&gt;p-1&lt;/code&gt;&lt;/strong&gt; method (1974), fast whenever &lt;code&gt;p-1&lt;/code&gt; happens to have only small prime factors [@pollard-pm1-1974], and his &lt;strong&gt;rho&lt;/strong&gt; method (1975), which finds a small factor &lt;code&gt;p&lt;/code&gt; in about $O(p^{1/2})$ steps using almost no memory [@pollard-rho-1975]. These are lethal against unlucky primes but hopeless against a balanced modulus whose factors are both enormous.&lt;/p&gt;
&lt;p&gt;The real lineage of general-purpose factoring begins with a single idea: instead of searching for a factor directly, manufacture a congruence of squares $x^2 \equiv y^2 \pmod{N}$ with $x \not\equiv \pm y$, and read a factor off $\gcd(x-y, N)$. Morrison and Brillhart&apos;s continued-fraction method, &lt;strong&gt;CFRAC&lt;/strong&gt; (1975), was the first to collect many small relations and combine them into that square with linear algebra, and the first general method to run in sub-exponential time [@morrison-brillhart-1975]. Carl Pomerance&apos;s &lt;strong&gt;Quadratic Sieve&lt;/strong&gt; (1985) replaced slow per-number testing with a fast sieve and dominated the 1980s and early 1990s at heuristic cost $L_N[1/2, 1]$ [@pomerance-qs-1985]. Then, in 1990, the &lt;strong&gt;Number Field Sieve&lt;/strong&gt; dropped the exponent from one half to one third, the single largest asymptotic improvement in the history of factoring, and the last one to date [@lenstra-nfs-1990].&lt;/p&gt;

Factoring costs are written with $L_N[\alpha, c] = \exp\big((c + o(1))(\ln N)^{\alpha}(\ln\ln N)^{1-\alpha}\big)$. The exponent $\alpha$ interpolates between two worlds: $\alpha = 1$ is fully exponential in the bit-length, $\alpha = 0$ is polynomial, and $\alpha = 1/3$ sits in between, &quot;sub-exponential.&quot; Sub-exponential is genuinely faster than exponential, which is why big numbers can be factored at all, and genuinely slower than polynomial, which is why they cannot be factored at cryptographic sizes.

The fastest known classical algorithm for factoring a general large integer, with heuristic running time $L_N[1/3, (64/9)^{1/3}] \approx L_N[1/3, 1.923]$ [@lenstra-nfs-1990]. It builds a congruence of squares by collecting relations that are simultaneously smooth on a rational side and an algebraic side, then solves a very large linear system. Every RSA factoring record since the late 1990s has used a GNFS implementation [@zimmermann-records].

An integer is B-smooth if every one of its prime factors is at most `B`. Smoothness is the lever every modern factoring algorithm pulls: the sieve hunts for values that are B-smooth, because only those factor completely over a fixed, small &quot;factor base&quot; of primes and can be fed into the linear algebra. The art of the Number Field Sieve is arranging for enough smooth relations to appear.
&lt;p&gt;Definitions establish that GNFS is sub-exponential. The record trajectory shows what sub-exponential &lt;em&gt;feels&lt;/em&gt; like against real keys, and it is the heart of this section&apos;s argument. Do not take &quot;glacial&quot; on faith. Watch the dates.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Challenge&lt;/th&gt;
&lt;th&gt;Modulus size&lt;/th&gt;
&lt;th&gt;Year factored&lt;/th&gt;
&lt;th&gt;Method and reported effort&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;RSA-129&lt;/td&gt;
&lt;td&gt;426 bits (129 digits)&lt;/td&gt;
&lt;td&gt;1994&lt;/td&gt;
&lt;td&gt;Quadratic sieve, worldwide volunteer effort [@atkins-rsa129-1995]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RSA-155&lt;/td&gt;
&lt;td&gt;512 bits&lt;/td&gt;
&lt;td&gt;1999&lt;/td&gt;
&lt;td&gt;Number Field Sieve [@cavallar-rsa155-2000]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RSA-768&lt;/td&gt;
&lt;td&gt;768 bits&lt;/td&gt;
&lt;td&gt;2009&lt;/td&gt;
&lt;td&gt;GNFS, nearly 2000 core-years [@kleinjung-rsa768-2010]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RSA-250&lt;/td&gt;
&lt;td&gt;829 bits&lt;/td&gt;
&lt;td&gt;2020&lt;/td&gt;
&lt;td&gt;GNFS, roughly 2700 core-years [@boudot-rsa250-2020]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Read the first and last rows together. From RSA-129 in 1994 to RSA-250 in 2020 is roughly 400 bits of progress in 26 years [@zimmermann-records; @wiki-rsa-numbers]. A deployed RSA key is 2048 bits. The record is still more than 1,200 bits short of it, and RSA-250 alone burned about 2,700 core-years of computation on the open-source CADO-NFS software [@boudot-rsa250-2020; @cado-nfs].A core-year is one processor core running flat out for a year, so 2,700 core-years is a large cluster running for months. The same team&apos;s peer-reviewed 240-digit experiment documents the sieving-and-linear-algebra methodology behind these records [@boudot-dlp240-2020]. The gap is not a matter of waiting a few more years for a faster cluster, because the cost curve is sub-exponential, so each additional bit is more expensive than the last. You can compute just how much more expensive.&lt;/p&gt;
&lt;p&gt;{`
from math import log, exp&lt;/p&gt;
Heuristic GNFS cost L_N[1/3, (64/9)^(1/3)] as a function of bit-length.
&lt;p&gt;def L(bits, alpha=1/3, c=(64/9)&lt;strong&gt;(1/3)):
    lnN = bits * log(2)                       # ln N for a &apos;bits&apos;-bit modulus
    return exp(c * lnN&lt;/strong&gt;alpha * (log(lnN))**(1 - alpha))&lt;/p&gt;
&lt;p&gt;cost_829  = L(829)    # RSA-250, the current classical record
cost_2048 = L(2048)   # a deployed key&lt;/p&gt;
&lt;p&gt;print(&quot;GNFS constant (64/9)^(1/3) =&quot;, round((64/9)**(1/3), 4))
print(&quot;Relative L-cost at  829 bits: %.3e&quot; % cost_829)
print(&quot;Relative L-cost at 2048 bits: %.3e&quot; % cost_2048)
print(&quot;RSA-2048 is harder than RSA-250 by a factor of about: %.3e&quot; % (cost_2048 / cost_829))
print()
print(&quot;RSA-250 already cost ~2700 core-years; scaling by that factor gives&quot;)
print(&quot;about %.1e core-years for RSA-2048 -- far beyond any foreseeable cluster.&quot;
      % (2700 * cost_2048 / cost_829))
`}&lt;/p&gt;
&lt;p&gt;The numbers that fall out are not &quot;a thousand times harder&quot; or &quot;a million times harder.&quot; They are astronomical: the same sober &lt;code&gt;L[1/3]&lt;/code&gt; curve that predicted RSA-250 puts a 2048-bit modulus permanently outside the reach of any classical machine anyone can foresee. This is the slow lane in one image. It works on every key, it needs no mistake by the defender, and it will almost certainly never reach a modern modulus.&lt;/p&gt;

flowchart TD
    A[&quot;Trial division and Fermat: fully exponential&quot;] --&amp;gt; B[&quot;Pollard p-1 (1974) and rho (1975): special-purpose&quot;]
    B --&amp;gt; C[&quot;CFRAC (1975): first sub-exponential&quot;]
    C --&amp;gt; D[&quot;Quadratic Sieve (1985): exponent one half&quot;]
    D --&amp;gt; E[&quot;Number Field Sieve (1990): exponent one third&quot;]
    E --&amp;gt; F[&quot;No asymptotic gain since 1990&quot;]
    A --&amp;gt; G[&quot;ECM (1987): niche, cost set by the smallest factor&quot;]
&lt;p&gt;The ladder has texture worth pausing on. When RSA-129 fell in 1994, the recovered plaintext was a puzzle phrase the designers had hidden inside the challenge.The RSA-129 plaintext was &quot;THE MAGIC WORDS ARE SQUEAMISH OSSIFRAGE&quot; [@atkins-rsa129-1995]. A widely repeated web summary claims it read &quot;SEND MORE MONEY&quot;; that is simply wrong. Pollard&apos;s &lt;code&gt;p-1&lt;/code&gt; method left a lasting mark on how primes were chosen: for years, key-generation guidance called for &quot;strong primes,&quot; primes &lt;code&gt;p&lt;/code&gt; where &lt;code&gt;p-1&lt;/code&gt; has a large prime factor, precisely so the &lt;code&gt;p-1&lt;/code&gt; attack could not bite.The strong-prime design rule is a direct descendant of Pollard&apos;s 1974 &lt;code&gt;p-1&lt;/code&gt; method [@pollard-pm1-1974]. Modern guidance mostly dropped the requirement once GNFS made the specific structure of &lt;code&gt;p-1&lt;/code&gt; irrelevant to the dominant attack, but the historical lineage is exact. And one rung of the ladder never went away, it just found a different job.Hendrik Lenstra&apos;s Elliptic Curve Method (1987) has a running time that depends on the size of the &lt;em&gt;smallest&lt;/em&gt; factor, not the whole modulus [@lenstra-ecm-1987]. That makes it superb at peeling small primes off a number and useless against a balanced RSA modulus whose two factors are each half the bits. It is a living tool, in the wrong weight class for this fight.&lt;/p&gt;
&lt;p&gt;The slow lane also has a recurring failure mode that is not technical but sociological, and it is worth immunizing against before the fast lane tempts you.&lt;/p&gt;

Every few years, a preprint claims to have shattered RSA, and every few years it evaporates on contact with implementation. The cleanest recent specimen is Claus Schnorr&apos;s 2021 IACR ePrint, whose abstract ended with the sentence &quot;This destroys the RSA cryptosystem&quot; [@schnorr-eprint-2021; @schneier-2021]. It did not. The claimed speedup relied on finding enough short lattice vectors to generate factoring relations, and when Leo Ducas implemented the method as *SchnorrGate*, it produced zero usable relations at cryptographic size [@ducas-schnorrgate]. Bruce Schneier&apos;s response carried the whole verdict in its title, and later revisions of the preprint quietly deleted the offending sentence [@schneier-2021]. The lesson is durable: an extraordinary cryptanalytic claim is worth exactly as much as its implementation, and until someone factors a real challenge number, the record trajectory stands.

&quot;No, RSA Is Not Broken.&quot; -- Bruce Schneier, on the 2021 claim that short-vector lattice algorithms had destroyed the RSA cryptosystem [@schneier-2021].
&lt;p&gt;So the front door is bolted, and it opens only at a crawl. Fifty years of the best available mathematics moved the record about 400 bits, and the cost curve guarantees the next 1,200 bits are not coming on any classical machine. A defender who only worries about factoring has been watching the wrong door. Because a locksmith&apos;s insight changes the whole game: what if you never had to open the front door at all? What if you never factored &lt;code&gt;N&lt;/code&gt;?&lt;/p&gt;
&lt;h2&gt;4. The fast lane opens: Hastad and Wiener&lt;/h2&gt;
&lt;p&gt;The insight that reroutes the entire story is deceptively small: you do not have to factor &lt;code&gt;N&lt;/code&gt; at all. Factoring is the &lt;em&gt;hardest&lt;/em&gt; way to break RSA, not the easiest. If the way this particular key or this particular message was built leaks structure, the key can fall in polynomial time, and &lt;code&gt;N&lt;/code&gt; stays untouched the whole time. Two attacks from the late 1980s and early 1990s proved the fast lane exists, and each one falls out of a single leaked parameter.&lt;/p&gt;
&lt;p&gt;The first is &lt;strong&gt;Johan Hastad&apos;s low-exponent broadcast attack&lt;/strong&gt; (introduced at CRYPTO &apos;85 and generalized in his 1988 SIAM paper). Suppose a sender uses a tiny public exponent, say $e = 3$, and sends the &lt;em&gt;same&lt;/em&gt; message &lt;code&gt;m&lt;/code&gt; to several recipients, each with their own modulus $N_i$, without randomized padding. Each recipient sees $c_i = m^3 \bmod N_i$. An eavesdropper who collects three of these ciphertexts applies the Chinese Remainder Theorem to combine them into a single value congruent to $m^3$ modulo $N_1 N_2 N_3$ [@hastad-1988].&lt;/p&gt;
&lt;p&gt;Since &lt;code&gt;m&lt;/code&gt; is smaller than every $N_i$, the true $m^3$ is smaller than the product $N_1 N_2 N_3$, so the combined congruence is an &lt;em&gt;equation over the integers&lt;/em&gt;: the combined value simply equals $m^3$, with no modular wraparound. Take an ordinary integer cube root and you have the message. No factoring, no lattice, just arithmetic [@hastad-1988].&lt;/p&gt;
&lt;p&gt;The precondition is loud, and it is the reason a good key is immune. Hastad needs a tiny exponent &lt;em&gt;and&lt;/em&gt; the same message broadcast unpadded to several recipients. Use $e = 65537$ instead of 3, or pad each message with fresh randomness so no two ciphertexts encrypt the same integer, and the broadcast structure that made $m^3$ recoverable is gone. The attack does not get slower; it stops applying.&lt;/p&gt;
&lt;p&gt;The second attack targets the other exponent. &lt;strong&gt;Michael Wiener&apos;s small private-exponent attack&lt;/strong&gt; (1990) shows that shrinking &lt;code&gt;d&lt;/code&gt; to speed up decryption is fatal. When the private exponent is small, specifically $d &amp;lt; \tfrac{1}{3}N^{1/4}$, the public ratio $e/N$ becomes an extraordinarily good rational approximation to the secret ratio $k/d$ that lurks in the key equation [@wiener-1990]. And there is a classical theorem of number theory that says the &lt;em&gt;only&lt;/em&gt; fractions that approximate a real number that well are its continued-fraction convergents. So the attacker expands $e/N$ as a continued fraction, and the secret denominator &lt;code&gt;d&lt;/code&gt; appears as one of the convergents&apos; denominators, recovered from nothing but the public key &lt;code&gt;(e, N)&lt;/code&gt; [@wiener-1990].&lt;/p&gt;

Any real number can be written as a nested fraction $a_0 + 1/(a_1 + 1/(a_2 + \cdots))$. Truncating that expansion after a few terms gives a sequence of rational approximations $h_i/k_i$ called convergents, and they are provably the *best* rational approximations for their denominator size. Wiener&apos;s attack turns key recovery into a search through the convergents of $e/N$: one of their denominators is the secret exponent `d`.
&lt;p&gt;Because the whole attack is a short walk through a list of fractions, it is genuinely fast, and it is easy to watch happen. The code below builds an RSA key with a deliberately small &lt;code&gt;d&lt;/code&gt;, publishes only &lt;code&gt;(e, N)&lt;/code&gt;, and then recovers &lt;code&gt;d&lt;/code&gt; from the public key alone.&lt;/p&gt;
&lt;p&gt;{`
from math import isqrt, gcd&lt;/p&gt;
Build a deliberately weak RSA key with a very small private exponent d.
&lt;p&gt;p = 999999937
q = 999999893
N = p * q
phi = (p - 1) * (q - 1)&lt;/p&gt;
Wiener succeeds whenever d &amp;lt; (1/3) * N**(1/4). Take the largest such d.
&lt;p&gt;bound = isqrt(isqrt(N)) // 3
d = next(x for x in range(bound, 2, -1) if gcd(x, phi) == 1)
e = pow(d, -1, phi)                      # matching public exponent
print(&quot;Public key:  N =&quot;, N)
print(&quot;             e =&quot;, e)
print(&quot;Hidden small d =&quot;, d, &quot; (Wiener bound about&quot;, bound, &quot;)&quot;)&lt;/p&gt;
The attacker sees only (e, N). Expand e/N as a continued fraction;
each convergent&apos;s denominator is a candidate for d.
&lt;p&gt;def convergents(num, den):
    a = []
    x, y = num, den
    while y:
        a.append(x // y)
        x, y = y, x % y
    h0, h1 = 0, 1
    k0, k1 = 1, 0
    for ai in a:
        h0, h1 = h1, ai * h1 + h0
        k0, k1 = k1, ai * k1 + k0
        yield h1, k1                     # (candidate k, candidate d)&lt;/p&gt;
&lt;p&gt;for k_cand, d_cand in convergents(e, N):
    if k_cand == 0:
        continue
    if (e * d_cand - 1) % k_cand == 0:           # phi(N) must be an integer
        phi_guess = (e * d_cand - 1) // k_cand
        s = N - phi_guess + 1                    # candidate p + q
        disc = s * s - 4 * N                     # roots of x^2 - s*x + N
        if disc &amp;gt;= 0 and isqrt(disc) ** 2 == disc:
            print(&quot;Recovered d =&quot;, d_cand, &quot; correct:&quot;, d_cand == d)
            break
`}&lt;/p&gt;
&lt;p&gt;Once again the precondition is the whole story. Wiener needs a small &lt;code&gt;d&lt;/code&gt;. A correctly generated key uses a full-size random &lt;code&gt;d&lt;/code&gt; on the order of &lt;code&gt;N&lt;/code&gt; itself, and there is no low-denominator convergent of $e/N$ to find, so the attack has nothing to grab.&lt;/p&gt;
&lt;p&gt;Notice what these two attacks share, and where each falls short. Both exploit a &lt;em&gt;leaked parameter&lt;/em&gt;, not the modulus. Both run in polynomial time. And both were, at first, treated as clever isolated tricks: a broadcast maneuver here, a continued-fraction maneuver there. Hastad even needs an awkward number of near-identical ciphertexts, and Wiener&apos;s $N^{1/4}$ bound is visibly loose, as if it could be pushed further with a better tool. For eight years the fast lane stayed a grab-bag of one-offs. Then someone found the single principle hiding underneath all of them.&lt;/p&gt;
&lt;h2&gt;5. Coppersmith&apos;s master key&lt;/h2&gt;
&lt;p&gt;In 1996, Don Coppersmith found the idea that turned the grab-bag into a theory. Stated plainly, it is one of the most useful facts in applied cryptography, and once you see it you cannot unsee it in any of the fast-lane attacks.&lt;/p&gt;
&lt;p&gt;Here is the theorem. Take a polynomial $f(x)$ of degree &lt;code&gt;d&lt;/code&gt;, and suppose it has a root $x_0$ modulo &lt;code&gt;N&lt;/code&gt; that is &lt;em&gt;small&lt;/em&gt;, meaning $|x_0| &amp;lt; N^{1/d}$. Then you can find $x_0$ in time polynomial in $\log N$ and &lt;code&gt;d&lt;/code&gt;, using lattice reduction [@coppersmith-1997]. That is the whole master key. Not &quot;factor &lt;code&gt;N&lt;/code&gt;,&quot; not &quot;guess the message,&quot; but: whenever an unknown quantity is &lt;em&gt;small&lt;/em&gt; and sits inside a &lt;em&gt;known&lt;/em&gt; algebraic structure, you can solve for it directly.&lt;/p&gt;

A lattice is the set of all integer combinations of some basis vectors, an infinite grid of points in space. The same lattice has many bases, some &quot;long and skew,&quot; some &quot;short and nearly perpendicular.&quot; The Lenstra-Lenstra-Lovasz (LLL) algorithm, from 1982, efficiently turns a bad basis into a reduced one whose vectors are short and close to orthogonal. Throughout this article LLL is a black box with one job: hand it a lattice, and it returns a surprisingly short vector in polynomial time [@may-survey-2009].
&lt;p&gt;The bridge from &quot;small modular root&quot; to &quot;short lattice vector&quot; is the contribution of Nick Howgrave-Graham (1997), whose reformulation is the version taught and coded today [@howgrave-graham-1997]. The trick is elegant. You do not attack $f$ directly. Instead you build a lattice out of shifted and scaled multiples of $f$, all of which vanish at the same secret root $x_0$ modulo powers of &lt;code&gt;N&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;LLL finds a short combination of them, and shortness has a precise payoff: a polynomial with small enough coefficients that, at the small value $x_0$, it cannot merely be &lt;em&gt;congruent&lt;/em&gt; to zero modulo &lt;code&gt;N&lt;/code&gt;; it must be &lt;em&gt;exactly&lt;/em&gt; zero as an integer [@howgrave-graham-1997]. The modular problem has become an ordinary equation over the integers, and ordinary equations over the integers are easy to solve for their roots. That is the same &quot;collapse to the integers&quot; trick that let Hastad&apos;s cube root work, generalized into a machine.&lt;/p&gt;

flowchart LR
    A[&quot;Known structure plus a small unknown&quot;] --&amp;gt; B[&quot;Write it as f(x) with a small root mod N&quot;]
    B --&amp;gt; C[&quot;Build a lattice from shifted multiples of f&quot;]
    C --&amp;gt; D[&quot;LLL returns a short vector&quot;]
    D --&amp;gt; E[&quot;A new polynomial, same root, small enough to hold over the integers&quot;]
    E --&amp;gt; F[&quot;Ordinary root-finding recovers x0&quot;]

A polynomial-time algorithm that, given a monic polynomial $f(x)$ of degree `d` and a modulus `N`, finds every integer root $x_0$ with $|x_0| &amp;lt; N^{1/d}$ satisfying $f(x_0) \equiv 0 \pmod{N}$ [@coppersmith-1997]. The size bound $N^{1/d}$ is the load-bearing threshold: it is generous for tiny degree (a cube-root-sized unknown for $d = 3$) and shrinks fast as the degree grows, which is exactly why a large public exponent starves the method of anything to find.
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Every fast-lane attack in this article is the same sentence in a different costume: known structure plus a small unknown lets you solve for the unknown. Hastad&apos;s broadcast, stereotyped messages, related messages, partial key exposure, and the strongest small-&lt;code&gt;d&lt;/code&gt; attack are all instances of Coppersmith&apos;s small-root method, powered by LLL whenever the unknown is smaller than $N^{1/d}$. The zoo is one animal.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Watch Hastad collapse to a corollary. His broadcast attack is just the small-root method for the polynomial $f(x) = x^e - c$ with the tiny exponent making the root findable; the CRT step is a convenience, not the essence [@coppersmith-1997]. The purest instance of all is textbook RSA with $e = 3$ and no padding, where the message itself is the small root. If $m^3 &amp;lt; N$, the ciphertext never wrapped around the modulus, so the &quot;encryption&quot; is just a cube, and a cube root is the entire attack.&lt;/p&gt;
&lt;p&gt;{`
def icbrt(n):
    # Exact integer cube root via Newton&apos;s method (works for huge integers).
    if n &amp;lt; 2:
        return n
    x = 1 &amp;lt;&amp;lt; ((n.bit_length() + 2) // 3)
    while True:
        y = (2 * x + n // (x * x)) // 3
        if y &amp;gt;= x:
            return x
        x = y&lt;/p&gt;
&lt;p&gt;N = (1 &amp;lt;&amp;lt; 2047) + 12345      # a 2048-bit stand-in modulus
e = 3
m = 42424242424242           # a short message: m^3 stays far below N
c = pow(m, e, N)             # textbook RSA &quot;encryption&quot;: c = m^3 mod N&lt;/p&gt;
&lt;p&gt;print(&quot;Is m^3 &amp;lt; N ?&quot;, m**3 &amp;lt; N)
print(&quot;recovered m =&quot;, icbrt(c), &quot; correct:&quot;, icbrt(c) == m)&lt;/p&gt;
Real padding widens the message so that m2^3 exceeds N and wraps around.
&lt;p&gt;m2 = (1 &amp;lt;&amp;lt; 700) | m
c2 = pow(m2, e, N)
print(&quot;Is (padded m2)^3 &amp;lt; N ?&quot;, m2**3 &amp;lt; N)
print(&quot;plain cube root now fails:&quot;, icbrt(c2) != m2)
`}&lt;/p&gt;
&lt;p&gt;The second half of that snippet is the entire defense in miniature. Once the message is widened by real padding so that its cube exceeds &lt;code&gt;N&lt;/code&gt;, the ciphertext wraps around the modulus, the &quot;small root&quot; is no longer small, and the cube root returns garbage. The attack did not get harder to run; its precondition vanished. Hold onto that distinction, because it is the shape of every result in the next section: one theorem, many doors. So which locks does the master key actually open on a real RSA deployment, and, just as important, which ones stay firmly shut?&lt;/p&gt;
&lt;h2&gt;6. The Coppersmith family today&lt;/h2&gt;
&lt;p&gt;The mature fast lane is the master key reused, deliberately, by name. Each member of the family has the same shape, known structure hiding one small unknown, and each is neutralized by exactly one standard parameter choice. Walk them in order and the pattern becomes impossible to miss.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Stereotyped and known-bits messages.&lt;/strong&gt; Suppose an attacker knows most of a message, a fixed template &lt;code&gt;B&lt;/code&gt;, and only a short secret block &lt;code&gt;x&lt;/code&gt; is unknown, so the plaintext is $B + x$. With public exponent &lt;code&gt;e&lt;/code&gt;, the ciphertext gives the polynomial $f(x) = (B + x)^e - c$, whose small root is the secret block, recoverable whenever $|x| &amp;lt; N^{1/e}$ [@coppersmith-1997]. A low exponent and a mostly-known message is all it takes. Raise &lt;code&gt;e&lt;/code&gt; to 65537 and the recoverable window $N^{1/e}$ shrinks to almost nothing; randomize the message with padding and the &quot;small unknown&quot; becomes the entire plaintext, far too big to be a small root.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Factoring with high bits of &lt;code&gt;p&lt;/code&gt; known.&lt;/strong&gt; Coppersmith&apos;s method also attacks the modulus, but only with a head start. If an attacker already knows roughly the top half of the bits of &lt;code&gt;p&lt;/code&gt;, the remaining low bits form a small root of a polynomial modulo &lt;code&gt;N&lt;/code&gt;, and the method recovers them, factoring &lt;code&gt;N&lt;/code&gt; in polynomial time [@coppersmith-1997; @may-survey-2009]. The precondition is severe: you must already know half of a secret prime. Generate both primes from a good random source and no such head start exists.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Related messages and short pads.&lt;/strong&gt; If two messages satisfy a &lt;em&gt;known linear relation&lt;/em&gt; and are sent under the same small exponent, the attacker forms two polynomials sharing the plaintext as a root and takes their polynomial greatest common divisor, which reveals it. This is the Franklin-Reiter base case [@cfpr-1996]. Coppersmith extended it to the case where the relation is an &lt;em&gt;unknown but short&lt;/em&gt; pad, solved with the small-root method, the short-pad attack [@cfpr-1996]. Both need a small &lt;code&gt;e&lt;/code&gt; and a short or structured relationship between messages. &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;OAEP&lt;/a&gt;&apos;s long, fully random pad destroys any such relation, which is precisely what it was designed to do.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Partial key exposure.&lt;/strong&gt; Perhaps the most unsettling member: a &lt;em&gt;fraction&lt;/em&gt; of the private key&apos;s bits can reconstruct the rest. Boneh, Durfee, and Frankel showed in 1998 that for a low public exponent, roughly a quarter of the least-significant bits of &lt;code&gt;d&lt;/code&gt; suffice to recover the whole exponent [@bdf98-1998]. Ernst, Jochemsz, May, and de Weger removed the low-exponent restriction in 2005, extending partial key exposure to full-size exponents with multivariate Coppersmith techniques [@ernst-pke-2005]. The precondition is a &lt;em&gt;leak&lt;/em&gt;: some bits of &lt;code&gt;d&lt;/code&gt; or &lt;code&gt;p&lt;/code&gt; must escape. With no leakage, there is nothing to extend, and &lt;em&gt;how&lt;/em&gt; bits leak, timing, power, a fault, is the implementation sibling&apos;s subject, not RSA&apos;s mathematics.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Boneh-Durfee.&lt;/strong&gt; Finally, the master key circles back to finish what Wiener started. Boneh and Durfee re-aimed Coppersmith&apos;s lattice at the key equation itself and pushed the vulnerable small-&lt;code&gt;d&lt;/code&gt; bound from Wiener&apos;s $N^{1/4}$ up to $d &amp;lt; N^{0.292}$, the strongest small-exponent attack known [@boneh-durfee-1999]. It is the same lattice engine, pointed at a different polynomial. And it dies against the same defense: a full-size random &lt;code&gt;d&lt;/code&gt; on the order of &lt;code&gt;N&lt;/code&gt; sits far above the $N^{0.292}$ threshold.&lt;/p&gt;
&lt;p&gt;These are cryptanalytic tools, not shipped software, but they are entirely practical to run. LLL and its stronger cousin BKZ live in the open-source &lt;strong&gt;fplll&lt;/strong&gt; library and its Python binding &lt;strong&gt;fpylll&lt;/strong&gt; [@fplll; @fpylll], and Coppersmith&apos;s small-root method is a single function call, &lt;code&gt;small_roots()&lt;/code&gt;, in SageMath [@sagemath-smallroots]. The barrier to using them is never the tooling. It is finding a key with a precondition to attack.&lt;/p&gt;

A stereotyped-message attack in SageMath looks close to this: work in `Zmod(N)`, define the polynomial `f = (B + x)^e - c` whose small root is the secret block, and call `f.small_roots(X=bound, beta=1)`. The library builds the lattice, runs LLL, and returns the root, with no hand-rolled lattice at all [@sagemath-smallroots]. Swap in a different `f` and the same call becomes factoring-with-known-bits or a related-message attack: one engine, pointed at a different polynomial.

flowchart TD
    E[&quot;Coppersmith small-root engine&quot;] --&amp;gt; A[&quot;Stereotyped or known-bits message: short secret block&quot;]
    E --&amp;gt; B[&quot;Factoring with high bits of p known: half of p leaks&quot;]
    E --&amp;gt; C[&quot;Franklin-Reiter and short-pad: same small e, short or known pad&quot;]
    E --&amp;gt; D[&quot;Partial key exposure: a fraction of d&apos;s bits leak&quot;]
    E --&amp;gt; F[&quot;Boneh-Durfee: deliberately small private exponent d&quot;]
&lt;p&gt;Lay the whole family in a table and the argument writes itself. Every row is a real, polynomial-time attack. Every row also has a right-hand column that a correctly generated RSA-2048 key fills in by default.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Fast-lane attack&lt;/th&gt;
&lt;th&gt;Exact precondition it needs&lt;/th&gt;
&lt;th&gt;Closed by&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Hastad broadcast&lt;/td&gt;
&lt;td&gt;tiny &lt;code&gt;e&lt;/code&gt;, same message sent unpadded to many recipients&lt;/td&gt;
&lt;td&gt;$e = 65537$ or randomized padding [@hastad-1988]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stereotyped / known-bits&lt;/td&gt;
&lt;td&gt;most of the message is a known template, short secret block&lt;/td&gt;
&lt;td&gt;randomized OAEP padding [@rfc8017]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Factoring, high bits of &lt;code&gt;p&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;roughly half the top bits of &lt;code&gt;p&lt;/code&gt; already known&lt;/td&gt;
&lt;td&gt;independent, well-sourced random primes [@may-survey-2009]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Franklin-Reiter / short-pad&lt;/td&gt;
&lt;td&gt;same small &lt;code&gt;e&lt;/code&gt;, a known or short relation between messages&lt;/td&gt;
&lt;td&gt;$e = 65537$ plus OAEP&apos;s long random pad [@cfpr-1996]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Partial key exposure&lt;/td&gt;
&lt;td&gt;a constant fraction of &lt;code&gt;d&lt;/code&gt;&apos;s or &lt;code&gt;p&lt;/code&gt;&apos;s bits leaked&lt;/td&gt;
&lt;td&gt;no key-bit leakage; full-size random &lt;code&gt;d&lt;/code&gt; [@ernst-pke-2005]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wiener small-&lt;code&gt;d&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;$d &amp;lt; \tfrac{1}{3}N^{1/4}$&lt;/td&gt;
&lt;td&gt;full-size random &lt;code&gt;d&lt;/code&gt; [@wiener-1990]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Boneh-Durfee small-&lt;code&gt;d&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;$d &amp;lt; N^{0.292}$&lt;/td&gt;
&lt;td&gt;full-size random &lt;code&gt;d&lt;/code&gt; near &lt;code&gt;N&lt;/code&gt; [@boneh-durfee-1999]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

The randomized padding scheme standardized for RSA encryption in PKCS #1 v2.2 (RFC 8017) [@rfc8017]. Before exponentiation, OAEP mixes the message with fresh random bytes through a two-round structure, so that the integer actually raised to the power `e` is large, high-entropy, and different every time, even for identical plaintexts. That single step removes the &quot;known structure&quot; and the &quot;small unknown&quot; that every Coppersmith-family attack needs, which is why OAEP is the defense that closes most of the table at once.
&lt;p&gt;There is something almost paradoxical here, and it is the sharpest structural point in all of RSA cryptanalysis. None of these attacks is wrong. None is slow. None has been refuted or patched away. They remain perfectly correct, polynomial-time algorithms. They are simply &lt;em&gt;inapplicable&lt;/em&gt; to a key that never grants their precondition. The fast lane does not fail against a good key by being outrun, the way the slow lane is outrun by a big modulus. It fails by &lt;em&gt;precondition-absence&lt;/em&gt;: there is nothing for the lattice to grab.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This is the mental model to keep. A larger key defeats the slow lane by making factoring more expensive. Nothing defeats the fast lane, because the fast lane was never a contest of speed. It is a contest of &lt;em&gt;whether a defect exists&lt;/em&gt;. Remove the defect, small exponent, small &lt;code&gt;d&lt;/code&gt;, missing padding, leaked bits, correlated primes, and each attack does not slow down; it simply has no input. A correct RSA-2048 key wins the fast lane by forfeit.&lt;/p&gt;
&lt;/blockquote&gt;

An attack that is perfectly correct yet perfectly inapplicable is the sharpest point in RSA cryptanalysis. Against a well-generated key, the fast lane has no applicable attack.
&lt;p&gt;So put the two lanes together against a specific, correct target: RSA-2048 with $e = 65537$, a full-size random &lt;code&gt;d&lt;/code&gt;, two independent well-sourced primes, and OAEP padding. The slow lane is available but glacial, more than 1,200 bits and an astronomical cost curve away from success. The fast lane is polynomial but inert, because every precondition in the table above is absent [@boneh-survey-1999; @rfc8017]. Against that key, the classical state of the art is a phrase worth memorizing: &lt;em&gt;no applicable attack.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The fast lane is fast but conditional; the slow lane is universal but glacial. Put all three roads on one table, and ask the only question that matters: which one actually threatens a well-generated key?&lt;/p&gt;
&lt;h2&gt;7. Three roads, compared&lt;/h2&gt;
&lt;p&gt;Everything so far has been building one picture. Lay the slow lane, the fast lane, and the third road side by side, and the article&apos;s thesis stops being a claim and becomes something you can read straight off a table.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;Slow lane: GNFS&lt;/th&gt;
&lt;th&gt;Fast lane: Coppersmith family&lt;/th&gt;
&lt;th&gt;Third road: Shor&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;What it attacks&lt;/td&gt;
&lt;td&gt;the hardness assumption (factor &lt;code&gt;N&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;the instantiation (a specific defect)&lt;/td&gt;
&lt;td&gt;the hardness assumption (factor &lt;code&gt;N&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Input required&lt;/td&gt;
&lt;td&gt;&lt;code&gt;N&lt;/code&gt; only&lt;/td&gt;
&lt;td&gt;&lt;code&gt;N&lt;/code&gt; plus a parameter or key-gen defect&lt;/td&gt;
&lt;td&gt;&lt;code&gt;N&lt;/code&gt; only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Precondition&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;td&gt;small &lt;code&gt;e&lt;/code&gt;, small &lt;code&gt;d&lt;/code&gt;, no padding, leaked bits, or correlated primes&lt;/td&gt;
&lt;td&gt;a working quantum computer of the right size&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Worst-case time&lt;/td&gt;
&lt;td&gt;$L_N[1/3, 1.923]$, sub-exponential&lt;/td&gt;
&lt;td&gt;polynomial&lt;/td&gt;
&lt;td&gt;polynomial in $\log N$&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Breaks a correct RSA-2048 key?&lt;/td&gt;
&lt;td&gt;not in practice&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Computational model&lt;/td&gt;
&lt;td&gt;classical&lt;/td&gt;
&lt;td&gt;classical&lt;/td&gt;
&lt;td&gt;quantum&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Read the table as three sentences. The &lt;strong&gt;slow lane&lt;/strong&gt; breaks &lt;em&gt;any&lt;/em&gt; key, needs no mistake, and is asymptotically stalled: its $L_N[1/3, 1.923]$ cost has not improved since 1990, and against 2048 bits it is glacial [@lenstra-nfs-1990]. The &lt;strong&gt;fast lane&lt;/strong&gt; is genuinely polynomial and genuinely fast, but it goes completely dark against a correct key, because every one of its attacks needs a defect the key does not have [@coppersmith-1997]. Two roads, and &lt;em&gt;neither&lt;/em&gt; threatens a well-generated RSA-2048 key in practice: one is too slow, the other has no opening.&lt;/p&gt;
&lt;p&gt;That is the corner the argument has painted us into, and it forces the third road into view. If the slow lane is stalled and the fast lane is inert, then the only way to break a correct key is to stop playing the classical game entirely, to change the &lt;em&gt;machine&lt;/em&gt;. That is Shor&apos;s algorithm, first announced at FOCS in 1994 and published in full in 1997 [@shor-focs-1994; @shor-siam-1997].&lt;/p&gt;
&lt;p&gt;It attacks the same hardness assumption as the slow lane, factoring &lt;code&gt;N&lt;/code&gt; with no defect required, but it runs in time polynomial in the number of digits of &lt;code&gt;N&lt;/code&gt;, an exponential speedup over GNFS. It is the one entry in the table that breaks a flawless key, and it carries the one precondition no careful key generation can supply or deny: a large, fault-tolerant quantum computer, which does not exist as of 2026.&lt;/p&gt;
&lt;p&gt;The mechanism is the subject of the next section; for now, the table has delivered its verdict. The only structural attack left standing against a good key is a change of computational model.&lt;/p&gt;
&lt;p&gt;That verdict points at one uncomfortable question the table cannot answer. The slow lane is stalled, and we have been treating that as if it were a law of nature. But is factoring &lt;em&gt;actually&lt;/em&gt; hard, or have we simply not found the trick yet? The honest answer is more unsettling than either the optimists or the doomsayers usually admit.&lt;/p&gt;
&lt;h2&gt;8. Is factoring even hard, and how hard?&lt;/h2&gt;
&lt;p&gt;Beneath fifty years of engineering confidence lies an uncomfortable truth: nobody has ever &lt;em&gt;proven&lt;/em&gt; that factoring is hard. RSA&apos;s security is a conjecture that has survived a long time, which is a very different thing from a theorem.&lt;/p&gt;
&lt;p&gt;Start with the most common misconception, because correcting it reframes everything. People often say factoring is NP-hard, as if RSA inherited the full difficulty of the hardest problems in NP. It did not. The decision version of factoring sits in $\text{NP} \cap \text{co-NP}$: a factor is a short certificate that the answer is &quot;yes,&quot; and because primality can be checked efficiently, there is also a short certificate for &quot;no&quot; [@hac-1996]. A problem in that intersection cannot be NP-complete unless NP equals co-NP, which almost no one believes.&lt;/p&gt;
&lt;p&gt;So factoring is very likely &lt;em&gt;not&lt;/em&gt; among the hardest problems in NP, and the casual &quot;RSA is NP-hard&quot; intuition is simply false [@hac-1996].&lt;/p&gt;
&lt;p&gt;It may be worse than that, in a precise and interesting way: breaking RSA might be &lt;em&gt;strictly easier&lt;/em&gt; than factoring. Boneh and Venkatesan gave evidence that no &quot;algebraic reduction&quot; can turn an efficient low-exponent RSA-breaker into a general factoring algorithm, which would mean recovering a message does not require the full strength of factoring [@boneh-venkatesan-1998].&lt;/p&gt;
&lt;p&gt;Aggarwal and Maurer later proved that breaking RSA &lt;em&gt;is&lt;/em&gt; equivalent to factoring, but only in the restricted &quot;generic ring model,&quot; where the attacker is forbidden from exploiting the specific bit-representation of numbers [@aggarwal-maurer-2009]. Put together, the honest statement is that we do not know whether the RSA problem and factoring are equally hard. We only know the assumption rests on belief, layered on belief.&lt;/p&gt;
&lt;p&gt;What we &lt;em&gt;can&lt;/em&gt; state precisely are the upper bounds, and the gap between them is the whole story. Classically, the best we can do is GNFS, sub-exponential $L_N[1/3, 1.923]$ [@lenstra-nfs-1990]. On a quantum computer, Shor&apos;s algorithm factors in time polynomial in the number of digits of &lt;code&gt;N&lt;/code&gt;, an exponential improvement [@shor-siam-1997].&lt;/p&gt;
&lt;p&gt;There is no known classical &lt;em&gt;lower&lt;/em&gt; bound anywhere near the upper bound, so the space between &quot;maybe there is a fast classical algorithm we have not found&quot; and &quot;there is definitely a fast quantum algorithm&quot; is enormous and almost entirely unmapped.&lt;/p&gt;
&lt;p&gt;Shor&apos;s mechanism deserves to be seen, because it is not a faster search; it is a genuinely different idea. Factoring &lt;code&gt;N&lt;/code&gt; is reduced to finding the &lt;em&gt;period&lt;/em&gt; of the function $a^x \bmod N$ for a random base &lt;code&gt;a&lt;/code&gt;, that is, the smallest &lt;code&gt;r&lt;/code&gt; with $a^r \equiv 1 \pmod{N}$. Classically, finding that period is as hard as factoring.&lt;/p&gt;
&lt;p&gt;Quantumly, a superposition over all &lt;code&gt;x&lt;/code&gt;, a modular exponentiation, and a quantum Fourier transform extract &lt;code&gt;r&lt;/code&gt; efficiently. Once you have an even &lt;code&gt;r&lt;/code&gt; with $a^{r/2} \not\equiv -1 \pmod N$, an ordinary classical greatest-common-divisor, $\gcd(a^{r/2} \pm 1, N)$, hands you a factor [@shor-siam-1997]. It is a classical reduction wrapped around a single quantum subroutine.&lt;/p&gt;

flowchart TD
    A[&quot;Pick a random a coprime to N&quot;] --&amp;gt; B[&quot;Quantum: find the period r of a^x mod N with the QFT&quot;]
    B --&amp;gt; C{&quot;r even and a^(r/2) not congruent to -1?&quot;}
    C --&amp;gt;|&quot;no, retry&quot;| A
    C --&amp;gt;|&quot;yes&quot;| D[&quot;Classical: compute gcd(a^(r/2) plus or minus 1, N)&quot;]
    D --&amp;gt; E[&quot;A nontrivial factor of N&quot;]

A quantum computer large and reliable enough to run Shor&apos;s algorithm against real cryptographic parameters, for example to factor a 2048-bit RSA modulus. Because Shor needs many high-fidelity logical qubits maintained through a long computation, a CRQC requires fault-tolerant error correction over a vast number of physical qubits. No such machine exists as of 2026, and building one is an unsolved engineering problem, not merely a matter of scaling up today&apos;s devices.
&lt;p&gt;How far is that machine? The honest answer comes from the people doing the most careful accounting, and their numbers are moving in a way worth understanding. In 2019, Craig Gidney and Martin Ekera estimated that factoring a 2048-bit RSA key with Shor would take roughly 20 million noisy physical qubits running for about 8 hours [@gidney-ekera-2021]. In May 2025, Gidney revised the estimate to &lt;em&gt;fewer than one million&lt;/em&gt; noisy qubits in under a week, under the &lt;em&gt;same&lt;/em&gt; hardware assumptions as the 2019 analysis [@gidney-2025].&lt;/p&gt;
&lt;p&gt;Read those two figures together carefully. The twentyfold drop did not come from better hardware; it came from better &lt;em&gt;algorithms&lt;/em&gt; for organizing the computation. The &lt;em&gt;estimate&lt;/em&gt; is improving far faster than the &lt;em&gt;machines&lt;/em&gt;, and today&apos;s largest quantum devices remain orders of magnitude below even the reduced requirement [@gidney-2025]. No cryptographically relevant quantum computer exists as of 2026.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; It is easy to slide from &quot;the resource estimates are dropping fast&quot; to &quot;a quantum break is imminent.&quot; That slide is not supported here. As of 2026 there is no machine capable of running Shor against RSA-2048, and predicting when, or whether, one will be built is genuinely uncertain. What the falling estimates establish is that the &lt;em&gt;paper cost&lt;/em&gt; of the attack is shrinking, not that the &lt;em&gt;hardware&lt;/em&gt; has arrived. Treat any specific date you see quoted, from anyone, as a forecast, not a fact.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Two facts about scale make the quantum threat qualitatively different from the classical one, and both cut against the defender&apos;s usual instinct. First, a bigger key does not help. Shor&apos;s cost grows only &lt;em&gt;polynomially&lt;/em&gt; in the number of digits of &lt;code&gt;N&lt;/code&gt;, so doubling the modulus from 2048 to 4096 bits multiplies the quantum work by a small constant, not by the astronomical factor that same doubling imposes on GNFS. The move that defeats the slow lane is nearly useless against the third road.&lt;/p&gt;
&lt;p&gt;Second, and for the same reason, there is no &quot;safe classical margin&quot; to buy. Against Shor, the defense is not a larger RSA key; it is a different kind of cryptography entirely.&lt;/p&gt;

Grover&apos;s algorithm is the other quantum result people invoke, and it is a boundary marker, not a structural break [@grover-1996]. It gives a generic square-root speedup for brute-force search, turning a $2^{n}$ key search into about $2^{n/2}$. That halves the effective strength of a symmetric key, which is why AES-256 is favored for post-quantum margin [@nist-sp800-57], but it does nothing structural to RSA: it does not factor `N`, and a square-root speedup on an already-astronomical factoring search changes nothing.
&lt;p&gt;Sit with what this section actually established, because it is the third and deepest shift in the whole article. We cannot prove factoring is hard; its decision problem is not even NP-complete, so RSA rests on a belief rather than a theorem. The fast lane is inert against a correct key, and the slow lane has been asymptotically frozen since 1990. Therefore the only structural break left standing against a well-generated key is a change of computational model, Shor&apos;s, and against that change a bigger key does essentially nothing.&lt;/p&gt;
&lt;p&gt;The confidence that &quot;a large enough RSA key is safe forever&quot; quietly dissolves. What replaces it is not panic but humility: the security you rely on is an assumption with a possible expiry date you cannot see.&lt;/p&gt;
&lt;p&gt;So we cannot prove it is hard, and we cannot yet build the machine that makes it easy. That leaves a precise list of things the field genuinely does not know, and one of them carries a deadline that is invisible precisely because no one can read it.&lt;/p&gt;
&lt;h2&gt;9. What is genuinely unresolved&lt;/h2&gt;
&lt;p&gt;Strip away the settled results and four honest unknowns remain. This is where the frontier actually sits, and naming the unknowns precisely is more useful than any confident prediction.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Is factoring in P?&lt;/strong&gt; No polynomial-time classical factoring algorithm is known, and none has been ruled out. The strongest evidence for &quot;hard&quot; is negative and empirical: the GNFS exponent has not moved off one third since 1990, and RSA-250 still stands as the largest general-purpose factorization [@lenstra-nfs-1990; @zimmermann-records]. But &quot;we have not found a faster algorithm in 35 years&quot; is not a proof that none exists, and no lower bound forbids one. This is the open problem the entire slow lane rests on.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Is the RSA problem strictly easier than factoring?&lt;/strong&gt; Also open. Boneh and Venkatesan&apos;s evidence points toward &quot;yes, at least for algebraic reductions,&quot; while Aggarwal and Maurer&apos;s equivalence holds only inside the generic ring model [@boneh-venkatesan-1998; @aggarwal-maurer-2009]. Whether recovering an RSA plaintext genuinely requires factoring, in the full model where an attacker can do anything, is unresolved.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How far can the small-&lt;code&gt;d&lt;/code&gt; lattice bound be pushed?&lt;/strong&gt; Boneh-Durfee reaches $d &amp;lt; N^{0.292}$, and Boneh and Durfee themselves conjecture the true insecurity threshold is $d &amp;lt; N^{0.5}$ [@boneh-durfee-1999]. The gap between $0.292$ and $0.5$ has resisted every attempt to close it, and subsequent lattice reformulations reach the same $0.292$ more cleanly without surpassing it [@may-survey-2009]. Nobody knows where the real boundary lies.&lt;/p&gt;

The exponent $0.292\ldots$ is not a round number; it is exactly $1 - 1/\sqrt{2} \approx 0.2929$, a quadratic irrational (the root of $2\delta^2 - 4\delta + 1 = 0$) that falls out of the lattice determinant condition [@boneh-durfee-1999]. Two honesty caveats travel with it: the conjectured true bound $N^{0.5}$ is only a conjecture, and even the proven $N^{0.292}$ result relies on the standard, unproven heuristic that the short lattice vectors LLL returns are algebraically independent. The fast lane&apos;s strongest result is itself built on an assumption.
&lt;p&gt;&lt;strong&gt;When does a cryptographically relevant quantum computer arrive?&lt;/strong&gt; Genuinely unknowable. And this is the unknown with teeth, because it does not need to be answered to be dangerous.&lt;/p&gt;

An attacker records encrypted traffic today and stores it, betting that a cryptographically relevant quantum computer will exist before the data stops being sensitive. When that machine arrives, the archived ciphertext is decrypted retroactively with Shor&apos;s algorithm. The threat is live *now*, even though the tool to exploit it does not exist yet, because the interception happens today and only the decryption waits.

Harvest-now-decrypt-later is what converts an unpredictable timeline into a present-day decision. If your data must stay confidential for ten or twenty years, medical records, state secrets, long-term financial or identity data, then the relevant question is not &quot;does a quantum computer exist today?&quot; but &quot;might one exist within the confidentiality lifetime of what I am encrypting now?&quot; For long-lived secrets, the honest answer is that you cannot rule it out, and the falling resource estimates make ruling it out harder each year [@gidney-2025]. That is the entire case for beginning migration to [post-quantum key-establishment](/blog/one-event-three-assumptions-five-answers-a-field-guide-to-th/) even though no CRQC exists and no credible timeline can be given. You are not reacting to a machine; you are protecting data whose lifetime outruns your ability to forecast.
&lt;p&gt;Unknowable timelines are not an excuse for paralysis. If you ship RSA today, all four open problems collapse into one concrete, answerable question: what do you actually &lt;em&gt;do&lt;/em&gt;?&lt;/p&gt;
&lt;h2&gt;10. How not to be the vulnerable key&lt;/h2&gt;
&lt;p&gt;Here is the practical reward for all this theory: every fast-lane attack in this article maps to exactly one parameter choice that closes it. The defense is not vigilance or luck. It is a short, checkable list, and mainstream libraries already implement most of it by default.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Do this&lt;/th&gt;
&lt;th&gt;It closes&lt;/th&gt;
&lt;th&gt;Anchor&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Use at least 2048-bit keys; 3072-bit for long-lived data&lt;/td&gt;
&lt;td&gt;the slow lane (GNFS)&lt;/td&gt;
&lt;td&gt;[@nist-sp800-57]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Set $e = 65537$, never 3&lt;/td&gt;
&lt;td&gt;Hastad, stereotyped, Franklin-Reiter and short-pad&lt;/td&gt;
&lt;td&gt;[@hastad-1988]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use a full-size random &lt;code&gt;d&lt;/code&gt;, never a small one&lt;/td&gt;
&lt;td&gt;Wiener, Boneh-Durfee&lt;/td&gt;
&lt;td&gt;[@boneh-durfee-1999]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Encrypt with OAEP, never textbook RSA&lt;/td&gt;
&lt;td&gt;known-bits and related-message recovery&lt;/td&gt;
&lt;td&gt;[@rfc8017]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generate two independent, well-sourced random primes&lt;/td&gt;
&lt;td&gt;known-bits-of-&lt;code&gt;p&lt;/code&gt; factoring&lt;/td&gt;
&lt;td&gt;[@may-survey-2009]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Begin migrating long-lived secrets to post-quantum schemes&lt;/td&gt;
&lt;td&gt;Shor plus harvest-now-decrypt-later&lt;/td&gt;
&lt;td&gt;[@gidney-2025]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;NIST maps key sizes to security levels calibrated directly against the GNFS cost curve: RSA-2048 gives roughly 112-bit security and RSA-3072 roughly 128-bit, which is why 3072 bits is the right choice for data that must survive well past 2030 [@nist-sp800-57]. That single row is the &lt;em&gt;only&lt;/em&gt; place where &quot;use a bigger key&quot; is the correct advice, because it is the only threat, the slow lane, that key size actually defends against.&lt;/p&gt;

Why $e = 65537$ specifically? It is $2^{16} + 1$, a Fermat prime. Being greater than the tiny exponents lets it defeat the low-exponent attacks, Hastad&apos;s broadcast, stereotyped-message recovery, Franklin-Reiter, while being only 17 bits long, with just two set bits, so encryption stays fast: a square-and-multiply exponentiation needs only 17 steps. It is the sweet spot: recommended by RFC 8017 [@rfc8017] and now the near-ubiquitous default in practice.
&lt;p&gt;The two scaling facts from the last two sections invert the usual intuition. A bigger key buys you &lt;em&gt;nothing&lt;/em&gt; against a fast-lane defect: an RSA-4096 key with a small &lt;code&gt;d&lt;/code&gt; falls to Wiener exactly as fast as an RSA-2048 key with a small &lt;code&gt;d&lt;/code&gt;, because the attack never touched the modulus size. And a bigger key buys you &lt;em&gt;nothing&lt;/em&gt; against Shor, whose cost grows only polynomially in the key length.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; A bigger RSA key does one thing: it makes the slow lane slower. It does nothing against a fast-lane defect, because those attacks ignore the modulus, and nothing against Shor, whose cost barely grows with key size. Security against the fast lane comes only from &lt;em&gt;removing the precondition&lt;/em&gt;; security against the third road comes only from &lt;em&gt;changing the primitive&lt;/em&gt;. Neither is bought with bits.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Use a 2048-bit key (3072-bit for long-lived data), the default $e = 65537$, a full-size random &lt;code&gt;d&lt;/code&gt;, two independent random primes from a vetted generator, and OAEP for encryption via your library&apos;s high-level API. That configuration closes the entire fast lane by construction and pushes the slow lane past any classical machine. The remaining work is not choosing better parameters, it is starting to plan a migration path for secrets whose confidentiality must outlast the arrival of a quantum computer.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;One honest reminder, because a checklist can create false comfort. This list closes the &lt;em&gt;structural&lt;/em&gt; attacks, the subject of this article. It does not, by itself, protect you from the implementation and protocol failures that break RSA far more often in the real world: padding oracles, timing and fault leaks, weak random-number generators, the ROCA key-generation defect, and downgrade attacks such as FREAK. Those are a different discipline, covered by the empirical sibling &lt;em&gt;How RSA Breaks in Real Life&lt;/em&gt;. A perfectly parameterized key in a leaky implementation is still a broken key.&lt;/p&gt;
&lt;p&gt;Follow the checklist and the entire fast lane goes dark while the slow lane stays glacial, which leaves exactly one way a correctly generated key ever breaks.&lt;/p&gt;
&lt;h2&gt;11. The verdict&lt;/h2&gt;
&lt;p&gt;Return to the two-speed map, now carrying everything the article has shown. The front door, factoring the modulus, is bolted, and it opens only at a crawl. In 26 years the classical record moved from RSA-129 to RSA-250, roughly 400 bits, and it is still more than 1,200 bits short of a deployed 2048-bit key, on a cost curve that makes the remaining distance astronomical [@zimmermann-records; @boudot-rsa250-2020]. The engineers who picture a break as &quot;someone factors my key&quot; are watching the one door a bigger key actually guards.&lt;/p&gt;
&lt;p&gt;The fast cracks come through side windows, and a well-generated key never leaves them open. Against RSA-2048 with $e = 65537$, a full-size random &lt;code&gt;d&lt;/code&gt;, two independent primes, and OAEP, every Coppersmith-family precondition is absent, and the classical state of the art is simply &lt;em&gt;no applicable attack&lt;/em&gt; [@boneh-survey-1999; @rfc8017]. The fast lane is not slow against a good key; it is inapplicable, which is a stronger and stranger kind of safety.&lt;/p&gt;
&lt;p&gt;The one attack that opens the front door itself is Shor&apos;s, structural, polynomial, and almost indifferent to key size. It breaks even a flawless key, and it waits on hardware that does not exist as of 2026, with no credible timeline [@shor-siam-1997]. So the most-likely eventual &lt;em&gt;structural&lt;/em&gt; break of a good RSA key is not a classical factoring breakthrough at all. It is quantum, on a machine not yet built, and harvest-now-decrypt-later is what makes that future-tense sentence something to act on in the present [@gidney-2025].&lt;/p&gt;

The most-likely eventual break of a good RSA key is quantum, on a machine that has not been built. That is exactly why the forecast is actionable today.
&lt;p&gt;The misconceptions this reframing overturns, &quot;RSA is already broken,&quot; &quot;a quantum computer just cracked it,&quot; &quot;factoring is NP-hard,&quot; &quot;a bigger key stops everything,&quot; deserve direct answers, which the questions below provide. This article asked how RSA &lt;em&gt;would&lt;/em&gt; break. The answer is a two-speed map with a quantum horizon, and every road on it is now labeled.&lt;/p&gt;
&lt;h2&gt;12. Frequently asked questions&lt;/h2&gt;
&lt;p&gt;The claims below are the ones that come up most often, corrected against the evidence in this article.&lt;/p&gt;


No. A correctly generated RSA-2048 key with $e = 65537$, a full-size random `d`, independent primes, and OAEP padding has no applicable classical attack: the slow lane (GNFS) is astronomically far from a 2048-bit modulus, and every fast-lane attack needs a defect this key does not have [@boneh-survey-1999; @boudot-rsa250-2020]. RSA is not broken. It is a well-understood assumption with a known and distant classical threat, and a structural quantum threat that has no hardware yet.


No. Recurring headlines claim exactly this, and none has broken RSA-2048. No cryptographically relevant quantum computer exists as of 2026 [@gidney-2025]. The quantum result people most often conflate with a break, Grover&apos;s search algorithm, is only a quadratic speedup and is not a structural attack on RSA [@grover-1996]. The classical &quot;shortcut&quot; claims follow the same pattern as Schnorr&apos;s 2021 preprint, whose method produced zero usable relations at cryptographic size when implemented [@ducas-schnorrgate; @schneier-2021].


No, and this is the most common technical misconception. The decision version of factoring lies in the intersection of NP and co-NP, so it cannot be NP-complete unless NP equals co-NP, which is widely disbelieved [@hac-1996]. RSA does not inherit the difficulty of the hardest problems in NP. Its security rests on the specific, unproven belief that factoring is hard, not on a theorem [@hac-1996].


No. Shor&apos;s cost grows only polynomially in the number of digits of `N`, so doubling the modulus from 2048 to 4096 bits multiplies the quantum work by a small constant, not by the astronomical factor that same change imposes on classical factoring [@shor-siam-1997]. Key size defends only against the slow lane. Against the quantum threat, the answer is a different primitive, not a longer RSA key [@gidney-2025].


With correct OAEP padding, the low-exponent attacks lose their precondition, so $e = 3$ is not automatically fatal [@cfpr-1996; @rfc8017]. But $e = 65537$ is the safer default: it defeats the low-exponent family outright while staying cheap to compute, so a single padding mistake with $e = 3$ does not immediately reopen Hastad&apos;s broadcast or the stereotyped-message attack [@hastad-1988]. Choose the exponent that fails safe.


Those are out of scope for this article by design, because they are not breaks of RSA&apos;s mathematics. ROCA is a key-generation library defect, Bleichenbacher and Manger are padding oracles, FREAK is a protocol downgrade, and timing and fault attacks are physical side channels. Every one of them breaks the implementation or protocol around RSA, not the algorithm itself. They are the subject of the companion article, *How RSA Breaks in Real Life*.


Yes, but only for data with a long confidentiality lifetime. An attacker can record RSA-encrypted traffic now and decrypt it once a quantum computer exists [@gidney-2025]. If your secrets must stay protected for a decade or more, begin planning migration to post-quantum key-establishment even though no such machine exists today and no credible timeline can be given. For short-lived data, the classical picture in this article still governs.

&lt;p&gt;The question this article opened with was not whether RSA is broken, but how it &lt;em&gt;would&lt;/em&gt; break if it ever did. The evidence has drawn the map: a bolted front door that opens at a crawl, side windows a good key never leaves ajar, and a single quantum road to a machine still on the horizon.&lt;/p&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;how-rsa-would-break&quot; keyTerms={[
  { term: &quot;Trapdoor one-way function&quot;, definition: &quot;Easy to compute forward, hard to invert without a secret. RSA&apos;s trapdoor is the factorization of N, and its security is the conjecture that inversion stays hard without it.&quot; },
  { term: &quot;General Number Field Sieve (GNFS)&quot;, definition: &quot;The fastest known classical factoring algorithm, heuristic cost L_N[1/3, (64/9)^(1/3)]; sub-exponential and glacial at cryptographic sizes.&quot; },
  { term: &quot;Sub-exponential / L-notation&quot;, definition: &quot;L_N[a,c] = exp((c+o(1))(ln N)^a (ln ln N)^(1-a)); the exponent a=1/3 sits between polynomial (0) and fully exponential (1).&quot; },
  { term: &quot;Coppersmith&apos;s small-root method&quot;, definition: &quot;Finds a root x0 of a degree-d modular polynomial in polynomial time whenever |x0| &amp;lt; N^(1/d), via LLL lattice reduction. The engine behind the whole fast lane.&quot; },
  { term: &quot;Continued-fraction convergent&quot;, definition: &quot;A best rational approximation h/k to a real number; Wiener&apos;s attack finds a small private exponent d as a convergent denominator of e/N.&quot; },
  { term: &quot;Boneh-Durfee bound&quot;, definition: &quot;The strongest small-d attack: recovers d whenever d &amp;lt; N^0.292, using Coppersmith&apos;s lattice aimed at the RSA key equation. Conjectured true bound is N^0.5.&quot; },
  { term: &quot;OAEP&quot;, definition: &quot;Randomized RSA padding from RFC 8017; injects fresh randomness so the encrypted integer is large and unique, removing the structure every Coppersmith-family attack needs.&quot; },
  { term: &quot;Shor&apos;s algorithm&quot;, definition: &quot;Quantum factoring in time polynomial in log N, via period-finding plus a classical gcd. Breaks even a correctly generated key, but needs a fault-tolerant quantum computer.&quot; },
  { term: &quot;CRQC&quot;, definition: &quot;A cryptographically relevant quantum computer: large and reliable enough to run Shor against RSA-2048. None exists as of 2026.&quot; },
  { term: &quot;Harvest now, decrypt later&quot;, definition: &quot;Record ciphertext today, decrypt once a CRQC exists; the reason an undated quantum threat is actionable now for long-lived secrets.&quot; }
]} questions={[
  { q: &quot;Why is factoring the slow path rather than the likely one?&quot;, a: &quot;GNFS is sub-exponential, so its cost climbs steeply with key size; the record moved only about 400 bits in 26 years and remains over 1200 bits short of RSA-2048. A bigger key defeats it outright.&quot; },
  { q: &quot;Why does the fast lane go dark against a correctly generated key?&quot;, a: &quot;Every Coppersmith-family attack needs a defect: a small exponent, a small d, missing padding, leaked bits, or correlated primes. A correct RSA-2048/OAEP key supplies none, so the attacks are correct but inapplicable.&quot; },
  { q: &quot;What single idea unifies Hastad, Wiener, Franklin-Reiter, partial key exposure, and Boneh-Durfee?&quot;, a: &quot;Coppersmith&apos;s small-root method: known structure plus a small unknown lets you solve for the unknown, using LLL whenever the unknown is smaller than N^(1/d).&quot; },
  { q: &quot;Why is the claim that RSA is NP-hard false?&quot;, a: &quot;The decision version of factoring lies in NP intersect co-NP, so it cannot be NP-complete unless NP equals co-NP. RSA rests on a belief that factoring is hard, not on a hardness theorem.&quot; },
  { q: &quot;Why does a bigger key fail to defend against Shor?&quot;, a: &quot;Shor&apos;s cost grows only polynomially in the digits of N, so doubling the modulus adds only a small constant of quantum work. Defending against the quantum road requires a different primitive, not more RSA bits.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>rsa</category><category>cryptanalysis</category><category>factoring</category><category>coppersmith</category><category>lattice-attacks</category><category>shor</category><category>public-key</category><category>post-quantum</category><author>noreply@paragmali.com (Parag Mali)</author></item><item><title>RSA Is a Trapdoor, Not a Cryptosystem: OAEP, PSS, and the 25-Year Padding-Oracle Lineage</title><link>https://paragmali.com/blog/rsa-is-a-trapdoor-not-a-cryptosystem-oaep-pss-and-the-25-yea/</link><guid isPermaLink="true">https://paragmali.com/blog/rsa-is-a-trapdoor-not-a-cryptosystem-oaep-pss-and-the-25-yea/</guid><description>Textbook RSA is a trapdoor, not a cryptosystem. A field guide to OAEP, PSS, PKCS#1 v1.5, and the Bleichenbacher-ROBOT-Marvin padding-oracle lineage, done right.</description><pubDate>Sat, 11 Jul 2026 09:07:03 GMT</pubDate><content:encoded>
**RSA is a trapdoor permutation, not a cryptosystem** -- and almost every real-world RSA break came from treating the bare trapdoor as if it were already secure. Textbook RSA is deterministic and malleable. PKCS#1 v1.5 *encryption* turns &quot;is this padding valid?&quot; into a decryption oracle that leaked through ever-quieter channels for 25 years, from Bleichenbacher (1998) [@bleichenbacher98] through DROWN [@drown16] and ROBOT [@robot18] to Marvin&apos;s pure-timing attack (2023) [@marvin23]. &quot;Done right&quot; is a stack that must all hold at once: the right scheme (**OAEP** for encryption, **PSS** for new signatures), the right parameters (2048-bit floor, `e = 65537`, CSPRNG primes), and a **constant-time, fault-checked implementation** -- because security is a property of the scheme *and* its implementation, not of the math. And keep one split absolute: v1.5 *signatures* are unbroken and still dominant (verify strictly), while v1.5 *encryption* must be retired.
&lt;h2&gt;1. The Modulus Was Never Factored&lt;/h2&gt;
&lt;p&gt;In 2018, three researchers signed a message with the private key behind &lt;code&gt;facebook.com&lt;/code&gt;&apos;s TLS certificate [@robot18]. They never factored Facebook&apos;s 2,048-bit modulus. Nobody has ever publicly factored a 2,048-bit modulus -- the public record stands at 829 bits, and that took roughly 2,700 core-years [@rsa250].&lt;/p&gt;
&lt;p&gt;Instead, they asked one of Facebook&apos;s front-end servers the same yes-or-no question a few hundred thousand times -- &lt;em&gt;is this padding valid?&lt;/em&gt; -- and let the pattern of answers spell out the secret [@robot18]. The attack they used was already nineteen years old [@robotsite]. Five years later, a Red Hat engineer reproduced the same break against software that was supposed to be immune, using nothing but a stopwatch, and called it Marvin [@marvin23].&lt;/p&gt;
&lt;p&gt;Notice what did not happen. No prime was recovered. No number was factored. The RSA problem -- invert &lt;code&gt;c = m^e mod N&lt;/code&gt; without the private key -- stood exactly as hard the day after as the day before. What broke was the server&apos;s &lt;em&gt;reaction&lt;/em&gt;: the way it answered a question about a ciphertext it did not create.&lt;/p&gt;
&lt;p&gt;That is the whole subject in one sentence. Textbook RSA -- the bare &lt;code&gt;m^e mod N&lt;/code&gt; you meet in a first course -- is a &lt;strong&gt;trapdoor permutation, not a cryptosystem&lt;/strong&gt;. It is a beautiful one-way function with a secret shortcut, and nothing more.&lt;/p&gt;
&lt;p&gt;Everything that turns it into secure encryption or a secure signature lives &lt;em&gt;around&lt;/em&gt; the permutation, in the padding, the parameters, and the code that runs the operation. Almost every famous RSA disaster of the last three decades is a variation on one theme: someone used the bare trapdoor as if it were already a cryptosystem, or let the machinery meant to secure it confess -- through an error message, a network timeout, a microsecond of timing, or an injected fault -- whether a check had passed.&lt;/p&gt;

The math was never broken. The padding check told the attacker whether it passed.
&lt;p&gt;So here is the diagnostic question this article keeps asking, the one that unlocks the entire failure catalog: &lt;strong&gt;when a ciphertext or signature it did not create arrives, what does the receiver reveal about it -- through its answer, its timing, or its faults -- before and after it has checked the padding?&lt;/strong&gt; Four names you may know as headlines -- Bleichenbacher, DROWN, ROBOT, Marvin -- are four answers to that question, each leaking the same single bit through a quieter channel than the last. To see why one yes-or-no question about padding is enough to reconstruct a session key, you first have to see what RSA actually &lt;em&gt;is&lt;/em&gt;, and what it is not.&lt;/p&gt;
&lt;h2&gt;2. A Trapdoor for Diffie-Hellman&apos;s Challenge&lt;/h2&gt;
&lt;p&gt;In 1976, Whitfield Diffie and Martin Hellman wrote down the shape of a future that did not yet have an engine. Their paper &lt;em&gt;New Directions in Cryptography&lt;/em&gt; described public-key encryption and, remarkably, the idea of a digital signature -- a value only you can produce but anyone can check [@dh76]. What they could not supply was a concrete &lt;em&gt;trapdoor&lt;/em&gt;: a function easy to compute in one direction, hard to invert, yet effortless to invert if you hold a secret. Their paper is a challenge with a hole in it, and the hole is shaped exactly like RSA.&lt;/p&gt;
&lt;p&gt;A year later, Ron Rivest, Adi Shamir, and Leonard Adleman filled it. Pick two large primes $p$ and $q$ and set $N = pq$. Choose a public exponent $e$, and compute a private exponent $d$ with $ed \equiv 1 \pmod{\lambda(N)}$. Publish $(N, e)$; keep $d$, $p$, and $q$ secret. To encrypt a message represented as a number $m &amp;lt; N$, raise it to the public exponent; to decrypt, raise the result to the private one [@rsa78]:&lt;/p&gt;
&lt;p&gt;$$c = m^e \bmod N, \qquad m = c^d \bmod N.$$&lt;/p&gt;
&lt;p&gt;Why does the second operation undo the first? Because of Euler&apos;s theorem (1763): for any $m$ coprime to $N$, $m^{\phi(N)} \equiv 1 \pmod N$, with the totient $\phi(N) = (p-1)(q-1)$. Its Carmichael-function refinement (Carmichael, 1910) gives the same identity for the smaller $\lambda(N) = \mathrm{lcm}(p-1, q-1)$. Since $ed \equiv 1 \pmod{\lambda(N)}$, we have $ed = 1 + k\lambda(N)$ for some integer $k$, so $c^d = m^{ed} = m \cdot (m^{\lambda(N)})^k \equiv m \pmod N$. The exponents cancel, and the plaintext falls out -- but only for someone who could compute $d$, and computing $d$ requires $\lambda(N)$, which requires the factors of $N$. That is the trapdoor: the factorization of $N$ is the secret that inverts the permutation.The original 1978 paper used $\phi(N) = (p-1)(q-1)$, Euler&apos;s totient. Modern standards use the smaller Carmichael function $\lambda(N) = \mathrm{lcm}(p-1, q-1)$, which yields a smaller valid $d$ and the same correctness. Either works; $\lambda(N)$ is now the convention in FIPS 186-5.&lt;/p&gt;

A function that is easy to evaluate in the forward direction, computationally hard to invert without a secret, and easy to invert with it. RSA&apos;s forward map is x maps to x raised to the e, modulo N; the trapdoor that inverts it is the factorization of N. A trapdoor permutation is a primitive, not a complete encryption scheme -- it says nothing about hiding partial information or resisting tampering.
&lt;p&gt;The elegance that made RSA famous is that the &lt;em&gt;same&lt;/em&gt; operation both encrypts and signs. Swap the roles of the exponents: to sign a message, raise it to the private exponent, $s = m^d \bmod N$, an act only the key holder can perform; to verify, raise the signature to the public exponent and check that $s^e \equiv m \pmod N$, which anyone can do [@rsa78]. One modular exponentiation, read in two directions, is both a lock only you can open and a seal only you can stamp. Boneh&apos;s survey calls this duality the source of both RSA&apos;s reach and its long catalogue of misuse [@boneh99].&lt;/p&gt;
&lt;p&gt;Two engineering choices from this era matter later, because each returns as an attack surface. The first is the public exponent. Almost every deployed RSA key uses $e = 65537$.65537 is the Fermat prime $F_4 = 2^{16} + 1$. Written in binary it is &lt;code&gt;1&lt;/code&gt; followed by fifteen &lt;code&gt;0&lt;/code&gt;s and a final &lt;code&gt;1&lt;/code&gt; -- a Hamming weight of just 2 -- so public-key operations cost only sixteen squarings and one multiplication. Small enough to be fast, large enough to dodge the low-exponent traps of $e = 3$. The second is how the private operation is computed. Rather than one exponentiation modulo $N$, implementations work modulo $p$ and modulo $q$ separately and recombine, using the Chinese Remainder Theorem for roughly a fourfold speedup.&lt;/p&gt;

A technique for computing the private operation c raised to the d, modulo N, by working separately modulo p and modulo q on half-size numbers and then recombining the two halves. It cuts the cost of decryption and signing by about four times. Because it splits the secret operation across the two prime factors, it also opens a physical-fault attack surface that the single-modulus form does not have.
&lt;p&gt;Hold those two choices in mind: the small public exponent and the CRT shortcut will each come back to bite an implementation that treats them casually. But the deepest seed was planted in the 1978 paper itself, and it was invisible at the time.&lt;/p&gt;
&lt;p&gt;Rivest, Shamir, and Adleman demonstrated the trapdoor on &lt;em&gt;raw&lt;/em&gt; message numbers. That bare application is deterministic, algebraically malleable, and carries structure an attacker can exploit -- three properties that, in 1978, looked like harmless features of a clean mathematical object. One operation, elegant enough to both lock and sign. So why is calling that operation directly -- what cryptographers now dismiss as &quot;textbook RSA&quot; -- treated as a bug in every serious codebase?&lt;/p&gt;
&lt;h2&gt;3. Why Textbook RSA Is Not a Cryptosystem&lt;/h2&gt;
&lt;p&gt;Encryption has a minimum bar -- lower than most people think -- and textbook RSA fails to clear it. The bar is called &lt;a href=&quot;https://paragmali.com/blog/secure-against-whom-the-security-definitions-every-protocol-/&quot; rel=&quot;noopener&quot;&gt;IND-CPA&lt;/a&gt;: an adversary who picks two plaintexts and receives the encryption of one cannot tell which, better than a coin flip. (Part 1 of this series builds that definition carefully; here we only need its consequences.) Bare RSA loses this game three separate ways, each a direct consequence of the naked permutation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It is deterministic.&lt;/strong&gt; The same plaintext always encrypts to the same ciphertext, because $m^e \bmod N$ is a function with no randomness in it. That is fatal whenever the message space is small or guessable. Suppose a server encrypts a one-word trading instruction, either &lt;code&gt;BUY&lt;/code&gt; or &lt;code&gt;SELL&lt;/code&gt;, under a known public key. An eavesdropper does not need to decrypt anything: they encrypt both candidate words, compare against the captured ciphertext, and read the plaintext with zero queries. Determinism can never be semantic security -- this is structural, not a missing optimization you can bolt on later.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It is malleable.&lt;/strong&gt; RSA is multiplicatively homomorphic: multiply a ciphertext by $k^e$ and the plaintext is silently multiplied by $k$.&lt;/p&gt;

A cipher is malleable when an attacker can transform a ciphertext into another valid ciphertext whose plaintext is a predictable function of the original -- without decrypting anything. RSA satisfies the multiplicative relation: the encryption of m times the encryption-form of k decrypts to m times k, modulo N. Useful for some protocols, catastrophic for confidentiality, and the exact algebraic lever Bleichenbacher later pulls.
&lt;p&gt;That relation is not a curiosity; it is the crowbar behind the entire padding-oracle lineage. The demonstration below uses toy primes so the arithmetic is legible in a browser, but the algebra is identical at 2,048 bits.&lt;/p&gt;
&lt;p&gt;{`
// Toy RSA: p=61, q=53, N=3233, e=17, d=2753. NOT secure sizes -- for illustration.
function modpow(base, exp, mod) {
  base = base % mod; let r = 1n;
  while (exp &amp;gt; 0n) {
    if (exp &amp;amp; 1n) r = (r * base) % mod;
    base = (base * base) % mod; exp &amp;gt;&amp;gt;= 1n;
  }
  return r;
}
const N = 3233n, e = 17n, d = 2753n;
const m = 42n;&lt;/p&gt;
&lt;p&gt;// 1) Deterministic: encrypting the same message twice gives the same ciphertext.
const c1 = modpow(m, e, N), c2 = modpow(m, e, N);
console.log(&apos;encrypt 42 twice -&amp;gt;&apos;, c1.toString(), c2.toString(), &apos;| identical?&apos;, c1 === c2);&lt;/p&gt;
&lt;p&gt;// 2) Malleable: multiply the ciphertext by k^e and the plaintext scales by k.
const k = 2n;
const cForged = (c1 * modpow(k, e, N)) % N;      // attacker never decrypts
const mForged = modpow(cForged, d, N);           // what the victim would recover
console.log(&apos;tampered ct decrypts to&apos;, mForged.toString(), &apos;= (42*2) mod N =&apos;, ((m * k) % N).toString());
`}&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It leaks structure for small exponents and short messages.&lt;/strong&gt; If a message is short enough that $m^e &amp;lt; N$, no modular reduction ever happens, so recovering $m$ is a plain integer $e$-th root -- no factoring required.&lt;/p&gt;
&lt;p&gt;Johan Hastad showed in 1988 that if the same message is broadcast to $e$ recipients under $e = 3$, the plaintext falls out by the Chinese Remainder Theorem [@hastad88]. Don Coppersmith sharpened this in 1996 into a lattice method that recovers a message whenever the unknown part is smaller than $N^{1/e}$, breaking &quot;stereotyped&quot; messages with a small hidden field [@coppersmith97]. Every one of these is an attack on &lt;em&gt;textbook&lt;/em&gt; RSA, not on the RSA problem itself -- the factoring assumption stays intact while the plaintext walks out the front door [@boneh99].&lt;/p&gt;
&lt;p&gt;So a trapdoor permutation is not a cryptosystem. To become one, it needs a transformation applied to the message &lt;em&gt;before&lt;/em&gt; the permutation -- padding -- and that padding has to do three separable jobs.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; A trapdoor becomes a cryptosystem only when the padding does three separable jobs: (1) add &lt;strong&gt;randomness&lt;/strong&gt;, so equal plaintexts produce different ciphertexts; (2) add &lt;strong&gt;checkable redundancy&lt;/strong&gt;, so the receiver can detect a tampered or malformed ciphertext; and (3) -- the job the field kept forgetting -- be &lt;strong&gt;implemented so that no observable behaviour reveals whether that check passed.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The first two jobs are about the &lt;em&gt;scheme&lt;/em&gt;. The third is about the &lt;em&gt;implementation&lt;/em&gt;, and the entire history of RSA breaks is the field learning, over and over, that the third job is not optional. Hold that third clause; it is the trap the next section springs.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If your code invokes a modular-exponentiation &quot;textbook RSA&quot; function directly on a message -- no OAEP, no PSS, no padding layer -- it is broken before it ships. Every serious library hides the bare permutation precisely so that no application accidentally uses it as encryption or a signature.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The first widely deployed answer to those three jobs was PKCS#1 version 1.5, specified by RSA Laboratories in the early 1990s and republished as RFC 2313 in 1998 [@rfc2313]. For encryption, it wraps the message as &lt;code&gt;0x00 || 0x02 || PS || 0x00 || M&lt;/code&gt;, where &lt;code&gt;PS&lt;/code&gt; is at least eight nonzero random bytes -- that random padding supplies job one [@rfc8017]. For signatures it uses a different, fixed frame, &lt;code&gt;0x00 || 0x01 || 0xFF...0xFF || 0x00 || DigestInfo&lt;/code&gt;, whose rigid structure supplies job two [@rfc8017].&lt;/p&gt;
&lt;p&gt;On paper it fixed textbook RSA&apos;s two headline problems: the random bytes killed determinism, and the fixed structure gave the receiver something to check. For five years, it looked as if PKCS#1 v1.5 had turned the trapdoor into a cryptosystem. The structure was supposed to &lt;em&gt;add&lt;/em&gt; security. In 1998, Daniel Bleichenbacher showed that the structure was the vulnerability.&lt;/p&gt;
&lt;h2&gt;4. The Atom and Its Echoes: The Encryption Padding-Oracle Lineage&lt;/h2&gt;
&lt;p&gt;Before the detailed walk, here is the whole story on one timeline -- two intertwined tracks, the schemes on one side and the breaks on the other, with each break forcing the next response.&lt;/p&gt;

timeline
    title RSA schemes and their breaks, 1976 to 2026
    1977 : RSA trapdoor answers the Diffie-Hellman challenge
    1990 : Wiener breaks small private exponents
    1993 : PKCS#1 v1.5 padding deployed
    1997 : Bellcore CRT fault factors N from one signature
    1998 : Bleichenbacher padding oracle : OAEP standardized in response
    2001 : Manger reopens the oracle inside OAEP decoders
    2003 : Remote timing attacks proven practical : PSS standardized
    2016 : DROWN revives the oracle through SSLv2
    2017 : ROCA factors structured Infineon keys
    2018 : ROBOT signs with the facebook.com key : TLS 1.3 deletes RSA key exchange
    2023 : Marvin recovers keys by timing alone
    2024 : NIST IR 8547 sets the quantum retirement clock
    2025 : CFRG draft moves to deprecate v1.5 encryption
&lt;p&gt;Bleichenbacher&apos;s insight was not about RSA the mathematics at all. It was about a server&apos;s manners. A TLS server in the 1990s received an RSA-encrypted pre-master secret, decrypted it, and checked whether the result had valid PKCS#1 v1.5 padding -- did it start with the bytes &lt;code&gt;0x00 0x02&lt;/code&gt;, with a nonzero pad and a delimiter in the right place? If not, it returned an error. That error, however polite, answered a question the attacker was not supposed to be able to ask: &lt;em&gt;was this the encryption of a well-formed message?&lt;/em&gt; And because RSA is malleable, the attacker could turn that one bit of feedback into a full decryption.&lt;/p&gt;
&lt;p&gt;Here is the mechanism. The attacker holds a target ciphertext $c$ that encrypts an unknown $m$ -- say, a captured TLS session key. They pick a value $s$, compute $c \cdot s^e \bmod N$, and send it to the server. By the homomorphic property, the server is really decrypting $m \cdot s \bmod N$. If the server reports valid padding, the attacker learns that $m \cdot s \bmod N$ begins with &lt;code&gt;0x00 0x02&lt;/code&gt; -- which means it lies in the interval $[2B, 3B)$, where $B = 2^{8(k-2)}$ for a $k$-byte modulus.&lt;/p&gt;
&lt;p&gt;Each conforming $s$ is a linear inequality on the secret $m$. Collect enough of them, adaptively choosing each new $s$ to bisect the surviving range, and the interval of possible $m$ collapses to a single value. Bleichenbacher&apos;s 1998 paper showed this takes on the order of $2^{20}$ -- about a million -- queries for a 1,024-bit key, and the private key is never touched [@bleichenbacher98].&lt;/p&gt;

sequenceDiagram
    participant A as Attacker
    participant S as Decrypting server
    Note over A: Holds target ciphertext c, wants secret m
    A-&amp;gt;&amp;gt;S: Submit c times s to the e, for chosen s
    S-&amp;gt;&amp;gt;S: Decrypt and check PKCS#1 v1.5 padding
    alt Decrypted value starts with 00 02
        S--&amp;gt;&amp;gt;A: Conforming, no error or fast reply
        Note over A,S: Attacker learns m times s mod N is in 2B to 3B
    else Padding invalid
        S--&amp;gt;&amp;gt;A: Non-conforming, error, alert, or slow reply
    end
    Note over A: Narrow the possible range of m, choose next s
    A-&amp;gt;&amp;gt;S: Repeat, roughly a million queries in total
    Note over A: Range collapses to one value, plaintext m recovered
&lt;p&gt;A generation of engineers filed this under &quot;performance&quot; or &quot;obscure edge case.&quot; It is neither. It is a correctness and security failure of the &lt;em&gt;construction&lt;/em&gt;: the receiver&apos;s validity check, exposed through any observable side effect, is a decryption oracle for chosen ciphertexts. That is the &lt;a href=&quot;https://paragmali.com/blog/they-read-your-plaintext-without-breaking-your-cipher-a-fiel/&quot; rel=&quot;noopener&quot;&gt;symmetric-side padding-oracle attack&lt;/a&gt; of Part 6, transplanted to public-key land -- the same disease, a different organ.&lt;/p&gt;

Any observable behaviour -- an error message, a network reset, an injected fault, or a difference in response time -- that reveals whether a decrypted ciphertext had valid padding. Because the attacker chooses the ciphertexts, a padding-validity signal becomes a decryption oracle: enough yes-or-no answers reconstruct the plaintext without ever recovering the private key.
&lt;p&gt;The break violates the strongest standard security goal for encryption, IND-CCA2, in which the adversary may submit chosen ciphertexts to a decryption oracle and still must not learn anything about a challenge plaintext.&lt;/p&gt;

The security goal a padding oracle destroys: an adversary who can submit arbitrary ciphertexts for decryption still cannot distinguish which of two chosen plaintexts a challenge ciphertext encrypts. PKCS#1 v1.5 encryption fails this because its validity check leaks. Part 1 of this series develops the full definition.
&lt;p&gt;The scheme-level fix arrived almost immediately. In direct response to Bleichenbacher, RSA Laboratories standardized a new encryption padding, RSAES-OAEP, in PKCS#1 v2.0 (RFC 2437) later in 1998 [@rfc2437]. OAEP&apos;s design goal, spelled out in Section 6, is that any tampered ciphertext decodes to unstructured noise, so there is no &quot;conformant&quot; interval left to test -- the oracle has nothing to grade. It fixed the scheme. What it did not, and could not, fix by itself was the decoder.&lt;/p&gt;
&lt;p&gt;James Manger proved that in 2001. OAEP&apos;s decoding has two distinct early failure modes: the recovered integer can be too large to fit the byte block, or it can fit but fail the padding check. A decoder that distinguishes those two cases through different errors or different timing hands the attacker a &lt;em&gt;new&lt;/em&gt; oracle -- and Manger&apos;s variant is dramatically cheaper than Bleichenbacher&apos;s, needing on the order of $\log_2 N$ queries, roughly 2,048 for a 2,048-bit key, instead of $2^{20}$ [@manger01]. OAEP, the provably secure scheme, re-opened the identical class of attack through an imperfect implementation. The lesson the field wrote down, and then kept having to re-learn, was not &quot;use OAEP.&quot; It was &quot;use OAEP &lt;em&gt;and&lt;/em&gt; decode it in constant time.&quot;&lt;/p&gt;
&lt;p&gt;If Bleichenbacher&apos;s attack is the atom, the next quarter-century is three quieter echoes of it -- the same leaked bit, reached through channels that get progressively harder to see.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DROWN (2016): a cross-protocol channel.&lt;/strong&gt; By 2016, TLS servers had long since patched the obvious padding-error message. But many still supported SSLv2, an obsolete protocol from the 1990s, often on a different service such as a mail server -- and often with the &lt;em&gt;same&lt;/em&gt; RSA key. DROWN showed that an attacker could use the weak, deliberately export-crippled SSLv2 endpoint as the padding oracle, then use its answers to decrypt a modern TLS session that shared the key.The DROWN team measured that roughly 33 percent of all HTTPS servers were vulnerable at disclosure in March 2016, because key reuse across a TLS service and a forgotten SSLv2 service was rampant [@drownsite]. The math of the oracle was 1998&apos;s; only the delivery was new [@drown16].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ROBOT (2018): the same oracle, nineteen years on.&lt;/strong&gt; Hanno Bock, Juraj Somorovsky, and Craig Young revisited the original attack and found it alive across the modern internet. The padding-error message was gone, but the oracle now leaked through subtler tells: a TCP reset here, a connection timeout there, a duplicated alert message somewhere else -- any behaviour that differed between conforming and non-conforming padding. It affected almost a third of the top 100 domains, including Facebook and PayPal, and traced to products from F5, Citrix, Radware, Palo Alto Networks, IBM, and Cisco [@robot18].To make the point unmissable, the ROBOT authors used the recovered oracle to sign a message with the private key behind facebook.com&apos;s certificate -- a decryption oracle repurposed to forge a signature, without ever touching the factorization [@robotsite].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Marvin (2023): pure timing, no error at all.&lt;/strong&gt; The quietest channel yet removes the error entirely. Hubert Kario&apos;s Marvin attack observes only the &lt;em&gt;time&lt;/em&gt; the decryption operation takes, since a conforming and a non-conforming padding often run through subtly different code paths. No alert, no reset, no message -- just a stopwatch. Marvin re-found exploitable leaks in implementations that had been declared immune after ROBOT, and it reaches well beyond TLS into S/MIME, JSON Web Tokens, and hardware tokens such as HSMs and smartcards [@marvin23]. The peer-reviewed write-up appeared at ESORICS 2023 under the fitting title &lt;em&gt;Everlasting ROBOT&lt;/em&gt; [@eprint2023]. Its recommendation was blunt: stop using PKCS#1 v1.5 encryption.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Every member of this lineage leaks the same single bit -- was the padding valid? -- through a different channel. You cannot patch your way to safety one channel at a time, because the next channel is always quieter than the last. The only durable fixes are structural: remove the mode (as TLS 1.3 did) or forbid it (as FIPS did). If a standard forces RSA encryption, use OAEP with constant-time decoding, never v1.5.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Read the four together and the pattern is impossible to miss. The channel gets quieter each time -- an error string in 1998, a cross-protocol zombie in 2016, a TCP quirk in 2018, a bare microsecond in 2023 -- but the leaked bit never changes. This is why &quot;add more padding&quot; was never the answer and constant-time, uniform-failure decoding was. The catalog below is the evidence for this article&apos;s whole argument: every row is some party using the bare trapdoor as if it were a scheme, or letting a check confess.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attack&lt;/th&gt;
&lt;th&gt;Year&lt;/th&gt;
&lt;th&gt;Front&lt;/th&gt;
&lt;th&gt;Leaked channel&lt;/th&gt;
&lt;th&gt;Root cause&lt;/th&gt;
&lt;th&gt;The rule it teaches&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Textbook RSA [@rsa78]&lt;/td&gt;
&lt;td&gt;1978&lt;/td&gt;
&lt;td&gt;Encryption&lt;/td&gt;
&lt;td&gt;None needed&lt;/td&gt;
&lt;td&gt;Deterministic, malleable bare permutation&lt;/td&gt;
&lt;td&gt;Never encrypt with the raw primitive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hastad / Coppersmith [@hastad88, @coppersmith97]&lt;/td&gt;
&lt;td&gt;1988 / 96&lt;/td&gt;
&lt;td&gt;Params&lt;/td&gt;
&lt;td&gt;Algebraic structure&lt;/td&gt;
&lt;td&gt;Small e, short or related messages&lt;/td&gt;
&lt;td&gt;Pad first, use e equals 65537&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bleichenbacher [@bleichenbacher98]&lt;/td&gt;
&lt;td&gt;1998&lt;/td&gt;
&lt;td&gt;Encryption&lt;/td&gt;
&lt;td&gt;Padding-error message&lt;/td&gt;
&lt;td&gt;v1.5 validity check is a decryption oracle&lt;/td&gt;
&lt;td&gt;Uniform, unobservable failure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Manger [@manger01]&lt;/td&gt;
&lt;td&gt;2001&lt;/td&gt;
&lt;td&gt;Implementation&lt;/td&gt;
&lt;td&gt;Error-type or timing split&lt;/td&gt;
&lt;td&gt;Non-constant-time OAEP decode&lt;/td&gt;
&lt;td&gt;OAEP AND constant-time decoding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DROWN [@drown16]&lt;/td&gt;
&lt;td&gt;2016&lt;/td&gt;
&lt;td&gt;Encryption&lt;/td&gt;
&lt;td&gt;SSLv2 cross-protocol&lt;/td&gt;
&lt;td&gt;Same RSA key on a weak zombie protocol&lt;/td&gt;
&lt;td&gt;Never reuse keys, kill SSLv2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ROBOT [@robot18]&lt;/td&gt;
&lt;td&gt;2018&lt;/td&gt;
&lt;td&gt;Encryption&lt;/td&gt;
&lt;td&gt;TCP reset, timeout, alert&lt;/td&gt;
&lt;td&gt;v1.5 oracle still live behind subtle tells&lt;/td&gt;
&lt;td&gt;Remove v1.5 key exchange&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Marvin [@marvin23]&lt;/td&gt;
&lt;td&gt;2023&lt;/td&gt;
&lt;td&gt;Implementation&lt;/td&gt;
&lt;td&gt;Decryption timing only&lt;/td&gt;
&lt;td&gt;Non-constant-time v1.5 depadding&lt;/td&gt;
&lt;td&gt;Retire v1.5 encryption entirely&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;e equals 3 forgery [@cve2006]&lt;/td&gt;
&lt;td&gt;2006&lt;/td&gt;
&lt;td&gt;Signature&lt;/td&gt;
&lt;td&gt;None, forged offline&lt;/td&gt;
&lt;td&gt;Lax verifier ignores trailing bytes&lt;/td&gt;
&lt;td&gt;Verify strictly, parse it all&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BERserk [@cve2014]&lt;/td&gt;
&lt;td&gt;2014&lt;/td&gt;
&lt;td&gt;Signature&lt;/td&gt;
&lt;td&gt;None, forged offline&lt;/td&gt;
&lt;td&gt;NSS mis-parses ASN.1 lengths&lt;/td&gt;
&lt;td&gt;Verify strictly, re-encode and compare&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bellcore fault [@bdl97]&lt;/td&gt;
&lt;td&gt;1997&lt;/td&gt;
&lt;td&gt;Implementation&lt;/td&gt;
&lt;td&gt;One faulty signature&lt;/td&gt;
&lt;td&gt;CRT fault reveals a prime by gcd&lt;/td&gt;
&lt;td&gt;Verify signature before release&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kocher, Brumley-Boneh [@kocher96, @brumleyboneh03]&lt;/td&gt;
&lt;td&gt;1996 / 2003&lt;/td&gt;
&lt;td&gt;Implementation&lt;/td&gt;
&lt;td&gt;Exponentiation timing&lt;/td&gt;
&lt;td&gt;Secret-dependent modexp time&lt;/td&gt;
&lt;td&gt;Base blinding, constant time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wiener [@wiener90]&lt;/td&gt;
&lt;td&gt;1990&lt;/td&gt;
&lt;td&gt;Params&lt;/td&gt;
&lt;td&gt;Public key structure&lt;/td&gt;
&lt;td&gt;Private exponent d too small&lt;/td&gt;
&lt;td&gt;Never shrink d for speed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mining Ps and Qs [@miningpq12]&lt;/td&gt;
&lt;td&gt;2012&lt;/td&gt;
&lt;td&gt;Params&lt;/td&gt;
&lt;td&gt;Shared prime factors&lt;/td&gt;
&lt;td&gt;Low boot-time entropy at keygen&lt;/td&gt;
&lt;td&gt;Seed the CSPRNG properly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ROCA [@roca17]&lt;/td&gt;
&lt;td&gt;2017&lt;/td&gt;
&lt;td&gt;Params&lt;/td&gt;
&lt;td&gt;Public modulus structure&lt;/td&gt;
&lt;td&gt;Infineon&apos;s structured primes&lt;/td&gt;
&lt;td&gt;Generate primes uniformly&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Fourteen rows, one disease. But the encryption oracle is only one of four ways the bare trapdoor betrays its owner. The other three -- the lazy verifier, the glitched chip, and the badly chosen numbers -- are just as instructive, and one of them factors your modulus from a single fault.&lt;/p&gt;
&lt;h2&gt;5. The Rest of the Catalog: Signatures, Faults, and Bad Primes&lt;/h2&gt;
&lt;p&gt;If the encryption oracle is the trapdoor leaking through the decryptor&apos;s &lt;em&gt;answer&lt;/em&gt;, the remaining breaks are the trapdoor leaking through the verifier&apos;s &lt;em&gt;laziness&lt;/em&gt;, the hardware&apos;s &lt;em&gt;faults&lt;/em&gt;, and the &lt;em&gt;numbers&lt;/em&gt; you fed it. Three fronts, and the encryption-versus-signature split stays absolute across all of them.&lt;/p&gt;
&lt;h3&gt;Front A: the signature track, and the precision that governs it&lt;/h3&gt;
&lt;p&gt;Start with a fact that surprises people who lump all of v1.5 together: RFC 8017 records &lt;strong&gt;no known attack against the RSASSA-PKCS1-v1_5 &lt;em&gt;signature scheme itself&lt;/em&gt;&lt;/strong&gt; [@rfc8017]. Unlike v1.5 encryption, the signature padding has never been broken as a construction. It rests on a heuristic argument rather than a tight proof, which is why cryptographers reach for PSS in new designs, but it is legacy-not-broken. Where it &lt;em&gt;is&lt;/em&gt; fragile is at the verifier -- and that fragility has bitten twice.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The $e = 3$ forgery (2006, CVE-2006-4339).&lt;/strong&gt; Daniel Bleichenbacher -- the same name, a different result eight years later -- described a forgery that needs no private key at all. A v1.5 signature block ends with the ASN.1 &lt;code&gt;DigestInfo&lt;/code&gt; structure, and a lazy verifier checks that the high-order bytes look right without confirming that the &lt;code&gt;DigestInfo&lt;/code&gt; sits flush against the end with no trailing data.&lt;/p&gt;
&lt;p&gt;With a small public exponent such as $e = 3$, an attacker can construct a number whose cube reproduces the correct prefix and hash in the leading bytes, then pack arbitrary garbage into the trailing bytes the verifier never inspects. Because cubing is cheap and the low bytes are free, the forged &quot;signature&quot; is just a carefully chosen cube root [@cve2006]. OpenSSL&apos;s advisory of 5 September 2006 traced it to exactly that omission: &quot;not checking for excess data&quot; after the exponentiation [@openssl2006].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;BERserk (2014, CVE-2014-1568).&lt;/strong&gt; Eight years on, the same antipattern returned in a different guise. Mozilla&apos;s NSS library mis-parsed ASN.1 length fields during signature verification, letting an attacker smuggle forged content past the check and produce signatures that NSS -- and therefore Firefox and Chrome builds of the era -- accepted as valid, including for TLS certificates [@cve2014]. Once again, no scheme was broken; a verifier was.&lt;/p&gt;
&lt;p&gt;The recurring lesson is one line: &lt;strong&gt;verify strictly.&lt;/strong&gt; Parse the entire structure, reject any trailing data, re-encode the expected block and compare it byte-for-byte, and never take an $e = 3$ shortcut. The provable alternative, PSS, removes the temptation to hand-roll a lenient check by making the encoding randomized and its verification total; its mechanism is in the next section [@pss96]. These verifier bugs live where v1.5 signatures live -- inside the &lt;a href=&quot;https://paragmali.com/blog/a-perfect-signature-for-a-certificate-that-should-never-have/&quot; rel=&quot;noopener&quot;&gt;X.509 and PKI machinery&lt;/a&gt; that Part 4 of this series covers.&lt;/p&gt;

&quot;Still-deployed PKCS#1 v1.5&quot; hides two opposite truths, and conflating them is the single most common error in RSA writing. v1.5 *encryption* (RSAES-PKCS1-v1_5) is fundamentally dangerous padding: its validity check is a decryption oracle, and it should be retired. v1.5 *signatures* (RSASSA-PKCS1-v1_5) are dominant across Web PKI, FIPS-approved in FIPS 186-5, and unbroken as a scheme -- keep them where mandated and verify strictly [@rfc8017], [@fips1865]. One phrase must never carry both meanings. When you read &quot;RSA v1.5 is broken,&quot; ask which one, because the honest answer is &quot;the encryption, not the signatures.&quot;
&lt;h3&gt;Front B: the physical layer&lt;/h3&gt;
&lt;p&gt;Here the secret &lt;em&gt;is&lt;/em&gt; the factorization, so anything the hardware leaks about the private operation leaks the factors directly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The CRT fault (Boneh, DeMillo, and Lipton, 1997).&lt;/strong&gt; Recall that fast RSA signing computes the result modulo $p$ and modulo $q$ separately, then recombines. Suppose a single bit flips during the modulo-$p$ half -- from a voltage glitch, a clock fault, cosmic radiation, or a deliberate injection. The faulty signature $s&apos;$ is now correct modulo $q$ but wrong modulo $p$. Then $s&apos;^e - m$ is divisible by $q$ but not by $p$, so a single $\gcd(s&apos;^e - m, N)$ hands you $q$ -- and the modulus is factored from &lt;em&gt;one&lt;/em&gt; faulty signature [@bdl97]. The demonstration below does exactly that with toy primes.&lt;/p&gt;
&lt;p&gt;{`
// Bellcore fault: a fault in one CRT half leaks a prime of N. Toy primes for clarity.
function modpow(base, exp, mod) {
  base = ((base % mod) + mod) % mod; let r = 1n;
  while (exp &amp;gt; 0n) { if (exp &amp;amp; 1n) r = (r * base) % mod; base = (base * base) % mod; exp &amp;gt;&amp;gt;= 1n; }
  return r;
}
function gcd(a, b) { while (b) { const t = a % b; a = b; b = t; } return a; }
const p = 61n, q = 53n, N = p * q, e = 17n, d = 2753n;
const m = 123n % N;                       // message representative to sign
const dp = d % (p - 1n), dq = d % (q - 1n);
const qInv = modpow(q, p - 2n, p);&lt;/p&gt;
&lt;p&gt;// Correct CRT signature (Garner recombination):
const sp = modpow(m, dp, p), sq = modpow(m, dq, q);
const s = (sq + q * (((qInv * (sp - sq)) % p + p) % p)) % N;
console.log(&apos;correct signature verifies?&apos;, modpow(s, e, N) === m);&lt;/p&gt;
&lt;p&gt;// A fault corrupts ONLY the mod-p half:
const spBad = (sp + 1n) % p;
const sBad = (sq + q * (((qInv * (spBad - sq)) % p + p) % p)) % N;
console.log(&apos;faulty  signature verifies?&apos;, modpow(sBad, e, N) === m);&lt;/p&gt;
&lt;p&gt;// One gcd factors the modulus:
const diff = ((modpow(sBad, e, N) - m) % N + N) % N;
console.log(&apos;gcd(sBad^e - m, N) =&apos;, gcd(diff, N).toString(), &apos;-&amp;gt; a secret prime of N (61 or 53)&apos;);
`}&lt;/p&gt;
&lt;p&gt;The fix is a single line of discipline: &lt;strong&gt;verify before release.&lt;/strong&gt; Recompute $s^e \bmod N$ and confirm it equals $m$ before the signature ever leaves the chip. A faulty signature never escapes, and the gcd trick has nothing to work with.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Timing (Kocher, 1996; Brumley and Boneh, 2003).&lt;/strong&gt; Paul Kocher observed in 1996 that the time to compute $c^d \bmod N$ depends on the secret bits of $d$, because square-and-multiply does extra work on &lt;code&gt;1&lt;/code&gt; bits [@kocher96]. Folklore held that timing attacks needed local access. David Brumley and Dan Boneh demolished that in 2003 by recovering an OpenSSL server&apos;s private key &lt;em&gt;over a network&lt;/em&gt;, measuring only response times [@brumleyboneh03].&lt;/p&gt;
&lt;p&gt;The fix is &lt;strong&gt;base blinding&lt;/strong&gt;: multiply the input by $r^e$ for a fresh random $r$ before exponentiating, then divide the result by $r$ afterward, so the timing depends on a value the attacker cannot predict. OpenSSL turned blinding on by default in 2003. Marvin, from the previous section, is this front&apos;s 2023 revival -- the timing channel never truly closed.&lt;/p&gt;
&lt;h3&gt;Front C: the parameters&lt;/h3&gt;
&lt;p&gt;The trapdoor is only as strong as the numbers behind it.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Wiener (1990).&lt;/strong&gt; If you shrink the private exponent for speed so that $d &amp;lt; \tfrac{1}{3} N^{1/4}$, a continued-fraction expansion of $e/N$ recovers $d$ outright [@wiener90]. You cannot buy decryption speed by making the secret small.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Coppersmith (1996 to 1997).&lt;/strong&gt; His lattice method sets the barrier $|x| &amp;lt; N^{1/e}$ that both &lt;em&gt;enables&lt;/em&gt; low-exponent attacks on short or stereotyped messages and &lt;em&gt;bounds&lt;/em&gt; them -- the same result that returns, weaponized, as ROCA [@coppersmith97].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mining Your Ps and Qs (2012).&lt;/strong&gt; Heninger and colleagues scanned the internet&apos;s public keys and computed pairwise gcds. Devices that generated keys at first boot, before they had gathered entropy, sometimes shared a prime -- and a shared prime means a free gcd factors both moduli. They computed private keys for about 0.50 percent of TLS hosts and 0.03 percent of SSH hosts this way [@miningpq12].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ROCA (2017, CVE-2017-15361).&lt;/strong&gt; Infineon&apos;s key-generation library built primes with a special structure to speed things up. That structure let a Coppersmith attack factor the public modulus for a practical cost, and the affected chips were everywhere: TPMs, YubiKey 4 tokens, national electronic ID cards, and BitLocker deployments [@roca17], [@cve2017]. Coppersmith&apos;s 1996 barrier, patient for twenty years, collected its debt.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The root cause of the last two is not RSA math at all -- it is the &lt;a href=&quot;https://paragmali.com/blog/predictable-or-repeated-the-only-two-ways-cryptographic-rand/&quot; rel=&quot;noopener&quot;&gt;CSPRNG that generates the primes&lt;/a&gt;, the subject of Part 2 of this series. Feed RSA weak randomness and no scheme, no padding, and no proof can save it.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Turn the diagnostic question on each front and it answers itself. The verifier confesses through a check it skipped. The chip confesses through a fault it did not catch. The clock confesses through a branch it did not equalize. The keygen confesses through primes it did not draw uniformly. In every case the attacker reads the private key off the receiver&apos;s &lt;em&gt;behaviour&lt;/em&gt;, not off the mathematics.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Keep the empirical yardstick in view: the largest RSA modulus ever publicly factored is RSA-250, at 829 bits.RSA-250 was factored on 28 February 2020 using the Number Field Sieve, at a cost of roughly 2,700 core-years of computation [@rsa250]. That is the real, measured cost of breaking RSA by its front door -- which is exactly why nobody attacks that door when a padding check will open the side gate for a million cheap queries. Four fronts, one disease. The cure is not a cleverer patch on any single front. It is a change in what we mean when we say a scheme is secure.&lt;/p&gt;
&lt;h2&gt;6. Security Is a Property of the Scheme AND the Implementation&lt;/h2&gt;
&lt;p&gt;There are two famous ideas behind &quot;RSA done right,&quot; and a third, deeper one that the first two kept teaching the hard way.&lt;/p&gt;
&lt;h3&gt;Idea 1: OAEP, the all-or-nothing randomized transform&lt;/h3&gt;
&lt;p&gt;Optimal Asymmetric Encryption Padding, designed by Mihir Bellare and Phillip Rogaway in 1994, encodes the message before the RSA permutation so that the encoded block has no gradable structure for an attacker to probe [@oaep94]. Its construction is a two-round Feistel network with a hash-based mask-generation function, MGF1, as the round function -- the &lt;a href=&quot;https://paragmali.com/blog/the-fingerprint-two-files-shared-a-field-guide-to-cryptograp/&quot; rel=&quot;noopener&quot;&gt;hashing machinery&lt;/a&gt; that Part 10 of this series develops. Writing $\Vert$ for concatenation and $\oplus$ for XOR, and starting from a random $\mathrm{seed}$:&lt;/p&gt;
&lt;p&gt;$$\mathrm{DB} = \mathrm{lHash} \Vert \mathrm{PS} \Vert \texttt{0x01} \Vert M$$
$$\mathrm{maskedDB} = \mathrm{DB} \oplus \mathrm{MGF1}(\mathrm{seed}), \qquad \mathrm{maskedSeed} = \mathrm{seed} \oplus \mathrm{MGF1}(\mathrm{maskedDB})$$
$$\mathrm{EM} = \texttt{0x00} \Vert \mathrm{maskedSeed} \Vert \mathrm{maskedDB}$$&lt;/p&gt;
&lt;p&gt;Then the RSA permutation is applied to $\mathrm{EM}$ [@rfc8017]. The two Feistel rounds make every bit of the encoded block depend on every bit of the message &lt;em&gt;and&lt;/em&gt; the random seed. That is the property that kills the padding oracle: flip a single bit of an OAEP ciphertext and the decoded block is randomized wholesale, so a tampered ciphertext decodes to noise with overwhelming probability. There is no conformant interval to bisect, no structured remnant to grade.&lt;/p&gt;
&lt;p&gt;With the randomness supplying non-determinism and the all-or-nothing mixing supplying tamper-detection, OAEP is not only semantically secure but also non-malleable and secure against chosen-ciphertext attack -- IND-CCA2 in the random-oracle model [@oaep94abs].&lt;/p&gt;

Optimal Asymmetric Encryption Padding: a randomized, all-or-nothing transform applied to a message before the RSA permutation. It mixes the message with a random seed through two mask-generation passes -- a two-round Feistel network -- so that every bit of the encoded block depends on every bit of the input. Flipping any ciphertext bit randomizes the whole decoded block, which destroys malleability and yields chosen-ciphertext security in the random-oracle model.

OAEP&apos;s history includes a moment cryptography should be proud of. In 2001, Victor Shoup showed that the celebrated 1994 security proof did not go through for an arbitrary trapdoor permutation -- it quietly assumed more than the definition guarantees [@shoup01]. The scheme was not broken; the *argument* was. Later that year, Fujisaki, Okamoto, Pointcheval, and Stern repaired it, proving RSA-OAEP is chosen-ciphertext secure in the random-oracle model under the RSA assumption, by leaning on a property called partial-domain one-wayness -- though the resulting reduction is non-tight [@fops04]. A public &quot;our proof, not our scheme, was wrong,&quot; followed by a public fix, is exactly how a mature field is supposed to work.
&lt;h3&gt;Idea 2: PSS, the salted encoding with a tight proof&lt;/h3&gt;
&lt;p&gt;For signatures, the Probabilistic Signature Scheme, also from Bellare and Rogaway, plays the analogous role [@pss96]. To sign, it hashes the message to $\mathrm{mHash}$, draws a random $\mathrm{salt}$, and forms $M&apos; = \texttt{padding} \Vert \mathrm{mHash} \Vert \mathrm{salt}$; sets $H = \mathrm{Hash}(M&apos;)$; builds $\mathrm{DB} = \mathrm{PS} \Vert \texttt{0x01} \Vert \mathrm{salt}$; masks it as $\mathrm{maskedDB} = \mathrm{DB} \oplus \mathrm{MGF1}(H)$; and assembles $\mathrm{EM} = \mathrm{maskedDB} \Vert H \Vert \texttt{0xbc}$ before applying the RSA private operation [@rfc8017].&lt;/p&gt;
&lt;p&gt;The randomization and MGF mixing buy something v1.5 signatures never had: a &lt;em&gt;tight&lt;/em&gt; exact-security reduction. A forger against PSS implies an algorithm that inverts RSA at almost the same cost -- so breaking the signatures is essentially as hard as the RSA problem itself, not merely conjectured to be [@pss96]. That is strictly stronger than v1.5&apos;s heuristic argument. PSS entered the standard in PKCS#1 v2.1 (RFC 3447) in 2003 and remains in the current v2.2 [@rfc3447]. Yet the split holds: PSS is the provable &lt;em&gt;upgrade&lt;/em&gt;, but v1.5 signatures are not superseded in deployment -- they remain the Web PKI default.Beyond these two deployed schemes, the literature holds academic-only refinements -- SAEP/SAEP+, OAEP+, three-round OAEP, tight RSA-KEM variants, and message-recovery PSS-R -- which tighten proofs or trim assumptions but never displaced OAEP and PSS in practice. A pointer, not a section.&lt;/p&gt;

Probabilistic Signature Scheme: a randomized, salted RSA signature encoding. A fresh random salt and MGF1 mixing make every signature of the same message different, and the scheme comes with a tight security reduction -- a forger would yield an almost-equally-efficient algorithm for inverting RSA, the strongest guarantee any RSA scheme offers.
&lt;h3&gt;Idea 3: the one the first two kept teaching&lt;/h3&gt;
&lt;p&gt;Here is where the whole article turns. OAEP is provably secure, yet Manger re-opened the identical oracle inside a non-constant-time &lt;em&gt;decoder&lt;/em&gt;. PSS is provably secure, yet a fault or a timing leak in the &lt;em&gt;signer&lt;/em&gt; factors the key. The scheme was never the whole story.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Security is a property of the scheme AND its implementation, not of the math. A perfect scheme run by a decoder that leaks whether padding verified is exactly as broken as no scheme at all. The implementation disciplines below are part of the construction, not optional hygiene layered on top.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Three disciplines close the three channels the catalog exposed:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Constant-time depadding with implicit rejection.&lt;/strong&gt; On any decryption failure, do not branch or return a distinguishable error; substitute a deterministic pseudo-random value and continue, so whether the padding verified stays unobservable. OpenSSL 3.2 ships this by default and aligned its behaviour with NSS so neither library can be an oracle for the other [@openssl32], [@gorsa].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CRT verify-before-release.&lt;/strong&gt; Recompute and check the signature before it leaves the device, defeating Bellcore faults [@bdl97].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Base blinding.&lt;/strong&gt; Randomize the input before exponentiation so timing reveals nothing about the secret [@kocher96], [@brumleyboneh03].&lt;/li&gt;
&lt;/ul&gt;

A decryption strategy in which a padding failure does not produce a distinguishable outcome. Instead of branching or returning a specific error, the code substitutes a deterministic pseudo-random value derived from the private key and ciphertext and proceeds. Success and failure become indistinguishable through content, error type, or timing, so there is no oracle left to query.

flowchart TD
    M[Message or ciphertext arrives] --&amp;gt; SCH{&quot;Scheme layer&quot;}
    SCH --&amp;gt;|Encrypt| OAEP[RSAES-OAEP, randomized all-or-nothing]
    SCH --&amp;gt;|Sign| PSS[RSASSA-PSS, salted with tight proof]
    OAEP --&amp;gt; IMPL{&quot;Implementation layer&quot;}
    PSS --&amp;gt; IMPL
    IMPL --&amp;gt; CT[Constant-time depad, implicit rejection]
    IMPL --&amp;gt; VBR[CRT verify-before-release]
    IMPL --&amp;gt; BL[Base blinding]
    CT --&amp;gt; PAR{&quot;Parameter layer&quot;}
    VBR --&amp;gt; PAR
    BL --&amp;gt; PAR
    PAR --&amp;gt; P1[Modulus at least 2048 bits, e equals 65537, CSPRNG primes]
    P1 --&amp;gt; GATE{&quot;Does any behaviour reveal the padding verdict?&quot;}
    GATE --&amp;gt;|No| SAFE[RSA done right]
    GATE --&amp;gt;|Yes| BROKEN[Oracle reopens, the catalog repeats]
&lt;p&gt;The libraries now say this in plain language. Go&apos;s standard library deprecated its v1.5 decryption function outright, with a warning that doubles as the thesis of this article:&lt;/p&gt;

&quot;PKCS #1 v1.5 encryption is dangerous and should not be used ... whether this function returns an error or not discloses secret information.&quot; -- Go crypto/rsa package documentation [@gorsa]
&lt;p&gt;That is the whole discipline in one sentence: done right closes the padding-oracle class Part 6 traces across all of cryptography, and it does so at the implementation layer, not the math. So what does the whole stack look like in 2024 to 2026 -- and which parts are quietly being switched off?&lt;/p&gt;
&lt;h2&gt;7. State of the Art (2024 to 2026): Done Right Is a Stack, Not a Method&lt;/h2&gt;
&lt;p&gt;Most primitives have a single &quot;best&quot; option you can name. RSA does not. &quot;Done right&quot; in 2026 is a &lt;em&gt;conjunction&lt;/em&gt; of independent choices that must all hold at once. Remove any one and the 25-year catalog reopens at that layer. Here is the stack, layer by layer.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;Job&lt;/th&gt;
&lt;th&gt;What it adds&lt;/th&gt;
&lt;th&gt;Security status&lt;/th&gt;
&lt;th&gt;Still requires&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;v1.5 encryption&lt;/td&gt;
&lt;td&gt;Encrypt&lt;/td&gt;
&lt;td&gt;Randomness only&lt;/td&gt;
&lt;td&gt;Broken as a target -- padding oracle&lt;/td&gt;
&lt;td&gt;Retire it; no safe deployment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RSAES-OAEP&lt;/td&gt;
&lt;td&gt;Encrypt&lt;/td&gt;
&lt;td&gt;Randomness plus all-or-nothing mixing&lt;/td&gt;
&lt;td&gt;IND-CCA2 in the random-oracle model&lt;/td&gt;
&lt;td&gt;Constant-time, implicit-rejection decode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;v1.5 signature&lt;/td&gt;
&lt;td&gt;Sign&lt;/td&gt;
&lt;td&gt;Fixed checkable structure&lt;/td&gt;
&lt;td&gt;Unbroken scheme, heuristic argument&lt;/td&gt;
&lt;td&gt;Strict verification, no e equals 3 shortcut&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RSASSA-PSS&lt;/td&gt;
&lt;td&gt;Sign&lt;/td&gt;
&lt;td&gt;Salt plus MGF, tight proof&lt;/td&gt;
&lt;td&gt;Provably as hard as the RSA problem&lt;/td&gt;
&lt;td&gt;CRT verify-before-release, blinding&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Encryption scheme.&lt;/strong&gt; When a standard genuinely mandates RSA encryption of a small payload, the answer is RSAES-OAEP with SHA-256 and MGF1-SHA-256, decoded in constant time [@rfc8017]. But note the capacity ceiling: a 2,048-bit OAEP-SHA-256 ciphertext carries at most about 190 bytes of plaintext [@sp80056b]. &quot;Encrypt a file with RSA-OAEP&quot; is therefore not just risky but physically wrong -- RSA encryption is for keys, never bulk data.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Signatures.&lt;/strong&gt; New designs use RSASSA-PSS, which TLS 1.3 makes mandatory for handshake signatures [@pss96], [@rfc8446]. Yet RSASSA-PKCS1-v1_5 signatures remain dominant and FIPS-approved across X.509 and TLS certificates [@fips1865]. This is not a contradiction: keep v1.5 signatures where they are mandated, and verify them strictly [@rfc8017].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Implementation hardening.&lt;/strong&gt; This is the layer that actually stops the attacks. OpenSSL 3.2 enables constant-time depadding with implicit rejection by default [@openssl32], Go has deprecated its v1.5 decryption entry point [@gorsa], and the CFRG&apos;s 2025 implementation-guidance draft folds all of this into formal advice amending RFC 8017 [@cfrgdraft].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Parameters.&lt;/strong&gt; A 2,048-bit modulus is the floor for 112-bit security; use 3,072 or 4,096 bits for long-term secrets; keep $e = 65537$; and draw primes from a properly seeded CSPRNG [@sp80057], [@fips1865].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Deployment and policy.&lt;/strong&gt; The most durable fixes were structural, not cryptographic. TLS 1.3 &lt;em&gt;deleted&lt;/em&gt; RSA key exchange entirely, which killed the Bleichenbacher-on-TLS class at the protocol level rather than patching each oracle [@rfc8446]. FIPS policy disallows RSA v1.5 key transport after 31 December 2023 [@sp800131a], [@sp80056b]. And NIST IR 8547 puts a clock on RSA itself, deprecating 112-bit strength after 2030 and disallowing it after 2035 [@ir8547].&lt;/p&gt;

If you operate under FIPS 140-3, the encryption side of this is not advisory. NIST SP 800-131A Rev. 2 and SP 800-56B Rev. 2 together disallow RSAES-PKCS1-v1_5 key transport after 31 December 2023; approved RSA key establishment must use OAEP [@sp800131a], [@sp80056b]. The signature side is the opposite: RSASSA-PKCS1-v1_5 signatures remain FIPS-approved under FIPS 186-5 [@fips1865]. Same version number, opposite compliance verdicts -- which is exactly why the encryption-signature split is not pedantry.
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Right scheme (OAEP to encrypt, PSS for new signatures), right implementation (constant-time depad with implicit rejection, CRT verify-before-release, base blinding), right parameters (2,048-bit floor, e equals 65537, CSPRNG primes), inside the right protocol (TLS 1.3, no RSA key exchange). Every deployed disaster in the catalog removed exactly one of these. None of it is new in 2026; the interesting movement is not toward a better RSA but away from RSA entirely.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;RSA done right is &lt;em&gt;stable&lt;/em&gt;. The genuinely current story is mostly about what to switch off and what is migrating away -- because for both of RSA&apos;s jobs, something smaller and faster is already taking over.&lt;/p&gt;
&lt;h2&gt;8. What RSA Is Losing To: ECDH, KEM-DEM, and the Post-Quantum Elephant&lt;/h2&gt;
&lt;p&gt;RSA is not being fixed into the future; it is being replaced out of it -- and the reasons have nothing to do with padding.&lt;/p&gt;
&lt;p&gt;The cleanest of those reasons is a design pattern that removes the attacker&apos;s target entirely. Never RSA-encrypt data. Instead, encapsulate a fresh random &lt;em&gt;symmetric&lt;/em&gt; key with the public key, and let an authenticated cipher carry the bulk. The public-key operation then transports only a uniform random key -- there is no attacker-chosen, structured plaintext for any oracle to grade. The entire Bleichenbacher-to-Marvin family loses its object, because the thing being decrypted is indistinguishable from random by construction [@rfc8446].&lt;/p&gt;

A two-part construction for hybrid encryption. A Key Encapsulation Mechanism (KEM) uses the public key to transport a freshly generated random symmetric key; a Data Encapsulation Mechanism (DEM) then encrypts the actual data with that key under an authenticated cipher. Because the public-key step only ever carries a uniform random key -- never a chosen, structured message -- there is no padding structure for an oracle to probe, so the padding-oracle class simply does not apply.

sequenceDiagram
    participant S as Sender
    participant R as Recipient
    Note over R: Publishes a public key
    S-&amp;gt;&amp;gt;S: Encapsulate, generate a random key K for the recipient
    S-&amp;gt;&amp;gt;S: Stretch K with a KDF, AEAD-encrypt the data
    S-&amp;gt;&amp;gt;R: Send the encapsulation and the AEAD ciphertext
    R-&amp;gt;&amp;gt;R: Decapsulate to recover K, run the same KDF
    R-&amp;gt;&amp;gt;R: AEAD-decrypt and verify the data
    Note over R,S: The public-key part carried only a random K, nothing to grade
&lt;p&gt;This is why elliptic-curve key agreement (ECDH, with Ed25519 and ECDSA for signatures) displaced RSA key transport: it does the same jobs with far smaller keys, faster operations, and forward secrecy -- a property RSA key transport never had, and the direct reason TLS 1.3 could &lt;em&gt;delete&lt;/em&gt; RSA key exchange rather than merely patch it [@rfc8446]. The &lt;a href=&quot;https://paragmali.com/blog/the-tag-verified-the-cipher-held-the-forgery-went-through-a-/&quot; rel=&quot;noopener&quot;&gt;KEM-DEM composition&lt;/a&gt; is developed in Part 11 of this series, the KDF step in Part 13, and the &lt;a href=&quot;https://paragmali.com/blog/the-aead-decision-matrix-seven-ciphers-three-edges-one-choic/&quot; rel=&quot;noopener&quot;&gt;AEAD that carries the payload&lt;/a&gt; in Part 7.&lt;/p&gt;
&lt;p&gt;Then there is the elephant. Peter Shor&apos;s algorithm factors integers in polynomial time on a large fault-tolerant quantum computer, which makes &lt;em&gt;all&lt;/em&gt; factoring-based cryptography -- every RSA key length, done right or not -- eventually breakable. NIST has already named the destination: ML-KEM (FIPS 203) for key encapsulation, and ML-DSA and SLH-DSA (FIPS 204 and 205) for signatures [@fips203], [@fips204], [@fips205].&lt;/p&gt;
&lt;p&gt;The migration is lopsided. Key encapsulation is moving fast -- hybrid X25519 plus ML-KEM-768 already carries a double-digit percentage of Cloudflare&apos;s TLS 1.3 traffic -- while post-quantum &lt;em&gt;signatures&lt;/em&gt; lag badly, because they run 10 to 200 times larger than an RSA signature and no public post-quantum certificate infrastructure existed before roughly 2026 [@cloudflare24], [@ir8547]. The lattice and hash-based internals belong to a later part of this series; here they matter only as RSA&apos;s replacement, not its repair.&lt;/p&gt;

Quantum risk is not only a future problem. An adversary can record RSA-encrypted traffic today and decrypt it once a capable quantum computer exists. For any secret that must stay confidential past roughly 2030, the exposure is *present tense* -- which is why NIST IR 8547 frames the transition as urgent rather than eventual, and why hybrid key exchange is being deployed now rather than when the machine arrives [@ir8547], [@cloudflare24].
&lt;p&gt;Laid side by side, the trade-offs explain why key transport migrated first and signatures are dragging. For moving a key:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Key transport&lt;/th&gt;
&lt;th&gt;Forward secrecy&lt;/th&gt;
&lt;th&gt;Padding-oracle exposure&lt;/th&gt;
&lt;th&gt;Relative cost&lt;/th&gt;
&lt;th&gt;Quantum status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;RSAES-OAEP [@rfc8017]&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes, if decode is not constant-time&lt;/td&gt;
&lt;td&gt;Large ciphertext, slow keygen&lt;/td&gt;
&lt;td&gt;Broken by Shor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ECDH (X25519) [@rfc8446]&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;None, no RSA decryption&lt;/td&gt;
&lt;td&gt;Small and fast&lt;/td&gt;
&lt;td&gt;Broken by Shor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ML-KEM-768 [@fips203]&lt;/td&gt;
&lt;td&gt;Yes (ephemeral)&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Kilobyte-scale, fast&lt;/td&gt;
&lt;td&gt;Resistant&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hybrid X25519 + ML-KEM-768 [@cloudflare24]&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Sum of both, still practical&lt;/td&gt;
&lt;td&gt;Resistant if either holds&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;And for signing:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Signature&lt;/th&gt;
&lt;th&gt;Provable security&lt;/th&gt;
&lt;th&gt;Approx. signature size&lt;/th&gt;
&lt;th&gt;Main failure mode&lt;/th&gt;
&lt;th&gt;Quantum status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;RSASSA-PSS [@pss96]&lt;/td&gt;
&lt;td&gt;Yes, tight in ROM&lt;/td&gt;
&lt;td&gt;256 bytes at 2048-bit&lt;/td&gt;
&lt;td&gt;Fault or timing in the signer&lt;/td&gt;
&lt;td&gt;Broken by Shor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RSASSA-PKCS1-v1_5 [@rfc8017]&lt;/td&gt;
&lt;td&gt;No, heuristic only&lt;/td&gt;
&lt;td&gt;256 bytes at 2048-bit&lt;/td&gt;
&lt;td&gt;Lax-verifier forgery&lt;/td&gt;
&lt;td&gt;Broken by Shor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ECDSA / Ed25519 [@rfc8446]&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;64 bytes&lt;/td&gt;
&lt;td&gt;Nonce reuse (ECDSA)&lt;/td&gt;
&lt;td&gt;Broken by Shor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ML-DSA-65 [@fips204]&lt;/td&gt;
&lt;td&gt;Yes, lattice&lt;/td&gt;
&lt;td&gt;About 3.3 kilobytes&lt;/td&gt;
&lt;td&gt;Implementation bugs&lt;/td&gt;
&lt;td&gt;Resistant&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SLH-DSA [@fips205]&lt;/td&gt;
&lt;td&gt;Yes, hash-based&lt;/td&gt;
&lt;td&gt;Many kilobytes&lt;/td&gt;
&lt;td&gt;Large and slow&lt;/td&gt;
&lt;td&gt;Resistant&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The signature column is the migration&apos;s hard problem, which is why post-quantum certificates lag key exchange by years [@ir8547]. If RSA is on the clock, it is worth asking where its security actually came from in the first place -- and why nobody has ever proved it was there.&lt;/p&gt;
&lt;h2&gt;9. Theoretical Limits: Where the Security Comes From, and Its Ceiling&lt;/h2&gt;
&lt;p&gt;Here is the uncomfortable truth a first course skips: there is no proof that RSA is secure.&lt;/p&gt;
&lt;p&gt;Start with the assumption itself. The RSA problem is to compute $e$-th roots modulo $N$ without the factorization. We know this is &lt;em&gt;no harder&lt;/em&gt; than factoring -- if you can factor $N$, you can compute $d$ and invert everything, so RSA $\le$ factoring. What nobody has shown is the reverse. It is an open question whether breaking RSA is &lt;em&gt;equivalent&lt;/em&gt; to factoring, and Boneh and Venkatesan gave evidence that a broad class of algebraic reductions from factoring to low-exponent RSA is unlikely to exist -- suggesting the two problems may not be equivalent at all [@bv98].&lt;/p&gt;
&lt;p&gt;Worse, factoring itself is not known to be hard in any proven sense: it sits in NP intersect co-NP, which is evidence it is probably &lt;em&gt;not&lt;/em&gt; NP-complete, and no one has proved a super-polynomial lower bound for it. RSA&apos;s security is heuristic and empirical -- it has survived decades of attack, and that is the entire argument [@boneh99].&lt;/p&gt;
&lt;p&gt;The empirical ceiling is concrete. The best classical algorithm, the General Number Field Sieve, runs in sub-exponential time, and the public record is RSA-250 at 829 bits, factored in February 2020 for roughly 2,700 core-years [@rsa250]. RSA-250 was one of the RSA Factoring Challenge moduli that RSA Laboratories first published in 1991 as public benchmarks for exactly this kind of progress [@rsanumbers]. That record sets the practical floors:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;RSA modulus&lt;/th&gt;
&lt;th&gt;Symmetric-equivalent strength&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;1024-bit&lt;/td&gt;
&lt;td&gt;About 80 bits&lt;/td&gt;
&lt;td&gt;Broken within reach, disallowed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2048-bit&lt;/td&gt;
&lt;td&gt;112 bits&lt;/td&gt;
&lt;td&gt;Current minimum, deprecated after 2030&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3072-bit&lt;/td&gt;
&lt;td&gt;128 bits&lt;/td&gt;
&lt;td&gt;Long-term use&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4096-bit&lt;/td&gt;
&lt;td&gt;About 140 bits (interpolated)&lt;/td&gt;
&lt;td&gt;High assurance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7680-bit&lt;/td&gt;
&lt;td&gt;192 bits&lt;/td&gt;
&lt;td&gt;Next tabulated SP 800-57 step&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;15360-bit&lt;/td&gt;
&lt;td&gt;256 bits&lt;/td&gt;
&lt;td&gt;Shows how badly RSA scales&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Those equivalences come from NIST SP 800-57, except the 4,096-bit figure -- a common interpolation, since the standard steps directly from 3,072 bits (128) to 7,680 bits (192). The last row is the quiet punchline: matching a 256-bit symmetric key needs a 15,360-bit RSA modulus, because RSA strength grows only sub-exponentially in key length while the cost of using it grows with the cube [@sp80057]. RSA scales badly, and that alone pushes new systems toward elliptic curves.&lt;/p&gt;
&lt;p&gt;Then the cliff. On a large fault-tolerant quantum computer, Shor&apos;s algorithm factors in polynomial time -- not faster, but &lt;em&gt;categorically&lt;/em&gt; faster, collapsing the whole assumption. The only question is engineering, and the estimates are falling fast. In 2019, Gidney and Ekera estimated 20 million noisy qubits and 8 hours to factor a 2,048-bit modulus [@gidney19]; by 2025, Gidney had cut the qubit estimate to under a million [@gidney25].A 20-fold reduction in the resource estimate in six years, with no fundamental barrier in sight, is precisely the trend that drove NIST to put firm dates -- 2030 and 2035 -- on RSA&apos;s retirement in IR 8547. The deadline is set by the slope, not by any single machine.&lt;/p&gt;
&lt;p&gt;Three impossibility results frame the whole subject, each already seen in this article. First, determinism can never be IND-CPA -- that is structural, not fixable, which is why padding must randomize. Second, there is no known standard-model proof of IND-CCA2 for RSA-OAEP under the plain RSA assumption; the guarantee is random-oracle-model only, and even there non-tight [@shoup01], [@fops04]. Third, Coppersmith&apos;s barrier $|x| &amp;lt; N^{1/e}$ both enables low-exponent attacks and bounds them, a hard mathematical edge that no parameter choice moves [@coppersmith97].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; RSA&apos;s safety lives in an unproven gap -- breaking it is no harder than factoring, but maybe strictly easier, and factoring is not even proven hard -- and that gap sits on the near side of a quantum cliff with a falling date on it. &quot;Done right&quot; buys you security against every known classical attack. It does not buy you a proof, and it cannot buy you time past Shor.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If the ground under RSA is this uncertain, what exactly is still unsettled -- and which of those open problems can bite you today?&lt;/p&gt;
&lt;h2&gt;10. Open Problems: What Remains Genuinely Unsettled&lt;/h2&gt;
&lt;p&gt;Some of these are for theorists. Others are live in your dependency tree right now.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Is the RSA problem equivalent to factoring?&lt;/strong&gt; We have only one direction, RSA $\le$ factoring; the reverse is open, with evidence it may fail [@bv98]. It matters because RSA&apos;s whole security story rests on a hardness we have never actually pinned down.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A deployed, standard-model IND-CCA2 RSA scheme.&lt;/strong&gt; Constructions that avoid the random-oracle model exist on paper, but none is a shipping default; practice sidesteps the gap entirely by using KEM-DEM instead of RSA encryption [@fops04].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Constant-time RSA is a perpetually moving target.&lt;/strong&gt; Marvin re-found timing leaks in implementations previously believed immune, and only a handful -- such as BearSSL and BoringSSL -- passed its tests; leaks hide in general-purpose bignum code and even in error-logging paths, which is why the CFRG draft concludes the only safe path is to deprecate v1.5 encryption outright rather than keep hardening it [@marvin23], [@cfrgdraft].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The long tail of v1.5 encryption.&lt;/strong&gt; HSMs, PKCS#11 tokens, S/MIME, and JWE still use it in places that cannot simply be switched off -- exactly where Marvin keeps finding live oracles [@marvin23], [@gorsa].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Generation-time entropy and structured primes.&lt;/strong&gt; Mining Your Ps and Qs and ROCA are operational failures with no clean universal fix: you cannot prove every device in the world seeded its CSPRNG correctly [@miningpq12], [@roca17].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The &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;post-quantum migration timeline&lt;/a&gt;.&lt;/strong&gt; Key exchange is migrating; signatures are years behind, and harvest-now-decrypt-later keeps the pressure on [@cloudflare24], [@ir8547].&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Most of this list is someone else&apos;s research agenda. Two entries are not: the v1.5 &lt;em&gt;encryption&lt;/em&gt; long tail and weak key-generation entropy are the ones most likely to be sitting in your own stack right now, in an HSM integration or an embedded device you inherited. Audit those two first.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Enough theory. Here is the whole argument compressed into rules you can apply on Monday.&lt;/p&gt;
&lt;h2&gt;11. The Practical Guide and the Misuse Catalog&lt;/h2&gt;
&lt;p&gt;Every rule below is one named break from the catalog, turned inside out. If you remember nothing else, remember the decision tree.&lt;/p&gt;

flowchart TD
    START{&quot;What do you need?&quot;} --&amp;gt;|Confidentiality| ENC{&quot;Can you avoid RSA encryption?&quot;}
    START --&amp;gt;|Authenticity| SIG{&quot;New design or legacy mandate?&quot;}
    ENC --&amp;gt;|Yes| KEM[Use ECDH or hybrid X25519 plus ML-KEM-768]
    ENC --&amp;gt;|No, a standard forces RSA| OAEP[RSAES-OAEP, SHA-256, constant-time decode, at least 2048-bit]
    SIG --&amp;gt;|New design| PSS[RSASSA-PSS with SHA-256]
    SIG --&amp;gt;|Legacy mandate| V15[v1.5 signature, verify strictly, no e equals 3 shortcut]
    KEM --&amp;gt; KEYS[Keys: e equals 65537, CSPRNG primes, verify-before-release, blinding]
    OAEP --&amp;gt; KEYS
    PSS --&amp;gt; KEYS
    V15 --&amp;gt; KEYS
    KEYS --&amp;gt; PQ{&quot;Secret must survive past 2030?&quot;}
    PQ --&amp;gt;|Yes| HY[Deploy hybrid post-quantum now]
    PQ --&amp;gt;|No| DONE[Ship it]
&lt;p&gt;Spelled out as decision rules:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Encryption and key transport.&lt;/strong&gt; Prefer ECDH or a KEM, migrating to hybrid X25519 plus ML-KEM-768. If a standard forces RSA encryption, use RSAES-OAEP with SHA-256 and MGF1-SHA-256, a modulus of at least 2,048 bits, and a constant-time decoder with implicit rejection -- never v1.5 encryption [@rfc8017], [@sp80056b]. Never RSA-encrypt a payload; encapsulate a symmetric key and let an AEAD carry the data.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Signatures.&lt;/strong&gt; Use RSASSA-PSS for new designs [@pss96], [@fips1865]. Use v1.5 signatures only where mandated, and then verify strictly: full parse, re-encode and compare, reject trailing data, no $e = 3$ shortcut [@rfc8017].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Keys and parameters.&lt;/strong&gt; A 2,048-bit floor, 3,072 or 4,096 bits for long-term secrets; $e = 65537$; independent CSPRNG-drawn primes per key; CRT with verify-before-release; base blinding [@sp80057], [@fips1865].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Migration.&lt;/strong&gt; Deploy hybrid post-quantum key agreement now, and inventory every RSA usage against the IR 8547 2030 and 2035 clock [@ir8547].&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The same rules as a lookup table:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Use&lt;/th&gt;
&lt;th&gt;Key parameters&lt;/th&gt;
&lt;th&gt;Because (which break)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Key transport, preferred&lt;/td&gt;
&lt;td&gt;ECDH or hybrid X25519 + ML-KEM-768&lt;/td&gt;
&lt;td&gt;Ephemeral keys&lt;/td&gt;
&lt;td&gt;Forward secrecy, no oracle, quantum hedge&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Key transport, if RSA forced&lt;/td&gt;
&lt;td&gt;RSAES-OAEP, constant-time decode&lt;/td&gt;
&lt;td&gt;SHA-256, MGF1-SHA-256, at least 2048-bit&lt;/td&gt;
&lt;td&gt;Bleichenbacher, Manger, Marvin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Signature, new design&lt;/td&gt;
&lt;td&gt;RSASSA-PSS&lt;/td&gt;
&lt;td&gt;SHA-256, random salt&lt;/td&gt;
&lt;td&gt;v1.5 hand-wave, e equals 3 forgery&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Signature, legacy mandate&lt;/td&gt;
&lt;td&gt;v1.5, verified strictly&lt;/td&gt;
&lt;td&gt;Full parse, reject trailing bytes&lt;/td&gt;
&lt;td&gt;e equals 3 forgery, BERserk&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Key generation&lt;/td&gt;
&lt;td&gt;e equals 65537, CSPRNG primes&lt;/td&gt;
&lt;td&gt;2048 floor, 3072+ long-term&lt;/td&gt;
&lt;td&gt;Wiener, ROCA, Mining Ps and Qs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Private operation&lt;/td&gt;
&lt;td&gt;CRT verify-before-release, base blinding&lt;/td&gt;
&lt;td&gt;Recompute before output&lt;/td&gt;
&lt;td&gt;Bellcore fault, Kocher timing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Long-term secrets&lt;/td&gt;
&lt;td&gt;Hybrid post-quantum now&lt;/td&gt;
&lt;td&gt;Inventory to IR 8547 clock&lt;/td&gt;
&lt;td&gt;Shor, harvest-now-decrypt-later&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Now the misuse catalog. Each antipattern maps to exactly one rule it violates -- the findings that recur in real code review:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;v1.5 encryption &quot;kept for compatibility.&quot;&lt;/strong&gt; The single most dangerous line in an RSA integration. Violates: retire v1.5 encryption.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Non-constant-time OAEP or v1.5 decode.&lt;/strong&gt; A decoder that branches or times differently on padding failure. Violates: constant-time, implicit-rejection decoding (Manger, Marvin).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Distinct decryption error messages, or branch timing.&lt;/strong&gt; Any observable difference between &quot;bad padding&quot; and &quot;other error.&quot; Violates: uniform, unobservable failure (Bleichenbacher).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Missing CRT verify-before-release.&lt;/strong&gt; Signing without recomputing the result first. Violates: verify before release (Bellcore fault).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Unblinded exponentiation.&lt;/strong&gt; A modexp whose time depends on the secret. Violates: base blinding (Kocher, Brumley-Boneh).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;An $e = 3$ shortcut in a verifier.&lt;/strong&gt; Checking the prefix without rejecting trailing data. Violates: verify strictly (e-equals-3 forgery, BERserk).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Textbook RSA copied from a tutorial.&lt;/strong&gt; The raw permutation on a message. Violates: never call the raw primitive.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RSA-encrypting a large payload.&lt;/strong&gt; Treating RSA as a bulk cipher. Violates: encapsulate a key, never encrypt data.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Weak, shared, or reused-modulus keys.&lt;/strong&gt; Primes drawn from a cold CSPRNG or a structured library. Violates: seed the CSPRNG, draw primes uniformly (Mining Ps and Qs, ROCA).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OAEP hash or label mismatch, or MGF1 silently defaulting to SHA-1.&lt;/strong&gt; A quiet interoperability and downgrade trap. Violates: pin the hash and MGF explicitly.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Treating a &quot;small&quot; side channel as unexploitable.&lt;/strong&gt; Marvin demolished that folklore -- a few microseconds recovered keys [@marvin23]. Violates: assume every observable leaks.&lt;/li&gt;
&lt;/ul&gt;

Grep for the dangerous entry points and confirm every RSA decryption path uses OAEP with a constant-time decoder:&lt;ul&gt;
&lt;li&gt;Go: search for &lt;code&gt;DecryptPKCS1v15&lt;/code&gt; and &lt;code&gt;EncryptPKCS1v15&lt;/code&gt;; move to &lt;code&gt;DecryptOAEP&lt;/code&gt; and &lt;code&gt;EncryptOAEP&lt;/code&gt;. The v1.5 decryptor is deprecated for the reason quoted earlier [@gorsa].&lt;/li&gt;
&lt;li&gt;Java: flag &lt;code&gt;Cipher.getInstance(&quot;RSA/ECB/PKCS1Padding&quot;)&lt;/code&gt;; require &lt;code&gt;RSA/ECB/OAEPWithSHA-256AndMGF1Padding&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;OpenSSL CLI: &lt;code&gt;openssl pkeyutl -encrypt -pubin -inkey pub.pem -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If a dependency genuinely still needs v1.5 decryption, confirm it runs a constant-time, implicit-rejection decoder -- OpenSSL 3.2 does so by default [@openssl32].
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; In practice, three violations dominate real audits: RSA v1.5 &lt;em&gt;encryption&lt;/em&gt; still enabled &quot;for a legacy client,&quot; a decryption path that is not verifiably constant-time, and RSA being used to encrypt bulk data instead of a symmetric key. Fix those three and you have closed most of the catalog [@marvin23], [@gorsa], [@openssl32].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Read the whole failure catalog again as this checklist, and one pattern remains.&lt;/p&gt;
&lt;h2&gt;12. Trapdoor, Not Cryptosystem&lt;/h2&gt;
&lt;p&gt;Return to where we began. The researchers who signed with facebook.com&apos;s key never factored its modulus, and neither did anyone in the twenty-five years of breaks between Bleichenbacher and Marvin. The factoring problem stood untouched the whole time. What fell, every single time, was something else: the decryptor&apos;s error handling, the signer&apos;s fault behaviour, the implementation&apos;s clock, or the generator&apos;s entropy. The attacker&apos;s real move is never to solve the hard math -- it is to turn the receiver&apos;s own reaction into the private-key operation.&lt;/p&gt;

The attacker does not factor the modulus. They turn the decryptor&apos;s reaction into the private-key operation -- and &quot;done right&quot; is the discipline of leaving that reaction with nothing to say.
&lt;p&gt;That is why &quot;RSA done right&quot; is a stack and not a setting. The right scheme, OAEP to encrypt and PSS for new signatures, does two of the three jobs. The right parameters -- a 2,048-bit floor, $e = 65537$, primes from a real CSPRNG -- keep the trapdoor strong. And the constant-time, fault-checked, blinded implementation does the third job, the one the field kept forgetting: it leaves no observable behaviour that answers the attacker&apos;s one question.&lt;/p&gt;
&lt;p&gt;Every deployed disaster in this article is a stack with exactly one layer missing. Textbook RSA is broken not because the math is weak but because it is &lt;em&gt;only&lt;/em&gt; the trapdoor, with none of the layers that make a trapdoor into a cryptosystem.&lt;/p&gt;
&lt;p&gt;The forward horizon makes the discipline sharper, not softer. RSA done right is stable against every known classical attack, and it still has an expiration date, because the one gap RSA can never close is the quantum one. The destination is not a better RSA. It is KEM-DEM composition and post-quantum algorithms -- constructions where the public-key operation carries only a uniform random key, and where Shor has no polynomial-time shortcut to wait for.&lt;/p&gt;
&lt;p&gt;So ask the diagnostic question one final time, now that it is answerable. When a ciphertext or signature it did not create arrives, what does the receiver reveal about it -- through its answer, its timing, or its faults? Done right, the answer is nothing at all.&lt;/p&gt;


No, but the word &quot;RSA&quot; hides three different answers. Textbook RSA is broken. PKCS#1 v1.5 *encryption* is dangerous and should be retired [@marvin23]. Done-right RSA -- OAEP or PSS, constant-time, at least 2,048 bits, public exponent 65537 -- is fine against every known classical attack, right up until a large quantum computer exists, which is why you should be planning migration in parallel [@ir8547].


No. Encapsulate a fresh random symmetric key with the public key and let an authenticated cipher encrypt the file. RSA-OAEP at 2,048 bits carries only about 190 bytes of plaintext anyway, so it was never meant for bulk data -- it moves keys, not files [@sp80056b].


No. OAEP fixes the *scheme*, not the decoder. James Manger showed that a non-constant-time OAEP decoder re-opens the very same padding oracle, and more cheaply than the original Bleichenbacher attack [@manger01]. The rule is &quot;OAEP AND constant-time decoding,&quot; never OAEP alone.


Not as a scheme -- there is no known attack against the RSASSA-PKCS1-v1_5 signature construction itself [@rfc8017]. What breaks is lax *verifiers*: the 2006 e-equals-3 forgery and the 2014 BERserk bug both forged signatures past sloppy verification, not by breaking the scheme [@cve2006], [@cve2014]. Verify strictly -- parse the entire structure and reject any trailing data.


Only with correct padding and a strict verifier, and it is not worth the risk. A small exponent has repeatedly enabled Hastad&apos;s broadcast attack, Coppersmith&apos;s low-exponent attacks, and signature forgeries [@hastad88], [@coppersmith97]. Use 65537: it is fast and dodges every low-exponent trap.


Yes for today -- a 2,048-bit modulus gives about 112 bits of security [@sp80057]. Use 3,072 bits or more for anything that must stay secret long-term, and start post-quantum planning: NIST deprecates 112-bit RSA after 2030 and disallows it after 2035 [@ir8547].


For most new work, yes. ECDH and Ed25519 give smaller, faster keys with the forward secrecy RSA key transport never had [@rfc8446], and hybrid X25519 plus ML-KEM-768 is already carrying real TLS traffic for the quantum transition [@cloudflare24]. RSA&apos;s destination is retirement, not repair.

&lt;p&gt;&amp;lt;StudyGuide slug=&quot;rsa-done-right-oaep-pss-bleichenbacher&quot; keyTerms={[
  { term: &quot;Trapdoor permutation&quot;, definition: &quot;A one-way function with a secret shortcut. RSA maps x to x-to-the-e modulo N, invertible only by whoever knows the factorization of N. It is a primitive, not a complete cryptosystem.&quot; },
  { term: &quot;Malleability&quot;, definition: &quot;RSA&apos;s multiplicative homomorphism: multiplying a ciphertext by a chosen factor predictably scales the plaintext, letting an attacker transform messages without decrypting. It is the lever behind the padding-oracle attacks.&quot; },
  { term: &quot;Padding oracle&quot;, definition: &quot;Any observable behaviour (an error, a timing difference, or a fault) that reveals whether a decrypted ciphertext had valid padding, turning a validity check into a decryption oracle.&quot; },
  { term: &quot;RSAES-OAEP&quot;, definition: &quot;A randomized, all-or-nothing encryption padding applied before the RSA permutation, giving chosen-ciphertext security in the random-oracle model, provided the decoder runs in constant time.&quot; },
  { term: &quot;RSASSA-PSS&quot;, definition: &quot;A randomized, salted RSA signature encoding with a tight security reduction to the RSA problem, the provable choice for new signature designs.&quot; },
  { term: &quot;Implicit rejection&quot;, definition: &quot;Returning a deterministic pseudo-random value on a padding failure instead of a distinguishable error, so success and failure are unobservable through content, error type, or timing.&quot; },
  { term: &quot;CRT in RSA&quot;, definition: &quot;Computing the private operation modulo p and modulo q separately for a roughly fourfold speedup, at the cost of a fault-attack surface unless the result is verified before release.&quot; },
  { term: &quot;KEM-DEM&quot;, definition: &quot;Transporting a random symmetric key with the public key, then encrypting the data with that key under an authenticated cipher, so no chosen structured plaintext exists for an oracle to grade.&quot; },
  { term: &quot;IND-CCA2&quot;, definition: &quot;The strongest standard security goal for encryption: even with access to a decryption oracle, an attacker cannot tell which plaintext a ciphertext hides. Padding oracles violate it.&quot; }
]} questions={[
  { q: &quot;Why is textbook RSA not a cryptosystem?&quot;, a: &quot;It is deterministic, malleable, and structurally leaky for small exponents. It needs padding that adds randomness, adds checkable redundancy, and leaks nothing about whether the check passed.&quot; },
  { q: &quot;What single bit did every attack from Bleichenbacher to Marvin leak?&quot;, a: &quot;Whether the padding was valid. Only the channel changed, from an error message to a cross-protocol zombie to a TCP quirk to pure timing.&quot; },
  { q: &quot;Why is OAEP necessary but not sufficient?&quot;, a: &quot;OAEP secures the scheme, but Manger showed that a non-constant-time decoder re-opens the same oracle. Security is a property of the scheme and its implementation together.&quot; },
  { q: &quot;What is the one split you must never blur?&quot;, a: &quot;v1.5 encryption is dangerous and should be retired, while v1.5 signatures are unbroken as a scheme and still dominant. Verify the signatures strictly.&quot; },
  { q: &quot;Why does done-right RSA still have an expiration date?&quot;, a: &quot;There is no proof RSA is secure, and Shor&apos;s algorithm factors in polynomial time on a quantum computer, so the destination is KEM-DEM plus post-quantum cryptography.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>rsa</category><category>oaep</category><category>rsa-pss</category><category>padding-oracle</category><category>bleichenbacher</category><category>post-quantum-crypto</category><category>cryptography</category><category>applied-cryptography</category><author>noreply@paragmali.com (Parag Mali)</author></item></channel></rss>