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