前序博客有:
本文重点关注:
本节将展示当前SNARKjs和PIL-STARK工具栈的证明能力。尤其是演示如何实现某些类型的证明组合,从而超过SNARKjs和PIL-STARK原本的能力。
接下来,均以证明如下statement为例:
“I known a (secret) value a 1 = 1 a_1 = 1 a1=1 such that the ( 2 5 + 1 = ) (2^5 + 1 =) (25+1=) 33 33 33-th element of the Fibonacci sequence on (public) input a 0 = 1 a_0 = 1 a0=1 and a 1 a_1 a1 is equal to 3524578 3524578 3524578.”
本文前2小节,将展示如何生成(depth 0)proof。
以Circom来表示上述statement,即意味着将Fibonacci序列计算以R1CS格式表示:
该电路特定实例(即 a 0 = 1 , a 1 = 1 a_0=1,a_1=1 a0=1,a1=1)的execution trace为:
其中红色字体数字为仅对Prover已知的信息,而绿色字体数字为对Prover和Verifier都已知的信息。
在以Circom对该电路描述之后,可使用SNARKjs来为其生成有效的zk-SNARK证明:【当前SNARKjs支持Groth16、Fflonk和Plonk。为简化接下来都称为Plonk。】
$ mkdir -p build && circom src/fibonacci.circom --r1cs --wasm -o build
template instances: 1
non-linear constraints: 0
linear constraints: 0
public inputs: 1
public outputs: 1
private inputs: 1
private outputs: 0
wires: 3
labels: 35
input.json
输入文件:$ cat <<EOT > input.json
{ "a0": 1, "a1": 1}
EOT
$ snarkjs wc build/fibonacci_js/fibonacci.wasm src/input.json build/fibonacci.wtns
out = 3524578
$ wget https://hermez.s3-eu-west-1.amazonaws.com/powersOfTau28_hez_final_10.ptau -O build/powersOfTau.ptau
$ snarkjs pks build/fibonacci.r1cs build/powersOfTau.ptau build/fibonacci.zkey
[INFO] snarkJS: Reading r1cs
[INFO] snarkJS: Plonk constraints: 2
[INFO] snarkJS: Setup Finished
$ snarkjs zkev build/fibonacci.zkey build/fibonacci-vk.json
[INFO] snarkJS: EXPORT VERIFICATION KEY STARTED
[INFO] snarkJS: > Detected protocol: plonk
[INFO] snarkJS: EXPORT VERIFICATION KEY FINISHED
$ snarkjs pkp build/fibonacci.zkey build/fibonacci.wtns build/fibonacci.proof.json build/fibonacci.public.json
$ snarkjs pkv build/fibonacci-vk.json build/fibonacci.public.json build/fibonacci.proof.json
[ INFO ] snarkJS : OK!
以PIL来表示以上statement,即意味着需将Fibonacci序列的计算以AIR格式表示,即基于domain G = < g > G=
均满足,则原始statement为true。
此处:
该状态机特定实例(即 a 0 ( g ) = 1 , a 1 ( g ) = 1 a_0(g)=1,a_1(g)=1 a0(g)=1,a1(g)=1)的execution trace为:
在以PIL描述完电路之后,可使用pil-stark来为以上实例生成有效的eSTARK proof:
$ mkdir -p build && node src/main_buildconst.js -o build/fibonacci.const
file Generated Correctly
$ node src/main_buildcommit.js -i src/input.json -o build/fibonacci.commit
Result: 3524578
file Generated Correctly
$ node node_modules/pilcom/src/main_pilverifier.js build/fibonacci.commit -p src / fibonacci.pil -c build/fibonacci.const
PIL OK !!
starkstruct.json
文件:$ cat << EOT > starkstruct.json
{
"nBits": 5,
"nBitsExt": 6,
"nQueries": 64,
"verificationHashType": "GL",
"steps": [
{ "nBits": 6},
{ "nBits": 4},
{ "nBits": 2}
]
}
EOT
starkstruct.json
文件,生成,生成eSTARK所需的starkinfo.json
文件:$ node node_modules/pil-stark/src/main_genstarkinfo.js -p src/fibonacci.pil -s src/starkstruct.json -i build/starkinfo.json
files Generated Correctly
$ node node_modules/pil-stark/src/main_buildconsttree.js -c build/fibonacci.const -p src/fibonacci.pil -s src/starkstruct.json -t build/fibonacci.consttree -v build/fibonacci.verkey.json
files Generated Correctly
$ node node_modules/pil-stark/src/main_prover.js -m build/fibonacci.commit -c build/fibonacci.const -t build/fibonacci.consttree -p src/fibonacci.pil -s build/starkinfo.json -o build/fibonacci.proof.json -z build/fibonacci.zkin.json -b build/fibonacci.public.json
files Generated Correctly
$ node node_modules/pil-stark/src/main_verifier.js -p src/fibonacci.pil -s build/starkinfo.json -v build/fibonacci.verkey.json -o build/fibonacci.proof.json -b build/fibonacci.public.json
Verification Ok!!
本节将展示如何为以Circom直接编写的Fibonacci电路生成eSTARK proof:
$ mkdir -p build && circom src/fibonacci.circom --O1 --prime goldilocks --r1cs --wasm -o build
template instances: 1
non-linear constraints: 0
linear constraints: 31
public inputs: 1
public outputs: 1
private inputs: 1
private outputs: 0
wires: 34
labels: 35
注意此处采用Goldilocks素数域,而不是(Circom中默认的)定义BN128椭圆曲线的素数域。原因在于,当前以PIL编写的状态机仅支持Goldilocks域。input.json
:$ cat << EOT > input.json
{ "a0": 1 , "a1": 1}
EOT
$ snarkjs wc build/fibonacci_js/fibonacci.wasm src/input.json build/fibonacci.wtns
out = 3524578
$ node node_modules/pil-stark/src/main_plonksetup.js -r build/fibonacci.r1cs -p build/fibonacci.pil -e build/fibonacci.exec -c build/fibonacci.const
files Generated Correctly
输出的fibonacci.pil
中,以PIL编写的状态机为:【该转换过程中还会生成一个包含constant多项式的文件fibonacci.const
。】
constant % N = 2**6;
namespace Global(%N);
pol constant L1 ;
pol constant L2 ;
namespace PlonkCircuit(%N) ;
pol constant S[3];
pol constant Qm, Ql, Qr, Qo, Qk;
pol commit a[3];
public pub0 = a[0](0) ;
public pub1 = a[0](1) ;
Global.L1 * (a[0] - :pub0) = 0;
Global.L2 * (a[0] - :pub1) = 0;
// Normal plonk ecuations
pol a01 = a[0]*a[1];
Qm*a01 + Ql*a[0] + Qr*a[1] + Qo*a[2] + Qk = 0;
// Connection equations
{a[0] , a[1] , a[2]} connect {S[0], S[1], S[2]};
$ node node_modules/pil-stark/src/main_plonkexec.js -w build/fibonacci.wtns -p build/fibonacci.pil -e build/fibonacci.exec -m build/fibonacci.commit
file Generated Correctly
$ node node_modules/pilcom/src/main_pilverifier.js build/fibonacci.commit -p build/fibonacci.pil -c build/fibonacci.const
PIL OK!!
strakstruct.json
文件:$ cat << EOT > starkstruct.json
{
"nBits": 6,
"nBitsExt": 7,
"nQueries": 64,
"verificationHashType": "BN128",
"steps": [
{ "nBits": 7},
{ "nBits": 5},
{ "nBits": 3}
]
}
EOT
需注意,此处所需的nBits值需由5增加到6,因为将R1CS转换为Plonk的开销(具体可见上面的fibonacci.pil
状态机)。starkstruct.json
文件,生成,生成eSTARK所需的starkinfo.json
文件:$ node node_modules/pil-stark/src/main_genstarkinfo.js -p src/fibonacci.pil -s src/starkstruct.json -i build/starkinfo.json
files Generated Correctly
$ node node_modules/pil-stark/src/main_buildconsttree.js -c build/fibonacci.const -p src/fibonacci.pil -s src/starkstruct.json -t build/fibonacci.consttree -v build/fibonacci.verkey.json
files Generated Correctly
$ node node_modules/pil-stark/src/main_prover.js -m build/fibonacci.commit -c build/fibonacci.const -t build/fibonacci.consttree -p src/fibonacci.pil -s build/starkinfo.json -o build/fibonacci.proof.json -z build/fibonacci.zkin.json -b build/fibonacci.public.json
files Generated Correctly
$ node node_modules/pil-stark/src/main_verifier.js -p src/fibonacci.pil -s build/starkinfo.json -v build/fibonacci.verkey.json -o build/fibonacci.proof.json -b build/fibonacci.public.json
Verification Ok!!
接下来的小节中,将使用"PIL-STARK + PIL-STARK" 或 “PIL-STARK + SNARKjs” 组合来展开之前的2个流程。
接下来将展示,如何为,以Circom表示的statement的eSTARK proof有效,而生成的SNARK proof:
$ mkdir -p build && circom src/fibonacci.circom --O1 --prime goldilocks --r1cs --wasm -o build
Everything went okay, circom safe
input.json
:$ cat << EOT > input.json
{ "a0": 1, "a1": 1}
EOT
$ snarkjs wc build/fibonacci_js/fibonacci.wasm src/input.json build/fibonacci.wtns
out = 3524578
$ node node_modules/pil-stark/src/main_plonksetup.js -r build/fibonacci.r1cs -p build/fibonacci.pil -e build/fibonacci.exec -c build/fibonacci.const
files Generated Correctly
$ node node_modules/pil-stark/src/main_plonkexec.js -w build/fibonacci.wtns -p build/fibonacci.pil -e build/fibonacci.exec -m build/fibonacci.commit
file Generated Correctly
$ node node_modules/pilcom/src/main_pilverifier.js build/fibonacci.commit -p build/fibonacci.pil -c build/fibonacci.const
PIL OK!!
strakstruct.json
文件:$ cat << EOT > starkstruct.json
{
"nBits": 6,
"nBitsExt": 7,
"nQueries": 64,
"verificationHashType": "BN128",
"steps": [
{ "nBits": 7},
{ "nBits": 5},
{ "nBits": 3}
]
}
EOT
starkstruct.json
文件,生成,生成eSTARK proof所需的strakinfo.json
文件:$ node node_modules/pil-stark/src/main_genstarkinfo.js -p build/fibonacci.pil -s src/starkstruct.json -i build/starkinfo.json
files Generated Correctly
$ node node_modules/pil-stark/src/main_buildconsttree.js -c build/fibonacci.const -p build/fibonacci.pil -s src/starkstruct.json -t build/fibonacci.consttree -v build/fibonacci.verkey.json
files Generated Correctly
$ node node_modules/pil-stark/src/main_prover.js -m build/fibonacci.commit -c build/fibonacci.const -t build/fibonacci.consttree -p build/fibonacci.pil -s build/starkinfo.json -o build/fibonacci.proof.json -z build/fibonacci.zkin.json -b build/fibonacci.public.json --proverAddr 0x7BAbF98C66454aF8a3C366F893f99EBa26a15c66
files Generated Correctly
$ node node_modules/pil-stark/src/main_verifier.js -p build/fibonacci.pil -s build/starkinfo.json -v build/fibonacci.verkey.json -o build/fibonacci.proof.json -b build/fibonacci.public.json
Verification Ok!!
$ node node_modules/pil-stark/src/main_pil2circom.js -p build/fibonacci.pil -s build/starkinfo.json -v build/fibonacci.verkey.json -o build/verifier.circom
file Generated Correctly
此处支持递归性:若以之前生成的eSTARK proof为输入,生成了一个有效的SNARK,则可证明该eSTARK proof是有效的。circuits.gl
中的电路来编译该eSTARK verifier电路:$ circom build/verifier circom --r1cs --wasm -l node_modules/pil-stark/circuits.bn128 -l node_modules/circomlib/circuits -o build
template instances: 465
non-linear constraints: 2123834
linear constraints: 0
public inputs: 0
public outputs: 1
private inputs: 14682
private outputs: 0
wires: 2125925
labels: 5010997
input.json
:$ cat << EOT > input.json
{ "a0": 1, "a1": 1}
EOT
$ snarkjs wc build/verifier_js/verifier.wasm build/fibonacci.zkin.json build/verifier.wtns
out = 3524578
$ wget https://hermez.s3-eu-west-1.amazonaws.com/powersOfTau28_hez_final_16.ptau -O build/powersOfTau.ptau
$ snarkjs pks build/verifier.r1cs build/powersOfTau.ptau build/fibonacci.zkey
[INFO] snarkJS: Reading r1cs
[INFO] snarkJS: Plonk constraints: 2
[INFO] snarkJS: Setup Finished
$ snarkjs zkev build/veirifer.zkey build/veirifer-vk.json
[INFO] snarkJS: EXPORT VERIFICATION KEY STARTED
[INFO] snarkJS: > Detected protocol: plonk
[INFO] snarkJS: EXPORT VERIFICATION KEY FINISHED
$ snarkjs pkp build/veirifer.zkey build/veirifer.wtns build/veirifer.proof.json build/veirifer.public.json
$ snarkjs pkv build/veirifer-vk.json build/veirifer.public.json build/veirifer.proof.json
[INFO] snarkJS: OK!
本节,将针对:
以上相同的流程可不停重复,从而实现无限深度的proof composition。如之前各小节所示,无限的eSTARK composition最终以final SNARK结尾。
以下流程展示了PIL-STARK和SNARKjs工具栈的强大之处:
$ mkdir -p build && node src/main_buildconst.js -o build/fibonacci.const
file Generated Correctly
$ node src/main_buildcommit.js -i src/input.json -o build/fibonacci.commit
Result: 3524578
file Generated Correctly
$ node node_modules/pilcom/src/main_pilverifier.js build/fibonacci.commit -p src/fibonacci.pil -c build/fibonacci.const
PIL OK!!
strakstruct.json
文件:$ cat << EOT > fibonacci.starkstruct.json
{
"nBits": 5,
"nBitsExt": 6,
"nQueries": 64,
"verificationHashType": "GL",
"steps": [
{ "nBits": 6},
{ "nBits": 4},
{ "nBits": 2}
]
}
EOT
strakstruct.json
文件,生成,生成eSTARK proof所需的starkinfo.json
文件:$ node node_modules/pil-stark/src/main_genstarkinfo.js -p src/fibonacci.pil -s src/fibonacci.starkstruct.json -i build/starkinfo.json
files Generated Correctly
$ node node_modules/pil-stark/src/main_buildconsttree.js -c build/fibonacci.const -p src/fibonacci.pil -s src/fibonacci.starkstruct.json -t build/fibonacci.consttree -v build/fibonacci.verkey.json
files Generated Correctly
$ node node_modules/pil-stark/src/main_prover.js -m build/fibonacci.commit -c build/fibonacci.const -t build/fibonacci.consttree -p src/fibonacci.pil -s build/starkinfo.json -o build/fibonacci.proof.json -z build/fibonacci.zkin.json -b build/fibonacci.public.json
files Generated Correctly
$ node node_modules/pil-stark/src/main_verifier.js -p src/fibonacci.pil -s build/starkinfo.json -v build/fibonacci.verkey.json -o build/fibonacci.proof.json -b build/fibonacci.public.json
Verification Ok!!
$ node node_modules/pil-stark/src/main_pil2circom.js -p src/fibonacci.pil -s build/starkinfo.json -v build/fibonacci.verkey.json -o build/verifier.circom
Verification Ok!!
$ circom --O1 --prime goldilocks --r1cs --wasm build/verifier.circom -l node_modules/pil-stark/circuits.gl -o build
Verification Ok!!
$ snarkjs wc build/verifier_js/verifier.wasm build/fibonacci.zkin.json build/verifier.wtns
out = 3524578
$ node node_modules/pil-stark/src/main_plonksetup.js -r build/verifier.r1cs -p build/verifier.pil -c build/verifier.const -e build/verifier.exec
files Generated Correctly
$ node node_modules/pil-stark/src/main_plonkexec.js -w build/verifier.wtns -p build/verifier.pil -e build/verifier.exec -m build/verifier.commit
files Generated Correctly
$ node node_modules/pilcom/src/main_pilverifier.js build/verifier.commit -p build/verifier.pil -c build/verifier.const
PIL OK!!
verifier.starkstruct.json
文件:$ cat << EOT > verifier.starkstruct.json
{
"nBits": 16,
"nBitsExt": 17,
"nQueries": 64,
"verificationHashType": "GL",
"steps": [
{ "nBits": 17},
{ "nBits": 14},
{ "nBits": 10},
{ "nBits": 6}
]
}
EOT
至此,就可采用之前的流程来生成eSTARK proof。verifier.starkstruct.json
文件,生成,生成eSTARK proof所需的verifier.starkinfo.json
文件:$ node node_modules/pil-stark/src/main_genstarkinfo.js -p build/verifier.pil -s src/verifier.starkstruct.json -i build/verifier.starkinfo.json
files Generated Correctly
verifier.pil
:$ node node_modules/pil-stark/src/main_buildconsttree.js -c build/verifier.const -p build/verifier.pil -s src/verifier.starkstruct.json -t build/verifier.consttree -v build/verifier.verkey.json
files Generated Correctly
$ node node_modules/pil-stark/src/main_prover.js -m build/verifier.commit -c build/verifier.const -t build/verifier.consttree -p build/verifier.pil -s build/verifier.starkinfo.json -o build/verifier.proof.json -z build/verifier.zkin.json -b build/verifier.public.json
files Generated Correctly
$ node node_modules/pil-stark/src/main_verifier.js -p build/verifier.pil -s build/verifier.starkinfo.json -v build/verifier.verkey.json -o build/verifier.proof.json -b build/verifier.public.json
Verification Ok !!
正如之前所提及的,可为eSTARK verifier生成Circom电路,并遵循10-18步骤来重复以上流程,其中每次重复会创建一个starkstruct.json文件。
[1] Polygon zkEVM技术文档 Recursion, aggregation and composition of proofs v.1.1