snarkjs 是 zkSNARK 方案的 JavaScript库。类似 Zokrates,它提供了另外一种语言 circom 来编写电路。同样,我们扩展它来生成证明和在比特币上验证证明。
curl -Ls https://scrypt.io/scripts/setup-circom.sh | sh
然后使用以下命令从安装我们的 扩展版本:
npm install -g snarkjs-scrypt
整个工作流程与原始 snarkjs 相同,只是验证步骤是在比特币上完成的。一般来说,它包含以下步骤:
用 circom 语言实现电路。例如,这个名为 factor.circom
的简单电路/程序证明了人们知道将整数 n
分解为两个整数,而无需透露整数。该电路有两个名为 p
和 q
的私有输入和一个名为 n
的公共输入。关于如何使用 circom 的更多信息,您可以参考 https://docs.circom.io 。
// p 和 q 是 n 的因式分解 pragma circom 2.0.0; template Factor() { // Private Inputs: signal input p; signal input q; // Public Inputs: signal output n; assert(p > 1); assert(q > 1); n <== p * q; } component main = Factor();
使用以下命令编译电路:
circom factor.circom --r1cs --wasm
这个 new
的命令用于启动 powers of tau 的仪式。
snarkjs powersoftau new bn128 12 pot12_0000.ptau snarkjs powersoftau contribute pot12_0000.ptau pot12_0001.ptau --name="First contribution" -e="$(openssl rand -base64 20)" snarkjs powersoftau prepare phase2 pot12_0001.ptau pot12_final.ptau
最后得到输出文件 pot12_final.ptau
。 验证该文件是否可用:
snarkjs powersoftau verify pot12_final.ptau
目前,snarkjs 支持 2 个证明系统:groth16 和 PLONK。 Groth16 要求每个电路都进行 powers of tau 的仪式。 PLONK 不需要它,只要有通用的 powers of tau 的仪式的就足够了。
这将为该电路生成一个证明密钥并验证该密钥。
Plonk
snarkjs plonk setup factor.r1cs pot12_final.ptau circuit_final.zkey
Groth16
snarkjs groth16 setup factor.r1cs pot12_final.ptau factor_0000.zkey snarkjs zkey contribute factor_0000.zkey circuit_final.zkey --name="Second contribution" -e="$(openssl rand -base64 20)" snarkjs zkey verify factor.r1cs pot12_final.ptau circuit_final.zkey
我们将验证密钥从 circuit_final.zkey
导出到 verification_key.json
中。
snarkjs zkey export verificationkey circuit_final.zkey verification_key.json
首先,我们创建一个包含电路输入的文件 input.json
,其内容为:
{ "p": 7, "q": 13 }
接下来,我们使用编译电路得到的 factor.wasm
来计算见证人:
node generate_witness.js factor.wasm ../input.json ../witness.wtns
它使用证明密钥和见证人生成证明。
PLONK
snarkjs plonk prove circuit_final.zkey witness.wtns proof.json public.json
Groth16
snarkjs groth16 prove circuit_final.zkey witness.wtns proof.json public.json
这会输出一个智能合约文件“verifier.scrypt”,其中包含在链上验证证明所需的所有代码。
snarkjs zkey export scryptverifier
您可以在本地验证它:
PLONK
snarkjs plonk verify verification_key.json public.json proof.json
Groth16
snarkjs groth16 verify verification_key.json public.json proof.json
完成右边的电路, 以确保 秘密输入 x
的平方等于 y
。