RSA and ECDH key exchange — the algorithms protecting every TLS connection today — will be broken by a sufficiently powerful quantum computer running Shor’s algorithm. Not “might be broken” or “theoretically vulnerable.” Broken. The math is settled; only the engineering timeline is uncertain.
ML-KEM (Module-Lattice-Based Key Encapsulation Mechanism), standardized as NIST FIPS 203 in August 2024, is the replacement. Formerly known as CRYSTALS-Kyber, it’s the algorithm that will protect key exchange in TLS, VPNs, messaging protocols, and every system that currently relies on Diffie-Hellman or RSA key transport.
Why Key Exchange Breaks First
Quantum computers threaten two categories of cryptography differently:
| Category | Classical Algorithm | Quantum Attack | Impact |
|---|---|---|---|
| Key Exchange / Encryption | RSA, ECDH, DH | Shor’s algorithm (polynomial time) | Completely broken |
| Symmetric Encryption | AES-128, AES-256 | Grover’s algorithm (square root speedup) | Halved security (AES-256 → 128-bit effective) |
| Hash Functions | SHA-256, SHA-3 | Grover’s (preimage), BHT (collision) | Reduced but still secure at 256-bit |
| Digital Signatures | RSA, ECDSA, EdDSA | Shor’s algorithm | Completely broken |
Key exchange is the most urgent problem because of harvest now, decrypt later (HNDL) attacks. Adversaries recording encrypted traffic today can decrypt it once quantum computers arrive. Data with long confidentiality requirements (government secrets, medical records, financial data) is already at risk.

ML-KEM protects against this by replacing the vulnerable key exchange with a quantum-resistant mechanism today.
How ML-KEM Works (Simplified)
ML-KEM is based on the Module Learning With Errors (MLWE) problem — a mathematical problem that’s hard for both classical and quantum computers.
The Core Idea
Instead of relying on factoring large numbers (RSA) or computing discrete logarithms (ECDH), ML-KEM relies on the difficulty of finding a secret vector when given noisy linear equations over a lattice.

Key encapsulation (KEM) is different from key exchange (like Diffie-Hellman):
- In DH, both parties contribute to the shared secret
- In a KEM, one party generates the secret and encapsulates it for the other
- The result is the same: both parties share a secret key
Why Lattices Are Quantum-Resistant
The MLWE problem asks: given a matrix A and a vector t = As + e (where e is a small “error” vector), find s. This is easy if you know e, but without it, the problem is as hard as finding the shortest vector in a high-dimensional lattice — a problem for which no efficient quantum algorithm exists.
ML-KEM Parameter Sets
NIST standardized three security levels:
| Parameter Set | Security Level | NIST Category | Equivalent Classical Security | Use Case |
|---|---|---|---|---|
| ML-KEM-512 | Level 1 | Category 1 | ~AES-128 | General purpose, performance-sensitive |
| ML-KEM-768 | Level 3 | Category 3 | ~AES-192 | Recommended default |
| ML-KEM-1024 | Level 5 | Category 5 | ~AES-256 | High-security, long-term protection |
Size and Performance Comparison
| Metric | ML-KEM-768 | ECDH P-256 | RSA-2048 |
|---|---|---|---|
| Public key size | 1,184 bytes | 32 bytes | 256 bytes |
| Ciphertext size | 1,088 bytes | 32 bytes | 256 bytes |
| Shared secret | 32 bytes | 32 bytes | 32 bytes |
| Key generation | ~30 μs | ~50 μs | ~50 ms |
| Encapsulation | ~40 μs | ~80 μs | ~10 μs |
| Decapsulation | ~40 μs | ~80 μs | ~1 ms |
| Combined bandwidth | 2,272 bytes | 64 bytes | 512 bytes |
The tradeoff is clear: ML-KEM is fast (faster than RSA, comparable to ECDH) but has significantly larger keys and ciphertexts. This impacts TLS handshake size, which matters for:
- Mobile networks with small MTU
- IoT devices with constrained memory
- High-frequency API calls where handshake overhead matters
ML-KEM in TLS 1.3
ML-KEM integrates into TLS 1.3 via the key_share extension. In practice, deployments use hybrid mode — combining ML-KEM with ECDH so that the connection is secure even if one algorithm is broken:

