better standard compliance
[rofl0r-kripto.git] / lib / hash / keccak1600.c
blob58f95a67a88648f807dfc6e5937ab09bcfcf1ac8
1 /*
2 * Copyright (C) 2013 Gregor Pintar <grpintar@gmail.com>
4 * Permission is granted to deal in this work without any restriction,
5 * including unlimited rights to use, publicly perform, publish,
6 * reproduce, relicence, modify, merge, and/or distribute in any form,
7 * for any purpose, with or without fee, and by any means.
9 * This work is provided "AS IS" and WITHOUT WARRANTY of any kind,
10 * to the utmost extent permitted by applicable law. In no event
11 * shall a licensor, author or contributor be held liable for any
12 * issues arising in any way out of dealing in the work.
15 #include <stdint.h>
16 #include <stddef.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <limits.h>
21 #include <kripto/cast.h>
22 #include <kripto/loadstore.h>
23 #include <kripto/rotate.h>
24 #include <kripto/memwipe.h>
25 #include <kripto/hash.h>
26 #include <kripto/desc/hash.h>
27 #include <kripto/object/hash.h>
29 #include <kripto/hash/keccak1600.h>
31 struct kripto_hash
33 struct kripto_hash_object obj;
34 unsigned int r;
35 unsigned int rate;
36 unsigned int i;
37 int o;
38 uint8_t s[200];
41 static const uint64_t rc[48] =
43 0x0000000000000001, 0x0000000000008082,
44 0x800000000000808A, 0x8000000080008000,
45 0x000000000000808B, 0x0000000080000001,
46 0x8000000080008081, 0x8000000000008009,
47 0x000000000000008A, 0x0000000000000088,
48 0x0000000080008009, 0x000000008000000A,
49 0x000000008000808B, 0x800000000000008B,
50 0x8000000000008089, 0x8000000000008003,
51 0x8000000000008002, 0x8000000000000080,
52 0x000000000000800A, 0x800000008000000A,
53 0x8000000080008081, 0x8000000000008080,
54 0x0000000080000001, 0x8000000080008008,
55 0x8000000080008082, 0x800000008000800A,
56 0x8000000000000003, 0x8000000080000009,
57 0x8000000000008082, 0x0000000000008009,
58 0x8000000000000080, 0x0000000000008083,
59 0x8000000000000081, 0x0000000000000001,
60 0x000000000000800B, 0x8000000080008001,
61 0x0000000000000080, 0x8000000000008000,
62 0x8000000080008001, 0x0000000000000009,
63 0x800000008000808B, 0x0000000000000081,
64 0x8000000000000082, 0x000000008000008B,
65 0x8000000080008009, 0x8000000080000000,
66 0x0000000080000080, 0x0000000080008003
69 static void keccak1600_F(kripto_hash *s)
71 uint64_t a0 = LOAD64L(s->s);
72 uint64_t a1 = LOAD64L(s->s + 8);
73 uint64_t a2 = LOAD64L(s->s + 16);
74 uint64_t a3 = LOAD64L(s->s + 24);
75 uint64_t a4 = LOAD64L(s->s + 32);
76 uint64_t a5 = LOAD64L(s->s + 40);
77 uint64_t a6 = LOAD64L(s->s + 48);
78 uint64_t a7 = LOAD64L(s->s + 56);
79 uint64_t a8 = LOAD64L(s->s + 64);
80 uint64_t a9 = LOAD64L(s->s + 72);
81 uint64_t a10 = LOAD64L(s->s + 80);
82 uint64_t a11 = LOAD64L(s->s + 88);
83 uint64_t a12 = LOAD64L(s->s + 96);
84 uint64_t a13 = LOAD64L(s->s + 104);
85 uint64_t a14 = LOAD64L(s->s + 112);
86 uint64_t a15 = LOAD64L(s->s + 120);
87 uint64_t a16 = LOAD64L(s->s + 128);
88 uint64_t a17 = LOAD64L(s->s + 136);
89 uint64_t a18 = LOAD64L(s->s + 144);
90 uint64_t a19 = LOAD64L(s->s + 152);
91 uint64_t a20 = LOAD64L(s->s + 160);
92 uint64_t a21 = LOAD64L(s->s + 168);
93 uint64_t a22 = LOAD64L(s->s + 176);
94 uint64_t a23 = LOAD64L(s->s + 184);
95 uint64_t a24 = LOAD64L(s->s + 192);
97 uint64_t b0;
98 uint64_t b1;
99 uint64_t b2;
100 uint64_t b3;
101 uint64_t b4;
102 uint64_t b5;
103 uint64_t b6;
104 uint64_t b7;
105 uint64_t b8;
106 uint64_t b9;
107 uint64_t b10;
108 uint64_t b11;
109 uint64_t b12;
110 uint64_t b13;
111 uint64_t b14;
112 uint64_t b15;
113 uint64_t b16;
114 uint64_t b17;
115 uint64_t b18;
116 uint64_t b19;
117 uint64_t b20;
118 uint64_t b21;
119 uint64_t b22;
120 uint64_t b23;
121 uint64_t b24;
123 uint64_t c0;
124 uint64_t c1;
125 uint64_t c2;
126 uint64_t c3;
127 uint64_t c4;
129 uint64_t d0;
130 uint64_t d1;
131 uint64_t d2;
132 uint64_t d3;
133 uint64_t d4;
135 unsigned int i;
137 for(i = 0; i < s->r; i++)
139 c0 = a0 ^ a5 ^ a10 ^ a15 ^ a20;
140 c1 = a1 ^ a6 ^ a11 ^ a16 ^ a21;
141 c2 = a2 ^ a7 ^ a12 ^ a17 ^ a22;
142 c3 = a3 ^ a8 ^ a13 ^ a18 ^ a23;
143 c4 = a4 ^ a9 ^ a14 ^ a19 ^ a24;
145 d0 = ROL64(c1, 1) ^ c4;
146 d1 = ROL64(c2, 1) ^ c0;
147 d2 = ROL64(c3, 1) ^ c1;
148 d3 = ROL64(c4, 1) ^ c2;
149 d4 = ROL64(c0, 1) ^ c3;
151 a0 ^= d0;
152 c0 = a0;
153 a6 ^= d1;
154 c1 = ROL64(a6, 44);
155 a12 ^= d2;
156 c2 = ROL64(a12, 43);
157 a18 ^= d3;
158 c3 = ROL64(a18, 21);
159 a24 ^= d4;
160 c4 = ROL64(a24, 14);
162 b0 = c0 ^ ((~c1) & c2) ^ rc[i];
163 b1 = c1 ^ ((~c2) & c3);
164 b2 = c2 ^ ((~c3) & c4);
165 b3 = c3 ^ ((~c4) & c0);
166 b4 = c4 ^ ((~c0) & c1);
168 a3 ^= d3;
169 c0 = ROL64(a3, 28);
170 a9 ^= d4;
171 c1 = ROL64(a9, 20);
172 a10 ^= d0;
173 c2 = ROL64(a10, 3);
174 a16 ^= d1;
175 c3 = ROL64(a16, 45);
176 a22 ^= d2;
177 c4 = ROL64(a22, 61);
179 b5 = c0 ^ ((~c1) & c2);
180 b6 = c1 ^ ((~c2) & c3);
181 b7 = c2 ^ ((~c3) & c4);
182 b8 = c3 ^ ((~c4) & c0);
183 b9 = c4 ^ ((~c0) & c1);
185 a1 ^= d1;
186 c0 = ROL64(a1, 1);
187 a7 ^= d2;
188 c1 = ROL64(a7, 6);
189 a13 ^= d3;
190 c2 = ROL64(a13, 25);
191 a19 ^= d4;
192 c3 = ROL64(a19, 8);
193 a20 ^= d0;
194 c4 = ROL64(a20, 18);
196 b10 = c0 ^ ((~c1) & c2);
197 b11 = c1 ^ ((~c2) & c3);
198 b12 = c2 ^ ((~c3) & c4);
199 b13 = c3 ^ ((~c4) & c0);
200 b14 = c4 ^ ((~c0) & c1);
202 a4 ^= d4;
203 c0 = ROL64(a4, 27);
204 a5 ^= d0;
205 c1 = ROL64(a5, 36);
206 a11 ^= d1;
207 c2 = ROL64(a11, 10);
208 a17 ^= d2;
209 c3 = ROL64(a17, 15);
210 a23 ^= d3;
211 c4 = ROL64(a23, 56);
213 b15 = c0 ^ ((~c1) & c2);
214 b16 = c1 ^ ((~c2) & c3);
215 b17 = c2 ^ ((~c3) & c4);
216 b18 = c3 ^ ((~c4) & c0);
217 b19 = c4 ^ ((~c0) & c1);
219 a2 ^= d2;
220 c0 = ROL64(a2, 62);
221 a8 ^= d3;
222 c1 = ROL64(a8, 55);
223 a14 ^= d4;
224 c2 = ROL64(a14, 39);
225 a15 ^= d0;
226 c3 = ROL64(a15, 41);
227 a21 ^= d1;
228 c4 = ROL64(a21, 2);
230 b20 = c0 ^ ((~c1) & c2);
231 b21 = c1 ^ ((~c2) & c3);
232 b22 = c2 ^ ((~c3) & c4);
233 b23 = c3 ^ ((~c4) & c0);
234 b24 = c4 ^ ((~c0) & c1);
236 a0 = b0;
237 a1 = b1;
238 a2 = b2;
239 a3 = b3;
240 a4 = b4;
241 a5 = b5;
242 a6 = b6;
243 a7 = b7;
244 a8 = b8;
245 a9 = b9;
246 a10 = b10;
247 a11 = b11;
248 a12 = b12;
249 a13 = b13;
250 a14 = b14;
251 a15 = b15;
252 a16 = b16;
253 a17 = b17;
254 a18 = b18;
255 a19 = b19;
256 a20 = b20;
257 a21 = b21;
258 a22 = b22;
259 a23 = b23;
260 a24 = b24;
263 STORE64L(a0, s->s);
264 STORE64L(a1, s->s + 8);
265 STORE64L(a2, s->s + 16);
266 STORE64L(a3, s->s + 24);
267 STORE64L(a4, s->s + 32);
268 STORE64L(a5, s->s + 40);
269 STORE64L(a6, s->s + 48);
270 STORE64L(a7, s->s + 56);
271 STORE64L(a8, s->s + 64);
272 STORE64L(a9, s->s + 72);
273 STORE64L(a10, s->s + 80);
274 STORE64L(a11, s->s + 88);
275 STORE64L(a12, s->s + 96);
276 STORE64L(a13, s->s + 104);
277 STORE64L(a14, s->s + 112);
278 STORE64L(a15, s->s + 120);
279 STORE64L(a16, s->s + 128);
280 STORE64L(a17, s->s + 136);
281 STORE64L(a18, s->s + 144);
282 STORE64L(a19, s->s + 152);
283 STORE64L(a20, s->s + 160);
284 STORE64L(a21, s->s + 168);
285 STORE64L(a22, s->s + 176);
286 STORE64L(a23, s->s + 184);
287 STORE64L(a24, s->s + 192);
290 static kripto_hash *keccak1600_recreate
292 kripto_hash *s,
293 unsigned int r,
294 size_t len
297 s->o = s->i = 0;
299 s->r = r;
300 if(!s->r) s->r = 24;
302 s->rate = 200 - (len << 1);
304 memset(s->s, 0, 200);
306 return s;
309 static void keccak1600_input
311 kripto_hash *s,
312 const void *in,
313 size_t len
316 size_t i;
318 /* switch back to input mode */
319 if(s->o) s->o = s->i = 0;
321 /* input */
322 for(i = 0; i < len; i++)
324 s->s[s->i++] ^= CU8(in)[i];
326 if(s->i == s->rate)
328 keccak1600_F(s);
329 s->i = 0;
334 static void keccak1600_output
336 kripto_hash *s,
337 void *out,
338 size_t len
341 size_t i;
343 /* switch to output mode */
344 if(!s->o)
346 /* pad */
347 s->s[s->i] ^= 0x01;
348 s->s[s->rate - 1] ^= 0x80;
350 keccak1600_F(s);
352 s->i = 0;
353 s->o = -1;
356 /* output */
357 for(i = 0; i < len; i++)
359 if(s->i == s->rate)
361 keccak1600_F(s);
362 s->i = 0;
365 U8(out)[i] = s->s[s->i++];
369 static kripto_hash *keccak1600_create(unsigned int r, size_t len)
371 kripto_hash *s;
373 s = malloc(sizeof(struct kripto_hash));
374 if(!s) return 0;
376 s->obj.desc = kripto_hash_keccak1600;
378 (void)keccak1600_recreate(s, r, len);
380 return s;
383 static void keccak1600_destroy(kripto_hash *s)
385 kripto_memwipe(s, sizeof(kripto_hash));
386 free(s);
389 static int keccak1600_hash
391 unsigned int r,
392 const void *in,
393 size_t in_len,
394 void *out,
395 size_t out_len
398 kripto_hash s;
400 (void)keccak1600_recreate(&s, r, out_len);
401 keccak1600_input(&s, in, in_len);
402 keccak1600_output(&s, out, out_len);
404 kripto_memwipe(&s, sizeof(kripto_hash));
406 return 0;
409 static const kripto_hash_desc keccak1600 =
411 &keccak1600_create,
412 &keccak1600_recreate,
413 &keccak1600_input,
414 &keccak1600_output,
415 &keccak1600_destroy,
416 &keccak1600_hash,
417 SIZE_MAX, /* max output */
418 200 /* block_size */
421 const kripto_hash_desc *const kripto_hash_keccak1600 = &keccak1600;
423 const kripto_hash_desc *const kripto_hash_sha3 = &keccak1600;