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

Posted PlatON技术团队

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PrivacIN Week4课程回顾 | ZK应用实践相关的知识,希望对你有一定的参考价值。

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老师耐心地为学员解答了一系列电路设计技巧和开发相关的问题。

吴恩达深度学习专项课程3学习笔记/week1/Setting up ML Application

应用ML是一个高度迭代的过程

Idea->Code->Experment->...

去不断地调整超参数。

Train/Dev/Test sets

通常将数据集划分为Train/Dev/Test集。

  • Training set: 用于模型的训练

  • Hold-out cross validation set/Developmet set: 用于测试,调整模型超参数

  • Test set: 用于最终评估

以前的ML问题:数据规模在w级,通常70/30划分Train/Test集或者60/20/20比例划分。

现在的大数据时代:数据规模在百w级,趋势是Dev/Test集的比例减小,因为Dev集只需要大到足够判断不同的模型的优劣就可以了,Test集类似。如有100w的数据集,98/1/1的比例是一种较合理的划分。

经验:

  1. 确保Dev/Test集来自同一个分布,这样有助于算法进步的效率。
  2. 训练集则可以采取网页爬取等方式以获得更大量的数据。
  3. 没有测试集也是可以的,只用Dev集来调整。

Bias/Variance

可以通过Train set error和Dev set error来判断模型是否存在high bias/variance的问题。

比如,假设假设bayes error约为0%,即人类可以几乎完全准确识别,并且Train和Dev集来自同一个分布。

Train set error Dev set error 结果
1% 11% high variance
15% 16 high bias
15% 30% high variance & high bias
0.5% 1% low variance & low bias

Some Basic recipe(基本准则)

STEP1 High bias? --> 更大的网络;训练更长时间;(其他NN架构)

STEP2 High variance? --> 更多的数据;正则化;(其他NN架构)

在深度学习时代,不需要再过多考虑bias 和 variance的权衡,如果合理的正则化,采用更大的网络在降低bias的同时几乎不会增加variance,如果有足够大的网络,获得更多的数据在降低variance时几乎不会增加Bias,这也是深度学习在监督学习领域十分有效地原因之一。

以上是关于PrivacIN Week4课程回顾 | ZK应用实践的主要内容,如果未能解决你的问题,请参考以下文章

Coursera TensorFlow 基础课程-week4

Coursera TensorFlow 基础课程-week4

分布式技术之dubbo

分布式技术之dubbo

week4_自学python_decorator

斯坦福-随机图模型-week4.2_