1. 引言


上图源自 Vitalik 2021年11月博客 Halo and more: exploring incremental verification and SNARKs without pairings。

目前的多项式承诺Polynomial commitment方案主要有:

  • Kate polynomial commitment:具体可参见Dankrad Feist的介绍 Kate polynomial commitments
  • Bulletproofs commitment:具体可参见curve25519-dalek团队的介绍 Module bulletproofs:: notes::inner_product_proof
  • FRI (Fast Reed-Solomon Interactive Oracle Proofs of Proximity):具体可参见V神的介绍 STARKs, Part II: Thank Goodness It’s FRI-day

其中,Kate polynomial commitment需要用到 elliptic curve pairing。
相对来说,FRI更容易理解。

2. Kate多项式承诺

Kate多项式承诺又称KZG承诺,基于pairing曲线构建,满足bilinear属性:

详细的Kate多项式承诺方案见Kate等人2010年论文《Constant-Size Commitments to Polynomials and Their Applications》:

3. Bulletproofs多项式承诺

见博客 Halo: Recursive Proof Composition without a Trusted Setup 学习笔记 中“3. Polynomial commitments”:
假设polynomial p(X)p(X)p(X) 的degree bound为d−1d-1d−1,则:

  • Setup(1λ,d)Setup(1^{\lambda}, d)Setup(1λ,d):输出为common reference string σ=(G,Fp,G⃗,H)\sigma=(\mathbb{G},\mathbb{F}_p,\vec{G},H)σ=(G,Fp​,G,H) for group G\mathbb{G}G of prime order ppp, with random G⃗∈Gd\vec{G}\in\mathbb{G}^dG∈Gd and H∈GH\in\mathbb{G}H∈G。
  • Commit(σ,p(X);r)=<a⃗,G⃗>+[r]HCommit(\sigma,p(X);r)=<\vec{a},\vec{G}>+[r]HCommit(σ,p(X);r)=<a,G>+[r]H,其中rrr为blinding factor,ai∈Fa_i\in\mathbb{F}ai​∈F为多项式p(X)p(X)p(X)的 iiith degree term 系数,p(X)∈Fp[X]p(X)\in\mathbb{F}_p[X]p(X)∈Fp​[X]为maximal degree d−1d-1d−1。可将其看成是对多项式系数的Pedersen vector commitment,具有很好的hiding和加法同态属性——对于∀a,b,r,s∈Fp,p(X),q(X)∈Fp[X]\forall a,b,r,s\in\mathbb{F}_p, p(X),q(X)\in\mathbb{F}_p[X]∀a,b,r,s∈Fp​,p(X),q(X)∈Fp​[X],有:
    [a]Commit(σ,p(X);r)+[b]Commit(σ,q(X);s)=Commit(σ,a⋅p(X)+b⋅q(X);ar+bs)[a]Commit(\sigma,p(X);r)+[b]Commit(\sigma,q(X);s)=Commit(\sigma,a\cdot p(X)+b\cdot q(X); ar+bs)[a]Commit(σ,p(X);r)+[b]Commit(σ,q(X);s)=Commit(σ,a⋅p(X)+b⋅q(X);ar+bs)
  • Open(p(X),x)Open(p(X),x)Open(p(X),x):输出为v∈Fpv\in\mathbb{F}_pv∈Fp​。
  • VerifyOpen(P,x,v)VerifyOpen(P,x,v)VerifyOpen(P,x,v):判断the polynomial contained “inside” the commitment PPP evaluates to vvv at xxx。输出为1表示接受,0表示拒绝。

然后可将(Setup,Open,VerifyOpen)(Setup,Open,VerifyOpen)(Setup,Open,VerifyOpen)看成是a PSHVZK (perfect special honest-verifier zero knowledge) argument of knowledge for the relation:
{((P,x,v):(a⃗,r)):P=<a⃗,G⃗>+[r]H∧v=<a⃗,(1,x,x2,⋯,xd−1)>}\{((P,x,v):(\vec{a},r)): P=<\vec{a},\vec{G}>+[r]H\wedge v=<\vec{a},(1,x,x^2,\cdots,x^{d-1})>\}{((P,x,v):(a,r)):P=<a,G>+[r]H∧v=<a,(1,x,x2,⋯,xd−1)>}
以上relation 可用于证明 the polynomial contained “inside” the commitment PPP evaluates to vvv at xxx,甚至 the committed polynomial has maximum degree d−1d-1d−1。

基本信息展开为:

  • public info:P∈G,x,v∈FpP\in\mathbb{G},x,v\in\mathbb{F}_pP∈G,x,v∈Fp​
  • private info:a⃗∈Fpn,r∈Fp\vec{a}\in\mathbb{F}_p^n,r\in\mathbb{F}_pa∈Fpn​,r∈Fp​
  • relation:P=<a⃗,G⃗>+[r]H∧v=<a⃗,(1,x,x2,⋯,xd−1)>P=<\vec{a},\vec{G}>+[r]H\wedge v=<\vec{a},(1,x,x^2,\cdots,x^{d-1})>P=<a,G>+[r]H∧v=<a,(1,x,x2,⋯,xd−1)>

