keccak256-circom/circuits/permutations.circom
circuits/permutations.circomRaw
1// Keccak256 hash function (ethereum version).
2// For LICENSE check https://github.com/vocdoni/keccak256-circom/blob/master/LICENSE
3
4pragma circom 2.0.0;
5
6include "./utils.circom";
7
8
9// Theta
10
11template D(n, shl, shr) {
12 // d = b ^ (a<<shl | a>>shr)
13 signal input a[n];
14 signal input b[n];
15 signal output out[n];
16 var i;
17
18 component aux0 = ShR(64, shr);
19 for (i=0; i<64; i++) {
20 aux0.in[i] <== a[i];
21 }
22 component aux1 = ShL(64, shl);
23 for (i=0; i<64; i++) {
24 aux1.in[i] <== a[i];
25 }
26 component aux2 = OrArray(64);
27 for (i=0; i<64; i++) {
28 aux2.a[i] <== aux0.out[i];
29 aux2.b[i] <== aux1.out[i];
30 }
31 component aux3 = XorArray(64);
32 for (i=0; i<64; i++) {
33 aux3.a[i] <== b[i];
34 aux3.b[i] <== aux2.out[i];
35 }
36 for (i=0; i<64; i++) {
37 out[i] <== aux3.out[i];
38 }
39}
40
41template Theta() {
42 signal input in[25*64];
43 signal output out[25*64];
44
45 var i;
46
47 component c0 = Xor5(64);
48 for (i=0; i<64; i++) {
49 c0.a[i] <== in[i];
50 c0.b[i] <== in[5*64+i];
51 c0.c[i] <== in[10*64+i];
52 c0.d[i] <== in[15*64+i];
53 c0.e[i] <== in[20*64+i];
54 }
55
56 component c1 = Xor5(64);
57 for (i=0; i<64; i++) {
58 c1.a[i] <== in[1*64+i];
59 c1.b[i] <== in[6*64+i];
60 c1.c[i] <== in[11*64+i];
61 c1.d[i] <== in[16*64+i];
62 c1.e[i] <== in[21*64+i];
63 }
64
65 component c2 = Xor5(64);
66 for (i=0; i<64; i++) {
67 c2.a[i] <== in[2*64+i];
68 c2.b[i] <== in[7*64+i];
69 c2.c[i] <== in[12*64+i];
70 c2.d[i] <== in[17*64+i];
71 c2.e[i] <== in[22*64+i];
72 }
73
74 component c3 = Xor5(64);
75 for (i=0; i<64; i++) {
76 c3.a[i] <== in[3*64+i];
77 c3.b[i] <== in[8*64+i];
78 c3.c[i] <== in[13*64+i];
79 c3.d[i] <== in[18*64+i];
80 c3.e[i] <== in[23*64+i];
81 }
82
83 component c4 = Xor5(64);
84 for (i=0; i<64; i++) {
85 c4.a[i] <== in[4*64+i];
86 c4.b[i] <== in[9*64+i];
87 c4.c[i] <== in[14*64+i];
88 c4.d[i] <== in[19*64+i];
89 c4.e[i] <== in[24*64+i];
90 }
91
92 // d = c4 ^ (c1<<1 | c1>>(64-1))
93 component d0 = D(64, 1, 64-1);
94 for (i=0; i<64; i++) {
95 d0.a[i] <== c1.out[i];
96 d0.b[i] <== c4.out[i];
97 }
98 // r[0] = a[0] ^ d
99 component r0 = XorArray(64);
100 for (i=0; i<64; i++) {
101 r0.a[i] <== in[i];
102 r0.b[i] <== d0.out[i];
103 }
104 for (i=0; i<64; i++) {
105 out[i] <== r0.out[i];
106 }
107 // r[5] = a[5] ^ d
108 component r5 = XorArray(64);
109 for (i=0; i<64; i++) {
110 r5.a[i] <== in[5*64+i];
111 r5.b[i] <== d0.out[i];
112 }
113 for (i=0; i<64; i++) {
114 out[5*64+i] <== r5.out[i];
115 }
116 // r[10] = a[10] ^ d
117 component r10 = XorArray(64);
118 for (i=0; i<64; i++) {
119 r10.a[i] <== in[10*64+i];
120 r10.b[i] <== d0.out[i];
121 }
122 for (i=0; i<64; i++) {
123 out[10*64+i] <== r10.out[i];
124 }
125 // r[15] = a[15] ^ d
126 component r15 = XorArray(64);
127 for (i=0; i<64; i++) {
128 r15.a[i] <== in[15*64+i];
129 r15.b[i] <== d0.out[i];
130 }
131 for (i=0; i<64; i++) {
132 out[15*64+i] <== r15.out[i];
133 }
134 // r[20] = a[20] ^ d
135 component r20 = XorArray(64);
136 for (i=0; i<64; i++) {
137 r20.a[i] <== in[20*64+i];
138 r20.b[i] <== d0.out[i];
139 }
140 for (i=0; i<64; i++) {
141 out[20*64+i] <== r20.out[i];
142 }
143
144 // d = c0 ^ (c2<<1 | c2>>(64-1))
145 component d1 = D(64, 1, 64-1);
146 for (i=0; i<64; i++) {
147 d1.a[i] <== c2.out[i];
148 d1.b[i] <== c0.out[i];
149 }
150 // r[1] = a[1] ^ d
151 component r1 = XorArray(64);
152 for (i=0; i<64; i++) {
153 r1.a[i] <== in[1*64+i];
154 r1.b[i] <== d1.out[i];
155 }
156 for (i=0; i<64; i++) {
157 out[1*64+i] <== r1.out[i];
158 }
159 // r[6] = a[6] ^ d
160 component r6 = XorArray(64);
161 for (i=0; i<64; i++) {
162 r6.a[i] <== in[6*64+i];
163 r6.b[i] <== d1.out[i];
164 }
165 for (i=0; i<64; i++) {
166 out[6*64+i] <== r6.out[i];
167 }
168 // r[11] = a[11] ^ d
169 component r11 = XorArray(64);
170 for (i=0; i<64; i++) {
171 r11.a[i] <== in[11*64+i];
172 r11.b[i] <== d1.out[i];
173 }
174 for (i=0; i<64; i++) {
175 out[11*64+i] <== r11.out[i];
176 }
177 // r[16] = a[16] ^ d
178 component r16 = XorArray(64);
179 for (i=0; i<64; i++) {
180 r16.a[i] <== in[16*64+i];
181 r16.b[i] <== d1.out[i];
182 }
183 for (i=0; i<64; i++) {
184 out[16*64+i] <== r16.out[i];
185 }
186 // r[21] = a[21] ^ d
187 component r21 = XorArray(64);
188 for (i=0; i<64; i++) {
189 r21.a[i] <== in[21*64+i];
190 r21.b[i] <== d1.out[i];
191 }
192 for (i=0; i<64; i++) {
193 out[21*64+i] <== r21.out[i];
194 }
195
196 // d = c1 ^ (c3<<1 | c3>>(64-1))
197 component d2 = D(64, 1, 64-1);
198 for (i=0; i<64; i++) {
199 d2.a[i] <== c3.out[i];
200 d2.b[i] <== c1.out[i];
201 }
202 // r[2] = a[2] ^ d
203 component r2 = XorArray(64);
204 for (i=0; i<64; i++) {
205 r2.a[i] <== in[2*64+i];
206 r2.b[i] <== d2.out[i];
207 }
208 for (i=0; i<64; i++) {
209 out[2*64+i] <== r2.out[i];
210 }
211 // r[7] = a[7] ^ d
212 component r7 = XorArray(64);
213 for (i=0; i<64; i++) {
214 r7.a[i] <== in[7*64+i];
215 r7.b[i] <== d2.out[i];
216 }
217 for (i=0; i<64; i++) {
218 out[7*64+i] <== r7.out[i];
219 }
220 // r[12] = a[12] ^ d
221 component r12 = XorArray(64);
222 for (i=0; i<64; i++) {
223 r12.a[i] <== in[12*64+i];
224 r12.b[i] <== d2.out[i];
225 }
226 for (i=0; i<64; i++) {
227 out[12*64+i] <== r12.out[i];
228 }
229 // r[17] = a[17] ^ d
230 component r17 = XorArray(64);
231 for (i=0; i<64; i++) {
232 r17.a[i] <== in[17*64+i];
233 r17.b[i] <== d2.out[i];
234 }
235 for (i=0; i<64; i++) {
236 out[17*64+i] <== r17.out[i];
237 }
238 // r[22] = a[22] ^ d
239 component r22 = XorArray(64);
240 for (i=0; i<64; i++) {
241 r22.a[i] <== in[22*64+i];
242 r22.b[i] <== d2.out[i];
243 }
244 for (i=0; i<64; i++) {
245 out[22*64+i] <== r22.out[i];
246 }
247
248 // d = c2 ^ (c4<<1 | c4>>(64-1))
249 component d3 = D(64, 1, 64-1);
250 for (i=0; i<64; i++) {
251 d3.a[i] <== c4.out[i];
252 d3.b[i] <== c2.out[i];
253 }
254 // r[3] = a[3] ^ d
255 component r3 = XorArray(64);
256 for (i=0; i<64; i++) {
257 r3.a[i] <== in[3*64+i];
258 r3.b[i] <== d3.out[i];
259 }
260 for (i=0; i<64; i++) {
261 out[3*64+i] <== r3.out[i];
262 }
263 // r[8] = a[8] ^ d
264 component r8 = XorArray(64);
265 for (i=0; i<64; i++) {
266 r8.a[i] <== in[8*64+i];
267 r8.b[i] <== d3.out[i];
268 }
269 for (i=0; i<64; i++) {
270 out[8*64+i] <== r8.out[i];
271 }
272 // r[13] = a[13] ^ d
273 component r13 = XorArray(64);
274 for (i=0; i<64; i++) {
275 r13.a[i] <== in[13*64+i];
276 r13.b[i] <== d3.out[i];
277 }
278 for (i=0; i<64; i++) {
279 out[13*64+i] <== r13.out[i];
280 }
281 // r[18] = a[18] ^ d
282 component r18 = XorArray(64);
283 for (i=0; i<64; i++) {
284 r18.a[i] <== in[18*64+i];
285 r18.b[i] <== d3.out[i];
286 }
287 for (i=0; i<64; i++) {
288 out[18*64+i] <== r18.out[i];
289 }
290 // r[23] = a[23] ^ d
291 component r23 = XorArray(64);
292 for (i=0; i<64; i++) {
293 r23.a[i] <== in[23*64+i];
294 r23.b[i] <== d3.out[i];
295 }
296 for (i=0; i<64; i++) {
297 out[23*64+i] <== r23.out[i];
298 }
299
300 // d = c3 ^ (c0<<1 | c0>>(64-1))
301 component d4 = D(64, 1, 64-1);
302 for (i=0; i<64; i++) {
303 d4.a[i] <== c0.out[i];
304 d4.b[i] <== c3.out[i];
305 }
306 // r[4] = a[4] ^ d
307 component r4 = XorArray(64);
308 for (i=0; i<64; i++) {
309 r4.a[i] <== in[4*64+i];
310 r4.b[i] <== d4.out[i];
311 }
312 for (i=0; i<64; i++) {
313 out[4*64+i] <== r4.out[i];
314 }
315 // r[9] = a[9] ^ d
316 component r9 = XorArray(64);
317 for (i=0; i<64; i++) {
318 r9.a[i] <== in[9*64+i];
319 r9.b[i] <== d4.out[i];
320 }
321 for (i=0; i<64; i++) {
322 out[9*64+i] <== r9.out[i];
323 }
324 // r[14] = a[14] ^ d
325 component r14 = XorArray(64);
326 for (i=0; i<64; i++) {
327 r14.a[i] <== in[14*64+i];
328 r14.b[i] <== d4.out[i];
329 }
330 for (i=0; i<64; i++) {
331 out[14*64+i] <== r14.out[i];
332 }
333 // r[19] = a[19] ^ d
334 component r19 = XorArray(64);
335 for (i=0; i<64; i++) {
336 r19.a[i] <== in[19*64+i];
337 r19.b[i] <== d4.out[i];
338 }
339 for (i=0; i<64; i++) {
340 out[19*64+i] <== r19.out[i];
341 }
342 // r[24] = a[24] ^ d
343 component r24 = XorArray(64);
344 for (i=0; i<64; i++) {
345 r24.a[i] <== in[24*64+i];
346 r24.b[i] <== d4.out[i];
347 }
348 for (i=0; i<64; i++) {
349 out[24*64+i] <== r24.out[i];
350 }
351}
352
353// RhoPi
354
355template stepRhoPi(shl, shr) {
356 // out = a<<shl|a>>shr
357 signal input a[64];
358 signal output out[64];
359 var i;
360
361 component aux0 = ShR(64, shr);
362 for (i=0; i<64; i++) {
363 aux0.in[i] <== a[i];
364 }
365 component aux1 = ShL(64, shl);
366 for (i=0; i<64; i++) {
367 aux1.in[i] <== a[i];
368 }
369 component aux2 = OrArray(64);
370 for (i=0; i<64; i++) {
371 aux2.a[i] <== aux0.out[i];
372 aux2.b[i] <== aux1.out[i];
373 }
374 for (i=0; i<64; i++) {
375 out[i] <== aux2.out[i];
376 }
377}
378template RhoPi() {
379 signal input in[25*64];
380 signal output out[25*64];
381
382 var i;
383
384 // r[10] = a[1]<<1|a[1]>>(64-1)
385 component s10 = stepRhoPi(1, 64-1);
386 for (i=0; i<64; i++) {
387 s10.a[i] <== in[1*64+i];
388 }
389 // r[7] = a[10]<<3|a[10]>>(64-3)
390 component s7 = stepRhoPi(3, 64-3);
391 for (i=0; i<64; i++) {
392 s7.a[i] <== in[10*64+i];
393 }
394 // r[11] = a[7]<<6|a[7]>>(64-6)
395 component s11 = stepRhoPi(6, 64-6);
396 for (i=0; i<64; i++) {
397 s11.a[i] <== in[7*64+i];
398 }
399 // r[17] = a[11]<<10|a[11]>>(64-10)
400 component s17 = stepRhoPi(10, 64-10);
401 for (i=0; i<64; i++) {
402 s17.a[i] <== in[11*64+i];
403 }
404 // r[18] = a[17]<<15|a[17]>>(64-15)
405 component s18 = stepRhoPi(15, 64-15);
406 for (i=0; i<64; i++) {
407 s18.a[i] <== in[17*64+i];
408 }
409 // r[3] = a[18]<<21|a[18]>>(64-21)
410 component s3 = stepRhoPi(21, 64-21);
411 for (i=0; i<64; i++) {
412 s3.a[i] <== in[18*64+i];
413 }
414 // r[5] = a[3]<<28|a[3]>>(64-28)
415 component s5 = stepRhoPi(28, 64-28);
416 for (i=0; i<64; i++) {
417 s5.a[i] <== in[3*64+i];
418 }
419 // r[16] = a[5]<<36|a[5]>>(64-36)
420 component s16 = stepRhoPi(36, 64-36);
421 for (i=0; i<64; i++) {
422 s16.a[i] <== in[5*64+i];
423 }
424 // r[8] = a[16]<<45|a[16]>>(64-45)
425 component s8 = stepRhoPi(45, 64-45);
426 for (i=0; i<64; i++) {
427 s8.a[i] <== in[16*64+i];
428 }
429 // r[21] = a[8]<<55|a[8]>>(64-55)
430 component s21 = stepRhoPi(55, 64-55);
431 for (i=0; i<64; i++) {
432 s21.a[i] <== in[8*64+i];
433 }
434 // r[24] = a[21]<<2|a[21]>>(64-2)
435 component s24 = stepRhoPi(2, 64-2);
436 for (i=0; i<64; i++) {
437 s24.a[i] <== in[21*64+i];
438 }
439 // r[4] = a[24]<<14|a[24]>>(64-14)
440 component s4 = stepRhoPi(14, 64-14);
441 for (i=0; i<64; i++) {
442 s4.a[i] <== in[24*64+i];
443 }
444 // r[15] = a[4]<<27|a[4]>>(64-27)
445 component s15 = stepRhoPi(27, 64-27);
446 for (i=0; i<64; i++) {
447 s15.a[i] <== in[4*64+i];
448 }
449 // r[23] = a[15]<<41|a[15]>>(64-41)
450 component s23 = stepRhoPi(41, 64-41);
451 for (i=0; i<64; i++) {
452 s23.a[i] <== in[15*64+i];
453 }
454 // r[19] = a[23]<<56|a[23]>>(64-56)
455 component s19 = stepRhoPi(56, 64-56);
456 for (i=0; i<64; i++) {
457 s19.a[i] <== in[23*64+i];
458 }
459 // r[13] = a[19]<<8|a[19]>>(64-8)
460 component s13 = stepRhoPi(8, 64-8);
461 for (i=0; i<64; i++) {
462 s13.a[i] <== in[19*64+i];
463 }
464 // r[12] = a[13]<<25|a[13]>>(64-25)
465 component s12 = stepRhoPi(25, 64-25);
466 for (i=0; i<64; i++) {
467 s12.a[i] <== in[13*64+i];
468 }
469 // r[2] = a[12]<<43|a[12]>>(64-43)
470 component s2 = stepRhoPi(43, 64-43);
471 for (i=0; i<64; i++) {
472 s2.a[i] <== in[12*64+i];
473 }
474 // r[20] = a[2]<<62|a[2]>>(64-62)
475 component s20 = stepRhoPi(62, 64-62);
476 for (i=0; i<64; i++) {
477 s20.a[i] <== in[2*64+i];
478 }
479 // r[14] = a[20]<<18|a[20]>>(64-18)
480 component s14 = stepRhoPi(18, 64-18);
481 for (i=0; i<64; i++) {
482 s14.a[i] <== in[20*64+i];
483 }
484 // r[22] = a[14]<<39|a[14]>>(64-39)
485 component s22 = stepRhoPi(39, 64-39);
486 for (i=0; i<64; i++) {
487 s22.a[i] <== in[14*64+i];
488 }
489 // r[9] = a[22]<<61|a[22]>>(64-61)
490 component s9 = stepRhoPi(61, 64-61);
491 for (i=0; i<64; i++) {
492 s9.a[i] <== in[22*64+i];
493 }
494 // r[6] = a[9]<<20|a[9]>>(64-20)
495 component s6 = stepRhoPi(20, 64-20);
496 for (i=0; i<64; i++) {
497 s6.a[i] <== in[9*64+i];
498 }
499 // r[1] = a[6]<<44|a[6]>>(64-44)
500 component s1 = stepRhoPi(44, 64-44);
501 for (i=0; i<64; i++) {
502 s1.a[i] <== in[6*64+i];
503 }
504
505 for (i=0; i<64; i++) {
506 out[i] <== in[i];
507 out[10*64+i] <== s10.out[i];
508 out[7*64+i] <== s7.out[i];
509 out[11*64+i] <== s11.out[i];
510 out[17*64+i] <== s17.out[i];
511 out[18*64+i] <== s18.out[i];
512 out[3*64+i] <== s3.out[i];
513 out[5*64+i] <== s5.out[i];
514 out[16*64+i] <== s16.out[i];
515 out[8*64+i] <== s8.out[i];
516 out[21*64+i] <== s21.out[i];
517 out[24*64+i] <== s24.out[i];
518 out[4*64+i] <== s4.out[i];
519 out[15*64+i] <== s15.out[i];
520 out[23*64+i] <== s23.out[i];
521 out[19*64+i] <== s19.out[i];
522 out[13*64+i] <== s13.out[i];
523 out[12*64+i] <== s12.out[i];
524 out[2*64+i] <== s2.out[i];
525 out[20*64+i] <== s20.out[i];
526 out[14*64+i] <== s14.out[i];
527 out[22*64+i] <== s22.out[i];
528 out[9*64+i] <== s9.out[i];
529 out[6*64+i] <== s6.out[i];
530 out[1*64+i] <== s1.out[i];
531 }
532}
533
534
535// Chi
536
537template stepChi() {
538 // out = a ^ (^b) & c
539 signal input a[64];
540 signal input b[64];
541 signal input c[64];
542 signal output out[64];
543 var i;
544
545 // ^b
546 component bXor = XorArraySingle(64);
547 for (i=0; i<64; i++) {
548 bXor.a[i] <== b[i];
549 }
550 // (^b)&c
551 component bc = AndArray(64);
552 for (i=0; i<64; i++) {
553 bc.a[i] <== bXor.out[i];
554 bc.b[i] <== c[i];
555 }
556 // a^(^b)&c
557 component abc = XorArray(64);
558 for (i=0; i<64; i++) {
559 abc.a[i] <== a[i];
560 abc.b[i] <== bc.out[i];
561 }
562 for (i=0; i<64; i++) {
563 out[i] <== abc.out[i];
564 }
565}
566
567template Chi() {
568 signal input in[25*64];
569 signal output out[25*64];
570
571 var i;
572
573 component r0 = stepChi();
574 for (i=0; i<64; i++) {
575 r0.a[i] <== in[i];
576 r0.b[i] <== in[1*64+i];
577 r0.c[i] <== in[2*64+i];
578 }
579 component r1 = stepChi();
580 for (i=0; i<64; i++) {
581 r1.a[i] <== in[1*64+i];
582 r1.b[i] <== in[2*64+i];
583 r1.c[i] <== in[3*64+i];
584 }
585 component r2 = stepChi();
586 for (i=0; i<64; i++) {
587 r2.a[i] <== in[2*64+i];
588 r2.b[i] <== in[3*64+i];
589 r2.c[i] <== in[4*64+i];
590 }
591 component r3 = stepChi();
592 for (i=0; i<64; i++) {
593 r3.a[i] <== in[3*64+i];
594 r3.b[i] <== in[4*64+i];
595 r3.c[i] <== in[0*64+i];
596 }
597 component r4 = stepChi();
598 for (i=0; i<64; i++) {
599 r4.a[i] <== in[4*64+i];
600 r4.b[i] <== in[i];
601 r4.c[i] <== in[1*64+i];
602 }
603
604 component r5 = stepChi();
605 for (i=0; i<64; i++) {
606 r5.a[i] <== in[5*64+i];
607 r5.b[i] <== in[6*64+i];
608 r5.c[i] <== in[7*64+i];
609 }
610 component r6 = stepChi();
611 for (i=0; i<64; i++) {
612 r6.a[i] <== in[6*64+i];
613 r6.b[i] <== in[7*64+i];
614 r6.c[i] <== in[8*64+i];
615 }
616 component r7 = stepChi();
617 for (i=0; i<64; i++) {
618 r7.a[i] <== in[7*64+i];
619 r7.b[i] <== in[8*64+i];
620 r7.c[i] <== in[9*64+i];
621 }
622 component r8 = stepChi();
623 for (i=0; i<64; i++) {
624 r8.a[i] <== in[8*64+i];
625 r8.b[i] <== in[9*64+i];
626 r8.c[i] <== in[5*64+i];
627 }
628 component r9 = stepChi();
629 for (i=0; i<64; i++) {
630 r9.a[i] <== in[9*64+i];
631 r9.b[i] <== in[5*64+i];
632 r9.c[i] <== in[6*64+i];
633 }
634
635 component r10 = stepChi();
636 for (i=0; i<64; i++) {
637 r10.a[i] <== in[10*64+i];
638 r10.b[i] <== in[11*64+i];
639 r10.c[i] <== in[12*64+i];
640 }
641 component r11 = stepChi();
642 for (i=0; i<64; i++) {
643 r11.a[i] <== in[11*64+i];
644 r11.b[i] <== in[12*64+i];
645 r11.c[i] <== in[13*64+i];
646 }
647 component r12 = stepChi();
648 for (i=0; i<64; i++) {
649 r12.a[i] <== in[12*64+i];
650 r12.b[i] <== in[13*64+i];
651 r12.c[i] <== in[14*64+i];
652 }
653 component r13 = stepChi();
654 for (i=0; i<64; i++) {
655 r13.a[i] <== in[13*64+i];
656 r13.b[i] <== in[14*64+i];
657 r13.c[i] <== in[10*64+i];
658 }
659 component r14 = stepChi();
660 for (i=0; i<64; i++) {
661 r14.a[i] <== in[14*64+i];
662 r14.b[i] <== in[10*64+i];
663 r14.c[i] <== in[11*64+i];
664 }
665
666 component r15 = stepChi();
667 for (i=0; i<64; i++) {
668 r15.a[i] <== in[15*64+i];
669 r15.b[i] <== in[16*64+i];
670 r15.c[i] <== in[17*64+i];
671 }
672 component r16 = stepChi();
673 for (i=0; i<64; i++) {
674 r16.a[i] <== in[16*64+i];
675 r16.b[i] <== in[17*64+i];
676 r16.c[i] <== in[18*64+i];
677 }
678 component r17 = stepChi();
679 for (i=0; i<64; i++) {
680 r17.a[i] <== in[17*64+i];
681 r17.b[i] <== in[18*64+i];
682 r17.c[i] <== in[19*64+i];
683 }
684 component r18 = stepChi();
685 for (i=0; i<64; i++) {
686 r18.a[i] <== in[18*64+i];
687 r18.b[i] <== in[19*64+i];
688 r18.c[i] <== in[15*64+i];
689 }
690 component r19 = stepChi();
691 for (i=0; i<64; i++) {
692 r19.a[i] <== in[19*64+i];
693 r19.b[i] <== in[15*64+i];
694 r19.c[i] <== in[16*64+i];
695 }
696
697 component r20 = stepChi();
698 for (i=0; i<64; i++) {
699 r20.a[i] <== in[20*64+i];
700 r20.b[i] <== in[21*64+i];
701 r20.c[i] <== in[22*64+i];
702 }
703 component r21 = stepChi();
704 for (i=0; i<64; i++) {
705 r21.a[i] <== in[21*64+i];
706 r21.b[i] <== in[22*64+i];
707 r21.c[i] <== in[23*64+i];
708 }
709 component r22 = stepChi();
710 for (i=0; i<64; i++) {
711 r22.a[i] <== in[22*64+i];
712 r22.b[i] <== in[23*64+i];
713 r22.c[i] <== in[24*64+i];
714 }
715 component r23 = stepChi();
716 for (i=0; i<64; i++) {
717 r23.a[i] <== in[23*64+i];
718 r23.b[i] <== in[24*64+i];
719 r23.c[i] <== in[20*64+i];
720 }
721 component r24 = stepChi();
722 for (i=0; i<64; i++) {
723 r24.a[i] <== in[24*64+i];
724 r24.b[i] <== in[20*64+i];
725 r24.c[i] <== in[21*64+i];
726 }
727
728 for (i=0; i<64; i++) {
729 out[i] <== r0.out[i];
730 out[1*64+i] <== r1.out[i];
731 out[2*64+i] <== r2.out[i];
732 out[3*64+i] <== r3.out[i];
733 out[4*64+i] <== r4.out[i];
734
735 out[5*64+i] <== r5.out[i];
736 out[6*64+i] <== r6.out[i];
737 out[7*64+i] <== r7.out[i];
738 out[8*64+i] <== r8.out[i];
739 out[9*64+i] <== r9.out[i];
740
741 out[10*64+i] <== r10.out[i];
742 out[11*64+i] <== r11.out[i];
743 out[12*64+i] <== r12.out[i];
744 out[13*64+i] <== r13.out[i];
745 out[14*64+i] <== r14.out[i];
746
747 out[15*64+i] <== r15.out[i];
748 out[16*64+i] <== r16.out[i];
749 out[17*64+i] <== r17.out[i];
750 out[18*64+i] <== r18.out[i];
751 out[19*64+i] <== r19.out[i];
752
753 out[20*64+i] <== r20.out[i];
754 out[21*64+i] <== r21.out[i];
755 out[22*64+i] <== r22.out[i];
756 out[23*64+i] <== r23.out[i];
757 out[24*64+i] <== r24.out[i];
758 }
759}
760
761// Iota
762
763template RC(r) {
764 signal output out[64];
765 var rc[24] = [
766 0x0000000000000001, 0x0000000000008082, 0x800000000000808A,
767 0x8000000080008000, 0x000000000000808B, 0x0000000080000001,
768 0x8000000080008081, 0x8000000000008009, 0x000000000000008A,
769 0x0000000000000088, 0x0000000080008009, 0x000000008000000A,
770 0x000000008000808B, 0x800000000000008B, 0x8000000000008089,
771 0x8000000000008003, 0x8000000000008002, 0x8000000000000080,
772 0x000000000000800A, 0x800000008000000A, 0x8000000080008081,
773 0x8000000000008080, 0x0000000080000001, 0x8000000080008008
774 ];
775 for (var i=0; i<64; i++) {
776 out[i] <== (rc[r] >> i) & 1;
777 }
778}
779
780template Iota(r) {
781 signal input in[25*64];
782 signal output out[25*64];
783 var i;
784
785 component rc = RC(r);
786
787 component iota = XorArray(64);
788 for (var i=0; i<64; i++) {
789 iota.a[i] <== in[i];
790 iota.b[i] <== rc.out[i];
791 }
792 for (i=0; i<64; i++) {
793 out[i] <== iota.out[i];
794 }
795 for (i=64; i<25*64; i++) {
796 out[i] <== in[i];
797 }
798}
799