bpo-33164: update blake2 implementation (GH-6286)

This commit is contained in:
David Carlier 2019-05-23 04:32:44 +00:00 committed by Inada Naoki
parent 20e1e2582e
commit 51aa35e9e1
27 changed files with 18373 additions and 679 deletions

View file

@ -0,0 +1 @@
Updated blake2 implementation which uses secure memset implementation provided by platform.

View file

@ -1,23 +1,20 @@
/*
BLAKE2 reference source code package - optimized C implementations
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
your option. The terms of these licenses can be found at:
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
- OpenSSL license : https://www.openssl.org/source/license.html
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
More information about the BLAKE2 hash function can be found at
https://blake2.net.
You should have received a copy of the CC0 Public Domain Dedication along with
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#pragma once
#ifndef __BLAKE2_CONFIG_H__
#define __BLAKE2_CONFIG_H__
/* These don't work everywhere */
#if defined(__SSE2__) || defined(__x86_64__) || defined(__amd64__)
#if defined(__SSE2__)
#define HAVE_SSE2
#endif
@ -26,7 +23,7 @@
#endif
#if defined(__SSE4_1__)
#define HAVE_SSE41
#define HAVE_SSE4_1
#endif
#if defined(__AVX__)
@ -51,8 +48,8 @@
#endif
#ifdef HAVE_AVX
#ifndef HAVE_SSE41
#define HAVE_SSE41
#ifndef HAVE_SSE4_1
#define HAVE_SSE4_1
#endif
#endif

View file

