Open this in zkREPL →
This file can be included into other zkREPLs with include "gist:fe6c0feed9b35a2c2d5ca696ec7b30c9";
pragma circom 2.1.2; | |
include "circomlib/comparators.circom"; | |
template VarSubarray(n) { | |
signal input in[n]; | |
signal input start; | |
signal input end; | |
signal output out[n]; | |
component isWithinStartEndRange[n]; | |
component quinSelector[n]; | |
component modulo[n]; | |
var y = 0; | |
var z = start; | |
while(y < n){ | |
// fetch value with index z modulo n from array in | |
quinSelector[y] = QuinSelector(n); | |
modulo[y] = Modulo(n); | |
var k; | |
for (k=0; k<n; k++) { | |
quinSelector[y].in[k] <== in[k]; | |
} | |
modulo[y].in <== z; | |
quinSelector[y].index <== modulo[y].out; | |
// evaluate whether the index z is within the range [start, end) | |
isWithinStartEndRange[y] = IsWithinStartEndRange(); | |
isWithinStartEndRange[y].index <== z; | |
isWithinStartEndRange[y].end <== end; | |
// if it is in the range add the corresponding value to the out array, if not add 0 | |
out[y] <== quinSelector[y].out * isWithinStartEndRange[y].flag; | |
y++; | |
z++; | |
} | |
} | |
template QuinSelector(choices) { | |
signal input in[choices]; | |
signal input index; | |
signal output out; | |
// Ensure that index < choices | |
component lessThan = LessThan(10); | |
lessThan.in[0] <== index; | |
lessThan.in[1] <== choices; | |
lessThan.out === 1; | |
component calcTotal = CalculateTotal(choices); | |
component eqs[choices]; | |
// For each item, check whether its index equals the input index. | |
for (var i = 0; i < choices; i ++) { | |
eqs[i] = IsEqual(); | |
eqs[i].in[0] <== i; | |
eqs[i].in[1] <== index; | |
// eqs[i].out is 1 if the index matches. As such, at most one input to | |
// calcTotal is not 0. | |
calcTotal.nums[i] <== eqs[i].out * in[i]; | |
} | |
// Returns 0 + 0 + ... + item | |
out <== calcTotal.sum; | |
} | |
// This circuit returns the sum of the inputs. | |
// n must be greater than 0. | |
template CalculateTotal(n) { | |
signal input nums[n]; | |
signal output sum; | |
signal sums[n]; | |
sums[0] <== nums[0]; | |
for (var i=1; i < n; i++) { | |
sums[i] <== sums[i - 1] + nums[i]; | |
} | |
sum <== sums[n - 1]; | |
} | |
// This circuit takes an input (in) and return in mod n. | |
template Modulo(n) { | |
signal input in; | |
signal q; | |
signal output out; | |
out <-- in%n; | |
q <-- in\n; //where '\' is the integer division operator | |
in === q*n + out; //this works! | |
} | |
template IsWithinStartEndRange() { | |
signal input index; | |
signal input end; | |
signal output flag; | |
component lessThan = LessThan(10); | |
lessThan.in[0]<== index; | |
lessThan.in[1]<== end; | |
flag <== lessThan.out; | |
} | |
component main = VarSubarray(1000); | |
/* INPUT = { | |
"in": [ | |
55, 45, 71, 36, 24, 72, 77, 9, 3, 3, 37, 37, | |
67, 83, 18, 69, 12, 1, 89, 97, 45, 17, 40, 27, | |
92, 10, 37, 77, 45, 2, 39, 15, 60, 72, 30, 66, | |
73, 63, 14, 17, 51, 20, 41, 91, 23, 29, 60, 60, | |
29, 31, 11, 13, 20, 26, 18, 31, 82, 50, 81, 33, | |
18, 21, 94, 73, 84, 77, 17, 6, 96, 9, 16, 41, | |
7, 57, 46, 58, 49, 97, 41, 65, 4, 13, 78, 19, | |
9, 15, 93, 62, 10, 64, 95, 4, 47, 92, 33, 93, | |
29, 49, 92, 17, | |
55, 45, 71, 36, 24, 72, 77, 9, 3, 3, 37, 37, | |
67, 83, 18, 69, 12, 1, 89, 97, 45, 17, 40, 27, | |
92, 10, 37, 77, 45, 2, 39, 15, 60, 72, 30, 66, | |
73, 63, 14, 17, 51, 20, 41, 91, 23, 29, 60, 60, | |
29, 31, 11, 13, 20, 26, 18, 31, 82, 50, 81, 33, | |
18, 21, 94, 73, 84, 77, 17, 6, 96, 9, 16, 41, | |
7, 57, 46, 58, 49, 97, 41, 65, 4, 13, 78, 19, | |
9, 15, 93, 62, 10, 64, 95, 4, 47, 92, 33, 93, | |
29, 49, 92, 17, | |
55, 45, 71, 36, 24, 72, 77, 9, 3, 3, 37, 37, | |
67, 83, 18, 69, 12, 1, 89, 97, 45, 17, 40, 27, | |
92, 10, 37, 77, 45, 2, 39, 15, 60, 72, 30, 66, | |
73, 63, 14, 17, 51, 20, 41, 91, 23, 29, 60, 60, | |
29, 31, 11, 13, 20, 26, 18, 31, 82, 50, 81, 33, | |
18, 21, 94, 73, 84, 77, 17, 6, 96, 9, 16, 41, | |
7, 57, 46, 58, 49, 97, 41, 65, 4, 13, 78, 19, | |
9, 15, 93, 62, 10, 64, 95, 4, 47, 92, 33, 93, | |
29, 49, 92, 17, | |
55, 45, 71, 36, 24, 72, 77, 9, 3, 3, 37, 37, | |
67, 83, 18, 69, 12, 1, 89, 97, 45, 17, 40, 27, | |
92, 10, 37, 77, 45, 2, 39, 15, 60, 72, 30, 66, | |
73, 63, 14, 17, 51, 20, 41, 91, 23, 29, 60, 60, | |
29, 31, 11, 13, 20, 26, 18, 31, 82, 50, 81, 33, | |
18, 21, 94, 73, 84, 77, 17, 6, 96, 9, 16, 41, | |
7, 57, 46, 58, 49, 97, 41, 65, 4, 13, 78, 19, | |
9, 15, 93, 62, 10, 64, 95, 4, 47, 92, 33, 93, | |
29, 49, 92, 17, | |
55, 45, 71, 36, 24, 72, 77, 9, 3, 3, 37, 37, | |
67, 83, 18, 69, 12, 1, 89, 97, 45, 17, 40, 27, | |
92, 10, 37, 77, 45, 2, 39, 15, 60, 72, 30, 66, | |
73, 63, 14, 17, 51, 20, 41, 91, 23, 29, 60, 60, | |
29, 31, 11, 13, 20, 26, 18, 31, 82, 50, 81, 33, | |
18, 21, 94, 73, 84, 77, 17, 6, 96, 9, 16, 41, | |
7, 57, 46, 58, 49, 97, 41, 65, 4, 13, 78, 19, | |
9, 15, 93, 62, 10, 64, 95, 4, 47, 92, 33, 93, | |
29, 49, 92, 17, | |
55, 45, 71, 36, 24, 72, 77, 9, 3, 3, 37, 37, | |
67, 83, 18, 69, 12, 1, 89, 97, 45, 17, 40, 27, | |
92, 10, 37, 77, 45, 2, 39, 15, 60, 72, 30, 66, | |
73, 63, 14, 17, 51, 20, 41, 91, 23, 29, 60, 60, | |
29, 31, 11, 13, 20, 26, 18, 31, 82, 50, 81, 33, | |
18, 21, 94, 73, 84, 77, 17, 6, 96, 9, 16, 41, | |
7, 57, 46, 58, 49, 97, 41, 65, 4, 13, 78, 19, | |
9, 15, 93, 62, 10, 64, 95, 4, 47, 92, 33, 93, | |
29, 49, 92, 17, | |
55, 45, 71, 36, 24, 72, 77, 9, 3, 3, 37, 37, | |
67, 83, 18, 69, 12, 1, 89, 97, 45, 17, 40, 27, | |
92, 10, 37, 77, 45, 2, 39, 15, 60, 72, 30, 66, | |
73, 63, 14, 17, 51, 20, 41, 91, 23, 29, 60, 60, | |
29, 31, 11, 13, 20, 26, 18, 31, 82, 50, 81, 33, | |
18, 21, 94, 73, 84, 77, 17, 6, 96, 9, 16, 41, | |
7, 57, 46, 58, 49, 97, 41, 65, 4, 13, 78, 19, | |
9, 15, 93, 62, 10, 64, 95, 4, 47, 92, 33, 93, | |
29, 49, 92, 17, | |
55, 45, 71, 36, 24, 72, 77, 9, 3, 3, 37, 37, | |
67, 83, 18, 69, 12, 1, 89, 97, 45, 17, 40, 27, | |
92, 10, 37, 77, 45, 2, 39, 15, 60, 72, 30, 66, | |
73, 63, 14, 17, 51, 20, 41, 91, 23, 29, 60, 60, | |
29, 31, 11, 13, 20, 26, 18, 31, 82, 50, 81, 33, | |
18, 21, 94, 73, 84, 77, 17, 6, 96, 9, 16, 41, | |
7, 57, 46, 58, 49, 97, 41, 65, 4, 13, 78, 19, | |
9, 15, 93, 62, 10, 64, 95, 4, 47, 92, 33, 93, | |
29, 49, 92, 17, | |
55, 45, 71, 36, 24, 72, 77, 9, 3, 3, 37, 37, | |
67, 83, 18, 69, 12, 1, 89, 97, 45, 17, 40, 27, | |
92, 10, 37, 77, 45, 2, 39, 15, 60, 72, 30, 66, | |
73, 63, 14, 17, 51, 20, 41, 91, 23, 29, 60, 60, | |
29, 31, 11, 13, 20, 26, 18, 31, 82, 50, 81, 33, | |
18, 21, 94, 73, 84, 77, 17, 6, 96, 9, 16, 41, | |
7, 57, 46, 58, 49, 97, 41, 65, 4, 13, 78, 19, | |
9, 15, 93, 62, 10, 64, 95, 4, 47, 92, 33, 93, | |
29, 49, 92, 17, | |
55, 45, 71, 36, 24, 72, 77, 9, 3, 3, 37, 37, | |
67, 83, 18, 69, 12, 1, 89, 97, 45, 17, 40, 27, | |
92, 10, 37, 77, 45, 2, 39, 15, 60, 72, 30, 66, | |
73, 63, 14, 17, 51, 20, 41, 91, 23, 29, 60, 60, | |
29, 31, 11, 13, 20, 26, 18, 31, 82, 50, 81, 33, | |
18, 21, 94, 73, 84, 77, 17, 6, 96, 9, 16, 41, | |
7, 57, 46, 58, 49, 97, 41, 65, 4, 13, 78, 19, | |
9, 15, 93, 62, 10, 64, 95, 4, 47, 92, 33, 93, | |
29, 49, 92, 17 | |
], | |
"start": 25, | |
"end" : 30 | |
} */ |
Open this in zkREPL →
This file can be included into other zkREPLs with include "gist:fe6c0feed9b35a2c2d5ca696ec7b30c9";