keccak256-circom/circuits/keccak256.circom
circuits/keccak256.circomRaw
1pragma circom 2.0.0;
2
3include "./utils.circom";
4include "./theta.circom";
5include "./rhopi.circom";
6include "./chi.circom";
7include "./iota.circom";
8
9template Pad(nBits) {
10 signal input in[nBits];
11
12 var blockSize=136*8;
13 signal output out[blockSize];
14 signal out2[blockSize];
15
16 var i;
17
18 for (i=0; i<nBits; i++) {
19 out2[i] <== in[i];
20 }
21 var domain = 0x01;
22 for (i=0; i<8; i++) {
23 out2[nBits+i] <== (domain >> i) & 1;
24 }
25 for (i=nBits+8; i<blockSize; i++) {
26 out2[i] <== 0;
27 }
28 component aux = OrArray(8);
29 for (i=0; i<8; i++) {
30 aux.a[i] <== out2[blockSize-8+i];
31 aux.b[i] <== (0x80 >> i) & 1;
32 }
33 for (i=0; i<8; i++) {
34 out[blockSize-8+i] <== aux.out[i];
35 }
36 for (i=0; i<blockSize-8; i++) {
37 out[i]<==out2[i];
38 }
39}
40
41template KeccakfRound(r) {
42 signal input in[25*64];
43 signal output out[25*64];
44 var i;
45
46 component theta = Theta();
47 component rhopi = RhoPi();
48 component chi = Chi();
49 component iota = Iota(r);
50
51 for (i=0; i<25*64; i++) {
52 theta.in[i] <== in[i];
53 }
54 for (i=0; i<25*64; i++) {
55 rhopi.in[i] <== theta.out[i];
56 }
57 for (i=0; i<25*64; i++) {
58 chi.in[i] <== rhopi.out[i];
59 }
60 for (i=0; i<25*64; i++) {
61 iota.in[i] <== chi.out[i];
62 }
63 for (i=0; i<25*64; i++) {
64 out[i] <== iota.out[i];
65 }
66}
67
68template Keccakf() {
69 signal input in[25*64];
70 signal output out[25*64];
71 var i;
72 var j;
73
74 // 24 rounds
75 component round[24];
76 signal midRound[24*25*64];
77 for (i=0; i<24; i++) {
78 round[i] = KeccakfRound(i);
79 if (i==0) {
80 for (j=0; j<25*64; j++) {
81 midRound[j] <== in[j];
82 }
83 }
84 for (j=0; j<25*64; j++) {
85 round[i].in[j] <== midRound[i*25*64+j];
86 }
87 if (i<23) {
88 for (j=0; j<25*64; j++) {
89 midRound[(i+1)*25*64+j] <== round[i].out[j];
90 }
91 }
92 }
93
94 for (i=0; i<25*64; i++) {
95 out[i] <== round[23].out[i];
96 }
97}