前序博客有:
通过本文,将理解如何将Computational Integrity statement转换为:
STARK协议的目标是:
STARK的第一步称为Arithmetization:
算术化是有用的,因为它可以使用纠错码领域的工具,有效地进行低度测试。
但是算术化本身近似将Computational Integrity statement转换为某多项式,然后Prover需要通过STARK Low Degree Testing——FRI 交互协议来使Verifier信服该多项式确实是低度的。当且仅当原始计算是正确时(除外概率很低),Verifier才信服该多项式是低度的。STARK最后一步会将FRI交互协议转换为非交互协议,可将相应的非交互STARK提交到链上并由任何人公开验证。
Arithmetization算术化本身分为2个阶段:
Prover和Verifier交互过程中,实际是对多项式约束达成共识。然后Prover生成execution trace,并在后续的交互过程中,Prover试图说服Verifier其execution trace满足该多项式承诺,尽管execution trace对Verifier是不可见的。

传统的Computational Integrity Statements举例为:如,给超市的付款总金额计算正确,传统的proof是如下的收据:

收据中包含每项内容及相应的价格,总金额列在最下面。
简单起见,将该statement理解为:求和计算正确。
为验证该statement是否成立,方法之一对着收据逐项求和,检查最终的值是否与收据下方的值一致。
算术化的第一阶段是将某CI statement(如“区块7218290内的第15笔交易是正确的”),转换为 formal algebraic language。
主要有2个目的:
algebraic表示时通常有2大要素:
execution trace可能很长,但多项式约束可比较精简。
所生成的execution trace应易于精简测试,应具有如下两个特点:
以上两个特点将直接影响STARK proof size。
仍然以超市收据为例,来说明何为易于精简测试:

通过引入新的一列“running total”,使得可在已知previous row的情况下,独立验证每一行。
如在计算中检查这2行:

仅需检查12.96+3.45=16.41即可。注意,对于每组pair of rows,都可使用相同的约束,我们将其称为succinct constraints。
将添加了新列的超市收据以table表示为:

将第
i
i
i行第
j
j
j列的单元格值表示为
A
i
,
j
A_{i,j}
Ai,j,从而可将求和正确性 改写为 一组多项式约束:
这些即为 A i , j A_{i,j} Ai,j的线性多项式约束。若所使用的多项式为high degree,则对proof length和生成证明所需时间 都有反向作用。因此,线性约束是我们所希望的最好状态。
多项式约束的size与收据的长度无关。
从而,将验证超市收据总额的CI problem,转换为一个精简易于测试的execution trace,以及相应的一组多项式约束,使得当前仅当原始收据的总额是正确的,这组多项式约束才成立。
1937年,德国名为Lothar Collatz的数学家在数论领域提出了Collatz Conjecture。初看这是一个可爱的数学谜题,但实际上,它是数论领域的一个公开难题。数年来它吸引了很多数学家的注意,获得了大量同义词(如the 3n + 1 conjecture, the Ulam conjecture, Kakutani’s problem等等)。Paul Erdős曾评论称:“Mathematics may not be ready for such problems”。
Collatz数列以任意正整数开始,其中后续元素的计算规则为:
以初始值为52为例,有:
52 -> 26 -> 13 -> 40 -> 20 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1.
Collatz Conjecture是指:以任意正整数开始,最终Collatz数列都将达到1值。
不过,Collatz Conjecture本身并不在本文考虑范畴,本文重点关注:如何验证以某特定整数开始的Collatz数列计算正确。
Collatz数列的CI statement为:
“A Collatz sequence that starts with 52, ends with 1 after 11 iterations”。
令 A A A为该数列计算的execution trace,第 i i i行表示为 A i A_i Ai,对应为该数列中的第 i i i个元素。所有元素都以二进制表示,使得其易于在多项式中表示其奇偶性。以 A i , j A_{i,j} Ai,j表示数列中第 i i i个元素的第 j j j个最低有效位。如 A 0 = 001011 A_0=001011 A0=001011表示初始值52(注意52的二进制表示为1101001,在此处以逆序表示,以简化后续多项式约束中的索引)。
对应的execution trace为:

