1. The exact problem ML-KEM solves
The threat is not theoretical post-quantum cryptanalysis at some indeterminate future date. The threat is harvest-now-decrypt-later (HNDL): an adversary captures TLS, IPsec, or SSH ciphertext today, stores it, and decrypts it once a cryptographically-relevant quantum computer (CRQC) running Shor's algorithm becomes available. Any session whose confidentiality must outlive that horizon is already compromised the moment it crosses a hostile network.
The classical key-establishment primitives in the field — ECDHE over P-256, X25519, finite-field DH, and RSA key transport — all reduce to problems Shor solves in polynomial time. RSA-2048 falls to roughly 4099 logical qubits per Gidney–Ekerå (2019); X25519 falls to a few thousand. Symmetric primitives degrade only quadratically under Grover, so AES-256-GCM retains ~128-bit post-quantum security and is not the migration target. The migration target is key establishment and signatures.
ML-KEM (FIPS 203, finalised 13 August 2024) is the standardised key-encapsulation mechanism intended to replace (EC)DH for confidentiality of session keys. Its function in a hybrid TLS 1.3 handshake is unambiguous: produce a shared secret that is intractable for both classical and quantum adversaries, then HKDF-combine it with the X25519 secret so that compromise of either component does not compromise the session.
2. The primitive in detail
ML-KEM is the FIPS-203 derivative of CRYSTALS-Kyber. It is a lattice-based KEM whose security reduces to Module-LWE (Module Learning With Errors) over the ring R_q = Z_q[X]/(X^256 + 1) with q = 3329. The module rank k selects the parameter set:
ML-KEM-512—k=2, NIST Category 1 (~AES-128 PQ), public key 800 B, ciphertext 768 BML-KEM-768—k=3, NIST Category 3 (~AES-192 PQ), public key 1184 B, ciphertext 1088 B — the recommended defaultML-KEM-1024—k=4, NIST Category 5 (~AES-256 PQ), public key 1568 B, ciphertext 1568 B
The construction is a Fujisaki–Okamoto transform of an IND-CPA Kyber PKE into an IND-CCA2 KEM. Encapsulation samples a 32-byte message m, derives randomness r = G(m, H(pk)), runs deterministic IND-CPA encryption to produce ciphertext c, and outputs shared secret K = KDF(m, c). Decapsulation re-encrypts and performs implicit rejection: on a malformed c, the decapsulator returns a pseudo-random secret derived from a per-key z, never an error. This is the property that defeats Bleichenbacher-style oracles.
Note ML-KEM is a KEM, not a signature. Authentication of the handshake still requires a signature scheme — ML-DSA (FIPS 204, EUF-CMA) or SLH-DSA (FIPS 205) — or, transitionally, classical Ed25519/ECDSA-P256 certificates while the WebPKI catches up. ML-KEM does not authenticate anything on its own.
3. Reference implementations, mid-2026
- liboqs 0.12+ (Open Quantum Safe) — FIPS-203 final, constant-time AVX2 path, the upstream most other projects vendor. Production-suitable for KEM operations; not FIPS-validated as a module.
- OpenSSL 3.5 — ships native
ML-KEM-512/768/1024viaEVP_PKEYand theX25519MLKEM768hybrid group for TLS 1.3. Theoqs-providerremains for ML-DSA/SLH-DSA until those land natively. - BoringSSL —
X25519MLKEM768(TLS group0x11ec, RFC 9794-aligned codepoint) is the production hybrid in Chrome since v131 (Nov 2024); the earlierX25519Kyber768Draft00(0x6399) is being retired. - OpenSSH 9.9+ —
mlkem768x25519-sha256is the default KEX as of OpenSSH 10.0 (April 2025). Host-key signatures remain Ed25519/RSA pending ML-DSA integration. - BIND 9.20 — experimental ML-DSA DNSSEC algorithm allocations; ML-KEM is not relevant to DNSSEC (signatures, not encryption). Mentioned only to disambiguate.
- Cloudflare —
X25519MLKEM768served on edge since March 2024; ~35% of TLS handshakes by late 2025. - AWS KMS —
pq-hybridTLS mode for KMS API endpoints (TLS_AES_256_GCM_SHA384withX25519MLKEM768). - Azure Key Vault / GCP Cloud KMS — hybrid KEM on the control plane endpoints; HSM-backed ML-KEM private keys are not yet generally available.
- strongSwan 6.0 — IKEv2 additional key exchanges per RFC 9370, with
ML-KEM-768asADDKE1.
OpenVPN 2.7 inherits PQ via its OpenSSL backend; WireGuard has no upstream PQ KEX and remains a gap.
4. Deployment pattern — hybrid first, always
The non-negotiable rule for 2026 deployments is hybrid: never deploy ML-KEM standalone in a production handshake. Combine it with X25519 and feed both shared secrets through HKDF. If ML-KEM is later cryptanalysed (the lattice assumptions are younger than ECDLP), the X25519 component still provides classical security; if a CRQC arrives, the ML-KEM component carries confidentiality.
Nginx 1.27 against OpenSSL 3.5, accepting hybrid only:
ssl_protocols TLSv1.3;
ssl_ciphers TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256;
ssl_ecdh_curve X25519MLKEM768:X25519;
ssl_conf_command Groups X25519MLKEM768:X25519;
ssl_certificate /etc/ssl/ed25519.crt;
ssl_certificate_key /etc/ssl/ed25519.key;
OpenSSH server configuration pinning hybrid KEX:
KexAlgorithms mlkem768x25519-sha256,sntrup761x25519-sha512@openssh.com
HostKeyAlgorithms ssh-ed25519,rsa-sha2-512
PubkeyAcceptedAlgorithms ssh-ed25519,rsa-sha2-512
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com
Programmatic encapsulation against a peer public key with OpenSSL 3.5:
EVP_PKEY *pk = /* peer ML-KEM-768 public key, 1184 B SPKI */;
EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pk, NULL);
EVP_PKEY_encapsulate_init(ctx, NULL);
size_t ct_len = 1088, ss_len = 32;
unsigned char ct[1088], ss[32];
EVP_PKEY_encapsulate(ctx, ct, &ct_len, ss, &ss_len);
/* Combine with X25519 shared secret via HKDF-Extract before use */
5. What goes wrong in production
- ClientHello fragmentation. An
X25519MLKEM768key share is 1216 bytes. The ClientHello now exceeds the initial congestion window and frequently a single TCP segment. Middleboxes that assumed ClientHello fits one MTU drop or mangle the second segment. Symptom: handshake hangs at server hello. Fix: validate path withtcpdumpand replace or bypass the offending appliance. - Codepoint drift. Early Chrome shipped
X25519Kyber768Draft00(0x6399); the standard is0x11ec. Servers that pin only the draft codepoint reject post-2024 clients. -
Schedule a sovereign-cryptography assessment
Book a security call →