本章节, 我们将讲解如何使用 circom 和 snarkjs 创建一个零知识 zkSnark 电路, 并展示如何创建证明并在以太坊上进行链外和链上验证
libsnark 使用步骤:
- 将待证明的命题表达为 R1CS
- 使用生成算法 G 为该命题生成公共参数
- 使用证明生成算法生成 R1CS 可满足的证明
- 使用验证算法来验证证明
- 安装依赖
yarn
- 创建 circuit.circom 文件 文件内容如下
pragma circom 2.0.0;
/*This circuit template multiplies in1 and in2.*/
template Multiplier2 () {
// Declaration of signals.
signal input a;
signal input b;
signal output c;
// Statements.
c <== a * b;
}
component main = Multiplier2();
- 编译电路
circom circuit.circom --r1cs --wasm --sym
- 显示电路的信息
npx snarkjs r1cs info circuit.r1cs
PS: 查看 snarkjs 的具体命令参数可使用 npx snarkjs --help
- 打印电路的约束
npx snarkjs r1cs print circuit.r1cs circuit.sym
- 下载 tau ceremony 文件
wget https://hermez.s3-eu-west-1.amazonaws.com/powersOfTau28_hez_final_10.ptau
- 生成 zkey 文件
npx snarkjs zkey new circuit.r1cs powersOfTau28_hez_final_10.ptau circuit_0000.zkey
- 增加 out contribution,随机输入一段文本,比如'123'
npx snarkjs zkey contribute circuit_0000.zkey circuit_final.zkey
- 导出证明 key
npx snarkjs zkey export verificationkey circuit_final.zkey verification_key.json
- 创建 input.json 文件, 文件内容如下
{"a": 3, "b": 11}
- 计算见证
node ./circuit_js/generate_witness.js ./circuit_js/circuit.wasm input.json witness.wtns
- 导出 witness.wtns 见证文件为 json 格式
npx snarkjs wtns export json witness.wtns witness.json
- 创建证明
npx snarkjs groth16 prove circuit_final.zkey witness.wtns proof.json public.json
- 验证证明
npx snarkjs groth16 verify verification_key.json public.json proof.json
- 生成 Solidity 的证明
npx snarkjs zkey export solidityverifier circuit_final.zkey verifier.sol
-
发布证明 可以复制 verifier.sol 代码到 remix 进行部署
-
生成调用的参数
npx snarkjs zkey export soliditycalldata public.json proof.json
- 进行调用
将命令的输出复制到 Remix 中的 verifyProof 方法的 parameters 字段中,点击 call 调用 verifyProof
如果一切正常,方法应该返回 true
如果仅更改参数中的任何位,则可以检查结果返回 false
- 创建第一个零知识 snark 电路: https://learnblockchain.cn/article/1078
- circom2 doc:https://docs.circom.io/circom-language/basic-operators/