文章

09. Plonky2:Goldilocks、宽门 PLONK 与 FRI 多项式测试

09. Plonky2:Goldilocks、宽门 PLONK 与 FRI 多项式测试

版本口径:协议公式主要对应 Polygon Zero 的 2022 年 Plonky2 技术稿;实现参数对应已弃用仓库主分支快照 5d9da5a。二者不一致处会显式指出。

1. 先把名字说准确

Plonky2 不是“原始 PLONK 换了一套 Rust 实现”,也不是传统意义上以 KZG 为后端的 PLONK。

更准确的分层是:

1
2
3
4
5
6
7
8
9
10
11
关系 / 程序
  ↓
宽 trace 上的 PLONKish custom gates
  ↓
PLONK permutation argument 处理 copy constraints
  ↓
约束合并与 quotient identity
  ↓
基于 Merkle + FRI 的批量多项式测试
  ↓
Fiat–Shamir 非交互化

因此:

\[\boxed{ \text{Plonky2} = \text{PLONKish arithmetization} + \text{DEEP/FRI-style polynomial testing}. }\]

它从 PLONK 继承的是:

  • 一行一个 gate instance 的电路视图;
  • wire columns、selector/constants;
  • permutation grand product;
  • quotient polynomial identity;
  • 随机点 $\zeta$ 上的约束检查。

它没有采用经典 PLONK 的 KZG opening,而是:

  • 对低度扩展后的 evaluation vectors 建 Merkle tree;
  • 用 FRI 检查承诺向量接近低次多项式;
  • 用 DEEP quotient 把“声称的点值”绑定到这些向量。
flowchart LR
    A["CircuitBuilder<br/>变量与 copy constraints"] --> B["宽 PLONKish trace<br/>custom gates"]
    B --> C["wire / selector / sigma 多项式"]
    C --> D["permutation Z<br/>partial products"]
    D --> E["约束随机合并 C_j"]
    E --> F["quotient q_j = C_j / Z_H"]
    F --> G["LDE + Merkle caps"]
    G --> H["DEEP batch + FRI"]
    H --> I["非交互 argument"]

2. Goldilocks 域为什么是核心选择

2.1 模数

Plonky2 的基础域是

\[\mathbb F_p, \qquad p=2^{64}-2^{32}+1.\]

这个素数通常称为 Goldilocks prime。它同时满足:

  1. 域元素可装进一个 64-bit word;
  2. $p-1=2^{32}(2^{32}-1)$,有很大的二次幂子群;
  3. 模数的特殊形状使 128-bit 乘积能快速约减。

\[p=2^{64}-2^{32}+1\]

可得

\[2^{64}\equiv 2^{32}-1\pmod p\]

以及

\[2^{96} =2^{32}2^{64} \equiv 2^{32}(2^{32}-1) =2^{64}-2^{32} \equiv -1 \pmod p.\]

2.2 128-bit 乘积的特殊约减

把一个不超过 128 bit 的整数写为

\[n=n_0+2^{64}n_1+2^{96}n_2,\]

其中 $n_0$ 为低 64 bit,$n_1,n_2$ 各为 32 bit。则

\[\begin{aligned} n &\equiv n_0+(2^{32}-1)n_1-n_2 \pmod p. \end{aligned}\]

右侧只需:

  • 位移;
  • 加减;
  • 根据 carry/borrow 做一次条件修正。

这比对任意 64-bit 素数做通用 Montgomery reduction 更贴近 CPU 原生指令。真正的性能还取决于 lazy reduction、SIMD、内存布局与具体微架构;“模数形状好”不是单独的 benchmark 结论。

2.3 二进制 FFT 友好性

因为

\[2^{32}\mid p-1,\]

$\mathbb F_p^*$ 中存在阶为 $2^{32}$ 的元素,所以可直接构造最大规模 $2^{32}$ 的 two-adic 乘法子群。

对大小为 $N=2^m$、$m\le 32$ 的 trace,可选择

\[H=\langle\omega\rangle, \qquad |H|=N,\]

