Rust密码学库libcrux-ml-kem的使用:后量子安全的ML-KEM密钥封装机制实现
Rust密码学库libcrux-ml-kem的使用:后量子安全的ML-KEM密钥封装机制实现
ML-KEM
该crate实现了所有三种ML-KEM(FIPS 203)变体:512、768和1024。对于每种算法,它包含一个可移植的Rust实现,以及针对Intel AVX2和AArch64 Neon平台的SIMD实现。
![verified]
验证
可移植代码和AVX2代码用于字段算术、NTT多项式算术、序列化,以及高级算法的通用代码,使用hax和F*进行了形式化验证。
使用
默认情况下,所有ML-KEM参数集都启用。如果需要,它们可以通过功能标志mlkem512
、mlkem768
和mlkem1024
单独使用。
该crate中的函数使用CPU功能检测来在每个平台上选择最有效的版本。要使用带有您自己的功能检测的特定版本,请使用例如以下之一:
mlkem768::avx2::generate_key_pair
mlkem768::neon::generate_key_pair
mlkem768::portable::generate_key_pair
对于封装和解封装也类似。
以下是示例代码:
use rand::{rngs::OsRng, RngCore};
// 确保使用良好的随机性
// 不建议直接使用OsRng!
// 强烈建议使用像NIST的DRBG这样的RNG来解决系统熵不足的问题
fn random_array<const L: usize>() -> [u8; L] {
let mut rng = OsRng;
let mut seed = [0; L];
rng.try_fill_bytes(&mut seed).unwrap();
seed
}
use libcrux_ml_kem::*;
// 此示例使用ML-KEM 768。其他变体可以相同的方式使用
// 生成密钥对
let randomness = random_array();
let key_pair = mlkem768::generate_key_pair(randomness);
// 封装共享密钥到公钥
let randomness = random_array();
let (ciphertext, shared_secret) = mlkem768::encapsulate(key_pair.public_key(), randomness);
// 用私钥解封装共享密钥
let shared_secret_decapsulated = mlkem768::decapsulate(key_pair.private_key(), &ciphertext);
Kyber Round 3
kyber
标志还提供了对Kyber的实现访问,该实现作为NIST PQ竞赛第三轮提交,但尚未经过验证。
完整示例代码
use rand::{rngs::OsRng, RngCore};
use libcrux_ml_kem::mlkem768;
// 安全的随机数生成函数
fn secure_random_bytes<const L: usize>() -> [u8; L] {
let mut rng = OsRng;
let mut bytes = [0u8; L];
rng.try_fill_bytes(&mut bytes).expect("Failed to generate random bytes");
bytes
}
fn main() {
// 1. 生成密钥对
let key_pair_randomness = secure_random_bytes();
let key_pair = mlkem768::generate_key_pair(key_pair_randomness);
println!("Public key length: {} bytes", key_pair.public_key.len());
println!("Private key length: {} bytes", key_pair.private_key.len());
// 2. 封装共享密钥
let encapsulation_randomness = secure_random_bytes();
let (ciphertext, shared_secret_encapsulated) =
mlkem768::encapsulate(key_pair.public_key, encapsulation_randomness);
println!("Ciphertext length: {} bytes", ciphertext.len());
println!("Shared secret length: {} bytes", shared_secret_encapsulated.len());
// 3. 解封装共享密钥
let shared_secret_decapsulated =
mlkem768::decapsulate(key_pair.private_key, &ciphertext);
// 验证解封装结果与封装结果一致
assert_eq!(shared_secret_encapsulated, shared_secret_decapsulated);
println!("Key encapsulation and decapsulation successful!");
// 可选:使用AVX2加速版本
#[cfg(target_feature = "avx2")]
{
let key_pair_avx2 = mlkem768::avx2::generate_key_pair(key_pair_randomness);
let (ciphertext_avx2, shared_secret_avx2) =
mlkem768::avx2::encapsulate(key_pair_avx2.public_key, encapsulation_randomness);
let shared_secret_decapsulated_avx2 =
mlkem768::avx2::decapsulate(key_pair_avx2.private_key, &ciphertext_avx2);
assert_eq!(shared_secret_avx2, shared_secret_decapsulated_avx2);
println!("AVX2 accelerated version works correctly!");
}
}
要使用此库,请将以下内容添加到您的Cargo.toml中:
[dependencies]
libcrux-ml-kem = "0.0.3"
rand = "0.8" # 用于随机数生成
Rust密码学库libcrux-ml-kem使用指南:后量子安全的ML-KEM密钥封装机制
概述
libcrux-ml-kem是一个Rust实现的ML-KEM(Module-Lattice-based Key Encapsulation Mechanism)密钥封装机制库,提供了后量子安全的加密方案。该库实现了NIST后量子密码学标准化项目中选定的Kyber算法变种。
特性
- 完全用Rust实现的后量子安全密钥封装
- 支持ML-KEM-512、ML-KEM-768和ML-KEM-1024三种安全级别
- 零开销抽象和恒定时间操作
- 经过严格的形式验证
安装
在Cargo.toml中添加依赖:
[dependencies]
libcrux = { version = "0.1", features = ["ml-kem"] }
基本用法
密钥生成
use libcrux::ml_kem;
fn generate_keypair() -> (Vec<u8>, Vec<u8>) {
// 选择安全级别(512, 768或1024)
let kem = ml_kem::MlKem::new(ml_kem::Algorithm::MlKem512).unwrap();
// 生成密钥对
let (public_key, secret_key) = kem.key_gen().unwrap();
(public_key, secret_key)
}
密钥封装
use libcrux::ml_kem;
fn encapsulate(public_key: &[u8]) -> (Vec<u8>, Vec<u8>) {
let kem = ml_kem::MlKem::new(ml_kem::Algorithm::MlKem512).unwrap();
// 封装密钥,生成共享密钥和密文
let (shared_secret, ciphertext) = kem.encapsulate(public_key).unwrap();
(shared_secret, ciphertext)
}
密钥解封装
use libcrux::ml_kem;
fn decapsulate(secret_key: &[u8], ciphertext: &[u8]) -> Vec<u8> {
let kem = ml_kem::MlKem::new(ml_kem::Algorithm::MlKem512).unwrap();
// 解封装获取共享密钥
let shared_secret = kem.decapsulate(secret_key, ciphertext).unwrap();
shared_secret
}
完整示例
use libcrux::ml_kem;
fn main() {
// 1. 初始化ML-KEM实例(选择512位安全级别)
let kem = ml_kem::MlKem::new(ml_kem::Algorithm::MlKem512).unwrap();
// 2. 生成密钥对
let (public_key, secret_key) = kem.key_gen().unwrap();
// 3. 发送方:使用公钥封装密钥
let (sender_shared_secret, ciphertext) = kem.encapsulate(&public_key).unwrap();
// 4. 接收方:使用私钥解封装
let receiver_shared_secret = kem.decapsulate(&secret_key, &ciphertext).unwrap();
// 5. 验证双方共享密钥是否相同
assert_eq!(sender_shared_secret, receiver_shared_secret);
println!("密钥交换成功! 共享密钥: {:?}", &sender_shared_secret[..16]);
}
安全注意事项
- 始终使用最新版本的库
- 密钥和共享密钥应安全存储
- 对于生产环境,建议使用ML-KEM-768或ML-KEM-1024安全级别
- 定期轮换密钥对
性能考虑
不同安全级别的性能特征:
- ML-KEM-512: 最高性能,最低安全性
- ML-KEM-768: 平衡性能与安全性(NIST推荐)
- ML-KEM-1024: 最高安全性,较低性能
错误处理
所有操作都返回Result
类型,应妥善处理错误:
match kem.key_gen() {
Ok((pk, sk)) => { /* 成功处理 */ },
Err(e) => { /* 错误处理 */ }
}
完整示例demo
以下是一个更完整的示例,展示如何在真实场景中使用libcrux-ml-kem进行安全的密钥交换:
use libcrux::ml_kem;
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
// 选择安全级别(NIST推荐的768位)
let kem = ml_kem::MlKem::new(ml_kem::Algorithm::MlKem768)?;
// 生成密钥对
let (public_key, secret_key) = kem.key_gen()?;
println!("公钥长度: {} 字节", public_key.len());
println!("私钥长度: {} 字节", secret_key.len());
// 模拟发送方:使用公钥封装密钥
let (sender_shared_secret, ciphertext) = kem.encapsulate(&public_key)?;
println!("密文长度: {} 字节", ciphertext.len());
// 模拟接收方:使用私钥解封装
let receiver_shared_secret = kem.decapsulate(&secret_key, &ciphertext)?;
// 验证双方共享密钥是否相同
assert_eq!(sender_shared_secret, receiver_shared_secret);
// 打印共享密钥的前16字节(仅用于演示)
println!("成功建立共享密钥(前16字节): {:02X?}", &sender_shared_secret[..16]);
// 实际应用中,这个共享密钥可以用于对称加密
// 例如: let cipher = Aes256Gcm::new_from_slice(&shared_secret)?;
Ok(())
}
这个完整示例展示了:
- 选择NIST推荐的ML-KEM-768安全级别
- 生成密钥对并输出密钥长度信息
- 模拟发送方和接收方的完整密钥交换流程
- 验证共享密钥的一致性
- 展示了如何在实际应用中使用生成的共享密钥
libcrux-ml-kem为Rust开发者提供了符合后量子安全标准的密钥封装实现,是传统非对称加密算法向抗量子计算迁移的重要工具。