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.
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>
33 struct kripto_hash_object obj
;
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
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
;
87 #define G(A, B, C, D, M0, M1) \
90 D = ROR32(D ^ A, 16); \
92 B = ROR32(B ^ C, 12); \
95 D = ROR32(D ^ A, 8); \
97 B = ROR32(B ^ C, 7); \
100 static void blake2s_process(kripto_hash
*s
, const uint8_t *data
)
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);
151 x12
= iv
[4] ^ s
->len
[0];
152 x13
= iv
[5] ^ s
->len
[1];
156 for(r
= 0, i
= 0; r
< s
->r
; r
++, i
++)
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);
183 static void blake2s_input
192 for(i
= 0; i
< len
; i
++)
203 blake2s_process(s
, s
->buf
);
207 s
->buf
[s
->i
++] = CU8(in
)[i
];
211 static void blake2s_finish(kripto_hash
*s
)
214 if(s
->len
[0] < s
->i
) s
->len
[1]++;
216 while(s
->i
< 64) s
->buf
[s
->i
++] = 0;
220 blake2s_process(s
, s
->buf
);
225 static void blake2s_output(kripto_hash
*s
, void *out
, size_t len
)
229 if(!s
->f
) blake2s_finish(s
);
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
)
243 s
= malloc(sizeof(kripto_hash
));
246 s
->obj
.desc
= kripto_hash_blake2s
;
248 (void)blake2s_recreate(s
, r
, len
);
253 static void blake2s_destroy(kripto_hash
*s
)
255 kripto_memwipe(s
, sizeof(kripto_hash
));
259 static int blake2s_hash
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
));
279 static const kripto_hash_desc blake2s
=
291 const kripto_hash_desc
*const kripto_hash_blake2s
= &blake2s
;