Yu Guo [email protected]
最后更新时间:2025-06-10
协议回顾¶
对于任意一个 n 个变量(Indeterminate)的 Multilinear Polynomial f~(X0,X1,…,Xn−1)∈F≤1[X0,X1,…,Xn−1],如果要证明其在一个任意点 u=(u0,u1,…,un−1) 的运算值是正确的,Basefold 协议 [ZCF23] 提供了一个简洁优雅的方案。其核心思路是用 Sumcheck 协议来证明 f~(u0,u1,…,un−1) ,然后在 Sumcheck 协议的最后一步,Verifier 需要验证 f~(r0,r1,…,rn−1) 的运算值, Basefold 并没有借助于另一个 MLE PCS 来完成这最后一步的证明,而是借助一个 FRI 协议来辅助完成。本来 FRI 协议的证明目的是证明一个 Codeword 的 Proximity,即与正确的码字的距离不超过一个安全参数 δ,然而在 FRI 协议的最后一步,Prover 会发送一个折叠后的 Codeword 对应的 Message,如果折叠充分,那么最后的 Message 是一个常数(多项式),如果 Prover 诚实,那么这个值恰好等于 f~(r0,r1,…,rn−1) 的值,恰好与 Sumcheck 形成互补的情况。
下面我们过一下协议细节,首先 f~(X) 可以重写成下面的等式:
f~(X)=b∈{0,1}n∑f~(b)⋅eq(X,b) 可以看出等式右边是一个求和式,这满足 Sumcheck 协议的要求。Sumcheck 协议可以证明下面的内积等式:
v=b∈{0,1}n∑f~(b)⋅g~(b) 基于 Sumcheck 协议的内积证明¶
我们回顾一下如何利用 Sumcheck 协议证明内积,我们假设两个长度为 2n 的向量 f 与 g 分别对应两个 n 个变量的 Multilinear Polynomial,f~ 与 g~,那么接下来我们解释 Prover 和 Verifier 如何证明下面的目标:
s=b∈{0,1}n∑f~(b0,b1,…,bn−1)⋅g~(b0,b1,…,bn−1) 第一轮:Prover 构造一个 Degree 为 2 的一元多项式 h(0)(X),发送它在 X=0,1,2 这三个点上的求值,即 (h(0)(0),h(0)(1),h(0)(2))。
h(0)(X)=b∈{0,1}n−1∑f~(X,b1,b2,…,bn−1)⋅g~(X,b1,b2,…,bn−1) Verifier 检查 h(0)(0)+h(0)(1)=?v,如果成立,则回应一个随机挑战数 r0∈Fq,然后证明目标就被转换成了一个新的证明目标:
h(0)(r0)=b∈{0,1}n−1∑f~(r0,b1,b2,…,bn−1)⋅g~(r0,b1,b2,…,bn−1) 观察到 f~(r0,X1,…,Xn−1) 和 g~(r0,X1,…,Xn−1) 仍然是 Multilinear Polynomial,我们将其分别记为 f~(1)(X1,…,Xn−1) 与 g~(1)(X1,…,Xn−1),
f~(1)(X1,…,Xn−1)g~(1)(X1,…,Xn−1)=f~(r0,X1,…,Xn−1)=g~(r0,X1,…,Xn−1) 于是新的证明目标可以写为:
h(0)(r0)=v(1)=?b∈{0,1}n−1∑f~(1)(b1,…,bn−1)⋅g~(1)(b1,…,bn−1) 这样 Sumcheck 可以看成一个递归调用的协议,每次调用就会讲求和的长度减半。
接着 Prover 和 Verifier 重复上述过程,直到 Sumcheck 的证明长度变成 1 为止。
第 n 轮,Prover 构造 h(n−1)(X),发送 (h(n−1)(0),h(n−1)(1),h(n−1)(2)) 三个点,
h(n−1)(X)=f~(n−1)(X)⋅g~(n−1)(X) Verifier 检查 h(n−1)(0)+h(n−1)(1)=?v(n−1),如果成立,则回应一个随机挑战数 rn−1∈Fq,然后证明目标就被转换成了一个新的证明目标:
h(n−1)(rn−1)=?f~(n−1)(rn−1)⋅g~(n−1)(rn−1) 然后 Prover 无需再发送任何消息,Verifier 直接计算 h(n−1)(rn−1) 的值,然后调用 f~(X0,X1,…,Xn−1) 与 g~(X0,X1,…,Xn−1) 的 Oracle,得到 f~(n−1)(rn−1) 与 g~(n−1)(rn−1) 的值,然后验证等式是否成立:
f(n−1)(rn−1)g(n−1)(rn−1)=f~(r0,r1,…,rn−1)=g~(r0,r1,…,rn−1) 通常来说,在 Sumcheck 最后一步,Verifier 所依赖的 f~ 与 g~ 的 Oracle 采用 Polynomial Commitment 来实现。即在 Sumcheck 开始之前,Prover 先发送它们的 Commitment,然后在 Sumcheck 的最后一步,由 Prover 来发送 f~(r0,r1,…,rn−1) 与 g~(r0,r1,…,rn−1) 的值,并附上相应的 Multilinear Polynomial Evaluation 的证明。
基于 FRI 协议的 Proximity 证明¶
TODO
基于 Multilinear Basis 的 Basefold 证明过程¶
我们采用实现的视角过一遍 Prover 的证明过程。为了方便读者理解,我们假设 f~ 是一个三变量的 Multilinear Polynomial,协议总共有 n=3 轮,那么 Prover 先做一轮的 Sumcheck,然后复用 Sumcheck 的随机数,再做一轮 FRI 协议,这等于完成了一轮的 Basefold 协议;然后依次做下去,直到 Sumcheck 的证明长度变成 1 为止。
v=(b0,b1,b2)∈{0,1}3∑f~(b0,b1,b2)⋅eq((u0,u1,u2),(b0,b1,b2))=i=0∑7ai⋅wi 这里 v=f~(u0,u1,u2),向量 a=(a0,a1,⋯,a7) 是 f~(X) 在 Boolean Hypercube 上的运算值,而 w=(w0,w1,⋯,w7) 是 eq(u,X) 在 Boolean Hypercube 上取值:
w0w1w2w3w4w5w6w7=(1−u0)(1−u1)(1−u2)=u0(1−u1)(1−u2)=(1−u0)u1(1−u2)=u0u1(1−u2)=(1−u0)(1−u1)u2=u0(1−u1)u2=(1−u0)u1u2=u0u1u2 Prover 需要证明这个内积计算的正确性。即
v=a0w0+a1w1+a2w2+a3w3+a4w4+a5w5+a6w6+a7w7 Prover 维护长度为 2n 的两个数组,分别保存 a 和 w,分别对应 f~ 和 eq 的 Evaluations 表示。
aiwi=f~(i0,i1,i2)=eq((u0,u1,u2),(i0,i1,i2)) 第一轮的 Sumcheck 协议,Prover 计算 h(0)(X)。这是一个 Degree 为 2 的一元多项式,我们只要得到它在至少三个不同点上的求值,就可以唯一表示这个多项式,为了优化计算,我们特意选择 X=0,1,2 这三个点。
h(0)(X)=b1,b2∈{0,1}2∑f~(X,b1,b2)⋅g~(X,b1,b2) 而 h(0)(0) 恰好等于内积求和项中的位于偶数位置的项的和,而 h(0)(1) 恰好等于内积求和项中的位于奇数位置的项的和,表示如下:
h(0)(0)h(0)(1)=a0w0+a2w2+a4w4+a6w6=a1w1+a3w3+a5w5+a7w7 因此 Prover 只需两遍 2n−1 次乘法与 2n−1 次加法(总计 2n 次乘法与 2n 次加法)就能计算出 h(0)(0) 和 h(0)(1)。但如何计算 h(0)(2) 呢?我们先证明下面的等式,这个等式我们反复要用到:
f~(X0+1,X1,X2)=f~(X0,X1,X2)+f~(1,X1,X2)−f~(0,X1,X2) 推而广之,我们可以得到下面的式子
f~(Y,Xk+1,Z)=f~(Y,Xk,Z)+f~(Y,1,Z)−f~(Y,0,Z) 那么根据 Multilinear Polynomial 的性质,我们可以计算出 h(0)(2) 的值:
h(0)(2)=b1,b2∈{0,1}2∑f~(2,b1,b2)⋅w~(2,b1,b2)=b1,b2∈{0,1}2∑(2⋅f~(1,b1,b2)−f~(0,b1,b2))⋅(2⋅w~(1,b1,b2)−w~(0,b1,b2)) 这需要 Prover 计算 2n−1 次乘法 与 5⋅2n−1 次加法。然后 Prover 发送 h(0)(0),h(0)(1),h(0)(2) 给 Verifier,Verifier 检查下面的等式是否成立:
h(0)(0)+h(0)(1)=?v 如果成立,则回复一个随机数 r0∈Fq,然后证明目标就 Reduce 成了一个新的证明目标:
h(0)(r0)=b1,b2∈{0,1}2∑f~(r0,b1,b2)⋅w~(r0,b1,b2)=b1,b2∈{0,1}2∑f~(1)(b1,b2)⋅w~(1)(b1,b2) 这里 f(1)(X1,X2) 和 w(1)(X1,X2) 在二维 Boolean Hypercube 上的 Evaluations 实际上直接可以通过 f~ 和 w~ 的 Evaluations 计算得到:
a0(1)a1(1)a2(1)a3(1)=f~(1)(0,0)=(1−r0)⋅f~(0,0,0)+r0⋅f~(1,0,0)=f~(1)(0,1)=(1−r0)⋅f~(0,0,1)+r0⋅f~(1,0,1)=f~(1)(1,0)=(1−r0)⋅f~(0,1,0)+r0⋅f~(1,1,0)=f~(1)(1,1)=(1−r0)⋅f~(0,1,1)+r0⋅f~(1,1,1) 所以这需要 Prover 计算 2n−1 次乘法与 2n 次加法从而得到 f(1)(X1,X2) 的 Evaluations 表示,记在 (a0(1),a1(1),a2(1),a3(1)) 中
a0(1)a1(1)a2(1)a3(1)=(1−r0)⋅a0+r0⋅a1=(1−r0)⋅a2+r0⋅a3=(1−r0)⋅a4+r0⋅a5=(1−r0)⋅a6+r0⋅a7 除此之外,Prover 还需要以同样的方式(2n−1 次乘法与 2n 次加法)计算 w~(1)(X1,X2) 的 Evaluations 表示:
w0(1)w1(1)w2(1)w3(1)=w~(1)(0,0)=(1−r0)⋅w~(0,0,0)+r0⋅w~(1,0,0)=w~(1)(0,1)=(1−r0)⋅w~(0,0,1)+r0⋅w~(1,0,1)=w~(1)(1,0)=(1−r0)⋅w~(0,1,0)+r0⋅w~(1,1,0)=w~(1)(1,1)=(1−r0)⋅w~(0,1,1)+r0⋅w~(1,1,1) 这两部分对 Multilinear Polynomial 的折叠计算加起来总共需要 2n 次乘法与 2⋅2n 次加法。计算结果保存在两个长度为 2n−1 的数组 a(1) 和 w(1) 中。
接下来 Prover 和 Verifier 要完成 FRI 协议的第一轮(Commit-phase),即计算折叠后的一元多项式的 RS Code。下面是 f~(X0,X1,X2) 所对应的一元多项式,f^(X)。请务必注意,它的系数式对应于 f~(X) 的 Evaluations表示,这不同于 Basefold 论文 [ZCF23] 中的形式:
f^(X)=a0+a1X+a2X2+a3X3+a4X4+a5X5+a6X6+a7X7 Prover 在 Sumcheck 第一轮中已经计算得到了折叠后的 f~(1)(X1,X2) 的 Evaluations 表示,即 a(1)。它也对应到一个一元多项式 f^(1)(X),其系数式表示为:
f^(1)(X)=a0(1)+a1(1)X+a2(1)X2+a3(1)X3 接下来,Prover 需要计算 f~(1)(X) 的 RS Code,如果直接计算,这需要 Prover 计算 (n2n−1) 次乘法。幸运地是,由于 RS Code 是一种「线性编码」,因此 Prover 可以直接在 f^(X) 的 RS Code 上直接用 (1−r0,r0) 进行折叠运算,即可得到 f^(1)(X) 的 RS Code。
先回顾下熟悉的 f^(X) 的多项式分解:
f^(X)f^(−X)=fe(X2)+X⋅fo(X2)=fe(X2)−X⋅fo(X2) 其中 fe(X) 是偶数项组成的多项式,fo(X) 是奇数项组成的多项式:
fe(X)fo(X)=a0+a2X+a4X2+a6X3=a1+a3X+a5X2+a7X3 又因为
f^(1)(X2)=(1−r0)⋅fe(X2)+r0⋅fo(X2)=(1−r0)⋅2f^(X)+f^(−X)+r0⋅2f^(X)−f^(−X) 所以,Prover 只需要对 f^(X) 的 RS Code 进行同样的折叠运算,就可以得到 f^(1)(X) 的 RS Code:
encode(f^(1))i=(1−r0)⋅encode(f^)i+r0⋅encode(f^)(i+N/2),i∈[0,N) 这里 N 为长度为 2n 的消息经过编码后的长度,其中 ρ=2n/N 为码率。
这时候 Prover 发送 encode(f^(1)) 的 Merkle Root 作为承诺,然后 Prover 和 Verifier 进行 Sumcheck 的第二轮,重复上面的过程,直到 Sumcheck 协议的求和项长度为 1 ,这时伴随执行的 FRI 协议也将多项式折叠到了一个常数多项式 f^(3)(X)。如果 Prover 诚实,那么 f^(3)(X) 的常数项恰好就是 f~(r0,r1,r2):
f^(3)(X)=f~(r0,r1,r2) 这个值正好可以被 Verifier 利用用来验证:
v(3)=?f^(3)(0)⋅eq~((u0,u1,u2),(r0,r1,r2)) 这时候,Verifier 需要计算 eq~((u0,u1,u2),(r0,r1,r2)) 来完成最后的验证步,这需要 2n 次乘法:
eq~((u0,u1,u2),(r0,r1,r2))=i=0∏2((1−ri)⋅(1−ui)+ri⋅ui)=i=0∏2(1+2ri⋅ui−ri−ui) 对于 FRI 的 Query-phase 部分,这里我们略去。
Sumcheck 性能分析¶
在 Sumcheck 协议部分,Prover 总共的计算量为
- 计算 w:2n 次乘法
- 计算 hi(0):2n 次乘法,2⋅2n 次加法
- 计算 hi(1):2n 次乘法,2⋅2n 次加法
- 计算 hi(2): 需要 2n 次乘法 与 5⋅2n 次加法
- 折叠计算 a: 需要 2n 次乘法 与 2⋅2n 次加法
- 折叠计算 w: 需要 2n 次乘法 与 2⋅2n 次加法
Verifier 计算量:
- 验证 h(i)(0)+h(i)(1)=?h(i−1)(ri−1): n 次加法
- 插值计算 h(i)(ri):4n 次除法、3n 次乘法与 9n 次加法
- 计算 eq~(r0,r1,⋯,rn−1): n 次乘法,4n 次加法
- 最终验证:1 次乘法
Sumcheck 优化¶
在上面的协议中,Prover 需要发送 Degree 为 2 的 h(0)(X),h(1)(X),h(2)(X) 三个多项式。最朴素的实现是 Prover 发送这些多项式在 X=0,1,2 处的三个运算值,Verifier 检查前两个值,然后利用第三个值来计算 Lagrange Interpolation,计算得到 h(0)(r0)。
我们可以对上面的协议稍做变化,即可让 Prover 只发送 Degree 为 1 的线性多项式,那么 Prover 仅需要发两个点的运算值即可,而且 Verifier 也只需要做线性插值即可计算出下一个求和值。
Habock 在 [Hab24] 中给出了一个 Basefold 协议的优化版本,可以把 h(X) 变成 Degree 为 1 的线性多项式。这个优化技术最早出现在 [Gru24] 中。下面我们简述下这个优化技术。
根据 eq~(X,Y) 的定义,它可以被分解为:
eq~(X0∥X1,Y0∥Y1)=eq(X0,Y0)⋅eq(X1,Y1) 我们先观察下 h(0)(X) 的定义:
h(0)(X)=b1,b2∈{0,1}2∑f~(X,b1,b2)⋅eq~((u0,u1,u2),(X,b1,b2)) 它的等式右边可以改写为:
h(0)(X)=b1,b2∈{0,1}2∑f~(X,b1,b2)⋅eq~((u0,u1,u2),(X,b1,b2))=b1,b2∈{0,1}2∑f~(X,b1,b2)⋅eq(u0,X)⋅eq((u1,u2),(b1,b2))=eq(u0,X)⋅(b1,b2)∈{0,1}2‘∑(f~(X,b1,b2)⋅eq((u1,u2),(b1,b2))) 我们引入记号 g(0)(X) 来表示等式右边的除 eq(u0,X) 之外的线性多项式,那么 h(0)(X) 可以表示为两个线性多项式的乘积:
h(0)(X)=eq(u0,X)⋅g(0)(X) 我们按照下面的方式修改协议,让 Prover 不直接发送 h0(X),而是发送线性多项式 g0(X),即 g(0)(0),g(0)(1),
g(0)(X)=(b1,b2)∈{0,1}2∑(f~(X,b1,b2)⋅eq((u1,u2),(b1,b2))) 而 Verifier 收到 g(0)(0),g(0)(1) 多项式之后,可以自行计算 h(0)(0),h(0)(1) 的值,因为
h(0)(0)h(0)(1)=(1−u0)⋅g(0)(0)=u0⋅g(0)(1) 然后 Verifier 可以验证 h(0)(0)+h(0)(1)=?v,如果验证通过,那么 Verifier 可以计算 h(0)(r0),
h(0)(r0)=((1−u0)(1−r0)+u0r0)⋅g(0)(r0) 这里 g(0)(r0) 也可以通过 g(0)(0),g(0)(1) 计算得到:
g(0)(r0)=g(0)(0)+(g(0)(1)−g(0)(0))⋅r0 最后计算得到 h0(r0) 。总结下,这样Verifier 需要一个乘法来验证 v,三个乘法来计算 h(0)(r0)。
性能分析¶
Prover 总共的计算量为
- 计算 gi(0):2n 次乘法,2⋅2n 次加法
- 计算 gi(1):2n 次乘法
- 折叠计算 a: 需要 2n 次乘法 与 2⋅2n 次加法
- 折叠计算 w: 需要 2n 次乘法 与 2⋅2n 次加法
Verifier 计算量:
- 计算 h(i)(0):n 次乘法,n 次加法
- 计算 h(i)(1):n 次乘法,n 次加法
- 验证 h(i)(0)+h(i)(1): n 次加法
- 计算 h(i)(ri):3n 次乘法、6n 次加法
- 计算 eq~(r0,r1,⋯,rn−1): n 次乘法,4n 次加法
- 最终验证:1 次乘法
进一步优化 Verifier¶
我们再观察下 g(0)(X) 的定义:
g(0)(X)=(b1,b2)∈{0,1}2∑(f~(X,b1,b2)⋅eq((u1,u2),(b1,b2))) 这个求和式恰好等于 f~(X,u1,u2),于是我们可以换一个视角回顾下上面的优化协议:
Prover 在第一步发送 g(0)(0),g(0)(1),实际上是发送:
g(0)(0)g(0)(1)=f~(0,u1,u2)=f~(1,u1,u2) Verifier 检查验证 h(0)(X) 的正确性,等价于验证 g(0)(X) 的正确性:
h(0)(u0)=eq(u0,u0)⋅g(0)(u0)=g(0)(u0)=g(0)(0)+(g(0)(1)−g(0)(0))⋅u0=?v 然后 Verifier 计算 g(0)(r0) 作为下一轮 Sumcheck 的求和值。
g(0)(r0)=g(0)(0)+(g(0)(1)−g(0)(0))⋅r0 因此,我们好像可以不再需要引入 h(i)(X),而直接使用 g(i)(X) 即可。这样每一轮 Sumcheck 协议,Prover 需要发送 g(i)(0),g(i)(1),Verifier 只需要计算两次乘法,一次用来计算 g(i)(ui),一次用来计算 g(i)(ri)。而且在 Sumcheck 的最后一步,Verifier 只需要验证:
g(n−1)(rn−1)=?f~(r0,r1,⋯,rn−1) 不难发现,在第 i 轮,如果 Prover 诚实,g(i)(X) 恰好应该等于 f~(i)(r0,r1,⋯,ri−1,X,ui+1,⋯,un−1)。我们重新写一下 改头换面后的 Sumcheck 协议:
第一轮:Prover 发送 f~(0,u1,u2),f~(1,u1,u2),Verifier 验证:
(1−u0)⋅f~(0,u1,u2)+u0⋅f~(1,u1,u2)=?f~(u0,u1,u2)=v Verifier 回应 r0∈F,并计算 g(0)(r0)=f~(r0,u1,u2) 作为新的求和值 v(1):
f~(r0,u1,u2)=(1−r0)⋅f~(0,u1,u2)+r0⋅f~(1,u1,u2) 第二轮:Prover 发送 f~(r0,0,u2),f~(r0,1,u2),Verifier 验证:
(1−u1)⋅f~(r0,0,u2)+u1⋅f~(r0,1,u2)=?f~(r0,u1,u2)=v(1) Verifier 回应 r1∈F,并计算 g(1)(r1)=f~(r0,r1,u2) 作为新的求和值:
f~(r0,r1,u2)=(1−r1)⋅f~(r0,0,u2)+r1⋅f~(r0,1,u2) 第三轮:Prover 发送 f~(r0,r1,0),f~(r0,r1,1),Verifier 验证:
(1−u2)⋅f~(r0,r1,0)+u2⋅f~(r0,r1,1)=?f~(r0,r1,u2)=v(2) Verifier 回应 r2∈F,并计算 g(2)(r2)=f~(r0,r1,r2) 作为新的求和值:
f~(r0,r1,r2)=(1−r2)⋅f~(r0,r1,0)+r2⋅f~(r0,r1,1) 验证步:Verifier 通过 f~(X0,X1,X2) Oracle,验证下面的等式:
g(2)(r2)=?f~(r0,r1,r2) 这样每轮 Verifier 只需要进行两次乘法运算即可,第一个乘法是验证求和值 v(i) 的正确性,第二个乘法是计算 g(i)(ri),总共 2n 个乘法。
Prover 的计算优化¶
Prover 在三轮中,需要依次发送:g(0)(0) 和 g(0)(1),g(1)(0) 和 g(1)(1),g(2)(0) 和 g(2)(1)。
g(0)(0)g(0)(1)g(1)(0)g(1)(1)g(2)(0)g(2)(1)=f~(0,u1,u2)=f~(1,u1,u2)=f~(r0,0,u2)=f~(r0,1,u2)=f~(r0,r1,0)=f~(r0,r1,1) 这一节我们看下 Prover 如何能高效地计算 g(i)(0),g(i)(1)。
前文我们提到 Prover 维护了一个数组 a,长度为 2n,
a0a1a2a3a4a5a6a7=f~(0,0,0)=f~(1,0,0)=f~(0,1,0)=f~(1,1,0)=f~(0,0,1)=f~(1,0,1)=f~(0,1,1)=f~(1,1,1) 在每次 Sumcheck 轮中进行折叠,例如在经过第一轮的折叠( r0 作为折叠因子)后,Prover 得到:
a0(1)a1(1)a2(1)a3(1)=f~(1)(0,0)=(1−r0)⋅f~(0,0,0)+r0⋅f~(1,0,0)=f~(1)(0,1)=(1−r0)⋅f~(0,0,1)+r0⋅f~(1,0,1)=f~(1)(1,0)=(1−r0)⋅f~(0,1,0)+r0⋅f~(1,1,0)=f~(1)(1,1)=(1−r0)⋅f~(0,1,1)+r0⋅f~(1,1,1) 为了高效计算 g(i)(0),g(i)(1),我们让 Prover 在 Sumcheck 协议开始前,进行一番预计算,得到一个长度为 2n−1 的向量 d。
这个向量是将 a 向量(u2,u1,u0 作为折叠因子)折叠后计算得到的结果。我们先将 a 向量采用 u2 折叠,得到 d0,d1,d2,d3:
d0d1d2d3=(1−u2)⋅a0+u2⋅a4=f~(0,0,u2)=(1−u2)⋅a1+u2⋅a5=f~(1,0,u2)=(1−u2)⋅a2+u2⋅a6=f~(0,1,u2)=(1−u2)⋅a3+u2⋅a7=f~(1,1,u2) 然后 Prover 对 d0,d1,d2,d3 再次进行折叠运算,使用折叠因子 u1,得到 d4,d5:
d4d5=(1−u1)⋅d0+u1⋅d2=f~(0,u1,u2)=(1−u1)⋅d1+u1⋅d3=f~(1,u1,u2) 最后 Prover 对 d4,d5 进行折叠运算,使用折叠因子 u0,得到 d6:
d6=(1−u0)⋅d4+u0⋅d5=f~(u0,u1,u2) 观察下,向量 (d0,d1,d2,d3,d4,d5,d6) 的末尾值 d6 恰好是 f~(u0,u1,u2),而倒数第二个和第三个元素,恰好是 g(0)(0),g(0)(1):
g(0)(0)=d4g(0)(1)=d5 如果 Prover 去除 d6,将剩下的向量 (d0,d1,d2,d3,d4,d5) 跟随 a 一同折叠(采用 r0 作为折叠因子),那么我们可以得到:
d0′d1′d2′=(1−r0)⋅d0+r0⋅d1=f~(r0,0,u2)=(1−r0)⋅d2+r0⋅d3=f~(r0,1,u2)=(1−r0)⋅d4+r0⋅d5=f~(r0,u1,u2) 我们惊奇地发现,d2′ 恰好是 g(0)(r0) 的值,而 d0′,d1′ 恰好是 g(1)(0),g(1)(1) 的值。
接下来在第二轮 Sumcheck 中,Prover 将 (d0′,d1′) 跟随 a′ 一起采用 r1 进行折叠,可以得到 d0′′ 的值:
d0′′=(1−r1)⋅d0′+r1⋅d1′=f~(r0,r1,u2) 这恰好是 g(1)(r1) 的值。
那么在第三轮 Sumcheck 中,Prover 需要发送 g(2)(0),g(2)(1) 的值,可是 d 向量已经折叠消失,不过这时候,Prover 手里有折叠后的 a 向量:
a0(2)a1(2)=f~(2)(0)=f~(r0,r1,0)=f~(2)(1)=f~(r0,r1,1) 这两个值恰好等于 g(2)(0),g(2)(1) 的值。
性能分析¶
至此,我们总结下,只需要让 Prover 在 Sumcheck 开始前,预计算出向量 d,它保存了 f~(X0,X1,X2) 依次带入 X2=u2,X1=u1,X0=u0 进行 Partial Evaluation 的所有中间结果。而这个向量跟随 a 向量采用相同的随机挑战数一同进行折叠,那么就可以高效计算出 g(i)(0),g(i)(1),g(i)(ri) 的值。其中预计算需要 2n−1 次乘法,折叠总共需要 2n−2 次乘法。
Prover 计算量:
- 预计算 d:2n 次乘法与 2⋅2n 次加法
- 折叠 a:2n 次乘法与 2⋅2n 次加法
- 折叠 d:2n 次乘法与 2⋅2n 次加法
Verifier 计算量:
- 验证 g(i)(0),g(i)(1):n 次乘法与 2n 次加法
- 计算 g(i)(ri):n 次乘法与 2n 次加法
再进一步优化 Verifier¶
在上面的协议中,Prover 需要发送 g(i)(0),g(i)(1) ,然后 Verifier 验证
g(i)(0)+(g(i)(1)−g(i)(0))⋅ui=?g(i−1)(ri−1)=g(i)(ui) 那么其实,Prover 在每轮 Sumcheck 中只需发送一个值 g(i)(0),然后 Verifier 根据「验证等式」反向计算得到 g(i)(1) :
g(i)(1)=uig(i−1)(ri−1)−g(i)(0)+g(i)(0) 这样一来 Verifier 用一次除法计算来换取通讯量的减少(一半)。但注意有限域除法(求逆)的计算开销要显著大于乘法,计算量至少是 o(logq) 的复杂度。但是无论如何,我们通过这种方式,可以进一步减少通讯量,即 Proof size。
其实,我们不难发现这个开销相对不小的除法是可以优化掉的,这个思路来源于 Deepfold []。我们让 Prover 在每轮 Sumcheck 中只发送 g(i)(ui+1) 而不是 gi(0) 或 gi(1):
g(i)(ui+1)=g(i)(ui)+g(i)(1)−g(i)(0) 再次提醒,g(i)(ui) 是 d 向量每次折叠之后的尾部元素,因此它的计算开销已经包含在 d 的折叠计算中。因此 Prover 的代价仅仅为在每轮额外计算两次加法。
然后,又因为此时Verifier 手里已经有了 g(i)(ui)=g(i−1)(ri−1),这样 Verifier 可以不用除法就可得到 g(i)(ri):
g(i)(ri)=g(i)(ui)+(g(i)(ui+1)−g(i)(ui))⋅(ri−ui) 计算开销仅为三次加法与一次乘法。
性能分析¶
Prover 计算量:
- 预计算 d:2n 次乘法与 2⋅2n 次加法
- 折叠 a:2n 次乘法与 2⋅2n 次加法
- 折叠 d:2n 次乘法与 2⋅2n 次加法
- 计算 g(i)(ui+1): 2n 次加法
Verifier 计算量:
- 计算 g(i)(ri):n 次乘法与 3n 次加法
从另一个角度来理解 Sumcheck 优化¶
上面我们经过多步的优化,达到了一个比较理想的状态。我们看看能否更容易地去理解这个简洁的协议。
我们可以把上面的优化协议看成是一个 Recursive Split-and-fold 风格的求和证明。因为本身 f~(u0,u1,u2) 就是一个数量为 8 项的求和式:
f~(u0,u1,u2)=a0(1−u0)(1−u1)(1−u2)+a1u0(1−u1)(1−u2)+a2(1−u0)u1(1−u2)+a3u0u1(1−u2)+a4(1−u0)u1u2+a5u0(1−u1)u2+a6u0u1(1−u2)+a7u0u1u2=(1−u0)⋅(a0(1−u1)(1−u2)+a2u1(1−u2)+a4(1−u1)u2+a6u1u2)+u0⋅(a1(1−u1)(1−u2)+a3u1(1−u2)+a5(1−u1)u2+a7u1u2) 第一轮,Prover 分别发送左半边的括号中 4 项的和,右半边括号中 4 项的和,分别记为 g0(0) 和 g0(1),并发送给 Verifier:
g0(0)g0(1)=a0(1−u1)(1−u2)+a2u1(1−u2)+a4(1−u1)u2+a6u1u2=a1(1−u1)(1−u2)+a3u1(1−u2)+a5(1−u1)u2+a7u1u2 或者
g0(0)g0(1)=f~(0,u1,u2)=f~(1,u1,u2) 然后 Verifier 首先验证 (g0(0),g0(1)) 与 (1−u0,u0) 进行内积的结果是否等于待证明的和 v,
(1−u0)⋅g0(0)+u0⋅g0(1)=?f~(u0,u1,u2) 这样一来,Prover 和 Verifier 就将长度为 8 的求和证明 Reduce 到了两个长度为 4 的求和证明。又因为这两个新的求和式实际上具有相同的结构,即它们都是多项式的奇偶项系数分别和同一向量 (1−u1,u1)⊗(1−u2,u2) 进行内积的结果,
g(0)(0)g(0)(1)=⟨(a0,a2,a4,a6),(1−u1,u1)⊗(1−u2,u2)⟩=⟨(a1,a3,a5,a7),(1−u1,u1)⊗(1−u2,u2)⟩ 所以 Verifier 可以给出一个随机数 r0,利用它把这两个新的求和证明合并(Batching)在一起。巧合的是,合并之后的长度为 4 的求和值恰好是 g(0)(r0) ,并且它等于 f~(r0,u1,u2)。当然这其实不是巧合,因为我们故意采用 (1−r0,r0) 这种 Multilinear Basis 对 g(0)(0),g(0)(1) 进行折叠,目的正是使之与 g(0)(r0) 保持相等:
(1−r0)⋅g0(0)+r0⋅g0(1)=f~(r0,u1,u2) 这样,Prover 和 Verifier 接下来证明合并后的长度为 4 个向量的求和值等于 f~(r0,u1,u2),即
(1−r0)⋅g(0)(0)+r0⋅g(0)(1)=?a0′w0′+a1′w1′+a2′w2′+a3′w3′ 依次类推,这个协议和 Sumcheck 协议的思路是一致的,都是将一个求和等式,通过拆分成多段不同部分的求和,然后再用随机数将这些不同的求和段合并在一起证明。直到最后一轮,求和证明 Reduce 到了多项式的求值证明,Prover 和 Verifier 再借助其他工具来补上最后的证明部分。
而最原始的 Sumcheck in Basefold 协议,则没有利用求和式内部结构,而是采用了一个更通用的内积求和的证明。因此本文介绍的简洁协议正式充分利用了求和项的内部结构。
References¶
- [GLH+24] Yanpei Guo, Xuanming Liu, Kexi Huang, Wenjie Qu, Tianyang Tao, and Jiaheng Zhang. “DeepFold: Efficient Multilinear Polynomial Commitment from Reed-Solomon Code and Its Application to Zero-knowledge Proofs.” Cryptology ePrint Archive (2024).
- [ACFY24] Gal Arnon, Alessandro Chiesa, Giacomo Fenzi, and Eylon Yogev. “WHIR: Reed–Solomon Proximity Testing with Super-Fast Verification.” Cryptology ePrint Archive (2024).
- [ZCF23] Hadas Zeilberger, Binyi Chen, and Ben Fisch. “BaseFold: efficient field-agnostic polynomial commitment schemes from foldable codes.” Annual International Cryptology Conference. Cham: Springer Nature Switzerland, 2024.
- [Hab24] Ulrich Haböck. “Basefold in the List Decoding Regime.” Cryptology ePrint Archive(2024).
- [Gru24] Angus Gruen. “Some Improvements for the PIOP for ZeroCheck”. (2024). https://eprint.iacr.org/2024/108.