注意,该trace中仅有6列,是因为6个bit就足以表达该数列中的最大值了。若初始值为51,则最大值为154,相应的trace表示需引入8列。
当且仅当trace A中描述了指定的Collatz数列(以52开始,以1结束,相邻2行的transition计算正确),相应的多项式约束才成立。
本例中,trace A的size为6x12,即表示Collatz数列中有12个6-bit数字,相应的多项式约束为:【
n
=
12
,
m
=
6
n=12,m=6
n=12,m=6】

前三个约束很直观:
接下来仔细检查这些约束,对于任意的
i
<
n
−
1
i

对于每一个
i
<
n
−
1
i

A
i
,
0
A_{i,0}
Ai,0为第
i
i
i个元素的最低有效位,可确定该整数的极性,因此,该约束可用于描述Collatz sequence的规则。
总之,当前仅当execution trace代表了某Collatz sequence的有效计算时,以上所有约束才能满足。
注意,任意长度为 n n n的Collatz数列,可以 n ∗ m n*m n∗m大小的trace来表示,其中 m m m为该数列中最大值所需要的bit数,相应的多项式约束也需要调整。但是,注意,多项式约束并不会随着 n 和 m n和m n和m增加,仍保持简单和简洁性。
已知Collatz数列的某特定初始值,一个简单的计算机程序就可输出相应的execution trace和多项式约束。
以Collatz数列为例,展示了如何将CI statement转换为execution trace和多项式约束。类似的方法也可用于转换任何计算,通常,任意CI statement都可转换为该形式。具体的细节可能千差万别。
同时,对于同一计算,可能有多种execution trace和多项式约束表示方法,但是,只有一小部分方法会产生一个小的、可以有效构造的STARK证明。Starkware团队推荐使用AIR(Algebraic Intermediate Representation)来生成好的多项式约束。
算术化第二阶段,用于将算术化第一阶段中生成的execution trace和一系列多项式约束 转换为a single polynomial,使得当且仅当该多项式是低度的,原始计算才是正确的。这样转换之后,可实现succinct verification,使得Verifier该计算所需的资源 为指数级少于 自己直接重放整个计算。
回顾下,基本目的是,支持Verifier向Prover询问非常少量的问题,然后以很高的准确性来判断是接受还是拒绝该proof。
理论上,Verifier可让Prover提供execution trace中的少量随机位置的值,然后检查多项式约束在这些位置是否成立。正确的execution trace自然可测试通过,但是,构建一个并不完全错误的execution trace并不困难,使得仅在某个单点位置违背了相应的约束,将导致一个完全不同的输出。为识别类似这种错误,仅通过少量随机queries是极不可能的。
针对该问题的通用技术为Error Correction Codes,纠错码。
纠错码可将一组非常相似的字符串,转换为,相互非常不同的字符串,相比于原始字符串,纠错码编码之后的字符串长度更长。
有趣的是,多项式可用于构建很好的纠错码,因为对于2个不同的degree为
d
d
d的多项式,基于比
d
d
d更大的domain进行evaluate时,其几乎在所有位置都是不同的,这样的码也称为Reed-Solomon码。
即相应的多项式fact为:

经观察可发现,可将execution trace看成是某多项式基于某domain的evaluation值,并扩展为在更大的domain对同一多项式evaluate。以类似的方式扩展不正确的execution trace会导致非常不同的字符串,这反过来使得Verifier可以使用少量查询来区分这些情况。
所以,接下来的计划是:
如,CI statement为:
“The prover has a sequence of 512 numbers, all of which are either 0 or 1”。
希望通过读取远远少于512个数字来验证这一点。
接下来看相应的execution trace和多项式约束为:
未来将execution trace重组为多项式:

多项式及其roots的一个基本fact为:
若
p
(
x
)
p(x)
p(x)为某多项式,且对于某
a
a
a有
p
(
a
)
=
0
p(a)=0
p(a)=0,则当且仅当存在某多项式
q
(
x
)
q(x)
q(x),使得
(
x
−
a
)
q
(
x
)
=
p
(
x
)
(x-a)q(x)=p(x)
(x−a)q(x)=p(x),且
deg
(
p
)
=
deg
(
q
)
+
1
\deg(p)=\deg(q)+1
deg(p)=deg(q)+1。
对于所有的
x
≠
a
x\neq a
x=a,可evaluate
q
(
x
)
q(x)
q(x)为:
q
(
x
)
=
p
(
x
)
(
x
−
a
)
q(x)=\frac{p(x)}{(x-a)}
q(x)=(x−a)p(x)
依次类推,对于
k
k
k个roots
{
a
0
,
a
1
,
⋯
,
a
k
−
1
}
\{a_0,a_1,\cdots,a_{k-1}\}
{a0,a1,⋯,ak−1},存在degree为
deg
(
p
)
−
k
\deg(p)-k
deg(p)−k的多项式
q
(
x
)
q(x)
q(x):
q
(
x
)
=
p
(
x
)
∏
i
=
0
k
−
1
(
x
−
a
i
)
q(x)=\frac{p(x)}{\prod_{i=0}^{k-1}(x-a_i)}
q(x)=∏i=0k−1(x−ai)p(x)
将约束
A
i
∗
A
i
−
A
i
=
0
A_i*A_i-A_i=0
Ai∗Ai−Ai=0以
f
f
f多项式表示为:
f
(
x
)
2
−
f
(
x
)
=
0
f(x)^2-f(x)=0
f(x)2−f(x)=0
定义其roots为
1
,
g
,
g
2
,
⋯
,
g
511
1,g,g^2,\cdots,g^{511}
1,g,g2,⋯,g511,当且仅当execution trace中的cell为0或1。从而可定义:
p
(
x
)
=
f
(
x
)
2
−
f
(
x
)
∏
i
=
0
511
(
x
−
g
i
)
p(x)=\frac{f(x)^2-f(x)}{\prod_{i=0}^{511}(x-g^i)}
p(x)=∏i=0511(x−gi)f(x)2−f(x)
即存在degree最多为
2
⋅
deg
(
f
)
−
512
2\cdot \deg(f)-512
2⋅deg(f)−512 的某多项式agrees with
p
p
p on all
x
∉
{
1
,
g
,
g
2
,
⋯
,
g
511
}
x\notin\{1,g,g^2,\cdots,g^{511}\}
x∈/{1,g,g2,⋯,g511} 当且仅当 该execution trace确实为a list of 512 bits(即0或1)。
注意,此前,Prover已将该execution trace扩展至更大的domain了,因此querying for the polynomial values in that domain is well defined。
若存在某协议(见STARK Low Degree Testing——FRI)使得Prover可使Verifier信服该多项式确实是低度的,使得Verifier仅需请求该execution trace之外的值,从而仅当该CI statement确实为true时,Verifier才会被说服。
如需证明基于
Z
96769
Z_{96769}
Z96769域的Fibonacci数列计算正确:
a
0
=
1
a_0=1
a0=1
a
1
=
1
a_1=1
a1=1
a
n
+
2
=
(
a
n
+
1
+
a
n
)
m
o
d
96769
a_{n+2}=(a_{n+1}+a_n)\mod 96769
an+2=(an+1+an)mod96769
claim为 a 511 = 62215 a_{511}=62215 a511=62215。
相应的execution trace为:

相应的多项式约束为:

定义degree最多为512的多项式
f
(
x
)
f(x)
f(x),使得:

将多项式约束以
f
f
f表示为:

由于多项式的组合仍然为一个多项式——将约束中的
A
i
A_i
Ai替换为
f
(
g
i
)
f(g^i)
f(gi)仍然是多项式约束。
注意,其中的1、2、4约束仅引用
f
f
f的某单个值,我们将这种约束称为boundary constraints。
Fibonacci的递归关系,体现在了基于整个execution trace的一组约束,可重组表示为:

