SNARK中哈希的基准测试

  • han___
  • 发布于 2天前
  • 阅读 32

本文对多种零知识证明(ZKP)框架在哈希函数上的性能进行了基准测试,包括plonky3、stwo、binius、hashcaster和expander。文章详细比较了它们在不同哈希算法(如Blake3、Keccak、Poseidon2等)上的吞吐量、证明大小和内存占用情况,并讨论了优化方向以及各个框架的优缺点。

用例

  • 基于哈希的签名的聚合
    • 乐观要求:50万个哈希/秒[1]
  • STARKed 二叉哈希树
    • 最坏情况要求:10万个哈希/秒[2]

要求

  • 后量子友好
  • 可证明的可靠性
  • 编写规范不太复杂

基准候选

基准

  • 机器配置

    • CPU:i9-13900K
    • 内存:64GB (2x Crucial DDR5 5600 32GB 双通道)
    • 操作系统:Linux 5.15.0-124-generic x86-64
    • 环境:
    • RAYON_NUM_THREADS: 4
  • 代码: https://github.com/han0110/bench-hash-in-snark/tree/3398a8c

  • 输出

    • perm: 证明的置换次数 (210..20)
    • time: 10 个样本的平均证明时间
    • throughput: 10 个样本的平均吞吐量 (= perm / time)
    • proof_size: 10 个样本的平均证明大小
    • peak_memory: 由 /usr/bin/time 度量的证明命令的峰值内存使用量(如果进程由于 OOM 被终止,该行将填充 -
  • 所有软件包的实现都是具有固定初始状态的一轮置换,如果实际输入长度大于哈希函数的块长度,则需要基于构造对实现施加更多约束,但与置换相比,成本应该可以忽略不计。

    • *

plonky3

FRI 参数:

  • 域大小:124(31 位域的 4 度扩展)

  • 速率:1/2

  • 查询次数:256

  • Poseidon2 参数(符号遵循 https://eprint.iacr.org/2023/323.pdf

    • n=31t=16d=3RF=8RP=20
    • p=231−224+1 (KoalaBear)
  • 124 位域太小,无法达到 128 位可证明的可靠性,我们需要大约 192 位域,但目前没有可用的选项。

这使得下面的 throughput 有点乐观。

  • 查询次数也需要稍微增加才能达到准确的 128 位可证明的可靠性,但不会与当前值相差太远。

这使得下面的 proof_size 有点乐观。

要重现,请进入代码存储库并运行:

for i in $(seq 10 20); do
    RAYON_NUM_THREADS=4 ./bench.sh plonky3 blake3 $i
    RAYON_NUM_THREADS=4 ./bench.sh plonky3 keccak $i
    RAYON_NUM_THREADS=4 ./bench.sh plonky3 poseidon2 $i
done;
python3 render_table.py
hash perm time throughput proof_size peak_mem
blake3 210 59.02 ms 17.35 K/s 9.85 MB 100.58 MB
blake3 211 120.67 ms 16.97 K/s 9.96 MB 170.68 MB
blake3 212 242.09 ms 16.92 K/s 10.08 MB 316.95 MB
blake3 213 483.01 ms 16.96 K/s 10.20 MB 605.91 MB
blake3 214 982.55 ms 16.67 K/s 10.33 MB 1.16 GB
blake3 215 2.06 s 15.88 K/s 10.47 MB 2.29 GB
blake3 216 4.35 s 15.06 K/s 10.62 MB 4.54 GB
blake3 217 10.11 s 12.96 K/s 10.77 MB 9.06 GB
blake3 218 23.10 s 11.35 K/s 10.93 MB 18.09 GB
blake3 219 49.49 s 10.59 K/s 11.10 MB 36.15 GB
blake3 220 - - - -
keccak 210 587.01 ms 2.33 K/s 3.89 MB 692.65 MB
keccak 211 1.20 s 2.27 K/s 4.04 MB 1.34 GB
keccak 212 2.50 s 2.19 K/s 4.19 MB 2.66 GB
keccak 213 5.06 s 2.16 K/s 4.35 MB 5.31 GB
keccak 214 10.74 s 2.03 K/s 4.52 MB 10.61 GB
keccak 215 23.03 s 1.90 K/s 4.70 MB 21.20 GB
keccak 216 54.17 s 1.61 K/s 4.89 MB 42.39 GB
keccak 217 - - - -
keccak 218 - - - -
keccak 219 - - - -
keccak 220 - - - -
poseidon2 210 3.61 ms 283.96 K/s 1.68 MB 44.39 MB
poseidon2 211 4.50 ms 455.39 K/s 1.76 MB 44.80 MB
poseidon2 212 6.04 ms 677.63 K/s 1.85 MB 45.20 MB
poseidon2 213 9.86 ms 830.99 K/s 1.95 MB 44.31 MB
poseidon2 214 16.98 ms 965.01 K/s 2.06 MB 44.86 MB
poseidon2 215 34.77 ms 942.38 K/s 2.17 MB 53.09 MB
poseidon2 216 78.66 ms 833.12 K/s 2.30 MB 96.97 MB
poseidon2 217 161.45 ms 811.83 K/s 2.43 MB 184.11 MB
poseidon2 218 327.44 ms 800.58 K/s 2.57 MB 359.19 MB
poseidon2 219 647.94 ms 809.16 K/s 2.71 MB 708.80 MB
poseidon2 220 1.34 s 779.93 K/s 2.87 MB 1.38 GB

相同的 FRI 参数,但速率 = 1/4

要重现,请进入代码存储库并运行:

for i in $(seq 10 20); do
    RAYON_NUM_THREADS=4 PCS_LOG_INV_RATE=2 ./bench.sh plonky3 blake3 $i
    RAYON_NUM_THREADS=4 PCS_LOG_INV_RATE=2 ./bench.sh plonky3 keccak $i
    RAYON_NUM_THREADS=4 PCS_LOG_INV_RATE=2 ./bench.sh plonky3 poseidon2 $i
done;
python3 render_table.py
hash perm time throughput proof_size peak_mem
blake3 210 95.24 ms 10.75 K/s 5.10 MB 167.62 MB
blake3 211 184.65 ms 11.09 K/s 5.16 MB 311.15 MB
blake3 212 375.61 ms 10.90 K/s 5.22 MB 600.53 MB
blake3 213 766.45 ms 10.69 K/s 5.29 MB 1.15 GB
blake3 214 1.58 s 10.34 K/s 5.36 MB 2.28 GB
blake3 215 3.30 s 9.94 K/s 5.43 MB 4.54 GB
blake3 216 6.98 s 9.39 K/s 5.51 MB 9.06 GB
blake3 217 16.11 s 8.14 K/s 5.59 MB 18.08 GB
blake3 218 37.18 s 7.05 K/s 5.67 MB 36.14 GB
blake3 219 - - - -
blake3 220 - - - -
keccak 210 942.43 ms 1.45 K/s 2.04 MB 1.34 GB
keccak 211 1.93 s 1.42 K/s 2.12 MB 2.66 GB
keccak 212 3.95 s 1.38 K/s 2.20 MB 5.30 GB
keccak 213 8.07 s 1.35 K/s 2.28 MB 10.60 GB
keccak 214 17.35 s 1.26 K/s 2.37 MB 21.18 GB
keccak 215 37.05 s 1.18 K/s 2.46 MB 42.35 GB
keccak 216 - - - -
keccak 217 - - - -
keccak 218 - - - -`
keccak 219 - - - -
keccak 220 - - - -
poseidon2 210 4.03 ms 254.37 K/s 903.14 KB 44.68 MB
poseidon2 211 4.41 ms 464.28 K/s 950.17 KB 44.64 MB
poseidon2 212 7.68 ms 533.45 K/s 0.98 MB 44.70 MB
poseidon2 213 12.51 ms 654.95 K/s 1.03 MB 44.86 MB
poseidon2 214 27.83 ms 588.72 K/s 1.09 MB 52.23 MB
poseidon2 215 59.70 ms 548.83 K/s 1.15 MB 95.39 MB
poseidon2 216 123.37 ms 531.22 K/s 1.22 MB 182.63 MB
poseidon2 217 249.28 ms 525.81 K/s 1.29 MB 357.43 MB
poseidon2 218 500.62 ms 523.64 K/s 1.36 MB 706.47 MB
poseidon2 219 1.02 s 514.07 K/s 1.44 MB 1.37 GB
poseidon2 220 2.09 s 502.81 K/s 1.52 MB 2.74 GB

stwo

FRI 参数:

  • 域大小:124(31 位域的 4 度扩展)

  • 速率:1/2

  • 查询次数:256

  • Poseidon2 参数(符号遵循 https://eprint.iacr.org/2023/323.pdf

    • n=31t=16d=5RF=8RP=14
    • p=231−1 (Mersenne31)
  • 124 位域太小,无法达到 128 位可证明的可靠性,我们需要大约 192 位域,但目前没有可用的选项。

这使得下面的 throughput 有点乐观。

  • 查询次数也需要稍微增加才能达到准确的 128 位可证明的可靠性,但不会与当前值相差太远。

这使得下面的 proof_size 有点乐观。

要重现,请进入代码存储库并运行:

for i in $(seq 10 20); do
    RAYON_NUM_THREADS=4 ./bench.sh stwo blake2s $i
    RAYON_NUM_THREADS=4 ./bench.sh stwo poseidon2 $i
done;
python3 render_table.py
hash perm time throughput proof_size peak_mem
blake2s 210 807.93 ms 1.27 K/s 3.28 MB 772.36 MB
blake2s 211 898.52 ms 2.28 K/s 3.28 MB 853.77 MB
blake2s 212 1.06 s 3.85 K/s 3.32 MB 1018.40 MB
blake2s 213 1.43 s 5.73 K/s 3.30 MB 1.31 GB
blake2s 214 1.90 s 8.62 K/s 3.43 MB 2.04 GB
blake2s 215 3.10 s 10.58 K/s 3.57 MB 3.49 GB
blake2s 216 5.35 s 12.24 K/s 3.67 MB 6.40 GB
blake2s 217 10.02 s 13.08 K/s 3.79 MB 12.21 GB
blake2s 218 19.57 s 13.40 K/s 3.96 MB 23.83 GB
blake2s 219 - - - -
blake2s 220 - - - -
poseidon2 210 7.28 ms 140.66 K/s 892.29 KB 36.17 MB
poseidon2 211 12.66 ms 161.80 K/s 1.15 MB 36.61 MB
poseidon2 212 19.98 ms 204.98 K/s 1.25 MB 36.62 MB
poseidon2 213 45.35 ms 180.63 K/s 1.40 MB 40.01 MB
poseidon2 214 85.72 ms 191.14 K/s 1.53 MB 75.77 MB
poseidon2 215 137.20 ms 238.84 K/s 1.63 MB 147.96 MB
poseidon2 216 289.18 ms 226.63 K/s 1.70 MB 291.55 MB
poseidon2 217 523.06 ms 250.59 K/s 1.79 MB 579.75 MB
poseidon2 218 1.03 s 253.99 K/s 1.91 MB 1.13 GB
poseidon2 219 1.94 s 269.86 K/s 2.00 MB 2.25 GB
poseidon2 220 2.44 s 429.44 K/s 2.12 MB 4.50 GB

相同的 FRI 参数,但速率 = 1/4

要重现,请进入代码存储库并运行:

for i in $(seq 10 20); do
    RAYON_NUM_THREADS=4 PCS_LOG_INV_RATE=2 ./bench.sh stwo blake2s $i
    RAYON_NUM_THREADS=4 PCS_LOG_INV_RATE=2 ./bench.sh stwo poseidon2 $i
done;
python3 render_table.py
hash perm time throughput proof_size peak_mem
blake2s 210 1.35 s 756.10 /s 1.81 MB 1.53 GB
blake2s 211 1.49 s 1.38 K/s 1.81 MB 1.67 GB
blake2s 212 1.74 s 2.36 K/s 1.81 MB 1.93 GB
blake2s 213 2.24 s 3.65 K/s 1.81 MB 2.46 GB
blake2s 214 2.92 s 5.61 K/s 1.88 MB 3.82 GB
blake2s 215 4.70 s 6.97 K/s 1.94 MB 6.67 GB
blake2s 216 7.92 s 8.28 K/s 2.01 MB 12.37 GB
blake2s 217 - - - -
blake2s 218 - - - -
blake2s 219 - - - -
blake2s 220 - - - -
poseidon2 210 7.11 ms 144.09 K/s 721.87 KB 36.41 MB
poseidon2 211 11.88 ms 172.43 K/s 746.97 KB 36.50 MB
poseidon2 212 21.57 ms 189.87 K/s 810.15 KB 36.62 MB
poseidon2 213 32.85 ms 249.40 K/s 857.73 KB 36.67 MB
poseidon2 214 48.68 ms 336.57 K/s 899.84 KB 63.93 MB
poseidon2 215 126.33 ms 259.38 K/s 947.25 KB 123.99 MB
poseidon2 216 216.96 ms 302.07 K/s 987.39 KB 244.27 MB
poseidon2 217 398.75 ms 328.71 K/s 1.02 MB 484.21 MB
poseidon2 218 819.53 ms 319.87 K/s 1.07 MB 964.48 MB
poseidon2 219 1.64 s 319.43 K/s 1.15 MB 1.88 GB
poseidon2 220 2.30 s 455.03 K/s 1.20 MB 3.76 GB

binius

FRI 参数:

  • 域大小:128

  • 速率:1/2

  • 查询次数:241

  • 可证明的可靠性:100 位

  • 128 位域太小,无法达到 128 位可证明的可靠性,我们需要大约 150 位域,但目前没有可用的选项。

这使得下面的 throughput 有点乐观。

要重现,请进入代码存储库并运行:

for i in $(seq 10 20); do
    RAYON_NUM_THREADS=4 ./bench.sh binius keccak $i
    RAYON_NUM_THREADS=4 ./bench.sh binius vision $i
done;
python3 render_table.py
hash perm time throughput proof_size peak_mem
keccak 210 372.85 ms 2.75 K/s 429.68 KB 153.11 MB
keccak 211 734.93 ms 2.79 K/s 453.10 KB 288.49 MB
keccak 212 1.41 s 2.90 K/s 536.74 KB 551.79 MB
keccak 213 2.86 s 2.86 K/s 561.60 KB 1.06 GB
keccak 214 5.59 s 2.93 K/s 588.65 KB 2.11 GB
keccak 215 11.12 s 2.95 K/s 619.60 KB 4.26 GB
keccak 216 21.96 s 2.98 K/s 710.77 KB 8.50 GB
keccak 217 43.68 s 3.00 K/s 745.79 KB 16.75 GB
keccak 218 87.99 s 2.98 K/s 780.49 KB 34.11 GB
keccak 219 - - - -
keccak 220 - - - -
vision 210 571.78 ms 1.79 K/s 847.87 KB 155.05 MB
vision 211 886.24 ms 2.31 K/s 867.41 KB 235.49 MB
vision 212 1.47 s hash perm time throughput proof_size peak_mem
--- --- --- --- --- ---
keccak 210 440.88 ms 2.32 K/s 316.43 KB 173.86 MB
keccak 211 827.01 ms 2.48 K/s 331.88 KB 330.25 MB
keccak 212 1.62 s 2.53 K/s 384.24 KB 633.39 MB
keccak 213 3.27 s 2.51 K/s 402.57 KB 1.22 GB
keccak 214 6.46 s 2.54 K/s 421.90 KB 2.42 GB
keccak 215 13.06 s 2.51 K/s 441.98 KB 4.82 GB
keccak 216 25.85 s 2.54 K/s 498.96 KB 9.81 GB
keccak 217 51.52 s 2.54 K/s 521.92 KB 19.70 GB
keccak 218 103.61 s 2.53 K/s 545.87 KB 38.87 GB
keccak 219 - - - -
keccak 220 - - - -
vision 210 625.80 ms 1.64 K/s 739.43 KB 164.54 MB
vision 211 951.49 ms 2.15 K/s 754.16 KB 255.32 MB
vision 212 1.52 s 2.69 K/s 769.65 KB 432.86 MB
vision 213 2.57 s 3.19 K/s 822.04 KB 779.41 MB
vision 214 4.57 s 3.58 K/s 840.40 KB 1.42 GB
vision 215 8.79 s 3.73 K/s 859.76 KB 2.76 GB
vision 216 16.91 s 3.88 K/s 879.87 KB 5.42 GB
vision 217 33.11 s 3.96 K/s 936.88 KB 10.92 GB
vision 218 65.25 s 4.02 K/s 959.87 KB 21.57 GB
vision 219 127.21 s 4.12 K/s 983.85 KB 43.49 GB
vision 220 - - - -

hashcaster

由于 hashcaster 仅实现了 PIOP 部分,因此下面的基准测试使用 Binius 承诺方案来完成它。

FRI 参数:

  • 字段大小:128

  • 速率:1/2

  • 查询数量:241

  • 可证明的可靠性:100 位

  • 128 位字段太小,无法达到 128 位可证明的可靠性,我们Roughly需要 150 位字段,但目前没有可用的选项。

这使得下面的 throughput 有点乐观。

  • keccak-f 中的 iota 步骤尚未实现,但它应该是可以忽略不计的,因为它可以延迟并合并到线性层中。

这使得下面的 throughput 有点乐观。

要重现,请进入代码仓库并运行:

for i in $(seq 10 20); do
    RAYON_NUM_THREADS=4 ./bench.sh hashcaster keccak $i
done;
python3 render_table.py
hash perm time throughput proof_size peak_mem
keccak 210 84.53 ms 18.17 K/s 522.81 KB 47.09 MB
keccak 211 126.91 ms 24.21 K/s 540.91 KB 46.80 MB
keccak 212 202.20 ms 30.39 K/s 622.99 KB 86.95 MB
keccak 213 338.92 ms 36.26 K/s 642.52 KB 168.63 MB
keccak 214 676.60 ms 36.32 K/s 664.24 KB 333.86 MB
keccak 215 1.35 s 36.44 K/s 689.87 KB 662.56 MB
keccak 216 2.87 s 34.22 K/s 779.48 KB 1.31 GB
keccak 217 6.15 s 31.99 K/s 806.55 KB 2.59 GB
keccak 218 12.87 s 30.54 K/s 835.80 KB 5.12 GB
keccak 219 25.81 s 30.47 K/s 868.95 KB 10.20 GB
keccak 220 52.34 s 30.05 K/s 966.10 KB 20.39 GB

expander

这使得下面的 proof_size 比预期的大得多。

  • GKR 中使用的 93 位字段太小,无法达到 128 位可证明的可靠性。

这使得下面的 throughput 有点乐观。

要重现,请进入代码仓库并运行:

cd expander/circuit/
go run gf2_keccak.go
go run m31_poseidon.go
cd ../../
for i in $(seq 10 20); do
    RAYON_NUM_THREADS=4 ./bench.sh expander keccak $i
    RAYON_NUM_THREADS=4 ./bench.sh expander poseidon $i
done
python3 render_table.py
hash perm time throughput proof_size peak_mem
keccak 210 481.14 ms 2.13 K/s 518.82 KB 3.93 GB
keccak 211 1.10 s 1.87 K/s 788.70 KB 7.86 GB
keccak 212 2.32 s 1.76 K/s 1.28 MB 15.70 GB
keccak 213 4.97 s 1.65 K/s 2.30 MB 31.34 GB
keccak 214 - - - -
keccak 215 - - - -
keccak 216 - - - -
keccak 217 - - - -
keccak 218 - - - -
keccak 219 - - - -
keccak 220 - - - -
poseidon 210 2.40 ms 426.93 K/s 222.76 KB 61.77 MB
poseidon 211 4.99 ms 410.02 K/s 357.09 KB 62.34 MB
poseidon 212 9.68 ms 423.27 K/s 619.41 KB 119.96 MB
poseidon 213 18.74 ms 437.14 K/s 1.11 MB 235.33 MB
poseidon 214 37.95 ms 431.75 K/s 2.12 MB 465.13 MB
poseidon 215 78.41 ms 417.88 K/s 4.12 MB 926.41 MB
poseidon 216 180.71 ms 362.65 K/s 8.13 MB 1.81 GB
poseidon 217 449.54 ms 291.57 K/s 16.14 MB 3.59 GB
poseidon 218 1.09 s 241.31 K/s 32.14 MB 7.18 GB
poseidon 219 2.33 s 225.40 K/s 64.15 MB 14.36 GB
poseidon 220 4.59 s 228.30 K/s 128.15 MB 28.74 GB

可能的进一步优化

  • hashcaster

    • 直接在 polyval 字段上使用 binius PCS
    • *
  1. 8k 签名 * 每个签名 250 个哈希,在乐观情况下为 4 秒。↩︎

  2. https://learnblockchain.cn/article/11633#starked-binary-hash-trees

https://ethresear.ch/t/proposal-delay-stateroot-reference-to-increase-throughput-and-reduce-latency/20490 ↩︎

  • 原文链接: hackmd.io/@han/bench-has...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
han___
han___
江湖只有他的大名,没有他的介绍。