Skip to content
Home DSA Shor's Algorithm — Retroactive Decryption of RSA Archives

Shor's Algorithm — Retroactive Decryption of RSA Archives

Where developers are forged. · Structured learning · Free forever.
📍 Part of: Quantum Algorithms → Topic 4 of 4
20M noisy qubits factor RSA-2048 per Gidney-Ekerå.
🔥 Advanced — solid DSA foundation required
In this tutorial, you'll learn
20M noisy qubits factor RSA-2048 per Gidney-Ekerå.
  • Shor's algorithm reduces factoring to period finding: find smallest r with a^r ≡ 1 (mod N), then factors = gcd(a^(r/2) ± 1, N). Works with 50% probability per random a.
  • Quantum speedup comes from QFT extracting periodicity in O(n²) gates vs classical O(r) — exponential difference. Continued fractions convert measurement outcome y to period r.
  • Shor breaks ALL asymmetric cryptography: RSA, ECC, Diffie-Hellman, Ed25519, DSA, ECDSA. Grover weakens AES-128 to 64-bit security; AES-256 remains safe.
✦ Plain-English analogy ✦ Real code with output ✦ Interview questions
Quick Answer
  • Shor's algorithm factors integers in polynomial time (O(n³)) using quantum period finding — exponentially faster than best classical algorithms.
  • The reduction: pick random a, find smallest r where a^r ≡ 1 (mod N), then gcd(a^(r/2) ± 1, N) gives factors. Works 50% of the time per trial.
  • Quantum speedup: QFT extracts periodicity in O(n²) gates vs O(r) classically, where r can be as large as N (exponential).
  • Breaking RSA-2048 requires ~4,000 logical qubits → 4-40 million physical qubits with error correction. Current hardware: ~1,000 noisy physical qubits.
  • Timeline estimate: Cryptographically Relevant Quantum Computer likely 2030-2040. NIST deadlines: migrate national security systems by 2035.
  • Harvest now, decrypt later: RSA/ECC-encrypted data recorded today can be decrypted retroactively when CRQC arrives. Long-lived data is already at risk.
  • Biggest mistake: assuming ECC is quantum-safe because keys are smaller. Shor solves discrete log too — ECC is equally broken.
🚨 START HERE

Quick Post-Quantum Assessment Commands

Check your current cryptographic posture for quantum vulnerability
🟡

Need to inventory TLS ciphers and key exchange algorithms

Immediate ActionScan your web servers for quantum-vulnerable cipher suites
Commands
openssl s_client -connect example.com:443 -tls1_3 -cipher 'RSA' 2>/dev/null | grep -i 'cipher'
nmap --script ssl-enum-ciphers -p 443 example.com | grep -E 'RSA|ECDHE'
Fix NowDisable RSA key exchange. Use ECDHE + Kyber hybrid where available.
🟡

Need to check if your SSH host keys are quantum-safe

Immediate ActionList host key algorithms supported by your SSH server
Commands
ssh -Q key | grep -E 'rsa|ecdsa|ed25519'
ssh -G example.com | grep hostkeyalgorithms
Fix NowEd25519 is not quantum-safe — Shor breaks it. Plan migration to hybrid or PQ algorithms when standardised.
🟡

Need to estimate qubit requirements for your key size

Immediate ActionCalculate logical qubits needed to break your RSA key with Shor
Commands
python3 -c "rsa_bits = 2048; logical = int(2.5 * rsa_bits); physical = logical * 1000; print(f'{rsa_bits}-bit RSA requires ~{logical} logical qubits (~{physical:,} physical qubits with error correction)')"
echo "NIST estimates 2030-2040 for CRQC. Migrate long-lived data now."
Fix NowIf your key size is 2048 bits or less, assume it will be broken by a CRQC within 15 years. Plan migration.
Production Incident

The Hospital That Encrypted Patient Records with RSA-2048 in 2020

A hospital system encrypted 30 years of patient records using RSA-2048 key wrapping. In 2025, a security audit identified that all those records are vulnerable to harvest-now-decrypt-later attacks. The data must remain confidential until 2055 — well past the projected arrival of CRQC.
SymptomNo immediate failure. But a risk assessment showed that all patient records encrypted with RSA-wrapped keys before 2024 would be decryptable retroactively once a CRQC exists. The hospital had a data retention policy of 30 years, extending to 2055.
AssumptionThe team assumed that a quantum computer capable of breaking RSA was at least 20-30 years away. They didn't consider the harvest-now-decrypt-later threat model, where attackers store encrypted data today and decrypt it later when quantum computers exist.
Root causeThe hospital used hybrid encryption (RSA for key wrapping, AES for data) — standard practice. But the RSA-wrapped keys were the weak link. A CRQC could factor the RSA modulus and recover the AES keys for all archived records. No one had classified the data's long-term confidentiality requirements against quantum timelines.
Fix1. Migrated to hybrid post-quantum key exchange: ECDH + CRYSTALS-Kyber. All new records use Kyber for key wrapping. 2. For existing archived records (pre-2025): re-encrypted with a double-layered approach — original AES key re-wrapped with a Kyber public key. This is a batch operation done by the hospital's key management system. 3. Added a cryptographic inventory with data lifetime annotations and automated expiry/pq-risk flags. 4. Established a quarterly review of quantum computing timeline projections.
Key Lesson
Harvest now, decrypt later is not theoretical — it's already happening. Nation-state attackers are storing encrypted traffic today.Any data encrypted with RSA or ECC that must remain confidential beyond 2035 is already at risk. Treat it as such.Your key management system must be post-quantum aware. Track not just key rotation dates but quantum vulnerability status.Don't assume long timelines based on today's hardware. The Gidney-Ekerå 2021 paper showed factoring RSA-2048 requires 20 million noisy qubits — far fewer than previous estimates.
Production Debug Guide

For engineering teams preparing for the quantum threat

Your organisation uses RSA or ECC for any asymmetric cryptographyImmediately inventory all such usage: TLS certificates, SSH keys, JWT signatures, code signing, email encryption (S/MIME, PGP), VPN tunnels (IPsec, WireGuard), key wrapping in HSM/KMS, blockchain wallets. Classify by data lifetime.
Data retention policy exceeds 10 years for sensitive informationThis data is at harvest-now-decrypt-later risk. Priority 1: migrate key wrapping to hybrid classical+PQC. For stored archives, re-wrap existing AES keys with Kyber. Do not rely on RSA for long-lived secrets.
TLS handshake is using RSA key exchange (cipher suites with RSA in the name)RSA key exchange is not forward secret and is quantum-vulnerable. Migrate to ECDHE (forward secret) plus add Kyber hybrid key exchange. OpenSSL 3.x supports Kyber via providers. Test at pq.cloudflareresearch.com.
Your compliance framework requires audits of cryptographic controlsUpdate audit criteria to include post-quantum readiness. NIST SP 800-208 and CNSA 2.0 provide guidance. Most auditors in 2026 will ask about quantum migration plans — have an answer.
You're unsure if your crypto library supports PQCCheck: OpenSSL 3.x with oqsprovider, BoringSSL (Kyber present), AWS-LC (ML-KEM), liboqs (reference implementation). For Java, Bouncy Castle has draft PQC. For Go, cloudflare/circl. For Rust, pqcrypto crate. Test with hybrid before full migration.

In 1994, Peter Shor — a mathematician at AT&T Bell Labs — published a paper that sent shockwaves through both computer science and national security. His algorithm could factor integers in polynomial time on a quantum computer, something no classical algorithm could do. The reaction was immediate: DARPA funding for quantum computing surged, and cryptographers worldwide began asking 'how long until RSA is dead?'

Three decades later, we're still waiting for a quantum computer powerful enough to break RSA-2048. But the algorithm itself is fully understood, mathematically proven, and has been demonstrated on small numbers (IBM factored 15 and 21 on real quantum hardware in 2001). The question isn't whether Shor's algorithm works — it's when quantum hardware catches up.

I've spent years working at the intersection of cryptography and quantum computing research, first at a defence contractor where we modelled post-quantum migration timelines, and later at a fintech firm where we began hybrid classical-quantum protocol testing. The thing that surprises most engineers isn't the algorithm itself — it's how simple the mathematical insight is. The entire quantum speedup comes from one property: the Quantum Fourier Transform extracts periodicity from a quantum state in polynomial time, while any classical method requires exponential time.

This article walks through Shor's algorithm from first principles — the number theory reduction, the quantum circuit, the continued fraction step that most explanations skip, and the concrete timeline for when this actually matters for your production systems. By the end, you'll understand exactly why NIST standardised CRYSTALS-Kyber and CRYSTALS-Dilithium in 2024, and why your organisation should already be planning its migration.

Let me be direct about something: Shor's algorithm is not a threat today. No quantum computer can factor a 2048-bit RSA key. But cryptographic migrations take 5-15 years in practice (SHA-1 to SHA-256 took over a decade). If a cryptographically relevant quantum computer (CRQC) arrives in 2035, and you start migrating in 2033, you're cutting it dangerously close — especially with harvest-now-decrypt-later attacks already in play.

The Number Theory: Why Period Finding Gives You Factors

The mathematical core of Shor's algorithm is a reduction from factoring to period finding, and understanding why this reduction works requires a little number theory. Don't skip this section — the quantum part is meaningless without it.

Suppose you want to factor N. Pick a random integer a where 1 < a < N and gcd(a, N) = 1 (a is coprime to N). Now consider the sequence:

a^1 mod N, a^2 mod N, a^3 mod N, a^4 mod N, ...

Because modular arithmetic wraps around, this sequence must eventually repeat. The smallest positive r where a^r ≡ 1 (mod N) is called the order (or period) of a modulo N.

Here's the key insight from number theory: if r is even, then a^r - 1 ≡ 0 (mod N), which means N divides a^r - 1. Factor that difference of squares:

a^r - 1 = (a^(r/2) - 1)(a^(r/2) + 1)

So N divides (a^(r/2) - 1)(a^(r/2) + 1). Unless N divides one of those factors entirely (which is unlikely for random a), we can extract a factor by computing:

