paulmillr/noble-post-quantum
GitHub: paulmillr/noble-post-quantum
这是一个可审计、极简的 JavaScript 后量子密码学库,实现了 NIST FIPS 203/204/205 标准算法及混合模式,帮助开发者提前布局量子时代的安全基础设施。
Stars: 284 | Forks: 32
# noble-post-quantum
可审计且极简的后量子公钥密码学 JS 实现。
- 🔒 可审计
- 🔻 可 Tree-shake:未使用的代码将从构建中排除
- 🔍 可靠:测试确保正确性
- 🦾 ML-KEM & CRYSTALS-Kyber:基于 FIPS-203 的格基 KEM
- 🔋 ML-DSA & CRYSTALS-Dilithium:基于 FIPS-204 的格基签名
- 🐈 SLH-DSA & SPHINCS+:基于 FIPS-205 的哈希 Winternitz 签名
- 🍡 混合算法,结合了经典算法与后量子算法:Concrete, XWing, KitchenSink
- 🪶 所有功能共计 16KB (gzipped),包含内置的哈希和曲线
请浏览 [GitHub Discussions](https://github.com/paulmillr/noble-post-quantum/discussions) 以获取问题和支持。
### 此库属于 _noble_ 密码学项目
- 零依赖或最小依赖
- 高度可读的 TypeScript / JS 代码
- PGP 签名的发布版本和透明的 NPM 构建
- 所有库:
[ciphers](https://github.com/paulmillr/noble-ciphers),
[curves](https://github.com/paulmillr/noble-curves),
[hashes](https://github.com/paulmillr/noble-hashes),
[post-quantum](https://github.com/paulmillr/noble-post-quantum),
5kb [secp256k1](https://github.com/paulmillr/noble-secp256k1) /
[ed25519](https://github.com/paulmillr/noble-ed25519)
- [查看主页](https://paulmillr.com/noble/)
以获取阅读资源、文档以及使用 noble 构建的应用
## 用法
我们支持所有主要平台和运行时。
对于 React Native,你可能需要一个
[getRandomValues 的 polyfill](https://github.com/LinusU/react-native-get-random-values)。
同时也提供一个独立文件
[noble-post-quantum.js](https://github.com/paulmillr/noble-post-quantum/releases)。
```
// import * from '@noble/post-quantum'; // Error: use sub-imports instead
import { ml_kem512, ml_kem768, ml_kem1024 } from '@noble/post-quantum/ml-kem.js';
import { ml_dsa44, ml_dsa65, ml_dsa87 } from '@noble/post-quantum/ml-dsa.js';
import {
slh_dsa_sha2_128f,
slh_dsa_sha2_128s,
slh_dsa_sha2_192f,
slh_dsa_sha2_192s,
slh_dsa_sha2_256f,
slh_dsa_sha2_256s,
slh_dsa_shake_128f,
slh_dsa_shake_128s,
slh_dsa_shake_192f,
slh_dsa_shake_192s,
slh_dsa_shake_256f,
slh_dsa_shake_256s,
} from '@noble/post-quantum/slh-dsa.js';
import {
ml_kem768_x25519, ml_kem768_p256, ml_kem1024_p384,
KitchenSink_ml_kem768_x25519, XWing,
QSF_ml_kem768_p256, QSF_ml_kem1024_p384,
} from '@noble/post-quantum/hybrid.js';
```
- [ML-KEM / Kyber](#ml-kem--kyber-shared-secrets)
- [ML-DSA / Dilithium](#ml-dsa--dilithium-signatures)
- [SLH-DSA / SPHINCS+](#slh-dsa--sphincs-signatures)
- [混合模式: XWing, KitchenSink 及其他](#hybrid-xwing-kitchensink-and-others)
- [我应该使用什么?](#what-should-i-use)
- [安全性](#security)
- [速度](#speed)
- [贡献与测试](#contributing--testing)
- [许可证](#license)
### ML-KEM / Kyber 共享密钥
```
import { ml_kem512, ml_kem768, ml_kem1024 } from '@noble/post-quantum/ml-kem.js';
import { randomBytes } from '@noble/post-quantum/utils.js';
const seed = randomBytes(64); // seed is optional
const aliceKeys = ml_kem768.keygen(seed);
const { cipherText, sharedSecret: bobShared } = ml_kem768.encapsulate(aliceKeys.publicKey);
const aliceShared = ml_kem768.decapsulate(cipherText, aliceKeys.secretKey);
// Warning: Can be MITM-ed
const malloryKeys = ml_kem768.keygen();
const malloryShared = ml_kem768.decapsulate(cipherText, malloryKeys.secretKey); // No error!
notDeepStrictEqual(aliceShared, malloryShared); // Different key!
```
基于格的密钥封装机制,定义于 [FIPS-203](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.203.pdf) ([网站](https://www.pq-crystals.org/kyber/resources.shtml),[仓库](https://github.com/pq-crystals/kyber))。
可按如下方式使用:
1. *Alice* 生成密钥和公钥,然后将 publicKey 发送给 *Bob*
2. *Bob* 为 Alice 的 publicKey 生成共享密钥。
bobShared 永远不会离开 *Bob* 的系统,且对其他方不可见
3. *Alice* 从 Bob 处获取并解密 cipherText
现在,Alice 和 Bob 拥有了相同的 sharedSecret 密钥
而无需以明文形式交换:aliceShared == bobShared。
关于安全性存在一些顾虑:请参阅
[djb 博客](https://blog.cr.yp.to/20231003-countcorrectly.html) 和
[邮件列表](https://groups.google.com/a/list.nist.gov/g/pqc-forum/c/W2VOzy0wz_E)。
旧的、不兼容的版本未提供。如果需要,请提出 issue。
### ML-DSA / Dilithium 签名
```
import { ml_dsa44, ml_dsa65, ml_dsa87 } from '@noble/post-quantum/ml-dsa.js';
import { randomBytes } from '@noble/post-quantum/utils.js';
const seed = randomBytes(32); // seed is optional
const keys = ml_dsa65.keygen(seed);
const msg = new TextEncoder().encode('hello noble');
const sig = ml_dsa65.sign(msg, keys.secretKey);
const isValid = ml_dsa65.verify(sig, msg, keys.publicKey);
```
基于格的数字签名算法,定义于 [FIPS-204](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.204.pdf) ([网站](https://www.pq-crystals.org/dilithium/index.shtml),
[仓库](https://github.com/pq-crystals/dilithium))。
其内部结构与 ML-KEM 相似,但密钥和参数不同。
### SLH-DSA / SPHINCS+ 签名
```
import {
slh_dsa_sha2_128f as sph,
slh_dsa_sha2_128s,
slh_dsa_sha2_192f,
slh_dsa_sha2_192s,
slh_dsa_sha2_256f,
slh_dsa_sha2_256s,
slh_dsa_shake_128f,
slh_dsa_shake_128s,
slh_dsa_shake_192f,
slh_dsa_shake_192s,
slh_dsa_shake_256f,
slh_dsa_shake_256s,
} from '@noble/post-quantum/slh-dsa.js';
const keys2 = sph.keygen();
const msg2 = new TextEncoder().encode('hello noble');
const sig2 = sph.sign(msg2, keys2.secretKey);
const isValid2 = sph.verify(sig2, msg2, keys2.publicKey);
```
基于哈希的数字签名算法,定义于 [FIPS-205](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.205.pdf) ([网站](https://sphincs.org),[仓库](https://github.com/sphincs/sphincsplus))。我们实现了包含 FIPS 调整的规范 v3.1。
- sha2 vs shake (sha3):表示所使用的内部哈希函数
- 128 / 192 / 256:表示以比特为单位的安全级别
- s / f:表示“小”与“快”的权衡
SLH-DSA 较慢:请参阅 [基准测试](#speed) 以了解密钥大小和速度。
### 混合模式: XWing, KitchenSink 及其他
```
import {
ml_kem768_x25519, ml_kem768_p256, ml_kem1024_p384,
KitchenSink_ml_kem768_x25519, XWing,
QSF_ml_kem768_p256, QSF_ml_kem1024_p384,
} from '@noble/post-quantum/hybrid.js';
```
混合子模块将后量子算法与椭圆曲线密码学相结合:
- `ml_kem768_x25519`: ML-KEM-768 + X25519 (CG Framework,与 XWing 相同)
- `ml_kem768_p256`: ML-KEM-768 + P-256 (CG Framework)
- `ml_kem1024_p384`: ML-KEM-1024 + P-384 (CG Framework)
- `KitchenSink_ml_kem768_x25519`: 使用 HKDF-SHA256 组合器的 ML-KEM-768 + X25519
- `QSF_ml_kem768_p256`: ML-KEM-768 + P-256 (QSF 结构)
- `QSF_ml_kem1024_p384`: ML-KEM-1024 + P-384 (QSF 结构)
符合以下规范草案:
- [irtf-cfrg-hybrid-kems-07](https://datatracker.ietf.org/doc/draft-irtf-cfrg-hybrid-kems/)
- [irtf-cfrg-concrete-hybrid-kems-02](https://datatracker.ietf.org/doc/draft-irtf-cfrg-concrete-hybrid-kems/)
- [connolly-cfrg-xwing-kem-09](https://datatracker.ietf.org/doc/draft-connolly-cfrg-xwing-kem/)
- [tls-westerbaan-xyber768d00-03](https://datatracker.ietf.org/doc/draft-tls-westerbaan-xyber768d00/)
### 我应该使用什么?
| | 速度 | 密钥大小 | 签名大小 | 创造于 | 普及于 | 后量子? |
| ------- | ------ | ----------- | ----------- | ---------- | -------------- | ------------- |
| RSA | 正常 | 256B - 2KB | 256B - 2KB | 1970s | 1990s | No |
| ECC | 正常 | 32 - 256B | 48 - 128B | 1980s | 2010s | No |
| ML-KEM | 快 | 1.6 - 31KB | 1KB | 1990s | 2020s | Yes |
| ML-DSA | 正常 | 1.3 - 2.5KB | 2.5 - 4.5KB | 1990s | 2020s | Yes |
| SLH-DSA | 慢 | 32 - 128B | 17 - 50KB | 1970s | 2020s | Yes |
| FN-DSA | 慢 | 0.9 - 1.8KB | 0.6 - 1.2KB | 1990s | 2020s | Yes |
我们建议使用 ECC + ML-KEM 进行密钥协商,使用 ECC + SLH-DSA 进行签名。
ML-KEM 和 ML-DSA 是基于格的。SLH-DSA 是基于哈希的,这意味着它建立在更古老、更保守的原语之上。NIST 安全级别指南:
- 类别 3 (~AES-192): ML-KEM-768, ML-DSA-65, SLH-DSA-192
- 类别 5 (~AES-256): ML-KEM-1024, ML-DSA-87, SLH-DSA-256
NIST 建议使用 cat-3+,而澳大利亚的 [ASD 仅允许在 2030 年后使用 cat-5](https://www.cyber.gov.au/resources-business-and-government/essential-cyber-security/ism/cyber-security-guidelines/guidelines-cryptography)。
查看 [NIST SP 800-131Ar3](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar3.ipd.pdf)
对于“加密算法和密钥长度的过渡使用”也很有用。
对于 [哈希](https://github.com/paulmillr/noble-hashes),使用 SHA512 或 SHA3-512 (不要用 SHA256);对于 [密码](https://github.com/paulmillr/noble-ciphers),确保使用 AES-256 或 ChaCha。
## 安全性
该库尚未经过独立审计。
如果你发现任何异常:请调查并报告。
### 恒定时间性
目前没有针对侧信道攻击的保护。
我们正在积极研究如何在 JS 中为后量子算法提供此属性。
请记住,即使是硬件版本的 ML-KEM 也[存在漏洞](https://eprint.iacr.org/2023/1084)。
### 供应链安全
- **Commits** 使用 PGP 密钥签名以防止伪造。请务必验证提交签名
- **Releases** 通过无令牌的 GitHub CI 和可信发布透明进行。请务必验证 [来源日志](https://docs.npmjs.com/generating-provenance-statements) 以确保真实性。
- 实行**罕见发布**,以最大限度地减少最终用户重新审计的需要。
- **Dependencies** 被最小化并严格锁定,以降低供应链风险。
- 我们使用尽可能少的依赖。
- 版本范围被锁定,并使用 npm-diff 检查更改。
- **Dev dependencies** 从最终用户安装中排除;它们仅用于开发和构建步骤。
对于此包,有 2 个依赖项;以及一些开发依赖项:
- [noble-hashes](https://github.com/paulmillr/noble-hashes) 提供加密哈希功能,在每个算法内部使用
- [noble-curves](https://github.com/paulmillr/noble-curves) 为混合算法提供椭圆曲线密码学
- jsbt 用于基准测试 / 测试 / 构建工具,由同一作者开发
- prettier, fast-check 和 typescript 用于代码质量 / 测试生成 / ts 编译
### 随机性
我们依赖内置的
[`crypto.getRandomValues`](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues),
这被认为是一个加密安全的 PRNG。
浏览器过去曾存在弱点——而且可能会再次出现——但在用户空间实现 CSPRNG 甚至更糟,因为没有可靠的用户空间高质量熵源。
## 速度
Noble 是后量子算法最快的 JS 实现。WASM 库可能会更快。
Apple M4 上的基准测试(**越高越好**):
| OPs/sec | Keygen | Signing | Verification | Shared secret |
| ----------------- | ------ | ------- | ------------ | ------------- |
| ECC x/ed25519 | 14216 | 6849 | 1400 | 1981 |
| ML-KEM-768 | 3778 | | | 3750 |
| ML-DSA65 | 580 | 272 | 546 | |
| SLH-DSA-SHA2-192f | 245 | 8 | 169 | |
```
# ML-KEM768
keygen x 3,778 ops/sec @ 264μs/op
encapsulate x 3,220 ops/sec @ 310μs/op
decapsulate x 4,029 ops/sec @ 248μs/op
# ML-DSA65
keygen x 580 ops/sec @ 1ms/op
sign x 272 ops/sec @ 3ms/op
verify x 546 ops/sec @ 1ms/op
# SLH-DSA SHA2 192f
keygen x 245 ops/sec @ 4ms/op
sign x 8 ops/sec @ 114ms/op
verify x 169 ops/sec @ 5ms/op
```
SLH-DSA:
| | sig size | keygen | sign | verify |
| --------- | -------- | ------ | ------ | ------ |
| sha2_128f | 18088 | 4ms | 90ms | 6ms |
| sha2_192f | 35664 | 6ms | 160ms | 9ms |
| sha2_256f | 49856 | 15ms | 340ms | 9ms |
| sha2_128s | 7856 | 260ms | 2000ms | 2ms |
| sha2_192s | 16224 | 380ms | 3800ms | 3ms |
| sha2_256s | 29792 | 250ms | 3400ms | 4ms |
| shake_192f | 35664 | 21ms | 553ms | 29ms |
| shake_192s | 16224 | 260ms | 2635ms | 2ms |
## 贡献与测试
- `npm install && npm run build && npm test` 将构建代码并运行测试。
- `npm run lint` / `npm run format` 将运行 linter / 修复 linter 问题。
- `npm run bench` 将运行基准测试
- `npm run build:release` 将构建单个文件
查看 [github.com/paulmillr/guidelines](https://github.com/paulmillr/guidelines)
了解通用编码实践和规则。
参阅 [paulmillr.com/noble](https://paulmillr.com/noble/)
获取与该库相关的有用资源、文章、文档和演示。
## 许可证
MIT 许可证 (MIT)
版权所有 (c) 2024 Paul Miller [(https://paulmillr.com)](https://paulmillr.com)
请参阅 LICENSE 文件。
标签:CMS安全, CVE, Dilithium, FIPS-203, FIPS-204, FIPS-205, JavaScript, KEM, Kyber, MITM代理, ML-DSA, ML-KEM, NIST标准化, NPM包, OSV-Scalibr, SLH-DSA, SPHINCS+, Tree-shaking, TypeScript, Web安全, 前端安全, 加密算法, 后量子密码学, 哈希基签名, 安全插件, 审计友好, 密码学库, 密钥封装机制, 抗量子计算, 数字签名, 数据可视化, 格密码学, 混合加密, 自动化攻击, 蓝队分析, 蓝队防御, 零依赖