Hermez zkEVM

本文主要对Hermez 2.0 zkEVM设计思路进行简单介绍。

Fibonacci 状态机

先从Fibonacci状态机示例开始,Fibonacci是一个序列,可以通过两个寄存器A和B表示的状态机:

Fibonacci Sequence

初始条件为: , 并且寄存器的状态满足以下关系:

可以将寄存器的状态表示为多项式, 定义域为 为 上的8次单位根。可以得到以下关系:

将寄存器状态进一步表示为恒等关系式为:

但是这个恒等关系并不完全成立:

  • 寄存器是非循环的,当在 估值时:

  • 可以改变初始条件,例如 , 同样满足恒等关系。

为了解决这些问题,可以添加一个辅助寄存器C:

Fibonacci Sequence Aux

C 对应的多项式为:

通过辅助寄存器, 新的多项式恒等关系为:

当时, 恒等关系满足:

若初始条件为: , 多项式恒等关系为:

上例中:

状态机证明

Polynomial Commitment

多项式关系可以通过多项式承诺证明,例如 Kate 和基于FRI的承诺。

多项式承诺满足 bindinghiding的关系。

简单的状态机

状态机可以表示为下图过程:

image

下述汇编指令表示带有两个寄存器 A 和 B, 接受一个外部输入:

其中:

  • : 将一个输入的值保存到寄存器 X;
  • : 将一个常量移动到寄存器 X ;
  • : 将寄存器 A 和 B的值加在一起,将输入保存到寄存器 A 中;

当输入为7的时候,执行的路径为:
\begin{array}{|l|c|c|c|c|c|} \hline \mathbf{Instruction} & \mathbf{freeIn} & \mathbf{A} & \mathbf{A^{+1}} & \mathbf{B} & \mathbf{B^{+1}} \\ \hline \mathbf{FREELOAD}~~A & 7 & 0 & 7 & 0 & 0 \\ \hline \mathbf{MOV}~~B~3 & 0 & 7 & 7 & 0 & 3 \\ \hline \mathbf{ADD}~~A~B & 0 & 7 & 10 & 3 & 3 \\ \hline \mathbf{STOP} & 0 & 10 & 0 & 3 & 0 \\ \hline \end{array}
在上述的指令中, 表示寄存器 的下一步的状态。

指令会重置状态的值。

可以在脱离指令的情况下,通过一系列值推导寄存器的下一个状态。此时,需要添加辅助状态和选择子(selectors)来表示这种关系。寄存器 A 和 B 更新的状态是辅助寄存器和选择子的线性关系,如下图所示:

image

其中:

  • : 选择子,用以包含寄存器 是否在线性组合中;
  • : 选择子,以表示是否将线性组合的结果保存到寄存器 中;
  • : 包含执行程序的输入;
  • : 包含指令的固定值。

通过引入输助变量,可以得到下述的表格:
\scriptsize \begin{array}{|l|} \hline \mathbf{Instruction} \\ \hline \mathbf{FREELOAD}~~A \\ \hline \mathbf{MOV}~~B~3 \\ \hline \mathbf{ADD}~~A~B \\ \hline \mathbf{STOP} \\ \hline \end{array} \hspace{0.1cm} \begin{array}{|c|c|c|c|c|c|c|c|} \hline \textbf{freeIn} & \textbf{const} & \textbf{setB} & \textbf{setA} & \textbf{inFreeIn} & \textbf{inB} & \textbf{inA} \\ \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 \mathbf{A} & \mathbf{A^{+1}} & \mathbf{B} & \mathbf{B^{+1}} \\ \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} &\mathsf{A_{i+1}} = \mathsf{A_i} + \mathsf{setA_i} \cdot (\mathsf{inA_i} \cdot \mathsf{A_i} + \mathsf{inB_i} \cdot \mathsf{B_i} + \mathsf{inFreeIn}_i \cdot \mathsf{freeIn_i} + \mathsf{const_i} - \mathsf{A_i}), \\ &\mathsf{B_{i+1}} = \mathsf{B_i} + \mathsf{setB_i} \cdot (\mathsf{inA_i} \cdot \mathsf{A_i} + \mathsf{inB_i} \cdot \mathsf{B_i} + \mathsf{inFreeIn}_i \cdot \mathsf{freeIn_i} + \mathsf{const_i} - \mathsf{B_i}). \end{aligned}
可以将寄存器状态表示为四步的多项式 , 定义域为: , 可以定义一个循环关系:
\begin{aligned} &\mathsf{A}(x\omega) = \mathsf{A}(x) + \mathsf{setA}(x) \cdot (\mathsf{inA}(x) \cdot \mathsf{A}(x) + \mathsf{inB}(x) \cdot \mathsf{B}(x) + \mathsf{inFreeIn}(x) \cdot \mathsf{freeIn}(x) + \mathsf{const}(x) - \mathsf{A}(x)), \\ &\mathsf{B}(x\omega) = \mathsf{B}(x) + \mathsf{setB}(x) \cdot (\mathsf{inA}(x) \cdot \mathsf{A}(x) + \mathsf{inB}(x) \cdot \mathsf{B}(x) + \mathsf{inFreeIn}(x) \cdot \mathsf{freeIn}(x) + \mathsf{const}(x) - \mathsf{B}(x)). \end{aligned}
则程序执行完全由常量(公开)多项式: 和 表示。

多项式 可以公开的承诺的多项式,对于同一个程序,可以在不同的初始条件下进行执行。

在上述程序中,执行结果为 。

选择条件

下面将在汇编程序中添加 指令,若执行操作为0, 将会跳到指定的位置。

在下面的程序中, 会跳到位置 4 ,若 为0的话。
\begin{array}{|c|l|} \hline \textbf{Position} & \mathbf{Instruction} \\ \hline 0 & \mathbf{FREELOAD}~~A \\ \hline 1 & \mathbf{MOV}~~B~-3 \\ \hline 2 & \mathbf{ADD}~~A~B,~\mathbf{JMPIZ}~~4 \\ \hline 3 & \mathbf{ADD}~~A~B \\ \hline 4 & \mathbf{STOP} \\ \hline \end{array}
当出现条件语句的时候,执行路径的长度不是固定的,依赖于 公开输入:
\scriptsize \begin{array}{|l|c|c|c|c|c|} \hline \mathbf{Instruction} & \mathbf{freeIn} & \mathbf{A} & \mathbf{A^{+1}} & \mathbf{B} & \mathbf{B^{+1}} \\ \hline \mathbf{FREELOAD}~~A & 7 & 0 & 7 & 0 & 0 \\ \hline \mathbf{MOV}~~B~-3 & 0 & 7 & 7 & 0 & -3 \\ \hline \mathbf{ADD}~~A~B,~\mathbf{JMPIZ}~~4 & 0 & 7 & 4 & -3 & -3 \\ \hline \mathbf{ADD}~~A~B & 0 & 4 & 1 & -3 & -3 \\ \hline \mathbf{STOP} & 0 & 1 & 0 & -3 & 0 \\ \hline \end{array}

\scriptsize \begin{array}{|l|c|c|c|c|c|} \hline \mathbf{Instruction} & \mathbf{freeIn} & \mathbf{A} & \mathbf{A^{+1}} & \mathbf{B} & \mathbf{B^{+1}} \\ \hline \mathbf{FREELOAD}~~A & 3 & 0 & 3 & 0 & 0 \\ \hline \mathbf{MOV}~~B~-3 & 0 & 3 & 3 & 0 & -3 \\ \hline \mathbf{ADD}~~A~B,~\mathbf{JMPIZ}~~4 & 0 & 3 & 0 & -3 & -3 \\ \hline \mathbf{STOP} & 0 & 0 & 0 & -3 & 0 \\ \hline \end{array}

第一执行步骤是5步,每二个是4步。

管理条件选择

可以引入一种新的模型,管理条件选择(conditional jump):

image

