39 个版本 (稳定)

4.1.3 2024年6月18日
4.1.2 2024年2月7日
4.1.1 2023年9月20日
4.0.0 2023年7月22日
0.1.3 2016年12月9日

加密学 中排名第 2

Download history 433926/week @ 2024-05-03 480648/week @ 2024-05-10 503004/week @ 2024-05-17 507846/week @ 2024-05-24 509762/week @ 2024-05-31 455407/week @ 2024-06-07 464352/week @ 2024-06-14 464752/week @ 2024-06-21 396670/week @ 2024-06-28 415565/week @ 2024-07-05 456175/week @ 2024-07-12 474637/week @ 2024-07-19 452365/week @ 2024-07-26 477178/week @ 2024-08-02 506774/week @ 2024-08-09 460658/week @ 2024-08-16

每月下载量 1,984,779
用于 5,617 个 crate (271 个直接使用)

BSD-3-Clause

1MB
26K SLoC

curve25519-dalek CI

dalek-cryptography logo: a dalek with edwards curves as sparkles coming out of its radar-schnozzley blaster thingies

Ristretto 和 Curve25519 上的群运算的纯 Rust 实现。

curve25519-dalek 是一个库,提供 Curve25519 的 Edwards 和 Montgomery 形式的群运算,以及素阶 Ristretto 群的群运算。