详细的思路为:

  • Verifier:生成随机group element U∈GU\in\mathbb{G}U∈G,将U∈GU\in\mathbb{G}U∈G发送给Prover。
  • Prover和Verifier:都计算P′=P+[v]UP'=P+[v]UP′=P+[v]U。
  • Prover:转为证明Prover知道a⃗∈Fpd,r,v′∈Fp\vec{a}\in\mathbb{F}_p^d,r,v'\in\mathbb{F}_pa∈Fpd​,r,v′∈Fp​,使得P′=<a⃗,G⃗>+[r]H+[v′]UP'=<\vec{a},\vec{G}>+[r]H+[v']UP′=<a,G>+[r]H+[v′]U成立,其中v′=<a⃗,(1,x,x2,⋯,xd−1)>v'=<\vec{a},(1,x,x^2,\cdots,x^{d-1})>v′=<a,(1,x,x2,⋯,xd−1)>。若Prover无法提前知道UUU,则v=v′v=v'v=v′成立。【注意,本文的“U”由Verifier在收到commitment PPP之后才提供,Bulletproofs中的也类似,而Hyrax中的dot-product proof protocol中没有做相应约定,存在prover在PPP中包含UUU信息,进而伪造证明的情况——a prover with malicious control of PPP would then be able to interfere with the argument by including terms involving UUU in PPP。】(参见博客 Hyrax: Doubly-efficient zkSNARKs without trusted setup学习笔记 第4.2节“dot-product proof with Bulletproofs”)

Bulletproofs中实现的基本信息为:(此处的UUU由Verifier先知道P=<a⃗,G⃗>+<b⃗,H⃗>P=<\vec{a},\vec{G}>+<\vec{b},\vec{H}>P=<a,G>+<b,H>后,发送challenge x∈Fx\in\mathbb{F}x∈F,然后Prover和Verifier重新计算的U=xU∈GU=xU\in\mathbb{G}U=xU∈G。)【非zero-knowledge的inner product argument】

  • public info:commitment P′P'P′,generators G⃗,H⃗∈Gd,U∈G\vec{G},\vec{H}\in\mathbb{G}^d,U\in\mathbb{G}G,H∈Gd,U∈G。
  • private info:a⃗,b⃗∈Fd\vec{a},\vec{b}\in\mathbb{F}^da,b∈Fd。
  • relation:P′=<a⃗,G⃗>+<b⃗,H⃗>+[<a⃗,b⃗>]UP'=<\vec{a},\vec{G}>+<\vec{b},\vec{H}>+[<\vec{a},\vec{b}>]UP′=<a,G>+<b,H>+[<a,b>]U

本文针对的情况是,其中b⃗=(1,x,x2,⋯,xn−1)\vec{b}=(1,x,x^2,\cdots,x^{n-1})b=(1,x,x2,⋯,xn−1) 为public info,对Prover和Verifier均已知,所以,此时不再需要H⃗∈Gd\vec{H}\in\mathbb{G}^dH∈Gd。根据需要,可额外再引入generator H∈GH\in\mathbb{G}H∈G来实现blinding both prover messages and the commitment P′P'P′。最终基本信息为:

  • public info:commitment P′P'P′,generators G⃗∈Gd,H,U∈G\vec{G}\in\mathbb{G}^d, H, U\in\mathbb{G}G∈Gd,H,U∈G 和b⃗∈Fd\vec{b}\in\mathbb{F}^db∈Fd。
  • private info:a⃗∈Fd\vec{a}\in\mathbb{F}^da∈Fd和blinding r∈Fr\in\mathbb{F}r∈F。
  • relation:P′=<a⃗,G⃗>+rH+[<a⃗,b⃗>]UP'=<\vec{a},\vec{G}>+rH+[<\vec{a},\vec{b}>]UP′=<a,G>+rH+[<a,b>]U。

假设d=2k,k>0d=2^k,k>0d=2k,k>0,Prover初始化G⃗′=G⃗,a⃗′=a⃗,b⃗′=b⃗,P=P′\vec{G}'=\vec{G},\vec{a}'=\vec{a},\vec{b}'=\vec{b},P=P'G′=G,a′=a,b′=b,P=P′,然后进行kkk轮交互,其中 in the jjjth round (starting with j=kj=kj=k and finishing with j=1j=1j=1):
1)若d=1d=1d=1,则:【目前有2种实现思路。】
1.1)Hyrax中的思路为:【此时有P=a′G′+rH+a′b′UP=a'G'+rH+a'b'UP=a′G′+rH+a′b′U,其中a′,r∈Fa',r\in\mathbb{F}a′,r∈F为private info,b′∈F,G′,H,U,P∈Gb'\in\mathbb{F}, G',H,U,P\in\mathbb{G}b′∈F,G′,H,U,P∈G均为public info。】

  • Prover:引入Prover私有blinding随机数d,rδ,rβ←Fd,r_{\delta},r_{\beta}\leftarrow\mathbb{F}d,rδ​,rβ​←F,计算δ=dG′+rδH,β=dU+rδH\delta=dG'+r_{\delta}H, \beta=dU+r_{\delta}Hδ=dG′+rδ​H,β=dU+rδ​H,将δ,β∈G\delta,\beta\in\mathbb{G}δ,β∈G发送给Verifier。
  • Verifier:发送challenge c←Fc\leftarrow \mathbb{F}c←F 给Prover。
  • Prover:计算z1=d+c⋅a′b′,z2=b′(c⋅r+rβ)+rδz_1=d+c\cdot a'b', z_2=b'(c\cdot r+r_{\beta})+r_{\delta}z1​=d+c⋅a′b′,z2​=b′(c⋅r+rβ​)+rδ​,将z1,z2∈Fz_1,z_2\in\mathbb{F}z1​,z2​∈F发送给Verifier。
  • Verifier:验证b′(cP+β)+δ=z1(G′+b′U)+z2Hb'(cP+\beta)+\delta=z_1(G'+b'U)+z_2Hb′(cP+β)+δ=z1​(G′+b′U)+z2​H是否成立即可。

1.2)本文的思路为(相比于Hyrax方案,proof size少了一个group element G\mathbb{G}G):【此时有P=[a′]G′+[r]H+[a′b′]U=[a′](G+[b′]U)+[r]HP=[a']G'+[r]H+[a'b']U=[a'](G+[b']U)+[r]HP=[a′]G′+[r]H+[a′b′]U=[a′](G+[b′]U)+[r]H,其中a′,r∈Fa',r\in\mathbb{F}a′,r∈F为private info,b′∈F,G′,H,U,P∈Gb'\in\mathbb{F}, G',H,U,P\in\mathbb{G}b′∈F,G′,H,U,P∈G均为public info。】(其中(G+[b′]U)(G+[b']U)(G+[b′]U)为public info,可直接用 博客 基于Sigma protocol实现的零知识证明protocol集锦 第2.4节 “2.4 Protocol 4. Knowledge of the opening of Pedersen commitment”来计算。)

  • Prover:引入Prover私有blinding随机数d,rδ←Fd,r_{\delta}\leftarrow\mathbb{F}d,rδ​←F,计算δ=d(G′+b′U)+rδH\delta=d(G'+b'U)+r_{\delta}Hδ=d(G′+b′U)+rδ​H,将δ∈G\delta \in\mathbb{G}δ∈G发送给Verifier。
  • Verifier:发送challenge c←Fc\leftarrow \mathbb{F}c←F 给Prover。
  • Prover:计算z1=d+a′c,z2=rδ+rcz_1=d+a'c, z_2=r_{\delta}+rcz1​=d+a′c,z2​=rδ​+rc,将z1,z2∈Fz_1,z_2\in\mathbb{F}z1​,z2​∈F发送给Verifier。
  • Verifier:验证cP+δ=z1(G′+b′U)+z2HcP+\delta=z_1(G'+b'U)+z_2HcP+δ=z1​(G′+b′U)+z2​H是否成立即可。