上述添加了 , PC是一种特别的寄存器,包含程序执行指定的位置。

使用 表示状态机的线性组合,用以简化约束条件的描述,如下所示:

image

若 为0, 指令将会跳到地址. 下面将介绍 如何检查 是否为0.

为了检查域 的某个元素是否为0, 可以通过 是否有逆元素判断 。若 , 有一个乘法逆元。

因此可以使用下述定义,限制 检查。

可以把这两个方程合成一个约束:

可以引入下述机制以引入 jumps:

image

上述添加一个选择子 , 以编码 指令,并表述 的行为。则约束集合如下所示:
\begin{aligned} & \mathsf{op_i} := \mathsf{inA_i}\cdot \mathsf{A_i}+\mathsf{inB_i}\cdot B_i+\mathsf{inFreeIn_i}\cdot \mathsf{freeIn_i}+const_i, \\ & PC_{i+1} =PC_i + 1 +selJMPIZ_i\cdot (1 - op_i\cdot op_i^{-1})\cdot(addr_i -PC_i-1), \\ & (1-\mathsf{op_i}\cdot \mathsf{op_i^{-1}})\cdot \mathsf{op_i}=0. \end{aligned}
由以上可知:

  • 若 , 则 ;
  • 若 , 则 .

则公开输入为分别为7 和 3的时候,执行路径分别为:
\tiny \begin{array}{|l|} \hline \mathbf{Instruction} \\ \hline \mathbf{FREELOAD}~~A \\ \hline \mathbf{MOV}~~B~-3 \\ \hline \mathbf{ADD}~~A~B,~\mathbf{JMPIZ}~~4 \\ \hline \mathbf{ADD}~~A~B \\ \hline \mathbf{STOP} \\ \hline \end{array} \hspace{0.1cm} \begin{array}{|c|c|c|c|c|c|c|c|c|c|c|} \hline \textbf{freeIn} & \textbf{const} & \textbf{addr} & \textbf{selJMPIZ} & \textbf{setB} & \textbf{setA} & \textbf{inFreeIn} & \textbf{inB} & \textbf{inA} & \textbf{op} & \textbf{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 & 4 & 1 & 0 & 1 & 0 & 1 & 1 & \mathbf{\color{blue!75!black} 4} & \mathbf{\color{blue!75!black} 4^{-1}} \\ \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 \mathbf{PC} & \mathbf{PC^{+1}} & \mathbf{A} & \mathbf{A^{+1}} & \mathbf{B} & \mathbf{B^{+1}} \\ \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 & 1 & -3 & -3\\ \hline 4 & 0 & 1 & 0 & -3 & 0\\ \hline \end{array}

\tiny \begin{array}{|l|} \hline \mathbf{Instruction} \\ \hline \mathbf{FREELOAD}~~A \\ \hline \mathbf{MOV}~~B~-3 \\ \hline \mathbf{ADD}~~A~B,~\mathbf{JMPIZ}~~4 \\ \hline \mathbf{STOP} \\ \hline \end{array} \hspace{0.1cm} \begin{array}{|c|c|c|c|c|c|c|c|c|c|c|c|} \hline \textbf{freeIn} & \textbf{const} & \textbf{addr} & \textbf{selJMPIZ} & \textbf{setB} & \textbf{setA} & \textbf{inFreeIn} & \textbf{inB} & \textbf{inA} & \textbf{op} & \textbf{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 & 4 & 1 & 0 & 1 & 0 & 1 & 1 & \mathbf{\color{blue!75!black} 0} & \mathbf{\color{blue!75!black} \alpha} \\ \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 \mathbf{PC} & \mathbf{PC^{+1}} & \mathbf{A} & \mathbf{A^{+1}} & \mathbf{B} & \mathbf{B^{+1}} \\ \hline 0 & 1 & 0 & 3 & 0 & 0\\ \hline 1 & 2 & 3 & 3 & 0 & -3\\ \hline 2 & 4 & 3 & 0 & -3 & -3\\ \hline 4 & 0 & 0 & 0 & -3 & 0\\ \hline \end{array}

其中 列 表示为 的逆。

并且 是非常重要的寄存器,因为它可以修改指令序列的执行方式。

目前多项式没有经过预处理,表格的值不仅依赖于程序,还依赖输入的值。因此,需要保证待验证的程序是正确的。

程序执行的证明

目前为止,可以证明每个指令都正确执行,但是怎么证明正确执行了指定的程序指令?需要检查每个执行的指令在我们的程序中,但是如何简洁实现这种证明方式?

为了实现这个目标,我们提供了每个指令的编码方式,并且检查每个执行指令的编码确实在程序的指令中。

首先来展示如何对指令编码,作为一个简单示例, 采用4位编码一个指令(实际中可能需要32位编码),4位编码如下所示:
\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}
去掉数值 , 采用 -7 到 7的范围,可以编码 的域元素为:
\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}
因此可以约束

