Published on

Intro to Circom


Today I enrolled on a course Zero-Knowledge University (zku.ONE). The course starts on Feb 28th but today is my first day to learn about Zero-Knowledge Proof(ZKP), Merkle tree, and circom (absolutely my brain is 0 knowledge 🤣), then I decided to jot notes what I learned about Circom.

Link to Week 1 - Theory, there are so many useful resources provided on the course materials.


Install Rust

Install Rust with rustup in case you don't install yet.

curl --proto '=https' --tlsv1.2 -sSf | sh

Install snarkjs on global using NPM:

npm install -g snarkjs

Create a simple circuit

Create a new file named multiplier.circom:

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

  c <== a * b;

component main = Multiplier();

For the circom syntax:

c <== a * b;

Which is equivalent to:

c === a * b;
c <-- a * b;

Compile the circuit

When we have a circuit file, we are ready to compile the circuit, the syntax look like is:

circom <filename.circom> --r1cs --wasm --sym --output ./my-exist-folder

To compile, run this command:

# Create an empty folder
mkdir multiplier

circom multiplier.circom --r1cs --wasm --sym --output ./multiplier

The script will generate the output files into the multiplier folder instead of the root folder (. by default)

View information with snarkjs

snarkjs r1cs info multiplier/multiplier.r1cs

The result should be:

[INFO]  snarkJS: Curve: bn-128
[INFO]  snarkJS: # of Wires: 4
[INFO]  snarkJS: # of Constraints: 1
[INFO]  snarkJS: # of Private Inputs: 2
[INFO]  snarkJS: # of Public Inputs: 0
[INFO]  snarkJS: # of Labels: 4
[INFO]  snarkJS: # of Outputs: 1

Generate withness

The syntax to generate witness is:

node generate_witness.js <file.wasm> <input.json> <output.wtns>

Before we generate, we have to create input.json for inputs of a and b variables.

  "a": "10",
  "b": "5"

then run generate_witness.js inside multiplier/multiplier_js folder.

node generate_witness.js multiplier.wasm input.json output.wtns

The output file is output.wtns but it's a binary file. To view the content, we need to convert it into JSON format.

snarkjs wtns export json output.wtns output.json

Then the output file is ready: output.json with the content below:

["1", "50", "10", "5"]

I also create notes on my Github repository intro-to-circom

That's it for today, Time to do the assignment! 🙏