<?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: elliptic-curve-cryptography</title><description>Posts tagged elliptic-curve-cryptography.</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/elliptic-curve-cryptography/rss.xml" rel="self" type="application/rss+xml"/><item><title>How Elliptic Curves and Diffie-Hellman Break in Real Life: The Discrete Log Never Fell</title><link>https://paragmali.com/blog/how-elliptic-curves-and-diffie-hellman-break-in-real-life-th/</link><guid isPermaLink="true">https://paragmali.com/blog/how-elliptic-curves-and-diffie-hellman-break-in-real-life-th/</guid><description>No one has solved the discrete log on a strong curve or a 2048-bit group -- yet PS3, Android wallets, TPMs, CurveBall, and Logjam all fell. Here is exactly how.</description><pubDate>Sat, 18 Jul 2026 00:00:00 GMT</pubDate><content:encoded>
On a strong curve or a 2048-bit group, no one has ever solved the discrete logarithm in the field -- yet PlayStation 3 consoles, Android Bitcoin wallets, tamper-resistant TPMs, Windows certificate validation, and live TLS sessions all fell. Every one of those breaks attacked a layer the discrete-log math depends on but does not control: the per-signature nonce (PS3, Android, Minerva, TPM-Fail, LadderLeak), the curve and certificate parameters (CurveBall), or the negotiated strength (Logjam). A *reused* nonce surrenders the key from just two signatures; a *biased* nonce needs a statistical attack over many. The only discrete log ever computed here was Logjam&apos;s, against a downgrade-forced, export-crippled, shared 512-bit prime -- never a strong deployed curve. The fix is never a bigger curve. It is hedged, constant-time signing, validated parameters, and retiring export and shared groups.
&lt;h2&gt;1. Seven Breaks, One Unbroken Problem&lt;/h2&gt;
&lt;p&gt;On a well-chosen elliptic curve, the best attack anyone has ever fielded against the discrete logarithm is a square-root-time random walk that has barely moved since the 1970s [@hac-ch11][@teske-2001]. No deployed P-256, Curve25519, or secp256k1 key, and no standard 2048-bit Diffie-Hellman group, has ever had its discrete log solved in public. By every measurement we can make, the mathematics is holding.&lt;/p&gt;
&lt;p&gt;And yet. PlayStation 3 consoles were jailbroken [@fail0verflow-ps3-2010]. Android Bitcoin wallets were emptied [@bitcoin-android-2013]. Tamper-resistant TPMs certified to government standards surrendered their signing keys [@tpmfail-2020]. Windows accepted forged certificates that chained to a counterfeit authority [@curveball-cve-2020-0601]. Live TLS sessions were downgraded and decrypted in transit [@logjam-weakdh-2015]. Every one of those systems ran the discrete-log math exactly as specified. The math was never where they broke.&lt;/p&gt;
&lt;p&gt;That is the paradox this article resolves, and the resolution fits in one sentence: none of these attacks solved a discrete logarithm. Each attacked a layer the math &lt;em&gt;depends on but does not control&lt;/em&gt;. There are exactly three such layers, and they organize everything that follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The per-signature nonce&lt;/strong&gt; -- the throwaway secret ECDSA needs for every signature. PS3, Android, Minerva, TPM-Fail, and LadderLeak all landed here.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The curve and certificate parameters&lt;/strong&gt; -- which curve, and whose generator, you are actually talking to. CurveBall landed here.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The negotiated strength&lt;/strong&gt; -- how strong a key exchange two parties agree to use before they exchange anything. Logjam landed here.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The discrete-logarithm assumption protects the private key against being &lt;em&gt;directly computed&lt;/em&gt; -- and nothing else. &quot;Nobody solved the discrete log&quot; and &quot;somebody recovered the private key&quot; are not contradictory statements, because the discrete-log &lt;em&gt;problem&lt;/em&gt; (genuinely hard) and a discrete-log &lt;em&gt;deployment&lt;/em&gt; (a nonce, some parameters, a negotiation) are different things. Every real break in this article lives in the gap between them.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A note on scope. This piece treats the hardness of the elliptic-curve discrete logarithm as a black box: assume it holds, and watch everything around it fail. The structural mathematics of curve choice -- why one curve is weak and another is strong, how the number field sieve and Shor&apos;s algorithm actually work -- belongs to a companion article, &quot;How the Discrete Log Would Break: Elliptic Curves, Finite Fields, and Why Curve Choice Is the Weak Part.&quot; Here, we assume the strongbox is uncrackable and ask how the key kept getting out anyway.&lt;/p&gt;
&lt;p&gt;To see why a hard problem protects so little, you first have to see exactly what it promises -- and what it quietly leaves to the deployment.&lt;/p&gt;
&lt;h2&gt;2. What the Math Actually Promises&lt;/h2&gt;
&lt;p&gt;In 1976, Whitfield Diffie and Martin Hellman reduced the ancient problem of exchanging a secret over an open wire to a single piece of hard arithmetic: the discrete logarithm [@diffie-hellman-1976]. Two parties each pick a private exponent, exchange public powers of a shared generator, and combine them into a key that an eavesdropper cannot reconstruct without solving for one of those exponents.&lt;/p&gt;
&lt;p&gt;Nine years later, Victor Miller and, independently, Neal Koblitz moved the same hard problem onto elliptic curves [@miller-1985][@koblitz-1987]. Koblitz argued the curve version was &quot;likely to be harder than the classical discrete logarithm problem&quot; [@koblitz-1987] -- which is why a 256-bit curve buys security that a finite field needs thousands of bits to match. A clean, triumphant origin. So where did the promise leak?&lt;/p&gt;

Given a generator `G` and a public point `Q = dG` on an elliptic curve (or a base `g` and `g^d` in a finite field), recovering the secret integer `d` is the discrete logarithm problem. The security of ECDSA, ECDH, and Diffie-Hellman rests on the assumption that this recovery is computationally infeasible for well-chosen parameters. It is the one thing the math promises -- and, as we will see, the only thing.
&lt;p&gt;Signatures are where the story starts, because signatures introduce a second secret. The Elliptic Curve Digital Signature Algorithm (ECDSA) signs a message hash &lt;code&gt;z&lt;/code&gt; under a long-term private key &lt;code&gt;d&lt;/code&gt; by generating a fresh random value &lt;code&gt;k&lt;/code&gt;, computing a point &lt;code&gt;kG&lt;/code&gt;, taking its x-coordinate as &lt;code&gt;r&lt;/code&gt;, and producing:&lt;/p&gt;
&lt;p&gt;$$s = k^{-1},(z + r,d) \bmod n$$&lt;/p&gt;
&lt;p&gt;where &lt;code&gt;n&lt;/code&gt; is the order of the group. The verifier only ever sees &lt;code&gt;(r, s)&lt;/code&gt;. The private key &lt;code&gt;d&lt;/code&gt; is buried inside, protected by the discrete-log assumption -- nobody can read &lt;code&gt;d&lt;/code&gt; off the signature. But look at what else is in that equation.&lt;/p&gt;

The `k` in ECDSA is a *nonce*: a number used once. It must be secret, statistically uniform, and unique to each signature. It is not the private key, and it is thrown away the instant the signature is produced. It is also the single most load-bearing prerequisite in the whole scheme -- because `k` and `d` appear together in one linear equation, anything an attacker learns about `k` turns directly into knowledge of `d`.
&lt;p&gt;The discrete-log assumption guards &lt;code&gt;d&lt;/code&gt; against being &lt;em&gt;computed&lt;/em&gt; from the public key. It says nothing whatsoever about three things the assumption quietly depends on but does not itself enforce:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;The nonce &lt;code&gt;k&lt;/code&gt; must be secret, uniform, and unique.&lt;/strong&gt; The math assumes a perfect &lt;code&gt;k&lt;/code&gt; and never checks that you supplied one.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The parameters must be the standard, named ones.&lt;/strong&gt; The math assumes you are on the curve you think you are, with the generator you think you have.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The negotiated strength must not be crippled or shared.&lt;/strong&gt; The math assumes the group you agreed to use is actually strong.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Each of those is the deployment&apos;s responsibility, not the primitive&apos;s. And each one became a pillar of failure.&lt;/p&gt;

flowchart TD
    DLP[&quot;(EC)DLP is hard: d cannot be computed from the public key dG&quot;]
    DLP --&amp;gt; N[&quot;Depends on the per-signature nonce k&quot;]
    DLP --&amp;gt; P[&quot;Depends on the curve and certificate parameters&quot;]
    DLP --&amp;gt; G[&quot;Depends on the negotiated group strength&quot;]
    N --&amp;gt; P1[&quot;Pillar 1 nonce: PS3, Android, Minerva, TPM-Fail, LadderLeak&quot;]
    P --&amp;gt; P2[&quot;Pillar 2 validation: CurveBall&quot;]
    G --&amp;gt; P3[&quot;Pillar 3 downgrade: Logjam&quot;]
&lt;p&gt;The curve migration itself is not our subject.Miller (1985) and Koblitz (1987) are mentioned here only to fix the primitive&apos;s birth. Whether a &lt;em&gt;particular&lt;/em&gt; curve is structurally weak -- anomalous curves, small embedding degrees, the number field sieve, Shor&apos;s algorithm -- is the structural mathematics deferred to the companion article. This article assumes the curve is strong and attacks everything around it. The math guards the key against being computed. It says nothing about the key being &lt;em&gt;handed over&lt;/em&gt;. Three contracts govern that handover, and each one broke.&lt;/p&gt;
&lt;h2&gt;3. Three Contracts the Deployment Signs and Never Reads&lt;/h2&gt;
&lt;p&gt;Every cryptographic deployment signs a contract it never reads. There are three clauses, one for each layer the math leans on, and the fine print on all three is where real products sank.&lt;/p&gt;
&lt;h3&gt;The nonce contract: k must be fresh&lt;/h3&gt;
&lt;p&gt;Take the ECDSA signing equation and ask the cruelest possible question: what if &lt;code&gt;k&lt;/code&gt; is not unique? Suppose two different messages, with hashes &lt;code&gt;z1&lt;/code&gt; and &lt;code&gt;z2&lt;/code&gt;, are signed under the &lt;em&gt;same&lt;/em&gt; nonce &lt;code&gt;k&lt;/code&gt;. Because &lt;code&gt;r&lt;/code&gt; is the x-coordinate of &lt;code&gt;kG&lt;/code&gt;, the same &lt;code&gt;k&lt;/code&gt; produces the same &lt;code&gt;r&lt;/code&gt; in both signatures. Now write them down side by side:&lt;/p&gt;
&lt;p&gt;$$s_1 = k^{-1}(z_1 + r,d), \qquad s_2 = k^{-1}(z_2 + r,d) \pmod n$$&lt;/p&gt;
&lt;p&gt;Subtract. The &lt;code&gt;rd&lt;/code&gt; term is identical in both, so it cancels, and &lt;code&gt;k&lt;/code&gt; falls straight out:&lt;/p&gt;
&lt;p&gt;$$s_1 - s_2 = k^{-1}(z_1 - z_2), \qquad k = \frac{z_1 - z_2}{s_1 - s_2} \bmod n$$&lt;/p&gt;
&lt;p&gt;Once you know &lt;code&gt;k&lt;/code&gt;, the first equation has exactly one unknown left, and you solve for the private key by hand:&lt;/p&gt;
&lt;p&gt;$$d = \frac{s_1,k - z_1}{r} \bmod n$$&lt;/p&gt;
&lt;p&gt;No lattice. No side channel. No discrete log. &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;Two signatures that share a nonce&lt;/a&gt; are two linear equations in two unknowns, and a middle-schooler with modular arithmetic can finish the job.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The discrete-logarithm assumption protects &lt;code&gt;d&lt;/code&gt; against &lt;em&gt;direct computation from the public key&lt;/em&gt; -- and nothing else. It does not protect &lt;code&gt;d&lt;/code&gt; against being algebraically extracted when the nonce misbehaves. The moment two signatures reuse &lt;code&gt;k&lt;/code&gt;, the strongbox is irrelevant, because the deployment left a second door wide open.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The contract, then, is strict: &lt;code&gt;k&lt;/code&gt; must be secret, statistically uniform, and never reused or partially leaked. Break any word of that clause and the algebra above (or its statistical cousin, later) takes your key.&lt;/p&gt;
&lt;h3&gt;The parameter contract: talk to the curve you think you are&lt;/h3&gt;
&lt;p&gt;The second clause is about identity. A &lt;em&gt;named&lt;/em&gt; curve -- &quot;P-256,&quot; &quot;secp256k1&quot; -- is an agreement to use one specific set of domain parameters, and in particular one specific generator, the base point &lt;code&gt;G&lt;/code&gt; that every public key is measured against.&lt;/p&gt;

Every named elliptic curve fixes a single public point `G` from which all key material is derived: a private key `d` corresponds to the public point `dG`. The generator is not a secret -- it is a published constant. But it is load-bearing: &quot;the public key is `dG`&quot; is only meaningful if both sides agree on which `G`.

A certificate can specify its curve two ways. A *named curve* is an object identifier pointing at standardized domain parameters (fixed `a`, `b`, `p`, `G`, `n`). *Explicit parameters* spell out all of those numbers inline, which lets the certificate carry a *custom* generator. Accepting explicit parameters without checking them against a known named curve means trusting an attacker to tell you what `G` is.
&lt;p&gt;The contract: never trust attacker-supplied explicit parameters. A validator that checks a public &lt;em&gt;point&lt;/em&gt; but not the &lt;em&gt;generator&lt;/em&gt; it was measured against has, in effect, let the attacker choose the ruler and then declared the measurement correct. That is precisely the door CurveBall walked through [@curveball-cve-2020-0601].&lt;/p&gt;
&lt;h3&gt;The negotiation contract: agree to strength, not to a museum piece&lt;/h3&gt;
&lt;p&gt;The third clause governs what two parties agree to &lt;em&gt;before&lt;/em&gt; they exchange anything. In &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;ephemeral Diffie-Hellman&lt;/a&gt;, each side picks a fresh secret per connection, which is supposed to guarantee that compromising one session cannot retroactively expose others.&lt;/p&gt;

In ephemeral DH, the private exponents are generated fresh for each connection and discarded afterward, so a key recovered later cannot decrypt past sessions. This property is called forward secrecy. It is the reason &quot;just use a fresh ephemeral key&quot; feels like a complete defense -- and, as Logjam showed, the reason that feeling is dangerously incomplete.

In the 1990s, US export regulations capped the strength of cryptography shipped abroad, producing deliberately weakened cipher suites such as 512-bit `DHE_EXPORT` Diffie-Hellman [@logjam-weakdh-2015]. The policy was abandoned, but the code was not: two decades later, servers and libraries still spoke these crippled suites on request.
&lt;p&gt;The contract: the negotiated group must be strong, fresh, and unshared. The fine print that sank it: many servers ship the &lt;em&gt;same&lt;/em&gt; standardized 512-bit prime, so breaking one group breaks all of them at once [@logjam-weakdh-2015]. A fresh ephemeral exponent does not save you when the prime itself is weak and shared.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Contract&lt;/th&gt;
&lt;th&gt;What it requires&lt;/th&gt;
&lt;th&gt;What violates it&lt;/th&gt;
&lt;th&gt;Field break&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Nonce&lt;/td&gt;
&lt;td&gt;&lt;code&gt;k&lt;/code&gt; secret, uniform, unique per signature&lt;/td&gt;
&lt;td&gt;a constant, repeated, or biased &lt;code&gt;k&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;PS3, Android, Minerva, TPM-Fail, LadderLeak&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Parameter&lt;/td&gt;
&lt;td&gt;named curve, standard generator &lt;code&gt;G&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;trusting attacker-supplied explicit parameters&lt;/td&gt;
&lt;td&gt;CurveBall&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Negotiation&lt;/td&gt;
&lt;td&gt;strong, fresh, unshared group&lt;/td&gt;
&lt;td&gt;downgrade to a crippled, shared group&lt;/td&gt;
&lt;td&gt;Logjam&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Three contracts, three clauses of fine print. Over fifteen years, every clause was breached in the field -- and the breaches fall into exactly three piles.&lt;/p&gt;
&lt;h2&gt;4. The Failure Catalog: Seven Breaks, Three Layers, One Shape&lt;/h2&gt;
&lt;p&gt;None of the seven incidents below solved a discrete logarithm. Every one of them recovered a private key or forged a trusted one. Watch where each attack actually landed -- because the landing spot, not the marquee name, is the whole lesson.&lt;/p&gt;

timeline
    title EC and DH in the field, the assumption versus the breaks
    1976 : Diffie-Hellman, the assumption is born
    1985-1987 : Miller and Koblitz, the curve migration
    2010 : PS3 constant nonce, reuse
    2013 : Android SecureRandom, reuse
    2015 : Logjam, downgrade plus shared-prime NFS
    2019-2020 : Minerva and TPM-Fail, lattice bias
    2020 : LadderLeak, Bleichenbacher-Fourier sub-bit : CurveBall, unvalidated generator
&lt;p&gt;Here is the entire corpus on one page. The rightmost column is the thesis in a single word, repeated seven times.&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;Effort to break&lt;/th&gt;
&lt;th&gt;What fell&lt;/th&gt;
&lt;th&gt;Discrete log solved?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;PS3&lt;/td&gt;
&lt;td&gt;2010&lt;/td&gt;
&lt;td&gt;Nonce (reuse)&lt;/td&gt;
&lt;td&gt;a constant &lt;code&gt;k&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2 signatures&lt;/td&gt;
&lt;td&gt;ECDSA firmware-signing key&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Android wallets&lt;/td&gt;
&lt;td&gt;2013&lt;/td&gt;
&lt;td&gt;Nonce (reuse)&lt;/td&gt;
&lt;td&gt;repeated &lt;code&gt;k&lt;/code&gt; from a broken RNG&lt;/td&gt;
&lt;td&gt;2 reused signatures&lt;/td&gt;
&lt;td&gt;Bitcoin wallet keys&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Logjam&lt;/td&gt;
&lt;td&gt;2015&lt;/td&gt;
&lt;td&gt;Downgrade&lt;/td&gt;
&lt;td&gt;forced 512-bit shared prime&lt;/td&gt;
&lt;td&gt;1 NFS precompute per prime&lt;/td&gt;
&lt;td&gt;TLS session secrecy&lt;/td&gt;
&lt;td&gt;Only a crippled, shared 512-bit export prime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TPM-Fail&lt;/td&gt;
&lt;td&gt;2019-2020&lt;/td&gt;
&lt;td&gt;Nonce (bias)&lt;/td&gt;
&lt;td&gt;timing leak of nonce bit-length&lt;/td&gt;
&lt;td&gt;many signatures + lattice&lt;/td&gt;
&lt;td&gt;256-bit TPM keys&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Minerva&lt;/td&gt;
&lt;td&gt;2020&lt;/td&gt;
&lt;td&gt;Nonce (bias)&lt;/td&gt;
&lt;td&gt;timing leak of nonce bit-length&lt;/td&gt;
&lt;td&gt;about 2100 signatures + lattice&lt;/td&gt;
&lt;td&gt;ECDSA key&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LadderLeak&lt;/td&gt;
&lt;td&gt;2020&lt;/td&gt;
&lt;td&gt;Nonce (bias)&lt;/td&gt;
&lt;td&gt;sub-bit ladder leak&lt;/td&gt;
&lt;td&gt;many signatures + Bleichenbacher/Fourier&lt;/td&gt;
&lt;td&gt;ECDSA key&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CurveBall&lt;/td&gt;
&lt;td&gt;2020&lt;/td&gt;
&lt;td&gt;Validation&lt;/td&gt;
&lt;td&gt;an unchecked generator&lt;/td&gt;
&lt;td&gt;1 forged certificate&lt;/td&gt;
&lt;td&gt;certificate trust itself&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Six &quot;No&quot;s and one heavily qualified &quot;Yes.&quot; Let us walk the three pillars in turn.&lt;/p&gt;
&lt;h3&gt;Pillar 1a: the nonce, reused (certain, from two signatures)&lt;/h3&gt;
&lt;p&gt;In December 2010, at the 27th Chaos Communication Congress, the group fail0verflow presented &quot;Console Hacking 2010&quot; and revealed that Sony had signed PlayStation 3 firmware using ECDSA with a &lt;em&gt;constant&lt;/em&gt; nonce [@fail0verflow-ps3-2010]. Not a weak random &lt;code&gt;k&lt;/code&gt;. The same &lt;code&gt;k&lt;/code&gt;, every time. Every signature Sony ever produced shared a nonce with every other, which means any two of them collapse to the algebra from Section 3.Keep two PS3 events distinct. fail0verflow&apos;s 27C3 talk exposed the constant-nonce &lt;em&gt;mechanism&lt;/em&gt;. George Hotz released a separate PS3 root key weeks later, in January 2011 [@hotz-ps3-2011]. The teaching case -- a hardcoded constant nonce -- is fail0verflow&apos;s. The console&apos;s chain of trust, the thing Sony spent years engineering, came apart because &lt;a href=&quot;https://paragmali.com/blog/predictable-or-repeated-the-only-two-ways-cryptographic-rand/&quot; rel=&quot;noopener&quot;&gt;a random number generator&lt;/a&gt; was told to always return the same number.&lt;/p&gt;

