Pick a depth. Each prompt opens in your AI pre-loaded with the lesson. Click a row to preview the prompt.
Circom has arrays of signals and loops, but with a sharp twist: loops are unrolled at compile time. This means for (var i = 0; i < 100; i++) produces 100 copies of the body in R1CS, one per iteration. There is no 'runtime loop.' This is why the circuit size is determined entirely at compile time and why 'check this one of N items' is expensive unless you use specific techniques (selectors, Merkle proofs).
A circuit that sums an array of N signals. Straightforward with a compile-time loop — produces N constraints. Beginners often reach for 'sum all items in a list of unknown length'; Circom forces you to fix the length at compile time, or use a maximum-N + padding pattern.
pragma circom 2.1.6;
template Sum(N) {
signal input in[N];
signal output out;
signal acc[N];
acc[0] <== in[0];
for (var i = 1; i < N; i++) {
acc[i] <== acc[i-1] + in[i];
}
out <== acc[N-1];
}
template SelectorOneOfN(N) {
// Prove: 'this index selects this value from the array'
signal input arr[N];
signal input idx;
signal output out;
// Build a one-hot vector [0,0,1,0,...] whose '1' is at position idx.
signal selector[N];
var sum = 0;
for (var i = 0; i < N; i++) {
// selector[i] = 1 if i == idx else 0.
// Force via: selector[i] * (i - idx) = 0 AND sum of selectors = 1.
selector[i] <-- (i == idx) ? 1 : 0;
selector[i] * (i - idx) === 0;
sum += selector[i];
}
sum === 1;
var acc = 0;
for (var i = 0; i < N; i++) { acc += selector[i] * arr[i]; }
out <== acc;
}
component main = Sum(10);out <== arr[idx]). Compile fails: arrays can't be indexed by a signal (idx must be a compile-time var OR you need the selector pattern).