并通过 radix-2 FFT 做:

  • 插值;
  • low-degree extension;
  • quotient-domain evaluation;
  • FRI folding 所需的 coset 运算。

这说明 Goldilocks 的优势不是只有“64 bit 小域”,而是:

\[\boxed{ \text{小字长} + \text{特殊约减} + \text{高 two-adicity}. }\]

2.4 为什么还需要扩域

64-bit 基础域不足以让每个随机线性组合错误都自动小到可忽略。Plonky2 在需要较大 challenge space 的位置使用二次扩域

\[\mathbb E = \mathbb F_p[\varphi]/(\varphi^2-7).\]

任意扩域元素写为

\[a+b\varphi, \qquad a,b\in\mathbb F_p, \qquad \varphi^2=7.\]

其乘法为

\[(a+b\varphi)(c+d\varphi) = (ac+7bd)+(ad+bc)\varphi.\]

扩域大小约为

\[|\mathbb E|=p^2\approx 2^{128}.\]

这里必须区分两件事:

  • trace、Merkle leaves、FFT 的大部分工作仍在基础域 $\mathbb F_p$;
  • $\zeta$、FRI folding challenges 等关键随机量可落在 $\mathbb E$。

这种“基础域做吞吐、扩域买 soundness”的分工后来也成为许多 small-field STARK 的常见设计。

3. 从三列 PLONK 到 135 列宽 trace

3.1 一行不是固定的加乘门

经典 PLONK 常用三列 $a,b,c$ 和一个类似

\[q_Mab+q_La+q_Rb+q_Oc+q_C=0\]

的通用门。

Plonky2 更接近 TurboPLONK:每一种 gate 可以声明若干多项式约束。例如 division gate 用 wires

\[(w_1,w_2,w_3,w_4)=(x,y,q,i)\]

并约束

\[w_3w_2-w_1=0, \qquad w_2w_4-1=0.\]

第二个约束同时保证 $y\ne0$,因为 witness 必须给出 $i=y^{-1}$。

3.2 源码默认宽度

最终仓库的 standard_recursion_config 配置为:

参数含义
num_wires135每行总 wire 数
num_routed_wires80参加 permutation argument 的 wires
advice wires55不参加 copy permutation 的局部辅助 wires
num_constants2每行可用常量列数
num_challenges2对小域 soundness 子协议的并行挑战数
max_quotient_degree_factor8quotient degree factor 上限
zero_knowledgefalse标准递归配置本身不启用 ZK

因此常见的“Plonky2 有 135 列”还不完整。更重要的是

\[135=80\text{ routed}+55\text{ advice}.\]

3.3 routed wire 与 advice wire

若两个远处 cells 必须相等,builder 添加 copy constraint:

\[w_j(\omega^r)=w_k(\omega^s).\]

这两个位置必须是 routed wires,因为它们会进入 permutation argument。

而某个 gate 内部独占的中间量,例如:

  • $y^{-1}$;
  • Poseidon 某一轮 S-box 的中间值;
  • 插值的临时乘积;

若不需要连接到别行,可放在 advice wire。这样能减少:

  • $\sigma_j$ permutation polynomials 数量;
  • grand-product 每行的乘积宽度;
  • opening 数量;
  • verifier 工作。

advice 并不是“不受约束”。它仍必须满足本行 gate equations,只是不参与全局 wiring permutation。

flowchart TB
    subgraph ROW["某个 gate row"]
        R1["routed wire<br/>可连到远处 cell"]
        R2["routed wire<br/>进入 permutation"]
        A1["advice wire<br/>仅由本行约束"]
        A2["advice wire<br/>不进入 permutation"]
    end
    R1 --> P["copy-permutation argument"]
    R2 --> P
    A1 --> G["custom-gate equations"]
    A2 --> G
    R1 --> G
    R2 --> G

4. 一个 selector 如何复用给多个 gate

4.1 直接 one-hot selector 的问题

若有 $k$ 种 custom gates,为每种 gate 各放一个 selector polynomial

\[s_j(\omega^i)\in\{0,1\}\]

会增加 $k$ 个预处理多项式和 opening 负担。

