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