You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

799 lines
20 KiB

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