better standard compliance
[rofl0r-kripto.git] / lib / hash / blake2s.c
blob4604381577932be14b411a8c96098b331af36559
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 <limits.h>
19 #include <assert.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/blake2s.h>
31 struct kripto_hash
33 struct kripto_hash_object obj;
34 unsigned int r;
35 uint32_t h[8];
36 uint32_t len[2];
37 uint32_t f;
38 uint8_t buf[64];
39 unsigned int i;
42 static const uint8_t sigma[10][16] =
44 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
45 {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
46 {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4},
47 { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8},
48 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13},
49 { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9},
50 {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11},
51 {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10},
52 { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5},
53 {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0}
56 static const uint32_t iv[8] =
58 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
59 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
62 static kripto_hash *blake2s_recreate
64 kripto_hash *s,
65 unsigned int r,
66 size_t len
69 s->r = r;
70 if(!s->r) s->r = 10;
72 s->f = s->len[0] = s->len[1] = s->i = 0;
74 /* s->h[0] = iv[0] ^ 0x01010020; */
75 s->h[0] = iv[0] ^ 0x01010000 ^ (uint8_t)len;
76 s->h[1] = iv[1];
77 s->h[2] = iv[2];
78 s->h[3] = iv[3];
79 s->h[4] = iv[4];
80 s->h[5] = iv[5];
81 s->h[6] = iv[6];
82 s->h[7] = iv[7];
84 return s;
87 #define G(A, B, C, D, M0, M1) \
88 { \
89 A += B + (M0); \
90 D = ROR32(D ^ A, 16); \
91 C += D; \
92 B = ROR32(B ^ C, 12); \
94 A += B + (M1); \
95 D = ROR32(D ^ A, 8); \
96 C += D; \
97 B = ROR32(B ^ C, 7); \
100 static void blake2s_process(kripto_hash *s, const uint8_t *data)
102 uint32_t x0;
103 uint32_t x1;
104 uint32_t x2;
105 uint32_t x3;
106 uint32_t x4;
107 uint32_t x5;
108 uint32_t x6;
109 uint32_t x7;
110 uint32_t x8;
111 uint32_t x9;
112 uint32_t x10;
113 uint32_t x11;
114 uint32_t x12;
115 uint32_t x13;
116 uint32_t x14;
117 uint32_t x15;
118 uint32_t m[16];
119 unsigned int r;
120 unsigned int i;
122 m[0] = LOAD32L(data);
123 m[1] = LOAD32L(data + 4);
124 m[2] = LOAD32L(data + 8);
125 m[3] = LOAD32L(data + 12);
126 m[4] = LOAD32L(data + 16);
127 m[5] = LOAD32L(data + 20);
128 m[6] = LOAD32L(data + 24);
129 m[7] = LOAD32L(data + 28);
130 m[8] = LOAD32L(data + 32);
131 m[9] = LOAD32L(data + 36);
132 m[10] = LOAD32L(data + 40);
133 m[11] = LOAD32L(data + 44);
134 m[12] = LOAD32L(data + 48);
135 m[13] = LOAD32L(data + 52);
136 m[14] = LOAD32L(data + 56);
137 m[15] = LOAD32L(data + 60);
139 x0 = s->h[0];
140 x1 = s->h[1];
141 x2 = s->h[2];
142 x3 = s->h[3];
143 x4 = s->h[4];
144 x5 = s->h[5];
145 x6 = s->h[6];
146 x7 = s->h[7];
147 x8 = iv[0];
148 x9 = iv[1];
149 x10 = iv[2];
150 x11 = iv[3];
151 x12 = iv[4] ^ s->len[0];
152 x13 = iv[5] ^ s->len[1];
153 x14 = iv[6] ^ s->f;
154 x15 = iv[7];
156 for(r = 0, i = 0; r < s->r; r++, i++)
158 if(i == 10) i = 0;
160 G(x0, x4, x8, x12, m[sigma[i][0]], m[sigma[i][1]]);
161 G(x1, x5, x9, x13, m[sigma[i][2]], m[sigma[i][3]]);
162 G(x2, x6, x10, x14, m[sigma[i][4]], m[sigma[i][5]]);
163 G(x3, x7, x11, x15, m[sigma[i][6]], m[sigma[i][7]]);
165 G(x0, x5, x10, x15, m[sigma[i][8]], m[sigma[i][9]]);
166 G(x1, x6, x11, x12, m[sigma[i][10]], m[sigma[i][11]]);
167 G(x2, x7, x8, x13, m[sigma[i][12]], m[sigma[i][13]]);
168 G(x3, x4, x9, x14, m[sigma[i][14]], m[sigma[i][15]]);
171 kripto_memwipe(m, 64);
173 s->h[0] ^= x0 ^ x8;
174 s->h[1] ^= x1 ^ x9;
175 s->h[2] ^= x2 ^ x10;
176 s->h[3] ^= x3 ^ x11;
177 s->h[4] ^= x4 ^ x12;
178 s->h[5] ^= x5 ^ x13;
179 s->h[6] ^= x6 ^ x14;
180 s->h[7] ^= x7 ^ x15;
183 static void blake2s_input
185 kripto_hash *s,
186 const void *in,
187 size_t len
190 size_t i;
192 for(i = 0; i < len; i++)
194 if(s->i == 64)
196 s->len[0] += 64;
197 if(!s->len[0])
199 s->len[1]++;
200 assert(s->len[1]);
203 blake2s_process(s, s->buf);
204 s->i = 0;
207 s->buf[s->i++] = CU8(in)[i];
211 static void blake2s_finish(kripto_hash *s)
213 s->len[0] += s->i;
214 if(s->len[0] < s->i) s->len[1]++;
216 while(s->i < 64) s->buf[s->i++] = 0;
218 s->f = 0xFFFFFFFF;
220 blake2s_process(s, s->buf);
222 s->i = 0;
225 static void blake2s_output(kripto_hash *s, void *out, size_t len)
227 unsigned int i;
229 if(!s->f) blake2s_finish(s);
231 /* little endian */
232 for(i = 0; i < len; s->i++, i++)
234 U8(out)[i] = s->h[s->i >> 2];
235 s->h[s->i >> 2] >>= 8;
239 static kripto_hash *blake2s_create(unsigned int r, size_t len)
241 kripto_hash *s;
243 s = malloc(sizeof(kripto_hash));
244 if(!s) return 0;
246 s->obj.desc = kripto_hash_blake2s;
248 (void)blake2s_recreate(s, r, len);
250 return s;
253 static void blake2s_destroy(kripto_hash *s)
255 kripto_memwipe(s, sizeof(kripto_hash));
256 free(s);
259 static int blake2s_hash
261 unsigned int r,
262 const void *in,
263 size_t in_len,
264 void *out,
265 size_t out_len
268 kripto_hash s;
270 (void)blake2s_recreate(&s, r, out_len);
271 blake2s_input(&s, in, in_len);
272 blake2s_output(&s, out, out_len);
274 kripto_memwipe(&s, sizeof(kripto_hash));
276 return 0;
279 static const kripto_hash_desc blake2s =
281 &blake2s_create,
282 &blake2s_recreate,
283 &blake2s_input,
284 &blake2s_output,
285 &blake2s_destroy,
286 &blake2s_hash,
287 32, /* max output */
288 64 /* block_size */
291 const kripto_hash_desc *const kripto_hash_blake2s = &blake2s;