Circom模板参数、变量、循环、If语句、断言

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

本文介绍了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 条评论

请先 登录 后评论
RareSkills
RareSkills
https://www.rareskills.io/