# Post-quantum TLS: X25519MLKEM768 and Merkle Tree Certificates

> Post-quantum TLS in 2026: the hybrid ML-KEM key exchange browsers already use, why post-quantum certificates are hard, and how Merkle Tree Certificates help.

Source: https://ssl.sh/learn/post-quantum-tls/
Last updated: 2026-11-10

Post-quantum TLS in production today means one thing: the hybrid key exchange X25519MLKEM768, which Chrome, Edge and other clients already negotiate with servers that support it. It protects recorded traffic from later decryption by a quantum computer. Certificates stay classical because post-quantum signatures are large; the web's plan for them, Merkle Tree Certificates, is still experimental as of November 2026.

## Why key exchange moved first

Key exchange is urgent because of "harvest now, decrypt later": traffic recorded today can be decrypted once a cryptographically relevant quantum computer exists. Shor's algorithm breaks both RSA and elliptic-curve cryptography, so the ECDHE secret that protects a 2026 TLS session would fall along with everything it encrypted.

Signatures are different. A forged signature only matters while the certificate is valid and the attacker is online, so a quantum computer built in the future cannot retroactively impersonate a server in a past connection.

| Part of TLS | Classical algorithm today | Quantum threat | Urgency |
|---|---|---|---|
| Key exchange (session secrecy) | ECDHE with X25519 or P-256 | Recorded traffic decrypted later | Now: data captured today is at risk |
| Server authentication (certificates, CertificateVerify) | RSA, ECDSA | Live impersonation once a quantum computer exists | Before such a computer exists, with downgrade protection |
| Symmetric encryption | AES-128/256-GCM, ChaCha20-Poly1305 | Grover's algorithm roughly halves effective strength | Low: AES-256 and even AES-128 hold up in practice |

## The standards: ML-KEM, ML-DSA and SLH-DSA

NIST published the first three post-quantum standards on August 13, 2024, and TLS uses them in two different roles.

| Standard | Algorithm | Origin | Role in TLS |
|---|---|---|---|
| FIPS 203 | ML-KEM (512, 768, 1024) | CRYSTALS-Kyber | Key exchange (key encapsulation) |
| FIPS 204 | ML-DSA (44, 65, 87) | CRYSTALS-Dilithium | Signatures: certificates, CertificateVerify |
| FIPS 205 | SLH-DSA | SPHINCS+ | Conservative hash-based signatures; very large |

For TLS 1.3 key exchange, RFC 10024 (August 2026) defines three hybrid groups: `X25519MLKEM768` (0x11EC), `SecP256r1MLKEM768` and `SecP384r1MLKEM1024`. Earlier deployments used `X25519Kyber768Draft00` (0x6399), a pre-standard version of Kyber that browsers have since dropped.

## How hybrid key exchange works

X25519MLKEM768 runs ML-KEM-768 and X25519 side by side inside a single TLS 1.3 key share and concatenates the two results. The handshake message flow does not change; only the size of the `key_share` values does.

```text
ClientHello
  supported_groups: X25519MLKEM768, X25519, ...
  key_share (X25519MLKEM768) = ML-KEM-768 encapsulation key (1184 B) || X25519 public (32 B)
                               = 1216 bytes
                                   |
                                   v
ServerHello
  key_share (X25519MLKEM768) = ML-KEM-768 ciphertext (1088 B) || X25519 public (32 B)
                               = 1120 bytes

shared secret = ML-KEM shared secret (32 B) || X25519 shared secret (32 B) = 64 bytes
                -> TLS 1.3 HKDF key schedule (unchanged)
```

An attacker has to break both components to recover the session keys. If ML-KEM turns out to have a flaw, the connection is no weaker than a classical X25519 one; if a quantum computer breaks X25519, ML-KEM still protects it.

The cost is bytes. Measured locally with OpenSSL 3.6.1 against a test server:

| Configuration | ClientHello handshake message | ServerHello |
|---|---|---|
| X25519 only | 283 bytes | 122 bytes |
| OpenSSL default (X25519MLKEM768 + X25519 shares) | 1,517 bytes | 1,210 bytes |

The computation itself is cheap; ML-KEM is fast on ordinary CPUs. The size is what causes trouble.

