当前位置: 首页 > news >正文

ICICLE-Snark:目前最快的 Groth16 实现

1. 引言

零知识证明(Zero-Knowledge Proofs)近年来迅速发展,其中 Groth16 已成为最广泛使用的证明系统之一,具有许多非常适合区块链应用的特点:

  • 验证继续3次 pairing 运算,使Groth16成为验证速度非常快的 ZK 证明。
  • Groth16 生成的证明是固定大小,仅3个群元素,这比其它证明系统在链上存储和交易成本上更节省。
  • 虽然Groth16 证明者(prover)端计算量很大,但通过硬件加速可以显著加快,使 Groth16 在高吞吐量应用中也可行。

Groth16 最大的权衡是每个电路(circuit)都需要可信设置(trusted setup)。尽管这是一个缺点,但Groth16的以上特点,使其成为区块链及其它以外用途的理想选择 —— 单个证明就能证明复杂计算的正确性而不暴露输入,任何人只需3次 pairing 就能验证。

2. Groth16 工作原理

生成一个 Groth16 证明需要在大的素域(prime field)和椭圆曲线群上执行大量算术运算。本文不深入 QAP(Quadratic Arithmetic Programs)和 R1CS(Rank-1 Constraint Systems)。

可以把Groth16证明者阶段分成两步:

  • 计算商多项式(quotient)
  • 和 生成证明。
    在这里插入图片描述

在这些步骤中,会包含:

  • 3 个 IFFT(反快速傅里叶变换),
  • 3 个 FFT(快速傅里叶变换),
  • 以及 5 个 MSM(多标量乘法,多标量乘法是指多个标量与群元素的结合操作)。
  • 除此之外,还有element-wise 按元素乘法和减法等操作。

MSM 和 NTT/FFT 这两大原语掌控了Groth16 证明过程的大部分时间。

  • MSM(Multi-Scalar Multiplication)与基于快速傅里叶变换的多项式求值(FFT/NTT)是最主要的瓶颈。MSM 大约占证明时间的 ~60%,FFT 大约占 ~30%。

Groth16 证明者需要两个文件:witness 文件 与 zkey 文件。

  • witness 文件包含给定输入根据电路产生的中间值,包括公开与私密输入。对每个输入都是独一无二的。
  • zkey 文件则包含电路、可信设置、证明与验证密钥等,是在可信设置阶段生成的,对每个电路唯一。

3. 现有 Groth16 实现的状况

