使用 Halo2 开发电路
2022-08-0217:16
Sin7y
2022-08-02 17:16
Sin7y
2022-08-02 17:16
收藏文章
订阅专栏


Halo2 是 ECC 公司在 Halo 的基础上,使用 PLONK 对 Halo 进行升级改造,充分利用了 PLONK 的特性,比如 custom gate,PLONKup 等,使得用 Halo2 开发零知识证明电路更加高效和方便。关于 Halo2 的原理详情,请参见我们之前的文章 Halo2: 原理详解


Halo2 广泛使用在目前众多的 zkEVM 的方案中,我们在这篇文章中,以一个简单的例子为例,来介绍如何进行 Halo2 的电路开发。

图片来自 Deep dive on Halo2


1. Halo2 电路系统

在开始讲解例子之前,先说说 Halo2 的证明系统。Halo2 电路是由表(matrix/table)定义,一般使用 matrix 的行 (rows)  ,列 (columns) ,单元格 (cells) 来表示各种特殊不同的意义。


一个电路取决于如下的配置:

  有限域 F,单元格元素都是 F 域元素。

  和另一个 ZKP 电路系统 bellman 不同,Halo2 的电路系统用 advice 列代表 witness,instance 列代表 public input,fixed 列代表电路中固定的部分,Plonk 中引用出来的 lookup table 就是在 fixed 列中,selector 列是 fixed 列的辅助字段,用于确定在什么条件下激活门。

  一部分可用于相等性约束的列。

  一个多项式阶上限。

  一系列多项式约束,这些都是在有限域 F 上的多变量多项式,每行的结果都必须是 0。多项式约束中的变量可以是当前行的某一列的单元格,或者相对于当前行的某一列的某一单元格。

•  一系列在输入表达式(如上述所述的多变量多项式)和 table 列上定义的查找表,这个就是 PLONK 里的 plonkup。

  一系列用于指定两个单元格有相同值的相等性约束,熟悉 PLONK 的同学知道,这其实就是拷贝约束。


关于 Halo2 的电路系统,参见下图:


其中:

  a 代表的黄色的列,是 advice column

  i 代表的红色的列,是 instance column

  f 代表的蓝色的列,是 fixed column

  s 代表的紫色的列,是 selector column


对于不同的 proof,advice 和 instance column 不同,这个好理解,因为每次生成不同的 proof,witness 和 public input 基本上不同;而 fixed 和 selector column 都是和电路有关,跟输入无关。

图片来自 UltraPLONK arithmetisation (Halo2)


2. Halo2 提供的工具

•  Mock Prover

用于调试电路的工具,可以在单元测试中,将电路中的每个约束都测试一遍。对 Halo2 的电路开发非常重要,我们在电路开发过程中,需要经常使用 halo2::dev::MockProver 来调试代码。如果某个约束不满足,则 run 报错,否则正常返回。


  电路可视化工具

circuit_layout 可以用图表的形式展示电路的不同部分,如上面讲到的 advice / fixed / instance。


  电路消耗检测工具

cost-model 工具可以用来计算电路生成的 proof 大小,verify 花费的时间等。


3. Halo2 电路开发示例

如下,要开发一个电路, a, b 作为 private input,c 作为 public input,来证明得到:a2∗b2=c


a. 定义 instructions

因为电路可用于任意场景的证明描述,比如小的判断大小,大的一个程序执行的正确性。在这儿电路需要证明上述等式,就需要定义上述场景的电路,在这儿是乘法。以 a 的平方为例,其可以看成是 a 乘以 a。最外面则是 a 的平方乘以 b 的平方。并且我们电路处理的是两个数字的相乘,所以这个 instructions 输入和输出都是 Num。


该接口如下:

其中,Num 用于适配这个接口中处理的类型,load_private 用于载入 witness,load_constant 用于载入常量,mul 用于计算两数相乘,expose_public 用于设置 instance。


b. 定义 chip 实现

使用 Halo2 进行电路开发,大多数时候,不需要自己定义 instructions 和 chip,这些模块实现特别功能,属于基础设施,一般用 Halo2 提供的就足够了。但如果需要使用复杂的,而 Halo2 没有提供的,则需要自己实现,比如实现一个新兴的密码学算法。


如果要开发自定义 chip,则需要对 Halo2 的 chip trait 进行实现。