## Browser and server support as of November 2026

Hybrid ML-KEM is already the default between modern browsers and modern servers.

| Software | Status |
|---|---|
| Chrome | Hybrid Kyber (X25519Kyber768) added in Chrome 116 (August 2023), on by default for desktop from Chrome 124 (April 2024); switched to X25519MLKEM768 in Chrome 131, dropping Kyber |
| Edge and other Chromium browsers | Follow Chromium's TLS stack; versions lag Chrome by however far the vendor's kernel lags |
| Firefox, Safari | Have added X25519MLKEM768 support in recent releases; defaults depend on version and platform, so test the versions your users run |
| OpenSSL | 3.5 (LTS) added ML-KEM, ML-DSA and SLH-DSA; default key shares are X25519MLKEM768 and X25519 |
| nginx, Apache, HAProxy | Inherit support from the TLS library they are built against |
| CDNs | Large CDNs negotiate X25519MLKEM768 with supporting browsers |

Chrome 131 offered only one post-quantum key share at a time; Google explained that sending both Kyber and ML-KEM would make the ClientHello too large. A server that supports only the old Kyber codepoint therefore gets classical X25519 from current Chrome.

On a server, hybrid key exchange usually needs no change beyond a recent TLS library. With nginx built against OpenSSL 3.5 or later, you can set the order explicitly:

```nginx
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ecdh_curve X25519MLKEM768:X25519:prime256v1:secp384r1;
```

Check what `nginx -V` reports as the OpenSSL version first; many distribution packages are built against older OpenSSL 3.0 or 3.2 releases, where the `X25519MLKEM768` name is unknown and nginx fails to start with this line.

Test a server from the command line (OpenSSL 3.5+):

```bash
openssl s_client -connect example.com:443 -servername example.com \
  -groups X25519MLKEM768 -brief </dev/null
```

```text
Connecting to 203.0.113.10
CONNECTION ESTABLISHED
Protocol version: TLSv1.3
Ciphersuite: TLS_AES_256_GCM_SHA384
Peer certificate: CN=example.com
Signature type: ecdsa_secp256r1_sha256
Verification: OK
Negotiated TLS1.3 group: X25519MLKEM768
```