目前已有很多 Groth16 的实现,常见的包括:

  • SnarkJS(https://github.com/iden3/snarkjs(JavaScript)) — 易用、访问性好,也提供了3种zkSNARKs证明系统,以及用于设置与验证的工具。
  • Rapidsnark(https://github.com/iden3/rapidsnark(C++ 和 汇编)) — 用 C++ 和 汇编 写成,比 SnarkJS 快约 4 到 10 倍。
  • Arkworks(http://github.com/arkworks-rs/groth16(Rust))
  • Lambdaworks(https://github.com/lambdaclass/lambdaworks/tree/main/crates/provers/groth16(Rust))
  • Gnark(https://github.com/Consensys/gnark(Go))

4. 用 ICICLE 突破 Groth16 速度障碍

ICICLE 是一个前沿的密码学库(ICICLE-snark(https://github.com/ingonyama-zk/icicle-snark(C++和Rust))),旨在加速诸如 ZKP(零知识证明)等高级算法与协议,在多种计算后端(包括 GPU、CPU、Metal 等)上运行。它支持 C++、Rust、Go 多种前端,使得在不同开发环境中集成更加容易。只用一个代码库,就能利用三种流行语言和多个硬件平台。

4.1 ICICLE 加速 Groth16

起初Ingonyama团队只计划把 MSM 和 NTT 部分集成进 ICICLE,但由于数据传输与类型转换的问题,性能并没有达到预期。最终的解决方案是从头构建一个 Groth16 的 prover,该 prover 使用 ICICLE 实现。参考代码库是 (iden3 团队的)SnarkJS(https://github.com/iden3/snarkjs(JavaScript))。这样可以允许所构造的 prover 使用现有的 zkey 文件。任何人都可以从 SnarkJS 或 Rapidsnark 切换到 ICICLE-snark(https://github.com/ingonyama-zk/icicle-snark(C++和Rust))。

  • ICICLE 已经对 第2节“Groth16 工作原理” 中提到的那些原语(MSM, FFT/NTT 等)做了高度优化。

另一个现有工具的问题在于,它们被设计为 命令行工具(CLI) 使用。
这意味着如果要多次为同一个电路生成证明,那么其实有许多数据是可以缓存并复用的,如:

  • 证明密钥(proving key)
  • 基(bases)
  • 和 NTT 域(NTT domain)。

为了利用这种缓存技巧,Ingonyama团将其Groth16 prover 开发成了一个 后台工作进程 和 Rust 库。

4.2 ICICLE 中的数据转换与数据传输

将代码迁移到 GPU 时,最大的问题之一是数据传输和数据类型转换。要能使用 ICICLE 并利用 CUDA,需要将数据转换为 ICICLE 的类型并移动到device端。通常为 CUDA kernel 准备数据的时间会比 kernel 本身执行时间还要长。

  • 类型转换(conversion)如果用 naïve 的方式(如多次调用 from 函数)会非常慢。在 Rust 中,如果可以保证安全,可以使用 transmute 直接改动已有内存的类型,这样几乎可以完全加速——transmute 调用只花费约 20–30 纳秒,而 naive 转换可能花费约 100 毫秒。
  • 数据传输速度受限于硬件。因此如果可能,应尽量避免将数据在host与device之间频繁移动。这是为什么团队选择从头构造 Groth16 prover 而不是仅替换部分 MSM/NTT 调用。

4.3 ICICLE 中的 MSM 与 NTT 优化

ICICLE 中的 MSM 与 NTT 优化有:

  • 替换5个 MSM 所用的实现为 ICICLE 的 MSM,在规模为 2222^{22}222 的情况下平均提升约 63倍。
  • 同样替换 3 个 IFFT + 3 个 FFT 为 ICICLE 的 FFT API,在规模为 2222^{22}222 的情况下平均提升约 320倍。

4.4 ICICLE 中的VecOps(向量运算)优化

ICICLE 中的VecOps(向量运算)优化:

  • 有很多地方需要对长向量做element-wise按元素的乘法与减法。这类操作在 GPU 上高度并行化。
    • 使用 ICICLE 的 VecOps API 而不是在 CPU 上处理这些长数组,平均提升约 200倍(在规模 2222^{22}222 时)。

在这里插入图片描述

4.5 ICICLE 中的缓存机制(Cache)优化

在许多应用场景中(如证明服务或 Layer-2 rollups),可能会对同一个电路和证明密钥(proving key)做多个证明。

  • ICICLE 利用这一点,把与 zkey 文件相关的计算保留在设备内存中,并缓存这些计算结果。称为 CacheManager。如果某次已经针对某个 zkey 文件算过某些值,下次用到就可以重用,不必重新计算。

在这里插入图片描述

5. 性能基准与实验结果

在以下两种设置上进行了基准测试:

  • 使用 4080 GPU + Intel i9-13900K CPU
  • 使用 4090 GPU + Ryzen 9 9950X CPU

用 MoPro(https://github.com/zkmopro/benchmark-app/tree/main/mopro-core/examples/circom) 基准里的电路来对比不同证明系统的性能。测试包括:

  • “复杂电路”:用于纯粹基准测试,以便对比约束数量多寡与性能差异。
  • Anon Aadhaar:一个零知识协议,允许 Aadhaar 身份所有者在不暴露其身份信息的情况下证明身份。
  • Aptos Keyless:Aptos Keyless 让用户无需密钥或助记词,而使用诸如 OIDC 凭证(Google, Apple 等)来创建账户。

如前所述,在生产环境中,一个项目更有可能重复证明相同的电路。
为了利用这一点,ICICLE使用了 缓存系统(Cache system)。
然而,由于所对比的其他工具都是 命令行工具(CLI),因此在一次证明完成后就会退出。
为了保持公平,同时提供了 启用缓存 和 不启用缓存 两种基准测试结果。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6. 如何集成 ICICLE

可将 ICICLE-snark 集成到自身项目的代码库里。根据使用的语言有两种方式:

  • 在 Rust 项目中使用
  • 在其他编程语言中使用

6.1 在 Rust 项目中使用 ICICLE

如果自身项目代码库是用 Rust 编写的,那么最佳实践是将ICICLE Groth16 prover作为 Rust Crate 使用。
只需要通过执行:

cargo add ICICLE-snark

将其添加到依赖中。

之后,就可以导入证明函数,并创建一个 CacheManager 实例,然后通过提供 witness 文件 和 zkey 文件 的路径来开始证明。

use icicle_snark::{groth16_prove, CacheManager};fn main() {let mut cache_manager = CacheManager::default();let witness = "witness.wtns";let zkey = "circuit_final.zkey";let proof = "proof.json";let public = "public.json";let device = "CUDA"; // 若需可以替换为 CPU 或 METALgroth16_prove(&witness,&zkey,&proof,&public,device,&mut cache_manager).unwrap();
}

6.2 在其他编程语言中使用 ICICLE

如果自身项目代码库是用其它语言写的,也可以使用 ICICLE prover。方式是用“worker 模式”(worker mode)运行 ICICLE-snark,然后从项目代码库与ICICLE worker 通信。ICICLE 的例子目录里有相关用了该模式的示例。

参考资料

[1] 2025年3月18日Ingonyama团队博客 ICICLE-Snark: The Fastest Groth16 Implementation in the World

http://www.dtcms.com/a/415845.html

相关文章:

  • 做网站建设的公司seo优化网站推广
  • 网站原型设计和版式设计湖南手机版建站系统开发
  • 黔南网站建设做网站多大上行速度
  • m 外贸网站阿里巴巴可以做公司网站吗
  • 太仓网站建设有限公司网站备案域名证书
  • 家用机做网站服务器企业网站多大空间
  • 网站做sem优化全国卫生机构建设管理系统网站
  • 优质网站建设价格天津网站建设哪里好
  • 建设银行网站号圣诞网站源码
  • 多合一网站建设网站漂浮
  • 金华高端网站设计wordpress图片主题模板下载
  • 昌吉网站建设电话菠萝蜜影视传媒有限公司
  • 谷歌建站哪家好企业免费建站网站
  • 10. C++ 类—构造函数
  • 网站建设与制作设计公司洛阳网站设计哪家专业
  • 湘潭网站建设 w磐石网络中国能源建设集团有限公司是央企
  • 网站建设中间件收费游戏网站建设的策划
  • 关于单片机的原理与应用!
  • 电子商务网站建设与电子支付hao123网址怎么删除
  • 织梦的网站地图更新电子商务网站建设论文资料
  • 外贸网站论文可以做免费广告的网站有哪些
  • C语言中的浮点数与整数的存储方式
  • 备案一个网站为什么需要域名企业域名注册费用
  • 北碚网站建设公司ssh精品课程网站开发
  • 高功耗显卡散热与兼容性全解析
  • 关系代数的核心操作:深入理解笛卡尔积与自然连接
  • 江门市住房城乡建设局网站wordpress设置上传大小
  • C# Socket高性能编程:从瓶颈原理到优化实践
  • 中国建设银行网站多少网站标题更改后要多久才能收录
  • 我们为什么选择做电子商务网站深圳营销建网站公司