Caloogy Blog
中文

Post-Quantum Cryptography Explained

Date
Oct 19, 2026
Series
Cryptography
Reading
21 min
Topics
Post quantumLatticeLWEKyber

The one-sentence version

With Shor's algorithm, a quantum computer can factor large integers and solve discrete logarithms in polynomial time, so RSA and elliptic curves (ECC) would be broken completely; for AES and hashes, Grover's algorithm can only "halve" the security, which longer keys can absorb. Post-quantum cryptography switches to mathematical problems quantum computers aren't good at either, and the mainstay is lattices: hiding the secret behind the tiny noise ee in b=As+e(modq)b = As + e \pmod q. In the language of abstract algebra, Kyber (ML-KEM) computes in the quotient ring Rq=Zq[x]/(x256+1)R_q = \mathbb{Z}_q[x]/(x^{256}+1), and its fast multiplication (the NTT) is a ring isomorphism given by the Chinese Remainder Theorem.

This article has three layers:

  1. The intuition: what quantum computers actually threaten, why we must switch now, and the intuition behind lattice cryptography
  2. Real-world use: NIST standards, real deployments in browsers, Signal, iMessage and SSH, migration timelines, blockchains
  3. The mathematics: lattices and SVP/CVP, LWE, Ring/Module-LWE, the full Kyber flow, NTT and CRT, hash-based signatures and worked examples

Layer 1: The Intuition

1.1 What today's cryptography rests on

Nearly every case of "strangers establishing a secure connection" relies on public-key cryptography:

Use Common algorithms The underlying hard problem
Key exchange (HTTPS handshake) RSA, ECDH (X25519) Integer factorization, the elliptic curve discrete logarithm
Digital signatures (certificates, software updates, Bitcoin transactions) RSA, ECDSA, Ed25519 Same as above
Encrypting large amounts of data AES No neat mathematical structure, only brute-force search
Digests, commitments SHA-256, SHA-3 Same as above

The security of public-key algorithms rests on one sentence: "This math problem would take a classical computer until the end of the universe." For example, factoring a 2048-bit number N=pqN = pq back into pp and qq with the best known classical algorithm (the number field sieve) takes roughly

exp⁡ ⁣(c (ln⁡N)1/3(ln⁡ln⁡N)2/3),\exp\!\Big(c\,(\ln N)^{1/3}(\ln\ln N)^{2/3}\Big),

which is completely infeasible for RSA-2048.

1.2 Shor's algorithm: RSA and ECC would be broken completely

In 1994, Peter Shor proved: a quantum computer can factor integers and solve discrete logarithms in polynomial time.

The intuition goes like this. Factoring NN reduces to finding the period of a function: take any aa and see how often

f(k)=ak mod Nf(k) = a^k \bmod N

repeats. Let the period be rr, so ar≡1(modN)a^r \equiv 1 \pmod N. If rr is even, then

(ar/2−1)(ar/2+1)≡0(modN),(a^{r/2}-1)(a^{r/2}+1) \equiv 0 \pmod N,

so gcd⁡(ar/2−1, N)\gcd(a^{r/2}-1,\,N) is very likely a proper factor of NN.

A classical computer can only find the period by trying values one by one; a quantum computer can put all kk in "superposition" and apply a quantum Fourier transform, and the period emerges like fringes from a diffraction grating. The elliptic curve discrete logarithm is also a "hidden period" problem, falls the same way, and needs even fewer qubits than RSA.

This isn't "slower", it's "zero"

Shor's algorithm doesn't shorten cracking time from 103010^{30} years to 102010^{20} years; it drops from exponential to polynomial time. Lengthening an RSA key from 2048 to 4096 bits barely helps, and it can only be replaced entirely. Resource estimates keep falling: Craig Gidney's 2025 estimate is that RSA-2048 could be factored with fewer than a million noisy physical qubits in about a week. Today's largest quantum computers are still far from this, but ten years ago this number was "on the order of a billion".

1.3 Grover's algorithm: AES is only weakened

Symmetric ciphers (AES) and hashes (SHA-256) have no algebraic structure for Shor to exploit, leaving a quantum computer with "unstructured search". Grover's algorithm reduces the time to find an answer among NN candidates from NN to about N\sqrt{N}:

2128  ⟶  2128=264.2^{128} \;\longrightarrow\; \sqrt{2^{128}} = 2^{64}.

So under quantum attack AES-128 "nominally" has only 64 bits of security left. But this is only a quadratic speedup:

Algorithm Classical security Quantum attack Security under quantum attack Response
RSA-2048 About 21122^{112} Shor Breakable in polynomial time Switch to post-quantum algorithms
ECC P-256 / X25519 About 21282^{128} Shor Breakable in polynomial time Switch to post-quantum algorithms
AES-128 21282^{128} Grover About 2642^{64} (in theory) Switch to AES-256
AES-256 22562^{256} Grover About 21282^{128} No change needed
SHA-256 (preimage resistance) 22562^{256} Grover About 21282^{128} No change needed