2)若d>1d>1d>1,则j=log⁡2d,d′=d2j=\log_2{d}, d'=\frac{d}{2}j=log2​d,d′=2d​,有:

  • Prover:计算:
    d′=d/2d'=d/2d′=d/2。
    引入Prover私有blinding随机数lj,rj←Fl_j,r_j\leftarrow\mathbb{F}lj​,rj​←F,计算Lj=<a⃗lo′,G⃗hi′>+[lj]H+[<a⃗lo′,b⃗hi′>]UL_j=<\vec{a}'_{lo},\vec{G}'_{hi}>+[l_j]H+[<\vec{a}'_{lo},\vec{b}'_{hi}>]ULj​=<alo′​,Ghi′​>+[lj​]H+[<alo′​,bhi′​>]U,Rj=<a⃗hi′,G⃗lo′>+[rj]H+[<a⃗hi′,b⃗lo′>]UR_j=<\vec{a}'_{hi},\vec{G}'_{lo}>+[r_j]H+[<\vec{a}'_{hi},\vec{b}'_{lo}>]URj​=<ahi′​,Glo′​>+[rj​]H+[<ahi′​,blo′​>]U。
    将Lj,Rj∈GL_j,R_j\in\mathbb{G}Lj​,Rj​∈G发送给Verifier。

  • Verifier:发送random challenge uj∈Fu_j\in\mathbb{F}uj​∈F 给Prover。

  • Prover:计算:
    a⃗′=a⃗hi′⋅uj−1+a⃗lo′⋅uj\vec{a}'=\vec{a}'_{hi}\cdot u_j^{-1}+\vec{a}'_{lo}\cdot u_ja′=ahi′​⋅uj−1​+alo′​⋅uj​
    r′=ljuj2+r+rjuj−2r'=l_ju_j^2+r+r_ju_j^{-2}r′=lj​uj2​+r+rj​uj−2​

  • Prover和Verifier:计算:
    b⃗′=b⃗lo′⋅uj−1+b⃗hi′⋅uj\vec{b}'=\vec{b}'_{lo}\cdot u_j^{-1}+\vec{b}'_{hi}\cdot u_jb′=blo′​⋅uj−1​+bhi′​⋅uj​
    G⃗′=G⃗lo′⋅uj−1+G⃗hi′⋅uj\vec{G}'=\vec{G}'_{lo}\cdot u_j^{-1}+\vec{G}'_{hi}\cdot u_jG′=Glo′​⋅uj−1​+Ghi′​⋅uj​
    P′=[uj2]Lj+P+[uj−2]RjP'= [u_j^2]L_j+P+ [u_j^{-2}]R_jP′=[uj2​]Lj​+P+[uj−2​]Rj​

  • 设置d=d′,P=P′,r=r′d=d',P=P',r=r'd=d′,P=P′,r=r′,继续从步骤1)开始执行。

在以上证明过程中,关注Prover在每轮递归调用时计算的内容:
a⃗′=a⃗hi′⋅uj−1+a⃗lo′⋅uj\vec{a}'=\vec{a}'_{hi}\cdot u_j^{-1}+\vec{a}'_{lo}\cdot u_ja′=ahi′​⋅uj−1​+alo′​⋅uj​
b⃗′=b⃗lo′⋅uj−1+b⃗hi′⋅uj\vec{b}'=\vec{b}'_{lo}\cdot u_j^{-1}+\vec{b}'_{hi}\cdot u_jb′=blo′​⋅uj−1​+bhi′​⋅uj​
G⃗′=G⃗lo′⋅uj−1+G⃗hi′⋅uj\vec{G}'=\vec{G}'_{lo}\cdot u_j^{-1}+\vec{G}'_{hi}\cdot u_jG′=Glo′​⋅uj−1​+Ghi′​⋅uj​

  • 与最后一轮d=1d=1d=1时的G′∈G,b′∈FG'\in\mathbb{G},b'\in\mathbb{F}G′∈G,b′∈F之间的关系为G′=<s⃗,G⃗>,b′=<s⃗,b⃗>G'=<\vec{s},\vec{G}>,b'=<\vec{s},\vec{b}>G′=<s,G>,b′=<s,b>,其中s⃗\vec{s}s为:
    s⃗=(u1−1u2−1⋯uk−1,u1u2−1⋯uk−1,u1−1u2⋯uk−1,u1u2⋯uk−1,⋮u1u2⋯uk)\vec{s}=(u_1^{-1}u_2^{-1}\cdots u_k^{-1}, \\ u_1 u_2^{-1}\cdots u_k^{-1}, \\ u_1^{-1}u_2\cdots u_k^{-1},\\ u_1u_2\cdots u_k^{-1},\\ \vdots \\ u_1u_2\cdots u_k)s=(u1−1​u2−1​⋯uk−1​,u1​u2−1​⋯uk−1​,u1−1​u2​⋯uk−1​,u1​u2​⋯uk−1​,⋮u1​u2​⋯uk​)
  • Verifier在最后一轮收到的commitment P′P'P′,满足以下公式:
    P′=∑j=1k([uj2]Lj)+P+∑j=1k([uj−2]Rj)P'= \sum_{j=1}^{k}([u_j^2]L_j)+P+ \sum_{j=1}^{k}([u_j^{-2}]R_j)P′=∑j=1k​([uj2​]Lj​)+P+∑j=1k​([uj−2​]Rj​)
  • Prover在最后一轮的blinding值r′r'r′满足如下公式:
    r′=∑j=1k(ljuj2)+r+∑j=1k(rjuj−2)r'=\sum_{j=1}^{k}(l_ju_j^2)+r+\sum_{j=1}^{k}(r_ju_j^{-2})r′=∑j=1k​(lj​uj2​)+r+∑j=1k​(rj​uj−2​)