flowchart LR
    A[&quot;Sig 1: s1 = k^-1 (z1 + r d)&quot;] --&amp;gt; C[&quot;Same k means same r&quot;]
    B[&quot;Sig 2: s2 = k^-1 (z2 + r d)&quot;] --&amp;gt; C
    C --&amp;gt; D[&quot;Subtract, k cancels: k = (z1 - z2) / (s1 - s2) mod n&quot;]
    D --&amp;gt; E[&quot;Solve for d = (s1 k - z1) / r mod n&quot;]
    E --&amp;gt; F[&quot;Private key recovered, no discrete log solved&quot;]
&lt;p&gt;This is not a metaphor. Here is the recovery, executable. Two signatures share a nonce, and a dozen lines of BigInt arithmetic reproduce the private key exactly:&lt;/p&gt;
&lt;p&gt;{`
// secp256k1 group order
const n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141n;
const mod = (a, m) =&amp;gt; ((a % m) + m) % m;&lt;/p&gt;
&lt;p&gt;// Modular inverse via the extended Euclidean algorithm
function inv(a, m) {
  let [oldr, r] = [mod(a, m), m];
  let [olds, s] = [1n, 0n];
  while (r !== 0n) {
    const q = oldr / r;
    [oldr, r] = [r, oldr - q * r];
    [olds, s] = [s, olds - q * s];
  }
  return mod(olds, m);
}&lt;/p&gt;
&lt;p&gt;// A victim signs two different messages with the SAME nonce k
const d  = 0x00c0ffee1234567890abcdef00c0ffee1234567890abcdef00c0ffee12345678n; // secret
const k  = 0x0000deadbeef0000feed0000deadbeef0000feed0000deadbeef0000feed0001n; // reused nonce
const r  = mod(0x1122334455667788112233445566778811223344556677881122334455667788n, n);
const z1 = 0x1111111111111111111111111111111111111111111111111111111111111111n;
const z2 = 0x2222222222222222222222222222222222222222222222222222222222222222n;
const s1 = mod(inv(k, n) * mod(z1 + mod(r * d, n), n), n);
const s2 = mod(inv(k, n) * mod(z2 + mod(r * d, n), n), n);&lt;/p&gt;
&lt;p&gt;// The attacker sees only (r, s1, z1) and (r, s2, z2). Recover k, then d.
const kRec = mod((z1 - z2) * inv(mod(s1 - s2, n), n), n);
const dRec = mod((mod(s1 * kRec, n) - z1) * inv(r, n), n);
console.log(&apos;recovered nonce matches:  &apos; + (kRec === k));
console.log(&apos;recovered private key:    &apos; + (dRec === d));
console.log(&apos;d = 0x&apos; + dRec.toString(16));
`}&lt;/p&gt;
&lt;p&gt;Three years later, the same algebra emptied wallets. In August 2013, an advisory on bitcoin.org warned that &quot;a component of Android responsible for generating secure random numbers contains critical weaknesses&quot; that rendered &quot;all Android wallets&quot; vulnerable to theft [@bitcoin-android-2013]. The root cause, per Google&apos;s own postmortem, was that the platform&apos;s &lt;code&gt;SecureRandom&lt;/code&gt; &quot;may not receive cryptographically strong values&quot; because the underlying PRNG was improperly initialized [@android-securerandom-2013].&lt;/p&gt;
&lt;p&gt;The consequence was nonce &lt;em&gt;repetition&lt;/em&gt; across transactions. And because every Bitcoin signature is broadcast to a public ledger, anyone could scan the chain for two signatures sharing an &lt;code&gt;r&lt;/code&gt; and drain the wallet behind them.The bitcoin.org advisory names the flaw and the affected wallets but states no total loss figure [@bitcoin-android-2013]. Any &quot;coins stolen&quot; number you have seen is reported, not established -- treat it accordingly.&lt;/p&gt;
&lt;p&gt;The detector that would have caught both PS3 and Android is embarrassingly short. Group public signatures by &lt;code&gt;r&lt;/code&gt;; any collision is an exposed key:&lt;/p&gt;
&lt;p&gt;{`
const n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141n;
const mod = (a, m) =&amp;gt; ((a % m) + m) % m;
function inv(a, m) {
  let [oldr, r] = [mod(a, m), m];
  let [olds, s] = [1n, 0n];
  while (r !== 0n) { const q = oldr / r; [oldr, r] = [r, oldr - q * r]; [olds, s] = [s, olds - q * s]; }
  return mod(olds, m);
}
// Build a public feed in which one signer reused a nonce, then forget the secret
const dSecret = 777n, kReused = 424242n, rReused = 987654321n;
const mk = (z) =&amp;gt; ({ r: rReused, s: mod(inv(kReused, n) * mod(z + mod(rReused * dSecret, n), n), n), z });
const feed = [ { r: 111n, s: 22n, z: 5n }, mk(1001n), { r: 222n, s: 44n, z: 9n }, mk(2002n), { r: 333n, s: 66n, z: 12n } ];&lt;/p&gt;
&lt;p&gt;const seen = new Map();
for (const g of feed) {
  const key = g.r.toString();
  if (seen.has(key)) {
    const a = seen.get(key), b = g;
    const k = mod((a.z - b.z) * inv(mod(a.s - b.s, n), n), n);
    const d = mod((mod(a.s * k, n) - a.z) * inv(a.r, n), n);
    console.log(&apos;NONCE REUSE at r = &apos; + key + &apos;  -&amp;gt;  private key d = &apos; + d.toString());
  } else {
    seen.set(key, g);
  }
}
`}&lt;/p&gt;
&lt;p&gt;Two incidents, two different root causes -- a hardcoded constant and a starved RNG -- and one identical, certain outcome. This is the crudest form of the whole thesis: the deployment lost the key while the discrete log stood untouched.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; A &lt;em&gt;repeated&lt;/em&gt; nonce is certain key recovery from just two signatures, by elementary algebra. A &lt;em&gt;biased&lt;/em&gt; nonce -- one that merely leans, statistically, toward certain values -- leaks only a partial statistic and requires a statistical attack over many signatures. &quot;One biased signature leaks your key&quot; is false. The distinction is the difference between the next two subsections, and blurring it is the single most common error in this area.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;Reused nonce&lt;/th&gt;
&lt;th&gt;Biased nonce&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;What leaks&lt;/td&gt;
&lt;td&gt;the whole nonce (it repeats)&lt;/td&gt;
&lt;td&gt;a partial statistic about the nonce&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Signatures needed&lt;/td&gt;
&lt;td&gt;exactly 2&lt;/td&gt;
&lt;td&gt;many (Minerva about 2100; PuTTY about 60 [@putty-cve-2024-31497])&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Attack&lt;/td&gt;
&lt;td&gt;elementary algebra&lt;/td&gt;
&lt;td&gt;Hidden Number Problem (lattice or Fourier)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Certainty&lt;/td&gt;
&lt;td&gt;certain&lt;/td&gt;
&lt;td&gt;statistical&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Examples&lt;/td&gt;
&lt;td&gt;PS3, Android&lt;/td&gt;
&lt;td&gt;Minerva, TPM-Fail, LadderLeak, PuTTY&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h3&gt;Pillar 1b: the nonce, biased (statistical, over many signatures)&lt;/h3&gt;
&lt;p&gt;Reuse is loud. The subtler failure is a nonce that never repeats but is not quite uniform -- one whose top bit is a little too often zero, say. It turns out that even this surrenders the key, and the theory predicting it predates the exploits by two decades.&lt;/p&gt;

Given many samples that each leak a few of the most-significant bits of `k`, together with the public signature data, recover the fixed secret `d`. Boneh and Venkatesan defined this problem in 1996 and proved it tractable [@boneh-venkatesan-1996]. Every biased-nonce attack in this article -- Minerva, TPM-Fail, LadderLeak, PuTTY -- is an instance of it.
&lt;p&gt;Nguyen and Shparlinski turned the abstract HNP into a concrete lattice attack on (EC)DSA with partially known nonces [@nguyen-shparlinski-2003], and Brumley and Tuveri showed in 2011 that the necessary bit-leak could be harvested &lt;em&gt;remotely&lt;/em&gt;, over a network, from an OpenSSL implementation whose scalar multiplication was not constant-time [@brumley-tuveri-2011]. Then the field split into two solver regimes, and telling them apart is essential.&lt;/p&gt;
&lt;p&gt;When the &lt;a href=&quot;https://paragmali.com/blog/correct-constant-time-and-still-owned-a-field-guide-to-side-/&quot; rel=&quot;noopener&quot;&gt;timing channel&lt;/a&gt; leaks a &lt;em&gt;few bits&lt;/em&gt; of the nonce -- typically its exact bit-length -- the HNP is solved by &lt;strong&gt;lattice reduction&lt;/strong&gt;. Minerva (CHES 2020) demonstrated this against smartcards and libraries whose scalar multiplication ran in time correlated with the nonce&apos;s length, reporting roughly &quot;2100 signatures to recover the private key on the standard secp256r1 curve&quot; [@minerva-2020].&lt;/p&gt;
&lt;p&gt;TPM-Fail (USENIX Security 2020) carried the same idea into hardware roots of trust. A timing leak in Intel firmware TPMs (CVE-2019-11090 [@cve-2019-11090]) and STMicroelectronics ST33 chips (CVE-2019-16863 [@cve-2019-16863]) recovered a 256-bit ECDSA key from an Intel fTPM in 4 to 20 minutes, and a VPN authentication key remotely in about five hours [@tpmfail-2020].Two honesty notes. Minerva&apos;s project page retracted its original EdDSA claim; the confirmed result is ECDSA-only [@minerva-2020]. And the TPM-Fail targets were not toys -- they held Common Criteria EAL4+ and FIPS 140-2 certification, and the leak survived that scrutiny [@tpmfail-2020].&lt;/p&gt;

flowchart TD
    L[&quot;A timing channel leaks partial information about the nonce k&quot;] --&amp;gt; Q{&quot;How much leaks per signature?&quot;}
    Q --&amp;gt;|&quot;at least 2 bits&quot;| LAT[&quot;Lattice reduction of the HNP: Minerva, TPM-Fail&quot;]
    Q --&amp;gt;|&quot;under 1 bit&quot;| FFT[&quot;Bleichenbacher and Fourier HNP: LadderLeak&quot;]
    LAT --&amp;gt; R[&quot;Private key d recovered over MANY signatures&quot;]
    FFT --&amp;gt; R
&lt;p&gt;The second regime is where people get it wrong. When the leak drops &lt;em&gt;below a single bit&lt;/em&gt; -- LadderLeak revealed the most-significant bit of the nonce &quot;but with probability less than one&quot; -- lattices become intractable, and the attack instead revives a Fourier-analysis method the paper credits to Daniel Bleichenbacher [@ladderleak-2020].&lt;/p&gt;
&lt;p&gt;The LadderLeak authors note that &quot;most of the attacks so far have relied on at least two bits of nonce bias,&quot; precisely the lattice regime. Their contribution was to break below it, over curves sect163r1 and NIST P-192, using the Fourier solver rather than a lattice [@ladderleak-2020]. Calling LadderLeak a lattice attack is the field&apos;s classic mistake.&lt;/p&gt;

&quot;Breaking ECDSA With Less Than One Bit Of Nonce Leakage&quot; -- the title of the LadderLeak paper, and the most compact statement of how little a nonce must betray before the key is gone.
&lt;p&gt;Notice what happened across this subsection. Every one of these attacks beat a signer that had already removed the reuse bug. The leak had moved from how the nonce was &lt;em&gt;generated&lt;/em&gt; to how it was &lt;em&gt;used&lt;/em&gt; -- a variable-time scalar multiplication -- and the cure had to move with it. Hold that thought; it is the pivot of the entire article. But reuse or bias, lattice or Fourier, two signatures or two thousand, the outcome is the same and the discrete logarithm is never touched: the deployment hands over &lt;code&gt;d&lt;/code&gt;, and the strongbox stays locked.&lt;/p&gt;
&lt;h3&gt;Pillar 2: the parameters, unvalidated (CurveBall)&lt;/h3&gt;
&lt;p&gt;The nonce pillar is about a secret the deployment mishandles. The second pillar is about an identity the deployment fails to check. On 14 January 2020, Microsoft patched CVE-2020-0601, reported by the NSA: &quot;a spoofing vulnerability exists in the way Windows CryptoAPI (Crypt32.dll) validates Elliptic Curve Cryptography (ECC) certificates&quot; [@curveball-cve-2020-0601]. It became known as CurveBall, and it is the cleanest example in the whole corpus of a break that has nothing to do with the mathematics of ECC.&lt;/p&gt;
&lt;p&gt;Recall the parameter contract. A public key is the point &lt;code&gt;dG&lt;/code&gt; -- meaningful only if everyone agrees on &lt;code&gt;G&lt;/code&gt;. CryptoAPI, when handed a certificate that specified its curve with &lt;em&gt;explicit&lt;/em&gt; parameters, checked that the certificate&apos;s public &lt;em&gt;point&lt;/em&gt; matched a trusted root&apos;s public key. What it did not check was the &lt;em&gt;generator&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;So an attacker could craft a curve with a custom generator &lt;code&gt;G&apos;&lt;/code&gt;, pick any private key &lt;code&gt;d&apos;&lt;/code&gt; they liked, and compute &lt;code&gt;G&apos;&lt;/code&gt; such that &lt;code&gt;d&apos; * G&apos;&lt;/code&gt; equals the exact public point of a &lt;a href=&quot;https://paragmali.com/blog/a-perfect-signature-for-a-certificate-that-should-never-have/&quot; rel=&quot;noopener&quot;&gt;trusted root certificate authority&lt;/a&gt;. The forged certificate then presents the right public point on the wrong curve. Windows, comparing only the point, accepts it -- while a library that pins named curves rejects it instantly, because &lt;code&gt;G&apos;&lt;/code&gt; is not the standard base point.&lt;/p&gt;

flowchart TD
    A[&quot;Attacker picks explicit curve parameters with a custom generator G-prime&quot;] --&amp;gt; B[&quot;Chooses private key d-prime so that d-prime times G-prime equals a trusted root public point Q&quot;]
    B --&amp;gt; C[&quot;Forged certificate presents point Q on the attacker curve&quot;]
    C --&amp;gt; D{&quot;Windows CryptoAPI validation&quot;}
    D --&amp;gt;|&quot;Public point matches a trusted root? YES&quot;| E[&quot;Accepted, but the generator was never checked&quot;]
    D -.-&amp;gt;|&quot;A named-curve-pinning library also checks G&quot;| F[&quot;Rejected, G-prime is not the standard base point&quot;]
    E --&amp;gt; G[&quot;Forged code-signing or TLS certificate chains to a trusted root&quot;]
&lt;p&gt;The ECDLP was never in play. The attacker chose their own private key; they never had to recover anyone&apos;s. The failure is a single missing comparison -- generator against named curve -- buried in a certificate validation stack that a billion machines trusted. CurveBall is a validation bug, not a curve break, and the fix is exactly what the missing check would have been: reject explicit parameters, or fully re-validate them against the claimed named curve.&lt;/p&gt;
&lt;h3&gt;Pillar 3: the negotiation, downgraded (Logjam)&lt;/h3&gt;
&lt;p&gt;The third pillar is the one honest exception, and handled carelessly it looks like a refutation of the whole thesis. In 2015, the Logjam team (CVE-2015-4000) showed that a man-in-the-middle could rewrite a TLS handshake -- &quot;rewriting a ClientHello with DHE replaced by DHE_EXPORT&quot; -- to force the connection onto a 512-bit export-grade Diffie-Hellman group [@cve-2015-4000]. And here, unlike everywhere else, the attacker really does compute a discrete logarithm.&lt;/p&gt;
&lt;p&gt;The trick is that the expensive part of the number field sieve has to be done only once per prime, and servers share primes.&lt;/p&gt;

The fastest known classical algorithm for the finite-field discrete logarithm (and for integer factoring). Its decisive feature here: its costly first stage depends only on the *prime* being attacked, not on any particular exchanged key. Precompute once per prime, and every session under that prime becomes cheap to break. The internals belong to the companion article; what matters here is that one structural fact.
&lt;p&gt;The Logjam researchers found that &quot;8.4% of the Top 1 Million domains were initially vulnerable,&quot; and that because so many servers reused a handful of standardized 512-bit primes, &quot;the first step in the number field sieve ... is dependent only on this prime&quot; [@logjam-weakdh-2015]. One precomputation, amortized across every server that shipped that prime.&lt;/p&gt;

&quot;The first step in the number field sieve ... is dependent only on this prime.&quot; One precomputation breaks every server that shares the group.

sequenceDiagram
    participant C as Client
    participant M as MITM
    participant S as Server
    Note over M: One-time NFS precomputation per shared 512-bit prime
    C-&amp;gt;&amp;gt;M: ClientHello offering DHE
    M-&amp;gt;&amp;gt;S: ClientHello rewritten to DHE_EXPORT
    S-&amp;gt;&amp;gt;M: 512-bit export DH parameters, a shared standardized prime
    M-&amp;gt;&amp;gt;C: forwards the weak parameters
    Note over M: Precomputation done, so this connection solves fast
    M--&amp;gt;&amp;gt;C: session decrypted in near real time

The 512-bit `DHE_EXPORT` groups existed because 1990s US export regulations forbade shipping strong cryptography abroad, mandating deliberately breakable key exchange for foreign markets [@logjam-weakdh-2015]. The policy was abandoned by the early 2000s, but the cipher suites were never removed from server software. Logjam, in 2015, exploited a legal compromise that had been dead for over a decade and a codebase that never got the memo. The math did not decay -- the deployment simply kept a museum piece plugged in.
&lt;p&gt;Read carefully, Logjam is not a counterexample; it is the thesis in its most literal form. A discrete log &lt;em&gt;was&lt;/em&gt; computed, but only against a 512-bit prime that a downgrade forced the connection onto and that policy had left crippled and shared. The deployment set the weak, shared group on the table; the number field sieve merely finished the job. No strong, standard-sized group ever fell. The fix is the same shape as the break: remove export ciphers, negotiate vetted named groups (RFC 7919 [@rfc7919]), and adopt TLS 1.3, which removes static Diffie-Hellman entirely [@rfc8446].&lt;/p&gt;
&lt;p&gt;Three pillars, seven breaks, one shape: every attack hit a layer the discrete-log math depends on but does not control. Name the shape, and you have the whole discipline.&lt;/p&gt;
&lt;h2&gt;5. The Realization: Fix the Contracts, Not the Curve&lt;/h2&gt;
&lt;p&gt;There was no single eureka here. The insight accumulated across fifteen years of incidents and then snapped into one sentence: every field break attacked a layer the discrete-log math &lt;em&gt;depends on but does not control&lt;/em&gt; -- the nonce, then the parameters, then the negotiated strength -- and every fix changed &lt;em&gt;how the primitive is generated, used, validated, or negotiated&lt;/em&gt;, never the curve and never the log.&lt;/p&gt;
&lt;p&gt;The sharpest crystallization hides inside the word &quot;bias.&quot; For years it was treated as one problem with one fix: remove the random number generator, derive the nonce deterministically (RFC 6979 [@rfc6979], later blessed by FIPS 186-5 [@fips-186-5]), and the biased-nonce class is solved. But Minerva, TPM-Fail, and LadderLeak all recovered keys from signers that had &lt;em&gt;already&lt;/em&gt; done that. The reason is that &quot;bias&quot; was concealing two distinct root causes with two distinct cures.&lt;/p&gt;

flowchart TD
    B[&quot;One word: nonce bias&quot;] --&amp;gt; G[&quot;Generation defect: the RNG returns a constant, repeated, or predictable k&quot;]
    B --&amp;gt; U[&quot;Usage defect: variable-time scalar multiplication leaks the bit-length of k&quot;]
    G --&amp;gt; GC[&quot;Cure: deterministic and hedged nonces, RFC 6979 and FIPS 186-5&quot;]
    U --&amp;gt; UC[&quot;Cure: constant-time, exception-free scalar multiplication&quot;]
    GC --&amp;gt; BOTH[&quot;You need BOTH, they are orthogonal&quot;]
    UC --&amp;gt; BOTH
&lt;p&gt;A &lt;em&gt;generation&lt;/em&gt; defect is a bad nonce coming out of the sampler -- a constant (PS3), a repeat (Android), a predictable value. Determinism and hedging cure it. A &lt;em&gt;usage&lt;/em&gt; defect is a perfectly good nonce leaking through the &lt;em&gt;timing&lt;/em&gt; of the scalar multiplication that consumes it -- the bit-length falling out through a side channel (Minerva, TPM-Fail) or a sub-bit correlation (LadderLeak). Only constant-time code cures that. The two cures are orthogonal, and you need both.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Generalize the two-cures fork and you get the entire discipline of this field: four contracts, not one curve. &lt;em&gt;Generate&lt;/em&gt; the nonce so it cannot be predicted or repeated; &lt;em&gt;use&lt;/em&gt; it in constant time so it cannot leak; &lt;em&gt;validate&lt;/em&gt; your parameters so no attacker chooses your generator; &lt;em&gt;negotiate&lt;/em&gt; only strong, unshared groups so no downgrade can strand you. Every documented break is a breach of one of those four. No break in the corpus is a break of the discrete logarithm.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This also dissolves the apparent contradiction the article opened with. &quot;Nobody solved the discrete log&quot; and &quot;somebody recovered the key&quot; only sound incompatible if you conflate the discrete-log &lt;em&gt;problem&lt;/em&gt; with a discrete-log &lt;em&gt;deployment&lt;/em&gt;. The problem is a statement about computational hardness; the deployment is a nonce, a set of parameters, and a negotiation, wrapped around that hardness. The problem stayed hard. The wrapping tore.&lt;/p&gt;

