Chapter 1: Introduction to Snarkjs/Circom

snarkjs is a JavaScript library for the zkSNARK scheme. Similar to Zokrates, it provides another language, circom, to write circuits. Again, we extend it to generate proofs and verify proofs on Bitcoin.

Install

1. Install circom compiler

curl -Ls https://scrypt.io/scripts/setup-circom.sh | sh

2. Install snarkjs library

Then install our extended version using the following command:

npm install https://github.com/sCrypt-Inc/snarkjs.git

Workflow

The entire workflow is the same as the original snarkjs, except that the verification step is done on Bitcoin. Generally, it consists of the following steps:

1. Design a circuit

Implement circuits in circom language. For example, this simple circuit/program called factor.circom proves that people know to factor the integer n into two integers without revealing the integer. The circuit has two private inputs named p and q and one public input named n. For more information on how to use circom, you can refer to https://docs.circom.io.

// p and q are factorizations of 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();

2. Compile the circuit

Compile the circuit with the following command:

circom factor.circom --r1cs --wasm

3. Start a new powers of tau ceremony

The new command is used to initiate the ceremony of 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

Finally get the output file pot12_final.ptau. Verify that the file is available:

snarkjs powersoftau verify pot12_final.ptau

3. Setup

This will generate a proving key for the circuit and verify that key.

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 circuit.r1cs pot12_final.ptau circuit_final.zkey

4. Export verification key

We export the verification key from circuit_final.zkey into verification_key.json.

snarkjs zkey export verificationkey circuit_final.zkey verification_key.json

5. Calculating a witness

First, we create a file input.json containing the circuit inputs with the following contents:

{ "p": 7, "q": 13, "n": 91 }

Next, we use the factor.wasm obtained by compiling the circuit to calculate the witnesses:

node generate_witness.js circuit.wasm ../input.json ../witness.wtns

6. Create a proof

It uses proving keys and witnesses to generate proofs.

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

6. Export an sCrypt verifier

This outputs a smart contract file "verifier.scrypt" that contains all the code needed to verify the proof on-chain.

snarkjs zkey export scryptverifier

7. Proof of verification

You can verify it locally:

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

Put it to the test

Complete the circuit on the right to ensure that the square of the private input x equals y .