3.1 Amortization Strategy摊销策略

以上polynomial commitment,尽管其communication complexity为O(log⁡2(d))O(\log_2(d))O(log2​(d)),其中d−1d-1d−1为多项式的degree bound,但是Verifier必须在验证时计算G′=<s⃗,G⃗>,b′=<s⃗,b⃗>G'=<\vec{s},\vec{G}>,b'=<\vec{s},\vec{b}>G′=<s,G>,b′=<s,b>,其中s⃗=(u1−1u2−1⋯uk−1,u1u2−1⋯uk−1,u1−1u2⋯uk−1,u1u2⋯uk−1,⋮u1u2⋯uk)\vec{s}=(u_1^{-1}u_2^{-1}\cdots u_k^{-1}, \\ u_1 u_2^{-1}\cdots u_k^{-1}, \\ u_1^{-1}u_2\cdots u_k^{-1},\\ u_1u_2\cdots u_k^{-1},\\ \vdots \\ u_1u_2\cdots u_k)s=(u1−1​u2−1​⋯uk−1​,u1​u2−1​⋯uk−1​,u1−1​u2​⋯uk−1​,u1​u2​⋯uk−1​,⋮u1​u2​⋯uk​)。

注意,本文针对的情况是b⃗=(1,x,x2,⋯,xn−1)\vec{b}=(1,x,x^2,\cdots,x^{n-1})b=(1,x,x2,⋯,xn−1)为public info的情况,其中的<s⃗,b⃗><\vec{s},\vec{b}><s,b>可看成对多项式:【注意,感觉论文的g(X,u1,u2,⋯,uk)g(X,u_1,u_2,\cdots,u_k)g(X,u1​,u2​,⋯,uk​)公式有点问题,但是作者说木问题。。。
g(X,u1,u2,⋯,uk)=∏i=1k(ui−1+uiX2i−1)g(X,u_1,u_2,\cdots,u_k)=\prod_{i=1}^{k}(u_i^{-1}+u_iX^{2^{i-1}})g(X,u1​,u2​,⋯,uk​)=∏i=1k​(ui−1​+ui​X2i−1)
在point xxx的evaluation值,即b′=<s⃗,b⃗>=g(x,u1,u2,⋯,uk)b'=<\vec{s},\vec{b}>=g(x,u_1,u_2,\cdots,u_k)b′=<s,b>=g(x,u1​,u2​,⋯,uk​)。Verifier可计算该evaluation值in logarithmic time。
但是,对于G′=<s⃗,G⃗>G'=<\vec{s},\vec{G}>G′=<s,G>计算,仍然需要a linear-time multiscalar multiplication。但是仔细观察,可将G′G'G′看成是对多项式g(X,u1,u2,⋯,uk)g(X,u_1,u_2,\cdots,u_k)g(X,u1​,u2​,⋯,uk​)系数的commitment值:
G′=Commit(σ,g(X,u1,u2,⋯,uk))G'=Commit(\sigma, g(X,u_1,u_2,\cdots,u_k))G′=Commit(σ,g(X,u1​,u2​,⋯,uk​))
所以 与其让Verifier为mmm个(independent)arguments 自己计算Gi′G'_iGi′​,不如将该计算外包给不可信的第三方“helper“ ,”helper”在提供G1′,G2′,⋯,Gm′G_1',G_2',\cdots,G_m'G1′​,G2′​,⋯,Gm′​ (for mmm separate arguments) 计算结果的同时提供相应的argument that each are correct by demonstrating that a random linear combination of the commitments opens at a random point to a value the verifier can compute in time O(mlog⁡(d))O(m\log(d))O(mlog(d))。基于Schwartz-Zippel Lemma,”helper“可让Verifier信服其结果是正确计算的(其伪造成功的概率不高于d−1p−1\frac{d-1}{p-1}p−1d−1​)。
也就是说,此时,Verifier需调用“helper“运行对g(X,u1,u2,⋯,uk)g(X,u_1,u_2,\cdots,u_k)g(X,u1​,u2​,⋯,uk​)的polynomial commitment opening protocol,最终Verifier仍需要进行一次linear-time operation,但是通过此操作,the verifier has traded mmm linear-time operations for one, with a marginal cost that is logarithmic in the degree bound。

4. FRI多项式承诺

详细见:

  • STARK入门知识 “第4章 FRI”
  • Fast Reed-Solomon Interactive Oracle Proofs of Proximity学习笔记

采用基于FRI的compiler可将Polynomial IOP转换为a concrete proof system。

FRI协议用于确认a committed polynomial具有bounded degree。

FRI全称为Fast Reed-Solomon IOP of Proximity,其中IOP表示interactive oracle proof。

FRI采用codewords来表示,Verifier无法读取Prover发来的所有codewords,Verifier会make oracle-queries to read them in select locations。
FRI中的codewords为Reed-Solomon codewords,即其值对应为the evaluation of some low-degree polynomial in a list of points called the domain DDD。该list的length要大于多项式中可能的非零值系数的个数 ρ\rhoρ倍,ρ\rhoρ称为expansion factor(或blowup factor)。
【即有:initial_codeword_length = (degree + 1) * expansion_factor

codewords表示low-degree polynomials。codewords采用merkle tree来实例化。

常规的Polynomial commitment scheme为:

  • polynomial commitment及实现方式对比

而FRI scheme有所不同。FRI用于证明某codeword属于a polynomial of low degree。所谓low,是指degree 值不高于 ρ⋅len(codeword)\rho\cdot len(codeword)ρ⋅len(codeword)。Prover知道codeword具体内容,而Verifier仅知道Merkle root和其选择的leaf。通过authentication path verification来确认the leaf’s membership to the Merkle tree。

proof system中很赞的一个思想是:split-and-fold技术。可:(假设待证明的claim size为nnn)

  • 1)将a claim reduce为 two claims of half the size。
  • 2)然后利用Verifier提供的random challenge合并为一个claim。
  • 3)重复以上步骤log⁡2(n)−1\log_2(n)-1log2​(n)−1次,可最终reduce为a trivial size claim,其为true 当且仅当 原始claim为true。