curve25519-dalek 不旨在提供任何特定加密协议的实现。相反,这些协议的实现(如 x25519-daleked25519-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_baseRistrettoPoint::mul_base的速度提高约4倍,但会增加约30KB的代码大小。
rand_core 启用Scalar::randomRistrettoPoint::random。这是一个可选依赖项,其版本不受SemVer约束。更多详情请见下文
digest 启用RistrettoPoint::{from_hash, hash_from_bytes}Scalar::{from_hash, hash_from_bytes}。这是一个可选依赖项,其版本不受SemVer约束。更多详情请见下文
serde 为所有点和标量类型启用serde序列化和反序列化。
legacy_compatibility 启用Scalar::from_bits,允许用户构建未简化的标量,其算术可能不正确。除非你了解自己在做什么,否则不要使用此功能。
group 启用外部groupff crate特质。

要禁用使用curve25519-dalek作为依赖项时的默认功能,请在您的Cargo.toml中的依赖项中添加default-features = false。要禁用运行cargo时的默认功能,请添加CLI标志--no-default-features

主要版本API更改

每个主要版本发布中的破坏性更改可以在CHANGELOG.md中的“破坏性更改”子标题下找到。以下是高级别中最新破坏性更改的概述

4.0.0中的破坏性更改

  • 将MSRV从1.41更新到1.60
  • 提供SemVer策略
  • digestrand_core作为可选功能
  • 移除stdnightly功能
  • 替换后端选择 - 请参阅CHANGELOG.md后端
  • 用常量Scalar::{ZERO, ONE}替换方法Scalar::{zero, one}
  • 现在 Scalar::from_canonical_bytes 返回 CtOption
  • 现在 Scalar::is_canonical 返回 Choice
  • 删除 Scalar::from_bytes_clampedScalar::reduce
  • 弃用并隐藏 Scalar::from_bitslegacy_compatibility 之后
  • 弃用 EdwardsPoint::hash_from_bytes 并将其重命名为 EdwardsPoint::nonspec_map_to_curve
  • 在使用 EdwardsBasepointTableRistrettoBasepointTable 时,需要包含一个新的特性,use curve25519_dalek::traits::BasepointTable

此次发布还进行了大量依赖项的更新和放宽,以解决上游构建问题。

后端

曲线算术由以下后端之一实现和使用

后端 选择 实现 位 / 字大小
串行 自动 一个优化、非并行实现 3264
fiat 手动 来自 fiat-crypto 的形式化验证字段算术 3264
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 将根据构建目标自动选择 fiatserial 后端的字大小。例如,当选择 serialfiat 后端时,构建 64 位机器将自动选择默认的 64 位字大小。

在某些目标上,可能需要覆盖字大小以获得更好的性能。可以通过设置环境变量覆盖 serialfiat 后端的字大小

RUSTFLAGS='--cfg curve25519_dalek_bits="SIZE"'

SIZE 的值为 3264。与上文相同,这也可以放置在 ~/.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 nightly进行编译自动选择。具体条件如下所述。

对于给定的CPU功能,您也可以指定适当的 -C target_feature 来构建一个假设所需的SIMD指令始终可用的二进制文件。如果没有充分的理由,请不要这样做。

后端 RUSTFLAGS 需要nightly吗?
avx2 -C target_feature=+avx2 no
avx512 -C target_feature=+avx512ifma,+avx512vl yes

如果使用非nightly编译器编译,curve25519-dalek 将不包括AVX512代码,因此永远不会在运行时选择它。

文档

semver-stable、面向公众的 curve25519-dalek API 在此处有文档:这里

在本地构建文档

curve25519-dalek 文档需要自定义HTML标题,以包含用于数学支持的KaTeX。不幸的是,当前 cargo doc 不支持此功能,但可以使用以下方法构建文档:

make doc

for常规文档,和

make doc-internal

for包含私有项目的文档。

维护策略

此库的所有默认功能都受 语义版本控制 (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 依赖项 groupdigestrand_core 小SemVer增加

安全性

curve25519-dalek 类型旨在使非法状态不可表示。例如,任何 EdwardsPoint 实例都将保证持有Edwards曲线上的点,任何 RistrettoPoint 实例都将保证持有Ristretto群中的有效点。

所有操作都是使用恒时逻辑(没有依赖于秘密的分支,没有依赖于秘密的内存访问)实现的,除非明确标记为可变时码。我们相信我们的恒时逻辑被降低到恒时汇编,至少在 x86_64 目标上。

为了防止未来编译器的优化,subtle 包在每次条件移动或赋值之前放置了一个优化屏障。更多详情请见 subtle 包的文档

某些功能(例如,多标量乘法或批量求逆)需要堆分配临时缓冲区。所有可能包含秘密数据的堆分配缓冲区在释放之前都将显式清零。

然而,我们并没有尝试将堆栈数据清零,原因有两个。首先,这样做是不可能的:我们无法控制堆栈分配,因此无法知道要擦除多少数据。其次,因为 curve25519-dalek 提供了一个中间层 API,因此正确开始清零堆栈数据的地方可能不是在 curve25519-dalek 函数的入口点,而是在其他 crate 中函数的入口点。

实现是内存安全的,并且不包含任何显著的 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

遗憾的是,我们目前没有计划直接向 curve25519-dalek 添加 FFI。原因是,我们使用 Rust 功能提供了一个保持安全性的 API,这不可能在 FFI 边界上保持。例如,如上文中 安全性 部分所述,无效点是不可能构建的,而如果我们在 FFI 中公开点操作,情况就不会是这样。

然而,curve25519-dalek 被设计为一个 中间层 API,旨在实现其他更高级的原语。而不是在中间层提供 FFI,我们的建议是在 Rust 中实现高级原语(签名、PAKE、ZKP 等),将 curve25519-dalek 作为依赖项,并让该 crate 为该原语提供最小、面向字节缓冲区的 FFI。

贡献

请参阅 CONTRIBUTING.md

关于

剧透警告: 第十二任博士第一次遇见戴立克是在他的第二集完整剧集,“进入戴立克”。联合银河抵抗组织的困境中的一艘船发现了一个坏了的戴立克,它变成了“好人”,希望杀死所有其他戴立克。博士、克拉拉和一支士兵小队被缩小并进入了戴立克,博士将其命名为 Rusty。他们修复了损坏,但意外地将其恢复到原始状态,导致它进行大屠杀,并警告戴立克舰队叛乱飞船的位置。然而,博士通过将自己的思想与戴立克连接起来,设法将 Rusty 恢复到之前的状态:Rusty 与博士一样,欣赏宇宙的美,但同时也对戴立克有着深刻的仇恨。Rusty 摧毁了其他戴立克,离开了飞船,决心追踪并结束戴立克种族。

curve25519-dalek 由 Isis Agora Lovecruft 和 Henry de Valence 撰写。

此库的部分内容最初是 Adam Langley 的 Golang ed25519 库的移植,该库反过来又是参考 ref10 实现的移植。此后,大部分代码,包括 32 位字段算术,都已重写。

快速的 u32u64 标量算术是由 Andrew Moon 实现的,标量逆运算的加法链是由 Brian Smith 提供的。优化批逆运算是由 Sean Bowe 和 Daira Hopwood 贡献的。

no_stdzeroize 支持是由 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