MultiOR
pragma circom 2.1.8;
include "../node_modules/circomlib/circuits/comparators.circom";
// Write a circuit that returns true when at least one
// element is 1. It should return false if all elements
// are 0. It should be unsatisfiable if any of the inputs
// are not 0 or not 1.
template MultiOR(n) {
signal input in[n];
signal output out;
}
component main = MultiOR(4);
Answer
template MultiOR(n) {
signal input in[n];
signal output out;
// constrain inputs to be only 1 or 0
for (var i = 0; i < n; i++) {
in[i] * (1 - in[i]) === 0;
}
// transformation
signal s[n];
// flip the first
s[0] <== 1 - in[0];
// flip term & multiply w/ prev. term
for(var i = 1; i < n; i++){
s[i] <== (1 - in[i]) * s[i - 1];
}
out <== 1 - s[n-1];
}
component main = MultiOR(4);
If you have a series of multiplications, within which there is a 0: x * x *
0 * x
, the entire series returns 0.
What MultiOR is saying is that: x * x * 1 * x * x
, the entire series returns 1.
If there is a '1' term, the entire multiplication should return 1.
Observe the following transformation:
in --> 1 - in
[0,0,0] --> [1,1,1]
[1,1,1] --> [0,0,0]
[1,0,0] --> [0,1,1] ** 0*1*1 = 0
if we had at least one 1
, then there will be at least one 0
, upon transformation. If we multiply the inputs after transformation, we would get 0.
Then if we minus the result from 1, (1-0), we will get 1.
return 1, if at least 1 of the inputs is 1
[0,0,0] --> [1,1,1] || 1*1*1 = 1 || 1-1 = 0
if we had all inputs as
0
, then they will be transformed to1
multiplying the resulting inputs give us 1
Then if we minus the result from 1, (1-1), we will get 0.
return 0, if all the elements are 0
Last updated
Was this helpful?