@ -0,0 +1,577 @@
/*
BLAKE2 reference source code package - optimized C implementations
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include <stdio.h>
#if defined(WIN32)
#include <windows.h>
#endif
#include "blake2.h"
#if defined(__x86_64__) || defined(__i386__) || defined(_M_IX86) || defined(_M_X64)
#define HAVE_X86
#endif
typedef enum
{
NONE = 0,
#if defined(HAVE_X86)
SSE2 = 1,
SSSE3 = 2,
SSE41 = 3,
AVX = 4,
XOP = 5,
/* AVX2 = 6, */
#endif
} cpu_feature_t;
static const char feature_names[][8] =
{
"none",
#if defined(HAVE_X86)
"sse2",
"ssse3",
"sse41",
"avx",
"xop",
/* "avx2" */
#endif
};
#if defined(HAVE_X86)
#if defined(__GNUC__)
static inline void cpuid( uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx )
{
__asm__ __volatile__(
#if defined(__i386__) /* This is needed for -fPIC to work on i386 */
"movl %%ebx, %%esi\n\t"
#endif
"cpuid\n\t"
#if defined(__i386__)
"xchgl %%ebx, %%esi\n\t"
: "=a"( *eax ), "=S"( *ebx ), "=c"( *ecx ), "=d"( *edx ) : "a"( *eax ) );
#else
: "=a"( *eax ), "=b"( *ebx ), "=c"( *ecx ), "=d"( *edx ) : "a"( *eax ) );
#endif
}
static inline uint64_t xgetbv(uint32_t xcr)
{
uint32_t a, d;
__asm__ __volatile__(
"xgetbv"
: "=a"(a),"=d"(d)
: "c"(xcr)
);
return ((uint64_t)d << 32) | a;
}
#elif defined(_MSC_VER)
#include <intrin.h>
static inline void cpuid( uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx )
{
int regs[4];
__cpuid( regs, *eax );
*eax = regs[0];
*ebx = regs[1];
*ecx = regs[2];
*edx = regs[3];
}
#else
#error "Don't know how to call cpuid on this compiler!"
#endif
#endif /* HAVE_X86 */
static inline cpu_feature_t get_cpu_features( void )
{
#if defined(HAVE_X86)
static volatile int initialized = 0;
static cpu_feature_t feature = NONE; // Safe default
uint32_t eax, ecx, edx, ebx;
if( initialized )
return feature;
eax = 1;
cpuid( &eax, &ebx, &ecx, &edx );
if( 1 & ( edx >> 26 ) )
feature = SSE2;
if( 1 & ( ecx >> 9 ) )
feature = SSSE3;
if( 1 & ( ecx >> 19 ) )
feature = SSE41;
#if defined(WIN32) /* Work around the fact that Windows <7 does NOT support AVX... */
if( IsProcessorFeaturePresent(17) ) /* Some environments don't know about PF_XSAVE_ENABLED */
#endif
{
/* check for AVX and OSXSAVE bits */
if( 1 & ( ecx >> 28 ) & (ecx >> 27) ) {
#if !defined(WIN32) /* Already checked for this in WIN32 */
if( (xgetbv(0) & 6) == 6 ) /* XCR0 */
#endif
feature = AVX;
}
eax = 0x80000001;
cpuid( &eax, &ebx, &ecx, &edx );
if( 1 & ( ecx >> 11 ) )
feature = XOP;
}
/* For future architectures */
/*
eax = 7; ecx = 0;
cpuid(&eax, &ebx, &ecx, &edx);
if(1&(ebx >> 5))
feature = AVX2;
*/
/* fprintf( stderr, "Using %s engine\n", feature_names[feature] ); */
initialized = 1;
return feature;
#else
return NONE;
#endif
}
#if defined(__cplusplus)
extern "C" {
#endif
int blake2b_init_ref( blake2b_state *S, size_t outlen );
int blake2b_init_key_ref( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
int blake2b_init_param_ref( blake2b_state *S, const blake2b_param *P );
int blake2b_update_ref( blake2b_state *S, const uint8_t *in, size_t inlen );
int blake2b_final_ref( blake2b_state *S, uint8_t *out, size_t outlen );
int blake2b_ref( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
#if defined(HAVE_X86)
int blake2b_init_sse2( blake2b_state *S, size_t outlen );
int blake2b_init_key_sse2( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
int blake2b_init_param_sse2( blake2b_state *S, const blake2b_param *P );
int blake2b_update_sse2( blake2b_state *S, const uint8_t *in, size_t inlen );
int blake2b_final_sse2( blake2b_state *S, uint8_t *out, size_t outlen );
int blake2b_sse2( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
int blake2b_init_ssse3( blake2b_state *S, size_t outlen );
int blake2b_init_key_ssse3( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
int blake2b_init_param_ssse3( blake2b_state *S, const blake2b_param *P );
int blake2b_update_ssse3( blake2b_state *S, const uint8_t *in, size_t inlen );
int blake2b_final_ssse3( blake2b_state *S, uint8_t *out, size_t outlen );
int blake2b_ssse3( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
int blake2b_init_sse41( blake2b_state *S, size_t outlen );
int blake2b_init_key_sse41( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
int blake2b_init_param_sse41( blake2b_state *S, const blake2b_param *P );
int blake2b_update_sse41( blake2b_state *S, const uint8_t *in, size_t inlen );
int blake2b_final_sse41( blake2b_state *S, uint8_t *out, size_t outlen );
int blake2b_sse41( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
int blake2b_init_avx( blake2b_state *S, size_t outlen );
int blake2b_init_key_avx( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
int blake2b_init_param_avx( blake2b_state *S, const blake2b_param *P );
int blake2b_update_avx( blake2b_state *S, const uint8_t *in, size_t inlen );
int blake2b_final_avx( blake2b_state *S, uint8_t *out, size_t outlen );
int blake2b_avx( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
int blake2b_init_xop( blake2b_state *S, size_t outlen );
int blake2b_init_key_xop( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
int blake2b_init_param_xop( blake2b_state *S, const blake2b_param *P );
int blake2b_update_xop( blake2b_state *S, const uint8_t *in, size_t inlen );
int blake2b_final_xop( blake2b_state *S, uint8_t *out, size_t outlen );
int blake2b_xop( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
#endif /* HAVE_X86 */
int blake2s_init_ref( blake2s_state *S, size_t outlen );
int blake2s_init_key_ref( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
int blake2s_init_param_ref( blake2s_state *S, const blake2s_param *P );
int blake2s_update_ref( blake2s_state *S, const uint8_t *in, size_t inlen );
int blake2s_final_ref( blake2s_state *S, uint8_t *out, size_t outlen );
int blake2s_ref( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
#if defined(HAVE_X86)
int blake2s_init_sse2( blake2s_state *S, size_t outlen );
int blake2s_init_key_sse2( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
int blake2s_init_param_sse2( blake2s_state *S, const blake2s_param *P );
int blake2s_update_sse2( blake2s_state *S, const uint8_t *in, size_t inlen );
int blake2s_final_sse2( blake2s_state *S, uint8_t *out, size_t outlen );
int blake2s_sse2( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
int blake2s_init_ssse3( blake2s_state *S, size_t outlen );
int blake2s_init_key_ssse3( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
int blake2s_init_param_ssse3( blake2s_state *S, const blake2s_param *P );
int blake2s_update_ssse3( blake2s_state *S, const uint8_t *in, size_t inlen );
int blake2s_final_ssse3( blake2s_state *S, uint8_t *out, size_t outlen );
int blake2s_ssse3( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
int blake2s_init_sse41( blake2s_state *S, size_t outlen );
int blake2s_init_key_sse41( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
int blake2s_init_param_sse41( blake2s_state *S, const blake2s_param *P );
int blake2s_update_sse41( blake2s_state *S, const uint8_t *in, size_t inlen );
int blake2s_final_sse41( blake2s_state *S, uint8_t *out, size_t outlen );
int blake2s_sse41( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
int blake2s_init_avx( blake2s_state *S, size_t outlen );
int blake2s_init_key_avx( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
int blake2s_init_param_avx( blake2s_state *S, const blake2s_param *P );
int blake2s_update_avx( blake2s_state *S, const uint8_t *in, size_t inlen );
int blake2s_final_avx( blake2s_state *S, uint8_t *out, size_t outlen );
int blake2s_avx( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
int blake2s_init_xop( blake2s_state *S, size_t outlen );
int blake2s_init_key_xop( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
int blake2s_init_param_xop( blake2s_state *S, const blake2s_param *P );
int blake2s_update_xop( blake2s_state *S, const uint8_t *in, size_t inlen );
int blake2s_final_xop( blake2s_state *S, uint8_t *out, size_t outlen );
int blake2s_xop( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
#endif /* HAVE_X86 */
#if defined(__cplusplus)
}
#endif
typedef int ( *blake2b_init_fn )( blake2b_state *, size_t );
typedef int ( *blake2b_init_key_fn )( blake2b_state *, size_t, const void *, size_t );
typedef int ( *blake2b_init_param_fn )( blake2b_state *, const blake2b_param * );
typedef int ( *blake2b_update_fn )( blake2b_state *, const uint8_t *, size_t );
typedef int ( *blake2b_final_fn )( blake2b_state *, uint8_t *, size_t );
typedef int ( *blake2b_fn )( uint8_t *, const void *, const void *, size_t, size_t, size_t );
typedef int ( *blake2s_init_fn )( blake2s_state *, size_t );
typedef int ( *blake2s_init_key_fn )( blake2s_state *, size_t, const void *, size_t );
typedef int ( *blake2s_init_param_fn )( blake2s_state *, const blake2s_param * );
typedef int ( *blake2s_update_fn )( blake2s_state *, const uint8_t *, size_t );
typedef int ( *blake2s_final_fn )( blake2s_state *, uint8_t *, size_t );
typedef int ( *blake2s_fn )( uint8_t *, const void *, const void *, size_t, size_t, size_t );
static const blake2b_init_fn blake2b_init_table[] =
{
blake2b_init_ref,
#if defined(HAVE_X86)
blake2b_init_sse2,
blake2b_init_ssse3,
blake2b_init_sse41,
blake2b_init_avx,
blake2b_init_xop
#endif
};
static const blake2b_init_key_fn blake2b_init_key_table[] =
{
blake2b_init_key_ref,
#if defined(HAVE_X86)
blake2b_init_key_sse2,
blake2b_init_key_ssse3,
blake2b_init_key_sse41,
blake2b_init_key_avx,
blake2b_init_key_xop
#endif
};
static const blake2b_init_param_fn blake2b_init_param_table[] =
{
blake2b_init_param_ref,
#if defined(HAVE_X86)
blake2b_init_param_sse2,
blake2b_init_param_ssse3,
blake2b_init_param_sse41,
blake2b_init_param_avx,
blake2b_init_param_xop
#endif
};
static const blake2b_update_fn blake2b_update_table[] =
{
blake2b_update_ref,
#if defined(HAVE_X86)
blake2b_update_sse2,
blake2b_update_ssse3,
blake2b_update_sse41,
blake2b_update_avx,
blake2b_update_xop
#endif
};
static const blake2b_final_fn blake2b_final_table[] =
{
blake2b_final_ref,
#if defined(HAVE_X86)
blake2b_final_sse2,
blake2b_final_ssse3,
blake2b_final_sse41,
blake2b_final_avx,
blake2b_final_xop
#endif
};
static const blake2b_fn blake2b_table[] =
{
blake2b_ref,
#if defined(HAVE_X86)
blake2b_sse2,
blake2b_ssse3,
blake2b_sse41,
blake2b_avx,
blake2b_xop
#endif
};
static const blake2s_init_fn blake2s_init_table[] =
{
blake2s_init_ref,
#if defined(HAVE_X86)
blake2s_init_sse2,
blake2s_init_ssse3,
blake2s_init_sse41,
blake2s_init_avx,
blake2s_init_xop
#endif
};
static const blake2s_init_key_fn blake2s_init_key_table[] =
{
blake2s_init_key_ref,
#if defined(HAVE_X86)
blake2s_init_key_sse2,
blake2s_init_key_ssse3,
blake2s_init_key_sse41,
blake2s_init_key_avx,
blake2s_init_key_xop
#endif
};
static const blake2s_init_param_fn blake2s_init_param_table[] =
{
blake2s_init_param_ref,
#if defined(HAVE_X86)
blake2s_init_param_sse2,
blake2s_init_param_ssse3,
blake2s_init_param_sse41,
blake2s_init_param_avx,
blake2s_init_param_xop
#endif
};
static const blake2s_update_fn blake2s_update_table[] =
{
blake2s_update_ref,
#if defined(HAVE_X86)
blake2s_update_sse2,
blake2s_update_ssse3,
blake2s_update_sse41,
blake2s_update_avx,
blake2s_update_xop
#endif
};
static const blake2s_final_fn blake2s_final_table[] =
{
blake2s_final_ref,
#if defined(HAVE_X86)
blake2s_final_sse2,
blake2s_final_ssse3,
blake2s_final_sse41,
blake2s_final_avx,
blake2s_final_xop
#endif
};
static const blake2s_fn blake2s_table[] =
{
blake2s_ref,
#if defined(HAVE_X86)
blake2s_sse2,
blake2s_ssse3,
blake2s_sse41,
blake2s_avx,
blake2s_xop
#endif
};
#if defined(__cplusplus)
extern "C" {
#endif
int blake2b_init_dispatch( blake2b_state *S, size_t outlen );
int blake2b_init_key_dispatch( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
int blake2b_init_param_dispatch( blake2b_state *S, const blake2b_param *P );
int blake2b_update_dispatch( blake2b_state *S, const uint8_t *in, size_t inlen );
int blake2b_final_dispatch( blake2b_state *S, uint8_t *out, size_t outlen );
int blake2b_dispatch( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
int blake2s_init_dispatch( blake2s_state *S, size_t outlen );
int blake2s_init_key_dispatch( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
int blake2s_init_param_dispatch( blake2s_state *S, const blake2s_param *P );
int blake2s_update_dispatch( blake2s_state *S, const uint8_t *in, size_t inlen );
int blake2s_final_dispatch( blake2s_state *S, uint8_t *out, size_t outlen );
int blake2s_dispatch( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
#if defined(__cplusplus)
}
#endif
static blake2b_init_fn blake2b_init_ptr = blake2b_init_dispatch;
static blake2b_init_key_fn blake2b_init_key_ptr = blake2b_init_key_dispatch;
static blake2b_init_param_fn blake2b_init_param_ptr = blake2b_init_param_dispatch;
static blake2b_update_fn blake2b_update_ptr = blake2b_update_dispatch;
static blake2b_final_fn blake2b_final_ptr = blake2b_final_dispatch;
static blake2b_fn blake2b_ptr = blake2b_dispatch;
static blake2s_init_fn blake2s_init_ptr = blake2s_init_dispatch;
static blake2s_init_key_fn blake2s_init_key_ptr = blake2s_init_key_dispatch;
static blake2s_init_param_fn blake2s_init_param_ptr = blake2s_init_param_dispatch;
static blake2s_update_fn blake2s_update_ptr = blake2s_update_dispatch;
static blake2s_final_fn blake2s_final_ptr = blake2s_final_dispatch;
static blake2s_fn blake2s_ptr = blake2s_dispatch;
int blake2b_init_dispatch( blake2b_state *S, size_t outlen )
{
blake2b_init_ptr = blake2b_init_table[get_cpu_features()];
return blake2b_init_ptr( S, outlen );
}
int blake2b_init_key_dispatch( blake2b_state *S, size_t outlen, const void *key, size_t keylen )
{
blake2b_init_key_ptr = blake2b_init_key_table[get_cpu_features()];
return blake2b_init_key_ptr( S, outlen, key, keylen );
}
int blake2b_init_param_dispatch( blake2b_state *S, const blake2b_param *P )
{
blake2b_init_param_ptr = blake2b_init_param_table[get_cpu_features()];
return blake2b_init_param_ptr( S, P );
}
int blake2b_update_dispatch( blake2b_state *S, const uint8_t *in, size_t inlen )
{
blake2b_update_ptr = blake2b_update_table[get_cpu_features()];
return blake2b_update_ptr( S, in, inlen );
}
int blake2b_final_dispatch( blake2b_state *S, uint8_t *out, size_t outlen )
{
blake2b_final_ptr = blake2b_final_table[get_cpu_features()];
return blake2b_final_ptr( S, out, outlen );
}
int blake2b_dispatch( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
{
blake2b_ptr = blake2b_table[get_cpu_features()];
return blake2b_ptr( out, in, key, outlen, inlen, keylen );
}
BLAKE2_API int blake2b_init( blake2b_state *S, size_t outlen )
{
return blake2b_init_ptr( S, outlen );
}
BLAKE2_API int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen )
{
return blake2b_init_key_ptr( S, outlen, key, keylen );
}
BLAKE2_API int blake2b_init_param( blake2b_state *S, const blake2b_param *P )
{
return blake2b_init_param_ptr( S, P );
}
BLAKE2_API int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen )
{
return blake2b_update_ptr( S, in, inlen );
}
BLAKE2_API int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen )
{
return blake2b_final_ptr( S, out, outlen );
}
BLAKE2_API int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
{
return blake2b_ptr( out, in, key, outlen, inlen, keylen );
}
int blake2s_init_dispatch( blake2s_state *S, size_t outlen )
{
blake2s_init_ptr = blake2s_init_table[get_cpu_features()];
return blake2s_init_ptr( S, outlen );
}
int blake2s_init_key_dispatch( blake2s_state *S, size_t outlen, const void *key, size_t keylen )
{
blake2s_init_key_ptr = blake2s_init_key_table[get_cpu_features()];
return blake2s_init_key_ptr( S, outlen, key, keylen );
}
int blake2s_init_param_dispatch( blake2s_state *S, const blake2s_param *P )
{
blake2s_init_param_ptr = blake2s_init_param_table[get_cpu_features()];
return blake2s_init_param_ptr( S, P );
}
int blake2s_update_dispatch( blake2s_state *S, const uint8_t *in, size_t inlen )
{
blake2s_update_ptr = blake2s_update_table[get_cpu_features()];
return blake2s_update_ptr( S, in, inlen );
}
int blake2s_final_dispatch( blake2s_state *S, uint8_t *out, size_t outlen )
{
blake2s_final_ptr = blake2s_final_table[get_cpu_features()];
return blake2s_final_ptr( S, out, outlen );
}
int blake2s_dispatch( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
{
blake2s_ptr = blake2s_table[get_cpu_features()];
return blake2s_ptr( out, in, key, outlen, inlen, keylen );
}
BLAKE2_API int blake2s_init( blake2s_state *S, size_t outlen )
{
return blake2s_init_ptr( S, outlen );
}
BLAKE2_API int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen )
{
return blake2s_init_key_ptr( S, outlen, key, keylen );
}
BLAKE2_API int blake2s_init_param( blake2s_state *S, const blake2s_param *P )
{
return blake2s_init_param_ptr( S, P );
}
BLAKE2_API int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen )
{
return blake2s_update_ptr( S, in, inlen );
}
BLAKE2_API int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen )
{
return blake2s_final_ptr( S, out, outlen );
}
BLAKE2_API int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
{
return blake2s_ptr( out, in, key, outlen, inlen, keylen );
}

View file

@ -1,32 +1,39 @@
/*
BLAKE2 reference source code package - optimized C implementations
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
your option. The terms of these licenses can be found at:
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
- OpenSSL license : https://www.openssl.org/source/license.html
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
More information about the BLAKE2 hash function can be found at
https://blake2.net.
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#pragma once
#ifndef __BLAKE2_IMPL_H__
#define __BLAKE2_IMPL_H__
#if defined(_WIN32) || defined(WIN32)
#include <windows.h>
#endif
#include <stddef.h>
#include <stdint.h>
#include <string.h>
BLAKE2_LOCAL_INLINE(uint32_t) load32( const void *src )
#define BLAKE2_IMPL_CAT(x,y) x ## y
#define BLAKE2_IMPL_EVAL(x,y) BLAKE2_IMPL_CAT(x,y)
#define BLAKE2_IMPL_NAME(fun) BLAKE2_IMPL_EVAL(fun, SUFFIX)
static inline uint32_t load32( const void *src )
{
#if defined(NATIVE_LITTLE_ENDIAN)
uint32_t w;
memcpy(&w, src, sizeof w);
memcpy( &w, src, sizeof( w ) );
return w;
#else
const uint8_t *p = ( const uint8_t * )src;
const uint8_t *p = ( uint8_t * )src;
uint32_t w = *p++;
w |= ( uint32_t )( *p++ ) << 8;
w |= ( uint32_t )( *p++ ) << 16;
@ -35,14 +42,14 @@ BLAKE2_LOCAL_INLINE(uint32_t) load32( const void *src )
#endif
}
BLAKE2_LOCAL_INLINE(uint64_t) load64( const void *src )
static inline uint64_t load64( const void *src )
{
#if defined(NATIVE_LITTLE_ENDIAN)
uint64_t w;
memcpy(&w, src, sizeof w);
memcpy( &w, src, sizeof( w ) );
return w;
#else
const uint8_t *p = ( const uint8_t * )src;
const uint8_t *p = ( uint8_t * )src;
uint64_t w = *p++;
w |= ( uint64_t )( *p++ ) << 8;
w |= ( uint64_t )( *p++ ) << 16;
@ -55,10 +62,10 @@ BLAKE2_LOCAL_INLINE(uint64_t) load64( const void *src )
#endif
}
BLAKE2_LOCAL_INLINE(void) store32( void *dst, uint32_t w )
static inline void store32( void *dst, uint32_t w )
{
#if defined(NATIVE_LITTLE_ENDIAN)
memcpy(dst, &w, sizeof w);
memcpy( dst, &w, sizeof( w ) );
#else
uint8_t *p = ( uint8_t * )dst;
*p++ = ( uint8_t )w; w >>= 8;
@ -68,10 +75,10 @@ BLAKE2_LOCAL_INLINE(void) store32( void *dst, uint32_t w )
#endif
}
BLAKE2_LOCAL_INLINE(void) store64( void *dst, uint64_t w )
static inline void store64( void *dst, uint64_t w )
{
#if defined(NATIVE_LITTLE_ENDIAN)
memcpy(dst, &w, sizeof w);
memcpy( dst, &w, sizeof( w ) );
#else
uint8_t *p = ( uint8_t * )dst;
*p++ = ( uint8_t )w; w >>= 8;
@ -85,7 +92,7 @@ BLAKE2_LOCAL_INLINE(void) store64( void *dst, uint64_t w )
#endif
}
BLAKE2_LOCAL_INLINE(uint64_t) load48( const void *src )
static inline uint64_t load48( const void *src )
{
const uint8_t *p = ( const uint8_t * )src;
uint64_t w = *p++;
@ -97,7 +104,7 @@ BLAKE2_LOCAL_INLINE(uint64_t) load48( const void *src )
return w;
}
BLAKE2_LOCAL_INLINE(void) store48( void *dst, uint64_t w )
static inline void store48( void *dst, uint64_t w )
{
uint8_t *p = ( uint8_t * )dst;
*p++ = ( uint8_t )w; w >>= 8;
@ -108,31 +115,44 @@ BLAKE2_LOCAL_INLINE(void) store48( void *dst, uint64_t w )
*p++ = ( uint8_t )w;
}
BLAKE2_LOCAL_INLINE(uint32_t) rotl32( const uint32_t w, const unsigned c )
static inline uint32_t rotl32( const uint32_t w, const unsigned c )
{
return ( w << c ) | ( w >> ( 32 - c ) );
}
BLAKE2_LOCAL_INLINE(uint64_t) rotl64( const uint64_t w, const unsigned c )
static inline uint64_t rotl64( const uint64_t w, const unsigned c )
{
return ( w << c ) | ( w >> ( 64 - c ) );
}
BLAKE2_LOCAL_INLINE(uint32_t) rotr32( const uint32_t w, const unsigned c )
static inline uint32_t rotr32( const uint32_t w, const unsigned c )
{
return ( w >> c ) | ( w << ( 32 - c ) );
}
BLAKE2_LOCAL_INLINE(uint64_t) rotr64( const uint64_t w, const unsigned c )
static inline uint64_t rotr64( const uint64_t w, const unsigned c )
{
return ( w >> c ) | ( w << ( 64 - c ) );
}
/* prevents compiler optimizing out memset() */
BLAKE2_LOCAL_INLINE(void) secure_zero_memory(void *v, size_t n)
static inline void secure_zero_memory(void *v, size_t n)
{
static void *(*const volatile memset_v)(void *, int, size_t) = &memset;
memset_v(v, 0, n);
#if defined(_WIN32) || defined(WIN32)
SecureZeroMemory(v, n);
#else
// prioritize first the general C11 call
#if defined(HAVE_MEMSET_S)
memset_s(v, n, 0, n);
#elif defined(HAVE_EXPLICIT_BZERO)
explicit_bzero(v, n);
#elif defined(HAVE_EXPLICIT_MEMSET)
explicit_memset(v, 0, n);
#else
memset(v, 0, n);
__asm__ __volatile__("" :: "r"(v) : "memory");
#endif
#endif
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,16 +1,14 @@
/*
BLAKE2 reference source code package - reference C implementations
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
your option. The terms of these licenses can be found at:
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
- OpenSSL license : https://www.openssl.org/source/license.html
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
More information about the BLAKE2 hash function can be found at
https://blake2.net.
BLAKE2 reference source code package - optimized C implementations
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#pragma once
#ifndef __BLAKE2_H__
@ -19,16 +17,36 @@
#include <stddef.h>
#include <stdint.h>
#ifdef BLAKE2_NO_INLINE
#define BLAKE2_LOCAL_INLINE(type) static type
#if defined(_WIN32) || defined(__CYGWIN__)
#define BLAKE2_DLL_IMPORT __declspec(dllimport)
#define BLAKE2_DLL_EXPORT __declspec(dllexport)
#define BLAKE2_DLL_PRIVATE
#elif __GNUC__ >= 4
#define BLAKE2_DLL_IMPORT __attribute__ ((visibility ("default")))
#define BLAKE2_DLL_EXPORT __attribute__ ((visibility ("default")))
#define BLAKE2_DLL_PRIVATE __attribute__ ((visibility ("hidden")))
#else
#define BLAKE2_DLL_IMPORT
#define BLAKE2_DLL_EXPORT
#define BLAKE2_DLL_PRIVATE
#endif
#ifndef BLAKE2_LOCAL_INLINE
#define BLAKE2_LOCAL_INLINE(type) static inline type
#if defined(BLAKE2_DLL)
#if defined(BLAKE2_DLL_EXPORTS) // defined if we are building the DLL
#define BLAKE2_API BLAKE2_DLL_EXPORT
#else
#define BLAKE2_API BLAKE2_DLL_IMPORT
#endif
#define BLAKE2_PRIVATE BLAKE2_DLL_PRIVATE // must only be used by hidden logic
#else
#define BLAKE2_API
#define BLAKE2_PRIVATE
#endif
#if defined(__cplusplus)
extern "C" {
#elif defined(_MSC_VER) && !defined(inline)
#define inline __inline
#endif
enum blake2s_constant
@ -49,23 +67,56 @@ extern "C" {
BLAKE2B_PERSONALBYTES = 16
};
#pragma pack(push, 1)
typedef struct __blake2s_param
{
uint8_t digest_length; // 1
uint8_t key_length; // 2
uint8_t fanout; // 3
uint8_t depth; // 4
uint32_t leaf_length; // 8
uint8_t node_offset[6];// 14
uint8_t node_depth; // 15
uint8_t inner_length; // 16
// uint8_t reserved[0];
uint8_t salt[BLAKE2S_SALTBYTES]; // 24
uint8_t personal[BLAKE2S_PERSONALBYTES]; // 32
} blake2s_param;
typedef struct __blake2s_state
{
uint32_t h[8];
uint32_t t[2];
uint32_t f[2];
uint8_t buf[2 * BLAKE2S_BLOCKBYTES];
size_t buflen;
uint32_t buflen;
uint8_t outlen;
uint8_t last_node;
} blake2s_state;
typedef struct __blake2b_param
{
uint8_t digest_length; // 1
uint8_t key_length; // 2
uint8_t fanout; // 3
uint8_t depth; // 4
uint32_t leaf_length; // 8
uint64_t node_offset; // 16
uint8_t node_depth; // 17
uint8_t inner_length; // 18
uint8_t reserved[14]; // 32
uint8_t salt[BLAKE2B_SALTBYTES]; // 48
uint8_t personal[BLAKE2B_PERSONALBYTES]; // 64
} blake2b_param;
typedef struct __blake2b_state
{
uint64_t h[8];
uint64_t t[2];
uint64_t f[2];
uint8_t buf[2 * BLAKE2B_BLOCKBYTES];
size_t buflen;
uint32_t buflen;
uint8_t outlen;
uint8_t last_node;
} blake2b_state;
@ -73,82 +124,52 @@ extern "C" {
{
blake2s_state S[8][1];
blake2s_state R[1];
uint8_t buf[8 * BLAKE2S_BLOCKBYTES];
size_t buflen;
uint8_t buf[8 * BLAKE2S_BLOCKBYTES];
uint32_t buflen;
uint8_t outlen;
} blake2sp_state;
typedef struct __blake2bp_state
{
blake2b_state S[4][1];
blake2b_state R[1];
uint8_t buf[4 * BLAKE2B_BLOCKBYTES];
size_t buflen;
uint8_t buf[4 * BLAKE2B_BLOCKBYTES];
uint32_t buflen;
uint8_t outlen;
} blake2bp_state;
#pragma pack(push, 1)
typedef struct __blake2s_param
{
uint8_t digest_length; /* 1 */
uint8_t key_length; /* 2 */
uint8_t fanout; /* 3 */
uint8_t depth; /* 4 */
uint32_t leaf_length; /* 8 */
uint8_t node_offset[6];// 14
uint8_t node_depth; /* 15 */
uint8_t inner_length; /* 16 */
/* uint8_t reserved[0]; */
uint8_t salt[BLAKE2S_SALTBYTES]; /* 24 */
uint8_t personal[BLAKE2S_PERSONALBYTES]; /* 32 */
} blake2s_param;
typedef struct __blake2b_param
{
uint8_t digest_length; /* 1 */
uint8_t key_length; /* 2 */
uint8_t fanout; /* 3 */
uint8_t depth; /* 4 */
uint32_t leaf_length; /* 8 */
uint64_t node_offset; /* 16 */
uint8_t node_depth; /* 17 */
uint8_t inner_length; /* 18 */
uint8_t reserved[14]; /* 32 */
uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */
uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */
} blake2b_param;
#pragma pack(pop)
/* Streaming API */
int blake2s_init( blake2s_state *S, const uint8_t outlen );
int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, const uint8_t keylen );
int blake2s_init_param( blake2s_state *S, const blake2s_param *P );
int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen );
int blake2s_final( blake2s_state *S, uint8_t *out, uint8_t outlen );
// Streaming API
BLAKE2_API int blake2s_init( blake2s_state *S, size_t outlen );
BLAKE2_API int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
BLAKE2_API int blake2s_init_param( blake2s_state *S, const blake2s_param *P );
BLAKE2_API int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen );
BLAKE2_API int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen );
int blake2b_init( blake2b_state *S, const uint8_t outlen );
int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen );
int blake2b_init_param( blake2b_state *S, const blake2b_param *P );
int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen );
int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen );
BLAKE2_API int blake2b_init( blake2b_state *S, size_t outlen );
BLAKE2_API int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
BLAKE2_API int blake2b_init_param( blake2b_state *S, const blake2b_param *P );
BLAKE2_API int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen );
BLAKE2_API int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen );
int blake2sp_init( blake2sp_state *S, const uint8_t outlen );
int blake2sp_init_key( blake2sp_state *S, const uint8_t outlen, const void *key, const uint8_t keylen );
int blake2sp_update( blake2sp_state *S, const uint8_t *in, uint64_t inlen );
int blake2sp_final( blake2sp_state *S, uint8_t *out, uint8_t outlen );
BLAKE2_API int blake2sp_init( blake2sp_state *S, size_t outlen );
BLAKE2_API int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen );
BLAKE2_API int blake2sp_update( blake2sp_state *S, const uint8_t *in, size_t inlen );
BLAKE2_API int blake2sp_final( blake2sp_state *S, uint8_t *out, size_t outlen );
int blake2bp_init( blake2bp_state *S, const uint8_t outlen );
int blake2bp_init_key( blake2bp_state *S, const uint8_t outlen, const void *key, const uint8_t keylen );
int blake2bp_update( blake2bp_state *S, const uint8_t *in, uint64_t inlen );
int blake2bp_final( blake2bp_state *S, uint8_t *out, uint8_t outlen );
BLAKE2_API int blake2bp_init( blake2bp_state *S, size_t outlen );
BLAKE2_API int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen );
BLAKE2_API int blake2bp_update( blake2bp_state *S, const uint8_t *in, size_t inlen );
BLAKE2_API int blake2bp_final( blake2bp_state *S, uint8_t *out, size_t outlen );
/* Simple API */
int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen );
int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen );
// Simple API
BLAKE2_API int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
BLAKE2_API int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
int blake2sp( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen );
int blake2bp( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen );
BLAKE2_API int blake2sp( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
BLAKE2_API int blake2bp( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
static inline int blake2( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen )
static inline int blake2( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
{
return blake2b( out, in, key, outlen, inlen, keylen );
}

View file

@ -1,16 +1,14 @@
/*
BLAKE2 reference source code package - optimized C implementations
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
your option. The terms of these licenses can be found at:
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
- OpenSSL license : https://www.openssl.org/source/license.html
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
More information about the BLAKE2 hash function can be found at
https://blake2.net.
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#pragma once
#ifndef __BLAKE2B_LOAD_SSE2_H__

View file

@ -1,16 +1,14 @@
/*
BLAKE2 reference source code package - optimized C implementations
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
your option. The terms of these licenses can be found at:
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
- OpenSSL license : https://www.openssl.org/source/license.html
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
More information about the BLAKE2 hash function can be found at
https://blake2.net.
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#pragma once
#ifndef __BLAKE2B_LOAD_SSE41_H__

View file

@ -1,16 +1,14 @@
/*
BLAKE2 reference source code package - reference C implementations
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
your option. The terms of these licenses can be found at:
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
- OpenSSL license : https://www.openssl.org/source/license.html
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
More information about the BLAKE2 hash function can be found at
https://blake2.net.
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include <stdint.h>
@ -45,41 +43,36 @@ static const uint8_t blake2b_sigma[12][16] =
};
BLAKE2_LOCAL_INLINE(int) blake2b_set_lastnode( blake2b_state *S )
static inline int blake2b_set_lastnode( blake2b_state *S )
{
S->f[1] = -1;
S->f[1] = ~0ULL;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2b_clear_lastnode( blake2b_state *S )
static inline int blake2b_clear_lastnode( blake2b_state *S )
{
S->f[1] = 0;
S->f[1] = 0ULL;
return 0;
}
/* Some helper functions, not necessarily useful */
BLAKE2_LOCAL_INLINE(int) blake2b_is_lastblock( const blake2b_state *S )
{
return S->f[0] != 0;
}
BLAKE2_LOCAL_INLINE(int) blake2b_set_lastblock( blake2b_state *S )
static inline int blake2b_set_lastblock( blake2b_state *S )
{
if( S->last_node ) blake2b_set_lastnode( S );
S->f[0] = -1;
S->f[0] = ~0ULL;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2b_clear_lastblock( blake2b_state *S )
static inline int blake2b_clear_lastblock( blake2b_state *S )
{
if( S->last_node ) blake2b_clear_lastnode( S );
S->f[0] = 0;
S->f[0] = 0ULL;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2b_increment_counter( blake2b_state *S, const uint64_t inc )
static inline int blake2b_increment_counter( blake2b_state *S, const uint64_t inc )
{
S->t[0] += inc;
S->t[1] += ( S->t[0] < inc );
@ -88,95 +81,106 @@ BLAKE2_LOCAL_INLINE(int) blake2b_increment_counter( blake2b_state *S, const uint
/* Parameter-related functions */
BLAKE2_LOCAL_INLINE(int) blake2b_param_set_digest_length( blake2b_param *P, const uint8_t digest_length )
// Parameter-related functions
static inline int blake2b_param_set_digest_length( blake2b_param *P, const uint8_t digest_length )
{
P->digest_length = digest_length;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2b_param_set_fanout( blake2b_param *P, const uint8_t fanout )
static inline int blake2b_param_set_fanout( blake2b_param *P, const uint8_t fanout )
{
P->fanout = fanout;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2b_param_set_max_depth( blake2b_param *P, const uint8_t depth )
static inline int blake2b_param_set_max_depth( blake2b_param *P, const uint8_t depth )
{
P->depth = depth;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2b_param_set_leaf_length( blake2b_param *P, const uint32_t leaf_length )
static inline int blake2b_param_set_leaf_length( blake2b_param *P, const uint32_t leaf_length )
{
store32( &P->leaf_length, leaf_length );
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2b_param_set_node_offset( blake2b_param *P, const uint64_t node_offset )
static inline int blake2b_param_set_node_offset( blake2b_param *P, const uint64_t node_offset )
{
store64( &P->node_offset, node_offset );
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2b_param_set_node_depth( blake2b_param *P, const uint8_t node_depth )
static inline int blake2b_param_set_node_depth( blake2b_param *P, const uint8_t node_depth )
{
P->node_depth = node_depth;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2b_param_set_inner_length( blake2b_param *P, const uint8_t inner_length )
static inline int blake2b_param_set_inner_length( blake2b_param *P, const uint8_t inner_length )
{
P->inner_length = inner_length;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2b_param_set_salt( blake2b_param *P, const uint8_t salt[BLAKE2B_SALTBYTES] )
static inline int blake2b_param_set_salt( blake2b_param *P, const uint8_t salt[BLAKE2B_SALTBYTES] )
{
memcpy( P->salt, salt, BLAKE2B_SALTBYTES );
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2b_param_set_personal( blake2b_param *P, const uint8_t personal[BLAKE2B_PERSONALBYTES] )
static inline int blake2b_param_set_personal( blake2b_param *P, const uint8_t personal[BLAKE2B_PERSONALBYTES] )
{
memcpy( P->personal, personal, BLAKE2B_PERSONALBYTES );
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2b_init0( blake2b_state *S )
static inline int blake2b_init0( blake2b_state *S )
{
int i;
memset( S, 0, sizeof( blake2b_state ) );
for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i];
for( int i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i];
return 0;
}
#if defined(__cplusplus)
extern "C" {
#endif
int blake2b_init( blake2b_state *S, size_t outlen );
int blake2b_init_param( blake2b_state *S, const blake2b_param *P );
int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen );
int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen );
int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
#if defined(__cplusplus)
}
#endif
/* init xors IV with input parameter block */
int blake2b_init_param( blake2b_state *S, const blake2b_param *P )
{
const uint8_t *p = ( const uint8_t * )( P );
size_t i;
blake2b_init0( S );
uint8_t *p = ( uint8_t * )( P );
/* IV XOR ParamBlock */
for( i = 0; i < 8; ++i )
for( size_t i = 0; i < 8; ++i )
S->h[i] ^= load64( p + sizeof( S->h[i] ) * i );
S->outlen = P->digest_length;
return 0;
}
int blake2b_init( blake2b_state *S, const uint8_t outlen )
int blake2b_init( blake2b_state *S, size_t outlen )
{
blake2b_param P[1];
if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
P->digest_length = outlen;
P->digest_length = ( uint8_t ) outlen;
P->key_length = 0;
P->fanout = 1;
P->depth = 1;
@ -191,7 +195,7 @@ int blake2b_init( blake2b_state *S, const uint8_t outlen )
}
int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen )
int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen )
{
blake2b_param P[1];
@ -199,8 +203,8 @@ int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, c
if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1;
P->digest_length = outlen;
P->key_length = keylen;
P->digest_length = ( uint8_t ) outlen;
P->key_length = ( uint8_t ) keylen;
P->fanout = 1;
P->depth = 1;
store32( &P->leaf_length, 0 );
@ -227,7 +231,7 @@ static int blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCK
{
uint64_t m[16];
uint64_t v[16];
int i;
size_t i;
for( i = 0; i < 16; ++i )
m[i] = load64( block + i * sizeof( m[i] ) );
@ -286,29 +290,29 @@ static int blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCK
return 0;
}
/* inlen now in bytes */
int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen )
int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen )
{
while( inlen > 0 )
{
size_t left = S->buflen;
size_t fill = 2 * BLAKE2B_BLOCKBYTES - left;
uint32_t left = S->buflen;
uint32_t fill = 2 * BLAKE2B_BLOCKBYTES - left;
if( inlen > fill )
{
memcpy( S->buf + left, in, fill ); /* Fill buffer */
memcpy( S->buf + left, in, fill ); // Fill buffer
S->buflen += fill;
blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
blake2b_compress( S, S->buf ); /* Compress */
memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); /* Shift buffer left */
blake2b_compress( S, S->buf ); // Compress
memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); // Shift buffer left
S->buflen -= BLAKE2B_BLOCKBYTES;
in += fill;
inlen -= fill;
}
else /* inlen <= fill */
else // inlen <= fill
{
memcpy( S->buf + left, in, (size_t)inlen );
S->buflen += (size_t)inlen; /* Be lazy, do not compress */
memcpy( S->buf + left, in, inlen );
S->buflen += ( uint32_t ) inlen; // Be lazy, do not compress
in += inlen;
inlen -= inlen;
}
@ -317,24 +321,19 @@ int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen )
return 0;
}
/* Is this correct? */
int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen )
int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen )
{
uint8_t buffer[BLAKE2B_OUTBYTES] = {0};
int i;
uint8_t buffer[BLAKE2B_OUTBYTES];
size_t i;
if( out == NULL || outlen == 0 || outlen > BLAKE2B_OUTBYTES )
return -1;
if( blake2b_is_lastblock( S ) )
return -1;
if(S->outlen != outlen) return -1;
if( S->buflen > BLAKE2B_BLOCKBYTES )
{
blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
blake2b_compress( S, S->buf );
S->buflen -= BLAKE2B_BLOCKBYTES;
memmove( S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen );
memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen );
}
blake2b_increment_counter( S, S->buflen );
@ -349,8 +348,7 @@ int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen )
return 0;
}
/* inlen, at least, should be uint64_t. Others can be size_t. */
int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen )
int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
{
blake2b_state S[1];
@ -374,47 +372,8 @@ int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen
if( blake2b_init( S, outlen ) < 0 ) return -1;
}
blake2b_update( S, ( const uint8_t * )in, inlen );
blake2b_final( S, out, outlen );
return 0;
if( blake2b_update( S, ( uint8_t * )in, inlen ) < 0 ) return -1;
return blake2b_final( S, out, outlen );
}
#if defined(SUPERCOP)
int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen )
{
return blake2b( out, in, NULL, BLAKE2B_OUTBYTES, inlen, 0 );
}
#endif
#if defined(BLAKE2B_SELFTEST)
#include <string.h>
#include "blake2-kat.h"
int main( int argc, char **argv )
{
uint8_t key[BLAKE2B_KEYBYTES];
uint8_t buf[KAT_LENGTH];
size_t i;
for( i = 0; i < BLAKE2B_KEYBYTES; ++i )
key[i] = ( uint8_t )i;
for( i = 0; i < KAT_LENGTH; ++i )
buf[i] = ( uint8_t )i;
for( i = 0; i < KAT_LENGTH; ++i )
{
uint8_t hash[BLAKE2B_OUTBYTES];
blake2b( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES );
if( 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) )
{
puts( "error" );
return -1;
}
}
puts( "ok" );
return 0;
}
#endif

View file

@ -1,22 +1,23 @@
/*
BLAKE2 reference source code package - optimized C implementations
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
your option. The terms of these licenses can be found at:
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
- OpenSSL license : https://www.openssl.org/source/license.html
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
More information about the BLAKE2 hash function can be found at
https://blake2.net.
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#pragma once
#ifndef __BLAKE2B_ROUND_H__
#define __BLAKE2B_ROUND_H__
#define LOADU(p) _mm_loadu_si128( (const __m128i *)(p) )
#define LOAD(p) _mm_load_si128( (__m128i *)(p) )
#define STORE(p,r) _mm_store_si128((__m128i *)(p), r)
#define LOADU(p) _mm_loadu_si128( (__m128i *)(p) )
#define STOREU(p,r) _mm_storeu_si128((__m128i *)(p), r)
#define TOF(reg) _mm_castsi128_ps((reg))
@ -137,7 +138,7 @@
#endif
#if defined(HAVE_SSE41)
#if defined(HAVE_SSE4_1)
#include "blake2b-load-sse41.h"
#else
#include "blake2b-load-sse2.h"

View file

@ -0,0 +1,43 @@
/*
BLAKE2 reference source code package - optimized C implementations
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include <stdio.h>
#include <string.h>
#include "blake2.h"
#include "blake2-kat.h"
int main( int argc, char **argv )
{
uint8_t key[BLAKE2B_KEYBYTES];
uint8_t buf[KAT_LENGTH];
for( size_t i = 0; i < BLAKE2B_KEYBYTES; ++i )
key[i] = ( uint8_t )i;
for( size_t i = 0; i < KAT_LENGTH; ++i )
buf[i] = ( uint8_t )i;
for( size_t i = 0; i < KAT_LENGTH; ++i )
{
uint8_t hash[BLAKE2B_OUTBYTES];
if( blake2b( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES ) < 0 ||
0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) )
{
puts( "error" );
return -1;
}
}
puts( "ok" );
return 0;
}

View file

@ -1,16 +1,14 @@
/*
BLAKE2 reference source code package - optimized C implementations
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
your option. The terms of these licenses can be found at:
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
- OpenSSL license : https://www.openssl.org/source/license.html
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
More information about the BLAKE2 hash function can be found at
https://blake2.net.
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include <stdint.h>
@ -22,23 +20,36 @@
#include "blake2-config.h"
#ifdef _MSC_VER
#include <intrin.h> /* for _mm_set_epi64x */
#if defined(_MSC_VER)
#include <intrin.h>
#endif
#if defined(HAVE_SSE2)
#include <emmintrin.h>
// MSVC only defines _mm_set_epi64x for x86_64...
#if defined(_MSC_VER) && !defined(_M_X64)
static inline __m128i _mm_set_epi64x( const uint64_t u1, const uint64_t u0 )
{
return _mm_set_epi32( u1 >> 32, u1, u0 >> 32, u0 );
}
#endif
#endif
#if defined(HAVE_SSSE3)
#include <tmmintrin.h>
#endif
#if defined(HAVE_SSE41)
#if defined(HAVE_SSE4_1)
#include <smmintrin.h>
#endif
#if defined(HAVE_AVX)
#include <immintrin.h>
#endif
#if defined(HAVE_XOP)
#if defined(HAVE_XOP) && !defined(_MSC_VER)
#include <x86intrin.h>
#endif
#include "blake2b-round.h"
static const uint64_t blake2b_IV[8] =
@ -67,44 +78,39 @@ static const uint8_t blake2b_sigma[12][16] =
/* Some helper functions, not necessarily useful */
BLAKE2_LOCAL_INLINE(int) blake2b_set_lastnode( blake2b_state *S )
static inline int blake2b_set_lastnode( blake2b_state *S )
{
S->f[1] = -1;
S->f[1] = ~0ULL;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2b_clear_lastnode( blake2b_state *S )
static inline int blake2b_clear_lastnode( blake2b_state *S )
{
S->f[1] = 0;
S->f[1] = 0ULL;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2b_is_lastblock( const blake2b_state *S )
{
return S->f[0] != 0;
}
BLAKE2_LOCAL_INLINE(int) blake2b_set_lastblock( blake2b_state *S )
static inline int blake2b_set_lastblock( blake2b_state *S )
{
if( S->last_node ) blake2b_set_lastnode( S );
S->f[0] = -1;
S->f[0] = ~0ULL;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2b_clear_lastblock( blake2b_state *S )
static inline int blake2b_clear_lastblock( blake2b_state *S )
{
if( S->last_node ) blake2b_clear_lastnode( S );
S->f[0] = 0;
S->f[0] = 0ULL;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2b_increment_counter( blake2b_state *S, const uint64_t inc )
static inline int blake2b_increment_counter( blake2b_state *S, const uint64_t inc )
{
#if __x86_64__
/* ADD/ADC chain */
#if defined(__x86_64__) && (defined(__GNUC__) || defined(__clang__))
// ADD/ADC chain
__uint128_t t = ( ( __uint128_t )S->t[1] << 64 ) | S->t[0];
t += inc;
S->t[0] = ( uint64_t )( t >> 0 );
@ -117,94 +123,119 @@ BLAKE2_LOCAL_INLINE(int) blake2b_increment_counter( blake2b_state *S, const uint
}
/* Parameter-related functions */
BLAKE2_LOCAL_INLINE(int) blake2b_param_set_digest_length( blake2b_param *P, const uint8_t digest_length )
// Parameter-related functions
static inline int blake2b_param_set_digest_length( blake2b_param *P, const uint8_t digest_length )
{
P->digest_length = digest_length;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2b_param_set_fanout( blake2b_param *P, const uint8_t fanout )
static inline int blake2b_param_set_fanout( blake2b_param *P, const uint8_t fanout )
{
P->fanout = fanout;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2b_param_set_max_depth( blake2b_param *P, const uint8_t depth )
static inline int blake2b_param_set_max_depth( blake2b_param *P, const uint8_t depth )
{
P->depth = depth;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2b_param_set_leaf_length( blake2b_param *P, const uint32_t leaf_length )
static inline int blake2b_param_set_leaf_length( blake2b_param *P, const uint32_t leaf_length )
{
P->leaf_length = leaf_length;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2b_param_set_node_offset( blake2b_param *P, const uint64_t node_offset )
static inline int blake2b_param_set_node_offset( blake2b_param *P, const uint64_t node_offset )
{
P->node_offset = node_offset;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2b_param_set_node_depth( blake2b_param *P, const uint8_t node_depth )
static inline int blake2b_param_set_node_depth( blake2b_param *P, const uint8_t node_depth )
{
P->node_depth = node_depth;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2b_param_set_inner_length( blake2b_param *P, const uint8_t inner_length )
static inline int blake2b_param_set_inner_length( blake2b_param *P, const uint8_t inner_length )
{
P->inner_length = inner_length;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2b_param_set_salt( blake2b_param *P, const uint8_t salt[BLAKE2B_SALTBYTES] )
static inline int blake2b_param_set_salt( blake2b_param *P, const uint8_t salt[BLAKE2B_SALTBYTES] )
{
memcpy( P->salt, salt, BLAKE2B_SALTBYTES );
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2b_param_set_personal( blake2b_param *P, const uint8_t personal[BLAKE2B_PERSONALBYTES] )
static inline int blake2b_param_set_personal( blake2b_param *P, const uint8_t personal[BLAKE2B_PERSONALBYTES] )
{
memcpy( P->personal, personal, BLAKE2B_PERSONALBYTES );
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2b_init0( blake2b_state *S )
static inline int blake2b_init0( blake2b_state *S )
{
int i;
memset( S, 0, sizeof( blake2b_state ) );
for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i];
for( int i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i];
return 0;
}
#define blake2b_init BLAKE2_IMPL_NAME(blake2b_init)
#define blake2b_init_param BLAKE2_IMPL_NAME(blake2b_init_param)
#define blake2b_init_key BLAKE2_IMPL_NAME(blake2b_init_key)
#define blake2b_update BLAKE2_IMPL_NAME(blake2b_update)
#define blake2b_final BLAKE2_IMPL_NAME(blake2b_final)
#define blake2b BLAKE2_IMPL_NAME(blake2b)
#if defined(__cplusplus)
extern "C" {
#endif
int blake2b_init( blake2b_state *S, size_t outlen );
int blake2b_init_param( blake2b_state *S, const blake2b_param *P );
int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen );
int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen );
int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
#if defined(__cplusplus)
}
#endif
/* init xors IV with input parameter block */
int blake2b_init_param( blake2b_state *S, const blake2b_param *P )
{
/*blake2b_init0( S ); */
const uint8_t * v = ( const uint8_t * )( blake2b_IV );
const uint8_t * p = ( const uint8_t * )( P );
uint8_t * h = ( uint8_t * )( S->h );
int i;
uint8_t *p, *h, *v;
//blake2b_init0( S );
v = ( uint8_t * )( blake2b_IV );
h = ( uint8_t * )( S->h );
p = ( uint8_t * )( P );
/* IV XOR ParamBlock */
memset( S, 0, sizeof( blake2b_state ) );
for( i = 0; i < BLAKE2B_OUTBYTES; ++i ) h[i] = v[i] ^ p[i];
for( int i = 0; i < BLAKE2B_OUTBYTES; ++i ) h[i] = v[i] ^ p[i];
S->outlen = P->digest_length;
return 0;
}
/* Some sort of default parameter block initialization, for sequential blake2b */
int blake2b_init( blake2b_state *S, const uint8_t outlen )
int blake2b_init( blake2b_state *S, size_t outlen )
{
if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
const blake2b_param P =
{
outlen,
( uint8_t ) outlen,
0,
1,
1,
@ -216,18 +247,19 @@ int blake2b_init( blake2b_state *S, const uint8_t outlen )
{0},
{0}
};
if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
return blake2b_init_param( S, &P );
}
int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen )
int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen )
{
if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
if ( ( !keylen ) || keylen > BLAKE2B_KEYBYTES ) return -1;
const blake2b_param P =
{
outlen,
keylen,
( uint8_t ) outlen,
( uint8_t ) keylen,
1,
1,
0,
@ -239,10 +271,6 @@ int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, c
{0}
};
if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
if ( ( !keylen ) || keylen > BLAKE2B_KEYBYTES ) return -1;
if( blake2b_init_param( S, &P ) < 0 )
return 0;
@ -256,7 +284,7 @@ int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, c
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] )
static inline int blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] )
{
__m128i row1l, row1h;
__m128i row2l, row2h;
@ -268,7 +296,7 @@ BLAKE2_LOCAL_INLINE(int) blake2b_compress( blake2b_state *S, const uint8_t block
const __m128i r16 = _mm_setr_epi8( 2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9 );
const __m128i r24 = _mm_setr_epi8( 3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10 );
#endif
#if defined(HAVE_SSE41)
#if defined(HAVE_SSE4_1)
const __m128i m0 = LOADU( block + 00 );
const __m128i m1 = LOADU( block + 16 );
const __m128i m2 = LOADU( block + 32 );
@ -327,28 +355,28 @@ BLAKE2_LOCAL_INLINE(int) blake2b_compress( blake2b_state *S, const uint8_t block
}
int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen )
int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen )
{
while( inlen > 0 )
{
size_t left = S->buflen;
size_t fill = 2 * BLAKE2B_BLOCKBYTES - left;
uint32_t left = S->buflen;
uint32_t fill = 2 * BLAKE2B_BLOCKBYTES - left;
if( inlen > fill )
{
memcpy( S->buf + left, in, fill ); /* Fill buffer */
memcpy( S->buf + left, in, fill ); // Fill buffer
S->buflen += fill;
blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
blake2b_compress( S, S->buf ); /* Compress */
memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); /* Shift buffer left */
blake2b_compress( S, S->buf ); // Compress
memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); // Shift buffer left
S->buflen -= BLAKE2B_BLOCKBYTES;
in += fill;
inlen -= fill;
}
else /* inlen <= fill */
else // inlen <= fill
{
memcpy( S->buf + left, in, inlen );
S->buflen += inlen; /* Be lazy, do not compress */
S->buflen += ( uint32_t ) inlen; // Be lazy, do not compress
in += inlen;
inlen -= inlen;
}
@ -358,20 +386,16 @@ int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen )
}
int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen )
int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen )
{
if( outlen > BLAKE2B_OUTBYTES )
return -1;
if( blake2b_is_lastblock( S ) )
return -1;
if(S->outlen != outlen) return -1;
if( S->buflen > BLAKE2B_BLOCKBYTES )
{
blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
blake2b_compress( S, S->buf );
S->buflen -= BLAKE2B_BLOCKBYTES;
memmove( S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen );
memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen );
}
blake2b_increment_counter( S, S->buflen );
@ -383,7 +407,7 @@ int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen )
}
int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen )
int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
{
blake2b_state S[1];
@ -407,9 +431,8 @@ int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen
if( blake2b_init( S, outlen ) < 0 ) return -1;
}
blake2b_update( S, ( const uint8_t * )in, inlen );
blake2b_final( S, out, outlen );
return 0;
if( blake2b_update( S, ( uint8_t * )in, inlen ) < 0) return -1;
return blake2b_final( S, out, outlen );
}
#if defined(SUPERCOP)
@ -418,36 +441,3 @@ int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen
return blake2b( out, in, NULL, BLAKE2B_OUTBYTES, inlen, 0 );
}
#endif
#if defined(BLAKE2B_SELFTEST)
#include <string.h>
#include "blake2-kat.h"
int main( int argc, char **argv )
{
uint8_t key[BLAKE2B_KEYBYTES];
uint8_t buf[KAT_LENGTH];
size_t i;
for( i = 0; i < BLAKE2B_KEYBYTES; ++i )
key[i] = ( uint8_t )i;
for( i = 0; i < KAT_LENGTH; ++i )
buf[i] = ( uint8_t )i;
for( i = 0; i < KAT_LENGTH; ++i )
{
uint8_t hash[BLAKE2B_OUTBYTES];
blake2b( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES );
if( 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) )
{
puts( "error" );
return -1;
}
}
puts( "ok" );
return 0;
}
#endif

View file

@ -0,0 +1,44 @@
/*
BLAKE2 reference source code package - optimized C implementations
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include <stdio.h>
#include <string.h>
#include "blake2.h"
#include "blake2-kat.h"
int main( int argc, char **argv )
{
uint8_t key[BLAKE2B_KEYBYTES];
uint8_t buf[KAT_LENGTH];
for( size_t i = 0; i < BLAKE2B_KEYBYTES; ++i )
key[i] = ( uint8_t )i;
for( size_t i = 0; i < KAT_LENGTH; ++i )
buf[i] = ( uint8_t )i;
for( size_t i = 0; i < KAT_LENGTH; ++i )
{
uint8_t hash[BLAKE2B_OUTBYTES];
if( blake2bp( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES ) < 0 ||
0 != memcmp( hash, blake2bp_keyed_kat[i], BLAKE2B_OUTBYTES ) )
{
puts( "error" );
return -1;
}
}
puts( "ok" );
return 0;
}

View file

@ -0,0 +1,274 @@
/*
BLAKE2 reference source code package - optimized C implementations
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#if defined(_OPENMP)
#include <omp.h>
#endif
#include "blake2.h"
#include "blake2-impl.h"
#define PARALLELISM_DEGREE 4
static int blake2bp_init_leaf( blake2b_state *S, uint8_t outlen, uint8_t keylen, uint64_t offset )
{
blake2b_param P[1];
P->digest_length = outlen;
P->key_length = keylen;
P->fanout = PARALLELISM_DEGREE;
P->depth = 2;
store32(&P->leaf_length, 0);
store64(&P->node_offset, offset);
P->node_depth = 0;
P->inner_length = BLAKE2B_OUTBYTES;
memset( P->reserved, 0, sizeof( P->reserved ) );
memset( P->salt, 0, sizeof( P->salt ) );
memset( P->personal, 0, sizeof( P->personal ) );
blake2b_init_param( S, P );
S->outlen = P->inner_length;
return 0;
}
static int blake2bp_init_root( blake2b_state *S, uint8_t outlen, uint8_t keylen )
{
blake2b_param P[1];
P->digest_length = outlen;
P->key_length = keylen;
P->fanout = PARALLELISM_DEGREE;
P->depth = 2;
store32(&P->leaf_length, 0);
store64(&P->node_offset, 0);
P->node_depth = 1;
P->inner_length = BLAKE2B_OUTBYTES;
memset( P->reserved, 0, sizeof( P->reserved ) );
memset( P->salt, 0, sizeof( P->salt ) );
memset( P->personal, 0, sizeof( P->personal ) );
blake2b_init_param( S, P );
S->outlen = P->digest_length;
return 0;
}
int blake2bp_init( blake2bp_state *S, size_t outlen )
{
if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;
memset( S->buf, 0, sizeof( S->buf ) );
S->buflen = 0;
if( blake2bp_init_root( S->R, ( uint8_t ) outlen, 0 ) < 0 )
return -1;
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
if( blake2bp_init_leaf( S->S[i], ( uint8_t ) outlen, 0, i ) < 0 ) return -1;
S->R->last_node = 1;
S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
S->outlen = ( uint8_t ) outlen;
return 0;
}
int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen )
{
if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;
if( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1;
memset( S->buf, 0, sizeof( S->buf ) );
S->buflen = 0;
if( blake2bp_init_root( S->R, ( uint8_t ) outlen, ( uint8_t ) keylen ) < 0 )
return -1;
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
if( blake2bp_init_leaf( S->S[i], ( uint8_t ) outlen, ( uint8_t ) keylen, i ) < 0 )
return -1;
S->R->last_node = 1;
S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
S->outlen = ( uint8_t ) outlen;
{
uint8_t block[BLAKE2B_BLOCKBYTES];
memset( block, 0, BLAKE2B_BLOCKBYTES );
memcpy( block, key, keylen );
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
blake2b_update( S->S[i], block, BLAKE2B_BLOCKBYTES );
secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */
}
return 0;
}
int blake2bp_update( blake2bp_state *S, const uint8_t *in, size_t inlen )
{
size_t left = S->buflen;
size_t fill = sizeof( S->buf ) - left;
if( left && inlen >= fill )
{
memcpy( S->buf + left, in, fill );
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES );
in += fill;
inlen -= fill;
left = 0;
}
#if defined(_OPENMP)
omp_set_num_threads(PARALLELISM_DEGREE);
#pragma omp parallel shared(S)
#else
for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )
#endif
{
#if defined(_OPENMP)
size_t id__ = ( size_t ) omp_get_thread_num();
#endif
size_t inlen__ = inlen;
const uint8_t *in__ = ( const uint8_t * )in;
in__ += id__ * BLAKE2B_BLOCKBYTES;
while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES )
{
blake2b_update( S->S[id__], in__, BLAKE2B_BLOCKBYTES );
in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;
inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;
}
}
in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES );
inlen %= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;
if( inlen > 0 )
memcpy( S->buf + left, in, inlen );
S->buflen = ( uint32_t ) left + ( uint32_t ) inlen;
return 0;
}
int blake2bp_final( blake2bp_state *S, uint8_t *out, size_t outlen )
{
uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES];
if(S->outlen != outlen) return -1;
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
{
if( S->buflen > i * BLAKE2B_BLOCKBYTES )
{
size_t left = S->buflen - i * BLAKE2B_BLOCKBYTES;
if( left > BLAKE2B_BLOCKBYTES ) left = BLAKE2B_BLOCKBYTES;
blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, left );
}
blake2b_final( S->S[i], hash[i], BLAKE2B_OUTBYTES );
}
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
blake2b_update( S->R, hash[i], BLAKE2B_OUTBYTES );
return blake2b_final( S->R, out, outlen );
}
int blake2bp( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
{
uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES];
blake2b_state S[PARALLELISM_DEGREE][1];
blake2b_state FS[1];
/* Verify parameters */
if ( NULL == in && inlen > 0 ) return -1;
if ( NULL == out ) return -1;
if ( NULL == key && keylen > 0) return -1;
if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;
if( keylen > BLAKE2B_KEYBYTES ) return -1;
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
if( blake2bp_init_leaf( S[i], ( uint8_t ) outlen, ( uint8_t ) keylen, i ) < 0 )
return -1;
S[PARALLELISM_DEGREE - 1]->last_node = 1; // mark last node
if( keylen > 0 )
{
uint8_t block[BLAKE2B_BLOCKBYTES];
memset( block, 0, BLAKE2B_BLOCKBYTES );
memcpy( block, key, keylen );
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
blake2b_update( S[i], block, BLAKE2B_BLOCKBYTES );
secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */
}
#if defined(_OPENMP)
omp_set_num_threads(PARALLELISM_DEGREE);
#pragma omp parallel shared(S,hash)
#else
for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )
#endif
{
#if defined(_OPENMP)
size_t id__ = ( size_t ) omp_get_thread_num();
#endif
size_t inlen__ = inlen;
const uint8_t *in__ = ( const uint8_t * )in;
in__ += id__ * BLAKE2B_BLOCKBYTES;
while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES )
{
blake2b_update( S[id__], in__, BLAKE2B_BLOCKBYTES );
in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;
inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;
}
if( inlen__ > id__ * BLAKE2B_BLOCKBYTES )
{
const size_t left = inlen__ - id__ * BLAKE2B_BLOCKBYTES;
const size_t len = left <= BLAKE2B_BLOCKBYTES ? left : BLAKE2B_BLOCKBYTES;
blake2b_update( S[id__], in__, len );
}
blake2b_final( S[id__], hash[id__], BLAKE2B_OUTBYTES );
}
if( blake2bp_init_root( FS, ( uint8_t ) outlen, ( uint8_t ) keylen ) < 0 )
return -1;
FS->last_node = 1; // Mark as last node
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
blake2b_update( FS, hash[i], BLAKE2B_OUTBYTES );
return blake2b_final( FS, out, outlen );
}

