Merge commit 'b94a338e56475943eb9bcc79be60ed6afd586796'

This commit is contained in:
Eric Frias 2017-06-21 16:19:49 -04:00
commit 7c88a95df1
22 changed files with 146 additions and 2323 deletions

View file

@ -228,7 +228,6 @@ 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
@ -258,7 +257,6 @@ list(APPEND sources "${CMAKE_CURRENT_BINARY_DIR}/git_revision.cpp")
list(APPEND sources ${fc_headers})
add_subdirectory( vendor/websocketpp EXCLUDE_FROM_ALL )
add_subdirectory( vendor/equihash )
setup_library( fc SOURCES ${sources} LIBRARY_TYPE STATIC )
install( DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/" DESTINATION include )
@ -313,6 +311,12 @@ ELSE()
target_compile_options(fc PUBLIC ${CPP_STANDARD} -Wall -fnon-call-exceptions)
endif()
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CPP_STANDARD} -Wall -fnon-call-exceptions")
if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" )
if( CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 4.0.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.0.0 )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-invalid-partial-specialization" )
endif()
endif()
ENDIF()
ENDIF()
@ -374,14 +378,13 @@ target_include_directories(fc
${CMAKE_CURRENT_SOURCE_DIR}/vendor/boost_1.51/include
${CMAKE_CURRENT_SOURCE_DIR}/vendor/cyoencode-1.0.2/src
${CMAKE_CURRENT_SOURCE_DIR}/vendor/secp256k1-zkp
${CMAKE_CURRENT_SOURCE_DIR}/vendor/equihash
)
#target_link_libraries( fc PUBLIC ${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} equihash ${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} ${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" )
@ -397,7 +400,6 @@ ENDIF(MSVC)
ENDIF()
include_directories( vendor/websocketpp )
include_directories( vendor/equihash )
add_subdirectory(tests)

View file

