#signature #ed25519 #curve25519 #ecc #ed25519-key #signature-verification

no-std crev-ed25519-dalek

ed25519-dalek 的分支,用于 crev(直到主线再次可用为止)

3个版本

使用旧的Rust 2015

0.1.2 2019年4月12日
0.1.1 2019年4月12日
0.1.0 2019年3月23日

#2116 in 密码学

BSD-3-Clause

78KB
838

ed25519-dalek

在Rust中快速高效地实现ed25519密钥生成、签名和验证。

文档

文档可在 此处 获取。

基准测试

在一个3.30 GHz的Intel Skylake i9-7900X上运行,不启用TurboBoost,此代码达到以下性能基准

!isisⒶmistakenot:(master *=)~/code/rust/ed25519-dalek ∴ cargo bench
   Compiling ed25519-dalek v0.7.0 (file:///home/isis/code/rust/ed25519-dalek)
    Finished release [optimized] target(s) in 3.11s
      Running target/release/deps/ed25519_benchmarks-721332beed423bce

Ed25519 signing                     time:   [15.617 us 15.630 us 15.647 us]
Ed25519 signature verification      time:   [45.930 us 45.968 us 46.011 us]
Ed25519 keypair generation          time:   [15.440 us 15.465 us 15.492 us]

通过启用avx2后端(在具有兼容微架构的机器上),签名验证的性能得到了显著提高

!isisⒶmistakenot:(master *=)~/code/rust/ed25519-dalek ∴ export RUSTFLAGS=-Ctarget_cpu=native
∃!isisⒶmistakenot:(master *=)~/code/rust/ed25519-dalek ∴ cargo bench --features=avx2_backend
   Compiling ed25519-dalek v0.7.0 (file:///home/isis/code/rust/ed25519-dalek)
    Finished release [optimized] target(s) in 4.28s
      Running target/release/deps/ed25519_benchmarks-e4866664de39c84d
Ed25519 signing                     time:   [15.923 us 15.945 us 15.967 us]
Ed25519 signature verification      time:   [33.382 us 33.411 us 33.445 us]
Ed25519 keypair generation          time:   [15.246 us 15.260 us 15.275 us]

相比之下,Golang中的等效包表现如下

!isisⒶmistakenot:(master *=)~/code/go/src/github.com/agl/ed25519 ∴ go test -bench .
BenchmarkKeyGeneration     30000             47007 ns/op
BenchmarkSigning           30000             48820 ns/op
BenchmarkVerification      10000            119701 ns/op
ok      github.com/agl/ed25519  5.775s

使密钥生成和签名大致平均快2倍,验证快2.5-3倍,具体取决于avx2的可用性。当然,这只是我的机器,这些结果——远非严谨——应该带有一些盐。

换算成粗略的周期数:我们在3300 MHz CPU上以3.3的系数将纳秒转换为每秒周期数,验证为110256周期,签名为52618周期,这与手动优化的汇编实现具有竞争力。

此外,如果您使用的是 rand 包中的CSPRNG,nightly 功能将启用那里的 u128/i128 功能,从而可能提高性能。

如果您的协议或应用程序能够批量处理签名进行验证,那么 verify_batch() 函数的性能得到了极大提升。在上述的英特尔Skylake i9-7900X处理器上,验证96个签名需要1.7673毫秒。这相当于每个签名验证大约18.4094微秒,或者大约60750个周期,比原始论文中给出的批量验证速度快了一倍多(这很可能不是一个公平的比较,因为那是一台Nehalem机器)。测试名称中 / 后面的数字指的是批量的大小

!isisⒶmistakenot:(master *=)~/code/rust/ed25519-dalek ∴ export RUSTFLAGS=-Ctarget_cpu=native
∃!isisⒶmistakenot:(master *=)~/code/rust/ed25519-dalek ∴ cargo bench --features=avx2_backend batch
   Compiling ed25519-dalek v0.8.0 (file:///home/isis/code/rust/ed25519-dalek)
    Finished release [optimized] target(s) in 34.16s
      Running target/release/deps/ed25519_benchmarks-cf0daf7d68fc71b6
Ed25519 batch signature verification/4   time:   [105.20 us 106.04 us 106.99 us]
Ed25519 batch signature verification/8   time:   [178.66 us 179.01 us 179.39 us]
Ed25519 batch signature verification/16  time:   [325.65 us 326.67 us 327.90 us]
Ed25519 batch signature verification/32  time:   [617.96 us 620.74 us 624.12 us]
Ed25519 batch signature verification/64  time:   [1.1862 ms 1.1900 ms 1.1943 ms]
Ed25519 batch signature verification/96  time:   [1.7611 ms 1.7673 ms 1.7742 ms]
Ed25519 batch signature verification/128 time:   [2.3320 ms 2.3376 ms 2.3446 ms]
Ed25519 batch signature verification/256 time:   [5.0124 ms 5.0290 ms 5.0491 ms]

如您所见,每台机器都有一个最佳批量大小,因此您可能需要在目标CPU上运行基准测试以发现最佳大小。对于这台机器,每批大约100个签名是最佳选择

此外,多亏了Rust,这个实现既具有类型安全性,也具有内存安全性。它还很容易被更多能够阅读qhasm的人阅读,使其更容易审计。我们认为,最终,这些功能——与速度相结合——比仅仅周期数更有价值。

关于签名可变形性的说明

这个库生成的签名是可变形的,正如在原始论文中所讨论的

我们可以通过乘以曲线特征因子来消除可变形性属性,但是这将导致我们的实现不会与现有的每个实现相匹配。截至本文撰写时,RFC 8032,“爱德华曲线数字签名算法(EdDSA)”,建议进行更强的检查。虽然我们同意应该进行更强的检查,但我们认为,不应该在十年后更改“ed25519验证”的定义,从而与每个其他实现不兼容。

简而言之,如果可变形性签名对您的协议不利,请不要使用它们。考虑使用基于curve25519的可验证随机函数(VRF),例如Trevor Perrin的VXEdDSA。我们计划最终在curve25519-dalek中支持VXEdDSA。

安装

要安装,请在项目的 Cargo.toml 中添加以下内容

[dependencies.ed25519-dalek]
version = "1"

然后,在您的库或可执行源文件中添加

extern crate ed25519_dalek;

功能

为了使应用程序默认启用nightly功能构建 ed25519-dalek,请改为

[dependencies.ed25519-dalek]
version = "1"
features = ["nightly"]

要使应用程序在某人使用 cargo build --features="nightly" 时启用nightly功能,请将以下内容添加到 Cargo.toml

[features]
nightly = ["ed25519-dalek/nightly"]

要启用 serde 支持,使用以下方式构建 ed25519-dalek

[dependencies.ed25519-dalek]
version = "1"
features = ["serde"]

默认情况下,ed25519-dalek会针对curve25519-daleku64_backend特性进行编译,该特性使用Rust的i128特性,使速度大约提高一倍,相对于u32_backend特性。然而,当针对32位系统进行编译时,您可能希望使用以下命令进行编译:cargo build --no-default-features --features="u32_backend"。如果您为具有avx2指令的机器进行编译,还可以使用实验性的avx2_backend。要使用它,请使用以下命令进行编译:RUSTFLAGS="-C target_cpu=native" cargo build --no-default-features --features="avx2_backend"

依赖项

~3MB
~58K SLoC