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