circomlib/circuits/multiplexer.circom
circuits/multiplexer.circomRaw
1/*
2 Copyright 2018 0KIMS association.
3
4 This file is part of circom (Zero Knowledge Circuit Compiler).
5
6 circom is a free software: you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 circom is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with circom. If not, see <https://www.gnu.org/licenses/>.
18*/
19
20/*
21 Copyright 2018 0KIMS association.
22
23 This file is part of circom (Zero Knowledge Circuit Compiler).
24
25 circom is a free software: you can redistribute it and/or modify it
26 under the terms of the GNU General Public License as published by
27 the Free Software Foundation, either version 3 of the License, or
28 (at your option) any later version.
29
30 circom is distributed in the hope that it will be useful, but WITHOUT
31 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
32 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
33 License for more details.
34
35 You should have received a copy of the GNU General Public License
36 along with circom. If not, see <https://www.gnu.org/licenses/>.
37*/
38
39// --> Assignation without constraint
40// <-- Assignation without constraint
41// === Constraint
42// <== Assignation with constraint
43// ==> Assignation with constraint
44// All variables are members of the field F[p]
45// https://github.com/zcash-hackworks/sapling-crypto
46// https://github.com/ebfull/bellman
47
48/*
49function log2(a) {
50 if (a==0) {
51 return 0;
52 }
53 let n = 1;
54 let r = 1;
55 while (n<a) {
56 r++;
57 n *= 2;
58 }
59 return r;
60}
61*/
62
63template EscalarProduct(w) {
64 signal input in1[w];
65 signal input in2[w];
66 signal output out;
67 signal aux[w];
68 var lc = 0;
69 for (var i=0; i<w; i++) {
70 aux[i] <== in1[i]*in2[i];
71 lc = lc + aux[i];
72 }
73 out <== lc;
74}
75
76template Decoder(w) {
77 signal input inp;
78 signal output out[w];
79 signal output success;
80 var lc=0;
81
82 for (var i=0; i<w; i++) {
83 out[i] <-- (inp == i) ? 1 : 0;
84 out[i] * (inp-i) === 0;
85 lc = lc + out[i];
86 }
87
88 lc ==> success;
89 success * (success -1) === 0;
90}
91
92
93template Multiplexer(wIn, nIn) {
94 signal input inp[nIn][wIn];
95 signal input sel;
96 signal output out[wIn];
97 component dec = Decoder(nIn);
98 component ep[wIn];
99
100 for (var k=0; k<wIn; k++) {
101 ep[k] = EscalarProduct(nIn);
102 }
103
104 sel ==> dec.inp;
105 for (var j=0; j<wIn; j++) {
106 for (var k=0; k<nIn; k++) {
107 inp[k][j] ==> ep[j].in1[k];
108 dec.out[k] ==> ep[j].in2[k];
109 }
110 ep[j].out ==> out[j];
111 }
112 dec.success === 1;
113}