4个版本
4.0.0-pre.5 | 2022年11月24日 |
---|
#1160 in 加密学
1MB
25K 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
API文档在这里进行说明这里。此外,不稳定内部实现细节的文档在这里进行说明这里。
curve25519-dalek
文档需要自定义HTML标题来包含KaTeX进行数学支持。不幸的是,cargo doc
目前不支持此功能,但可以使用以下方法构建文档
make doc
make doc-internal
使用
要导入curve25519-dalek
,请将以下内容添加到项目的Cargo.toml
依赖部分
curve25519-dalek = "4.0.0-pre.2"
主要版本API更改
请参阅 CHANGELOG.md
了解更多详情。
2.x
2.x
系列的 API 几乎与 1.x
系列完全相同,除了以下改动:
- 纠正了 (可选的)
serde
功能的数据建模错误,因此当使用2.x
系列的serde
实现与serde-bincode
一起使用时,导出的序列化与常用的 X/Ed25519 格式匹配; - 更新了
rand
版本。
3.x(当前稳定版)
3.x
系列的唯一重大变更是对 digest
版本的更新,非重大变更包括:
- 在稳定 Rust 中支持使用
alloc
代替std
; - 支持 Edwards 点的 Elligator2 编码;
- 修复了使用
packed_simd2
的错误; - 各种文档修复和改进;
- 支持配置大小的预计算查找表,用于基点标量乘法;
- 两个新的形式验证字段算术后端,它们使用来自 Fiat Crypto Rust 代码的代码,该代码是从 Coq 理论证明系统验证的函数正确性的证明中生成的;
- 支持显式调用所有点类型的
zeroize
特性。
4.x(当前 alpha 版)
4.x
系列的 API 几乎与 3.x
相同,但更新了 rand
依赖项。
它还需要在每次使用 EdwardsBasepointTable
或 RistrettoBasepointTable
时包含一个新的特性 use curve25519_dalek::traits::BasepointTable
。
后端选择也已更新,以更自动化的方式进行。请参见下文。
后端和特性
nightly
特性启用仅在 Rust 夜间编译器中使用时才可用的特性。特别是,它对于渲染文档和 SIMD 后端是必需的。
曲线算术是通过以下后端之一实现的:
- 使用串行公式和
u64
积的u32
后端; - 使用串行公式和
u128
积的u64
后端; - 使用并行公式和
avx2
指令(设置速度记录)的avx2
后端; - 使用并行公式和
ifma
指令(设置速度记录)的ifma
后端; - 使用来自 fiat-crypto 的形式验证字段算术的
fiat
后端;
std
特性默认启用,但可以使用 --no-default-features
禁用,以便进行无 std
构建。请注意,这需要使用其中一个 _backend
特性显式选择算术后端。如果没有选择后端,则编译将失败。
后端选择
后端选择是自动完成的。例如,如果在64位机器上编译,则自动选择u64
后端。如果设置了fiat_backend
功能,则选择fiat u64
后端。
如果您需要在u64
机器上使用u32
后端,那么在x86-64 Linux机器上简单交叉编译将工作。
sudo apt install gcc-multilib
(或您使用的任何软件包管理器)rustuptarget add i686-unknown-linux-gnu
cargobuild --targeti686-unknown-linux-gnu
最低支持的Rust版本
此crate至少需要Rust 1.56.1。此crate的3.x版本支持MSRV 1.41。
将来,MSRV的变化将伴随小版本号的提升。
安全性
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
# Uses avx2 or ifma only if compiled for an appropriate target.
export RUSTFLAGS="-C target_cpu=native"
cargo +nightly bench --no-default-features --features simd_backend
性能是正确性、安全性和清晰度之后的次要目标,但我们的目标是与其他实现具有竞争力。
FFI
很遗憾,我们没有计划直接将FFI添加到curve25519-dalek
中。原因是,我们使用Rust特性来提供一个保持安全性不变量的API,这些不变量在FFI边界上是不可能保持的。例如,如上文中“安全性”部分所述,无效点是不可能构建的,如果我们通过FFI公开点操作,情况就不会是这样。
然而,curve25519-dalek
被设计为一个中间层 API,旨在实现其他,更高层的原语。我们建议不是在中间层提供FFI,而是在Rust中实现高层原语(如签名、PAKE、ZKP等),将其作为curve25519-dalek
的依赖项,并由该crate提供针对该原语的最小、以字节缓冲区为中心的特定FFI。
贡献
请参阅CONTRIBUTING.md。
补丁和pull请求应该针对develop
分支进行,而不是 main
分支。
关于
剧透警告: 第十二任博士与 Daleks 的第一次接触是在他的第二集全剧,“进入 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 以及无数其他人做出的贡献。
依赖项
~0.4–1.9MB
~39K SLoC