零知识证明之书

2025年02月27日更新 28 人订阅
原价: ¥ 144 限时优惠
专栏简介 P vs NP 及其在零知识证明中的应用 ZK的算术电路 用于零知识证明的有限域与模运算 为程序员准备的基础集合论 抽象代数 程序员的基本群论 同态映射 椭圆曲线点加法 有限域上的椭圆曲线 Python、Solidity 和 EVM 中的双线性配对(Bilinear Pairings) 将代数电路转换为R1CS(一阶约束系统) 从R1CS构建零知识证明 使用Python实现拉格朗日插值 Schwartz-Zippel 引理及其在零知识证明中的应用 二次算术程序 在Python中将R1CS转换为有限域上的二次算术程序(QAP) 可信设置 在可信设置中评估和二次算术程序 Groth16 详解 Circom 零知识电路简介 Circom 之 Hello World Circom模板参数、变量、循环、If语句、断言 二次约束 - Circom Circom中的符号变量 Circom 中间信号与子组件 先指示再约束 - 在 Circom 中复杂约束条件的方法 先计算,后约束 - ZK 电路设计模式 Circom循环中的组件 使用虚假证明攻击欠约束的Circom电路 Circomlib中的AliasCheck和Num2Bits strict Circom 中的条件语句 Quin Selector(选择器) ZK 中有状态计算简介 在Circom中交换数组中的两个条目 选择排序的零知识证明 在 ZK 中建模栈数据结构 - 如何在 Circom 中创建一个堆栈 ZKVM 的工作原理 ZK中的32位仿真 Circom 中的 MD5 哈希 零知识证明友好的哈希函数 排列论证 - The Permutation Argument Tornado Cash 的工作原理(开发者逐行解析) BulletProofs 详解 什么是Pedersen承诺及其工作原理 多项式承诺通过 Pedersen 承诺实现 零知识乘法 内积的零知识证明 向量承诺的简洁证明 对数大小的承诺证明 Bulletproofs零知识证明:内积的零知识与简洁证明 内积代数 通过随机线性组合减少等式检查(约束)的数量 范围证明

Circom 零知识电路简介

  • RareSkills
  • 发布于 2025-04-16 10:16
  • 阅读 1520

本文介绍了 Circom 编程语言,它用于创建 Rank 1 Constraint Systems (R1CS) 并填充 R1CS 的 witness 向量,主要是为了简化约束系统的设计和自动化 witness 的生成。文章还解释了 Circom 存在的意义,以及它如何帮助开发者更轻松地进行零知识证明相关的开发,最后说明了学习 Circom 的理由,并概述了资源结构,包括语法和约束设计。

Circom 是一种用于创建 Rank 1 Constraint Systems (R1CS) 并填充 R1CS 的 witness 向量的编程语言。

R1CS 格式之所以引人关注,是因为该格式对于构建 SNARKs 非常有用,尤其是 Groth16。通过 SNARKs,我们可以实现可验证计算,从而能够证明计算的正确性。在验证时,感兴趣方花费较少的计算资源来确认正确性,而不是自己执行计算。也可以生成证明而不泄露底层数据,在这种情况下,我们将其称为 zkSNARKs。

我们 ZK 书的第一部分侧重于证明给定 R1CS 的 witness 的有效性。本资源侧重于如何以编程方式生成 R1CS,以及如何设计它们来模拟真实的算法,例如虚拟机或密码学哈希函数。

预备知识

我们希望读者已经熟悉我们 ZK 书中的以下章节:

我们将假设读者了解什么是 R1CS 以及它代表什么。这在上面的四个章节中已得到充分解释。

没有必要完全理解 ZK 背后的数学原理才能使用 Circom,但是必须完全掌握一些原则,否则 Circom 将毫无意义。

尽管如此,如果读者想在 ZK 领域有所发展,那么学习 ZK 的基础知识必不可少。为此,我们强烈建议通读 ZK 书籍 的前两部分,并从头开始构建 Groth16 证明系统,以加强学习。

但是,如果读者的目标是快速了解 ZK 应用程序,那么我们建议阅读上面列出的四个章节,然后使用本资源。

为什么存在 Circom

创建 Circom 是为了解决为 SNARKs 开发约束系统中的两个主要问题。

  1. 手动设计约束系统既繁琐又容易出错,尤其是在处理大规模或重复性约束时。
  2. 填充 witness 同样具有挑战性,并且需要手动计算中间值,而这些中间值可以通过编程方式推导出来。

因此,Circom 1) 简化了约束设计,并 2) 自动化了 witness 填充。

1. 设计约束系统很繁琐

手动设计一组(正确的)约束,然后将其转换为 R1CS 的任务既繁琐又容易出错。创建 Circom 是为了通过以编程方式生成约束来使此任务更轻松且不那么繁琐。

例如,要说值 x 只能具有值 $\set{1,2,3}$,我们可以使用约束来表示:

$$ 0 === (x – 1) (x – 2) (x – 3) $$

但是,R1CS 每个约束只能有一个非恒定的乘法,因此我们必须将上述约束分解为两个约束:

$$ \begin{align} s &=== (x – 1)(x – 2) &&= x x – 3 * x + 2 \\

0 &=== s(x – 3) &&= x s – 3 s \end{align*} $$

对于小型系统,这种手动转换是可管理的。但是,如果我们需要为 100 甚至 1000 个变量创建此约束,则手动执行此操作将非常烦人。如果我们有数千个非常相似的约束,最好为约束创建一个“模板”并在 for 循环中生成约束。Circom 允许我们以编程方式创建这些约束。

例如,假设我们要约束 1,000 个变量具有值 $\set{0,1}$。Circom 可以通过循环生成这些值,如下所示:

template Constrain1000Example() {
  signal input in[1000];

  for (var i = 0; i < 1000; i++) {
    0 === in[i] * (in[i] - 1);
  }
}

component main = Constrain1000Example();

我们将在后面的章节中进一步解释语法,但核心思想是我们定义了一个约束 0 === in[i] * (in[i] - 1) 并重复了 1000 次。

2. 填充 witness 很繁琐

ZK 上下文中的 witness 是对变量的赋值,该赋值满足算术电路中的所有约束。

正如我们在 算术电路 的文章中所看到的,证明一个数字小于另一个数字需要将两个数字都转换为二进制,因为“大于”在有限域中没有意义,因为数字会回绕。

以二进制形式表示数字 $x$,假设它适合四个位,则需要 $x$ 满足以下约束:

$$ \begin{align} x&===b_0+2b_1+4b_2+8b_3\\ 0&===b_0(b_0 – 1)\\ 0&===b_1(b_1 – 1)\\ 0&===b_2(b_2 – 1)\\ 0&===b_3(b_3 – 1) \end{align} $$

在这里,$b_0$ 是最低有效位,$b_3$ 是最高有效位。证明者必须提供 $b_0, b_1, b_2, b_3$,它们是 $x$ 的二进制位,以及 $x$ 本身。

在这种情况下,证明 $x$ 是一个四位数字变得更加繁琐,因为除了 $x$ 之外,我们还必须提供 $x$ 的二进制值,即使它们可以确定性且直接地导出。Circom 自动化了此过程,并允许我们编写代码以根据其他变量填充 witness 中的变量。例如,要填充二进制变量,我们可以编写以下 Circom 代码(...

剩余50%的内容订阅专栏后可查看

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论