#curve25519 #ristretto #ristretto255 #crypto

无std dalek-test-curve-docs

ristretto255和Curve25519上的纯Rust实现

1个版本 (0个不稳定版本)

4.0.0-pre.52022年11月24日

#14 in #ristretto255

BSD-3-Clause

1MB
25K SLoC

curve25519-dalek

ristretto和Curve25519上的纯Rust实现。

curve25519-dalek是一个提供Curve25519的Edwards和Montgomery形式以及素数阶Ristretto群上群操作的库。

curve25519-dalek不打算提供任何特定加密协议的实现。相反,那些协议的实现(如x25519-daleked25519-dalek)应将curve25519-dalek作为库使用。

curve25519-dalek旨在提供一个干净、安全的中级别 API,用于实现各种基于ECC的加密协议,如密钥协商、签名、匿名凭证、范围证明和零知识证明系统。

特别是,curve25519-dalek实现了Ristretto,它从一个非素数阶Edwards曲线构造出一个素数阶群。这提供了Edwards曲线算术的速度和安全优势,而没有与系数相关的抽象不匹配的问题。

文档

semver稳定的、面向公众的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 依赖项包。

它还要求在每次使用 EdwardsBasepointTableRistrettoBasepointTable 时,包括一个新的特性 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(或您使用的任何包管理器)
  • rustup添加目标 i686-unknown-linux-gnu
  • cargo构建 --目标i686-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等),将其作为依赖项,并让该crate提供针对该原语的特定FFI,以最小化、面向字节数据缓冲区的方式。

贡献

请参阅CONTRIBUTING.md

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

关于

剧透警告:第十二任博士与戴立克的第一次相遇是在他的第二集全剧集“进入戴立克”中。一艘“联合银河抵抗”的疲惫飞船发现了一个损坏的戴立克,它变成了“好人”,渴望杀死所有其他戴立克。博士、克拉拉和一队士兵被缩小并进入戴立克,博士将其命名为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以及无数其他人为他们的贡献。

依赖

~0.4–1.9MB
~39K SLoC