R1CS json format
The file contains a dictionary with a single entry "constraints" and a list of constraints as value.
{
"constraints": [
constraint_1,
...
constraint_n
]
}
where every constraint is a list with three elements which are the linear expresions A, B and C that represent the constraint A*B -C = 0.
[lin_expr_A,lin_expr_B,lin_expr_C]
where the linear expression is represented by a dictionary with the signal numbers as strings occurring in the linear expression (with non-zero coefficient) as entries and their coefficients (as string) as values:
{ "sig_num_l1": "coef_1", ... , "sig_num_lm": "coef_m"}`
If you also include the --sym
flag, in the generated sym file you can see the qualified name in the circom program associated to each signal number, with the signal number 0 always expressing the constant 1. This way we can express any constant by having it as coefficient of the signal 0.
Let us consider the following simple circuit in 'basic.circom':
pragma circom 2.0.0;
template Internal() {
signal input in[2];
signal output out;
out <== in[0]*in[1];
}
template Main() {
signal input in[2];
signal output out;
component c = Internal ();
c.in[0] <== in[0];
c.in[1] <== in[1]+2*in[0]+1;
c.out ==> out;
}
if we run
circom basic.circom --json --wasm
a file 'basic_contraints.json' is generated and it contains two constraints:
{
"constraints": [
[{"2":"21888242871839275222246405745257275088548364400416034343698204186575808495616"},{"4":"1"},{"1":"21888242871839275222246405745257275088548364400416034343698204186575808495616"}],
[{},{},{"0":"1","2":"2","3":"1","4":"21888242871839275222246405745257275088548364400416034343698204186575808495616"}]
]
}
As we can see, only constant and renaming (equalities between signals) simplifications have been applied (since the --O1 simplification is the default).
Instead, if we run
circom basic.circom --json --wasm --O0
to indicate that we do not want to apply any simplification the generated file 'basic_constraints.json' contains
{
"constraints": [
[{},{},{"2":"1","5":"21888242871839275222246405745257275088548364400416034343698204186575808495616"}],
[{},{},{"0":"1","2":"2","3":"1","6":"21888242871839275222246405745257275088548364400416034343698204186575808495616"}],
[{},{},{"1":"21888242871839275222246405745257275088548364400416034343698204186575808495616","4":"1"}],
[{"5":"21888242871839275222246405745257275088548364400416034343698204186575808495616"},{"6":"1"},{"4":"21888242871839275222246405745257275088548364400416034343698204186575808495616"}]
]
}
Finally, if we run
circom basic.circom --json --wasm --O2
we can see that only one constraint is taken after applying the full simplification:
{
"constraints": [
[{"2":"21888242871839275222246405745257275088548364400416034343698204186575808495616"},{"0":"1","2":"2","3":"1"},{"1":"21888242871839275222246405745257275088548364400416034343698204186575808495616"}]
]
}