#ntru #理想格基 #rust

ntrulp

纯实现高安全度素度大伽罗瓦群惰模理想格基密码学

6个版本

0.1.9 2023年10月17日
0.1.8 2023年10月17日
0.1.7 2023年9月26日

#303 in 密码学

39 每月下载量

自定义许可

96KB
2K SLoC

NTRUP Rust

此存储库展示了在Rust编程语言上实现高安全度素度大伽罗瓦群惰模理想格基密码学的实现。 “素度”等是针对潜在攻击的防御手段;见官方网站

此实现使用:形式为(Z/q)[x]/(xp −x−1)的域,其中p是素数,在本文中引入的“NTRU Prime”中使用,并且具有我们推荐的所有防御措施。

NTRU Prime的符号和参数

在NTRU Prime的上下文中,一些参数和符号在定义加密系统中起着至关重要的作用。

参数集

NTRU Prime的参数集表示为(p, q, w)的三元组,这是系统中主要代数结构的基础。让我们分析一下这些参数

  • P:此参数对应于不可约多项式P = xp − x − 1的次数,必须是素数。参数集中常用的p值包括653、761、857、953、1013、1277。

  • Q:表示域R/q = (Z/q)[x]/P的特征,q也是素数。q的典型值取决于[5]中考虑的具体度,包括4621、4591、5167、6343、7177、7879。

  • W:权重参数W是一个正整数,它控制特定多项式中的非零系数的数量。

  • P = 653,Q = 4621,W = 288

  • P = 761,Q = 4591,W = 286

  • P = 857,Q = 5167,W = 322

  • P = 953,Q = 6343,W = 396

  • P = 1013,Q = 7177,W = 448

  • P = 1277,Q = 7879,W = 492

额外参数集

  • R3_BYTES - 编码R3多项式的长度
  • RQ_BYTES - 编码Rq多项式的字节数
  • PUBLICKEYS_BYTES - 编码公钥的长度
  • SECRETKEYS_BYTES - 秘钥的长度
  • DIFFICULT - 此参数负责应用统计分析算法的复杂性。

有效参数集条件

为了确保参数集的有效性,它必须满足以下条件

  • 2P ≥ 3W:这个不等式对p和w之间的关系施加了约束,强调了这些参数平衡选择的重要性。
  • Q ≥ 16W + 1:另一个关键条件,这个不等式对q相对于权重参数w施加了限制。

符号缩写

为了简明和清晰,以下符号缩写被使用

R3: 表示环 (Z/3)[x]/P,它是与环 R 相关的一种特定变体。Rq:表示域 (Z/q)[x]/P,这是加密系统中另一个关键元素。

Rust 功能

您可以通过功能选择参数,您必须选择参数!

  • ntrup653
  • ntrup761
  • ntrup857
  • ntrup953
  • ntrup1013
  • ntrup1277
# Cargo.toml

ntrulp = { version = "0.1.7", features = ["ntrup653"] }
ntrulp = { version = "0.1.7", features = ["ntrup761"] }
ntrulp = { version = "0.1.7", features = ["ntrup857"] }
ntrulp = { version = "0.1.7", features = ["ntrup953"] }
ntrulp = { version = "0.1.7", features = ["ntrup1013"] }
ntrulp = { version = "0.1.7", features = ["ntrup1277"] }

安装

cargo add ntrulp

测试

git clone https://github.com/zebra-sh/ntrulp.git
cd ntrulp
cargo test --features ntrup1277

git clone https://github.com/zebra-sh/ntrulp.git
cd ntrulp
cargo bench --features ntrup1277

密钥生成

let mut rng = NTRURandom::new();
let f: Rq = Rq::from(rng.short_random().unwrap());
let mut g: R3;
let sk = loop {
    g = R3::from(rng.random_small().unwrap());

    match PrivKey::compute(&f, &g) {
        Ok(s) => break s,
        Err(_) => continue,
    };
};

let pk = PubKey::compute(&f, &g).unwrap();
let imported_pk = PubKey::from_sk(&sk).unwrap();
let pk_bytes = imported_pk.as_bytes();
let from_bytes = PubKey::import(&pk_bytes).unwrap();

assert_eq!(from_bytes.coeffs, pk.coeffs);

加密/解密字节示例

use std::sync::Arc;

use ntrulp::key::priv_key::PrivKey;
use ntrulp::key::pub_key::PubKey;
use ntrulp::ntru::cipher::{
    bytes_decrypt, parallel_bytes_decrypt, parallel_bytes_encrypt, 
};
use ntrulp::ntru::errors::NTRUErrors;
use ntrulp::random::{CommonRandom, NTRURandom};


fn gen_keys<'a>() -> Result<(Arc<PrivKey>, Arc<PubKey>), NTRUErrors<'a>> {
    let mut rng = NTRURandom::new();
    let mut g: R3;
    let f: Rq = Rq::from(rng.short_random().unwrap());
    let sk = loop {
        g = R3::from(rng.random_small().unwrap());

        match PrivKey::compute(&f, &g) {
            Ok(s) => break s,
            Err(_) => continue,
        };
    };
    let pk = PubKey::compute(&f, &g).unwrap();

    Ok((Arc::new(sk), Arc::new(pk)))
}

let mut rng = NTRURandom::new();
let bytes = Arc::new(rng.randombytes::<1024>().to_vec());
let (sk, pk) = gen_keys().unwrap();

let num_threads = 4;
let encrypted1 = Arc::new(parallel_bytes_encrypt(&mut rng, &bytes, &pk, num_threads).unwrap());
let decrypted0 = parallel_bytes_decrypt(&encrypted1, &sk, num_threads).unwrap();
let decrypted1 = bytes_decrypt(&encrypted1, &sk).unwrap();

assert_eq!(decrypted0, decrypted1);

待办事项

  • 添加 Falcon 算法进行签名、验证签名

警告

实现

此实现尚未经过任何安全审计,尽管已尽最大努力,但无法保证其正确性或底层函数的恒定时间运行。 请自行承担风险。

依赖项

~315KB