ML-KEM (Post-Quantum)
Post-quantum ML-KEM-768 (Kyber) key encapsulation with Web Crypto at the edge - PQC demo for quantum-resistant key exchange
ML-KEM (formerly Kyber) is NIST's post-quantum key encapsulation standard. This Worker demonstrates ML-KEM-768 with the Web Crypto API on Cloudflare Workers: generate a key pair, encapsulate a shared secret, and decapsulate to verify - a pasteable PQC reference for quantum-resistant key exchange at the edge.
API Reference
GET /keygen
Generate an ML-KEM-768 key pair, encapsulate to a ciphertext, and decapsulate to verify that the shared secrets match.
Parameters: None
Example request
curl https://ml-kem.example.workers.dev/keygenExample response
{
"algorithm": "ML-KEM-768",
"publicKey": "a1b2c3d4...",
"ciphertext": "e5f6g7h8...",
"encapsulatedSecret": "i9j0k1l2...",
"decapsulatedSecret": "i9j0k1l2...",
"secretsMatch": true,
"publicKeyLength": 1184,
"ciphertextLength": 1088,
"sharedSecretLength": 32
}Fields
algorithmstring- The ML-KEM variant used (ML-KEM-768)publicKeystring- Hex-encoded public keyciphertextstring- Hex-encoded ciphertext from encapsulationencapsulatedSecretstring- Truncated hex-encoded shared secret (first 32 chars + "...")decapsulatedSecretstring- Truncated hex-encoded shared secret from decapsulationsecretsMatchboolean-truewhen encapsulated and decapsulated secrets matchpublicKeyLengthnumber- Public key size in bytes (1184 for ML-KEM-768)ciphertextLengthnumber- Ciphertext size in bytes (1088 for ML-KEM-768)sharedSecretLengthnumber- Shared secret size in bytes (32)
Use Cases
- Demonstrating post-quantum cryptography at the edge
- Testing ML-KEM-768 implementation for migration planning
- Building quantum-resistant key exchange demos
- Educational exploration of NIST post-quantum standards
Limitations
- Uses the
webcrypto_modern_algorithmscompatibility flag (may not be available in all environments) - Generates a fresh key pair on every request (stateless demo)
- Shared secrets are truncated in response for readability
- No persistent storage or key management
Use in your project
Copy these files into an existing Worker. Prefer Deployment to try the full experiment first. Source: apps/experiments/ml-kem.
export async function generateKeyPairAndTest() { const keyPair = (await crypto.subtle.generateKey( { name: "ML-KEM", namedCurve: "ML-KEM-768", }, true, ["deriveBits"] )) as CryptoKeyPair; const publicKeyExported = await crypto.subtle.exportKey("raw", keyPair.publicKey); const publicKeyHex = arrayBufferToHex(publicKeyExported); const { ciphertext, sharedSecret: encapsulatedSecret } = await crypto.subtle.encapsulate( keyPair.publicKey ); const ciphertextHex = arrayBufferToHex(ciphertext); const encapsulatedSecretHex = arrayBufferToHex(encapsulatedSecret); const decapsulatedSecret = await crypto.subtle.decapsulate(keyPair.privateKey, ciphertext); const decapsulatedSecretHex = arrayBufferToHex(decapsulatedSecret); const secretsMatch = encapsulatedSecretHex === decapsulatedSecretHex; return { algorithm: "ML-KEM-768", publicKey: publicKeyHex, ciphertext: ciphertextHex, encapsulatedSecret: encapsulatedSecretHex.substring(0, 32) + "...", decapsulatedSecret: decapsulatedSecretHex.substring(0, 32) + "...", secretsMatch, publicKeyLength: publicKeyExported.byteLength, ciphertextLength: ciphertext.byteLength, sharedSecretLength: decapsulatedSecret.byteLength, };}function arrayBufferToHex(buffer: ArrayBuffer): string { return Array.from(new Uint8Array(buffer)) .map((b) => b.toString(16).padStart(2, "0")) .join("");}Deployment
Test the endpoint
curl https://ml-kem.your-subdomain.workers.dev/keygenYou should see a JSON response with secretsMatch: true.
Local Development
cd apps/experiments/ml-kem
npm install
npm run devThe Worker runs at http://localhost:8787.
Test locally
curl http://localhost:8787/keygenConfiguration
Compatibility flags
This experiment requires the webcrypto_modern_algorithms flag in wrangler.json:
{
"compatibility_flags": ["webcrypto_modern_algorithms"]
}No bindings or secrets required.
Cloudflare Features Used
- Workers - Edge compute platform
- Web Crypto API - Cryptographic operations at the edge
- ML-KEM-768 post-quantum key encapsulation (via
webcrypto_modern_algorithmsflag)