对于FRI,相应的computational claim为:某特定codeword对应为a polynomial of low degree。令NNN为codeword length。ddd为该对应多项式的最大degree,表示为f(X)=∑idciXif(X)=\sum_{i}^{d}c_iX^if(X)=∑id​ci​Xi。

根据FFT的divide-and-conquer策略,可将多项式分为奇数项和偶数项表示:
f(X)=fE(X2)+X⋅fO(X2)f(X)=f_E(X^2)+X\cdot f_O(X^2)f(X)=fE​(X2)+X⋅fO​(X2)
其中:
fE(X2)=f(X)+f(−X)2=∑i=0d+12−1c2iX2if_E(X^2)=\frac{f(X)+f(-X)}{2}=\sum_{i=0}^{\frac{d+1}{2}-1}c_{2i}X^{2i}fE​(X2)=2f(X)+f(−X)​=∑i=02d+1​−1​c2i​X2i
fO(X2)=f(X)−f(−X)2X=∑i=0d+12−1c2i+1X2if_O(X^2)=\frac{f(X)-f(-X)}{2X}=\sum_{i=0}^{\frac{d+1}{2}-1}c_{2i+1}X^{2i}fO​(X2)=2Xf(X)−f(−X)​=∑i=02d+1​−1​c2i+1​X2i

FRI协议的关键是根据codeword for f(X)f(X)f(X) 来派生 codeword for f∗(X)=fE(X)+α⋅fO(X)f^{*}(X)=f_E(X)+\alpha\cdot f_O(X)f∗(X)=fE​(X)+α⋅fO​(X)。其中α\alphaα为由Verifier提供的random scalar。

假设DDD为某multiplicative group的subgroup,DDD 具有even order NNN。令ω\omegaω为生成subgroup DDD的generator:⟨ω⟩=D⊂Fp\{0}\langle \omega \rangle = D \subset \mathbb{F}_p \backslash\lbrace 0\rbrace⟨ω⟩=D⊂Fp​\{0}。
令{f(ωi)}i=0N−1\lbrace f(\omega^i)\rbrace_{i=0}^{N-1}{f(ωi)}i=0N−1​ 为f(X)f(X)f(X)的codeword,其实对应为evaluation on DDD。

令 D⋆=⟨ω2⟩D^\star = \langle \omega^2 \rangleD⋆=⟨ω2⟩ 为另一domain,其length为DDD的一半。
令 {fE(ω2i)}i=0N/2−1\lbrace f_ E(\omega^{2i})\rbrace_{i=0}^{N/2-1}{fE​(ω2i)}i=0N/2−1​,{fO(ω2i)}i=0N/2−1\lbrace f_ O(\omega^{2i})\rbrace_{i=0}^{N/2-1}{fO​(ω2i)}i=0N/2−1​ 和 {f⋆(ω2i)}i=0N/2−1\lbrace f^\star(\omega^{2i})\rbrace_ {i=0}^{N/2-1}{f⋆(ω2i)}i=0N/2−1​ 分别为 the codewords for fE(X)f_E(X)fE​(X),fO(X)f_O(X)fO​(X) 和 f⋆(X)f^\star(X)f⋆(X),其实对应为evaluation on D⋆D^\starD⋆。

将 f⋆(X)f^\star(X)f⋆(X) 的定义扩展为:
{f⋆(ω2i)}i=0N/2−1={fE(ω2i)+α⋅fO(ω2i)}i=0N/2−1.\lbrace f^\star(\omega^{2i})\rbrace_{i=0}^{N/2-1} = \lbrace f_E(\omega^{2i}) + \alpha \cdot f_O(\omega^{2i})\rbrace_{i=0}^{N/2-1} . {f⋆(ω2i)}i=0N/2−1​={fE​(ω2i)+α⋅fO​(ω2i)}i=0N/2−1​.

再次根据fE(X2)f_E(X^2)fE​(X2) 和 fO(X2)f_O(X^2)fO​(X2) 的定义将 f⋆(X)f^\star(X)f⋆(X) 扩展为:
{f⋆(ω2i)}i=0N/2−1\lbrace f^\star(\omega^{2i})\rbrace_{i=0}^{N/2-1} {f⋆(ω2i)}i=0N/2−1​
={f(ωi)+f(−ωi)2+α⋅f(ωi)−f(−ωi)2ωi}i=0N/2−1= \left\lbrace \frac{f(\omega^i) + f(-\omega^i)}{2} + \alpha \cdot \frac{f(\omega^i) - f(-\omega^i)}{2 \omega^i} \right\rbrace_{i=0}^{N/2-1} ={2f(ωi)+f(−ωi)​+α⋅2ωif(ωi)−f(−ωi)​}i=0N/2−1​
={2−1⋅((1+α⋅ω−i)⋅f(ωi)+(1−α⋅ω−i)⋅f(−ωi))}i=0N/2−1= \lbrace 2^{-1} \cdot \left( ( 1 + \alpha \cdot \omega^{-i} ) \cdot f(\omega^i) + (1 - \alpha \cdot \omega^{-i} ) \cdot f(-\omega^i) \right) \rbrace_{i=0}^{N/2-1} ={2−1⋅((1+α⋅ω−i)⋅f(ωi)+(1−α⋅ω−i)⋅f(−ωi))}i=0N/2−1​

由于ω\omegaω的order为NNN,因此有ωN/2=−1\omega^{N/2}=-1ωN/2=−1,从而有f(−ωi)=f(ωN/2+i)f(-\omega^i)=f(\omega^{N/2+i})f(−ωi)=f(ωN/2+i)。因此,尽管iterate index减半为由000到N/2−1N/2-1N/2−1,但是所有的points并未减半,仍为{f(ωi)}i=0N−1\{f(\omega^i)\}_{i=0}^{N-1}{f(ωi)}i=0N−1​。所有的这些points用于派生{f⋆(ω2i)}i=0N/2−1\lbrace f^\star(\omega^{2i})\rbrace_{i=0}^{N/2-1}{f⋆(ω2i)}i=0N/2−1​,尽管派生后的codeword仅有一半length,尽管其polynomial仅有half the degree。

