20 个不稳定版本 (8 个破坏性版本)
0.9.0 | 2024年5月9日 |
---|---|
0.8.3 | 2024年3月15日 |
0.8.1 | 2024年2月21日 |
0.7.0 | 2023年10月23日 |
0.2.0 | 2021年8月24日 |
#66 in 密码学
11,302 每月下载量
用于 48 个 crate (8 直接)
535KB
9K SLoC
Winter crypto
此 crate 包含用于 STARK 证明生成和验证所需的加密操作模块。
哈希
哈希 模块定义了一组可用于加密操作的哈希函数。目前,支持以下哈希函数
- SHA3 输出 256 位。
- BLAKE3 输出 256 位或 192 位。较小的输出版本可用于减少 STARK 证明大小,但这也将证明的安全性级别限制在最多 96 位。
- 在 64 位字段上的 Rescue Prime,输出 256 位,在 62 位字段上输出 248 位。Rescue 是一个适合算术化的哈希函数,当需要递归证明组合时可以在 STARK 协议中使用。然而,Winterfell STARK 证明器和验证器尚未支持此函数。
- 与上述相同的 64 位字段上的 Rescue Prime,输出 256 位,但使用新颖的 Jive 压缩模式 以获得更小的状态和更快的 2-to-1 压缩。
Rescue 哈希函数实现
Rescue 哈希函数是根据 Rescue Prime 规范 实现的,但有以下例外
- 我们将轮数设置为 7,这意味着比规范中使用的 50% 安全边际提高了 40%(50% 边际向上取整为 8 轮)。这样做的主要动机是,将轮数设为小于 2 的幂的数可以简化涉及哈希函数的计算的 AIR 设计。
- 在散列一系列元素时,我们不会在序列末尾追加Fp(1)后跟Fp(0)个元素作为填充。相反,我们将容量元素之一初始化为要散列的元素数量,并且只使用Fp(0)元素填充序列。这确保了当我们使用
merge()
函数(例如,构建Merkle树)散列8个域元素来计算2-to-1散列时,以及当我们使用hash_elements()
函数将8个域元素作为元素序列散列时,散列函数的输出是相同的。然而,这也意味着我们的Rescue Prime实例不能以流模式使用,因为必须事先知道要散列的元素数量。 - 对于实例
RP64_256
,我们还进行了以下修改- 我们使用状态的前4个元素(而不是状态的最后一个4个元素)作为容量,其余8个元素作为速率。散列函数的输出来自状态速率部分的第一个四个元素(元素4,5,6和7)。这实际上在XLIX置换之前和之后应用了一个固定的位置换。我们断言这不会影响构造的安全性。
- 我们不是使用Rescue Prime论文中描述的标准方法,即使用Vandermonde矩阵生成MDS矩阵,而是使用Polygon Zero开发的方法来找到一个系数在频域中是两个小的二进制幂的MDS矩阵。这使我们能够显著减少MDS矩阵乘法的时间。使用不同的MDS矩阵不会影响散列函数的安全性,因为任何MDS矩阵都满足Rescue Prime构造(如论文第4.2节所述)。
- 使用Jive作为压缩模式的
RPJive64_256
实例的Rescue Prime实现了与Rp64_256
类似的修改,唯一的例外是其填充规则实现了Hirose填充。此外,由于使用了Jive,当我们使用hash_elements()
函数将8个域元素作为元素序列散列时,以及当我们使用2-to-1 Jive压缩模式将8个域元素压缩为4(例如,构建Merkle树)时,散列函数的输出并不相同。
用于实例化函数的参数是
- 对于
RP64_256
- 域:模数为264 - 232 + 1的64位素域。
- 状态宽度:12个域元素。
- 容量大小:4个域元素。
- 摘要大小:4个域元素(可以序列化为32字节)。
- 找到的数量:7。
- S-Box度:7。
- 目标安全级别:128位。
- 对于
RPJive64_256
- 域:模数为264 - 232 + 1的64位素域。
- 状态宽度:8个域元素。
- 容量大小:4个域元素。
- 摘要大小:4个域元素(可以序列化为32字节)。
- 找到的数量:7。
- S-Box度:7。
- 目标安全级别:128位。
- 对于
RP62_248
- 域:模数为262 - 111 * 239 + 1的62位素域。
- 状态宽度:12个域元素。
- 容量大小:4个域元素。
- 摘要大小:4个域元素(可以序列化为31字节)。
- 找到的数量:7。
- S-Box度:3。
- 目标安全级别:124位。
散列函数性能
在STARK证明生成期间执行的核心操作之一是构建Merkle树。我们非常关注尽快构建这些树,因此,对于STARK协议,2-to-1散列操作(例如,计算两个32字节值的散列)尤为重要。下表包含计算所有当前实现散列函数2-to-1散列的粗略基准。
CPU | BLAKE3_256 | SHA3_256 | RP64_256 | RPJ64_256 | RP62_248 |
---|---|---|---|---|---|
苹果M1 Pro | 76 ns | 227 ns | 5.1 us | 3.8 us | 7.1 us |
AMD Ryzen 9 5950X @ 3.4 GHz | 62 ns | 310 ns | 5.2 us | 3.9 us | 6.9 us |
Core i9-9980KH @ 2.4 GHz | 66 ns | 400 ns | - | - | 6.6 us |
Core i5-7300U @ 2.6 GHz | 81 ns | 540 ns | - | - | 9.5 us |
Core i5-4300U @ 1.9 GHz | 106 ns | 675 ns | - | - | 13.9 us |
从表中可以看出,BLAKE3是目前最快的哈希函数,而我们的代数哈希实现比BLAKE3慢70倍,比SHA3慢20倍。
默克尔
默克尔模块包含一个默克尔树实现,该树支持批处理证明生成和验证。批处理证明基于此处描述的章鱼算法(此处)。
箱子功能
此箱子可以编译以下功能
std
- 默认启用并依赖于Rust标准库。concurrent
- 意味着std
并使某些箱子函数启用多线程执行。no_std
不依赖于Rust标准库并使编译到WebAssembly成为可能。
要使用no_std
编译,通过--no-default-features
标志禁用默认功能。
并发执行
当启用concurrent
功能进行编译时,以下操作将在多个线程中执行
MerkleTree::new()
- 即,将在多个线程中构建默克尔树。
线程数可以通过RAYON_NUM_THREADS
环境变量进行配置,通常默认为机器上的逻辑核心数。
许可证
本项目是MIT许可。
依赖关系
~3MB
~53K SLoC