A server without support aborts with `alert handshake failure` (alert 40), because the client offered no other group. Note the `Signature type: ecdsa_secp256r1_sha256` line: the key exchange is post-quantum, the authentication is not. More group and protocol tests are in [cipher and protocol commands](https://ssl.sh/cookbook/ciphers-and-protocols/).

## Large ClientHellos and middleboxes

The most common deployment problem is not cryptography but network equipment that mishandles a ClientHello larger than one packet. A ClientHello with an X25519MLKEM768 share is around 1.5 KB to 1.8 KB depending on other extensions, so with a typical 1,500-byte MTU it no longer fits in a single TCP segment or QUIC packet.

Known failure patterns:

- Firewalls, TLS-inspection proxies and load balancers that read only the first TCP segment to extract SNI, then drop or reset the connection.
- Fixed-size ClientHello buffers in older appliances, which close the connection when the message exceeds them.
- Servers that do not understand the new group must answer with HelloRetryRequest; well-behaved clients also send an X25519 share to avoid that extra round trip.

When Chrome turned hybrid key exchange on, Google gave administrators an enterprise policy (`PostQuantumKeyAgreementEnabled`) as a temporary switch while vendors fixed their equipment. The real fix is updating the middlebox; on the server side, make sure your load balancer or WAF firmware is current before you enable ML-KEM groups at the origin.

## Why post-quantum certificates are hard

Post-quantum signatures are an order of magnitude larger than ECDSA, and a TLS handshake carries several of them. Sizes from FIPS 204 and common practice:

| Algorithm | Public key | Signature |
|---|---|---|
| ECDSA P-256 | 64 bytes (65 encoded) | about 64 to 72 bytes |
| RSA-2048 | 256 bytes | 256 bytes |
| ML-DSA-44 | 1,312 bytes | 2,420 bytes |
| ML-DSA-65 | 1,952 bytes | 3,309 bytes |
| ML-DSA-87 | 2,592 bytes | 4,627 bytes |

A typical web handshake authenticates with at least two public keys (leaf and intermediate) and five signatures: the intermediate's signature on the leaf, the root's signature on the intermediate, the server's CertificateVerify, and two or more [SCTs](https://ssl.sh/glossary/sct/) required by [Certificate Transparency](https://ssl.sh/learn/certificate-transparency/). If every one of them became ML-DSA-44, that is roughly 5 × 2,420 + 2 × 1,312 ≈ 14.7 KB of authentication data, compared with under 1 KB for an ECDSA chain. A minimal self-signed certificate generated locally with OpenSSL 3.6.1 shows the same jump: 389 bytes with P-256, 785 bytes with RSA-2048 and 3,985 bytes with ML-DSA-44.

Fourteen kilobytes matters because it pushes the server's first flight past TCP's initial congestion window of ten segments (RFC 6928), adding round trips on every new connection, and it makes the middlebox problems above worse. Google's February 2026 announcement says Chrome has "no immediate plan" to add X.509 certificates with post-quantum cryptography to the Chrome Root Store.

## Merkle Tree Certificates

Merkle Tree Certificates (MTCs) replace the chain of signatures with a short proof that the certificate is included in a signed Merkle tree. The design comes from the IETF PLANTS (PKI, Logs, And Tree Signatures) working group as `draft-ietf-plants-merkle-tree-certs`, which grew out of an earlier individual draft by David Benjamin.

```text
Classical X.509 + CT                          Merkle Tree Certificate
--------------------                          -----------------------
Root signs Intermediate      (signature)      CA signs one tree head covering
Intermediate signs Leaf      (signature)      many certificates          (1 signature,
CT logs sign SCTs            (2+ signatures)                              fetched out of band)
Server signs handshake       (signature)
                                              Server sends: its key + inclusion proof
Server sends: chain + SCTs + CertificateVerify   (a few hashes) + CertificateVerify
```

Because the browser learns the signed tree heads ahead of time, the handshake carries hashes instead of large signatures, and transparency is built in: a certificate cannot exist without being in a public tree. In February 2026 Google described the plan in phases: a feasibility study with Cloudflare on real traffic, in which every MTC connection is backed by a normal X.509 certificate as a fail-safe; then bootstrapping public MTCs with existing CT log operators; then a separate Chrome Quantum-resistant Root Store that accepts only MTCs. As of November 2026 this is still experimental, and the draft is still changing.

## Downgrade protection: the hard part of authentication

Adding post-quantum certificates protects nobody until browsers can refuse classical ones. An attacker with a quantum computer would forge a classical certificate from any trusted CA and impersonate a site, regardless of which certificate the real site uses. Chromium's post-quantum authentication roadmap (February 2026) therefore describes stages: add post-quantum options, let individual sites opt in to requiring them through an HSTS-like mechanism, then require a post-quantum PKI, and only far in the future require post-quantum server keys everywhere. The opt-in idea works like [HSTS](https://ssl.sh/learn/hsts/): a header with `max-age` that a browser remembers.

## What to do now

Most sites need one change now, enabling X25519MLKEM768, and should not buy post-quantum certificates yet. The full list:

1. **Turn on hybrid key exchange.** Upgrade to a TLS library that supports X25519MLKEM768 (OpenSSL 3.5+, a current BoringSSL-based proxy or a CDN that negotiates it) and confirm with `s_client -groups`.
2. **Check the network path.** Test through your load balancer, WAF and any TLS-inspection device; that is where large ClientHellos break.
3. **Keep TLS 1.3 enabled.** Hybrid groups are defined only for TLS 1.3. See [TLS 1.3](https://ssl.sh/learn/tls-1-3/).
4. **Inventory long-lived secrets.** VPNs, internal APIs and data links carrying information that must stay secret for a decade are the first places to require ML-KEM.
5. **Do not buy "post-quantum certificates" for public websites yet.** Keep certificate issuance automated instead, so that a future switch to MTCs or ML-DSA is a configuration change rather than a project.

For definitions, see [post-quantum cryptography](https://ssl.sh/glossary/post-quantum-cryptography/), [ML-KEM](https://ssl.sh/glossary/ml-kem/) and [X25519MLKEM768](https://ssl.sh/glossary/x25519mlkem768/).