View file

@ -1,16 +1,14 @@
/*
BLAKE2 reference source code package - optimized C implementations
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
your option. The terms of these licenses can be found at:
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
- OpenSSL license : https://www.openssl.org/source/license.html
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
More information about the BLAKE2 hash function can be found at
https://blake2.net.
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#pragma once
#ifndef __BLAKE2S_LOAD_SSE2_H__

View file

@ -1,16 +1,14 @@
/*
BLAKE2 reference source code package - optimized C implementations
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
your option. The terms of these licenses can be found at:
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
- OpenSSL license : https://www.openssl.org/source/license.html
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
More information about the BLAKE2 hash function can be found at
https://blake2.net.
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#pragma once
#ifndef __BLAKE2S_LOAD_SSE41_H__

View file

@ -1,35 +1,31 @@
/*
BLAKE2 reference source code package - optimized C implementations
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
your option. The terms of these licenses can be found at:
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
- OpenSSL license : https://www.openssl.org/source/license.html
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
More information about the BLAKE2 hash function can be found at
https://blake2.net.
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#pragma once
#ifndef __BLAKE2S_LOAD_XOP_H__
#define __BLAKE2S_LOAD_XOP_H__
#define TOB(x) ((x)*4*0x01010101 + 0x03020100) /* ..or not TOB */
#define TOB(x) ((x)*4*0x01010101 + 0x03020100) // ..or not TOB
#if 0
/* Basic VPPERM emulation, for testing purposes */
static __m128i _mm_perm_epi8(const __m128i src1, const __m128i src2, const __m128i sel)
/*static __m128i _mm_perm_epi8(const __m128i src1, const __m128i src2, const __m128i sel)
{
const __m128i sixteen = _mm_set1_epi8(16);
const __m128i t0 = _mm_shuffle_epi8(src1, sel);
const __m128i s1 = _mm_shuffle_epi8(src2, _mm_sub_epi8(sel, sixteen));
const __m128i mask = _mm_or_si128(_mm_cmpeq_epi8(sel, sixteen),
_mm_cmpgt_epi8(sel, sixteen)); /* (>=16) = 0xff : 00 */
_mm_cmpgt_epi8(sel, sixteen)); // (>=16) = 0xff : 00
return _mm_blendv_epi8(t0, s1, mask);
}
#endif
}*/
#define LOAD_MSG_0_1(buf) \
buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(6),TOB(4),TOB(2),TOB(0)) );