4.2 gate 编号 selector

对一组 gates $G$,可用一个 selector $S(X)$ 编码当前行的全局 gate index。记 gate $g_j$ 的 index 为 $j$:

\[S(\omega^i)=j \quad\Longleftrightarrow\quad \text{第 }i\text{ 行使用 }g_j.\]

若整个电路只需要一个 selector polynomial,则每一行都属于这个唯一 group。要只激活 $g_j$,可构造 filter(与源码只差一个整体符号):

\[F_j(S) = \prod_{\substack{k\in G\\k\ne j}} (S-k), \qquad \deg_S F_j=|G|-1.\]

但当源码把 gates 分成两个或更多 selector groups 时,属于其他 group 的行在本 group 的 selector 中不取某个 gate index,而取哨兵值

\[u=\texttt{UNUSED\_SELECTOR}.\]

因此多 group 情形必须再加入一个零点:

\[\boxed{ F_j(S) = (S-u) \prod_{\substack{k\in G\\k\ne j}} (S-k), \qquad \deg_S F_j=|G|. }\]

于是:

  • 当 $S(\omega^i)=k\ne j$ 时,乘积中出现零因子;
  • 多 group 时,当该行属于其他 group、$S(\omega^i)=u$ 时,额外因子关闭本组所有 gates;
  • 当 $S(\omega^i)=j$ 时,$F_j(S(\omega^i))\ne0$。

若 gate $g_j$ 的第 $\ell$ 个约束为 $C_{j,\ell}$,实际约束是

\[F_j(S(X))C_{j,\ell}(X)=0 \quad\text{on }H.\]

4.3 为什么还要把 gates 分组

若原 gate constraint 的 formal degree 为 $d_j$,selector 本身作为一个已承诺 polynomial 代入后,filtered constraint 的 formal degree 上界分两种情况:

\[\deg\bigl(F_j(S(X))C_{j,\ell}(X)\bigr) \le \begin{cases} d_j+|G|-1, &\text{只有一个 selector group},\\[2mm] d_j+|G|, &\text{存在多个 selector groups}. \end{cases}\]

因此源码把 gates 贪心分组,使每组满足类似

\[\begin{cases} |G|-1+\max_{g\in G}\deg(g)\le d_{\max}, &\text{单 group 特例},\\ |G|+\max_{g\in G}\deg(g)\le d_{\max}, &\text{多 group}. \end{cases}\]

每组使用一个 selector polynomial,在:

  • selector 数量;
  • quotient degree;
  • opening 成本

之间取平衡。

这是 Plonky2 “custom gate 很多但 selector 不一定很多”的关键。

5. copy constraints:宽 permutation 与部分积

5.1 位置标签

设 trace domain

\[H=\{1,\omega,\ldots,\omega^{N-1}\},\]

有 $r$ 个 routed columns。给每个 cell $(j,i)$ 一个唯一标签

\[\operatorname{id}_j(\omega^i).\]

copy wiring 定义一个 cell permutation $\sigma$,对应预处理多项式满足

\[\sigma_j(\omega^i) = \operatorname{id}_{\sigma(j,i)}.\]

5.2 随机压缩 value 与位置

对随机 $\beta,\gamma$,定义

\[\begin{aligned} u_j(X)&=w_j(X)+\beta\operatorname{id}_j(X)+\gamma,\\ v_j(X)&=w_j(X)+\beta\sigma_j(X)+\gamma. \end{aligned}\]

若 wire values 沿 wiring permutation 一致,则整个 domain 上的两个 multisets 相同:

\[\prod_{x\in H}\prod_{j=1}^{r}u_j(x) = \prod_{x\in H}\prod_{j=1}^{r}v_j(x).\]

5.3 grand product recurrence

定义 accumulator $Z$,令

\[Z(1)=1\]

并在每行满足

\[Z(\omega X) \prod_{j=1}^{r}v_j(X) = Z(X) \prod_{j=1}^{r}u_j(X).\]

最后配合边界约束闭合 $Z$。方向可因实现记号相反,但本质是:

