#2.1 Circom: Quadratic Constraints
This article serves as a quick review on constraints.
Circom constraints
While Circom at present can compile into either Groth16 or PLONK proving systems, they must expressed quadratically. That means a maximum of 1 multiplication per constraint.
Constraints are created with
===
notation.Only
*
,+
,-
operators are allowed.Constraints must be of quadratic form:
Ua * Vb + Wc
:there can only be 1 multiplicative operations between signals in a single constraint
U,V,W must be integer values
U,V,W cannot be signals
The number of addition operations per constraint definition have no restrictions:
for example
a * b + c + d + e
is allowed
The following forms are all accepted:
a * b === c;
2a * 3b === 4c; // integer coefficients allowed
a * b + c === d;
a * b + c === d + e + f; // no restrictions on addition
The following forms are not accepted:
// 2 multiplicative operations between signals
a * b * c === d;
a * b === c * d;
// other operators besides: +,-,*
a / c === d;
a % b === d;
Constraints can look like either:
a * b + c === d;
// or
d === a * b + c;
In either variation, the outcome is the same, the value of the LHS must be equivalent to that of the RHS.
To recap, per constraint definition, the following must be adhered:
no restriction on number of addition, integer or signal.
no restriction on number of integer multiplication operations.
only 1 multiplication operation between signals.
order around the constraint operator (LHS vs RHS), is irrelevant.
The following code does not compile:
templage Mul3() {
signal input a;
signal input b;
signal input c;
signal input res;
// not allowed
res === a * b * c;
}
The following code will compile:
templage Mul3() {
signal input a;
signal input b;
signal input c;
signal input res;
// all allowed
c === a * b;
c === a * b + res;
}
This should be familiar to the reader, from their understanding of arithmetization and R1CS.
Quadratic form and R1CS
Recall that in arithmetization, we flatten our verification program into a series of intermediate steps, where each intermediate step only contains only a single multiplication between unknown variables.
Consider the following verification example:
def someProblem(x, y, out):
res = y^2 + 4*(x^2)*y -2
assert out == res, "incorrect inputs";
Arithmetization would yield us:
v1 === y * y
v2 === x * x
out === v1 + (4v2 * y) - 2
Arithmetization requires us to restructure the problem into intermediate steps that only have 1 multiplication operation between signals.
This creates our system of constraints.
Consequently, the R1CS representation would be:

Since we previously ensured that there was only 1 multiplication per constraint, we are able to express the system of constraints in vector form, which is essentially R1CS.
Last updated
Was this helpful?