2 个版本
0.7.2 | 2024 年 6 月 27 日 |
---|---|
0.7.1 | 2024 年 6 月 8 日 |
#521 in 加密学
用于 3 个包(通过 sentc-crypto-std-keys)
310KB
7.5K SLoC
Kyber
Rust 实现的 Kyber 算法,该算法是 NIST 后量子标准化项目标准化的 KEM。
本库
- 与 no_std 兼容,无需分配器,适用于嵌入式设备。
- 参考文件不包含不安全代码,并使用纯 Rust 编写。
- 在 x86_64 平台上提供 avx2 优化版本,其中包含来自 C 参考仓库的汇编代码。
- 使用 wasm-bindgen 编译为 WASM,并在 NPM 上发布可用的二进制文件。
有关安全级别和工作模式的不同选项,请参阅 功能 部分。默认安全设置是 kyber768。
建议将 Kyber 与传统的密钥交换算法(如 X25519)一起在混合系统中使用。
请在使用前阅读 安全注意事项。
最低支持的 Rust 版本:1.56.0
安装
cargo add pqc_kyber
使用
use pqc_kyber::*;
对于 x86 平台的优化,启用 avx2
功能和以下 RUSTFLAGS
export RUSTFLAGS="-C target-feature=+aes,+avx2,+sse2,+sse4.1,+bmi2,+popcnt"
密钥封装
// Generate Keypair
let keys_bob = keypair(&mut rng)?;
// Alice encapsulates a shared secret using Bob's public key
let (ciphertext, shared_secret_alice) = encapsulate(&keys_bob.public, &mut rng)?;
// Bob decapsulates a shared secret using the ciphertext sent by Alice
let shared_secret_bob = decapsulate(&ciphertext, &keys_bob.secret)?;
assert_eq!(shared_secret_alice, shared_secret_bob);
单方认证密钥交换
let mut rng = rand::thread_rng();
// Initialize the key exchange structs
let mut alice = Uake::new();
let mut bob = Uake::new();
// Generate Bob's Keypair
let bob_keys = keypair(&mut rng)?;
// Alice initiates key exchange
let client_init = alice.client_init(&bob_keys.public, &mut rng)?;
// Bob authenticates and responds
let server_response = bob.server_receive(
client_init, &bob_keys.secret, &mut rng
)?;
// Alice decapsulates the shared secret
alice.client_confirm(server_response)?;
// Both key exchange structs now have the same shared secret
assert_eq!(alice.shared_secret, bob.shared_secret);
相互认证密钥交换
遵循相同的流程,除了 Bob 需要 Alice 的公钥
let mut alice = Ake::new();
let mut bob = Ake::new();
let alice_keys = keypair(&mut rng)?;
let bob_keys = keypair(&mut rng)?;
let client_init = alice.client_init(&bob_keys.public, &mut rng)?;
let server_response = bob.server_receive(
client_init, &alice_keys.public, &bob_keys.secret, &mut rng
)?;
alice.client_confirm(server_response, &alice_keys.secret)?;
assert_eq!(alice.shared_secret, bob.shared_secret);
错误
KyberError 枚举有两个变体
-
InvalidInput - 函数的一个或多个输入大小不正确。这种情况的可能原因是两方在尝试协商密钥交换时使用不同的安全级别。
-
Decapsulation - 无法对密文进行认证。共享密钥未被解封装。
-
RandomBytesGeneration - 尝试填充随机字节时出错(即外部(硬件)RNG 模块可能失败)。
功能
如果未指定安全级别,则默认使用 kyber768,这是作者推荐的。它与 AES-192 大约相当。除了两个安全级别外,所有其他功能都可以根据需要组合。例如
[dependencies]
pqc_kyber = {version = "0.7.1", features = ["kyber512", "90s", "avx2"]}
功能 | 描述 |
---|---|
std | 启用标准库 |
kyber512 | 启用 kyber512 模式,安全级别与 AES-128 大约相当。 |
kyber1024 | 启用 kyber1024 模式,安全级别与 AES-256 大约相当。如果指定了多个安全级别,则会引发编译时错误。 |
90s | 使用AES256计数模式以及SHA2作为SHAKE的替代方案。这可以在某些情况下提供硬件加速。 |
90s-fixslice | 使用RustCrypto的AES256 fixslice实现,这提供了更高的侧信道攻击抵抗力,尤其是在嵌入式平台上。 |
avx2 | 在x86_64平台上启用优化版本。此标志在其他架构上会导致编译错误。 |
wasm | 用于编译WASM目标。 |
nasm | 使用Netwide Assembler的avx2代码而不是GAS以提高可移植性。需要nasm编译器:[https://www.nasm.us/](https://www.nasm.us/) |
zeroize | 这将使用zeroize crate在丢弃时将密钥交换结构清零 |
benchmarking | 启用criterion基准测试套件。 |
测试
使用run_all_tests脚本将通过运行安全级别、变体和crate功能的矩阵遍历所有可能的代码路径。
已知答案测试需要确定的rng种子,在RUSTFLAGS
中启用kyber_kat
以使用它们。在cargo test
之外使用此功能将导致编译时错误。测试向量文件相当大,您需要从C参考代码自行构建它们。有一个辅助脚本可以这样做这里。
# This example runs the basic tests for kyber768
cargo test
# This runs the KATs for kyber512 in 90's mode
RUSTFLAGS='--cfg kyber_kat' cargo test --features "kyber512 90s"
有关更全面的信息,请参阅测试readme。
Benchmarking
使用criterion进行基准测试。如果您已安装GNUPlot,它将在./target/criterion/
中生成统计图。
您需要启用benchmarking
功能。
有关正确使用信息,请参阅基准测试readme。
Fuzzing
模糊测试套件使用honggfuzz,安装和说明在模糊测试页面上。
WebAssembly
此库已编译成WebAssembly并作为npm包发布。使用说明在这里
https://npmjs.net.cn/package/pqc-kyber
它也位于wasm readme中
安装
npm i pqc-kyber
要自行编译wasm文件,您需要启用wasm
功能。
例如,使用wasm-pack
wasm-pack build -- --features wasm
它将导出wasm、javascript和typescript文件到./pkg/。
将不同变体编译到单独的文件夹
wasm-pack build --out-dir pkg_kyber512/ -- --features "wasm kyber512"
在www文件夹中还有一个基本的html演示。
从www文件夹运行
npm run start
安全考虑
尽管在从C参考代码库迁移时已尽了很大努力,但此库尚未经过任何第三方安全审计,也不能保证LWE密码学中的潜在漏洞或由此实现引起的潜在侧信道攻击的可能性。
Kyber相对较新,建议将其与X25519等传统算法结合使用,而不是单独使用。
关于进一步阅读,IETF在TLS 1.3中有一个混合密钥交换的草案
https://www.ietf.org/archive/id/draft-ietf-tls-hybrid-design-04.html
您还可以在此处查看此类系统是如何在OpenSSH中以C语言实现的:https://github.com/openssh/openssh-portable/blob/a2188579032cf080213a78255373263466cb90cc/kexsntrup761x25519.c
请自行承担风险。
关于
Kyber是一种IND-CCA2安全密钥封装机制(KEM),其安全性基于在模块格子上解决学习错误(LWE)问题的难度。它是NIST后量子密码学项目的最终标准化算法结果。NIST后量子密码学项目。
官方网站:https://pq-crystals.org/kyber/
Kyber算法的作者
- Roberto Avanzi,ARM Limited(德国)
- Joppe Bos,NXP Semiconductors(比利时)
- Léo Ducas,CWI Amsterdam(荷兰)
- Eike Kiltz,Ruhr University Bochum(德国)
- Tancrède Lepoint,SRI International(美国)
- Vadim Lyubashevsky,IBM Research Zurich(瑞士)
- John M. Schanck,University of Waterloo(加拿大)
- Peter Schwabe,Radboud University(荷兰)
- Gregor Seiler,IBM Research Zurich(瑞士)
- Damien Stehle,ENS Lyon(法国)
贡献
欢迎贡献。对于pull请求,请创建一个功能分支并将其提交到开发分支。更多信息可在贡献页面上找到。
替代方案
PQClean项目为他们的Kyber C代码库提供了Rust绑定。
依赖项
~0–11MB
~95K SLoC