#ecdh #key-exchange #ecdsa #crypto #dh

无 std static-dh-ecdh

纯 Rust 实现的静态 Diffie-Hellman 和椭圆曲线 Diffie-Hellman 密钥交换

2 个版本

0.1.1 2021 年 1 月 12 日
0.1.0 2021 年 1 月 8 日

#1667 in 密码学

MIT/Apache

76KB
1K SLoC

crypto-code-decipher

这是什么?

纯 Rust 实现的 静态 Diffie-Hellman 密钥交换和 ECDSA。它包括对普通 DH、椭圆曲线 DH 以及 p256、p384 的 ECDSA 实现的 impl。

  • 标准的 DH 实现是一个面向对象的 API。它支持多个 DH 组:DH5、DH14、DH15、DH16、DH17、DH18。
  • ECDH 实现附带了一个教科书级别的实现,将 RustCrypto 中的 Affine-Point 算法作为 Projective-Point 算法实现。在 RustCrypto 中,只有 p256、secp256k1 曲线实现了这种算法,并且正在考虑支持更多曲线,但目前尚未提供。
  • ECDSA 实现使用 ECDH 模块进行密钥生成。
  • 该包广泛使用 min-const-generics 进行代码复用。您需要 rust-1.51,它已添加了对它的支持。min-const-generics 现在在 rust-nightly 中是稳定的。

用法

use static_dh_ecdh::ecdh::ecdh::{ECDHNISTP384, KeyExchange, ToBytes};

fn main () {
    let alice_sk = ECDHNISTP384::<48>::generate_private_key([12; 32]);
    let alice_pk = ECDHNISTP384::<48>::generate_public_key(&alice_sk);

    let bob_sk = ECDHNISTP384::<48>::generate_private_key([21; 32]);
    let bob_pk = ECDHNISTP384::<48>::generate_public_key(&bob_sk);

    let alice_ss = ECDHNISTP384::<48>::generate_shared_secret(&alice_sk, &bob_pk);
    let bob_ss = ECDHNISTP384::<48>::generate_shared_secret(&bob_sk, &alice_pk);

    assert_eq!(alice_ss, bob_ss);

    println!("alice_ss: {:x}", &alice_ss.unwrap().to_bytes()); 
    println!("bob_ss:   {:x}", &bob_ss.unwrap().to_bytes());

}

输出

   Compiling static-dh-ecdh v0.1.0 (C:\Users\Nil\devspace\rust\projects\static-ecdh)
    Finished dev [unoptimized + debuginfo] target(s) in 3.84s
     Running `target\debug\examples\ecdh_p384_curve.exe`   

alice_ss: 66e078e64405a21f61324f23ecc3eaa1376105e4aea83b632625cb4bd1afdb8cb26295c2d20cb89d4af87735491b4214
bob_ss:   66e078e64405a21f61324f23ecc3eaa1376105e4aea83b632625cb4bd1afdb8cb26295c2d20cb89d4af87735491b4214

use p384::{EncodedPoint};
use static_dh_ecdh::signatures::{ECDSASHA256Signature, ECDSASHA384Signature, ECSignature};


fn main () {
    let data = b"ECDSA proves knowledge of a secret number in the context of a single message";
    let mut signer = ECDSASHA256Signature([0; 32], [0; 64]);
    let _keys = signer.generate_keypair([12; 32]);  // test seed value
    let signature = signer.sign(data).unwrap();
    let v = signer.verify(data, &signature.as_ref());

    println!("verified_256: {:?}", v);
    println!("r256: {:?}", ECDSASHA256Signature::r(signature));
    println!("s256: {:?}", ECDSASHA256Signature::s(signature));

    let data = b"ECDSA proves knowledge of a secret number in the context of a single message";
    let mut signer = ECDSASHA384Signature([0; 48], EncodedPoint::identity());
    let _keys = signer.generate_keypair([12; 32]); // test seed value
    let signature = signer.sign(data).unwrap();
    let v = signer.verify(data, &signature.as_ref());
    
    println!("verified_384: {:?}", v);
    println!("r384: {:?}", ECDSASHA384Signature::r(signature));
    println!("s384: {:?}", ECDSASHA384Signature::s(signature));

}

输出


    Finished dev [unoptimized + debuginfo] target(s) in 0.11s
     Running `target\debug\examples\signatures_test.exe`     

verified_256: Ok(true)
r256: [196, 233, 13, 80, 251, 14, 164, 68, 13, 130, 177, 28, 244, 209, 119, 121, 79, 202, 214, 127, 124, 220, 31, 10, 196, 233, 219, 21, 82, 130, 32, 94]  
s256: [156, 131, 138, 215, 204, 167, 103, 102, 47, 2, 88, 246, 171, 235, 128, 210, 180, 243, 74, 72, 20, 75, 26, 178, 185, 58, 183, 245, 209, 186, 33, 162]

verified_384: Ok(true)
r384: [109, 4, 148, 3, 54, 155, 152, 101, 150, 29, 132, 220, 207, 181, 248, 248, 74, 150, 212, 247, 43, 110, 113, 200, 116, 197, 243, 194, 45, 100, 173, 250, 230, 155, 9, 145, 50, 250, 189, 59, 59, 40, 149, 133, 117, 121, 103, 88]
s384: [183, 102, 204, 199, 243, 16, 212, 232, 50, 154, 154, 87, 92, 167, 101, 87, 222, 7, 15, 182, 219, 143, 178, 57, 2, 15, 162, 104, 160, 201, 5, 163, 31, 205, 21, 172, 160, 200, 142, 227, 253, 135, 53, 129, 29, 139, 20, 230]

注意:此包并不旨在取代 RustCrypto ECC 实现。我正在开发一个需要 ECDH 的 prototype 网络协议,而 RustCrypto 尚不支持一些曲线(p-521 和 Brainpool),并且还没有为已实现的曲线提供 out-of-the-box 支持(静态 ECDH)。因此,我编写了这个包。

注意事项

考虑到这一点,以下是一些注意事项

  • 此包尚未经过测试(它只包含一些工作示例)
  • 性能没有被考虑 - 此包中使用的算术是教科书的 Affine-Point 数学版本,并依赖于 num_bigint_dig 包。虽然初步测试似乎表明它(实际上)很好。我的假设是 num_bigint_dig 是原因,但无法确认。
  • 它是一个 no_std lib,但它不是无动态内存分配的,因为 num_bigint_dig 依赖于 alloc
  • 未考虑 Side-channel 攻击,未关注诸如 constant time equality 操作等问题。
  • 这个crate从RustCrypto的椭圆曲线库中借用了一些类型,以便构建统一的API,并便于在将来支持其他曲线时集成rustcrypto-ecc
  • 这个crate包含了RustCrypto项目尚未支持(或完全支持)的曲线。支持的曲线列表——
    • p256 - 这是crate中的一个实现,你可以在生产环境中使用它,因为它是从一个经过良好测试的crate(rust-hpke)中提取出来的(直接使用),该crate反过来又以RustCrypto的p256 crate为基础。
    • P384 - 使用Affine-Point数学和一些来自RustoCrypto库的额外类型来实现。
    • P521 - 将添加支持(实现将与P384类似)
    • Brainpool - 将添加支持(实现将与P384非常相似)

依赖关系

~4MB
~88K SLoC