Circom in Remix Part 1: Definitions

Rob Stupay
Remix Project
Published in
5 min readDec 19, 2023

Remix now has a Circom Compiler for running circuits and generating ZK Proofs. This is Part 1 of a 2-part series about Circom in Remix. This article goes through ZKProof vocabulary and concepts so you can understand the interface of the Remix Circom compiler. But, if you want to jump ahead, here’s the link to Part 2.

In order to work with Circom, you should go through their docs and their ZK Background page. Many of the definitions contained in this article are from this excellent video, Arithmetic Circuits in Circom v2.0 by Darth Cy.

Basic Elements of a zk-SNARK

A ZKProof, contains these elements:

  • Public inputs that are known to everyone
  • Private inputs that are only known to the prover, who claims that these are the right inputs for solving the problem.
  • Problem: a function that takes private and public inputs. It is also the circuit, which we will get into below.
  • Prover: a person who knows the solution (the private inputs) for the problem. The prover runs the program that executes the circuit and generates a proof.
  • Verifier: a program or a person that takes a proof (with the public inputs), and can verify its validity without needing the private inputs.

ZK Proof is in a mathematical context

The prover wants to prove to the verifier that they have a piece of information —while hiding this information. In the context of Circom (and most ZK Proofs), the information is a number or an encoding — like a hash of some text. And in this mathematical context, the private input will need to satisfy a criteria — like an equation.

The Mechanism of a ZK Proof

In a proof, there is the original, private input which is encoded and used in a polynomial equation let’s call it f(x). Then a prover comes along and says they have the same private input which is also encoded and used in another polynomial equation g(x) , let’s call this the expected polynomial equation.

The verification system is a way of comparing the two equations by feeding them arbitrary data and checking that the results are the same. The arbitrary data must indeed be random, otherwise the proof of the private input could be faked.

Now let’s get into a technical glossary of the basics.

Circom

Circom is a low-level language that describes mathematical procedures by simplifying complex mathematical operations into circuits.

Circuits

In the context of Circom, a circuit is a mathematical equation — a polynomial equation. It is written with a series of logic gates. The logic gates of Circom can either be where two numbers are multiplied, or where an arbitrary set of numbers are added.

So this equation:

is rewritten as steps, where x is multiplied by x, and then the result of that is multiplied by y, and that result is added to 6.

This is also referred to as “flattening” the equation.

Then, each step of the equation is a multiplication or summation logic gate.

By breaking down a complex equation into smaller steps, there will be intermediary outputs. These intermediary outputs in the formula above are m1 and m2.

Signals

Signals can be the original inputs, the intermediate outputs, or the final output.

Templates

Templates are the building blocks of the Circom language. They take signals as their inputs, and their outputs are also signals. In other languages, templates are known as classes. But take note that in Remix, templates, used in the context of Workspaces, are the files that load with a new Workspace.

Witness

The witness is generated from the signals which includes all inputs, outputs and intermediary signals.

The intermediary signals are an ingredient in the witness to show that the circuit went through an honest execution.

To generate the proof, only the witness is needed.

Constraints

These are the individual steps in the computation of an equation.

R1CS — Rank 1 Constraint System

R1CS is a protocol for organizing the constraints. For more, see this article. Basically, R1CS flattens the equation and organizes the arrangement.

Groth16

Groth16 is a proving system.

As described above, verification is done by sending a set of arbitrary data to the circuit and checking that it returns the same results as the circuit derived from the original private input.

Randomness

It is essential that the arbitrary data fed into the circuits are truly random, otherwise a proof could be forged.

The process of getting the random points is the Trusted Setup.

Also see Darth Cy’s video about Groth16, as well as Vitalik Buterin’s 2016 article.

Trusted Setup

The trusted setup is the process of creating a dataset of random numbers. It involves any number of parties contributing randomness (also called “entropy”) to a dataset.

The trusted setup is called a ceremony, and the specific one for Groth16 is the Powers of Tau ceremony.

Once the randomness from the ceremony is encapsulated into a randomness file, it is prepared for phase2.

Phase2

Groth16 needs two types of random number sets:

  • a set from a trusted setup and that have nothing to do with a specific circuit
  • Phase2 number sets which are specific to a circuit

The preparation the Phase2 dataset is a process that first involves the creation of a final ceremony file. Then the circuit you are working with is “intertwine” and a ZKEY file is produced. The ZKEY file is required every time you want to generate a proof for a particular circuit.

Typically, additional randomness is added to the ZKEY file.

Like French cooks who always add butter, ZKP chefs are always adding randomness to their recipes.

Read more about Phase2 in the snarksjs docs.

Generating a Proof

To generate the proof you need:

  1. Circuit-specific witness calculator — a program, which calculates witness from input signals (private and public)
  2. ZKey file which is a representation of the circuit
  3. input.json — a file with public and private signals.

The basic background is done!

…there’s more to study, but that’s will get you familiar with most of the terms in the Circom compiler

So it’s time to find the proof in the pudding. And by the way, the proof in this pudding is not in the eating, it is in evaluating the polynomials. So get your hands out of the dessert and into some honestly random data and circuits.

Learn about how to use Remix’s Circom compiler in Part 2 , which you will find here.

--

--