Why hybrid?
- If ML-KEM has an undiscovered weakness, ECDH still protects the session
- If quantum computers break ECDH, ML-KEM still protects the session
- Both must be broken simultaneously to compromise the connection
- Provides a smooth migration path — remove ECDH later when confidence in ML-KEM is absolute
Browser and Server Support (2026)
| Implementation | ML-KEM Support | Hybrid Mode | Default |
|---|---|---|---|
| Chrome/Chromium | ML-KEM-768 (since Chrome 131) | X25519+ML-KEM-768 | Yes (default since 2025) |
| Firefox | ML-KEM-768 (since Firefox 132) | X25519+ML-KEM-768 | Yes |
| Safari/WebKit | ML-KEM-768 (since Safari 18.2) | X25519+ML-KEM-768 | Yes |
| OpenSSL 3.5+ | All parameter sets | Configurable | No (opt-in) |
| BoringSSL | ML-KEM-768 | X25519+ML-KEM-768 | Yes |
| AWS CloudFront | ML-KEM-768 | X25519+ML-KEM-768 | Yes |
| Cloudflare | ML-KEM-768 | X25519+ML-KEM-768 | Yes |
| Nginx (with OpenSSL 3.5) | All parameter sets | Configurable | No |
Enabling ML-KEM in OpenSSL 3.5+
# Check if ML-KEM is available
openssl list -kem-algorithms | grep ML-KEM
# Test a connection with hybrid key exchange
openssl s_client -connect server.example.com:443 \
-groups X25519MLKEM768:X25519:P-256 \
-servername server.example.com
# Check what key exchange was used
openssl s_client -connect cloudflare.com:443 2>/dev/null | grep "Server Temp Key"
# Output: Server Temp Key: X25519MLKEM768
Nginx Configuration
# Enable hybrid PQC key exchange (requires OpenSSL 3.5+)
ssl_ecdh_curve X25519MLKEM768:X25519:secp384r1:secp256r1;
# Or for maximum security
ssl_ecdh_curve MLKEM1024X448:X25519MLKEM768:X25519;
Migration Timeline
CNSA 2.0 Deadlines (NSA)
| System Type | Deadline | Requirement |
|---|---|---|
| Software/firmware signing | 2025 | ML-DSA for new signatures |
| Web servers/browsers (TLS) | 2025 | ML-KEM hybrid key exchange |
| VPN/IPsec | 2026 | ML-KEM for IKEv2 key exchange |
| Legacy systems | 2030 | Full transition, no classical-only |
| National Security Systems | 2033 | Exclusively PQC (no hybrid) |
Practical Enterprise Timeline
| Phase | Timeframe | Actions |
|---|---|---|
| Inventory | Now | Identify all systems using RSA/ECDH key exchange |
| Test | 2025-2026 | Enable hybrid ML-KEM in non-production, measure impact |
| Deploy hybrid | 2026-2027 | Enable X25519+ML-KEM-768 on all TLS endpoints |
| Monitor | 2027-2028 | Track compatibility issues, performance impact |
| Remove classical | 2030+ | Transition to ML-KEM-only when ecosystem is ready |
Performance Impact in Practice
TLS Handshake Size
| Configuration | ClientHello Size | ServerHello Size | Total Handshake |
|---|---|---|---|
| X25519 only | ~300 bytes | ~150 bytes | ~3 KB |
| X25519 + ML-KEM-768 (hybrid) | ~1,500 bytes | ~1,300 bytes | ~6 KB |
| ML-KEM-768 only | ~1,400 bytes | ~1,250 bytes | ~5.5 KB |
Real-world impact:
- Desktop/broadband: Negligible (< 1ms additional latency)
- Mobile 4G/5G: 1-3ms additional latency per handshake
- Satellite/high-latency: Noticeable if MTU fragmentation occurs
- IoT/constrained: May require protocol adjustments
Middlebox Compatibility
Some network middleboxes (firewalls, load balancers, TLS inspection proxies) fail when they encounter the larger ClientHello from hybrid key exchange:
| Issue | Cause | Fix |
|---|---|---|
| Connection timeout | Middlebox drops oversized ClientHello | Update firmware, or split ClientHello |
| TLS inspection failure | Proxy can’t parse ML-KEM key_share | Update proxy to support PQC, or bypass inspection |
| Load balancer reset | Buffer too small for hybrid handshake | Increase buffer limits |
Chrome and Firefox implement ClientHello splitting to work around middleboxes that can’t handle large ClientHellos — the ClientHello is split across two TCP segments.
ML-KEM vs Other PQC KEMs
| Algorithm | NIST Status | Based On | Key Size | Ciphertext | Performance |
|---|---|---|---|---|---|
| ML-KEM (Kyber) | FIPS 203 (standardized) | Module lattices (MLWE) | 1,184 B | 1,088 B | Fast |
| BIKE | Round 4 candidate | Code-based (QC-MDPC) | 1,541 B | 1,573 B | Slower |
| HQC | Round 4 candidate | Code-based (quasi-cyclic) | 2,249 B | 4,481 B | Slower |
| Classic McEliece | Round 4 candidate | Code-based (Goppa) | 261,120 B | 128 B | Tiny ciphertext, huge key |
| FrodoKEM | Not selected | Plain LWE (conservative) | 9,616 B | 9,720 B | Slow, conservative |
ML-KEM won because: Best balance of security confidence, key/ciphertext size, and computational performance. Lattice-based cryptography has been studied for 25+ years with no practical attacks found.
Implementing ML-KEM in Applications
Python (using pqcrypto or oqs-python)
# Using liboqs Python wrapper
from oqs import KeyEncapsulation
# Key generation (server-side)
kem = KeyEncapsulation("ML-KEM-768")
public_key = kem.generate_keypair()
# Encapsulation (client-side)
kem_client = KeyEncapsulation("ML-KEM-768")
ciphertext, shared_secret_client = kem_client.encap_secret(public_key)
# Decapsulation (server-side)
shared_secret_server = kem.decap_secret(ciphertext)
assert shared_secret_client == shared_secret_server
print(f"Shared secret: {shared_secret_server.hex()[:32]}...")
print(f"Public key size: {len(public_key)} bytes")
print(f"Ciphertext size: {len(ciphertext)} bytes")
Go (using Cloudflare’s circl)
package main
import (
"fmt"
"github.com/cloudflare/circl/kem/mlkem/mlkem768"
)
func main() {
// Key generation
publicKey, privateKey, _ := mlkem768.GenerateKeyPair(nil)
// Encapsulation
ciphertext, sharedSecretA, _ := mlkem768.Encapsulate(nil, publicKey)
// Decapsulation
sharedSecretB, _ := mlkem768.Decapsulate(privateKey, ciphertext)
fmt.Printf("Keys match: %v\n", sharedSecretA == sharedSecretB)
fmt.Printf("Public key: %d bytes\n", len(publicKey))
fmt.Printf("Ciphertext: %d bytes\n", len(ciphertext))
}
Testing Your Server’s PQC Support
# Check if a server supports hybrid PQC key exchange
openssl s_client -connect server.example.com:443 \
-groups X25519MLKEM768 \
-servername server.example.com 2>&1 | grep "Server Temp Key"
# If it shows "X25519MLKEM768" — PQC is active
# If it falls back to "X25519" or "P-256" — server doesn't support PQC yet
# Test with Chrome's behavior (hybrid preferred)
curl --curves X25519MLKEM768:X25519 https://server.example.com -v 2>&1 | grep "SSL connection"
What ML-KEM Doesn’t Solve
ML-KEM replaces key exchange only. A complete post-quantum migration also requires:
| Component | Classical | Post-Quantum Replacement | NIST Standard |
|---|---|---|---|
| Key exchange | ECDH, DH, RSA | ML-KEM | FIPS 203 |
| Digital signatures | RSA, ECDSA, EdDSA | ML-DSA (Dilithium) | FIPS 204 |
| Hash-based signatures | — | SLH-DSA (SPHINCS+) | FIPS 205 |
| Symmetric encryption | AES-128 | AES-256 (double key size) | Existing |
| Hash functions | SHA-256 | SHA-384/SHA-512 (or SHA-3) | Existing |
For TLS specifically:
- Key exchange: ML-KEM (deploy now in hybrid mode)
- Server certificate signatures: ML-DSA (coming — certificates will be larger)
- Certificate chain: All CAs must eventually sign with PQC algorithms
FAQ
Q: Is ML-KEM the same as Kyber?
ML-KEM is the standardized version of CRYSTALS-Kyber. NIST renamed it during standardization to follow their naming convention (ML = Module Lattice). The core algorithm is the same, but FIPS 203 includes minor changes from the original Kyber submission (different key derivation, explicit domain separation). Libraries should use the FIPS 203 version, not the original Kyber round 3 specification.
Q: When will quantum computers actually break RSA/ECDH?
Estimates range from 2030 to 2045+ for a cryptographically relevant quantum computer (CRQC). The exact timeline is uncertain, but the “harvest now, decrypt later” threat means data encrypted today with classical key exchange is already at risk if it needs to remain confidential for 10+ years. The migration should start now regardless of the exact Q-Day timeline.
Q: Does ML-KEM protect existing encrypted data?
No. ML-KEM protects future key exchanges. Data already encrypted with classical key exchange (recorded TLS sessions, stored encrypted files using RSA key transport) remains vulnerable. This is why early adoption matters — every day of delay is another day of traffic that can be harvested.
Q: Can I use ML-KEM without hybrid mode?
Technically yes, but it’s not recommended yet. Hybrid mode (X25519+ML-KEM) ensures security even if a flaw is found in ML-KEM. NIST and NSA both recommend hybrid deployment during the transition period. Pure ML-KEM-only is expected to be acceptable after 2030 once confidence in the algorithm is fully established.
Q: How does ML-KEM affect certificate sizes?
ML-KEM itself doesn’t affect certificates — it’s used for key exchange, not signatures. However, the companion algorithm ML-DSA (for signatures) will significantly increase certificate sizes. An ML-DSA-65 signature is ~3,300 bytes vs ~256 bytes for ECDSA. A full certificate chain with ML-DSA signatures could be 10-15 KB vs the current 3-5 KB.
Q: Do I need to change my certificates for ML-KEM?
No. ML-KEM operates at the TLS key exchange layer, independent of the certificate. Your existing RSA or ECDSA certificates continue to work with ML-KEM hybrid key exchange. Certificate algorithm migration (to ML-DSA) is a separate, later step.
Related Reading: