jjzjj

PrivacIN Week4课程回顾 | ZK应用实践

PlatON技术团队 2024-07-02 原文

7月23日,隐私学院【PrivacyIN】第一期ZK训练营第四课——《ZK Hands-on》如期开讲。本期课堂由资深隐私开发工程师Kelvin Wong讲授,主要介绍Circom电路开发和ZK应用实践。

背景

随着零知识证明(ZKP)技术理论和工程应用的进步,ZK-Dapp已经成为区块链技术的应用热点,但ZKP技术的过高的技术门槛,使得设计和开发一个基于区块链系统的完整ZK-Dapp依然有较高的难度。因此PrivacyIN特别开设实践课程,从理论到实践,帮助开发者快速进入ZK应用开发。

主要课程内容

本期课堂Kelvin Wong主要围绕Circom电路设计和零知识证明应用开发进行展开。

ZK应用介绍

Kelvin老师首先介绍了当前ZK应用发展概况,带领学员了解当前主流的ZK应用和发展方向,将ZK应用主要分为:L2 ZK-Rollup应用、ZK-VM & ZK-EVM、ZK区块链系统、流行的ZK开发框架及编译器、其他热门电路及应用等,并进行分类的介绍和特点分析。

ZK-Rollup主要使用zkSNARKs技术将批量交易线下聚合,再将聚合交易及证明记录到智能合约,借助zkSANRKs其简洁、可验证、零知识性的特点,非常优雅地解决了以太坊等交易处理效率低和手续费昂贵的问题。目前ZK-Rollup涌现了非常多热点应用,包括降低转账手续费的STARKNET、zkSync、LOOPRING等,应用类ZigZog、Curve、zkNFT等。

ZK-VM是基于ZKP来保证程序执行状态转换的安全性和可验证性的可信通用虚拟机,一般ZK-VM都提供类似电路描述语言来实现计算应用。

EVM是运行在以太坊上,用来执行智能合约的虚拟机器,EVM是基于栈架构的,主要组件包括:Stack、Memory、PC、Storage等,EVM使用Gas进行指令计价和约束执行。

ZK-EVM是以ZKP方式执行智能合约或EVM指令的虚拟机,一般可以按照兼容性分为合约兼容ZK-EVM、EVM指令级别ZK-EVM、EVM标准规范级别ZK-EVM。ZK-EVM赋予了EVM执行正确性证明和可验证的特点,主要是用来构建兼容以太坊智能合约的ZK-Rollup方案或区块链系统。

基于ZK的区块链系统,最著名的是ZCash,它是第一个基于zkSNARK技术构建的提供匿名交易的电子货币实现。随着ZK理论和技术的发展,越来越多区块链系统基于ZK技术进行构建,以提供更好的匿名性和安全性。比如monero门罗币也将使用ZK技术构建,其将使用BulletProof协议来实现匿名交易;Mina使用递归零知识证明技术来构建简洁和轻量的区块链系统;Filecoin借助递归零知识证明技术来实现数据存储证明;Aleo则基于ZK构建通用、私密、高效公链系统。

在开放性区块链世界,ZK公链和应用的发展离不开开源社区,开源社区为ZK技术的发展提供了坚实的基础,以Arkworks、Matters Labs、Polygon等为代表社区或公司提供丰富的密码学开发基础库、ZK协议实现、编译器等。比较流行有开发库有:libnark、ZK-Garage/plonk、snarkjs、halo2等;经典的编译器及开发库套件,包括:Circom+Snarkjs、Aleo、ZoKrates、Cairo等。

以电路应用开发的视角来看,有很多热门的应用方向,包括:ZK-ML机器学习、ZK-DID、ZK-NFT、ZK-DAO外包计算等。按照电路用途分类,可以分为:通用性电路库(Circomlib)、专用性电路库(Semphore成员关系证明)、zkEVM-Circuits(EVM构建基础电路)等。

ZK应用开发工作流

一个完整的ZK应用开发是一个完整的软件工程用例构建,本次课堂不按照完整的软件工程工作流来展示应用开发过程,而是将电路逻辑来表示业务逻辑,围绕构建电路电路实现可验证计算的能力。zkSNARKs协议由于其简洁、非交互、高效性的特点,ZK主流应用基本上都使用zkSNARKs构建,课堂中将主要介绍基于zkSNARKs(主要为Plonk、Groth16协议)的应用开发。

zkSNARs应用开发的主要步骤,主要包括:

1.电路构建&编译

主要将计算业务使用电路语言描述,然后编译器翻译为R1CS或Plonkish等风格约束

2.Setup

公共参数、电路参数生成,包括创建prover/verifier各自的keys

3.创建证明proof

证明者(prover)使用自己私有输入witness和Setup得到keys,构建关于电路的证明。

4.验证电路proof

验证者(verifier)使用prover生成的proof,验证“prover使用witness作为输入并正确执行了电路”。

目前比较流行的集成开发套件有Aleo、ZoKrates、Circom+Snarkjs等,基本上采取类似的工作流程,本次课堂则选取“Circom & Snarkjs”进行详细的电路应用开发介绍。

Circom & Snarkjs工作流程

Circom & Snarkjs主要的优点在于有比较丰富的电路开发模板库,Snarkjs功能非常强大,支持Web和验证合约生成,对主流协议Groth16和Plonk支持比较完备。

Circom & Snarkjs的工作流程如下:

1.算数电路设计(Circom语言)

将计算业务转化为统一的算术表达式,然后将算术表达式用Circom语言描述实现。

2.编译电路

将Circom语言表示的电路翻译成低级别的R1CS形式电路(可以生产wasm以及调试信息),其实用circom编译器。

参考命令:circom circuit.circom --r1cs --wasm --sym

3.Snarkjs生成witness文件

参考命令:snarkjs calculatewitness --wasm circuit.wasm --input input.json --witness witness.json

4.可信设置 & 证明生成

可信设置使用MPC接力仪式生成,包括:universal-trusted-setup和电路相关的trusted-setup。

universal-trusted-setup主要为生成通用参数,适用于所有电路,主要命令参考:snarkjs powersoftau new/contribute (仪式参数初始化/接力)

电路相关的trusted-setup,生成适用于指定电路的ZKP计算参数,主要命令参考

snarkjs groth16/plonk setup (创建proving key和verification key)

snarkjs zkey powersoftau new/contribute (指定电路参数初始化/生成接力)

证明(proof)生成基于可信设置生成的通用参数、指定电路参数以及witness,生成指定电路的计算的证明proof,其主要命令参考:snarkjs plonk/groth16 prove

5.验证证明 & 验证智能合约生成

使用电路和witness生成的proof可以用来进行正确性验证(validate),也可以生成适用于以太坊的验证智能合约(generate verifier)。

参考命令:snarkjs validate/generateverifier (验证/生成验证合约)

Circom电路设计

Circom是一个表示R1CS电路约束的DSL语言,同时也是一个针对该语言的编译器,它是一个强类型检测和静态分析语言,目前主要支持算术电路。Circom通过定义显式电路约束实现电路逻辑,用户设计电路则类似于编写电路信号(线)的赋值和定义约束,然后Circom编译器将这些编写的电路翻译成R1CS约束(也包括WASM、C++等相关语言),提供给snarkjs使用,并借助snarkjs实现完整的ZKP计算流程。

Circom的语法比较简单,主要为支持有限域(finite-field)的电路运算,提供了template(有点类似C++)来定义子电路模块component,提供了function用来定义非电路函数代码块等。

一个完整的Circom电路包括:预编译指令、电路模板实现、main定义,如下定义了一个简单的乘法电路(注:参考官方文档):

预编译,主要指定编译器兼容版本;电路模板实现,主要实现电路逻辑,包括定义输入输出信号(signal),中间信号,构建约束等;main定义,定义入口main组件,其使用电路模板构建的实例。

Circom表示的算术电路定义包括:私有输入、共有输入、共有输出、电路门和线约束,这些元素工作在有限域Fp上,通过构建R1CS的格式的约束实现电路。

Circom的Signal

signal类似电路的wire(或变量),主要分为input(输入)signal、output(输出)signal、默认signal(中间变量),这些signal工作在有限域Fp上 (mod p)。

signal默认为private,可以在main{}中设置input signal为public,output signal总是为public,不能设置为private,默认定义的signal为private。

Circom的表达式

Circom支持常量表达式(只有常量操作或赋值)、线性表达式(只有常量和信号的乘法和加法)、二元表达式,其中常量表达式、线性表达式是二元表达式的特殊形式。二元表达式形式类似于”AB-C”其中A、B、C为线性表达式,比如合法的二元表达式:2x + 3y + 2) * (x+y) + 6x + y – 2。

Circom的Template

Template用来创建通用电路的模板,其他电路Template或main可以通过创建模板实例来使用电路,提供类似模块化的能力,即一个大电路可以由很多个小的电路实例集成构建得到。目前Circom社区提供了很多优质的电路模板,比如circomlib、Semphore等,可以基于这些电路模板构建复杂的电路。

Circom的Constraint

Circom使用constraint定义R1CS电路约束,constraint操作符一般配合二元表达式使用,主要的constraint操作符有:等于约束 (=),赋值等于 (>或<==),signal赋值(–>或<–)。

Cricom一般推荐使用赋值等于(>或<)进行赋值和约束同时定义,灵活的场景下则将两者分开,比如:除法操作转化为赋值和乘法约束, A/B=C则使用“C<-- A/B; C*B===A”表示。

Circom范例学习

课程中以实现简单多项式零知识证明为例,给定一个单变量多项式poly3(x)=1 + 2x + 3x^2 + 4x^3,演示如何进行设计Circom电路实现poly3多项式。

