Hybrid TLS: Merging Classic and Post-Quantum Security
TL;DR
The industry is not replacing classical key exchange with post-quantum key exchange — it is running both in
every handshake. X25519MLKEM768, now the default in major browsers, combines a classical X25519
(Curve25519) Diffie-Hellman exchange with an ML-KEM-768
encapsulation, concatenates both resulting secrets, and feeds the concatenation into TLS 1.3's existing HKDF
key schedule as a single shared secret: . The security argument is
a disjunction, not a sum: the combined key remains secure if either component's hardness assumption
holds, which is precisely why lattice-based ML-KEM is wrapped around X25519 rather than deployed alone — ML-KEM
has had a few years of public cryptanalysis against ECC's multi-decade track record, and hybridization means a
structural break in the new math degrades the connection back to classical security instead of to no security
at all. Negotiation reuses TLS 1.3's existing key_share mechanism — no new handshake flow, no certificate
changes — which is what makes this deployable today rather than after a full protocol revision.
Why Hybrid, Not PQC-Only
ML-KEM's Module-LWE hardness assumption has been public since 2016 and standardized since 2024. X25519's discrete-log-based hardness assumption has been public since 1976 and has survived roughly five decades of cryptanalysis, including the entire post-quantum research program searching for classical weaknesses. Deploying ML-KEM alone means every TLS connection's confidentiality rests on an assumption with a short public track record; deploying X25519 alone means every connection remains exposed to Shor's algorithm once a cryptographically relevant quantum computer exists.
Hybridization removes the need to choose. Define the combined secret as the concatenation of both component secrets, fed through the key derivation function already used in TLS 1.3's handshake:
An attacker who wants to recover the resulting handshake secret must solve both the X25519 discrete logarithm problem and invert ML-KEM's encapsulation — breaking only one component leaves the other's secret still mixed unrecoverably into via the KDF. This holds even if the two schemes fail for entirely different reasons: a classical cryptanalytic break of Module-LWE and a future quantum break of elliptic-curve discrete log are both survivable by the same hybrid handshake, because neither failure alone determines . Reverting to classical-only security on an ML-KEM break, rather than to no security at all, is the entire point of wrapping the new algorithm in the old one instead of the reverse.
What X25519MLKEM768 Actually Sends
The name is literal: it concatenates a classical group (X25519) with a post-quantum KEM parameter set
(ML-KEM-768), and TLS negotiates it as a single named group in the supported_groups and key_share
extensions — the same extensions TLS 1.3 already uses for plain X25519 or secp256r1. No new extension type,
no new handshake message, no new round trip.
A client offering this group generates two independent ephemeral key pairs and sends both public values
concatenated as one key_share entry: an X25519 public key and an ML-KEM-768 encapsulation key. A server that
selects this group performs both operations independently — an X25519 Diffie-Hellman computation against the
client's X25519 share, and an ML-KEM encapsulation against the client's ML-KEM encapsulation key — and returns
its own X25519 public key concatenated with the ML-KEM ciphertext in its own key_share. Both sides now hold
and independently, concatenate them in the fixed order the specification
defines, and hand the result to the same HKDF-based key schedule TLS 1.3 already runs for a non-hybrid
handshake. Every downstream step — Handshake Secret, Master Secret, traffic key derivation — is unchanged.
Negotiating It in Practice
- Client advertises multiple groups. A ClientHello lists
X25519MLKEM768alongside plainX25519(and oftensecp256r1) insupported_groups, ordered by preference, so the handshake still completes against servers that don't support the hybrid group. - Client sends key shares optimistically. To avoid an extra round trip, clients typically generate and
send
key_shareentries for their top one or two preferred groups upfront, rather than waiting to be asked — a server requesting an unsent group triggers aHelloRetryRequest, adding a round trip only on that fallback path. - Server selects and responds. A server configured to prefer
X25519MLKEM768performs both component operations against the client's hybridkey_shareand returns its own combined share in the ServerHello. A server that doesn't recognize the hybrid group simply falls through to the next group the client offered. - No certificate changes required. The hybrid mechanism operates entirely on the ephemeral key exchange. Certificate signatures remain classical (RSA or ECDSA) or migrate to ML-DSA independently, on its own deployment timeline — the two migrations (key exchange, signatures) are decoupled.
- Server-side requirements. This needs a TLS stack built against a library version that implements
ML-KEM and the hybrid group (OpenSSL 3.5+, BoringSSL, or equivalent), with the group explicitly enabled and
prioritized in the server's group/curve configuration — the exact directive name is stack-specific, but the
pattern is the same as any other curve preference list: place
X25519MLKEM768ahead ofX25519so capable clients get the hybrid exchange while older clients still negotiate successfully.
Chrome and other major browsers already offer X25519MLKEM768 by default as of 2024–2025, so a server that
enables it sees a meaningful fraction of real handshakes upgrade to hybrid key exchange without any
client-side change required from end users.
PQC-Ready Providers
Provider comparisons and deployment guides for enabling X25519MLKEM768 on your own stack are
in progress — check back soon.