\[\frac{Z(\omega X)}{Z(X)} = \prod_j\frac{u_j(X)}{v_j(X)}.\]

5.4 80 个 routed wires 不能直接相乘

若直接使用全部 $r=80$ 个 factors,约束 degree 过高。Plonky2 引入 partial-product polynomials。

设单个约束最多容纳 $d$ 个 factors,源码默认 quotient degree factor 上限为

\[d=8.\]

\[(u_1,\ldots,u_r), \qquad (v_1,\ldots,v_r)\]

分块。令

\[P_0(X)=Z(X), \qquad P_t(X) = P_{t-1}(X) \prod_{j\in B_t} \frac{u_j(X)}{v_j(X)}.\]

为了避免电路约束中出现除法,实际检查

\[P_{t-1}(X) \prod_{j\in B_t}u_j(X) - P_t(X) \prod_{j\in B_t}v_j(X) =0.\]

最后一个 accumulator 对接 $Z(\omega X)$。

flowchart LR
    Z0["Z(X)"] --> B1["乘第 1 组<br/>最多 8 对 factors"]
    B1 --> P1["partial product π_1(X)"]
    P1 --> B2["乘第 2 组"]
    B2 --> P2["partial product π_2(X)"]
    P2 --> BM["继续分块"]
    BM --> Z1["Z(ωX)"]

对 $r$ 个 factors,每块至多 $d$ 个,额外 partial products 数量大致为

\[\left\lceil\frac rd\right\rceil-1.\]

这说明 custom wide trace 并非免费:宽度减短了行数,却会增加 permutation 的多项式数量和部分积。

5.5 小域下的重复挑战

经典 PLONK 常把 $1/\lvert\mathbb F\rvert$ 量级错误视为足够小。Goldilocks 只有约 64 bit,不能这样做。

例如一个错误 permutation 逃过随机 $(\beta,\gamma)$ 检查的粗略概率可含

\[\varepsilon_{\mathrm{perm}} \lesssim \frac Np.\]

用独立挑战重复 $s$ 次,可把对应项压到近似

\[\left(\frac Np\right)^s.\]

最终源码默认 num_challenges = 2,目标是约 100-bit 的整体配置;技术稿用“三次重复可在特定 $N$ 上达到 128 bit”作说明。不能把技术稿的示例次数、源码默认次数和任意 trace 长度混为一谈。

6. 约束如何成为 quotient

6.1 所有局部等式在 $H$ 上为零

将 gate、permutation、边界、lookup 等约束记为

\[C_0(X),\ldots,C_{m-1}(X).\]

验证者采样 $\alpha$,做随机线性组合

\[C_\alpha(X) = \sum_{i=0}^{m-1}\alpha^i C_i(X).\]

若所有约束在 $H$ 上成立,则

\[Z_H(X)=X^N-1\]

整除 $C_\alpha$:

\[Q(X) = \frac{C_\alpha(X)}{Z_H(X)}\]

是低次多项式。

6.2 为什么要拆 quotient

\[\deg C_\alpha<dN,\]

\[\deg Q<(d-1)N.\]

基础 trace polynomials 通常按 degree 小于 $N$ 的对象承诺。于是把高次 quotient 拆成若干 chunks:

\[Q(X) = Q_0(X)+X^NQ_1(X)+\cdots+X^{(t-1)N}Q_{t-1}(X),\]

每个 $Q_i$ 的 degree 小于 $N$。

在随机点 $\zeta$ 上重组:

\[Q(\zeta) = \sum_{i=0}^{t-1}\zeta^{iN}Q_i(\zeta).\]

这里描述的正是固定 Plonky2 源码的做法:prover 直接按每 $N$ 个系数切分 quotient_poly.chunks(degree),所以这些是 monomial chunks,verifier 使用 $\zeta^N$ 的幂进行 Horner 重组。disjoint-subdomain 的消失多项式基重组属于旧版 Plonky3/QED Plonky2.5 等其他协议形状,不能与本节固定 Plonky2 的 chunk 语义混用。

6.3 随机点恒等式

prover 给出所有相关多项式在 $\zeta$ 与必要 rotations 上的 openings。verifier 重算

