X25519MLKEM768 as a stand-alone kem.
rustls 0.23.27+ ships X25519MLKEM768 inside its TLS stack but does not expose it as a reusable kem. anyone outside rustls (custom QUIC, MLS PQ ciphersuites, embedded TLS, HPKE PQ extensions) reimplements the byte concat and shared-secret combiner by hand. the closest existing crate, x-wing, is a different CFRG construction with a different byte layout, not wire-compatible. mlkem-tls is the TLS-WG hybrid combiner as a stand-alone crate, decoupled from rustls, with the byte order pinned to the draft.
bytes match the draft.
variant encaps key ciphertext shared TLS codepoint X25519MLKEM768 1216 B 1120 B 64 B 0x11EC X25519MLKEM1024 1600 B 1600 B 64 B non-standard on-the-wire layout, both parameter sets: encaps_key = MLKEM.ek || X25519.pub ciphertext = MLKEM.ct || X25519.eph_pub shared = MLKEM.ss || X25519.ss ML-KEM bytes first, X25519 second. the draft inverts the convention of secp256r1+mlkem hybrids, which put ECDHE first.
two halves, concat, no kdf.
classical: x25519-dalek
the audited curve25519-dalek family. the path that protects you against any classical adversary today. constant-time scalar multiplication, widely used in audited stacks (rustls, IPFS, age).
post-quantum: mlkem-rs
mlkem-rs, FIPS 203 ML-KEM in pure rust. the path that protects you when an adversary acquires a quantum computer. all three security levels, 180 NIST ACVP test vectors green, 11 kani-verified formal proofs, dudect-style timing evidence.
combiner: byte concat
the shared secret is `MLKEM.ss || X25519.ss` (32 bytes each). no kdf wrapper. matches §1.5 of draft-ietf-tls-ecdhe-mlkem-04 and what cloudflare, chrome, firefox and rustls 0.23.27+ ship today. resulting strength is at least the stronger of the two halves at any given moment.
RustCrypto-trait shaped
per-level newtypes (`EncapsKey768`, `DecapsKey768`, `Ciphertext768Hybrid`, `SharedSecret768Hybrid`). `as_bytes()` for typed exit, `TryFrom<&[u8]>` with `LengthError` for the validating entry. constant-time `PartialEq` via `subtle`. `ZeroizeOnDrop` on the secret types.
no_std-friendly
default feature `std` is on; turn it off for embedded / wasm builds. only crypto deps are mlkem-rs, x25519-dalek, sha3, subtle, zeroize. no `unsafe` blocks. no git deps. no pre-1.0 crypto.
audit-readiness pack
SECURITY.md + SUPPLY_CHAIN.md. the post-quantum half (mlkem-rs) ships a full pack of its own (SECURITY, SIDE_CHANNELS, AUDIT_SCOPE, FORMAL_VERIFICATION, SUPPLY_CHAIN).
rustls already ships hybrid. why a separate crate?
rustls bakes the X25519MLKEM768 combiner into its TLS stack. fine for users who run their TLS through rustls. less fine for everyone else. quinn users wiring custom crypto for QUIC reimplement the concat. embedded TLS implementations need a kem they can ship in 30 KB. MLS PQ ciphersuites and HPKE PQ extensions need the hybrid combiner with the same byte order rustls uses, but as a library, not a TLS stack. the closest crate that exists today, x-wing, is a different CFRG construction with a different byte layout. it is not wire-compatible.
so this crate is the missing piece. one job: take the TLS-WG hybrid combiner, expose it as a stand-alone kem with the kind of typed surface the RustCrypto ecosystem is used to. compose it into your protocol, your way, your library.
one line.
$ cargo add mlkem-tls
for embedded / wasm: cargo add mlkem-tls --no-default-features. requires rust 1.70+.
not audited. for production hybrid TLS in rustls, use rustls 0.23.27+ which ships the audited rustcrypto ml-kem inside the TLS stack. this crate is for stacks that don't use rustls.