View file

@ -1,16 +1,14 @@
/*
BLAKE2 reference source code package - reference C implementations
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
your option. The terms of these licenses can be found at:
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
- OpenSSL license : https://www.openssl.org/source/license.html
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
More information about the BLAKE2 hash function can be found at
https://blake2.net.
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include <stdint.h>
@ -40,137 +38,143 @@ static const uint8_t blake2s_sigma[10][16] =
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
};
BLAKE2_LOCAL_INLINE(int) blake2s_set_lastnode( blake2s_state *S )
static inline int blake2s_set_lastnode( blake2s_state *S )
{
S->f[1] = -1;
S->f[1] = ~0U;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2s_clear_lastnode( blake2s_state *S )
static inline int blake2s_clear_lastnode( blake2s_state *S )
{
S->f[1] = 0;
S->f[1] = 0U;
return 0;
}
/* Some helper functions, not necessarily useful */
BLAKE2_LOCAL_INLINE(int) blake2s_is_lastblock( const blake2s_state *S )
{
return S->f[0] != 0;
}
BLAKE2_LOCAL_INLINE(int) blake2s_set_lastblock( blake2s_state *S )
static inline int blake2s_set_lastblock( blake2s_state *S )
{
if( S->last_node ) blake2s_set_lastnode( S );
S->f[0] = -1;
S->f[0] = ~0U;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2s_clear_lastblock( blake2s_state *S )
static inline int blake2s_clear_lastblock( blake2s_state *S )
{
if( S->last_node ) blake2s_clear_lastnode( S );
S->f[0] = 0;
S->f[0] = 0U;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2s_increment_counter( blake2s_state *S, const uint32_t inc )
static inline int blake2s_increment_counter( blake2s_state *S, const uint32_t inc )
{
S->t[0] += inc;
S->t[1] += ( S->t[0] < inc );
return 0;
}
/* Parameter-related functions */
BLAKE2_LOCAL_INLINE(int) blake2s_param_set_digest_length( blake2s_param *P, const uint8_t digest_length )
// Parameter-related functions
static inline int blake2s_param_set_digest_length( blake2s_param *P, const uint8_t digest_length )
{
P->digest_length = digest_length;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2s_param_set_fanout( blake2s_param *P, const uint8_t fanout )
static inline int blake2s_param_set_fanout( blake2s_param *P, const uint8_t fanout )
{
P->fanout = fanout;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2s_param_set_max_depth( blake2s_param *P, const uint8_t depth )
static inline int blake2s_param_set_max_depth( blake2s_param *P, const uint8_t depth )
{
P->depth = depth;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2s_param_set_leaf_length( blake2s_param *P, const uint32_t leaf_length )
static inline int blake2s_param_set_leaf_length( blake2s_param *P, const uint32_t leaf_length )
{
store32( &P->leaf_length, leaf_length );
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2s_param_set_node_offset( blake2s_param *P, const uint64_t node_offset )
static inline int blake2s_param_set_node_offset( blake2s_param *P, const uint64_t node_offset )
{
store48( P->node_offset, node_offset );
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2s_param_set_node_depth( blake2s_param *P, const uint8_t node_depth )
static inline int blake2s_param_set_node_depth( blake2s_param *P, const uint8_t node_depth )
{
P->node_depth = node_depth;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2s_param_set_inner_length( blake2s_param *P, const uint8_t inner_length )
static inline int blake2s_param_set_inner_length( blake2s_param *P, const uint8_t inner_length )
{
P->inner_length = inner_length;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2s_param_set_salt( blake2s_param *P, const uint8_t salt[BLAKE2S_SALTBYTES] )
static inline int blake2s_param_set_salt( blake2s_param *P, const uint8_t salt[BLAKE2S_SALTBYTES] )
{
memcpy( P->salt, salt, BLAKE2S_SALTBYTES );
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2s_param_set_personal( blake2s_param *P, const uint8_t personal[BLAKE2S_PERSONALBYTES] )
static inline int blake2s_param_set_personal( blake2s_param *P, const uint8_t personal[BLAKE2S_PERSONALBYTES] )
{
memcpy( P->personal, personal, BLAKE2S_PERSONALBYTES );
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2s_init0( blake2s_state *S )
static inline int blake2s_init0( blake2s_state *S )
{
int i;
memset( S, 0, sizeof( blake2s_state ) );
for( i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i];
for( int i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i];
return 0;
}
#if defined(__cplusplus)
extern "C" {
#endif
int blake2s_init( blake2s_state *S, size_t outlen );
int blake2s_init_param( blake2s_state *S, const blake2s_param *P );
int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen );
int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen );
int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
#if defined(__cplusplus)
}
#endif
/* init2 xors IV with input parameter block */
int blake2s_init_param( blake2s_state *S, const blake2s_param *P )
{
const uint32_t *p = ( const uint32_t * )( P );
size_t i;
blake2s_init0( S );
uint32_t *p = ( uint32_t * )( P );
/* IV XOR ParamBlock */
for( i = 0; i < 8; ++i )
for( size_t i = 0; i < 8; ++i )
S->h[i] ^= load32( &p[i] );
S->outlen = P->digest_length;
return 0;
}
/* Sequential blake2s initialization */
int blake2s_init( blake2s_state *S, const uint8_t outlen )
// Sequential blake2s initialization
int blake2s_init( blake2s_state *S, size_t outlen )
{
blake2s_param P[1];
/* Move interval verification here? */
if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
P->digest_length = outlen;
P->digest_length = ( uint8_t) outlen;
P->key_length = 0;
P->fanout = 1;
P->depth = 1;
@ -178,13 +182,13 @@ int blake2s_init( blake2s_state *S, const uint8_t outlen )
store48( &P->node_offset, 0 );
P->node_depth = 0;
P->inner_length = 0;
/* memset(P->reserved, 0, sizeof(P->reserved) ); */
// memset(P->reserved, 0, sizeof(P->reserved) );
memset( P->salt, 0, sizeof( P->salt ) );
memset( P->personal, 0, sizeof( P->personal ) );
return blake2s_init_param( S, P );
}
int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, const uint8_t keylen )
int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen )
{
blake2s_param P[1];
@ -192,15 +196,15 @@ int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, c
if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1;
P->digest_length = outlen;
P->key_length = keylen;
P->digest_length = ( uint8_t ) outlen;
P->key_length = ( uint8_t ) keylen;
P->fanout = 1;
P->depth = 1;
store32( &P->leaf_length, 0 );
store48( &P->node_offset, 0 );
P->node_depth = 0;
P->inner_length = 0;
/* memset(P->reserved, 0, sizeof(P->reserved) ); */
// memset(P->reserved, 0, sizeof(P->reserved) );
memset( P->salt, 0, sizeof( P->salt ) );
memset( P->personal, 0, sizeof( P->personal ) );
@ -220,12 +224,11 @@ static int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCK
{
uint32_t m[16];
uint32_t v[16];
size_t i;
for( i = 0; i < 16; ++i )
for( size_t i = 0; i < 16; ++i )
m[i] = load32( block + i * sizeof( m[i] ) );
for( i = 0; i < 8; ++i )
for( size_t i = 0; i < 8; ++i )
v[i] = S->h[i];
v[ 8] = blake2s_IV[0];
@ -269,7 +272,7 @@ static int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCK
ROUND( 8 );
ROUND( 9 );
for( i = 0; i < 8; ++i )
for( size_t i = 0; i < 8; ++i )
S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
#undef G
@ -278,28 +281,28 @@ static int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCK
}
int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen )
int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen )
{
while( inlen > 0 )
{
size_t left = S->buflen;
size_t fill = 2 * BLAKE2S_BLOCKBYTES - left;
uint32_t left = S->buflen;
uint32_t fill = 2 * BLAKE2S_BLOCKBYTES - left;
if( inlen > fill )
{
memcpy( S->buf + left, in, fill ); /* Fill buffer */
memcpy( S->buf + left, in, fill ); // Fill buffer
S->buflen += fill;
blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
blake2s_compress( S, S->buf ); /* Compress */
memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); /* Shift buffer left */
blake2s_compress( S, S->buf ); // Compress
memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); // Shift buffer left
S->buflen -= BLAKE2S_BLOCKBYTES;
in += fill;
inlen -= fill;
}
else /* inlen <= fill */
else // inlen <= fill
{
memcpy( S->buf + left, in, (size_t)inlen );
S->buflen += (size_t)inlen; /* Be lazy, do not compress */
memcpy( S->buf + left, in, inlen );
S->buflen += ( uint32_t ) inlen; // Be lazy, do not compress
in += inlen;
inlen -= inlen;
}
@ -308,24 +311,19 @@ int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen )
return 0;
}
int blake2s_final( blake2s_state *S, uint8_t *out, uint8_t outlen )
int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen )
{
uint8_t buffer[BLAKE2S_OUTBYTES] = {0};
int i;
if( out == NULL || outlen == 0 || outlen > BLAKE2S_OUTBYTES )
return -1;
if( blake2s_is_lastblock( S ) )
return -1;
uint8_t buffer[BLAKE2S_OUTBYTES];
size_t i;
if(S->outlen != outlen) return -1;
if( S->buflen > BLAKE2S_BLOCKBYTES )
{
blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
blake2s_compress( S, S->buf );
S->buflen -= BLAKE2S_BLOCKBYTES;
memmove( S->buf, S->buf + BLAKE2S_BLOCKBYTES, S->buflen );
memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, S->buflen );
}
blake2s_increment_counter( S, ( uint32_t )S->buflen );
@ -335,12 +333,12 @@ int blake2s_final( blake2s_state *S, uint8_t *out, uint8_t outlen )
for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
store32( buffer + sizeof( S->h[i] ) * i, S->h[i] );
memcpy( out, buffer, outlen );
return 0;
}
int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen )
int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
{
blake2s_state S[1];
@ -349,7 +347,7 @@ int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen
if ( NULL == out ) return -1;
if ( NULL == key && keylen > 0) return -1;
if ( NULL == key && keylen > 0 ) return -1;
if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
@ -364,48 +362,7 @@ int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen
if( blake2s_init( S, outlen ) < 0 ) return -1;
}
blake2s_update( S, ( const uint8_t * )in, inlen );
blake2s_final( S, out, outlen );
return 0;
if( blake2s_update( S, ( uint8_t * )in, inlen ) < 0) return -1;
return blake2s_final( S, out, outlen );
}
#if defined(SUPERCOP)
int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen )
{
return blake2s( out, in, NULL, BLAKE2S_OUTBYTES, inlen, 0 );
}
#endif
#if defined(BLAKE2S_SELFTEST)
#include <string.h>
#include "blake2-kat.h"
int main( int argc, char **argv )
{
uint8_t key[BLAKE2S_KEYBYTES];
uint8_t buf[KAT_LENGTH];
size_t i;
for( i = 0; i < BLAKE2S_KEYBYTES; ++i )
key[i] = ( uint8_t )i;
for( i = 0; i < KAT_LENGTH; ++i )
buf[i] = ( uint8_t )i;
for( i = 0; i < KAT_LENGTH; ++i )
{
uint8_t hash[BLAKE2S_OUTBYTES];
blake2s( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES );
if( 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) )
{
puts( "error" );
return -1;
}
}
puts( "ok" );
return 0;
}
#endif

View file

@ -1,22 +1,23 @@
/*
BLAKE2 reference source code package - optimized C implementations
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
your option. The terms of these licenses can be found at:
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
- OpenSSL license : https://www.openssl.org/source/license.html
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
More information about the BLAKE2 hash function can be found at
https://blake2.net.
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#pragma once
#ifndef __BLAKE2S_ROUND_H__
#define __BLAKE2S_ROUND_H__
#define LOADU(p) _mm_loadu_si128( (const __m128i *)(p) )
#define LOAD(p) _mm_load_si128( (__m128i *)(p) )
#define STORE(p,r) _mm_store_si128((__m128i *)(p), r)
#define LOADU(p) _mm_loadu_si128( (__m128i *)(p) )
#define STOREU(p,r) _mm_storeu_si128((__m128i *)(p), r)
#define TOF(reg) _mm_castsi128_ps((reg))
@ -68,7 +69,7 @@
#if defined(HAVE_XOP)
#include "blake2s-load-xop.h"
#elif defined(HAVE_SSE41)
#elif defined(HAVE_SSE4_1)
#include "blake2s-load-sse41.h"
#else
#include "blake2s-load-sse2.h"

View file

@ -0,0 +1,43 @@
/*
BLAKE2 reference source code package - optimized C implementations
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include <stdio.h>
#include <string.h>
#include "blake2.h"
#include "blake2-kat.h"
int main( int argc, char **argv )
{
uint8_t key[BLAKE2S_KEYBYTES];
uint8_t buf[KAT_LENGTH];
for( size_t i = 0; i < BLAKE2S_KEYBYTES; ++i )
key[i] = ( uint8_t )i;
for( size_t i = 0; i < KAT_LENGTH; ++i )
buf[i] = ( uint8_t )i;
for( size_t i = 0; i < KAT_LENGTH; ++i )
{
uint8_t hash[BLAKE2S_OUTBYTES];
if( blake2s( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES ) < 0 ||
0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) )
{
puts( "error" );
return -1;
}
}
puts( "ok" );
return 0;
}

View file

@ -1,16 +1,14 @@
/*
BLAKE2 reference source code package - optimized C implementations
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
your option. The terms of these licenses can be found at:
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
- OpenSSL license : https://www.openssl.org/source/license.html
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
More information about the BLAKE2 hash function can be found at
https://blake2.net.
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include <stdint.h>
@ -22,18 +20,32 @@
#include "blake2-config.h"
#if defined(_MSC_VER)
#include <intrin.h>
#endif
#if defined(HAVE_SSE2)
#include <emmintrin.h>
// MSVC only defines _mm_set_epi64x for x86_64...
#if defined(_MSC_VER) && !defined(_M_X64)
static inline __m128i _mm_set_epi64x( const uint64_t u1, const uint64_t u0 )
{
return _mm_set_epi32( u1 >> 32, u1, u0 >> 32, u0 );
}
#endif
#endif
#if defined(HAVE_SSSE3)
#include <tmmintrin.h>
#endif
#if defined(HAVE_SSE41)
#if defined(HAVE_SSE4_1)
#include <smmintrin.h>
#endif
#if defined(HAVE_AVX)
#include <immintrin.h>
#endif
#if defined(HAVE_XOP)
#if defined(HAVE_XOP) && !defined(_MSC_VER)
#include <x86intrin.h>
#endif
@ -61,40 +73,35 @@ static const uint8_t blake2s_sigma[10][16] =
/* Some helper functions, not necessarily useful */
BLAKE2_LOCAL_INLINE(int) blake2s_set_lastnode( blake2s_state *S )
static inline int blake2s_set_lastnode( blake2s_state *S )
{
S->f[1] = -1;
S->f[1] = ~0U;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2s_clear_lastnode( blake2s_state *S )
static inline int blake2s_clear_lastnode( blake2s_state *S )
{
S->f[1] = 0;
S->f[1] = 0U;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2s_is_lastblock( const blake2s_state *S )
{
return S->f[0] != 0;
}
BLAKE2_LOCAL_INLINE(int) blake2s_set_lastblock( blake2s_state *S )
static inline int blake2s_set_lastblock( blake2s_state *S )
{
if( S->last_node ) blake2s_set_lastnode( S );
S->f[0] = -1;
S->f[0] = ~0U;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2s_clear_lastblock( blake2s_state *S )
static inline int blake2s_clear_lastblock( blake2s_state *S )
{
if( S->last_node ) blake2s_clear_lastnode( S );
S->f[0] = 0;
S->f[0] = 0U;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2s_increment_counter( blake2s_state *S, const uint32_t inc )
static inline int blake2s_increment_counter( blake2s_state *S, const uint32_t inc )
{
uint64_t t = ( ( uint64_t )S->t[1] << 32 ) | S->t[0];
t += inc;
@ -104,91 +111,114 @@ BLAKE2_LOCAL_INLINE(int) blake2s_increment_counter( blake2s_state *S, const uint
}
/* Parameter-related functions */
BLAKE2_LOCAL_INLINE(int) blake2s_param_set_digest_length( blake2s_param *P, const uint8_t digest_length )
// Parameter-related functions
static inline int blake2s_param_set_digest_length( blake2s_param *P, const uint8_t digest_length )
{
P->digest_length = digest_length;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2s_param_set_fanout( blake2s_param *P, const uint8_t fanout )
static inline int blake2s_param_set_fanout( blake2s_param *P, const uint8_t fanout )
{
P->fanout = fanout;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2s_param_set_max_depth( blake2s_param *P, const uint8_t depth )
static inline int blake2s_param_set_max_depth( blake2s_param *P, const uint8_t depth )
{
P->depth = depth;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2s_param_set_leaf_length( blake2s_param *P, const uint32_t leaf_length )
static inline int blake2s_param_set_leaf_length( blake2s_param *P, const uint32_t leaf_length )
{
P->leaf_length = leaf_length;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2s_param_set_node_offset( blake2s_param *P, const uint64_t node_offset )
static inline int blake2s_param_set_node_offset( blake2s_param *P, const uint64_t node_offset )
{
store48( P->node_offset, node_offset );
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2s_param_set_node_depth( blake2s_param *P, const uint8_t node_depth )
static inline int blake2s_param_set_node_depth( blake2s_param *P, const uint8_t node_depth )
{
P->node_depth = node_depth;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2s_param_set_inner_length( blake2s_param *P, const uint8_t inner_length )
static inline int blake2s_param_set_inner_length( blake2s_param *P, const uint8_t inner_length )
{
P->inner_length = inner_length;
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2s_param_set_salt( blake2s_param *P, const uint8_t salt[BLAKE2S_SALTBYTES] )
static inline int blake2s_param_set_salt( blake2s_param *P, const uint8_t salt[BLAKE2S_SALTBYTES] )
{
memcpy( P->salt, salt, BLAKE2S_SALTBYTES );
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2s_param_set_personal( blake2s_param *P, const uint8_t personal[BLAKE2S_PERSONALBYTES] )
static inline int blake2s_param_set_personal( blake2s_param *P, const uint8_t personal[BLAKE2S_PERSONALBYTES] )
{
memcpy( P->personal, personal, BLAKE2S_PERSONALBYTES );
return 0;
}
BLAKE2_LOCAL_INLINE(int) blake2s_init0( blake2s_state *S )
static inline int blake2s_init0( blake2s_state *S )
{
int i;
memset( S, 0, sizeof( blake2s_state ) );
for( i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i];
for( int i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i];
return 0;
}
#define blake2s_init BLAKE2_IMPL_NAME(blake2s_init)
#define blake2s_init_param BLAKE2_IMPL_NAME(blake2s_init_param)
#define blake2s_init_key BLAKE2_IMPL_NAME(blake2s_init_key)
#define blake2s_update BLAKE2_IMPL_NAME(blake2s_update)
#define blake2s_final BLAKE2_IMPL_NAME(blake2s_final)
#define blake2s BLAKE2_IMPL_NAME(blake2s)
#if defined(__cplusplus)
extern "C" {
#endif
int blake2s_init( blake2s_state *S, size_t outlen );
int blake2s_init_param( blake2s_state *S, const blake2s_param *P );
int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen );
int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen );
int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
#if defined(__cplusplus)
}
#endif
/* init2 xors IV with input parameter block */
int blake2s_init_param( blake2s_state *S, const blake2s_param *P )
{
/*blake2s_init0( S ); */
const uint8_t * v = ( const uint8_t * )( blake2s_IV );
const uint8_t * p = ( const uint8_t * )( P );
uint8_t * h = ( uint8_t * )( S->h );
int i;
uint8_t *p, *h, *v;
//blake2s_init0( S );
v = ( uint8_t * )( blake2s_IV );
h = ( uint8_t * )( S->h );
p = ( uint8_t * )( P );
/* IV XOR ParamBlock */
memset( S, 0, sizeof( blake2s_state ) );
for( i = 0; i < BLAKE2S_OUTBYTES; ++i ) h[i] = v[i] ^ p[i];
for( int i = 0; i < BLAKE2S_OUTBYTES; ++i ) h[i] = v[i] ^ p[i];
S->outlen = P->digest_length;
return 0;
}
/* Some sort of default parameter block initialization, for sequential blake2s */
int blake2s_init( blake2s_state *S, const uint8_t outlen )
int blake2s_init( blake2s_state *S, size_t outlen )
{
if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
const blake2s_param P =
{
outlen,
@ -202,14 +232,16 @@ int blake2s_init( blake2s_state *S, const uint8_t outlen )
{0},
{0}
};
/* Move interval verification here? */
if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
return blake2s_init_param( S, &P );
}
int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, const uint8_t keylen )
int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen )
{
if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
if ( ( !key ) || ( !keylen ) || keylen > BLAKE2S_KEYBYTES ) return -1;
const blake2s_param P =
{
outlen,
@ -224,11 +256,6 @@ int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, c
{0}
};
/* Move interval verification here? */
if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
if ( ( !key ) || ( !keylen ) || keylen > BLAKE2S_KEYBYTES ) return -1;
if( blake2s_init_param( S, &P ) < 0 )
return -1;
@ -243,11 +270,11 @@ int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, c
}
BLAKE2_LOCAL_INLINE(int) blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCKBYTES] )
static inline int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCKBYTES] )
{
__m128i row1, row2, row3, row4;
__m128i buf1, buf2, buf3, buf4;
#if defined(HAVE_SSE41)
#if defined(HAVE_SSE4_1)
__m128i t0, t1;
#if !defined(HAVE_XOP)
__m128i t2;
@ -258,7 +285,7 @@ BLAKE2_LOCAL_INLINE(int) blake2s_compress( blake2s_state *S, const uint8_t block
const __m128i r8 = _mm_set_epi8( 12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1 );
const __m128i r16 = _mm_set_epi8( 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2 );
#endif
#if defined(HAVE_SSE41)
#if defined(HAVE_SSE4_1)
const __m128i m0 = LOADU( block + 00 );
const __m128i m1 = LOADU( block + 16 );
const __m128i m2 = LOADU( block + 32 );
@ -300,8 +327,8 @@ BLAKE2_LOCAL_INLINE(int) blake2s_compress( blake2s_state *S, const uint8_t block
return 0;
}
/* inlen now in bytes */
int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen )
int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen )
{
while( inlen > 0 )
{
@ -310,11 +337,11 @@ int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen )
if( inlen > fill )
{
memcpy( S->buf + left, in, fill ); /* Fill buffer */
memcpy( S->buf + left, in, fill ); // Fill buffer
S->buflen += fill;
blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
blake2s_compress( S, S->buf ); /* Compress */
memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); /* Shift buffer left */
blake2s_compress( S, S->buf ); // Compress
memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); // Shift buffer left
S->buflen -= BLAKE2S_BLOCKBYTES;
in += fill;
inlen -= fill;
@ -322,7 +349,7 @@ int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen )
else /* inlen <= fill */
{
memcpy( S->buf + left, in, inlen );
S->buflen += inlen; /* Be lazy, do not compress */
S->buflen += inlen; // Be lazy, do not compress
in += inlen;
inlen -= inlen;
}
@ -331,24 +358,19 @@ int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen )
return 0;
}
/* Is this correct? */
int blake2s_final( blake2s_state *S, uint8_t *out, uint8_t outlen )
int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen )
{
uint8_t buffer[BLAKE2S_OUTBYTES] = {0};
int i;
uint8_t buffer[BLAKE2S_OUTBYTES];
if( outlen > BLAKE2S_OUTBYTES )
return -1;
if( blake2s_is_lastblock( S ) )
return -1;
if(outlen != S->outlen ) return -1;
if( S->buflen > BLAKE2S_BLOCKBYTES )
{
blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
blake2s_compress( S, S->buf );
S->buflen -= BLAKE2S_BLOCKBYTES;
memmove( S->buf, S->buf + BLAKE2S_BLOCKBYTES, S->buflen );
memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, S->buflen );
}
blake2s_increment_counter( S, ( uint32_t )S->buflen );
@ -356,15 +378,14 @@ int blake2s_final( blake2s_state *S, uint8_t *out, uint8_t outlen )
memset( S->buf + S->buflen, 0, 2 * BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */
blake2s_compress( S, S->buf );
for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
for( int i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
store32( buffer + sizeof( S->h[i] ) * i, S->h[i] );
memcpy( out, buffer, outlen );
return 0;
}
/* inlen, at least, should be uint64_t. Others can be size_t. */
int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen )
int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
{
blake2s_state S[1];
@ -388,48 +409,14 @@ int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen
if( blake2s_init( S, outlen ) < 0 ) return -1;
}
blake2s_update( S, ( const uint8_t * )in, inlen );
blake2s_final( S, out, outlen );
return 0;
if( blake2s_update( S, ( uint8_t * )in, inlen ) < 0) return -1;
return blake2s_final( S, out, outlen );
}
#if defined(SUPERCOP)
int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen )
{
return blake2s( out, in, NULL, BLAKE2S_OUTBYTES, inlen, 0 );
return blake2s( out, in, NULL, BLAKE2S_OUTBYTES, (size_t)inlen, 0 );
}
#endif
#if defined(BLAKE2S_SELFTEST)
#include <string.h>
#include "blake2-kat.h"
int main( int argc, char **argv )
{
uint8_t key[BLAKE2S_KEYBYTES];
uint8_t buf[KAT_LENGTH];
size_t i;
for( i = 0; i < BLAKE2S_KEYBYTES; ++i )
key[i] = ( uint8_t )i;
for( i = 0; i < KAT_LENGTH; ++i )
buf[i] = ( uint8_t )i;
for( i = 0; i < KAT_LENGTH; ++i )
{
uint8_t hash[BLAKE2S_OUTBYTES];
if( blake2s( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES ) < 0 ||
0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) )
{
puts( "error" );
return -1;
}
}
puts( "ok" );
return 0;
}
#endif

View file

@ -0,0 +1,43 @@
/*
BLAKE2 reference source code package - optimized C implementations
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include <stdio.h>
#include <string.h>
#include "blake2.h"
#include "blake2-kat.h"
int main( int argc, char **argv )
{
uint8_t key[BLAKE2S_KEYBYTES];
uint8_t buf[KAT_LENGTH];
for( size_t i = 0; i < BLAKE2S_KEYBYTES; ++i )
key[i] = ( uint8_t )i;
for( size_t i = 0; i < KAT_LENGTH; ++i )
buf[i] = ( uint8_t )i;
for( size_t i = 0; i < KAT_LENGTH; ++i )
{
uint8_t hash[BLAKE2S_OUTBYTES];
if( blake2sp( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES ) < 0 ||
0 != memcmp( hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES ) )
{
puts( "error" );
return -1;
}
}
puts( "ok" );
return 0;
}

View file

@ -0,0 +1,274 @@
/*
BLAKE2 reference source code package - optimized C implementations
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#if defined(_OPENMP)
#include <omp.h>
#endif
#include "blake2.h"
#include "blake2-impl.h"
#define PARALLELISM_DEGREE 8
static int blake2sp_init_leaf( blake2s_state *S, uint8_t outlen, uint8_t keylen, uint64_t offset )
{
blake2s_param P[1];
P->digest_length = outlen;
P->key_length = keylen;
P->fanout = PARALLELISM_DEGREE;
P->depth = 2;
P->leaf_length = 0;
store48( P->node_offset, offset );
P->node_depth = 0;
P->inner_length = BLAKE2S_OUTBYTES;
memset( P->salt, 0, sizeof( P->salt ) );
memset( P->personal, 0, sizeof( P->personal ) );
blake2s_init_param( S, P );
S->outlen = P->inner_length;
return 0;
}
static int blake2sp_init_root( blake2s_state *S, uint8_t outlen, uint8_t keylen )
{
blake2s_param P[1];
P->digest_length = outlen;
P->key_length = keylen;
P->fanout = PARALLELISM_DEGREE;
P->depth = 2;
P->leaf_length = 0;
store48( P->node_offset, 0ULL );
P->node_depth = 1;
P->inner_length = BLAKE2S_OUTBYTES;
memset( P->salt, 0, sizeof( P->salt ) );
memset( P->personal, 0, sizeof( P->personal ) );
blake2s_init_param( S, P );
S->outlen = P->digest_length;
return 0;
}
int blake2sp_init( blake2sp_state *S, size_t outlen )
{
if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
memset( S->buf, 0, sizeof( S->buf ) );
S->buflen = 0;
if( blake2sp_init_root( S->R, ( uint8_t ) outlen, 0 ) < 0 )
return -1;
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
if( blake2sp_init_leaf( S->S[i], ( uint8_t ) outlen, 0, i ) < 0 ) return -1;
S->R->last_node = 1;
S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
S->outlen = ( uint8_t ) outlen;
return 0;
}
int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen )
{
if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
if( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1;
memset( S->buf, 0, sizeof( S->buf ) );
S->buflen = 0;
if( blake2sp_init_root( S->R, ( uint8_t ) outlen, ( uint8_t ) keylen ) < 0 )
return -1;
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
if( blake2sp_init_leaf( S->S[i], ( uint8_t ) outlen, ( uint8_t ) keylen, i ) < 0 )
return -1;
S->R->last_node = 1;
S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
S->outlen = ( uint8_t ) outlen;
{
uint8_t block[BLAKE2S_BLOCKBYTES];
memset( block, 0, BLAKE2S_BLOCKBYTES );
memcpy( block, key, keylen );
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
blake2s_update( S->S[i], block, BLAKE2S_BLOCKBYTES );
secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
}
return 0;
}
int blake2sp_update( blake2sp_state *S, const uint8_t *in, size_t inlen )
{
size_t left = S->buflen;
size_t fill = sizeof( S->buf ) - left;
if( left && inlen >= fill )
{
memcpy( S->buf + left, in, fill );
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES );
in += fill;
inlen -= fill;
left = 0;
}
#if defined(_OPENMP)
omp_set_num_threads(PARALLELISM_DEGREE);
#pragma omp parallel shared(S)
#else
for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )
#endif
{
#if defined(_OPENMP)
size_t id__ = ( size_t ) omp_get_thread_num();
#endif
size_t inlen__ = inlen;
const uint8_t *in__ = ( const uint8_t * )in;
in__ += id__ * BLAKE2S_BLOCKBYTES;
while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES )
{
blake2s_update( S->S[id__], in__, BLAKE2S_BLOCKBYTES );
in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
}
}
in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES );
inlen %= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
if( inlen > 0 )
memcpy( S->buf + left, in, inlen );
S->buflen = ( uint32_t ) left + ( uint32_t ) inlen;
return 0;
}
int blake2sp_final( blake2sp_state *S, uint8_t *out, size_t outlen )
{
uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES];
if(S->outlen != outlen) return -1;
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
{
if( S->buflen > i * BLAKE2S_BLOCKBYTES )
{
size_t left = S->buflen - i * BLAKE2S_BLOCKBYTES;
if( left > BLAKE2S_BLOCKBYTES ) left = BLAKE2S_BLOCKBYTES;
blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, left );
}
blake2s_final( S->S[i], hash[i], BLAKE2S_OUTBYTES );
}
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
blake2s_update( S->R, hash[i], BLAKE2S_OUTBYTES );
blake2s_final( S->R, out, outlen );
return 0;
}
int blake2sp( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
{
uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES];
blake2s_state S[PARALLELISM_DEGREE][1];
blake2s_state FS[1];
/* Verify parameters */
if ( NULL == in && inlen > 0 ) return -1;
if ( NULL == out ) return -1;
if ( NULL == key && keylen > 0 ) return -1;
if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
if( keylen > BLAKE2S_KEYBYTES ) return -1;
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
if( blake2sp_init_leaf( S[i], ( uint8_t ) outlen, ( uint8_t ) keylen, i ) < 0 )
return -1;
S[PARALLELISM_DEGREE - 1]->last_node = 1; // mark last node
if( keylen > 0 )
{
uint8_t block[BLAKE2S_BLOCKBYTES];
memset( block, 0, BLAKE2S_BLOCKBYTES );
memcpy( block, key, keylen );
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
blake2s_update( S[i], block, BLAKE2S_BLOCKBYTES );
secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
}
#if defined(_OPENMP)
omp_set_num_threads(PARALLELISM_DEGREE);
#pragma omp parallel shared(S,hash)
#else
for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )
#endif
{
#if defined(_OPENMP)
size_t id__ = ( size_t ) omp_get_thread_num();
#endif
size_t inlen__ = inlen;
const uint8_t *in__ = ( const uint8_t * )in;
in__ += id__ * BLAKE2S_BLOCKBYTES;
while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES )
{
blake2s_update( S[id__], in__, BLAKE2S_BLOCKBYTES );
in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
}
if( inlen__ > id__ * BLAKE2S_BLOCKBYTES )
{
const size_t left = inlen__ - id__ * BLAKE2S_BLOCKBYTES;
const size_t len = left <= BLAKE2S_BLOCKBYTES ? left : BLAKE2S_BLOCKBYTES;
blake2s_update( S[id__], in__, len );
}
blake2s_final( S[id__], hash[id__], BLAKE2S_OUTBYTES );
}
if( blake2sp_init_root( FS, ( uint8_t ) outlen, ( uint8_t ) keylen ) < 0 )
return -1;
FS->last_node = 1;
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
blake2s_update( FS, hash[i], BLAKE2S_OUTBYTES );
return blake2s_final( FS, out, outlen );
}

10
aclocal.m4 vendored
View file

@ -55,7 +55,7 @@ dnl
dnl See the "Since" comment for each macro you use to see what version
dnl of the macros you require.
m4_defun([PKG_PREREQ],
[m4_define([PKG_MACROS_VERSION], [0.29.1])
[m4_define([PKG_MACROS_VERSION], [0.29.2])
m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
])dnl PKG_PREREQ
@ -156,7 +156,7 @@ AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
pkg_failed=no
AC_MSG_CHECKING([for $1])
AC_MSG_CHECKING([for $2])
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
_PKG_CONFIG([$1][_LIBS], [libs], [$2])
@ -166,11 +166,11 @@ and $1[]_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.])
if test $pkg_failed = yes; then
AC_MSG_RESULT([no])
AC_MSG_RESULT([no])
_PKG_SHORT_ERRORS_SUPPORTED
if test $_pkg_short_errors_supported = yes; then
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
else
else
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
@ -187,7 +187,7 @@ installed software in a non-standard prefix.
_PKG_TEXT])[]dnl
])
elif test $pkg_failed = untried; then
AC_MSG_RESULT([no])
AC_MSG_RESULT([no])
m4_default([$4], [AC_MSG_FAILURE(
[The pkg-config script could not be found or is too old. Make sure it
is in your PATH or set the PKG_CONFIG environment variable to the full

4
configure vendored
View file

@ -11462,14 +11462,14 @@ fi
# checks for library functions
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
clock confstr ctermid dup3 execv faccessat fchmod fchmodat fchown fchownat \
clock confstr ctermid dup3 execv explicit_bzero explicit_memset faccessat fchmod fchmodat fchown fchownat \
fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
getgrgid_r getgrnam_r \
getgrouplist getgroups getlogin getloadavg getpeername getpgid getpid \
getpriority getresuid getresgid getpwent getpwnam_r getpwuid_r getspnam getspent getsid getwd \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
initgroups kill killpg lchmod lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \

View file

@ -3519,15 +3519,13 @@ fi
# checks for library functions
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
clock confstr ctermid dup3 execv faccessat fchmod fchmodat fchown fchownat \
clock confstr ctermid dup3 execv explicit_bzero explicit_memset faccessat fchmod fchmodat fchown fchownat \
fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
getgrgid_r getgrnam_r \
getgrouplist getgroups getlogin getloadavg getpeername getpgid getpid \
getpriority getresuid getresgid getpwent getpwnam_r getpwuid_r getspnam getspent getsid getwd \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill putenv pwrite pwritev pwritev2 \

View file

@ -302,6 +302,12 @@
/* Define to 1 if you have the `execv' function. */
#undef HAVE_EXECV
/* Define to 1 if you have the `explicit_bzero' function. */
#undef HAVE_EXPLICIT_BZERO
/* Define to 1 if you have the `explicit_memset' function. */
#undef HAVE_EXPLICIT_MEMSET
/* Define to 1 if you have the `expm1' function. */
#undef HAVE_EXPM1
@ -664,6 +670,9 @@
/* Define to 1 if you have the `memrchr' function. */
#undef HAVE_MEMRCHR
/* Define to 1 if you have the `memset_s' function. */
#undef HAVE_MEMSET_S
/* Define to 1 if you have the `mkdirat' function. */
#undef HAVE_MKDIRAT