Groth16算法是zkSNARK的典型算法,目前在ZCash,Filecoin,Coda等项目中使用。本文从计算量的角度详细分析Groth16计算。Groth16计算分成三个部分:Setup针对电路生成Pk/Vk(证明/验证密钥),Prove针对电路,在给定witness/statement的情况下生成证明,Verify通过Vk验证证明是否正确。
所有的术语和数学符号和Groth16论文保持一致(On the Size of Pairing-based Non-interactive Arguments,具体的计算在17/18页):
https://eprint.iacr.org/2016/260.pdf
对Groth16算法的理解可查看:
Groth16算法介绍
1. 电路描述
所有的电路描述有个专业的术语:Relation(变量和变量的关系描述)。描述Relation的语言很多:R1CS,QAP,tinyRAM,bacs等等。目前开发,电路一般采用R1CS语言描述。R1CS相对来说,非常直观。A*B=C(A/B/C分别是输入变量的线性组合)。但是,要应用Groth16算法,需要将R1CS描述的电路,转化为QAP描述。两种电路描述语言的转化,称为Reduction。
1.1 R1CS描述
给定M’个变量(第一个变量约定为恒量1),以及N’个约束,所有的R1CS描述可以表示如下:
每一行是一个约束。举例,第一行的约束表示的是:
( ∑ i = 0 M ′ a i u 0 i ) ∗ ( ∑ i = 0 M ′ a i v 0 i ) = ( ∑ i = 0 M ′ a i w 0 i ) (\sum_{i=0}^{M'} a_i u_{0i})*(\sum_{i=0}^{M'} a_i v_{0i}) = (\sum_{i=0}^{M'} a_i w_{0i}) (i=0∑M′aiu0i)∗(i=0∑M′aiv0i)=(i=0∑M′aiw0i)
1.2 QAP转化
介绍具体的转化之前,先介绍一个简单的术语,拉格朗日插值以及拉格朗日basis。
给定一系列的x和y的对应关系,通过拉格朗日插值的方式,可以确定多项式:
p ( x ) = y 0 l 0 ( x ) + y 1 l 1 ( x ) + . . . + y n l n ( x ) p(x) = y_0l_0(x) + y_1l_1(x) + ... + y_nl_n(x) p(x)=y0l0(x)+y1l1(x)+...+ynln(x)
其中 l 0 ( x ) , l 1 ( x ) , . . . l n ( x ) l_0(x), l_1(x), ... l_n(x) l0(x),l1(x),...ln(x)就称为拉格朗日basis,计算公式如下:
l j ( x ) : = ∏ i = 0 , i ≠ j n x − x i x j − x i = ( x − x 0 x j − x 0