status update, probably last commit
[rofl0r-kripto.git] / lib / hash / keccak1600.c
blobf7c254ddc295241dc569277ddf713cd99b72c1d6
1 /*
2 * Written in 2013 by Gregor Pintar <grpintar@gmail.com>
4 * To the extent possible under law, the author(s) have dedicated
5 * all copyright and related and neighboring rights to this software
6 * to the public domain worldwide.
7 *
8 * This software is distributed without any warranty.
10 * You should have received a copy of the CC0 Public Domain Dedication.
11 * If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
14 #include <stdint.h>
15 #include <stddef.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <limits.h>
20 #include <kripto/cast.h>
21 #include <kripto/loadstore.h>
22 #include <kripto/rotate.h>
23 #include <kripto/memwipe.h>
24 #include <kripto/hash.h>
25 #include <kripto/desc/hash.h>
26 #include <kripto/object/hash.h>
28 #include <kripto/hash/keccak1600.h>
30 struct kripto_hash
32 struct kripto_hash_object obj;
33 unsigned int r;
34 unsigned int rate;
35 unsigned int i;
36 int o;
37 uint8_t s[200];
40 static const uint64_t rc[48] =
42 0x0000000000000001, 0x0000000000008082,
43 0x800000000000808A, 0x8000000080008000,
44 0x000000000000808B, 0x0000000080000001,
45 0x8000000080008081, 0x8000000000008009,
46 0x000000000000008A, 0x0000000000000088,
47 0x0000000080008009, 0x000000008000000A,
48 0x000000008000808B, 0x800000000000008B,
49 0x8000000000008089, 0x8000000000008003,
50 0x8000000000008002, 0x8000000000000080,
51 0x000000000000800A, 0x800000008000000A,
52 0x8000000080008081, 0x8000000000008080,
53 0x0000000080000001, 0x8000000080008008,
54 0x8000000080008082, 0x800000008000800A,
55 0x8000000000000003, 0x8000000080000009,
56 0x8000000000008082, 0x0000000000008009,
57 0x8000000000000080, 0x0000000000008083,
58 0x8000000000000081, 0x0000000000000001,
59 0x000000000000800B, 0x8000000080008001,
60 0x0000000000000080, 0x8000000000008000,
61 0x8000000080008001, 0x0000000000000009,
62 0x800000008000808B, 0x0000000000000081,
63 0x8000000000000082, 0x000000008000008B,
64 0x8000000080008009, 0x8000000080000000,
65 0x0000000080000080, 0x0000000080008003
68 static void keccak1600_F(kripto_hash *s)
70 uint64_t a0 = LOAD64L(s->s);
71 uint64_t a1 = LOAD64L(s->s + 8);
72 uint64_t a2 = LOAD64L(s->s + 16);
73 uint64_t a3 = LOAD64L(s->s + 24);
74 uint64_t a4 = LOAD64L(s->s + 32);
75 uint64_t a5 = LOAD64L(s->s + 40);
76 uint64_t a6 = LOAD64L(s->s + 48);
77 uint64_t a7 = LOAD64L(s->s + 56);
78 uint64_t a8 = LOAD64L(s->s + 64);
79 uint64_t a9 = LOAD64L(s->s + 72);
80 uint64_t a10 = LOAD64L(s->s + 80);
81 uint64_t a11 = LOAD64L(s->s + 88);
82 uint64_t a12 = LOAD64L(s->s + 96);
83 uint64_t a13 = LOAD64L(s->s + 104);
84 uint64_t a14 = LOAD64L(s->s + 112);
85 uint64_t a15 = LOAD64L(s->s + 120);
86 uint64_t a16 = LOAD64L(s->s + 128);
87 uint64_t a17 = LOAD64L(s->s + 136);
88 uint64_t a18 = LOAD64L(s->s + 144);
89 uint64_t a19 = LOAD64L(s->s + 152);
90 uint64_t a20 = LOAD64L(s->s + 160);
91 uint64_t a21 = LOAD64L(s->s + 168);
92 uint64_t a22 = LOAD64L(s->s + 176);
93 uint64_t a23 = LOAD64L(s->s + 184);
94 uint64_t a24 = LOAD64L(s->s + 192);
96 uint64_t b0;
97 uint64_t b1;
98 uint64_t b2;
99 uint64_t b3;
100 uint64_t b4;
101 uint64_t b5;
102 uint64_t b6;
103 uint64_t b7;
104 uint64_t b8;
105 uint64_t b9;
106 uint64_t b10;
107 uint64_t b11;
108 uint64_t b12;
109 uint64_t b13;
110 uint64_t b14;
111 uint64_t b15;
112 uint64_t b16;
113 uint64_t b17;
114 uint64_t b18;
115 uint64_t b19;
116 uint64_t b20;
117 uint64_t b21;
118 uint64_t b22;
119 uint64_t b23;
120 uint64_t b24;
122 uint64_t c0;
123 uint64_t c1;
124 uint64_t c2;
125 uint64_t c3;
126 uint64_t c4;
128 uint64_t d0;
129 uint64_t d1;
130 uint64_t d2;
131 uint64_t d3;
132 uint64_t d4;
134 unsigned int i;
136 for(i = 0; i < s->r; i++)
138 c0 = a0 ^ a5 ^ a10 ^ a15 ^ a20;
139 c1 = a1 ^ a6 ^ a11 ^ a16 ^ a21;
140 c2 = a2 ^ a7 ^ a12 ^ a17 ^ a22;
141 c3 = a3 ^ a8 ^ a13 ^ a18 ^ a23;
142 c4 = a4 ^ a9 ^ a14 ^ a19 ^ a24;
144 d0 = ROL64_01(c1) ^ c4;
145 d1 = ROL64_01(c2) ^ c0;
146 d2 = ROL64_01(c3) ^ c1;
147 d3 = ROL64_01(c4) ^ c2;
148 d4 = ROL64_01(c0) ^ c3;
150 a0 ^= d0;
151 c0 = a0;
152 a6 ^= d1;
153 c1 = ROL64_44(a6);
154 a12 ^= d2;
155 c2 = ROL64_43(a12);
156 a18 ^= d3;
157 c3 = ROL64_21(a18);
158 a24 ^= d4;
159 c4 = ROL64_14(a24);
161 b0 = c0 ^ ((~c1) & c2) ^ rc[i];
162 b1 = c1 ^ ((~c2) & c3);
163 b2 = c2 ^ ((~c3) & c4);
164 b3 = c3 ^ ((~c4) & c0);
165 b4 = c4 ^ ((~c0) & c1);
167 a3 ^= d3;
168 c0 = ROL64_28(a3);
169 a9 ^= d4;
170 c1 = ROL64_20(a9);
171 a10 ^= d0;
172 c2 = ROL64_03(a10);
173 a16 ^= d1;
174 c3 = ROL64_45(a16);
175 a22 ^= d2;
176 c4 = ROL64_61(a22);
178 b5 = c0 ^ ((~c1) & c2);
179 b6 = c1 ^ ((~c2) & c3);
180 b7 = c2 ^ ((~c3) & c4);
181 b8 = c3 ^ ((~c4) & c0);
182 b9 = c4 ^ ((~c0) & c1);
184 a1 ^= d1;
185 c0 = ROL64_01(a1);
186 a7 ^= d2;
187 c1 = ROL64_06(a7);
188 a13 ^= d3;
189 c2 = ROL64_25(a13);
190 a19 ^= d4;
191 c3 = ROL64_08(a19);
192 a20 ^= d0;
193 c4 = ROL64_18(a20);
195 b10 = c0 ^ ((~c1) & c2);
196 b11 = c1 ^ ((~c2) & c3);
197 b12 = c2 ^ ((~c3) & c4);
198 b13 = c3 ^ ((~c4) & c0);
199 b14 = c4 ^ ((~c0) & c1);
201 a4 ^= d4;
202 c0 = ROL64_27(a4);
203 a5 ^= d0;
204 c1 = ROL64_36(a5);
205 a11 ^= d1;
206 c2 = ROL64_10(a11);
207 a17 ^= d2;
208 c3 = ROL64_15(a17);
209 a23 ^= d3;
210 c4 = ROL64_56(a23);
212 b15 = c0 ^ ((~c1) & c2);
213 b16 = c1 ^ ((~c2) & c3);
214 b17 = c2 ^ ((~c3) & c4);
215 b18 = c3 ^ ((~c4) & c0);
216 b19 = c4 ^ ((~c0) & c1);
218 a2 ^= d2;
219 c0 = ROL64_62(a2);
220 a8 ^= d3;
221 c1 = ROL64_55(a8);
222 a14 ^= d4;
223 c2 = ROL64_39(a14);
224 a15 ^= d0;
225 c3 = ROL64_41(a15);
226 a21 ^= d1;
227 c4 = ROL64_02(a21);
229 b20 = c0 ^ ((~c1) & c2);
230 b21 = c1 ^ ((~c2) & c3);
231 b22 = c2 ^ ((~c3) & c4);
232 b23 = c3 ^ ((~c4) & c0);
233 b24 = c4 ^ ((~c0) & c1);
235 a0 = b0;
236 a1 = b1;
237 a2 = b2;
238 a3 = b3;
239 a4 = b4;
240 a5 = b5;
241 a6 = b6;
242 a7 = b7;
243 a8 = b8;
244 a9 = b9;
245 a10 = b10;
246 a11 = b11;
247 a12 = b12;
248 a13 = b13;
249 a14 = b14;
250 a15 = b15;
251 a16 = b16;
252 a17 = b17;
253 a18 = b18;
254 a19 = b19;
255 a20 = b20;
256 a21 = b21;
257 a22 = b22;
258 a23 = b23;
259 a24 = b24;
262 STORE64L(a0, s->s);
263 STORE64L(a1, s->s + 8);
264 STORE64L(a2, s->s + 16);
265 STORE64L(a3, s->s + 24);
266 STORE64L(a4, s->s + 32);
267 STORE64L(a5, s->s + 40);
268 STORE64L(a6, s->s + 48);
269 STORE64L(a7, s->s + 56);
270 STORE64L(a8, s->s + 64);
271 STORE64L(a9, s->s + 72);
272 STORE64L(a10, s->s + 80);
273 STORE64L(a11, s->s + 88);
274 STORE64L(a12, s->s + 96);
275 STORE64L(a13, s->s + 104);
276 STORE64L(a14, s->s + 112);
277 STORE64L(a15, s->s + 120);
278 STORE64L(a16, s->s + 128);
279 STORE64L(a17, s->s + 136);
280 STORE64L(a18, s->s + 144);
281 STORE64L(a19, s->s + 152);
282 STORE64L(a20, s->s + 160);
283 STORE64L(a21, s->s + 168);
284 STORE64L(a22, s->s + 176);
285 STORE64L(a23, s->s + 184);
286 STORE64L(a24, s->s + 192);
289 static kripto_hash *keccak1600_recreate
291 kripto_hash *s,
292 unsigned int r,
293 size_t len
296 s->o = s->i = 0;
298 s->r = r;
299 if(!s->r) s->r = 24;
301 s->rate = 200 - (len << 1);
303 memset(s->s, 0, 200);
305 return s;
308 static void keccak1600_input
310 kripto_hash *s,
311 const void *in,
312 size_t len
315 size_t i;
317 /* switch back to input mode */
318 if(s->o) s->o = s->i = 0;
320 /* input */
321 for(i = 0; i < len; i++)
323 if(s->i == s->rate)
325 keccak1600_F(s);
326 s->i = 0;
329 s->s[s->i++] ^= CU8(in)[i];
333 static void keccak1600_output
335 kripto_hash *s,
336 void *out,
337 size_t len
340 size_t i;
342 /* switch to output mode */
343 if(!s->o)
345 /* pad */
346 s->s[s->i] ^= 0x01;
347 s->s[s->rate - 1] ^= 0x80;
349 keccak1600_F(s);
351 s->i = 0;
352 s->o = -1;
355 /* output */
356 for(i = 0; i < len; i++)
358 if(s->i == s->rate)
360 keccak1600_F(s);
361 s->i = 0;
364 U8(out)[i] = s->s[s->i++];
368 static kripto_hash *keccak1600_create(unsigned int r, size_t len)
370 kripto_hash *s;
372 s = malloc(sizeof(struct kripto_hash));
373 if(!s) return 0;
375 s->obj.desc = kripto_hash_keccak1600;
377 (void)keccak1600_recreate(s, r, len);
379 return s;
382 static void keccak1600_destroy(kripto_hash *s)
384 kripto_memwipe(s, sizeof(kripto_hash));
385 free(s);
388 static int keccak1600_hash
390 unsigned int r,
391 const void *in,
392 size_t in_len,
393 void *out,
394 size_t out_len
397 kripto_hash s;
399 (void)keccak1600_recreate(&s, r, out_len);
400 keccak1600_input(&s, in, in_len);
401 keccak1600_output(&s, out, out_len);
403 kripto_memwipe(&s, sizeof(kripto_hash));
405 return 0;
408 static const kripto_hash_desc keccak1600 =
410 &keccak1600_create,
411 &keccak1600_recreate,
412 &keccak1600_input,
413 &keccak1600_output,
414 &keccak1600_destroy,
415 &keccak1600_hash,
416 SIZE_MAX, /* max output */
417 200 /* block_size */
420 const kripto_hash_desc *const kripto_hash_keccak1600 = &keccak1600;