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.
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/>.
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/blake2s.h>
32 struct kripto_hash_object obj
;
41 static const uint8_t sigma
[10][16] =
43 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
44 {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
45 {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4},
46 { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8},
47 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13},
48 { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9},
49 {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11},
50 {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10},
51 { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5},
52 {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0}
55 static const uint32_t iv
[8] =
57 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
58 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
61 static kripto_hash
*blake2s_recreate
71 s
->f
= s
->len
[0] = s
->len
[1] = s
->i
= 0;
73 /* s->h[0] = iv[0] ^ 0x01010020; */
74 s
->h
[0] = iv
[0] ^ 0x01010000 ^ (uint8_t)len
;
86 #define G(A, B, C, D, M0, M1) \
89 D = ROR32_16(D ^ A); \
91 B = ROR32_12(B ^ C); \
94 D = ROR32_08(D ^ A); \
96 B = ROR32_07(B ^ C); \
99 static void blake2s_process(kripto_hash
*s
, const uint8_t *data
)
121 m
[0] = LOAD32L(data
);
122 m
[1] = LOAD32L(data
+ 4);
123 m
[2] = LOAD32L(data
+ 8);
124 m
[3] = LOAD32L(data
+ 12);
125 m
[4] = LOAD32L(data
+ 16);
126 m
[5] = LOAD32L(data
+ 20);
127 m
[6] = LOAD32L(data
+ 24);
128 m
[7] = LOAD32L(data
+ 28);
129 m
[8] = LOAD32L(data
+ 32);
130 m
[9] = LOAD32L(data
+ 36);
131 m
[10] = LOAD32L(data
+ 40);
132 m
[11] = LOAD32L(data
+ 44);
133 m
[12] = LOAD32L(data
+ 48);
134 m
[13] = LOAD32L(data
+ 52);
135 m
[14] = LOAD32L(data
+ 56);
136 m
[15] = LOAD32L(data
+ 60);
150 x12
= iv
[4] ^ s
->len
[0];
151 x13
= iv
[5] ^ s
->len
[1];
155 for(r
= 0, i
= 0; r
< s
->r
; r
++, i
++)
159 G(x0
, x4
, x8
, x12
, m
[sigma
[i
][0]], m
[sigma
[i
][1]]);
160 G(x1
, x5
, x9
, x13
, m
[sigma
[i
][2]], m
[sigma
[i
][3]]);
161 G(x2
, x6
, x10
, x14
, m
[sigma
[i
][4]], m
[sigma
[i
][5]]);
162 G(x3
, x7
, x11
, x15
, m
[sigma
[i
][6]], m
[sigma
[i
][7]]);
164 G(x0
, x5
, x10
, x15
, m
[sigma
[i
][8]], m
[sigma
[i
][9]]);
165 G(x1
, x6
, x11
, x12
, m
[sigma
[i
][10]], m
[sigma
[i
][11]]);
166 G(x2
, x7
, x8
, x13
, m
[sigma
[i
][12]], m
[sigma
[i
][13]]);
167 G(x3
, x4
, x9
, x14
, m
[sigma
[i
][14]], m
[sigma
[i
][15]]);
170 kripto_memwipe(m
, 64);
182 static void blake2s_input
191 for(i
= 0; i
< len
; i
++)
202 blake2s_process(s
, s
->buf
);
206 s
->buf
[s
->i
++] = CU8(in
)[i
];
210 static void blake2s_finish(kripto_hash
*s
)
213 if(s
->len
[0] < s
->i
) s
->len
[1]++;
215 while(s
->i
< 64) s
->buf
[s
->i
++] = 0;
219 blake2s_process(s
, s
->buf
);
224 static void blake2s_output(kripto_hash
*s
, void *out
, size_t len
)
228 if(!s
->f
) blake2s_finish(s
);
231 for(i
= 0; i
< len
; s
->i
++, i
++)
233 U8(out
)[i
] = s
->h
[s
->i
>> 2];
234 s
->h
[s
->i
>> 2] >>= 8;
238 static kripto_hash
*blake2s_create(unsigned int r
, size_t len
)
242 s
= malloc(sizeof(kripto_hash
));
245 s
->obj
.desc
= kripto_hash_blake2s
;
247 (void)blake2s_recreate(s
, r
, len
);
252 static void blake2s_destroy(kripto_hash
*s
)
254 kripto_memwipe(s
, sizeof(kripto_hash
));
258 static int blake2s_hash
269 (void)blake2s_recreate(&s
, r
, out_len
);
270 blake2s_input(&s
, in
, in_len
);
271 blake2s_output(&s
, out
, out_len
);
273 kripto_memwipe(&s
, sizeof(kripto_hash
));
278 static const kripto_hash_desc blake2s
=
290 const kripto_hash_desc
*const kripto_hash_blake2s
= &blake2s
;