If you remember one operational thing from this article, make it this: deterministic ECDSA and constant-time scalar multiplication are not two names for the same safeguard. A team can adopt RFC 6979, check the box marked &quot;nonce,&quot; and still ship a signer that a co-located attacker times to death. Ask both questions separately -- how is the nonce generated, and how is it used -- because they have separate answers.
&lt;p&gt;If the discipline is &quot;honor the four contracts, not the curve,&quot; what does a deployment that honors all four actually look like in 2026?&lt;/p&gt;
&lt;h2&gt;6. What Correct EC/DH Deployment Looks Like in 2026&lt;/h2&gt;
&lt;p&gt;The state of the art in this field is not a better discrete-log solver -- no such thing exists. It is a &lt;em&gt;deployment discipline&lt;/em&gt; at the three layers the math never controlled. Here it is, pillar by pillar.&lt;/p&gt;
&lt;h3&gt;Nonce: two orthogonal cures, and a primitive that folds in both&lt;/h3&gt;

Derive the nonce `k` deterministically from the private key and the message hash via an HMAC-based construction, so the signer &quot;do[es] not need access to a source of high-quality randomness&quot; [@rfc6979]. Identical key-and-message pairs always yield the same `k`; distinct messages yield unrelated nonces. This closes the *generation* defect -- the PS3 and Android reuse classes cannot occur.
&lt;p&gt;RFC 6979 also quietly records the deeper lesson. It insists on comparing each candidate nonce against the group order rather than reducing it modulo the order, warning that a &quot;simple modular reduction would induce biases that would be detrimental to signature security&quot; [@rfc6979]. That is a standards document, in 2013, acknowledging that &lt;em&gt;bias&lt;/em&gt;, not just reuse, is fatal. You can watch the effect yourself:&lt;/p&gt;
&lt;p&gt;{&lt;code&gt;// A raw sampler emits values in [0, 256). We need a nonce in [0, q). const q = 200n, B = 256n, trials = 400000; const raw = () =&amp;gt; BigInt(Math.floor(Number(B) * Math.random())); let biasedHigh = 0, fairHigh = 0; const half = q / 2n; for (let i = 0; i &amp;lt; trials; i++) {   const reduced = raw() % q;              // reduce mod q -&amp;gt; BIASED   if (reduced &amp;gt;= half) biasedHigh++;   let fair; do { fair = raw(); } while (fair &amp;gt;= q);  // compare to q, retry -&amp;gt; FAIR   if (fair &amp;gt;= half) fairHigh++; } console.log(&apos;reduce mod q -&amp;gt; P(nonce in top half): &apos; + (biasedHigh / trials).toFixed(4)); console.log(&apos;compare to q -&amp;gt; P(nonce in top half): &apos; + (fairHigh / trials).toFixed(4)); console.log(&apos;That gap from 0.5 is a free bit for a Hidden Number Problem attacker.&apos;);&lt;/code&gt;}&lt;/p&gt;
&lt;p&gt;Determinism, though, fixes only generation. On hardware it also &lt;em&gt;adds&lt;/em&gt; a risk.&lt;/p&gt;

Compute the nonce from the private key, the message hash, *and* a few bytes of fresh randomness. A dead RNG falls back to the safe deterministic core; a differential fault, which needs two identical signings to differ, is defeated by the fresh input. FIPS 186-5 recommends this for hardware because bare determinism is &quot;of particular concern for ... deterministic signature schemes, as well as embedded or IoT devices and smartcards&quot; [@fips-186-5].

Compute `kG` with a data-independent trace of instructions, branches, and memory accesses, so the runtime never depends on the bit-length or value of `k`. This is the *usage* cure -- the only defense against Minerva, TPM-Fail, and LadderLeak, whose leaks all live in the multiplication, not the sampler. Its precursor is Brumley and Tuveri&apos;s 2011 remote attack on a non-constant-time OpenSSL ladder [@brumley-tuveri-2011].
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Hedged signing and constant-time multiplication are the two cures of the fork, and they do not substitute for each other. A hardware signer needs &lt;em&gt;both&lt;/em&gt;: hedge the generation, and make the usage constant-time. Checking one box leaves the other break wide open.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;New designs can sidestep the whole fork by choosing a misuse-resistant primitive. Ed25519 (RFC 8032) derives its nonce as a hash of the secret and message -- deterministic by construction, no per-signature RNG -- and signs with a single &lt;em&gt;complete&lt;/em&gt;, constant-time addition law that has no exceptional cases to mishandle [@rfc8032]. It folds both cures into the primitive and removes the dangerous choices from the caller&apos;s hands.Misuse-resistant is not misuse-proof. PuTTY derived P-521 ECDSA nonces such that &quot;the first 9 bits of each ECDSA nonce are zero,&quot; allowing &quot;full secret key recovery in roughly 60 signatures&quot; (CVE-2024-31497) [@putty-cve-2024-31497]. Determinism implemented carelessly re-introduced exactly the bias it was meant to prevent.&lt;/p&gt;
&lt;h3&gt;Validation: reject what you cannot vouch for&lt;/h3&gt;
&lt;p&gt;The CurveBall cure is direct: bind a certificate&apos;s curve to the standard parameters of its named curve, and reject explicit parameters or fully re-validate them. The January 2020 patch made &lt;code&gt;crypt32.dll&lt;/code&gt; check the generator, not merely the point [@curveball-cve-2020-0601].&lt;/p&gt;
&lt;p&gt;For key &lt;em&gt;exchange&lt;/em&gt; with static keys, the discipline is fuller. Before using a received point, confirm it is not the identity, lies on the curve, and sits in the correct prime-order subgroup -- the full public-key validation of NIST SP 800-56A, which blocks &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;invalid-curve and small-subgroup attacks&lt;/a&gt; that would otherwise bleed a static key out one query at a time [@sp-800-56a-r3].&lt;/p&gt;
&lt;p&gt;The most durable answer is to make invalid inputs unrepresentable. X25519 works on a Montgomery curve chosen so that &lt;em&gt;every&lt;/em&gt; 32-byte string is an acceptable public key; the RFC even instructs implementations to &quot;accept non-canonical values,&quot; and to run the conditional swap &quot;in constant time&quot; [@rfc7748]. There is no explicit-parameter path to abuse and no on-curve check to forget.This is the &quot;make invalid states unrepresentable&quot; principle applied to cryptography: the safest validation code is the code you deleted because the type system already guarantees the property. But note the boundary carefully.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; X25519&apos;s scalar &quot;clamping&quot; fixes the cofactor and twist problems for ephemeral key exchange. It does &lt;em&gt;not&lt;/em&gt; replace named-curve pinning in the X.509 world, and some protocols still need a contributory-behavior check on the shared secret. Twist-secure curves solve the problems they were designed for -- not every parameter problem.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Negotiation: remove the weak option entirely&lt;/h3&gt;
&lt;p&gt;The downgrade pillar&apos;s fix is structural. RFC 7919 replaced ad-hoc, shared Diffie-Hellman primes with a menu of vetted named groups negotiated like curves [@rfc7919]. TLS 1.3 went further and deleted the weak options outright, so there is nothing to downgrade &lt;em&gt;to&lt;/em&gt;.&lt;/p&gt;

&quot;Static RSA and Diffie-Hellman cipher suites have been removed; all public-key based key exchange mechanisms now provide forward secrecy.&quot; -- RFC 8446, the TLS 1.3 specification [@rfc8446].
&lt;p&gt;Because TLS 1.3 permits only strong ephemeral groups and binds the negotiation into the handshake transcript, the Logjam rewrite is not merely discouraged -- it is structurally impossible [@rfc8446]. The end state of the negotiation pillar is a protocol in which the crippled, shared 512-bit group Logjam relied on simply cannot be selected.&lt;/p&gt;
&lt;p&gt;Each of these is a choice, and where there is a choice, engineers argue. Which discipline actually wins in which threat model?&lt;/p&gt;
&lt;h2&gt;7. Competing Approaches: Which Defense Answers Which Adversary&lt;/h2&gt;
&lt;p&gt;These defenses are not rungs on one ladder. They are answers to different adversaries, and the honest way to compare them is one pillar at a time.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; A constant-time multiplier and a named-curve pin do not compete -- they defend different layers, and a real system needs one from each pillar. The comparisons below rank options &lt;em&gt;within&lt;/em&gt; a pillar. Picking the best nonce discipline does nothing for your parameter validation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Nonce: which signing discipline stops which adversary&lt;/h3&gt;
&lt;p&gt;The load-bearing insight is that no single column stops every row. Generation cures (deterministic [@rfc6979], hedged [@fips-186-5]) and the usage cure (constant-time) are orthogonal, which is why hedged-plus-constant-time became the practitioner default and why Ed25519 [@rfc8032] folds most of both into the primitive.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Adversary / failure&lt;/th&gt;
&lt;th&gt;Randomized (bare RNG)&lt;/th&gt;
&lt;th&gt;Deterministic (RFC 6979)&lt;/th&gt;
&lt;th&gt;Hedged (FIPS 186-5)&lt;/th&gt;
&lt;th&gt;Constant-time mult&lt;/th&gt;
&lt;th&gt;Ed25519&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;RNG returns constant or repeat (PS3, Android)&lt;/td&gt;
&lt;td&gt;fails&lt;/td&gt;
&lt;td&gt;stops&lt;/td&gt;
&lt;td&gt;stops&lt;/td&gt;
&lt;td&gt;orthogonal&lt;/td&gt;
&lt;td&gt;stops&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Differential fault on a deterministic signer&lt;/td&gt;
&lt;td&gt;randomness helps&lt;/td&gt;
&lt;td&gt;fails&lt;/td&gt;
&lt;td&gt;stops&lt;/td&gt;
&lt;td&gt;orthogonal&lt;/td&gt;
&lt;td&gt;inherits the caveat&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Timing leak of nonce bit-length (Minerva, TPM-Fail)&lt;/td&gt;
&lt;td&gt;fails&lt;/td&gt;
&lt;td&gt;fails&lt;/td&gt;
&lt;td&gt;fails&lt;/td&gt;
&lt;td&gt;stops&lt;/td&gt;
&lt;td&gt;stops (uniform ladder)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sub-bit ladder leak (LadderLeak)&lt;/td&gt;
&lt;td&gt;fails&lt;/td&gt;
&lt;td&gt;fails&lt;/td&gt;
&lt;td&gt;fails&lt;/td&gt;
&lt;td&gt;stops&lt;/td&gt;
&lt;td&gt;stops (uniform ladder)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Read the rows, not the columns: reuse fails only the first row and is certain from two signatures; the timing leaks fail three of the five columns and are cured on a different axis entirely. That is the two-cures fork, rendered as a matrix.&lt;/p&gt;
&lt;h3&gt;Validation: three philosophies of not trusting your input&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;Named-curve pinning&lt;/th&gt;
&lt;th&gt;Full validation (SP 800-56A)&lt;/th&gt;
&lt;th&gt;All-inputs-valid (X25519)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Philosophy&lt;/td&gt;
&lt;td&gt;reject non-standard parameters&lt;/td&gt;
&lt;td&gt;validate every received input&lt;/td&gt;
&lt;td&gt;make invalid inputs unrepresentable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stops CurveBall (unvalidated generator)&lt;/td&gt;
&lt;td&gt;yes, its exact fix&lt;/td&gt;
&lt;td&gt;yes, re-derives the generator&lt;/td&gt;
&lt;td&gt;yes, no explicit-parameter path&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stops invalid-curve / small-subgroup&lt;/td&gt;
&lt;td&gt;partial&lt;/td&gt;
&lt;td&gt;yes, on-curve plus subgroup&lt;/td&gt;
&lt;td&gt;yes, twist-secure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Per-operation cost&lt;/td&gt;
&lt;td&gt;O(1) table compare&lt;/td&gt;
&lt;td&gt;O(1) up to one scalar mult&lt;/td&gt;
&lt;td&gt;one constant-time ladder&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best suited for&lt;/td&gt;
&lt;td&gt;X.509, code-signing, PKI&lt;/td&gt;
&lt;td&gt;static-key ECDH, HSMs&lt;/td&gt;
&lt;td&gt;ephemeral ECDH&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Named-curve pinning is the precise CurveBall fix [@curveball-cve-2020-0601]; SP 800-56A validation is the belt-and-suspenders choice for static keys [@sp-800-56a-r3]; X25519 deletes the problem by construction [@rfc7748]. They converge on stopping CurveBall and diverge on everything else.&lt;/p&gt;
&lt;h3&gt;Downgrade: hardening, deletion, or hedging against tomorrow&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;Config hardening + FFDHE&lt;/th&gt;
&lt;th&gt;TLS 1.3&lt;/th&gt;
&lt;th&gt;Hybrid post-quantum&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Removes the 512-bit export rung&lt;/td&gt;
&lt;td&gt;yes, within FFDHE&lt;/td&gt;
&lt;td&gt;yes, structurally&lt;/td&gt;
&lt;td&gt;yes, inherits 1.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Removes shared or unknown primes&lt;/td&gt;
&lt;td&gt;yes, named menu&lt;/td&gt;
&lt;td&gt;yes, fixed groups&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Downgrade protection in the handshake&lt;/td&gt;
&lt;td&gt;no, still in-band&lt;/td&gt;
&lt;td&gt;yes, transcript-bound&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Defends against a future Shor adversary&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;yes, if ML-KEM holds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Residual weakness&lt;/td&gt;
&lt;td&gt;the legacy long tail&lt;/td&gt;
&lt;td&gt;non-TLS 1024-bit primes&lt;/td&gt;
&lt;td&gt;a KEM is not a NIKE, young PQC&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;RFC 7919 named groups [@rfc7919] are the transitional hardening for TLS 1.2; TLS 1.3 is the structural end state [@rfc8446]; hybrid X25519 with &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;ML-KEM&lt;/a&gt; (RFC 9954 [@rfc9954], ML-KEM standardized as FIPS 203 [@fips-203]) is the forward hedge against a quantum adversary. Only the last column defends against a break that would be genuine mathematics rather than a deployment slip.&lt;/p&gt;
&lt;p&gt;Every column in every table changed the deployment, not the curve. So is the discrete log itself simply unbreakable? Almost -- and the &quot;almost&quot; is the most honest paragraph in this article.&lt;/p&gt;
&lt;h2&gt;8. Theoretical Limits: What Is Provably True on Both Sides&lt;/h2&gt;
&lt;p&gt;This is the honest concession the thesis has been earning the right to make. There are two provable sides here, and the argument needs both.&lt;/p&gt;
&lt;h3&gt;The hardness side: no room for a strong curve to fall&lt;/h3&gt;
&lt;p&gt;On a well-chosen group, the discrete logarithm is genuinely hard, and we can say so with unusual precision. The best classical attack is Pollard&apos;s rho, a square-root-time random walk that needs negligible memory [@teske-2001]. In the strict generic model its expected cost is about $\sqrt{\pi n/2}$, roughly 1.25 times $\sqrt{n}$ group operations; on an elliptic curve, the negation map (where $P$ and $-P$ share an x-coordinate) trims that to about 0.886 times $\sqrt{n}$. Either way the exponent is the same, matching baby-step giant-step&apos;s $O(\sqrt{n})$ time [@hac-ch11].&lt;/p&gt;
&lt;p&gt;Against that upper bound, Shoup proved a generic &lt;em&gt;lower&lt;/em&gt; bound of $\Omega(\sqrt{p})$: no algorithm restricted to the group operation can do better [@shoup-1997]. The two meet at $\Theta(\sqrt{n})$. The generic gap is essentially closed -- which is exactly why a 256-bit curve delivers around 128-bit security, and why no strong deployed curve&apos;s discrete log has fallen.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Quantity&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Note&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Best classical DL attack&lt;/td&gt;
&lt;td&gt;Pollard&apos;s rho, about 1.25 times sqrt(n) generic; 0.886 times sqrt(n) on curves&lt;/td&gt;
&lt;td&gt;negligible space&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Baby-step giant-step&lt;/td&gt;
&lt;td&gt;O(sqrt(n)) time and O(sqrt(n)) space&lt;/td&gt;
&lt;td&gt;the space-heavy twin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generic lower bound&lt;/td&gt;
&lt;td&gt;Omega(sqrt(p)), provably no faster generic algorithm&lt;/td&gt;
&lt;td&gt;Shoup 1997&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Finite-field DH (non-generic)&lt;/td&gt;
&lt;td&gt;sub-exponential via the number field sieve&lt;/td&gt;
&lt;td&gt;why DH needs about 3072-bit primes (2048-bit minimum)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strong deployed curve or standard group ever solved&lt;/td&gt;
&lt;td&gt;none, only Logjam&apos;s crippled shared 512-bit prime&lt;/td&gt;
&lt;td&gt;the thesis in one row&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The last two rows carry the concession. Finite-field Diffie-Hellman is &lt;em&gt;not&lt;/em&gt; generic: the number field sieve solves it in sub-exponential time, which is why finite-field DH needs primes of about 3072 bits to match the security a 256-bit curve gives (2048 bits is the absolute minimum), and why Logjam&apos;s downgrade to 512 bits was finishable at all [@logjam-weakdh-2015]. The number-field-sieve mathematics belongs to the companion article.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Logjam is the only break in this corpus that reached the mathematics, and the reason is structural, not accidental. A finite field carries extra arithmetic structure that a generic group lacks, which lets the number field sieve run in sub-exponential time, faster than the square-root barrier that protects a strong elliptic curve. That structural gap is the sole opening the discrete log ever offered, and even it was not enough alone: the computation became feasible only after the prime was cut to 512 export-grade bits. Raise the group back to a standard 2048-bit prime, or move to a curve where no such shortcut exists, and the opening closes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;The leakage side: no room to hide a little bias&lt;/h3&gt;
&lt;p&gt;The other provable side indicts the deployment just as sharply. The Hidden Number Problem makes partial leakage fatal by construction: Boneh and Venkatesan proved that recovering a secret from many small most-significant-bit leaks is tractable [@boneh-venkatesan-1996], and Nguyen and Shparlinski turned that into a working lattice attack on (EC)DSA with partial nonces [@nguyen-shparlinski-2003].&lt;/p&gt;
&lt;p&gt;There is no &quot;a little bias is tolerable&quot; regime: any &lt;em&gt;consistent&lt;/em&gt; partial leak of &lt;code&gt;k&lt;/code&gt;, integrated over enough signatures, provably recovers &lt;code&gt;d&lt;/code&gt;. Two or more leaked bits fall to a lattice; a sub-bit leak falls to Bleichenbacher&apos;s Fourier method [@ladderleak-2020]. &quot;&lt;code&gt;k&lt;/code&gt; is secret, uniform, and unique&quot; is not a best practice -- it is a hard boundary.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The math is safe at the sizes we deploy (the generic gap is closed), and leakage is fatal at any size (the HNP admits no safe margin). Both proofs point the same way: the primitive is not the weak part. The nonce, the parameters, and the negotiation are.&lt;/p&gt;
&lt;/blockquote&gt;

Two clouds sit on the horizon. First, the shared-prime structure Logjam exploited at 512 bits revives at 1024. The Logjam team estimated that precomputing the single most common 1024-bit prime would expose roughly 18% of the top HTTPS sites; a second common prime would reach about 66% of IPsec VPNs and around 26% of SSH servers [@logjam-weakdh-2015] -- the same trick, resized, and a resourced adversary&apos;s project. Second, a large fault-tolerant quantum computer running Shor&apos;s algorithm would break the discrete logarithm outright, curve and finite field alike. That is the one future break that *is* the mathematics, and it is the subject of the companion article, not this one. The deployment answer, already shipping, is hybrid key exchange.
&lt;p&gt;So where, concretely, does EC and DH still break tomorrow?&lt;/p&gt;
&lt;h2&gt;9. Where EC and DH Still Break in the Field&lt;/h2&gt;
&lt;p&gt;The incidents are settled. The &lt;em&gt;classes&lt;/em&gt; are not. Every open problem below is a documented pattern waiting for its next instance, and each one maps to a pillar you have already met.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The next SecureRandom (nonce generation, Pillar 1).&lt;/strong&gt; A signer needs a unique, secret nonce at the exact moment its entropy is weakest: first boot, a headless IoT device with no entropy events, or a freshly cloned virtual machine carrying a duplicated seed. This is the mechanism behind Android 2013 [@android-securerandom-2013], and it recurs whenever hardware is provisioned faster than it can gather randomness.Cloned-VM state duplication is an especially nasty modern form: two hosts that never coordinated can emit the &lt;em&gt;same&lt;/em&gt; &quot;random&quot; nonce because they booted from one snapshot. The signing path can be hedged [@fips-186-5], but key generation and ephemeral key exchange still need a live, well-seeded source.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The next Minerva or LadderLeak (nonce usage, Pillar 1).&lt;/strong&gt; Constant-time scalar multiplication must be re-established against every new microarchitecture -- caches, execution ports, prefetchers, simultaneous multithreading -- and on every fragile incomplete-addition curve. The bit-length leak of Minerva [@minerva-2020] and the sub-bit leak of LadderLeak [@ladderleak-2020] both post-date deterministic nonces precisely because the leak had moved to usage. Formally verified primitives close the &lt;em&gt;known&lt;/em&gt; channels on the &lt;em&gt;chosen&lt;/em&gt; curve; FIPS-mandated P-curves and secp256k1 keep hand-written code in production.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The long tail of shared primes (downgrade, Pillar 3).&lt;/strong&gt; TLS 1.3 closes the web protocol layer, but export-grade and shared standardized primes outlived their policy elsewhere. IKEv1 VPNs and older SSH still ship shared 1024-bit Diffie-Hellman groups, and a single precomputation per shared prime amortizes across every server using it [@logjam-weakdh-2015]. The consensus recommendation is blunt: retire 1024-bit DH now.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The next CurveBall (validation, Pillar 2).&lt;/strong&gt; CurveBall was one unchecked generator in one library [@curveball-cve-2020-0601]; the class is &quot;somewhere in a large validation stack, attacker-supplied parameters are trusted.&quot; Every new parser, certificate profile, or post-quantum key format reopens the class, and a single such bug in a widely embedded validator forges trust across everything that depends on it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Post-quantum migration ahead of Shor (cross-pillar).&lt;/strong&gt; Hybrid key exchange -- running X25519 alongside ML-KEM so the session stays secure if either component holds -- is standardized (RFC 9954 [@rfc9954]; concrete groups such as X25519MLKEM768 in the ongoing ECDHE-MLKEM work [@draft-ietf-tls-ecdhe-mlkem]; ML-KEM standardized as FIPS 203 [@fips-203]) and is already deployed at scale: it protected a majority of the human web traffic Cloudflare measured by late 2025 [@cloudflare-pq-radar]. But the migration carries a trap that has nothing to do with the discrete log.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; ML-KEM is a key-&lt;em&gt;encapsulation&lt;/em&gt; mechanism, not a non-interactive key agreement. It does not reproduce X25519&apos;s static Diffie-Hellman semantics, where two long-term public keys combine without any live exchange. Systems that quietly assume &quot;post-quantum DH&quot; is a drop-in replacement for classical DH will find the shape of the primitive has changed underneath them. Migrate deliberately, not by search-and-replace.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;None of these needs new mathematics to break you. Each needs exactly one deployment mistake. Here is how not to make it.&lt;/p&gt;
&lt;h2&gt;10. What to Do on Monday&lt;/h2&gt;
&lt;p&gt;Every item below maps to a specific incident in this article. Do these, and you do not ship the next one.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Never put a bare runtime RNG in the signing path.&lt;/strong&gt; Use deterministic (RFC 6979 [@rfc6979]) or, on hardware, hedged (FIPS 186-5 [@fips-186-5]) nonces. &lt;em&gt;Prevents:&lt;/em&gt; PS3, Android.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Demand constant-time, exception-free scalar multiplication.&lt;/strong&gt; This is a separate control from the nonce discipline, not a duplicate of it. &lt;em&gt;Prevents:&lt;/em&gt; Minerva, TPM-Fail, LadderLeak.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prefer misuse-resistant primitives.&lt;/strong&gt; Ed25519 for new signing [@rfc8032], X25519 for ephemeral key exchange [@rfc7748]; for static-key ECDH, run full public-key validation per SP 800-56A [@sp-800-56a-r3]. &lt;em&gt;Prevents:&lt;/em&gt; whole classes of implementer error.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reject explicit curve parameters; require named curves.&lt;/strong&gt; Pin the curve, and the generator with it. &lt;em&gt;Prevents:&lt;/em&gt; CurveBall [@curveball-cve-2020-0601].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Disable export ciphers and use vetted groups.&lt;/strong&gt; RFC 7919 named groups [@rfc7919] for residual TLS 1.2 DHE, or move to TLS 1.3 [@rfc8446]. &lt;em&gt;Prevents:&lt;/em&gt; Logjam.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Never assume a fresh ephemeral rescues a shared prime.&lt;/strong&gt; The number-field-sieve precomputation is per-prime, not per-connection [@logjam-weakdh-2015]. &lt;em&gt;Prevents:&lt;/em&gt; the subtle half of Logjam.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Plan the post-quantum migration as hybrid, not pure.&lt;/strong&gt; Run a classical curve alongside ML-KEM (RFC 9954 [@rfc9954]); remember a KEM is not a NIKE. &lt;em&gt;Prevents:&lt;/em&gt; harvest-now-decrypt-later exposure.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; New signing design, free to pick the curve: Ed25519. Must use ECDSA on a NIST or secp256k1 curve: hedged RFC 6979 &lt;em&gt;and&lt;/em&gt; a vetted constant-time multiply. Hardware or embedded signer: hedged, never bare-deterministic. Ephemeral key exchange: X25519. Static-key ECDH: full SP 800-56A validation. Certificate or PKI validation: pin named curves. Any TLS: version 1.3, and if you are stuck on 1.2 DHE, RFC 7919 groups with export ciphers off. Long-lived confidentiality: hybrid X25519 with ML-KEM.&lt;/p&gt;
&lt;/blockquote&gt;

1. **Nonce:** For every signature, can you show the nonce is both unpredictable (hedged or deterministic) *and* consumed in constant time? If you can only answer one half, you are exposed to the other.
2. **Parameters:** Does your certificate and key-exchange path reject attacker-supplied explicit parameters and validate every received point against the named curve?
3. **Negotiation:** Can a man-in-the-middle force any weaker group or version than you intend? If you cannot prove &quot;no,&quot; assume &quot;yes.&quot;
&lt;p&gt;Notice that not one item on this list is &quot;use a bigger curve.&quot; For every break except Logjam&apos;s downgrade, key size is irrelevant -- a 384-bit curve reuses a nonce exactly as fatally as a 256-bit one. The controls are about generation, usage, validation, and negotiation, because those are the four contracts, and the contracts are where reality broke.&lt;/p&gt;
&lt;p&gt;Two questions decide whether you got this right, and they happen to be the two most-repeated errors in the field.&lt;/p&gt;
&lt;h2&gt;11. FAQ: Misconceptions, Precisely Corrected&lt;/h2&gt;

Once, and only against a deliberately crippled target. Logjam computed discrete logarithms against a 512-bit export-grade Diffie-Hellman prime -- one that a man-in-the-middle downgrade could select and that many servers had in common [@logjam-weakdh-2015][@cve-2015-4000]. No strong deployed curve -- P-256, Curve25519, secp256k1 -- and no standard-sized group of 2048 bits or more has ever had its discrete log solved in public. The ceiling of the entire corpus is a 512-bit prime that policy left broken.

No, and this is the most common error. A *repeated* nonce recovers the key with certainty from exactly two signatures, by elementary algebra. A merely *biased* nonce emits only a faint statistical signal per signature, so recovery takes many of them plus a dedicated lattice or Fourier attack -- about 2100 for Minerva on secp256r1 [@minerva-2020], roughly 60 for PuTTY&apos;s nine-zero-bit bias [@putty-cve-2024-31497]. One biased signature leaks almost nothing.

No. LadderLeak&apos;s leak is under a single bit per signature, which lattice methods cannot exploit; it revives Bleichenbacher&apos;s Fourier-analysis solver instead [@ladderleak-2020]. The lattice regime is Minerva and TPM-Fail, whose leaks are two bits or more [@minerva-2020][@tpmfail-2020]. Calling all three &quot;lattice attacks&quot; collapses a distinction the attacks themselves are built on.

No. Padding oracles are an RSA and CBC-mode phenomenon; there is no elliptic-curve or Diffie-Hellman padding-oracle exemplar, and you should not go looking to manufacture one. The EC and DH attack surface is exactly the three pillars here -- the nonce, parameter validation, and downgrade. RSA&apos;s padding oracles, and the fact that RSA signing has no per-signature secret nonce to reuse, are covered in the companion piece &quot;How RSA Breaks in Real Life.&quot;

Only against half the problem. RFC 6979 removes the random number generator from the signing path and eliminates the reuse class [@rfc6979], but it does nothing about a timing leak during nonce *usage* -- which is exactly how Minerva, TPM-Fail, and LadderLeak recovered keys from deterministic signers. The complete answer is hedged signing plus constant-time scalar multiplication [@fips-186-5], the two orthogonal cures.

Almost never. The nonce, validation, and downgrade defects are all indifferent to key size: a forged CurveBall certificate is accepted no matter how large the curve is, because the flaw is a skipped generator check rather than a hard curve [@curveball-cve-2020-0601], and a reused or leaked nonce surrenders the private key whether that key is 256 or 384 bits. The one place size mattered was the export-group downgrade, and there the fix was to stop negotiating the 512-bit group at all [@logjam-weakdh-2015], not to enlarge it.

The primitive, no. The discrete logarithm on a strong group remains as hard as it was in the 1970s. What broke, repeatedly, was the deployment around it. Fix the nonce path, validate your parameters against named curves, and retire export and shared groups, and you have closed every break in this article. CurveBall was a validation bug, not a curve break [@curveball-cve-2020-0601] -- and that distinction is the whole point.
&lt;p&gt;Half a century after Diffie and Hellman reduced key exchange to one hard problem, the scoreboard is unambiguous: seven documented field breaks across three deployment layers, and a discrete-log ceiling that only ever reached a deliberately crippled, shared 512-bit export group -- never a strong deployed curve, never a standard-sized group. The mathematics kept its promise. The deployments did not.&lt;/p&gt;

The discrete log never fell. The nonce did, the parameters did, and the negotiation did -- and every one of those is the deployment&apos;s job, not the curve&apos;s.
&lt;p&gt;For the other half of the story -- how a curve itself could be structurally weak, how the number field sieve and Shor&apos;s algorithm actually break the math -- see the structural companion, &quot;How the Discrete Log Would Break.&quot; For the primitive that has no per-signature nonce to reuse and its own &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;padding-oracle history&lt;/a&gt;, see the series sibling, &quot;How RSA Breaks in Real Life.&quot; This article was about the gap between a hard problem and a shipped product. That gap is where the keys keep getting out.&lt;/p&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;how-ecc-and-dh-break-in-real-life&quot; keyTerms={[
  { term: &quot;Per-signature nonce (k)&quot;, definition: &quot;The once-used secret in ECDSA that must be secret, uniform, and unique per signature; the load-bearing prerequisite behind PS3, Android, Minerva, TPM-Fail, and LadderLeak.&quot; },
  { term: &quot;Nonce reuse vs. bias&quot;, definition: &quot;A repeated nonce recovers the key with certainty from two signatures; a biased nonce needs a statistical Hidden Number Problem attack over many signatures.&quot; },
  { term: &quot;Hidden Number Problem&quot;, definition: &quot;Recovering a fixed secret from many samples that each leak a few most-significant bits; the framework behind every biased-nonce attack.&quot; },
  { term: &quot;Two-cures fork&quot;, definition: &quot;Determinism and hedging fix nonce generation; constant-time scalar multiplication fixes nonce usage. The two are orthogonal and both are required.&quot; },
  { term: &quot;CurveBall (CVE-2020-0601)&quot;, definition: &quot;A Windows CryptoAPI bug that matched a certificate public point but never checked the generator against the named curve; a validation bug, not a curve break.&quot; },
  { term: &quot;Logjam (CVE-2015-4000)&quot;, definition: &quot;A TLS downgrade to a shared 512-bit export Diffie-Hellman prime, breakable because the number field sieve precomputes once per prime; the only discrete log in the corpus.&quot; },
  { term: &quot;Named curve vs. explicit parameters&quot;, definition: &quot;Referencing standardized domain parameters by identifier versus trusting attacker-supplied inline parameters, including a custom generator.&quot; }
]} questions={[
  { q: &quot;Why does a reused nonce recover the key from only two signatures?&quot;, a: &quot;Two signatures with the same nonce share r; subtracting the signing equations cancels the private-key term, yielding the nonce, and one equation then solves for the key.&quot; },
  { q: &quot;Why is LadderLeak not a lattice attack?&quot;, a: &quot;Its leak is under one bit per signature, which lattices cannot exploit, so it uses Bleichenbacher&apos;s Fourier method instead. Lattices are the Minerva and TPM-Fail regime.&quot; },
  { q: &quot;Is Logjam a counterexample to the thesis?&quot;, a: &quot;No. The only discrete log computed landed on a downgrade-forced, crippled, shared 512-bit prime; no strong or standard-sized group ever fell.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>elliptic-curve-cryptography</category><category>ecdsa</category><category>diffie-hellman</category><category>nonce-reuse</category><category>side-channel-attacks</category><category>tls-security</category><category>post-quantum</category><category>applied-cryptography</category><author>noreply@paragmali.com (Parag Mali)</author></item><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>The Curve Was Hard; The Gap Was Soft: A Field Guide to Using Elliptic Curves Safely</title><link>https://paragmali.com/blog/the-curve-was-hard-the-gap-was-soft-a-field-guide-to-using-e/</link><guid isPermaLink="true">https://paragmali.com/blog/the-curve-was-hard-the-gap-was-soft-a-field-guide-to-using-e/</guid><description>Textbook ECC is hard; deployed ECC broke anyway. A field guide to P-256, Curve25519, Ristretto255, invalid-curve attacks, cofactors, and constant-time.</description><pubDate>Sat, 11 Jul 2026 16:08:14 GMT</pubDate><content:encoded>
**The elliptic-curve discrete-log problem was never the weak point.** On a well-chosen curve, ECDLP is the hardest discrete log we know how to build -- which is why a 256-bit curve buys what a 3072-bit RSA modulus does -- and yet across three decades of deployment, almost no real-world break ever solved one. They did not have to. Every named disaster lives in the gap between a hard curve and safe code: the server that fed an attacker&apos;s off-curve point into scalar multiplication and leaked its private key (invalid-curve attacks); the low-order point that clamping never filtered (the Monero cofactor bug); the certificate whose *base point* was never checked (Curveball, CVE-2020-0601); the microsecond of branch timing in a non-constant-time ladder (Brumley-Tuveri). The evolution of curves -- NIST short-Weierstrass (P-256, secp256k1), then Curve25519/X25519, then Ed25519, then the Ristretto255 prime-order abstraction -- is one sustained move: take the safety burden off the implementer and bake it into the curve, the group, and the encoding, so the simple implementation becomes the secure one. Using elliptic curves safely is a stack: the right curve for the job (X25519 for key agreement, Ed25519 for new signatures, P-256 only where FIPS compels it, secp256k1 only for blockchain), validate every untrusted point, multiply in constant time, and prefer constructions where the dangerous case cannot be reached. Remove any layer and the gap reopens.
&lt;h2&gt;1. Two Lines of Code&lt;/h2&gt;
&lt;p&gt;In January 2020, Microsoft patched a vulnerability the U.S. National Security Agency had quietly reported to it -- an unusually public gesture from an agency that normally hoards such findings. The bug was almost embarrassing in its simplicity. Windows would check a TLS certificate&apos;s elliptic-curve signature against a trusted root, and it would never check the curve&apos;s base point. If you supplied a certificate that carried its own curve parameters -- with a generator you had chosen yourself -- Windows would trust the forged chain as though a real &lt;a href=&quot;https://paragmali.com/blog/a-perfect-signature-for-a-certificate-that-should-never-have/&quot; rel=&quot;noopener&quot;&gt;certificate authority&lt;/a&gt; had signed it [@cve-2020-0601]. Nobody factored a modulus. Nobody solved a discrete logarithm. The math of P-256 stood untouched. The attacker handed the code one parameter it forgot to validate, and the industry named the result Curveball.&lt;/p&gt;
&lt;p&gt;Now go one layer down and back five years. In 2015, researchers recovered a TLS server&apos;s ECDH &lt;em&gt;private key&lt;/em&gt; -- the actual secret -- by feeding it points that were not on the intended curve at all. The server&apos;s own scalar-multiplication routine did the leaking, one small residue at a time, until the whole key fell out [@jager-2015]. Two breaks, at two different layers of the same stack, with exactly one shape. In neither case did anyone attack the problem the textbooks call hard.&lt;/p&gt;
&lt;p&gt;That is the claim this article proves. &lt;strong&gt;ECDLP-hardness is not the same thing as ECC-security, and every deployed elliptic-curve break lives in the gap between them.&lt;/strong&gt; The discrete logarithm on a good curve is the strongest one-way function in wide use. The security of a system built on it is a different property entirely -- one that depends on what your code does with a point before it has decided the point is legitimate, and whether it does the arithmetic in a time an attacker cannot measure.&lt;/p&gt;

The private curve stayed hard; the code around it confessed.
&lt;p&gt;So here is the diagnostic question the rest of this piece hands you, the one to ask of any elliptic-curve code you own: &lt;em&gt;when a point you did not generate arrives, what does your code do with it before it has checked that the point is on the intended curve and in the right prime-order subgroup -- and does it do that arithmetic in constant time?&lt;/em&gt; Hold that question. The names you already fear -- invalid-curve attacks, Curveball, twist attacks, small-subgroup leaks, the cofactor, timing side channels -- are all one sentence underneath it. One mechanism explains the entire catalog, and the thirty-year evolution of curves is a single sustained campaign to put that mechanism out of reach.&lt;/p&gt;
&lt;p&gt;To see how an unchecked point hands over a private key -- and why &quot;just use Curve25519&quot; is a real answer but not the whole one -- you first have to see what an elliptic curve actually &lt;em&gt;is&lt;/em&gt;, and what makes its discrete log hard.&lt;/p&gt;
&lt;h2&gt;2. What an Elliptic Curve Actually Is, and Where It Came From&lt;/h2&gt;
&lt;p&gt;In 1976, Whitfield Diffie and Martin Hellman handed the world a template rather than a cryptosystem [@diffie-hellman-1976]. Pick a mathematical group in which one operation is easy to compute and its inverse is hard. Publish the result of applying that operation $k$ times to a fixed element -- call it $[k]G$. Keep $k$ secret. Anyone can combine public values to agree on a shared secret; no eavesdropper can run the operation backward. The template was sound. The group they had, the integers modulo a large prime, was not thrifty: because sub-exponential algorithms (index calculus) attack discrete logs in that group, safety demanded enormous keys. The obvious question hung in the air for nine years. What if you kept the template and changed the group?&lt;/p&gt;
&lt;h3&gt;Two inventors, no shared citation&lt;/h3&gt;
&lt;p&gt;The answer arrived twice, independently, from two people who did not cite each other. Victor Miller proposed it at CRYPTO &apos;85 [@miller-1985]; Neal Koblitz published the same idea in &lt;em&gt;Mathematics of Computation&lt;/em&gt; in 1987 [@koblitz-1987]. Both suggested using the group of points on an elliptic curve over a finite field. The decisive property: for a well-chosen curve, the best algorithm anyone knows is &lt;em&gt;generic&lt;/em&gt; -- it works in any group and costs about $\sqrt{n}$ operations for a group of size $n$ -- rather than the sub-exponential index calculus that makes ordinary discrete logs cheap. No shortcut specific to the curve exists. That single absence is the whole reason elliptic-curve cryptography exists.Miller (1985) and Koblitz (1987) proposed elliptic-curve cryptography independently and neither cited the other. It is one of cryptography&apos;s cleaner cases of simultaneous invention -- the idea was ready to be found.&lt;/p&gt;
&lt;h3&gt;The primitive, kept tight&lt;/h3&gt;
&lt;p&gt;Here is the object itself, because this &lt;em&gt;is&lt;/em&gt; the primitive and everything later depends on reading it correctly. Take the equation&lt;/p&gt;
&lt;p&gt;$$y^2 = x^3 + ax + b$$&lt;/p&gt;
&lt;p&gt;over a finite field $\mathbb{F}_p$ (the integers modulo a prime $p$). The set of solutions $(x, y)$, together with one extra &quot;point at infinity&quot; that acts as a zero, forms a finite abelian group. The group operation is a geometric rule called chord-and-tangent addition: to add two points, draw the line through them, find the third place it meets the curve, and reflect over the $x$-axis. To double a point, use the tangent line instead. The rule looks whimsical and turns out to be associative -- the proof runs through divisors and Riemann-Roch, which we cheerfully defer to Silverman.&lt;/p&gt;

Repeated point addition: adding a base point G to itself k times, written [k]G. Computed in about log k doublings and additions by the double-and-add method, it is the easy, forward direction of the elliptic-curve trapdoor -- fast to compute, believed hard to reverse.
&lt;p&gt;Scalar multiplication is that forward direction: $[k]G = G + G + \dots + G$, $k$ times. Because you can double repeatedly, computing $[k]G$ for a 256-bit $k$ takes a few hundred operations, not $2^{256}$ of them. Reversing it -- recovering $k$ from $G$ and $Q = [k]G$ -- is the hard problem the whole field rests on.&lt;/p&gt;

Given a base point G on an elliptic curve and a second point Q = [k]G, recover the scalar k. This is the one-way assumption elliptic-curve cryptography depends on: easy to compute [k]G in the forward direction, believed infeasible to invert for a well-chosen curve.
&lt;p&gt;Feel the asymmetry directly. The demonstration below computes $[13]G$ on a tiny curve in a handful of steps, then tries to walk it back. At these toy sizes the reversal is trivial; at 256 bits the same reversal is roughly $2^{128}$ operations, which is why the forward arrow is a trapdoor and the backward arrow is a wall.&lt;/p&gt;
&lt;p&gt;{`
// Toy curve y^2 = x^3 + 2x + 2 over F_17. Illustrative sizes, NOT secure.
const p = 17n, a = 2n;
function mod(x){ return ((x % p) + p) % p; }
function inv(x){ // modular inverse via Fermat: x^(p-2) mod p
  let r = 1n, b = mod(x), e = p - 2n;
  while (e &amp;gt; 0n){ if (e &amp;amp; 1n) r = mod(r&lt;em&gt;b); b = mod(b&lt;/em&gt;b); e &amp;gt;&amp;gt;= 1n; }
  return r;
}
function add(P, Q){
  if (P === null) return Q;
  if (Q === null) return P;
  const [x1,y1] = P, [x2,y2] = Q;
  if (x1 === x2 &amp;amp;&amp;amp; mod(y1 + y2) === 0n) return null; // P + (-P) = O
  let s;
  if (x1 === x2 &amp;amp;&amp;amp; y1 === y2) s = mod((3n&lt;em&gt;x1&lt;/em&gt;x1 + a) * inv(2n&lt;em&gt;y1)); // tangent (double)
  else s = mod((y2 - y1) * inv(x2 - x1));                          // chord (add)
  const x3 = mod(s&lt;/em&gt;s - x1 - x2);
  const y3 = mod(s*(x1 - x3) - y1);
  return [x3, y3];
}
function mul(k, G){ // double-and-add: the FORWARD (easy) direction
  let R = null, base = G;
  while (k &amp;gt; 0n){ if (k &amp;amp; 1n) R = add(R, base); base = add(base, base); k &amp;gt;&amp;gt;= 1n; }
  return R;
}
const G = [5n, 1n];         // generator; this subgroup has prime order 19
const secret = 13n;         // the &quot;private key&quot;
const Q = mul(secret, G);   // the &quot;public key&quot; [13]G, computed in ~5 steps
console.log(&apos;public point [13]G =&apos;, Q[0].toString() + &apos;,&apos; + Q[1].toString());&lt;/p&gt;
&lt;p&gt;// Now INVERT it: recover the secret from G and Q. The only general method on a
// real curve is search -- trivial here, about 2^128 work at 256 bits.
let found = null, R = null;
for (let k = 1n; k &amp;lt;= 19n; k++){
  R = add(R, G);
  if (R &amp;amp;&amp;amp; R[0] === Q[0] &amp;amp;&amp;amp; R[1] === Q[1]){ found = k; break; }
}
console.log(&apos;recovered secret by brute force =&apos;, found.toString());
`}&lt;/p&gt;
&lt;h3&gt;Why the keys shrink&lt;/h3&gt;
&lt;p&gt;That missing shortcut is not an academic footnote; it is the entire economic case for the primitive. For discrete logs modulo a prime, and for RSA, index-calculus methods run in sub-exponential time, so defenders must inflate the modulus to stay ahead -- 3072 bits to reach roughly 128-bit security. On a well-chosen prime-field curve, no such method is known, so the attacker is stuck paying the generic $\sqrt{n}$ price. A 256-bit curve therefore delivers about 128 bits of security [@miller-1985], [@safecurves-rho]. Same protection, an order of magnitude smaller keys, faster operations. Hold onto one detail for later: this economic win, the thing everyone remembers about elliptic curves, is the one property that has &lt;em&gt;never&lt;/em&gt; been what broke.The absence of a sub-exponential attack on prime-field curves is the whole argument. It is why 256-bit ECC stands in for a 3072-bit RSA key -- and it is a statement about what we do not know how to do, not a theorem.&lt;/p&gt;
&lt;h3&gt;One clean curve, and the seeds of trouble&lt;/h3&gt;
&lt;p&gt;Standardization made the primitive interoperable. ECDSA was standardized as a digital-signature algorithm (ANSI X9.62) and folded into NIST&apos;s FIPS 186 series [@fips-186-5]; the P-curve we still call P-256 dates to FIPS 186-2 in 2000. The Standards for Efficient Cryptography Group published the matching &lt;code&gt;secp&lt;/code&gt; parameter sets -- including secp256r1, which &lt;em&gt;is&lt;/em&gt; P-256, and its efficiency-minded sibling secp256k1 [@sec2-v2]. The result was a single, clean, interoperable curve with prime order and a genuine strength most of its successors would come to envy. Which raises the puzzle that drives the next two sections: if P-256 is that good, why do the very people who designed its replacement consider &quot;just implement P-256&quot; to be dangerous advice?&lt;/p&gt;
&lt;h2&gt;3. The NIST Curves, and What They Cost&lt;/h2&gt;
&lt;p&gt;P-256 did one big thing exactly right, and three smaller things in a way that made the &lt;em&gt;simple&lt;/em&gt; implementation &lt;em&gt;insecure&lt;/em&gt;. Both halves are true at once, and holding them together is the beginning of expertise here.&lt;/p&gt;
&lt;h3&gt;What went right&lt;/h3&gt;
&lt;p&gt;P-256 is the curve $y^2 = x^3 - 3x + b$ over the special prime $p = 2^{256} - 2^{224} + 2^{192} + 2^{96} - 1$, and its single most underrated property is boring: its group has &lt;strong&gt;prime order&lt;/strong&gt;, cofactor 1 [@sec2-v2]. There is no smaller subgroup for an attacker to trap you in, no cofactor to clear, no torsion points hiding in the corners. Add to that an enormous interoperable deployment -- P-256 is the elliptic curve behind most of the web&apos;s ECC certificates [@ssl-pulse] -- and you have a curve whose &lt;em&gt;group-level&lt;/em&gt; security is excellent. Remember this when Curve25519 arrives two sections from now carrying a cofactor of 8.&lt;/p&gt;

The ratio of a curve&apos;s full group order to the prime order of the subgroup used for cryptography. P-256 has cofactor 1 (its whole group has prime order), while edwards25519 has cofactor 8, meaning small-order &quot;torsion&quot; points exist alongside the useful prime-order subgroup and must be handled with care.
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Cofactor 1 means P-256 has no small-order subgroups at all. That single fact rules out an entire family of attacks at the group level. Keep it in mind when the next generation trades it away for other advantages -- prime order is exactly what Curve25519 gives up and what Ristretto255 later works hard to rebuild.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Cost one: nobody can explain the seed&lt;/h3&gt;
&lt;p&gt;The coefficient $b$ and the base point were produced from a seed run through SHA-1 -- &quot;verifiably random,&quot; in the standard&apos;s language, meaning anyone can rerun the hash and confirm the parameters were not obviously cooked. The catch is that the &lt;em&gt;seed itself&lt;/em&gt; is an unexplained string of bytes. Nobody outside its authors can say why that seed and not another. SafeCurves calls this failure &lt;strong&gt;rigidity&lt;/strong&gt;: a curve is rigid only when its parameters follow from stated principles with no unexplained freedom, and the NIST P-curves are not [@safecurves-index]. This is a trust concern, not a break -- but trust is a load-bearing beam, as the next beat shows.The P-256 parameters are &quot;verifiably random&quot; from a seed, yet the seed is never justified. That gap -- reproducible but unexplained -- is exactly what rigidity objects to. You can check the arithmetic and still not know why these constants.&lt;/p&gt;
&lt;h3&gt;Cost two: the addition law has holes&lt;/h3&gt;
&lt;p&gt;The classic short-Weierstrass addition formulas are not total. They have exceptional cases -- adding a point to its own negation, doubling a point whose $y$-coordinate is zero, anything involving the point at infinity -- where the generic slope formula divides by zero and returns nonsense. A working implementation must branch around those cases. And a branch whose direction depends on secret data is either wrong on the rare input that hits it, or observable through timing, or both. This incomplete addition law is the seed of the timing break we meet in the next section.&lt;/p&gt;
&lt;h3&gt;Cost three: the formula never looks at b&lt;/h3&gt;
&lt;p&gt;Here is the sharp one. Look back at the addition code in Section 2 and notice what is missing: the coefficient $b$ never appears. The short-Weierstrass scalar-multiplication formulas depend on $a$, on the coordinates, on the prime -- but not on $b$. So if you hand the routine a point that satisfies some &lt;em&gt;other&lt;/em&gt; curve $y^2 = x^3 + ax + c$ with a different constant term, the arithmetic proceeds without complaint, silently computing on that other, possibly far weaker, curve [@safecurves-twist]. The curve has no twist security to catch the mistake. This omission is the seed of the invalid-curve break, and we detonate it in Section 4.&lt;/p&gt;
&lt;h3&gt;The Dual EC shadow&lt;/h3&gt;
&lt;p&gt;There is one more reason the community distrusts NIST-supplied constants, and precision matters because it is widely misremembered. In 2007, Dan Shumow and Niels Ferguson showed that the Dual EC DRBG random-number generator &lt;em&gt;could&lt;/em&gt; conceal a back door: whoever chose its two special points might hold a secret relationship between them that predicts the generator&apos;s output [@shumow-ferguson-2007]. Edward Snowden&apos;s 2013 disclosures and, in 2015, a backdoor found inside Juniper&apos;s ScreenOS gave that theoretical worry a concrete afterlife.&lt;/p&gt;
&lt;p&gt;But be exact about what this does and does not implicate. &lt;strong&gt;No weakness has ever been demonstrated in the P-256 curve itself.&lt;/strong&gt; Dual EC poisoned trust in &lt;em&gt;NIST-supplied constants as a category&lt;/em&gt; -- which is precisely why so many engineers now prefer rigid curves -- but it is a trust-and-rigidity argument, not a proven backdoor in the P-curves.Dual EC DRBG is a random-number-generator story, not a P-curve story. It shows NIST-chosen constants &lt;em&gt;could&lt;/em&gt; be poisoned; it does not show that P-256&apos;s were. Conflating the two overstates the case and is a common error. And notice the shape already forming: prime-order, FIPS-mandated, mathematically strong -- yet the &lt;em&gt;simple&lt;/em&gt; implementation is the insecure one.&lt;/p&gt;
&lt;h3&gt;The efficiency sibling&lt;/h3&gt;
&lt;p&gt;One more curve belongs on the table. secp256k1 is the SECG&apos;s efficiency variant: the curve $y^2 = x^3 + 7$ over $p = 2^{256} - 2^{32} - 977$, with $j$-invariant 0 and an endomorphism (the GLV method) that speeds scalar multiplication [@sec2-v2]. It is the curve Bitcoin chose, and later the base for Taproot&apos;s BIP-340 Schnorr signatures [@bip-340]. Keep its domain straight throughout this article: secp256k1 owns the blockchain world and is essentially absent from web PKI and TLS -- a blockchain-interoperability answer, never a general-purpose competitor to the curves that carry your HTTPS traffic.&lt;/p&gt;
&lt;p&gt;Two of those three costs -- the unused $b$ and the branchy ladder -- are not abstractions. Each became a remote private-key recovery against real servers. To see how, you need the one mechanism that sits underneath the entire failure catalog.&lt;/p&gt;
&lt;h2&gt;4. The Failure Catalog: One Atom, Many Surfaces&lt;/h2&gt;
&lt;p&gt;Here is the mechanism the whole catalog reuses. Call it the atom: &lt;em&gt;a point you did not generate, fed into scalar multiplication before you validate it -- or multiplied in variable time -- is a key-recovery oracle.&lt;/em&gt; The discrete logarithm is never solved. The implementation simply computes on the attacker&apos;s terms and leaks the answer, one small piece at a time.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The atom of every deployed elliptic-curve break: a point you did not generate, used before it is validated -- or a secret scalar multiplied in a time an attacker can measure -- turns your own scalar-multiplication routine into an oracle that hands back the private key. ECDLP stays intact; the code around it does the leaking.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Deriving the atom: invalid-curve attacks&lt;/h3&gt;
&lt;p&gt;Recall Cost three from the last section: the short-Weierstrass formulas never read $b$. Ingrid Biehl, Bernd Meyer, and Volker Muller turned that omission into an attack at CRYPTO 2000 [@biehl-meyer-muller-2000]. Send the victim a point that satisfies a &lt;em&gt;different&lt;/em&gt; curve $y^2 = x^3 + ax + c$ -- one you chose specifically because its group has small-order subgroups. The victim&apos;s routine, blind to the constant term, computes your scalar multiple on that weak curve. Its response now lives in a small subgroup, so it reveals the secret scalar modulo a small number. SafeCurves states the mechanism about as plainly as it can be stated:&lt;/p&gt;

The standard formulas for scalar multiplication on short Weierstrass curves do not involve the constant coefficient b, so they automatically also work for y^2 = x^3 + ax + c ... Bob will successfully compute n(x,y) without realizing that anything is amiss.

Feeding an implementation a point that is not on the intended curve into scalar-multiplication formulas that ignore the coefficient b. The operation runs on a different, attacker-chosen curve whose group has small subgroups, so the response leaks the private scalar modulo small numbers -- with the intended curve&apos;s discrete-log hardness never touched.

flowchart TD
    A[&quot;Attacker sends a point not on the intended curve&quot;] --&amp;gt; B[&quot;Scalar-multiply formula ignores coefficient b&quot;]
    B --&amp;gt; C[&quot;Arithmetic runs on a different, weaker curve&quot;]
    C --&amp;gt; D[&quot;That curve has small-order subgroups&quot;]
    D --&amp;gt; E[&quot;Response reveals the secret modulo a small number&quot;]
    E --&amp;gt; F[&quot;Repeat with several coprime small orders&quot;]
    F --&amp;gt; G[&quot;Chinese Remainder Theorem reassembles the whole key&quot;]
&lt;p&gt;The demonstration below runs the leak on a toy curve whose order factors as $105 = 3 \times 5 \times 7$. The attacker sends three low-order points, harvests three residues, and the Chinese Remainder Theorem stitches them into the secret. Nothing here is a discrete-log computation; it is bookkeeping.&lt;/p&gt;
&lt;p&gt;{`
// Toy curve y^2 = x^3 + x + 1 over F_101. Group order 105 = 3&lt;em&gt;5&lt;/em&gt;7.
// Illustrative ONLY -- a real curve has PRIME order and ~2^256 points.
const p = 101n, a = 1n;
const mod = x =&amp;gt; ((x % p) + p) % p;
function inv(x){ let r=1n,b=mod(x),e=p-2n; while(e&amp;gt;0n){ if(e&amp;amp;1n) r=mod(r&lt;em&gt;b); b=mod(b&lt;/em&gt;b); e&amp;gt;&amp;gt;=1n;} return r; }
function add(P,Q){
  if(P===null) return Q; if(Q===null) return P;
  const [x1,y1]=P,[x2,y2]=Q;
  if(x1===x2 &amp;amp;&amp;amp; mod(y1+y2)===0n) return null;      // P + (-P) = O
  const s = (x1===x2 &amp;amp;&amp;amp; y1===y2)
    ? mod((3n&lt;em&gt;x1&lt;/em&gt;x1+a)&lt;em&gt;inv(2n&lt;/em&gt;y1))                 // tangent (double)
    : mod((y2-y1)&lt;em&gt;inv(x2-x1));                     // chord (add)
  const x3 = mod(s&lt;/em&gt;s-x1-x2);
  return [x3, mod(s*(x1-x3)-y1)];
}
function mul(k,P){ let R=null,b=P; while(k&amp;gt;0n){ if(k&amp;amp;1n) R=add(R,b); b=add(b,b); k&amp;gt;&amp;gt;=1n;} return R; }&lt;/p&gt;
&lt;p&gt;const k = 47n;                    // the victim&apos;s PRIVATE scalar
// Attacker-crafted low-order points (orders 3, 5, 7). None is the real base point.
const traps = [ {P:[28n,8n], t:3n}, {P:[86n,67n], t:5n}, {P:[72n,5n], t:7n} ];&lt;/p&gt;
&lt;p&gt;const residues = [], moduli = [];
for (const {P,t} of traps){
  const Q = mul(k, P);            // victim naively returns [k]P = [k mod t]P
  let R = null;
  for (let i=0n;i&amp;lt;t;i++){         // attacker matches against the tiny orbit
    const same = (R===null&amp;amp;&amp;amp;Q===null) || (R&amp;amp;&amp;amp;Q&amp;amp;&amp;amp;R[0]===Q[0]&amp;amp;&amp;amp;R[1]===Q[1]);
    if (same){ residues.push(i); moduli.push(t); break; }
    R = add(R,P);
  }
}
console.log(&apos;leaked:&apos;, residues.map((r,i)=&amp;gt;&apos;k mod &apos;+moduli[i]+&apos; = &apos;+r).join(&apos;,  &apos;));&lt;/p&gt;
&lt;p&gt;// Chinese Remainder Theorem stitches the residues into k mod 105.
let M=1n; for(const m of moduli) M*=m;
let x=0n;
for(let i=0;i&amp;lt;residues.length;i++){
  const Mi=M/moduli[i];
  let mi=1n; for(let j=1n;j&amp;lt;moduli[i];j++){ if((Mi*j)%moduli[i]===1n){ mi=j; break; } }
  x += residues[i]&lt;em&gt;Mi&lt;/em&gt;mi;
}
console.log(&apos;CRT-reassembled secret =&apos;, (((x%M)+M)%M).toString(), &apos; (true k = &apos;+k+&apos;)&apos;);
`}&lt;/p&gt;
&lt;h3&gt;Surface one: small-subgroup attacks&lt;/h3&gt;
&lt;p&gt;You do not even need to leave the intended curve to run the atom. Chae Hoon Lim and Pil Joong Lee showed this at CRYPTO &apos;97 [@lim-lee-1997]. If the curve&apos;s group is not of prime order -- if it has small-order subgroups -- then an attacker submits an element of small order $t$, and the victim&apos;s response is forced into that tiny subgroup, revealing the secret modulo $t$. Collect a few coprime $t$ values, apply the Chinese Remainder Theorem, and the full scalar falls out. This is the conceptual root of the rule &quot;validate the subgroup, not just the curve,&quot; and it is exactly why prime order mattered so much back in Section 3. It also plants a flag we return to: any curve with a cofactor greater than 1 has these small subgroups by construction.&lt;/p&gt;

Submitting a group element of small order so that the victim&apos;s scalar multiplication lands in a tiny subgroup, making the response reveal the secret scalar modulo that small order. Repeated across several coprime small orders, the Chinese Remainder Theorem reassembles the full private key. It is the reason implementations must check that inputs lie in the correct prime-order subgroup.
&lt;h3&gt;Surface two: the atom made remote&lt;/h3&gt;
&lt;p&gt;Theory became a remote server compromise in 2015, when Tibor Jager, Jorg Schwenk, and Juraj Somorovsky recovered real TLS servers&apos; ECDH private keys [@jager-2015]. The conditions were mundane: a server that reused a single ECDH key pair across handshakes and did not validate the incoming peer point. Each handshake fed the server another attacker-chosen invalid point; each response leaked another small residue; a few thousand handshakes later, the CRT delivered the private key. No discrete logarithm was ever computed. This is the atom of Section 4, wearing a TLS badge.The practical TLS result is Jager, Schwenk, and Somorovsky&apos;s ESORICS 2015 paper, &quot;Practical Invalid Curve Attacks on TLS-ECDH&quot; -- distinct from the same trio&apos;s separate USENIX Security 2015 work. The theoretical root is Biehl-Meyer-Muller (2000). Getting the citation right matters, because the two 2015 papers are often conflated.&lt;/p&gt;
&lt;h3&gt;Surface three: the cofactor, in production&lt;/h3&gt;
&lt;p&gt;Now the promised return to cofactors. The curve edwards25519 (the signing sibling of Curve25519) has cofactor 8, which means low-order &quot;torsion&quot; points exist. Monero&apos;s ring-signature scheme used &lt;em&gt;key images&lt;/em&gt; to prevent double-spending: each spent output should map to exactly one key image. The bug was that the code never required a key image to lie in the prime-order subgroup, so an attacker could add a low-order torsion point to a legitimate key image, producing a different but still valid-looking image for the same output -- and spend it twice [@loup-vaillant-cofactor]. The fix was to demand that every key image $I$ satisfy $[\ell]I = \mathcal{O}$, where $\ell$ is the prime subgroup order: multiply by the group order and you must land on the identity, proving no torsion component is hiding inside.&lt;/p&gt;
&lt;p&gt;The precise lesson here is the one most often gotten wrong, so it gets its own box.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Curve25519 secret scalars are &quot;clamped&quot; -- specific bits are forced -- and engineers routinely mistake this for input validation. It is not. Clamping constrains &lt;em&gt;your own&lt;/em&gt; secret scalar so that it is a multiple of the cofactor and sits in a fixed range. It does nothing to a malicious low-order &lt;em&gt;input&lt;/em&gt; point someone else hands you. The Monero cofactor bug is exactly this confusion. If a protocol needs a prime-order group, validate or clear the cofactor on inputs -- or use a construction that removes the choice entirely.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Surface four: Curveball, one layer up&lt;/h3&gt;
&lt;p&gt;The atom does not care which layer it runs on. In Curveball (CVE-2020-0601), the mishandled point was not a peer&apos;s ephemeral key but the curve&apos;s own &lt;em&gt;base point&lt;/em&gt;. Windows CryptoAPI accepted certificates carrying explicit curve parameters and trusted the generator inside them without checking it against the named curve&apos;s real generator. Choose your own generator with a known relationship to a trusted CA&apos;s public key, and you forge a signing chain [@cve-2020-0601]. Same disease, higher in the stack: a parameter that should have been validated -- here, the generator itself -- was taken on faith.&lt;/p&gt;
&lt;h3&gt;Surface five: the clock, with no malicious point at all&lt;/h3&gt;
&lt;p&gt;The final surface uses no bad input whatsoever. In 2011, Billy Bob Brumley and Nicola Tuveri recovered an OpenSSL ECDSA private key from a &lt;em&gt;remote&lt;/em&gt; server purely by timing its scalar multiplications [@brumley-tuveri-2011]. OpenSSL&apos;s ladder for binary-field curves ran in data-dependent time; the timing leaked the bit-length of each per-signature nonce, and a lattice computation turned a few hundred such leaks into the key. The underlying flaw earned CVE-2011-1945, whose description is blunt: the implementation &quot;does not properly implement curves over binary fields, which makes it easier for ... attackers to determine private keys via a timing attack and a lattice calculation&quot; [@cve-2011-1945]. This is the atom&apos;s other face: arithmetic on a secret, performed in observable time, is an oracle even when every input is honest.&lt;/p&gt;
&lt;h3&gt;The one family this article does not re-derive&lt;/h3&gt;

There is a whole lineage of ECDSA breaks -- fail0verflow&apos;s PlayStation 3 key recovery, biased-nonce lattice attacks, LadderLeak, Minerva, TPM-Fail -- that shares the atom&apos;s DNA but belongs to a sibling story about randomness and leakage rather than point validation [@minerva-2020], [@ladderleak-2020]. The result is quick to state: a repeated or biased per-signature nonce leaks the ECDSA private key through a lattice, deterministic nonces (RFC 6979) fix the generation half, and constant-time arithmetic fixes the leakage half [@rfc6979]. The lattice machinery is owned by this series&apos; dedicated nonce-reuse post, so this article signposts it and moves on.
&lt;h3&gt;The pattern, stated once&lt;/h3&gt;
&lt;p&gt;Read the six surfaces together and one sentence covers all of them: &lt;em&gt;the implementation touched a value it should have rejected, or acted in a time it should have hidden.&lt;/em&gt; The leaked bit is never &quot;the discrete logarithm.&quot; It is &quot;was this point on the curve,&quot; or &quot;was this element in the right subgroup,&quot; or &quot;how long did that multiply take,&quot; or &quot;do I trust this generator.&quot; The table below is the evidence for the entire thesis. Every row is the same atom on a different surface.&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;Surface&lt;/th&gt;
&lt;th&gt;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;Small-subgroup, Lim-Lee [@lim-lee-1997]&lt;/td&gt;
&lt;td&gt;1997&lt;/td&gt;
&lt;td&gt;Subgroup&lt;/td&gt;
&lt;td&gt;Response residue&lt;/td&gt;
&lt;td&gt;Non-prime-order group element accepted&lt;/td&gt;
&lt;td&gt;Validate subgroup membership&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Invalid-curve, Biehl-Meyer-Muller [@biehl-meyer-muller-2000]&lt;/td&gt;
&lt;td&gt;2000&lt;/td&gt;
&lt;td&gt;Off-curve point&lt;/td&gt;
&lt;td&gt;Response residue&lt;/td&gt;
&lt;td&gt;Formula ignores the coefficient b&lt;/td&gt;
&lt;td&gt;Check the point is on the intended curve&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remote timing, Brumley-Tuveri [@brumley-tuveri-2011], [@cve-2011-1945]&lt;/td&gt;
&lt;td&gt;2011&lt;/td&gt;
&lt;td&gt;Scalar-mult timing&lt;/td&gt;
&lt;td&gt;Wall-clock time&lt;/td&gt;
&lt;td&gt;Non-constant-time ladder&lt;/td&gt;
&lt;td&gt;Multiply in constant time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Practical invalid-curve TLS, Jager et al. [@jager-2015]&lt;/td&gt;
&lt;td&gt;2015&lt;/td&gt;
&lt;td&gt;Off-curve point, reused key&lt;/td&gt;
&lt;td&gt;Response residue&lt;/td&gt;
&lt;td&gt;No peer-point validation&lt;/td&gt;
&lt;td&gt;Validate points, do not reuse ECDH keys&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cofactor key image, Monero [@loup-vaillant-cofactor]&lt;/td&gt;
&lt;td&gt;2017&lt;/td&gt;
&lt;td&gt;Cofactor torsion&lt;/td&gt;
&lt;td&gt;Forged key image&lt;/td&gt;
&lt;td&gt;Key image not in prime-order subgroup&lt;/td&gt;
&lt;td&gt;Enforce prime order, clamping is not validation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Curveball [@cve-2020-0601]&lt;/td&gt;
&lt;td&gt;2020&lt;/td&gt;
&lt;td&gt;PKI base point&lt;/td&gt;
&lt;td&gt;Forged certificate chain&lt;/td&gt;
&lt;td&gt;Explicit generator trusted&lt;/td&gt;
&lt;td&gt;Use named curves, never trust explicit parameters&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ECDSA-nonce family [@minerva-2020], [@ladderleak-2020]&lt;/td&gt;
&lt;td&gt;2020&lt;/td&gt;
&lt;td&gt;Nonce leakage&lt;/td&gt;
&lt;td&gt;Timing then lattice&lt;/td&gt;
&lt;td&gt;Biased or leaked nonce&lt;/td&gt;
&lt;td&gt;Deterministic nonces plus constant time&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Six surfaces, one disease. And notice what the cure was &lt;em&gt;not&lt;/em&gt;: it was not a warning label stapled to P-256. It was a decade-long engineering program to build curves where the dangerous case cannot be reached at all -- and that program, not the catalog, is the most instructive part of the story.&lt;/p&gt;
&lt;h2&gt;5. The Evolution: Moving Safety Off the Implementer&lt;/h2&gt;
&lt;p&gt;Read the last section again as a to-do list for curve designers. Each generation that follows crosses off one entry -- and here is the pattern that makes the story an argument rather than a parade of curves: they do it not by warning implementers to be careful, but by making the mistake unreachable. It is an attacker&apos;s kill-chain run in reverse. Where an intruder normally advances stage by stage, here the &lt;em&gt;defenders&lt;/em&gt; advance, retiring one failure class per curve generation until the dangerous case no longer exists to reach.&lt;/p&gt;

flowchart LR
    G1[&quot;Gen 1 NIST short-Weierstrass&quot;] --&amp;gt; F1[&quot;Leaves timing and invalid-curve to the implementer&quot;]
    F1 --&amp;gt; G2[&quot;Gen 2 Curve25519 ladder&quot;]
    G2 --&amp;gt; R2[&quot;Retires branch timing and invalid-curve for DH&quot;]
    R2 --&amp;gt; G3[&quot;Gen 3 Ed25519 Edwards law&quot;]
    G3 --&amp;gt; R3[&quot;Retires incomplete addition and the nonce disaster&quot;]
    R3 --&amp;gt; G4[&quot;Gen 4 Ristretto255 encoding&quot;]
    G4 --&amp;gt; R4[&quot;Retires the cofactor class at the type level&quot;]
&lt;p&gt;The chronology underneath that progression spans half a century, from a template to a post-quantum hybrid.&lt;/p&gt;

flowchart LR
    A[&quot;1976 Diffie-Hellman template&quot;] --&amp;gt; B[&quot;1985-87 Miller and Koblitz propose ECC&quot;]
    B --&amp;gt; C[&quot;2000 NIST P-curves standardized&quot;]
    C --&amp;gt; D[&quot;2006 Curve25519 constant-time ladder&quot;]
    D --&amp;gt; E[&quot;2011 Ed25519 complete Edwards law&quot;]
    E --&amp;gt; F[&quot;2015-2023 Ristretto255 prime-order abstraction&quot;]
    F --&amp;gt; G[&quot;2024-2026 X25519 plus ML-KEM hybrid&quot;]
&lt;h3&gt;Generation one, and its own rescue&lt;/h3&gt;
&lt;p&gt;The NIST and SECG short-Weierstrass curves gave the world prime order, which we have already granted is a real strength. But their exceptional-case addition law and their branchy, easily-non-constant-time ladders left the two most dangerous jobs -- constant-time arithmetic and on-curve validation -- squarely with the implementer. Section 4 is the proof of what happens when an implementer drops them.&lt;/p&gt;
&lt;p&gt;The honest rebuttal belongs right here, though, because it is the reason &quot;P-256 is broken&quot; is the wrong sentence. In 2016, Joost Renes, Craig Costello, and Lejla Batina published efficient &lt;em&gt;complete&lt;/em&gt; addition formulas that work for every prime-order short-Weierstrass curve, with no exceptional cases to branch around [@rcb-2016]. Given those formulas and a vetted constant-time field implementation, P-256 is perfectly safe -- &lt;em&gt;harder to implement safely&lt;/em&gt;, not broken. Its danger is that the naive implementation is the insecure one, and for two decades the naive implementation is what shipped.&lt;/p&gt;
&lt;h3&gt;Generation two: the ladder that is constant-time by construction&lt;/h3&gt;
&lt;p&gt;In 2006, Daniel J. Bernstein introduced Curve25519, the Montgomery-form curve $y^2 = x^3 + 486662x^2 + x$ over the prime $2^{255} - 19$ [@curve25519-2006]. The form and its ladder trace back to Peter Montgomery&apos;s 1987 work on factorization, revived here for an entirely new purpose [@montgomery-1987]. Two design choices retire whole rows of the failure catalog for free.&lt;/p&gt;
&lt;p&gt;The first is the &lt;strong&gt;Montgomery ladder&lt;/strong&gt;: a scalar-multiplication method whose sequence of field operations is identical regardless of the secret bits. There is no secret-dependent branch to time, so the timing surface -- Brumley-Tuveri&apos;s surface -- closes by construction rather than by careful coding. Key agreement uses only the $x$-coordinate, so a peer sends 32 bytes and the $y$-coordinate never enters the arithmetic.&lt;/p&gt;

A scalar-multiplication algorithm that performs the same sequence of field operations for every bit of the secret -- one conditional swap plus a combined add-and-double per bit -- so its running time and memory-access pattern are independent of the scalar. It is constant-time by construction rather than by defensive programming.
&lt;p&gt;The second is &lt;strong&gt;twist security&lt;/strong&gt;. When someone hands you an $x$-coordinate, it corresponds either to a point on Curve25519 or to a point on its quadratic twist. Bernstein chose the parameters so that &lt;em&gt;both&lt;/em&gt; the curve and its twist have near-prime order [@curve25519-2006], [@safecurves-twist]. A hostile off-curve input therefore still lands you in a group where the discrete log is hard, and the invalid-curve attack of Section 4 is defused -- without any explicit on-curve check in the fast path.&lt;/p&gt;

A property of a curve whose quadratic twist also has near-prime order. Because a hostile input maps to a point on either the curve or its twist, and both groups are cryptographically hard, an off-curve input cannot be steered into a weak subgroup -- so invalid-curve attacks are defeated without an explicit on-curve validation step.
&lt;p&gt;The new cost is the seed of the next two generations: Curve25519 does not have prime order. Its group has cofactor 8, so low-order points exist.Bernstein states the orders exactly: the curve over its base field has $8 \times \ell$ points, where $\ell$ is the prime $2^{252} + 27742317\ldots$, and its twist has $4 \times \ell&apos;$ points for a different prime $\ell&apos;$ [@curve25519-2006]. That factor of 8 is the cofactor the next two generations spend their effort taming. To keep secret scalars inside the safe range, X25519 &lt;strong&gt;clamps&lt;/strong&gt; them. And clamping is the single most misunderstood step in the whole subject.&lt;/p&gt;

Forcing specific bits of an X25519 secret scalar: clearing the low three bits so the scalar is a multiple of the cofactor 8, clearing the high bit, and setting the second-highest bit so every scalar has the same length. Clamping constrains your own secret to sidestep small-subgroup and timing issues on your side. It is emphatically not validation of an input point someone else sends you.
&lt;p&gt;Clamping clears the low three bits (making your scalar a multiple of 8, so multiplying a low-order input contributes nothing on &lt;em&gt;your&lt;/em&gt; side), clears the top bit, and sets the second-highest bit so the ladder runs a fixed number of steps [@rfc7748].The X25519 clamp: &lt;code&gt;scalar[0] &amp;amp;= 248&lt;/code&gt; clears the low three bits, &lt;code&gt;scalar[31] &amp;amp;= 127&lt;/code&gt; clears bit 255, and &lt;code&gt;scalar[31] |= 64&lt;/code&gt; sets bit 254 [@rfc7748]. It protects you, the holder of the secret. It does nothing about a malicious low-order point arriving from outside -- which is why the Monero bug happened on a curve whose users clamped diligently.&lt;/p&gt;
&lt;h3&gt;Generation three: a complete addition law, and deterministic nonces&lt;/h3&gt;
&lt;p&gt;Curve25519 fixed key agreement, but signatures still lived on the branchy Weierstrass world or on Curve25519&apos;s cofactor. Ed25519 (2011) moved signing onto &lt;strong&gt;edwards25519&lt;/strong&gt;, the twisted-Edwards curve birationally equivalent to Curve25519 [@ed25519-2011]. The payoff is Harold Edwards&apos; 2007 normal form: a single addition formula with &lt;em&gt;no exceptional cases&lt;/em&gt; at all [@edwards-2007]. Doubling, adding, the identity -- one formula handles them, so the code has no secret-dependent branch and is naturally constant-time at the group-law level, retiring the incomplete-addition surface. Ed25519 also pairs the curve with &lt;strong&gt;deterministic nonces&lt;/strong&gt;, derived by hashing the message and a secret, which kill the catastrophic ECDSA per-signature-randomness disaster by construction (the nonce can no longer be repeated or biased by a &lt;a href=&quot;https://paragmali.com/blog/predictable-or-repeated-the-only-two-ways-cryptographic-rand/&quot; rel=&quot;noopener&quot;&gt;weak RNG&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;The cofactor did not vanish, though. edwards25519 still has cofactor 8, which is why signature malleability, &lt;a href=&quot;https://paragmali.com/blog/the-signature-was-valid-the-message-was-forged-a-field-guide/&quot; rel=&quot;noopener&quot;&gt;non-canonical encodings&lt;/a&gt;, and disagreements about whether verification should be &quot;cofactored&quot; are real concerns -- and precisely why RFC 8032 specifies canonical-encoding checks, bounds on the signature scalar, and cofactor handling [@rfc8032]. The nonce disaster itself is this series&apos; nonce-reuse post&apos;s territory; here it is enough that determinism closes the generation half of it.&lt;/p&gt;
&lt;h3&gt;Generation four: quotient the cofactor out of existence&lt;/h3&gt;
&lt;p&gt;The fourth generation asks a sharper question. Instead of patching every protocol to handle cofactor 8, what if the cofactor simply did not exist at the level you program against? Mike Hamburg&apos;s Decaf (2015) showed how: build a genuine prime-order group &lt;em&gt;in the encoding&lt;/em&gt; on top of a cofactor curve, so that the torsion points are quotiented away and never appear as elements [@decaf-2015]. Ristretto255 is the cofactor-8 instantiation for edwards25519, standardized in RFC 9496 in 2023 [@rfc9496]. The consequence is the cleanest safety property in the whole article: &lt;strong&gt;decoding is validation.&lt;/strong&gt; A sequence of bytes either decodes to a unique, legitimate prime-order element or it is rejected. There is no low-order point to submit, because low-order points are not representable.&lt;/p&gt;

flowchart TD
    A[&quot;Wire bytes for a ristretto255 element&quot;] --&amp;gt; B{&quot;Valid canonical encoding?&quot;}
    B --&amp;gt;|No| C[&quot;Reject: not a group element&quot;]
    B --&amp;gt;|Yes| D[&quot;Decode yields a unique prime-order point&quot;]
    D --&amp;gt; E[&quot;No cofactor, no torsion, no small subgroup&quot;]
    E --&amp;gt; F[&quot;Element is safe to use directly&quot;]

A group of prime order with no cofactor, constructed over the cofactor-8 curve edwards25519 by encoding equivalence classes of points rather than raw points. Because only valid prime-order elements have encodings, decoding a byte string is itself the validation step, and the entire cofactor and small-subgroup failure class disappears at the type level.
&lt;p&gt;Curve448 and its prime-order sibling decaf448 play the conservative role: a larger, roughly 224-bit-security option standardized in the same family but far more thinly deployed than the 25519 curves [@ed448-goldilocks-2015], [@rfc9496]. Treat it as the extra-margin choice, not a rival to X25519&apos;s ubiquity.&lt;/p&gt;
&lt;h3&gt;The through-line&lt;/h3&gt;
&lt;p&gt;These four generations are not a strict succession where each kills the last. They coexist: P-256 remains FIPS-mandated, X25519 and Ed25519 split the key-agreement and signature jobs between them, and ristretto255 sits underneath new protocols that need a clean prime-order group. What each generation truly superseded was not its predecessor curve but the &lt;em&gt;burden on the person writing the code&lt;/em&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Each generation took a rule off the implementer and baked it into the curve, the group, or the encoding. Constant-time became the ladder&apos;s default. On-curve validation became twist security. Exception-free addition became the Edwards law. Cofactor handling became the ristretto255 encoding. The simple implementation kept becoming the secure one.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Curve&lt;/th&gt;
&lt;th&gt;Form&lt;/th&gt;
&lt;th&gt;Field prime&lt;/th&gt;
&lt;th&gt;Cofactor&lt;/th&gt;
&lt;th&gt;Constant-time&lt;/th&gt;
&lt;th&gt;Twist secure&lt;/th&gt;
&lt;th&gt;Coordinates&lt;/th&gt;
&lt;th&gt;Best for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;P-256 (secp256r1)&lt;/td&gt;
&lt;td&gt;Short Weierstrass&lt;/td&gt;
&lt;td&gt;2^256 - 2^224 + 2^192 + 2^96 - 1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;With care (complete formulas)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Full (x, y)&lt;/td&gt;
&lt;td&gt;FIPS certificates, ECDSA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;secp256k1&lt;/td&gt;
&lt;td&gt;Short Weierstrass&lt;/td&gt;
&lt;td&gt;2^256 - 2^32 - 977&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;With care&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Full (x, y)&lt;/td&gt;
&lt;td&gt;Blockchain (Bitcoin, BIP-340)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Curve25519 / X25519&lt;/td&gt;
&lt;td&gt;Montgomery&lt;/td&gt;
&lt;td&gt;2^255 - 19&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;By construction&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;x-only (32 bytes)&lt;/td&gt;
&lt;td&gt;Key agreement&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;edwards25519 / Ed25519&lt;/td&gt;
&lt;td&gt;Twisted Edwards&lt;/td&gt;
&lt;td&gt;2^255 - 19&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;By construction&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;Compressed point&lt;/td&gt;
&lt;td&gt;Signatures&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ristretto255&lt;/td&gt;
&lt;td&gt;Prime-order over edwards25519&lt;/td&gt;
&lt;td&gt;2^255 - 19&lt;/td&gt;
&lt;td&gt;1 (effective)&lt;/td&gt;
&lt;td&gt;By construction&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;32-byte encoding&lt;/td&gt;
&lt;td&gt;New prime-order protocols&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Four generations, each erasing one line of the failure catalog. Someone still had to name the law they were all obeying -- and to say out loud that a hard curve and a safe cryptosystem were never the same thing.&lt;/p&gt;
&lt;h2&gt;6. ECDLP-Hardness Is Not ECC-Security&lt;/h2&gt;
&lt;p&gt;In 2013, Daniel J. Bernstein and Tanja Lange put the entire argument of this article onto one website, with a claim engineered to provoke: if you implement the standard curves, chances are you are doing it wrong [@safecurves-index]. The website was SafeCurves, and it is the moment the field said the quiet part out loud.&lt;/p&gt;

There is a gap between ECDLP difficulty and ECC security ... if you implement the standard curves, chances are you&apos;re doing it wrong.
&lt;p&gt;SafeCurves names four concrete places that gap opens: implementations that return wrong results on rare curve points, that leak secrets when fed off-curve inputs, that branch in secret-dependent time, and that leak through cache-timing [@safecurves-index]. Every one of those is a surface from Section 4. And the criteria SafeCurves proposes -- rigidity, twist security, complete addition, ladder support, a handled cofactor -- are not a beauty contest. They are a single design program stated as a checklist: &lt;em&gt;choose the curve so that the easy implementation is the safe one.&lt;/em&gt; That is the whole of Section 5 compressed into one sentence.&lt;/p&gt;
&lt;p&gt;Which lets us state the thesis in its most general form.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Security is a property of the curve, the group, and the implementation together -- not of ECDLP alone. A hard discrete logarithm is necessary and nowhere near sufficient. Every generation in the previous section is this one sentence, applied to a different part of the stack.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;The honest tension, handled carefully&lt;/h3&gt;
&lt;p&gt;It would be easy to read SafeCurves as a verdict that the NIST curves are unsafe. That reading is wrong, and getting it right is part of being an expert here rather than a partisan.&lt;/p&gt;

SafeCurves is a strong, deliberately opinionated argument from around 2013 to 2015, not a neutral consensus standard. NIST P-256 and P-384 do fail several of its criteria -- rigidity, twist security, complete addition in the naive formulas -- and yet they remain FIPS-mandated and, implemented with care, secure. The Renes-Costello-Batina complete formulas close the completeness gap in software [@rcb-2016], and vetted constant-time libraries close the rest. The defensible position is precise: P-256 is *harder to implement safely* than Curve25519, not *broken*. &quot;Prefer 25519 for new designs&quot; and &quot;P-256 is unsafe&quot; are different claims, and only the first is true [@safecurves-index].
&lt;p&gt;The scorecard below is the honest version. Read a &quot;No&quot; or a &quot;With care&quot; as &quot;the naive implementation needs help here,&quot; never as &quot;this curve is broken.&quot; Prime order is where the NIST curves quietly win, and it is exactly what the 25519 curves trade away.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Curve&lt;/th&gt;
&lt;th&gt;Rigidity&lt;/th&gt;
&lt;th&gt;Twist security&lt;/th&gt;
&lt;th&gt;Complete addition&lt;/th&gt;
&lt;th&gt;Ladder-friendly&lt;/th&gt;
&lt;th&gt;Prime order&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;P-256&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;With care&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;secp256k1&lt;/td&gt;
&lt;td&gt;Partly&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;With care&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;Curve25519 / X25519&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No (cofactor 8)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ed25519&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;No (cofactor 8)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ristretto255&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The footnote that keeps this table honest: every &quot;No&quot; for the NIST curves is a statement about the &lt;em&gt;default&lt;/em&gt; implementation, not the mathematics. secp256k1 is marked &quot;Partly&quot; rigid because its parameters follow a stated efficiency rationale rather than an unexplained seed. Give P-256 complete formulas and a constant-time field, and its row stops mattering. That is why the state of the art is not a single crowned curve but a matter of knowing which curve already does which job for you -- and in 2026, that picture is unusually settled.&lt;/p&gt;
&lt;h2&gt;7. State of the Art (2024-2026): Which Curve Does Which Job&lt;/h2&gt;
&lt;p&gt;There is no single best curve to crown. The state of the art is a small, stable set, each member owning a job -- plus one transition quietly rewriting every handshake on the internet.&lt;/p&gt;
&lt;h3&gt;X25519 owns key agreement&lt;/h3&gt;
&lt;p&gt;For ephemeral key agreement, X25519 is the default answer. It is constant-time by construction, twist-secure, and moves 32 bytes per side; it is a standardized TLS 1.3 named group [@rfc8446], the Diffie-Hellman step in WireGuard&apos;s Noise handshake [@wireguard-protocol], and the key exchange in Signal, all built on the same Curve25519 arithmetic [@rfc7748]. For plain Diffie-Hellman you need no explicit point-validation code, because twist security already handles hostile inputs -- the operational rules reduce to rejecting the all-zero output and running the shared secret through a KDF rather than using it raw.&lt;/p&gt;
&lt;h3&gt;P-256 ECDSA owns FIPS certificates&lt;/h3&gt;
&lt;p&gt;P-256 is co-dominant, and for a specific reason: it is FIPS-mandatory for certificates [@fips-186-5]. Among the curves used in web certificates it is overwhelmingly the one [@ssl-pulse], now implemented with complete formulas or vetted constant-time assembly plus point validation on untrusted inputs [@sp-800-56a-r3]. Where a compliance regime names the curve, P-256 done carefully is exactly right.&lt;/p&gt;
&lt;h3&gt;Ed25519 is now FIPS-approved too&lt;/h3&gt;
&lt;p&gt;The important recent shift for signatures is regulatory. FIPS 186-5, published February 3, 2023, approves EdDSA alongside ECDSA [@fips-186-5], so Ed25519 is now both the technically cleaner option and a compliant one. It is standard in OpenSSH, in Git commit signing, and in package-signing tools such as minisign and OpenBSD&apos;s signify. Ed25519 needs about 87,500 CPU cycles to sign and about 273,000 to verify -- near 134,000 per signature when many are checked in one batch [@ed25519-2011] -- with the eBACS suite serving as the live cross-CPU benchmark authority [@bench-cr-yp-to]. The state-of-the-art guidance: Ed25519 for new designs, ECDSA where compliance compels it [@rfc8032].&lt;/p&gt;
&lt;h3&gt;secp256k1 owns blockchain, and only blockchain&lt;/h3&gt;
&lt;p&gt;secp256k1 carries an enormous deployment -- Bitcoin, Ethereum, and their descendants -- through ECDSA and, since Taproot, BIP-340 Schnorr signatures [@bip-340]. It is nonetheless essentially absent from web PKI and TLS. On any decision about a certificate or a general key exchange, secp256k1 is not a candidate; it is the answer only when the job is blockchain interoperability.&lt;/p&gt;
&lt;h3&gt;Ristretto255 is the prime-order substrate for new protocols&lt;/h3&gt;
&lt;p&gt;When a protocol needs a clean prime-order group -- password-authenticated key exchange, verifiable random functions, oblivious pseudorandom functions, threshold signatures, zero-knowledge systems -- ristretto255 (RFC 9496) is the current substrate [@rfc9496]. It is the recommended ciphersuite of the FROST threshold-Schnorr standard, which is defined generically over any prime-order group and also specifies Ed25519, Ed448, P-256, and secp256k1 suites [@rfc9591]; and it ships in production inside Signal&apos;s libsignal, whose zkgroup and zkcredential modules build on ristretto255 points [@libsignal].&lt;/p&gt;
&lt;h3&gt;The post-quantum overlay: ECC wrapped, not replaced&lt;/h3&gt;
&lt;p&gt;The headline of 2024 to 2026 is not a new curve; it is a wrapper. The hybrid &lt;strong&gt;X25519 plus ML-KEM-768&lt;/strong&gt; combines the classical curve with 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;NIST-standardized lattice KEM&lt;/a&gt;, and it is now shipping by default in Chrome and across Cloudflare&apos;s network [@cloudflare-pq-2024], and available in OpenSSH 9.9, released September 2024 [@openssh-9.9]. The motive is &quot;harvest now, decrypt later&quot;: an adversary can record today&apos;s X25519 traffic and wait for a quantum computer, so the hybrid forces them to break &lt;em&gt;both&lt;/em&gt; the curve and the lattice.Post-quantum-encrypted traffic on Cloudflare&apos;s network nearly doubled across 2025, from about 29% of human-generated web requests at the start of the year to roughly 52% by early December [@cloudflare-radar-2025], with a live tracker following the trend [@cloudflare-radar-pq-tracker].&lt;/p&gt;
&lt;p&gt;The enabling techniques are themselves state of the art. The Montgomery ladder, the Renes-Costello-Batina complete formulas [@rcb-2016], and machine-checked, correct-by-construction field arithmetic (fiat-crypto, whose code for Curve25519 and P-256 ships inside BoringSSL) are what make these curves safe in practice rather than merely on paper [@fiat-crypto].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; It is not a single best curve. It is &quot;the right curve for the job&quot; -- X25519 for key agreement, Ed25519 for new signatures, P-256 where FIPS compels it, secp256k1 only for blockchain, ristretto255 for new prime-order protocols -- plus the hybrid transition that wraps the classical curve in a post-quantum KEM.&lt;/p&gt;
&lt;/blockquote&gt;

FIPS 186-5 approves EdDSA, so Ed25519 is now a compliant signature choice [@fips-186-5]; ECDSA over P-256 remains mandated for certificates; and SP 800-56A Rev. 3 requires point and subgroup validation for untrusted inputs in key establishment [@sp-800-56a-r3]. Compliance and good engineering point the same way more often than they used to.
&lt;p&gt;&quot;Which curve owns which job&quot; is a summary, not a decision procedure. When the jobs overlap -- when a compliance regime, a blockchain, and a threshold protocol pull in three directions at once -- you need the head-to-head.&lt;/p&gt;
&lt;h2&gt;8. The Decision Matrix&lt;/h2&gt;
&lt;p&gt;The deployed curves do not all compete for the same job, so the useful comparison is per task -- and it hinges on one axis the benchmarks never advertise: &lt;em&gt;how much of the failure catalog you must defend against by hand.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;Key agreement: X25519 unless something forces your hand&lt;/h3&gt;
&lt;p&gt;Default to X25519. Its twist security and constant-time ladder mean the dangerous inputs are already handled, so your implementation burden is low: reject the all-zero shared secret and run the result through a KDF. Choose P-256 ECDH only where a compliance regime mandates it -- and then take on the full burden the curve leaves you: validate the peer point is on the curve &lt;em&gt;and&lt;/em&gt; in the prime-order subgroup, use complete formulas or vetted constant-time code, and never feed the raw x-coordinate to anything but a KDF [@sp-800-56a-r3], [@rcb-2016]. Reach for X448 only when a policy demands a larger margin.&lt;/p&gt;
&lt;p&gt;| Curve | Form | Security | Cofactor | Constant-time | Twist secure | Element | Safety burden | Compliance |
| --- | --- | --- | --- | --- | --- | --- | --- |
| X25519 | Montgomery | ~128-bit | 8 | By construction | Yes | 32 B | Low: reject zero, KDF the output | Not required for certificates |
| P-256 ECDH | Short Weierstrass | ~128-bit | 1 | With care | No | 33 B compressed | High: validate point and subgroup, constant-time | FIPS-mandated |
| X448 | Montgomery | ~224-bit | 4 | By construction | Yes | 56 B | Low | Extra-margin option |&lt;/p&gt;
&lt;p&gt;The one rule that survives every row: never use the raw shared x-coordinate as a key. Run it through a KDF, as this series&apos; key-derivation installment argues.&lt;/p&gt;
&lt;h3&gt;Signatures: Ed25519 for new work, ECDSA where mandated&lt;/h3&gt;
&lt;p&gt;For new designs, Ed25519 wins on the axis that matters -- it removes the per-signature randomness that has destroyed more ECDSA keys than any cryptanalysis, and its complete addition law removes the exceptional cases [@rfc8032]. Use ECDSA over P-256 only where a standard names it, and then defend it deliberately: RFC 6979 deterministic nonces, constant-time scalar multiplication, and point validation [@rfc6979]. BIP-340 Schnorr is the right choice for new Bitcoin work and nowhere else [@bip-340].&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scheme&lt;/th&gt;
&lt;th&gt;Nonce&lt;/th&gt;
&lt;th&gt;Nonce-failure blast radius&lt;/th&gt;
&lt;th&gt;Addition law&lt;/th&gt;
&lt;th&gt;Malleability rule&lt;/th&gt;
&lt;th&gt;Sizes&lt;/th&gt;
&lt;th&gt;Batch verify&lt;/th&gt;
&lt;th&gt;Compliance&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Ed25519&lt;/td&gt;
&lt;td&gt;Deterministic (hash-based)&lt;/td&gt;
&lt;td&gt;None by construction&lt;/td&gt;
&lt;td&gt;Complete Edwards&lt;/td&gt;
&lt;td&gt;Enforce canonical S and cofactor checks&lt;/td&gt;
&lt;td&gt;64 B sig, 32 B key&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;FIPS 186-5 approved&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ECDSA P-256&lt;/td&gt;
&lt;td&gt;Random, or RFC 6979 deterministic&lt;/td&gt;
&lt;td&gt;Catastrophic: a reused or biased nonce leaks the key&lt;/td&gt;
&lt;td&gt;Incomplete Weierstrass&lt;/td&gt;
&lt;td&gt;Low-S recommended&lt;/td&gt;
&lt;td&gt;~64-72 B sig, 33 B key&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;FIPS-mandated&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BIP-340 Schnorr&lt;/td&gt;
&lt;td&gt;Deterministic with auxiliary randomness&lt;/td&gt;
&lt;td&gt;Reduced versus ECDSA&lt;/td&gt;
&lt;td&gt;secp256k1&lt;/td&gt;
&lt;td&gt;Fixed by encoding&lt;/td&gt;
&lt;td&gt;64 B sig, 32 B x-only key&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Bitcoin only&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h3&gt;Group abstraction: ristretto255 over hand-rolled cofactor clearing&lt;/h3&gt;
&lt;p&gt;If you are building a new prime-order protocol -- a PAKE, a VRF, an OPRF, a threshold scheme, a zero-knowledge system -- build it on ristretto255 rather than hand-rolling cofactor clearing over raw edwards25519 [@rfc9496]. Decode-is-validation removes the last implementation choice that could go wrong, which is the entire point of Generation four.&lt;/p&gt;
&lt;h3&gt;The cross-primitive view&lt;/h3&gt;
&lt;p&gt;Two comparisons sit outside this table but belong in your head. Against &lt;a href=&quot;https://paragmali.com/blog/rsa-is-a-trapdoor-not-a-cryptosystem-oaep-pss-and-the-25-yea/&quot; rel=&quot;noopener&quot;&gt;RSA&lt;/a&gt;, elliptic curves do the same public-key jobs with smaller keys and faster operations, and they share the reframe this series keeps returning to: the math was never the thing that broke. Against post-quantum schemes, ECC is not yet replaced -- the classical curve is the defense-in-depth half of a hybrid, present precisely because a lattice KEM is young and a recorded handshake is forever. Neither comparison changes a single row above; both change how long these rows stay valid.&lt;/p&gt;
&lt;p&gt;Every row here assumes the curve&apos;s discrete log is genuinely hard. That assumption has a precise boundary -- and a hard expiration date.&lt;/p&gt;
&lt;h2&gt;9. Where the Hardness Lives, and Its Ceiling&lt;/h2&gt;
&lt;p&gt;Here is the uncomfortable pair of facts a first course tends to skip. For a well-chosen curve, the security level is &lt;em&gt;exactly&lt;/em&gt; the generic bound -- there is no hidden margin above it, but nothing better is known either. And that entire edifice falls to a quantum computer in polynomial time.&lt;/p&gt;
&lt;h3&gt;The generic bound, matched from both sides&lt;/h3&gt;
&lt;p&gt;The best classical attacks on a well-chosen curve are &lt;em&gt;generic&lt;/em&gt; -- they work in any group and know nothing special about elliptic curves. Pollard rho finds a discrete log in about $\sqrt{n}$ group operations for a group of order $n$, using parallel collision search with distinguished points and almost no memory [@safecurves-rho]. Pohlig-Hellman reduces the problem to the largest prime factor of the group order, which is the deep reason prime order matters: a smooth order is a soft target. Against those upper bounds sits a matching lower bound -- Shoup (1997) and Nechaev (1994) proved that &lt;em&gt;any&lt;/em&gt; generic algorithm needs $\Omega(\sqrt{n})$ operations. Upper and lower bounds meet.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; For a well-chosen curve, the security level is the generic square-root bound itself: about $\sqrt{n}$ work, matched by a proven lower bound. That is solid -- but it means there is no safety margin hiding above the number, and, as we are about to see, a quantum cliff waiting below it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That closed gap is genuinely unusual among cryptographic assumptions, and it is the whole reason a 256-bit curve is trusted at the 128-bit level.Most hardness assumptions leave a gap between the best known attack and the best provable lower bound. For generic ECDLP on a well-chosen curve, the two coincide at $\sqrt{n}$. You are trusting a bound that is tight, not merely unbroken. The reason no &lt;em&gt;better&lt;/em&gt; attack exists is the absence we opened with: no index-calculus method is known that beats $\sqrt{n}$ on prime-field curves. Semaev&apos;s summation polynomials and the programs built on them have not produced one. The economic case of Section 2 is really this limit, seen from the other side.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symmetric security&lt;/th&gt;
&lt;th&gt;Elliptic-curve size&lt;/th&gt;
&lt;th&gt;RSA / finite-field DH modulus&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;112-bit&lt;/td&gt;
&lt;td&gt;224-bit&lt;/td&gt;
&lt;td&gt;2048-bit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;128-bit&lt;/td&gt;
&lt;td&gt;256-bit&lt;/td&gt;
&lt;td&gt;3072-bit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;192-bit&lt;/td&gt;
&lt;td&gt;384-bit&lt;/td&gt;
&lt;td&gt;7680-bit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;256-bit&lt;/td&gt;
&lt;td&gt;512-bit&lt;/td&gt;
&lt;td&gt;15360-bit&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The table is the standard security-level mapping, and its middle row is the sentence everyone quotes: 256-bit ECC stands in for 3072-bit RSA at roughly 128-bit strength, because the curve attacker pays $\sqrt{n}$ while the RSA attacker enjoys sub-exponential index calculus [@safecurves-rho], [@miller-1985].&lt;/p&gt;
&lt;h3&gt;What &quot;well-chosen&quot; rules out&lt;/h3&gt;
&lt;p&gt;The generic bound holds only for curves that avoid a short list of special structures, and each item on that list is a curve that &lt;em&gt;looks&lt;/em&gt; fine but collapses. The MOV reduction (Menezes, Okamoto, and Vanstone, 1993) maps a curve with low embedding degree -- supersingular curves are the extreme case -- into a finite field where index calculus applies, collapsing its ECDLP [@mov-1993]. Anomalous, or trace-one, curves, where the number of points equals the field prime, admit an additive transfer that solves the discrete log in &lt;em&gt;polynomial&lt;/em&gt; time (Smart; independently Satoh-Araki and Semaev) [@smart-1999]. And the small-subgroup and twist conditions of Section 4 round out the list. &quot;Well-chosen&quot; is exactly &quot;avoids these.&quot;&lt;/p&gt;
&lt;h3&gt;The one bound that is not the square root&lt;/h3&gt;
&lt;p&gt;Every limit so far is classical. The exception is the one that sets the deadline. Shor&apos;s algorithm (1997) solves both factoring and discrete logarithms -- including ECDLP -- in polynomial time on a fault-tolerant quantum computer [@shor-1997]. Resource estimates make it concrete: at equal classical security ECC is the easier quantum target -- breaking a 256-bit curve needs roughly 2,330 logical qubits and about $1.3 \times 10^{11}$ Toffoli gates, versus roughly 6,100 logical qubits for RSA-3072, so ECC&apos;s smaller keys are the smaller quantum target and fall first [@roetteler-2017]. No choice of curve escapes this; it is a property of the group structure Shor exploits, not of any parameter.&lt;/p&gt;

This is why today&apos;s ECDH traffic is already on a clock, before any quantum computer exists. An adversary records your X25519 handshakes now and decrypts them the day a machine can run Shor at scale. The recorded session is not refreshed; its forward secrecy is only as good as the assumption that the curve stays hard forever -- which Shor says it will not [@shor-1997]. That single fact, not any classical advance, is what put the hybrid transition of Section 7 on every roadmap.
&lt;p&gt;If the mathematics is this settled -- a closed classical bound and a known quantum ceiling -- then everything still open lives in the code, the trust, and the migration. That is where the real frontier is.&lt;/p&gt;
&lt;h2&gt;10. What Remains Genuinely Unsettled&lt;/h2&gt;
&lt;p&gt;The core science is settled, and the failure catalog and its defenses are not in dispute. What is open sits at the edges -- and two of these are live in your dependency tree right now.&lt;/p&gt;
&lt;h3&gt;Constant-time is a perpetually moving target&lt;/h3&gt;
&lt;p&gt;Montgomery ladders and complete formulas close the obvious channels, and still the leaks keep reappearing at finer grain. Minerva recovered secp256r1 private keys from about 2,100 signatures by measuring how the nonce&apos;s bit-length shifted the signing time [@minerva-2020]. TPM-Fail pulled 256-bit ECDSA keys out of an Intel firmware TPM and an STMicroelectronics TPM despite their certifications [@tpm-fail-2020]. LadderLeak broke ECDSA with less than one bit of nonce leakage [@ladderleak-2020]. There is no general, machine-checkable guarantee of constant-time behavior that survives arbitrary compilers and microarchitectures. The lattice step that turns these leaks into keys belongs to this series&apos; &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;nonce-reuse post&lt;/a&gt;; the open problem here is the leakage itself.&lt;/p&gt;
&lt;h3&gt;The NIST-curve trust question is sociological, not solved&lt;/h3&gt;
&lt;p&gt;No weakness has ever been demonstrated in P-256 or P-384, and they remain FIPS-mandated [@safecurves-index]. Yet Dual EC DRBG proved that NIST-supplied constants &lt;em&gt;could&lt;/em&gt; be poisoned, which is why a large part of the community prefers rigid curves for new work [@shumow-ferguson-2007]. This is not the kind of question a proof can close -- you cannot prove the absence of a motive. The practical resolution is a posture, not a theorem: prefer 25519 for new designs, use P-256 with care where compliance compels it.&lt;/p&gt;
&lt;h3&gt;The cofactor long tail&lt;/h3&gt;
&lt;p&gt;RFC 9496 eliminates the cofactor failure class -- for the protocols that adopt it [@rfc9496]. The long tail of deployed EdDSA and X25519 protocols that predate or simply ignore ristretto255 remains a live source of subgroup bugs, with Monero the canonical example [@loup-vaillant-cofactor]. This is a migration problem, not a research problem, which somehow makes it more stubborn rather than less.&lt;/p&gt;
&lt;h3&gt;The post-quantum migration, past the easy part&lt;/h3&gt;
&lt;p&gt;Hybrid key agreement is deploying fast [@cloudflare-radar-2025], but the interesting questions start after the first hybrid ships: how long ECC&apos;s small keys keep it useful inside hybrids, whether and when to drop the classical half, which combiner and negotiation are right, and the genuinely harder migration on the signature side, where the post-quantum replacements are large and awkward.&lt;/p&gt;
&lt;h3&gt;Formal verification at scale&lt;/h3&gt;
&lt;p&gt;fiat-crypto ships proven-correct field arithmetic for Curve25519 and P-256 inside BoringSSL, which is a real milestone [@fiat-crypto]. But end-to-end verification -- field, then group law, then protocol, then constant-time behavior on the actual target instruction set -- is not yet routine. The field-arithmetic layer is solved; the stack above it is not.&lt;/p&gt;
&lt;p&gt;There is also a structural non-problem worth naming, so you can stop worrying about it: no one has found a faster-than-square-root attack on prime-field ECDLP, and the summation-polynomial work that raised hopes lives in binary and composite fields -- one more reason NIST now steers new work to prime-field curves: SP 800-186 deprecates the binary and Koblitz curves, retaining them only for legacy interoperability, and FIPS 186-5 dropped them from approval for new signatures [@sp-800-186], [@fips-186-5].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Of the five open fronts, two are the ones likely to be in &lt;em&gt;your&lt;/em&gt; stack today: a non-constant-time scalar multiplication somewhere in a dependency, and a protocol built on raw edwards25519 that never adopted ristretto255. The other three are the industry&apos;s problem. These two are yours.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Enough theory and frontier. Here is the entire article compressed into rules you can apply on Monday -- each one a named break from the catalog, turned inside out.&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 row of the failure catalog, inverted. If you remember nothing else from this article, remember the decision tree.&lt;/p&gt;

flowchart TD
    A{&quot;What is the job?&quot;} --&amp;gt; B[&quot;Key agreement&quot;]
    A --&amp;gt; C[&quot;Signature&quot;]
    A --&amp;gt; D[&quot;Prime-order protocol&quot;]
    A --&amp;gt; E[&quot;Long-lived confidentiality&quot;]
    B --&amp;gt; B1{&quot;FIPS-mandated curve?&quot;}
    B1 --&amp;gt;|No| B2[&quot;X25519, reject zero output, KDF the result&quot;]
    B1 --&amp;gt;|Yes| B3[&quot;P-256 ECDH, validate point and subgroup, constant-time, KDF&quot;]
    C --&amp;gt; C1{&quot;New design?&quot;}
    C1 --&amp;gt;|Yes| C2[&quot;Ed25519, enforce canonical S, strict library&quot;]
    C1 --&amp;gt;|Mandated| C3[&quot;ECDSA P-256, RFC 6979 nonce, constant-time, validate points&quot;]
    D --&amp;gt; D1[&quot;Build on ristretto255 or decaf448&quot;]
    E --&amp;gt; E1[&quot;Wrap X25519 in the ML-KEM-768 hybrid&quot;]
&lt;h3&gt;The decision rules, in words&lt;/h3&gt;
&lt;p&gt;For &lt;strong&gt;key agreement&lt;/strong&gt;, reach for X25519 by default: constant-time by construction, twist security handling hostile inputs, and one operational rule -- run the shared secret through a KDF and reject the all-zero output, never using the raw x-coordinate as a key [@rfc7748]. Use P-256 ECDH only where FIPS compels it, and then validate the peer point on the curve &lt;em&gt;and&lt;/em&gt; in the prime-order subgroup, use complete formulas or a vetted constant-time library, and KDF the result [@sp-800-56a-r3], [@rcb-2016].&lt;/p&gt;
&lt;p&gt;For &lt;strong&gt;signatures&lt;/strong&gt;, choose Ed25519 for new designs -- deterministic nonces, a complete addition law, and a strict library that enforces the canonical-S check [@rfc8032]. Use ECDSA over P-256 only where mandated, with RFC 6979 deterministic nonces, constant-time scalar multiplication, and point validation [@rfc6979].&lt;/p&gt;
&lt;p&gt;For &lt;strong&gt;point handling&lt;/strong&gt;, always validate untrusted points -- on the curve and in the right subgroup -- remember that clamping is not validation, and never accept explicit curve parameters from a certificate or message; use named curves only, which is the whole lesson of Curveball [@cve-2020-0601]. For &lt;strong&gt;new prime-order protocols&lt;/strong&gt;, build on ristretto255 or decaf448 instead of hand-rolling cofactor clearing [@rfc9496]. For &lt;strong&gt;long-lived confidentiality&lt;/strong&gt;, deploy the X25519 plus ML-KEM-768 hybrid now rather than waiting for a pure post-quantum replacement.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Job&lt;/th&gt;
&lt;th&gt;Use&lt;/th&gt;
&lt;th&gt;Key parameters&lt;/th&gt;
&lt;th&gt;Because (the named break)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Key agreement (default)&lt;/td&gt;
&lt;td&gt;X25519&lt;/td&gt;
&lt;td&gt;Reject zero output, KDF the secret&lt;/td&gt;
&lt;td&gt;Raw-x misuse, twist security handles inputs [@rfc7748]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Key agreement (FIPS)&lt;/td&gt;
&lt;td&gt;P-256 ECDH&lt;/td&gt;
&lt;td&gt;Validate point and subgroup, constant-time&lt;/td&gt;
&lt;td&gt;Invalid-curve TLS recovery [@jager-2015], timing [@brumley-tuveri-2011]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Signature (new)&lt;/td&gt;
&lt;td&gt;Ed25519&lt;/td&gt;
&lt;td&gt;Canonical S, strict library&lt;/td&gt;
&lt;td&gt;Nonce disaster and malleability [@rfc8032]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Signature (mandated)&lt;/td&gt;
&lt;td&gt;ECDSA P-256&lt;/td&gt;
&lt;td&gt;RFC 6979 nonce, constant-time, validate&lt;/td&gt;
&lt;td&gt;Nonce reuse or bias [@rfc6979]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prime-order protocol&lt;/td&gt;
&lt;td&gt;ristretto255 / decaf448&lt;/td&gt;
&lt;td&gt;Decode is validation&lt;/td&gt;
&lt;td&gt;Cofactor double-spend [@loup-vaillant-cofactor]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Certificates&lt;/td&gt;
&lt;td&gt;Named curves only&lt;/td&gt;
&lt;td&gt;Reject explicit parameters&lt;/td&gt;
&lt;td&gt;Curveball [@cve-2020-0601]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Long-lived secrecy&lt;/td&gt;
&lt;td&gt;X25519 + ML-KEM-768&lt;/td&gt;
&lt;td&gt;Hybrid combiner now&lt;/td&gt;
&lt;td&gt;Harvest-now-decrypt-later [@shor-1997]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h3&gt;Why &quot;clamping is not validation&quot; is a rule, not a slogan&lt;/h3&gt;
&lt;p&gt;The single most common confusion deserves a demonstration rather than an assertion. On a curve with a cofactor, an attacker can add a low-order point to a legitimate one. Clamping your secret scalar hides that tampering inside a Diffie-Hellman product -- so clamping alone cannot even detect it -- while an explicit prime-order subgroup check catches it immediately.&lt;/p&gt;
&lt;p&gt;{`
// Toy curve y^2 = x^3 + x over F_53. Group order 68 = 4 * 17 (cofactor 4, prime l = 17).
const p = 53n, a = 1n, ELL = 17n;
const mod = x =&amp;gt; ((x % p) + p) % p;
function inv(x){ let r=1n,b=mod(x),e=p-2n; while(e&amp;gt;0n){ if(e&amp;amp;1n) r=mod(r&lt;em&gt;b); b=mod(b&lt;/em&gt;b); e&amp;gt;&amp;gt;=1n;} return r; }
const eq = (P,Q) =&amp;gt; (P===null&amp;amp;&amp;amp;Q===null) || (P&amp;amp;&amp;amp;Q&amp;amp;&amp;amp;P[0]===Q[0]&amp;amp;&amp;amp;P[1]===Q[1]);
function add(P,Q){
  if(P===null) return Q; if(Q===null) return P;
  const [x1,y1]=P,[x2,y2]=Q;
  if(x1===x2 &amp;amp;&amp;amp; mod(y1+y2)===0n) return null;
  const s=(x1===x2&amp;amp;&amp;amp;y1===y2)? mod((3n&lt;em&gt;x1&lt;/em&gt;x1+a)&lt;em&gt;inv(2n&lt;/em&gt;y1)) : mod((y2-y1)&lt;em&gt;inv(x2-x1));
  const x3=mod(s&lt;/em&gt;s-x1-x2); return [x3, mod(s*(x1-x3)-y1)];
}
function mul(k,P){ let R=null,b=P; while(k&amp;gt;0n){ if(k&amp;amp;1n) R=add(R,b); b=add(b,b); k&amp;gt;&amp;gt;=1n;} return R; }&lt;/p&gt;
&lt;p&gt;const P = [6n,13n];                 // legitimate prime-order point (order 17)
const Low = [0n,0n];                // low-order point (order 2, divides the cofactor 4)
const tampered = add(P, Low);       // attacker adds a low-order component
console.log(&apos;P and P+Low are distinct encodings?&apos;, !eq(P, tampered));&lt;/p&gt;
&lt;p&gt;// Clamping forces the secret to a multiple of the cofactor, so it HIDES the tamper:
const kClamped = 4n * 5n;           // 20, a multiple of the cofactor 4
console.log(&apos;clamped [k]P equals clamped &lt;a href=&quot;P+Low&quot; rel=&quot;noopener&quot;&gt;k&lt;/a&gt;?&apos;, eq(mul(kClamped,P), mul(kClamped,tampered)));&lt;/p&gt;
&lt;p&gt;// The real defence is an explicit prime-order subgroup check [l]X == identity:
console.log(&apos;subgroup check -- [l]P is identity?&apos;, mul(ELL,P) === null);
console.log(&apos;subgroup check -- &lt;a href=&quot;P+Low&quot; rel=&quot;noopener&quot;&gt;l&lt;/a&gt; is identity?&apos;, mul(ELL,tampered) === null);
`}&lt;/p&gt;
&lt;p&gt;The clamped multiplication reports the tampered point as identical, and only the $[\ell]X = \mathcal{O}$ subgroup check flags it. That is the Monero bug in nine lines: the code that needed to reject the tampered element was not the clamp, it was the subgroup test.&lt;/p&gt;

On most systems you can see the real curves in seconds. `ssh -Q key` and `ssh -Q kex` list your SSH key and key-exchange algorithms -- look for `ssh-ed25519` and a hybrid like `mlkem768x25519-sha256`. For TLS, `openssl s_client -connect example.com:443 -tls1_3` reports the negotiated group, often `X25519` or the hybrid `X25519MLKEM768`. Versions differ, but these tell you which curve and which post-quantum wrapper your traffic actually uses today, rather than which one you assume it does.
&lt;h3&gt;The misuse catalog&lt;/h3&gt;
&lt;p&gt;Each antipattern below is exactly one violated rule, and each maps to a named break you have now met:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Using the raw ECDH x-coordinate as a key.&lt;/strong&gt; Run it through a KDF instead; the shared secret is an input to key derivation, not a key.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Treating clamping as validation.&lt;/strong&gt; Clamping constrains your secret; it does not filter a hostile input point (Monero [@loup-vaillant-cofactor]).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skipping point validation on Weierstrass curves.&lt;/strong&gt; The formula ignores $b$, so an off-curve point is processed on a weaker curve (invalid-curve, Jager et al. [@jager-2015]).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Accepting explicit curve parameters.&lt;/strong&gt; Trusting a generator you did not choose forges chains (Curveball [@cve-2020-0601]).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Non-constant-time or unvalidated P-256.&lt;/strong&gt; Data-dependent timing is an oracle even with honest inputs (Brumley-Tuveri [@brumley-tuveri-2011]).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ignoring the cofactor or non-canonical encodings in edwards25519 protocols.&lt;/strong&gt; Low-order points and duplicate encodings break uniqueness (Monero [@loup-vaillant-cofactor]).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rolling your own curve arithmetic.&lt;/strong&gt; Use fiat-crypto-backed libraries; hand-written field code is where constant-time dies [@fiat-crypto].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reusing or biasing ECDSA nonces.&lt;/strong&gt; A repeated or leaky nonce hands over the key through a lattice (RFC 6979 fixes the generation half [@rfc6979]).&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If your time is limited, hunt these first: the raw ECDH x-coordinate used directly as a key; a P-256 ECDH path that neither validates the peer point nor runs in constant time; and any code path that accepts explicit curve parameters instead of a named curve. Those three account for most real elliptic-curve findings in production code.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Read the whole failure catalog again as this checklist, and one sentence remains true of every row.&lt;/p&gt;
&lt;h2&gt;12. The Curve Was Hard; The Gap Was Soft&lt;/h2&gt;
&lt;p&gt;Return to where we started. The NSA phoned Microsoft, and nobody solved a discrete logarithm [@cve-2020-0601]. That is not an anomaly; it is the whole pattern in one image. Across three decades of deployed elliptic-curve cryptography, almost no real break ever inverted the function the textbooks call hard. Attackers fed the implementation a point it should have rejected -- off the curve, or of small order, or a certificate&apos;s own untrusted generator (invalid-curve, small-subgroup, Curveball) [@jager-2015]. They added a low-order component that clamping never filtered (Monero) [@loup-vaillant-cofactor]. Or they simply read the clock while the code multiplied a secret (Brumley-Tuveri, and the Minerva-TPM-Fail-LadderLeak lineage) [@brumley-tuveri-2011].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The curve was hard; the gap was soft. ECDLP-hardness bought the small keys and the speed, and it held every single time. The breaks all lived in the code, the trust, and the encoding around the curve -- the space between a hard problem and a safe system.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So &quot;using elliptic curves safely&quot; is not one decision but a stack: the right curve for the job, point and subgroup validation on every untrusted input, constant-time scalar multiplication, and -- the deepest lesson the evolution kept teaching -- a preference for constructions where the dangerous case cannot be reached at all, as ristretto255 makes literal [@rfc9496]. Remove any single layer and the gap reopens. And the horizon is honest about its own limit: the destination is not a better curve, because no curve survives Shor [@shor-1997]. It is wrapping the curve in a post-quantum hybrid and buying time.&lt;/p&gt;

The private curve stayed hard; the code around it confessed.
&lt;p&gt;Which makes the diagnostic question we opened with finally answerable. When a point you did not generate arrives, what does your code reveal about it -- through its result, its timing, or the parameters it trusts? Using elliptic curves safely is the discipline of making that answer &lt;em&gt;nothing an attacker can measure.&lt;/em&gt;&lt;/p&gt;


No weakness has ever been shown in P-256 or P-384. The real concern is *rigidity*: their generator and coefficient come from an unexplained seed, and the Dual EC DRBG affair proved that NIST-supplied constants *could* be poisoned in some other primitive. That history is why many engineers prefer rigid curves like Curve25519 for new designs. But &quot;prefer 25519&quot; is a different claim from &quot;P-256 is broken,&quot; and only the first one is supported.


No -- it is *harder to implement safely*, not broken. Its naive addition formulas have exceptional cases and it lacks twist security, so a careless implementation can leak. Complete addition formulas (Renes-Costello-Batina) and vetted constant-time libraries close those gaps. Implemented carefully, P-256 is secure and remains FIPS-mandated for certificates.


For plain Diffie-Hellman, no on-curve check is required: Curve25519&apos;s twist security means a hostile input still lands in a hard group, so you just reject the all-zero output and run the result through a KDF. But low-order points still matter for protocols that need a genuine prime-order group. Validate or clear the cofactor there, or better, build on ristretto255 and let decoding do the validation.


No. Clamping constrains *your own* secret scalar so a low-order component contributes nothing to your Diffie-Hellman product. It does nothing to validate a malicious input point, and it does not make a tampered point canonical. The Monero cofactor bug is exactly this confusion -- the fix was an explicit prime-order subgroup check, not clamping.


Only if you are doing blockchain interoperability. secp256k1 is the Bitcoin and Ethereum curve; it is essentially absent from web PKI and TLS. For general key agreement use X25519, and for certificates use P-256. Reaching for secp256k1 outside the blockchain context is almost always a sign something is being reinvented.


Use Ed25519 for new work: deterministic nonces remove the per-signature randomness that has destroyed more ECDSA keys than any cryptanalysis, the addition law is complete and constant-time, and EdDSA has been FIPS-approved since 186-5. Use ECDSA over P-256 only where a standard mandates it, and then with RFC 6979 deterministic nonces, constant-time scalar multiplication, and point validation.


No. Shor&apos;s algorithm breaks the elliptic-curve discrete log in polynomial time on a fault-tolerant quantum computer, and at equal classical security ECC is the easier quantum target -- a 256-bit curve needs about 2,330 logical qubits versus roughly 6,100 for RSA-3072, so it falls first. Because recorded traffic can be decrypted later, deploy the X25519 plus ML-KEM-768 hybrid now rather than waiting for a pure post-quantum replacement.

&lt;p&gt;&amp;lt;StudyGuide slug=&quot;elliptic-curves-real-world-p256-curve25519&quot; keyTerms={[
  { term: &quot;ECDLP&quot;, definition: &quot;The elliptic-curve discrete-log problem: given a base point G and Q equal to k times G, recover the scalar k. Easy to compute forward, believed infeasible to invert on a well-chosen curve. It is the one-way assumption all of elliptic-curve cryptography rests on.&quot; },
  { term: &quot;Scalar multiplication&quot;, definition: &quot;Repeated point addition, adding G to itself k times, written as k times G. Computed in about log k steps by double-and-add. It is the fast forward direction of the trapdoor.&quot; },
  { term: &quot;Cofactor&quot;, definition: &quot;The ratio of a curve&apos;s full group order to the prime order of the subgroup used for cryptography. P-256 has cofactor 1 (prime order); edwards25519 has cofactor 8, so low-order torsion points exist and must be handled.&quot; },
  { term: &quot;Invalid-curve attack&quot;, definition: &quot;Feeding an implementation a point not on the intended curve into formulas that ignore the coefficient b, so the arithmetic runs on a weaker curve and leaks the secret modulo small numbers, with the intended curve untouched.&quot; },
  { term: &quot;Small-subgroup attack&quot;, definition: &quot;Submitting a low-order element so the response reveals the secret modulo that small order. Repeated over coprime orders, the Chinese Remainder Theorem reassembles the full private key.&quot; },
  { term: &quot;Twist security&quot;, definition: &quot;A property of a curve whose quadratic twist also has near-prime order, so a hostile off-curve input still lands in a hard group. Invalid-curve attacks are defeated without an explicit on-curve check.&quot; },
  { term: &quot;Montgomery ladder&quot;, definition: &quot;A scalar-multiplication method whose sequence of field operations is identical for every secret bit, so it is constant-time by construction rather than by defensive coding.&quot; },
  { term: &quot;Clamping&quot;, definition: &quot;Forcing specific bits of an X25519 secret scalar so it is a multiple of the cofactor and a fixed length. It constrains your own secret and is emphatically not validation of an input point.&quot; },
  { term: &quot;Prime-order group (ristretto255)&quot;, definition: &quot;A prime-order group built in the encoding over cofactor-8 edwards25519, so decoding a byte string is itself the validation step and the cofactor failure class disappears at the type level (RFC 9496).&quot; }
]} questions={[
  { q: &quot;Why is ECDLP-hardness not the same as ECC-security?&quot;, a: &quot;A hard discrete log is necessary but not sufficient. Security is a property of the curve, the group, and the implementation together. Every deployed break exploited the implementation or the encoding, not the discrete log.&quot; },
  { q: &quot;What single mechanism explains the whole failure catalog?&quot;, a: &quot;The atom: a point you did not generate, used before it is validated, or a secret multiplied in observable time, turns your own scalar-multiplication routine into an oracle that leaks the key one small piece at a time.&quot; },
  { q: &quot;Why is clamping not point validation?&quot;, a: &quot;Clamping constrains your own secret scalar so a low-order input contributes nothing to your Diffie-Hellman product, but it neither validates nor canonicalizes an input point. A protocol that relies on point uniqueness needs an explicit prime-order subgroup check.&quot; },
  { q: &quot;Which curve should you use for which job?&quot;, a: &quot;X25519 for key agreement, Ed25519 for new signatures, P-256 only where FIPS compels it, secp256k1 only for blockchain, and ristretto255 for new prime-order protocols. Long-lived confidentiality gets the X25519 plus ML-KEM-768 hybrid.&quot; },
  { q: &quot;Why does even correctly implemented ECC have an expiration date?&quot;, a: &quot;For a well-chosen curve the classical security level is exactly the generic square-root bound, with no margin above it, and Shor&apos;s algorithm breaks the discrete log in polynomial time on a quantum computer. The answer is to wrap ECC in a post-quantum hybrid.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>elliptic-curve-cryptography</category><category>curve25519</category><category>p-256</category><category>ristretto255</category><category>invalid-curve-attack</category><category>constant-time</category><category>post-quantum-crypto</category><category>applied-cryptography</category><author>noreply@paragmali.com (Parag Mali)</author></item></channel></rss>