#2 Circom: Template parameters, Variables, Loops
Template parameters
Previously we looked at a circuit (IsBinary
) that verified if the supplied inputs were indeed binary.
That circuit circuit was hardcoded to accept only 2 inputs.
What if we want to parametrize the number of inputs? We would modify the circuit, like so:
Notice that the template declaration has changed to include n
in the parenthesis
n
here is known as a template parametern
is used within the circuit to specify the size of the arrayin
on instantiating, we must specify the value of
n
Circuits and constraints in Circom must have a fixed, known structure at instantiation; meaning they can't change after compilation. While templates can use parameters, once compiled, the circuit must be static and clearly defined. There is no support for "dynamic-length" circuits or constraints —everything must be fixed and well-defined from the start.
It is not possible to support variability in circuits and constraints post-compilation, as such variability would undermine the integrity of said circuits. Hence, it is crucial to ensure the scope of proving and verification is static and well-defined. Imagine having an R1CS system of constraints whose structure was mutable based on input signal values. Neither the prover nor the verifier could operate effectively as the number of constraints are not set in stone.
Although we have parametrized the array to be based on n
inputs, the number of constraints remain unchanged - there are 4 constraints and they only verify for the first 4 elements of the array. In the next example, we will explore how to generalize the number of constraints to match our array, using loops.
For loop and Variables: for
, var
for
, var
Use a for loop to generate constraints programmatically to match the number of inputs, like so:
both inputs and loop iterations are defined by
n
for each input, a constraint is defined with the purpose of verifying that it is either
0
or1
We have introduced two new keywords into the circuit: for
and var
Usage of the
for
keyword should be no mystery to the reader.The
var
keyword is used to declare a variable;i
, as seen in the loop definition.Variable assignment is made using the equal symbol
=
Here, variable i
is used to programmatically refer to different signals in the input array, while creating constraints for them.
Variables
Variables hold non-signal data and are mutable. Here is an example of a variable declaration outside of a loop:
Variables are not part of the R1CS system of constraints.
Variables are used to compute values outside the R1CS, to help define the R1CS.
When working with variables, Circom behaves like a normal programming language.
Operators
=
,==
,>=
,<=
, and!=
,++
, and--
behave the way you expect them to with variables.However, these operators do not work with signals (Circom will not compile such code), as they would not honour quadratic expressions.
Example
non-quadratic expressions are allowed with variables
acc
would be assigned the value of 15
Since we can use non-quadratic expressions with variables, they are very useful for side calculations, which can yield a value that can subsequently be used within a constraint.
input signal
s
is constrained toacc
the circuit serves to verify if the input signal is indeed 15.
Summary Example
Let’s combine all the above concepts into a less trivial example. The circuit below serves to verify if someone knows the decimal form of a binary number.
It expected both the binary and its supposed decimal equivalent to be provided for verification.
circuit takes the binary number input as an array
in[n]
and the decimal result asres
the provided binary number is converted to decimal form and assigned it to
sum
res
is then constrained againstsum
If the computed decimal value is not equal to the provided decimal value, verification fails.
This example showcases how a circuit can be created via parameters.
In the next article we will discuss in-depth where and how parameters can be used.
Last updated
Was this helpful?