其中,config 函数返回自定义 chip 的配置,loaded 函数返回自定义 chip 的载入数据,此处不需要返回。


c. 配置 chip

一个 chip 的关键, 都在其 config 中。如下, 我们自定义的 chip 需要两个 advice 列, 一个 instance 列, 一个 selector 列, 以及一个 constant。

其中, 最关键的函数 configure,enable_equality 用于进行传入参数的相等性检查, 在 create_gate 函数中, 两个 adive(a,b)在同一行的不同列, 而相乘的结果 advice 和 a 在同一列下一行, 最后函数返回多项式约束:如果 s_mul 不为 0, 则激活检查乘法约束, 要结果是 0, 则 lhs * rhs - out 须为 0,则 lhs * rhs = out;如果 s_mul 为 0, 则没有激活检查乘法约束, 后面任何数值都可以, 我们不关心。


d. 实现 chip 接口

我们之前定义的 instructions 接口需要实现,我们定义 Number 的实现,是对有限域元素的封装。

其中,最关键的函数 mul 中,从 config 里取出两个 cell,检查和输入的 a,b 是否相等,再返回 a * b。需要注意的是,cell 的位置,除了 row 和 column,还可以通过相对位置 offset 来确定,一般 offset 就三种,0 代表当前位置,1 代表下一个位置,-1 代表上一个位置。


e. 构造电路

circuit trait 是开发电路的入口,我们需要定义自己的 circuit 结构,接入 witness 输入。

之前定义的接口,在这儿都用到了。configure 创建 advice / instance / constant 的存储 column。synthesize 是使用自定义 chip,来获取输入 witness 和 constant,最后计算结果,并返回 public input。


其实对一般电路开发来说,只需要实现 circuit trait 就能满足绝大多数的场景,一些常见的功能 chip,Halo2 都已经实现了。


f. 测试电路

我们在工具章节中说到的 MockProver 和 CircuitLayout 可以派上用场了。

使用 MockProver 可以检查约束,查看其 verify 函数可知,检查了 selector,gate,lookup,permutation 几种约束。而使用下述代码,则可以输出电路 layout,展示电路的不同部分,感兴趣的自己去尝试,看看这个简单例子的电路可视化 layout 是什么样子的。

这个例子中,circuit,chip,instructions trait 以及其实现之间的关系如下图所示:


4. 总结

我们在本文中, 介绍了 Halo2 电路开发的基本流程, 希望对读者有所帮助。Halo2 电路设计和 bellman 方案颇为不同, 有自己 row / column / cell / chip / region 等的新奇设计。Halo2 中的门, 更多的使用了 PLONK 的门设计, 和 R1CS 的门不同。在我们写这篇文章时, AZtec 团队又发布了 PLONK 的最新升级算法——Fflonk, 新算法提升 verify 效率, 节省 verify 时间, ECC 团队是否会将 Fflonk 结合到 Halo2 中, 我们拭目以待。而关于 Fflonk 的原理分析, 敬请期待我们后面的文章。


参考文献:

The Halo2 Book

(https://zcash.github.io/halo2/index.html )


Deep dive on Halo2

(https://github.com/daira/halographs/blob/master/deepdive.pdf )


区块链中的数学(八十一)-- Halo2 Circuit

(https://mp.weixin.qq.com/s/01H6X1iT0kATn8ev-0A7-A )


Halo2 repo

(https://github.com/zcash/halo2 )


关于我们

Sin7y 成立于 2021 年,由顶尖的区块链开发者组成。我们既是项目孵化器也是区块链技术研究团队,探索 EVM、Layer2、跨链、隐私计算、自主支付解决方案等最重要和最前沿的技术。

微信公众号:Sin7y

GitHub: Sin7y

Twitter: @Sin7y_Labs

Medium: Sin7y

Mirror: Sin7y

HackMD: Sin7y

HackerNoon: Sin7y

Email: contact@sin7y.org


【免责声明】市场有风险,投资需谨慎。本文不构成投资建议,用户应考虑本文中的任何意见、观点或结论是否符合其特定状况。据此投资,责任自负。

专栏文章
查看更多
数据请求中

推荐专栏

数据请求中

一起「遇见」未来

DOWNLOAD FORESIGHT NEWS APP

Download QR Code