\[C_\alpha(\zeta)\]

并检查

\[\boxed{ C_\alpha(\zeta) = Z_H(\zeta)Q(\zeta). }\]

如果两边对应的多项式并不恒等,随机 $\zeta\in\mathbb E$ 命中其根的概率受 degree 与 $\lvert\mathbb E\rvert$ 控制。

7. 公开输入不是一列任意长 PI polynomial

Plonky2 先在电路中把公开输入

\[x_0,\ldots,x_{\ell-1}\]

哈希为四个域元素

\[h=(h_0,h_1,h_2,h_3),\]

再把它们 routed 到一个 PublicInputGate,约束对应 wires 等于这四个 digest elements。

这把约束系统中的公开输入接口从“长度 $\ell$ 的多项式”压成固定四个 field elements。

但安全边界是:

  1. proof object 仍携带原始 public inputs;
  2. verifier 必须使用完全相同的无歧义编码与 hash;
  3. transcript 必须吸收 public-input hash;
  4. application 必须检查 public inputs 是自己期望的 statement,而不能只调用“proof valid”。

8. Poseidon 为什么做成一整行 gate

8.1 参数

Plonky2 默认 Poseidon 置换的技术稿参数为:

  • state width:12 个 Goldilocks elements;
  • S-box:$x^7$;
  • full rounds:8;
  • partial rounds:22。

8.2 单个 Poseidon gate

一般 AIR 会用多行表达一个 permutation,每轮一行。Plonky2 反过来使用一个很宽的 PoseidonGate 表达整次 permutation。

为使最高 constraint degree 保持在 7,电路为 S-box 输入安排大量 intermediate wires,然后约束

\[y=x^7.\]

优点:

  • round constants 可直接固化在 gate 描述中;
  • 不需要额外 periodic/preprocessed columns;
  • 递归 verifier 的 Merkle hashing 行数更少。

代价:

  • trace 很宽;
  • 需要 135 wires 的配置;
  • gate-specific layout 更复杂。

技术稿报告递归电路大约 75% 用于 Merkle proof verification,所以 hash gate 的设计直接决定 recursion threshold。

8.3 MDS 优化

技术稿选择第一行为

\[[1,1,2,1,8,32,2,256,4096,8,65536,1024]\]

的 circulant MDS matrix。大量系数是二次幂,方便用位移、SIMD lane permutation 和延迟约减优化。

注意:这是具体实现参数,不是“任意 Poseidon 都自动同样快”。

9. 从 Merkle commitment 到 FRI opening

9.1 对 evaluation matrix 承诺

对多项式组

\[\mathbf p=(p_0,\ldots,p_{k-1})\]

先在扩展 domain $L$ 上求值:

\[\operatorname{LDE}(\mathbf p) = \bigl(p_j(x)\bigr)_{x\in L,\,j\in[k]}.\]

每个 $x$ 对应的整行 evaluations 放在同一 Merkle leaf:

\[\operatorname{leaf}_x = \bigl(p_0(x),\ldots,p_{k-1}(x)\bigr).\]

因此一个 Merkle opening 可同时认证同一点上的多列。

9.2 Merkle cap

Plonky2 在递归配置中不只发送单个 root,而发送树上某一高度的全部节点,称为 cap。

若 cap height 为 $c$,cap 包含

\[2^c\]

个 digests。源码默认 $c=4$,即 16 个 digests。

效果:

  • 每条 authentication path 少做 $c$ 次 hash;
  • path 长度固定,适合静态电路;
  • proof 中承诺本身变大。

9.3 单点 opening 转成 DEEP quotient

若声称

\[p(\zeta)=y,\]

定义

\[b(X)=\frac{p(X)-y}{X-\zeta}.\]

当且仅当 $y$ 真的是 $p(\zeta)$ 时,分子被 $X-\zeta$ 整除,$b$ 是低次多项式。

若要同时打开许多 $(p_i,\zeta_i,y_i)$,采样 batch challenge $\rho$,组合为

