Post-Quantum Cryptography: An Introduction
Imagine every bank transfer, every TLS handshake, every signed software update on Earth secured by RSA or elliptic-curve cryptography. Now imagine a sufficiently large quantum computer arrives. All of that math unravels in polynomial time. This is not science fiction anymore — it is a scheduling problem. Governments and standards bodies are racing to replace the public-key infrastructure of the internet before that day arrives. This urgency exists because encrypted traffic captured today can be decrypted retroactively once a quantum computer exists. This attack model is called "harvest now, decrypt later." The problem is structural. RSA Security and the Factoring Problem and The Discrete Logarithm Problem both rely on number-theoretic problems. These problems are hard for classical computers. But they fall to Peter Shor's 1994 quantum algorithm. Shor's algorithm factors integers and computes discrete logarithms in polynomial time on a quantum computer. Every widely deployed public-key system — RSA, Diffie–Hellman, ECDSA, ECDH — inherits this vulnerability. This happens because they are all instances of the same hidden-subgroup structure. Shor's algorithm exploits exactly that structure. Post-quantum cryptography (PQC) is the discipline of building public-key primitives. Their security rests on mathematical problems believed to resist both classical and quantum attack. This does not mean "encrypt with quantum physics" — that is quantum key distribution, a different field. PQC systems run on ordinary classical computers today. Only their hardness assumptions are chosen to survive a future quantum adversary. The leading candidate families are lattice-based, code-based, and hash-based cryptography. Each has a distinct hard problem, distinct performance profile, and distinct history of cryptanalysis. This article explains precisely why Shor's algorithm breaks factoring and discrete log. It shows what mathematical structure the post-quantum families use instead. It also shows how a representative scheme from each family actually works step by step. It closes with the practical picture: which algorithms NIST has standardized, where they are deployed, and what tradeoffs engineers must navigate when migrating real systems.
- Shor's algorithm solves factoring and discrete log in quantum polynomial time, breaking RSA, DH, and ECC.
- Grover's algorithm only gives a quadratic quantum speedup against symmetric ciphers and hash functions, so doubling key sizes suffices there.
- Lattice-based cryptography (e.g., Kyber/ML-KEM, Dilithium/ML-DSA) relies on worst-case-hard lattice problems like Learning With Errors.
- Code-based cryptography (e.g., Classic McEliece) relies on decoding random linear codes, a problem open since 1978.
- Hash-based signatures (e.g., SPHINCS+) rely only on hash function security, giving the most conservative trust assumption.
- NIST finalized ML-KEM, ML-DSA, and SLH-DSA as standards in 2024; migration is already underway in browsers and protocols.
Post-quantum cryptography replaces number-theoretic hardness (factoring, discrete log) with structurally different problems — lattice, code, and hash problems — for which no efficient quantum algorithm is known.
The idea
A public-key cryptosystem is only as secure as the computational problem it is built on. RSA's security reduces to the hardness of factoring large integers; Diffie–Hellman and ECDSA reduce to the hardness of the discrete logarithm problem in some group. Both problems share a hidden algebraic structure: they can be phrased as finding the period of a function over an abelian group. Shor's algorithm uses quantum Fourier transforms to find that period in polynomial time, and once the period is known, factoring or discrete-log falls out by elementary number theory. This is not a minor speedup — it converts a problem believed to require sub-exponential or exponential classical time into one solvable in time polynomial in the bit-length of the modulus. Post-quantum cryptography's central idea is to abandon group-structured hardness altogether and build on problems that are not known to reduce to period-finding. The three mature families are:
- Lattice-based cryptography: security rests on problems like Shortest Vector Problem (SVP) and Learning With Errors (LWE) in high-dimensional lattices, which lack the smooth algebraic structure Shor's transform exploits.
- Code-based cryptography: security rests on the hardness of decoding a random linear error-correcting code, a problem (syndrome decoding) that is NP-hard in the worst case and has resisted 45+ years of cryptanalysis, classical and quantum.
- Hash-based cryptography: signature schemes built entirely from cryptographic hash functions, whose only required property is one-wayness/collision-resistance, quantities Grover's algorithm degrades only quadratically, not exponentially.
A fourth family, isogeny-based cryptography, looked promising (SIKE) until a 2022 classical attack (Castryck–Decru) broke it, illustrating that "post-quantum" is a moving target requiring ongoing cryptanalysis, not a permanent guarantee. This is why standards bodies favor problems with long track records and worst-case-to-average-case reductions, such as lattices.
How it works
Why Shor's algorithm breaks RSA and discrete log
Both factoring and discrete log reduce to order-finding: given group elements, find the smallest such that . Shor's algorithm finds using a quantum circuit that computes in superposition over all , then applies the quantum Fourier transform (QFT) to extract the period with high probability, using only gates — polynomial in the input size. Classically, the best known factoring algorithm (the general number field sieve) runs in sub-exponential time . The gap between polynomial quantum time and sub-exponential classical time is why a large enough fault-tolerant quantum computer would break RSA-2048 in hours, not centuries. Grover's algorithm, in contrast, searches an unstructured space of size in quantum queries versus classically — a quadratic, not exponential, speedup. This is why AES-256 and SHA-256 remain safe against quantum attack (with AES-128 downgraded to roughly 64-bit quantum security, motivating a move to 256-bit keys), while RSA and ECC of any practical size are completely broken. PQC therefore focuses entirely on replacing public-key primitives; symmetric cryptography needs only larger keys.
Lattice-based cryptography: Learning With Errors (LWE)
A lattice is the set of all integer combinations of basis vectors in . The Learning With Errors problem, introduced by Regev in 2005, asks an adversary to recover a secret vector given many noisy linear equations: ``` given: (a_i, b_i) where b_i = + e_i (mod q) a_i drawn uniformly at random from Z_q^n e_i drawn from a small "error" distribution (e.g., discrete Gaussian) find: s ``` Without the noise , this is trivial linear algebra (Gaussian elimination). The noise is what makes LWE hard: distinguishing from uniformly random pairs is believed to be as hard as solving worst-case lattice problems like the approximate Shortest Vector Problem, via a formal reduction proved by Regev. This "worst-case to average-case" reduction is a major reason lattices are trusted: breaking a randomly generated LWE instance would imply an efficient algorithm for the worst-case lattice problem, something 40+ years of lattice research has failed to find, quantumly or classically.
Kyber (standardized as ML-KEM) is a key-encapsulation mechanism (KEM) built on Module-LWE, a structured variant of LWE that uses polynomial rings for efficiency. Here is the core mechanism, simplified to essentials: ``` PARAMETERS: ring R_q = Z_q[x] / (x^n + 1), matrix dimension k, error distribution χ KEYGEN(): A ← uniform random k×k matrix over R_q # public, can be a shared seed s, e ← sampled from error distribution χ, each a length-k vector over R_q t ← A·s + e # (mod q), the "noisy" public value public_key ← (A, t) secret_key ← s return (public_key, secret_key) ENCAPSULATE(public_key = (A, t)): r, e1, e2 ← sampled from χ u ← A^T·r + e1 # (mod q) v ← t^T·r + e2 + encode(m) # m: random shared-secret seed ciphertext ← (u, v) shared_secret ← KDF(m) return (ciphertext, shared_secret) DECAPSULATE(secret_key = s, ciphertext = (u, v)): m' ← decode(v - s^T·u) shared_secret ← KDF(m') return shared_secret ``` Decapsulation works because , and the accumulated error is small enough that `decode` (a rounding function) recovers correctly with overwhelming probability, while an eavesdropper who only sees faces a Module-LWE instance that is computationally indistinguishable from random.
Code-based cryptography: McEliece
The McEliece cryptosystem, proposed in 1978, is one of the oldest public-key schemes never broken by a structural attack, classical or quantum. It hides an efficiently decodable error-correcting code (a binary Goppa code) so that it looks like a random linear code, whose decoding problem (finding the nearest codeword given noise) is NP-hard in general. ``` KEYGEN(): Choose a binary Goppa code C with generator matrix G (k×n), able to correct t errors S ← random invertible k×k matrix # scrambler P ← random n×n permutation matrix # scrambler G_pub ← S·G·P # looks like a random linear code public_key ← (G_pub, t) secret_key ← (S, G, P, efficient_decoder_for_C) return (public_key, secret_key) ENCRYPT(public_key = (G_pub, t), message m): e ← random error vector of weight exactly t c ← m·G_pub + e return c DECRYPT(secret_key = (S, G, P), ciphertext c): c' ← c·P^{-1} # = m·S·G + e·P^{-1} m'·G ← decode_efficiently(c') # uses the Goppa structure m ← m'·S^{-1} return m ``` The scrambling matrices and disguise the Goppa code's structure so that an attacker sees only , from which recovering requires decoding a seemingly random linear code — believed hard even for quantum computers, since no quantum algorithm is known to solve general syndrome decoding faster than a modest (Grover-style, quadratic) speedup over the best classical decoding algorithms (information-set decoding). The tradeoff: public keys are large (hundreds of KB to ~1MB for Classic McEliece), but ciphertexts are small and the scheme's hardness assumption is exceptionally well-tested by decades of cryptanalysis.
Hash-based signatures: the Merkle tree construction
Hash-based signatures rest on the weakest possible assumption: that a cryptographic hash function is one-way and collision-resistant. The building block is a one-time signature (OTS) scheme, such as Lamport signatures, combined into a many-time scheme using a Merkle hash tree. ``` LAMPORT KEYGEN (one-time use only): for i in 1..256: # for each bit of a 256-bit message hash sk[i][0], sk[i][1] ← random 256-bit strings pk[i][0] ← H(sk[i][0]) pk[i][1] ← H(sk[i][1]) return (pk, sk) LAMPORT SIGN(message m, sk): h ← H(m) # 256-bit digest for i in 1..256: signature[i] ← sk[i][ bit_i(h) ] return signature LAMPORT VERIFY(message m, signature, pk): h ← H(m) for i in 1..256: if H(signature[i]) != pk[i][ bit_i(h) ]: return REJECT return ACCEPT ``` A Lamport key pair is secure for exactly one signature — reusing it leaks half of each `sk[i]` pair, letting a forger sign a second, different message. Merkle's insight (1979) was to authenticate many one-time public keys with a single, small public key using a binary hash tree: ``` MERKLE KEYGEN(height h): generate 2^h Lamport key pairs (pk_0..pk_{2^h - 1}, sk_0..sk_{2^h - 1}) leaves[i] ← H(pk_i) build binary tree: parent = H(left_child || right_child) root ← the single hash at the top public_key ← root secret_key ← all sk_i plus the tree structure (or seeds to regenerate them) return (public_key, secret_key) MERKLE SIGN(message m, index i, sk_i, auth_path_i): ots_sig ← LAMPORT_SIGN(m, sk_i) return (i, ots_sig, pk_i, auth_path_i) # auth_path: sibling hashes up to root MERKLE VERIFY(message m, signature = (i, ots_sig, pk_i, auth_path), public_key = root): if LAMPORT_VERIFY(m, ots_sig, pk_i) == REJECT: return REJECT node ← H(pk_i) for each sibling in auth_path (bottom to top): node ← H(node || sibling) or H(sibling || node) # per tree side return (node == root) ? ACCEPT : REJECT ``` Every leaf's one-time key is used exactly once, and the authentication path proves that leaf belongs to the tree without exposing other leaves' secrets. SPHINCS+ (standardized as SLH-DSA) extends this idea into a "stateless" hyper-tree of many such Merkle trees so that signers do not need to remember which leaf indices have already been used — a critical practical safety property, since reusing a Lamport leaf catastrophically breaks security.
Complexity & correctness
Shor's algorithm. Factoring an -bit integer classically via the general number field sieve costs — sub-exponential but super-polynomial. Shor's quantum algorithm costs gates, polynomial in . The exponential-to-polynomial gap is the entire motivation for PQC: it is not that quantum computers are "somewhat faster," it is that the security parameter must be increased to infinity (impractical) to compensate, so the underlying problem must be replaced.
LWE-based schemes (Kyber/ML-KEM). Key generation, encapsulation, and decapsulation each perform matrix–vector multiplications over a ring of dimension (typically ) with components (typically ), using the Number Theoretic Transform (NTT) for polynomial multiplication. Total work per operation is , which is a few hundred microseconds on commodity hardware — competitive with or faster than RSA-2048. Correctness (decapsulation recovers the right shared secret) holds as long as the accumulated noise term stays below half the rounding threshold used by `decode`; parameters are chosen so this fails with probability below , an engineering choice, not a proof of unconditional correctness, but negligible for all practical purposes. Security reduces, via Regev's proof, to the worst-case hardness of approximating the shortest vector in an -dimensional lattice to within a polynomial factor — a problem for which the best known quantum algorithm (still exponential in ) offers no meaningful advantage over the best classical lattice-reduction algorithms (e.g., BKZ).
McEliece. Encryption costs one matrix–vector multiplication, bit operations. Decryption's dominant cost is the Patterson decoding algorithm for Goppa codes, or better with modern implementations, still fast. The public key, however, is the full generator matrix, roughly bits — hundreds of kilobytes to over a megabyte, versus a few kilobytes for lattice schemes. Security rests on the assumed hardness of decoding a random-looking linear code; the best classical attacks (information-set decoding) run in time exponential in , and known quantum speedups (via Grover-accelerated ISD) are only quadratic, so parameters need only modest inflation, not a change of algorithm family.
Hash-based signatures. Signing and verifying a Merkle tree of height costs hash evaluations for the authentication path plus for the one-time signature, where is the hash output length in bits (e.g., 256). SPHINCS+'s hypertree structure trades signature size (tens of kilobytes) for a stateless signer — no risk of catastrophic key reuse from state corruption, at the cost of speed and size. Correctness is immediate from hash-tree consistency: verification succeeds iff every hash on the path from leaf to root matches, which happens exactly when the signer possessed the correct leaf secret. Security reduces solely to the hash function's collision-resistance and (second-)preimage resistance — properties Grover's algorithm only weakens quadratically, meaning doubling the hash output length restores the original security margin. This is the most conservative of the three families precisely because it makes the fewest new assumptions.
Honest tradeoff summary. No PQC family is a strict improvement on RSA/ECC across every axis. Lattice schemes are fast and compact but rely on assumptions only ~20 years old (LWE, 2005) compared to RSA's 45+ years, and rely on structured variants (Ring-LWE, Module-LWE) whose extra algebraic structure is a theoretical (if not yet practical) attack surface. Code-based McEliece has the oldest track record but the largest keys. Hash-based signatures make the weakest assumptions but produce the largest signatures and, in stateful variants, require careful state management to avoid catastrophic reuse.
Worked example
Trace a small, illustrative (non-parameter-accurate) Module-LWE-style encapsulation with tiny numbers to make the arithmetic concrete. Use modulus , a single ring element treated as a plain integer (i.e., , no polynomial structure) purely to show the noise cancellation.
Setup (KeyGen).
| Quantity | Value |
|---|---|
| Public matrix element | 5 |
| Secret | 3 |
| Error | 1 |
| Public value |
Public key: . Secret key: .
Encapsulation. Alice wants to send shared-secret bit (encoded as , a standard "round to half the modulus" encoding).
| Step | Computation | Result |
|---|---|---|
| Sample | (random, small) | |
| Sample | (random, small) | |
| Sample | (random, small) | |
Ciphertext sent: .
Decapsulation. Bob computes :
Compare to the two possible encodings: (for ) or (for ). Since is closer to than to (distance 1 vs. distance 7, on the cyclic modulus), `decode` outputs — correct.
Why it worked. Expand algebraically:
The "signal" term survives, perturbed only by the small combined noise term , which is far smaller than , so rounding still recovers correctly. In real Kyber, , error terms are drawn from a centered binomial distribution, and the ring dimension is 256, but the cancellation mechanism is identical: the honest party's secret makes the large structured terms cancel, leaving only a small noise term that rounding can absorb, while an eavesdropper without sees values computationally indistinguishable from uniform random.
Common pitfalls & traps
| Pitfall | Why it happens | Consequence |
|---|---|---|
| Treating "post-quantum" as permanently secure | Conflating "resists known quantum algorithms" with "mathematically proven safe forever" | SIKE (isogeny-based) was a NIST finalist broken by a classical attack in 2022 |
| Reusing a hash-based one-time key (stateful schemes like XMSS/LMS) | Poor state management, VM snapshot/restore, key backup restoration | Total signature forgery — the classic Sony PS3 ECDSA-nonce-reuse mistake, analogue in hash-land |
| Assuming Grover breaks AES like Shor breaks RSA | Confusing quadratic speedup with exponential speedup | Unnecessary, costly over-engineering (or, in reverse, dangerous under-provisioning if the distinction is missed the other way) |
| Ignoring large public-key/signature sizes in protocol design | Porting TLS/certificate assumptions sized for RSA/ECC | Handshake fragmentation, MTU issues, certificate chain bloat with McEliece or SPHINCS+ |
| Using "textbook" LWE without proper error/parameter tuning | Rolling a custom implementation instead of using standardized parameter sets | Decryption failures, or worse, exploitable side channels leaking the secret |
| Skipping hybrid (classical + PQC) key exchange during migration | Assuming a new PQC scheme is drop-in ready | If the new scheme has an undiscovered flaw, the whole connection is broken; hybrid modes hedge this risk |
Pioneers & history
Origins · 1 minPeter Shor and how this was discovered
Where this matters
Web browsers and TLS libraries (Chrome, Firefox, BoringSSL, OpenSSL) have already deployed hybrid key exchange combining classical X25519 with ML-KEM (Kyber), so that a connection stays secure even if one of the two mechanisms is later broken. Signal and other secure-messaging protocols use similar hybrid PQC key agreement to defend against harvest-now-decrypt-later attacks on today's captured ciphertext. Governments — the U.S. National Security Agency's CNSA 2.0 suite, and equivalents in the EU and China — mandate migration timelines for classified and critical infrastructure systems. Hardware security modules, smart cards, and firmware/software update-signing systems are adopting SLH-DSA or ML-DSA for signatures where long-term trust in the algorithm matters more than signature size. Certificate authorities and the Web PKI are prototyping PQC-capable X.509 certificates, and cryptographic library maintainers (e.g., liboqs, OpenSSL 3.x providers) now ship ML-KEM and ML-DSA implementations as first-class options, marking one of the largest coordinated cryptographic migrations since the move from DES to AES.
Ask the tutor: How does the choice between ML-KEM, McEliece, and SPHINCS+ change if I'm designing a constrained IoT device versus a long-term software update signing system?
Does post-quantum cryptography require a quantum computer to use?
No. Post-quantum algorithms like ML-KEM, ML-DSA, and SLH-DSA run entirely on ordinary classical hardware — laptops, servers, smartphones, and embedded devices. "Post-quantum" describes the threat model the algorithm is designed to resist, not the hardware it runs on. This is different from quantum key distribution (QKD), which genuinely uses quantum physics (photon polarization, entanglement) during the protocol itself. PQC is a drop-in mathematical replacement for RSA and ECC inside existing classical protocols like TLS, SSH, and code-signing systems, which is precisely why it can be deployed today, years before any cryptographically relevant quantum computer exists.
If no large quantum computer exists yet, why migrate to post-quantum cryptography now?
The main driver is the "harvest now, decrypt later" attack: an adversary can record encrypted traffic today and decrypt it once a sufficiently powerful quantum computer becomes available, which could be years away but is not guaranteed to be decades away. Data with long confidentiality requirements — medical records, state secrets, long-term intellectual property — is at risk even under this uncertain timeline. Migrating cryptographic infrastructure across the entire internet (certificate authorities, hardware, protocols, libraries) is also a multi-year undertaking historically, so standards bodies push early adoption well before the threat materializes, mirroring the decade-long, still-incomplete migration away from SHA-1.
Are lattice-based schemes like ML-KEM proven secure?
Not in an absolute sense — no widely used public-key scheme has an unconditional security proof, including RSA. What lattice schemes offer is a reduction: breaking a random Module-LWE instance would imply an efficient algorithm for worst-case lattice problems, which decades of research (classical and quantum) have failed to solve efficiently in high dimensions. This is a strong theoretical guarantee, but it is conditional on the hardness assumption holding, and the specific structured variants used for efficiency (Module-LWE, Ring-LWE) introduce additional algebraic structure whose long-term cryptanalytic robustness is actively studied, though not yet threatened.
Why do code-based and hash-based schemes have such large keys or signatures compared to RSA or lattice schemes?
Code-based schemes like Classic McEliece must publish an entire scrambled generator matrix as the public key, since disguising a Goppa code's structure requires transmitting essentially the whole linear code — hundreds of kilobytes to over a megabyte. Hash-based signatures like SPHINCS+ must include the full Merkle authentication path (a chain of sibling hashes from leaf to root) plus a one-time signature per message, producing signatures of tens of kilobytes. This is the direct cost of making the fewest possible cryptographic assumptions: both schemes sacrifice compactness for extremely conservative, well-studied hardness foundations.
What is the difference between ML-KEM and ML-DSA?
ML-KEM (based on Kyber) is a key-encapsulation mechanism: two parties use it to agree on a shared symmetric key, analogous to what Diffie–Hellman or RSA key transport does today. ML-DSA (based on Dilithium) is a digital signature scheme, analogous to RSA-PSS or ECDSA, used to authenticate messages, certificates, or software updates. Both are lattice-based and standardized by NIST in 2024 (FIPS 203 and FIPS 204 respectively), but they solve different problems — confidentiality/key agreement versus authenticity/non-repudiation — and a complete PQC-secured system typically needs both, alongside a signature-only backup like SLH-DSA for defense-in-depth.
Could a quantum computer break lattice-based cryptography the way it breaks RSA?
No known quantum algorithm solves the lattice problems underlying ML-KEM or ML-DSA in polynomial time. Shor's algorithm works because factoring and discrete log reduce to period-finding in an abelian group, a structure the quantum Fourier transform exploits directly. LWE and SVP lack this clean periodic structure; the best known quantum algorithms for lattice problems are still exponential in the lattice dimension, offering at most modest constant-factor or sub-exponential improvements over the best classical lattice-reduction algorithms like BKZ. This is why lattice problems, rather than group-structured ones, form the foundation of essentially every major post-quantum standard.
What should a software engineer actually do to prepare systems for the post-quantum transition?
Start by inventorying where RSA, ECDSA, ECDH, and DH are used — TLS certificates, SSH keys, VPNs, code signing, and internal service-to-service authentication — since each has a different migration urgency. Prefer hybrid key exchange (classical algorithm plus ML-KEM) in any new TLS or messaging deployment, so security degrades gracefully rather than catastrophically if either component is later broken. Use vetted, standardized libraries (OpenSSL 3.x, liboqs, BoringSSL) rather than custom lattice or code-based implementations, since subtle parameter or side-channel mistakes are common. Finally, budget for larger key and signature sizes in protocol design, bandwidth, and storage planning well before a hard compliance deadline arrives.