@ -1,127 +0,0 @@
# Find Wt includes and libraries
#
# This script sets the following variables:
#
# Wt_INCLUDE_DIR
# Wt_LIBRARIES - Release libraries
# Wt_FOUND - True if release libraries found
# Wt_DEBUG_LIBRARIES - Debug libraries
# Wt_DEBUG_FOUND - True if debug libraries found
#
# To direct the script to a particular Wt installation, use the
# standard cmake variables CMAKE_INCLUDE_PATH and CMAKE_LIBRARY_PATH
#
# To use this script to find Wt, when using the new style for include files:
# #include <Wt/WLineEdit>
# #include <Wt/Ext/LineEdit>
# #include <Wt/Chart/WPieChart>
#
# include the following CMake snippet in your project:
#
# FIND_PACKAGE( Wt REQUIRED )
# INCLUDE_DIRECTORIES( ${Wt_INCLUDE_DIR} )
# TARGET_LINK_LIBRARIES( yourexe
# ${Wt_DEBUG_LIBRARY} # or {Wt_LIBRARY}
# ${Wt_HTTP_DEBUG_LIBRARY} # or {Wt_HTTP_LIBRARY}
# ${Wt_EXT_DEBUG_LIBRARY} # or {Wt_EXT_LIBRARY}
# )
#
# To use this script to find Wt, when using the old include style:
# #include <WLineEdit>
# #include <Ext/LineEdit>
# #include <Chart/WPieChart>
# style of include files, change the INCLUDE_DIRECTORIES statement to:
# INCLUDE_DIRECTORIES( ${Wt_INCLUDE_DIR} ${Wt_INCLUDE_DIR}/Wt )
#
#
#
#
# Copyright (c) 2007, Pau Garcia i Quiles, <pgquiles@elpauer.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
FIND_PATH( Wt_INCLUDE_DIR NAMES Wt/WObject PATHS ENV PATH PATH_SUFFIXES include wt )
SET( Wt_FIND_COMPONENTS Release Debug )
IF( Wt_INCLUDE_DIR )
FIND_LIBRARY( Wt_LIBRARY NAMES wt PATHS PATH PATH_SUFFIXES lib lib-release lib_release )
FIND_LIBRARY( Wt_EXT_LIBRARY NAMES wtext PATHS PATH PATH_SUFFIXES lib lib-release lib_release )
FIND_LIBRARY( Wt_HTTP_LIBRARY NAMES wthttp PATHS PATH PATH_SUFFIXES lib lib-release lib_release )
FIND_LIBRARY( Wt_FCGI_LIBRARY NAMES wtfcgi PATHS PATH PATH_SUFFIXES lib lib-release lib_release )
FIND_LIBRARY( Wt_DBO_LIBRARY NAMES wtdbo PATHS PATH PATH_SUFFIXES lib lib-release lib_release )
FIND_LIBRARY( Wt_DBOSQLITE3_LIBRARY NAMES wtdbosqlite3 PATHS PATH PATH_SUFFIXES lib lib-release lib_release )
FIND_LIBRARY( Wt_DBOPOSTGRES_LIBRARY NAMES wtdbopostgres PATHS PATH PATH_SUFFIXES lib lib-release lib_release )
FIND_LIBRARY( Wt_DEBUG_LIBRARY NAMES wtd wt PATHS PATH PATH_SUFFIXES lib libd lib-debug lib_debug HINTS /usr/lib/debug/usr/lib)
FIND_LIBRARY( Wt_EXT_DEBUG_LIBRARY NAMES wtextd wtext PATHS PATH PATH_SUFFIXES lib libd lib-debug lib_debug HINTS /usr/lib/debug/usr/lib)
FIND_LIBRARY( Wt_HTTP_DEBUG_LIBRARY NAMES wthttpd wthttp PATHS PATH PATH_SUFFIXES lib libd lib-debug lib_debug HINTS /usr/lib/debug/usr/lib)
FIND_LIBRARY( Wt_FCGI_DEBUG_LIBRARY NAMES wtfcgid wtfcgi PATHS PATH PATH_SUFFIXES lib libd lib-debug lib_debug HINTS /usr/lib/debug/usr/lib)
FIND_LIBRARY( Wt_DBO_DEBUG_LIBRARY NAMES wtdbod wtdbo PATHS PATH PATH_SUFFIXES lib lib-debug lib_debug HINTS /usr/lib/debug/usr/lib)
FIND_LIBRARY( Wt_DBOSQLITE3_DEBUG_LIBRARY NAMES wtdbosqlite3d wtdbosqlite3 PATHS PATH PATH_SUFFIXES lib lib-debug lib_debug HINTS /usr/lib/debug/usr/lib)
FIND_LIBRARY( Wt_DBOPOSTGRES_DEBUG_LIBRARY NAMES wtdbopostgresd wtdbopostgres PATHS PATH PATH_SUFFIXES lib lib-debug lib_debug HINTS /usr/lib/debug/usr/lib)
IF( Wt_LIBRARY AND Wt_EXT_LIBRARY AND Wt_HTTP_LIBRARY)
SET( Wt_FOUND TRUE )
SET( Wt_FIND_REQUIRED_Release TRUE )
SET( Wt_LIBRARIES ${Wt_HTTP_LIBRARY} ${Wt_EXT_LIBRARY} ${Wt_LIBRARY} )
ENDIF( Wt_LIBRARY AND Wt_EXT_LIBRARY AND Wt_HTTP_LIBRARY)
IF( Wt_DBO_LIBRARY )
SET( Wt_LIBRARIES ${Wt_LIBRARIES} ${Wt_DBO_LIBRARY} )
IF( Wt_DBOSQLITE3_LIBRARY )
SET( Wt_LIBRARIES ${Wt_LIBRARIES} ${Wt_DBOSQLITE3_LIBRARY} )
ENDIF( Wt_DBOSQLITE3_LIBRARY )
IF( Wt_DBOPOSTGRES_LIBRARY )
SET( Wt_LIBRARIES ${Wt_LIBRARIES} ${Wt_DBOPOSTGRES_LIBRARY} )
ENDIF( Wt_DBOPOSTGRES_LIBRARY )
ENDIF( Wt_DBO_LIBRARY )
IF( Wt_FCGI_LIBRARY )
SET( Wt_LIBRARIES ${Wt_LIBRARIES} ${Wt_FCGI_LIBRARY} )
ENDIF( Wt_FCGI_LIBRARY )
IF( Wt_DEBUG_LIBRARY AND Wt_EXT_DEBUG_LIBRARY AND Wt_HTTP_DEBUG_LIBRARY)
SET( Wt_DEBUG_FOUND TRUE )
SET( Wt_FIND_REQUIRED_Debug TRUE )
SET( Wt_DEBUG_LIBRARIES ${Wt_HTTP_DEBUG_LIBRARY} ${Wt_EXT_DEBUG_LIBRARY} ${Wt_DEBUG_LIBRARY} )
ENDIF( Wt_DEBUG_LIBRARY AND Wt_EXT_DEBUG_LIBRARY AND Wt_HTTP_DEBUG_LIBRARY)
IF( Wt_DBO_DEBUG_LIBRARY )
SET( Wt_DEBUG_LIBRARIES ${Wt_DEBUG_LIBRARIES} ${Wt_DBO_DEBUG_LIBRARY} )
IF( Wt_DBOSQLITE3_DEBUG_LIBRARY )
SET( Wt_DEBUG_LIBRARIES ${Wt_DEBUG_LIBRARIES} ${Wt_DBOSQLITE3_DEBUG_LIBRARY} )
ENDIF( Wt_DBOSQLITE3_DEBUG_LIBRARY )
IF( Wt_DBOPOSTGRES_DEBUG_LIBRARY )
SET( Wt_DEBUG_LIBRARIES ${Wt_DEBUG_LIBRARIES} ${Wt_DBOPOSTGRES_DEBUG_LIBRARY} )
ENDIF( Wt_DBOPOSTGRES_DEBUG_LIBRARY )
ENDIF( Wt_DBO_DEBUG_LIBRARY )
IF( Wt_FCGI_DEBUG_LIBRARY )
SET( Wt_DEBUG_LIBRARIES ${Wt_DEBUG_LIBRARIES} ${Wt_FCGI_DEBUG_LIBRARY} )
ENDIF( Wt_FCGI_DEBUG_LIBRARY )
IF(Wt_FOUND)
IF (NOT Wt_FIND_QUIETLY)
MESSAGE(STATUS "Found the Wt libraries at ${Wt_LIBRARIES}")
MESSAGE(STATUS "Found the Wt headers at ${Wt_INCLUDE_DIR}")
ENDIF (NOT Wt_FIND_QUIETLY)
ELSE(Wt_FOUND)
IF(Wt_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could NOT find Wt")
ENDIF(Wt_FIND_REQUIRED)
ENDIF(Wt_FOUND)
IF(Wt_DEBUG_FOUND)
IF (NOT Wt_FIND_QUIETLY)
MESSAGE(STATUS "Found the Wt debug libraries at ${Wt_DEBUG_LIBRARIES}")
MESSAGE(STATUS "Found the Wt debug headers at ${Wt_INCLUDE_DIR}")
ENDIF (NOT Wt_FIND_QUIETLY)
ELSE(Wt_DEBUG_FOUND)
IF(Wt_FIND_REQUIRED_Debug)
MESSAGE(FATAL_ERROR "Could NOT find Wt debug libraries")
ENDIF(Wt_FIND_REQUIRED_Debug)
ENDIF(Wt_DEBUG_FOUND)
ENDIF( Wt_INCLUDE_DIR )

View file

@ -16,8 +16,8 @@ namespace fc {
void unpack( Stream& s, flat_set<T>& value );
template<typename Stream, typename K, typename... V>
void pack( Stream& s, const flat_map<K,V...>& value );
template<typename Stream, typename K, typename... V>
void unpack( Stream& s, flat_map<K,V...>& value ) ;
template<typename Stream, typename K, typename V, typename... A>
void unpack(Stream& s, flat_map<K, V, A...>& value);
template<typename Stream, typename T, typename A>

View file

@ -1,22 +0,0 @@
#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( bool test_canonical_order = false, bool test_intermediate_zeros = false ) const;
void canonize_indexes();
static proof hash( uint32_t n, uint32_t k, sha256 seed );
};
} } // fc
FC_REFLECT( fc::equihash::proof, (n)(k)(seed)(inputs) )

View file

@ -23,7 +23,10 @@ namespace fc { namespace rpc {
response(){}
response( int64_t i, fc::variant r ):id(i),result(r){}
response( int64_t i, error_object r ):id(i),error(r){}
response( int64_t i, fc::variant r, string j ):id(i),jsonrpc(j),result(r){}
response( int64_t i, error_object r, string j ):id(i),jsonrpc(j),error(r){}
int64_t id = 0;
optional<fc::string> jsonrpc;
optional<fc::variant> result;
optional<error_object> error;
};
@ -57,4 +60,4 @@ namespace fc { namespace rpc {
FC_REFLECT( fc::rpc::request, (id)(method)(params) );
FC_REFLECT( fc::rpc::error_object, (code)(message)(data) )
FC_REFLECT( fc::rpc::response, (id)(result)(error) )
FC_REFLECT( fc::rpc::response, (id)(jsonrpc)(result)(error) )

View file

@ -90,8 +90,8 @@ namespace fc
template<typename K, typename... T>
void to_variant( const fc::flat_map<K,T...>& var, variant& vo );
template<typename K, typename... T>
void from_variant( const variant& var, fc::flat_map<K,T...>& vo );
template<typename K, typename T, typename... A>
void from_variant(const variant& var, flat_map<K, T, A...>& vo);
template<typename K, typename T, typename C>
void to_variant( const std::map<K,T, C>& var, variant& vo );

View file

@ -66,74 +66,71 @@ public:
/** C++ wrapper for BIGNUM (OpenSSL bignum) */
class CBigNum : public BIGNUM
class CBigNum
{
BIGNUM* bn;
public:
CBigNum()
{
BN_init(this);
}
: bn(BN_new()) {}
CBigNum(const CBigNum& b)
: CBigNum()
{
BN_init(this);
if (!BN_copy(this, &b))
if (!BN_copy(bn, b.bn))
{
BN_clear_free(this);
BN_clear_free(bn);
throw bignum_error("CBigNum::CBigNum(const CBigNum&) : BN_copy failed");
}
}
CBigNum& operator=(const CBigNum& b)
{
if (!BN_copy(this, &b))
if (!BN_copy(bn, b.bn))
throw bignum_error("CBigNum::operator= : BN_copy failed");
return (*this);
}
~CBigNum()
{
BN_clear_free(this);
BN_clear_free(bn);
}
//CBigNum(char n) is not portable. Use 'signed char' or 'unsigned char'.
CBigNum(signed char n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
CBigNum(short n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
CBigNum(int n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
//CBigNum(long n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
CBigNum(int64_t n) { BN_init(this); setint64(n); }
CBigNum(unsigned char n) { BN_init(this); setulong(n); }
CBigNum(unsigned short n) { BN_init(this); setulong(n); }
CBigNum(unsigned int n) { BN_init(this); setulong(n); }
//CBigNum(unsigned long n) { BN_init(this); setulong(n); }
CBigNum(uint64_t n) { BN_init(this); setuint64(n); }
CBigNum(signed char n) :CBigNum() { if (n >= 0) setulong(n); else setint64(n); }
CBigNum(short n) :CBigNum() { if (n >= 0) setulong(n); else setint64(n); }
CBigNum(int n) :CBigNum() { if (n >= 0) setulong(n); else setint64(n); }
CBigNum(int64_t n) :CBigNum() { setint64(n); }
CBigNum(unsigned char n) :CBigNum() { setulong(n); }
CBigNum(unsigned short n) :CBigNum() { setulong(n); }
CBigNum(unsigned int n) :CBigNum() { setulong(n); }
CBigNum(uint64_t n) :CBigNum() { setuint64(n); }
explicit CBigNum(const std::vector<unsigned char>& vch)
: CBigNum()
{
BN_init(this);
setvch(vch);
}
void setulong(unsigned long n)
{
if (!BN_set_word(this, n))
if (!BN_set_word(bn, n))
throw bignum_error("CBigNum conversion from unsigned long : BN_set_word failed");
}
unsigned long getulong() const
{
return BN_get_word(this);
return BN_get_word(bn);
}
unsigned int getuint() const
{
return BN_get_word(this);
return BN_get_word(bn);
}
int getint() const
{
unsigned long n = BN_get_word(this);
if (!BN_is_negative(this))
unsigned long n = BN_get_word(bn);
if (!BN_is_negative(bn))
return (n > (unsigned long)std::numeric_limits<int>::max() ? std::numeric_limits<int>::max() : n);
else
return (n > (unsigned long)std::numeric_limits<int>::max() ? std::numeric_limits<int>::min() : -(int)n);
@ -171,7 +168,7 @@ public:
pch[1] = (nSize >> 16) & 0xff;
pch[2] = (nSize >> 8) & 0xff;
pch[3] = (nSize) & 0xff;
BN_mpi2bn(pch, p - pch, this);
BN_mpi2bn(pch, p - pch, bn);
}
void setuint64(uint64_t n)
@ -198,7 +195,7 @@ public:
pch[1] = (nSize >> 16) & 0xff;
pch[2] = (nSize >> 8) & 0xff;
pch[3] = (nSize) & 0xff;
BN_mpi2bn(pch, p - pch, this);
BN_mpi2bn(pch, p - pch, bn);
}
@ -214,16 +211,16 @@ public:
vch2[3] = (nSize >> 0) & 0xff;
// swap data to big endian
reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4);
BN_mpi2bn(&vch2[0], vch2.size(), this);
BN_mpi2bn(&vch2[0], vch2.size(), bn);
}
std::vector<unsigned char> getvch() const
{
unsigned int nSize = BN_bn2mpi(this, NULL);
unsigned int nSize = BN_bn2mpi(bn, NULL);
if (nSize <= 4)
return std::vector<unsigned char>();
std::vector<unsigned char> vch(nSize);
BN_bn2mpi(this, &vch[0]);
BN_bn2mpi(bn, &vch[0]);
vch.erase(vch.begin(), vch.begin() + 4);
reverse(vch.begin(), vch.end());
return vch;
@ -237,16 +234,16 @@ public:
if (nSize >= 1) vch[4] = (nCompact >> 16) & 0xff;
if (nSize >= 2) vch[5] = (nCompact >> 8) & 0xff;
if (nSize >= 3) vch[6] = (nCompact >> 0) & 0xff;
BN_mpi2bn(&vch[0], vch.size(), this);
BN_mpi2bn(&vch[0], vch.size(), bn);
return *this;
}
unsigned int GetCompact() const
{
unsigned int nSize = BN_bn2mpi(this, NULL);
unsigned int nSize = BN_bn2mpi(bn, NULL);
std::vector<unsigned char> vch(nSize);
nSize -= 4;
BN_bn2mpi(this, &vch[0]);
BN_bn2mpi(bn, &vch[0]);
unsigned int nCompact = nSize << 24;
if (nSize >= 1) nCompact |= (vch[4] << 16);
if (nSize >= 2) nCompact |= (vch[5] << 8);
@ -281,7 +278,7 @@ public:
*this += n;
}
if (fNegative)
*this = 0 - *this;
BN_set_negative(bn, 1);
}
std::string ToString(int nBase=10) const
@ -291,20 +288,20 @@ public:
CBigNum bn0 = 0;
std::string str;
CBigNum bn = *this;
BN_set_negative(&bn, false);
BN_set_negative(bn.bn, false);
CBigNum dv;
CBigNum rem;
if (BN_cmp(&bn, &bn0) == 0)
if (BN_cmp(bn.bn, bn0.bn) == 0)
return "0";
while (BN_cmp(&bn, &bn0) > 0)
while (BN_cmp(bn.bn, bn0.bn) > 0)
{
if (!BN_div(&dv, &rem, &bn, &bnBase, pctx))
if (!BN_div(dv.bn, rem.bn, bn.bn, bnBase.bn, pctx))
throw bignum_error("CBigNum::ToString() : BN_div failed");
bn = dv;
unsigned int c = rem.getulong();
str += "0123456789abcdef"[c];
}
if (BN_is_negative(this))
if (BN_is_negative(this->bn))
str += "-";
reverse(str.begin(), str.end());
return str;
@ -319,45 +316,50 @@ public:
bool operator!() const
{
return BN_is_zero(this);
return BN_is_zero(bn);
}
CBigNum& operator+=(const CBigNum& b)
{
if (!BN_add(this, this, &b))
if (!BN_add(bn, bn, b.bn))
throw bignum_error("CBigNum::operator+= : BN_add failed");
return *this;
}
CBigNum& operator-=(const CBigNum& b)
{
*this = *this - b;
if (!BN_sub(bn, bn, b.bn))
throw bignum_error("CBigNum::operator-= : BN_sub failed");
return *this;
}
CBigNum& operator*=(const CBigNum& b)
{
CAutoBN_CTX pctx;
if (!BN_mul(this, this, &b, pctx))
if (!BN_mul(bn, bn, b.bn, pctx))
throw bignum_error("CBigNum::operator*= : BN_mul failed");
return *this;
}
CBigNum& operator/=(const CBigNum& b)
{
*this = *this / b;
CAutoBN_CTX pctx;
if (!BN_div(bn, NULL, bn, b.bn, pctx))
throw bignum_error("CBigNum::operator/= : BN_div failed");
return *this;
}
CBigNum& operator%=(const CBigNum& b)
{
*this = *this % b;
CAutoBN_CTX pctx;
if (!BN_div(NULL, bn, bn, b.bn, pctx))
throw bignum_error("CBigNum::operator%= : BN_div failed");
return *this;
}
CBigNum& operator<<=(unsigned int shift)
{
if (!BN_lshift(this, this, shift))
if (!BN_lshift(bn, bn, shift))
throw bignum_error("CBigNum:operator<<= : BN_lshift failed");
return *this;
}
@ -368,13 +370,13 @@ public:
// if built on ubuntu 9.04 or 9.10, probably depends on version of openssl
CBigNum a = 1;
a <<= shift;
if (BN_cmp(&a, this) > 0)
if (BN_cmp(a.bn, bn) > 0)
{
*this = 0;
return *this;
}
if (!BN_rshift(this, this, shift))
if (!BN_rshift(bn, bn, shift))
throw bignum_error("CBigNum:operator>>= : BN_rshift failed");
return *this;
}
@ -383,7 +385,7 @@ public:
CBigNum& operator++()
{
// prefix operator
if (!BN_add(this, this, BN_value_one()))
if (!BN_add(bn, bn, BN_value_one()))
throw bignum_error("CBigNum::operator++ : BN_add failed");
return *this;
}
@ -400,7 +402,7 @@ public:
{
// prefix operator
CBigNum r;
if (!BN_sub(&r, this, BN_value_one()))
if (!BN_sub(r.bn, bn, BN_value_one()))
throw bignum_error("CBigNum::operator-- : BN_sub failed");
*this = r;
return *this;
@ -414,10 +416,12 @@ public:
return ret;
}
friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b);
friend inline const CBigNum operator/(const CBigNum& a, const CBigNum& b);
friend inline const CBigNum operator%(const CBigNum& a, const CBigNum& b);
const BIGNUM* to_bignum() const {
return bn;
}
BIGNUM* to_bignum() {
return bn;
}
};
@ -425,7 +429,7 @@ public:
inline const CBigNum operator+(const CBigNum& a, const CBigNum& b)
{
CBigNum r;
if (!BN_add(&r, &a, &b))
if (!BN_add(r.to_bignum(), a.to_bignum(), b.to_bignum()))
throw bignum_error("CBigNum::operator+ : BN_add failed");
return r;
}
@ -433,7 +437,7 @@ inline const CBigNum operator+(const CBigNum& a, const CBigNum& b)
inline const CBigNum operator-(const CBigNum& a, const CBigNum& b)
{
CBigNum r;
if (!BN_sub(&r, &a, &b))
if (!BN_sub(r.to_bignum(), a.to_bignum(), b.to_bignum()))
throw bignum_error("CBigNum::operator- : BN_sub failed");
return r;
}
@ -441,7 +445,7 @@ inline const CBigNum operator-(const CBigNum& a, const CBigNum& b)
inline const CBigNum operator-(const CBigNum& a)
{
CBigNum r(a);
BN_set_negative(&r, !BN_is_negative(&r));
BN_set_negative(r.to_bignum(), !BN_is_negative(r.to_bignum()));
return r;
}
@ -449,7 +453,7 @@ inline const CBigNum operator*(const CBigNum& a, const CBigNum& b)
{
CAutoBN_CTX pctx;
CBigNum r;
if (!BN_mul(&r, &a, &b, pctx))
if (!BN_mul(r.to_bignum(), a.to_bignum(), b.to_bignum(), pctx))
throw bignum_error("CBigNum::operator* : BN_mul failed");
return r;
}
@ -458,7 +462,7 @@ inline const CBigNum operator/(const CBigNum& a, const CBigNum& b)
{
CAutoBN_CTX pctx;
CBigNum r;
if (!BN_div(&r, NULL, &a, &b, pctx))
if (!BN_div(r.to_bignum(), NULL, a.to_bignum(), b.to_bignum(), pctx))
throw bignum_error("CBigNum::operator/ : BN_div failed");
return r;
}
@ -467,7 +471,7 @@ inline const CBigNum operator%(const CBigNum& a, const CBigNum& b)
{
CAutoBN_CTX pctx;
CBigNum r;
if (!BN_mod(&r, &a, &b, pctx))
if (!BN_mod(r.to_bignum(), a.to_bignum(), b.to_bignum(), pctx))
throw bignum_error("CBigNum::operator% : BN_div failed");
return r;
}
@ -475,7 +479,7 @@ inline const CBigNum operator%(const CBigNum& a, const CBigNum& b)
inline const CBigNum operator<<(const CBigNum& a, unsigned int shift)
{
CBigNum r;
if (!BN_lshift(&r, &a, shift))
if (!BN_lshift(r.to_bignum(), a.to_bignum(), shift))
throw bignum_error("CBigNum:operator<< : BN_lshift failed");
return r;
}
@ -487,12 +491,12 @@ inline const CBigNum operator>>(const CBigNum& a, unsigned int shift)
return r;
}
inline bool operator==(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) == 0); }
inline bool operator!=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) != 0); }
inline bool operator<=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) <= 0); }
inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) >= 0); }
inline bool operator<(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) < 0); }
inline bool operator>(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) > 0); }
inline bool operator==(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.to_bignum(), b.to_bignum()) == 0); }
inline bool operator!=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.to_bignum(), b.to_bignum()) != 0); }
inline bool operator<=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.to_bignum(), b.to_bignum()) <= 0); }
inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.to_bignum(), b.to_bignum()) >= 0); }
inline bool operator<(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.to_bignum(), b.to_bignum()) < 0); }
inline bool operator>(const CBigNum& a, const CBigNum& b) { return (BN_cmp(a.to_bignum(), b.to_bignum()) > 0); }
static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
@ -522,7 +526,7 @@ inline std::string EncodeBase58(const unsigned char* pbegin, const unsigned char
CBigNum rem;
while (bn > bn0)
{
if (!BN_div(&dv, &rem, &bn, &bn58, pctx))
if (!BN_div(dv.to_bignum(), rem.to_bignum(), bn.to_bignum(), bn58.to_bignum(), pctx))
throw bignum_error("EncodeBase58 : BN_div failed");
bn = dv;
unsigned int c = rem.getulong();
@ -572,7 +576,7 @@ inline bool DecodeBase58(const char* psz, std::vector<unsigned char>& vchRet)
break;
}
bnChar.setulong(p1 - pszBase58);
if (!BN_mul(&bn, &bn, &bn58, pctx))
if (!BN_mul(bn.to_bignum(), bn.to_bignum(), bn58.to_bignum(), pctx))
throw bignum_error("DecodeBase58 : BN_mul failed");
bn += bnChar;
}

View file

@ -1,6 +1,9 @@
#include <fc/crypto/dh.hpp>
#include <openssl/dh.h>
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
#endif
namespace fc {
SSL_TYPE(ssl_dh, DH, DH_free)
@ -12,10 +15,19 @@ namespace fc {
bool diffie_hellman::generate_params( int s, uint8_t g )
{
ssl_dh dh = DH_generate_parameters( s, g, NULL, NULL );
ssl_dh dh;
DH_generate_parameters_ex(dh.obj, s, g, NULL);
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
ssl_bignum bn_p;
DH_get0_pqg(dh.obj, (const BIGNUM**)&bn_p.obj, NULL, NULL);
p.resize( BN_num_bytes( bn_p ) );
if( p.size() )
BN_bn2bin( bn_p, (unsigned char*)&p.front() );
#else
p.resize( BN_num_bytes( dh->p ) );
if( p.size() )
BN_bn2bin( dh->p, (unsigned char*)&p.front() );
#endif
this->g = g;
return fc::validate( dh, valid );
}
@ -25,8 +37,14 @@ namespace fc {
if( !p.size() )
return valid = false;
ssl_dh dh = DH_new();
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
const auto bn_p = BN_bin2bn( (unsigned char*)&p.front(), p.size(), NULL );
const auto bn_g = BN_bin2bn( (unsigned char*)&g, 1, NULL );
DH_set0_pqg(dh.obj, bn_p, NULL, bn_g);
#else
dh->p = BN_bin2bn( (unsigned char*)&p.front(), p.size(), NULL );
dh->g = BN_bin2bn( (unsigned char*)&g, 1, NULL );
#endif
return fc::validate( dh, valid );
}
@ -35,8 +53,14 @@ namespace fc {
if( !p.size() )
return valid = false;
ssl_dh dh = DH_new();
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
const auto bn_p = BN_bin2bn( (unsigned char*)&p.front(), p.size(), NULL );
const auto bn_g = BN_bin2bn( (unsigned char*)&g, 1, NULL );
DH_set0_pqg(dh.obj, bn_p, NULL, bn_g);
#else
dh->p = BN_bin2bn( (unsigned char*)&p.front(), p.size(), NULL );
dh->g = BN_bin2bn( (unsigned char*)&g, 1, NULL );
#endif
if( !fc::validate( dh, valid ) )
{
@ -44,21 +68,42 @@ namespace fc {
}
DH_generate_key(dh);
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
ssl_bignum bn_pub_key;
ssl_bignum bn_priv_key;
DH_get0_key(dh.obj, (const BIGNUM**)&bn_pub_key.obj, (const BIGNUM**)&bn_priv_key.obj);
pub_key.resize( BN_num_bytes( bn_pub_key ) );
priv_key.resize( BN_num_bytes( bn_priv_key ) );
if( pub_key.size() )
BN_bn2bin( bn_pub_key.obj, (unsigned char*)&pub_key.front() );
if( priv_key.size() )
BN_bn2bin( bn_priv_key.obj, (unsigned char*)&priv_key.front() );
#else
pub_key.resize( BN_num_bytes( dh->pub_key ) );
priv_key.resize( BN_num_bytes( dh->priv_key ) );
if( pub_key.size() )
BN_bn2bin( dh->pub_key, (unsigned char*)&pub_key.front() );
if( priv_key.size() )
BN_bn2bin( dh->priv_key, (unsigned char*)&priv_key.front() );
#endif
return true;
}
bool diffie_hellman::compute_shared_key( const char* buf, uint32_t s ) {
ssl_dh dh = DH_new();
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
auto bn_p = BN_bin2bn( (unsigned char*)&p.front(), p.size(), NULL );
auto bn_pub_key = BN_bin2bn( (unsigned char*)&pub_key.front(), pub_key.size(), NULL );
auto bn_priv_key = BN_bin2bn( (unsigned char*)&priv_key.front(), priv_key.size(), NULL );
auto bn_g = BN_bin2bn( (unsigned char*)&g, 1, NULL );
DH_set0_pqg(dh.obj, bn_p, NULL, bn_g);
DH_set0_key(dh.obj, bn_pub_key, bn_priv_key);
#else
dh->p = BN_bin2bn( (unsigned char*)&p.front(), p.size(), NULL );
dh->pub_key = BN_bin2bn( (unsigned char*)&pub_key.front(), pub_key.size(), NULL );
dh->priv_key = BN_bin2bn( (unsigned char*)&priv_key.front(), priv_key.size(), NULL );
dh->g = BN_bin2bn( (unsigned char*)&g, 1, NULL );
#endif
int check;
DH_check(dh,&check);

View file

@ -1,57 +0,0 @@
#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( bool test_canonical_order, bool test_intermediate_zeros ) const
{
_POW::Proof test( n, k, sha_to_seed( seed ), EQUIHASH_NONCE, inputs );
if( test_canonical_order && !test.CheckIndexesCanon() )
return false;
if( test_intermediate_zeros )
return test.FullTest();
return test.Test();
}
void proof::canonize_indexes()
{
_POW::Proof p( n, k, sha_to_seed( seed ), EQUIHASH_NONCE, inputs );
_POW::Proof p_canon = p.CanonizeIndexes();
inputs = p_canon.inputs;
}
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

View file

@ -155,7 +155,7 @@ namespace fc
* and other information that is generally only useful for
* developers.
*/
string exception::to_detail_string( log_level ll )const
string exception::to_detail_string( log_level ll )const
{
fc::stringstream ss;
ss << variant(my->_code).as_string() <<" " << my->_name << ": " <<my->_what<<"\n";
@ -173,13 +173,14 @@ namespace fc
/**
* Generates a user-friendly error report.
*/
string exception::to_string( log_level ll )const
string exception::to_string( log_level ll )const
{
fc::stringstream ss;
ss << what() << " (" << variant(my->_code).as_string() <<")\n";
ss << what() << ":";
for( auto itr = my->_elog.begin(); itr != my->_elog.end(); ++itr )
{
ss << fc::format_string( itr->get_format(), itr->get_data() ) <<"\n";
if( itr->get_format().size() )
ss << " " << fc::format_string( itr->get_format(), itr->get_data() );
// ss << " " << itr->get_context().to_string() <<"\n";
}
return ss.str();

View file

@ -14,6 +14,7 @@
#include <fc/exception/exception.hpp>
#include <iomanip>
#include <sstream>
#include <mutex>
namespace fc {
@ -27,7 +28,7 @@ namespace fc {
#endif
};
console_appender::console_appender( const variant& args )
console_appender::console_appender( const variant& args )
:my(new impl)
{
configure( args.as<config>() );
@ -66,7 +67,7 @@ namespace fc {
#ifdef WIN32
static WORD
#else
static const char*
static const char*
#endif
get_console_color(console_appender::color::type t ) {
switch( t ) {
@ -140,7 +141,7 @@ namespace fc {
#endif
if( text.size() )
fprintf( out, "%s", text.c_str() ); //fmt_str.c_str() );
fprintf( out, "%s", text.c_str() ); //fmt_str.c_str() );
#ifdef WIN32
if (my->console_handle != INVALID_HANDLE_VALUE)

View file

@ -87,6 +87,7 @@ std::string websocket_api_connection::on_message(
{
auto var = fc::json::from_string(message);
const auto& var_obj = var.get_object();
if( var_obj.contains( "method" ) )
{
auto call = var.as<fc::rpc::request>();
@ -112,7 +113,7 @@ std::string websocket_api_connection::on_message(
if( call.id )
{
auto reply = fc::json::to_string( response( *call.id, result ) );
auto reply = fc::json::to_string( response( *call.id, result, "2.0" ) );
if( send_message )
_connection.send_message( reply );
return reply;
@ -129,7 +130,7 @@ std::string websocket_api_connection::on_message(
}
if( optexcept ) {
auto reply = fc::json::to_string( response( *call.id, error_object{ 1, optexcept->to_detail_string(), fc::variant(*optexcept)} ) );
auto reply = fc::json::to_string( response( *call.id, error_object{ 1, optexcept->to_string(), fc::variant(*optexcept)}, "2.0" ) );
if( send_message )
_connection.send_message( reply );

View file

@ -1,19 +0,0 @@
file(GLOB HEADERS "include/equihash/*.hpp" )
set( CMAKE_C_FLAGS "-std=c99" )
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
)

View file

@ -1,72 +0,0 @@
/*
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

View file

@ -1,136 +0,0 @@
/*
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

View file

@ -1,157 +0,0 @@
/*
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

View file

@ -1,68 +0,0 @@
/*
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

View file

@ -1,402 +0,0 @@
/*
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

View file

@ -1,170 +0,0 @@
/*
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);

View file

@ -1,120 +0,0 @@
/*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();
bool FullTest()const;
bool CheckIndexesCanon()const;
Proof CanonizeIndexes()const;
};
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

View file

@ -1,469 +0,0 @@
/*
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;
}

View file

@ -1,415 +0,0 @@
/*Code by Dmitry Khovratovich, 2016
CC0 license
Modifications by Steemit, Inc. 2016
*/
#include <equihash/pow.hpp>
#include <equihash/blake2.h>
#include <algorithm>
#ifdef EQUIHASH_POW_VERBOSE
#include <iomanip>
#include <iostream>
#define EQUIHASH_LOG(s) \
std::cerr << s << std::endl;
#else
#define EQUIHASH_LOG(s)
#endif
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].CanonizeIndexes();
}
}
}
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].CanonizeIndexes();
}
}
return Proof(n, k, seed, nonce, std::vector<uint32_t>());
}
Proof Proof::CanonizeIndexes()const
{
// We consider the index values in the inputs array to be the leaf nodes of a binary
// tree, and the inner nodes to be labelled with the XOR of the corresponding vector
// elements.
//
// Define a binary tree to be canonically sorted if, for each inner node, the least
// leaf descendant of the left child is less than the least leaf descendant of the
// right child.
//
// This method puts the inputs into canonical order without altering the inner node
// labels. Thus canonization preserves the validity of the proof and the
// footprint of Wagner's algorithm.
//
// We use a bottom-up traversal, dividing the input into successively larger power-of-2
// blocks and swapping the two half-blocks if non-canonical.
//
// Say a block is least-first if the least element is the first element.
//
// If each half-block is least-first, the conditional swap ensures the full block will also
// be least-first. The half-blocks in the initial iteration are obviously least-first
// (they only have a single element!). So by induction, at each later iteration the half-blocks
// of that iteration are least-first (since they were the full blocks of the previous iteration,
// which were made least-first by the previous iteration's conditional swap).
//
// As a consequence, no search is necessary to find the least element in each half-block,
// it is always the first element in the half-block.
std::vector< uint32_t > new_inputs = inputs;
size_t input_size = inputs.size();
size_t half_size = 1;
size_t block_size = 2;
while( block_size <= input_size )
{
for( size_t i=0; i+block_size<=input_size; i+=block_size )
{
auto ita = new_inputs.begin()+i, itb = ita+half_size;
if( (*ita) >= (*itb) )
{
std::swap_ranges( ita, itb, itb );
}
}
half_size = block_size;
block_size += block_size;
}
return Proof(n, k, seed, nonce, new_inputs);
}
bool Proof::CheckIndexesCanon()const
{
// This method is logically identical to CanonizeIndexes() but will return false
// instead of swapping elements.
size_t input_size = inputs.size();
size_t half_size = 1;
size_t block_size = 2;
while( block_size <= input_size )
{
for( size_t i=0; i+block_size<=input_size; i+=block_size )
{
auto ita = inputs.begin()+i, itb = ita+half_size;
if( (*ita) >= (*itb) )
return false;
}
half_size = block_size;
block_size += block_size;
}
return true;
}
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;
}
bool Proof::FullTest()const
{
// Length must be 2**k
if( inputs.size() != size_t(1 << k) )
{
EQUIHASH_LOG( "PoW failed length test" );
return false;
}
// Ensure all values are distinct
std::vector<Input> sorted_inputs = inputs;
std::sort( sorted_inputs.begin(), sorted_inputs.end() );
for( size_t i=1; i<inputs.size(); i++ )
{
if( sorted_inputs[i-1] >= sorted_inputs[i] )
{
EQUIHASH_LOG( "PoW failed distinct test" );
return false;
}
}
// Ensure all values are canonically indexed
/*
if( !CheckIndexesCanon() )
return false;
*/
// Initialize blocks array
uint32_t input[SEED_LENGTH + 2];
for( size_t 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< std::vector< uint32_t > > blocks;
const uint32_t max_input = uint32_t(1) << (n / (k + 1) + 1);
for( size_t i=0; i<inputs.size(); i++ )
{
input[SEED_LENGTH + 1] = inputs[i];
if( inputs[i] >= max_input )
{
EQUIHASH_LOG( "PoW failed max_input test" );
return false;
}
blake2b((uint8_t*)buf, &input, NULL, sizeof(buf), sizeof(input), 0);
blocks.emplace_back();
std::vector<uint32_t>& x = blocks.back();
x.resize(k+1);
for( size_t j=0; j<(k+1); j++ )
{
//select j-th block of n/(k+1) bits
x[j] = buf[j] >> (32 - n / (k + 1));
}
}
while( true )
{
#ifdef EQUIHASH_POW_VERBOSE
std::cerr << "\n\nBegin loop iteration\n";
for( const std::vector< uint32_t >& x : blocks )
{
for( const uint32_t& e : x )
std::cerr << std::hex << std::setw(5) << e << " ";
std::cerr << std::endl;
}
#endif
size_t count = blocks.size();
if( count == 0 )
{
EQUIHASH_LOG( "PoW failed with count == 0" );
return false;
}
if( count == 1 )
{
if( blocks[0].size() != 1 )
{
EQUIHASH_LOG( "PoW failed due to vector size" );
return false;
}
if( blocks[0][0] != 0 )
{
EQUIHASH_LOG( "PoW failed because final bits are not zero" );
return false;
}
return true;
}
if( (count&1) != 0 )
{
EQUIHASH_LOG( "PoW failed with odd count" );
return false;
}
for( size_t i=0,new_i=0; i<count; i+=2,new_i++ )
{
if( blocks[i][0] != blocks[i+1][0] )
{
EQUIHASH_LOG( "PoW failed because leading element of vector pair does not match" );
return false;
}
for( size_t j=1; j<blocks[i].size(); j++ )
blocks[new_i][j-1] = blocks[i][j] ^ blocks[i+1][j];
blocks[new_i].resize(blocks[new_i].size()-1);
}
blocks.resize(blocks.size() >> 1);
}
}