\[B(X) = \sum_i\rho^i \frac{p_i(X)-y_i}{X-\zeta_i}.\]

然后对 $B$ 的 committed evaluation behavior 做一次 FRI,而不是每个 opening 各跑一次。

10. FRI 折叠的 Plonky2 形式

10.1 一般 $a$ 元折叠

设当前 polynomial 写成

\[f(X) = \sum_{j=0}^{a-1}X^j f_j(X^a),\]

其中 $a=2^b$。verifier 采样 $\beta$,定义下一层

\[f_{\mathrm{next}}(Y) = \sum_{j=0}^{a-1}\beta^j f_j(Y).\]

degree 大致缩小 $a$ 倍。

对一个大小为 $a$ 的 coset,只要打开整组 evaluations,就能插值出 $f_0,\ldots,f_{a-1}$ 在相应点的值,并检查下一层 leaf 与折叠结果一致。

10.2 early stopping

不必一直折到常数。若最后 degree 已足够小,prover 直接发送 final polynomial coefficients,verifier:

  1. 检查其 degree bound;
  2. 在 query 归约后的点上求值;
  3. 与最后一次 fold 结果比较。

10.3 技术稿与最终源码配置不同

来源recursion-oriented folding 描述
2022 技术稿固定 arity 8,使 verifier gate 形状统一
最终源码 standard_recursion_configConstantArityBits(4, 5),即反复做 $2^4=16$ 元折叠,直到 final degree bits 不超过 5,或受 cap height 限制

这不是数学矛盾,而是实现参数演进。阅读 benchmark 或 proof format 时必须绑定具体 commit/release。

11. 源码默认 FRI 参数逐项解释

最终 standard_recursion_config

参数默认值数学意义
rate_bits3RS code rate $2^{-3}=1/8$,LDE blowup 为 8
cap_height4每个 cap 有 $2^4=16$ 个 digests
proof_of_work_bits16query 前 grinding 16 bit
reduction_strategyConstantArityBits(4,5)最大 16 元 fold,final degree 至多约 $2^5$
num_query_rounds2828 个 query indices
security_bits100配置目标,不是由字段名自动保证的定理

最粗略的旧式 conjectural heuristic 会把

\[\text{FRI query contribution} \approx \text{rate\_bits}\times\text{queries} =3\cdot28=84\]

再加 16-bit grinding 得到约 100 bits。

但这只是 ethSTARK 风格 conjectural 估计,不是完整 proven soundness:

  • 还要计入 ALI/DEEP、constraint batching、field-size errors;
  • correlated agreement / proximity-gap 的精确界很关键;
  • hash collision resistance 构成上限;
  • Fiat–Shamir 还需要随机预言机模型下的分析。

因此“28 queries + 16 PoW = 100 bit”应理解为该版本的参数设计目标,而非可脱离协议形状复用的公式。

12. 完整 transcript 顺序

令:

  • $C_{\mathrm{cs}}$:constants 与 $\sigma$ 的预处理 cap;
  • $C_w$:wire LDE cap;
  • $C_Z$:permutation $Z$ 与 partial products 的 cap;
  • $C_Q$:quotient chunks cap;
  • $h_{\mathrm{PI}}$:公开输入 hash;
  • $d_{\mathrm{circ}}$:circuit digest。

源码挑战顺序可概括为:

sequenceDiagram
    participant P as Prover
    participant T as Fiat-Shamir transcript
    participant V as Verifier
    P->>T: FRI 参数、circuit digest、PI hash
    P->>T: wire cap C_w
    T-->>P: permutation beta_j 与 gamma_j
    P->>T: Z 与 partial-products cap C_Z
    T-->>P: constraint-combination alpha_j
    P->>T: quotient cap C_Q
    T-->>P: OOD point zeta in extension field
    P->>T: zeta 上的 claimed openings
    T-->>P: FRI batch challenge rho
    P->>T: 各层 FRI caps
    T-->>P: folding challenges
    P->>T: final polynomial 与 PoW witness
    T-->>P: query indices
    P->>V: Merkle paths 与 coset openings

顺序的原则是:

