arnaucube
arnaucube/keccak256-circomPublic Self-hosted repository
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