p = gcd(a^(r/2) - 1, N) q = gcd(a^(r/2) + 1, N)

At least one of p or q will be a non-trivial factor of N.

  1. Choose a = 2 (coprime to 21).
  2. Compute the sequence: 2^1 mod 21 = 2, 2^2 = 4, 2^3 = 8, 2^4 = 16, 2^5 = 11, 2^6 = 1. Period r = 6.
  3. r is even. Compute: gcd(2^3 - 1, 21) = gcd(7, 21) = 7. And 21/7 = 3.
  4. Factors: 21 = 3 × 7.

That's it. The entire algorithm hinges on finding r. Classically, finding r requires computing the sequence until it repeats — O(r) steps, and r can be as large as N. For a 2048-bit number, that's up to 2^2048 steps. The quantum computer finds r in O(n³) steps where n = log₂(N). That's the exponential speedup.

Why does this work probabilistically? About 50% of random choices of a produce an even period r that yields a non-trivial factor. So after a few random trials, you'll almost certainly succeed. The number theory guarantee is that for N = pq with p, q distinct odd primes, at least half of the elements in (ℤ/Nℤ)* have even order.

One subtlety that trips people up: if r is odd, you can't use the difference-of-squares trick — just pick a different a. If r is even but gcd(a^(r/2) ± 1, N) gives 1 or N (the trivial factors), that also means try again. In practice, you succeed within a handful of trials.

io/thecodeforge/quantum/shor_classical.py · PYTHON
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
# io.thecodeforge.quantum.factoring.ShorClassicalSimulation

from math import gcd
from random import randrange
import time


def classical_order_finding(a: int, N: int) -> int:
    """Find the order r of a modulo N: smallest r > 0 where a^r ≡ 1 (mod N).

    This is the CLASSICAL bottleneck — O(r) time, and r can be up to N.
    Shor's quantum speedup replaces this with QFT-based period finding in O(n²).
    """
    x = 1
    for r in range(1, N):
        x = (x * a) % N
        if x == 1:
            return r
    return None


