零知识证明之书

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:13
  • 阅读 902

本文介绍了在 Circom 中使用 indicator signals 和 Circomlib comparator library 来实现复杂约束条件的方法。

如果我们想表达 “x 可以等于 5 或 6”,我们可以简单地使用以下约束:

(x - 6) * (x - 5) === 0

然而,假设我们想表达 “x 小于 5 或者 x 大于 17”。在这种情况下,我们不能直接组合这两个条件,因为如果 x 小于 5,它会违反 x 大于 17 的约束,反之亦然。

解决方案是创建不同条件的 指示器 信号(例如,x 小于 5,或者大于 17),然后对指示器施加约束。

Circomlib 比较器库

Circomlib 比较器库 包含一个 LessThan 组件,它返回 0 或 1 来指示 in[0] 是否小于 in[1]。这个组件的工作原理在 算术电路 章节中有所描述。但作为总结,假设 xy 最大为 3 位。如果我们计算 z = 2^3 + (x - y),那么如果 x 小于 yz 将小于 2^3,反之亦然 (2^3 = 8)。由于 z 是一个 4 位数字,我们可以通过仅查看最高有效位来有效地检查 z 是否小于 2^3。2^3 在二进制中是 1000₂。每个大于或等于 2^3 的 4 位数字的最高有效位等于 1,而每个小于 2^3 的 4 位数字的最高有效位等于 0。

数字 二进制表示 是否大于或等于 2^3
15 1111
14 1110
13 1101
10 1010
9 1001
8 (2^3) 1000
7 0111
6 0110
2 0010
1 0001
0 0000

对于一般的 n 位数字,我们可以通过检查最高有效位是否设置来检查 x 是否大于或等于 2^n。因此,我们可以推广,如果 xyn-1 位数字,那么我们可以通过检查 2^(n-1) + (x - y) 的最高有效位是否被设置来检测 x < y

这是一个使用 LessThan 模板的最小示例:

include "circomlib/comparators.circom";

template Example () {
  signal input a;
  signal input b;
  signal output out;

  // 252 将在下一节中解释
  out <== LessThan(252)([a, b]);
}

component main = Example();

/* INPUT = {
  "a": "9",
  "b": "10"
} */

252 的来源

有限域(Circom 使用的)中的数字不能相互比较为“小于”或“大于”,因为不等式的典型代数定律不成立。

例如,如果 $x > y$,那么如果 $c$ 为正数,则 $x+c>y+c$ 应该始终成立。然而,这在有限域中是不成立的。我们可以选择 $c$,使其为 $x$ 的加法逆元,即 $x + c=0\mod p$。然后我们最终会得到一个无意义的陈述,即 0 大于一个非零数。例如,如果 $p = 7$ 且 $x=2$ 且 $y=1$,我们有 $x>y$。但是,如果我们给 $x$ 和 $y$ 都加上 $6$,那么我们就有了 \$0>1$。

252 指定了 LessThan 组件中的位数,以限制 xy 的大小,以便可以进行有意义的比较(上面的部分使用了 4 位作为示例)。

Circom 可以在有限域中保存最大 253 位的数字。出于 别名检查 章节中讨论的安全原因,我们不应该将域元素转换为可以编码大于该域的数字的二进制表示。因此,Circom 不允许使用超过 252 位的比较模板 (源代码)。

然而,回想一下,对于 LessThan(n),我们需要计算 z = 2^n + (x - y),并且 2^n 需要比 xy 大一位。因...

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

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

0 条评论

请先 登录 后评论