ML-KEM (FIPS 203, August 2024) is the NIST-standardized successor to CRYSTALS-Kyber — same lattice construction, new name. As a KEM it cannot encrypt data directly; it encapsulates a fresh 32-byte shared secret against a recipient’s public key. The standard pattern is KEM-DEM: use that secret to key a symmetric AEAD (here AES-256-GCM), which mirrors how TLS hybrid key exchange deploys post-quantum crypto today.
MlKem768HybridAlgorithm in lib/algorithms implements this construction:
Unlike the symmetric specimens, key management is keypair-based: a sender holding only the public key can encrypt, but only the secret-key holder can decapsulate. Every encrypt() performs a fresh encapsulation, so each message is keyed independently — there is no long-lived symmetric key to rotate or leak.
from lib.algorithms import MlKem768HybridAlgorithm, MlKem768HybridInput# Recipient generates a keypair and publishes the public keypublic_key, secret_key = MlKem768HybridAlgorithm.generate_keypair()sender = MlKem768HybridAlgorithm(public_key=public_key)recipient = MlKem768HybridAlgorithm(public_key=public_key, secret_key=secret_key)encrypted = sender.encrypt(MlKem768HybridInput(plaintext=b"post-quantum hello"))decrypted = recipient.decrypt(encrypted)print("plaintext:", decrypted.data)print("kem ciphertext:", len(encrypted.kem_ciphertext), "bytes")print("encrypt metrics:", encrypted.metrics)print("decrypt metrics:", decrypted.metrics)
2.0 — Riding the Composer: PQ Hybrid vs Classical AEADs
How much does post-quantum security cost? We register the hybrid alongside the two classical production AEADs and let the composer answer. Note the hybrid is adapted without a key — it manages its own keypair, and the adapter persists the per-message KEM ciphertext and nonce through the CryptoRegistry.
The hybrid pays a fixed per-message tax: one encapsulation (~0.1 ms) plus 1,088 bytes of KEM ciphertext, regardless of payload size. At 100 B that tax dominates; at 100 KB it is noise and throughput converges toward plain AES-256-GCM, since the DEM does all the bulk work.
That is the whole argument for KEM-DEM in practice: post-quantum key establishment costs are O(1) per message, so the classical/PQ throughput gap shrinks as payloads grow. The interesting research direction for this lab is layering — running the KEM step and a classical key exchange and combining the secrets, which is exactly what the Multi Encryption composer on the roadmap is for.