\[\boxed{ \text{任何 challenge 必须在其要约束的 prover message 之后采样。} }\]

例如若 $\zeta$ 在 $C_Q$ 之前生成,prover 可针对已知 $\zeta$ 选择 quotient commitment;若 query indices 在 FRI caps 之前生成,prover 可只修补被查询位置。

13. verifier 最后究竟检查什么

把验证拆成三层最清楚。

13.1 commitment authentication

对每个 query:

  • 重新哈希 wire、$Z$/partial products、quotient、FRI layers 的 Merkle paths;
  • 检查所得节点属于相应 cap。

13.2 FRI consistency

对每一层:

  • 把 query 所在 coset 的 evaluations 插值;
  • 用 folding challenge 计算下一值;
  • 检查它等于下一层被认证的 evaluation;
  • 最后与 final polynomial evaluation 相等。

13.3 PLONK identity

用 $\zeta$ 上 openings 重算:

  • custom gate constraints;
  • selector filters;
  • permutation recurrence 与边界;
  • partial-product relations;
  • 公开输入 hash binding;
  • lookup constraints(若存在)。

然后检查

\[C_{\alpha_j}(\zeta) = Z_H(\zeta)Q_j(\zeta)\]

对所有重复 challenge $j$ 成立。

注意:FRI 只证明“承诺向量接近合适 degree 的 Reed–Solomon codeword”;PLONK identity 才证明这些 codewords 共同描述合法 circuit witness。二者缺一不可。

14. zero-knowledge 是显式开关

最终默认递归配置:

\[\texttt{zero\_knowledge=false}.\]

另有

1
CircuitConfig::standard_recursion_zk_config()

启用 hiding 机制。

技术稿描述的主要思路包括:

  1. 在 padding 到二次幂前向 trace 添加随机 rows;
  2. 对 permutation accumulator 添加成对随机 rows并维持 copy constraints;
  3. 不在原 trace domain 上直接发送 witness evaluations,而使用 coset;
  4. 对 Merkle leaf 加随机 salt,使 vector commitment hiding。

因此应区分:

\[\text{validity argument} \ne \text{zero-knowledge argument}.\]

如果配置、proof type 或 wrapper 没有启用并正确分析 blinding,不能仅因项目属于 ZK 生态就声称 witness privacy。

15. 一个小型端到端代数例子

假设只有一个 division gate,位于第 $i$ 行:

\[(x_i,y_i,q_i,r_i)\]

其中 $r_i$ 声称是 $y_i^{-1}$。selector filter 为 $F_{\mathrm{div}}$。

本行约束:

\[\begin{aligned} c_0(X) &= F_{\mathrm{div}}(X) \bigl(q(X)y(X)-x(X)\bigr),\\ c_1(X) &= F_{\mathrm{div}}(X) \bigl(y(X)r(X)-1\bigr). \end{aligned}\]

随机组合:

\[C_\alpha(X) =c_0(X)+\alpha c_1(X)+\alpha^2c_{\mathrm{perm}}(X)+\cdots.\]

合法 trace 使

\[Z_H\mid C_\alpha.\]

prover 承诺 $x,y,q,r,Z,\pi,Q$ 的 LDE,发送 $\zeta$ 上点值,并用 FRI 证明这些 openings 与低度 codewords 一致。verifier 检查:

\[\begin{aligned} C_\alpha(\zeta) &= F_{\mathrm{div}}(\zeta) \bigl(q(\zeta)y(\zeta)-x(\zeta)\bigr)\\ &\quad+ \alpha F_{\mathrm{div}}(\zeta) \bigl(y(\zeta)r(\zeta)-1\bigr) +\cdots\\ &=Z_H(\zeta)Q(\zeta). \end{aligned}\]

若 $y_i=0$,不存在 $r_i$ 使 $y_ir_i=1$,所以 witness 生成器不能通过第二个约束。

这个例子显示三种绑定各司其职:

  • gate constraint:本行语义;
  • permutation:跨行 wiring;
  • FRI:所有声称多项式的低度性与 openings。

16. 安全与实现边界

16.1 100 bit 是 conjectured target

