# snarkjs This is a **JavaScript and Pure Web Assembly implementation of zkSNARK schemes.** It uses the Groth16 Protocol (3 point only and 3 pairings). This library includes all the tools required to perform trusted setup multi-party ceremonies: including the universal [*powers of tau*](https://medium.com/coinmonks/announcing-the-perpetual-powers-of-tau-ceremony-to-benefit-all-zk-snark-projects-c3da86af8377) ceremony, and the second phase circuit specific ceremonies. > Any zk-snark project can pick a round from the common phase 1 to start their circuit-specific phase 2 ceremony. The formats used in this library for the multi-party computation are compatible with the ones used in [Semaphore's Perpetual Powers of Tau](https://github.com/weijiekoh/perpetualpowersoftau) and [other implementations](https://github.com/kobigurk/phase2-bn254). This library uses the compiled circuits generated by the [circom](https://github.com/iden3/circom) compiler. It works in [`node.js`](#using-node) as well as directly in the [browser](#in-the-browser). It's an [ES module](https://hacks.mozilla.org/2018/03/es-modules-a-cartoon-deep-dive/), so it can be directly imported into bigger projects using [Rollup](https://rollupjs.org/guide/en/) or [Webpack](https://webpack.js.org/). The low-level cryptography is performed directly in `wasm`, and uses worker threads to parallelize the computations. The result is a high performance library with benchmarks comparable to host implementations. ## Preliminaries ### Install node v14 First off, make sure you have a recent version of `Node.js` installed. While any version after `v12` should work fine, we recommend you install `v14` or later. If you’re not sure which version of Node you have installed, you can run: ```sh node -v ``` To download the latest version of Node, see [here](https://nodejs.org/en/download/). ### Install snarkjs and circom To install `circom` and `snarkjs`, run: ```sh npm install -g circom@latest npm install -g snarkjs@latest ``` If you're seeing an error, try prefixing both commands with `sudo` and running them again. ### Understand the `help` command To see a list of all `snarkjs` commands, as well as descriptions about their inputs and outputs, run: ```sh snarkjs --help ``` You can also use the `--help` option with specific commands: ```sh snarkjs groth16 prove --help ``` Most of the commands have an alternative shorter alias (which you can discover using `--help`). For example, the previous command can also be invoked with: ```sh snarkjs g16p --help ``` ### Debugging tip If you a feel a command is taking longer than it should, re-run it with a `-v` or `--verbose` option to see more details about how it's progressing and where it's getting blocked. ## Guide ### 0. Create and move into a new directory ```sh mkdir snarkjs_example cd snarkjs_example ``` ### 1. Start a new powers of tau ceremony ```sh snarkjs powersoftau new bn128 12 pot12_0000.ptau -v ``` The `new` command is used to start a powers of tau ceremony. The first parameter after `new` refers to the type of curve you wish to use. At the moment, we support both `bn128` and `bls12-381`. The second parameter, in this case `12`, is the power of two of the maximum number of contraints that the ceremony can accept: in this case, the number of constraints is `2 ^ 12 = 4096`. The maximum value supported here is `28`, which means you can use `snarkjs` to securely generate zk-snark parameters for circuits with up to `2 ^ 28` (≈268 million) constraints. ### 2. Contribute to the ceremony ```sh snarkjs powersoftau contribute pot12_0000.ptau pot12_0001.ptau --name="First contribution" -v ``` The `contribute` command creates a ptau file with a new contribution. You'll be prompted to enter some random text to provide an extra source of entropy. `contribute` takes as input the transcript of the protocol so far, in this case `pot12_0000.ptau`, and outputs a new transcript, in this case `pot12_0001.ptau`, which includes the computation carried out by the new contributor (`ptau` files contain a history of all the challenges and responses that have taken place so far). `name` can be anything you want, and is just included for reference (it will be printed when you verify the file (step 5). ### 3. Provide a second contribution ```sh snarkjs powersoftau contribute pot12_0001.ptau pot12_0002.ptau --name="Second contribution" -v -e="some random text" ``` By letting you write the random text as part of the command, the `-e` parameter allows `contribute` to be non-interactive. ### 4. Provide a third contribution using third party software ```sh 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" ``` The challenge and response files are compatible with [this software](https://github.com/kobigurk/phase2-bn254). This allows you to use different types of software in a single ceremony. ### 5. Verify the protocol so far ```sh snarkjs powersoftau verify pot12_0003.ptau ``` The `verify` command verifies a `ptau` (powers of tau) file. Which means it checks all the contributions to the multi-party computation (MPC) up to that point. It also prints the hashes of all the intermediate results to the console. If everything checks out, you should see the following at the top of the output: ```sh [INFO] snarkJS: Powers Of tau file OK! ``` In sum, whenever a new zk-snark project needs to perform a trusted setup, you can just pick the latest `ptau` file, and run the `verify` command to verify the entire chain of challenges and responses so far. ### 6. Apply a random beacon ```sh snarkjs powersoftau beacon pot12_0003.ptau pot12_beacon.ptau 0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f 10 -n="Final Beacon" ``` The `beacon` command creates a `ptau` file with a contribution applied in the form of a random beacon. We need to apply a random beacon in order to finalise phase 1 of the trusted setup. > To paraphrase Sean Bowe and Ariel Gabizon, a random beacon is a source of public randomness that is not available before a fixed time. The beacon itself can be a delayed hash function (e.g. 2^40 iterations of SHA256) evaluated on some high entropy and publicly available data. Possible sources of data include: the closing value of the stock market on a certain date in the future, the output of a selected set of national lotteries, or the value of a block at a particular height in one or more blockchains. E.g. the hash of the 11 millionth Ethereum block (which as of this writing is some 3 months in the future). See [here](https://eprint.iacr.org/2017/1050.pdf) for more on the importance of a random beacon. For the purposes of this tutorial, the beacon is essentially a delayed hash function evaluated on `0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f` (in practice this value will be some form of high entropy and publicly available data of your choice). The next input -- in our case `10` -- just tells `snarkjs` to perform `2 ^ 10` iterations of this hash function. > Note that [security holds](https://eprint.iacr.org/2017/1050) even if an adversary has limited influence on the beacon. ### 7. Prepare phase 2 ```sh snarkjs powersoftau prepare phase2 pot12_beacon.ptau pot12_final.ptau -v ``` We're now ready to prepare phase 2 of the setup (the circuit-specific phase). Under the hood, the `prepare phase2` command calculates the encrypted evaluation of the Lagrange polynomials at tau for `tau`, `alpha*tau` and `beta*tau`. It takes the beacon `ptau` file we generated in the previous step, and outputs a final `ptau` file which will be used to generate the circuit proving and verification keys. ### 8. Verify the final `ptau` ```sh snarkjs powersoftau verify pot12_final.ptau ``` The `verify` command verifies a powers of tau file. Before we go ahead and create the circuit, we perform a final check and verify the final protocol transcript. > Notice there is no longer a warning informing you that the file does not contain phase 2 precalculated values. ### 9. Create the circuit ```sh cat < circuit.circom template Multiplier(n) { signal private input a; signal private input b; signal output c; signal int[n]; int[0] <== a*a + b; for (var i=1; i input.json {"a": 3, "b": 11} EOT snarkjs wtns calculate circuit.wasm input.json witness.wtns ``` Calculate the witness (given the inputs `a = 3` and `b = 11`). ### 23. Debug the final witness calculation ```sh snarkjs wtns debug circuit.wasm input.json witness.wtns circuit.sym --trigger --get --set ``` And check for any errors in the witness calculation process (best practice). The `wtns debug` command logs every time a new component starts/ends (`--trigger`), when a signal is set (`--set`) and when it's read (`--get`). ### 24. Create the proof ```sh snarkjs groth16 prove circuit_final.zkey witness.wtns proof.json public.json ``` We create the proof. `groth16 prove` generates the files `proof.json` and `public.json`: `proof.json` contains the actual proof, whereas `public.json` contains the values of the public inputs and output. > Note that it's also possible to create the proof and calculate the witness in the same command by running: > ```sh > snarkjs groth16 fullprove input.json circuit.wasm circuit_final.zkey proof.json public.json > ``` ### 25. Verify the proof ```sh snarkjs groth16 verify verification_key.json public.json proof.json ``` We use the `groth16 verify` command to verify the proof, passing in the `verification_key` we exported earlier. If all is well, you should see that `OK` has been outputted to your console. This signifies the proof is valid. ### 26. Turn the verifier into a smart contract ```sh snarkjs zkey export solidityverifier circuit_final.zkey verifier.sol ``` Finally, we export the verifier as a Solidity smart-contract so that we can publish it on-chain -- using [remix](https://remix.ethereum.org/) for example. For the details on how to do this, refer to section 4 of [this tutorial](https://blog.iden3.io/first-zk-proof.html). ### 27. Simulate a verification call ```sh snarkjs zkey export soliditycalldata public.json proof.json ``` We use `soliditycalldata` to simulate a verification call, and cut and paste the result directly in the verifyProof field in the deployed smart contract in the remix envirotment. And voila! That's all there is to it :) ## Using Node ```sh npm init npm install snarkjs ``` ```js const snarkjs = require("snarkjs"); const fs = require("fs"); async function run() { const { proof, publicSignals } = await snarkjs.groth16.fullProve({a: 10, b: 21}, "circuit.wasm", "circuit_final.zkey"); console.log("Proof: "); console.log(JSON.stringify(proof, null, 1)); const vKey = JSON.parse(fs.readFileSync("verification_key.json")); const res = await snarkjs.groth16.verify(vKey, publicSignals, proof); if (res === true) { console.log("Verification OK"); } else { console.log("Invalid proof"); } } run().then(() => { process.exit(0); }); ``` ## In the browser Load `snarkjs.min.js` and start using it as usual. ``` cp node_modules/snarkjs/build/snarkjs.min.js . ``` ```html Snarkjs client example

Snarkjs client example

 Proof: 
 Result: 
``` ## Further resources - [Announcing the Perpetual Powers of Tau Ceremony to benefit all zk-SNARK projects](https://medium.com/coinmonks/announcing-the-perpetual-powers-of-tau-ceremony-to-benefit-all-zk-snark-projects-c3da86af8377) - [Scalable Multi-party Computation for zk-SNARK Parameters in the Random Beacon Model](https://eprint.iacr.org/2017/1050.pdf) - [phase2-bn254](https://github.com/kobigurk/phase2-bn254) - [Perpetual Powers of Tau](https://github.com/weijiekoh/perpetualpowersoftau) - [Powers of Tau](https://github.com/ebfull/powersoftau) - [Trusted setup ceremonies explored](https://www.zeroknowledge.fm/133) ## Final note We hope you enjoyed this quick walk-through. Please address any questions you may have to our [telegram group](https://t.me/iden3io) (it’s also a great way to join the community and stay up-to-date with the latest circom and snarkjs developments) 💙 ## License snarkjs is part of the iden3 project copyright 2018 0KIMS association and published with GPL-3 license. Please check the COPYING file for more details.