以FRI protocol中的一轮为例:

  • 1)Prover commit to f(X)f(X)f(X):将其codeword {f(ωi)}i=0N−1\lbrace f(\omega^i)\rbrace_{i=0}^{N-1}{f(ωi)}i=0N−1​ 的merkle root发送给Verifier。
  • 2)Verifier发送challenge α\alphaα。
  • 3)Prover计算并commit to f⋆(X)f^\star(X)f⋆(X):将其codeword {f⋆(ω2i)}i=0N/2−1\lbrace f^\star(\omega^{2i})\rbrace_{i=0}^{N/2-1}{f⋆(ω2i)}i=0N/2−1​ 的merkle root发送给Verifier。
  • 4)Verifier此时有2组polynomial commitments,接下来要验证两者之间的关系是否正确:
    f⋆(X)=2−1⋅((1+αX−1)⋅f(X)+(1−αX−1)⋅f(−X))f^\star(X) = 2^{-1} \cdot \left( (1 + \alpha X^{-1}) \cdot f(X) + (1 - \alpha X^{-1} ) \cdot f(-X) \right)f⋆(X)=2−1⋅((1+αX−1)⋅f(X)+(1−αX−1)⋅f(−X))
    为此,Verifier需随机选择一个index i←R{0,…,N/2−1}i \xleftarrow{R} \lbrace 0, \ldots, N/2-1\rbraceiR​{0,…,N/2−1},【注意,index的选择是与round关联的。如果index的选择与round不相关,则可能会存在fail to catch hybrid codewords的情况。实时上,可在所有轮中复用相同的index,必要时基于codeword length 进行modulo运算。】
    从而可确定3个point:

    • A:(ωi,f(ωi))A: (\omega^i, f(\omega^i))A:(ωi,f(ωi))
    • B:(ωN/2+i,f(ωN/2+i))B: (\omega^{N/2+i}, f(\omega^{N/2+i}))B:(ωN/2+i,f(ωN/2+i))
    • C:(α,f⋆(ω2i))C: (\alpha, f^\star(\omega^{2i}))C:(α,f⋆(ω2i))
      注意,A和BA和BA和B的xxx坐标为ω2i\omega^{2i}ω2i的平方根。
  • 5)Prover收到Verifier发来的index iii之后,仅需提供Merkle authentication paths的yyy坐标。
  • 6)Verifier验证该authentication path与root匹配,同时验证A,B,CA,B,CA,B,C在同一条直线上(又称为colinearity check)。
    colinearity check成立的原因在于:穿过A、B的直线可表示为:
    y=∑iyi∏j≠ix−xjxi−xj=f(ωi)⋅x−ωN/2+iωi−ωN/2+i+f(ωN/2+i)⋅x−ωiωN/2+i−ωi=f(ωi)⋅2−1⋅ω−i⋅(x+ωi)−f(ωN/2+i)⋅2−1⋅ω−i(x−ωi)=2−1⋅((1+x⋅ω−i)⋅f(ωi)+(1−x⋅ω−i)⋅f(ωN/2+i)).y = \sum_i y_i \prod_{j \neq i} \frac{x - x_j}{x_i - x_j} \\ = f(\omega^i) \cdot \frac{x - \omega^{N/2+i}}{\omega^{i} - \omega^{N/2+i}} + f(\omega^{N/2+i}) \cdot \frac{x - \omega^{i}}{\omega^{N/2+i} - \omega^{i}} \\ = f(\omega^i) \cdot 2^{-1} \cdot \omega^{-i} \cdot (x + \omega^i) - f(\omega^{N/2+i}) \cdot 2^{-1} \cdot \omega^{-i} (x - \omega^i) \\ = 2^{-1} \cdot \left( (1 + x \cdot \omega^{-i}) \cdot f(\omega^i) + (1 - x \cdot \omega^{-i}) \cdot f(\omega^{N/2 + i}) \right) \enspace .y=i∑​yi​j=i∏​xi​−xj​x−xj​​=f(ωi)⋅ωi−ωN/2+ix−ωN/2+i​+f(ωN/2+i)⋅ωN/2+i−ωix−ωi​=f(ωi)⋅2−1⋅ω−i⋅(x+ωi)−f(ωN/2+i)⋅2−1⋅ω−i(x−ωi)=2−1⋅((1+x⋅ω−i)⋅f(ωi)+(1−x⋅ω−i)⋅f(ωN/2+i)).
    当x=αx=\alphax=α时,即有y=f⋆(ω2i)y= f^\star(\omega^{2i})y=f⋆(ω2i),从而说明CCC也在该直线上。

重复以上round即可。一共需要log⁡2(d+1)−1\log_2(d+1)-1log2​(d+1)−1轮,其中ddd为原始多项式的degree。最终获得的为constant polynomial,其codeword也为constant。最后一轮中,Prover直接将该constant而不是merkle root发送给Verifier即可。

4.1 FRI多项式承诺代码解析

