译自 halo2 book:https://zcash.github.io/halo2/design/proving-system/lookup.html
查表论证(Lookup argument)
Halo 2 使用以下查表技术,它允许在任意集合中进行查表,并且可以说比 Plookup 更简单。
关于术语的说明
除了关于术语的通用说明之外:
- 我们把 多项式(置换论证中的大乘积论证多项式,grand product argument polynomial)称为"置换乘积"(permutation product)列。
技术描述
为了便于讲解,我们先描述一个忽略零知识(zero knowledge)的简化版本论证。
我们用一个"子集论证"(subset argument)来表达查表,该论证作用于一张具有 行(从 0 开始编号)、含有列 和 的表格之上。
子集论证的目标是强制 中的每个单元格都等于 中的_某个_单元格。这意味着 中的多个单元格可以等于 中的_同一个_单元格,而 中的某些单元格不需要等于 中的任何单元格。
- 可以是固定的,但不必如此。也就是说,我们既支持在固定表中查值,也支持在变量表(后者包含建议列)中查值。
- 和 可以包含重复项。如果 和/或 所表示的集合的大小不天然为 ,我们就用重复项扩充 ,并用已知存在于 中的占位值(dummy value)扩充 。
- 或者,我们可以添加一个"查表选择子"(lookup selector),用来控制 列中的哪些元素参与查表。这会修改下面置换规则中 的出现:当某行未被选中进行查表时,把 替换为(例如)。
设 为拉格朗日基(Lagrange basis)多项式,它在第 行求值为 ,其余处为 。
我们先允许证明者提供 和 的置换列。分别称之为 和 。我们可以用一个带乘积列 的置换论证来强制它们确实是置换,规则如下:
即:只要不发生除以零的情况,对所有 我们有:
这是置换论证的一个版本,它允许 和 分别是 和 的置换,但并不指定具体的置换。 和 是两个独立的挑战(challenge),这样我们就可以把这两个置换论证合并为一个,而不必担心它们彼此干扰。
这些置换的目标,是允许证明者以特定方式排列 和 :
- 列中的所有单元格被排列成:取值相同的单元格在竖直方向上相邻。这可以通过某种排序算法完成,但真正重要的只是:取值相同的单元格在 列中位于连续的行上,且 是 的一个置换。
- 在 中一段相同取值的序列里,第一行就是 中具有相应取值的那一行。除此约束之外, 可以是 的任意置换。
现在,我们用如下规则来强制要么 ,要么 :
此外,我们用如下规则强制 :
(尽管 会"绕回",这里第一条规则中的 项在第 行也不起作用,因为有第二条规则。)
这些约束合在一起,有效地强制 (从而 )中的每个元素都至少等于 (从而 )中的一个元素。证明:对各行前缀做归纳。
零知识调整
为了让基于 PLONK 的证明系统实现零知识,我们需要把每一列的最后 行填充为随机值。这要求对查表论证作出调整,因为这些随机值并不满足上面描述的约束。
我们把可用行(usable row)的数量限制为 。我们添加两个选择子:
- 在最后 行上置为 ,其余处为 ;
- 仅在第 行置为 ,其余处为 (即它被置于可用行与盲化行之间的那一行)。
我们仅对可用行启用上面的约束:
在第 行启用的规则保持不变:
由于我们不能再依赖绕回(wraparound)来保证乘积 在 处重新变为 ,我们改为需要把 约束为 。然而,这里存在一个潜在困难:如果对某个 , 或 中有任何一个为零,那么可能无法满足置换论证。这种情况在 和 的选择上以可忽略的概率发生,但它既是实现完美零知识的障碍(因为对手可以排除掉会导致这种情况的见证值),也是实现完美完备性(perfect completeness)的障碍。
为了同时确保完美完备性和完美零知识,我们允许 取零或一:
现在,如果对某个 , 或 为零,我们就可以对 设 ,从而满足约束系统。
注意,挑战 和 是在对 和 (以及 和 )做出承诺之后才选定的,因此证明者无法强行制造出某个 或 为零的情况。由于这种情况以可忽略的概率发生,可靠性(soundness)不受影响。
开销
- 有原始列 和固定列 。
- 有一个置换乘积列 。
- 有两个置换 和 。
- 这些门的次数(degree)都很低。
推广
Halo 2 的查表论证实现以如下方式推广了上述技术:
- 和 可以扩展为多列,并用一个随机挑战组合起来。 和 仍保持为单列。
- 对 各列的承诺可以预先计算,然后在挑战已知后,利用 Pedersen 承诺的同态(homomorphic)性质廉价地组合起来。
- 的各列可以用相对引用以任意多项式表达式给出。这些表达式会被代入乘积列约束中,但要受最大次数界(maximum degree bound)的限制。这有可能节省一个或多个建议列。
- 然后,任意宽度关系的查表论证可以用子集论证来实现,即:为了在每一行约束 ,把 看作一个元组集合 (使用上一点的方法),并检查 。
- 在 表示一个函数的情况下,这隐式地也检查了输入是否在定义域内。这通常正是我们想要的,且常常能省掉一次额外的范围检查(range check)。
- 我们可以在同一个电路中支持多张表,办法是把它们合并成单张表,其中包含一个标签列(tag column)来标识原始表。
- 如果前面提到的"查表选择子"得以实现,标签列可以与之合并。
这些推广与 Plookup 论文第 4、5 节中的推广类似。也就是说,与 Plookup 的差异在于子集论证。这一论证随后可以用于所有相同的用途;例如,Plookup 论文第 5 节中优化的范围检查技术也可以与这个子集论证一起使用。