Sin7Y 团队全面解读——如何使用 Halo2 开发电路

本文由ZKSwap和Sin7Y团队联合撰写,详细介绍了如何使用Halo2进行电路开发。Halo2是ECC公司在Halo基础上的改进,用于更高效地开发零知识证明电路。文章涵盖了Halo2电路系统、提供的工具,以及一个简单的电路开发示例,包括定义instructions、实现chip、配置和构造电路。同时,提供了Mock Prover和circuit_layout等调试工具。
摘要由CSDN通过智能技术生成

作者:ZKSwap、Sin7Y 团队联合撰写  文章来源:zks.org

使用 Halo2 开发电路

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

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

1.png

图片来自 Deep dive on Halo2

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 都是和电路有关,跟输入无关。

2.png

图片来自 Ultra Plonk arithmetisation (Halo2)

Halo2 提供的工具

  • `Mock Prover`

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

  • 电路可视化工具

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

  • 电路消耗检测工具

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

Halo2 电路开发示例

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

$$
a^2 * b^2 = c
$$

1. 定义 instructions

因为电路可用于任意场景的证明描述,比如小的判断大小,大的一个程序执行的正确性。在这儿电路需要证明上述等式,就需要定义上述场景的电路,在这儿是乘法。以 a 的平方为例,其可以看成是 a 乘以 a。最外面则是 a 的平方乘以 b 的平方。

并且我们电路处理的是两个数字的相乘,所以这个 instructions 输入和输出都是 Num。该接口如下:

trait NumericInstructions<F: FieldExt>: Chip<F> {
    /// Variable representing a number.
    type Num;

    /// Loads a number into the circuit as a private input.
    fn load_private(&self, layouter: impl Layouter<F>, a: Option<F>) -> Result<Self::Num, Error>;

    /// Loads a number into the circuit as a fixed constant.
    fn load_constant(&self, layouter: impl Layouter<F>, constant: F) -> Result<Self::Num, Error>;

  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值