ZKP: Introduction to Circom Language 1

Table of contents

No heading

No headings in the article.

With the progress of Zero-Knowledge Proof coming to fore, into the blockchain ecosystem, there are unique languages peculiar for creating Zsnarks. These languages help generate arithmetic circuits on which the application applies the principle of ZKP. In this article, you will understand what Circom is, how to install it, know some basic concepts and the role of functionalities it takes in implementing the ZKP.

WHAT IS CIRCOM?

Circom is a programming language that helps compute the arithmetic circuits of a Zero-Knowledge Proof application. Circuits are built from signals. Circom was originally built with Javascript but the current version is built with Rust.

HOW TO INSTALL CIRCOM

The installation processes is quite clear. Ensure that you have the required dependencies to successfully install circom into your working environment. For those using either Linux OS and Mac OS, the installation processes is quite easy. For Window users, it is appropriate and fast to use a Window Subsytem for Linux (WSL).

Start with installing rust into your environment.

curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh

On successful installation of rust into your machine, you begin the installation of Circom by running the command below. Clone this repository to your root folder.

git clone https://github.com/iden3/circom.git

Navigate into the cloned folder and run:

cargo build --release

If you get a cargo: command not found error, then you have not installed Rust successfully into the machine.

When it finally builds, it generates an extra file target/release that has the circom binary. This command runs approximately 3 minutes if your internet connection is stable. Run the following to install the circom binary.

cargo install --path circom

This installs circom to the root folder of your machine and for this reason the circom commands only run when you navigate to the root directory. Run the command below to confirm if circom installed successfully.

circom --version

The command shows you the version of the circom compiler you installed. One more package needs to be installed globally into your machine. This package helps in the generation and validation of ZK proofs detected from the artifacts from circom; snarkjs.

npm install -g snarkjs

UNDERSTANDING SOME BASIC CIRCOM CONCEPTS AND SYNTAX

SIGNALS AND VARIABLES The signal keyword is used in creating a new variable in circom. It could either be an input, output or intermediate.

signal input a;
signal output b[N];
signal c;

The first is an input signal whose identifier is a. The secod line of code is an output signal of N array of b. The last is an intermediate signal with an identifier of c.

Below is a full prototype of a circom syntax.

pragma circom 2.0.0;

template Multiplier2(){
   //Declaration of signals
   signal input a;
   signal b;
   signal output c;

// Constraints.
   c <== a * b;
}

component main {public [a,b]} = Multiplier2();

I will explain each line of the codes to get us to understand the syntax of circom. The first pragma circom 2.0.0 specifies the compiler version of the arithmetic circuit. Like the contract keyword in Solidity, template is used to start a circuit. This is a Multiplier2() template. The next is a comment which is quite the same in other languages.

The next three lines are declaration of signals. The first is an input signal of a. The second is an intermediate signal of b while the Third is an output signal of c. These are all private signals and cannot be called in other circuits. In order to make signals accessible in other circuit, you have to implement the last line of code to make the signals public. It is important to add that output signals called in a the main component becomes public even without mentioning it in the main component. For input signals, the public keyword must be added.

The code directly under the constraints comment shows the logic of the circuits.

EXPRESSIONS IN CIRCOM

Expressions in circom is a combination of the operation and the signals to form the logic. In circom, the following are expressions:

Constant Values

Linear Expression

Quadratic expression

Non-quadratic expression

COMPILING OF CIRCUITS

For the compilation of these circuits, they must be saved with the .circom extension for it compile. Run this command to compile.

circom multiplier2.circom --r1cs --wasm --sym --c

This command generates the witness files and other necessary tools to help handle the debugging of constraints.

COMPILING WITNESS

Witnesses are generated to help test the logic in the arithmetic circuit. There are two processes to compile a witness; using WASM or C++. The WebAssemble will be shown here. To compile first, the witness starts with the creation of the test logics in a standard json file. For instance, we want to check that a equals 4 and b equals 12. This json file is created inside the multiplier_js file generated from the compile of the circuit.

{"a": 4, "b": 12}

Using WebAssembly

    node generate_witness.js multiplier2.wasm input.json witness.wtns

The compilation of the circuits and witnesses will thereafter help in generating a proof and verifying the proofs; it could be verified from your terminal using snarkjs or from smart contracts.

The above is only an introduction of what circom is, how to set it up and understand some basic syntax of the language. We will dive deep into Circom in the nearest future. We will look into understand the expressions, data types, scoping, and arithmetic operations.

REFERENCE

https://docs.circom.io/getting-started/installation/