ML-KEM, Explained: How Kyber Got Into Your TLS Handshake
From encryption to encapsulation: a different way to deliver a key
Establishing a symmetric TLS session key always comes back to one problem: how do two parties agree on a secret over a public channel? Classical answers came in two generations — the RSA era encrypted a pre-master secret with the server's public key; the ECDH era had both sides publish ephemeral keys and run a Diffie-Hellman exchange. Both generations share a foundation — factoring and elliptic-curve discrete log — that collapses under Shor's algorithm (background in the previous post).
ML-KEM is the third generation: a key encapsulation mechanism. Three steps:
- Keygen: produce a public and private key (as before)
- Encapsulate: anyone holding the public key runs the encapsulation algorithm, which outputs a ciphertext and a fresh random shared secret
- Decapsulate: the private-key holder recovers the same shared secret from the ciphertext
The difference from RSA-OAEP's "pick a key, then encrypt and send it" is who controls the key's birth: in a KEM the shared secret is derived inside the algorithm, so you never choose a key and then figure out how to ship it — eliminating an entire class of "the key wasn't random enough" engineering incidents.
Where Kyber came from: an eight-year competition
ML-KEM's predecessor, Kyber, emerged from NIST's post-quantum standardization competition (launched 2016), was selected in July 2022 as the basis for the KEM standard, and was published in August 2024 as FIPS 203. The ML stands for module lattice — the mathematical ground shifts from factoring to noisy linear systems over lattices, where quantum algorithms currently hold no structural advantage. You don't need lattice math to remember its engineering profile: fast (software performance in the same league as ECDH), big keys (an order of magnitude above X25519), quantum-resistant.
Three parameter sets and their sizes: the root of all friction
| Parameter set | Equivalent strength | Public key | Ciphertext | vs. X25519 |
|---|---|---|---|---|
| ML-KEM-512 | AES-128 | 800 B | 768 B | 32 B |
| ML-KEM-768 | AES-192 | 1,184 B | 1,088 B | 32 B |
| ML-KEM-1024 | AES-256 | 1,568 B | 1,568 B | 32 B |
TLS deployments today mostly run ML-KEM-768. Public key plus ciphertext totals ~2.3KB — over thirty times X25519. That number drives nearly all the engineering friction below.
The hybrid handshake: not a transition, a design
What browsers and servers run today is not "pure ML-KEM" but the X25519MLKEM768 hybrid group:
- The ClientHello's key_share carries both an X25519 public key (32B) and an ML-KEM-768 public key (1,184B)
- The server completes key exchange for both algorithms, yielding two shared secrets
- The TLS 1.3 key schedule (HKDF-based) derives the session key from the two secrets concatenated together
The key property: an attacker must break both the lattice problem and the elliptic-curve problem to recover the session. If quantum breaks the classical side, ML-KEM holds; if ML-KEM turns out to have a weakness, X25519 holds. "Hybrid" is often misread as a transitional compromise — it's a redundancy structure that won't be retired anytime soon.
The ClientHello-bloat middlebox trap
The extra 1.1KB pushes the ClientHello past a single TCP segment. Chrome hit this for real while rolling out X25519Kyber768 (the hybrid's predecessor): some enterprise firewalls dropped oversized or "unfamiliar" handshakes outright. Hence the deployment order — canary at the CDN/edge first, watch handshake success rates, then full rollout. That's why the migration checklist lists "canary + handshake monitoring" as mandatory.
How to turn it on (October 2026)
- Browsers: Chrome and Firefox already support it by default — nothing to configure
- OpenSSL 3.5+: ships the
X25519MLKEM768group - nginx (linked against OpenSSL 3.5+):
ssl_ecdh_curve X25519MLKEM768:X25519;(keep X25519 as fallback) - CDNs: Cloudflare and peers expose toggles; if your origin sits behind a CDN, upgrading the origin buys little — negotiation happens at the edge
- To verify: check the key-exchange group name in your browser's developer tools Security panel, or inspect the negotiated group with a hybrid-capable
openssl s_client. Your certificate itself (visible in the certificate decoder) is still RSA/ECDSA for now — moving certificates to PQC is the slower timeline, because signatures wait on the ML-DSA ecosystem
Implementer's note
There's a concrete reason this site has no PQC tool yet: WebCrypto still has no ML-KEM interface (the crypto.subtle roster remains RSA/ECDH/AES), so running ML-KEM in a browser means a wasm build of liboqs — multi-megabyte payloads, which is hostile to "open and use" online tools. Writing the RSA tool, I left a comparison point: encrypting a 32-byte key with RSA-OAEP costs hundreds of bytes of overhead, and ML-KEM-768 encapsulates a similar-sized secret into 1,088 bytes — ciphertext size is the most tangible difference between KEM and DH families. Once WebCrypto ships native support, ML-KEM goes into the tool matrix and that comparison becomes playable.
Related reading
- Harvest now, decrypt later: whose data moves first
- Post-quantum migration self-check: 12 items
- RSA encryption, explained properly
- HMAC and key derivation
Related Tools
Related Articles
Post-Quantum Migration Self-Check: From Algorithm Inventory to Hybrid TLS — 12 Things to Do in 2026
A practical self-check framework for PQC migration: why three overlapping regulatory timelines make 2026 the starting line, how to build a cryptographic bill of materials (CBOM), ranking by HNDL exposure, enabling X25519+ML-KEM hybrid TLS, and what crypto-agility means in practice. With a 12-item checklist.
PIPL PIA Self-Check: The Five Triggering Scenarios, Three Assessment Elements, and a Working Framework
China's Personal Information Protection Law (Articles 55-56) requires a prior Personal Information Protection Impact Assessment (PIA) for five categories of processing. This post covers the triggers, the statutory three-element report structure, the three-year retention requirement, and a data-map → risk-matrix → controls framework. With the MLPS/miping/PIA three-pillar relationship.
Passkeys, Explained: Why the Server Can No Longer Hold a Copy of Your Password
How passkeys (WebAuthn/FIDO2) work: public-key challenge-response replacing shared secrets, why phishing resistance is structural (origin binding), what servers storing only public keys actually means, synced vs. device-bound passkeys, and the three enterprise adoption hurdles (enrollment, multi-device, recovery). With a capability table against passwords and TOTP.