本文通过一个笔和纸的例子,介绍了使用STARKs进行计算完整性的方法。
在 LambdaClass,我们正在构建 Lambdaworks,一个用于开发零知识应用的库。一个重要的证明系统是 STARKs (Scalable, transparent arguments of knowledge,可扩展的,透明的知识论证)。STARKs 是一个强大的工具,允许我们证明给定计算的完整性。有关 STARKs 的概述,你可以查看我们 之前的帖子 或 Starkware 提供的优秀教程,例如 STARK-101 (对于 rust 版本,你可以关注 此链接)以及关于 算术化 I 和 II 的帖子,还有 STARK 解剖。
在这篇文章中,我们将做一个 STARKs 的纸笔示例,以便我们可以按照生成和验证证明所需的所有步骤进行操作(但我们将跳过哈希部分)。一个需要指出的重要方面是,在这种情况下,我们对我们所做事情的安全性不感兴趣(但在现实生活中,这应该非常重要)。让我们跳到问题中......
假设我们想要计算一个由以下关系给出的序列:
a0=3a0=3
an+1=an2an+1=an2
该序列给出前一个数的平方,从值 3 开始。我们将使用素数 17(费马素数,24+124+1)作为模数,并且我们将理解所有模 17 完成的运算。 17 的优点在于它包含一个具有 16 个元素的乘法群,这对于 STARKs 很有用(通常,我们希望 p−1p−1 为 2m×q2m×q,其中 mm 应该足够大,而 qq 是奇素数)。序列的前四个元素是:
a0=3a0=3
a1=a02=9a1=a02=9
a2=a12=92=81≡13(mod17)a2=a12=92=81≡13(mod17)
a3=a22=132=169≡16(mod17)a3=a22=132=169≡16(mod17)
第一步是将这些值解释为多项式在合适域上的求值。我们正在使用 p=17p=17,其乘法群有 16 个元素:{1,2,3,4,…,15,16}{1,2,3,4,…,15,16}。我们将选择以下子群 Dt=1,13,16,4Dt=1,13,16,4,这恰恰是由 1313 模 1717 的所有幂形成的群:
130=1130=1
131=13131=13
132=169≡16(mod17)132=169≡16(mod17)
133≡4(mod17)133≡4(mod17)
134≡1(mod17)134≡1(mod17)
从现在开始,我们将省略 (mod17)(mod17),这是从上下文中理解的。我们看到 1313 的幂每 4 个重复一次,这是元素在乘法群中的阶。使用这个并且将插值迹的多项式称为 t(x)t(x),我们有:
t(1)=3t(1)=3
t(13)=9t(13)=9
t(16)=13t(16)=13
t(4)=16t(4)=16
我们可以使用拉格朗日插值来找到多项式(对于更大的问题,最好使用快速傅里叶变换):
t(x)=L1(x)t(1)+L2(x)t(13)+L3(x)t(16)+L4(x)t(4)t(x)=L1(x)t(1)+L2(x)t(13)+L3(x)t(16)+L4(x)t(4)
拉格朗日多项式 L1(x)L1(x) 由下式给出
L1(x)=(x−13)(x−16)(x−4)(1−13)(1−16)(1−4)L1(x)=(x−13)(x−16)(x−4)(1−13)(1−16)(1−4)
进行运算,我们得到
L1(x)t(1)=5(x3+x2+x+1)L1(x)t(1)=5(x3+x2+x+1)
其他的多项式是
L2(x)t(13)=8x3+2x2+9x+15L2(x)t(13)=8x3+2x2+9x+15
L3(x)t(16)=x3+16x2+x+16L3(x)t(16)=x3+16x2+x+16
L4(x)t(4)=16x3+13x2+x+4L4(x)t(4)=16x3+13x2+x+4
因此,迹插值多项式为
t(x)=13x3+2x2+16x+6t(x)=13x3+2x2+16x+6
如果我们计算多项式在 DtDt 处的值,你可以检查我们是否获得了与迹执行表中的相同值。
我们必须提交到迹插值多项式。为此,我们通过选择与原始域不同的更大的域来执行低次扩展。如果我们选择 h=9h=9 及其幂,我们将得到一个具有 88 个元素的循环子群,{h0,h1,h2,…,h7}{h0,h1,h2,…,h7}。该群包含来自 DtDt 的元素,因此我们通过引入陪集的元素 ww 并形成以下域将其移动到另一个域,
D0={wh0,wh1,wh2,…,wh7}D0={wh0,wh1,wh2,…,wh7}
我们可以选择 w=3w=3,因此域变为
D0={3,10,5,11,14,7,12,6}D0={3,10,5,11,14,7,12,6}
要提交,我们在 D0D0 中的所有值上计算 t(x)t(x) 并形成一个 Merkle 树,其叶子是这些值。
xx | t(x)t(x) |
---|---|
3 | 15 |
10 | 4 |
5 | 10 |
11 | 13 |
14 | 16 |
7 | 0 |
12 | 0 |
6 | 7 |
我们现在需要关注计算给出的迹元素上的约束。在这个问题中,我们有两个约束:
此时我们需要做的是将迹多项式与这些约束组合以在整个迹上强制执行它们。
第一个约束是
p1(x)=t(x)−3p1(x)=t(x)−3
为了确保它在第一步中被强制执行,多项式 p1(x)p1(x) 必须可被 x−1x−1 整除(多项式的一个属性是 p(a)=bp(a)=b 当且仅当 r(x)=p(x)−br(x)=p(x)−b 可被 x−ax−a 整除)。
我们有
p1(x)=13x3+2x2+16x+3p1(x)=13x3+2x2+16x+3
如果我们分解这个多项式,我们得到
p1(x)=13(x−1)(x2+9x+5)p1(x)=13(x−1)(x2+9x+5)
它有因子 (x−1)(x−1)。如果我们除,我们得到
C1(x)=13(x2+9x+5)C1(x)=13(x2+9x+5)
你可以检查,如果我们想要 t(x)−at(x)−a 可以被 x−1x−1 整除,则必然 a=3a=3。
为了评估第二个约束,我们需要能够选择迹的一个元素和下一个元素。我们可以通过注意 DtDt 的元素由 g=13g=13 生成来做到这一点,因此如果我们选择 x=x0x=x0,则 y=gx0y=gx0 是下一个。所以,y=t(gx)=t(13x)y=t(gx)=t(13x) 并且
t(gx)=x3+15x2+4x+6t(gx)=x3+15x2+4x+6
我们现在将这些多项式替换为过渡验证多项式 P(x,y)P(x,y),以获得 p2(x)p2(x)
p2(x)=P(t(x),t(gx))=x6+16x5+5x4+2x3+7x2+16x+4p2(x)=P(t(x),t(gx))=x6+16x5+5x4+2x3+7x2+16x+4
你可以检查,如果我们选择 x∈1,13,16x∈1,13,16,则多项式计算结果为 00。这是预期的,因为元素 anan 和 an+1an+1 通过公式 an+1=an2an+1=an2 连接。 44 的情况不再如此,因为没有下一个元素。与之前一样,如果约束有效,则 p2(x)p2(x) 应可被 Z2(x)Z2(x) 整除,后者是在约束被强制执行的域上的消失多项式。在我们的例子中,
Z2(x)=(x−1)(x−13)(x−16)Z2(x)=(x−1)(x−13)(x−16)
我们也可以将其写成
Z2=x4−1x−4Z2=x4−1x−4
在这里我们只是删除了约束未被强制执行的元素。我们验证了对于 x∈1,13,16x∈1,13,16,p2(x)=0p2(x)=0,因此 p2(x)p2(x) 具有因子 (x−1)(x−13)(x−16)(x−1)(x−13)(x−16)。其完整分解为
p2(x)=(x−1)(x−13)(x−16)(x3+12x2+9x+16)p2(x)=(x−1)(x−13)(x−16)(x3+12x2+9x+16)
因此,
C2(x)=p2(x)Z2(x)=x3+12x2+9x+16C2(x)=p2(x)Z2(x)=x3+12x2+9x+16
我们现在处于构建组合多项式的条件
H(x)=C1(x)(α1xD−D1+β1)+C2(x)(α2xD−D2+β2)H(x)=C1(x)(α1xD−D1+β1)+C2(x)(α2xD−D2+β2)
其中 αkαk 和 βkβk 是验证者提供的值。添加项 D−DkD−Dk 是为了使线性组合中的所有多项式都具有相同的次数。我们希望总次数为 22 的幂,因此 D=4D=4。
假设验证者将以下内容作为随机系数采样:α1=1α1=1、β1=3β1=3、α2=2α2=2、β2=4β2=4。 然后,
C1(x)(1x4−2+3)=13x4+15x3+2x2+11x+8C1(x)(1x4−2+3)=13x4+15x3+2x2+11x+8
C2(x)(2x4−3+4)=2x4+11x3+15x2+13C2(x)(2x4−3+4)=2x4+11x3+15x2+13
然后,
H(x)=15x4+9x3+11x+4H(x)=15x4+9x3+11x+4
将多项式分成奇数项和偶数项,
H1(x2)=15x4+4H1(x2)=15x4+4
H2(x2)=9x2+11H2(x2)=9x2+11
以便
H(x)=H1(x2)+xH2(x2)H(x)=H1(x2)+xH2(x2)
我们可以通过在 D0D0 上计算并形成 Merkle 树来提交到多项式 H(x)H(x) 或其部分 H1(x)H1(x) 和 H2(x)H2(x)。
xx | H1(x)H1(x) | H2(x)H2(x) |
---|---|---|
3 | 12 | 7 |
10 | 13 | 10 |
5 | 12 | 15 |
11 | 13 | 12 |
验证者现在选择一个随机点 zz,该点位于迹插值和评估域之外。在我们的示例中,这些点之外的点是 {2,8,9,15}{2,8,9,15}。假设验证者选择 z=8z=8。 然后,
H(8)=10H(8)=10
每个部分都是
H1(82)=6H1(82)=6
H2(82)=9H2(82)=9
我们需要检查组合多项式和迹元素是否相关。为了能够以数值方式评估约束,我们需要 t(z)t(z) 和 t(gz)t(gz) (记住,gg 是迹插值域的生成器),因为我们必须计算 P(x,y)P(x,y)。 必要的值是:
t(8)=16t(8)=16
t(13×8)=t(2)=14t(13×8)=t(2)=14
验证者现在可以检查迹和组合多项式是否相关:
我们看到 H1(z2)H1(z2) 和 H2(z2)H2(z2) 的计算结果与来自迹元素的 H(z)H(z) 的计算结果相匹配。
验证者如何检查我们传递的值确实是 zz 和 gzgz 处的迹和组合多项式计算结果?我们可以使用相同的技巧:如果多项式 y(x)y(x) 在 x=ax=a 中计算为 bb,则 y(x)−by(x)−b 可被 x−ax−a 整除。 我们形成 DEEP 组合多项式,
P0(x)=γ1t(x)−t(z)x−z+γ2t(x)−t(gz)x−gz+γ3H1(x2)−H1(z2)x−z2+γ4H2(x2)−H2(z2)x−z2P0(x)=γ1t(x)−t(z)x−z+γ2t(x)−t(gz)x−gz+γ3H1(x2)−H1(z2)x−z2+γ4H2(x2)−H2(z2)x−z2
让我们计算每一项
t(x)−t(8)x−8=13(x+13)(x+3)=13(x2+16x+5)t(x)−t(8)x−8=13(x+13)(x+3)=13(x2+16x+5)
t(x)−t(2)x−2=13(x+8)(x+2)=13(x2+10x+16)t(x)−t(2)x−2=13(x+8)(x+2)=13(x2+10x+16)
H1(x2)−H1(82)x−82=15(x+15)(x+8)(x+2)H1(x2)−H1(82)x−82=15(x+15)(x+8)(x+2)
H2(x2)−H1(82)x−82=9(x+8)H2(x2)−H1(82)x−82=9(x+8)
每一项都是一个多项式,因此线性组合也是一个多项式。通过应用 FRI 协议,我们必须向验证者证明这接近于一个低次多项式。多项式是(使用 γi=1γi=1),
P0(x)=15x3+15x+1P0(x)=15x3+15x+1
我们可以使用 D0D0 并形成 Merkle 树来提交到这个多项式,
xx | P0(x)P0(x) |
---|---|
3 | 9 |
10 | 4 |
5 | 13 |
11 | 3 |
14 | 10 |
7 | 15 |
12 | 6 |
6 | 16 |
分为奇数项和偶数项,
xP0,odd(x)=15x3+15xxP0,odd(x)=15x3+15x
P0,even(x)=1P0,even(x)=1
验证者采样 β0=4β0=4。 然后,
P1(y=x2)=9y+10P1(y=x2)=9y+10
该域由 y=x2y=x2 形式的点给出,因此 D1={9,15,8,2}D1={9,15,8,2}。 Merkle 树的叶子是
yy | P1(y)P1(y) |
---|---|
9 | 6 |
15 | 9 |
8 | 11 |
2 | 14 |
我们重复这个过程,
yP0,odd(y)=9yyP0,odd(y)=9y
P0,even(y)=10P0,even(y)=10
验证者采样 β1=3β1=3
P2(z=y2)=3P2(z=y2)=3.
我们以一个常数多项式结束。第二个域是 D2={13,4}D2={13,4}
为了生成证明,验证者从 D0D0 中选择一个元素。 我们必须将重构组合多项式和 FRI 步骤的评估所需的所有元素发送给他。 假设他选择 x=10x=10,这对应于等于 11 的索引。为了评估所有内容,我们必须传递 xx 和 −x−x 处每个层的评估,以及在 xx 和 gxgx 处评估的迹多项式。
从 P0(x)P0(x) 我们传递值 P0(x=10)=4P0(x=10)=4 和 P0(x=7)=15P0(x=7)=15,以及它们的身份验证路径。
从 P1(x)P1(x) 我们传递值 P1(x=15)=9P1(x=15)=9 和 P1(x=2)=11P1(x=2)=11 以及它们的身份验证路径。
从 P2(x)P2(x),我们只需要 33 的常数值。
检查 FRI 的正确性需要验证每个值是否与其 Merkle 树和共线性测试相对应,
Pi+1(x2)=Pi(x)+Pi(−x)2+βiPi(x)−Pi(−x)2xPi+1(x2)=Pi(x)+Pi(−x)2+βiPi(x)−Pi(−x)2x
让我们检查从每层的跳跃:
P1(15)=16=P0(10)+P0(7)2+4P0(10)−P0(7)2×10P1(15)=16=P0(10)+P0(7)2+4P0(10)−P0(7)2×10
我们可以看到
P0(10)+P0(7)2=1P0(10)+P0(7)2=1
和
4P0(10)−P0(7)2×10=84P0(10)−P0(7)2×10=8
让我们跳到下一层,
P2(y2)=P1(y)+P1(−y)2+β1P1(y)−P1(−y)2yP2(y2)=P1(y)+P1(−y)2+β1P1(y)−P1(−y)2y
替换这些值,
P2(y2)=3P2(y2)=3
和
P1(15)+P1(2)2=10P1(15)+P1(2)2=10
3P1(15)−P1(2)2×15=103P1(15)−P1(2)2×15=10
但是
10+10=3=P2(4)10+10=3=P2(4)
完成检查。 你可以尝试选择其他指数并验证证明。
唯一剩下的检查表明迹和组合多项式是相关的。 我们将其作为一个挑战留给读者(答案将很快出现)
这篇文章介绍了使用 STARKs 进行计算完整性的纸笔示例。 我们选择了一个序列,其中每个元素都是前一个元素的平方,从 3 开始。我们陈述了问题,将计算解释为在合适的域上评估多项式,并执行了拉格朗日插值。 之后,我们强制执行执行迹上的约束并获得了组合多项式。 为了提高稳健性,我们强制证明者在域之外的点 zz 处进行评估,并表明迹和组合多项式是相关的。 然后,我们创建了一个有理函数,以确保证明者没有作弊并发送了正确的值。 如果证明者是诚实的,那么结果函数就是一个多项式,我们通过使用 FRI 表明它接近于一个低次多项式。 如果你想尝试更复杂的例子,请关注 Lambdaworks 的更新。
我们采访了开发 Iroh 的团队,Iroh 是一个开箱即用的 Rust 点对点库。
- 原文链接: blog.lambdaclass.com/div...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!