X25519MLKEM768 vs X25519 is the key-exchange decision in every TLS 1.3 handshake today. X25519 alone is fast and tiny but falls to a quantum computer, which means traffic recorded now could be decrypted later. X25519MLKEM768 runs X25519 and ML-KEM-768 together, so the session stays confidential unless both are broken.
At a glance
| X25519 | X25519MLKEM768 | |
|---|---|---|
| TLS supported group | x25519, 29 (0x001D) | X25519MLKEM768, 4588 (0x11EC), IANA Recommended |
| Specification | RFC 7748, RFC 9846 | RFC 10024 (2026), framework RFC 9954 |
| Components | X25519 | ML-KEM-768 (FIPS 203) and X25519 |
| Client key share | 32 bytes | 1,216 bytes (1,184 ML-KEM encapsulation key + 32) |
| Server key share | 32 bytes | 1,120 bytes (1,088 ML-KEM ciphertext + 32) |
| Shared secret into the key schedule | 32 bytes | 64 bytes (ML-KEM secret first, then X25519) |
| Quantum resistance | No | Yes, as long as ML-KEM-768 holds |
| Classical security | X25519 | At least X25519, even if ML-KEM were broken |
| CPU per handshake, OpenSSL 3.6.5 | about 52,000 X25519 operations per second | about 19,000–24,000 keygen, encapsulation or decapsulation per second |
| ClientHello measured below | 306 bytes | 1,484 bytes |
| ServerHello measured below | 122 bytes | 1,210 bytes |
Throughput from openssl speed on one Apple M4 Max core; handshake sizes from the capture below.
Why hybrid now
Key exchange is exposed to harvest-now-decrypt-later: an adversary records encrypted sessions today and decrypts them once a cryptographically relevant quantum computer exists, recovering the session keys from the recorded X25519 exchange. Forward secrecy does not help, because each recorded exchange can be broken individually. Anything whose confidentiality must outlast the arrival of such a computer is already at risk, which is why key exchange moved first while signatures can wait longer.
The hybrid design hedges the other way too. ML-KEM was standardized in August 2024 and is young compared with X25519, so a mathematical or implementation break is not unthinkable. X25519MLKEM768 concatenates both shared secrets into the TLS key schedule, so an attacker must break both. RFC 10024 orders the ML-KEM share and secret first for this group, unlike the NIST-curve hybrids (SecP256r1MLKEM768, 0x11EB, and SecP384r1MLKEM1024, 0x11ED), which put ECDH first.
What changes on the wire
The client sends a 1,216-byte key share instead of 32 bytes, so a typical ClientHello grows from about 300 bytes to about 1.5 KB and no longer fits in one network packet with all the other extensions of a browser. The server answers with a 1,120-byte share. A live handshake with Cloudflare, captured with OpenSSL 3.6.5, shows the difference:
echo | openssl s_client -connect cloudflare.com:443 -servername cloudflare.com -groups X25519MLKEM768 -brief 2>&1 | grep -E "Protocol|group"
echo | openssl s_client -connect cloudflare.com:443 -servername cloudflare.com -groups X25519MLKEM768 -msg 2>&1 | grep -E "ClientHello|ServerHello"
echo | openssl s_client -connect cloudflare.com:443 -servername cloudflare.com -groups X25519 -msg 2>&1 | grep -E "ClientHello|ServerHello"
Protocol version: TLSv1.3
Negotiated TLS1.3 group: X25519MLKEM768
>>> TLS 1.3, Handshake [length 05cc], ClientHello
<<< TLS 1.3, Handshake [length 04ba], ServerHello
>>> TLS 1.3, Handshake [length 0132], ClientHello
<<< TLS 1.3, Handshake [length 007a], ServerHello
That is 1,484 against 306 bytes for the ClientHello and 1,210 against 122 for the ServerHello. Larger ClientHellos exposed bugs in servers and middleboxes that assumed the message arrives in one TCP read or one packet; when Chrome enabled hybrid Kyber shares by default in version 124 (2024), several firewall and proxy products had to be fixed, a problem class documented at tldr.fail. Cloudflare and Google reported a few percent of median handshake latency from the extra bytes, which matters far less than the round trips saved by TLS 1.3 itself.
Deployment status
- Browsers: Chrome and Edge offer X25519MLKEM768 by default since version 131 (November 2024), Firefox since 132 on desktop, Safari and Apple's system TLS since iOS 26 and macOS 26 (2025). The pre-standard
X25519Kyber768Draft00(0x6399) they used earlier is deprecated. - Libraries: OpenSSL 3.5 (April 2025) sends X25519MLKEM768 and X25519 key shares by default; Go 1.24 enables it by default in
crypto/tls; JDK 27 (September 2026, JEP 527) offers it first by default; BoringSSL, rustls and NSS support it. - Servers and CDNs: Cloudflare, Google and other large providers negotiate it with supporting clients; nginx, Apache and HAProxy pick it up from the linked OpenSSL.
- SSH: the equivalent
mlkem768x25519-sha256is the OpenSSH default since 10.0 (RFC 10042).
The browser PQ check shows what your own browser negotiates.
When to choose which
- Public HTTPS and APIs: offer X25519MLKEM768 first and X25519 second; every modern client negotiates the hybrid and old ones fall back.
- Internal service mesh and mTLS: hybrid by default, especially for data with long confidentiality requirements.
- FIPS-oriented deployments:
SecP256r1MLKEM768orSecP384r1MLKEM1024if your module's approved list requires NIST curves; X25519MLKEM768 qualifies where ML-KEM is the approved component. - Constrained links where every packet counts: measure first; the hybrid adds one packet per direction, which is usually acceptable.
- X25519 alone: only for peers that cannot do the hybrid, never as a deliberate choice for new deployments.
Migration notes
- Upgrade the TLS library (OpenSSL 3.5 or later, Go 1.24 or later, current BoringSSL or rustls); with OpenSSL 3.5 the default groups already include the hybrid.
- If you set groups explicitly, add it: for example
ssl_ecdh_curve X25519MLKEM768:X25519:prime256v1;in nginx orGroups = X25519MLKEM768:X25519:P-256in an OpenSSL configuration file. - Test the path, not just the server: load balancers, WAFs and TLS-inspecting proxies must handle a ClientHello split across packets and reads; retest after their upgrades.
- Verify what is negotiated with
openssl s_client -groups X25519MLKEM768or browser developer tools, and monitor the share of hybrid handshakes. - Plan the signature side separately: the hybrid protects confidentiality only; certificates and handshake signatures remain classical until post-quantum signatures arrive in the WebPKI.