From Code to Arithmetic Constraints
Computations are converted into arithmetic circuits consisting of addition and multiplication gates over finite field elements. Every statement must be expressed in Rank-1 Constraint System (R1CS) form: $(A \cdot s) \times (B \cdot s) = (C \cdot s)$, where $s$ is the witness vector containing inputs and intermediate variables.
Writing Circom Circuits
Circom is a domain-specific language for defining arithmetic constraints. Circuits define input signals (public or private) and generate constraints that output a witness file used by the prover.
// Circom arithmetic constraint example
pragma circom 2.1.6;
template Multiplier() {
signal input a;
signal input b;
signal output c;
// R1CS constraint: a * b === c
c <== a * b;
}
component main = Multiplier();