v151 · security · post-quantum
ML-KEM Key Encapsulation
ML-KEM (FIPS 203) is a lattice-based key-encapsulation mechanism. Instead of both sides agreeing on a secret, the sender encapsulates a fresh random secret against the recipient's public key, producing a ciphertext; the recipient decapsulates that ciphertext with their private key to recover the identical secret. This demo runs the real crypto.subtle.encapsulateBits / decapsulateBits methods end to end.
WebCryptoPQC runtime feature. To run this for real:
- Quit Chrome, then relaunch with
--enable-blink-features=WebCryptoPQC(in a Chrome/Canary build containing the experimental implementation), or - Join the
WebCryptoAdditionalAlgorithms202606origin trial and add its token to your page.
sender → encapsulateBits(publicKey)
shared secret derived by the sender
ciphertext sent to the recipient
recipient → decapsulateBits(privateKey, ciphertext)
shared secret recovered by the recipient
the code
// 1. Recipient generates an ML-KEM key pair
const { publicKey, privateKey } = await crypto.subtle.generateKey(
{ name: "ML-KEM-768" }, true, ["encapsulateBits", "decapsulateBits"]);
// 2. Sender encapsulates a fresh shared secret against the public key
const { sharedKey, ciphertext } =
await crypto.subtle.encapsulateBits("ML-KEM-768", publicKey);
// 3. Recipient decapsulates the ciphertext to recover the same secret
const recovered =
await crypto.subtle.decapsulateBits("ML-KEM-768", privateKey, ciphertext);
// sharedKey === recovered, byte for byte
Unlike Diffie-Hellman, encapsulation is one-directional: only the recipient's public key is needed, and only the recipient can recover the secret. That shared secret then seeds a symmetric cipher (like the ChaCha20-Poly1305 demo) for the actual data.
see also
- ML-DSA Post-Quantum Signatures
- Algorithm Support Probe — detect ML-KEM before you call it.
- ChaCha20-Poly1305 AEAD — encrypt with the derived secret.