相应的Python伪代码示例为:

  • 1)初始化:

    import math
    from hashlib import blake2bclass Fri:def __init__( self, offset, omega, initial_domain_length, expansion_factor, num_colinearity_tests ):self.offset = offsetself.omega = omegaself.domain_length = initial_domain_lengthself.field = omega.fieldself.expansion_factor = expansion_factorself.num_colinearity_tests = num_colinearity_testsdef num_rounds( self ):codeword_length = self.domain_lengthnum_rounds = 0while codeword_length > self.expansion_factor and 4*self.num_colinearity_tests < codeword_length:codeword_length /= 2num_rounds += 1return num_roundsdef eval_domain( self ):return [self.offset * (self.omega^i) for i in range(self.domain_length)]
    
  • 2)证明:

    def prove( self, codeword, proof_stream ):assert(self.domain_length == len(codeword)), "initial codeword length does not match length of initial codeword"# commit phasecodewords = self.commit(codeword, proof_stream)# get indicestop_level_indices = self.sample_indices(proof_stream.prover_fiat_shamir(), len(codewords[1]), len(codewords[-1]), self.num_colinearity_tests)indices = [index for index in top_level_indices]# query phasefor i in range(len(codewords)-1):indices = [index % (len(codewords[i])//2) for index in indices] # foldself.query(codewords[i], codewords[i+1], indices, proof_stream)return top_level_indices
    

    其中Prover在commit阶段包含了多轮,在每一轮中,会:

    • 计算the working codeword的Merkle root;
    • 将该Merkle root发送给Verifier;
    • Verifier提供随机challenge α\alphaα;
    • Prover运用split-and-fold共识来派生a codeword for the next round;
    • Prover对offset ggg和generator ω\omegaω求平方,使得{g⋅ωi∣i∈Z}\{g\cdot \omega^i|i\in\mathbb{Z}\}{g⋅ωi∣i∈Z}总是对应working codeword的evaluation domain。【为避免与STARK协议中的evaluation domain有交集,此处引入了offset ggg以实现Coset-FRI。】

    commit阶段最后一轮运行完成后,Prover仅有一个codeword,将该codeword以明文形式发送给Verifier。最后,Prover需要跟踪每一轮所计算的codewords,以便在Query阶段中可open相应的Merkle tree proof。
    详细的commit示例代码为:

     def commit( self, codeword, proof_stream, round_index=0 ):one = self.field.one()two = FieldElement(2, self.field)omega = self.omegaoffset = self.offsetcodewords = []# for each roundfor r in range(self.num_rounds()):# compute and send Merkle rootroot = Merkle.commit(codeword)proof_stream.push(root)# prepare next round, if necessaryif r == self.num_rounds() - 1:break# get challengealpha = self.field.sample(proof_stream.prover_fiat_shamir())# collect codewordcodewords += [codeword]# split and foldcodeword = [two.inverse() * ( (one + alpha / (offset * (omega^i)) ) * codeword[i] + (one - alpha / (offset * (omega^i)) ) * codeword[len(codeword)//2 + i] ) for i in range(len(codeword)//2)]omega = omega^2offset = offset^2# send last codewordproof_stream.push(codeword)# collect last codeword toocodewords = codewords + [codeword]return codewords
    

    commit阶段还包含具有相同迭代次数的另一个循环:

    • A点和B点的x坐标的indices均派生自 C点x坐标的indices,即共用相同的iii。
    • 会将indices所指定的codeword值 以及 相应的authentication paths 发送给Verifier。

    具体获取indices见sample_indices函数,基于seed和counter调用blake2b来获得伪随机indices:

    def sample_index( byte_array, size ):acc = 0for b in byte_array:acc = (acc << 8) ^ int(b)return acc % sizedef sample_indices( self, seed, size, reduced_size, number ):assert(number <= reduced_size), f"cannot sample more indices than available in last codeword; requested: {number}, available: {reduced_size}"assert(number <= 2*reduced_size), "not enough entropy in indices wrt last codeword"indices = []reduced_indices = []counter = 0while len(indices) < number:index = Fri.sample_index(blake2b(seed + bytes(counter)).digest(), size)reduced_index = index % reduced_sizecounter += 1if reduced_index not in reduced_indices:indices += [index]reduced_indices += [reduced_index]return indices
    

    Query阶段,为

    def query( self, current_codeword, next_codeword, c_indices, proof_stream ):# infer a and b indicesa_indices = [index for index in c_indices]b_indices = [index + len(current_codeword)//2 for index in c_indices]# reveal leafsfor s in range(self.num_colinearity_tests):proof_stream.push((current_codeword[a_indices[s]], current_codeword[b_indices[s]], next_codeword[c_indices[s]]))# reveal authentication pathsfor s in range(self.num_colinearity_tests):proof_stream.push(Merkle.open(a_indices[s], current_codeword))proof_stream.push(Merkle.open(b_indices[s], current_codeword))proof_stream.push(Merkle.open(c_indices[s], next_codeword))return a_indices + b_indices
    
  • 3)验证:Verifier验证过程中:

    • 3.1)从proof stream中读取Merkle roots,借助Fiat-Shamir重构出每轮的random scalar α\alphaα;
    • 3.2)从proof sream中读取最后一轮的codewords,检查其是否与a low degree polynomial匹配,同时检查是否与最后一个Merkle root匹配;
    • 3.3)借助Fiat-Shamir,重构出master list of random indices,然后推断出colinearity checks所需的indices;
    • 3.4)从proof stream中读取Merkle leaves及其authentication paths,并验证their authenticity against the indices;
    • 3.5)为每组相邻codewords运行colinearity checks。
    def verify( self, proof_stream, polynomial_values ):omega = self.omegaoffset = self.offset# extract all roots and alphasroots = []alphas = []for r in range(self.num_rounds()):roots += [proof_stream.pull()]alphas += [self.field.sample(proof_stream.verifier_fiat_shamir())]# extract last codewordlast_codeword = proof_stream.pull()# check if it matches the given rootif roots[-1] != Merkle.commit(last_codeword):print("last codeword is not well formed")return False# check if it is low degreedegree = (len(last_codeword) // self.expansion_factor) - 1last_omega = omegalast_offset = offsetfor r in range(self.num_rounds()-1):last_omega = last_omega^2last_offset = last_offset^2# assert that last_omega has the right orderassert(last_omega.inverse() == last_omega^(len(last_codeword)-1)), "omega does not have right order"# compute interpolantlast_domain = [last_offset * (last_omega^i) for i in range(len(last_codeword))]poly = Polynomial.interpolate_domain(last_domain, last_codeword)#coefficients = intt(last_omega, last_codeword)#poly = Polynomial(coefficients).scale(last_offset.inverse())# verify by  evaluatingassert(poly.evaluate_domain(last_domain) == last_codeword), "re-evaluated codeword does not match original!"if poly.degree() > degree:print("last codeword does not correspond to polynomial of low enough degree")print("observed degree:", poly.degree())print("but should be:", degree)return False# get indicestop_level_indices = self.sample_indices(proof_stream.verifier_fiat_shamir(), self.domain_length >> 1, self.domain_length >> (self.num_rounds()-1), self.num_colinearity_tests)# for every round, check consistency of subsequent layersfor r in range(0, self.num_rounds()-1):# fold c indicesc_indices = [index % (self.domain_length >> (r+1)) for index in top_level_indices]# infer a and b indicesa_indices = [index for index in c_indices]b_indices = [index + (self.domain_length >> (r+1)) for index in a_indices]# read values and check colinearityaa = []bb = []cc = []for s in range(self.num_colinearity_tests):(ay, by, cy) = proof_stream.pull()aa += [ay]bb += [by]cc += [cy]# record top-layer values for later verificationif r == 0:polynomial_values += [(a_indices[s], ay), (b_indices[s], by)]# colinearity checkax = offset * (omega^a_indices[s])bx = offset * (omega^b_indices[s])cx = alphas[r]if test_colinearity([(ax, ay), (bx, by), (cx, cy)]) == False:print("colinearity check failure")return False# verify authentication pathsfor i in range(self.num_colinearity_tests):path = proof_stream.pull()if Merkle.verify(roots[r], a_indices[i], path, aa[i]) == False:print("merkle authentication path verification fails for aa")return Falsepath = proof_stream.pull()if Merkle.verify(roots[r], b_indices[i], path, bb[i]) == False:print("merkle authentication path verification fails for bb")return Falsepath = proof_stream.pull()if Merkle.verify(roots[r+1], c_indices[i], path, cc[i]) == False:print("merkle authentication path verification fails for cc")return False# square omega and offset to prepare for next roundomega = omega^2offset = offset^2# all checks passedreturn True
    

