Circom is a circuit programming language and a compiler that allows programmers to design and create their own arithmetic circuits for zero-knowledge proofs.
The idea of
circom came up when we wanted to use zero-knowledge proofs in our iden3 project, a self-sovereign identity solution that uses this technology to safeguard the users' privacy. Although there were tools that allowed the generation and validation of zero-knowledge proofs, we missed a low-level tool that gave full flexibility and control to the programmer.
circom as a low-level circuit language, to some extend close to the design of electronic circuits, in which developers can create their arithmetic circuits and later on, apply zero-knowledge tools. In this context, we complemented the work with
circom that allows to generate and validate zero-knowledge proofs.
Zero-knowledge proofs is a very active area of research, with many new and improved papers coming in every day. We believe that developing tools that decouple the circuit design phase from the specific zero-knowledge protocol implementation is a good way for integrating new and better solutions in the future.
The aim of the
circom language is two-folded. On the one hand, it allows to describe arithmetic circuits by means of quadratic constraints. On the other hand, it allows to describe how to efficiently compute the output and intermediate signals from a set of given inputs.
If the circuit is well implemented, both the constraints and the signal computation code should describe the same relation between the output and the input signals, but while the aim of the constrains is to characterize this relation only using quadratic arithmetic constraints, the aim of the computation part is to efficiently obtain a witness for all signals when the inputs are given. You can read more about these two process here.
When writing circuits, you should take into account the following particularities of the language:
The description of the circuit is at a low level.
The constraints that describe the circuit are explicit, this means that the developer should write them explicitly, as the compiler does not add, modify or delete any constraint.
The job of the circom compiler is double:
Symbolic: it generates a file with the set of constraints that define the circuit.
Computational: given a set of explicit inputs, it computes a witness for the circuit.
Circom makes it possible to create large circuits by combining smaller ones called
templates. Users can create their custom templates, but to reduce development time and avoid possible bugs, we also provide an open source library of templates called
circomlib that contains hundreds of circuits such as comparators, hash functions, digital signatures, binary and decimal convertors and many more.
Once a circuit is created in
circom, the process of generating and validating a zero-knowledge proof associated to that circuit can be done easy and transparently with
snarkJS combined with
All our tools are open source and publicly available to practitioners and developers. You can find the repositories in the following links:
Circom , the circuit language for zero-knowledge: https://github.com/iden3/circom
Circomlib, the library of circom templates: https://github.com/iden3/circomlib
First, we would like to specially thank the Ethereum Foundation Ecosystem Support for their endowment granted to the project. Secondly, we would like to thank the team of researchers from the Complutense University of Madrid, the Pompeu Fabra University and the Polytechnic University of Catalonia that has worked together with iden3 in the libraries and the compilers.
And finally but not least, we would like to acknowledge the job done by all the external collaborators that have contributed with issues, code, suggestions or in any other manner, to improve our repositories, and without which, some bugs would still exist.