官方仓库明确说默认 FRI 参数面向约 100-bit conjectured security。不能把它改写成无条件 100-bit 定理。

16.2 默认 Poseidon 参数的单独安全估计

官方 README 同时指出:默认 width 12、8 full + 22 partial、$x^7$ 的 Poseidon 配置,根据其引用的 BBLP22 分析可能只有约 95-bit,而非完整 100-bit。

在协议实现满足规范、native verifier 与 recursive verifier 语义一致的前提下,密码学安全上限不超过最弱的已分析组件:

\[\lambda_{\mathrm{crypto}} \le \min( \lambda_{\mathrm{FRI}}, \lambda_{\mathrm{hash}}, \lambda_{\mathrm{algebraic}}, \lambda_{\mathrm{FS}} ).\]

实现正确性不应被伪装成另一个可相加或可取最小值的“security bits”项。更准确的逻辑结构是

\[\boxed{ \mathsf{ImplementationConformsToSpec} \quad\Longrightarrow\quad \Pr[\mathsf{CryptoBad}]\le\varepsilon_{\mathrm{crypto}}. }\]

若 parser、transcript、约束或递归 verifier 存在 bug,接受关系可能整体偏离规范;除非另行给出明确的随机故障模型,否则不存在通用的 $\lambda_{\mathrm{implementation}}$ 可以放进上式。

16.3 技术稿仍标为 draft

2022 文档清楚标注 DRAFT,且含未完成的 ZK 说明。该文档可用于理解设计,但部署审计不能把草稿当最终形式化 specification。

16.4 仓库已弃用

Plonky2 官方仓库已标注不再更新或支持,并建议使用 Plonky3。弃用不等于已生成 proofs 立刻失效,但意味着:

  • 新发现未必修复;
  • 依赖与工具链继续老化;
  • 新项目不应默认采用旧配置;
  • 长期维护者需要自行承担 fork、审计与参数责任。

16.5 verifier 必须固定 shape

安全 statement 不只有 proof bytes,还包括:

\[(\text{circuit digest}, \text{common circuit data}, \text{FRI params}, \text{hash config}, \text{public inputs}).\]

任何从不可信 proof 动态推导、却未被 verifier policy 固定或 transcript 绑定的 shape,都可能成为 statement substitution 或解析歧义入口。

17. 技术稿参数与最终实现参数对照

项目技术稿描述最终源码默认
基础域GoldilocksGoldilocks
challenge 扩域$\mathbb F_p[X]/(X^2-7)$quadratic extension
trace width135135
routed wires讨论宽 permutation80
quotient factor部分积每组 8最大 8
Poseidonwidth 12,8F+22P,$x^7$同一默认族
recursion FRI arity固定 8常用固定 16 元策略
FRI ratespeed 模式常用 $1/8$$1/8$
query / PoW以目标安全解释28 queries + 16-bit grinding
默认 ZK描述 hiding 技术standard recursion config 为 false;另有 ZK config

18. 总结

Plonky2 快速递归的数学原因不是某一个“神奇优化”,而是多层共同对齐:

\[\boxed{ \begin{aligned} &\text{Goldilocks:64-bit + 高 two-adicity}\\ &+\text{宽 custom gates:减少 verifier 行数}\\ &+\text{advice wires:缩小 permutation}\\ &+\text{partial products:控制宽 permutation degree}\\ &+\text{Poseidon 整置换 gate:降低 Merkle verifier 行数}\\ &+\text{FRI/Merkle cap:透明且递归友好的 polynomial test}. \end{aligned} }\]

代价同样清晰:

  • 宽 trace 与专用 gate layout;
  • 小域 soundness 必须精细重复与扩域;
  • proof 较 pairing-SNARK 大;
  • 默认配置未必 ZK;
  • FRI 与 Poseidon 安全目标含 conjectural/组件级边界;
  • 项目本身已经弃用。

19. 一手资料


上一篇:FRI 与 DEEP-FRI
下一篇:Plonky2 递归原理与工程
返回:总目录

本文由作者按照 CC BY 4.0 进行授权