diff --git "a/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/Q+W.png" "b/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/Q+W.png" new file mode 100644 index 0000000..b421c54 Binary files /dev/null and "b/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/Q+W.png" differ diff --git "a/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/W.png" "b/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/W.png" new file mode 100644 index 0000000..2d81d6d Binary files /dev/null and "b/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/W.png" differ diff --git "a/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/position change.png" "b/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/position change.png" new file mode 100644 index 0000000..26f810c Binary files /dev/null and "b/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/position change.png" differ diff --git "a/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/\344\275\215\347\275\256\347\237\251\351\230\265T.png" "b/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/\344\275\215\347\275\256\347\237\251\351\230\265T.png" new file mode 100644 index 0000000..f610375 Binary files /dev/null and "b/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/\344\275\215\347\275\256\347\237\251\351\230\265T.png" differ diff --git "a/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/\346\201\266\346\204\217prover \347\232\204\346\203\205\345\206\265.png" "b/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/\346\201\266\346\204\217prover \347\232\204\346\203\205\345\206\265.png" new file mode 100644 index 0000000..f8cbe1d Binary files /dev/null and "b/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/\346\201\266\346\204\217prover \347\232\204\346\203\205\345\206\265.png" differ diff --git "a/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/\346\226\260\347\232\204\347\272\246\346\235\237\345\205\263\347\263\273.png" "b/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/\346\226\260\347\232\204\347\272\246\346\235\237\345\205\263\347\263\273.png" new file mode 100644 index 0000000..56688a7 Binary files /dev/null and "b/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/\346\226\260\347\232\204\347\272\246\346\235\237\345\205\263\347\263\273.png" differ diff --git "a/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/\346\241\210\344\276\213\347\224\265\350\267\257.png" "b/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/\346\241\210\344\276\213\347\224\265\350\267\257.png" new file mode 100644 index 0000000..bef3acd Binary files /dev/null and "b/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/\346\241\210\344\276\213\347\224\265\350\267\257.png" differ diff --git "a/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/\347\224\265\350\267\257\346\257\224\350\276\203.png" "b/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/\347\224\265\350\267\257\346\257\224\350\276\203.png" new file mode 100644 index 0000000..7f8222f Binary files /dev/null and "b/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/\347\224\265\350\267\257\346\257\224\350\276\203.png" differ diff --git "a/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/\347\237\251\351\230\265 Q.png" "b/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/\347\237\251\351\230\265 Q.png" new file mode 100644 index 0000000..eadb7d1 Binary files /dev/null and "b/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/\347\237\251\351\230\265 Q.png" differ diff --git "a/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/\347\237\251\351\230\265.png" "b/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/\347\237\251\351\230\265.png" new file mode 100644 index 0000000..e55fabf Binary files /dev/null and "b/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/img/\347\237\251\351\230\265.png" differ diff --git "a/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226.md" "b/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226.md" new file mode 100644 index 0000000..1db0ddc --- /dev/null +++ "b/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226/\344\270\200\357\274\232Plonkish \347\256\227\346\234\257\345\214\226.md" @@ -0,0 +1,500 @@ +# 前言 + +算术化是指把计算转换成数学对象,然后进行零知识证明。 + +Plonkish 算术化是 Plonk 证明系统特有的算术化方法,在 Plonkish 出现之前,主流的电路表达形式为 R1CS,被 Pinocchio,Groth16,Bulletproofs 等广泛采用。2019 年 Plonk 方案提出了一种看似复古的电路编码方式,但由于 Plonk 方案将多项式的编码应用到了极致,它不再局限于算术电路中的「加法门」和「乘法门」,而是可以支持更灵活的「自定义门」与「查表门」。 + +本文里,我们将直切主题,先了解 Plonkish 算术化方案,明白一个电路里的组成部分和其背后的运算逻辑,最后可以对比 Plonkish 和 R1CS 算术化的区别,感受二者的差别,更加深入理解 Plonkish 编码存在的意义。 + +# Plonkish算术门 +首先,我们先了解电路的基本构成,看看静态下的空白电路有哪些组成部分,我们可以看下图的案例电路: + +案例电路 + +上图由几部分构成:算术门、左右输入引脚、输出引脚和引线。 + +我们把其中三个算术门编号为 `#1`、`#2`、`#3`,其中: + +`#1` 是乘法门,这个门的左输入引脚是 $x_5$,右输入引脚 $x_6$,输出引脚是 $out$; + +`#2` 是加法门,这个门的左输入引脚是 $x_1$,右输入引脚是 $x_2$,输出引脚是 $x_5$; + +`#3` 还是乘法门,这个门的左输入引脚是 $x_3$,右输入引脚是 $x_4$,输出引脚是 $x_6$ + +> 请注意: $x_5$ 和 $x_6$ 既做了 `#1` 的输入引脚,也分别做了 `#2` 和 `#3` 的输出引脚。 + +除了我们能看到的这些组成部分以外,隐形的是其中对应的数学关系,也就是这个电路要成立必须要满足的约束关系: + +$$ +\begin{array}{c} +x_1+ x_2 = x_5\\ +x_3\cdot x_4=x_6\\ +x_5\cdot x_6=out +\end{array} +$$ + +有了电路具体的约束关系后,我们可以将其中的关系转换成「矩阵」,这个矩阵可以用表格的形式来呈现,从而方便后续的计算。 + +**具体该怎么做呢?** + +首先,我们可以定义一个矩阵 $W\in\mathbb{F}^{n\times 3}$ (不必管 $\mathbb{F}$ 到底是什么,只需要知道表格内元素的取值是在一定的范围内就可以; $n$ 为算术门的数量,对应为行;3 表示多项式变量名的数量,对应为列)来表示约束,约束关系等式就可以变成: + +$$ +\begin{array}{c|c|c|c|} +\texttt{i} & w_a & w_b & w_c \\ +\hline +\texttt{1} & x_5 & x_6 & out \\ +\texttt{2} & x_1 & x_2 & x_5 \\ +\texttt{3} & x_3 & x_4 & x_6 \\ +\end{array} +$$ + +> 注:其中 $i$ 是表示电路中每个门的索引,从 1 开始逐行递增,它用来标识电路的每个门的位置。 + +在 Plonkish 中,如果 Prover 要向 Verifier 证明 Ta 知道某个秘密,那么需要用到一个固定的约束等式,验证电路的各个约束条件是否满足。只要这个固定的约束等式可以成立,就可以在不泄露秘密信息的情况下,验证电路的正确性。固定的约束等式如下: + +$$ +q_L \circ w_a + q_R \circ w_b + q_M\circ(w_a\cdot w_b) + q_C - q_O\circ w_c \overset{?}{=} 0 +$$ + +> 注:一般我们都会将所有的约束都移到等式的一侧。例如,在算术电路中,我们经常需要验证以下形式的方程: +> `左输入+右输入+乘法项+常数=输出`; +> 为了表示这一点,我们可以将等式全部移到方程左边,并等于零: +> `左输入+右输入+乘法项+常数−输出=0`; +> 这样有助于简化证明系统的构建和验证过程。例如在后续构建约束矩阵 $Q$ 的时候会出现选择器向量的系数选择问题,办法其实很简单,只需要对应固定等式的算术关系即可,不需要进行符号的变换,可参考下图矩阵 $Q\in\mathbb{F}^{n\times5}$。 + + + + +我们把上图的 $Q$ 矩阵和固定的约束等式 + +$$ +q_L \circ w_a + q_R \circ w_b + q_M\circ(w_a\cdot w_b) + q_C - q_O\circ w_c \overset{?}{=} 0 +$$ + +结合来看。 + +在上方固定的约束等式中: + +- $q_L$, $q_R$, $q_M$, $q_C$, $q_O$ 是选择器向量,用于选择特定的变量或操作 + - $q_L$ 表示左输入选择器 + - $q_R$ 表示右输入选择器 + - $q_M$ 表示乘法选择器 + - $q_C$ 表示常数选择器 + - $q_O$ 表示输出选择器 +- $w_a$, $w_b$, $w_c$ 是电路中的变量(或是电线上的值) + - $w_a$ 表示每个门的左输入引脚 + - $w_b$ 表示每个门的右输入引脚 + - $w_c$ 表示每个门的输出引脚 +- $\circ$ 表示元素对应相乘,即哈达玛积(Hadamard Product) + +- $\cdot$ 表示常规的乘法 + +为了验证电路,我们需要根据已有的约束关系(也就是矩阵 $W$)来构建约束矩阵 $Q$ + + + + +**矩阵 $Q$ 具体是怎么构建来的呢?** + +第一步,将约束都移到等式的一侧,所以: + +第一个门 `#1`,原来是 $x_3\cdot x_4 = x_6$,转换成 $x_3\cdot x_4 - x_6=0$; + +第二个门 `#2`, $x_1 + x_2 =x_5$,转换成 $x_1 + x_2 - x_5=0$; + +第三个门 `#3`, $x_5 \cdot x_6 = out$,转换成 $x_5 \cdot x_6 - out=0$。 + +> 为什么要将所有值移到等式一边? +> 1. 所有的约束等式形式统一为 $f(x) = 0$,这使得处理和验证这些等式更加一致和简单。 +> 2. 明确了每个选择器多项式的作用和系数,避免了正负号的混淆。 +> 3. 在验证过程中,统一的等式形式简化了对多项式的检查和验证。 + +非常简单是不是?很好,那么继续下一步。 + +第二步,根据已有的固定约束关系等式和三个转换后的等式,去判断选择器向量的系数,这里我们会用到 0 或 1 (系数 0 代表的是该选择器是关闭状态,系数 1 表示该选择器是开启状态): + +第一个门 `#1`: + +如果 $x_3\cdot x_4 - x_6=0$ 要满足 $q_L \circ w_a + q_R \circ w_b + q_M\circ(w_a\cdot w_b) + q_C - q_O\circ w_c = 0$ 这个固定等式关系,那么它的左输入选择器 $q_L=0$,它的右输入选择器 $q_R=0$,它的乘法选择器 $q_M=1$,常数选择器 $q_C=0$,输出选择器 $q_O=1$。 + +> 我们可以根据已有的约束关系判断对应选择器的具体数值(开关状态),我们也可以通过选择器的具体数值(开关状态)判断约束是否执行,二者可以互通有无。 + +我们可以对上面已经选择的选择器的值进行验证,如果将上面这些系数代入到 $q_L \circ w_a + q_R \circ w_b + q_M\circ(w_a\cdot w_b) + q_C - q_O\circ w_c = 0$ 中进行验算,以下是具体的计算过程: + +$$ +\begin{align} +0 \circ w_a + 0 \circ w_b + 1 \circ(w_a\cdot w_b) + 0 - 1\circ w_c & = 0\\ +1 \circ(w_a\cdot w_b) + 0 - 1\circ w_c & = 0 +\end{align} +$$ + +> $\circ$ 特指 Hadamard product,任何矩阵与零矩阵做哈达玛积结果仍然是零 + +再把约束关系相对应的选择器的值(0 or 1)代入上式: + +$$ +\begin{split} +0 \circ w_a + 0 \circ w_b + 1 \circ(w_a\cdot w_b) + 0 - 1\circ w_c &= 0\\ +1 \circ(w_a\cdot w_b) + 0 - 1\circ w_c &= 0\\ +1\circ(w_a\cdot w_b) &= 1\circ w_c\\ +x_5 \cdot x_6 &= out +\end{split} +$$ + +看!最后得到的结果 $x_5 \cdot x_6 = out$ ,用选择器的值代入到固定等式中和一开始例子中电路的约束关系是一致的。 + +相信到这里你已经可以学以致用了,建议自己可以按照上面的步骤推导剩下的内容: + +第二个门 `#2`,它的约束关系是 $x_1+x_2-x_5=0$,那么它的 $q_L=1$, $q_R=1$, $q_M=0$, $q_C=0$, $q_O=1$; + +第三个门 `#3`,它的约束关系是 $x_5 \cdot x_6 = out$,那么它的 $q_L=0$, $q_R=0$, $q_M=1$, $q_C=0$, $q_O=1$; + +> 如果你仔细观察上面会发现,如果是乘法门的话,拿 $x_5 \cdot x_6 = out$ 为例,它左右边的加法选择器都是关闭(选择器系数为 0)的状态,而表示乘法门的 $q_M$ 打开(选择器系数为 1);如果是加法门的话,以 $x_1+x_2-x_5=0$ 为例,它的右边的加法选择器是打开的状态(系数为 1),而它的左右边的加法选择器 $q_L$ 和 $q_R$ 是关闭状态(系数为 0)。 + + +现在把上面的这些数据整理起来,像 $W$ 一样,我们还是用表格的形式来表示约束矩阵 $Q\in\mathbb{F}^{n\times5}$( $n$ 算术门的数量,对应为行;5 表示选择器多项式的数量,即 $q_L$ ··· $q_O$ 对应为列)。 + + + + + +重点来了! + +有了约束矩阵 $Q$ 和 $W$ 的表格,接下来,我们就可以来验证,我们构建的两个矩阵的计算是否满足一开始的等式,即: + +$$ +q_L \circ w_a + q_R \circ w_b + q_M\circ(w_a\cdot w_b) + q_C - q_O\circ w_c = 0 +$$ + +如果把几个约束关系代入上面的固定等式中并展开计算,我们可以得到下面的等式: + +$$ +\left[ +\begin{array}{c} +0\\ +1 \\ +0\\ +\end{array} +\right] +\circ +\left[ +\begin{array}{c} +x_5 \\ +x_1 \\ +x_3\\ +\end{array} +\right] ++ +\left[ +\begin{array}{c} +0\\ +1 \\ +0\\ +\end{array} +\right] +\circ +\left[ +\begin{array}{c} +x_6 \\ +x_2 \\ +x_4\\ +\end{array} +\right] ++ +\left[ +\begin{array}{c} +1\\ +0 \\ +1\\ +\end{array} +\right] +\circ +\left[ +\begin{array}{c} +x_5\cdot x_6 \\ +x_1\cdot x_2 \\ +x_3\cdot x_4\\ +\end{array} +\right]=\left[ +\begin{array}{c} +1\\ +1 \\ +1\\ +\end{array} +\right] +\circ +\left[ +\begin{array}{c} +out \\ +x_5 \\ +x_6\\ +\end{array} +\right] +$$ + +以下是具体如何化简的计算过程: + +$$ +\left[ +\begin{array}{c} +0 \\ +x_1 \\ +0\\ +\end{array} +\right] ++ +\left[ +\begin{array}{c} +0 \\ +x_2 \\ +0\\ +\end{array} +\right] ++ +\left[ +\begin{array}{c} +x_5\cdot x_6 \\ +0 \\ +x_3\cdot x_4\\ +\end{array} +\right]=\left[ +\begin{array}{c} +out \\ +x_5 \\ +x_6\\ +\end{array} +\right] +$$ + +化简后: + +$$ +\left[ +\begin{array}{c} +x_5\cdot x_6 \\ +x_1+x_2 \\ +x_3\cdot x_4\\ +\end{array} +\right]=\left[ +\begin{array}{c} +out \\ +x_5 \\ +x_6\\ +\end{array} +\right] +$$ + +可以对比化简后的结果和最先的约束关系,你会发现我们不知不觉已经达到了彼岸——已经完成了证明。因为可以看到化简后得到的结果和一开始的约束关系是一致的。化简后的结果正好是三个计算门的计算关系。 + +不过仅仅是 $Q$ 矩阵里的内容不足以精确描述上面的例子电路,我们还需要别的内容。 + +
+ +# 复制约束(copy constraint) + +比较下面两个电路,它们能构成的 $Q$ 矩阵完全相同,但它们的电路结构却完全不同。 + + + + +两个电路的区别在于: $x_5, x_6$ 是否被接入了 `#1` 号门。 + + + +结合上面的电路比较图和矩阵 $W$ 一起来看,如果让 Prover 直接把电路赋值填入矩阵 $W$ 中,一个「诚实的」Prover 会在 $w_{(a,1)}$ (表示 $i=1$ 行, $w_a$ 列,也就是在第一行第一列)和 $w_{(c,2)}$(表示 $i=2$ 行, $w_c$ 列,也就是在第二行第三列) 的两个位置填上相同的值;而一个「恶意的」Prover 完全可以填上不同的值。如果恶意的 Prover 在 $w_{(b,1)}$ 和 $w_{(c,3)}$ 也填入不同的值,那么实际上 Prover 证明的是上图右边的电路,而非是和 Verifier 共识过的电路(左边),「恶意的」Prover 填写不同值的情况: + + + + +为了防止「恶意的」 Prover 作恶,我们需要增加新的约束,强制要求右边电路图中 $x_5=x_7$ 和 $x_6=x_8$,见下图。这等价于我们要求 Prover 把同一个变量填入表格多个位置时,必须填入相等的值。 + + + +这就需要一类新的约束——「拷贝约束」,即 Copy Constraint。Plonk 采用「置换证明」保证矩阵 $W$ 中多个位置上的值满足拷贝关系。我们继续用上面这个电路图的案例来说明其基本思路: + + + +设想我们把 $W$ 表格中的所有位置索引排成一个向量: + +$$ +\vec{\sigma_0}=(\boxed{w_{(a,1)}}, w_{(a,2)}, w_{(a,3)}, \underline{w_{(b,1)}}, w_{(b,2)}, w_{(b,3)}, w_{(c,1)}, \boxed{w_{(c,2)}}, \underline{w_{(c,3)}}) +$$ + +然后把应该相等的两个位置互换,比如上图中要求 ${w_{(a,1)}}={w_{(c,2)}}$ 和 ${w_{(b,1)}}=w_{(c,3)}$ 。于是我们得到了下面交换后的位置向量: + +$$ +\vec\sigma=(\boxed{w_{(c,2)}}, w_{(a,2)}, w_{(a,3)}, \underline{w_{(c,3)}}, w_{(b,2)}, w_{(b,3)}, w_{(c,1)}, \boxed{w_{(a,1)}}, \underline{w_{(b,1)}}) +$$ + +然后我们要求 Prover 证明:**$W$ 矩阵按照上面的置换之后,仍然等于自身**。置换位置前后的值的相等性可以保证 Prover 无法作弊。 + +再来一个例子,当约束一个向量中有三个(或多个)位置上的值必须相同时,只需要把这三个(或多个)位置的值进行循环移位(左移位或者右移位),然后证明移位后的向量与原向量相等即可。 + +比如: + +$$ +A = (b_1, b_2, \underline{a_1}, b_3, \underline{a_2}, b_4, \underline{a_3}) +$$ + +如果要证明 $a_1=a_2=a_3$,那么只需要证明: + +$$ +A' = (b_1, b_2, \underline{a_3}, b_3, \underline{a_1}, b_2, \underline{a_2}) = A +$$ + +在经过置换的向量 $A'$ 中, $a_1, a_2, a_3$ 依次右移交换,即 $a_1$ 放到了原来 $a_2$ 的位置,而 $a_2$ 放到了 $a_3$ 的位置, $a_3$ 则放到了 $a_1$ 的位置。 + +如果 $A'=A$ ,那么 $A'$ 和 $A$ 所有对应位置上的值都应该相等,可得: $a_1=a_3$, $a_2=a_1$, $a_3=a_2$,即 $a_1=a_2=a_3$。这个方法可以适用于任意数量的等价关系。(证明两个向量相等的方法请见后续章节「3」) + +**那么如何描述电路赋值表格中的交换操作呢?** 我们只需要记录 $\vec{\sigma}$ 即可,记录了变量在交换操作后的映射关系,也就是说,原先位置的变量经过交换后,被映射到新的位置。通过这种方式,我们只需要记录这个置换向量 ${\vec\sigma}$,就可以描述整个交换操作的结果。 $\vec{\sigma}$ 可以写成表格的形式,从而理解它的位置变化: + + + +> 让我们来说明一下上面这个位置矩阵表示的意思: + +> **初始次序 ($i$ 列)**: +> - 第 1 行的元素最初在位置1。 +> - 第 2 行的元素最初在位置2。 +> - 第 3 行的元素最初在位置3。 + +> **$σ_a$ 列**: +> - $w_c$ 最初在位置1,交换到位置2。 +> - $w_a$ 最初在位置2,保持在位置2。 +> - $w_a$ 最初在位置3,保持在位置3。 + +> **$σ_b$ 列**: +> - $w_c$ 最初在位置1,交换到位置3。 +> - $w_b$ 最初在位置2,保持在位置2。 +> - $w_b$ 最初在位置3,保持在位置3。 + +> **$σ_c$ 列**: +> - $w_c$ 最初在位置1,保持在位置1。 +> - $w_a$ 最初在位置2,交换到位置1。 +> - $w_b$ 最初在位置3,交换到位置1。 + +根据下面这张图,可以感受位置的变化: + + + + +> 总结一下,位置矩阵 $T$ 反应了映射关系,具体的位置变化可以看上图。通过这种方法,你不需要记录每一个变量具体如何交换,而是只需记录交换后的映射关系,这样就能简化对复杂交换操作的描述。 + +
+ +前面说到只构建约束矩阵 $Q$ 和 赋值矩阵 $W$ 是不足以精确描述「图:电路1」的例子电路,但是现在加上表示位置变换的 $\vec\sigma$,也就是位置矩阵 $T$,它们可以共同描述和验证电路。整个电路可以描述为 $(Q,\sigma)$ ,电路的赋值为 $W$ + + + + +$$ +\mathsf{Plonkish}_0 \triangleq (Q, \sigma; W) +$$ + +
+ + +# 电路验证协议框架 + +有了电路空白结构的描述和赋值,我们可以大致描述 Plonk 的协议框架。 + +**协议计算过程如下**: + +首先 Prover 和 Verifier 会对一个共同的电路进行共识—— $(Q,\sigma)$ 。 假设电路的公开输出为 $out=99$,而 $(x_1,x_2,x_3,x_4)$ 为秘密输入。 + +Prover 填写 $W$ 矩阵(Verifier 不可见): + +$$ +\begin{array}{c|c|c|c|} +i & w_a & w_b & w_c \\ +\hline +1 & \boxed{x_5} & \underline{x_6} & [out] \\ +2 & x_1 & x_2 & \boxed{x_5} \\ +3 & x_3 & x_4 & \underline{x_6} \\ +4 & 0 & 0 & [out] \\ +\end{array} +$$ + +其中增加的第四行是为了增加一个额外的算术约束: $out=99$ ,强调 $out$ 值在 $Q$ 矩阵中。 + +相应的那么 Prover 和 Verifier 共识的 $Q$ 矩阵为: + +$$ +\begin{array}{c|c|c|c|} +i & q_L & q_R & q_M & q_C & q_O \\ +\hline +1 & 0 & 0 & 1 & 0& 1 \\ +2 & 1 & 1 & 0 & 0& 1 \\ +3 & 0 & 0 & 1 & 0& 1 \\ +4 & 0 & 0 & 0 & 99& 1 \\ +\end{array} +$$ + +其中第四行约束,保证 $out=99$,可以把 $(q_L=0, q_R=0,q_M=0,q_C=99,q_O=1)$ 代入下面的算术约束中,求得 $99-w_c = 0$ ,即 $w_{(c,4)}=99$ (表示矩阵 $Q$ 中的 $q_c$ 列,第四行的位置上的值是 $99$)。 + +$$ +q_L \circ w_a + q_R \circ w_b + q_M\circ(w_a\cdot w_b) + q_C - q_O\circ w_c = 0 +$$ + +为了保证 $W$ 矩阵中的第一行的 $w_c$ 也必须为 $99$(确保输出 $out$ 在所有相关位置都正确反映),这就需要在 $\sigma$ 向量中添加额外的一条拷贝约束:确保 $out$ 变量的位置 $w_{(c,1)}$ 与 第四行的输出 $w_{(c,4)}$ 交换对调: + +$$ +\begin{array}{c|c|c|c|} +i & \sigma_a & \sigma_b & \sigma_c \\ +\hline +1 & \boxed{w_{(c,2)}} & \underline{w_{(c,3)}} & [{w_{(c,4)}}] \\ +2 & {w_{(a,2)}} & {w_{(b,2)}} & \boxed{w_{(a,1)}} \\ +3 & {w_{(a,3)}} & {w_{(b,3)}} & \underline{w_{(b,1)}} \\ +4 & {w_{(a,4)}} & {w_{(b,4)}} & [{w_{(c,1)}}]\\ +\end{array} +$$ + +如果 Prover 是诚实的,那么对于 $i\in \{1,2,3,4\}$,下面的算术约束等式成立: + +$$ +q_{L,i} \circ w_{a,i} + q_{R,i} \circ w_{b,i} + q_{M,i}\circ(w_{a,i}\cdot w_{b,i}) + q_{C,i} - q_{O,i}\circ w_{c,i} = 0 +$$ + + +**验证协议的大概思路如下:** + +协议开始:Prover 如实填写 $W$ 表格,然后把 $W$ 表格的每一列进行编码,并进行多项式编码,并把编码后的结果发送给 Verifier + +协议验证阶段:Verifier 与 Prover 通过进一步的交互,验证下面的等式是否成立: + +$$ +q_{L}(X) \cdot w_{a}(X) + q_{R}(X) \cdot w_{b}(X) + q_{M}(X)\cdot(w_{a}(X)\cdot w_{b}(X)) + q_{C}(X) - q_{O}(X)\cdot w_{c}(X) \overset{?}{=} 0 +$$ + + +> $$ +> q_{L,i}\circ w_{a,i} + q_{R,i}\circ w_{b,i} + q_{M,i}\circ (w_{a,i}\cdot w_{b,i}) + q_{C,i} - q_{O,i}\circ w_{c,i} = 0 +> $$ +> 和 +> $$ +> q_L(X) \cdot w_a(X) + q_R(X) \cdot w_b(X) + q_M(X) \cdot (w_a(X) \cdot w_b(X)) + q_C(X) - q_O(X) \cdot w_c(X) = 0 +> $$ + +> 这两个等式代表的其实是同一个意思。可以从以下几个维度对比理解: + +> 1. 索引和多项式表示: + 第一个等式:使用下标 $i$ 表示具体的索引,这意味着它是在特定点 $i$ 处的约束。 + 第二个等式:使用 $(X)$ 表示多项式,这意味着它是在整个域上的约束。 +> 2. 变量和系数: +> $q_{L,i}, q_{R,i}, q_{M,i}, q_{C,i}, q_{O,i}$ 与 $q_L(X), q_R(X), q_M(X), q_C(X), q_O(X)$ 代表相同的约束系数,只是在不同的表示方法下一个是具体数值,一个是多项式形式; +> $w_{a,i}, w_{b,i}, w_{c,i}$ 与 $w_a(X), w_b(X), w_c(X)$ 分别代表输入值,只是在不同的表示方法下一个是具体数值,一个是多项式形式。 +> 3. 操作符: + 在第一个等式中,使用了「 $\circ$ 」来表示乘法运算。 + 在第二个等式中,使用了「 $\cdot$ 」来表示乘法运算。 + +通过这种方式,验证者可以确保电路的所有计算都是正确的,从而验证整个计算过程的正确性。 + +当然只验证 + +$$ +q_{L}(X) \cdot w_{a}(X) + q_{R}(X) \cdot w_{b}(X) + q_{M}(X)\cdot(w_{a}(X)\cdot w_{b}(X)) + q_{C}(X) - q_{O}(X)\cdot w_{c}(X) \overset{?}{=} 0 +$$ + +还不够,还要验证 $(\sigma_a(X),\sigma_b(X),\sigma_c(X))$ 与 $(w_a(X),w_b(X),w_c(X))$ 之间的关系。 + +至于 Verifier 是如何通过多项式来验证电路的运算,即验证 $(\sigma_a(X),\sigma_b(X),\sigma_c(X))$ 与 $(w_a(X),w_b(X),w_c(X))$ 之间的关系,这部分内容请看后续章节。