authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-11 17:29:18-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-11 17:29:18-04:00
loga1132ffe0ff965ab48c160a658f11bae345bf2d2
tree9e77c3cd876108714ef7669edc8ee7e69fc83fa1
parent9227315bf24238c05c0c01a9f516449aa8525e41

stage1: build blake code with -std=c99


3 files changed, 546 insertions(+), 545 deletions(-)

CMakeLists.txt+7-6
...@@ -426,8 +426,8 @@ set(ZIG_SOURCES...@@ -426,8 +426,8 @@ set(ZIG_SOURCES
426 "${CMAKE_SOURCE_DIR}/src/util.cpp"426 "${CMAKE_SOURCE_DIR}/src/util.cpp"
427 "${CMAKE_SOURCE_DIR}/src/translate_c.cpp"427 "${CMAKE_SOURCE_DIR}/src/translate_c.cpp"
428)428)
429set(ZIG_SOURCES_O3429set(BLAKE_SOURCES
430 "${CMAKE_SOURCE_DIR}/src/blake2b.cpp"430 "${CMAKE_SOURCE_DIR}/src/blake2b.c"
431)431)
432set(ZIG_CPP_SOURCES432set(ZIG_CPP_SOURCES
433 "${CMAKE_SOURCE_DIR}/src/zig_llvm.cpp"433 "${CMAKE_SOURCE_DIR}/src/zig_llvm.cpp"
...@@ -795,6 +795,7 @@ else()...@@ -795,6 +795,7 @@ else()
795 set(EXE_CFLAGS "${EXE_CFLAGS} -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D_GNU_SOURCE -fno-exceptions -fno-rtti -Werror=strict-prototypes -Werror=old-style-definition -Werror=type-limits -Wno-missing-braces")795 set(EXE_CFLAGS "${EXE_CFLAGS} -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D_GNU_SOURCE -fno-exceptions -fno-rtti -Werror=strict-prototypes -Werror=old-style-definition -Werror=type-limits -Wno-missing-braces")
796endif()796endif()
797797
798set(BLAKE_CFLAGS "-std=c99")
798799
799set(EXE_LDFLAGS " ")800set(EXE_LDFLAGS " ")
800if(MINGW)801if(MINGW)
...@@ -816,9 +817,9 @@ set_target_properties(zig_cpp PROPERTIES...@@ -816,9 +817,9 @@ set_target_properties(zig_cpp PROPERTIES
816 COMPILE_FLAGS ${EXE_CFLAGS}817 COMPILE_FLAGS ${EXE_CFLAGS}
817)818)
818819
819add_library(zig_O3 STATIC ${ZIG_SOURCES_O3})820add_library(embedded_blake STATIC ${BLAKE_SOURCES})
820set_target_properties(zig_O3 PROPERTIES821set_target_properties(embedded_blake PROPERTIES
821 COMPILE_FLAGS "${EXE_CFLAGS} -O3"822 COMPILE_FLAGS "${BLAKE_CFLAGS} -O3"
822)823)
823824
824add_executable(zig ${ZIG_SOURCES})825add_executable(zig ${ZIG_SOURCES})
...@@ -829,7 +830,7 @@ set_target_properties(zig PROPERTIES...@@ -829,7 +830,7 @@ set_target_properties(zig PROPERTIES
829830
830target_link_libraries(zig LINK_PUBLIC831target_link_libraries(zig LINK_PUBLIC
831 zig_cpp832 zig_cpp
832 zig_O3833 embedded_blake
833 ${SOFTFLOAT_LIBRARIES}834 ${SOFTFLOAT_LIBRARIES}
834 ${CLANG_LIBRARIES}835 ${CLANG_LIBRARIES}
835 ${LLD_LIBRARIES}836 ${LLD_LIBRARIES}
src/blake2b.c created+539
...@@ -0,0 +1,539 @@
1/*
2 BLAKE2 reference source code package - reference C implementations
3
4 Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
5 terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
6 your option. The terms of these licenses can be found at:
7
8 - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
9 - OpenSSL license : https://www.openssl.org/source/license.html
10 - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
11
12 More information about the BLAKE2 hash function can be found at
13 https://blake2.net.
14*/
15
16#include <stdint.h>
17#include <string.h>
18#include <stdio.h>
19
20#include "blake2.h"
21/*
22 BLAKE2 reference source code package - reference C implementations
23
24 Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
25 terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
26 your option. The terms of these licenses can be found at:
27
28 - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
29 - OpenSSL license : https://www.openssl.org/source/license.html
30 - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
31
32 More information about the BLAKE2 hash function can be found at
33 https://blake2.net.
34*/
35#ifndef BLAKE2_IMPL_H
36#define BLAKE2_IMPL_H
37
38#include <stdint.h>
39#include <string.h>
40
41#if !defined(__cplusplus) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L)
42 #if defined(_MSC_VER)
43 #define BLAKE2_INLINE __inline
44 #elif defined(__GNUC__)
45 #define BLAKE2_INLINE __inline__
46 #else
47 #define BLAKE2_INLINE
48 #endif
49#else
50 #define BLAKE2_INLINE inline
51#endif
52
53static BLAKE2_INLINE uint32_t load32( const void *src )
54{
55#if defined(NATIVE_LITTLE_ENDIAN)
56 uint32_t w;
57 memcpy(&w, src, sizeof w);
58 return w;
59#else
60 const uint8_t *p = ( const uint8_t * )src;
61 return (( uint32_t )( p[0] ) << 0) |
62 (( uint32_t )( p[1] ) << 8) |
63 (( uint32_t )( p[2] ) << 16) |
64 (( uint32_t )( p[3] ) << 24) ;
65#endif
66}
67
68static BLAKE2_INLINE uint64_t load64( const void *src )
69{
70#if defined(NATIVE_LITTLE_ENDIAN)
71 uint64_t w;
72 memcpy(&w, src, sizeof w);
73 return w;
74#else
75 const uint8_t *p = ( const uint8_t * )src;
76 return (( uint64_t )( p[0] ) << 0) |
77 (( uint64_t )( p[1] ) << 8) |
78 (( uint64_t )( p[2] ) << 16) |
79 (( uint64_t )( p[3] ) << 24) |
80 (( uint64_t )( p[4] ) << 32) |
81 (( uint64_t )( p[5] ) << 40) |
82 (( uint64_t )( p[6] ) << 48) |
83 (( uint64_t )( p[7] ) << 56) ;
84#endif
85}
86
87static BLAKE2_INLINE uint16_t load16( const void *src )
88{
89#if defined(NATIVE_LITTLE_ENDIAN)
90 uint16_t w;
91 memcpy(&w, src, sizeof w);
92 return w;
93#else
94 const uint8_t *p = ( const uint8_t * )src;
95 return ( uint16_t )((( uint32_t )( p[0] ) << 0) |
96 (( uint32_t )( p[1] ) << 8));
97#endif
98}
99
100static BLAKE2_INLINE void store16( void *dst, uint16_t w )
101{
102#if defined(NATIVE_LITTLE_ENDIAN)
103 memcpy(dst, &w, sizeof w);
104#else
105 uint8_t *p = ( uint8_t * )dst;
106 *p++ = ( uint8_t )w; w >>= 8;
107 *p++ = ( uint8_t )w;
108#endif
109}
110
111static BLAKE2_INLINE void store32( void *dst, uint32_t w )
112{
113#if defined(NATIVE_LITTLE_ENDIAN)
114 memcpy(dst, &w, sizeof w);
115#else
116 uint8_t *p = ( uint8_t * )dst;
117 p[0] = (uint8_t)(w >> 0);
118 p[1] = (uint8_t)(w >> 8);
119 p[2] = (uint8_t)(w >> 16);
120 p[3] = (uint8_t)(w >> 24);
121#endif
122}
123
124static BLAKE2_INLINE void store64( void *dst, uint64_t w )
125{
126#if defined(NATIVE_LITTLE_ENDIAN)
127 memcpy(dst, &w, sizeof w);
128#else
129 uint8_t *p = ( uint8_t * )dst;
130 p[0] = (uint8_t)(w >> 0);
131 p[1] = (uint8_t)(w >> 8);
132 p[2] = (uint8_t)(w >> 16);
133 p[3] = (uint8_t)(w >> 24);
134 p[4] = (uint8_t)(w >> 32);
135 p[5] = (uint8_t)(w >> 40);
136 p[6] = (uint8_t)(w >> 48);
137 p[7] = (uint8_t)(w >> 56);
138#endif
139}
140
141static BLAKE2_INLINE uint64_t load48( const void *src )
142{
143 const uint8_t *p = ( const uint8_t * )src;
144 return (( uint64_t )( p[0] ) << 0) |
145 (( uint64_t )( p[1] ) << 8) |
146 (( uint64_t )( p[2] ) << 16) |
147 (( uint64_t )( p[3] ) << 24) |
148 (( uint64_t )( p[4] ) << 32) |
149 (( uint64_t )( p[5] ) << 40) ;
150}
151
152static BLAKE2_INLINE void store48( void *dst, uint64_t w )
153{
154 uint8_t *p = ( uint8_t * )dst;
155 p[0] = (uint8_t)(w >> 0);
156 p[1] = (uint8_t)(w >> 8);
157 p[2] = (uint8_t)(w >> 16);
158 p[3] = (uint8_t)(w >> 24);
159 p[4] = (uint8_t)(w >> 32);
160 p[5] = (uint8_t)(w >> 40);
161}
162
163static BLAKE2_INLINE uint32_t rotr32( const uint32_t w, const unsigned c )
164{
165 return ( w >> c ) | ( w << ( 32 - c ) );
166}
167
168static BLAKE2_INLINE uint64_t rotr64( const uint64_t w, const unsigned c )
169{
170 return ( w >> c ) | ( w << ( 64 - c ) );
171}
172
173/* prevents compiler optimizing out memset() */
174static BLAKE2_INLINE void secure_zero_memory(void *v, size_t n)
175{
176 static void *(*const volatile memset_v)(void *, int, size_t) = &memset;
177 memset_v(v, 0, n);
178}
179
180#endif
181
182static const uint64_t blake2b_IV[8] =
183{
184 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
185 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
186 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
187 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
188};
189
190static const uint8_t blake2b_sigma[12][16] =
191{
192 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
193 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
194 { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
195 { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
196 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
197 { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
198 { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
199 { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
200 { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
201 { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
202 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
203 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }
204};
205
206
207static void blake2b_set_lastnode( blake2b_state *S )
208{
209 S->f[1] = (uint64_t)-1;
210}
211
212/* Some helper functions, not necessarily useful */
213static int blake2b_is_lastblock( const blake2b_state *S )
214{
215 return S->f[0] != 0;
216}
217
218static void blake2b_set_lastblock( blake2b_state *S )
219{
220 if( S->last_node ) blake2b_set_lastnode( S );
221
222 S->f[0] = (uint64_t)-1;
223}
224
225static void blake2b_increment_counter( blake2b_state *S, const uint64_t inc )
226{
227 S->t[0] += inc;
228 S->t[1] += ( S->t[0] < inc );
229}
230
231static void blake2b_init0( blake2b_state *S )
232{
233 size_t i;
234 memset( S, 0, sizeof( blake2b_state ) );
235
236 for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i];
237}
238
239/* init xors IV with input parameter block */
240int blake2b_init_param( blake2b_state *S, const blake2b_param *P )
241{
242 const uint8_t *p = ( const uint8_t * )( P );
243 size_t i;
244
245 blake2b_init0( S );
246
247 /* IV XOR ParamBlock */
248 for( i = 0; i < 8; ++i )
249 S->h[i] ^= load64( p + sizeof( S->h[i] ) * i );
250
251 S->outlen = P->digest_length;
252 return 0;
253}
254
255
256
257int blake2b_init( blake2b_state *S, size_t outlen )
258{
259 blake2b_param P[1];
260
261 if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
262
263 P->digest_length = (uint8_t)outlen;
264 P->key_length = 0;
265 P->fanout = 1;
266 P->depth = 1;
267 store32( &P->leaf_length, 0 );
268 store32( &P->node_offset, 0 );
269 store32( &P->xof_length, 0 );
270 P->node_depth = 0;
271 P->inner_length = 0;
272 memset( P->reserved, 0, sizeof( P->reserved ) );
273 memset( P->salt, 0, sizeof( P->salt ) );
274 memset( P->personal, 0, sizeof( P->personal ) );
275 return blake2b_init_param( S, P );
276}
277
278
279int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen )
280{
281 blake2b_param P[1];
282
283 if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
284
285 if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1;
286
287 P->digest_length = (uint8_t)outlen;
288 P->key_length = (uint8_t)keylen;
289 P->fanout = 1;
290 P->depth = 1;
291 store32( &P->leaf_length, 0 );
292 store32( &P->node_offset, 0 );
293 store32( &P->xof_length, 0 );
294 P->node_depth = 0;
295 P->inner_length = 0;
296 memset( P->reserved, 0, sizeof( P->reserved ) );
297 memset( P->salt, 0, sizeof( P->salt ) );
298 memset( P->personal, 0, sizeof( P->personal ) );
299
300 if( blake2b_init_param( S, P ) < 0 ) return -1;
301
302 {
303 uint8_t block[BLAKE2B_BLOCKBYTES];
304 memset( block, 0, BLAKE2B_BLOCKBYTES );
305 memcpy( block, key, keylen );
306 blake2b_update( S, block, BLAKE2B_BLOCKBYTES );
307 secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */
308 }
309 return 0;
310}
311
312#define G(r,i,a,b,c,d) \
313 do { \
314 a = a + b + m[blake2b_sigma[r][2*i+0]]; \
315 d = rotr64(d ^ a, 32); \
316 c = c + d; \
317 b = rotr64(b ^ c, 24); \
318 a = a + b + m[blake2b_sigma[r][2*i+1]]; \
319 d = rotr64(d ^ a, 16); \
320 c = c + d; \
321 b = rotr64(b ^ c, 63); \
322 } while(0)
323
324#define ROUND(r) \
325 do { \
326 G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
327 G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
328 G(r,2,v[ 2],v[ 6],v[10],v[14]); \
329 G(r,3,v[ 3],v[ 7],v[11],v[15]); \
330 G(r,4,v[ 0],v[ 5],v[10],v[15]); \
331 G(r,5,v[ 1],v[ 6],v[11],v[12]); \
332 G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
333 G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
334 } while(0)
335
336static void blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] )
337{
338 uint64_t m[16];
339 uint64_t v[16];
340 size_t i;
341
342 for( i = 0; i < 16; ++i ) {
343 m[i] = load64( block + i * sizeof( m[i] ) );
344 }
345
346 for( i = 0; i < 8; ++i ) {
347 v[i] = S->h[i];
348 }
349
350 v[ 8] = blake2b_IV[0];
351 v[ 9] = blake2b_IV[1];
352 v[10] = blake2b_IV[2];
353 v[11] = blake2b_IV[3];
354 v[12] = blake2b_IV[4] ^ S->t[0];
355 v[13] = blake2b_IV[5] ^ S->t[1];
356 v[14] = blake2b_IV[6] ^ S->f[0];
357 v[15] = blake2b_IV[7] ^ S->f[1];
358
359 ROUND( 0 );
360 ROUND( 1 );
361 ROUND( 2 );
362 ROUND( 3 );
363 ROUND( 4 );
364 ROUND( 5 );
365 ROUND( 6 );
366 ROUND( 7 );
367 ROUND( 8 );
368 ROUND( 9 );
369 ROUND( 10 );
370 ROUND( 11 );
371
372 for( i = 0; i < 8; ++i ) {
373 S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
374 }
375}
376
377#undef G
378#undef ROUND
379
380int blake2b_update( blake2b_state *S, const void *pin, size_t inlen )
381{
382 const unsigned char * in = (const unsigned char *)pin;
383 if( inlen > 0 )
384 {
385 size_t left = S->buflen;
386 size_t fill = BLAKE2B_BLOCKBYTES - left;
387 if( inlen > fill )
388 {
389 S->buflen = 0;
390 memcpy( S->buf + left, in, fill ); /* Fill buffer */
391 blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
392 blake2b_compress( S, S->buf ); /* Compress */
393 in += fill; inlen -= fill;
394 while(inlen > BLAKE2B_BLOCKBYTES) {
395 blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
396 blake2b_compress( S, in );
397 in += BLAKE2B_BLOCKBYTES;
398 inlen -= BLAKE2B_BLOCKBYTES;
399 }
400 }
401 memcpy( S->buf + S->buflen, in, inlen );
402 S->buflen += inlen;
403 }
404 return 0;
405}
406
407int blake2b_final( blake2b_state *S, void *out, size_t outlen )
408{
409 uint8_t buffer[BLAKE2B_OUTBYTES] = {0};
410 size_t i;
411
412 if( out == NULL || outlen < S->outlen )
413 return -1;
414
415 if( blake2b_is_lastblock( S ) )
416 return -1;
417
418 blake2b_increment_counter( S, S->buflen );
419 blake2b_set_lastblock( S );
420 memset( S->buf + S->buflen, 0, BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */
421 blake2b_compress( S, S->buf );
422
423 for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
424 store64( buffer + sizeof( S->h[i] ) * i, S->h[i] );
425
426 memcpy( out, buffer, S->outlen );
427 secure_zero_memory(buffer, sizeof(buffer));
428 return 0;
429}
430
431/* inlen, at least, should be uint64_t. Others can be size_t. */
432int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen )
433{
434 blake2b_state S[1];
435
436 /* Verify parameters */
437 if ( NULL == in && inlen > 0 ) return -1;
438
439 if ( NULL == out ) return -1;
440
441 if( NULL == key && keylen > 0 ) return -1;
442
443 if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;
444
445 if( keylen > BLAKE2B_KEYBYTES ) return -1;
446
447 if( keylen > 0 )
448 {
449 if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1;
450 }
451 else
452 {
453 if( blake2b_init( S, outlen ) < 0 ) return -1;
454 }
455
456 blake2b_update( S, ( const uint8_t * )in, inlen );
457 blake2b_final( S, out, outlen );
458 return 0;
459}
460
461int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) {
462 return blake2b(out, outlen, in, inlen, key, keylen);
463}
464
465#if defined(SUPERCOP)
466int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen )
467{
468 return blake2b( out, BLAKE2B_OUTBYTES, in, inlen, NULL, 0 );
469}
470#endif
471
472#if defined(BLAKE2B_SELFTEST)
473#include <string.h>
474#include "blake2-kat.h"
475int main( void )
476{
477 uint8_t key[BLAKE2B_KEYBYTES];
478 uint8_t buf[BLAKE2_KAT_LENGTH];
479 size_t i, step;
480
481 for( i = 0; i < BLAKE2B_KEYBYTES; ++i )
482 key[i] = ( uint8_t )i;
483
484 for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
485 buf[i] = ( uint8_t )i;
486
487 /* Test simple API */
488 for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
489 {
490 uint8_t hash[BLAKE2B_OUTBYTES];
491 blake2b( hash, BLAKE2B_OUTBYTES, buf, i, key, BLAKE2B_KEYBYTES );
492
493 if( 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) )
494 {
495 goto fail;
496 }
497 }
498
499 /* Test streaming API */
500 for(step = 1; step < BLAKE2B_BLOCKBYTES; ++step) {
501 for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) {
502 uint8_t hash[BLAKE2B_OUTBYTES];
503 blake2b_state S;
504 uint8_t * p = buf;
505 size_t mlen = i;
506 int err = 0;
507
508 if( (err = blake2b_init_key(&S, BLAKE2B_OUTBYTES, key, BLAKE2B_KEYBYTES)) < 0 ) {
509 goto fail;
510 }
511
512 while (mlen >= step) {
513 if ( (err = blake2b_update(&S, p, step)) < 0 ) {
514 goto fail;
515 }
516 mlen -= step;
517 p += step;
518 }
519 if ( (err = blake2b_update(&S, p, mlen)) < 0) {
520 goto fail;
521 }
522 if ( (err = blake2b_final(&S, hash, BLAKE2B_OUTBYTES)) < 0) {
523 goto fail;
524 }
525
526 if (0 != memcmp(hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES)) {
527 goto fail;
528 }
529 }
530 }
531
532 puts( "ok" );
533 return 0;
534fail:
535 puts("error");
536 return -1;
537}
538#endif
539
src/blake2b.cpp deleted-539
...@@ -1,539 +0,0 @@
1/*
2 BLAKE2 reference source code package - reference C implementations
3
4 Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
5 terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
6 your option. The terms of these licenses can be found at:
7
8 - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
9 - OpenSSL license : https://www.openssl.org/source/license.html
10 - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
11
12 More information about the BLAKE2 hash function can be found at
13 https://blake2.net.
14*/
15
16#include <stdint.h>
17#include <string.h>
18#include <stdio.h>
19
20#include "blake2.h"
21/*
22 BLAKE2 reference source code package - reference C implementations
23
24 Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
25 terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
26 your option. The terms of these licenses can be found at:
27
28 - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
29 - OpenSSL license : https://www.openssl.org/source/license.html
30 - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
31
32 More information about the BLAKE2 hash function can be found at
33 https://blake2.net.
34*/
35#ifndef BLAKE2_IMPL_H
36#define BLAKE2_IMPL_H
37
38#include <stdint.h>
39#include <string.h>
40
41#if !defined(__cplusplus) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L)
42 #if defined(_MSC_VER)
43 #define BLAKE2_INLINE __inline
44 #elif defined(__GNUC__)
45 #define BLAKE2_INLINE __inline__
46 #else
47 #define BLAKE2_INLINE
48 #endif
49#else
50 #define BLAKE2_INLINE inline
51#endif
52
53static BLAKE2_INLINE uint32_t load32( const void *src )
54{
55#if defined(NATIVE_LITTLE_ENDIAN)
56 uint32_t w;
57 memcpy(&w, src, sizeof w);
58 return w;
59#else
60 const uint8_t *p = ( const uint8_t * )src;
61 return (( uint32_t )( p[0] ) << 0) |
62 (( uint32_t )( p[1] ) << 8) |
63 (( uint32_t )( p[2] ) << 16) |
64 (( uint32_t )( p[3] ) << 24) ;
65#endif
66}
67
68static BLAKE2_INLINE uint64_t load64( const void *src )
69{
70#if defined(NATIVE_LITTLE_ENDIAN)
71 uint64_t w;
72 memcpy(&w, src, sizeof w);
73 return w;
74#else
75 const uint8_t *p = ( const uint8_t * )src;
76 return (( uint64_t )( p[0] ) << 0) |
77 (( uint64_t )( p[1] ) << 8) |
78 (( uint64_t )( p[2] ) << 16) |
79 (( uint64_t )( p[3] ) << 24) |
80 (( uint64_t )( p[4] ) << 32) |
81 (( uint64_t )( p[5] ) << 40) |
82 (( uint64_t )( p[6] ) << 48) |
83 (( uint64_t )( p[7] ) << 56) ;
84#endif
85}
86
87static BLAKE2_INLINE uint16_t load16( const void *src )
88{
89#if defined(NATIVE_LITTLE_ENDIAN)
90 uint16_t w;
91 memcpy(&w, src, sizeof w);
92 return w;
93#else
94 const uint8_t *p = ( const uint8_t * )src;
95 return ( uint16_t )((( uint32_t )( p[0] ) << 0) |
96 (( uint32_t )( p[1] ) << 8));
97#endif
98}
99
100static BLAKE2_INLINE void store16( void *dst, uint16_t w )
101{
102#if defined(NATIVE_LITTLE_ENDIAN)
103 memcpy(dst, &w, sizeof w);
104#else
105 uint8_t *p = ( uint8_t * )dst;
106 *p++ = ( uint8_t )w; w >>= 8;
107 *p++ = ( uint8_t )w;
108#endif
109}
110
111static BLAKE2_INLINE void store32( void *dst, uint32_t w )
112{
113#if defined(NATIVE_LITTLE_ENDIAN)
114 memcpy(dst, &w, sizeof w);
115#else
116 uint8_t *p = ( uint8_t * )dst;
117 p[0] = (uint8_t)(w >> 0);
118 p[1] = (uint8_t)(w >> 8);
119 p[2] = (uint8_t)(w >> 16);
120 p[3] = (uint8_t)(w >> 24);
121#endif
122}
123
124static BLAKE2_INLINE void store64( void *dst, uint64_t w )
125{
126#if defined(NATIVE_LITTLE_ENDIAN)
127 memcpy(dst, &w, sizeof w);
128#else
129 uint8_t *p = ( uint8_t * )dst;
130 p[0] = (uint8_t)(w >> 0);
131 p[1] = (uint8_t)(w >> 8);
132 p[2] = (uint8_t)(w >> 16);
133 p[3] = (uint8_t)(w >> 24);
134 p[4] = (uint8_t)(w >> 32);
135 p[5] = (uint8_t)(w >> 40);
136 p[6] = (uint8_t)(w >> 48);
137 p[7] = (uint8_t)(w >> 56);
138#endif
139}
140
141static BLAKE2_INLINE uint64_t load48( const void *src )
142{
143 const uint8_t *p = ( const uint8_t * )src;
144 return (( uint64_t )( p[0] ) << 0) |
145 (( uint64_t )( p[1] ) << 8) |
146 (( uint64_t )( p[2] ) << 16) |
147 (( uint64_t )( p[3] ) << 24) |
148 (( uint64_t )( p[4] ) << 32) |
149 (( uint64_t )( p[5] ) << 40) ;
150}
151
152static BLAKE2_INLINE void store48( void *dst, uint64_t w )
153{
154 uint8_t *p = ( uint8_t * )dst;
155 p[0] = (uint8_t)(w >> 0);
156 p[1] = (uint8_t)(w >> 8);
157 p[2] = (uint8_t)(w >> 16);
158 p[3] = (uint8_t)(w >> 24);
159 p[4] = (uint8_t)(w >> 32);
160 p[5] = (uint8_t)(w >> 40);
161}
162
163static BLAKE2_INLINE uint32_t rotr32( const uint32_t w, const unsigned c )
164{
165 return ( w >> c ) | ( w << ( 32 - c ) );
166}
167
168static BLAKE2_INLINE uint64_t rotr64( const uint64_t w, const unsigned c )
169{
170 return ( w >> c ) | ( w << ( 64 - c ) );
171}
172
173/* prevents compiler optimizing out memset() */
174static BLAKE2_INLINE void secure_zero_memory(void *v, size_t n)
175{
176 static void *(*const volatile memset_v)(void *, int, size_t) = &memset;
177 memset_v(v, 0, n);
178}
179
180#endif
181
182static const uint64_t blake2b_IV[8] =
183{
184 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
185 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
186 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
187 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
188};
189
190static const uint8_t blake2b_sigma[12][16] =
191{
192 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
193 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
194 { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
195 { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
196 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
197 { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
198 { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
199 { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
200 { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
201 { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
202 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
203 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }
204};
205
206
207static void blake2b_set_lastnode( blake2b_state *S )
208{
209 S->f[1] = (uint64_t)-1;
210}
211
212/* Some helper functions, not necessarily useful */
213static int blake2b_is_lastblock( const blake2b_state *S )
214{
215 return S->f[0] != 0;
216}
217
218static void blake2b_set_lastblock( blake2b_state *S )
219{
220 if( S->last_node ) blake2b_set_lastnode( S );
221
222 S->f[0] = (uint64_t)-1;
223}
224
225static void blake2b_increment_counter( blake2b_state *S, const uint64_t inc )
226{
227 S->t[0] += inc;
228 S->t[1] += ( S->t[0] < inc );
229}
230
231static void blake2b_init0( blake2b_state *S )
232{
233 size_t i;
234 memset( S, 0, sizeof( blake2b_state ) );
235
236 for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i];
237}
238
239/* init xors IV with input parameter block */
240int blake2b_init_param( blake2b_state *S, const blake2b_param *P )
241{
242 const uint8_t *p = ( const uint8_t * )( P );
243 size_t i;
244
245 blake2b_init0( S );
246
247 /* IV XOR ParamBlock */
248 for( i = 0; i < 8; ++i )
249 S->h[i] ^= load64( p + sizeof( S->h[i] ) * i );
250
251 S->outlen = P->digest_length;
252 return 0;
253}
254
255
256
257int blake2b_init( blake2b_state *S, size_t outlen )
258{
259 blake2b_param P[1];
260
261 if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
262
263 P->digest_length = (uint8_t)outlen;
264 P->key_length = 0;
265 P->fanout = 1;
266 P->depth = 1;
267 store32( &P->leaf_length, 0 );
268 store32( &P->node_offset, 0 );
269 store32( &P->xof_length, 0 );
270 P->node_depth = 0;
271 P->inner_length = 0;
272 memset( P->reserved, 0, sizeof( P->reserved ) );
273 memset( P->salt, 0, sizeof( P->salt ) );
274 memset( P->personal, 0, sizeof( P->personal ) );
275 return blake2b_init_param( S, P );
276}
277
278
279int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen )
280{
281 blake2b_param P[1];
282
283 if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
284
285 if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1;
286
287 P->digest_length = (uint8_t)outlen;
288 P->key_length = (uint8_t)keylen;
289 P->fanout = 1;
290 P->depth = 1;
291 store32( &P->leaf_length, 0 );
292 store32( &P->node_offset, 0 );
293 store32( &P->xof_length, 0 );
294 P->node_depth = 0;
295 P->inner_length = 0;
296 memset( P->reserved, 0, sizeof( P->reserved ) );
297 memset( P->salt, 0, sizeof( P->salt ) );
298 memset( P->personal, 0, sizeof( P->personal ) );
299
300 if( blake2b_init_param( S, P ) < 0 ) return -1;
301
302 {
303 uint8_t block[BLAKE2B_BLOCKBYTES];
304 memset( block, 0, BLAKE2B_BLOCKBYTES );
305 memcpy( block, key, keylen );
306 blake2b_update( S, block, BLAKE2B_BLOCKBYTES );
307 secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */
308 }
309 return 0;
310}
311
312#define G(r,i,a,b,c,d) \
313 do { \
314 a = a + b + m[blake2b_sigma[r][2*i+0]]; \
315 d = rotr64(d ^ a, 32); \
316 c = c + d; \
317 b = rotr64(b ^ c, 24); \
318 a = a + b + m[blake2b_sigma[r][2*i+1]]; \
319 d = rotr64(d ^ a, 16); \
320 c = c + d; \
321 b = rotr64(b ^ c, 63); \
322 } while(0)
323
324#define ROUND(r) \
325 do { \
326 G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
327 G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
328 G(r,2,v[ 2],v[ 6],v[10],v[14]); \
329 G(r,3,v[ 3],v[ 7],v[11],v[15]); \
330 G(r,4,v[ 0],v[ 5],v[10],v[15]); \
331 G(r,5,v[ 1],v[ 6],v[11],v[12]); \
332 G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
333 G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
334 } while(0)
335
336static void blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] )
337{
338 uint64_t m[16];
339 uint64_t v[16];
340 size_t i;
341
342 for( i = 0; i < 16; ++i ) {
343 m[i] = load64( block + i * sizeof( m[i] ) );
344 }
345
346 for( i = 0; i < 8; ++i ) {
347 v[i] = S->h[i];
348 }
349
350 v[ 8] = blake2b_IV[0];
351 v[ 9] = blake2b_IV[1];
352 v[10] = blake2b_IV[2];
353 v[11] = blake2b_IV[3];
354 v[12] = blake2b_IV[4] ^ S->t[0];
355 v[13] = blake2b_IV[5] ^ S->t[1];
356 v[14] = blake2b_IV[6] ^ S->f[0];
357 v[15] = blake2b_IV[7] ^ S->f[1];
358
359 ROUND( 0 );
360 ROUND( 1 );
361 ROUND( 2 );
362 ROUND( 3 );
363 ROUND( 4 );
364 ROUND( 5 );
365 ROUND( 6 );
366 ROUND( 7 );
367 ROUND( 8 );
368 ROUND( 9 );
369 ROUND( 10 );
370 ROUND( 11 );
371
372 for( i = 0; i < 8; ++i ) {
373 S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
374 }
375}
376
377#undef G
378#undef ROUND
379
380int blake2b_update( blake2b_state *S, const void *pin, size_t inlen )
381{
382 const unsigned char * in = (const unsigned char *)pin;
383 if( inlen > 0 )
384 {
385 size_t left = S->buflen;
386 size_t fill = BLAKE2B_BLOCKBYTES - left;
387 if( inlen > fill )
388 {
389 S->buflen = 0;
390 memcpy( S->buf + left, in, fill ); /* Fill buffer */
391 blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
392 blake2b_compress( S, S->buf ); /* Compress */
393 in += fill; inlen -= fill;
394 while(inlen > BLAKE2B_BLOCKBYTES) {
395 blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
396 blake2b_compress( S, in );
397 in += BLAKE2B_BLOCKBYTES;
398 inlen -= BLAKE2B_BLOCKBYTES;
399 }
400 }
401 memcpy( S->buf + S->buflen, in, inlen );
402 S->buflen += inlen;
403 }
404 return 0;
405}
406
407int blake2b_final( blake2b_state *S, void *out, size_t outlen )
408{
409 uint8_t buffer[BLAKE2B_OUTBYTES] = {0};
410 size_t i;
411
412 if( out == NULL || outlen < S->outlen )
413 return -1;
414
415 if( blake2b_is_lastblock( S ) )
416 return -1;
417
418 blake2b_increment_counter( S, S->buflen );
419 blake2b_set_lastblock( S );
420 memset( S->buf + S->buflen, 0, BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */
421 blake2b_compress( S, S->buf );
422
423 for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
424 store64( buffer + sizeof( S->h[i] ) * i, S->h[i] );
425
426 memcpy( out, buffer, S->outlen );
427 secure_zero_memory(buffer, sizeof(buffer));
428 return 0;
429}
430
431/* inlen, at least, should be uint64_t. Others can be size_t. */
432int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen )
433{
434 blake2b_state S[1];
435
436 /* Verify parameters */
437 if ( NULL == in && inlen > 0 ) return -1;
438
439 if ( NULL == out ) return -1;
440
441 if( NULL == key && keylen > 0 ) return -1;
442
443 if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;
444
445 if( keylen > BLAKE2B_KEYBYTES ) return -1;
446
447 if( keylen > 0 )
448 {
449 if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1;
450 }
451 else
452 {
453 if( blake2b_init( S, outlen ) < 0 ) return -1;
454 }
455
456 blake2b_update( S, ( const uint8_t * )in, inlen );
457 blake2b_final( S, out, outlen );
458 return 0;
459}
460
461int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) {
462 return blake2b(out, outlen, in, inlen, key, keylen);
463}
464
465#if defined(SUPERCOP)
466int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen )
467{
468 return blake2b( out, BLAKE2B_OUTBYTES, in, inlen, NULL, 0 );
469}
470#endif
471
472#if defined(BLAKE2B_SELFTEST)
473#include <string.h>
474#include "blake2-kat.h"
475int main( void )
476{
477 uint8_t key[BLAKE2B_KEYBYTES];
478 uint8_t buf[BLAKE2_KAT_LENGTH];
479 size_t i, step;
480
481 for( i = 0; i < BLAKE2B_KEYBYTES; ++i )
482 key[i] = ( uint8_t )i;
483
484 for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
485 buf[i] = ( uint8_t )i;
486
487 /* Test simple API */
488 for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
489 {
490 uint8_t hash[BLAKE2B_OUTBYTES];
491 blake2b( hash, BLAKE2B_OUTBYTES, buf, i, key, BLAKE2B_KEYBYTES );
492
493 if( 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) )
494 {
495 goto fail;
496 }
497 }
498
499 /* Test streaming API */
500 for(step = 1; step < BLAKE2B_BLOCKBYTES; ++step) {
501 for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) {
502 uint8_t hash[BLAKE2B_OUTBYTES];
503 blake2b_state S;
504 uint8_t * p = buf;
505 size_t mlen = i;
506 int err = 0;
507
508 if( (err = blake2b_init_key(&S, BLAKE2B_OUTBYTES, key, BLAKE2B_KEYBYTES)) < 0 ) {
509 goto fail;
510 }
511
512 while (mlen >= step) {
513 if ( (err = blake2b_update(&S, p, step)) < 0 ) {
514 goto fail;
515 }
516 mlen -= step;
517 p += step;
518 }
519 if ( (err = blake2b_update(&S, p, mlen)) < 0) {
520 goto fail;
521 }
522 if ( (err = blake2b_final(&S, hash, BLAKE2B_OUTBYTES)) < 0) {
523 goto fail;
524 }
525
526 if (0 != memcmp(hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES)) {
527 goto fail;
528 }
529 }
530 }
531
532 puts( "ok" );
533 return 0;
534fail:
535 puts("error");
536 return -1;
537}
538#endif
539