ML-KEM & ML-DSA, on a lattice
Both new NIST post-quantum standards live on the same mathematical object: a lattice. The hard problem isn't factoring or discrete logs (Shor's algorithm crushes both). It's finding short vectors in a high-dimensional grid riddled with deliberate noise. Build the intuition in 2D, encrypt a single bit Regev-style, then bridge to the real specs through a Schnorr signature.
lattices and the LWE problem
post-quantumAn infinite grid of points
Pick two vectors. Take every integer combination of them. That set of points is a lattice. A 2D lattice looks like graph paper if your vectors are nice and orthogonal, or a skewed mess if they're not.
Real ML-KEM uses lattices in 256+ dimensions. The math is identical; your intuition just stops working past about 4 dimensions.
Closest vector, with noise
Given a target point off the lattice, finding the closest lattice point — the closest vector problem — is provably hard in high dimensions. There's no known classical or quantum algorithm that solves it efficiently.
That hardness is what every lattice-based cryptosystem rests on. ML-KEM hides a secret inside a noisy lattice point; only the key owner has the "shortcut" needed to recover it.
Both bases generate the exact same lattice — every integer combination of the orthogonal pair is also reachable by an integer combination of the skewed pair, and vice versa. The points on screen don't change when you toggle.
What changes is how easy the closest-vector search looks. With the orthogonal basis, you'd just round to the nearest grid line in each direction. With the skewed basis, the natural rounding gives you the wrong answer most of the time. A "good" basis is the secret key; a "bad" basis is what you publish. Anyone who only sees the bad basis is stuck doing CVP the hard way.
Now scale this up. In 256 dimensions there's no "obvious" rounding to try. The best known classical algorithm (BKZ, lattice basis reduction) runs in time exponential in the dimension. Even quantum computers only chip a small constant off the exponent — Shor's algorithm doesn't apply because lattices have no hidden subgroup structure.
// the LWE problem in dimension 4
// Without noise, you'd just solve A⁻¹·b = s by linear algebra.
// The noise e is what makes this a one-way function.
Linear equations are easy. Add noise and they aren't.
Without the noise vector e, this would be a classical
linear-algebra problem: invert the matrix A, multiply by
b, recover s. A high-school student could do it.
But e is small random noise — each entry is in {−1, 0, +1}.
That tiny perturbation breaks the linear-algebra approach completely. Now
recovering s requires solving the
Learning With Errors problem, which (for cryptographic
parameter sizes) is provably as hard as worst-case lattice problems
— including the closest vector problem you just played with above.
Notice: with n = 4 and q = 17 there are only
17⁴ = 83,521 possible s vectors. You could brute-force
this by hand in an afternoon. ML-KEM uses n = 256 per polynomial
and modulus q = 3329. The brute-force space is wider than the
observable universe.
Switching the noise off is a button click; you'll see decryption becomes trivial. That's the whole point of the noise — it's the ingredient that makes the lattice problem cryptographic.
encryption from LWE — Regev's trick
ML-KEM in miniatureRegev (2005) showed how to turn LWE into an encryption scheme. The construction is so direct it almost feels like cheating: the public key is just an LWE sample, and to encrypt a bit you mash a few of those samples together and add a half-of-q "kicker" if your bit is 1. To decrypt, you subtract off the secret part and check whether the leftover is closer to 0 or to q/2.
ML-KEM is a polished, polynomial-ring version of this. The mechanism you'll see below is the same one running in production TLS handshakes — just operating on tiny integers instead of 256-coefficient polynomials.
Generating the keypair
Click Keygen to create a fresh keypair. The secret key
is a small random vector s. The public key is a random matrix
A together with a noisy product b = A·s + e.
Anyone seeing (A, b) can't recover s — that's the
LWE assumption. But the matching private s can be used to
cancel out the noise during decryption.
from toys to ML-KEM
FIPS 203
Real ML-KEM does two things on top of toy LWE. First, it works over
polynomials in Rq = ℤq[X] / (X256 + 1)
— essentially, every "number" is replaced by a 256-coefficient
polynomial. Multiplication uses the Number Theoretic Transform (NTT)
for speed.
Second, ML-KEM is a key-encapsulation mechanism, not a general-purpose encryption scheme. Instead of encrypting your message directly, it encapsulates a fresh symmetric key. That key (32 bytes) then drives AES-GCM on the actual payload. The Fujisaki-Okamoto transform wraps the IND-CPA core into an IND-CCA-secure KEM.
The same shape, scaled up
Compare the toy Regev demo above to ML-KEM-768. In Regev: the secret is
a 4-element integer vector. In ML-KEM: the secret is a 3-element
polynomial vector, where each polynomial has 256 coefficients.
That's 3 × 256 = 768 small integers — hence the name.
The encryption operation looks identical at the structural level:
u = AT·r + e₁ and v = bT·r + e₂ + ⌊q/2⌋·m.
Just with polynomial arithmetic instead of integer arithmetic, and the
message m being a 256-bit packed value.
The Fujisaki-Okamoto transform is the box around all this that makes the scheme IND-CCA secure. It turns the KEM into a deterministic re-encryption check: the receiver re-encrypts the message they decrypt and rejects any ciphertext that doesn't match. This stops adaptive chosen-ciphertext attacks (the same family as Bleichenbacher's RSA padding-oracle attacks, but on the lattice side).
signatures — Schnorr to ML-DSA
FIPS 204ML-DSA's structure is easier to introduce through its classical ancestor — Schnorr signatures. Schnorr is a clean sigma-protocol: prover commits, verifier challenges, prover responds. Apply the Fiat-Shamir transform (use a hash function as the verifier) and you get a non-interactive signature.
ML-DSA does the exact same dance, but over a lattice. The complications it adds — rejection sampling and hint vectors — exist because lattices leak the secret through naive responses. Real ML-DSA is intricate; the structure is recognizable from Schnorr.
// toy Schnorr signature · group: ⟨g⟩ ⊂ ℤ*₂₃, order q = 11
From Schnorr to ML-DSA
Schnorr's signature is (R, s) where R = gk
commits the signer to a random nonce, and s = k + c·x reveals
a key-dependent linear combination. The verifier checks
gs = R · yc, which expands to
gk+cx = gk · gcx — true by exponent
arithmetic when the signer knows x.
ML-DSA does the same thing on a lattice. Replace gx with
A·s (matrix-vector product over a polynomial ring), replace
the response k + c·x with y + c·s where y is a
random polynomial vector. Same algebraic shape; different math underneath.
The catch: in lattice land, leaking y + c·s directly would let an
attacker recover s through enough samples (each y is small,
so the response leaks information about s). ML-DSA's solution is
rejection sampling: if the response would land in a region that
leaks too much, the signer aborts and re-rolls the nonce. The signature
is only emitted when it falls within a "safe" range. Hence the
algorithm name in earlier drafts: "Dilithium signatures with aborts."
Two more tricks make real ML-DSA work: hint vectors compress
the high bits of intermediate values for transmission; and the public
key is a compressed form of A·s + e. The result is a signature
~3000 bytes long — much bigger than Ed25519's 64, but small enough
to fit in a TLS handshake.
why quantum can't break it
Shor's quantum algorithm — the one that breaks RSA and ECDH — works by reducing the problem to period-finding over an abelian group. The quantum Fourier transform reads off the period in polynomial time. Both factoring and discrete log have this structure; that's why both fall to the same attack.
Lattice problems don't. There's no hidden cyclic structure for the QFT to extract. The best known quantum algorithm for the shortest vector problem is Grover-amplified BKZ — which only shaves a constant factor off the exponent. ML-KEM-1024 and ML-DSA-87 are designed with that constant factor included; their claimed security is post-quantum, not just classical.
That doesn't mean lattices are provably safe forever. Quantum algorithm research is active. But it's the closest thing the cryptographic community has to a quantum-resistant foundation, and four NIST competition rounds (2017–2022) failed to find a break.
| Classical (RSA, ECDH) | Lattice (ML-KEM, ML-DSA) | |
|---|---|---|
| Hard problem | Integer factoring · discrete logarithm | Module-LWE · Module-SIS · Closest Vector Problem |
| Best classical attack | NFS (sub-exponential) | BKZ basis reduction (exponential) |
| Best quantum attack | Shor (polynomial → broken) | Grover-improved BKZ (small constant speedup) |
| Public key size (≥128-bit security) | 3072-bit RSA · 256-bit ECDH | 800 B · 1184 B · 1568 B |
| Signature size | ~256 B (ECDSA) · 384 B (RSA-3072) | 2420 B · 3309 B · 4627 B |
| Speed | RSA decrypt slow · ECDH fast | All operations fast (microseconds in software) |
| Maturity | 40+ years deployed | Standardized 2024 · field-tested in TLS hybrid since 2023 |
X25519MLKEM768 hybrid key exchange in TLS. ~3% of TLS handshakes go post-quantum by year-end.Hybrid now, post-quantum later
The "harvest now, decrypt later" threat — record encrypted traffic today and decrypt it once you have a quantum computer — is what's driving the urgency. Anything you encrypt with X25519 alone in 2026 can be read in 2040 if a CRQC arrives by then.
Hybrid key exchange (classical AND post-quantum, both must be broken) is the bridge. If lattice cryptography turns out to have a flaw we missed, classical X25519 still protects the channel. If quantum computers arrive, ML-KEM still protects the channel. The cost is a slightly larger handshake (~1 KB extra).
The transition to post-quantum-only will probably take a decade more — until lattice cryptography has the same kind of decades-of-attacks track record that RSA and ECC have today. Until then, run both.