keccak256-circom/circuits/theta.circom
circuits/theta.circomRaw
1pragma circom 2.0.0;
2
3include "../node_modules/circomlib/circuits/gates.circom";
4include "../node_modules/circomlib/circuits/sha256/xor3.circom";
5include "../node_modules/circomlib/circuits/sha256/shift.circom"; // contains ShiftRight
6
7template Xor5(n) {
8 signal input a[n];
9 signal input b[n];
10 signal input c[n];
11 signal input d[n];
12 signal input e[n];
13 signal output out[n];
14 var i;
15
16 component xor3 = Xor3(n);
17 for (i=0; i<n; i++) {
18 xor3.a[i] <== a[i];
19 xor3.b[i] <== b[i];
20 xor3.c[i] <== c[i];
21 }
22 component xor4 = XorArray(n);
23 for (i=0; i<n; i++) {
24 xor4.a[i] <== xor3.out[i];
25 xor4.b[i] <== d[i];
26 }
27 component xor5 = XorArray(n);
28 for (i=0; i<n; i++) {
29 xor5.a[i] <== xor4.out[i];
30 xor5.b[i] <== e[i];
31 }
32 for (i=0; i<n; i++) {
33 out[i] <== xor5.out[i];
34 }
35}
36template XorArray(n) {
37 signal input a[n];
38 signal input b[n];
39 signal output out[n];
40 var i;
41
42 component aux[n];
43 for (i=0; i<n; i++) {
44 aux[i] = XOR();
45 aux[i].a <== a[i];
46 aux[i].b <== b[i];
47 }
48 for (i=0; i<n; i++) {
49 out[i] <== aux[i].out;
50 }
51}
52
53template ShL(n, r) {
54 signal input in[n];
55 signal output out[n];
56
57 for (var i=0; i<n; i++) {
58 if (i < r) {
59 out[i] <== 0;
60 } else {
61 out[i] <== in[ i-r ];
62 }
63 }
64}
65
66template D(n, shl, shr) {
67 // d = b ^ (a<<shl | a>>shr)
68 signal input a[n];
69 signal input b[n];
70 signal output out[n];
71 var i;
72
73 component aux0 = ShR(64, shr);
74 for (i=0; i<64; i++) {
75 aux0.in[i] <== a[i];
76 }
77 component aux1 = ShL(64, shl);
78 for (i=0; i<64; i++) {
79 aux1.in[i] <== a[i];
80 }
81 component aux2[64];
82 for (i=0; i<64; i++) {
83 aux2[i] = OR();
84 aux2[i].a <== aux0.out[i];
85 aux2[i].b <== aux1.out[i];
86 }
87 component aux3 = XorArray(64);
88 for (i=0; i<64; i++) {
89 aux3.a[i] <== b[i];
90 aux3.b[i] <== aux2[i].out;
91 }
92 for (i=0; i<64; i++) {
93 out[i] <== aux3.out[i];
94 }
95}
96
97template Theta() {
98 signal input in[25*64];
99 signal output out[25*64];
100
101 var i;
102
103 component c0 = Xor5(64);
104 for (i=0; i<64; i++) {
105 c0.a[i] <== in[i];
106 c0.b[i] <== in[5*64+i];
107 c0.c[i] <== in[10*64+i];
108 c0.d[i] <== in[15*64+i];
109 c0.e[i] <== in[20*64+i];
110 }
111
112 component c1 = Xor5(64);
113 for (i=0; i<64; i++) {
114 c1.a[i] <== in[1*64+i];
115 c1.b[i] <== in[6*64+i];
116 c1.c[i] <== in[11*64+i];
117 c1.d[i] <== in[16*64+i];
118 c1.e[i] <== in[21*64+i];
119 }
120
121 component c2 = Xor5(64);
122 for (i=0; i<64; i++) {
123 c2.a[i] <== in[2*64+i];
124 c2.b[i] <== in[7*64+i];
125 c2.c[i] <== in[12*64+i];
126 c2.d[i] <== in[17*64+i];
127 c2.e[i] <== in[22*64+i];
128 }
129
130 component c3 = Xor5(64);
131 for (i=0; i<64; i++) {
132 c3.a[i] <== in[3*64+i];
133 c3.b[i] <== in[8*64+i];
134 c3.c[i] <== in[13*64+i];
135 c3.d[i] <== in[18*64+i];
136 c3.e[i] <== in[23*64+i];
137 }
138
139 component c4 = Xor5(64);
140 for (i=0; i<64; i++) {
141 c4.a[i] <== in[4*64+i];
142 c4.b[i] <== in[9*64+i];
143 c4.c[i] <== in[14*64+i];
144 c4.d[i] <== in[19*64+i];
145 c4.e[i] <== in[24*64+i];
146 }
147
148 // d = c4 ^ (c1<<1 | c1>>(64-1))
149 component d0 = D(64, 1, 64-1);
150 for (i=0; i<64; i++) {
151 d0.a[i] <== c1.out[i];
152 d0.b[i] <== c4.out[i];
153 }
154 // r[0] = a[0] ^ d
155 component r0 = XorArray(64);
156 for (i=0; i<64; i++) {
157 r0.a[i] <== in[i];
158 r0.b[i] <== d0.out[i];
159 }
160 for (i=0; i<64; i++) {
161 out[i] <== r0.out[i];
162 }
163 // r[5] = a[5] ^ d
164 component r5 = XorArray(64);
165 for (i=0; i<64; i++) {
166 r5.a[i] <== in[5*64+i];
167 r5.b[i] <== d0.out[i];
168 }
169 for (i=0; i<64; i++) {
170 out[5*64+i] <== r5.out[i];
171 }
172 // r[10] = a[10] ^ d
173 component r10 = XorArray(64);
174 for (i=0; i<64; i++) {
175 r10.a[i] <== in[10*64+i];
176 r10.b[i] <== d0.out[i];
177 }
178 for (i=0; i<64; i++) {
179 out[10*64+i] <== r10.out[i];
180 }
181 // r[15] = a[15] ^ d
182 component r15 = XorArray(64);
183 for (i=0; i<64; i++) {
184 r15.a[i] <== in[15*64+i];
185 r15.b[i] <== d0.out[i];
186 }
187 for (i=0; i<64; i++) {
188 out[15*64+i] <== r15.out[i];
189 }
190 // r[20] = a[20] ^ d
191 component r20 = XorArray(64);
192 for (i=0; i<64; i++) {
193 r20.a[i] <== in[20*64+i];
194 r20.b[i] <== d0.out[i];
195 }
196 for (i=0; i<64; i++) {
197 out[20*64+i] <== r20.out[i];
198 }
199
200 // d = c0 ^ (c2<<1 | c2>>(64-1))
201 component d1 = D(64, 1, 64-1);
202 for (i=0; i<64; i++) {
203 d1.a[i] <== c2.out[i];
204 d1.b[i] <== c0.out[i];
205 }
206 // r[1] = a[1] ^ d
207 component r1 = XorArray(64);
208 for (i=0; i<64; i++) {
209 r1.a[i] <== in[1*64+i];
210 r1.b[i] <== d1.out[i];
211 }
212 for (i=0; i<64; i++) {
213 out[1*64+i] <== r1.out[i];
214 }
215 // r[6] = a[6] ^ d
216 component r6 = XorArray(64);
217 for (i=0; i<64; i++) {
218 r6.a[i] <== in[6*64+i];
219 r6.b[i] <== d1.out[i];
220 }
221 for (i=0; i<64; i++) {
222 out[6*64+i] <== r6.out[i];
223 }
224 // r[11] = a[11] ^ d
225 component r11 = XorArray(64);
226 for (i=0; i<64; i++) {
227 r11.a[i] <== in[11*64+i];
228 r11.b[i] <== d1.out[i];
229 }
230 for (i=0; i<64; i++) {
231 out[11*64+i] <== r11.out[i];
232 }
233 // r[16] = a[16] ^ d
234 component r16 = XorArray(64);
235 for (i=0; i<64; i++) {
236 r16.a[i] <== in[16*64+i];
237 r16.b[i] <== d1.out[i];
238 }
239 for (i=0; i<64; i++) {
240 out[16*64+i] <== r16.out[i];
241 }
242 // r[21] = a[21] ^ d
243 component r21 = XorArray(64);
244 for (i=0; i<64; i++) {
245 r21.a[i] <== in[21*64+i];
246 r21.b[i] <== d1.out[i];
247 }
248 for (i=0; i<64; i++) {
249 out[21*64+i] <== r21.out[i];
250 }
251
252 // d = c1 ^ (c3<<1 | c3>>(64-1))
253 component d2 = D(64, 1, 64-1);
254 for (i=0; i<64; i++) {
255 d2.a[i] <== c3.out[i];
256 d2.b[i] <== c1.out[i];
257 }
258 // r[2] = a[2] ^ d
259 component r2 = XorArray(64);
260 for (i=0; i<64; i++) {
261 r2.a[i] <== in[2*64+i];
262 r2.b[i] <== d2.out[i];
263 }
264 for (i=0; i<64; i++) {
265 out[2*64+i] <== r2.out[i];
266 }
267 // r[7] = a[7] ^ d
268 component r7 = XorArray(64);
269 for (i=0; i<64; i++) {
270 r7.a[i] <== in[7*64+i];
271 r7.b[i] <== d2.out[i];
272 }
273 for (i=0; i<64; i++) {
274 out[7*64+i] <== r7.out[i];
275 }
276 // r[12] = a[12] ^ d
277 component r12 = XorArray(64);
278 for (i=0; i<64; i++) {
279 r12.a[i] <== in[12*64+i];
280 r12.b[i] <== d2.out[i];
281 }
282 for (i=0; i<64; i++) {
283 out[12*64+i] <== r12.out[i];
284 }
285 // r[17] = a[17] ^ d
286 component r17 = XorArray(64);
287 for (i=0; i<64; i++) {
288 r17.a[i] <== in[17*64+i];
289 r17.b[i] <== d2.out[i];
290 }
291 for (i=0; i<64; i++) {
292 out[17*64+i] <== r17.out[i];
293 }
294 // r[22] = a[22] ^ d
295 component r22 = XorArray(64);
296 for (i=0; i<64; i++) {
297 r22.a[i] <== in[22*64+i];
298 r22.b[i] <== d2.out[i];
299 }
300 for (i=0; i<64; i++) {
301 out[22*64+i] <== r22.out[i];
302 }
303
304 // d = c2 ^ (c4<<1 | c4>>(64-1))
305 component d3 = D(64, 1, 64-1);
306 for (i=0; i<64; i++) {
307 d3.a[i] <== c4.out[i];
308 d3.b[i] <== c2.out[i];
309 }
310 // r[3] = a[3] ^ d
311 component r3 = XorArray(64);
312 for (i=0; i<64; i++) {
313 r3.a[i] <== in[3*64+i];
314 r3.b[i] <== d3.out[i];
315 }
316 for (i=0; i<64; i++) {
317 out[3*64+i] <== r3.out[i];
318 }
319 // r[8] = a[8] ^ d
320 component r8 = XorArray(64);
321 for (i=0; i<64; i++) {
322 r8.a[i] <== in[8*64+i];
323 r8.b[i] <== d3.out[i];
324 }
325 for (i=0; i<64; i++) {
326 out[8*64+i] <== r8.out[i];
327 }
328 // r[13] = a[13] ^ d
329 component r13 = XorArray(64);
330 for (i=0; i<64; i++) {
331 r13.a[i] <== in[13*64+i];
332 r13.b[i] <== d3.out[i];
333 }
334 for (i=0; i<64; i++) {
335 out[13*64+i] <== r13.out[i];
336 }
337 // r[18] = a[18] ^ d
338 component r18 = XorArray(64);
339 for (i=0; i<64; i++) {
340 r18.a[i] <== in[18*64+i];
341 r18.b[i] <== d3.out[i];
342 }
343 for (i=0; i<64; i++) {
344 out[18*64+i] <== r18.out[i];
345 }
346 // r[23] = a[23] ^ d
347 component r23 = XorArray(64);
348 for (i=0; i<64; i++) {
349 r23.a[i] <== in[23*64+i];
350 r23.b[i] <== d3.out[i];
351 }
352 for (i=0; i<64; i++) {
353 out[23*64+i] <== r23.out[i];
354 }
355
356 // d = c3 ^ (c0<<1 | c0>>(64-1))
357 component d4 = D(64, 1, 64-1);
358 for (i=0; i<64; i++) {
359 d4.a[i] <== c0.out[i];
360 d4.b[i] <== c3.out[i];
361 }
362 // r[4] = a[4] ^ d
363 component r4 = XorArray(64);
364 for (i=0; i<64; i++) {
365 r4.a[i] <== in[4*64+i];
366 r4.b[i] <== d4.out[i];
367 }
368 for (i=0; i<64; i++) {
369 out[4*64+i] <== r4.out[i];
370 }
371 // r[9] = a[9] ^ d
372 component r9 = XorArray(64);
373 for (i=0; i<64; i++) {
374 r9.a[i] <== in[9*64+i];
375 r9.b[i] <== d4.out[i];
376 }
377 for (i=0; i<64; i++) {
378 out[9*64+i] <== r9.out[i];
379 }
380 // r[14] = a[14] ^ d
381 component r14 = XorArray(64);
382 for (i=0; i<64; i++) {
383 r14.a[i] <== in[14*64+i];
384 r14.b[i] <== d4.out[i];
385 }
386 for (i=0; i<64; i++) {
387 out[14*64+i] <== r14.out[i];
388 }
389 // r[19] = a[19] ^ d
390 component r19 = XorArray(64);
391 for (i=0; i<64; i++) {
392 r19.a[i] <== in[19*64+i];
393 r19.b[i] <== d4.out[i];
394 }
395 for (i=0; i<64; i++) {
396 out[19*64+i] <== r19.out[i];
397 }
398 // r[24] = a[24] ^ d
399 component r24 = XorArray(64);
400 for (i=0; i<64; i++) {
401 r24.a[i] <== in[24*64+i];
402 r24.b[i] <== d4.out[i];
403 }
404 for (i=0; i<64; i++) {
405 out[24*64+i] <== r24.out[i];
406 }
407}