可以约束上述的条件为:

直接以2为底表示 , 以避免sum 运算。

下面将介绍 如何编码程序执行的每个一指令。
\scriptsize \begin{array}{|c|l|} \hline \mathbf{Instruction} \\ \hline \mathbf{FREELOAD}~~A \\ \hline \mathbf{MOV}~~B~-3 \\ \hline \mathbf{ADD}~~A~B,~\mathbf{JMPIZ}~~4 \\ \hline \mathbf{ADD}~~A~B \\ \hline \mathbf{STOP} \\ \hline \end{array} \hspace{0.1cm} \begin{array}{|c|c|c|c|c|c|c|c|c|c|c|} \hline \mathbf{\color{blue!75!black} \textbf{const+7}} & \textbf{addr} & \textbf{selJMPIZ} & \textbf{setB} & \textbf{setA} & \textbf{inFreeIn} & \textbf{inB} & \textbf{inA} & \textbf{instruction code} \\ \hline \mathbf{\color{blue!75!black} 7} & 0 & 0 & 0 & 1 & 1 & 0 & 0 & 0111.0000.001100 \\ \hline \mathbf{\color{blue!75!black} 4} & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0100.0000.010000 \\ \hline \mathbf{\color{blue!75!black} 7} & 4 & 1 & 0 & 1 & 0 & 1 & 1 & 0111.0100.101011 \\ \hline \mathbf{\color{blue!75!black} 7} & 0 & 0 & 0 & 1 & 0 & 1 & 1 & 0111.0000.001011 \\ \hline \mathbf{\color{blue!75!black} 7} & 0 & 1 & 1 & 1 & 0 & 0 & 0 & 0111.0000.111000 \\ \hline \end{array}
可以通过下面的规则编码指令:
\textsf{instruction}_i := 2^{13}\cdot(\textsf{const}_i + 7) + 2^9\cdot \textsf{addr}_i + 2^5\cdot \textsf{selJMPIZ}_i + 2^4 \cdot \textsf{setB}_i + 2^3 \cdot \textsf{setA}_i + 2^2 \cdot \textsf{inFreeIn}_i + 2 \cdot \textsf{inB}_i + \textsf{inA}_i.
另外,需要检查 选择子是二进制的,由4位组成,即

当 , 其表示 .

为了证明该程序,每个指令通过其代码和位置唯一识别,上例中采用4位来表示位置。

定义 , 由每个指令和位置来定义表示:

