Written by Pablo Gómez
Founder & CEO at Metlabs · Reviewed on October 11, 2026
The arithmetic circuit is the mandatory bridge of any proving system: no scheme can prove anything about a program until that program is expressed as constraints. The computation is modeled with addition and multiplication gates connected by wires, and is then compiled into a constraint system, usually R1CS (Rank-1 Constraint System), where each constraint has the form (A·s) × (B·s) = (C·s) and the vector s holds the assignment of all wires.
The prover searches for a valid assignment to those wires, called the witness, that satisfies every constraint, and generates the proof over that R1CS with a system like Groth16 or PLONK. A key rule is that constraints must be quadratic, of degree two, so complex expressions are broken down into pairwise multiplications. The number and quality of the constraints directly determine the cost of generating the proof.
To write these circuits without doing it by hand, specialized languages exist. Circom, developed by Iden3, defines circuits that compile to R1CS and generates the program that computes the witness; Tornado Cash and Semaphore use it through the circomlib library. Noir, created by Aztec with Rust-inspired syntax, works at a higher level and compiles to an intermediate representation (ACIR) that supports different proof backends. Both let a developer express the logic that a SNARK will then prove.
Also known as
- ZK circuit





