pragma circom 2.1.8;
// Create a circuit that takes an array of signals `in` and
// returns 1 if all of the signals are 1. If any of the
// signals are 0 return 0. If any of the signals are not
// 0 or 1 the circuit should not be satisfiable.
template MultiAND(n) {
signal input in[n];
signal output out;
}
component main = MultiAND(4);
Answer
template MultiAND(n) {
signal input in[n];
signal output out;
// constraint all inputs to be 1 or 0
for (var i = 0; i < n; i++) {
// in[i] must be either 1 or 0
in[i] * (1 - in[i]) === 0;
}
// multiply inputs
signal s[n];
s[0] <== in[0];
for(var i = 1; i < n; i++){
s[i] <== s[i - 1] * in[i];
}
// constraint out value to be RHS
out <== s[n-1];
}
component main = MultiAND(4);
If all the values can only be 1 or 0, then when multiplying them together, we should only get 1 or 0 as output values.
constraint input values to be 1 or 0
multiply. if all are 1, output is 1. if there is at least a single zero term, output is zero.
Alternative Solution: Non-general
template Mul() {
signal input in[2];
signal output out;
out <== in[0] * in[1];
}
template MultiAND(n) {
signal input in[n];
signal output out;
// constraint all inputs to be 1 or 0
for (var i = 0; i < n; i++) {
// in[i] must be either 1 or 0
in[i] * (1 - in[i]) === 0;
}
// multiply them together
signal a;
signal b;
// declare anon component
a <== Mul()([in[0], in[1]]);
b <== a * in[2];
// constraint out value to be RHS
out <== b * in[3];
}
the solution
Under-constrained example
out is not constrained.
this is under constrained although the tests clear