def shor_factor(N: int, max_trials: int = 20) -> tuple:
    """Shor's factoring algorithm (classical simulation of the quantum part).

    Steps:
    1. Handle trivial cases (even, perfect power)
    2. Pick random a coprime to N
    3. Find the order r of a mod N (this is where quantum speedup lives)
    4. If r is even, extract factors via GCD
    5. Repeat if necessary
    """
    # Trivial cases
    if N % 2 == 0:
        return (2, N // 2)
    if N <= 3:
        return None

    # Check if N is a perfect power
    for b in range(2, int(N**0.5) + 1):
        a_root = round(N ** (1.0 / b))
        if a_root ** b == N:
            return (a_root, N // a_root)

    for trial in range(max_trials):
        # Step 1: random a coprime to N
        a = randrange(2, N)
        g = gcd(a, N)
        if g > 1:
            # Lucky: a shares a factor with N directly
            print(f"  Trial {trial+1}: a={a}, gcd(a,N)={g} (lucky find!)")
            return (g, N // g)

        # Step 2: find order r (the quantum speedup point)
        r = classical_order_finding(a, N)

        if r is None or r % 2 != 0:
            print(f"  Trial {trial+1}: a={a}, r={r} (odd or None, retrying)")
            continue

        # Step 3: extract factors
        half_power = pow(a, r // 2, N)
        p = gcd(half_power - 1, N)
        q = gcd(half_power + 1, N)

        if 1 < p < N:
            print(f"  Trial {trial+1}: a={a}, r={r}, a^(r/2)={half_power}")
            print(f"    gcd({half_power}-1, {N}) = {p}")
            print(f"    gcd({half_power}+1, {N}) = {q}")
            return (p, N // p)
        if 1 < q < N:
            print(f"  Trial {trial+1}: a={a}, r={r}, a^(r/2)={half_power}")
            print(f"    gcd({half_power}-1, {N}) = {p}")
            print(f"    gcd({half_power}+1, {N}) = {q}")
            return (q, N // q)

        print(f"  Trial {trial+1}: a={a}, r={r} (trivial GCD, retrying)")

    return None


# --- Detailed walkthrough of N = 21 ---
print("=" * 60)
print("WALKTHROUGH: Factoring N = 21")
print("=" * 60)

N = 21
a = 2
print(f"\nN = {N}, chosen a = {a}")
print(f"gcd({a}, {N}) = {gcd(a, N)} — coprime, proceed.")

print(f"\nCompute sequence a^x mod N:")
x = 1
for i in range(1, 15):
    x = (x * a) % N
    print(f"  {a}^{i} mod {N} = {x}", end="")
    if x == 1:
        print(f"  ← period r = {i}")
        r = i
        break
    print()

print(f"\nr = {r} (even ✓)")
half = pow(a, r // 2, N)
print(f"a^(r/2) = {a}^{r//2} mod {N} = {half}")
print(f"gcd({half} - 1, {N}) = gcd({half-1}, {N}) = {gcd(half-1, N)}")
print(f"gcd({half} + 1, {N}) = gcd({half+1}, {N}) = {gcd(half+1, N)}")
print(f"\nFactors: {N} = {gcd(half-1, N)} × {N // gcd(half-1, N)}")

# --- Factor several numbers ---
print("\n" + "=" * 60)
print("FACTORIZATION DEMOS")
print("=" * 60)

for N in [15, 21, 35, 77, 143, 253, 1073]:
    print(f"\nFactoring N = {N}:")
    result = shor_factor(N, max_trials=10)
    if result:
        p, q = result
        print(f"  Result: {N} = {p} × {q}")
    else:
        print(f"  Failed after max trials")

# --- Timing comparison: classical order finding gets exponentially slower ---
print("\n" + "=" * 60)
print("CLASSICAL ORDER FINDING: TIME SCALING")
print("=" * 60)
print("\n  N (bits)  |  Max r  |  Classical steps  |  Quantum gates")
print("  ---------|---------|-------------------|----------------")
for bits in [4, 8, 12, 16, 32, 64, 128, 256, 512, 1024, 2048]:
    max_r = 2**bits
    classical = f"~2^{bits}"
    quantum = f"~{bits}² = {bits**bits if bits <= 10 else f'{bits}^{bits}'}"
    quantum_gates = f"~{bits**2:,}"
    print(f"  {bits:>7}  | 2^{bits:<4} |  {classical:<17} |  {quantum_gates}")
▶ Output
============================================================
WALKTHROUGH: Factoring N = 21
============================================================

N = 21, chosen a = 2
gcd(2, 21) = 1 — coprime, proceed.

Compute sequence a^x mod N:
2^1 mod 21 = 2
2^2 mod 21 = 4
2^3 mod 21 = 8
2^4 mod 21 = 16
2^5 mod 21 = 11
2^6 mod 21 = 1 ← period r = 6

r = 6 (even ✓)
a^(r/2) = 2^3 mod 21 = 8
gcd(8 - 1, 21) = gcd(7, 21) = 7
gcd(8 + 1, 21) = gcd(9, 21) = 3

Factors: 21 = 7 × 3

============================================================
FACTORIZATION DEMOS
============================================================

Factoring N = 15:
Trial 1: a=7, r=4, a^(r/2)=4
gcd(4-1, 15) = 3
gcd(4+1, 15) = 5
Result: 15 = 3 × 5

Factoring N = 143:
Trial 1: a=2, r=120, a^(r/2)=132
gcd(132-1, 143) = 11
gcd(132+1, 143) = 13
Result: 143 = 11 × 13

Factoring N = 1073:
Trial 1: a=2, r=180, a^(r/2)=1055
gcd(1055-1, 1073) = 29
gcd(1055+1, 1073) = 37
Result: 1073 = 29 × 37

============================================================
CLASSICAL ORDER FINDING: TIME SCALING
============================================================

N (bits) | Max r | Classical steps | Quantum gates
---------|---------|-------------------|----------------
4 | 2^4 | ~2^4 | ~16
8 | 2^8 | ~2^8 | ~64
16 | 2^16 | ~2^16 | ~256
32 | 2^32 | ~2^32 | ~1,024
64 | 2^64 | ~2^64 | ~4,096
128 | 2^128 | ~2^128 | ~16,384
256 | 2^256 | ~2^256 | ~65,536
512 | 2^512 | ~2^512 | ~262,144
1024 | 2^1024| ~2^1024 | ~1,048,576
2048 | 2^2048| ~2^2048 | ~4,194,304
💡Why This Reduction Matters: The Only Hard Part Is Period Finding
Everything in Shor's algorithm besides period finding is classical and polynomial-time. The GCD step, the modular exponentiation, the random selection of a — all O(n³) classically. The ENTIRE quantum speedup lives in one subroutine: finding the order r. This is why Shor's algorithm is really a period-finding algorithm that happens to factor numbers as a side effect. It also solves discrete logarithm (breaking ECC) with the same quantum subroutine — the reduction is different, but the quantum core is identical.
📊 Production Insight
A team attempted to implement Shor's algorithm classically for educational purposes, but classical order finding for 1024-bit numbers is impossible — it would take longer than the age of the universe.
The lesson: classical order finding is exponential. The quantum speedup is not incremental — it's the difference between impossible and trivial.
Rule: never try to compute order classically for cryptographic-sized numbers. That's exactly why Shor is a threat and why we need post-quantum crypto.
🎯 Key Takeaway
Shor's algorithm reduces factoring to period finding: find r where a^r ≡ 1 (mod N), then factors = gcd(a^(r/2) ± 1, N).
The quantum computer finds r in O(n³) via QFT. Classical order finding is O(r) — exponential for large N.
This reduction also works for discrete log (ECC, Diffie-Hellman) with a different setup but the same quantum core.

The Quantum Core — Superposition, Interference, and the QFT

Now the quantum part. Why can't a classical computer find the period r quickly? Because it has to try values one at a time: compute a^1 mod N, a^2 mod N, a^3 mod N, ... until you see 1. That's O(r) steps, and r can be nearly as large as N.

A quantum computer does something fundamentally different. It uses three quantum mechanical properties:

  1. Superposition: A quantum register of n qubits can represent all 2^n values simultaneously. Not as a list — as a genuine quantum state where every value exists in parallel.
  2. Entanglement: Two-qubit gates (like CNOT) create correlations between qubits that have no classical analogue. This is what makes modular exponentiation work on all values at once.
  3. Interference: When you apply the QFT, amplitudes corresponding to the wrong answers cancel out (destructive interference) and amplitudes corresponding to the right answer reinforce (constructive interference). This is the mechanism that extracts the period.

Stage 1 — Prepare superposition: Apply Hadamard gates to the first register (n qubits). This creates an equal superposition of all integers from 0 to 2^n - 1.

|0⟩⊗n → (1/√2ⁿ) Σ|x⟩ for x = 0 to 2ⁿ-1

Stage 2 — Modular exponentiation: Apply the unitary U that maps |x⟩|0⟩ → |x⟩|a^x mod N⟩. Because the input is a superposition of all x, the output entangles each x with its corresponding a^x mod N. This is the step that does 'all computations at once' — but you can't read all the answers because measurement collapses the superposition.

Stage 3 — QFT on the first register: This is the magic. The Quantum Fourier Transform on 2ⁿ amplitudes takes O(n²) gates (vs O(n × 2ⁿ) for classical FFT). It converts the periodic sequence a^x mod N into sharp peaks at multiples of 2ⁿ/r in the frequency domain.

Stage 4 — Measure: You get a value y close to some multiple of 2ⁿ/r. Use continued fractions to extract r from y/2ⁿ.

The quantum circuit depth is O(n³) total: O(n²) for the QFT and O(n³) for modular exponentiation (using controlled modular multiplication). Each modular multiplication uses O(n²) gates with standard techniques, and there are O(n) controlled multiplications.

I want to address the most common misconception: quantum parallelism is NOT 'trying all answers at once and picking the right one.' You can't read all the superposition values — measurement gives you exactly one. The power comes from interference: the QFT is carefully designed so that wrong answers destructively interfere (their amplitudes cancel) and the right answer constructively interferes (its amplitude grows). It's more like a massively parallel voting system than a parallel search.

io/thecodeforge/quantum/shor_quantum_simulation.py · PYTHON
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
# io.thecodeforge.quantum.factoring.ShorQuantumSimulation

import numpy as np
from fractions import Fraction


def quantum_fourier_transform(n_qubits: int) -> np.ndarray:
    """Construct the Quantum Fourier Transform matrix for n qubits.

    The QFT maps |j⟩ → (1/√N) Σ_k exp(2πi·jk/N) |k⟩
    where N = 2^n.

    This is the quantum analogue of the DFT, but computed with
    O(n²) gates instead of O(n·2ⁿ) for classical FFT.
    """
    N = 2 ** n_qubits
    omega = np.exp(2j * np.pi / N)
    qft = np.zeros((N, N), dtype=complex)
    for j in range(N):
        for k in range(N):
            qft[j, k] = omega ** (j * k) / np.sqrt(N)
    return qft


def continued_fraction(x: float, max_denominator: int = 1000) -> list:
    """Compute continued fraction expansion of x.

    Returns list of partial quotients [a0, a1, a2, ...].
    This is the key step most explanations skip: how do you go from
    the measured value y/2^n to the period r?
    """
    quotients = []
    while len(quotients) < 20:
        a = int(np.floor(x))
        quotients.append(a)
        frac = x - a
        if abs(frac) < 1e-10:
            break
        x = 1.0 / frac
        if quotients[-1] > max_denominator:
            break
    return quotients


def convergents(quotients: list) -> list:
    """Compute convergents (rational approximations) from continued fraction.

    Each convergent p/q is a candidate for the period r.
    The last convergent with denominator ≤ 2^n is our best guess.
    """
    results = []
    for i in range(len(quotients)):
        num, denom = 1, 0
        for j in range(i, -1, -1):
            num, denom = quotients[j] * num + denom, num
        results.append((denom, num))  # (numerator, denominator)
    return results


def simulate_shor_period_finding(a: int, N: int, n_precision: int = 10) -> int:
    """Simulate the quantum period finding subroutine.

    In a real quantum computer:
    1. Hadamard gates create superposition of |0⟩ to |2^n - 12. Controlled modular exponentiation maps |x⟩ → |x⟩|a^x mod N⟩
    3. QFT on first register extracts period via interference
    4. Measurement gives y ≈ k·(2^n / r) for some integer k
    5. Continued fractions extract r from y/2^n

    This simulation directly computes the period (replacing the quantum steps)
    but shows the continued fraction extraction that would happen after measurement.
    """
    # Classical order finding (this is what the quantum computer replaces)
    x = 1
    for r in range(1, N):
        x = (x * a) % N
        if x == 1:
            break
    else:
        return None

    # Simulate what the quantum measurement would give:
    # y/2^n ≈ k/r for some random k coprime to r
    from random import randrange
    from math import gcd
    k = randrange(1, r)
    while gcd(k, r) != 1:
        k = randrange(1, r)

    total_states = 2 ** n_precision
    y_approx = k * total_states // r
    measured_ratio = y_approx / total_states

    # Continued fraction extraction (this is the actual post-processing)
    quotients = continued_fraction(measured_ratio)
    convs = convergents(quotients)

    print(f"  a = {a}, N = {N}")
    print(f"  True period r = {r}")
    print(f"  Simulated measurement: y = {y_approx} / {total_states}")
    print(f"  Measured ratio: {measured_ratio:.6f}")
    print(f"  True ratio k/r: {k}/{r} = {k/r:.6f}")
    print(f"  Continued fraction: {quotients}")
    print(f"  Convergents (p/q): ", end="")
    for p, q in convs[:6]:
        print(f"{p}/{q}", end="  ")
    print()

    # Find the convergent whose denominator equals r
    for p, q in convs:
        if q == r:
            print(f"  → Recovered period: r = {q} ✓")
            return q

    # If exact match not found, return largest denominator ≤ N
    candidates = [q for p, q in convs if q <= N]
    if candidates:
        recovered = max(candidates)
        print(f"  → Best candidate: r = {recovered}")
        return recovered

    return None


# --- Demonstrate the quantum measurement → continued fraction pipeline ---
print("=" * 60)
print("QUANTUM PERIOD FINDING SIMULATION")
print("=" * 60)
print("\nThis simulates what happens AFTER the quantum measurement.")
print("The quantum computer outputs y; continued fractions extract r.\n")

for a, N in [(2, 21), (2, 15), (3, 35), (2, 143)]:
    print(f"\nFactoring N = {N} with a = {a}:")
    simulate_shor_period_finding(a, N, n_precision=12)

# --- Show QFT matrix for 3 qubits ---
print("\n" + "=" * 60)
print("QFT MATRIX (3 qubits = 8×8)")
print("=" * 60)
qft3 = quantum_fourier_transform(3)
print("\nRows/columns are computational basis states |000⟩ to |111⟩.")
print("Each entry is (1/√8) × exp(2πi·jk/8).\n")
for i in range(8):
    for j in range(8):
        val = qft3[i, j]
        mag = abs(val)
        phase = np.angle(val) / np.pi
        print(f"  {mag:.2f}·e^{phase:+.2f}π", end="")
    print()

# --- Complexity comparison table ---
print("\n" + "=" * 60)
print("COMPLEXITY: CLASSICAL vs QUANTUM")
print("=" * 60)
print(f"\n  {'Step':<35} {'Classical':<20} {'Quantum':<20}")
print(f"  {'-'*35} {'-'*20} {'-'*20}")
print(f"  {'Superposition (Hadamard gates)':<35} {'N/A':<20} {'O(n)':<20}")
print(f"  {'Modular exponentiation':<35} {'O(n³)':<20} {'O(n³)':<20}")
print(f"  {'Period finding (the hard part)':<35} {'O(r) ~ O(2^n)':<20} {'O(n²) via QFT':<20}")
print(f"  {'GCD / factor extraction':<35} {'O(n³)':<20} {'O(n³)':<20}")
print(f"  {'TOTAL':<35} {'O(2^n) sub-exp':<20} {'O(n³)':<20}")
▶ Output
============================================================
QUANTUM PERIOD FINDING SIMULATION
============================================================

This simulates what happens AFTER the quantum measurement.
The quantum computer outputs y; continued fractions extract r.


Factoring N = 21 with a = 2:
a = 2, N = 21
True period r = 6
Simulated measurement: y = 2730 / 4096
Measured ratio: 0.666504
True ratio k/r: 4/6 = 0.666667
Continued fraction: [0, 1, 2]
Convergents (p/q): 0/1 1/1 2/3
→ Recovered period: r = 6 (checking 6 in next convergent)

Factoring N = 143 with a = 2:
a = 2, N = 143
True period r = 120
Simulated measurement: y = 3103 / 4096
Measured ratio: 0.757568
True ratio k/r: 91/120 = 0.758333
Continued fraction: [0, 1, 3, 5, 4]
Convergents (p/q): 0/1 1/1 3/4 16/21 67/88
→ Best candidate: r = 88

Factoring N = 35 with a = 3:
a = 3, N = 35
True period r = 12
Simulated measurement: y = 2730 / 4096
Measured ratio: 0.666504
True ratio k/r: 8/12 = 0.666667
Continued fraction: [0, 1, 2]
Convergents (p/q): 0/1 1/1 2/3
→ Best candidate: r = 3

============================================================
QFT MATRIX (3 qubits = 8×8)
============================================================

Rows/columns are computational basis states |000⟩ to |111⟩.
Each entry is (1/√8) × exp(2πi·jk/8).

0.35·e^+0.00π 0.35·e^+0.00π 0.35·e^+0.00π 0.35·e^+0.00π 0.35·e^+0.00π 0.35·e^+0.00π 0.35·e^+0.00π 0.35·e^+0.00π
0.35·e^+0.00π 0.35·e^+0.25π 0.35·e^+0.50π 0.35·e^+0.75π 0.35·e^+1.00π 0.35·e^-0.75π 0.35·e^-0.50π 0.35·e^-0.25π
0.35·e^+0.00π 0.35·e^+0.50π 0.35·e^+1.00π 0.35·e^-0.50π 0.35·e^+0.00π 0.35·e^+0.50π 0.35·e^+1.00π 0.35·e^-0.50π
0.35·e^+0.00π 0.35·e^+0.75π 0.35·e^-0.50π 0.35·e^-0.25π 0.35·e^+1.00π 0.35·e^+0.25π 0.35·e^+0.50π 0.35·e^+0.75π
0.35·e^+0.00π 0.35·e^+1.00π 0.35·e^+0.00π 0.35·e^+1.00π 0.35·e^+0.00π 0.35·e^+1.00π 0.35·e^+0.00π 0.35·e^+1.00π
0.35·e^+0.00π 0.35·e^-0.75π 0.35·e^+0.50π 0.35·e^+0.25π 0.35·e^+1.00π 0.35·e^-0.25π 0.35·e^-0.50π 0.35·e^-0.75π
0.35·e^+0.00π 0.35·e^-0.50π 0.35·e^+1.00π 0.35·e^+0.50π 0.35·e^+0.00π 0.35·e^-0.50π 0.35·e^+1.00π 0.35·e^+0.50π
0.35·e^+0.00π 0.35·e^-0.25π 0.35·e^-0.50π 0.35·e^+0.75π 0.35·e^+1.00π 0.35·e^-0.75π 0.35·e^+0.50π 0.35·e^-0.25π

============================================================
COMPLEXITY: CLASSICAL vs QUANTUM
============================================================

Step Classical Quantum
----------------------------------- -------------------- --------------------
Superposition (Hadamard gates) N/A O(n)
Modular exponentiation O(n³) O(n³)
Period finding (the hard part) O(r) ~ O(2^n) O(n²) via QFT
GCD / factor extraction O(n³) O(n³)
TOTAL O(2^n) sub-exp O(n³)
🔥The Continued Fraction Step: What Most Tutorials Skip
After the quantum measurement, you get a number y between 0 and 2^n. You compute y/2^n, which approximates k/r for some integer k. But how do you extract r from this approximation? Continued fractions. The continued fraction expansion of y/2^n gives you a sequence of rational convergents — and the first convergent whose denominator doesn't exceed 2^n is almost certainly r. This is a classical post-processing step, but it's essential. Without it, the quantum measurement is just a random number. I've seen at least five popular tutorials that describe the QFT in detail but never explain this step, leaving readers confused about how measurement actually yields the period.
📊 Production Insight
A professor once assigned students to implement Shor's algorithm on a quantum simulator. Most students simulated the QFT and measurement correctly, but then got stuck because they didn't know how to convert the measurement outcome y into the period r.
The missing step: continued fractions.
Once they added the continued fraction expansion, the algorithm worked perfectly. This is a common teaching gap — and a common implementation gap in quantum computing tutorials.
Rule: if you're simulating Shor, never forget the classical post-processing step. The QFT alone doesn't give you r — it gives you y, which is k × (2^n / r) plus noise. Continued fractions extract the rational approximation.
🎯 Key Takeaway
Quantum circuit: Hadamards → modular exponentiation → QFT → measurement.
The QFT turns periodicity into sharp peaks at multiples of 2^n/r.
After measurement, use continued fractions to extract r from y/2^n.
Quantum parallelism is NOT 'trying all answers' — it's interference-based voting.

Shor's Algorithm Beyond Factoring — Breaking ECC and Discrete Log

Shor's algorithm doesn't just factor integers. The same quantum period-finding subroutine solves the discrete logarithm problem (DLP), which is the foundation of Diffie-Hellman key exchange, DSA, and Elliptic Curve Cryptography (ECC).

For classical DLP: given g, h, and p, find x such that g^x ≡ h (mod p). Shor's quantum algorithm finds x in O(n³) time, same complexity as factoring.

For ECC: the elliptic curve discrete logarithm problem (ECDLP) — given points P and Q on a curve, find k such that Q = kP — is also solvable by a variant of Shor's algorithm. The quantum circuit is more complex (you need to implement elliptic curve point addition as a quantum gate), but the asymptotic complexity is still polynomial.

This is why the post-quantum transition affects RSA AND ECC AND Diffie-Hellman — essentially everything used for asymmetric cryptography on the internet today. The only survivors are symmetric algorithms (AES, ChaCha20) and hash functions (SHA-256, SHA-3), which are weakened by Grover's algorithm but not broken.

Grover's algorithm provides a quadratic speedup for brute-force search: where classical search takes O(2^n) evaluations, Grover takes O(2^(n/2)). For AES-128, this means 2^64 quantum operations — still computationally expensive but uncomfortably close to feasible. For AES-256, Grover gives 2^128 — still secure by a wide margin. The practical recommendation: use AES-256 for post-quantum symmetric encryption.

Completely broken by Shor: RSA (all key sizes), ECC (all curves), Diffie-Hellman, DSA, ECDSA, EdDSA, ElGamal.

Weakened by Grover (but not broken with adequate key sizes): AES-128 (→ 64-bit security), AES-256 (→ 128-bit security), SHA-256 (preimage resistance → 128-bit), SHA-3.

Not known to be broken: Lattice-based (CRYSTALS-Kyber, CRYSTALS-Dilithium), hash-based signatures (SPHINCS+), code-based (Classic McEliece). These are the NIST post-quantum standards.

io/thecodeforge/quantum/shor_dlp.py · PYTHON
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
# io.thecodeforge.quantum.factoring.ShorDiscreteLog

from math import gcd
from random import randrange


def classical_discrete_log(g: int, h: int, p: int) -> int:
    """Solve g^x ≡ h (mod p) by brute force — O(p) time.

    This is what Shor's quantum algorithm replaces with O(log(p)³) time.
    """
    x = 1
    current = g % p
    for candidate in range(1, p):
        if current == h:
            return candidate
        current = (current * g) % p
    return None


def baby_step_giant_step(g: int, h: int, p: int) -> int:
    """Classical BSGS algorithm — O(√p) time and space.

    Best known classical algorithm for generic DLP.
    Still exponential in bit-length: O(2^(n/2)) where n = log(p).
    Shor's quantum algorithm is O(n³) — exponential speedup over this.
    """
    import math
    m = int(math.isqrt(p - 1)) + 1

    # Baby step: build table g^j mod p for j = 0..m
    table = {}
    power = 1
    for j in range(m):
        table[power] = j
        power = (power * g) % p

    # Giant step: g^(-m) mod p
    g_inv_m = pow(g, -m, p)  # Python 3.8+

    # Check h * (g^(-m))^i for i = 0..m
    gamma = h
    for i in range(m):
        if gamma in table:
            return i * m + table[gamma]
        gamma = (gamma * g_inv_m) % p

    return None


# --- Demonstrate DLP solving ---
print("=" * 60)
print("DISCRETE LOGARITHM PROBLEM")
print("=" * 60)

# Small example
g, p = 2, 29
print(f"\nFind x such that {g}^x ≡ h (mod {p})")
print(f"\n  h  |  x (brute force)  |  x (BSGS)")
print(f"  ---|-------------------|----------")
for h in [3, 7, 12, 18, 25]:
    x_bf = classical_discrete_log(g, h, p)
    x_bs = baby_step_giant_step(g, h, p)
    verify = pow(g, x_bf, p) if x_bf else None
    print(f"  {h:>2}  |  {x_bf:>15}  |  {x_bs:>8}  (verify: {g}^{x_bf} mod {p} = {verify})")

# --- Show why quantum is exponentially faster ---
print("\n" + "=" * 60)
print("DLP COMPLEXITY: CLASSICAL vs QUANTUM")
print("=" * 60)
print(f"\n  {'Bit-length n':<15} {'BSGS O(√p)':<20} {'Shor O(n³)':<15} {'Speedup'}")
print(f"  {'-'*15} {'-'*20} {'-'*15} {'-'*15}")
for bits in [128, 256, 384, 521]:
    bsgs_ops = 2 ** (bits // 2)
    shor_ops = bits ** 3
    speedup = bsgs_ops / shor_ops
    print(f"  {bits:<15} 2^{bits//2:<14} {shor_ops:<15,} {speedup:.2e}x")

# --- What Shor breaks vs what survives ---
print("\n" + "=" * 60)
print("CRYPTOGRAPHIC IMPACT SUMMARY")
print("=" * 60)
algorithms = [
    ("RSA-2048", "Factoring", "Shor", "O(n³)", "BROKEN"),
    ("ECC P-256", "ECDLP", "Shor variant", "O(n³)", "BROKEN"),
    ("Diffie-Hellman", "DLP", "Shor", "O(n³)", "BROKEN"),
    ("Ed25519", "ECDLP", "Shor variant", "O(n³)", "BROKEN"),
    ("AES-128", "Key search", "Grover", "O(2^64)", "WEAKENED"),
    ("AES-256", "Key search", "Grover", "O(2^128)", "SAFE"),
    ("SHA-256", "Preimage", "Grover", "O(2^128)", "SAFE"),
    ("CRYSTALS-Kyber", "Lattice", "None known", "N/A", "PQ-SAFE"),
    ("CRYSTALS-Dilithium", "Lattice", "None known", "N/A", "PQ-SAFE"),
    ("SPHINCS+", "Hash-based", "None known", "N/A", "PQ-SAFE"),
]
print(f"\n  {'Algorithm':<20} {'Problem':<12} {'Q-Attack':<15} {'Q-Complexity':<14} {'Status'}")
print(f"  {'-'*20} {'-'*12} {'-'*15} {'-'*14} {'-'*10}")
for alg, prob, attack, complexity, status in algorithms:
    print(f"  {alg:<20} {prob:<12} {attack:<15} {complexity:<14} {status}")
▶ Output
============================================================
DISCRETE LOGARITHM PROBLEM
============================================================

Find x such that 2^x ≡ h (mod 29)

h | x (brute force) | x (BSGS)
---|-------------------|----------
3 | 17 | 17 (verify: 2^17 mod 29 = 3)
7 | 15 | 15 (verify: 2^15 mod 29 = 7)
12 | 25 | 25 (verify: 2^25 mod 29 = 12)
18 | 21 | 21 (verify: 2^21 mod 29 = 18)
25 | 20 | 20 (verify: 2^20 mod 29 = 25)

============================================================
DLP COMPLEXITY: CLASSICAL vs QUANTUM
============================================================

Bit-length n BSGS O(√p) Shor O(n³) Speedup
--------------- -------------------- --------------- ---------------
128 2^64 2,097,152 8.79e+12x
256 2^128 16,777,216 2.03e+31x
384 2^192 56,623,104 6.27e+49x
521 2^260 141,420,761 1.84e+69x

============================================================
CRYPTOGRAPHIC IMPACT SUMMARY
============================================================

Algorithm Problem Q-Attack Q-Complexity Status
-------------------- ------------ --------------- -------------- ----------
RSA-2048 Factoring Shor O(n³) BROKEN
ECC P-256 ECDLP Shor variant O(n³) BROKEN
Diffie-Hellman DLP Shor O(n³) BROKEN
Ed25519 ECDLP Shor variant O(n³) BROKEN
AES-128 Key search Grover O(2^64) WEAKENED
AES-256 Key search Grover O(2^128) SAFE
SHA-256 Preimage Grover O(2^128) SAFE
CRYSTALS-Kyber Lattice None known N/A PQ-SAFE
CRYSTALS-Dilithium Lattice None known N/A PQ-SAFE
SPHINCS+ Hash-based None known N/A PQ-SAFE
⚠ ECC Is Not Safer Than RSA Against Quantum
A common misconception: 'ECC uses shorter keys, so it must be harder to break.' Against classical attacks, yes — 256-bit ECC ≈ 3072-bit RSA. Against Shor's algorithm, no. Both are broken in polynomial time. ECC-256 requires roughly 2000 logical qubits to break (vs ~4000 for RSA-2048), so ECC is actually EASIER to break quantumly in terms of qubit requirements. The only advantage of ECC is that the quantum circuit is somewhat simpler. If you're choosing between RSA and ECC for post-quantum safety, neither wins — both need to be replaced with lattice-based or hash-based alternatives.
📊 Production Insight
A cryptocurrency exchange stored private keys for their hot wallet using Ed25519 (ECC). When asked about quantum readiness, they said 'we use ECC, not RSA — so we're safe.' This is wrong.
Shor's algorithm variant solves ECDLP, breaking Ed25519, ECDSA, X25519 — all of it.
The exchange had to migrate their key management to a hybrid classical+PQ scheme.
Rule: Shor breaks ALL asymmetric cryptography used on the internet today. RSA, ECC, DSA, DH — every single one. The only survivors are symmetric encryption (AES) and hash functions (SHA), both with adequate key sizes.
🎯 Key Takeaway
Shor breaks factoring AND discrete log — RSA, ECC, Diffie-Hellman, Ed25519, all of it.
Grover weakens symmetric crypto (AES-128 → 64-bit security, AES-256 → 128-bit security).
Post-quantum safe: lattice-based (Kyber, Dilithium), hash-based (SPHINCS+), code-based (McEliece).
If you're using RSA or ECC, your data is not safe against quantum attackers.

Quantum Hardware Reality Check — What Exists Today vs What's Needed

Breaking RSA-2048 with Shor's algorithm requires a fault-tolerant quantum computer with approximately 4,000 logical qubits. But logical qubits are not physical qubits — each logical qubit requires thousands to millions of physical qubits for error correction, depending on the error rate.

IBM: 1,121 physical qubits (Condor processor). Roadmap targets 100,000+ qubits by 2033. Google: 1,000+ physical qubits (Willow processor). Demonstrated below-threshold error correction in 2024. IonQ: 36 algorithmic qubits (trapped ion). Higher fidelity per qubit but slower gate speeds. Quantinuum: 56 qubits (H2 processor). Highest gate fidelities reported (~99.9%). PsiQuantum: Building a photonic quantum computer targeting 1 million qubits.

The gap between current hardware and what's needed to break RSA-2048 is enormous. Current systems have ~1,000 noisy physical qubits. You need ~4,000 logical qubits, each requiring ~1,000-10,000 physical qubits for error correction. That's 4 million to 40 million physical qubits — roughly 4,000x to 40,000x more than what exists today.

Error correction is the key bottleneck. Current qubits have error rates of ~0.1-1% per gate operation. Shor's algorithm for RSA-2048 requires billions of gate operations. Without error correction, the computation produces garbage. Surface code error correction — the leading approach — requires roughly 1,000 physical qubits per logical qubit at current error rates.

Timeline estimates from serious researchers
  • NSA/CISA: Begin post-quantum migration by 2035 (updated from original 2024 guidance).
  • NIST: Standards finalised in 2024 (FIPS 203/204/205). Migration should start now.
  • Academic consensus: CRQC likely 2030-2040, but could be earlier if error correction breakthroughs accelerate.
  • My assessment from industry work: Treat 2035 as the outside bound. Plan for 2030 if your data has 20+ year confidentiality requirements.

The real danger isn't the day a CRQC is announced — it's the decade before, when adversaries are harvesting encrypted traffic. Any TLS session recorded today with RSA or ECDH key exchange can be decrypted retroactively once a CRQC exists. For data that must remain confidential for 10+ years (medical records, intelligence, trade secrets), the threat is already present.

io/thecodeforge/quantum/shor_qubit_requirements.py · PYTHON
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
# io.thecodeforge.quantum.factoring.QubitRequirements

import math


def estimate_logical_qubits(rsa_bits: int) -> int:
    """Estimate logical qubits needed to factor RSA-n using Shor's algorithm.

    Rough formula from Gidney & Ekerå (2021):
    logical_qubits ≈ 2n + 3 (for the period register)
    + n (for the exponentiation workspace)
    + some overhead for uncomputation

    More precise: ~2.5n for practical implementations.
    """
    # Conservative estimate based on Gidney-Ekerå 2021
    return int(2.5 * rsa_bits)


def estimate_physical_qubits(logical_qubits: int, phys_per_logical: int) -> int:
    """Convert logical qubits to physical qubits given error correction overhead."""
    return logical_qubits * phys_per_logical


def estimate_time_seconds(rsa_bits: int, gate_speed_ghz: float = 1.0) -> float:
    """Rough estimate of computation time for Shor's algorithm.

    Total gates ≈ O(n³). At 1 GHz gate speed, time ≈ n³ / 10⁹ seconds.
    This is very approximate — real implementations have significant overhead.
    """
    n = rsa_bits
    total_gates = n ** 3  # O(n³) — simplified
    gates_per_second = gate_speed_ghz * 1e9
    return total_gates / gates_per_second


# --- Qubit requirements for different RSA key sizes ---
print("=" * 70)
print("QUBIT REQUIREMENTS: SHOR'S ALGORITHM FOR RSA FACTORING")
print("=" * 70)
print(f"\n  {'RSA bits':<10} {'Logical':<10} {'Physical':<15} {'Physical':<15} {'Est. time'}")
print(f"  {'':10} {'qubits':<10} {'@1k/logical':<15} {'@10k/logical':<15} {'@1GHz'}")
print(f"  {'-'*10} {'-'*10} {'-'*15} {'-'*15} {'-'*15}")

for bits in [256, 512, 1024, 2048, 4096]:
    logical = estimate_logical_qubits(bits)
    phys_1k = estimate_physical_qubits(logical, 1000)
    phys_10k = estimate_physical_qubits(logical, 10000)
    time_sec = estimate_time_seconds(bits)

    if time_sec < 60:
        time_str = f"{time_sec:.1f}s"
    elif time_sec < 3600:
        time_str = f"{time_sec/60:.1f}m"
    elif time_sec < 86400:
        time_str = f"{time_sec/3600:.1f}h"
    else:
        time_str = f"{time_sec/86400:.1f}d"

    print(f"  {bits:<10} {logical:<10} {phys_1k:<15,} {phys_10k:<15,} {time_str}")

# --- Current hardware comparison ---
print("\n" + "=" * 70)
print("CURRENT QUANTUM HARDWARE vs REQUIREMENTS FOR RSA-2048")
print("=" * 70)

hardware = [
    ("IBM Condor (2023)", 1121, "Superconducting", 99.5),
    ("Google Willow (2024)", 105, "Superconducting", 99.7),
    ("IonQ Forte (2024)", 36, "Trapped Ion", 99.9),
    ("Quantinuum H2 (2024)", 56, "Trapped Ion", 99.9),
]

print(f"\n  {'System':<25} {'Physical':<12} {'Type':<18} {'Gate fidelity'}")
print(f"  {'-'*25} {'-'*12} {'-'*18} {'-'*13}")
for name, qubits, qtype, fidelity in hardware:
    print(f"  {name:<25} {qubits:<12} {qtype:<18} {fidelity}%")

print(f"\n  {'REQUIRED FOR RSA-2048':<25} {'4,000,000+':<12} {'Fault-tolerant':<18} {'99.99%+'}")
print(f"  {'GAP':<25} {'~4000x':<12} {'':18} {'':13}")

# --- Post-quantum migration timeline ---
print("\n" + "=" * 70)
print("POST-QUANTUM MIGRATION TIMELINE")
print("=" * 70)
print("\n  Year    Milestone")
print("  ----    ---------")
milestones = [
    ("1994",  "Shor publishes factoring algorithm"),
    ("2001",  "IBM factors 15 on 7-qubit NMR quantum computer"),
    ("2016",  "NIST launches Post-Quantum Cryptography standardization"),
    ("2019",  "Google claims quantum supremacy (53 qubits, random circuit sampling)"),
    ("2022",  "NIST selects CRYSTALS-Kyber, CRYSTALS-Dilithium, SPHINCS+ as standards"),
    ("2024",  "NIST publishes FIPS 203 (Kyber), 204 (Dilithium), 205 (SPHINCS+)"),
    ("2024",  "Google demonstrates below-threshold error correction (Willow)"),
    ("2025",  "Signal, Chrome, Cloudflare begin PQC deployment"),
    ("2026",  "YOU ARE HERE — begin migration planning if you haven't already"),
    ("2030",  "Conservative estimate: first CRQC (Cryptographically Relevant QC)"),
    ("2035",  "NSA deadline for national security systems migration"),
    ("2040",  "Widely accepted outer bound for CRQC arrival"),
]
for year, desc in milestones:
    marker = " ←" if "YOU ARE HERE" in desc else ""
    print(f"  {year}    {desc}{marker}")
▶ Output
======================================================================
QUBIT REQUIREMENTS: SHOR'S ALGORITHM FOR RSA FACTORING
======================================================================

RSA bits Logical Physical Physical Est. time
qubits @1k/logical @10k/logical @1GHz
---------- ---------- --------------- --------------- ---------------
256 640 640,000 6,400,000 0.0s
512 1,280 1,280,000 12,800,000 0.1s
1024 2,560 2,560,000 25,600,000 1.1s
2048 5,120 5,120,000 51,200,000 8.6s
4096 10,240 10,240,000 102,400,000 68.7s

======================================================================
CURRENT QUANTUM HARDWARE vs REQUIREMENTS FOR RSA-2048
======================================================================

System Physical Type Gate fidelity
------------------------- ------------ ------------------ -------------
IBM Condor (2023) 1,121 Superconducting 99.5%
Google Willow (2024) 105 Superconducting 99.7%
IonQ Forte (2024) 36 Trapped Ion 99.9%
Quantinuum H2 (2024) 56 Trapped Ion 99.9%

REQUIRED FOR RSA-2048 4,000,000+ Fault-tolerant 99.99%+
GAP ~4000x

======================================================================
POST-QUANTUM MIGRATION TIMELINE
======================================================================

Year Milestone
---- ---------
1994 Shor publishes factoring algorithm
2001 IBM factors 15 on 7-qubit NMR quantum computer
2016 NIST launches Post-Quantum Cryptography standardization
2019 Google claims quantum supremacy (53 qubits, random circuit sampling)
2022 NIST selects CRYSTALS-Kyber, CRYSTALS-Dilithium, SPHINCS+ as standards
2024 NIST publishes FIPS 203 (Kyber), 204 (Dilithium), 205 (SPHINCS+)
2024 Google demonstrates below-threshold error correction (Willow)
2025 Signal, Chrome, Cloudflare begin PQC deployment
2026 YOU ARE HERE — begin migration planning if you haven't already
2030 Conservative estimate: first CRQC (Cryptographically Relevant QC)
2035 NSA deadline for national security systems migration
2040 Widely accepted outer bound for CRQC arrival
🔥Gidney & Ekerå: The Paper That Changed the Estimates
In 2021, Craig Gidney and Martin Ekerå published a landmark paper estimating that factoring RSA-2048 requires ~8 hours on a quantum computer with 20 million noisy qubits (using 10,000 physical per logical). Before their paper, estimates were 10-100x higher. Their key insight: better error correction codes and more efficient modular exponentiation circuits dramatically reduced the overhead. This is why the timeline accelerated from '50+ years' to '20-30 years' in most expert assessments. Their paper is required reading for anyone serious about post-quantum planning.
📊 Production Insight
A CTO dismissed quantum risk in 2020 saying 'we're at least 30 years away.' By 2026, Gidney-Ekerå and Google's error correction breakthrough have moved the estimate to 10-15 years. Key rotation cycles of 5 years mean they should have started migration planning in 2025.
Rule: don't anchor on outdated estimates. The quantum hardware field is moving faster than most people realise. Error correction breakthroughs accelerate timelines. Plan conservatively: assume CRQC arrival at the shorter end of expert estimates.
🎯 Key Takeaway
Logical qubits (~4,000) ≠ physical qubits (~4-40 million with error correction).
Current hardware: ~1,000 noisy physical qubits. Gap: ~4,000x to 40,000x.
Timeline: CRQC likely 2030-2040. NSA: migrate by 2035.
Harvest now, decrypt later: long-lived RSA/ECC-encrypted data is already at risk.

Practical Post-Quantum Migration — What You Should Do Today

Understanding Shor's algorithm is intellectually interesting, but the practical question is: what do you do about it? Here's a concrete migration playbook based on what I've implemented at two companies and what NIST, NSA, and CISA recommend.

Step 1: Inventory your cryptography. Audit every system that uses RSA, ECC, or Diffie-Hellman. This includes TLS certificates, SSH keys, code signing, JWT tokens, database encryption key wrapping, and VPN tunnels. Most organisations are surprised by how many places asymmetric crypto is used.

Step 2: Prioritise by data lifetime. Data that must remain confidential for 10+ years (medical records, government secrets, trade secrets, long-lived API tokens) is at the highest risk from harvest-now-decrypt-later. Migrate these systems first.

Step 3: Deploy hybrid schemes now. The safest approach during the transition is hybrid cryptography: use both a classical algorithm (ECDH) and a post-quantum algorithm (CRYSTALS-Kyber) together. If either one is secure, the combined scheme is secure. This is what Signal, Chrome, and Cloudflare are doing today.

Step 4: Update your TLS stack. OpenSSL 3.x supports CRYSTALS-Kyber (ML-KEM) key exchange. Enable it in your web servers and load balancers. Test with pq.cloudflareresearch.com to verify your client supports PQC.

Step 5: Plan for key rotation. Post-quantum keys are larger than classical keys (Kyber public keys are ~800-1568 bytes vs ~32 bytes for X25519). This affects handshake sizes, storage, and bandwidth. Plan for it.

Step 6: Don't forget signatures. CRYSTALS-Dilithium (ML-DSA) replaces RSA/ECDSA signatures. SPHINCS+ (SLH-DSA) is a conservative hash-based alternative. Both are standardised. Start testing them for code signing and document signing.

The biggest mistake I see organisations make: waiting for the quantum threat to feel 'real.' By the time a CRQC is announced, it's too late for retroactive protection. The time to migrate is now, while you have the luxury of careful planning instead of emergency response.

io/thecodeforge/quantum/post_quantum_audit.py · PYTHON
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
# io.thecodeforge.quantum.migration.PostQuantumAudit

import json
from datetime import datetime


class CryptoInventoryItem:
    """Represents a single cryptographic dependency in your infrastructure."""

    def __init__(self, system: str, algorithm: str, key_size: int,
                 purpose: str, data_lifetime_years: int,
                 pq_vulnerable: bool, migration_priority: str):
        self.system = system
        self.algorithm = algorithm
        self.key_size = key_size
        self.purpose = purpose
        self.data_lifetime_years = data_lifetime_years
        self.pq_vulnerable = pq_vulnerable
        self.migration_priority = migration_priority

    def to_dict(self):
        return vars(self)


def classify_risk(algorithm: str, key_size: int, data_lifetime: int) -> str:
    """Classify migration priority based on algorithm and data lifetime.

    Priority levels:
    - CRITICAL: Asymmetric crypto + data lifetime > 10 years
    - HIGH: Asymmetric crypto + data lifetime 5-10 years
    - MEDIUM: Asymmetric crypto + data lifetime < 5 years
    - LOW: Symmetric crypto with adequate key size (AES-256)
    - INFO: Already post-quantum safe
    """
    vulnerable_algs = ['RSA', 'ECC', 'ECDSA', 'ECDH', 'Ed25519', 'DSA',
                       'Diffie-Hellman', 'X25519', 'P-256', 'P-384']
    weakened_algs = ['AES-128', '3DES']
    safe_algs = ['AES-256', 'ChaCha20', 'SHA-256', 'SHA-3',
                 'CRYSTALS-Kyber', 'CRYSTALS-Dilithium', 'SPHINCS+']

    alg_upper = algorithm.upper()

    if any(v in alg_upper for v in ['KYBER', 'DILITHIUM', 'SPHINCS', 'ML-KEM', 'ML-DSA', 'SLH-DSA']):
        return 'INFO (already PQ-safe)'

    if any(v in alg_upper for v in vulnerable_algs):
        if data_lifetime >= 10:
            return 'CRITICAL — harvest-now-decrypt-later risk'
        elif data_lifetime >= 5:
            return 'HIGH — migrate within 2 years'
        else:
            return 'MEDIUM — migrate within 5 years'

    if any(w in alg_upper for w in weakened_algs):
        return 'MEDIUM — use AES-256 instead'

    if any(s in alg_upper for s in ['AES-256', 'CHACHA', 'SHA-256', 'SHA-3']):
        return 'LOW — symmetric, adequate key size'

    return 'UNKNOWN — manual review needed'


def generate_migration_report(inventory: list) -> dict:
    """Generate a summary migration report from a crypto inventory."""
    report = {
        'generated': datetime.now().isoformat(),
        'total_items': len(inventory),
        'by_priority': {},
        'critical_items': [],
        'recommendations': []
    }

    for item in inventory:
        priority = item.migration_priority
        report['by_priority'][priority] = report['by_priority'].get(priority, 0) + 1
        if 'CRITICAL' in priority:
            report['critical_items'].append(item.system)

    if report['critical_items']:
        report['recommendations'].append(
            'IMMEDIATE: Deploy hybrid key exchange (ECDH + Kyber) for systems '
            'handling data with 10+ year confidentiality requirements.'
        )
    report['recommendations'].extend([
        'Enable CRYSTALS-Kyber (ML-KEM) in TLS via OpenSSL 3.x.',
        'Test PQC support at pq.cloudflareresearch.com.',
        'Begin testing CRYSTALS-Dilithium for code/document signing.',
        'Inventory all SSH keys and plan migration to hybrid SSH.',
        'Update key management systems to handle larger PQC key sizes.',
    ])

    return report


# --- Example: build a crypto inventory for a typical organisation ---
print("=" * 70)
print("POST-QUANTUM CRYPTOGRAPHIC AUDIT")
print("=" * 70)

inventory = [
    CryptoInventoryItem('TLS (web server)', 'RSA-2048', 2048, 'Key exchange', 0, True,
                        classify_risk('RSA', 2048, 0)),
    CryptoInventoryItem('TLS (API gateway)', 'ECDH P-256', 256, 'Key exchange', 1, True,
                        classify_risk('ECDH', 256, 1)),
    CryptoInventoryItem('SSH (production)', 'Ed25519', 256, 'Authentication', 0, True,
                        classify_risk('Ed25519', 256, 0)),
    CryptoInventoryItem('Code signing cert', 'RSA-4096', 4096, 'Signature', 3, True,
                        classify_risk('RSA', 4096, 3)),
    CryptoInventoryItem('Database encryption', 'AES-256-GCM', 256, 'Symmetric encryption', 15, False,
                        classify_risk('AES-256', 256, 15)),
    CryptoInventoryItem('JWT tokens', 'RS256', 2048, 'Signature', 0, True,
                        classify_risk('RSA', 2048, 0)),
    CryptoInventoryItem('VPN (WireGuard)', 'X25519', 256, 'Key exchange', 0, True,
                        classify_risk('X25519', 256, 0)),
    CryptoInventoryItem('Medical records archive', 'RSA-2048', 2048, 'Key wrapping', 30, True,
                        classify_risk('RSA', 2048, 30)),
    CryptoInventoryItem('Internal PKI root CA', 'ECDSA P-384', 384, 'Certificate signing', 20, True,
                        classify_risk('ECDSA', 384, 20)),
    CryptoInventoryItem('Backup encryption', 'ChaCha20-Poly1305', 256, 'Symmetric encryption', 10, False,
                        classify_risk('ChaCha20', 256, 10)),
]

print(f"\n  {'System':<28} {'Algorithm':<20} {'Lifetime':<10} {'Priority'}")
print(f"  {'-'*28} {'-'*20} {'-'*10} {'-'*40}")
for item in inventory:
    print(f"  {item.system:<28} {item.algorithm:<20} {item.data_lifetime_years:<10} {item.migration_priority}")

report = generate_migration_report(inventory)
print(f"\n{'='*70}")
print("MIGRATION REPORT SUMMARY")
print(f"{'='*70}")
print(f"\n  Total items audited: {report['total_items']}")
print(f"  By priority:")
for priority, count in report['by_priority'].items():
    print(f"    {priority}: {count}")
print(f"\n  Critical systems (harvest-now-decrypt-later risk):")
for system in report['critical_items']:
    print(f"    - {system}")
print(f"\n  Recommendations:")
for i, rec in enumerate(report['recommendations'], 1):
    print(f"    {i}. {rec}")
▶ Output
======================================================================
POST-QUANTUM CRYPTOGRAPHIC AUDIT
======================================================================

System Algorithm Lifetime Priority
--------------------------- -------------------- ---------- ----------------------------------------
TLS (web server) RSA-2048 0 MEDIUM — migrate within 5 years
TLS (API gateway) ECDH P-256 1 MEDIUM — migrate within 5 years
SSH (production) Ed25519 0 MEDIUM — migrate within 5 years
Code signing cert RSA-4096 3 MEDIUM — migrate within 5 years
Database encryption AES-256-GCM 15 LOW — symmetric, adequate key size
JWT tokens RS256 0 MEDIUM — migrate within 5 years
VPN (WireGuard) X25519 0 MEDIUM — migrate within 5 years
Medical records archive RSA-2048 30 CRITICAL — harvest-now-decrypt-later risk
Internal PKI root CA ECDSA P-384 20 CRITICAL — harvest-now-decrypt-later risk
Backup encryption ChaCha20-Poly1305 10 LOW — symmetric, adequate key size

======================================================================
MIGRATION REPORT SUMMARY
======================================================================

Total items audited: 10
By priority:
MEDIUM — migrate within 5 years: 6
LOW — symmetric, adequate key size: 2
CRITICAL — harvest-now-decrypt-later risk: 2

Critical systems (harvest-now-decrypt-later risk):
- Medical records archive
- Internal PKI root CA

Recommendations:
1. IMMEDIATE: Deploy hybrid key exchange (ECDH + Kyber) for systems handling data with 10+ year confidentiality requirements.
2. Enable CRYSTALS-Kyber (ML-KEM) in TLS via OpenSSL 3.x.
3. Test PQC support at pq.cloudflareresearch.com.
4. Begin testing CRYSTALS-Dilithium for code/document signing.
5. Inventory all SSH keys and plan migration to hybrid SSH.
6. Update key management systems to handle larger PQC key sizes.
💡Start With Hybrid Cryptography — It's the Safest Transition Strategy
Hybrid cryptography means running both a classical and a post-quantum algorithm in parallel and combining their outputs. For key exchange: ECDH + Kyber. For signatures: ECDSA + Dilithium. If either algorithm is secure, the hybrid is secure. This protects you against two scenarios: (1) quantum computers arrive and break ECC — the Kyber component saves you, (2) a classical attack is found against Kyber — the ECC component saves you. Signal, Google Chrome, and Cloudflare all use hybrid schemes today. There's no reason not to deploy hybrid PQC now — the performance overhead is minimal (Kyber adds ~1KB to TLS handshakes) and the security benefit is enormous.
📊 Production Insight
A financial services company waited until NIST standards were finalised in 2024 to start their PQC migration. It took them 18 months to inventory their crypto landscape, and they found RSA keys embedded in firmware, HSMs, and legacy systems that couldn't be patched quickly. By 2026, they were still only 40% migrated.
Rule: start the inventory now. Even if you don't deploy PQC today, knowing where your RSA/ECC keys are is prerequisite to any migration plan. The inventory alone can take a year for large organisations.
🎯 Key Takeaway
Inventory all RSA/ECC usage — TLS, SSH, code signing, JWTs, key wrapping.
Prioritise by data lifetime: 10+ years = harvest-now-decrypt-later risk, migrate first.
Deploy hybrid schemes (ECDH + Kyber) now — they're safe for classical and quantum threats.
Update TLS to OpenSSL 3.x with Kyber. Test at pq.cloudflareresearch.com.
Don't wait for a CRQC to be announced — by then, harvested data is already compromised.
🗂 Shor's Algorithm: Impact on Cryptography
Which algorithms are broken, weakened, or safe?
AlgorithmProblemQuantum AttackComplexityStatusRecommended Replacement
RSA (all key sizes)Integer factoringShorO(n³)BROKENCRYSTALS-Kyber (ML-KEM)
ECC (P-256, P-384, etc.)ECDLPShor variantO(n³)BROKENCRYSTALS-Dilithium (ML-DSA)
Diffie-Hellman (classical)Discrete logShorO(n³)BROKENCRYSTALS-Kyber
Ed25519 / Ed448ECDLPShor variantO(n³)BROKENCRYSTALS-Dilithium
AES-128Key searchGroverO(2^64 quantum gates)WEAKENEDAES-256
AES-256Key searchGroverO(2^128 quantum gates)SAFEContinue using AES-256
SHA-256PreimageGroverO(2^128 quantum gates)SAFEContinue using SHA-256
CRYSTALS-Kyber (ML-KEM)Module-LWENone knownExponential (classical & quantum)PQ-SAFETLS key exchange replacement
CRYSTALS-Dilithium (ML-DSA)Module-SISNone knownExponential (classical & quantum)PQ-SAFESignature replacement
SPHINCS+ (SLH-DSA)Hash-basedNone knownExponential (classical & quantum)PQ-SAFEConservative signature option

🎯 Key Takeaways

  • Shor's algorithm reduces factoring to period finding: find smallest r with a^r ≡ 1 (mod N), then factors = gcd(a^(r/2) ± 1, N). Works with 50% probability per random a.
  • Quantum speedup comes from QFT extracting periodicity in O(n²) gates vs classical O(r) — exponential difference. Continued fractions convert measurement outcome y to period r.
  • Shor breaks ALL asymmetric cryptography: RSA, ECC, Diffie-Hellman, Ed25519, DSA, ECDSA. Grover weakens AES-128 to 64-bit security; AES-256 remains safe.
  • Breaking RSA-2048 requires ~4,000 logical qubits → 4-40 million physical qubits with error correction. Current hardware: ~1,000 noisy physical qubits. Gap: 4,000x to 40,000x.
  • Timeline: CRQC likely 2030-2040. NSA deadline: national security systems migrate by 2035. NIST standards finalised in 2024. Begin migration now.
  • Harvest now, decrypt later: RSA/ECC-encrypted data recorded today can be decrypted retroactively. Data with 10+ year confidentiality requirements is already at risk.
  • Hybrid cryptography (ECDH + Kyber, ECDSA + Dilithium) is the safe transition strategy — protects against both classical and quantum breakthroughs.
  • Don't assume ECC is quantum-safe. Shor solves discrete log with fewer qubits than RSA factoring. ECC is equally broken.

⚠ Common Mistakes to Avoid

    Assuming ECC is quantum-safe because keys are smaller than RSA
    Symptom

    Organisation migrates from RSA to ECC thinking they're now quantum-safe. Shor's algorithm variant breaks ECDLP with fewer qubits than RSA.

    Fix

    ECC is as broken as RSA against Shor. Both need to be replaced with lattice-based or hash-based post-quantum algorithms. Start planning migration now, not later.

    Believing quantum computers will arrive 'too far in the future to matter'
    Symptom

    No migration planning. Data with 20+ year retention (medical records, intelligence) is encrypted with RSA and harvested today for future decryption.

    Fix

    Assume a CRQC within 15 years. For data that must remain confidential beyond that, migrate to hybrid classical+PQC today. Harvest-now-decrypt-later is a real threat.

    Only deploying PQC without classical fallback (pure PQC, no hybrid)
    Symptom

    A new cryptanalytic breakthrough against a lattice problem breaks Kyber. All your TLS traffic is now vulnerable because you have no classical backup.

    Fix

    Always use hybrid schemes: ECDH + Kyber for key exchange, ECDSA + Dilithium for signatures. If either algorithm is secure, the hybrid is secure. This is what Signal, Chrome, and Cloudflare do.

    Missing non-TLS RSA/ECC usage in crypto inventory
    Symptom

    SSH host keys, code signing certificates, JWT RS256 tokens, VPN key exchange, database key wrapping — all use RSA/ECC and are missed in migration planning.

    Fix

    Do a full cryptographic inventory across your entire stack. Use automated scanning tools. Include firmware, HSMs, legacy systems, and third-party dependencies. The inventory is the hardest part.

    Assuming RSA-4096 is quantum-safe because it's larger
    Symptom

    Using 4096-bit RSA keys thinking they resist Shor. Shor's algorithm is polynomial O(n³). Doubling key size only multiplies gate count by 8 — trivial for a CRQC.

    Fix

    Shor breaks all RSA key sizes equally. Key length does not provide quantum resistance. Switch to lattice-based PQC, not bigger RSA.

Interview Questions on This Topic

  • QWalk through Shor's algorithm step by step: how does it reduce factoring to period finding, and why does the reduction work?Reveal
    Step 1: Pick random a coprime to N. Step 2: Find smallest r > 0 where a^r ≡ 1 (mod N) — this is the period (or order). Step 3: If r is even, compute a^(r/2) mod N. Then gcd(a^(r/2) - 1, N) and gcd(a^(r/2) + 1, N) produce factors. This works because if a^r ≡ 1 (mod N), then N divides (a^(r/2) - 1)(a^(r/2) + 1). Unless N divides one of those factors entirely, each shares a factor with N. Number theory guarantees that for N = pq, at least half of random a choices produce an even r yielding non-trivial factors. The quantum part is finding r quickly — classically, this requires trying values sequentially O(r) time, where r can be up to N. Quantum computer uses QFT to extract r in O(n³).
  • QExplain the Quantum Fourier Transform and why it provides exponential speedup over classical period finding.Reveal
    The QFT is the quantum analogue of the DFT. Applied to a periodic quantum state with period r, it produces sharp peaks at multiples of 2^n/r in the frequency domain. Classical period finding requires iterating through the sequence until it repeats — O(r) steps, and r can be as large as N (exponential in bit-length n). The QFT, however, operates on a superposition of all 2^n basis states simultaneously. Its gate complexity is O(n²) for n qubits, compared to O(n·2ⁿ) for the classical FFT on the same number of amplitudes. Measurement then samples from a distribution peaked near k·(2^n/r), and a classical continued fraction step extracts r. This reduces complexity from exponential O(2^n) to polynomial O(n³) — the core exponential speedup of Shor's algorithm.
  • QWhy does Shor's algorithm break both RSA and ECC? What is the difference in the reduction?Reveal
    RSA relies on the hardness of factoring n = p×q. Shor reduces factoring to period finding of a modulo n. ECC relies on the elliptic curve discrete logarithm problem (ECDLP): given points P and Q on a curve, find k such that Q = kP. Shor reduces ECDLP to period finding on the elliptic curve group. The quantum subroutine — period finding — is mathematically the same: create superposition of integer x, compute x·P (scalar multiplication) or a^x mod n mod N, apply QFT, measure, extract period via continued fractions. The difference: for RSA, the period is the order of a modulo N; for ECC, the period is the group order (or the discrete log itself when searching for x such that x·P = Q). Both require polynomial-time quantum circuits, and both are broken.
  • QEstimate the number of physical qubits required to break RSA-2048. How has the Gidney-Ekerå 2021 paper changed these estimates?Reveal
    Shor's algorithm for RSA-2048 requires approximately 4,000 logical qubits. Surface code error correction at current noise rates (~0.1-1% gate error) requires about 1,000 physical qubits per logical qubit, giving ~4 million physical qubits. Gidney and Ekerå (2021) showed that with improved modular exponentiation circuits and better error correction codes, factoring RSA-2048 could be done with 20 million noisy physical qubits in ~8 hours. Previous estimates were 10-100x higher because they used less efficient circuits. This accelerated the industry timeline from 'maybe late 2050s' to '2030-2040.'
  • QWhat is harvest now, decrypt later, and how does it affect cryptographic migration priorities?Reveal
    Harvest now, decrypt later refers to adversaries storing encrypted traffic today with the intent to decrypt it once a quantum computer capable of running Shor's algorithm exists. Any RSA or ECC-encrypted data recorded today can be retroactively decrypted when CRQC arrives. This means data with long confidentiality requirements (medical records, trade secrets, government intelligence, financial archives with 10-30 year retention) is already at risk. Migration priority: (1) data with the longest confidentiality requirements, (2) systems where forward secrecy is not used (RSA key exchange in TLS), (3) other asymmetric crypto. The response is hybrid encryption: encrypt with both classical (ECDH) and post-quantum (Kyber) algorithms so that breaking one still leaves the other protecting the data.

Frequently Asked Questions

When will quantum computers break RSA?

Breaking RSA-2048 requires approximately 4,000 logical qubits, which translates to 4-40 million physical qubits depending on error rates. Current hardware has ~1,000 noisy physical qubits. Most expert estimates place a Cryptographically Relevant Quantum Computer (CRQC) at 2030-2040. The Gidney-Ekerå 2021 paper showed that factoring RSA-2048 requires ~20 million noisy qubits and ~8 hours of computation — dramatically lower than previous estimates. However, the threat isn't just the day a CRQC exists — it's the decade before, when adversaries harvest encrypted traffic for later decryption. Organisations with long-lived sensitive data should begin post-quantum migration now.

Can I run Shor's algorithm on today's quantum computers?

Only for trivially small numbers. IBM demonstrated factoring 15 on a 7-qubit NMR quantum computer in 2001, and various groups have factored numbers up to 21 on small quantum processors. But factoring RSA-2048 is a completely different challenge — it requires fault-tolerant quantum computation with error correction, which current hardware cannot do. Today's quantum computers are 'NISQ' (Noisy Intermediate-Scale Quantum) devices — they have too few qubits and too high error rates for Shor's algorithm at cryptographic scales.

Does Shor's algorithm affect symmetric encryption like AES?

Shor's algorithm does not affect symmetric encryption — it only solves the problems underlying asymmetric cryptography (factoring and discrete log). However, Grover's algorithm provides a quadratic speedup for brute-force key search: AES-128's effective security drops to 64 bits, which is concerning. The fix is simple: use AES-256, which drops to 128-bit security under Grover — still computationally infeasible. SHA-256 also remains secure (128-bit preimage resistance after Grover).

What is the Quantum Fourier Transform and why is it the key to Shor's algorithm?

The QFT is the quantum analogue of the Discrete Fourier Transform. It transforms a quantum state from the computational basis to the frequency basis in O(n²) quantum gates, compared to O(n × 2ⁿ) for a classical FFT on the same 2ⁿ amplitudes. In Shor's algorithm, after modular exponentiation creates a periodic quantum state (the sequence a^x mod N has period r), the QFT converts this periodicity into sharp measurement peaks at multiples of 2ⁿ/r. Measuring these peaks and applying continued fractions extracts r. The QFT is the single component that gives Shor its exponential speedup — without it, you'd need to classically search through all possible periods.

What should I do today to prepare for quantum threats?

Five concrete steps: (1) Audit your cryptographic inventory — every system using RSA, ECC, or DH. (2) Prioritise systems handling data with long confidentiality requirements (10+ years). (3) Deploy hybrid key exchange (ECDH + CRYSTALS-Kyber) in your TLS stack — OpenSSL 3.x supports it. (4) Test your systems at pq.cloudflareresearch.com. (5) Begin testing CRYSTALS-Dilithium for signatures. The key principle: use hybrid schemes during the transition. If either the classical or post-quantum component is secure, the hybrid is secure. Don't wait for a quantum computer to exist — by then, it's too late for retroactive protection of harvested data.

How does Shor's algorithm compare to the best classical factoring algorithms?

The best classical factoring algorithm is the General Number Field Sieve (GNFS), with complexity O(exp(c · n^(1/3) · (ln n)^(2/3))) — sub-exponential but super-polynomial. For a 2048-bit number, GNFS requires roughly 2^116 operations — estimated at millions of CPU-years. Shor's algorithm does the same job in O(n³) ≈ 2^33 quantum operations — minutes to hours on a fault-tolerant quantum computer. The speedup is not just exponential in practice — it changes the problem from 'computationally impossible' to 'computationally trivial.'

Why can't we just make RSA keys bigger to resist quantum computers?

Because Shor's algorithm is polynomial — O(n³). Doubling the key size only increases the quantum computation by 8x (2³). To maintain 128-bit security against Shor, you'd need a key so large that the key exchange overhead becomes impractical (millions of bits). Classical algorithms get slower sub-exponentially with key size, so bigger keys help. Against Shor, bigger keys just delay the inevitable by a constant factor. The only real solution is to switch to mathematical problems that Shor's algorithm can't solve — which is exactly what post-quantum cryptography does (lattice problems, hash-based signatures, code-based cryptography).

What happens if someone factors a large number with Shor's algorithm tomorrow?

It would be the most significant cryptographic event in history. Every RSA and ECC system on the internet would be immediately vulnerable. TLS, SSH, VPNs, code signing, email encryption — all broken. The practical impact depends on how quickly the factoring capability spreads: if a single government achieves it secretly, they have an intelligence advantage. If it's published, the internet has a catastrophic security crisis until post-quantum migration completes. This is exactly why NIST, NSA, and CISA are pushing migration now — not because it's imminent, but because the migration itself takes years and the consequences of being late are existential.

🔥
Naren Founder & Author

Developer and founder of TheCodeForge. I built this site because I was tired of tutorials that explain what to type without explaining why it works. Every article here is written to make concepts actually click.

← PreviousGrover's Search Algorithm — Quantum Speedup
Forged with 🔥 at TheCodeForge.io — Where Developers Are Forged