starkshield 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +101 -0
- package/bin/circom +0 -0
- package/bin/cli.js +36 -0
- package/bin/index.js +13 -0
- package/circomlib/.vscode/launch.json +63 -0
- package/circomlib/README.md +18 -0
- package/circomlib/circuits/README.md +830 -0
- package/circomlib/circuits/aliascheck.circom +33 -0
- package/circomlib/circuits/babyjub.circom +107 -0
- package/circomlib/circuits/binsub.circom +74 -0
- package/circomlib/circuits/binsum.circom +101 -0
- package/circomlib/circuits/bitify.circom +106 -0
- package/circomlib/circuits/comparators.circom +141 -0
- package/circomlib/circuits/compconstant.circom +74 -0
- package/circomlib/circuits/eddsa.circom +139 -0
- package/circomlib/circuits/eddsamimc.circom +124 -0
- package/circomlib/circuits/eddsamimcsponge.circom +124 -0
- package/circomlib/circuits/eddsaposeidon.circom +123 -0
- package/circomlib/circuits/escalarmul.circom +166 -0
- package/circomlib/circuits/escalarmulany.circom +197 -0
- package/circomlib/circuits/escalarmulfix.circom +299 -0
- package/circomlib/circuits/escalarmulw4table.circom +52 -0
- package/circomlib/circuits/gates.circom +96 -0
- package/circomlib/circuits/mimc.circom +156 -0
- package/circomlib/circuits/mimcsponge.circom +293 -0
- package/circomlib/circuits/montgomery.circom +142 -0
- package/circomlib/circuits/multiplexer.circom +115 -0
- package/circomlib/circuits/mux1.circom +48 -0
- package/circomlib/circuits/mux2.circom +63 -0
- package/circomlib/circuits/mux3.circom +75 -0
- package/circomlib/circuits/mux4.circom +119 -0
- package/circomlib/circuits/pedersen.circom +257 -0
- package/circomlib/circuits/pedersen_old.circom +68 -0
- package/circomlib/circuits/pointbits.circom +164 -0
- package/circomlib/circuits/poseidon.circom +208 -0
- package/circomlib/circuits/poseidon_constants.circom +24959 -0
- package/circomlib/circuits/poseidon_constants_old.circom +252 -0
- package/circomlib/circuits/poseidon_old.circom +97 -0
- package/circomlib/circuits/sha256/ch.circom +47 -0
- package/circomlib/circuits/sha256/constants.circom +53 -0
- package/circomlib/circuits/sha256/main.circom +35 -0
- package/circomlib/circuits/sha256/maj.circom +45 -0
- package/circomlib/circuits/sha256/rotate.circom +28 -0
- package/circomlib/circuits/sha256/sha256.circom +81 -0
- package/circomlib/circuits/sha256/sha256_2.circom +91 -0
- package/circomlib/circuits/sha256/sha256compression.circom +166 -0
- package/circomlib/circuits/sha256/sha256compression_function.circom +112 -0
- package/circomlib/circuits/sha256/shift.circom +33 -0
- package/circomlib/circuits/sha256/sigma.circom +77 -0
- package/circomlib/circuits/sha256/sigmaplus.circom +50 -0
- package/circomlib/circuits/sha256/t1.circom +58 -0
- package/circomlib/circuits/sha256/t2.circom +51 -0
- package/circomlib/circuits/sha256/xor3.circom +45 -0
- package/circomlib/circuits/sign.circom +36 -0
- package/circomlib/circuits/smt/smthash_mimc.circom +58 -0
- package/circomlib/circuits/smt/smthash_poseidon.circom +57 -0
- package/circomlib/circuits/smt/smtlevins.circom +103 -0
- package/circomlib/circuits/smt/smtprocessor.circom +261 -0
- package/circomlib/circuits/smt/smtprocessorlevel.circom +95 -0
- package/circomlib/circuits/smt/smtprocessorsm.circom +165 -0
- package/circomlib/circuits/smt/smtverifier.circom +138 -0
- package/circomlib/circuits/smt/smtverifierlevel.circom +71 -0
- package/circomlib/circuits/smt/smtverifiersm.circom +106 -0
- package/circomlib/circuits/switcher.circom +42 -0
- package/circomlib/doc/root_transfer.monopic +0 -0
- package/circomlib/doc/smt_diagram_0.monopic +0 -0
- package/circomlib/doc/smt_diagram_1.monopic +0 -0
- package/circomlib/doc/smt_hash.monopic +0 -0
- package/circomlib/doc/smt_levins.monopic +0 -0
- package/circomlib/doc/smt_sm.monopic +0 -0
- package/circomlib/doc/smt_verifier_sm.monopic +0 -0
- package/circomlib/doc/voting.monopic +0 -0
- package/circomlib/doc/window.monopic +0 -0
- package/circomlib/doc/window_chain.monopic +0 -0
- package/circomlib/index.js +2 -0
- package/circomlib/package.json +33 -0
- package/circomlib/test/aliascheck.js +77 -0
- package/circomlib/test/babyjub.js +118 -0
- package/circomlib/test/binsub.js +52 -0
- package/circomlib/test/binsum.js +38 -0
- package/circomlib/test/circuits/aliascheck_test.circom +4 -0
- package/circomlib/test/circuits/babyadd_tester.circom +4 -0
- package/circomlib/test/circuits/babycheck_test.circom +4 -0
- package/circomlib/test/circuits/babypbk_test.circom +4 -0
- package/circomlib/test/circuits/binsub_test.circom +33 -0
- package/circomlib/test/circuits/constants_test.circom +20 -0
- package/circomlib/test/circuits/eddsa_test.circom +5 -0
- package/circomlib/test/circuits/eddsamimc_test.circom +5 -0
- package/circomlib/test/circuits/eddsaposeidon_test.circom +5 -0
- package/circomlib/test/circuits/edwards2montgomery.circom +5 -0
- package/circomlib/test/circuits/escalarmul_min_test.circom +27 -0
- package/circomlib/test/circuits/escalarmul_test.circom +33 -0
- package/circomlib/test/circuits/escalarmul_test_min.circom +28 -0
- package/circomlib/test/circuits/escalarmulany_test.circom +30 -0
- package/circomlib/test/circuits/escalarmulfix_test.circom +31 -0
- package/circomlib/test/circuits/escalarmulw4table.circom +20 -0
- package/circomlib/test/circuits/escalarmulw4table_test.circom +19 -0
- package/circomlib/test/circuits/escalarmulw4table_test3.circom +19 -0
- package/circomlib/test/circuits/greatereqthan.circom +5 -0
- package/circomlib/test/circuits/greaterthan.circom +5 -0
- package/circomlib/test/circuits/isequal.circom +5 -0
- package/circomlib/test/circuits/iszero.circom +5 -0
- package/circomlib/test/circuits/lesseqthan.circom +5 -0
- package/circomlib/test/circuits/lessthan.circom +5 -0
- package/circomlib/test/circuits/mimc_sponge_hash_test.circom +5 -0
- package/circomlib/test/circuits/mimc_sponge_test.circom +5 -0
- package/circomlib/test/circuits/mimc_test.circom +5 -0
- package/circomlib/test/circuits/montgomery2edwards.circom +5 -0
- package/circomlib/test/circuits/montgomeryadd.circom +5 -0
- package/circomlib/test/circuits/montgomerydouble.circom +5 -0
- package/circomlib/test/circuits/mux1_1.circom +33 -0
- package/circomlib/test/circuits/mux2_1.circom +37 -0
- package/circomlib/test/circuits/mux3_1.circom +41 -0
- package/circomlib/test/circuits/mux4_1.circom +56 -0
- package/circomlib/test/circuits/pedersen2_test.circom +34 -0
- package/circomlib/test/circuits/pedersen_test.circom +31 -0
- package/circomlib/test/circuits/pointbits_loopback.circom +25 -0
- package/circomlib/test/circuits/poseidon3_test.circom +5 -0
- package/circomlib/test/circuits/poseidon6_test.circom +5 -0
- package/circomlib/test/circuits/poseidonex_test.circom +5 -0
- package/circomlib/test/circuits/sha256_2_test.circom +17 -0
- package/circomlib/test/circuits/sha256_test448.circom +5 -0
- package/circomlib/test/circuits/sha256_test512.circom +5 -0
- package/circomlib/test/circuits/sign_test.circom +5 -0
- package/circomlib/test/circuits/smtprocessor10_test.circom +5 -0
- package/circomlib/test/circuits/smtverifier10_test.circom +5 -0
- package/circomlib/test/circuits/sum_test.circom +33 -0
- package/circomlib/test/comparators.js +187 -0
- package/circomlib/test/eddsa.js +75 -0
- package/circomlib/test/eddsamimc.js +102 -0
- package/circomlib/test/eddsaposeidon.js +103 -0
- package/circomlib/test/escalarmul.js +121 -0
- package/circomlib/test/escalarmulany.js +51 -0
- package/circomlib/test/escalarmulfix.js +95 -0
- package/circomlib/test/helpers/printsignal.js +22 -0
- package/circomlib/test/helpers/sha256.js +178 -0
- package/circomlib/test/mimccircuit.js +27 -0
- package/circomlib/test/mimcspongecircuit.js +47 -0
- package/circomlib/test/montgomery.js +101 -0
- package/circomlib/test/multiplexer.js +101 -0
- package/circomlib/test/pedersen.js +83 -0
- package/circomlib/test/pedersen2.js +56 -0
- package/circomlib/test/point2bits.js +30 -0
- package/circomlib/test/poseidoncircuit.js +80 -0
- package/circomlib/test/sha256.js +118 -0
- package/circomlib/test/sign.js +82 -0
- package/circomlib/test/smtprocessor.js +219 -0
- package/circomlib/test/smtverifier.js +141 -0
- package/lib/compile.js +82 -0
- package/lib/deploy.js +391 -0
- package/lib/test.js +47 -0
- package/lib/verify.js +153 -0
- package/package.json +43 -0
- package/pot12_0000.ptau +0 -0
- package/pot12_0001.ptau +0 -0
- package/ptau/pot12_final.ptau +0 -0
|
@@ -0,0 +1,197 @@
|
|
|
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
|
+
pragma circom 2.0.0;
|
|
20
|
+
|
|
21
|
+
include "montgomery.circom";
|
|
22
|
+
include "babyjub.circom";
|
|
23
|
+
include "comparators.circom";
|
|
24
|
+
|
|
25
|
+
template Multiplexor2() {
|
|
26
|
+
signal input sel;
|
|
27
|
+
signal input in[2][2];
|
|
28
|
+
signal output out[2];
|
|
29
|
+
|
|
30
|
+
out[0] <== (in[1][0] - in[0][0])*sel + in[0][0];
|
|
31
|
+
out[1] <== (in[1][1] - in[0][1])*sel + in[0][1];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
template BitElementMulAny() {
|
|
35
|
+
signal input sel;
|
|
36
|
+
signal input dblIn[2];
|
|
37
|
+
signal input addIn[2];
|
|
38
|
+
signal output dblOut[2];
|
|
39
|
+
signal output addOut[2];
|
|
40
|
+
|
|
41
|
+
component doubler = MontgomeryDouble();
|
|
42
|
+
component adder = MontgomeryAdd();
|
|
43
|
+
component selector = Multiplexor2();
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
sel ==> selector.sel;
|
|
47
|
+
|
|
48
|
+
dblIn[0] ==> doubler.in[0];
|
|
49
|
+
dblIn[1] ==> doubler.in[1];
|
|
50
|
+
doubler.out[0] ==> adder.in1[0];
|
|
51
|
+
doubler.out[1] ==> adder.in1[1];
|
|
52
|
+
addIn[0] ==> adder.in2[0];
|
|
53
|
+
addIn[1] ==> adder.in2[1];
|
|
54
|
+
addIn[0] ==> selector.in[0][0];
|
|
55
|
+
addIn[1] ==> selector.in[0][1];
|
|
56
|
+
adder.out[0] ==> selector.in[1][0];
|
|
57
|
+
adder.out[1] ==> selector.in[1][1];
|
|
58
|
+
|
|
59
|
+
doubler.out[0] ==> dblOut[0];
|
|
60
|
+
doubler.out[1] ==> dblOut[1];
|
|
61
|
+
selector.out[0] ==> addOut[0];
|
|
62
|
+
selector.out[1] ==> addOut[1];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// p is montgomery point
|
|
66
|
+
// n must be <= 248
|
|
67
|
+
// returns out in twisted edwards
|
|
68
|
+
// Double is in montgomery to be linked;
|
|
69
|
+
|
|
70
|
+
template SegmentMulAny(n) {
|
|
71
|
+
signal input e[n];
|
|
72
|
+
signal input p[2];
|
|
73
|
+
signal output out[2];
|
|
74
|
+
signal output dbl[2];
|
|
75
|
+
|
|
76
|
+
component bits[n-1];
|
|
77
|
+
|
|
78
|
+
component e2m = Edwards2Montgomery();
|
|
79
|
+
|
|
80
|
+
p[0] ==> e2m.in[0];
|
|
81
|
+
p[1] ==> e2m.in[1];
|
|
82
|
+
|
|
83
|
+
var i;
|
|
84
|
+
|
|
85
|
+
bits[0] = BitElementMulAny();
|
|
86
|
+
e2m.out[0] ==> bits[0].dblIn[0];
|
|
87
|
+
e2m.out[1] ==> bits[0].dblIn[1];
|
|
88
|
+
e2m.out[0] ==> bits[0].addIn[0];
|
|
89
|
+
e2m.out[1] ==> bits[0].addIn[1];
|
|
90
|
+
e[1] ==> bits[0].sel;
|
|
91
|
+
|
|
92
|
+
for (i=1; i<n-1; i++) {
|
|
93
|
+
bits[i] = BitElementMulAny();
|
|
94
|
+
|
|
95
|
+
bits[i-1].dblOut[0] ==> bits[i].dblIn[0];
|
|
96
|
+
bits[i-1].dblOut[1] ==> bits[i].dblIn[1];
|
|
97
|
+
bits[i-1].addOut[0] ==> bits[i].addIn[0];
|
|
98
|
+
bits[i-1].addOut[1] ==> bits[i].addIn[1];
|
|
99
|
+
e[i+1] ==> bits[i].sel;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
bits[n-2].dblOut[0] ==> dbl[0];
|
|
103
|
+
bits[n-2].dblOut[1] ==> dbl[1];
|
|
104
|
+
|
|
105
|
+
component m2e = Montgomery2Edwards();
|
|
106
|
+
|
|
107
|
+
bits[n-2].addOut[0] ==> m2e.in[0];
|
|
108
|
+
bits[n-2].addOut[1] ==> m2e.in[1];
|
|
109
|
+
|
|
110
|
+
component eadder = BabyAdd();
|
|
111
|
+
|
|
112
|
+
m2e.out[0] ==> eadder.x1;
|
|
113
|
+
m2e.out[1] ==> eadder.y1;
|
|
114
|
+
-p[0] ==> eadder.x2;
|
|
115
|
+
p[1] ==> eadder.y2;
|
|
116
|
+
|
|
117
|
+
component lastSel = Multiplexor2();
|
|
118
|
+
|
|
119
|
+
e[0] ==> lastSel.sel;
|
|
120
|
+
eadder.xout ==> lastSel.in[0][0];
|
|
121
|
+
eadder.yout ==> lastSel.in[0][1];
|
|
122
|
+
m2e.out[0] ==> lastSel.in[1][0];
|
|
123
|
+
m2e.out[1] ==> lastSel.in[1][1];
|
|
124
|
+
|
|
125
|
+
lastSel.out[0] ==> out[0];
|
|
126
|
+
lastSel.out[1] ==> out[1];
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// This function assumes that p is in the subgroup and it is different to 0
|
|
130
|
+
|
|
131
|
+
template EscalarMulAny(n) {
|
|
132
|
+
signal input e[n]; // Input in binary format
|
|
133
|
+
signal input p[2]; // Point (Twisted format)
|
|
134
|
+
signal output out[2]; // Point (Twisted format)
|
|
135
|
+
|
|
136
|
+
var nsegments = (n-1)\148 +1;
|
|
137
|
+
var nlastsegment = n - (nsegments-1)*148;
|
|
138
|
+
|
|
139
|
+
component segments[nsegments];
|
|
140
|
+
component doublers[nsegments-1];
|
|
141
|
+
component m2e[nsegments-1];
|
|
142
|
+
component adders[nsegments-1];
|
|
143
|
+
component zeropoint = IsZero();
|
|
144
|
+
zeropoint.in <== p[0];
|
|
145
|
+
|
|
146
|
+
var s;
|
|
147
|
+
var i;
|
|
148
|
+
var nseg;
|
|
149
|
+
|
|
150
|
+
for (s=0; s<nsegments; s++) {
|
|
151
|
+
|
|
152
|
+
nseg = (s < nsegments-1) ? 148 : nlastsegment;
|
|
153
|
+
|
|
154
|
+
segments[s] = SegmentMulAny(nseg);
|
|
155
|
+
|
|
156
|
+
for (i=0; i<nseg; i++) {
|
|
157
|
+
e[s*148+i] ==> segments[s].e[i];
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (s==0) {
|
|
161
|
+
// force G8 point if input point is zero
|
|
162
|
+
segments[s].p[0] <== p[0] + (5299619240641551281634865583518297030282874472190772894086521144482721001553 - p[0])*zeropoint.out;
|
|
163
|
+
segments[s].p[1] <== p[1] + (16950150798460657717958625567821834550301663161624707787222815936182638968203 - p[1])*zeropoint.out;
|
|
164
|
+
} else {
|
|
165
|
+
doublers[s-1] = MontgomeryDouble();
|
|
166
|
+
m2e[s-1] = Montgomery2Edwards();
|
|
167
|
+
adders[s-1] = BabyAdd();
|
|
168
|
+
|
|
169
|
+
segments[s-1].dbl[0] ==> doublers[s-1].in[0];
|
|
170
|
+
segments[s-1].dbl[1] ==> doublers[s-1].in[1];
|
|
171
|
+
|
|
172
|
+
doublers[s-1].out[0] ==> m2e[s-1].in[0];
|
|
173
|
+
doublers[s-1].out[1] ==> m2e[s-1].in[1];
|
|
174
|
+
|
|
175
|
+
m2e[s-1].out[0] ==> segments[s].p[0];
|
|
176
|
+
m2e[s-1].out[1] ==> segments[s].p[1];
|
|
177
|
+
|
|
178
|
+
if (s==1) {
|
|
179
|
+
segments[s-1].out[0] ==> adders[s-1].x1;
|
|
180
|
+
segments[s-1].out[1] ==> adders[s-1].y1;
|
|
181
|
+
} else {
|
|
182
|
+
adders[s-2].xout ==> adders[s-1].x1;
|
|
183
|
+
adders[s-2].yout ==> adders[s-1].y1;
|
|
184
|
+
}
|
|
185
|
+
segments[s].out[0] ==> adders[s-1].x2;
|
|
186
|
+
segments[s].out[1] ==> adders[s-1].y2;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (nsegments == 1) {
|
|
191
|
+
segments[0].out[0]*(1-zeropoint.out) ==> out[0];
|
|
192
|
+
segments[0].out[1]+(1-segments[0].out[1])*zeropoint.out ==> out[1];
|
|
193
|
+
} else {
|
|
194
|
+
adders[nsegments-2].xout*(1-zeropoint.out) ==> out[0];
|
|
195
|
+
adders[nsegments-2].yout+(1-adders[nsegments-2].yout)*zeropoint.out ==> out[1];
|
|
196
|
+
}
|
|
197
|
+
}
|
|
@@ -0,0 +1,299 @@
|
|
|
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
|
+
pragma circom 2.0.0;
|
|
20
|
+
|
|
21
|
+
include "mux3.circom";
|
|
22
|
+
include "montgomery.circom";
|
|
23
|
+
include "babyjub.circom";
|
|
24
|
+
|
|
25
|
+
/*
|
|
26
|
+
Window of 3 elements, it calculates
|
|
27
|
+
out = base + base*in[0] + 2*base*in[1] + 4*base*in[2]
|
|
28
|
+
out4 = 4*base
|
|
29
|
+
|
|
30
|
+
The result should be compensated.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/*
|
|
34
|
+
|
|
35
|
+
The scalar is s = a0 + a1*2^3 + a2*2^6 + ...... + a81*2^243
|
|
36
|
+
First We calculate Q = B + 2^3*B + 2^6*B + ......... + 2^246*B
|
|
37
|
+
|
|
38
|
+
Then we calculate S1 = 2*2^246*B + (1 + a0)*B + (2^3 + a1)*B + .....+ (2^243 + a81)*B
|
|
39
|
+
|
|
40
|
+
And Finaly we compute the result: RES = SQ - Q
|
|
41
|
+
|
|
42
|
+
As you can see the input of the adders cannot be equal nor zero, except for the last
|
|
43
|
+
substraction that it's done in montgomery.
|
|
44
|
+
|
|
45
|
+
A good way to see it is that the accumulator input of the adder >= 2^247*B and the other input
|
|
46
|
+
is the output of the windows that it's going to be <= 2^246*B
|
|
47
|
+
*/
|
|
48
|
+
template WindowMulFix() {
|
|
49
|
+
signal input in[3];
|
|
50
|
+
signal input base[2];
|
|
51
|
+
signal output out[2];
|
|
52
|
+
signal output out8[2]; // Returns 8*Base (To be linked)
|
|
53
|
+
|
|
54
|
+
component mux = MultiMux3(2);
|
|
55
|
+
|
|
56
|
+
mux.s[0] <== in[0];
|
|
57
|
+
mux.s[1] <== in[1];
|
|
58
|
+
mux.s[2] <== in[2];
|
|
59
|
+
|
|
60
|
+
component dbl2 = MontgomeryDouble();
|
|
61
|
+
component adr3 = MontgomeryAdd();
|
|
62
|
+
component adr4 = MontgomeryAdd();
|
|
63
|
+
component adr5 = MontgomeryAdd();
|
|
64
|
+
component adr6 = MontgomeryAdd();
|
|
65
|
+
component adr7 = MontgomeryAdd();
|
|
66
|
+
component adr8 = MontgomeryAdd();
|
|
67
|
+
|
|
68
|
+
// in[0] -> 1*BASE
|
|
69
|
+
|
|
70
|
+
mux.c[0][0] <== base[0];
|
|
71
|
+
mux.c[1][0] <== base[1];
|
|
72
|
+
|
|
73
|
+
// in[1] -> 2*BASE
|
|
74
|
+
dbl2.in[0] <== base[0];
|
|
75
|
+
dbl2.in[1] <== base[1];
|
|
76
|
+
mux.c[0][1] <== dbl2.out[0];
|
|
77
|
+
mux.c[1][1] <== dbl2.out[1];
|
|
78
|
+
|
|
79
|
+
// in[2] -> 3*BASE
|
|
80
|
+
adr3.in1[0] <== base[0];
|
|
81
|
+
adr3.in1[1] <== base[1];
|
|
82
|
+
adr3.in2[0] <== dbl2.out[0];
|
|
83
|
+
adr3.in2[1] <== dbl2.out[1];
|
|
84
|
+
mux.c[0][2] <== adr3.out[0];
|
|
85
|
+
mux.c[1][2] <== adr3.out[1];
|
|
86
|
+
|
|
87
|
+
// in[3] -> 4*BASE
|
|
88
|
+
adr4.in1[0] <== base[0];
|
|
89
|
+
adr4.in1[1] <== base[1];
|
|
90
|
+
adr4.in2[0] <== adr3.out[0];
|
|
91
|
+
adr4.in2[1] <== adr3.out[1];
|
|
92
|
+
mux.c[0][3] <== adr4.out[0];
|
|
93
|
+
mux.c[1][3] <== adr4.out[1];
|
|
94
|
+
|
|
95
|
+
// in[4] -> 5*BASE
|
|
96
|
+
adr5.in1[0] <== base[0];
|
|
97
|
+
adr5.in1[1] <== base[1];
|
|
98
|
+
adr5.in2[0] <== adr4.out[0];
|
|
99
|
+
adr5.in2[1] <== adr4.out[1];
|
|
100
|
+
mux.c[0][4] <== adr5.out[0];
|
|
101
|
+
mux.c[1][4] <== adr5.out[1];
|
|
102
|
+
|
|
103
|
+
// in[5] -> 6*BASE
|
|
104
|
+
adr6.in1[0] <== base[0];
|
|
105
|
+
adr6.in1[1] <== base[1];
|
|
106
|
+
adr6.in2[0] <== adr5.out[0];
|
|
107
|
+
adr6.in2[1] <== adr5.out[1];
|
|
108
|
+
mux.c[0][5] <== adr6.out[0];
|
|
109
|
+
mux.c[1][5] <== adr6.out[1];
|
|
110
|
+
|
|
111
|
+
// in[6] -> 7*BASE
|
|
112
|
+
adr7.in1[0] <== base[0];
|
|
113
|
+
adr7.in1[1] <== base[1];
|
|
114
|
+
adr7.in2[0] <== adr6.out[0];
|
|
115
|
+
adr7.in2[1] <== adr6.out[1];
|
|
116
|
+
mux.c[0][6] <== adr7.out[0];
|
|
117
|
+
mux.c[1][6] <== adr7.out[1];
|
|
118
|
+
|
|
119
|
+
// in[7] -> 8*BASE
|
|
120
|
+
adr8.in1[0] <== base[0];
|
|
121
|
+
adr8.in1[1] <== base[1];
|
|
122
|
+
adr8.in2[0] <== adr7.out[0];
|
|
123
|
+
adr8.in2[1] <== adr7.out[1];
|
|
124
|
+
mux.c[0][7] <== adr8.out[0];
|
|
125
|
+
mux.c[1][7] <== adr8.out[1];
|
|
126
|
+
|
|
127
|
+
out8[0] <== adr8.out[0];
|
|
128
|
+
out8[1] <== adr8.out[1];
|
|
129
|
+
|
|
130
|
+
out[0] <== mux.out[0];
|
|
131
|
+
out[1] <== mux.out[1];
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
/*
|
|
136
|
+
This component does a multiplication of a escalar times a fix base
|
|
137
|
+
Signals:
|
|
138
|
+
e: The scalar in bits
|
|
139
|
+
base: the base point in edwards format
|
|
140
|
+
out: The result
|
|
141
|
+
dbl: Point in Edwards to be linked to the next segment.
|
|
142
|
+
*/
|
|
143
|
+
|
|
144
|
+
template SegmentMulFix(nWindows) {
|
|
145
|
+
signal input e[nWindows*3];
|
|
146
|
+
signal input base[2];
|
|
147
|
+
signal output out[2];
|
|
148
|
+
signal output dbl[2];
|
|
149
|
+
|
|
150
|
+
var i;
|
|
151
|
+
var j;
|
|
152
|
+
|
|
153
|
+
// Convert the base to montgomery
|
|
154
|
+
|
|
155
|
+
component e2m = Edwards2Montgomery();
|
|
156
|
+
e2m.in[0] <== base[0];
|
|
157
|
+
e2m.in[1] <== base[1];
|
|
158
|
+
|
|
159
|
+
component windows[nWindows];
|
|
160
|
+
component adders[nWindows];
|
|
161
|
+
component cadders[nWindows];
|
|
162
|
+
|
|
163
|
+
// In the last step we add an extra doubler so that numbers do not match.
|
|
164
|
+
component dblLast = MontgomeryDouble();
|
|
165
|
+
|
|
166
|
+
for (i=0; i<nWindows; i++) {
|
|
167
|
+
windows[i] = WindowMulFix();
|
|
168
|
+
cadders[i] = MontgomeryAdd();
|
|
169
|
+
if (i==0) {
|
|
170
|
+
windows[i].base[0] <== e2m.out[0];
|
|
171
|
+
windows[i].base[1] <== e2m.out[1];
|
|
172
|
+
cadders[i].in1[0] <== e2m.out[0];
|
|
173
|
+
cadders[i].in1[1] <== e2m.out[1];
|
|
174
|
+
} else {
|
|
175
|
+
windows[i].base[0] <== windows[i-1].out8[0];
|
|
176
|
+
windows[i].base[1] <== windows[i-1].out8[1];
|
|
177
|
+
cadders[i].in1[0] <== cadders[i-1].out[0];
|
|
178
|
+
cadders[i].in1[1] <== cadders[i-1].out[1];
|
|
179
|
+
}
|
|
180
|
+
for (j=0; j<3; j++) {
|
|
181
|
+
windows[i].in[j] <== e[3*i+j];
|
|
182
|
+
}
|
|
183
|
+
if (i<nWindows-1) {
|
|
184
|
+
cadders[i].in2[0] <== windows[i].out8[0];
|
|
185
|
+
cadders[i].in2[1] <== windows[i].out8[1];
|
|
186
|
+
} else {
|
|
187
|
+
dblLast.in[0] <== windows[i].out8[0];
|
|
188
|
+
dblLast.in[1] <== windows[i].out8[1];
|
|
189
|
+
cadders[i].in2[0] <== dblLast.out[0];
|
|
190
|
+
cadders[i].in2[1] <== dblLast.out[1];
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
for (i=0; i<nWindows; i++) {
|
|
195
|
+
adders[i] = MontgomeryAdd();
|
|
196
|
+
if (i==0) {
|
|
197
|
+
adders[i].in1[0] <== dblLast.out[0];
|
|
198
|
+
adders[i].in1[1] <== dblLast.out[1];
|
|
199
|
+
} else {
|
|
200
|
+
adders[i].in1[0] <== adders[i-1].out[0];
|
|
201
|
+
adders[i].in1[1] <== adders[i-1].out[1];
|
|
202
|
+
}
|
|
203
|
+
adders[i].in2[0] <== windows[i].out[0];
|
|
204
|
+
adders[i].in2[1] <== windows[i].out[1];
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
component m2e = Montgomery2Edwards();
|
|
208
|
+
component cm2e = Montgomery2Edwards();
|
|
209
|
+
|
|
210
|
+
m2e.in[0] <== adders[nWindows-1].out[0];
|
|
211
|
+
m2e.in[1] <== adders[nWindows-1].out[1];
|
|
212
|
+
cm2e.in[0] <== cadders[nWindows-1].out[0];
|
|
213
|
+
cm2e.in[1] <== cadders[nWindows-1].out[1];
|
|
214
|
+
|
|
215
|
+
component cAdd = BabyAdd();
|
|
216
|
+
cAdd.x1 <== m2e.out[0];
|
|
217
|
+
cAdd.y1 <== m2e.out[1];
|
|
218
|
+
cAdd.x2 <== -cm2e.out[0];
|
|
219
|
+
cAdd.y2 <== cm2e.out[1];
|
|
220
|
+
|
|
221
|
+
cAdd.xout ==> out[0];
|
|
222
|
+
cAdd.yout ==> out[1];
|
|
223
|
+
|
|
224
|
+
windows[nWindows-1].out8[0] ==> dbl[0];
|
|
225
|
+
windows[nWindows-1].out8[1] ==> dbl[1];
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
/*
|
|
230
|
+
This component multiplies a escalar times a fixed point BASE (twisted edwards format)
|
|
231
|
+
Signals
|
|
232
|
+
e: The escalar in binary format
|
|
233
|
+
out: The output point in twisted edwards
|
|
234
|
+
*/
|
|
235
|
+
template EscalarMulFix(n, BASE) {
|
|
236
|
+
signal input e[n]; // Input in binary format
|
|
237
|
+
signal output out[2]; // Point (Twisted format)
|
|
238
|
+
|
|
239
|
+
var nsegments = (n-1)\246 +1; // 249 probably would work. But I'm not sure and for security I keep 246
|
|
240
|
+
var nlastsegment = n - (nsegments-1)*249;
|
|
241
|
+
|
|
242
|
+
component segments[nsegments];
|
|
243
|
+
|
|
244
|
+
component m2e[nsegments-1];
|
|
245
|
+
component adders[nsegments-1];
|
|
246
|
+
|
|
247
|
+
var s;
|
|
248
|
+
var i;
|
|
249
|
+
var nseg;
|
|
250
|
+
var nWindows;
|
|
251
|
+
|
|
252
|
+
for (s=0; s<nsegments; s++) {
|
|
253
|
+
|
|
254
|
+
nseg = (s < nsegments-1) ? 249 : nlastsegment;
|
|
255
|
+
nWindows = ((nseg - 1)\3)+1;
|
|
256
|
+
|
|
257
|
+
segments[s] = SegmentMulFix(nWindows);
|
|
258
|
+
|
|
259
|
+
for (i=0; i<nseg; i++) {
|
|
260
|
+
segments[s].e[i] <== e[s*249+i];
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
for (i = nseg; i<nWindows*3; i++) {
|
|
264
|
+
segments[s].e[i] <== 0;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (s==0) {
|
|
268
|
+
segments[s].base[0] <== BASE[0];
|
|
269
|
+
segments[s].base[1] <== BASE[1];
|
|
270
|
+
} else {
|
|
271
|
+
m2e[s-1] = Montgomery2Edwards();
|
|
272
|
+
adders[s-1] = BabyAdd();
|
|
273
|
+
|
|
274
|
+
segments[s-1].dbl[0] ==> m2e[s-1].in[0];
|
|
275
|
+
segments[s-1].dbl[1] ==> m2e[s-1].in[1];
|
|
276
|
+
|
|
277
|
+
m2e[s-1].out[0] ==> segments[s].base[0];
|
|
278
|
+
m2e[s-1].out[1] ==> segments[s].base[1];
|
|
279
|
+
|
|
280
|
+
if (s==1) {
|
|
281
|
+
segments[s-1].out[0] ==> adders[s-1].x1;
|
|
282
|
+
segments[s-1].out[1] ==> adders[s-1].y1;
|
|
283
|
+
} else {
|
|
284
|
+
adders[s-2].xout ==> adders[s-1].x1;
|
|
285
|
+
adders[s-2].yout ==> adders[s-1].y1;
|
|
286
|
+
}
|
|
287
|
+
segments[s].out[0] ==> adders[s-1].x2;
|
|
288
|
+
segments[s].out[1] ==> adders[s-1].y2;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
if (nsegments == 1) {
|
|
293
|
+
segments[0].out[0] ==> out[0];
|
|
294
|
+
segments[0].out[1] ==> out[1];
|
|
295
|
+
} else {
|
|
296
|
+
adders[nsegments-2].xout ==> out[0];
|
|
297
|
+
adders[nsegments-2].yout ==> out[1];
|
|
298
|
+
}
|
|
299
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
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
|
+
pragma circom 2.0.0;
|
|
20
|
+
|
|
21
|
+
function pointAdd(x1,y1,x2,y2) {
|
|
22
|
+
var a = 168700;
|
|
23
|
+
var d = 168696;
|
|
24
|
+
|
|
25
|
+
var res[2];
|
|
26
|
+
res[0] = (x1*y2 + y1*x2) / (1 + d*x1*x2*y1*y2);
|
|
27
|
+
res[1] = (y1*y2 - a*x1*x2) / (1 - d*x1*x2*y1*y2);
|
|
28
|
+
return res;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function EscalarMulW4Table(base, k) {
|
|
32
|
+
var out[16][2];
|
|
33
|
+
|
|
34
|
+
var i;
|
|
35
|
+
var p[2];
|
|
36
|
+
|
|
37
|
+
var dbl[2] = base;
|
|
38
|
+
|
|
39
|
+
for (i=0; i<k*4; i++) {
|
|
40
|
+
dbl = pointAdd(dbl[0], dbl[1], dbl[0], dbl[1]);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
out[0][0] = 0;
|
|
44
|
+
out[0][1] = 1;
|
|
45
|
+
for (i=1; i<16; i++) {
|
|
46
|
+
p = pointAdd(out[i-1][0], out[i-1][1], dbl[0], dbl[1]);
|
|
47
|
+
out[i][0] = p[0];
|
|
48
|
+
out[i][1] = p[1];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return out;
|
|
52
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
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
|
+
pragma circom 2.0.0;
|
|
20
|
+
|
|
21
|
+
template XOR() {
|
|
22
|
+
signal input a;
|
|
23
|
+
signal input b;
|
|
24
|
+
signal output out;
|
|
25
|
+
|
|
26
|
+
out <== a + b - 2*a*b;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
template AND() {
|
|
30
|
+
signal input a;
|
|
31
|
+
signal input b;
|
|
32
|
+
signal output out;
|
|
33
|
+
|
|
34
|
+
out <== a*b;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
template OR() {
|
|
38
|
+
signal input a;
|
|
39
|
+
signal input b;
|
|
40
|
+
signal output out;
|
|
41
|
+
|
|
42
|
+
out <== a + b - a*b;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
template NOT() {
|
|
46
|
+
signal input in;
|
|
47
|
+
signal output out;
|
|
48
|
+
|
|
49
|
+
out <== 1 + in - 2*in;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
template NAND() {
|
|
53
|
+
signal input a;
|
|
54
|
+
signal input b;
|
|
55
|
+
signal output out;
|
|
56
|
+
|
|
57
|
+
out <== 1 - a*b;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
template NOR() {
|
|
61
|
+
signal input a;
|
|
62
|
+
signal input b;
|
|
63
|
+
signal output out;
|
|
64
|
+
|
|
65
|
+
out <== a*b + 1 - a - b;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
template MultiAND(n) {
|
|
69
|
+
signal input in[n];
|
|
70
|
+
signal output out;
|
|
71
|
+
component and1;
|
|
72
|
+
component and2;
|
|
73
|
+
component ands[2];
|
|
74
|
+
if (n==1) {
|
|
75
|
+
out <== in[0];
|
|
76
|
+
} else if (n==2) {
|
|
77
|
+
and1 = AND();
|
|
78
|
+
and1.a <== in[0];
|
|
79
|
+
and1.b <== in[1];
|
|
80
|
+
out <== and1.out;
|
|
81
|
+
} else {
|
|
82
|
+
and2 = AND();
|
|
83
|
+
var n1 = n\2;
|
|
84
|
+
var n2 = n-n\2;
|
|
85
|
+
ands[0] = MultiAND(n1);
|
|
86
|
+
ands[1] = MultiAND(n2);
|
|
87
|
+
var i;
|
|
88
|
+
for (i=0; i<n1; i++) ands[0].in[i] <== in[i];
|
|
89
|
+
for (i=0; i<n2; i++) ands[1].in[i] <== in[n1+i];
|
|
90
|
+
and2.a <== ands[0].out;
|
|
91
|
+
and2.b <== ands[1].out;
|
|
92
|
+
out <== and2.out;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
|