poly3多项式不是二元表达式(最高次数为3),将问题进行拆解,定义平方x2电路模板、x3电路模板分析多项式,然后进行线性组合即实现了poly3多项式。

实现步骤:

1.创建电路文件,添加预处理定义,指定编译器版本;

2.定义平方电路、立方电路模板;平方电路实现,其为一个乘法电路,输入信号相乘,只需添加复制等于约束。

立方电路实现,使用平方电路实例,再乘以输入信号即可,即x3=x*(x2)。

3.定义poly3电路实现模板,其通过创建平方电路和立方电路实例,线性组合实现;

4.定义main,即创建poly3电路实例。

将poly3多项式实现的电路保存为polynominal.circom文件,执行编译命令: circom polynominal.circom --inspect --wasm --c,将输出变量和约束信息;使用snarkjs命令行工具也能够查看编译输出的R1CS信息,如执行命令:snarkjs r1cs info polynominal.r1cs,将可以查看电路线数目、约束个数、私有输入变量、公共输入变量、公共输出变量等信息。

完整ZK- Dapp范例流程演示

给定一个多变量函数,包含3个变量x、y、z,其中x为0或1,定义如下:

如何实现一个完整的零知识证明可验证智能合约?

准备:

● 安装Circom和Snarkjs

● 下载或生成通用的ZK参数

可以从Polygen-Hermez下载已经完成的MPC仪式生成参数。

可以使用Snarkjs进行MPC接力仪式生产ZK参数,如命令:snarkjs contribute等。

开发实现:

1.实现电路

1.1. 将函数转化统一的算术表达式,if分支语句合并

为了简化计算,限制x为0或1,方便分支语句的合并。

1.2.电路拍平flatten,引入新的变量(信号signal),并使用R1CS表示

1.3. R1CS表示的电路转化为circom语言(直接翻译),保存为f.circom文件

2.编译电路编译输出r1cs二进制,snarkjs命令查看电路信息

3.Setup和创建证明&验证keys

4.创建witness和proof

5.生成验证合约verifier和调用数据

6.部署到remix并调用例如,可以将上一步骤生成的verifier合约部署到remix以太坊模拟环境,使用上一步骤的calldata作为输入,调用call接口:

如果输出true则表示计算proof验证成功。

可以看到基于Circom和Snarkjs能够实现一个完整的ZK应用,该开发套件灵活、可编程,提供多协议支持、丰富的基础电路、多语言的支持如C++、JavaScript、Solidity等,尤其Solidity验证合约的生成能力,则进一步增加了Web3-ZK应用开发的友好度。

自由讨论环节,Kelvin老师耐心地为学员解答了一系列电路设计技巧和开发相关的问题。

有关PrivacIN Week4课程回顾 | ZK应用实践的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby - 将差异补丁应用于字符串/文件 - 2

    对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl

  3. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  4. ruby - 无法运行 Rails 2.x 应用程序 - 2

    我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby​​:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r

  5. ruby-on-rails - Rails 应用程序中的 Rails : How are you using application_controller. rb 是新手吗? - 2

    刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr

  6. ruby-on-rails - 如何在我的 Rails 应用程序 View 中打印 ruby​​ 变量的内容? - 2

    我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby​​中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R

  7. ruby-on-rails - 如何在 Gem 中获取 Rails 应用程序的根目录 - 2

    是否可以在应用程序中包含的gem代码中知道应用程序的Rails文件系统根目录?这是gem来源的示例:moduleMyGemdefself.included(base)putsRails.root#returnnilendendActionController::Base.send:include,MyGem谢谢,抱歉我的英语不好 最佳答案 我发现解决类似问题的解决方案是使用railtie初始化程序包含我的模块。所以,在你的/lib/mygem/railtie.rbmoduleMyGemclassRailtie使用此代码,您的模块将在

  8. 报告回顾丨模型进化狂飙,DetectGPT能否识别最新模型生成结果? - 2

    导读语言模型给我们的生产生活带来了极大便利,但同时不少人也利用他们从事作弊工作。如何规避这些难辨真伪的文字所产生的负面影响也成为一大难题。在3月9日智源Live第33期活动「DetectGPT:判断文本是否为机器生成的工具」中,主讲人Eric为我们讲解了DetectGPT工作背后的思路——一种基于概率曲率检测的用于检测模型生成文本的工具,它可以帮助我们更好地分辨文章的来源和可信度,对保护信息真实、防止欺诈等方面具有重要意义。本次报告主要围绕其功能,实现和效果等展开。(文末点击“阅读原文”,查看活动回放。)Ericmitchell斯坦福大学计算机系四年级博士生,由ChelseaFinn和Chri

  9. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  10. 叮咚买菜基于 Apache Doris 统一 OLAP 引擎的应用实践 - 2

    导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵

随机推荐