# 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` .