使用generator
g
g
g来作为execution trace行的索引,有助于以简单的代数关系来表示“下一行”。若
x
x
x为execution trace中的某行,则
g
x
gx
gx表示其下一行,
g
2
x
g^2x
g2x表示下两行,
g
−
1
x
g^{-1}x
g−1x表示前一行。
最后两行除外,对于execution trace中的每一行的index
x
x
x值,递归关系多项式
f
(
g
2
x
)
−
f
(
g
x
)
−
f
(
x
)
=
0
f(g^2x)-f(gx)-f(x)=0
f(g2x)−f(gx)−f(x)=0。即意味着
1
,
g
,
g
2
,
⋯
,
g
509
1,g,g^2,\cdots,g^{509}
1,g,g2,⋯,g509为该递归关系多项式的all roots(且该递归关系多项式的degree最多为510),从而可构建如下
q
(
x
)
q(x)
q(x):

在STARK中,通常将
q
(
x
)
q(x)
q(x)称为组合多项式(composition polynomial)。当原始的execution trace遵循该Fibonacci递归关系时,仅当on all but these 510 values:
1
,
g
,
g
2
,
⋯
,
g
509
1,g,g^2,\cdots,g^{509}
1,g,g2,⋯,g509时,
q
(
x
)
q(x)
q(x)这种表示对应某degree最多为2的多项式(注意
f
f
f的degree最多为512)。不过composition polynomial这个属于有些不准确——当execution trace不满足相应的多项式约束时,
q
(
x
)
q(x)
q(x)的evaluation值 differ from any low degree polynomial in many places。换句话说,当且仅当原始CI是正确的时,
q
(
x
)
q(x)
q(x) close to 某低度多项式,这正是我们的目的。
通过以上步骤,可将 “检查某些特定多项式是否成立的问题” 转换为 “检查某多项式(对Prover已知)是否具有low degree”。
对于STARK来说,具有高效的verification技术至关重要。
STARK验证过程由2部分组成:
Verifier的工作主要有:
为避免1)中的情况,Verifier在query Fibonacci execution trace at 某行 w w w时,实际是请求 f f f在3个位置的值: f ( w ) , f ( g w ) , f ( g 2 w ) f(w),f(gw),f(g^2w) f(w),f(gw),f(g2w)。
Verifier可自行计算composition polynomial在
w
w
w处的值:

其中:
不过,trace中可能包含数十万行,计算分母将消耗Verifier大量时间。
以下计算对于succinctness来说至关重要——因,对the powers of
g
g
g形成的subgroup,有:

该等式成立,因等式两端均为degree为
∣
G
∣
|G|
∣G∣的多项式,其root正好都是
G
G
G中的元素。
若计算等式右侧看起来需要的计算量与 ∣ G ∣ |G| ∣G∣呈线性关系,但是,若借助exponentiation by squaring技术,等式左侧的计算running time为logarithmic in ∣ G ∣ |G| ∣G∣。
实际,可将Fibonacci composition polynomial的分母重写为:

这样,看起来将占用Verifier大量计算的分母,其实际仅需polylogarithmic time,这仅对“将execution trace看成是某多项式对某域的subgroup进行的evaluation”的情况下才成立,且多项式约束基于该subgroup成立。
类似的小技巧可用于更成熟的execution trace,但是,最重要的是,约束中的重复模型应对于域的某subgroup。
以上例子都很简单,以说明算术化的关键部分。
一个问题自然出现:
当有多列和多个约束时,该如何处理呢?
答案为:
We have shown how, given an execution trace and constraint polynomials, the prover can construct a polynomial which is of low degree if and only if the original CI statement holds. Furthermore, we have shown how the verifier can query the values of this polynomial efficiently, making sure that the prover did not replace the true polynomial with some false low-degree one.
[1] Starkware 2019年博客 Arithmetization I
[2] Starkware 2019年博客 Arithmetization II
[3] Starkware Eli Be-Sasson 2019年讲义 STARK Arithmetization