#curve25519 #ristretto #ristretto255 #crypto

no-std curve25519-entropic

Ristretto255 和 Curve25519 上的群运算的纯 Rust 实现

1 个稳定版本

使用旧的 Rust 2015

3.2.1 2022 年 8 月 21 日

#1184加密学

46 每月下载量
3 个 crate 中使用 (通过 ecvrf-rs)

BSD-3-Clause

1MB
26K SLoC

curve25519-dalek

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 曲线算术的速度和安全性优势,而没有系数相关抽象不匹配的问题。

文档

semver-stable 的、面向公众的 curve25519-dalek API 文档在此 。此外,不稳定的内部实现细节在此 文档。

《curve25519-dalek》的文档需要自定义HTML头部来包含KaTeX以支持数学公式。不幸的是,当前cargo doc不支持这一点,但可以使用以下方式构建文档:

make doc
make doc-internal

使用以下命令

要导入curve25519-dalek,请将以下内容添加到您项目Cargo.toml的依赖项部分:

curve25519-dalek = "3"

3.x系列中唯一的重大更改是对digest版本的更新,在非破坏性更改方面,包括以下内容:

  • 在稳定的Rust中支持使用alloc而不是std
  • Edwards点的Elligator2编码;
  • 使用packed_simd2的修复;
  • 各种文档的修复和改进;
  • 支持可配置大小的预计算查找表,用于基点标量乘法;
  • 两个新的形式化验证的字段算术后端,它们使用Fiat Crypto Rust代码,该代码由Coq定理证明系统验证的功能正确性证明生成;
  • 支持显式调用所有点类型的zeroize特性。

2.x系列的API几乎与1.x系列完全相同,只是:

  • 修正了(可选的)serde特性的数据建模错误,因此当使用2.x系列的serde实现与serde-bincode一起使用时,派生的序列化与通常的X/Ed25519格式匹配;
  • 更新了rand版本。

有关详细信息,请参阅CHANGELOG.md

后端和特性

nightly特性启用仅在Rust夜间编译器中使用时才可用的特性。特别是,它对于渲染文档和SIMD后端是必需的。

曲线算术是通过以下后端之一实现的:

  • 一个使用序列公式和u64乘积的u32后端;
  • 一个使用序列公式和u128乘积的u64后端;
  • 一个使用并行公式avx2指令的后端(设置速度记录);
  • 一个使用并行公式ifma指令的后端(设置速度记录);

默认情况下选择u64后端。要选择特定的后端,请使用以下命令:

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的库可以代表其用户选择后端,或者公开特性标志来控制curve25519-dalek的后端。

默认启用std特性,但可以使用--no-default-features禁用,以进行无std构建。请注意,这需要使用其中一个_backend特性显式选择算术后端。如果没有选择后端,则编译将失败。

安全性

《curve25519-dalek》的类型设计是为了使非法状态无法表示。例如,任何EdwardsPoint实例都保证包含Edwards曲线上的点,任何RistrettoPoint实例都保证包含Ristretto群中的有效点。

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

作为对未来编译器优化可能的额外保护,subtle 库在每个条件移动或赋值前放置了一个优化障碍。更多详细信息请参阅 subtle 库的文档

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

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

实现是内存安全的,不包含任何显著的 unsafe 代码。SIMD后端内部使用 unsafe 来调用SIMD内嵌函数。这些函数被标记为 unsafe 仅因为在不适当的CPU上调用它们会导致 SIGILL,但整个后端仅使用适当的 target_feature 编译,因此这种情况不会发生。

性能

基准测试使用 criterion.rs 运行。

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"

性能是正确性、安全性和清晰度之后的次要目标,但我们旨在与其他实现竞争。

FFI

遗憾的是,我们没有计划直接为 curve25519-dalek 添加 FFI。原因是,我们使用 Rust 功能来提供维护安全性不变性的API,这些不变性无法在 FFI 边界上维护。例如,如上所述,在 安全性 部分,无法构造无效点,而如果我们通过 FFI 暴露点操作,则情况并非如此。

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

贡献

请参阅 CONTRIBUTING.md

补丁和拉取请求应针对 develop 分支进行,而不是 main

关于

剧透警告:第十二任博士第一次遇见戴立克是在他的第二集完整剧集 "Into the Dalek"。一支饱受折磨的“联合银河抵抗”飞船发现了一个“变好”的损坏戴立克,它渴望杀死所有其他戴立克。博士、克拉拉和一支士兵小队被缩小并进入戴立克,博士将其命名为 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_u32_backendfiat_u64_backend与由Fiat Crypto项目生成的Rust集成,由François Garillot贡献。

还要感谢Ashley Hauck、Lucas Salibian、Manish Goregaokar、Jack Grigg、Pratyush Mishra、Michael Rosenberg以及无数其他人所做的贡献。

依赖项

~0.5–2MB
~42K SLoC