美文网首页
Polygon zkEVM 状态机设计原理

Polygon zkEVM 状态机设计原理

作者: 雪落无留痕 | 来源:发表于2022-10-06 00:28 被阅读0次

Polygon zkEVM是兼容EVM的zkRollup Layer 2 方案。zkEVM 证明的第一步是构建交易的执行路径 (execution trace)。trace 是一个矩阵,每一列有一个名字,对每一列进行多项式插值,将执行路径的正确性归纳为多项式之间的恒等关系,这称算术化(arithmetization)。状态机主要提供了EVM证明的算术化过程。

Fibonacci 示例

Fibonacci State Machine

对于给定初始条件Fibonacci 序列,可以用两个寄存器A 和 B 构建状态机,如下图:

状态机初始条件为 A_1 = 0, B_1 = 1, 并且有如下的关系:
A_{i+1} = B_i \\ B_{i+1} = A_i+B_i
将寄存器状态表示为多项式\mathbb{Z}_p[x], 定义域在子群 H=\{w, w^2, w^3, w^4, w^5, w^6, w^7, w^8=1\}, 即\mathbb{Z}_p^*的8次单位根上,关系如下:
A(w^i)=A_i \rightarrow A=[0,1,1,2,3,5,8,14] \\ B(w^i)=B_i \rightarrow B=[1,1,2,3,5,8,13,21]

状态机的关系可以转为多项式的恒等关系:
A(x\omega) = |_HB(x),\\ B(x\omega) = |_HA(x)+B(x)
但这些等式无法完全约束,例如:

  • 寄存器是非循环的,当在w^8 计算等式关系的时候:

A(\omega^9)=A(\omega)=0 \neq 21 = B(\omega^8) \\ B(\omega^9)=B(\omega)=1 \neq 34 = A(\omega^8)+ B(\omega^8)

  • 其它的初始条件也能满足恒等关系,例如 (2, 4)。

为了解决上述问题,可以添加一个辅助寄存器(C):

此时 多项式C 为:
C(\omega^i) = C_i \rightarrow C= [1,0,0,0,0,0,0,0]
新的多项式恒等关系为:
A(x\omega) = |_HB(x)(1-C(x\omega)) \\ B(w\omega)=|_H(A(x)+B(x))(1-C(x\omega))+ C(x\omega)
并且可以使用其它的初始条件(A_1,B_1), 修改多项式恒等关系为:
A(x\omega)=|_HB(x)(1-C(x\omega))+ A_1C(x\omega) \\ B(x\omega)=|_H(A(x)+B(x))(1-C(x\omega))+B_1C(x\omega)
在上一个例子中,(A_1, B_1)=(0,1)

状态机证明

多项式承诺需要满足BindingHiding, 可以使用Kate 和 FRI 承诺。

Simple State Machine

首先展示一个简单状态机的算术化过程,如下图:

下列程序描述寄存器 A 和 B 接受输入的过程:

Instruction
${getInput()} => A
3 => B
: ADD
0 => A, B

上面的程序由汇编语言实现,通过executor 读入,生成执行路径。上面的代码,汇编指令分别表示为:

  • ${ getInput() } => A: 寻求自由输入,并保存在寄存器 A中。
  • 3 => B. 将3移入寄存器B 中;
  • :ADD 将寄存器 A 和 B的值加起来,作为寄存器A 的输出;
  • 0 => A, B 将0 移动到寄存器 A 和 B上。

例如,对于自由输入为7时,执行路径为:

\begin{array}{|l|c|c|c|c|c|} \hline \mathbf{Instruction} & \mathtt{free} & \mathtt{A} & \mathtt{A'} & \mathtt{B} & \mathtt{B'} \\ \hline \mathtt{\$\{getInput()\} => A} & 7 & 0 & 7 & 0 & 0 \\ \hline \mathtt{3 => B} & 0 & 7 & 7 & 0 & 3 \\ \hline \mathtt{:ADD} & 0 & 7 & 10 & 3 & 3 \\ \hline \mathtt{0 => A,B} & 0 & 10 & 0 & 3 & 0 \\ \hline \end{array}
其中 X' 为 寄存器 X 的下一个状态, 其中 X\in \{A, B\}

为了创建合适的算术化约束条件,需要添加辅助的状态和选择子(selectors)表示寄存器AB 的关系:

其中 :

  • \mathtt{inX}^i \in \{0,1\}: 选择子,表示是否包含 X_i 在线性组合中;
  • \mathtt{setX}^i \in \{0,1\}: 选择子,表示是否将线性组合结果赋给X_{i+1};
  • \mathtt{freeIn^i}: 包含的自由输入
  • \mathtt{const}^i: 包含一些固定的值

