f4rkh4d/mlkem-rs
GitHub: f4rkh4d/mlkem-rs
纯 Rust 从头实现的后量子密钥封装标准 ML-KEM(FIPS 203),覆盖三个安全级别,代码简洁易读,适合学习研究和原型开发。
Stars: 0 | Forks: 1
# mlkem
纯 Rust 实现的后量子 KEM (ML-KEM,前身是 Kyber)。包含全部三个安全级别。通过了所有 180 个官方 NIST ACVP 测试向量,并与经过审计的 RustCrypto 参考实现在 3000 个随机种子上进行了逐字节的交叉验证。约 700 行代码,`sha3` 是唯一的加密依赖。
[](https://crates.io/crates/mlkem-rs)
[](https://docs.rs/mlkem-rs)
[](https://crates.io/crates/mlkem-rs)
[](https://github.com/f4rkh4d/mlkem-rs/actions)
[](#)
[](#)
[](#license)
## 这是什么
这是 [FIPS 203](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.203.pdf) 的一个实现,它是取代了 Kyber 的 NIST 后量子密钥封装标准。包含全部三个参数集(安全类别 1、3、5):
| 变体 | k | pk | sk | ct | NIST 类别 |
|--------------|---|---------|---------|---------|---------------|
| ml-kem-512 | 2 | 800 B | 1632 B | 768 B | 1 (aes-128) |
| ml-kem-768 | 3 | 1184 B | 2400 B | 1088 B | 3 (aes-192) |
| ml-kem-1024 | 4 | 1568 B | 3168 B | 1568 B | 5 (aes-256) |
根据规范从头编写。唯一的加密依赖是 `sha3`。没有 `unsafe`。没有 C 绑定。兼容 `no_std`(默认开启 `std` 特性;在嵌入式环境中请将其关闭)。
这是我个人实现的版本,未经过审计。如果您在生产环境中需要经过审计的加密库,请使用 RustCrypto 的 [`ml-kem`](https://crates.io/crates/ml-kem)。如果您想从头到尾阅读 700 行后量子代码,那么本项目正是为此而生。
## 安装
```
cargo add mlkem-rs
```
## 用法
```
use mlkem::{MlKem768, PublicKey768, SecretKey768};
use rand::thread_rng;
let mut rng = thread_rng();
// bob generates a keypair
let (bob_pk, bob_sk) = MlKem768::keygen(&mut rng);
// alice encapsulates to bob's public key
let (ct, alice_ss) = MlKem768::encapsulate(&bob_pk, &mut rng);
// bob decapsulates and recovers the same shared secret
let bob_ss = MlKem768::decapsulate(&bob_sk, &ct);
assert_eq!(alice_ss, bob_ss);
```
`MlKem512` 和 `MlKem1024` 具有相同的接口。如果您需要提供自己的种子(例如用于测试),可以使用确定性 API (`keygen_deterministic`, `encapsulate_deterministic`)。
## 正确性
- **NIST ACVP 向量。** `tests/nist_kats.rs` 运行了来自 [NIST 算法验证程序](https://github.com/usnistgov/ACVP-Server) 的全部 180 个官方 ML-KEM 测试用例(75 个密钥生成 + 75 个封装 + 30 个解封装),均匀分布在三个参数集中。每个输出的每一个字节都完全匹配。
- **交叉检查。** `tests/cross_check.rs` 分别针对每个参数集运行 1000 个确定性种子,同时通过本库和经过审计的 [RustCrypto `ml-kem`](https://crates.io/crates/ml-kem) 进行验证。它断言 pk、sk、密文和恢复出的共享秘密在字节级别上相等。总共 3000 次往返测试。只要有任何偏差,测试就会中断。
- **API 测试。** `tests/api.rs` 覆盖了握手、确定性、大小、篡改密文的隐式拒绝以及序列化往返测试。通过宏实例化适用于所有三个安全级别。
- **压力测试。** `tests/stress.rs` 在每次 `cargo test` 时运行 24000 次固定种子迭代:每个参数集执行 5000 次正常往返测试、2000 次随机篡改隐式拒绝检查、1000 次垃圾输入解封装调用。总共耗时约 1 秒。
- **模糊测试。** `fuzz/` 目录提供了一个包含四个目标 (decap-no-panic, encap-no-panic, tampered-ct-implicit-reject, round-trip) 的 `cargo-fuzz` 线束。仅限 nightly 版本;详情请参见 `fuzz/README.md`。
- **常量时间。** 共享秘密相等性检查、FO 变换密文检查以及密钥比较使用了 [`subtle`](https://crates.io/crates/subtle)。私钥和共享秘密均为 `ZeroizeOnDrop`。自 0.9.0 起,[`tests/timing.rs`](tests/timing.rs) 中引入了 [dudect](https://github.com/oreparaz/dudect)-风格的时序线束,对正常和被篡改密文的解封装延迟运行 Welch t 检验;在 Apple M 系列芯片上,20000 个样本的测试结果显示 `|t|=1.232`,远低于 dudect 严格的阈值 4.5。有关每个依赖秘密操作的清单,请参阅 [`SIDE_CHANNELS.md`](SIDE_CHANNELS.md)。
- **内存。** 内部缓冲区通过 `Vec` 处理。擦除机制适用于公开的 `SecretKey*` 和 `SharedSecret*` 类型,但不适用于内部暂存数据。如果您需要更强的安全保障,请在依赖前进行审计。
## 性能
Apple M 系列,使用 `opt-level = 3, lto = "thin"` 的 `cargo bench`,未启用 SIMD,纯 Barrett 约简:
| 操作 | ml-kem-512 | ml-kem-768 | ml-kem-1024 |
|--------------|-----------:|-----------:|------------:|
| keygen | 26 µs | 40 µs | 57 µs |
| encapsulate | 25 µs | 38 µs | 60 µs |
| decapsulate | 33 µs | 50 µs | 77 µs |
作为参考,[RustCrypto `ml-kem`](https://crates.io/crates/ml-kem) 在同一台机器上的结果为:512 下 13 / 12 / 17 µs,768 下 23 / 20 / 25 µs,1024 下 36 / 31 / 38 µs。因此,本库的周期数大约是经过审计的参考实现的 1.7-2 倍,且在三个级别上保持一致。这种差距源于未使用 Montgomery 约简和 SIMD。对于工具开发和学习来说性能足够,但如果您每秒需要处理一百万次握手,则可能不够。
在堆分配方面,代数核心(矩阵采样、多项式向量、NTT、basemul)自 0.5.0 版本起已实现零分配。目前仅剩的分配是 `kpke::keygen` / `encrypt` 返回的字节编码输出 `Vec`,这些数据随后会被复制到公开 API 的固定大小数组中。
## 缺少什么
- 没有硬件加速路径(无 AVX2,无 NEON,无 AARCH64 SVE)。
- 未审计。尽管与经过审计的 RustCrypto 库的交叉检查在我们测试过的每一个字节上都完全一致,但“在 3000 个种子上达成一致”并不等于“在所有种子上都是正确的”。
## 已标记事项
- `field::barrett_reduce` 简化为带有符号掩码规范化的 `i32` 算术。源码中是无分支的,相信 LLVM 不会将这些掩码转换为分支指令。目前尚未针对所有目标验证其汇编输出。
- `sample::sample_ntt` 由于拒绝采样而导致运行时可变,但它仅对公开种子 `rho` 进行操作。不存在依赖秘密的时序通道。
- `kpke::sample_matrix_a` 同样只处理公开数据。
- 自 0.5.0 起,内部暂存数据已改为栈分配(基于 `MAX_K = 4` 的上限)。分配时序不再是代数操作的侧信道;仅字节编码输出会通过 `Vec`。
## 特性
- `std` (默认)。标准库挂钩(`LengthError` 上的 `std::error::Error`,以及加密依赖的 std 版本)。
- `serde`。对三个参数集下的所有密钥、密文和共享秘密新型别提供 `Serialize` / `Deserialize` 支持。
## 示例
```
cargo run --release --example handshake
cargo run --release --example serde_save_restore --features serde
```
## 安全
漏洞报告请发送至 **hello@frkhd.com**,邮件主题为 `mlkem-rs security`。首选协调披露;请勿针对加密相关的发现提交公开的 GitHub Issue。完整策略详见 [`SECURITY.md`](SECURITY.md)。
## 审计准备
代码库根目录下有五份文档,供任何计划委托第三方审计的人士参考:
- [`SECURITY.md`](SECURITY.md) 公开威胁模型、范围,以及哪些属于/不属于审计范围
- [`SIDE_CHANNELS.md`](SIDE_CHANNELS.md) 每个依赖秘密的操作及其保护措施的清单
- [`AUDIT_SCOPE.md`](AUDIT_SCOPE.md) 一页纸的审计范围和方法论建议
- [`FORMAL_VERIFICATION.md`](FORMAL_VERIFICATION.md) 本库中所有经过 Kani 检查的证明
- [`SUPPLY_CHAIN.md`](SUPPLY_CHAIN.md) 所有运行时依赖、审计历史以及可复现的安装方案
0.10.0 版本中附带了 10 个 [`kani`](https://model-checking.github.io/kani/) 线束,涵盖了有限域算术和位打包宽度。它们为所有合法输入证明了 `barrett_reduce`、`fqadd`、`fqsub`、`compress_d` 和 `decompress_d` 的正确性。在 Apple M 系列芯片上,这十个测试总共在 60 秒内即可全部完成。运行命令:`cargo install --locked kani-verifier && cargo kani setup && cargo kani`。
## 链接
- [FIPS 203](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.203.pdf)
- [RustCrypto ml-kem](https://github.com/RustCrypto/KEMs)
- [pq-crystals/kyber 参考实现](https://github.com/pq-crystals/kyber)
- [NIST ACVP 测试向量](https://github.com/usnistgov/ACVP-Server)
- 测试:[`nist_kats`](tests/nist_kats.rs)、[`cross_check`](tests/cross_check.rs)、[`api`](tests/api.rs)、[`stress`](tests/stress.rs)、[`serde_roundtrip`](tests/serde_roundtrip.rs)
- 示例:[`handshake`](examples/handshake.rs)、[`serde_save_restore`](examples/serde_save_restore.rs)
- 更新日志:[CHANGELOG.md](CHANGELOG.md)
## 相关 Crates
与本库一同发布的其他小型 Rust 组件:
- [`mlkem-tls`](https://github.com/f4rkh4d/mlkem-tls) 根据 draft-ietf-tls-ecdhe-mlkem 实现的 X25519MLKEM768/1024 混合 KEM(使用本库作为后量子部分)
- [`bashward`](https://github.com/f4rkh4d/bashward) 为 Claude Code 中的 bash 副作用提供检查点和回滚功能
- [`skill-scan`](https://github.com/f4rkh4d/skill-scan) 针对 Claude 技能、MCP 和 AGENTS.md 的本地提示注入扫描器
- [`pluvgo`](https://github.com/f4rkh4d/pluvgo) 快速的 Neovim 插件管理器,单一 Rust 二进制文件,安装时无需 Neovim
## 许可证
根据您的选择,采用 MIT 或 Apache-2.0 双重许可。
标签:Crates.io, FIPS 203, Keccak, KEM, Kyber, ML-KEM, NIST, no_std, Rust, SHA3, 加密算法, 可视化界面, 后量子密码学, 密码学, 密钥封装, 嵌入式系统, 手动系统调用, 抗量子计算, 无unsafe代码, 格密码学, 纯Rust实现, 网络安全, 网络流量审计, 通知系统, 隐私保护