1个不稳定版本
使用旧的Rust 2015
0.1.0 | 2021年2月16日 |
---|
#1703 在 加密学
6,963 每月下载量
在 136 个crate(5个直接)中使用
1MB
26K SLoC
curve25519-dalek-fiat
关于
这是由Isis Agora Lovecruft和Henry de Valence创建的curve25519-dalek
项目的精简版本,旨在公开由fiat-crypto
项目提供的经过形式验证的后端,其中原语曲线运算是从Coq的算术正确性的证明中提取出来的。
Ristretto和Curve25519上的群运算的纯Rust实现。
curve25519-dalek
是一个库,提供了Curve25519的Edwards和Montgomery形式以及素数阶Ristretto群的群运算。
curve25519-dalek
不是旨在提供任何特定加密协议的实现。相反,这些协议的实现(如x25519-dalek
和ed25519-dalek
)应将curve25519-dalek
作为库使用。
curve25519-dalek
旨在提供一个干净且安全的中级别API,用于实现各种基于ECC的加密协议,如密钥协商、签名、匿名凭证、rangeproofs和零知识证明系统。
特别是,curve25519-dalek
实现了Ristretto,它从非素数阶Edwards曲线构造素数阶群。这提供了Edwards曲线算术的速度和安全优势,而没有因因数相关抽象不匹配而导致的陷阱。
使用
要将curve25519-dalek-fiat
导入到您的项目中,请将以下内容添加到项目Cargo.toml
文件的依赖关系部分
curve25519-dalek-fiat = "0.1.0"
有关更多详细信息,请参阅CHANGELOG.md
后端和功能
使用Rust夜间编译器时才可用的功能可以通过nightly
功能启用。特别是,它对于渲染文档和SIMD后端是必需的。
曲线算术是使用以下后端之一实现的
- 使用由
fiat-crypto
提供的已验证的 u64 后端fiat_u64_backend
; - 使用串行公式和
u64
乘积的u32
后端; - 使用串行公式和
u128
乘积的u64
后端; - 使用并行公式和
avx2
指令(速度记录)的avx2
后端; - 使用并行公式和
ifma
指令(速度记录)的ifma
后端;
默认情况下选择 u64
后端。要选择特定的后端,请使用
cargo build --no-default-features --features "std fiat_u64_backend"
cargo build --no-default-features --features "std u32_backend"
cargo build --no-default-features --features "std u64_backend"
# Requires nightly, RUSTFLAGS="-C target_feature=+avx2" to use avx2
cargo build --no-default-features --features "std simd_backend"
# Requires nightly, RUSTFLAGS="-C target_feature=+avx512ifma" to use ifma
cargo build --no-default-features --features "std simd_backend"
使用 curve25519-dalek
的 crate 可以代表其用户选择后端,或者公开特征标志来控制 curve25519-dalek
后端。
std
特性默认启用,但可以使用 --no-default-features
禁用于无 std
构建。请注意,这需要使用其中一个 _backend
特性显式选择算术后端。如果没有选择后端,编译将失败。
安全性
设计 curve25519-dalek
类型以使非法状态不可表示。例如,任何 EdwardsPoint
的实例都保证在 Edwards 曲线上有一个点,任何 RistrettoPoint
的实例都保证在 Ristretto 群中有一个有效的点。
所有操作都使用恒等时间逻辑实现(没有依赖于秘密的分支,没有依赖于秘密的内存访问),除非特别标记为可变时间代码。我们相信我们的恒等时间逻辑已降低到恒等时间汇编,至少在 x86_64
目标上。
作为对未来编译器优化可能的额外防护措施,subtle
crate 在每个条件移动或赋值之前放置了一个优化屏障。更多详细信息请参阅 subtle
crate 的文档。
某些功能(例如,多标量乘法或批量求逆)需要堆分配临时缓冲区。所有可能包含秘密数据的堆分配缓冲区在释放之前都会显式清零。
但是,我们不尝试清零堆栈数据,有两个原因。首先,这样做是不可能的:我们没有控制堆分配,因此无法知道要擦除多少数据。其次,因为 curve25519-dalek
提供了一个中间层 API,开始清零堆栈数据的地方可能不是在 curve25519-dalek
函数的入口点,而是在其他 crate 函数的入口点。
实现是内存安全的,不包含任何重要的 unsafe
代码。SIMD 后端使用 unsafe
内部调用 SIMD 内置函数。这些函数被标记为 unsafe
只是因为在不适当的 CPU 上调用它们会导致 SIGILL
,但整个后端仅使用适当的 target_feature
编译,因此这种情况不会发生。
性能
使用 criterion.rs
运行基准测试。
cargo bench --no-default-features --features "std fiat_u64_backend"
cargo bench --no-default-features --features "std u32_backend"
cargo bench --no-default-features --features "std u64_backend"
# Uses avx2 or ifma only if compiled for an appropriate target.
export RUSTFLAGS="-C target_cpu=native"
cargo bench --no-default-features --features "std simd_backend"
性能是正确性、安全性和清晰度之后的次要目标,但我们力求与其他实现竞争。新的 fiat_u64
后端与原始的 u64
后端相比,EdDSA 操作的速度会降低 8-15%。
组 | ed25519_fiat_u64_backend | ed25519_u64_backend |
---|---|---|
Ed25519 批量签名验证/128 | 1.10 3.0±0.01ms | 1.00 2.7±0.01ms |
Ed25519 批量签名验证/16 | 1.09 411.7±1.28µs | 1.00 377.8±0.92µs |
Ed25519 批量签名验证/256 | 1.09 5.4±0.01ms | 1.00 4.9±0.01ms |
Ed25519 批量签名验证/32 | 1.08 779.3±4.87µs | 1.00 723.9±3.21µs |
Ed25519 批量签名验证/4 | 1.09 137.9±0.75µs | 1.00 127.0±0.30µs |
Ed25519 批量签名验证/64 | 1.15 1590.2±44.34µs | 1.00 1385.2±6.80µs |
Ed25519 批量签名验证/8 | 1.09 229.0±0.92µs | 1.00 210.2±0.63µs |
Ed25519 批量签名验证/96 | 1.11 2.4±0.08ms | 1.00 2.2±0.01ms |
Ed25519 密钥对生成 | 1.07 17.9±0.07µs | 1.00 16.7±0.09µs |
Ed25519 签名验证 | 1.11 51.1±0.26µs | 1.00 46.1±0.29µs |
Ed25519 签名 | 1.05 18.9±0.09µs | 1.00 18.0±0.07µs |
Ed25519 带扩展密钥的签名 | 1.11 18.6±0.13µs | 1.00 16.8±0.13µs |
Ed25519 严格签名验证 | 1.06 53.0±0.33µs | 1.00 50.0±0.15µs |
依赖项
~0.4–2MB
~41K SLoC