#后量子密码学 #后量子 # #pqc #依赖

ntrust-native

Saber PQC 方案的纯 Rust 实现

2 个稳定版本

1.0.1 2022 年 5 月 4 日

#1868 in 密码学

MIT 许可证

275KB
3.5K SLoC

ntrust-native

NTRU 后量子方案的安全纯 Rust 实现。

  • NTRU 是一种基于格的密钥封装机制 (KEM)
  • 实现基于 NIST 第三轮的 NTRU 参考实现
  • 实现不利用任何并发技术(SIMD/线程/…,除了可能在你的 CPU 上的自动向量化)
  • 它依赖于 tiny-keccak 作为 SHA-3 实现,以及 aes 作为 AES 区块加密(用作 RNG 实现)
  • 它通过了 C 参考实现的 100 个测试案例
  • 它实现了三种变体的 NTRU-HPS(Hoffstein-Pipher-Silverman)方案
  • 它实现了 NTRU-HRSS(Hülsing-Rijneveld-Schanck-Schwabe)方案的一个变体
  • 该实现在一个现代计算机上运行需要 20 毫秒(ntruhps2048509)到 45 毫秒(ntruhps4096821
  • 该实现在软件指令级别上是常量的
  • 随机数生成器基于 AES256 的计数器模式
  • NTRUst 是一个 WebAssembly 实现。因此,这个实现被称为 ntrust-native

谁应该使用它?

任何希望使用 NTRU 方案在双方之间协商密钥的人。

如何使用它?

将其添加到您的 Cargo.toml

[dependencies]
ntrust-native = "1.0"

要使用特定的 NTRU 变体,您需要使用相应的功能标志导入它

[dependencies]
ntrust-native = { version = "1.0", features = ["ntruhrss701"] }

simple 示例说明了 API

use ntrust_native::AesState;
use ntrust_native::{crypto_kem_dec, crypto_kem_enc, crypto_kem_keypair};
use ntrust_native::{CRYPTO_BYTES, CRYPTO_CIPHERTEXTBYTES, CRYPTO_PUBLICKEYBYTES, CRYPTO_SECRETKEYBYTES};

use std::error;

fn main() -> Result<(), Box<dyn error::Error>> {
  let mut rng = AesState::new();
  let mut pk = [0u8; CRYPTO_PUBLICKEYBYTES];
  let mut sk = [0u8; CRYPTO_SECRETKEYBYTES];
  let mut ct = [0u8; CRYPTO_CIPHERTEXTBYTES];
  let mut ss_alice = [0u8; CRYPTO_BYTES];
  let mut ss_bob = [0u8; CRYPTO_BYTES];

  crypto_kem_keypair(&mut pk, &mut sk, &mut rng)?;
  crypto_kem_enc(&mut ct, &mut ss_bob, &pk, &mut rng)?;
  crypto_kem_dec(&mut ss_alice, &ct, &sk)?;

  assert_eq!(ss_bob, ss_alice);

  Ok(())
}

如何运行它?

此库包含两个示例

$ cargo run --example simple

输出使用 Alice/Bob 标注消息,以说明哪些数据由哪个当事人处理。 katkem 示例实现了 NIST PQC 框架的一部分经典请求/响应文件结构。

$ cargo run --example katkem PQCkemKAT_935.req PQCkemKAT_935.rsp
$ cargo run --example katkem PQCkemKAT_935.rsp

不同的变体(ntruhps2048509ntruhps2048677ntruhps4096821ntruhrss701)可以通过功能标志启用

$ cargo run --example katkem --features ntruhrss701 -- PQCkemKAT_1450.req PQCkemKAT_1450.rsp

ntruhps2048509 是默认变体。您不能同时启用两个变体。

它有多快?

所有数据都使用时钟周期作为单位。Rust 实现具有以下时钟周期计数特征(越小越好)

完整的 KEM密钥对加密解密
ntruhps204850919,980,85514,105,680472,9091,122,414
ntruhps204867727,478,93924,077,519895,9302,333,079
ntruhps409682142,083,12536,882,7831,487,4013,367,818
ntruhrss70132,433,99328,506,984828,1622,919,074

C语言的参考实现具有以下时钟周期计数特性(越小越好)

完整的 KEM密钥对加密解密
ntruhps204850915,912,90012,139,200811,6511,812,650
ntruhps204867728,911,50022,233,6001,520,6403,668,860
ntruhps409682141,914,80032,138,3002,089,3505,908,570
ntruhrss70128,966,60023,134,7001,368,2703,462,640

测试是在联想Thinkpad x260(Intel Core i5-6200U CPU @ 2.30GHz)上进行的。在Rust的情况下,已在benches/中使用了如给定的criterion 0.3.5,在C的情况下,使用了带有PFM支持且禁用CPU频率调整的Google的benchmark。我们的总结是,这两种实现具有可比的运行时间。Rust稍微慢一些(但为了类型安全使用了大量的复制操作,你可以用unsafe {}代码替换)。你可以使用bench子命令运行基准测试套件,并可选择一些变体功能标志

$ cargo bench --features ntruhrss701

源代码在哪里?

github

内容使用什么许可证?

MIT许可证

变更日志

  • 2022-05-04 版本 1.0.1:修复文档
  • 2022-05-03 版本 1.0.0:公开发布

我在哪里可以要求修复一个错误?

github

依赖关系

~630KB
~14K SLoC