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.
Files changed (156) hide show
  1. package/README.md +101 -0
  2. package/bin/circom +0 -0
  3. package/bin/cli.js +36 -0
  4. package/bin/index.js +13 -0
  5. package/circomlib/.vscode/launch.json +63 -0
  6. package/circomlib/README.md +18 -0
  7. package/circomlib/circuits/README.md +830 -0
  8. package/circomlib/circuits/aliascheck.circom +33 -0
  9. package/circomlib/circuits/babyjub.circom +107 -0
  10. package/circomlib/circuits/binsub.circom +74 -0
  11. package/circomlib/circuits/binsum.circom +101 -0
  12. package/circomlib/circuits/bitify.circom +106 -0
  13. package/circomlib/circuits/comparators.circom +141 -0
  14. package/circomlib/circuits/compconstant.circom +74 -0
  15. package/circomlib/circuits/eddsa.circom +139 -0
  16. package/circomlib/circuits/eddsamimc.circom +124 -0
  17. package/circomlib/circuits/eddsamimcsponge.circom +124 -0
  18. package/circomlib/circuits/eddsaposeidon.circom +123 -0
  19. package/circomlib/circuits/escalarmul.circom +166 -0
  20. package/circomlib/circuits/escalarmulany.circom +197 -0
  21. package/circomlib/circuits/escalarmulfix.circom +299 -0
  22. package/circomlib/circuits/escalarmulw4table.circom +52 -0
  23. package/circomlib/circuits/gates.circom +96 -0
  24. package/circomlib/circuits/mimc.circom +156 -0
  25. package/circomlib/circuits/mimcsponge.circom +293 -0
  26. package/circomlib/circuits/montgomery.circom +142 -0
  27. package/circomlib/circuits/multiplexer.circom +115 -0
  28. package/circomlib/circuits/mux1.circom +48 -0
  29. package/circomlib/circuits/mux2.circom +63 -0
  30. package/circomlib/circuits/mux3.circom +75 -0
  31. package/circomlib/circuits/mux4.circom +119 -0
  32. package/circomlib/circuits/pedersen.circom +257 -0
  33. package/circomlib/circuits/pedersen_old.circom +68 -0
  34. package/circomlib/circuits/pointbits.circom +164 -0
  35. package/circomlib/circuits/poseidon.circom +208 -0
  36. package/circomlib/circuits/poseidon_constants.circom +24959 -0
  37. package/circomlib/circuits/poseidon_constants_old.circom +252 -0
  38. package/circomlib/circuits/poseidon_old.circom +97 -0
  39. package/circomlib/circuits/sha256/ch.circom +47 -0
  40. package/circomlib/circuits/sha256/constants.circom +53 -0
  41. package/circomlib/circuits/sha256/main.circom +35 -0
  42. package/circomlib/circuits/sha256/maj.circom +45 -0
  43. package/circomlib/circuits/sha256/rotate.circom +28 -0
  44. package/circomlib/circuits/sha256/sha256.circom +81 -0
  45. package/circomlib/circuits/sha256/sha256_2.circom +91 -0
  46. package/circomlib/circuits/sha256/sha256compression.circom +166 -0
  47. package/circomlib/circuits/sha256/sha256compression_function.circom +112 -0
  48. package/circomlib/circuits/sha256/shift.circom +33 -0
  49. package/circomlib/circuits/sha256/sigma.circom +77 -0
  50. package/circomlib/circuits/sha256/sigmaplus.circom +50 -0
  51. package/circomlib/circuits/sha256/t1.circom +58 -0
  52. package/circomlib/circuits/sha256/t2.circom +51 -0
  53. package/circomlib/circuits/sha256/xor3.circom +45 -0
  54. package/circomlib/circuits/sign.circom +36 -0
  55. package/circomlib/circuits/smt/smthash_mimc.circom +58 -0
  56. package/circomlib/circuits/smt/smthash_poseidon.circom +57 -0
  57. package/circomlib/circuits/smt/smtlevins.circom +103 -0
  58. package/circomlib/circuits/smt/smtprocessor.circom +261 -0
  59. package/circomlib/circuits/smt/smtprocessorlevel.circom +95 -0
  60. package/circomlib/circuits/smt/smtprocessorsm.circom +165 -0
  61. package/circomlib/circuits/smt/smtverifier.circom +138 -0
  62. package/circomlib/circuits/smt/smtverifierlevel.circom +71 -0
  63. package/circomlib/circuits/smt/smtverifiersm.circom +106 -0
  64. package/circomlib/circuits/switcher.circom +42 -0
  65. package/circomlib/doc/root_transfer.monopic +0 -0
  66. package/circomlib/doc/smt_diagram_0.monopic +0 -0
  67. package/circomlib/doc/smt_diagram_1.monopic +0 -0
  68. package/circomlib/doc/smt_hash.monopic +0 -0
  69. package/circomlib/doc/smt_levins.monopic +0 -0
  70. package/circomlib/doc/smt_sm.monopic +0 -0
  71. package/circomlib/doc/smt_verifier_sm.monopic +0 -0
  72. package/circomlib/doc/voting.monopic +0 -0
  73. package/circomlib/doc/window.monopic +0 -0
  74. package/circomlib/doc/window_chain.monopic +0 -0
  75. package/circomlib/index.js +2 -0
  76. package/circomlib/package.json +33 -0
  77. package/circomlib/test/aliascheck.js +77 -0
  78. package/circomlib/test/babyjub.js +118 -0
  79. package/circomlib/test/binsub.js +52 -0
  80. package/circomlib/test/binsum.js +38 -0
  81. package/circomlib/test/circuits/aliascheck_test.circom +4 -0
  82. package/circomlib/test/circuits/babyadd_tester.circom +4 -0
  83. package/circomlib/test/circuits/babycheck_test.circom +4 -0
  84. package/circomlib/test/circuits/babypbk_test.circom +4 -0
  85. package/circomlib/test/circuits/binsub_test.circom +33 -0
  86. package/circomlib/test/circuits/constants_test.circom +20 -0
  87. package/circomlib/test/circuits/eddsa_test.circom +5 -0
  88. package/circomlib/test/circuits/eddsamimc_test.circom +5 -0
  89. package/circomlib/test/circuits/eddsaposeidon_test.circom +5 -0
  90. package/circomlib/test/circuits/edwards2montgomery.circom +5 -0
  91. package/circomlib/test/circuits/escalarmul_min_test.circom +27 -0
  92. package/circomlib/test/circuits/escalarmul_test.circom +33 -0
  93. package/circomlib/test/circuits/escalarmul_test_min.circom +28 -0
  94. package/circomlib/test/circuits/escalarmulany_test.circom +30 -0
  95. package/circomlib/test/circuits/escalarmulfix_test.circom +31 -0
  96. package/circomlib/test/circuits/escalarmulw4table.circom +20 -0
  97. package/circomlib/test/circuits/escalarmulw4table_test.circom +19 -0
  98. package/circomlib/test/circuits/escalarmulw4table_test3.circom +19 -0
  99. package/circomlib/test/circuits/greatereqthan.circom +5 -0
  100. package/circomlib/test/circuits/greaterthan.circom +5 -0
  101. package/circomlib/test/circuits/isequal.circom +5 -0
  102. package/circomlib/test/circuits/iszero.circom +5 -0
  103. package/circomlib/test/circuits/lesseqthan.circom +5 -0
  104. package/circomlib/test/circuits/lessthan.circom +5 -0
  105. package/circomlib/test/circuits/mimc_sponge_hash_test.circom +5 -0
  106. package/circomlib/test/circuits/mimc_sponge_test.circom +5 -0
  107. package/circomlib/test/circuits/mimc_test.circom +5 -0
  108. package/circomlib/test/circuits/montgomery2edwards.circom +5 -0
  109. package/circomlib/test/circuits/montgomeryadd.circom +5 -0
  110. package/circomlib/test/circuits/montgomerydouble.circom +5 -0
  111. package/circomlib/test/circuits/mux1_1.circom +33 -0
  112. package/circomlib/test/circuits/mux2_1.circom +37 -0
  113. package/circomlib/test/circuits/mux3_1.circom +41 -0
  114. package/circomlib/test/circuits/mux4_1.circom +56 -0
  115. package/circomlib/test/circuits/pedersen2_test.circom +34 -0
  116. package/circomlib/test/circuits/pedersen_test.circom +31 -0
  117. package/circomlib/test/circuits/pointbits_loopback.circom +25 -0
  118. package/circomlib/test/circuits/poseidon3_test.circom +5 -0
  119. package/circomlib/test/circuits/poseidon6_test.circom +5 -0
  120. package/circomlib/test/circuits/poseidonex_test.circom +5 -0
  121. package/circomlib/test/circuits/sha256_2_test.circom +17 -0
  122. package/circomlib/test/circuits/sha256_test448.circom +5 -0
  123. package/circomlib/test/circuits/sha256_test512.circom +5 -0
  124. package/circomlib/test/circuits/sign_test.circom +5 -0
  125. package/circomlib/test/circuits/smtprocessor10_test.circom +5 -0
  126. package/circomlib/test/circuits/smtverifier10_test.circom +5 -0
  127. package/circomlib/test/circuits/sum_test.circom +33 -0
  128. package/circomlib/test/comparators.js +187 -0
  129. package/circomlib/test/eddsa.js +75 -0
  130. package/circomlib/test/eddsamimc.js +102 -0
  131. package/circomlib/test/eddsaposeidon.js +103 -0
  132. package/circomlib/test/escalarmul.js +121 -0
  133. package/circomlib/test/escalarmulany.js +51 -0
  134. package/circomlib/test/escalarmulfix.js +95 -0
  135. package/circomlib/test/helpers/printsignal.js +22 -0
  136. package/circomlib/test/helpers/sha256.js +178 -0
  137. package/circomlib/test/mimccircuit.js +27 -0
  138. package/circomlib/test/mimcspongecircuit.js +47 -0
  139. package/circomlib/test/montgomery.js +101 -0
  140. package/circomlib/test/multiplexer.js +101 -0
  141. package/circomlib/test/pedersen.js +83 -0
  142. package/circomlib/test/pedersen2.js +56 -0
  143. package/circomlib/test/point2bits.js +30 -0
  144. package/circomlib/test/poseidoncircuit.js +80 -0
  145. package/circomlib/test/sha256.js +118 -0
  146. package/circomlib/test/sign.js +82 -0
  147. package/circomlib/test/smtprocessor.js +219 -0
  148. package/circomlib/test/smtverifier.js +141 -0
  149. package/lib/compile.js +82 -0
  150. package/lib/deploy.js +391 -0
  151. package/lib/test.js +47 -0
  152. package/lib/verify.js +153 -0
  153. package/package.json +43 -0
  154. package/pot12_0000.ptau +0 -0
  155. package/pot12_0001.ptau +0 -0
  156. 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
+