在引入辅助变量之后,可以得到下面的扩展表:
\scriptsize \begin{array}{|l|} \hline \mathbf{Instruction} \\ \hline \mathtt{\$\{getInput()\} => A} \\ \hline \mathtt{3 => B} \\ \hline \mathtt{:ADD} \\ \hline \mathtt{0 => A, B} \\ \hline \end{array} \hspace{0.1cm} \begin{array}{|c|c|c|c|c|c|c|c|} \hline \texttt{free} & \texttt{const} & \texttt{setB} & \texttt{setA} & \texttt{inFree} & \texttt{selB} & \texttt{selA} \\ \hline 7 & 0 & 0 & 1 & 1 & 0 & 0 \\ \hline 0 & 3 & 1 & 0 & 0 & 0 & 0 \\ \hline 0 & 0 & 0 & 1 & 0 & 1 & 1 \\ \hline 0 & 0 & 1 & 1 & 0 & 0 & 0 \\ \hline \end{array} \hspace{0.1cm} \begin{array}{|c|c|c|c|} \hline \mathtt{A} & \mathtt{A'} & \mathtt{B} & \mathtt{B'} \\ \hline 0 & 7 & 0 & 0\\ \hline 7 & 7 & 0 & 3\\ \hline 7 & 10 & 3 & 3\\ \hline 10 & 0 & 3 & 0\\ \hline \end{array}
寄存器状态的关系可以用如下代数关系表示:
\begin{aligned} &\mathtt{A}^{i+1} = \mathtt{A}^i + \mathtt{setA}^i \cdot (\mathtt{selA}^i \cdot \mathtt{A}^i + \mathtt{selB}^i \cdot \mathtt{B^i} + \mathtt{inFree}^i \cdot \mathtt{free}^i + \mathtt{const}^i - \mathtt{A}^i), \\ &\mathtt{B}^{i+1} = \mathtt{B}^i + \mathtt{setB}^i \cdot (\mathtt{selA}^i \cdot \mathtt{A}^i + \mathtt{selB}^i \cdot \mathtt{B}^i + \mathtt{inFree}^i \cdot \mathtt{free}^i + \mathtt{const}^i - \mathtt{B}^i).\\ \end{aligned}
将寄存器的状态表示为多项式 \mathtt{A},\mathtt{B} \in \mathbb{Z}_p[x], 定义域为子群H = {\omega, \omega^2, \omega^3,\omega^4 = 1}上,
&\mathtt{A}(x\omega) = \mathtt{A}(x) + \mathtt{setA}(x) \cdot (\mathtt{selA}(x) \cdot \mathtt{A}(x) + \mathtt{selB}(x) \cdot \mathtt{B}(x) + \mathtt{inFree}(x) \cdot \mathtt{free}(x) + \mathtt{const}(x) - \mathtt{A}(x)), \\ &\mathtt{B}(x\omega) = \mathtt{B}(x) + \mathtt{setB}(x) \cdot (\mathtt{selA}(x) \cdot \mathtt{A}(x) + \mathtt{selB}(x) \cdot \mathtt{B}(x) + \mathtt{inFree}(x) \cdot \mathtt{free}(x) + \mathtt{const}(x) - \mathtt{B}(x)).
这个程序可以完全由常量多项式: \mathtt{selA(x)}, \mathtt{selB(x)}, \mathtt{setA(x)}, \mathtt{setB(x)}, \mathtt{inFree(x)}, \mathtt{const(x)} 描述。

多项式 \mathtt{free(x)} 可以是公开的,或根据不同的初始条件 提前承诺。

程序的最终结果为A(\omega^4)

最后的指令重置寄存器的值到初始状态,形成一个循环。

条件语言跳转

下面引入指令 \mathtt{JMPZ},能够跳到指定的位置。在下面的程序中,当 \mathtt{A+B}值为0的时候, \mathtt{JMPZ} 将跳到 5 的位置:
\begin{array}{|c|l|} \hline \textbf{Position} & \mathbf{Instruction} \\ \hline 0 & \mathtt{\$\{getInput()\} => A} \\ \hline 1 & \mathtt{-3 => B} \\ \hline 2 & \mathtt{:ADD} \\ \hline 3 & \mathtt{:JMPZ(5)} \\ \hline 4 & \mathtt{:ADD} \\ \hline 5 & \mathtt{0 => A, B} \\ \hline \end{array}
当引入条件跳转的时候,根据不同的输入值,执行路径长度是不一样的,如下所示:
\scriptsize \begin{array}{|l|c|c|c|c|c|} \hline \mathbf{Instruction} & \mathtt{free} & \mathtt{A} & \mathtt{A'} & \mathtt{B} & \mathtt{B'} \\ \hline \mathtt{\$\{getInput()\} => A} & 7 & 0 & 7 & 0 & 0 \\ \hline \mathtt{-3 => B} & 0 & 7 & 7 & 0 & -3 \\ \hline \mathtt{:ADD} & 0 & 7 & 4 & -3 & -3 \\ \hline \mathtt{:JMPZ(5)} & 0 & 4 & 4 & -3 & -3 \\ \hline \mathtt{:ADD} & 0 & 4 & 1 & -3 & -3 \\ \hline \mathtt{0 => A, B} & 0 & 1 & 0 & -3 & 0 \\ \hline \end{array}

