# 4.1. Circom & snarkJS

Circom allows the creation of circuits for zk-proofs. The output of circom is compatible with snarkJS, a JavaScript implementation for zk-SNARKs. We explain step-by-step how to combine the two tools.

# Step-by-step

• Write your arithmetic circuit using circom and save the file with .circom extension. Remember that you can create your own circuits or use the templates from the library of circuits circomlib.

• Compile the circuit to get a system of arithmetic equations representing the circuit.

\$ circom circuit.circom --r1cs --wasm --sym
• Now, use snarkJS to generate and verify zk-SNARK proofs.

• First, introduce the inputs to your circuit and compute the corresponding witness.

\$ snarkjs wtns calculate circuit.wasm input.json witness.wtns
• Before generating the proof, you will need to generate a trusted setup. Generating a trusted setup consists of 2 parts: powers of tau and phase 2. We will not deep into this topic here, we recommend you to review our Getting started section or to read directly the snarkJS tutorial.

// Start a new powers of tau ceremony and make a contribution (enter some random text)
\$ snarkjs powersoftau new bn128 12 pot12_0000.ptau -v
\$ snarkjs powersoftau contribute pot12_0000.ptau pot12_0001.ptau --name="First contribution" -v
// Prapare phase 2
\$ snarkjs powersoftau prepare phase2 pot12_0001.ptau pot12_final.ptau -v
// Start a new zkey and make a contribution (enter some random text)
\$ snarkjs zkey new circuit.r1cs pot12_final.ptau circuit_0000.zkey
\$ snarkjs zkey contribute circuit_0000.zkey circuit_final.zkey --name="1st Contributor Name" -v
• Export the verification key from circuit_final.zkey.

\$ snarkjs zkey export verificationkey circuit_final.zkey verification_key.json
• Generate a zero-knowledge proof associated to the circuit and your witness.

\$ snarkjs groth16 prove circuit_final.zkey witness.wtns proof.json public.json
• Once you have the proof, it is possible to validate the proof by running the following command.

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

It is also possible to generate a solidity verifier that allows verifying proofs on Ethereum blockchain. To this end, you should:

• Generate the solidity code by typing the following.

\$ snarkjs zkey export solidityverifier circuit_final.zkey verifier.sol
• Cut and paste in Remix the code from the output file named verifier.sol . You only need to deploy the Verifier contract.