ML-KEM (FIPS 203)
ML-KEM is the NIST-standardized key-encapsulation mechanism derived from CRYSTALS-Kyber. Built on the Module Learning With Errors (Module-LWE) problem, it is fast, has small keys and ciphertexts, and is NIST's recommended general-purpose post-quantum KEM.
How it works
ML-KEM is a key-encapsulation mechanism (KEM): instead of encrypting an arbitrary message, it lets two parties agree on a fresh 32-byte shared secret. The sender uses the recipient's encapsulation key to produce a ciphertext plus a shared secret; the recipient uses its decapsulation key to recover the same secret from the ciphertext.
The core building block is K-PKE, a public-key encryption scheme whose security rests on Module-LWE — recovering a secret vector from noisy linear equations over a polynomial ring. K-PKE is only IND-CPA secure, so ML-KEM wraps it in the Fujisaki-Okamoto (FO) transform to obtain IND-CCA2 security: the decapsulator re-encrypts the recovered message and rejects the ciphertext if it does not match, with an implicit-rejection fallback that returns a pseudorandom secret rather than failing visibly.
ML-KEM uses the SHA3/SHAKE family of functions for hashing, XOF expansion, matrix generation, noise sampling, and key derivation. The matrix arithmetic is done with the Number-Theoretic Transform (NTT), which keeps the scheme very fast.
Parameter sets
Three parameter sets target NIST security categories 1, 3, and 5. All sizes are in bytes; the shared secret is always 32 bytes.
| Parameter set | Security level | Encaps key (ek) | Decaps key (dk) | Ciphertext (ct) | Shared secret |
|---|---|---|---|---|---|
| ML-KEM-512 | Category 1 | 800 | 1632 | 768 | 32 |
| ML-KEM-768 (default) | Category 3 | 1184 | 2400 | 1088 | 32 |
| ML-KEM-1024 | Category 5 | 1568 | 3168 | 1568 | 32 |
ML-KEM-768 is the recommended default for most deployments, balancing a comfortable security margin against modest bandwidth.
Strengths & tradeoffs
- Fast. Key generation, encapsulation, and decapsulation are all sub-millisecond on commodity hardware — competitive with or faster than classical ECDH.
- Compact. Keys and ciphertexts are a few kilobytes, small enough to fit in a TLS handshake without major disruption.
- Well-studied. Module-LWE has been analyzed extensively, and Kyber was the flagship lattice KEM through every NIST round.
- Tradeoff: larger than classical ECDH (32-byte keys), and lattice assumptions are newer than code-based ones. For algorithm diversity, NIST also selected the code-based HQC KEM for standardization as a backup (final FIPS not yet published).
When to use it
Use ML-KEM as your primary post-quantum KEM for TLS, SSH, IPsec, VPNs, and any protocol that performs an ephemeral key exchange. In practice it is deployed in a hybrid mode (e.g. X25519 + ML-KEM-768) so that the connection stays secure even if one of the two schemes is later broken.
ML-KEM replaces quantum-vulnerable public-key key-establishment mechanisms, such as finite-field DH, ECDH, and RSA-based key transport or KEM-style use cases. It does not replace digital signatures; use ML-DSA, SLH-DSA, or future FN-DSA for signature use cases.
Code example
A minimal encapsulate/decapsulate round trip using liboqs-python:
import oqs
kem = "ML-KEM-768"
with oqs.KeyEncapsulation(kem) as server:
public_key = server.generate_keypair()
# Client encapsulates against the server's public key
with oqs.KeyEncapsulation(kem) as client:
ciphertext, ss_client = client.encap_secret(public_key)
# Server recovers the same shared secret
ss_server = server.decap_secret(ciphertext)
assert ss_client == ss_server
print("shared secret bytes:", len(ss_client)) # 32
Standards & references
- FIPS 203 (ML-KEM) — the official ML-KEM standard.
- CRYSTALS-Kyber project — the design ML-KEM is derived from.
- Open Quantum Safe — liboqs implementation used in the code example.
- Resources — full standards register
Related
ML-KEM FIPS 203
ML-KEM 是 NIST 标准化的密钥封装机制,源自 CRYSTALS-Kyber。它基于模格上的带误差学习问题(Module-LWE),运算快、密钥与密文小巧,是 NIST 推荐的主力通用后量子 KEM。
工作原理
ML-KEM 是一种密钥封装机制(KEM):它不直接加密任意消息,而是让通信双方协商出一段全新的 32 字节共享密钥。发送方用接收方的封装公钥生成一段密文和一个共享密钥;接收方再用自己的解封装私钥从密文中还原出同一个密钥。
其核心组件是 K-PKE,一个安全性建立在 Module-LWE 之上的公钥加密方案——攻击者需要从带噪声的多项式环线性方程组中还原秘密向量。K-PKE 本身只满足 IND-CPA,因此 ML-KEM 用 Fujisaki-Okamoto(FO)变换将其升级为 IND-CCA2:解封装方会重新加密还原出的消息,若与收到的密文不一致则拒绝,并通过隐式拒绝返回一个伪随机密钥,而非暴露失败。
ML-KEM 使用 SHA3/SHAKE 系列函数完成哈希、XOF 扩展、矩阵生成、噪声采样和密钥派生等步骤。矩阵运算借助数论变换(NTT),使整体速度极快。
参数集
三组参数分别对应 NIST 安全等级 1、3、5。下表尺寸单位为字节,共享密钥固定为 32 字节。
| 参数集 | 安全等级 | 封装公钥 ek | 解封装私钥 dk | 密文 ct | 共享密钥 |
|---|---|---|---|---|---|
| ML-KEM-512 | 等级 1 | 800 | 1632 | 768 | 32 |
| ML-KEM-768 默认 | 等级 3 | 1184 | 2400 | 1088 | 32 |
| ML-KEM-1024 | 等级 5 | 1568 | 3168 | 1568 | 32 |
多数场景推荐以 ML-KEM-768 为默认,在充裕的安全裕度与适中的带宽之间取得平衡。
优势与取舍
- 快。密钥生成、封装、解封装在普通硬件上均为亚毫秒级,与经典 ECDH 相当甚至更快。
- 小巧。密钥和密文仅几千字节,足以塞进 TLS 握手而不致显著膨胀。
- 研究充分。Module-LWE 经过广泛分析,Kyber 也是 NIST 历轮评选中的格 KEM 旗舰。
- 取舍:体积仍大于经典 ECDH(32 字节密钥),且格假设的历史短于编码类。为保证算法多样性,NIST 另行将基于编码的 HQC KEM 选入标准化流程作为备份(最终 FIPS 尚未发布)。
适用场景
在 TLS、SSH、IPsec、VPN 等任何执行临时密钥交换的协议中,都可把 ML-KEM 作为首选的后量子 KEM。实际部署中普遍采用混合模式(如 X25519 + ML-KEM-768),即便其中一方日后被攻破,连接依然安全。
ML-KEM 替代的是易受量子攻击的公钥密钥建立机制,例如有限域 DH、ECDH,以及基于 RSA 的密钥传输或 KEM 类用途。它不替代数字签名;签名场景应使用 ML-DSA、SLH-DSA 或未来的 FN-DSA。
代码示例
使用 liboqs-python 完成一次最简封装/解封装往返:
import oqs
kem = "ML-KEM-768"
with oqs.KeyEncapsulation(kem) as server:
public_key = server.generate_keypair()
# 客户端用服务器公钥进行封装
with oqs.KeyEncapsulation(kem) as client:
ciphertext, ss_client = client.encap_secret(public_key)
# 服务器还原出相同的共享密钥
ss_server = server.decap_secret(ciphertext)
assert ss_client == ss_server
print("共享密钥字节数:", len(ss_client)) # 32
标准与参考
- FIPS 203 ML-KEM — ML-KEM 官方标准。
- CRYSTALS-Kyber 项目 — ML-KEM 所源自的设计。
- Open Quantum Safe — 代码示例所用的 liboqs 实现。
- 资源链接 — 完整标准登记册