2 个稳定版本
4.1.3 | 2024年5月12日 |
---|
200 在 加密学
每月 24 次下载
在 ed25519-dalek-v2 中使用
1MB
26K SLoC
curve25519-dalek
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
,请在项目 Cargo.toml
的依赖部分添加以下内容:
curve25519-dalek = "4"
如果您选择启用 SemVer 免疫功能,可以使用范围来限定测试兼容的版本范围,例如:
curve25519-dalek = ">= 4.0, < 4.2"
功能标志
功能 | 默认? | 描述 |
---|---|---|
alloc |
✓ | 启用 Edwards 和 Ristretto 多标量乘法、批量标量求逆和批量 Ristretto 双重压缩。同时启用 zeroize 。 |
zeroize |
✓ | 为所有标量和曲线点类型启用 Zeroize 。 |
precomputed-tables |
✓ | 包含预计算的基点乘法表。这可以将 EdwardsPoint::mul_base 和 RistrettoPoint::mul_base 的速度提高约 4 倍,但会增加约 30KB 的代码大小。 |
rand_core |
启用 Scalar::random 和 RistrettoPoint::random 。这是一个可选依赖项,其版本不受 SemVer 的约束。有关更多详细信息,请参阅 下面。 |
|
digest |
启用 RistrettoPoint::{from_hash, hash_from_bytes} 和 Scalar::{from_hash, hash_from_bytes} 。这是一个可选依赖项,其版本不受 SemVer 的约束。有关更多详细信息,请参阅 下面。 |
|
serde |
为所有点和标量类型启用 serde 序列化/反序列化。 |
|
legacy_compatibility |
启用 Scalar::from_bits ,允许用户构建未简化的标量,其算术是错误的。除非您知道自己在做什么,否则不要使用此功能。 |
|
group |
启用外部 group 和 ff crate 特性。 |
要禁用 curve25519-dalek
作为依赖项时的默认功能,请将 default-features = false
添加到您的 Cargo.toml
中的依赖项。要运行 cargo
时禁用,请添加 CLI 标志 --no-default-features
。
主版本 API 变更
每个主版本发布的破坏性更改可以在 CHANGELOG.md
中的 "破坏性更改" 子标题下找到。以下是高级别的最新破坏性更改:
4.0.0 的破坏性更改
- 将 MSRV 从 1.41 更新到 1.60
- 提供 SemVer 政策
- 将
digest
和rand_core
设置为可选功能 - 移除
std
和nightly
功能 - 替换后端选择 - 请参阅 CHANGELOG.md 和 后端
- 将方法
Scalar::{zero, one}
替换为常量Scalar::{ZERO, ONE}
Scalar::from_canonical_bytes
现在返回CtOption
Scalar::is_canonical
现在返回Choice
- 删除
Scalar::from_bytes_clamped
和Scalar::reduce
- 弃用并启用功能门
Scalar::from_bits
后面legacy_compatibility
- 弃用
EdwardsPoint::hash_from_bytes
并将其重命名为EdwardsPoint::nonspec_map_to_curve
- 在使用
EdwardsBasepointTable
或RistrettoBasepointTable
时,需要包含一个新的特型,use curve25519_dalek::traits::BasepointTable
此版本还进行了大量的依赖更新和放宽,以解决上游构建问题。
后端
曲线算术由以下后端之一实现和使用
后端 | 选择 | 实现 | 位 / 字大小 |
---|---|---|---|
串行 |
自动 | 一个优化的、非并行的实现 | 32 和 64 |
fiat |
手动 | 来自 fiat-crypto 的形式化验证域算术 | 32 和 64 |
simd |
自动 | Intel AVX2 / AVX512 IFMA 加速后端 | 64 仅限 |
在运行时,curve25519-dalek
从它编译支持的后端集中选择一个算术后端。对于 Intel x86-64 目标,除非指定其他情况,否则它将使用 simd
支持构建自身,并在检测到适当的 CPU 特性时默认使用 serial
。有关更多详细信息,请参阅 SIMD 后端。
将来,simd
后端可能扩展到覆盖更多的指令集。此更改将不会破坏性,因为这被视为实现细节。
手动后端覆盖
您可以强制crate使用特定的后端支持编译,例如,为 x86-64 目标使用 serial
以节省代码大小,或使用 fiat
强制运行时使用验证代码。为此,设置环境变量
RUSTFLAGS='--cfg curve25519_dalek_backend="BACKEND"'
等效地,您可以将内容写入 ~/.cargo/config
[build]
rustflags = ['--cfg=curve25519_dalek_backend="BACKEND"']
更多信息 这里。
注意:贡献者:目标后端并非完全独立。 SIMD 后端 直接依赖于串行后端的部分才能运行。
位 / 字大小
curve25519-dalek
会根据构建目标自动选择 fiat
和 serial
后端的字大小。例如,为 64 位机器构建时,如果选择了 serial
或 fiat
后端,则会自动选择默认的 64 位字大小。
在某些目标中,可能需要覆盖字大小以获得更好的性能。可以通过设置环境变量来覆盖 serial
和 fiat
后端的字大小。
RUSTFLAGS='--cfg curve25519_dalek_bits="SIZE"'
SIZE
是 32
或 64
。与上述部分一样,这也可以放在 ~/.cargo/config
中。
注意:SIMD 后端 需要 64 位字大小。尝试设置 bits=32 和 backend=simd
将导致编译错误。
交叉编译
由于后端选择是根据目标进行的,交叉编译将自动选择正确的字大小。例如,如果 x86-64 Linux 机器运行以下命令,curve25519-dalek
将使用 32 位的 serial
后端进行编译。
$ sudo apt install gcc-multilib # (or whatever package manager you use)
$ rustup target add i686-unknown-linux-gnu
$ cargo build --target i686-unknown-linux-gnu
SIMD 后端
具体的 SIMD 后端(AVX512 / AVX2 / serial
默认)根据当前可用的 CPU 功能和是否使用 Rust 夜间版进行编译自动选择。具体条件如下所述。
对于给定的 CPU 功能,您也可以指定适当的 -C target_feature
以构建假定所需的 SIMD 指令始终可用的二进制文件。如果没有充分的理由,请不要这样做。
后端 | RUSTFLAGS |
需要夜间版? |
---|---|---|
avx2 | -C target_feature=+avx2 |
no |
avx512 | -C target_feature=+avx512ifma,+avx512vl |
yes |
如果在非夜间编译器上编译,curve25519-dalek
将不包括 AVX512 代码,因此永远不会在运行时选择它。
文档
semver-stable、面向公众的 curve25519-dalek
API 在此处有文档:这里。
本地构建文档
curve25519-dalek
文档需要一个自定义 HTML 头来包含用于数学支持的 KaTeX。遗憾的是 cargo doc
目前不支持此功能,但可以使用以下方法构建文档:
make doc
用于常规文档,和
make doc-internal
用于包含私有项目的文档。
维护策略
此库的所有默认功能都受 语义版本控制(SemVer)的保护。以下概述了 MSRV 和公共 API 的 SemVer 免疫。
最低支持的 Rust 版本
版本 | MSRV |
---|---|
4.x | 1.60.0 |
3.x | 1.41.0 |
从 4.x 开始,MSRV 的变化将伴随着小版本号的增加。
公共 API SemVer 免疫
影响公共 API 的 SemVer 免疫组件的破坏性更改将伴随着一些版本号的增加。以下是一些具体的策略
版本 | 公共 API 组件 | 策略 |
---|---|---|
4.x | 依赖项 group 、digest 和 rand_core |
小版本号增加 |
安全性
curve25519-dalek
类型被设计为使非法状态不可表示。例如,任何 EdwardsPoint
实例都保证在 Edwards 曲线上有一个点,任何 RistrettoPoint
实例都保证在 Ristretto 群中有一个有效的点。
所有操作均使用常数时间逻辑(没有依赖于秘密的分支,没有依赖于秘密的内存访问)实现,除非特别标注为可变时间代码。我们相信我们的常数时间逻辑被降低到常数时间汇编,至少在 x86_64
目标上。
为了额外防范可能的未来编译器优化,subtle
库在每个条件移动或赋值之前放置了一个优化屏障。更多细节可以在 subtle
库的文档 中找到。
某些功能(例如,多标量乘法或批逆)需要堆分配临时缓冲区。所有可能包含秘密数据的堆分配缓冲区在释放之前都会被显式清零。
然而,我们没有尝试清零栈数据,原因有两个。首先,这样做是不可能的:我们没有控制栈分配,因此无法知道要擦除多少数据。其次,因为 curve25519-dalek
提供了一个中等级别的 API,正确的清零栈数据的开始位置可能是 curve25519-dalek
函数的入口点,而不是其他库中函数的入口点。
实现是内存安全的,不包含显著的 unsafe
代码。SIMD 后端内部使用 unsafe
调用 SIMD 内置函数。这些函数被标记为 unsafe
仅因为在不适当的 CPU 上调用它们会导致 SIGILL
,但整个后端仅在检测到适当的 CPU 特性时或在整个程序编译时使用适当的 target_feature
才会调用。
性能
基准测试使用 criterion.rs
运行。
cargo bench --features "rand_core"
export RUSTFLAGS='-C target_cpu=native'
cargo +nightly bench --features "rand_core"
性能是正确性、安全性和清晰度之后的次要目标,但我们旨在与其他实现具有竞争力。
FFI
不幸的是,我们没有计划直接将 FFI 添加到 curve25519-dalek
。原因是,我们使用 Rust 功能提供一个维护安全不变量的 API,这在 FFI 边界上是无法维护的。例如,如上文中 安全 部分所述,无法构造无效点,如果我们通过 FFI 公开点操作,则不会是这样。
然而,curve25519-dalek
被设计为一个 中等级别 API,旨在实现其他更高级别的原语。我们建议在 Rust 中实现高级原语(如签名、PAKE、ZKP 等),将 curve25519-dalek
作为依赖项,并让该库为该原语提供一个最小、以字节缓冲区为导向的 FFI。
贡献
请参阅 CONTRIBUTING.md。
关于
剧透警告: 第十二任博士与 Daleks 的第一次相遇是在他的第二集完整剧集“Into the Dalek”中。一艘饱受折磨的“联合银河抵抗力量”的船发现了一个坏掉的 Dalek 已经“变好”,渴望杀死所有的其他 Daleks。博士、克拉拉和一支士兵小队被缩小并进入 Dalek,博士将其命名为 Rusty。他们修复了损坏,但意外地使其恢复原状,导致它再次肆虐,并警告 Dalek 舰队叛乱舰船的位置。然而,博士设法通过将他的意识与 Dalek 连接起来将 Rusty 恢复到之前的状态:Rusty 与博士一样欣赏宇宙的美丽,但也对 Daleks 深恶痛绝。Rusty 摧毁其他 Daleks 并离开船只,决心追踪并结束 Dalek 种族。
curve25519-dalek
由 Isis Agora Lovecruft 和 Henry de Valence 创作。
本库的部分代码最初是Adam Langley的Golang ed25519库的移植,该库本身是基于参考实现ref10
的移植。此后,大部分代码,包括32位字段算术,都已重写。
快速的u32
和u64
标量算术由Andrew Moon实现,标量求逆的加法链由Brian Smith提供。优化的批量求逆由Sean Bowe和Daira Hopwood贡献。
no_std
和zeroize
支持由Tony Arcieri贡献。
形式化验证的fiat_backend
集成了由Fiat Crypto项目生成的Rust代码,由François Garillot贡献。
还要感谢Ashley Hauck、Lucas Salibian、Manish Goregaokar、Jack Grigg、Pratyush Mishra、Michael Rosenberg、@pinkforest以及无数其他人为他们的贡献。
依赖项
~0–1.4MB
~30K SLoC