Source: https://rareskills.io/zh-cn/post/rank-1-constraint-system
本文解释了如何将一组算术约束转换为秩一约束系统 (Rank One Constraint System, R1CS)。
本文的重点在于实现:与其他资料相比,我们涵盖了在进行此类转换时更多的边界情况,讨论了优化方法,并解释了 Circom 库是如何实现它的。
秩一约束系统 (R1CS) 是一种算术电路,其要求是每个等式约束只能包含一次乘法(对加法的数量没有限制)。
这使得算术电路的表示能够兼容双线性配对 (bilinear pairings) 的使用。配对的输出 $G_1 \bullet G_2 \rightarrow G_T$ 无法再次进行配对,因为 $G_T$ 中的元素不能用作另一个配对输入的一部分。因此,我们每个约束只允许一次乘法。
<aside> 💡 💡 为什么每个约束只准一次乘法?打个比方:双线性配对像一台『只能照一次的相机』——你把两个东西 $G_1$、$G_2$ 拍成一张合影 $G_T$,但这张合影本身没法再被拿去拍下一张。所以每个约束里乘法只能用一次,硬塞两次乘法这台相机就罢工了。加法不消耗这次机会,可以随便加。
</aside>
在算术电路中,见证 (witness) 是对满足方程约束的所有信号的赋值。
在秩一约束系统中,见证向量是一个 $1 \times n$ 的向量,其中包含了所有输入变量、输出变量以及中间变量的值。它表明你已经从头到尾执行了电路,并且知道输入、输出和所有的中间值。
按照惯例,第一个元素通常始终为 1,以使某些计算更加简便,我们稍后将对此进行演示。
例如,如果我们有约束条件
$z = x^2y$
声称我们知道它的解,那么这必定意味着我们知道 $x$ 、 $y$ 和 $z$ 。由于秩一约束系统要求每个约束只能进行一次乘法,上述多项式约束必须写成:
$\begin{aligned} v_{1} = xx \\ z = v_{1}y \end{aligned}$
<aside> 💡 💡 这里在做的事:原式 $z=x^2y$ 里其实藏了两次乘法($x\cdot x$ 一次,再乘 $y$ 一次)。规则只允许一行一次乘法,于是我们把它拆成两步走:先算 $v_1=x\cdot x$,再算 $z=v_1\cdot y$。$v_1$ 就是个『草稿纸上的中间结果』,专门用来接住第一次乘法的答案。
</aside>
见证意味着我们不仅知道 $x$ 、 y 和 z ,我们还必须知道这种展开形式中的每一个中间变量。具体来说,我们的见证是一个向量: