Sync develop with master #4
13 changed files with 1901 additions and 1 deletions
|
|
@ -220,6 +220,7 @@ set( fc_sources
|
|||
src/crypto/dh.cpp
|
||||
src/crypto/blowfish.cpp
|
||||
src/crypto/elliptic_common.cpp
|
||||
src/crypto/equihash.cpp
|
||||
${ECC_REST}
|
||||
src/crypto/elliptic_${ECC_IMPL}.cpp
|
||||
src/crypto/rand.cpp
|
||||
|
|
@ -253,6 +254,7 @@ list(APPEND sources ${fc_headers})
|
|||
|
||||
add_subdirectory( vendor/websocketpp )
|
||||
add_subdirectory( vendor/udt4 )
|
||||
add_subdirectory( vendor/equihash )
|
||||
|
||||
setup_library( fc SOURCES ${sources} LIBRARY_TYPE STATIC DONT_INSTALL_LIBRARY )
|
||||
|
||||
|
|
@ -354,13 +356,14 @@ target_include_directories(fc
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/vendor/udt4/src
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/vendor/websocketpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/vendor/secp256k1-zkp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/vendor/equihash
|
||||
)
|
||||
|
||||
#target_link_libraries( fc PUBLIC udt ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARIES} ${BZIP2_LIBRARIES} ${PLATFORM_SPECIFIC_LIBS} ${RPCRT4} ${CMAKE_DL_LIBS} ${rt_library} ${ECC_LIB} )
|
||||
IF(NOT WIN32)
|
||||
set(LINK_USR_LOCAL_LIB -L/usr/local/lib)
|
||||
ENDIF()
|
||||
target_link_libraries( fc PUBLIC ${LINK_USR_LOCAL_LIB} udt ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARIES} ${BZIP2_LIBRARIES} ${PLATFORM_SPECIFIC_LIBS} ${RPCRT4} ${CMAKE_DL_LIBS} ${rt_library} ${readline_libraries} ${ECC_LIB} )
|
||||
target_link_libraries( fc PUBLIC ${LINK_USR_LOCAL_LIB} udt equihash ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARIES} ${BZIP2_LIBRARIES} ${PLATFORM_SPECIFIC_LIBS} ${RPCRT4} ${CMAKE_DL_LIBS} ${rt_library} ${readline_libraries} ${ECC_LIB} )
|
||||
|
||||
if(MSVC)
|
||||
set_source_files_properties( src/network/http/websocket.cpp PROPERTIES COMPILE_FLAGS "/bigobj" )
|
||||
|
|
@ -376,6 +379,7 @@ ENDIF(MSVC)
|
|||
ENDIF()
|
||||
|
||||
include_directories( vendor/websocketpp )
|
||||
include_directories( vendor/equihash )
|
||||
|
||||
add_subdirectory(tests)
|
||||
|
||||
|
|
|
|||
21
include/fc/crypto/equihash.hpp
Normal file
21
include/fc/crypto/equihash.hpp
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#pragma once
|
||||
#include <fc/crypto/sha256.hpp>
|
||||
#include <fc/vector.hpp>
|
||||
|
||||
namespace fc { namespace equihash {
|
||||
|
||||
struct proof
|
||||
{
|
||||
uint32_t n;
|
||||
uint32_t k;
|
||||
sha256 seed;
|
||||
std::vector< uint32_t > inputs;
|
||||
|
||||
bool is_valid() const;
|
||||
|
||||
static proof hash( uint32_t n, uint32_t k, sha256 seed );
|
||||
};
|
||||
|
||||
} } // fc
|
||||
|
||||
FC_REFLECT( fc::equihash::proof, (n)(k)(seed)(inputs) )
|
||||
47
src/crypto/equihash.cpp
Normal file
47
src/crypto/equihash.cpp
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
#include <equihash/pow.hpp>
|
||||
|
||||
#include <fc/crypto/equihash.hpp>
|
||||
|
||||
#define EQUIHASH_NONCE 2
|
||||
|
||||
namespace fc { namespace equihash {
|
||||
|
||||
_POW::Seed sha_to_seed( sha256 seed )
|
||||
{
|
||||
_POW::Seed new_seed;
|
||||
|
||||
// Seed is 128 bits. Half of sha256 to create seed. Should still have enough randomness
|
||||
new_seed.v[0] = (unsigned int) seed._hash[0];
|
||||
new_seed.v[0] ^= (unsigned int) seed._hash[2];
|
||||
new_seed.v[1] = (unsigned int)( seed._hash[0] >> 32 );
|
||||
new_seed.v[1] ^= (unsigned int)( seed._hash[2] >> 32 );
|
||||
new_seed.v[2] = (unsigned int) seed._hash[1];
|
||||
new_seed.v[2] ^= (unsigned int) seed._hash[3];
|
||||
new_seed.v[3] = (unsigned int)( seed._hash[1] >> 32 );
|
||||
new_seed.v[3] ^= (unsigned int)( seed._hash[3] >> 32 );
|
||||
|
||||
return new_seed;
|
||||
}
|
||||
|
||||
bool proof::is_valid() const
|
||||
{
|
||||
_POW::Proof test( n, k, sha_to_seed( seed ), EQUIHASH_NONCE, inputs );
|
||||
return test.Test();
|
||||
|
||||
}
|
||||
|
||||
proof proof::hash( uint32_t n, uint32_t k, sha256 seed )
|
||||
{
|
||||
auto hash = _POW::Equihash( n, k, sha_to_seed( seed ) );
|
||||
auto result = hash.FindProof( EQUIHASH_NONCE );
|
||||
|
||||
proof p;
|
||||
p.n = n;
|
||||
p.k = k;
|
||||
p.seed = seed;
|
||||
p.inputs = result.inputs;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
} } // fc::equihash
|
||||
17
vendor/equihash/CMakeLists.txt
vendored
Normal file
17
vendor/equihash/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
file(GLOB HEADERS "include/equihash/*.hpp" )
|
||||
|
||||
add_library( equihash
|
||||
src/pow.cpp
|
||||
src/blake2b.c
|
||||
)
|
||||
|
||||
target_link_libraries( equihash )
|
||||
target_include_directories( equihash PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )
|
||||
|
||||
install( TARGETS
|
||||
equihash
|
||||
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
)
|
||||
72
vendor/equihash/include/equihash/blake2-config.h
vendored
Normal file
72
vendor/equihash/include/equihash/blake2-config.h
vendored
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
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_CONFIG_H__
|
||||
#define __BLAKE2_CONFIG_H__
|
||||
|
||||
// These don't work everywhere
|
||||
#if defined(__SSE2__)
|
||||
#define HAVE_SSE2
|
||||
#endif
|
||||
|
||||
#if defined(__SSSE3__)
|
||||
#define HAVE_SSSE3
|
||||
#endif
|
||||
|
||||
#if defined(__SSE4_1__)
|
||||
#define HAVE_SSE41
|
||||
#endif
|
||||
|
||||
#if defined(__AVX__)
|
||||
#define HAVE_AVX
|
||||
#endif
|
||||
|
||||
#if defined(__XOP__)
|
||||
#define HAVE_XOP
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_AVX2
|
||||
#ifndef HAVE_AVX
|
||||
#define HAVE_AVX
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XOP
|
||||
#ifndef HAVE_AVX
|
||||
#define HAVE_AVX
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_AVX
|
||||
#ifndef HAVE_SSE41
|
||||
#define HAVE_SSE41
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SSE41
|
||||
#ifndef HAVE_SSSE3
|
||||
#define HAVE_SSSE3
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SSSE3
|
||||
#define HAVE_SSE2
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_SSE2)
|
||||
#error "This code requires at least SSE2."
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
136
vendor/equihash/include/equihash/blake2-impl.h
vendored
Normal file
136
vendor/equihash/include/equihash/blake2-impl.h
vendored
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
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_IMPL_H__
|
||||
#define __BLAKE2_IMPL_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
static inline uint32_t load32( const void *src )
|
||||
{
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
uint32_t w;
|
||||
memcpy(&w, src, sizeof w);
|
||||
return w;
|
||||
#else
|
||||
const uint8_t *p = ( const uint8_t * )src;
|
||||
uint32_t w = *p++;
|
||||
w |= ( uint32_t )( *p++ ) << 8;
|
||||
w |= ( uint32_t )( *p++ ) << 16;
|
||||
w |= ( uint32_t )( *p++ ) << 24;
|
||||
return w;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint64_t load64( const void *src )
|
||||
{
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
uint64_t w;
|
||||
memcpy(&w, src, sizeof w);
|
||||
return w;
|
||||
#else
|
||||
const uint8_t *p = ( const uint8_t * )src;
|
||||
uint64_t w = *p++;
|
||||
w |= ( uint64_t )( *p++ ) << 8;
|
||||
w |= ( uint64_t )( *p++ ) << 16;
|
||||
w |= ( uint64_t )( *p++ ) << 24;
|
||||
w |= ( uint64_t )( *p++ ) << 32;
|
||||
w |= ( uint64_t )( *p++ ) << 40;
|
||||
w |= ( uint64_t )( *p++ ) << 48;
|
||||
w |= ( uint64_t )( *p++ ) << 56;
|
||||
return w;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void store32( void *dst, uint32_t w )
|
||||
{
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
memcpy(dst, &w, sizeof w);
|
||||
#else
|
||||
uint8_t *p = ( uint8_t * )dst;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void store64( void *dst, uint64_t w )
|
||||
{
|
||||
#if defined(NATIVE_LITTLE_ENDIAN)
|
||||
memcpy(dst, &w, sizeof w);
|
||||
#else
|
||||
uint8_t *p = ( uint8_t * )dst;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint64_t load48( const void *src )
|
||||
{
|
||||
const uint8_t *p = ( const uint8_t * )src;
|
||||
uint64_t w = *p++;
|
||||
w |= ( uint64_t )( *p++ ) << 8;
|
||||
w |= ( uint64_t )( *p++ ) << 16;
|
||||
w |= ( uint64_t )( *p++ ) << 24;
|
||||
w |= ( uint64_t )( *p++ ) << 32;
|
||||
w |= ( uint64_t )( *p++ ) << 40;
|
||||
return w;
|
||||
}
|
||||
|
||||
static inline void store48( void *dst, uint64_t w )
|
||||
{
|
||||
uint8_t *p = ( uint8_t * )dst;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w; w >>= 8;
|
||||
*p++ = ( uint8_t )w;
|
||||
}
|
||||
|
||||
static inline uint32_t rotl32( const uint32_t w, const unsigned c )
|
||||
{
|
||||
return ( w << c ) | ( w >> ( 32 - c ) );
|
||||
}
|
||||
|
||||
static inline uint64_t rotl64( const uint64_t w, const unsigned c )
|
||||
{
|
||||
return ( w << c ) | ( w >> ( 64 - c ) );
|
||||
}
|
||||
|
||||
static inline uint32_t rotr32( const uint32_t w, const unsigned c )
|
||||
{
|
||||
return ( w >> c ) | ( w << ( 32 - c ) );
|
||||
}
|
||||
|
||||
static inline uint64_t rotr64( const uint64_t w, const unsigned c )
|
||||
{
|
||||
return ( w >> c ) | ( w << ( 64 - c ) );
|
||||
}
|
||||
|
||||
/* prevents compiler optimizing out memset() */
|
||||
static inline void secure_zero_memory( void *v, size_t n )
|
||||
{
|
||||
volatile uint8_t *p = ( volatile uint8_t * )v;
|
||||
while( n-- ) *p++ = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
157
vendor/equihash/include/equihash/blake2.h
vendored
Normal file
157
vendor/equihash/include/equihash/blake2.h
vendored
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
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__
|
||||
#define __BLAKE2_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define ALIGN(x) __declspec(align(x))
|
||||
#else
|
||||
#define ALIGN(x) __attribute__ ((__aligned__(x)))
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum blake2s_constant
|
||||
{
|
||||
BLAKE2S_BLOCKBYTES = 64,
|
||||
BLAKE2S_OUTBYTES = 32,
|
||||
BLAKE2S_KEYBYTES = 32,
|
||||
BLAKE2S_SALTBYTES = 8,
|
||||
BLAKE2S_PERSONALBYTES = 8
|
||||
};
|
||||
|
||||
enum blake2b_constant
|
||||
{
|
||||
BLAKE2B_BLOCKBYTES = 128,
|
||||
BLAKE2B_OUTBYTES = 64,
|
||||
BLAKE2B_KEYBYTES = 64,
|
||||
BLAKE2B_SALTBYTES = 16,
|
||||
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;
|
||||
|
||||
ALIGN( 64 ) 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;
|
||||
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;
|
||||
|
||||
ALIGN( 64 ) 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;
|
||||
uint8_t last_node;
|
||||
} blake2b_state;
|
||||
|
||||
ALIGN( 64 ) typedef struct __blake2sp_state
|
||||
{
|
||||
blake2s_state S[8][1];
|
||||
blake2s_state R[1];
|
||||
uint8_t buf[8 * BLAKE2S_BLOCKBYTES];
|
||||
size_t buflen;
|
||||
} blake2sp_state;
|
||||
|
||||
ALIGN( 64 ) typedef struct __blake2bp_state
|
||||
{
|
||||
blake2b_state S[4][1];
|
||||
blake2b_state R[1];
|
||||
uint8_t buf[4 * BLAKE2B_BLOCKBYTES];
|
||||
size_t buflen;
|
||||
} blake2bp_state;
|
||||
#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 );
|
||||
|
||||
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 );
|
||||
|
||||
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 );
|
||||
|
||||
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 );
|
||||
|
||||
// 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 );
|
||||
int blake2b_long(uint8_t *out, const void *in, const uint32_t outlen, const uint64_t inlen);
|
||||
|
||||
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 );
|
||||
|
||||
static inline int blake2( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen )
|
||||
{
|
||||
return blake2b( out, in, key, outlen, inlen, keylen );
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
68
vendor/equihash/include/equihash/blake2b-load-sse2.h
vendored
Normal file
68
vendor/equihash/include/equihash/blake2b-load-sse2.h
vendored
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
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 __BLAKE2B_LOAD_SSE2_H__
|
||||
#define __BLAKE2B_LOAD_SSE2_H__
|
||||
|
||||
#define LOAD_MSG_0_1(b0, b1) b0 = _mm_set_epi64x(m2, m0); b1 = _mm_set_epi64x(m6, m4)
|
||||
#define LOAD_MSG_0_2(b0, b1) b0 = _mm_set_epi64x(m3, m1); b1 = _mm_set_epi64x(m7, m5)
|
||||
#define LOAD_MSG_0_3(b0, b1) b0 = _mm_set_epi64x(m10, m8); b1 = _mm_set_epi64x(m14, m12)
|
||||
#define LOAD_MSG_0_4(b0, b1) b0 = _mm_set_epi64x(m11, m9); b1 = _mm_set_epi64x(m15, m13)
|
||||
#define LOAD_MSG_1_1(b0, b1) b0 = _mm_set_epi64x(m4, m14); b1 = _mm_set_epi64x(m13, m9)
|
||||
#define LOAD_MSG_1_2(b0, b1) b0 = _mm_set_epi64x(m8, m10); b1 = _mm_set_epi64x(m6, m15)
|
||||
#define LOAD_MSG_1_3(b0, b1) b0 = _mm_set_epi64x(m0, m1); b1 = _mm_set_epi64x(m5, m11)
|
||||
#define LOAD_MSG_1_4(b0, b1) b0 = _mm_set_epi64x(m2, m12); b1 = _mm_set_epi64x(m3, m7)
|
||||
#define LOAD_MSG_2_1(b0, b1) b0 = _mm_set_epi64x(m12, m11); b1 = _mm_set_epi64x(m15, m5)
|
||||
#define LOAD_MSG_2_2(b0, b1) b0 = _mm_set_epi64x(m0, m8); b1 = _mm_set_epi64x(m13, m2)
|
||||
#define LOAD_MSG_2_3(b0, b1) b0 = _mm_set_epi64x(m3, m10); b1 = _mm_set_epi64x(m9, m7)
|
||||
#define LOAD_MSG_2_4(b0, b1) b0 = _mm_set_epi64x(m6, m14); b1 = _mm_set_epi64x(m4, m1)
|
||||
#define LOAD_MSG_3_1(b0, b1) b0 = _mm_set_epi64x(m3, m7); b1 = _mm_set_epi64x(m11, m13)
|
||||
#define LOAD_MSG_3_2(b0, b1) b0 = _mm_set_epi64x(m1, m9); b1 = _mm_set_epi64x(m14, m12)
|
||||
#define LOAD_MSG_3_3(b0, b1) b0 = _mm_set_epi64x(m5, m2); b1 = _mm_set_epi64x(m15, m4)
|
||||
#define LOAD_MSG_3_4(b0, b1) b0 = _mm_set_epi64x(m10, m6); b1 = _mm_set_epi64x(m8, m0)
|
||||
#define LOAD_MSG_4_1(b0, b1) b0 = _mm_set_epi64x(m5, m9); b1 = _mm_set_epi64x(m10, m2)
|
||||
#define LOAD_MSG_4_2(b0, b1) b0 = _mm_set_epi64x(m7, m0); b1 = _mm_set_epi64x(m15, m4)
|
||||
#define LOAD_MSG_4_3(b0, b1) b0 = _mm_set_epi64x(m11, m14); b1 = _mm_set_epi64x(m3, m6)
|
||||
#define LOAD_MSG_4_4(b0, b1) b0 = _mm_set_epi64x(m12, m1); b1 = _mm_set_epi64x(m13, m8)
|
||||
#define LOAD_MSG_5_1(b0, b1) b0 = _mm_set_epi64x(m6, m2); b1 = _mm_set_epi64x(m8, m0)
|
||||
#define LOAD_MSG_5_2(b0, b1) b0 = _mm_set_epi64x(m10, m12); b1 = _mm_set_epi64x(m3, m11)
|
||||
#define LOAD_MSG_5_3(b0, b1) b0 = _mm_set_epi64x(m7, m4); b1 = _mm_set_epi64x(m1, m15)
|
||||
#define LOAD_MSG_5_4(b0, b1) b0 = _mm_set_epi64x(m5, m13); b1 = _mm_set_epi64x(m9, m14)
|
||||
#define LOAD_MSG_6_1(b0, b1) b0 = _mm_set_epi64x(m1, m12); b1 = _mm_set_epi64x(m4, m14)
|
||||
#define LOAD_MSG_6_2(b0, b1) b0 = _mm_set_epi64x(m15, m5); b1 = _mm_set_epi64x(m10, m13)
|
||||
#define LOAD_MSG_6_3(b0, b1) b0 = _mm_set_epi64x(m6, m0); b1 = _mm_set_epi64x(m8, m9)
|
||||
#define LOAD_MSG_6_4(b0, b1) b0 = _mm_set_epi64x(m3, m7); b1 = _mm_set_epi64x(m11, m2)
|
||||
#define LOAD_MSG_7_1(b0, b1) b0 = _mm_set_epi64x(m7, m13); b1 = _mm_set_epi64x(m3, m12)
|
||||
#define LOAD_MSG_7_2(b0, b1) b0 = _mm_set_epi64x(m14, m11); b1 = _mm_set_epi64x(m9, m1)
|
||||
#define LOAD_MSG_7_3(b0, b1) b0 = _mm_set_epi64x(m15, m5); b1 = _mm_set_epi64x(m2, m8)
|
||||
#define LOAD_MSG_7_4(b0, b1) b0 = _mm_set_epi64x(m4, m0); b1 = _mm_set_epi64x(m10, m6)
|
||||
#define LOAD_MSG_8_1(b0, b1) b0 = _mm_set_epi64x(m14, m6); b1 = _mm_set_epi64x(m0, m11)
|
||||
#define LOAD_MSG_8_2(b0, b1) b0 = _mm_set_epi64x(m9, m15); b1 = _mm_set_epi64x(m8, m3)
|
||||
#define LOAD_MSG_8_3(b0, b1) b0 = _mm_set_epi64x(m13, m12); b1 = _mm_set_epi64x(m10, m1)
|
||||
#define LOAD_MSG_8_4(b0, b1) b0 = _mm_set_epi64x(m7, m2); b1 = _mm_set_epi64x(m5, m4)
|
||||
#define LOAD_MSG_9_1(b0, b1) b0 = _mm_set_epi64x(m8, m10); b1 = _mm_set_epi64x(m1, m7)
|
||||
#define LOAD_MSG_9_2(b0, b1) b0 = _mm_set_epi64x(m4, m2); b1 = _mm_set_epi64x(m5, m6)
|
||||
#define LOAD_MSG_9_3(b0, b1) b0 = _mm_set_epi64x(m9, m15); b1 = _mm_set_epi64x(m13, m3)
|
||||
#define LOAD_MSG_9_4(b0, b1) b0 = _mm_set_epi64x(m14, m11); b1 = _mm_set_epi64x(m0, m12)
|
||||
#define LOAD_MSG_10_1(b0, b1) b0 = _mm_set_epi64x(m2, m0); b1 = _mm_set_epi64x(m6, m4)
|
||||
#define LOAD_MSG_10_2(b0, b1) b0 = _mm_set_epi64x(m3, m1); b1 = _mm_set_epi64x(m7, m5)
|
||||
#define LOAD_MSG_10_3(b0, b1) b0 = _mm_set_epi64x(m10, m8); b1 = _mm_set_epi64x(m14, m12)
|
||||
#define LOAD_MSG_10_4(b0, b1) b0 = _mm_set_epi64x(m11, m9); b1 = _mm_set_epi64x(m15, m13)
|
||||
#define LOAD_MSG_11_1(b0, b1) b0 = _mm_set_epi64x(m4, m14); b1 = _mm_set_epi64x(m13, m9)
|
||||
#define LOAD_MSG_11_2(b0, b1) b0 = _mm_set_epi64x(m8, m10); b1 = _mm_set_epi64x(m6, m15)
|
||||
#define LOAD_MSG_11_3(b0, b1) b0 = _mm_set_epi64x(m0, m1); b1 = _mm_set_epi64x(m5, m11)
|
||||
#define LOAD_MSG_11_4(b0, b1) b0 = _mm_set_epi64x(m2, m12); b1 = _mm_set_epi64x(m3, m7)
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
402
vendor/equihash/include/equihash/blake2b-load-sse41.h
vendored
Normal file
402
vendor/equihash/include/equihash/blake2b-load-sse41.h
vendored
Normal file
|
|
@ -0,0 +1,402 @@
|
|||
/*
|
||||
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 __BLAKE2B_LOAD_SSE41_H__
|
||||
#define __BLAKE2B_LOAD_SSE41_H__
|
||||
|
||||
#define LOAD_MSG_0_1(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m0, m1); \
|
||||
b1 = _mm_unpacklo_epi64(m2, m3); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_0_2(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpackhi_epi64(m0, m1); \
|
||||
b1 = _mm_unpackhi_epi64(m2, m3); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_0_3(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m4, m5); \
|
||||
b1 = _mm_unpacklo_epi64(m6, m7); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_0_4(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpackhi_epi64(m4, m5); \
|
||||
b1 = _mm_unpackhi_epi64(m6, m7); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_1_1(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m7, m2); \
|
||||
b1 = _mm_unpackhi_epi64(m4, m6); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_1_2(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m5, m4); \
|
||||
b1 = _mm_alignr_epi8(m3, m7, 8); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_1_3(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_shuffle_epi32(m0, _MM_SHUFFLE(1,0,3,2)); \
|
||||
b1 = _mm_unpackhi_epi64(m5, m2); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_1_4(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m6, m1); \
|
||||
b1 = _mm_unpackhi_epi64(m3, m1); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_2_1(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_alignr_epi8(m6, m5, 8); \
|
||||
b1 = _mm_unpackhi_epi64(m2, m7); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_2_2(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m4, m0); \
|
||||
b1 = _mm_blend_epi16(m1, m6, 0xF0); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_2_3(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_blend_epi16(m5, m1, 0xF0); \
|
||||
b1 = _mm_unpackhi_epi64(m3, m4); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_2_4(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m7, m3); \
|
||||
b1 = _mm_alignr_epi8(m2, m0, 8); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_3_1(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpackhi_epi64(m3, m1); \
|
||||
b1 = _mm_unpackhi_epi64(m6, m5); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_3_2(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpackhi_epi64(m4, m0); \
|
||||
b1 = _mm_unpacklo_epi64(m6, m7); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_3_3(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_blend_epi16(m1, m2, 0xF0); \
|
||||
b1 = _mm_blend_epi16(m2, m7, 0xF0); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_3_4(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m3, m5); \
|
||||
b1 = _mm_unpacklo_epi64(m0, m4); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_4_1(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpackhi_epi64(m4, m2); \
|
||||
b1 = _mm_unpacklo_epi64(m1, m5); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_4_2(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_blend_epi16(m0, m3, 0xF0); \
|
||||
b1 = _mm_blend_epi16(m2, m7, 0xF0); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_4_3(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_blend_epi16(m7, m5, 0xF0); \
|
||||
b1 = _mm_blend_epi16(m3, m1, 0xF0); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_4_4(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_alignr_epi8(m6, m0, 8); \
|
||||
b1 = _mm_blend_epi16(m4, m6, 0xF0); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_5_1(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m1, m3); \
|
||||
b1 = _mm_unpacklo_epi64(m0, m4); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_5_2(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m6, m5); \
|
||||
b1 = _mm_unpackhi_epi64(m5, m1); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_5_3(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_blend_epi16(m2, m3, 0xF0); \
|
||||
b1 = _mm_unpackhi_epi64(m7, m0); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_5_4(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpackhi_epi64(m6, m2); \
|
||||
b1 = _mm_blend_epi16(m7, m4, 0xF0); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_6_1(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_blend_epi16(m6, m0, 0xF0); \
|
||||
b1 = _mm_unpacklo_epi64(m7, m2); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_6_2(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpackhi_epi64(m2, m7); \
|
||||
b1 = _mm_alignr_epi8(m5, m6, 8); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_6_3(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m0, m3); \
|
||||
b1 = _mm_shuffle_epi32(m4, _MM_SHUFFLE(1,0,3,2)); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_6_4(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpackhi_epi64(m3, m1); \
|
||||
b1 = _mm_blend_epi16(m1, m5, 0xF0); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_7_1(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpackhi_epi64(m6, m3); \
|
||||
b1 = _mm_blend_epi16(m6, m1, 0xF0); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_7_2(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_alignr_epi8(m7, m5, 8); \
|
||||
b1 = _mm_unpackhi_epi64(m0, m4); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_7_3(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpackhi_epi64(m2, m7); \
|
||||
b1 = _mm_unpacklo_epi64(m4, m1); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_7_4(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m0, m2); \
|
||||
b1 = _mm_unpacklo_epi64(m3, m5); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_8_1(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m3, m7); \
|
||||
b1 = _mm_alignr_epi8(m0, m5, 8); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_8_2(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpackhi_epi64(m7, m4); \
|
||||
b1 = _mm_alignr_epi8(m4, m1, 8); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_8_3(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = m6; \
|
||||
b1 = _mm_alignr_epi8(m5, m0, 8); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_8_4(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_blend_epi16(m1, m3, 0xF0); \
|
||||
b1 = m2; \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_9_1(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m5, m4); \
|
||||
b1 = _mm_unpackhi_epi64(m3, m0); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_9_2(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m1, m2); \
|
||||
b1 = _mm_blend_epi16(m3, m2, 0xF0); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_9_3(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpackhi_epi64(m7, m4); \
|
||||
b1 = _mm_unpackhi_epi64(m1, m6); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_9_4(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_alignr_epi8(m7, m5, 8); \
|
||||
b1 = _mm_unpacklo_epi64(m6, m0); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_10_1(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m0, m1); \
|
||||
b1 = _mm_unpacklo_epi64(m2, m3); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_10_2(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpackhi_epi64(m0, m1); \
|
||||
b1 = _mm_unpackhi_epi64(m2, m3); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_10_3(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m4, m5); \
|
||||
b1 = _mm_unpacklo_epi64(m6, m7); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_10_4(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpackhi_epi64(m4, m5); \
|
||||
b1 = _mm_unpackhi_epi64(m6, m7); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_11_1(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m7, m2); \
|
||||
b1 = _mm_unpackhi_epi64(m4, m6); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_11_2(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m5, m4); \
|
||||
b1 = _mm_alignr_epi8(m3, m7, 8); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_11_3(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_shuffle_epi32(m0, _MM_SHUFFLE(1,0,3,2)); \
|
||||
b1 = _mm_unpackhi_epi64(m5, m2); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define LOAD_MSG_11_4(b0, b1) \
|
||||
do \
|
||||
{ \
|
||||
b0 = _mm_unpacklo_epi64(m6, m1); \
|
||||
b1 = _mm_unpackhi_epi64(m3, m1); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
170
vendor/equihash/include/equihash/blake2b-round.h
vendored
Normal file
170
vendor/equihash/include/equihash/blake2b-round.h
vendored
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
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 __BLAKE2B_ROUND_H__
|
||||
#define __BLAKE2B_ROUND_H__
|
||||
|
||||
#define LOAD(p) _mm_load_si128( (const __m128i *)(p) )
|
||||
#define STORE(p,r) _mm_store_si128((__m128i *)(p), r)
|
||||
|
||||
#define LOADU(p) _mm_loadu_si128( (const __m128i *)(p) )
|
||||
#define STOREU(p,r) _mm_storeu_si128((__m128i *)(p), r)
|
||||
|
||||
#define TOF(reg) _mm_castsi128_ps((reg))
|
||||
#define TOI(reg) _mm_castps_si128((reg))
|
||||
|
||||
#define LIKELY(x) __builtin_expect((x),1)
|
||||
|
||||
|
||||
/* Microarchitecture-specific macros */
|
||||
#ifndef HAVE_XOP
|
||||
#ifdef HAVE_SSSE3
|
||||
#define _mm_roti_epi64(x, c) \
|
||||
(-(c) == 32) ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2,3,0,1)) \
|
||||
: (-(c) == 24) ? _mm_shuffle_epi8((x), r24) \
|
||||
: (-(c) == 16) ? _mm_shuffle_epi8((x), r16) \
|
||||
: (-(c) == 63) ? _mm_xor_si128(_mm_srli_epi64((x), -(c)), _mm_add_epi64((x), (x))) \
|
||||
: _mm_xor_si128(_mm_srli_epi64((x), -(c)), _mm_slli_epi64((x), 64-(-(c))))
|
||||
#else
|
||||
#define _mm_roti_epi64(r, c) _mm_xor_si128(_mm_srli_epi64( (r), -(c) ),_mm_slli_epi64( (r), 64-(-c) ))
|
||||
#endif
|
||||
#else
|
||||
/* ... */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1) \
|
||||
row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \
|
||||
row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \
|
||||
\
|
||||
row4l = _mm_xor_si128(row4l, row1l); \
|
||||
row4h = _mm_xor_si128(row4h, row1h); \
|
||||
\
|
||||
row4l = _mm_roti_epi64(row4l, -32); \
|
||||
row4h = _mm_roti_epi64(row4h, -32); \
|
||||
\
|
||||
row3l = _mm_add_epi64(row3l, row4l); \
|
||||
row3h = _mm_add_epi64(row3h, row4h); \
|
||||
\
|
||||
row2l = _mm_xor_si128(row2l, row3l); \
|
||||
row2h = _mm_xor_si128(row2h, row3h); \
|
||||
\
|
||||
row2l = _mm_roti_epi64(row2l, -24); \
|
||||
row2h = _mm_roti_epi64(row2h, -24); \
|
||||
|
||||
#define G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1) \
|
||||
row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \
|
||||
row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \
|
||||
\
|
||||
row4l = _mm_xor_si128(row4l, row1l); \
|
||||
row4h = _mm_xor_si128(row4h, row1h); \
|
||||
\
|
||||
row4l = _mm_roti_epi64(row4l, -16); \
|
||||
row4h = _mm_roti_epi64(row4h, -16); \
|
||||
\
|
||||
row3l = _mm_add_epi64(row3l, row4l); \
|
||||
row3h = _mm_add_epi64(row3h, row4h); \
|
||||
\
|
||||
row2l = _mm_xor_si128(row2l, row3l); \
|
||||
row2h = _mm_xor_si128(row2h, row3h); \
|
||||
\
|
||||
row2l = _mm_roti_epi64(row2l, -63); \
|
||||
row2h = _mm_roti_epi64(row2h, -63); \
|
||||
|
||||
#if defined(HAVE_SSSE3)
|
||||
#define DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \
|
||||
t0 = _mm_alignr_epi8(row2h, row2l, 8); \
|
||||
t1 = _mm_alignr_epi8(row2l, row2h, 8); \
|
||||
row2l = t0; \
|
||||
row2h = t1; \
|
||||
\
|
||||
t0 = row3l; \
|
||||
row3l = row3h; \
|
||||
row3h = t0; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(row4h, row4l, 8); \
|
||||
t1 = _mm_alignr_epi8(row4l, row4h, 8); \
|
||||
row4l = t1; \
|
||||
row4h = t0;
|
||||
|
||||
#define UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \
|
||||
t0 = _mm_alignr_epi8(row2l, row2h, 8); \
|
||||
t1 = _mm_alignr_epi8(row2h, row2l, 8); \
|
||||
row2l = t0; \
|
||||
row2h = t1; \
|
||||
\
|
||||
t0 = row3l; \
|
||||
row3l = row3h; \
|
||||
row3h = t0; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(row4l, row4h, 8); \
|
||||
t1 = _mm_alignr_epi8(row4h, row4l, 8); \
|
||||
row4l = t1; \
|
||||
row4h = t0;
|
||||
#else
|
||||
|
||||
#define DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \
|
||||
t0 = row4l;\
|
||||
t1 = row2l;\
|
||||
row4l = row3l;\
|
||||
row3l = row3h;\
|
||||
row3h = row4l;\
|
||||
row4l = _mm_unpackhi_epi64(row4h, _mm_unpacklo_epi64(t0, t0)); \
|
||||
row4h = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(row4h, row4h)); \
|
||||
row2l = _mm_unpackhi_epi64(row2l, _mm_unpacklo_epi64(row2h, row2h)); \
|
||||
row2h = _mm_unpackhi_epi64(row2h, _mm_unpacklo_epi64(t1, t1))
|
||||
|
||||
#define UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \
|
||||
t0 = row3l;\
|
||||
row3l = row3h;\
|
||||
row3h = t0;\
|
||||
t0 = row2l;\
|
||||
t1 = row4l;\
|
||||
row2l = _mm_unpackhi_epi64(row2h, _mm_unpacklo_epi64(row2l, row2l)); \
|
||||
row2h = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(row2h, row2h)); \
|
||||
row4l = _mm_unpackhi_epi64(row4l, _mm_unpacklo_epi64(row4h, row4h)); \
|
||||
row4h = _mm_unpackhi_epi64(row4h, _mm_unpacklo_epi64(t1, t1))
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SSE41)
|
||||
#include <equihash/blake2b-load-sse41.h>
|
||||
#else
|
||||
#include <equihash/blake2b-load-sse2.h>
|
||||
#endif
|
||||
|
||||
#define ROUND(r) \
|
||||
LOAD_MSG_ ##r ##_1(b0, b1); \
|
||||
G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \
|
||||
LOAD_MSG_ ##r ##_2(b0, b1); \
|
||||
G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \
|
||||
DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \
|
||||
LOAD_MSG_ ##r ##_3(b0, b1); \
|
||||
G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \
|
||||
LOAD_MSG_ ##r ##_4(b0, b1); \
|
||||
G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \
|
||||
UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h);
|
||||
|
||||
#endif
|
||||
|
||||
#define BLAKE2_ROUND(row1l,row1h,row2l,row2h,row3l,row3h,row4l,row4h) \
|
||||
G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \
|
||||
G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \
|
||||
\
|
||||
DIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \
|
||||
\
|
||||
G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \
|
||||
G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \
|
||||
\
|
||||
UNDIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h);
|
||||
117
vendor/equihash/include/equihash/pow.hpp
vendored
Normal file
117
vendor/equihash/include/equihash/pow.hpp
vendored
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
/*Code by Dmitry Khovratovich, 2016
|
||||
CC0 license
|
||||
*/
|
||||
|
||||
#ifndef __POW
|
||||
#define __POW
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <vector>
|
||||
#include <cstdio>
|
||||
|
||||
|
||||
const int SEED_LENGTH=4; //Length of seed in dwords ;
|
||||
const int NONCE_LENGTH=24; //Length of nonce in bytes;
|
||||
const int MAX_NONCE = 0xFFFFF;
|
||||
const int MAX_N = 32; //Max length of n in bytes, should not exceed 32
|
||||
const int LIST_LENGTH = 5;
|
||||
const unsigned FORK_MULTIPLIER=3; //Maximum collision factor
|
||||
|
||||
/* The block used to initialize the PoW search
|
||||
@v actual values
|
||||
*/
|
||||
namespace _POW{
|
||||
|
||||
struct Seed{
|
||||
std::vector<uint32_t> v;
|
||||
|
||||
Seed(){
|
||||
v.resize(SEED_LENGTH,0);
|
||||
}
|
||||
explicit Seed(uint32_t x){
|
||||
v.resize(SEED_LENGTH, x);
|
||||
}
|
||||
Seed(const Seed&r){
|
||||
v= r.v;
|
||||
}
|
||||
Seed& operator=(const Seed&r){
|
||||
v = r.v;
|
||||
return *this;
|
||||
}
|
||||
const uint32_t& operator[](unsigned i) const{ return v[i]; }
|
||||
};
|
||||
|
||||
/* Different nonces for PoW search
|
||||
@v actual values
|
||||
*/
|
||||
typedef uint32_t Nonce;
|
||||
typedef uint32_t Input;
|
||||
|
||||
/*Actual proof of work
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct Proof{
|
||||
const unsigned n;
|
||||
const unsigned k;
|
||||
const Seed seed;
|
||||
const Nonce nonce;
|
||||
const std::vector<Input> inputs;
|
||||
Proof(unsigned n_v, unsigned k_v, Seed I_v, Nonce V_v, std::vector<Input> inputs_v):
|
||||
n(n_v), k(k_v), seed(I_v), nonce(V_v), inputs(inputs_v){};
|
||||
Proof():n(0),k(1),seed(0),nonce(0),inputs(std::vector<Input>()) {};
|
||||
|
||||
bool Test();
|
||||
};
|
||||
|
||||
class Tuple {
|
||||
public:
|
||||
std::vector<uint32_t> blocks;
|
||||
Input reference;
|
||||
Tuple(unsigned i) { blocks.resize(i); }
|
||||
Tuple& operator=(const Tuple &r) {
|
||||
blocks = r.blocks;
|
||||
reference = r.reference;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
class Fork {
|
||||
public:
|
||||
Input ref1, ref2;
|
||||
Fork() {};
|
||||
Fork(Input r1, Input r2) : ref1(r1), ref2(r2) {};
|
||||
};
|
||||
|
||||
/*Algorithm class for creating proof
|
||||
Assumes that n/(k+1) <=32
|
||||
*
|
||||
*/
|
||||
class Equihash{
|
||||
std::vector<std::vector<Tuple>> tupleList;
|
||||
std::vector<unsigned> filledList;
|
||||
std::vector<Proof> solutions;
|
||||
std::vector<std::vector<Fork>> forks;
|
||||
unsigned n;
|
||||
unsigned k;
|
||||
Seed seed;
|
||||
Nonce nonce;
|
||||
public:
|
||||
/*
|
||||
Initializes memory.
|
||||
*/
|
||||
Equihash(unsigned n_in, unsigned k_in, Seed s) :n(n_in), k(k_in), seed(s) {};
|
||||
~Equihash() {};
|
||||
Proof FindProof();
|
||||
Proof FindProof( Nonce n );
|
||||
void FillMemory(uint32_t length); //fill with hash
|
||||
void InitializeMemory(); //allocate memory
|
||||
void ResolveCollisions(bool store);
|
||||
std::vector<Input> ResolveTree(Fork fork);
|
||||
std::vector<Input> ResolveTreeByLevel(Fork fork, unsigned level);
|
||||
};
|
||||
}
|
||||
|
||||
#endif //define __POW
|
||||
469
vendor/equihash/src/blake2b.c
vendored
Normal file
469
vendor/equihash/src/blake2b.c
vendored
Normal file
|
|
@ -0,0 +1,469 @@
|
|||
/*
|
||||
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 <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <equihash/blake2.h>
|
||||
#include <equihash/blake2-impl.h>
|
||||
|
||||
#include <equihash/blake2-config.h>
|
||||
|
||||
|
||||
#include <emmintrin.h>
|
||||
#if defined(HAVE_SSSE3)
|
||||
#include <tmmintrin.h>
|
||||
#endif
|
||||
#if defined(HAVE_SSE41)
|
||||
#include <smmintrin.h>
|
||||
#endif
|
||||
#if defined(HAVE_AVX)
|
||||
#include <immintrin.h>
|
||||
#endif
|
||||
#if defined(HAVE_XOP)
|
||||
#include <x86intrin.h>
|
||||
#endif
|
||||
|
||||
#include <equihash/blake2b-round.h>
|
||||
|
||||
ALIGN( 64 ) static const uint64_t blake2b_IV[8] =
|
||||
{
|
||||
0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
|
||||
0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
|
||||
0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
|
||||
0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
|
||||
};
|
||||
|
||||
static const uint8_t blake2b_sigma[12][16] =
|
||||
{
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
|
||||
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
|
||||
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
|
||||
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
|
||||
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
|
||||
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
|
||||
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
|
||||
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
|
||||
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
|
||||
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
|
||||
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }
|
||||
};
|
||||
|
||||
|
||||
/* Some helper functions, not necessarily useful */
|
||||
static inline int blake2b_set_lastnode( blake2b_state *S )
|
||||
{
|
||||
S->f[1] = ~0ULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_clear_lastnode( blake2b_state *S )
|
||||
{
|
||||
S->f[1] = 0ULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_set_lastblock( blake2b_state *S )
|
||||
{
|
||||
if( S->last_node ) blake2b_set_lastnode( S );
|
||||
|
||||
S->f[0] = ~0ULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_clear_lastblock( blake2b_state *S )
|
||||
{
|
||||
if( S->last_node ) blake2b_clear_lastnode( S );
|
||||
|
||||
S->f[0] = 0ULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static inline int blake2b_increment_counter( blake2b_state *S, const uint64_t inc )
|
||||
{
|
||||
#if __x86_64__
|
||||
// ADD/ADC chain
|
||||
__uint128_t t = ( ( __uint128_t )S->t[1] << 64 ) | S->t[0];
|
||||
t += inc;
|
||||
S->t[0] = ( uint64_t )( t >> 0 );
|
||||
S->t[1] = ( uint64_t )( t >> 64 );
|
||||
#else
|
||||
S->t[0] += inc;
|
||||
S->t[1] += ( S->t[0] < inc );
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
static inline int blake2b_param_set_fanout( blake2b_param *P, const uint8_t fanout )
|
||||
{
|
||||
P->fanout = fanout;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_param_set_max_depth( blake2b_param *P, const uint8_t depth )
|
||||
{
|
||||
P->depth = depth;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_param_set_leaf_length( blake2b_param *P, const uint32_t leaf_length )
|
||||
{
|
||||
P->leaf_length = leaf_length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_param_set_node_offset( blake2b_param *P, const uint64_t node_offset )
|
||||
{
|
||||
P->node_offset = node_offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_param_set_node_depth( blake2b_param *P, const uint8_t node_depth )
|
||||
{
|
||||
P->node_depth = node_depth;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_param_set_inner_length( blake2b_param *P, const uint8_t inner_length )
|
||||
{
|
||||
P->inner_length = inner_length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_param_set_salt( blake2b_param *P, const uint8_t salt[BLAKE2B_SALTBYTES] )
|
||||
{
|
||||
memcpy( P->salt, salt, BLAKE2B_SALTBYTES );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_param_set_personal( blake2b_param *P, const uint8_t personal[BLAKE2B_PERSONALBYTES] )
|
||||
{
|
||||
memcpy( P->personal, personal, BLAKE2B_PERSONALBYTES );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_init0( blake2b_state *S )
|
||||
{
|
||||
memset( S, 0, sizeof( blake2b_state ) );
|
||||
|
||||
for( int i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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 );
|
||||
/* IV XOR ParamBlock */
|
||||
memset( S, 0, sizeof( blake2b_state ) );
|
||||
|
||||
for( int i = 0; i < BLAKE2B_OUTBYTES; ++i ) h[i] = v[i] ^ p[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Some sort of default parameter block initialization, for sequential blake2b */
|
||||
int blake2b_init( blake2b_state *S, const uint8_t outlen )
|
||||
{
|
||||
if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
|
||||
|
||||
const blake2b_param P =
|
||||
{
|
||||
outlen,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
{0},
|
||||
{0},
|
||||
{0}
|
||||
};
|
||||
return blake2b_init_param( S, &P );
|
||||
}
|
||||
|
||||
int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen )
|
||||
{
|
||||
if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
|
||||
|
||||
if ( ( !keylen ) || keylen > BLAKE2B_KEYBYTES ) return -1;
|
||||
|
||||
const blake2b_param P =
|
||||
{
|
||||
outlen,
|
||||
keylen,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
{0},
|
||||
{0},
|
||||
{0}
|
||||
};
|
||||
|
||||
if( blake2b_init_param( S, &P ) < 0 )
|
||||
return 0;
|
||||
|
||||
{
|
||||
uint8_t block[BLAKE2B_BLOCKBYTES];
|
||||
memset( block, 0, BLAKE2B_BLOCKBYTES );
|
||||
memcpy( block, key, keylen );
|
||||
blake2b_update( S, block, BLAKE2B_BLOCKBYTES );
|
||||
secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] )
|
||||
{
|
||||
__m128i row1l, row1h;
|
||||
__m128i row2l, row2h;
|
||||
__m128i row3l, row3h;
|
||||
__m128i row4l, row4h;
|
||||
__m128i b0, b1;
|
||||
__m128i t0, t1;
|
||||
#if defined(HAVE_SSSE3) && !defined(HAVE_XOP)
|
||||
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)
|
||||
const __m128i m0 = LOADU( block + 00 );
|
||||
const __m128i m1 = LOADU( block + 16 );
|
||||
const __m128i m2 = LOADU( block + 32 );
|
||||
const __m128i m3 = LOADU( block + 48 );
|
||||
const __m128i m4 = LOADU( block + 64 );
|
||||
const __m128i m5 = LOADU( block + 80 );
|
||||
const __m128i m6 = LOADU( block + 96 );
|
||||
const __m128i m7 = LOADU( block + 112 );
|
||||
#else
|
||||
const uint64_t m0 = ( ( uint64_t * )block )[ 0];
|
||||
const uint64_t m1 = ( ( uint64_t * )block )[ 1];
|
||||
const uint64_t m2 = ( ( uint64_t * )block )[ 2];
|
||||
const uint64_t m3 = ( ( uint64_t * )block )[ 3];
|
||||
const uint64_t m4 = ( ( uint64_t * )block )[ 4];
|
||||
const uint64_t m5 = ( ( uint64_t * )block )[ 5];
|
||||
const uint64_t m6 = ( ( uint64_t * )block )[ 6];
|
||||
const uint64_t m7 = ( ( uint64_t * )block )[ 7];
|
||||
const uint64_t m8 = ( ( uint64_t * )block )[ 8];
|
||||
const uint64_t m9 = ( ( uint64_t * )block )[ 9];
|
||||
const uint64_t m10 = ( ( uint64_t * )block )[10];
|
||||
const uint64_t m11 = ( ( uint64_t * )block )[11];
|
||||
const uint64_t m12 = ( ( uint64_t * )block )[12];
|
||||
const uint64_t m13 = ( ( uint64_t * )block )[13];
|
||||
const uint64_t m14 = ( ( uint64_t * )block )[14];
|
||||
const uint64_t m15 = ( ( uint64_t * )block )[15];
|
||||
#endif
|
||||
row1l = LOADU( &S->h[0] );
|
||||
row1h = LOADU( &S->h[2] );
|
||||
row2l = LOADU( &S->h[4] );
|
||||
row2h = LOADU( &S->h[6] );
|
||||
row3l = LOADU( &blake2b_IV[0] );
|
||||
row3h = LOADU( &blake2b_IV[2] );
|
||||
row4l = _mm_xor_si128( LOADU( &blake2b_IV[4] ), LOADU( &S->t[0] ) );
|
||||
row4h = _mm_xor_si128( LOADU( &blake2b_IV[6] ), LOADU( &S->f[0] ) );
|
||||
ROUND( 0 );
|
||||
ROUND( 1 );
|
||||
ROUND( 2 );
|
||||
ROUND( 3 );
|
||||
ROUND( 4 );
|
||||
ROUND( 5 );
|
||||
ROUND( 6 );
|
||||
ROUND( 7 );
|
||||
ROUND( 8 );
|
||||
ROUND( 9 );
|
||||
ROUND( 10 );
|
||||
ROUND( 11 );
|
||||
row1l = _mm_xor_si128( row3l, row1l );
|
||||
row1h = _mm_xor_si128( row3h, row1h );
|
||||
STOREU( &S->h[0], _mm_xor_si128( LOADU( &S->h[0] ), row1l ) );
|
||||
STOREU( &S->h[2], _mm_xor_si128( LOADU( &S->h[2] ), row1h ) );
|
||||
row2l = _mm_xor_si128( row4l, row2l );
|
||||
row2h = _mm_xor_si128( row4h, row2h );
|
||||
STOREU( &S->h[4], _mm_xor_si128( LOADU( &S->h[4] ), row2l ) );
|
||||
STOREU( &S->h[6], _mm_xor_si128( LOADU( &S->h[6] ), row2h ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen )
|
||||
{
|
||||
while( inlen > 0 )
|
||||
{
|
||||
size_t left = S->buflen;
|
||||
size_t fill = 2 * BLAKE2B_BLOCKBYTES - left;
|
||||
|
||||
if( inlen > fill )
|
||||
{
|
||||
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
|
||||
S->buflen -= BLAKE2B_BLOCKBYTES;
|
||||
in += fill;
|
||||
inlen -= fill;
|
||||
}
|
||||
else // inlen <= fill
|
||||
{
|
||||
memcpy( S->buf + left, in, inlen );
|
||||
S->buflen += inlen; // Be lazy, do not compress
|
||||
in += inlen;
|
||||
inlen -= inlen;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen )
|
||||
{
|
||||
if( outlen > BLAKE2B_OUTBYTES )
|
||||
return -1;
|
||||
|
||||
if( S->buflen > BLAKE2B_BLOCKBYTES )
|
||||
{
|
||||
blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
|
||||
blake2b_compress( S, S->buf );
|
||||
S->buflen -= BLAKE2B_BLOCKBYTES;
|
||||
memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen );
|
||||
}
|
||||
|
||||
blake2b_increment_counter( S, S->buflen );
|
||||
blake2b_set_lastblock( S );
|
||||
memset( S->buf + S->buflen, 0, 2 * BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */
|
||||
blake2b_compress( S, S->buf );
|
||||
memcpy( out, &S->h[0], outlen );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen )
|
||||
{
|
||||
blake2b_state S[1];
|
||||
|
||||
/* Verify parameters */
|
||||
if ( NULL == in ) return -1;
|
||||
|
||||
if ( NULL == out ) return -1;
|
||||
|
||||
if( NULL == key ) keylen = 0;
|
||||
|
||||
if( keylen )
|
||||
{
|
||||
if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( blake2b_init( S, outlen ) < 0 ) return -1;
|
||||
}
|
||||
|
||||
blake2b_update( S, ( const uint8_t * )in, inlen );
|
||||
blake2b_final( S, out, outlen );
|
||||
return 0;
|
||||
}
|
||||
|
||||
#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];
|
||||
|
||||
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];
|
||||
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
|
||||
|
||||
int blake2b_long(uint8_t *out, const void *in, const uint32_t outlen, const uint64_t inlen)
|
||||
{
|
||||
blake2b_state blake_state;
|
||||
if (outlen <= BLAKE2B_OUTBYTES)
|
||||
{
|
||||
blake2b_init(&blake_state, outlen);
|
||||
blake2b_update(&blake_state, (const uint8_t*)&outlen, sizeof(uint32_t));
|
||||
blake2b_update(&blake_state, (const uint8_t *)in, inlen);
|
||||
blake2b_final(&blake_state, out, outlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t out_buffer[BLAKE2B_OUTBYTES];
|
||||
uint8_t in_buffer[BLAKE2B_OUTBYTES];
|
||||
blake2b_init(&blake_state, BLAKE2B_OUTBYTES);
|
||||
blake2b_update(&blake_state, (const uint8_t*)&outlen, sizeof(uint32_t));
|
||||
blake2b_update(&blake_state, (const uint8_t *)in, inlen);
|
||||
blake2b_final(&blake_state, out_buffer, BLAKE2B_OUTBYTES);
|
||||
memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2);
|
||||
out += BLAKE2B_OUTBYTES / 2;
|
||||
uint32_t toproduce = outlen - BLAKE2B_OUTBYTES / 2;
|
||||
while (toproduce > BLAKE2B_OUTBYTES)
|
||||
{
|
||||
memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES);
|
||||
blake2b(out_buffer, in_buffer, NULL, BLAKE2B_OUTBYTES, BLAKE2B_OUTBYTES, 0);
|
||||
memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2);
|
||||
out += BLAKE2B_OUTBYTES / 2;
|
||||
toproduce -= BLAKE2B_OUTBYTES / 2;
|
||||
}
|
||||
memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES);
|
||||
blake2b(out_buffer, in_buffer, NULL, toproduce, BLAKE2B_OUTBYTES, 0);
|
||||
memcpy(out, out_buffer, toproduce);
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
220
vendor/equihash/src/pow.cpp
vendored
Normal file
220
vendor/equihash/src/pow.cpp
vendored
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
/*Code by Dmitry Khovratovich, 2016
|
||||
CC0 license
|
||||
|
||||
Modifications by Steemit, Inc. 2016
|
||||
*/
|
||||
|
||||
#include <equihash/pow.hpp>
|
||||
#include <equihash/blake2.h>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
static uint64_t rdtsc(void) {
|
||||
#ifdef _MSC_VER
|
||||
return __rdtsc();
|
||||
#else
|
||||
#if defined(__amd64__) || defined(__x86_64__)
|
||||
uint64_t rax, rdx;
|
||||
__asm__ __volatile__("rdtsc" : "=a"(rax), "=d"(rdx) : : );
|
||||
return (rdx << 32) | rax;
|
||||
#elif defined(__i386__) || defined(__i386) || defined(__X86__)
|
||||
uint64_t rax;
|
||||
__asm__ __volatile__("rdtsc" : "=A"(rax) : : );
|
||||
return rax;
|
||||
#else
|
||||
#error "Not implemented!"
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
using namespace _POW;
|
||||
using namespace std;
|
||||
|
||||
void Equihash::InitializeMemory()
|
||||
{
|
||||
uint32_t tuple_n = ((uint32_t)1) << (n / (k + 1));
|
||||
Tuple default_tuple(k); // k blocks to store (one left for index)
|
||||
std::vector<Tuple> def_tuples(LIST_LENGTH, default_tuple);
|
||||
tupleList = std::vector<std::vector<Tuple>>(tuple_n, def_tuples);
|
||||
filledList= std::vector<unsigned>(tuple_n, 0);
|
||||
solutions.resize(0);
|
||||
forks.resize(0);
|
||||
}
|
||||
|
||||
void Equihash::FillMemory(uint32_t length) //works for k<=7
|
||||
{
|
||||
uint32_t input[SEED_LENGTH + 2];
|
||||
for (unsigned i = 0; i < SEED_LENGTH; ++i)
|
||||
input[i] = seed[i];
|
||||
input[SEED_LENGTH] = nonce;
|
||||
input[SEED_LENGTH + 1] = 0;
|
||||
uint32_t buf[MAX_N / 4];
|
||||
for (unsigned i = 0; i < length; ++i, ++input[SEED_LENGTH + 1]) {
|
||||
blake2b((uint8_t*)buf, &input, NULL, sizeof(buf), sizeof(input), 0);
|
||||
uint32_t index = buf[0] >> (32 - n / (k + 1));
|
||||
unsigned count = filledList[index];
|
||||
if (count < LIST_LENGTH) {
|
||||
for (unsigned j = 1; j < (k + 1); ++j) {
|
||||
//select j-th block of n/(k+1) bits
|
||||
tupleList[index][count].blocks[j - 1] = buf[j] >> (32 - n / (k + 1));
|
||||
}
|
||||
tupleList[index][count].reference = i;
|
||||
filledList[index]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Input> Equihash::ResolveTreeByLevel(Fork fork, unsigned level) {
|
||||
if (level == 0)
|
||||
return std::vector<Input>{fork.ref1, fork.ref2};
|
||||
auto v1 = ResolveTreeByLevel(forks[level - 1][fork.ref1], level - 1);
|
||||
auto v2 = ResolveTreeByLevel(forks[level - 1][fork.ref2], level - 1);
|
||||
v1.insert(v1.end(), v2.begin(), v2.end());
|
||||
return v1;
|
||||
}
|
||||
|
||||
std::vector<Input> Equihash::ResolveTree(Fork fork) {
|
||||
return ResolveTreeByLevel(fork, forks.size());
|
||||
}
|
||||
|
||||
|
||||
void Equihash::ResolveCollisions(bool store) {
|
||||
const unsigned tableLength = tupleList.size(); //number of rows in the hashtable
|
||||
const unsigned maxNewCollisions = tupleList.size()*FORK_MULTIPLIER; //max number of collisions to be found
|
||||
const unsigned newBlocks = tupleList[0][0].blocks.size() - 1;// number of blocks in the future collisions
|
||||
std::vector<Fork> newForks(maxNewCollisions); //list of forks created at this step
|
||||
auto tableRow = vector<Tuple>(LIST_LENGTH, Tuple(newBlocks)); //Row in the hash table
|
||||
vector<vector<Tuple>> collisionList(tableLength,tableRow);
|
||||
std::vector<unsigned> newFilledList(tableLength,0); //number of entries in rows
|
||||
uint32_t newColls = 0; //collision counter
|
||||
for (unsigned i = 0; i < tableLength; ++i) {
|
||||
for (unsigned j = 0; j < filledList[i]; ++j) {
|
||||
for (unsigned m = j + 1; m < filledList[i]; ++m) { //Collision
|
||||
//New index
|
||||
uint32_t newIndex = tupleList[i][j].blocks[0] ^ tupleList[i][m].blocks[0];
|
||||
Fork newFork = Fork(tupleList[i][j].reference, tupleList[i][m].reference);
|
||||
//Check if we get a solution
|
||||
if (store) { //last step
|
||||
if (newIndex == 0) {//Solution
|
||||
std::vector<Input> solution_inputs = ResolveTree(newFork);
|
||||
solutions.push_back(Proof(n, k, seed, nonce, solution_inputs));
|
||||
}
|
||||
}
|
||||
else { //Resolve
|
||||
if (newFilledList[newIndex] < LIST_LENGTH && newColls < maxNewCollisions) {
|
||||
for (unsigned l = 0; l < newBlocks; ++l) {
|
||||
collisionList[newIndex][newFilledList[newIndex]].blocks[l]
|
||||
= tupleList[i][j].blocks[l+1] ^ tupleList[i][m].blocks[l+1];
|
||||
}
|
||||
newForks[newColls] = newFork;
|
||||
collisionList[newIndex][newFilledList[newIndex]].reference = newColls;
|
||||
newFilledList[newIndex]++;
|
||||
newColls++;
|
||||
}//end of adding collision
|
||||
}
|
||||
}
|
||||
}//end of collision for i
|
||||
}
|
||||
forks.push_back(newForks);
|
||||
std::swap(tupleList, collisionList);
|
||||
std::swap(filledList, newFilledList);
|
||||
}
|
||||
|
||||
Proof Equihash::FindProof(){
|
||||
this->nonce = 1;
|
||||
while (nonce < MAX_NONCE) {
|
||||
nonce++;
|
||||
uint64_t start_cycles = rdtsc();
|
||||
InitializeMemory(); //allocate
|
||||
FillMemory(4UL << (n / (k + 1)-1)); //fill with hashes
|
||||
uint64_t fill_end = rdtsc();
|
||||
/*fp = fopen("proof.log", "a+");
|
||||
fprintf(fp, "\n===MEMORY FILLED:\n");
|
||||
PrintTuples(fp);
|
||||
fclose(fp);*/
|
||||
for (unsigned i = 1; i <= k; ++i) {
|
||||
uint64_t resolve_start = rdtsc();
|
||||
bool to_store = (i == k);
|
||||
ResolveCollisions(to_store); //XOR collisions, concatenate indices and shift
|
||||
uint64_t resolve_end = rdtsc();
|
||||
/* fp = fopen("proof.log", "a+");
|
||||
fprintf(fp, "\n===RESOLVED AFTER STEP %d:\n", i);
|
||||
PrintTuples(fp);
|
||||
fclose(fp);*/
|
||||
}
|
||||
uint64_t stop_cycles = rdtsc();
|
||||
|
||||
double mcycles_d = (double)(stop_cycles - start_cycles) / (1UL << 20);
|
||||
uint32_t kbytes = (tupleList.size()*LIST_LENGTH*k*sizeof(uint32_t)) / (1UL << 10);
|
||||
|
||||
//Duplicate check
|
||||
for (unsigned i = 0; i < solutions.size(); ++i) {
|
||||
auto vec = solutions[i].inputs;
|
||||
std::sort(vec.begin(), vec.end());
|
||||
bool dup = false;
|
||||
for (unsigned k = 0; k < vec.size() - 1; ++k) {
|
||||
if (vec[k] == vec[k + 1])
|
||||
dup = true;
|
||||
}
|
||||
if (!dup)
|
||||
return solutions[i];
|
||||
}
|
||||
}
|
||||
return Proof(n, k, seed, nonce, std::vector<uint32_t>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Added by Steemit, Inc. for single iteration
|
||||
*/
|
||||
Proof Equihash::FindProof( Nonce _nonce )
|
||||
{
|
||||
this->nonce = _nonce;
|
||||
InitializeMemory(); //allocate
|
||||
FillMemory(4UL << (n / (k + 1)-1)); //fill with hashes
|
||||
|
||||
for (unsigned i = 1; i <= k; ++i) {
|
||||
bool to_store = (i == k);
|
||||
ResolveCollisions(to_store); //XOR collisions, concatenate indices and shift
|
||||
}
|
||||
|
||||
//Duplicate check
|
||||
for (unsigned i = 0; i < solutions.size(); ++i) {
|
||||
auto vec = solutions[i].inputs;
|
||||
std::sort(vec.begin(), vec.end());
|
||||
bool dup = false;
|
||||
for (unsigned k = 0; k < vec.size() - 1; ++k) {
|
||||
if (vec[k] == vec[k + 1])
|
||||
dup = true;
|
||||
}
|
||||
if (!dup)
|
||||
return solutions[i];
|
||||
}
|
||||
|
||||
return Proof(n, k, seed, nonce, std::vector<uint32_t>());
|
||||
}
|
||||
|
||||
bool Proof::Test()
|
||||
{
|
||||
uint32_t input[SEED_LENGTH + 2];
|
||||
for (unsigned i = 0; i < SEED_LENGTH; ++i)
|
||||
input[i] = seed[i];
|
||||
input[SEED_LENGTH] = nonce;
|
||||
input[SEED_LENGTH + 1] = 0;
|
||||
uint32_t buf[MAX_N / 4];
|
||||
std::vector<uint32_t> blocks(k+1,0);
|
||||
for (unsigned i = 0; i < inputs.size(); ++i) {
|
||||
input[SEED_LENGTH + 1] = inputs[i];
|
||||
blake2b((uint8_t*)buf, &input, NULL, sizeof(buf), sizeof(input), 0);
|
||||
for (unsigned j = 0; j < (k + 1); ++j) {
|
||||
//select j-th block of n/(k+1) bits
|
||||
blocks[j] ^= buf[j] >> (32 - n / (k + 1));
|
||||
}
|
||||
}
|
||||
bool b = inputs.size() != 0;
|
||||
for (unsigned j = 0; j < (k + 1); ++j) {
|
||||
b &= (blocks[j] == 0);
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
Loading…
Reference in a new issue