多项式承诺Polynomial commitment方案汇总相关推荐

  1. 双变量polynomial commitment

    1. 引言 本博文主要研究的是 Benedikt Bünz 等人(standford,ethereum,berkeley) 2019年论文<Proofs for Inner Pairing Pr ...

  2. 比特承诺 Bit Commitment

    Introduction-A story  Alice:股票经纪人 Bob:股民    Alice:你的钱交给我,我替你买股票,我专业,挣钱多!    Bob:怎么证明?    Alice:我们上月买 ...

  3. 总奖金200万的算法赛方案汇总!

    2021DIGIX全球校园AI算法赛方案汇总 关于赛事信息(比赛8月底截止,点击下方可跳转) 地址:https://gitee.com/coggle/competition-baseline/tree ...

  4. Android适应方案汇总(三)

    在Android适应方案汇总(一个).(两)在.我们理解一些基本概念. 那么详细的开发,我们应该重视起来. 首先,我们需要知道.关键的事实是,这两个适配器: (1).这点在单位的使用上用dp.sp以及 ...

  5. 今天开始学模式识别与机器学习Pattern Recognition and Machine Learning 书,章节1.1,多项式曲线拟合(Polynomial Curve Fitting)

    转载自:http://blog.csdn.net/xbinworld/article/details/8834155 Pattern Recognition and Machine Learning ...

  6. 【数据竞赛】2020 Kaggle 10大竞赛方案汇总

    作者: 尘沙黑夜 2020 Kaggle 10大竞赛方案汇总 1  2020kaggle精选10大赛事汇总 1.1  2019 Data Science Bowl(3493只队伍) 1.2  Tens ...

  7. 【竞赛相关】Kaggle竞赛宝典国内外竞赛方案汇总

    本文汇总了kaggle竞赛宝典将近50个竞赛的Top方案&思路&代码. 2019年度所有国内外竞赛汇总 干货 | 2019 数据竞赛TOP方案合集 数据竞赛2019年度年鉴发布(250 ...

  8. 【数据竞赛】Kaggle竞赛宝典国内外竞赛方案汇总

    本文汇总了kaggle竞赛宝典将近50个竞赛的Top方案&思路&代码.关注"kaggle竞赛宝典"并在后台输入"竞赛宝典",还将获得5个kagg ...

  9. 太强了!Kaggle竞赛宝典方案汇总

    kaggle竞赛宝典公众号建立的初衷是希望将很多经典比赛的方案写成案例的形式,每个步骤都配有一定的阐述,讲述某些操作为什么有效等,希望可以帮助更多的新手快速入门(太多的开源只有代码,看代码的时间是巨大 ...

  10. 2021年Kaggle所有赛事TOP方案汇总

    本文摘自 coggle数据科学Kaggle2021TOP方案汇总Kaggle 2021年 45场比赛&优胜方案汇总 https://www.kaggle.com/c/tabular-playg ...

最新文章

  1. 几个解决 Maven Jar 包冲突的小技巧,太实用了!
  2. NYOJ 28 大数阶乘
  3. windows 的mysql5.7安装
  4. 排序、翻页、函数计算问题
  5. java遍历所有目录和文件
  6. 活动预告丨openGauss西安Meetup来啦!本周五见!
  7. java 反射 field get方法_JAVA学习之反射getDeclaredField()方法与getField()方法的区别
  8. mysql索引的创建与管理实验_mysql索引创建与管理笔记
  9. poj(2406) kmp
  10. bootlogo画面制作和替换
  11. python字符串重复输出例子_使用python语言,比较两个字符串是否相同的实例
  12. windows 快捷方式(.lnk)代码执行漏洞(CVE-2017-8464 )[附EXP生成工具]
  13. 深入浅出设计模式---5、享元模式
  14. RayData学习总结
  15. 2014年3月份全国计算机等级考试二级c语言选择题大全,2014年3月全国计算机二级C选择题考试真题...
  16. Centos服务器巡检报告
  17. c语言str系列函数
  18. 微信小程序,小游戏数据助手数据爬取!还敢随便授权小游戏吗?
  19. 内存不能为读的解决办法
  20. Android ImageView: resolveUri failed on bad bitmap uri

热门文章

  1. 什么是存储过程?用什么来调用?
  2. vue静态资源打包中的坑与解决方案
  3. 浅聊一下车载以太网技术及其EAVB和TSN技术
  4. 标量与向量乘积求导法则
  5. 如何设置excel表格表头冻结_Excel如何固定表头,Excel冻结首行首列或指定行
  6. 北京地铁各条线路介绍
  7. C# 读取SQLite
  8. AiTrust下预训练和小样本学习在中文医疗信息处理挑战榜CBLUE表现
  9. IT给生活带来了什么?
  10. vue3中的beforeEach里面的next函数---刷新页面导致白页