X25519MLKEM768 reference

X25519MLKEM768: codepoints, share sizes, and how to verify a hybrid handshake

X25519MLKEM768 is the hybrid key exchange most TLS 1.3 clients now offer by default. This page is the operator reference: the codepoint, the exact bytes on the wire, the ordering rule that differs between hybrid groups, and how to confirm what your server actually negotiated.

Decision brief

Primary query
x25519mlkem768
Best for
Engineers who run PKI or own cryptographic change and need reviewable evidence rather than a spreadsheet.
Safety boundary
Evidence supports decisions; it is not proof of implementation safety or compliance.

A hybrid group runs a classical key exchange and a post-quantum KEM in the same handshake and derives the TLS secret from both. If either component holds, the session holds. That is the whole reason hybrids exist: ML-KEM is young, X25519 is not quantum-resistant, and combining them means a break in one does not become a break in the connection. The cost is handshake size, which is where nearly all deployment problems come from.

Three hybrid groups were registered together. They do not share a concatenation rule, and that inconsistency is the source of most interoperability bugs when teams write their own implementations. In X25519MLKEM768 the ML-KEM share comes first and the X25519 share second. In SecP256r1MLKEM768 and SecP384r1MLKEM1024 the ECDH share comes first. The shared secret follows the same order as the key share in each case.

The older group X25519Kyber768Draft00 (codepoint 0x6399) is not the same thing. It uses round-3 Kyber, not the standardized ML-KEM from FIPS 203, and it is not interoperable with X25519MLKEM768. If a client and server fail to agree on a post-quantum group, check for this pair before checking anything else. Chrome shipped the Kyber draft group first and later replaced it, so a stack pinned to an older browser build may still be offering only the retired codepoint.

Reference

Values you can look up and check against your own systems

Hybrid group codepoints and wire sizes

Sizes are the key_share entry for each side. Registered in the IETF ECDHE-MLKEM hybrid key agreement draft.

GroupCodepointShare orderClient shareServer share
X25519MLKEM7680x11EC (4588)ML-KEM then X255191216 bytes1120 bytes
SecP256r1MLKEM7680x11EB (4587)ECDH then ML-KEM1249 bytes1153 bytes
SecP384r1MLKEM10240x11ED (4589)ECDH then ML-KEM1665 bytes1665 bytes
X25519Kyber768Draft000x6399 (25497)X25519 then Kyber1216 bytes1120 bytes
X25519 (classical)0x001D (29)n/a32 bytes32 bytes

Where the X25519MLKEM768 bytes come from

ML-KEM-768 values are the FIPS 203 parameter set. X25519 contributes 32 bytes on each side.

ComponentClient sendsServer sends
ML-KEM-768 encapsulation key1184 bytesnot sent
ML-KEM-768 ciphertextnot sent1088 bytes
X25519 ephemeral public key32 bytes32 bytes
Total key_share entry1216 bytes1120 bytes
Derived shared secret64 bytes (32 ML-KEM + 32 X25519)same

Verifying a hybrid handshake

Run these against a server you are authorized to test. The group name appears in the s_client session summary.

QuestionCommand
Does this OpenSSL build know the group?openssl list -tls-groups | grep -i mlkem
What did the server negotiate?openssl s_client -connect host:443 -tls1_3 </dev/null 2>&1 | grep -i 'Negotiated TLS1.3 group'
Force the hybrid group onlyopenssl s_client -connect host:443 -groups X25519MLKEM768 </dev/null
Confirm a fallback still worksopenssl s_client -connect host:443 -groups X25519 </dev/null
Which OpenSSL is on this path?openssl version -a

Support as of this page's review date

Confirm against your own build rather than this table. Distribution packages frequently lag upstream by a major version.

StackPosition
OpenSSL3.5 (released 8 April 2025) added ML-KEM, ML-DSA and SLH-DSA plus the hybrid TLS groups. 3.4 and earlier cannot negotiate them.
nginx / Apache httpdInherit the group list from the linked OpenSSL. Set it with ssl_ecdh_curve (nginx) or SSLOpenSSLConfCmd Groups (httpd).
Chrome and EdgeOffer X25519MLKEM768 by default from Chrome 131; the earlier X25519Kyber768Draft00 was retired.
FirefoxOffers X25519MLKEM768 for TLS from Firefox 132.
Gocrypto/tls offers X25519MLKEM768 by default from Go 1.24.
BoringSSL / rustlsBoth implement X25519MLKEM768; check the exact release notes for your pinned version.

Capabilities

What the operating model needs to do

01

Know the codepoint

0x11EC identifies X25519MLKEM768 in a ClientHello supported_groups list and in any packet capture you take of the handshake.

02

Budget the handshake

A 1216-byte client share pushes most ClientHello messages past 1400 bytes, so the first flight no longer fits one packet.

03

Prove the negotiation

Read the negotiated group from s_client rather than inferring it from configuration that may not have taken effect.

04

Keep a classical fallback

Leave X25519 in the group list so a client without ML-KEM support still completes a handshake instead of failing closed.

Workflow

A repeatable path to evidence

Use explicit scope, accountable decisions, and verification gates. Keep unknowns visible so progress is not manufactured by narrowing the denominator.

  1. 1

    Check the library

    Run openssl version -a and openssl list -tls-groups. If ML-KEM groups are absent, the server cannot negotiate a hybrid regardless of configuration.

  2. 2

    Set the group list

    Put X25519MLKEM768 first and keep X25519 and secp256r1 behind it. Reload, then confirm the running process picked up the change.

  3. 3

    Test from outside

    Use s_client with and without -groups to confirm both the hybrid path and the classical fallback complete.

  4. 4

    Watch the middle

    Look for handshake failures concentrated on specific networks or appliances. A ClientHello split across two packets is the usual cause.

Expected deliverables

Artifacts the next team can inspect

  • Recorded OpenSSL version and group list per endpoint
  • Negotiated-group evidence from an external client
  • Classical fallback test result
  • Handshake failure baseline before and after enabling the hybrid
  • Inventory entry linking each endpoint to its negotiated group

Buyer checklist

Questions for a proof of value

  1. 01Which endpoints can negotiate a hybrid group today, and which are blocked by an old OpenSSL?
  2. 02Does any endpoint still offer only X25519Kyber768Draft00?
  3. 03Did handshake failure rates move after the group list changed?
  4. 04Is the negotiated group recorded per endpoint, or only the configured intent?
  5. 05Which appliances sit between clients and these endpoints and inspect the ClientHello?

Limits and cautions

What this page does not promise

  • Offering a hybrid group is not the same as negotiating one. Only the server's own handshake output proves what happened.
  • A larger ClientHello can fail on paths that were fine with a classical handshake, and the failure often looks like an unrelated network problem.
  • Group names and default lists change between library releases. Treat any support table, including this one, as a starting point for your own check.
Local-first discovery

Talk to us about one representative repository

Qubrisk is in development and there is no self-serve signup yet. Tell us what your estate looks like and we will show you the evidence, the CBOM output, and the limits, without a sales sequence.

Contact us