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

【零知识证明】Groth16

一 相关介绍

1 Groth16

Groth16是一种用于零知识证明系统中的简洁非交互式知识论证(SNARK)协议,是一种表示计算的方式,在算术电路上操作,使用加法和乘法门。使用配对友好的椭圆曲线来实现高效的证明生成和验证。

Groth16的主要特点包括:

--1. 简洁性:生成的证明非常小,通常只有几百字节。

--2. 高效验证:验证过程计算量小,速度快。

--3. 非交互式:证明者只需发送一个证明,无需与验证者进行多轮交互。

--4. 通用性:可以用于各种计算问题的零知识证明。

--5. 安全性:基于一些标准的密码学假设。

2 Powers of Tau

Powers of Tau是零知识证明系统中的一个重要概念,特别是在zk-SNARKs(零知识简洁非交互式知识论证)中。它是一个多方计算(MPC)仪式,用于生成zk-SNARK系统的初始可信设置。旨在创建一个通用的加密"材料",可以用于后续的零知识证明。这个名字来源于希腊字母τ(tau),在这个过程中,计算τ的不同幂次(powers)。主要特点包括:

--1.安全性:只要参与仪式的至少一方是诚实的,整个系统就是安全的。

--2.可累积:多个参与者可以依次贡献自己的随机性。

--3.通用性:生成的结构可以用于多个不同的电路和证明。

二 Groth16设置

Phase 1 

1 启动一个新的Powers of Tau仪式

使用snarkjs工具创建Powers of Tau仪式的初始文件

snarkjs powersoftau new bn128 12 ceremoy_0000.ptau -v
  • snarkjs: 用于生成和验证零知识证明的JavaScript库。
  • powersoftau: snarkjs中的一个子命令,用于执行Powers of Tau仪式。
  • new: 表示我们要创建一个新的Powers of Tau仪式。
  • bn128: 指定使用的椭圆曲线类型。BN128(也称为BN254)是一种常用于零知识证明的配对友好曲线。
  • 12: 多项式的最大幂次,决定了电路的最大大小。2^12 = 4096,意味着这个设置最多可以支持4096个约束。
  • ceremoy_0000.ptau: 输出文件的名称,将数字附加到仪式词的末尾是传统做法,这样就可以跟踪哪些参与者为这个仪式文件贡献了随机性。。
  • -v: 表示"verbose"模式,会输出更详细的信息。

2 贡献阶段

多个参与者依次对ceremony文件进行贡献,其步骤为:

--1 下载当前的ceremony文件

--2 添加自己的随机性

--3 上传修改后的文件

snarkjs powersoftau contribute ceremoy_0000.ptau ceremoy_0001.ptau -v

输入随机数或者文字完成后,删除 ceremoy_0000.ptau ,继续提供随机性。

snarkjs powersoftau contribute ceremoy_0001.ptau ceremoy_0002.ptau -v

…… 

3 验证贡献

为确保该文件贡献随机性之前,仪式文件没有以任何方式被破坏,获取到仪式文件时可以验证完整性。

snarkjs powersoftau verify ceremoy_0001.ptau

打印出[INFO] snarkJS: Powers of Tau Ok!,则意味着仪式文件正确。

4 最终文件

文件随机性贡献完成后,生成最终文件:

snarkjs powersoftau prepare phase2 ceremoy_0002.ptau ceremoy_final.ptau -v

验证最后的生成文件:

snarkjs powersoftau verify ceremoy_final.ptau  

Phase 2

针对特定电路的设置过程

1 准备电路

首先,准备好想要证明的具体电路,MIMC5哈希电路为例。

pragma circom 2.0.0;// y = (x + k + c) ^ 5
// 输入信号x, k ,常量c
// base = x + k + c
// base2 = base * base
// base4 = base2 * base2
// base5 = base *base4
// 输出 ytemplate MIMC5(){signal input x;signal input k;signal output y;var nRounds = 10;signal lastOutput[nRounds + 1];signal base[nRounds];signal base2[nRounds];signal base4[nRounds];var c[nRounds] = [0,108628498564530119400845211344465696619893215909509348621394122327540108068425,97918840674612490766260259917122040983322146107578572117133348745818718934238,37080288021783359382631708635481166595643657187023815953993753410034258263757,73837458841121413400840196415753404416336899430626860296277530990112251638375,14175455430092778326653438909353750763438980656611040223157546655455727686661,85678297215287832106125129972569780982362546197552607669873965012182303538395,37616746480726794097353991145016865625300747892258420087145463257639176364046,96407012155233017139473625567546330731938257866046827176139377315631058571917,35426948207998228380140847549475429358133108689610886291038432834368020538887];lastOutput[0] <== x;for(var i = 0; i < nRounds; i++){base[i] <== lastOutput[i] + k + c[i];base2[i] <== base[i] * base[i];base4[i] <== base2[i] * base2[i];lastOutput[i+1] <== base[i] + base4[i]; }
}component main = MIMC5();

2 生成zkey文件

编译电路,生成circuit.r1cs文件并导入Phase 1(即之前运行的Powers of Tau命令)的输出

circom circuit.circom --r1cs

 启动Phase 2设置,使用编译后的电路和Phase 1输出的ptau文件生成一个初始的zkey文件。

snarkjs groth16 setup circuit.r1cs ceremoy_final.ptau setup_0000.zkey

zkey文件包含了特定于circuit.circom电路的证明和验证密钥

3 贡献随机性

与Phase 1类似,多方可以为zkey文件贡献随机性,以增加安全性。(可以重复多次)

snarkjs zkey contribute setup_0000.zkey setup_final.zkey

4 验证设置

完成贡献后,和Phase 1类似,需要验证最终的zkey文件以确保其正确性。

snarkjs zkey verify circuit.r1cs ceremoy_final.ptau setup_final.zkey

Phase 3

1 生成证明

先为电路添加输入x和k的值:

# 新建一个input.json文件
{"x" : "156345341","k" : "28965346"
}

再编译电路为WebAssembly形式,用于生成证明。

circom circuit.circom --wasm

使用编译后的电路、输入数据和最终的zkey文件来生成证明。

snarkjs groth16 fullprove input.json circuit_js/circuit.wasm setup_final.zkey proof.json public.json

2 导出Solidity验证器合约

创建一个Solidity合约,可以在以太坊上验证证明

snarkjs zkey export solidityverifier setup_final.zkey Verifier.sol

3 生成验证调用数据

生成可以用来调用验证器合约的数据。

snarkjs zkey export soliditycalldata public.json proof.json

 ["0x05fe0d95b181b07d383313d4b458ff17ac2ab3e7ae8433fa4e3c5869875d653c", "0x28e17a78038c2cd2685f9c536c2be7423dd6e23f7e2061b6e27c5071b3f58c36"],[["0x0e5e1552b27bbd45dbf8bbfbcaee1bdc71fa6a9c016654dff27a1beea7b2f57d", "0x03160fb7373a40993cbc74d121ccd75f4910c543c75c65934f93fdde1a16cb6a"],["0x221e506d697c36f9d1bf5b2f12dd1b83986a3f479360f31faf17e215f982681f", "0x227a10c7abfa2c835fe9a3c42e63dc2a67dadb8556942f42e913c943d3e96e75"]],["0x095e86f10679e5f4d96220678e98dbb8cbbd6ec613568ae372e955d088304dce", "0x03c00703bd4dc41af417765c411c84d0a61f9d76b82e22a3215f9889f5edab42"],["0x0000000000000000000000000000000000000000000000000000000000000000"]

 

4 在合约中验证:

最后,可以将生成的验证器合约部署到以太坊,并使用生成的调用数据来验证证明。

这个过程的美妙之处在于,一旦Phase 1和Phase 2完成,就可以重复使用setup_final.zkey文件来为相同电路的不同输入生成多个证明,而不需要重新进行可信设置。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 磐石云语音识别引擎
  • 笔记本电脑中怎么查看光驱
  • [VirtualBox+ubuntu24]设置linux学习环境
  • C++笔记14•二叉树之二叉搜索树•
  • while (r > b[i].r) del(a[r--]); while (r < b[i].r)
  • C/C++逆向:寻找mian函数(其他编译配置特征)
  • 信息安全数学基础(1)整除的概念
  • 值得收藏!为初学者设置Windows笔记本电脑的8个简单提示
  • CSS学习2
  • Python+VScode 两个不同文件夹里的py文件相互调用|python的模块调用|绝对导入
  • VUE2—defineProperty和VUE3—proxy 详解
  • 仿华为车机功能之--修改Launcher3,实现横向滑动桌面空白处切换壁纸
  • Go 语言版本管理——Goenv
  • 三、建造者模式
  • Kaggle克隆github项目+文件操作+Kaggle常见操作问题解决方案——一文搞定,以openpose姿态估计项目为例
  • ES6指北【2】—— 箭头函数
  • [ JavaScript ] 数据结构与算法 —— 链表
  • CSS3 变换
  • Druid 在有赞的实践
  • java小心机(3)| 浅析finalize()
  • js
  • LeetCode18.四数之和 JavaScript
  • vuex 笔记整理
  • 安卓应用性能调试和优化经验分享
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 融云开发漫谈:你是否了解Go语言并发编程的第一要义?
  • ionic异常记录
  • 如何在招聘中考核.NET架构师
  • ​LeetCode解法汇总2304. 网格中的最小路径代价
  • #java学习笔记(面向对象)----(未完结)
  • #Spring-boot高级
  • #stm32整理(一)flash读写
  • (22)C#传智:复习,多态虚方法抽象类接口,静态类,String与StringBuilder,集合泛型List与Dictionary,文件类,结构与类的区别
  • (day6) 319. 灯泡开关
  • (MonoGame从入门到放弃-1) MonoGame环境搭建
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (Redis使用系列) SpringBoot 中对应2.0.x版本的Redis配置 一
  • (Repost) Getting Genode with TrustZone on the i.MX
  • (附源码)springboot宠物管理系统 毕业设计 121654
  • (附源码)springboot社区居家养老互助服务管理平台 毕业设计 062027
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (贪心 + 双指针) LeetCode 455. 分发饼干
  • (一)SvelteKit教程:hello world
  • (转载)CentOS查看系统信息|CentOS查看命令
  • (转载)PyTorch代码规范最佳实践和样式指南
  • (自用)learnOpenGL学习总结-高级OpenGL-抗锯齿
  • .NET 4 并行(多核)“.NET研究”编程系列之二 从Task开始
  • .net SqlSugarHelper
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)...
  • .NET开发人员必知的八个网站
  • .NET是什么
  • .py文件应该怎样打开?
  • .secret勒索病毒数据恢复|金蝶、用友、管家婆、OA、速达、ERP等软件数据库恢复
  • ::before和::after 常见的用法
  • @property @synthesize @dynamic 及相关属性作用探究