Home

Awesome

<div align="center"> <a href="https://www.artstation.com/artwork/lRZAQJ/"> <img alt="eth logo" src="https://pbs.twimg.com/media/FQXMnOTXEAY5fzX?format=jpg&name=large" > </a> <p align="center"> <a href="https://github.com/LuozhuZhang/zkps-circuit-demo/graphs/contributors"> <img alt="GitHub contributors" src="https://img.shields.io/github/contributors/LuozhuZhang/zkps-circuit-demo"> </a> <a href="http://makeapullrequest.com"> <img alt="pull requests welcome badge" src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat"> </a> <a href="https://twitter.com/LuozhuZhang"> <img alt="Twitter" src="https://img.shields.io/twitter/url/https/twitter.com/LuozhuZhang.svg?style=social&label=Follow%20%40LuozhuZhang"> </a> </p> </div>

zk-SNARK

A zk-SNARK implementation, use circom and snarkjs

Welcome to submit any issues or prs, also welcome DM me via twitter

The Process

1. initialize and setup

Create random numbers and circuits, get pk and vk through trusted setup

image

  1. Install dependencies
yarn global add circom
yarn global add snarkjs
<br/>
  1. Secure Multi-party Computation

Here is the output tool of zcash in ceremonypowersoftau

snarkjs powersoftau new bn128 12 pot12_0000.ptau -v
snarkjs powersoftau contribute pot12_0000.ptau pot12_0001.ptau --name="First contribution" -v
snarkjs powersoftau contribute pot12_0001.ptau pot12_0002.ptau --name="Second contribution" -v -e="some random text"

snarkjs powersoftau export challenge pot12_0002.ptau challenge_0003
snarkjs powersoftau challenge contribute bn128 challenge_0003 response_0003 -e="some random text"
snarkjs powersoftau import response pot12_0002.ptau response_0003 pot12_0003.ptau -n="Third contribution name"

Verify the ptau file so far

snarkjs powersoftau verify pot12_0003.ptau

More info about the powers of tau ceremony and MPC

<br/>
  1. Apply a random beacon,get final ptau file
snarkjs powersoftau beacon pot12_0003.ptau pot12_beacon.ptau 0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f 10 -n="Final Beacon"
snarkjs powersoftau prepare phase2 pot12_beacon.ptau pot12_final.ptau -v

Verify this ptau file

snarkjs powersoftau verify pot12_final.ptau
<br/>
  1. Create circuit

Using circom to write circuit,the circomlib also encapsulates the basic circuit

cat <<EOT > circuit.circom

template Multiplier(n) {
    signal input a;
    signal input b;
    signal output c;

    signal int[n];

    int[0] <== a*a + b;
    for (var i=1; i<n; i++) {
    int[i] <== int[i-1]*int[i-1] + b;
    }

    c <== int[n-1];
}

component main = Multiplier(1000);
EOT

More circom specification refer official documentation

<br/>
  1. Compile circuit
circom circuit.circom --r1cs --wasm --sym

View circuit information

snarkjs r1cs info circuit.r1cs
snarkjs r1cs print circuit.r1cs circuit.sym
<br/>
  1. trusted setup Export r1cs.json and create witness
snarkjs r1cs export json circuit.r1cs circuit.r1cs.json

cat <<EOT > input.json
{"a": 3, "b": 11}
EOT

circuit_js$ node generate_witness.js circuit.wasm ../input.json ../witness.wtns
// or
snarkjs wtns calculate circuit.wasm input.json witness.wtns

You can use the proof system of plonk or groth16,and there will be Halo2 developed by Aztec and Zcash in the future

snarkjs plonk setup circuit.r1cs pot12_final.ptau circuit_final.zkey

snarkjs groth16 setup circuit.r1cs pot12_final.ptau circuit_0000.zkey
<br/>
  1. Get pk and export the vk
snarkjs zkey export verificationkey circuit_final.zkey verification_key.json

2. create proof

image

Import pk、witness(s,private input)and x(public input),export proof

snarkjs plonk prove circuit_final.zkey witness.wtns proof.json public.json

3. verify proof

image

Import proof、x(public input)and verification key,then verifiers can verify the result of proof

// plonk
snarkjs plonk verify verification_key.json public.json proof.json
// groth16
snarkjs groth16 verify verification_key.json public.json proof.json

4. deploy verification contract

Export solidity file,contracts can be deployed via Remix,you can call contract after deploy verifier.sol

snarkjs zkey export solidityverifier circuit_final.zkey verifier.sol

You can also use soliditycalldata to simulate the verification call, return the verifyProof field and put it in the environment where the remix contract is deployed

snarkjs zkey export soliditycalldata public.json proof.json

References

[1] : Create your first zero-knowledge snark circuit using circom and snarkjs

[2] : Explaining SNARKs Part I: Homomorphic Hidings

[3] : What are zk-SNARKs?

[4] : Why and How zk-SNARK Works 1: Introduction & the Medium of a Proof

[5] : Why and How zk-SNARK Works: Definitive Explanation

[6] : Zk-SNARKs: Under the Hood -- vitalik