因此相应的 表示为:
\begin{array}{|c|c|} \hline \textbf{Position} & \mathbf{Instruction} \\ \hline 0 & \mathbf{FREELOAD}~~A \\ \hline 1 & \mathbf{MOV}~~B~-3 \\ \hline 2 & \mathbf{ADD}~~A~B,~\mathbf{JMPIZ}~~4 \\ \hline 3 & \mathbf{ADD}~~A~B \\ \hline 4 & \mathbf{STOP} \\ \hline \end{array} \hspace{0.1cm} \begin{array}{|c|} \hline \textbf{ROM} \\ \hline 0000.0111.0000.001100 \\ \hline 0001.0100.0000.010000 \\ \hline 0010.0111.0100.101011 \\ \hline 0011.0111.0000.001011 \\ \hline 0100.0111.0000.111000 \\ \hline \end{array}
我们可以采用 来编码程序路径:
\scriptsize \begin{array}{|c|c|c|c|c|c|} \hline \mathbf{PC} \\ \hline 0 \\ \hline 1 \\ \hline 2 \\ \hline 3 \\ \hline 4 \\ \hline \end{array} \hspace{0.1cm} \begin{array}{|c|c|c|} \hline \mathbf{Instruction} \\ \hline \mathbf{FREELOAD}~~A \\ \hline \mathbf{MOV}~~B~-3 \\ \hline \mathbf{ADD}~~A~B,~\mathbf{JMPIZ}~~4 \\ \hline \mathbf{ADD}~~A~B \\ \hline \mathbf{STOP} \\ \hline \end{array} \hspace{0.1cm} \begin{array}{|c|c|c|c|c|c|c|c|c|} \hline \textbf{const+7} & \textbf{addr} & \textbf{selJMPIZ} & \textbf{setB} & \textbf{setA} & \textbf{inFreeIn} & \textbf{inB} & \textbf{inA} \\ \hline 7 & 0 & 0 & 0 & 1 & 1 & 0 & 0 \\ \hline 4 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\ \hline 7 & 4 & 1 & 0 & 1 & 0 & 1 & 1 \\ \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 \mathbf{insTrace} \\ \hline 0000.0111.0000.001100 \\ \hline 0001.0100.0000.010000 \\ \hline 0010.0111.0100.101011 \\ \hline 0011.0111.0000.001011 \\ \hline 0100.0111.0000.111000 \\ \hline \end{array}

\scriptsize \begin{array}{|c|c|c|c|c|c|} \hline \mathbf{PC} \\ \hline 0 \\ \hline 1 \\ \hline 2 \\ \hline 4 \\ \hline \end{array} \hspace{0.1cm} \begin{array}{|c|c|c|} \hline \mathbf{Instruction} \\ \hline \mathbf{FREELOAD}~~A \\ \hline \mathbf{MOV}~~B~-3 \\ \hline \mathbf{ADD}~~A~B,~\mathbf{JMPIZ}~~4 \\ \hline \mathbf{STOP} \\ \hline \end{array} \hspace{0.1cm} \begin{array}{|c|c|c|c|c|c|c|c|c|c|} \hline \textbf{const+7} & \textbf{addr} & \textbf{selJMPIZ} & \textbf{setB} & \textbf{setA} & \textbf{inFreeIn} & \textbf{inB} & \textbf{inA} \\ \hline 7 & 0 & 0 & 0 & 1 & 1 & 0 & 0 \\ \hline 4 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\ \hline 7 & 4 & 1 & 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 \mathbf{insTrace} \\ \hline 0000.0111.0000.001100 \\ \hline 0001.0100.0000.010000 \\ \hline 0010.0111.0100.101011 \\ \hline 0100.0111.0000.111000 \\ \hline \end{array}

其中 指令 设置 值为0, 使这个多项式构成循环。

那该如何检查执行了指定的程序了呢?

这时可以采用Plookup协议,检查对应的项目被正确有执行,采用Plookup 检查:

由此表明, 若指令的trace 包含在程序的ROM中,则执行的指令是实际的程序。

证明执行路径的恒等式

\begin{aligned} & A(x\omega) = A(x) + setA(x)\cdot (op(x)-A(x)), \\ & B(x\omega)=B(x)+ setB(x)\cdot(op(x)-B(x)), \\ & PC(x\omega)=P(x) + 1 + selJMPIZ(x)\cdot (1-op(x)\cdot invOp(x))\cdot(addr(x)-PC(x)-1), \\ & (1-op(x)\cdot invOp(x))\cdot op(x)=0. \end{aligned}

其中:

