零知识证明之书

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模板参数、变量、循环、If语句、断言

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

本文介绍了Circom中定义Rank 1约束系统(R1CS)的基本语法,包括模板参数的使用、循环和变量的声明与应用、以及如何在满足特定条件时生成约束。此外,还强调了在Circom中约束必须是静态的,不能依赖于信号动态改变,但变量可以作为常量参与R1CS运算,并解释了if语句在Circom中的使用限制,着重介绍了 variables 的使用方法,以及 signals 的使用限制。

本章介绍基本的语法,你会在大多数 Circom 程序中见到这些语法。使用 Circom,我们可以使用代码定义 Rank 1 Constraint System (R1CS),而不是显式地定义每个约束。我们将在本章中探讨这些工具。

模板参数

之前,我们看了一个电路 (IsBinary),它验证提供的输入是否确实是二进制的。该电路被硬编码为仅接受 2 个输入。

template IsBinary() {

  signal input in[2];

  in[0] * (in[0] - 1) === 0;
  in[1] * (in[1] - 1) === 0;
}

component main = IsBinary();

虽然上面的代码适用于两个输入,但修改它以支持大量的 n 输入将需要手动添加约束,这是一种糟糕的开发者体验。

因此,Circom 允许我们使用以下模式约束任意数量的信号,以自动生成约束:

template IsBinary(n) {

  // n 个输入的数组
  signal input in[n];

  // n 个循环:n 个约束
  for (var i = 0; i < n; i++) {
    in[i] * (in[i] - 1) === 0;
  }
}

// 使用 4 个输入和 4 个约束实例化
component main = IsBinary(4);

请注意,模板声明已更改为在括号中包含 n

  • 这里的 n 被称为模板参数
  • n 在电路中用于指定数组 in 的大小
  • 在实例化模板时,我们必须指定 n 的值

Circom 中的电路和约束必须具有固定的、已知的结构

虽然约束可以通过编程方式生成,但约束的存在和配置不能有条件地依赖于信号。

虽然模板可以使用参数,但电路必须是静态的且定义明确。不支持“动态长度”的电路或约束 —— 一切都必须从一开始就固定且定义明确。

想象一下,如果一个 R1CS 约束系统的结构可以根据输入信号值而改变,会发生什么。证明者和验证者都无法操作,因为约束的数量没有确定。

n 的值必须在编译时设置。

For 循环和变量:forvar

现在我们解释上面介绍的 for 循环。

template IsBinary(n) {

  // n 个输入的数组
  signal input in[n];

  // n 个循环:n 个约束
  for (var i = 0; i < n; i++) {
    in[i] * (in[i] - 1) === 0;
  }
}

// 使用 4 个输入和 4 个约束实例化
component main = IsBinary(4);
  • 输入和循环迭代都由 n 定义
  • 对于每个输入,都定义一个约束,目的是验证输入是 0 还是 1

我们在电路中引入了两个新的关键字:forvar

  • for 的工作方式与你习惯的方式相同。
  • var 关键字声明一个 变量;在本例中,是 i,如循环定义中所示。
  • 等号 = 将右边的值赋给左边的变量。

在这里,变量 i 用于以编程方式引用输入数组中的不同信号,同时为它们创建约束。能够以编程方式生成约束非常有用,因为当涉及到数百或数千个约束时,手动执行此操作将非常容易出错。

变量

变量保存非信号数据并且是可变的。这是一个在循环之外声明变量的示例:

template VariableExample(n) {
  var acc = 2;
  signal s;
}
  • 默认情况下,变量是 R1CS 约束系统的一部分。 *...

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

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

0 条评论

请先 登录 后评论