What does the word "circom" mean?
Circom is a language and a circuit compiler for zero-knowledge proofs, and the name is an acronym that stands for the words circuit and compiler.
Why did you create
The idea of designing a developer-friendly circuit language came up when applying zero-knowledge technology to specific projects. Although there were already tools that permitted the generation and validation of proofs, we missed a tool that gave flexibility and full control of the constraints to the programmer and at the same time abstracted the complexities of the zero-knowledge protocols.
We thought a good idea was to decouple the design of circuits from the specific zero-knowledge protocol implementation and decided to develop a circuit language that somehow was more electronic circuit based. As a result, circuits in
circomare built by combining components (templates) and wires (signals). You can listen to the whole story told by Jordi Baylina in the ZeroKnowledge podcast.
Who is behind
Circomwas first conceived by Jordi Baylina and later developed in Iden3, a project working on a self-sovereign identity system that uses this tool in the core protocol. The implementation of the language, the compiler and the library of
circomtemplates has been carried out with the help of the Ethereum Foundation Ecosystem Support and the collaboration of a group of researchers from the Complutense University of Madrid, Pompeu Fabra University and Polytechnic University of Catalonia.
Can I do any operation in a
Typically, in an arithmetic circuit you can only connect signals to addition and multiplication gates. However, in
circomyou can do any operation as long as you are able to reflect that operation as a quadratic constraint. We recommend you to look at this example.
Can I design my own circuits?
Yes, you can design and compile your own circuits but you are also welcome to use the templates from circomlib, a library of
circomcircuits that have been reviewed and tested by the community.
What happens if I do not write the constraints of a circuit properly?
One of the fundamentals of
circomlanguage is that you must add your own constraints. If you write a constraint that does not have the right form (i.e. it is not quadratic), then you will get a compilation error, but if you missed writing a constraint or wrote the wrong one, the compiler will not change anything for you. We recommend you to review the Constraints generation section to get to know more about how to write constraints in circuits.
What is the difference between the simple and the double arrow?
Double arrows (
<==) gather two actions together: they assign a value to signal and also generate a constraint at the same time. Simple arrows (
<--) only do the first action: they assign values to signals. Check out the section Assignment to signals to find out more details about the different
What is the difference between a signal and a variable?
A signal can be understood as a wire of the circuit, and as such, it can be either an input signal, an intermediate signal or an output signal. The connection of signals is done through addition and multiplication gates and constraints are used to capture these connections. The intermediate and output signals are calculated from the values assigned to the inputs, and once values are assigned to all signals, they can not be changed later on. This is why signals are considered immutable. On the contrary, variables are mutable elements of the code. Typically, variables are used in conditional and loop statements and may also be used as parameters of templates, allowing the creation of generic templates that depend on the values of certain variables (which would not be possible using signals). You can find more information about signals and variables here.
Circom seems to depend on the order of BN254 curve, can it operate on any other curve?
ZK-SNARK protocols make use of pairing-friendly elliptic curves to generate and validate proofs. In the case of Ethereum, this curve is alt_bn128 (also known as BN254). As a result, zero-knowledge on Ethereum can only be applied to arithmetic circuits that work modulo the order of this curve, which is this case, is the prime:
p = 21888242871839275222246405745257275088548364400416034343698204186575808495617
By default, arithmetic circuits build with
circomwork modulo this prime
p, but it is possible to change it, without affecting the rest of the language, using the parameter
GLOBAL_FIELD_P. As a result,
circomis a generic circuit language that can work with other curves and even in other blockchains.
What is the difference between Jubjub and Baby Jubjub curves?
To generate and verify zk-SNARK proofs, it is necessary to use a pairing-friendly elliptic curve. In Ethereum, this curve is alt_bn128 (also referred as BN254) and in Zcash, this curve is BLS12-381. In order to implement in a circuit cryptographic primitives that make use of elliptic curves, such as the Pedersen Hash or the Edwards Digital Signature Algorithm (EdDSA), it is necessary to construct an embedded curve. In the case of Zcash, the embedded curve is called Jubjub, and in Ethereum, the curve is Baby Jubjub. This means that the field modulus of Jubjub is the same as the group order of BLS12-381 and the field modulus of Baby Jubjub is the same as the group order of BN-254.
circom compatible with other software like
We decoupled the process of generating zero-knowledge proofs into two different processes: on the one side, the definition and representation of arithmetic circuits, and on the other side, the computation of circuit witnesses and generation and validation of zero-knowledge proofs about those circuits.
Circomserves the first purpose, and
snarkJSthe second. Hence, tools that integrate both steps in a unique software are not compatible with our programs but it is possible to replace
circomwith a circuit compiler and
snarkJSwith a zk-SNARKs implementation that draws from an R1CS circuit representation. Currently, there may be format compatibility issues but there are many efforts from the zero-knowledge community put into standardizing formats, which will greatly improve interoperability.
Is it possible to use other zero-knowledge systems, like Bulletproofs or STARKs, with
circomprovides an R1CS representation of circuits. So, any zero-knowledge system that draws from this representation, which is the case with most zk-SNARK protocols, is compatible with
circom. Other protocols use different representations of circuits but in many cases, the conversion from R1CS to these formats is not difficult. We have not yet worked on this, but it is in our to-do list! :)
circom already being used in production?
Can I add templates to
Yes, by submitting a pull request to the
circomlibrepository in GitHub. The addition of new templates may take some time, as we need to review the security considerations of each specific circuit. So, if you have already submitted a pull request, we kindly ask you to have some patience :)
If I spot a bug, who should I report it to?
The best way to report a bug or to contribute with code, tests or documentation, is to open an issue or submit a pull request in the specific repository in GitHub: circom, circomlib, snarkjs. If you prefer, you can also let us know your finding through our Telegram group. In any case, we thank you for your help!
My question does not appear in this list, what should I do?