并且,我们还需要添加下述的检查:
$$
\begin{aligned}
& const(x) + 7 \subset {0,1,\cdots,14}, \
& addr(x) \subset {0,1,\cdots, 15}, \
& position(x)\subset {0,1,\cdots, 15}, \
& PC(x) \subset {0,1,\cdots, 15}, \
& insTrace(x) \subset \mathsf{ROM}(x).

\end{aligned}

\begin{aligned}
& \textsf{instruction}(x) := 2^{13}(\textsf{const(x)}+7)+ 2^9 \cdot addr(x) + 2^5\cdot \textsf{selJMPIZ}(x)+ 2^4\cdot \textsf{setB}(x) + 2^3\cdot \textsf{setA}(x)+ 2^2\cdot \textsf{inFreeIn}(x)+ 2\cdot \textsf{inB}(x) + \textsf{inA}(x), \
& \textsf{ROM}(x) := 2^{17} \cdot \textsf{position}(x) + \textsf{instruction}(x), \
& \textsf{insTrace}(x):= 2^{17}\cdot \textsf{PC(x)} + \textsf{instruction}(x).
\end{aligned}
$$

最后,需要检查一系列选择子是二进制的,即:

\textsf{inA}(x)\cdot(\textsf{inA}(x)-1)=0, \textsf{setA}(x)\cdot(\textsf{setA}(x)-1)=0, \\ \textsf{inB}(x)\cdot (\textsf{inB}(x)-1)=0, \textsf{setB}(x)\cdot(\textsf{setB}(x)-1)=0, \\ \textsf{inFreeIn}(x)\cdot(\textsf{inFreeIn(x)}-1)=0, \textsf{selJMPIZ}(x)\cdot(\textsf{selJMPIZ}(x)-1)=0.
关于状态机中的多项式:

  • 需要对多项式 和 进行承诺;
  • 惟一需要预处理的多项式为:

模块化设计

分而治之

对上面的思路进一步扩展,例如要处理乘法运算。

可以通过增加列的方式, 来表述这这些运算,但是这将导致设计异常复杂难以处理。 但是我们可以采用divide and conquer 策略:

  • zk-EVM 架构由多个不同的相互连接的状态机构成;
  • 每个状态机证明其相应任务的执行路径;
  • 不同状态机的相关列多项式通过 inclusion proofs 关联在一起(采用plookup)。

下面将通过一个示例展现这个过程:

  • 设计一个状态机 执行32位的数值操作;
  • 通过inclusion proof 将该状态机和主状态机连在一起。

数值状态机

数值状态机能够执行32位的 sum, substraction, multiplication, division的运算, 采用如下所示的5个寄存器:

可以将上述关系表示为一个在子群 上的循环多项式的恒等式,即:

注意需要约束 在 定义域 的值为 32 bit.

设计如下状态机检查 上述的操作:
\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}
其中 用于表示寄存器 的下一个状态。采用 表示是否已准备好检查 实际的值。

其中 并不依赖输入,是不变的。

用于包含数值操作的一些值。

因此,定义数值状态机的多项式恒等式如下所示:
\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'} &= \mathcal{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}
因为 的值都来源于 , 所以有检查约束条件: . 下图展示了数值状态机的设计图:

image

扩展主状态机

基于主状态机,可以将 其扩展5个寄存器,添加一个arith 标签,将数值状态机边上主状态机。当airth 标签为1的时候,允许检查 数值运算。整体的设计图如下所示:

image

下图展示了如何连接两个状态机,关键点在于当 flag 值为1时,需要确何寄存器的值当 值为1时 在数值表中存在,即数值表的约束条件成立。因为,需要保证以下包含关系:

image

[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}]
从下图可以看出,我们采用Plookup 连接主状态机和其它具体的状态机。

image

它可以允许以模块化方式设计虚拟状态机,最后采用零知识证明技术验证。

参考

https://docs.hermez.io/zkEVM/architecture/introduction/

https://eprint.iacr.org/2020/315.pdf

你可能感兴趣的:(Hermez zkEVM)