The conclusion: what really must be replaced is public-key cryptography, namely key exchange and digital signatures.

1.4 "Harvest now, decrypt later": why we must switch now

Quantum computers haven't been built yet, so why the rush to switch in 2024? Because one attack is already happening today:

Harvest Now, Decrypt Later

Attackers are recording and storing encrypted network traffic right now. They can't decrypt it today, but once quantum computers exist in a decade or two, they can use Shor's algorithm to break that era's key exchanges and read everything.

TodayYou set up an HTTPSor chat connectionwith RSA / ECDHAn attacker records allthe ciphertext ontodiskYears laterLarge-scale quantumcomputers appearCrackedShor's algorithmrecovers session keysfrom handshakerecordsThat era's medicalrecords, diplomaticcables and tradesecrets are all exposedHarvest now, decrypt later

A classic inequality (Mosca's inequality) measures the danger. Let

If

x+y>z,x + y > z,

then you are already late. Medical records, state secrets and genomic data easily have xx of several decades, and large institutions often need yy of ten years, so even zz of 15 years isn't safe.

Note that the two uses differ in urgency:

1.5 The intuition of lattice cryptography: finding the nearest point in a high-dimensional grid

Post-quantum cryptography has several schools (lattices, hashes, codes, multivariate, isogenies), and lattice cryptography is by far the mainstay.

A lattice is a neatly arranged array of points in space. In the plane, take two vectors b1,b2b_1, b_2. All their integer combinations

{ a1b1+a2b2  :  a1,a2∈Z }\{\, a_1 b_1 + a_2 b_2 \;:\; a_1, a_2 \in \mathbb{Z} \,\}

form a lattice, which looks like a sheet of slanted graph paper.

A lattice can be generated by many different "bases":

The closest vector problem (CVP): given any point in space, find the lattice point nearest to it.

In two dimensions you can do it by eye, but raise the dimension to 500 or 1000, and no one knows how to do it efficiently. The best known algorithms (classical or quantum) all need exponential time.

The basic recipe of lattice cryptography

  • Private key = a good basis (or a "small" secret); public key = a bad basis (or data mixed with noise).
  • Encryption: pick a lattice point (encoding the message) and add a little noise, moving it slightly off the lattice point.
  • Decryption: the private-key holder can find the nearest lattice point and remove the noise; anyone else faces high-dimensional CVP.

Why can't quantum computers help? Shor's algorithm relies on algebraic structure like a "hidden period", and lattice problems have no period to exploit directly. People have looked for quantum lattice algorithms for decades, and the best give only constant-factor improvements. This is also why NIST chose lattices as the mainstay.


Layer 2: Real-World Use

2.1 The results of NIST standardization

The US National Institute of Standards and Technology (NIST) began publicly soliciting post-quantum algorithms in 2016, received 82 proposals, and after more than three rounds of public analysis published the first three official standards on August 13, 2024:

Standard Name Original proposal Use Mathematical basis
FIPS 203 ML-KEM CRYSTALS-Kyber Key encapsulation (replacing ECDH / RSA encryption) Module-LWE (lattices)
FIPS 204 ML-DSA CRYSTALS-Dilithium Digital signatures (the general first choice) Module-LWE / Module-SIS (lattices)
FIPS 205 SLH-DSA SPHINCS+ Digital signatures (a conservative backup) Depends only on hash functions
FIPS 206 (draft) FN-DSA Falcon Digital signatures (shorter) NTRU lattices
FIPS 207 (planned) HQC-KEM HQC Key encapsulation (a backup) Error-correcting codes

Where each algorithm fits:

Size comparison (in bytes):

Scheme Public key Ciphertext / signature Comparison
X25519 32 32 Classical ECDH
ML-KEM-768 1184 1088 About 35 times bigger, but computes even faster than X25519
Ed25519 32 64 Classical signature
ML-DSA-65 1952 3309 Signature about 50 times bigger
FN-DSA-512 897 About 666 Much smaller than ML-DSA
SLH-DSA-128s 32 7856 Tiny public key, very large signature

Why "KEM" rather than "encryption"?

A KEM (Key Encapsulation Mechanism) doesn't encrypt arbitrary messages. It does one thing: both parties securely obtain the same random 32-byte shared key, then use a symmetric algorithm like AES to encrypt the actual data. This is exactly what an HTTPS handshake needs.

2.2 Why "hybrid"

Nearly all real deployments don't simply replace X25519 with ML-KEM, but use both together:

K=KDF(KX25519 ∥ KML-KEM).K = \mathrm{KDF}\big(K_{\text{X25519}} \,\|\, K_{\text{ML-KEM}}\big).

An attacker must break both at once to get KK:

This caution has been earned: in 2022, the NIST round-4 candidate SIKE (isogeny cryptography) was broken by an ordinary laptop within an hour, and the signature candidate Rainbow (multivariate) was also broken that year. New mathematical problems need time to prove themselves.

2.3 Real deployments

Still in progress

Post-quantum signatures for certificates / PKI

Blockchain addresses and signatures

Deployed at scale

Chrome / Firefox / Safari
TLS: X25519MLKEM768

Cloudflare
over half of human traffic

Signal
PQXDH + SPQR

iMessage
PQ3

OpenSSH 10
mlkem768x25519-sha256 default

Browsers and TLS (HTTPS)

Signal

Apple iMessage PQ3 (February 2024, iOS 17.4)

OpenSSH

2.4 Migration timelines

Body Key milestones
NIST IR 8547 (November 2024 draft) RSA / ECC at 112-bit security: deprecated after 2030, disallowed after 2035
US NSA CNSA 2.0 National security systems: software signing, network equipment and so on prefer or use only post-quantum algorithms between 2025 and 2030, with full completion targeted around 2033–2035
EU coordinated roadmap (2025) Begin migrating by the end of 2026, complete critical infrastructure by 2030, and the rest as far as possible by 2035
UK NCSC Finish discovery by 2028, priority migration by 2031, everything by 2035

In short, 2035 is the nearly universal deadline for "retiring RSA/ECC".

"Crypto agility"

The biggest lesson of this migration: many systems hard-coded RSA in code, hardware and protocol formats, and changing an algorithm takes years. New systems should be designed so algorithms are replaceable.

2.5 The threat to blockchains

Blockchains are especially sensitive to quantum attacks, because signatures are ownership, and historical data is public forever.

Bitcoin

Ethereum

Proof of work itself (SHA-256 mining) faces only Grover's quadratic speedup, and the clock speed of quantum computers is far below ASIC miners, so it isn't a problem in the short term.


Layer 3: The Mathematics

3.1 Lattices, SVP and CVP

Definition (lattice)

Let b1,…,bn∈Rnb_1,\dots,b_n \in \mathbb{R}^n be linearly independent. The lattice they generate is L(B)={∑i=1naibi  :  ai∈Z}={ Ba:a∈Zn },\mathcal{L}(B) = \Big\{ \sum_{i=1}^n a_i b_i \;:\; a_i \in \mathbb{Z} \Big\} = \{\, Ba : a \in \mathbb{Z}^n \,\}, where B=[ b1∣⋯∣bn ]B = [\,b_1 \mid \cdots \mid b_n\,] is called a basis of the lattice.

In algebraic language, a lattice is a discrete additive subgroup of rank nn in Rn\mathbb{R}^n, isomorphic to Zn\mathbb{Z}^n as a Z\mathbb{Z}-module.

The same lattice has many bases: BB and B′B' generate the same lattice if and only if there is U∈GLn(Z)U \in GL_n(\mathbb{Z}) (an integer matrix with determinant ±1\pm 1) with B′=BUB' = BU. So ∣det⁡B∣|\det B| doesn't depend on the choice of basis; it is the lattice's "fundamental region volume".

Two core hard problems:

Known results:

What cryptography actually relies on is the hardness of SVP with polynomial approximation factors (GapSVP, SIVP).

3.2 LWE: learning with errors

Building cryptosystems directly from lattice bases (GGH, early NTRU variants) is rather inconvenient. In 2005 Oded Regev proposed an "algebraized" version: Learning With Errors (LWE).

Definition (LWE)

Take an integer nn and a modulus qq. Randomly choose a secret vector s∈Zqns \in \mathbb{Z}_q^n. Give mm samples b=As+e(modq),b = As + e \pmod q, where A∈Zqm×nA \in \mathbb{Z}_q^{m\times n} is uniformly random and each component of e∈Zme \in \mathbb{Z}^m is very small (say from {−2,…,2}\{-2,\dots,2\} or a narrow discrete Gaussian).

  • Search-LWE: given (A,b)(A, b), find ss.
  • Decision-LWE: distinguish (A, As+e)(A,\, As+e) from (A, u)(A,\, u), where uu is uniformly random.

Why is ee the key? Without ee, b=Asb = As is a system of linear equations, solved for ss in a few steps by Gaussian elimination over Zq\mathbb{Z}_q (a field when qq is prime). With a little noise added:

Regev's theorem (2005, briefly)

If an efficient algorithm solves LWE (with suitable parameters), then a quantum algorithm approximately solves GapSVP and SIVP on nn-dimensional lattices in the worst case.

This "worst-case to average-case" reduction is very strong: breaking a randomly generated LWE instance means being able to solve hard problems on all lattices. RSA has no such guarantee.

From LWE to public-key encryption (Regev's scheme, encrypting one bit):

3.3 A worked example: toy LWE encrypting one bit

Parameters

Take n=2n = 2, m=4m = 4 and q=17q = 17, so ⌊q/2⌋=8\lfloor q/2 \rfloor = 8.

  • Private key: s=(25)s = \begin{pmatrix} 2 \\ 5 \end{pmatrix}
  • Random matrix and errors: A=(375111429),e=(1−101).A = \begin{pmatrix} 3 & 7 \\ 5 & 1 \\ 11 & 4 \\ 2 & 9 \end{pmatrix}, \qquad e = \begin{pmatrix} 1 \\ -1 \\ 0 \\ 1 \end{pmatrix}.

Step 1: generate the public key. First compute AsAs:

As=(3⋅2+7⋅55⋅2+1⋅511⋅2+4⋅52⋅2+9⋅5)=(41154249)≡(715815)(mod17).As = \begin{pmatrix} 3\cdot 2 + 7\cdot 5 \\ 5\cdot 2 + 1\cdot 5 \\ 11\cdot 2 + 4\cdot 5 \\ 2\cdot 2 + 9\cdot 5 \end{pmatrix} = \begin{pmatrix} 41 \\ 15 \\ 42 \\ 49 \end{pmatrix} \equiv \begin{pmatrix} 7 \\ 15 \\ 8 \\ 15 \end{pmatrix} \pmod{17}.

Then add the errors:

b=As+e≡(7+115−18+015+1)=(814816)(mod17).b = As + e \equiv \begin{pmatrix} 7+1 \\ 15-1 \\ 8+0 \\ 15+1 \end{pmatrix} = \begin{pmatrix} 8 \\ 14 \\ 8 \\ 16 \end{pmatrix} \pmod{17}.

Publish (A,b)(A, b) and keep ss secret.

What if there were no errors?

The public key would be b′=(7,15,8,15)Tb' = (7, 15, 8, 15)^{\mathsf T}. An attacker takes the first two equations 3s1+7s2≡7,5s1+s2≡15(mod17),3s_1 + 7s_2 \equiv 7, \qquad 5s_1 + s_2 \equiv 15 \pmod{17}, The second gives s2≡15−5s1s_2 \equiv 15 - 5s_1, and substituting into the first gives 3s1+105−35s1≡73s_1 + 105 - 35 s_1 \equiv 7, that is −32s1≡−98-32 s_1 \equiv -98, which simplifies to 2s1≡4(mod17)2s_1 \equiv 4 \pmod{17}, so s1=2s_1 = 2 and s2=5s_2 = 5. The secret is exposed at once. With errors, the four equations are mutually "inconsistent", and elimination results are polluted by noise. At n=2n=2 you can still enumerate all 172=28917^2 = 289 possibilities, but real nn is in the hundreds, and the enumeration is on the order of qnq^{n}.

Step 2: encrypt the bit μ=1\mu = 1. Randomly choose r=(1,0,1,1)Tr = (1, 0, 1, 1)^{\mathsf T}, which adds samples 1, 3 and 4:

u=ATr=(3+11+27+4+9)=(1620)≡(163)(mod17),u = A^{\mathsf T} r = \begin{pmatrix} 3 + 11 + 2 \\ 7 + 4 + 9 \end{pmatrix} = \begin{pmatrix} 16 \\ 20 \end{pmatrix} \equiv \begin{pmatrix} 16 \\ 3 \end{pmatrix} \pmod{17},

v=bTr+8=(8+8+16)+8=40≡6(mod17).v = b^{\mathsf T} r + 8 = (8 + 8 + 16) + 8 = 40 \equiv 6 \pmod{17}.

The ciphertext is (u,v)=((16,3)T,  6)(u, v) = \big((16, 3)^{\mathsf T},\; 6\big).

Step 3: decrypt. With the private key, compute

uTs=16⋅2+3⋅5=47≡13(mod17),u^{\mathsf T} s = 16\cdot 2 + 3 \cdot 5 = 47 \equiv 13 \pmod{17},

d=v−uTs=6−13=−7≡10(mod17).d = v - u^{\mathsf T} s = 6 - 13 = -7 \equiv 10 \pmod{17}.

The decision rule: in Z17\mathbb{Z}_{17}, the values close to 00 are {13,…,16,0,1,…,4}\{13,\dots,16, 0, 1, \dots, 4\}, and those close to 88 are {5,…,12}\{5, \dots, 12\}. d=10d = 10 is only 22 from 88, so it decrypts to 11 ✓.

Checking the theory: eTr=1+0+1=2e^{\mathsf T} r = 1 + 0 + 1 = 2, and indeed

d=eTr+8=2+8=10.d = e^{\mathsf T} r + 8 = 2 + 8 = 10.

For comparison: encrypt μ=0\mu = 0. With the same rr, uu is unchanged and v=32≡15v = 32 \equiv 15, so d=15−13=2d = 15 - 13 = 2, close to 00, which decrypts to 00 ✓.

Why is it always correct? The absolute values of the components of ee sum to 33, so for any r∈{0,1}4r \in \{0,1\}^4 we have ∣eTr∣≤3<17/4|e^{\mathsf T} r| \le 3 < 17/4, and decryption never fails. (Verified with Python by enumerating all 242^4 values of rr and both bits.)

The scale of real parameters

In this example n=2n=2, and an attacker can break it by brute force. ML-KEM-768 is equivalent to n=768n = 768, q=3329q = 3329; brute force would take 33297683329^{768} operations, and the best lattice algorithm (BKZ) still takes about 21802^{180}.

3.4 Ring-LWE and Module-LWE

Plain LWE has a big problem: the public key is too large. The matrix AA has m×nm \times n elements, hundreds of thousands of numbers at n=768n = 768, for a public key of hundreds of KB.

The idea of Ring-LWE: give AA structure, replacing the whole matrix with one polynomial.

Take the quotient ring

Rq=Zq[x]/(xn+1),R_q = \mathbb{Z}_q[x] / (x^n + 1),

whose elements are polynomials of degree <n< n with coefficients in Zq\mathbb{Z}_q, simplified after multiplication with xn=−1x^n = -1. In the language of abstract algebra, RqR_q is the quotient of Z[x]\mathbb{Z}[x] by the ideal (q,  xn+1)(q,\; x^n+1):

Rq  ≅  Z[x]/(q,  xn+1).R_q \;\cong\; \mathbb{Z}[x] / (q,\; x^n + 1).

In RqR_q, "multiplying by a(x)a(x)" is a Zq\mathbb{Z}_q-linear map, corresponding to an n×nn\times n matrix:

a(x)⋅s(x)⟷(a0−an−1⋯−a1a1a0⋯−a2⋮⋮⋱⋮an−1an−2⋯a0)(s0s1⋮sn−1).a(x) \cdot s(x) \quad\longleftrightarrow\quad \begin{pmatrix} a_0 & -a_{n-1} & \cdots & -a_1 \\ a_1 & a_0 & \cdots & -a_2 \\ \vdots & \vdots & \ddots & \vdots \\ a_{n-1} & a_{n-2} & \cdots & a_0 \end{pmatrix} \begin{pmatrix} s_0 \\ s_1 \\ \vdots \\ s_{n-1} \end{pmatrix}.

This is called a negacyclic matrix: each column is the previous one "rotated down by one", with the element wrapping to the top changing sign, because x⋅xn−1=xn=−1x \cdot x^{n-1} = x^n = -1. The whole matrix is determined by nn numbers, so storage drops from n2n^2 to nn.

Ring-LWE

Given uniformly random a∈Rqa \in R_q and s,e∈Rqs, e \in R_q with small coefficients, distinguish (a,  as+e)(a,\; as + e) from (a,  u)(a,\; u).

Why xn+1x^n + 1? Take n=2kn = 2^k. Then

xn+1=Φ2n(x)x^n + 1 = \Phi_{2n}(x)

is the 2n2n-th cyclotomic polynomial (its complex roots are exactly all the primitive 2n2n-th roots of unity eπi(2j+1)/ne^{\pi i (2j+1)/n}). There are several reasons to choose it:

  1. It is irreducible over Q\mathbb{Q} (for Φ2k+1\Phi_{2^{k+1}}, apply Eisenstein's criterion to f(x+1)f(x+1) with p=2p=2). So Z[x]/(xn+1)\mathbb{Z}[x]/(x^n+1) is the ring of integers of the cyclotomic field Q(ζ2n)\mathbb{Q}(\zeta_{2n}). Lyubashevsky, Peikert and Regev (2010) used exactly this algebraic number theory structure to reduce the hardness of Ring-LWE to worst-case hard problems on ideal lattices.
  2. Irreducibility matters. A counterexample: with xn−1=(x−1)(⋯ )x^n - 1 = (x-1)(\cdots), there is a ring homomorphism Zq[x]/(xn−1)→Zq,f(x)↦f(1).\mathbb{Z}_q[x]/(x^n - 1) \to \mathbb{Z}_q, \qquad f(x) \mapsto f(1). Substituting x=1x = 1 into both sides of b=as+eb = as + e gives b(1)=a(1)s(1)+e(1)b(1) = a(1)s(1) + e(1). This is a small problem with just 1 unknown, and e(1)e(1) is fairly small, leaking enough information to mount an attack.
  3. Reduction is cheap: with xn≡−1x^n \equiv -1, modular reduction just flips the sign of high-degree terms and adds them back to low-degree ones. Coefficients also don't swell during reduction (the "expansion factor" is small), keeping errors small.
  4. It suits the NTT: when q≡1(mod2n)q \equiv 1 \pmod{2n} (or (modn)\pmod n), xn+1x^n+1 factors over Zq\mathbb{Z}_q, and multiplication can be accelerated with the NTT (see 3.6).

Module-LWE: between the two. Ring-LWE's structure is too "full", and Module-LWE steps back a little, using a k×kk \times k matrix of ring elements

A∈Rqk×k,s,e∈Rqk,t=As+e.\mathbf{A} \in R_q^{k\times k}, \qquad \mathbf{s}, \mathbf{e} \in R_q^{k}, \qquad \mathbf{t} = \mathbf{A}\mathbf{s} + \mathbf{e}.

This is LWE on the RqR_q-module RqkR_q^k, hence the name. The benefits:

Parameter set kk Equivalent LWE dimension nknk NIST security level
ML-KEM-512 2 512 1 (about AES-128)
ML-KEM-768 3 768 3 (about AES-192)
ML-KEM-1024 4 1024 5 (about AES-256)

All three use n=256n = 256 and q=3329q = 3329.

3.5 The flow of Kyber (ML-KEM)

Notation: Rq=Zq[x]/(x256+1)R_q = \mathbb{Z}_q[x]/(x^{256}+1) and q=3329q = 3329. The coefficients of "small" polynomials are sampled from a centered binomial distribution βη\beta_\eta, with values in {−η,…,η}\{-\eta, \dots, \eta\}; ML-KEM-768 has η=2\eta = 2.

Key generation

  1. Take a random seed ρ\rho and expand it with SHAKE128 into the matrix A∈Rqk×k\mathbf{A} \in R_q^{k\times k} (so the public key stores only the 32-byte ρ\rho, not the whole matrix).
  2. Sample small s,e∈Rqk\mathbf{s}, \mathbf{e} \in R_q^k.
  3. Compute t=As+e\mathbf{t} = \mathbf{A}\mathbf{s} + \mathbf{e}.
  4. The public key is pk=(ρ,t)\mathrm{pk} = (\rho, \mathbf{t}) and the private key is sk=s\mathrm{sk} = \mathbf{s}.

Encryption (the message mm is 256 bits, viewed as a polynomial with 0/10/1 coefficients)

  1. Sample small r,e1∈Rqk\mathbf{r}, \mathbf{e}_1 \in R_q^k and small e2∈Rqe_2 \in R_q.
  2. Compute u=ATr+e1,v=tTr+e2+⌈q2⌋⋅m.\mathbf{u} = \mathbf{A}^{\mathsf T}\mathbf{r} + \mathbf{e}_1, \qquad v = \mathbf{t}^{\mathsf T}\mathbf{r} + e_2 + \left\lceil \tfrac{q}{2} \right\rfloor \cdot m.
  3. Compress the coefficients of u,v\mathbf{u}, v (keeping only the high bits), and output the ciphertext c=(u,v)c = (\mathbf{u}, v).

Decryption

v−sTu=eTr+e2−sTe1⏟small noise  +  ⌈q2⌋⋅m.v - \mathbf{s}^{\mathsf T}\mathbf{u} = \underbrace{\mathbf{e}^{\mathsf T}\mathbf{r} + e_2 - \mathbf{s}^{\mathsf T}\mathbf{e}_1}_{\text{small noise}} \;+\; \left\lceil \tfrac{q}{2} \right\rfloor \cdot m . Round each coefficient: close to 00 gives 00, close to q/2≈1665q/2 \approx 1665 gives 11, recovering mm.

The derivation uses only t=As+e\mathbf{t} = \mathbf{A}\mathbf{s}+\mathbf{e} and the commutativity of RqR_q:

tTr−sTATr=(As)Tr+eTr−sTATr=eTr.\mathbf{t}^{\mathsf T}\mathbf{r} - \mathbf{s}^{\mathsf T}\mathbf{A}^{\mathsf T}\mathbf{r} = (\mathbf{A}\mathbf{s})^{\mathsf T}\mathbf{r} + \mathbf{e}^{\mathsf T}\mathbf{r} - \mathbf{s}^{\mathsf T}\mathbf{A}^{\mathsf T}\mathbf{r} = \mathbf{e}^{\mathsf T}\mathbf{r}.

This has exactly the same structure as the toy example in 3.3, with "integers" replaced by "polynomials in RqR_q", encrypting 256 bits at once instead of 1.

BobAliceBobAliceSample small s, et = A s + ePick random 32-byte mu = A^T r + e1v = t^T r + e2 + round(q/2) mRound v - s^T u to get mBoth derive the shared key K from m with a hashPublic key (rho, t)Ciphertext (u, v)

From "encryption" to "KEM": the Fujisaki–Okamoto transform

The scheme above only resists passive attacks (IND-CPA). ML-KEM wraps it in an FO transform: the randomness r,e1,e2\mathbf{r}, \mathbf{e}_1, e_2 for encryption is generated deterministically from a hash of mm and the public key; after recovering mm, the decrypting party re-encrypts and checks that it gets the same ciphertext, outputting a pseudorandom key if not ("implicit rejection"). This resists chosen-ciphertext attacks (IND-CCA2).

3.6 NTT: accelerating multiplication with the Chinese Remainder Theorem

The main computation in Kyber is polynomial multiplication in RqR_q. Direct multiplication needs 2562=65536256^2 = 65536 coefficient multiplications, and the NTT (number theoretic transform) reduces this to the order of O(nlog⁡n)O(n\log n). The NTT is the FFT over a finite field, and the mathematics behind it is the Chinese Remainder Theorem from abstract algebra.

The Chinese Remainder Theorem (polynomial ring version)

Let FF be a field and f=f1f2⋯frf = f_1 f_2 \cdots f_r, with the fif_i pairwise coprime. Then there is a ring isomorphism F[x]/(f)  →  ∼    F[x]/(f1)×⋯×F[x]/(fr),g↦(g mod f1,  …,  g mod fr).F[x]/(f) \;\xrightarrow{\;\sim\;}\; F[x]/(f_1) \times \cdots \times F[x]/(f_r), \qquad g \mapsto (g \bmod f_1,\; \dots,\; g \bmod f_r). Coprimality guarantees the ideals (fi)(f_i) are pairwise coprime ((fi)+(fj)=F[x](f_i) + (f_j) = F[x]), which is exactly the CRT's condition.

The key point: multiplication on the right side of the isomorphism is componentwise. So to compute g⋅hg \cdot h, you can:

  1. Map g,hg, h to the right side (forward NTT);
  2. Multiply componentwise (cheap);
  3. Map back to the left side (inverse NTT).

Steps 1 and 3 can recursively split in half like the FFT, using x2m−c2=(xm−c)(xm+c)x^{2m} - c^2 = (x^m - c)(x^m + c), in log⁡n\log n levels in all.

First, a small example: Z17[x]/(x4+1)\mathbb{Z}_{17}[x]/(x^4+1).

Because 17≡1(mod8)17 \equiv 1 \pmod 8, Z17×\mathbb{Z}_{17}^\times (a cyclic group of order 1616) contains primitive 8th roots of unity, so x4+1x^4 + 1 factors completely over Z17\mathbb{Z}_{17}. Its four roots are 2,8,9,152, 8, 9, 15 (for example 24=16≡−12^4 = 16 \equiv -1). So

Z17[x]/(x4+1)  ≅  Z17[x]/(x−2)×Z17[x]/(x−8)×Z17[x]/(x−9)×Z17[x]/(x−15)  ≅  Z174,\mathbb{Z}_{17}[x]/(x^4+1) \;\cong\; \mathbb{Z}_{17}[x]/(x-2) \times \mathbb{Z}_{17}[x]/(x-8) \times \mathbb{Z}_{17}[x]/(x-9) \times \mathbb{Z}_{17}[x]/(x-15) \;\cong\; \mathbb{Z}_{17}^4,

and the isomorphism is evaluation, g↦(g(2),g(8),g(9),g(15))g \mapsto \big(g(2), g(8), g(9), g(15)\big).

Take f=1+2x+x3f = 1 + 2x + x^3 and g=3+x2g = 3 + x^2. Computing directly (with x4=−1x^4 = -1, x5=−xx^5 = -x):

fg=3+6x+x2+5x3+x5=3+5x+x2+5x3.fg = 3 + 6x + x^2 + 5x^3 + x^5 = 3 + 5x + x^2 + 5x^3.

Verifying by evaluation:

Point aa f(a)f(a) g(a)g(a) f(a)g(a) mod 17f(a)g(a) \bmod 17 (fg)(a)(fg)(a)
22 1313 77 66 66
88 22 1616 1515 1515
99 00 1616 00 00
1515 66 77 88 88

A perfect match. Note in passing that f(9)=0f(9) = 0: ff isn't the zero polynomial yet vanishes on one component, so ff is a zero divisor in this ring. This shows RqR_q isn't an integral domain, which is the same fact as "x4+1x^4+1 is reducible over Z17\mathbb{Z}_{17}".

Back to Kyber: q=3329q = 3329 and q−1=3328=28⋅13q - 1 = 3328 = 2^8 \cdot 13.

x256+1=∏i=0127(x2−ζi),ζi=ζ 2 br7(i)+1,x^{256} + 1 = \prod_{i=0}^{127} \big(x^2 - \zeta_i\big), \qquad \zeta_i = \zeta^{\,2\,\mathrm{br}_7(i)+1},

where br7(i)\mathrm{br}_7(i) reverses the 7-bit binary representation of ii (just for the order of the FFT recursion). These 128 values ζi\zeta_i are exactly all the roots of y128=−1y^{128} = -1. By the CRT:

Rq=Zq[x]/(x256+1)  ≅  ∏i=0127Zq[x]/(x2−ζi).R_q = \mathbb{Z}_q[x]/(x^{256}+1) \;\cong\; \prod_{i=0}^{127} \mathbb{Z}_q[x]/(x^2 - \zeta_i).

Going further: x2−ζix^2 - \zeta_i is irreducible over Zq\mathbb{Z}_q. If ζi=y2\zeta_i = y^2, then yy would have order 512512, and no such element exists. So each factor is a field Fq2\mathbb{F}_{q^2}, and

Rq  ≅  Fq2×⋯×Fq2⏟128 copies.R_q \;\cong\; \underbrace{\mathbb{F}_{q^2} \times \cdots \times \mathbb{F}_{q^2}}_{128\text{ copies}}.

In the NTT domain, multiplying two polynomials becomes 128 "linear polynomial multiplications modulo x2−ζix^2 - \zeta_i":

(a0+a1x)(b0+b1x)≡(a0b0+ζi a1b1)+(a0b1+a1b0) x(modx2−ζi).(a_0 + a_1 x)(b_0 + b_1 x) \equiv (a_0 b_0 + \zeta_i\, a_1 b_1) + (a_0 b_1 + a_1 b_0)\, x \pmod{x^2 - \zeta_i}.

The engineering elegance

  • Kyber specifies that A\mathbf{A} is sampled directly in the NTT domain, and the public key t\mathbf{t} is also stored in NTT form, saving many forward and inverse transforms.
  • ML-DSA uses q=8380417q = 8380417, which satisfies q≡1(mod512)q \equiv 1 \pmod{512}, so x256+1x^{256}+1 factors completely into 256 linear factors, and the NTT splits all the way down.
  • This also explains why ML-KEM is even faster than X25519: the NTT and integer arithmetic with a small modulus are very efficient on CPUs.

3.7 The signature idea of ML-DSA (briefly)

ML-DSA (Dilithium) uses "Fiat–Shamir with aborts":

  1. Commit: randomly choose a small y\mathbf{y} and compute the high bits w1\mathbf{w}_1 of w=Ay\mathbf{w} = \mathbf{A}\mathbf{y}.
  2. Challenge: c=H(message ∥ w1)c = H(\text{message} \,\|\, \mathbf{w}_1), a sparse polynomial with only a few coefficients of ±1\pm 1.
  3. Respond: z=y+c s1\mathbf{z} = \mathbf{y} + c\,\mathbf{s}_1.
  4. Abort check: if the coefficients of z\mathbf{z} are too large (which might leak information about s1\mathbf{s}_1), discard and retry. By rejection sampling, the distribution of z\mathbf{z} is independent of the private key.

The verifier checks that the high bits of Az−c t\mathbf{A}\mathbf{z} - c\,\mathbf{t} equal w1\mathbf{w}_1, and that z\mathbf{z} is small enough. Security rests on Module-LWE and Module-SIS (finding a short vector x\mathbf{x} with Ax=0\mathbf{A}\mathbf{x} = 0).

3.8 Hash-based signatures: from Lamport to SPHINCS+

The security of hash-based signatures depends only on the one-wayness and collision resistance of a hash function, with no algebraic structure at all. It is the most conservative approach.

Lamport one-time signatures (1979): let HH output 256 bits.

Forging a signature requires a hash preimage of some yi,by_{i,b}. But each key can be used only once: signing two messages exposes parts of both sides of the private key, and an attacker can assemble a new signature.

The line of improvements:

Lamport
one-time, signature about 8 KB

Winternitz (WOTS)
hash chains compress signatures

Merkle trees (XMSS / LMS)
2^h one-time keys
requires tracking state

SPHINCS+ / SLH-DSA
hypertree + FORS
stateless


Summary

Shor

Grover

Quantum computers

RSA / ECC / pairing SNARKs
completely broken

AES / SHA
security halved; longer keys suffice

Post-quantum replacements

ML-KEM (Kyber)
key exchange

ML-DSA (Dilithium)
signatures

SLH-DSA (SPHINCS+)
conservative signatures

Module-LWE
R_q = Z_q[x]/(x^256+1)

NTT = CRT ring isomorphism
fast multiplication

Depends only on hash functions

Layer Key points
Intuition Shor takes RSA/ECC to zero, while Grover only halves AES; "harvest now, decrypt later" makes migration urgent; lattice cryptography = finding the nearest point in high-dimensional space
Real-world use FIPS 203/204/205 in 2024; Chrome, Cloudflare, Signal, iMessage and OpenSSH already use hybrid ML-KEM by default; 2035 is the retirement line for RSA/ECC
Mathematics LWE: b=As+eb = As + e, where the noise ee defeats linear algebra; Rq=Zq[x]/(x256+1)R_q = \mathbb{Z}_q[x]/(x^{256}+1) compresses public keys; the NTT is the CRT isomorphism Rq≅∏Zq[x]/(x2−ζi)R_q \cong \prod \mathbb{Z}_q[x]/(x^2 - \zeta_i)

The connection to abstract algebra

  • Quotient rings: Rq=Z[x]/(q,x256+1)R_q = \mathbb{Z}[x]/(q, x^{256}+1)
  • Irreducible polynomials: xn+1x^n+1 is irreducible over Q\mathbb{Q} and reducible over Zq\mathbb{Z}_q; the latter is exactly why the NTT works
  • Ring homomorphisms: the evaluation map f↦f(1)f \mapsto f(1) explains why xn−1x^n - 1 can't be used
  • The Chinese Remainder Theorem: the entire mathematical content of the NTT
  • Zero divisors: RqR_q isn't an integral domain, as in the example with f(9)=0f(9) = 0
  • Finite fields: each CRT component Zq[x]/(x2−ζi)≅Fq2\mathbb{Z}_q[x]/(x^2 - \zeta_i) \cong \mathbb{F}_{q^2}