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参数集都启用。如果需要,它们可以通过功能标志mlkem512mlkem768mlkem1024单独使用。

该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"  # 用于随机数生成

1 回复

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]);
}

安全注意事项

  1. 始终使用最新版本的库
  2. 密钥和共享密钥应安全存储
  3. 对于生产环境,建议使用ML-KEM-768或ML-KEM-1024安全级别
  4. 定期轮换密钥对

性能考虑

不同安全级别的性能特征:

  • 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(())
}

这个完整示例展示了:

  1. 选择NIST推荐的ML-KEM-768安全级别
  2. 生成密钥对并输出密钥长度信息
  3. 模拟发送方和接收方的完整密钥交换流程
  4. 验证共享密钥的一致性
  5. 展示了如何在实际应用中使用生成的共享密钥

libcrux-ml-kem为Rust开发者提供了符合后量子安全标准的密钥封装实现,是传统非对称加密算法向抗量子计算迁移的重要工具。

回到顶部