\scriptsize \begin{array}{|l|c|c|c|c|c|} \hline \mathbf{Instruction} & \mathtt{free} & \mathtt{A} & \mathtt{A'} & \mathtt{B} & \mathtt{B'} \\ \hline \mathtt{\$\{getInput()\} => A} & 3 & 0 & 3 & 0 & 0 \\ \hline \mathtt{-3 => B} & 0 & 3 & 3 & 0 & -3 \\ \hline \mathtt{:ADD} & 0 & 3 & 0 & -3 & -3 \\ \hline \mathtt{:JMPZ(5)} & 0 & 0 & 0 & -3 & -3 \\ \hline \mathtt{0 => A, B} & 0 & 0 & 0 & -3 & 0 \\ \hline \end{array}

上面的执行是6步,下面的执行是5步。

管理条件跳转

需要引入 新模型管理程序的条件跳转:

需要添加程序计数器\mathtt{Program Counter (PC)}, PC是一种特殊的寄存器,包含程序指令的执行位置。

下面使用 \mathtt{op_i} 作为以下线性组合的简写:
\mathtt{op}^i := \mathtt{setA}^i \cdot \mathtt{A}^i + \mathtt{setB}^i \cdot \mathtt{B}^i + \mathtt{inFree}^i \cdot \mathtt{free}^i + \mathtt{const}^i.

\mathtt{op}^i 为0, \mathtt{JMPZ} 将会跳转到指令 \mathtt{addr}^i 位置,首先需要检查操作在\mathbb{Z}_p 中是否为0.

为了检查 \mathbb{Z}_p 中的数是否为0, 需要使用新的方法:若a \neq 0, 则 a 必然有一个乘法逆元: a^{-1}

下面添加 \mathtt{isZero} 检查约束条件:
&\mathtt{isZero}^i := 1 - \mathtt{op}^i \cdot (\mathtt{op}^i)^{-1}, \\ &\mathtt{isZero}^i \cdot \mathtt{op}^i = 0.
可以将两个方程变成一个约束条件:
\mathtt{isZero}^i \cdot \mathtt{op}^i = 0,~~\mathtt{isZero}^i = 1 - \mathtt{op}^i \cdot (\mathtt{op}^i)^{-1}~~\rightarrow~~(1 - \mathtt{op}^i \cdot (\mathtt{op}^i)^{-1}) \cdot \mathtt{op}^i = 0.
引入下面的机制处理跳转:

添加选择子 \mathtt{jmpz}^i \in \{0, 1\}, 通过下面的约束描述 \mathtt{PC} 的行为。
\begin{aligned} &\mathtt{op}^i := \mathtt{setA}^i \cdot \mathtt{A}^i + \mathtt{setB}^i \cdot \mathtt{B}^i + \mathtt{inFree}^i \cdot \mathtt{free}^i + \mathtt{const}^i, \\ &\mathtt{PC}^{i+1} = \mathtt{PC}^i + 1 + \mathtt{jmpz}^i \cdot (1 - \mathtt{op}^i \cdot (\mathtt{op}^i)^{-1}) \cdot (\mathtt{addr}^i - \mathtt{PC}^i - 1),\\ &(1 - \mathtt{op}^i \cdot (\mathtt{op}^i)^{-1}) \cdot \mathtt{op}^i = 0. \end{aligned}
当输入分别为7和3的时候,执行路径分别为:
\tiny \begin{array}{|l|} \hline \mathbf{Instruction} \\ \hline \mathtt{\$\{getInput()\} => A} \\ \hline \mathtt{-3 => B} \\ \hline \mathtt{:ADD} \\ \hline \mathtt{:JMPZ(5)} \\ \hline \mathtt{:ADD} \\ \hline \mathtt{0 => A, B, PC} \\ \hline \end{array} \hspace{0.1cm} \begin{array}{|c|c|c|c|c|c|c|c|c|c|c|} \hline \texttt{free} & \textbf{const} & \texttt{addr} & \texttt{jmpz} & \texttt{setB} & \texttt{setA} & \texttt{inFree} & \texttt{selB} & \texttt{selA} & \texttt{op} & \texttt{invOp} \\ \hline 7 & 0 & 0 & 0 & 0 & 1 & 1 & 0 & 0 & 7 & 7^{-1} \\ \hline 0 & -3 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & -3 & (-3)^{-1} \\ \hline 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 & 1 & \mathbf{\color{blue!75!black} 4} & \mathbf{\color{blue!75!black} 4^{-1}} \\ \hline 0 & 0 & 5 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ \hline 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 & 1 & 1 & 1 \\ \hline 0 & 0 & 0 & 1 & 1 & 1 & 0 & 0 & 0 & 0 & 0 \\ \hline \end{array} \hspace{0.1cm} \begin{array}{|c|c|c|c|c|c|} \hline \mathtt{PC} & \mathtt{PC'} & \mathtt{A} & \mathtt{A'} & \mathtt{B} & \mathtt{B'} \\ \hline 0 & 1 & 0 & 7 & 0 & 0\\ \hline 1 & 2 & 7 & 7 & 0 & -3\\ \hline 2 & 3 & 7 & 4 & -3 & -3\\ \hline 3 & 4 & 4 & 4 & -3 & -3\\ \hline 4 & 5 & 4 & 1 & -3 & -3\\ \hline 5 & 0 & 1 & 0 & -3 & 0\\ \hline \end{array}

\tiny \begin{array}{|l|} \hline \mathbf{Instruction} \\ \hline \mathtt{\$\{getInput()\} => A} \\ \hline \mathtt{-3 => B} \\ \hline \mathtt{:ADD} \\ \hline \mathtt{:JMPZ(5)} \\ \hline \mathtt{0 => A, B} \\ \hline \end{array} \hspace{0.1cm} \begin{array}{|c|c|c|c|c|c|c|c|c|c|c|c|} \hline \texttt{free} & \texttt{const} & \texttt{addr} & \texttt{jmpz} & \texttt{setB} & \texttt{setA} & \texttt{inFree} & \texttt{selB} & \texttt{selA} & \texttt{op} & \texttt{invOp} \\ \hline 3 & 0 & 0 & 0 & 0 & 1 & 1 & 0 & 0 & 3 & 3^{-1} \\ \hline 0 & -3 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & -3 & (-3)^{-1} \\ \hline 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 & 1 & \mathbf{\color{blue!75!black} 0} & \mathbf{\color{blue!75!black} \alpha} \\ \hline 0 & 0 & 5 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ \hline 0 & 0 & 0 & 1 & 1 & 1 & 0 & 0 & 0 & 0 & 0 \\ \hline \end{array} \hspace{0.1cm} \begin{array}{|c|c|c|c|c|c|} \hline \mathtt{PC} & \mathtt{PC'} & \mathtt{A} & \mathtt{A'} & \mathtt{B} & \mathtt{B'} \\ \hline 0 & 1 & 0 & 3 & 0 & 0\\ \hline 1 & 2 & 3 & 3 & 0 & -3\\ \hline 2 & 3 & 3 & 0 & -3 & -3\\ \hline 3 & 5 & 3 & 0 & -3 & -3\\ \hline 5 & 0 & 0 & 0 & -3 & 0\\ \hline \end{array}

其中 \mathtt{invOp} 用来表示 \mathtt{op}的逆。

目前,多项式是没有经过预处理的,因为表中的值不仅依赖自由输入,还需要验证正确的执行了程序。

证明正确的程序执行

为了检查执行了正确有的程序,我们提供一种指令常数值编码的方法,然后检查执行指令的编码确实在程序中指令的编码中。

假设采用4位符号整数(实际中为32位)进行编码指令中的常数值,如下所示:
\begin{array}{|c|c|c|c|c|c|c|c|c|c|c|c|c|} \hline -8 & -7 & -6 & ... & -2 & -1 & 0 & 1 & 2 & ... & 6 & 7 & 8 \\ \hline 1000 & 1001 & 1010 & ... & 1110 & 1111 & 0000 & 0001 & 0010 & ... & 0110 & 0111 & 1000 \\ \hline \end{array}
去掉(8=-8), 编码余下的值为:
\begin{array}{|c|c|c|c|c|c|c|c|c|c|c|} \hline -7 & -6 & ... & -2 & -1 & 0 & 1 & 2 & ...& 6 & 7 \\ \hline p-7 & p-6 & ... & p-2 & p-1 & 0 & 1 & 2 & ...& 6 & 7 \\ \hline \end{array}
然后约束: \mathtt{const(x)} \in \{ p-7, p-6, \cdots, p-2, p-1, 0,1,2,\cdots,6,7 \}

等价于: \mathtt{const(x)}+7 \in \{0,1,2,\cdots, 14\}

对示例程序指令编码后的结果为:
\begin{array}{|c|c|} \hline \texttt{position} & \mathbf{Instruction} \\ \hline 0 & \mathtt{\$\{getInput()\} => A} \\ \hline 1 & \mathtt{-3 => B} \\ \hline 2 & \mathtt{:ADD} \\ \hline 3 & \mathtt{:JMPZ(5)} \\ \hline 4 & \mathtt{:ADD} \\ \hline 5 & \mathtt{0 => A, B, PC} \\ \hline \end{array} \hspace{0.1cm} \begin{array}{|c|} \hline \texttt{ROM} \\ \hline 0111.0000.001100 \\ \hline 0100.0000.010000 \\ \hline 0111.0000.001011\\ \hline 0111.0101.100000 \\ \hline 0111.0000.001011 \\ \hline 0111.0000.111000 \\ \hline \end{array}
采用如下规则编码指令:
\texttt{instruction}^i := 2^{10}\cdot(\texttt{const}^i + 7) + 2^6\cdot \texttt{addr}^i + 2^5\cdot \texttt{jmpz}^i + 2^4 \cdot \texttt{setB}^i + 2^3 \cdot \texttt{setA}^i + 2^2 \cdot \texttt{inFree}^i + 2 \cdot \texttt{selB}^i + \texttt{selA}^i.
另外,需要检查 selectors 是二进制的,\mathtt{addr} 是由4位组成, 即 \mathtt{addr}^i \in \{0,1,\cdots, 15\}.

对于\mathtt{const^i + 7 =7 }, 指 \mathtt{const}^i = 0, 表示没有使用常量。

为了证明程序,每个指令的编码和位置需要唯一识别,即:
\texttt{ROM}^i := 2^{14} \cdot \texttt{position}^i + \texttt{instruction}^i.
\mathtt{ROM} 可以唯一识别待验证的程序,如下所示:
\begin{array}{|c|c|} \hline \texttt{position} & \mathbf{Instruction} \\ \hline 0 & \mathtt{\$\{getInput()\} => A} \\ \hline 1 & \mathtt{-3 => B} \\ \hline 2 & \mathtt{:ADD} \\ \hline 3 & \mathtt{:JMPZ(5)} \\ \hline 4 & \mathtt{:ADD} \\ \hline 5 & \mathtt{0 => A, B, PC} \\ \hline \end{array} \hspace{0.1cm} \begin{array}{|c|} \hline \texttt{ROM} \\ \hline 0111.0000.001100 \\ \hline 0100.0000.010000 \\ \hline 0111.0000.001011\\ \hline 0111.0101.100000 \\ \hline 0111.0000.001011 \\ \hline 0111.0000.111000 \\ \hline \end{array}
采用 \mathtt{PC} 编码程序的路径:
\scriptsize \begin{array}{|c|c|c|c|c|c|} \hline \mathtt{PC} \\ \hline 0 \\ \hline 1 \\ \hline 2 \\ \hline 3 \\ \hline 4 \\ \hline 5 \\ \hline \end{array} \hspace{0.1cm} \begin{array}{|c|c|c|} \hline \mathtt{position} & \mathbf{Instruction} \\ \hline 0 & \mathtt{\$\{getInput()\} => A} \\ \hline 1 & \mathtt{-3 => B} \\ \hline 2 & \mathtt{:ADD} \\ \hline 3 & \mathtt{:JMPZ(5)} \\ \hline 4 & \mathtt{:ADD} \\ \hline 5 & \mathtt{0 => A, B, PC} \\ \hline \end{array} \hspace{0.1cm} \begin{array}{|c|c|c|c|c|c|c|c|c|} \hline \texttt{const+7} & \texttt{addr} & \texttt{jmpz} & \texttt{setB} & \texttt{setA} & \texttt{inFree} & \texttt{selB} & \texttt{selA} \\ \hline 7 & 0 & 0 & 0 & 1 & 1 & 0 & 0 \\ \hline 4 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\ \hline 7 & 0 & 0 & 0 & 1 & 0 & 1 & 1 \\ \hline 7 & 5 & 1 & 0 & 0 & 0 & 0 & 0 \\ \hline 7 & 0 & 0 & 0 & 1 & 0 & 1 & 1 \\ \hline 7 & 0 & 1 & 1 & 1 & 0 & 0 & 0 \\ \hline \end{array} \hspace{0.1cm} \begin{array}{|c|c|c|c|c|c|} \hline \mathtt{insTrace} \\ \hline 0000.0111.0000.001100 \\ \hline 0001.0100.0000.010000 \\ \hline 0010.0111.0000.001011\\ \hline 0011.0111.0101.100000 \\ \hline 0100.0111.0000.001011 \\ \hline 0101.0111.0000.111000 \\ \hline \end{array}

\scriptsize \begin{array}{|c|c|c|c|c|c|} \hline \mathtt{PC} \\ \hline 0 \\ \hline 1 \\ \hline 2 \\ \hline 3 \\ \hline 5 \\ \hline \end{array} \hspace{0.1cm} \begin{array}{|c|c|c|} \hline \mathtt{position} & \mathbf{Instruction} \\ \hline 0 & \mathtt{\$\{getInput()\} => A} \\ \hline 1 & \mathtt{-3 => B} \\ \hline 2 & \mathtt{:ADD} \\ \hline 3 & \mathtt{:JMPZ(5)} \\ \hline 4 & \mathtt{0 => A, B, PC} \\ \hline \end{array} \hspace{0.1cm} \begin{array}{|c|c|c|c|c|c|c|c|c|} \hline \texttt{const+7} & \texttt{addr} & \texttt{jmpz} & \texttt{setB} & \texttt{setA} & \texttt{inFree} & \texttt{selB} & \texttt{selA} \\ \hline 7 & 0 & 0 & 0 & 1 & 1 & 0 & 0 \\ \hline 4 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\ \hline 7 & 0 & 0 & 0 & 1 & 0 & 1 & 1 \\ \hline 7 & 5 & 1 & 0 & 0 & 0 & 0 & 0 \\ \hline 7 & 0 & 1 & 1 & 1 & 0 & 0 & 0 \\ \hline \end{array} \hspace{0.1cm} \begin{array}{|c|c|c|c|c|c|} \hline \mathtt{insTrace} \\ \hline 0000.0111.0000.001100 \\ \hline 0001.0100.0000.010000 \\ \hline 0010.0111.0000.001011\\ \hline 0011.0111.0101.100000 \\ \hline 0101.0111.0000.111000 \\ \hline \end{array}

那么要如何有效检查执行了正确的程序呢,可以采用Plookup 协议, 即:
\mathsf{insTrace(x)} \subset \mathsf{ROM(x)}
若指令路径包含在ROM 程序中,则表示执行了实际的程序。

证明执行路径的恒等关系

总而言之,可以采用如下的恒等关系定义程序:
\begin{aligned} &\mathsf{A}(x\omega) = \mathsf{A}(x) + \mathsf{setA}(x) \cdot (\mathsf{op}(x) - \mathsf{A}(x)), \\ &\mathsf{B}(x\omega) = \mathsf{B}(x) + \mathsf{setB}(x) \cdot (\mathsf{op}(x) - \mathsf{B}(x)), \\ &\mathsf{PC}(x\omega) = \mathsf{PC}(x) + 1 + \mathsf{jmpz}(x) \cdot (1 - \mathsf{op}(x) \cdot \mathsf{invOp}(x)) \cdot (\mathsf{addr}(x) - \mathsf{PC}(x) - 1), \\ &(1 - \mathsf{op}(x) \cdot \mathsf{invOp}(x)) \cdot \mathsf{op}(x) = 0. \end{aligned}
其中 \mathtt{op} 定义如下:
\mathsf{op}(x) := \mathsf{selA}(x) \cdot \mathsf{A}(x) + \mathsf{selB}(x) \cdot \mathsf{B}(x) + \mathsf{inFree}(x) \cdot \mathsf{free}(x) + \mathsf{const}(x).
还需要进行如下的 Plookup 检查:
\begin{aligned} &\textsf{const}(x) + 7 \subset \{0,1, \dots, 14\},\\ &\mathsf{addr}(x) \subset \{0,1, \dots, 15\},\\ &\mathsf{position}(x) \subset \{0,1, \dots, 15\},\\ &\mathsf{PC}(x) \subset \{0,1, \dots, 15\},\\ &\textsf{insTrace}(x) \subset \textsf{ROM}(x). \end{aligned}
相关的定义如下:
\begin{aligned} &\textsf{instruction}(x) := 2^{10}\cdot(\textsf{const}(x) + 7) + 2^6\cdot \textsf{addr}(x) + 2^5\cdot \textsf{jmpz}(x) + 2^4 \cdot \textsf{setB}(x) + \\ &\qquad \qquad \qquad \quad~~2^3 \cdot \textsf{setA}(x) + 2^2 \cdot \textsf{inFree}(x) + 2 \cdot \textsf{selB}(x) + \textsf{selA}(x),\\ &\textsf{ROM}(x) := 2^{14} \cdot \textsf{position}(x) + \textsf{instruction}(x), \\ &\textsf{insTrace}(x) := 2^{14} \cdot \textsf{PC}(x) + \textsf{instruction}(x). \end{aligned}
最后,还需要检查 selectors 是二进制的,即:
\begin{aligned} &\mathsf{selA}(x) \cdot (\mathsf{selA}(x) - 1) = 0, \quad \mathsf{setA}(x) \cdot (\mathsf{setA}(x) - 1) = 0, \quad\\ &\mathsf{selB}(x) \cdot (\mathsf{selB}(x)- 1) = 0, \quad \mathsf{setB}(x) \cdot (\mathsf{setB}(x) - 1) = 0, \quad\\ &\mathsf{inFree}(x) \cdot (\mathsf{inFree}(x) - 1) = 0, \quad \mathsf{jmpz}(x) \cdot (\mathsf{jmpz}(x) - 1) = 0. \end{aligned}
关于状态机中的多项式,需要承诺: \textsf{inFree}(x), \textsf{selA}(x), \textsf{selB}(x), \textsf{setA}(x), \textsf{setB}(x) \textsf{A}(x), \textsf{B}(x), \textsf{const}(x), \textsf{jmpz}(x), \textsf{invOp}(x), \textsf{addr}(x), \textsf{free}(x), \textsf{position}(x)\textsf{PC}(x).

\mathtt{ROM(x)} 是 唯一可能预处理的不变多项式。

模块化设计

分而治之

若要添加更多运算到状态机,例如乘法,可以添加列到状态机中,但这会导致设计更加复杂,且难以处理,可以采用分而治之的策略:

  • zkEVM 架构 由不同的状态机相互连接组成;
  • 每个状态机去证明指定的任务;
  • 不同状态机相关的列可以使用包含证明 (plookup)。

下面通过一个32位算术运算的状态机和主状态机的包含证明展示这个过程。

算术状态机

算术状态机可以对32位元素执行加,减,乘,除的运算,使用如下5个寄存器:
\mathcal{A}_i \cdot \mathcal{B}_i + \mathcal{C}_i = 2^{32} \mathcal{D}_i + \mathcal{E}_i.
可以用下多项式定义约束关系:
\mathcal{A}(x) \cdot \mathcal{B}(x) + \mathcal{C}(x) = 2^{32} \mathcal{D}(x) + \mathcal{E}(x).
注意还需要检查 \mathcal{A}(x), \mathcal{B}(x), \mathcal{C}(x),\mathcal{D}(x)H 处的值为32 位。

我们将设计一种检查这些操作的机制:
\tiny \begin{array}{|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|} \hline \textbf{set}\mathcal{A} & \textbf{set}\mathcal{B} & \textbf{set}\mathcal{C} & \textbf{set}\mathcal{D} & \textbf{set}\mathcal{E} & \textbf{latch} & \textbf{freeIn} & \mathcal{A} & \mathcal{A'} & \mathcal{B} & \mathcal{B'} & \mathcal{C} & \mathcal{C'} & \mathcal{D} & \mathcal{D'} & \mathcal{E} & \mathcal{E'}\\ \hline 1 & 0 & 0 & 0 & 0 & 0 & 0x0003 & 0 & 0x003 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\ \hline 0 & 1 & 0 & 0 & 0 & 0 & 0x0002 & 0x0003 & 0x0003 & 0 & 0x0002 & 0 & 0 & 0 & 0 & 0 & 0\\ \hline 0 & 0 & 1 & 0 & 0 & 0 & 0x0004 & 0x0003 & 0x0003 & 0x0002 & 0x0002 & 0 & 0x0004 & 0 & 0 & 0 & 0\\ \hline 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0x0003 & 0x0003 & 0x0002 & 0x0002 & 0x0004 & 0x0004 & 0 & 0 & 0 & 0\\ \hline 0 & 0 & 0 & 0 & 1 & 0 & 0x000a & 0x0003 & 0x0003 & 0x0002 & 0x0002 & 0x0004 & 0x0004 & 0 & 0 & 0 & 0x000a\\ \hline 1 & 0 & 0 & 0 & 0 & \mathbf{1} & 0x1111 & \mathbf{0x0003} & 0x1111 & \mathbf{0x0002} & 0x0002 & \mathbf{0x0004} & 0x0004 & \mathbf{0} & 0 & \mathbf{0x000a} & 0x000a\\ \hline 0 & 1 & 0 & 0 & 0 & 0 & 0x2222 & {0x1111} & 0x1111 & {0x0002} & 0x2222 & {0x0004} & 0x0004 & {0} & 0 & {0x000a} & 0x000a\\ \hline 0 & 0 & 1 & 0 & 0 & 0 & 0x3333 & {0x1111} & 0x1111 & {0x2222} & 0x2222 & {0x0004} & 0x3333 & {0} & 0 & {0x000a} & 0x000a\\ \hline 0 & 0 & 0 & 1 & 0 & 0 & 0x0246 & {0x1111} & 0x1111 & {0x2222} & 0x2222 & {0x3333} & 0x3333 & {0} & 0x0246 & {0x000a} & 0x000a\\ \hline 0 & 0 & 0 & 0 & 1 & 0 & 0xb975 & {0x1111} & 0x1111 & {0x2222} & 0x2222 & {0x3333} & 0x3333 & {0x0246} & 0x0246 & {0x000a} & 0xb975\\ \hline 1 & 0 & 0 & 0 & 0 & \mathbf{1} & 0x7777 & \mathbf{0x1111} & 0x7777 & \mathbf{0x2222} & 0x2222 & \mathbf{0x3333} & 0x3333 & \mathbf{0x0246} & 0x0246 & \mathbf{0xb975} & 0xb975\\ \hline ... & ... & ... & ... & ... & ... & ... & ... & ... & ... & ... & ... & ... & ... & ... & ... & ...\\ \hline \end{array}
使用 \mathtt{latch} 来标记需要检查 寄存器 \mathcal{A,B,C,D,E}之间的约束关系。 \textbf{set}\mathcal{A}, \textbf{set}\mathcal{B}, \textbf{set}\mathcal{C}, \textbf{set}\mathcal{D}, \textbf{set}\mathcal{E}\textbf{latch} 是不变的,即它们不依赖输入。

\mathtt{freeIn} 列的值需要承诺,\mathcal{A,B,C,D,E} 依赖 \mathtt{freeIn} , 也需要承诺。

因此算术状态机多项式恒等关系为:
\begin{aligned} \mathcal{A'} &= \mathbf{sel}\mathcal{A}\cdot(\mathbf{freeIn}-\mathcal{A}) + \mathcal{A} \\ \mathcal{B'} &= \mathbf{sel}\mathcal{B}\cdot(\mathbf{freeIn}-\mathcal{B}) + \mathcal{B} \\ \mathcal{C'} &= \mathbf{sel}\mathcal{C}\cdot(\mathbf{freeIn}-\mathcal{C}) + \mathcal{C} \\ \mathcal{D'} &= \mathbf{sel}\mathcal{D}\cdot(\mathbf{freeIn}-\mathcal{D}) + \mathcal{D} \\ \mathcal{E'} &= \mathbf{sel}\mathcal{E}\cdot(\mathbf{freeIn}-\mathcal{E}) + \mathcal{E} \\ 0 &= [ \mathcal{A} \cdot \mathcal{B} + \mathcal{C} - (2^{32} \mathcal{D} + \mathcal{E}) ] \cdot \mathbf{latch} \\ \mathbf{freeIn} &\subset byte4\end{aligned}
下图展示了算术状态机的架构图:

扩展主状态机

对于主状态机,可以将其扩展到5 个寄存器,添加一个arith 标记,用来连接算术状态机。 当arith 为1 的时候,需要检查算术化操作。整个设计如下图所示:

下图展示如何连接主状态机和算术状态机,当arith 为1的时候,需要确何算术表中的latch 为1。

因此,需要保证如下的包含关系:
[arith \cdot A , arith \cdot B , arith \cdot C , arith \cdot D, arith \cdot op] \subset [latch \cdot \mathcal{A} , latch \cdot \mathcal{B} , latch \cdot \mathcal{C} , latch \cdot \mathcal{D} , latch \cdot \mathcal{E}]
注: 使用\mathtt{op} 用来表示它包寄存器 \mathtt{E} 的值。

通过使用 Plookup作为总线,可以连接主状态机和其它具体的状态机:

由此可以设计一个模块化虚拟状态机,并通过零知识证明进行验证。

参考

https://docs.hermez.io/zkEVM/Basic-Concepts/introduction/

https://polygon.technology/solutions/polygon-zkevm

https://docs.hermez.io/

https://github.com/0xPolygonHermez/

https://blog.polygon.technology/the-future-is-now-for-ethereum-scaling-introducing-polygon-zkevm/?utm_source=ticker&utm_medium=website&utm_campaign=organic

https://ethresear.ch/t/proof-of-efficiency-a-new-consensus-mechanism-for-zk-rollups/11988

https://en.wikipedia.org/wiki/Fibonacci_number

相关文章

网友评论

      本文标题:Polygon zkEVM 状态机设计原理

      本文链接:https://www.haomeiwen.com/subject/wootnrtx.html