cover_image

Circom+SnarkJS 入门笔记(1)

Kurt Pan XPTY
2022年03月18日 14:38

安装

  • Circom macOS二进制程序:https://docs.circom.io/downloads/downloads/
  • 系统里要配置好Rust开发环境和Node.js开发环境。
  • 安装circom
    • 会将二进制文件安装到$HOME/.cargo/bin
    • 会在target/release中生成二进制文件
    • git clone https://github.com/iden3/circom.git
    • cargo build --release
    • cargo install --path circom
    • 可以在命令行中使用Circom: circom --help
  • 安装snarkjs
    • npm install -g snarkjs

背景知识

  • 算术电路:zkSNARKs要求将要证明的计算论断建模为算术电路。算术电路即为对域 中元素进行模 加法或乘法操作用加法门/乘法门/线路组成的算法描述模型。p = 21888242871839275222246405745257275088548364400416034343698204186575808495617
  • 电路的信号(signal):每条线路上的域元素值,包括输入信号,中间信号和输出信号。
  • 约束:以门为变量的方程组,描述信号之间的关系,即为电路的信号必须满足的条件。
  • R1CS(rank-1 constraint system):描述电路的约束集合,以下形式方程的方程组,s_1,...,s_n为算术电路的信号:
    • (a_1*s_1 + ... + a_n*s_n) * (b_1*s_1 + ... + b_n*s_n) + (c_1*s_1 + ... + c_n*s_n) = 0
  • 证据:满足电路约束的信号集合赋值,R1CS的解。
  • zk-SNARK:一种简洁高效的NIZK证明系统,在不泄漏证据信息的情况下证明拥有满足电路约束的证据信号集合。

快速开始

  • 保存下述程序为multiplier2.circom
  •      pragma circom 2.0.0;

         /*这个电路检验c是a与b的乘积*/

         template Multiplier2 () {  

         // 信号声明
         signal input a;  
         signal input b;  
         signal output c;  

         // 约束
         c <== a * b;  
         }

         /*创建模板的一个实例*/
         component main = Multiplier2();

编译程序

  • circom multiplier2.circom --r1cs --wasm --sym --c
    • --r1cs : 生成multiplier2.r1cs,包含电路R1CS约束系统的二进制文件
    • --wasm:生成multiplier2_js文件夹,包括multiplier2.wasm
    • --c:生成multiplier2_cpp文件夹,包括multiplier2.cpp等用来生成证据的文件
    • --sym:生成multiplier2.sym,调试打印约束系统的符号文件

计算证据

  • 假设要证明知道两个数乘积为33
  • 创建输入文件input.json: {"a": 3, "b": 11}
  • multiplier2_js中:node generate_witness.js multiplier2.wasm input.json witness.wtns
  • 或在multiplier2_cpp中:make ; ./multiplier2 input.json witness.wtns
    • 注意安装C++库依赖:nlohmann-json3-dev, libgmp-dev ,  nasm

用零知识证明系统证明电路

  • Powers of Tau
    • snarkjs powersoftau new bn128 12 pot12_0000.ptau -v
    • snarkjs powersoftau contribute pot12_0000.ptau pot12_0001.ptau --name="First contribution" -v
  • Phase 2
    • snarkjs powersoftau prepare phase2 pot12_0001.ptau pot12_final.ptau -v
    • snarkjs groth16 setup multiplier2.r1cs pot12_final.ptau multiplier2_0000.zkey
    • snarkjs zkey contribute multiplier2_0000.zkey multiplier2_0001.zkey --name="1st Contributor Name" -v
    • snarkjs zkey export verificationkey multiplier2_0001.zkey verification_key.json
  • 生成证明
    • snarkjs groth16 prove multiplier2_0001.zkey witness.wtns proof.json public.json
  • 验证证明
    • snarkjs groth16 verify verification_key.json public.json proof.json