Polygon zkEVM公式梳理

const resP = await starkGen(comPols, constPols, constTree, starkInfo)
其中输入有:

  • 1)comPols:为commit多项式trace domain evaluation值
  • 2)constPols:为常量多项式trace domain evaluation值
  • 3)constTree:为常量多项式Low Degree Extension domain evaluation值的Merkle树
  • 4)starkInfo:为Prover生成证明以及Verifier验证证明所需的逻辑表达

starkGen函数内各关键变量含义为:

  • cm1_n:为commit多项式trace domain的evaluation值。
  • cm1_2ns:为commit多项式low degree extension domain的evaluation值。
  • tree1:为commit多项式扩域上evaluation值构建的Merkle树。
  • cm2_n/cm2_2ns/tree2:为plookup约束相关evaluation值及Merkle树。
  • cm3_n/cm3_2ns/tree3:为plookup/permutation/connection约束Z多项式evaluation值及Merkle树。
  • exps_withq_n/exps_withq_2ns/q_2ns/tree4:为polIdentities约束相关evaluation值及Merkle树。【tree4为根据q_2ns构建的Merkle树。】
  • constTree:为constant多项式low degree extension domain的evaluation值对应的Merkle树。

各关键变量定义为:

  • N = 2 nBits N=2^{\text{nBits}} N=2nBits

  • Next = 2 nBitsExt \text{Next}=2^{\text{nBitsExt}} Next=2nBitsExt

  • extendBits = nBitsExt − nBits \text{extendBits}=\text{nBitsExt}-\text{nBits} extendBits=nBitsExtnBits

  • w w w F F F域内的 N N N-th root of unity, w ′ w' w F F F域内的 Next \text{Next} Next-th root of unity。

  • g g g F . shift F.\text{shift} F.shift e e e F F F域内的 2 extendBits 2^{\text{extendBits}} 2extendBits-th root of unity。

  • ctx.Zi \text{ctx.Zi} ctx.Zi 表示的是长度为 Next \text{Next} Next的数组,其每个元素i为:
    1 ( g w ′ ) 2 nBits − 1 = 1 ( g 2 nBits ∗ e i ) − 1 = 1 g N ∗ e i − 1 \frac{1}{(gw')^{2^{\text{nBits}}}-1}=\frac{1}{(g^{2^{\text{nBits}}}*e^i)-1}=\frac{1}{g^N*e^i-1} (gw)2nBits11=(g2nBitsei)11=gNei11

  • x_n为长度为N的数组,其每个元素 i i i为: w i w^i wi,其中 w w w F F F域内的 N N N-th root of unity。【ctx.x_n为trace domain的插值点】

  • x_2ns为长度为 Next \text{Next} Next的数组,其每个元素 i i i为: g w ′ i gw'^i gwi,其中 w ′ w' w F F F域内的 Next \text{Next} Next-th root of unity。【ctx.x_2ns为low degree extension domain的插值点】

  • 令challenge[7]= x i x_i xi,有: xis = x i / g , wxis = ( w x i ) / g \text{xis}=x_i/g,\text{wxis}=(wx_i)/g xis=xi/g,wxis=(wxi)/g。构建长度为 N N N的数组LEv_tmp,其每个元素 i i i为: ( x i / g ) i (x_i/g)^i (xi/g)i;构建长度为 N N N的数组LpEv_tmp,其每个元素 i i i为: ( ( w x i / g ) i ((wx_i/g)^i ((wxi/g)i。以LEv_tmp中值为插值点 y y y坐标,以x_n为插值点 x x x坐标,ifft获得多项式系数数组LEv;同理以LpEv_tmp中值为插值点 y y y坐标,以x_n为插值点 x x x坐标,ifft获得多项式系数数组LpEv。

    • starkInfo.json的evMap中的第 i i i项ev,若其ev.prime为true,则使用LpEv多项式;否则,使用LEv多项式。l = ev.prime ? LpEv : LEv;。根据ev.type取相应的扩域ctx.*_2ns evaluations中依次取第0、1<共N个值 v v v,计算 ctx.evals [ i ] = ∑ k = 0 N − 1 v [ k ] ∗ l [ k ] \text{ctx.evals}[i]=\sum_{k=0}^{N-1}v[k]*l[k] ctx.evals[i]=k=0N1v[k]l[k]。ctx.evals数组的长度为starkInfo.evMap.length。【后续计算FRI多项式扩域值ctx.exps_withoutq_2ns需用到。】
  • wxi = w x i \text{wxi}=wx_i wxi=wxi,其中 w w w F F F域内的 N N N-th root of unity。

  • ctx.xDivXSubXi 和 ctx.xDivXSubWXi 均为长度为 N \text{N} N的数组,其每个元素 i i i均为Goldilocks extension 3 域元素,表示为 [ a i , b i , c i ] [a_i,b_i,c_i] [ai,bi,ci]

    • ctx.xDivXSubXi的第 i i i个元素为: g w ′ i g w ′ i − x i \frac{gw'^i}{gw'^i-x_i} gwixigwi
    • ctx.xDivXSubWXi的第 i i i个元素为: g w ′ i g w ′ i − w x i \frac{gw'^i}{gw'^i-wx_i} gwiwxigwi
  • starkInfo.json中的“Zi”标签,在compileCode时翻译为ctx.Zi(i)

以Fibonacci为例:

namespace Fibonacci(%N);


    pol constant L1, LLAST; //constant多项式
    pol commit l1,l2; //commit多项式

    pol l2c = l2; //中间多项式
	//公开变量值
    public in1 = l2c(0);
    public in2 = l1(0);
    public out = l1(%N-1);

    (l2' - l1)*(1-LLAST) = 0; //约束1

    pol next = l1*l1 + l2*l2; //中间多项式

    (l1' - next)*(1-LLAST) = 0; //约束2

    L1 * (l2 - :in1) = 0; //约束3
    L1 * (l1 - :in2) = 0; //约束4
    LLAST * (l1 - :out) = 0; //约束5


序号 x x x A \mathbf{A} A l 2 ( x ) l_2(x) l2(x)多项式) B \mathbf{B} B l 1 ( x ) l_1(x) l1(x)多项式) i s I n i t i a l \mathbf{isInitial} isInitial L 1 ( x ) L_1(x) L1(x)多项式) i s L a s t \mathbf{isLast} isLast L L A S T ( x ) LLAST(x) LLAST(x)多项式)
0 ω 0 \omega^0 ω0 1 2 1 0
1 ω 1 \omega^1 ω1 2 5 0 0
2 ω 2 \omega^2 ω2 5 29 0 0
⋮ \vdots ⋮ \vdots ⋮ \vdots ⋮ \vdots ⋮ \vdots ⋮ \vdots
1023 ω 1023 \omega^{1023} ω1023 74469561660084004 0 1
  • 1)各多项式基本映射关系为:
    • L1->constP_0,LLAST->constP_1,l1->cmP_0,l2->cmP_1,l2c->imP_0,next->imP_2
    • 各commit多项式trace domain evaluation值: ctx.cm1_n − > [ ( l 1 ( w 0 ) , l 2 ( w 0 ) ) , . . . , ( l 1 ( w N − 1 ) , l 2 ( w N − 1 ) ) ] \text{ctx.cm1\_n}->[(l1(w^0),l2(w^0)),...,(l1(w^{N-1}),l2(w^{N-1}))] ctx.cm1_n>[(l1(w0),l2(w0)),...,(l1(wN1),l2(wN1))]
    • 各constant多项式trace domain evaluation值: ctx.const_n − > [ ( L 1 ( w 0 ) , LLAST ( w 0 ) ) , . . . , ( L 1 ( w N − 1 ) , LLAST ( w N − 1 ) ) ] \text{ctx.const\_n}->[(L1(w^0),\text{LLAST}(w^0)),...,(L1(w^{N-1}),\text{LLAST}(w^{N-1}))] ctx.const_n>[(L1(w0),LLAST(w0)),...,(L1(wN1),LLAST(wN1))]
    • 各中间多项式trace domain evaluation值: exps_withq_n − > [ ( next ( w 0 ) , polyIdentity ( w 0 ) ) , . . . , ( next ( w N − 1 ) , polyIdentity ( w N − 1 ) ) ] \text{exps\_withq\_n}->[(\text{next}(w^0),\text{polyIdentity}(w^0)),...,(\text{next}(w^{N-1}),\text{polyIdentity}(w^{N-1}))] exps_withq_n>[(next(w0),polyIdentity(w0)),...,(next(wN1),polyIdentity(wN1))](其中pol next = l1*l1 + l2*l2;polyIdentity多项式(也为中间多项式,有idQ标签)为借助challenges[4]将所有polIdentities约束合并为一个的多项式。【其中polyIdentity多项式基于Goldilocks extension 3 域,其每个evaluation值由 [ a , b , c ] [a,b,c] [a,b,c]三个元素表示。】)
    • 公开变量值:ctx.publics[0]->in1,ctx.publics[1]->in2,ctx.publics[2]->out。
  • 2)step4 经compileCode后对应的函数为:【本质为计算中间多项式next和polyIdentity在trace domain的evaluation值】
    (function anonymous(ctx,i
    ) {
    ctx.tmp[0] = ctx.F.mul(ctx.cm1_n[0 + i*2], ctx.cm1_n[0 + i*2]); //l1*l1
    ctx.tmp[1] = ctx.F.mul(ctx.cm1_n[1 + i*2], ctx.cm1_n[1 + i*2]); //l2*l2
    ctx.exps_withq_n[0 + i*4] = ctx.F.add(ctx.tmp[0], ctx.tmp[1]);// next=l1*l1+l2*l2
    ctx.tmp[2] = ctx.F.sub(ctx.cm1_n[1 + ((i + 1)%1024)*2], ctx.cm1_n[0 + i*2]); //l2'-l1
    ctx.tmp[3] = ctx.F.sub(1n, ctx.const_n[1 + i*2]); //1-LLAST
    ctx.tmp[4] = ctx.F.mul(ctx.tmp[2], ctx.tmp[3]); //(l2'-l1)*(1-LLAST)
    ctx.tmp[21] = ctx.F.sub(ctx.tmp[4], 0n); //(l2'-l1)*(1-LLAST)-0,约束1
    ctx.tmp[5] = ctx.F.sub(ctx.cm1_n[0 + ((i + 1)%1024)*2], ctx.exps_withq_n[0 + i*4]);//l1'-next
    ctx.tmp[6] = ctx.F.sub(1n, ctx.const_n[1 + i*2]);//1-LLAST
    ctx.tmp[7] = ctx.F.mul(ctx.tmp[5], ctx.tmp[6]);//(l1'-next)*(1-LLAST)
    ctx.tmp[22] = ctx.F.sub(ctx.tmp[7], 0n);//(l1'-next)*(1-LLAST)-0,约束2
    ctx.tmp[8] = ctx.F.sub(ctx.cm1_n[1 + i*2], ctx.publics[0]);//l2-in1
    ctx.tmp[9] = ctx.F.mul(ctx.const_n[0 + i*2], ctx.tmp[8]); //L1*(l2-in1)
    ctx.tmp[23] = ctx.F.sub(ctx.tmp[9], 0n);//L1*(l2-in1)-0,约束3
    ctx.tmp[10] = ctx.F.sub(ctx.cm1_n[0 + i*2], ctx.publics[1]);//l1-in2
    ctx.tmp[11] = ctx.F.mul(ctx.const_n[0 + i*2], ctx.tmp[10]);//L1*(l1-in2)
    ctx.tmp[24] = ctx.F.sub(ctx.tmp[11], 0n);//L1*(l1-in2)-0,约束4
    ctx.tmp[12] = ctx.F.sub(ctx.cm1_n[0 + i*2], ctx.publics[2]);//l1-out
    ctx.tmp[13] = ctx.F.mul(ctx.const_n[1 + i*2], ctx.tmp[12]);//LLAST*(l1-out)
    ctx.tmp[25] = ctx.F.sub(ctx.tmp[13], 0n);//LLAST*(l1-out)-0,约束5
    ctx.tmp[14] = ctx.F.mul(ctx.challenges[4], ctx.tmp[21]);
    ctx.tmp[15] = ctx.F.add(ctx.tmp[14], ctx.tmp[22]);
    ctx.tmp[16] = ctx.F.mul(ctx.challenges[4], ctx.tmp[15]);
    ctx.tmp[17] = ctx.F.add(ctx.tmp[16], ctx.tmp[23]);
    ctx.tmp[18] = ctx.F.mul(ctx.challenges[4], ctx.tmp[17]);
    ctx.tmp[19] = ctx.F.add(ctx.tmp[18], ctx.tmp[24]);
    ctx.tmp[20] = ctx.F.mul(ctx.challenges[4], ctx.tmp[19]);
    //借助challenges[4],将以上5个约束合并为一个约束多项式polyIdentity
    [ ctx.exps_withq_n[1 + i*4] , ctx.exps_withq_n[1 + i*4 + 1] , ctx.exps_withq_n[1 + i*4 + 2] ]
                = ctx.F.add(ctx.tmp[20], ctx.tmp[25]);
    })
    
  • 3)基于trace domain evaluation值ctx.const_n/cm1_n/cm2_n/cm3_n/exps_withq_n,extend计算在low degree extension domain中相应的evaluation值ctx.const_2ns/cm1_2ns/cm2_2ns/cm3_2ns/exps_withq_2ns。
    • 各commit多项式low degree extension domain evaluation值: ctx.cm1_2ns − > [ ( l 1 ( g w ′ 0 ) , l 2 ( g w ′ 0 ) ) , . . , ( l 1 ( g w ′ Next − 1 ) , l 2 ( g w ′ Next − 1 ) ) ] \text{ctx.cm1\_2ns}->[(l1(gw'^0),l2(gw'^0)),..,(l1(gw'^{\text{Next}-1}),l2(gw'^{\text{Next}-1}))] ctx.cm1_2ns>[(l1(gw0),l2(gw0)),..,(l1(gwNext1),l2(gwNext1))]
    • 各constant多项式low degree extension domain evaluation值: ctx.const_2ns − > [ ( L 1 ( g w ′ 0 ) , LLAST ( g w ′ 0 ) ) , . . . , ( L 1 ( g w ′ Next − 1 ) , LLAST ( g w ′ Next − 1 ) ) ] \text{ctx.const\_2ns}->[(L1(gw'^0),\text{LLAST}(gw'^0)),...,(L1(gw'^{\text{Next}-1}),\text{LLAST}(gw'^{\text{Next}-1}))] ctx.const_2ns>[(L1(gw0),LLAST(gw0)),...,(L1(gwNext1),LLAST(gwNext1))]
    • 各中间多项式low degree extension domain evaluation值: exps_withq_2ns − > [ ( next ( g w ′ 0 ) , polyIdentity ( g w ′ 0 ) ) , . . . , ( next ( g w ′ Next − 1 ) , polyIdentity ( g w ′ Next − 1 ) ) ] \text{exps\_withq\_2ns}->[(\text{next}(gw'^0),\text{polyIdentity}(gw'^0)),...,(\text{next}(gw'^{\text{Next}-1}),\text{polyIdentity}(gw'^{\text{Next}-1}))] exps_withq_2ns>[(next(gw0),polyIdentity(gw0)),...,(next(gwNext1),polyIdentity(gwNext1))](其中pol next = l1*l1 + l2*l2;polyIdentity多项式(也为中间多项式,有idQ标签)为借助challenges[4]将所有polIdentities约束合并为一个的多项式。【其中polyIdentity多项式基于Goldilocks extension 3 域,其每个evaluation值由 [ a , b , c ] [a,b,c] [a,b,c]三个元素表示。】)
  • 4)step4ns 经compileCode后对应的函数为:【本质为,构建中间多项式next和polyIdentity在扩域的约束,并均乘以Zi(i),获得ctx.q_2ns。】
    (function anonymous(ctx,i
    ) {
    ctx.tmp[0] = ctx.F.mul(ctx.cm1_2ns[0 + i*2], ctx.cm1_2ns[0 + i*2]); //l1*l1
    ctx.tmp[1] = ctx.F.mul(ctx.cm1_2ns[1 + i*2], ctx.cm1_2ns[1 + i*2]);//l2*l2
    ctx.tmp[2] = ctx.F.add(ctx.tmp[0], ctx.tmp[1]);//l1*l1+l2*l2
    ctx.tmp[3] = ctx.F.sub(ctx.tmp[2], ctx.exps_withq_2ns[0 + i*4]);//l1*l1+l2*l2-next,构建中间多项式next在扩域的约束
    ctx.q_2ns[0 + i*4] = ctx.F.mul(ctx.Zi(i), ctx.tmp[3]);//(l1*l1+l2*l2-next)*Zi(i),中间多项式next约束扩域值与Zi(i)相乘
    ctx.tmp[4] = ctx.F.sub(ctx.cm1_2ns[1 + ((i + 2)%2048)*2], ctx.cm1_2ns[0 + i*2]); // l2'-l1
    ctx.tmp[5] = ctx.F.sub(1n, ctx.const_2ns[1 + i*2]);//1-LLAST
    ctx.tmp[6] = ctx.F.mul(ctx.tmp[4], ctx.tmp[5]);//(l2'-l1)*(1-LLAST)
    ctx.tmp[25] = ctx.F.sub(ctx.tmp[6], 0n);//(l2'-l1)*(1-LLAST)-0,约束1
    ctx.tmp[7] = ctx.F.sub(ctx.cm1_2ns[0 + ((i + 2)%2048)*2], ctx.exps_withq_2ns[0 + i*4]);//l1'-next
    ctx.tmp[8] = ctx.F.sub(1n, ctx.const_2ns[1 + i*2])//1-LLAST
    ctx.tmp[9] = ctx.F.mul(ctx.tmp[7], ctx.tmp[8]);//(l1'-next)*(1-LLAST)
    ctx.tmp[26] = ctx.F.sub(ctx.tmp[9], 0n);//(l1'-next)*(1-LLAST)-0,约束2
    ctx.tmp[10] = ctx.F.sub(ctx.cm1_2ns[1 + i*2], ctx.publics[0]);//l2-in1
    ctx.tmp[11] = ctx.F.mul(ctx.const_2ns[0 + i*2], ctx.tmp[10]);//L1*(l2-in1)
    ctx.tmp[27] = ctx.F.sub(ctx.tmp[11], 0n);//L1*(l2-in1)-0,约束3
    ctx.tmp[12] = ctx.F.sub(ctx.cm1_2ns[0 + i*2], ctx.publics[1]);//l1-in2
    ctx.tmp[13] = ctx.F.mul(ctx.const_2ns[0 + i*2], ctx.tmp[12]);//L1*(l1-in2)
    ctx.tmp[28] = ctx.F.sub(ctx.tmp[13], 0n);//L1*(l1-in2)-0,约束4
    ctx.tmp[14] = ctx.F.sub(ctx.cm1_2ns[0 + i*2], ctx.publics[2]);//l1-out
    ctx.tmp[15] = ctx.F.mul(ctx.const_2ns[1 + i*2], ctx.tmp[14]);//LLAST*(l1-out)
    ctx.tmp[29] = ctx.F.sub(ctx.tmp[15], 0n);//LLAST*(l1-out)-0,约束5
    ctx.tmp[16] = ctx.F.mul(ctx.challenges[4], ctx.tmp[25]);
    ctx.tmp[17] = ctx.F.add(ctx.tmp[16], ctx.tmp[26]);
    ctx.tmp[18] = ctx.F.mul(ctx.challenges[4], ctx.tmp[17]);
    ctx.tmp[19] = ctx.F.add(ctx.tmp[18], ctx.tmp[27]);
    ctx.tmp[20] = ctx.F.mul(ctx.challenges[4], ctx.tmp[19]);
    ctx.tmp[21] = ctx.F.add(ctx.tmp[20], ctx.tmp[28]);
    ctx.tmp[22] = ctx.F.mul(ctx.challenges[4], ctx.tmp[21]);
    ctx.tmp[23] = ctx.F.add(ctx.tmp[22], ctx.tmp[29]);
    //引入challenges[4]将所有约束合并为一个中间多项式polyIdentity,
    //构建中间多项式polyIdentity在扩域的约束
    ctx.tmp[24] = ctx.F.sub(ctx.tmp[23], [ ctx.exps_withq_2ns[1 + i*4] , ctx.exps_withq_2ns[1 + i*4 + 1] ,
                                         ctx.exps_withq_2ns[1 + i*4 + 2] ]);
    //中间多项式polyIdentity约束扩域值与Zi(i)相乘
    [ ctx.q_2ns[1 + i*4] , ctx.q_2ns[1 + i*4 + 1] , ctx.q_2ns[1 + i*4 + 2] ] = ctx.F.mul(ctx.Zi(i), ctx.tmp[24]);
    })
    
  • 5)step52ns 经compileCode后对应的函数为:【负责将多个多项式合并为一个多项式——FRI多项式,如下面的exp8即为FRI多项式。并计算FRI多项式在扩域的插值ctx.exps_withoutq_2ns,其每个元素为Goldilocks extension 3 域元素。】
    • 5.1)借助challenges[5](即vf1),将commit和中间多项式合并为一个多项式,如:tmp30=(((l1*vf1)+l2)*vf1+q0)*vf1+q1;
    • 5.2)借助challenges[6](即vf2),将所有evaluate在同一point x i x_i xi(即xi)的商多项式(包含commit和const以及中间多项式)合并为一个多项式:tmp48=[(((((l1-l1(xi))*vf2+(LLAST-LLAST(xi)))*vf2+(l2-l2(xi)))*vf2+(q0-q0(xi)))*vf2+(L1-L1(xi)))*vf2+(q1-q1(xi))] * xDivXSubXi。
    • 5.3)借助challenges[5](即vf1),将5.1)和5.2)各多项式合并为:tmp49=tmp30*vf1+tmp48。
    • 5.4)借助challenges[6](即vf2),将所有evaluate在同一point w x i wx_i wxi(即wxi)的商多项式(包含commit和const以及中间多项式)合并为一个多项式:tmp55=[(l2-l2(wxi))*vf2+(l1-l1(wxi))] * xDivXSubWXi。
    • 5.5)借助challenges[5](即vf1),将5.3)和5.4)各多项式合并为:exp8=tmp49*vf1+tmp55。此处exp8即为FRI多项式。
    • 5.6)借助ctx.cm1_2ns/q_2ns/const_2ns/evals/xDivXSubXi/xDivXSubWXi以及ctx.challenges[5]/challengs[6]计算出FRI多项式的扩域插值ctx.exps_withoutq_2ns。【在starkGen函数中的friPol变量,即为FRI多项式的扩域插值,friPol本质就是ctx.exps_withoutq_2ns,friPol数组长度为 Next \text{Next} Next。】
    (function anonymous(ctx,i
    ) {
      ctx.tmp[25] = ctx.F.mul(ctx.challenges[5], ctx.cm1_2ns[0 + i*2]);
      ctx.tmp[26] = ctx.F.add(ctx.tmp[25], ctx.cm1_2ns[1 + i*2]);
      ctx.tmp[27] = ctx.F.mul(ctx.challenges[5], ctx.tmp[26]);
      ctx.tmp[28] = ctx.F.add(ctx.tmp[27], ctx.q_2ns[0 + i*4]);
      ctx.tmp[29] = ctx.F.mul(ctx.challenges[5], ctx.tmp[28]);
      ctx.tmp[30] = ctx.F.add(ctx.tmp[29], [ ctx.q_2ns[1 + i*4] , ctx.q_2ns[1 + i*4 + 1] , ctx.q_2ns[1 + i*4 + 2] ]);
      ctx.tmp[31] = ctx.F.mul(ctx.challenges[5], ctx.tmp[30]);
      ctx.tmp[32] = ctx.F.sub(ctx.cm1_2ns[0 + i*2], ctx.evals[1]);
      ctx.tmp[33] = ctx.F.mul(ctx.tmp[32], ctx.challenges[6]);
      ctx.tmp[34] = ctx.F.sub(ctx.const_2ns[1 + i*2], ctx.evals[2]);
      ctx.tmp[35] = ctx.F.add(ctx.tmp[33], ctx.tmp[34]);
      ctx.tmp[36] = ctx.F.mul(ctx.tmp[35], ctx.challenges[6]);
      ctx.tmp[37] = ctx.F.sub(ctx.cm1_2ns[1 + i*2], ctx.evals[3]);
      ctx.tmp[38] = ctx.F.add(ctx.tmp[36], ctx.tmp[37]);
      ctx.tmp[39] = ctx.F.mul(ctx.tmp[38], ctx.challenges[6]);
      ctx.tmp[40] = ctx.F.sub(ctx.q_2ns[0 + i*4], ctx.evals[4]);
      ctx.tmp[41] = ctx.F.add(ctx.tmp[39], ctx.tmp[40]);
      ctx.tmp[42] = ctx.F.mul(ctx.tmp[41], ctx.challenges[6]);
      ctx.tmp[43] = ctx.F.sub(ctx.const_2ns[0 + i*2], ctx.evals[6]);
      ctx.tmp[44] = ctx.F.add(ctx.tmp[42], ctx.tmp[43]);
      ctx.tmp[45] = ctx.F.mul(ctx.tmp[44], ctx.challenges[6]);
      ctx.tmp[46] = ctx.F.sub([ ctx.q_2ns[1 + i*4] , ctx.q_2ns[1 + i*4 + 1] , ctx.q_2ns[1 + i*4 + 2] ], ctx.evals[7]);
      ctx.tmp[47] = ctx.F.add(ctx.tmp[45], ctx.tmp[46]);
      ctx.tmp[48] = ctx.F.mul(ctx.tmp[47], [ctx.xDivXSubXi[3*i], ctx.xDivXSubXi[3*i+1], ctx.xDivXSubXi[3*i+2]]);
      ctx.tmp[49] = ctx.F.add(ctx.tmp[31], ctx.tmp[48]);
      ctx.tmp[50] = ctx.F.mul(ctx.challenges[5], ctx.tmp[49]);
      ctx.tmp[51] = ctx.F.sub(ctx.cm1_2ns[1 + i*2], ctx.evals[0]);
      ctx.tmp[52] = ctx.F.mul(ctx.tmp[51], ctx.challenges[6]);
      ctx.tmp[53] = ctx.F.sub(ctx.cm1_2ns[0 + i*2], ctx.evals[5]);
      ctx.tmp[54] = ctx.F.add(ctx.tmp[52], ctx.tmp[53]);
      ctx.tmp[55] = ctx.F.mul(ctx.tmp[54], [ctx.xDivXSubWXi[3*i], ctx.xDivXSubWXi[3*i+1], ctx.xDivXSubWXi[3*i+2]]);
      [ ctx.exps_withoutq_2ns[0 + i*3] , ctx.exps_withoutq_2ns[0 + i*3 + 1] , ctx.exps_withoutq_2ns[0 + i*3 + 2] ] = ctx.F.add(ctx.tmp[50], ctx.tmp[55]);
    })
    
  • 6)const friProof = await fri.prove(transcript, friPol, queryPol);,其中:
    • 1)steps为:【friProof数组的长度为steps.length,本例为3】
      	"steps": [
              {"nBits": 11},
              {"nBits": 7},
              {"nBits": 3}
          ]
      

你可能感兴趣的:(零知识证明,零知识证明)