Updates from BitShares FC #22

Closed
nathanielhourt wants to merge 693 commits from dapp-support into latest-fc
36 changed files with 319 additions and 802 deletions
Showing only changes of commit 2cf1510d81 - Show all commits

2
.gitignore vendored
View file

@ -36,7 +36,7 @@ Release/
CMakeCache.txt
CMakeFiles
Makefile
*.cmake
cmake_install.cmake
*.cbp
libfc.a

View file

@ -33,7 +33,6 @@ script:
- "tests/api 2>&1 | grep -vE 'callback result 9|remote_calc->add. 4, 5 .: 9|set callback|] \\.$'"
- tests/hmac_test 2>&1 | cat
- tests/ecc_test README.md 2>&1 | cat
- tests/log_test 2>&1 | cat
- 'find CMakeFiles/fc.dir -type d | while read d; do gcov -o "$d" "${d/CMakeFiles*.dir/./}"/*.cpp; done >/dev/null'
- 'which sonar-scanner && sonar-scanner || true'
- ccache -s

View file

@ -19,6 +19,8 @@ INCLUDE(GetPrerequisites)
INCLUDE( VersionMacros )
INCLUDE( SetupTargetMacros )
INCLUDE(GetGitRevisionDescription)
INCLUDE(CheckLibraryExists)
INCLUDE(CheckLibcxxAtomic)
get_git_head_revision(GIT_REFSPEC FC_GIT_REVISION_SHA)
get_git_unix_timestamp(FC_GIT_REVISION_UNIX_TIMESTAMP)
@ -38,6 +40,7 @@ SET (ORIGINAL_LIB_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
SET(BOOST_COMPONENTS)
LIST(APPEND BOOST_COMPONENTS thread date_time filesystem system program_options chrono unit_test_framework context iostreams regex)
# boost::endian is also required, but FindBoost can't handle header-only libs
SET( Boost_USE_STATIC_LIBS ON CACHE STRING "ON or OFF" )
# Configure secp256k1-zkp
@ -153,7 +156,7 @@ IF( WIN32 )
SET(Boost_LIBRARIES ${BOOST_LIBRARIES_TEMP} ${Boost_LIBRARIES})
ENDIF()
set( PLATFORM_SPECIFIC_LIBS wsock32.lib ws2_32.lib userenv.lib)
LIST(APPEND PLATFORM_SPECIFIC_LIBS wsock32.lib ws2_32.lib userenv.lib)
# iphlpapi.lib
ELSE(WIN32)
@ -180,6 +183,9 @@ IF(NOT "$ENV{OPENSSL_ROOT_DIR}" STREQUAL "")
message(STATUS "Setting up OpenSSL root and include vars to ${OPENSSL_ROOT_DIR}, ${OPENSSL_INCLUDE_DIR}")
ENDIF()
IF( LIBCXX_HAVE_CXX_ATOMICS_WITH_LIB )
LIST( APPEND PLATFORM_SPECIFIC_LIBS atomic )
ENDIF( LIBCXX_HAVE_CXX_ATOMICS_WITH_LIB )
find_package(OpenSSL REQUIRED)
@ -377,7 +383,9 @@ target_include_directories(fc
IF(NOT WIN32)
set(LINK_USR_LOCAL_LIB -L/usr/local/lib)
ENDIF()
target_link_libraries( fc PUBLIC ${LINK_USR_LOCAL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARIES} ${PLATFORM_SPECIFIC_LIBS} ${RPCRT4} ${CMAKE_DL_LIBS} ${rt_library} ${editline_libraries} secp256k1 )
target_link_libraries( fc PUBLIC ${LINK_USR_LOCAL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARIES}
${PLATFORM_SPECIFIC_LIBS} ${RPCRT4} ${CMAKE_DL_LIBS} ${rt_library}
${editline_libraries} secp256k1 ${CMAKE_REQUIRED_LIBRARIES} )
if(MSVC)
set_source_files_properties( src/network/http/websocket.cpp PROPERTIES COMPILE_FLAGS "/bigobj" )

View file

@ -0,0 +1,50 @@
# Taken from https://chromium.googlesource.com/chromium/llvm-project/libcxx/+/refs/heads/master/cmake/Modules/CheckLibcxxAtomic.cmake
# Apache License v2.0 with LLVM Exceptions
INCLUDE(CheckCXXSourceCompiles)
# Sometimes linking against libatomic is required for atomic ops, if
# the platform doesn't support lock-free atomics.
function(check_cxx_atomics varname)
set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++11")
if (${LIBCXX_GCC_TOOLCHAIN})
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} --gcc-toolchain=${LIBCXX_GCC_TOOLCHAIN}")
endif()
if (CMAKE_C_FLAGS MATCHES -fsanitize OR CMAKE_CXX_FLAGS MATCHES -fsanitize)
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-sanitize=all")
endif()
if (CMAKE_C_FLAGS MATCHES -fsanitize-coverage OR CMAKE_CXX_FLAGS MATCHES -fsanitize-coverage)
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters")
endif()
check_cxx_source_compiles("
#include <cstdint>
#include <boost/lockfree/queue.hpp>
boost::lockfree::queue<uint32_t*> q;
int main(int, char**) {
uint32_t* a;
uint32_t* b;
q.push(a);
q.pop(b);
}
" ${varname})
set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
endfunction(check_cxx_atomics)
# Perform the check for 64bit atomics without libatomic.
check_cxx_atomics(LIBCXX_HAVE_CXX_ATOMICS_WITHOUT_LIB)
# If not, check if the library exists, and atomics work with it.
if(NOT LIBCXX_HAVE_CXX_ATOMICS_WITHOUT_LIB)
check_library_exists(atomic __atomic_fetch_add_8 "" LIBCXX_HAS_ATOMIC_LIB)
if(LIBCXX_HAS_ATOMIC_LIB)
list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
check_cxx_atomics(LIBCXX_HAVE_CXX_ATOMICS_WITH_LIB)
if (NOT LIBCXX_HAVE_CXX_ATOMICS_WITH_LIB)
message(WARNING "Host compiler must support std::atomic!")
endif()
else()
message(WARNING "Host compiler appears to require libatomic, but cannot find it.")
endif()
endif()

View file

@ -1,28 +0,0 @@
#pragma once
#include <stdint.h>
namespace fc {
inline uint64_t endian_reverse_u64( uint64_t x )
{
return (((x >> 0x38) & 0xFF) )
| (((x >> 0x30) & 0xFF) << 0x08)
| (((x >> 0x28) & 0xFF) << 0x10)
| (((x >> 0x20) & 0xFF) << 0x18)
| (((x >> 0x18) & 0xFF) << 0x20)
| (((x >> 0x10) & 0xFF) << 0x28)
| (((x >> 0x08) & 0xFF) << 0x30)
| (((x ) & 0xFF) << 0x38)
;
}
inline uint32_t endian_reverse_u32( uint32_t x )
{
return (((x >> 0x18) & 0xFF) )
| (((x >> 0x10) & 0xFF) << 0x08)
| (((x >> 0x08) & 0xFF) << 0x10)
| (((x ) & 0xFF) << 0x18)
;
}
} // namespace fc

View file

@ -617,11 +617,6 @@ inline bloom_filter operator ^ (const bloom_filter& a, const bloom_filter& b)
} // namespace fc
FC_REFLECT( fc::bloom_filter, (salt_)(bit_table_)(salt_count_)(table_size_)(raw_table_size_)(projected_element_count_)(inserted_element_count_)(random_seed_)(desired_false_positive_probability_) )
FC_REFLECT( fc::bloom_parameters::optimal_parameters_t, (number_of_hashes)(table_size) )
FC_REFLECT( fc::bloom_parameters, (minimum_size)(maximum_size)(minimum_number_of_hashes)(maximum_number_of_hashes)(projected_element_count)(false_positive_probability)(random_seed)(optimal_parameters) )
/*
Note 1:
If it can be guaranteed that bits_per_char will be of the form 2^n then

View file

@ -1,5 +1,5 @@
#pragma once
#include <boost/endian/buffers.hpp>
#include <fc/fwd.hpp>
#include <fc/io/raw_fwd.hpp>
#include <fc/reflect/typename.hpp>
@ -68,7 +68,7 @@ class ripemd160
friend bool operator > ( const ripemd160& h1, const ripemd160& h2 );
friend bool operator < ( const ripemd160& h1, const ripemd160& h2 );
uint32_t _hash[5];
boost::endian::little_uint32_buf_t _hash[5];
};
namespace raw {

View file

@ -1,4 +1,5 @@
#pragma once
#include <boost/endian/buffers.hpp>
#include <fc/fwd.hpp>
#include <functional>
@ -64,7 +65,7 @@ class sha1
friend bool operator > ( const sha1& h1, const sha1& h2 );
friend bool operator < ( const sha1& h1, const sha1& h2 );
uint32_t _hash[5];
boost::endian::little_uint32_buf_t _hash[5];
};
namespace raw {

View file

@ -1,5 +1,5 @@
#pragma once
#include <unordered_map>
#include <boost/endian/buffers.hpp>
#include <fc/fwd.hpp>
#include <fc/io/raw_fwd.hpp>
@ -64,9 +64,8 @@ class sha224
friend bool operator >= ( const sha224& h1, const sha224& h2 );
friend bool operator > ( const sha224& h1, const sha224& h2 );
friend bool operator < ( const sha224& h1, const sha224& h2 );
friend std::size_t hash_value( const sha224& v ) { return uint64_t(v._hash[1])<<32 | v._hash[2]; }
uint32_t _hash[7];
boost::endian::little_uint32_buf_t _hash[7];
};
namespace raw {

View file

@ -1,6 +1,7 @@
#pragma once
#include <boost/endian/buffers.hpp>
#include <fc/fwd.hpp>
#include <fc/platform_independence.hpp>
#include <fc/string.hpp>
#include <fc/io/raw_fwd.hpp>
namespace fc
@ -67,34 +68,7 @@ class sha256
friend bool operator > ( const sha256& h1, const sha256& h2 );
friend bool operator < ( const sha256& h1, const sha256& h2 );
uint32_t pop_count()const
{
return (uint32_t)(__builtin_popcountll(_hash[0]) +
__builtin_popcountll(_hash[1]) +
__builtin_popcountll(_hash[2]) +
__builtin_popcountll(_hash[3]));
}
/**
* Count leading zero bits
*/
uint16_t clz()const;
/**
* Approximate (log_2(x) + 1) * 2**24.
*
* Detailed specs:
* - Return 0 when x == 0.
* - High 8 bits of result simply counts nonzero bits.
* - Low 24 bits of result are the 24 bits of input immediately after the most significant 1 in the input.
* - If above would require reading beyond the end of the input, zeros are used instead.
*/
uint32_t approx_log_32()const;
void set_to_inverse_approx_log_32( uint32_t x );
static double inverse_approx_log_32_double( uint32_t x );
uint64_t _hash[4];
boost::endian::little_uint64_buf_t _hash[4];
};
namespace raw {
@ -117,8 +91,6 @@ namespace raw {
void to_variant( const sha256& bi, variant& v, uint32_t max_depth );
void from_variant( const variant& v, sha256& bi, uint32_t max_depth );
uint64_t hash64(const char* buf, size_t len);
} // fc
namespace std
{

View file

@ -1,4 +1,5 @@
#pragma once
#include <boost/endian/buffers.hpp>
#include <fc/fwd.hpp>
namespace fc
@ -62,7 +63,7 @@ class sha512
friend bool operator > ( const sha512& h1, const sha512& h2 );
friend bool operator < ( const sha512& h1, const sha512& h2 );
uint64_t _hash[8];
boost::endian::little_uint64_buf_t _hash[8];
};
namespace raw {

View file

@ -89,94 +89,5 @@ class datastream<size_t> {
size_t _size;
};
template<typename ST>
inline datastream<ST>& operator<<(datastream<ST>& ds, const int32_t& d) {
ds.write( (const char*)&d, sizeof(d) );
return ds;
}
template<typename ST, typename DATA>
inline datastream<ST>& operator>>(datastream<ST>& ds, int32_t& d) {
ds.read((char*)&d, sizeof(d) );
return ds;
}
template<typename ST>
inline datastream<ST>& operator<<(datastream<ST>& ds, const uint32_t& d) {
ds.write( (const char*)&d, sizeof(d) );
return ds;
}
template<typename ST, typename DATA>
inline datastream<ST>& operator>>(datastream<ST>& ds, uint32_t& d) {
ds.read((char*)&d, sizeof(d) );
return ds;
}
template<typename ST>
inline datastream<ST>& operator<<(datastream<ST>& ds, const int64_t& d) {
ds.write( (const char*)&d, sizeof(d) );
return ds;
}
template<typename ST, typename DATA>
inline datastream<ST>& operator>>(datastream<ST>& ds, int64_t& d) {
ds.read((char*)&d, sizeof(d) );
return ds;
}
template<typename ST>
inline datastream<ST>& operator<<(datastream<ST>& ds, const uint64_t& d) {
ds.write( (const char*)&d, sizeof(d) );
return ds;
}
template<typename ST, typename DATA>
inline datastream<ST>& operator>>(datastream<ST>& ds, uint64_t& d) {
ds.read((char*)&d, sizeof(d) );
return ds;
}
template<typename ST>
inline datastream<ST>& operator<<(datastream<ST>& ds, const int16_t& d) {
ds.write( (const char*)&d, sizeof(d) );
return ds;
}
template<typename ST, typename DATA>
inline datastream<ST>& operator>>(datastream<ST>& ds, int16_t& d) {
ds.read((char*)&d, sizeof(d) );
return ds;
}
template<typename ST>
inline datastream<ST>& operator<<(datastream<ST>& ds, const uint16_t& d) {
ds.write( (const char*)&d, sizeof(d) );
return ds;
}
template<typename ST, typename DATA>
inline datastream<ST>& operator>>(datastream<ST>& ds, uint16_t& d) {
ds.read((char*)&d, sizeof(d) );
return ds;
}
template<typename ST>
inline datastream<ST>& operator<<(datastream<ST>& ds, const int8_t& d) {
ds.write( (const char*)&d, sizeof(d) );
return ds;
}
template<typename ST, typename DATA>
inline datastream<ST>& operator>>(datastream<ST>& ds, int8_t& d) {
ds.read((char*)&d, sizeof(d) );
return ds;
}
template<typename ST>
inline datastream<ST>& operator<<(datastream<ST>& ds, const uint8_t& d) {
ds.write( (const char*)&d, sizeof(d) );
return ds;
}
template<typename ST, typename DATA>
inline datastream<ST>& operator>>(datastream<ST>& ds, uint8_t& d) {
ds.read((char*)&d, sizeof(d) );
return ds;
}
} // namespace fc

View file

@ -1,178 +0,0 @@
#pragma once
#include <fc/utility.hpp>
#include <string.h>
#include <stdint.h>
namespace fc {
/**
* The purpose of this datastream is to provide a fast, effecient, means
* of calculating the amount of data "about to be written" and then
* writing it. This means having two modes of operation, "test run" where
* you call the entire pack sequence calculating the size, and then
* actually packing it after doing a single allocation.
*/
template<typename T>
class datastream {
public:
datastream( T start, size_t s )
:_start(start),_pos(start),_end(start+s){};
inline void skip( size_t s ){ _pos += s; }
inline bool read( char* d, size_t s ) {
if( size_t(_end - _pos) >= (size_t)s ) {
memcpy( d, _pos, s );
_pos += s;
return true;
}
detail::throw_datastream_range_error( _end-start, int64_t(-((_end-_pos) - 1)))
return false;
}
inline bool write( const char* d, size_t s ) {
if( _end - _pos >= (int32_t)s ) {
memcpy( _pos, d, s );
_pos += s;
return true;
}
detail::throw_datastream_range_error( _end-start, int64_t(-((_end-_pos) - 1)))
return false;
}
inline bool put(char c) {
if( _pos < _end ) {
*_pos = c;
++_pos;
return true;
}
detail::throw_datastream_range_error( _end-start, int64_t(-((_end-_pos) - 1)))
}
inline bool get( unsigned char& c ) { return get( *(char*)&c ); }
inline bool get( char& c ) {
if( _pos < _end ) {
c = *_pos;
++_pos;
return true;
}
detail::throw_datastream_range_error( _end-start, int64_t(-((_end-_pos) - 1)))
}
T pos()const { return _pos; }
inline bool valid()const { return _pos <= _end && _pos >= _start; }
inline bool seekp(size_t p) { _pos = _start + p; return _pos <= _end; }
inline size_t tellp()const { return _pos - _start; }
inline size_t remaining()const { return _end - _pos; }
private:
T _start;
T _pos;
T _end;
};
template<>
class datastream<size_t> {
public:
datastream( size_t init_size = 0):_size(init_size){};
inline bool skip( size_t s ) { _size += s; return true; }
inline bool write( const char* d,size_t s ) { _size += s; return true; }
inline bool put(char c) { ++_size; return true; }
inline bool valid()const { return true; }
inline bool seekp(size_t p) { _size = p; return true; }
inline size_t tellp()const { return _size; }
inline size_t remaining()const { return 0; }
private:
size_t _size;
};
template<typename ST>
inline datastream<ST>& operator<<(datastream<ST>& ds, const int32_t& d) {
ds.write( (const char*)&d, sizeof(d) );
return ds;
}
template<typename ST, typename DATA>
inline datastream<ST>& operator>>(datastream<ST>& ds, int32_t& d) {
ds.read((char*)&d, sizeof(d) );
return ds;
}
template<typename ST>
inline datastream<ST>& operator<<(datastream<ST>& ds, const uint32_t& d) {
ds.write( (const char*)&d, sizeof(d) );
return ds;
}
template<typename ST, typename DATA>
inline datastream<ST>& operator>>(datastream<ST>& ds, uint32_t& d) {
ds.read((char*)&d, sizeof(d) );
return ds;
}
template<typename ST>
inline datastream<ST>& operator<<(datastream<ST>& ds, const int64_t& d) {
ds.write( (const char*)&d, sizeof(d) );
return ds;
}
template<typename ST, typename DATA>
inline datastream<ST>& operator>>(datastream<ST>& ds, int64_t& d) {
ds.read((char*)&d, sizeof(d) );
return ds;
}
template<typename ST>
inline datastream<ST>& operator<<(datastream<ST>& ds, const uint64_t& d) {
ds.write( (const char*)&d, sizeof(d) );
return ds;
}
template<typename ST, typename DATA>
inline datastream<ST>& operator>>(datastream<ST>& ds, uint64_t& d) {
ds.read((char*)&d, sizeof(d) );
return ds;
}
template<typename ST>
inline datastream<ST>& operator<<(datastream<ST>& ds, const int16_t& d) {
ds.write( (const char*)&d, sizeof(d) );
return ds;
}
template<typename ST, typename DATA>
inline datastream<ST>& operator>>(datastream<ST>& ds, int16_t& d) {
ds.read((char*)&d, sizeof(d) );
return ds;
}
template<typename ST>
inline datastream<ST>& operator<<(datastream<ST>& ds, const uint16_t& d) {
ds.write( (const char*)&d, sizeof(d) );
return ds;
}
template<typename ST, typename DATA>
inline datastream<ST>& operator>>(datastream<ST>& ds, uint16_t& d) {
ds.read((char*)&d, sizeof(d) );
return ds;
}
template<typename ST>
inline datastream<ST>& operator<<(datastream<ST>& ds, const int8_t& d) {
ds.write( (const char*)&d, sizeof(d) );
return ds;
}
template<typename ST, typename DATA>
inline datastream<ST>& operator>>(datastream<ST>& ds, int8_t& d) {
ds.read((char*)&d, sizeof(d) );
return ds;
}
template<typename ST>
inline datastream<ST>& operator<<(datastream<ST>& ds, const uint8_t& d) {
ds.write( (const char*)&d, sizeof(d) );
return ds;
}
template<typename ST, typename DATA>
inline datastream<ST>& operator>>(datastream<ST>& ds, uint8_t& d) {
ds.read((char*)&d, sizeof(d) );
return ds;
}
} // namespace fc

View file

@ -1,4 +1,5 @@
#pragma once
#include <boost/endian/buffers.hpp>
#include <fc/io/raw_variant.hpp>
#include <fc/reflect/reflect.hpp>
#include <fc/io/datastream.hpp>
@ -89,52 +90,62 @@ namespace fc {
template<typename Stream>
inline void pack( Stream& s, const fc::time_point_sec& tp, uint32_t _max_depth )
{
uint32_t usec = tp.sec_since_epoch();
s.write( (const char*)&usec, sizeof(usec) );
pack( s, tp.sec_since_epoch(), _max_depth );
}
template<typename Stream>
inline void unpack( Stream& s, fc::time_point_sec& tp, uint32_t _max_depth )
{ try {
uint32_t sec;
s.read( (char*)&sec, sizeof(sec) );
unpack( s, sec, _max_depth );
tp = fc::time_point() + fc::seconds(sec);
} FC_RETHROW_EXCEPTIONS( warn, "" ) }
template<typename Stream>
inline void pack( Stream& s, const fc::time_point& tp, uint32_t _max_depth )
{
uint64_t usec = tp.time_since_epoch().count();
s.write( (const char*)&usec, sizeof(usec) );
pack( s, tp.time_since_epoch().count(), _max_depth );
}
template<typename Stream>
inline void unpack( Stream& s, fc::time_point& tp, uint32_t _max_depth )
{ try {
uint64_t usec;
s.read( (char*)&usec, sizeof(usec) );
unpack( s, usec, _max_depth );
tp = fc::time_point() + fc::microseconds(usec);
} FC_RETHROW_EXCEPTIONS( warn, "" ) }
template<typename Stream>
inline void pack( Stream& s, const fc::microseconds& usec, uint32_t _max_depth )
{
uint64_t usec_as_int64 = usec.count();
s.write( (const char*)&usec_as_int64, sizeof(usec_as_int64) );
pack( s, usec.count(), _max_depth );
}
template<typename Stream>
inline void unpack( Stream& s, fc::microseconds& usec, uint32_t _max_depth )
{ try {
uint64_t usec_as_int64;
s.read( (char*)&usec_as_int64, sizeof(usec_as_int64) );
unpack( s, usec_as_int64, _max_depth );
usec = fc::microseconds(usec_as_int64);
} FC_RETHROW_EXCEPTIONS( warn, "" ) }
template<typename Stream, typename T, size_t N>
inline void pack( Stream& s, const fc::array<T,N>& v, uint32_t _max_depth ) {
s.write((const char*)&v.data[0],N*sizeof(T));
template<typename Stream, size_t N>
inline void pack( Stream& s, const fc::array<char,N>& v, uint32_t _max_depth ) {
s.write( &v.data[0], N );
}
template<typename Stream, size_t N>
inline void pack( Stream& s, const fc::array<unsigned char,N>& v, uint32_t _max_depth ) {
s.write( (char*)&v.data[0], N );
}
template<typename Stream, size_t N>
inline void unpack( Stream& s, fc::array<char,N>& v, uint32_t _max_depth ) { try {
s.read( &v.data[0], N );
} FC_RETHROW_EXCEPTIONS( warn, "fc::array<char,${length}>", ("length",N) ) }
template<typename Stream, size_t N>
inline void unpack( Stream& s, fc::array<unsigned char,N>& v, uint32_t _max_depth ) { try {
s.read( (char*)&v.data[0], N );
} FC_RETHROW_EXCEPTIONS( warn, "fc::array<unsigned char,${length}>", ("length",N) ) }
template<typename Stream, typename T>
inline void pack( Stream& s, const std::shared_ptr<T>& v, uint32_t _max_depth )
@ -143,26 +154,20 @@ namespace fc {
fc::raw::pack( s, *v, _max_depth - 1 );
}
template<typename Stream, typename T>
inline void pack( Stream& s, const std::shared_ptr<const T>& v, uint32_t _max_depth )
{
FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, *v, _max_depth - 1 );
}
template<typename Stream, typename T, size_t N>
inline void unpack( Stream& s, fc::array<T,N>& v, uint32_t _max_depth )
{ try {
s.read((char*)&v.data[0],N*sizeof(T));
} FC_RETHROW_EXCEPTIONS( warn, "fc::array<type,length>", ("type",fc::get_typename<T>::name())("length",N) ) }
template<typename Stream, typename T>
inline void unpack( Stream& s, std::shared_ptr<T>& v, uint32_t _max_depth )
{ try {
FC_ASSERT( _max_depth > 0 );
v = std::make_shared<T>();
fc::raw::unpack( s, *v, _max_depth - 1 );
} FC_RETHROW_EXCEPTIONS( warn, "std::shared_ptr<T>", ("type",fc::get_typename<T>::name()) ) }
} FC_RETHROW_EXCEPTIONS( warn, "std::shared_ptr<${type}>", ("type",fc::get_typename<T>::name()) ) }
template<typename Stream, typename T>
inline void pack( Stream& s, const std::shared_ptr<const T>& v, uint32_t _max_depth )
{
FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, *v, _max_depth - 1 );
}
template<typename Stream, typename T>
inline void unpack( Stream& s, std::shared_ptr<const T>& v, uint32_t _max_depth )
@ -345,12 +350,96 @@ namespace fc {
template<>
struct if_class<fc::false_type> {
template<typename Stream, typename T>
static inline void pack( Stream& s, const T& v, uint32_t _max_depth ) {
s.write( (char*)&v, sizeof(v) );
}
static inline void pack( Stream& s, const T v, uint32_t _max_depth ) = delete;
template<typename Stream, typename T>
static inline void unpack( Stream& s, T& v, uint32_t _max_depth ) {
s.read( (char*)&v, sizeof(v) );
static inline void unpack( Stream& s, T& v, uint32_t _max_depth ) = delete;
template<typename Stream>
static inline void pack( Stream& s, const int64_t v, uint32_t _max_depth ) {
boost::endian::little_int64_buf_t tmp;
tmp = v;
s.write( (char*)&tmp, sizeof(tmp) );
}
template<typename Stream>
static inline void unpack( Stream& s, int64_t& v, uint32_t _max_depth ) {
boost::endian::little_int64_buf_t tmp;
s.read( (char*)&tmp, sizeof(tmp) );
v = tmp.value();
}
template<typename Stream>
static inline void pack( Stream& s, const uint64_t v, uint32_t _max_depth ) {
boost::endian::little_uint64_buf_t tmp;
tmp = v;
s.write( (char*)&tmp, sizeof(tmp) );
}
template<typename Stream>
static inline void unpack( Stream& s, uint64_t& v, uint32_t _max_depth ) {
boost::endian::little_uint64_buf_t tmp;
s.read( (char*)&tmp, sizeof(tmp) );
v = tmp.value();
}
template<typename Stream>
static inline void pack( Stream& s, const int32_t v, uint32_t _max_depth ) {
boost::endian::little_int32_buf_t tmp;
tmp = v;
s.write( (char*)&tmp, sizeof(tmp) );
}
template<typename Stream>
static inline void unpack( Stream& s, int32_t& v, uint32_t _max_depth ) {
boost::endian::little_int32_buf_t tmp;
s.read( (char*)&tmp, sizeof(tmp) );
v = tmp.value();
}
template<typename Stream>
static inline void pack( Stream& s, const uint32_t v, uint32_t _max_depth ) {
boost::endian::little_uint32_buf_t tmp;
tmp = v;
s.write( (char*)&tmp, sizeof(tmp) );
}
template<typename Stream>
static inline void unpack( Stream& s, uint32_t& v, uint32_t _max_depth ) {
boost::endian::little_uint32_buf_t tmp;
s.read( (char*)&tmp, sizeof(tmp) );
v = tmp.value();
}
template<typename Stream>
static inline void pack( Stream& s, const int16_t v, uint32_t _max_depth ) {
boost::endian::little_int16_buf_t tmp;
tmp = v;
s.write( (char*)&tmp, sizeof(tmp) );
}
template<typename Stream>
static inline void unpack( Stream& s, int16_t& v, uint32_t _max_depth ) {
boost::endian::little_int16_buf_t tmp;
s.read( (char*)&tmp, sizeof(tmp) );
v = tmp.value();
}
template<typename Stream>
static inline void pack( Stream& s, const uint16_t v, uint32_t _max_depth ) {
boost::endian::little_uint16_buf_t tmp;
tmp = v;
s.write( (char*)&tmp, sizeof(tmp) );
}
template<typename Stream>
static inline void unpack( Stream& s, uint16_t& v, uint32_t _max_depth ) {
boost::endian::little_uint16_buf_t tmp;
s.read( (char*)&tmp, sizeof(tmp) );
v = tmp.value();
}
template<typename Stream>
static inline void pack( Stream& s, const int8_t v, uint32_t _max_depth ) {
s.write( (char*)&v, 1 );
}
template<typename Stream>
static inline void unpack( Stream& s, int8_t& v, uint32_t _max_depth ) {
s.read( (char*)&v, 1 );
}
template<typename Stream>
static inline void pack( Stream& s, const uint8_t v, uint32_t _max_depth ) {
s.write( (char*)&v, 1 );
}
template<typename Stream>
static inline void unpack( Stream& s, uint8_t& v, uint32_t _max_depth ) {
s.read( (char*)&v, 1 );
}
};
@ -590,6 +679,18 @@ namespace fc {
}
}
template<typename Stream, boost::endian::order O, class T, std::size_t N, boost::endian::align A>
void pack( Stream& s, const boost::endian::endian_buffer<O,T,N,A>& v, uint32_t _max_depth )
{
FC_ASSERT( _max_depth > 0 );
s.write( v.data(), sizeof(v) );
}
template<typename Stream, boost::endian::order O, class T, std::size_t N, boost::endian::align A>
void unpack( Stream& s, boost::endian::endian_buffer<O,T,N,A>& v, uint32_t _max_depth )
{
FC_ASSERT( _max_depth > 0 );
s.read( v.data(), sizeof(v) );
}
template<typename Stream, typename T>
@ -688,7 +789,6 @@ namespace fc {
FC_ASSERT( _max_depth > 0 );
datastream<const char*> ds( d, s );
fc::raw::unpack( ds, v, _max_depth - 1 );
return v;
} FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) }
template<typename Stream>

View file

@ -1,4 +1,5 @@
#pragma once
#include <boost/endian/buffers.hpp>
#include <fc/config.hpp>
#include <fc/container/flat_fwd.hpp>
#include <fc/io/varint.hpp>
@ -117,9 +118,19 @@ namespace fc {
template<typename Stream> inline void pack( Stream& s, const char* v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream> inline void pack( Stream& s, const std::vector<char>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream> inline void unpack( Stream& s, std::vector<char>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, boost::endian::order O, class T, std::size_t N, boost::endian::align A>
inline void pack( Stream& s, const boost::endian::endian_buffer<O,T,N,A>& v, uint32_t _max_depth );
template<typename Stream, boost::endian::order O, class T, std::size_t N, boost::endian::align A>
inline void unpack( Stream& s, boost::endian::endian_buffer<O,T,N,A>& v, uint32_t _max_depth );
template<typename Stream, typename T, size_t N> inline void pack( Stream& s, const fc::array<T,N>& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, typename T, size_t N> inline void unpack( Stream& s, fc::array<T,N>& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH);
template<typename Stream, typename T, size_t N>
inline void pack( Stream& s, const fc::array<T,N>& v, uint32_t _max_depth ) = delete;
template<typename Stream, typename T, size_t N>
inline void unpack( Stream& s, fc::array<T,N>& v, uint32_t _max_depth ) = delete;
template<typename Stream, size_t N> inline void pack( Stream& s, const fc::array<char,N>& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, size_t N> inline void unpack( Stream& s, fc::array<char,N>& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH);
template<typename Stream, size_t N> inline void pack( Stream& s, const fc::array<unsigned char,N>& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH );
template<typename Stream, size_t N> inline void unpack( Stream& s, fc::array<unsigned char,N>& v, uint32_t _max_depth=FC_PACK_MAX_DEPTH);
template<typename Stream, typename T> inline void pack( Stream& s, const shared_ptr<T>& v,
uint32_t _max_depth=FC_PACK_MAX_DEPTH );

View file

@ -26,7 +26,7 @@ namespace fc { namespace raw {
}
virtual void handle( const double& v )const
{
fc::raw::pack( s, v, max_depth );
FC_THROW_EXCEPTION( invalid_arg_exception, "Can't pack double!" );
}
virtual void handle( const bool& v )const
{
@ -86,10 +86,7 @@ namespace fc { namespace raw {
}
case variant::double_type:
{
double val;
raw::unpack( s, val, _max_depth );
v = val;
return;
FC_THROW_EXCEPTION( invalid_arg_exception, "Can't unpack double!" );
}
case variant::bool_type:
{

View file

@ -32,6 +32,10 @@ namespace fc {
uint64_t to_uint64()const;
template<typename Stream>
inline void pack( Stream& s, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) {
pack( s, fixed, _max_depth );
}
private:
uint128 fixed;
};
@ -43,13 +47,15 @@ namespace fc {
{
template<typename Stream>
inline void pack( Stream& s, const real128& value_to_pack, uint32_t _max_depth=FC_PACK_MAX_DEPTH )
{ s.write( (char*)&value_to_pack, sizeof(value_to_pack) ); }
{ value_to_pack.pack( s, _max_depth ); }
template<typename Stream>
inline void unpack( Stream& s, real128& value_to_unpack, uint32_t _max_depth=FC_PACK_MAX_DEPTH )
{ s.read( (char*)&value_to_unpack, sizeof(value_to_unpack) ); }
{
uint128_t delegate;
unpack( s, delegate, _max_depth );
value_to_unpack = fc::real128::from_fixed( delegate );
}
}
} // namespace fc

View file

@ -6,6 +6,7 @@
#include <fc/config.hpp>
#include <fc/exception/exception.hpp>
#include <fc/crypto/city.hpp>
#include <fc/io/raw.hpp>
#ifdef _MSC_VER
#pragma warning (push)
@ -127,9 +128,15 @@ namespace fc
namespace raw
{
template<typename Stream>
inline void pack( Stream& s, const uint128& u, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) { s.write( (char*)&u, sizeof(u) ); }
inline void pack( Stream& s, const uint128& u, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) {
pack( s, u.hi, _max_depth );
pack( s, u.lo, _max_depth );
}
template<typename Stream>
inline void unpack( Stream& s, uint128& u, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) { s.read( (char*)&u, sizeof(u) ); }
inline void unpack( Stream& s, uint128& u, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) {
unpack( s, u.hi, _max_depth );
unpack( s, u.lo, _max_depth );
}
}
size_t city_hash_size_t(const char *buf, size_t len);
@ -140,10 +147,7 @@ namespace std
template<>
struct hash<fc::uint128>
{
size_t operator()( const fc::uint128& s )const
{
return fc::city_hash_size_t((char*)&s, sizeof(s));
}
size_t operator()( const fc::uint128& s )const;
};
}

View file

@ -12,6 +12,7 @@
#include <fc/optional.hpp>
#include <fc/container/flat_fwd.hpp>
#include <boost/endian/buffers.hpp>
#include <boost/multi_index_container_fwd.hpp>
#ifdef FC_ASSERT
@ -165,6 +166,19 @@ namespace fc
template<typename A, typename B>
void from_variant( const variant& v, std::pair<A,B>& p, uint32_t max_depth );
template<boost::endian::order O, class T, std::size_t N, boost::endian::align A>
void to_variant( const boost::endian::endian_buffer<O,T,N,A>& var, variant& vo, uint32_t max_depth )
{
to_variant( var.value(), vo, max_depth );
}
template<boost::endian::order O, class T, std::size_t N, boost::endian::align A>
void from_variant( const variant& var, boost::endian::endian_buffer<O,T,N,A>& vo, uint32_t max_depth )
{
T tmp;
from_variant( var, tmp, max_depth );
vo = tmp;
}
/**
* @brief stores null, int64, uint64, double, bool, string, std::vector<variant>,
* and variant_object's.

View file

@ -1,11 +0,0 @@
#pragma once
#ifdef _WIN32
# include <stdlib.h>
# define bswap_64(x) _byteswap_uint64(x)
#elif defined(__APPLE__)
# include <libkern/OSByteOrder.h>
# define bswap_64(x) OSSwapInt64(x)
#else
# include <byteswap.h>
#endif

View file

@ -9,6 +9,7 @@
#include <fc/log/logger.hpp>
#include <fc/thread/thread.hpp>
#include <boost/endian/buffers.hpp>
#include <boost/thread/mutex.hpp>
#include <openssl/opensslconf.h>
#ifndef OPENSSL_THREADS
@ -52,7 +53,10 @@ void aes_encoder::init( const fc::sha256& key, const fc::uint128& init_value )
* In this example we are using 256 bit AES (i.e. a 256 bit key). The
* IV size for *most* modes is the same as the block size. For AES this
* is 128 bits */
if(1 != EVP_EncryptInit_ex(my->ctx, EVP_aes_256_cbc(), NULL, (unsigned char*)&key, (unsigned char*)&init_value))
boost::endian::little_uint64_buf_t iv[2];
iv[0] = init_value.hi;
iv[1] = init_value.lo;
if(1 != EVP_EncryptInit_ex(my->ctx, EVP_aes_256_cbc(), NULL, (unsigned char*)&key, (const unsigned char*)iv[0].data()))
{
FC_THROW_EXCEPTION( aes_exception, "error during aes 256 cbc encryption init",
("s", ERR_error_string( ERR_get_error(), nullptr) ) );
@ -117,7 +121,10 @@ void aes_decoder::init( const fc::sha256& key, const fc::uint128& init_value )
* In this example we are using 256 bit AES (i.e. a 256 bit key). The
* IV size for *most* modes is the same as the block size. For AES this
* is 128 bits */
if(1 != EVP_DecryptInit_ex(my->ctx, EVP_aes_256_cbc(), NULL, (unsigned char*)&key, (unsigned char*)&init_value))
boost::endian::little_uint64_buf_t iv[2];
iv[0] = init_value.hi;
iv[1] = init_value.lo;
if(1 != EVP_DecryptInit_ex(my->ctx, EVP_aes_256_cbc(), NULL, (unsigned char*)&key, (const unsigned char*)iv[0].data()))
{
FC_THROW_EXCEPTION( aes_exception, "error during aes 256 cbc encryption init",
("s", ERR_error_string( ERR_get_error(), nullptr) ) );

View file

@ -4,7 +4,8 @@
#include <fc/crypto/base64.hpp>
#include <fc/exception/exception.hpp>
#include "../byteswap.hpp"
#include <boost/endian/buffers.hpp>
namespace fc {
bigint::bigint( const char* bige, uint32_t l ) {
@ -30,7 +31,8 @@ namespace fc {
bigint::bigint(uint64_t value)
{
uint64_t big_endian_value = bswap_64(value);
boost::endian::big_uint64_buf_t big_endian_value;
big_endian_value = value;
n = BN_bin2bn((const unsigned char*)&big_endian_value, sizeof(big_endian_value), NULL);
}
@ -53,9 +55,10 @@ namespace fc {
{
FC_ASSERT(BN_num_bits(n) <= 63);
size_t size = BN_num_bytes(n);
uint64_t abs_value = 0;
BN_bn2bin(n, (unsigned char*)&abs_value + (sizeof(uint64_t) - size));
return BN_is_negative(n) ? -(int64_t)bswap_64(abs_value) : bswap_64(abs_value);
boost::endian::big_int64_buf_t abs_value;
abs_value = 0;
BN_bn2bin(n, (unsigned char*)&abs_value + (sizeof(abs_value) - size));
return BN_is_negative(n) ? -abs_value.value() : abs_value.value();
}
int64_t bigint::log2()const { return BN_num_bits(n); }

View file

@ -35,6 +35,7 @@
#include <fc/crypto/city.hpp>
#include <fc/uint128.hpp>
#include <fc/array.hpp>
#include <boost/endian/buffers.hpp>
#if defined(__SSE4_2__) && defined(__x86_64__)
#include <nmmintrin.h>
@ -63,18 +64,6 @@ inline uint64_t Hash128to64(const uint128& x) {
return b;
}
static uint64_t UNALIGNED_LOAD64(const char *p) {
uint64_t result;
memcpy(&result, p, sizeof(result));
return result;
}
static uint32_t UNALIGNED_LOAD32(const char *p) {
uint32_t result;
memcpy(&result, p, sizeof(result));
return result;
}
#ifdef _WIN32
#include <stdlib.h>
@ -121,14 +110,6 @@ static uint32_t UNALIGNED_LOAD32(const char *p) {
#endif
#ifdef WORDS_BIGENDIAN
#define uint32_in_expected_order(x) (bswap_32(x))
#define uint64_in_expected_order(x) (bswap_64(x))
#else
#define uint32_in_expected_order(x) (x)
#define uint64_in_expected_order(x) (x)
#endif
#if !defined(LIKELY)
#if HAVE_BUILTIN_EXPECT
#define LIKELY(x) (__builtin_expect(!!(x), 1))
@ -138,11 +119,15 @@ static uint32_t UNALIGNED_LOAD32(const char *p) {
#endif
static uint64_t Fetch64(const char *p) {
return uint64_in_expected_order(UNALIGNED_LOAD64(p));
boost::endian::little_uint64_buf_t result;
memcpy(&result, p, sizeof(result));
return result.value();
}
static uint32_t Fetch32(const char *p) {
return uint32_in_expected_order(UNALIGNED_LOAD32(p));
boost::endian::little_uint32_buf_t result;
memcpy(&result, p, sizeof(result));
return result.value();
}
// Some primes between 2^63 and 2^64 for various uses.

View file

@ -139,11 +139,11 @@ namespace fc { namespace ecc {
std::string public_key::to_base58( const public_key_data &key )
{
uint32_t check = (uint32_t)sha256::hash(key.data, sizeof(key))._hash[0];
static_assert(sizeof(key) + sizeof(check) == 37, "Elliptic public key size (or its hash) is incorrect");
sha256 check = sha256::hash(key.data, sizeof(key));
static_assert(sizeof(key) + 4 == 37, "Elliptic public key size (or its hash) is incorrect");
array<char, 37> data;
memcpy(data.data, key.begin(), key.size());
memcpy(data.begin() + key.size(), (const char*)&check, sizeof(check));
memcpy(data.begin() + key.size(), (const char*)check._hash, 4);
return fc::to_base58(data.begin(), data.size());
}
@ -154,8 +154,8 @@ namespace fc { namespace ecc {
FC_ASSERT( s == sizeof(data) );
public_key_data key;
uint32_t check = (uint32_t)sha256::hash(data.data, sizeof(key))._hash[0];
FC_ASSERT( memcmp( (char*)&check, data.data + sizeof(key), sizeof(check) ) == 0 );
sha256 check = sha256::hash(data.data, sizeof(key));
FC_ASSERT( memcmp( (char*)check._hash, data.data + sizeof(key), 4 ) == 0 );
memcpy( (char*)key.data, data.data, sizeof(key) );
return from_key_data(key);
}

View file

@ -76,11 +76,11 @@ ripemd160 operator << ( const ripemd160& h1, uint32_t i ) {
}
ripemd160 operator ^ ( const ripemd160& h1, const ripemd160& h2 ) {
ripemd160 result;
result._hash[0] = h1._hash[0] ^ h2._hash[0];
result._hash[1] = h1._hash[1] ^ h2._hash[1];
result._hash[2] = h1._hash[2] ^ h2._hash[2];
result._hash[3] = h1._hash[3] ^ h2._hash[3];
result._hash[4] = h1._hash[4] ^ h2._hash[4];
result._hash[0] = h1._hash[0].value() ^ h2._hash[0].value();
result._hash[1] = h1._hash[1].value() ^ h2._hash[1].value();
result._hash[2] = h1._hash[2].value() ^ h2._hash[2].value();
result._hash[3] = h1._hash[3].value() ^ h2._hash[3].value();
result._hash[4] = h1._hash[4].value() ^ h2._hash[4].value();
return result;
}
bool operator >= ( const ripemd160& h1, const ripemd160& h2 ) {

View file

@ -60,11 +60,11 @@ sha1 operator << ( const sha1& h1, uint32_t i ) {
}
sha1 operator ^ ( const sha1& h1, const sha1& h2 ) {
sha1 result;
result._hash[0] = h1._hash[0] ^ h2._hash[0];
result._hash[1] = h1._hash[1] ^ h2._hash[1];
result._hash[2] = h1._hash[2] ^ h2._hash[2];
result._hash[3] = h1._hash[3] ^ h2._hash[3];
result._hash[4] = h1._hash[4] ^ h2._hash[4];
result._hash[0] = h1._hash[0].value() ^ h2._hash[0].value();
result._hash[1] = h1._hash[1].value() ^ h2._hash[1].value();
result._hash[2] = h1._hash[2].value() ^ h2._hash[2].value();
result._hash[3] = h1._hash[3].value() ^ h2._hash[3].value();
result._hash[4] = h1._hash[4].value() ^ h2._hash[4].value();
return result;
}
bool operator >= ( const sha1& h1, const sha1& h2 ) {

View file

@ -60,7 +60,7 @@ namespace fc {
sha224 operator ^ ( const sha224& h1, const sha224& h2 ) {
sha224 result;
for( uint32_t i = 0; i < 7; ++i )
result._hash[i] = h1._hash[i] ^ h2._hash[i];
result._hash[i] = h1._hash[i].value() ^ h2._hash[i].value();
return result;
}
bool operator >= ( const sha224& h1, const sha224& h2 ) {

View file

@ -77,10 +77,10 @@ namespace fc {
}
sha256 operator ^ ( const sha256& h1, const sha256& h2 ) {
sha256 result;
result._hash[0] = h1._hash[0] ^ h2._hash[0];
result._hash[1] = h1._hash[1] ^ h2._hash[1];
result._hash[2] = h1._hash[2] ^ h2._hash[2];
result._hash[3] = h1._hash[3] ^ h2._hash[3];
result._hash[0] = h1._hash[0].value() ^ h2._hash[0].value();
result._hash[1] = h1._hash[1].value() ^ h2._hash[1].value();
result._hash[2] = h1._hash[2].value() ^ h2._hash[2].value();
result._hash[3] = h1._hash[3].value() ^ h2._hash[3].value();
return result;
}
bool operator >= ( const sha256& h1, const sha256& h2 ) {
@ -99,100 +99,6 @@ namespace fc {
return memcmp( h1._hash, h2._hash, sizeof(h1._hash) ) == 0;
}
uint32_t sha256::approx_log_32()const
{
uint16_t lzbits = clz();
if( lzbits >= 0x100 )
return 0;
uint8_t nzbits = 0xFF-lzbits;
size_t offset = (size_t) (lzbits >> 3);
uint8_t* my_bytes = (uint8_t*) data();
size_t n = data_size();
uint32_t y = (uint32_t( my_bytes[offset ] ) << 0x18)
| (uint32_t(offset+1 < n ? my_bytes[offset+1] : 0) << 0x10)
| (uint32_t(offset+2 < n ? my_bytes[offset+2] : 0) << 0x08)
| (uint32_t(offset+3 < n ? my_bytes[offset+3] : 0) )
;
//
// lzbits&7 == 7 : 00000001 iff nzbits&7 == 0
// lzbits&7 == 6 : 0000001x iff nzbits&7 == 1
// lzbits&7 == 5 : 000001xx iff nzbits&7 == 2
//
y >>= (nzbits & 7);
y ^= 1 << 0x18;
y |= uint32_t( nzbits ) << 0x18;
return y;
}
void sha256::set_to_inverse_approx_log_32( uint32_t x )
{
uint8_t nzbits = uint8_t( x >> 0x18 );
_hash[0] = 0;
_hash[1] = 0;
_hash[2] = 0;
_hash[3] = 0;
if( nzbits == 0 )
return;
uint8_t x0 = uint8_t((x ) & 0xFF);
uint8_t x1 = uint8_t((x >> 0x08) & 0xFF);
uint8_t x2 = uint8_t((x >> 0x10) & 0xFF);
uint8_t* my_bytes = (uint8_t*) data();
my_bytes[0x1F] = x0;
my_bytes[0x1E] = x1;
my_bytes[0x1D] = x2;
my_bytes[0x1C] = 1;
if( nzbits <= 0x18 )
{
(*this) = (*this) >> (0x18 - nzbits);
}
else
(*this) = (*this) << (nzbits - 0x18);
}
double sha256::inverse_approx_log_32_double( uint32_t x )
{
uint8_t nzbits = uint8_t( x >> 0x18 );
if( nzbits == 0 )
return 0.0;
uint32_t b = 1 << 0x18;
uint32_t y = (x & (b-1)) | b;
return std::ldexp( y, int( nzbits ) - 0x18 );
}
uint16_t sha256::clz()const
{
const uint8_t* my_bytes = (uint8_t*) data();
size_t size = data_size();
size_t lzbits = 0;
static const uint8_t char2lzbits[] = {
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
size_t i = 0;
while( true )
{
uint8_t c = my_bytes[i];
lzbits += char2lzbits[c];
if( c != 0 )
break;
++i;
if( i >= size )
return 0x100;
}
return lzbits;
}
void to_variant( const sha256& bi, variant& v, uint32_t max_depth )
{
to_variant( std::vector<char>( (const char*)&bi, ((const char*)&bi) + sizeof(bi) ), v, max_depth );
@ -205,12 +111,6 @@ namespace fc {
memcpy( &bi, ve.data(), std::min<size_t>(ve.size(),sizeof(bi)) );
}
uint64_t hash64(const char* buf, size_t len)
{
sha256 sha_value = sha256::hash(buf,len);
return sha_value._hash[0];
}
template<>
unsigned int hmac<sha256>::internal_block_size() const { return 64; }
} //end namespace fc

View file

@ -59,14 +59,14 @@ namespace fc {
}
sha512 operator ^ ( const sha512& h1, const sha512& h2 ) {
sha512 result;
result._hash[0] = h1._hash[0] ^ h2._hash[0];
result._hash[1] = h1._hash[1] ^ h2._hash[1];
result._hash[2] = h1._hash[2] ^ h2._hash[2];
result._hash[3] = h1._hash[3] ^ h2._hash[3];
result._hash[4] = h1._hash[4] ^ h2._hash[4];
result._hash[5] = h1._hash[5] ^ h2._hash[5];
result._hash[6] = h1._hash[6] ^ h2._hash[6];
result._hash[7] = h1._hash[7] ^ h2._hash[7];
result._hash[0] = h1._hash[0].value() ^ h2._hash[0].value();
result._hash[1] = h1._hash[1].value() ^ h2._hash[1].value();
result._hash[2] = h1._hash[2].value() ^ h2._hash[2].value();
result._hash[3] = h1._hash[3].value() ^ h2._hash[3].value();
result._hash[4] = h1._hash[4].value() ^ h2._hash[4].value();
result._hash[5] = h1._hash[5].value() ^ h2._hash[5].value();
result._hash[6] = h1._hash[6].value() ^ h2._hash[6].value();
result._hash[7] = h1._hash[7].value() ^ h2._hash[7].value();
return result;
}
bool operator >= ( const sha512& h1, const sha512& h2 ) {

View file

@ -264,67 +264,6 @@ namespace fc {
return o;
}
istream& operator>>( istream& o, double& v )
{
assert(false && "not implemented");
return o;
}
istream& operator>>( istream& o, float& v )
{
assert(false && "not implemented");
return o;
}
istream& operator>>( istream& o, int64_t& v )
{
assert(false && "not implemented");
return o;
}
istream& operator>>( istream& o, uint64_t& v )
{
assert(false && "not implemented");
return o;
}
istream& operator>>( istream& o, int32_t& v )
{
assert(false && "not implemented");
return o;
}
istream& operator>>( istream& o, uint32_t& v )
{
assert(false && "not implemented");
return o;
}
istream& operator>>( istream& o, int16_t& v )
{
assert(false && "not implemented");
return o;
}
istream& operator>>( istream& o, uint16_t& v )
{
assert(false && "not implemented");
return o;
}
istream& operator>>( istream& o, int8_t& v )
{
assert(false && "not implemented");
return o;
}
istream& operator>>( istream& o, uint8_t& v )
{
assert(false && "not implemented");
return o;
}
char istream::get()
{
char tmp;

View file

@ -76,31 +76,6 @@ namespace fc {
void stringstream::close(){ my->ss.flush(); };
void stringstream::flush(){ my->ss.flush(); };
/*
istream& stringstream::read( char* buf, size_t len ) {
my->ss.read(buf,len);
return *this;
}
istream& stringstream::read( int64_t& v ) { my->ss >> v; return *this; }
istream& stringstream::read( uint64_t& v ) { my->ss >> v; return *this; }
istream& stringstream::read( int32_t& v ) { my->ss >> v; return *this; }
istream& stringstream::read( uint32_t& v ) { my->ss >> v; return *this; }
istream& stringstream::read( int16_t& v ) { my->ss >> v; return *this; }
istream& stringstream::read( uint16_t& v ) { my->ss >> v; return *this; }
istream& stringstream::read( int8_t& v ) { my->ss >> v; return *this; }
istream& stringstream::read( uint8_t& v ) { my->ss >> v; return *this; }
istream& stringstream::read( float& v ) { my->ss >> v; return *this; }
istream& stringstream::read( double& v ) { my->ss >> v; return *this; }
istream& stringstream::read( bool& v ) { my->ss >> v; return *this; }
istream& stringstream::read( char& v ) { my->ss >> v; return *this; }
istream& stringstream::read( std::string& v ) { my->ss >> *reinterpret_cast<std::string*>(&v); return *this; }
ostream& stringstream::write( const std::string& s) {
my->ss.write( s.c_str(), s.size() );
return *this;
}
*/
char stringstream::peek()
{
char c = my->ss.peek();

View file

@ -1,10 +1,10 @@
#include <fc/uint128.hpp>
#include <fc/variant.hpp>
#include <fc/crypto/bigint.hpp>
#include <boost/endian/buffers.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <stdexcept>
#include "byteswap.hpp"
namespace fc
{
@ -119,7 +119,9 @@ namespace fc
uint128::operator bigint()const
{
auto tmp = uint128( bswap_64( hi ), bswap_64( lo ) );
boost::endian::big_uint64_buf_t tmp[2];
tmp[0] = hi;
tmp[1] = lo;
bigint bi( (char*)&tmp, sizeof(tmp) );
return bi;
}
@ -367,6 +369,15 @@ namespace fc
} // namespace fc
namespace std {
size_t hash<fc::uint128>::operator()( const fc::uint128& s )const
{
boost::endian::little_uint64_buf_t tmp[2];
tmp[0] = s.hi;
tmp[1] = s.lo;
return fc::city_hash_size_t((char*)&tmp, sizeof(tmp));
}
}
/*
* Portions of the above code were adapted from the work of Evan Teran.

View file

@ -23,9 +23,6 @@ target_link_libraries( hmac_test fc )
add_executable( ecc_test crypto/ecc_test.cpp )
target_link_libraries( ecc_test fc )
add_executable( log_test crypto/log_test.cpp )
target_link_libraries( log_test fc )
#add_executable( test_aes aes_test.cpp )
#target_link_libraries( test_aes fc ${rt_library} ${pthread_library} )
#add_executable( test_sleep sleep.cpp )

View file

@ -59,15 +59,7 @@ BOOST_AUTO_TEST_CASE(bloom_test_1)
++count;
}
}
// wdump((filter));
auto packed_filter = fc::raw::pack(filter);
// wdump((packed_filter.size()));
// wdump((packed_filter));
std::stringstream out;
// std::string str = fc::json::to_string(packed_filter);
auto b64 = fc::base64_encode( packed_filter.data(), packed_filter.size() );
for( uint32_t i = 0; i < b64.size(); i += 1024 )
out << '"' << b64.substr( i, 1024 ) << "\",\n";
// FIXME: this doesn't really test anything.
}
catch ( const fc::exception& e )
{

View file

@ -1,114 +0,0 @@
#include <boost/multiprecision/cpp_int.hpp>
#include <fc/crypto/sha256.hpp>
#include <fc/exception/exception.hpp>
#include <fstream>
#include <iomanip>
#include <iostream>
uint64_t endian_reverse( uint64_t x )
{
uint64_t x0 = ((x ) & 0xFF);
uint64_t x1 = ((x >> 0x08) & 0xFF);
uint64_t x2 = ((x >> 0x10) & 0xFF);
uint64_t x3 = ((x >> 0x18) & 0xFF);
uint64_t x4 = ((x >> 0x20) & 0xFF);
uint64_t x5 = ((x >> 0x28) & 0xFF);
uint64_t x6 = ((x >> 0x30) & 0xFF);
uint64_t x7 = ((x >> 0x38) & 0xFF);
return (x0 << 0x38)
| (x1 << 0x30)
| (x2 << 0x28)
| (x3 << 0x20)
| (x4 << 0x18)
| (x5 << 0x10)
| (x6 << 0x08)
| (x7 );
}
int main(int argc, char**argv, char** envp)
{
std::ifstream infile("log_test.txt");
uint32_t ref_clz;
std::string str_h;
uint32_t ref_log;
uint32_t cases = 0;
uint32_t errors = 0;
while( true )
{
if( !(infile >> std::hex >> ref_clz) )
break;
if( !(infile >> str_h) )
break;
if( !(infile >> std::hex >> ref_log) )
break;
fc::sha256 h(str_h);
if( ref_clz != h.clz() )
{
std::cerr << "got error on clz(" << str_h << ")" << std::endl;
++errors;
}
if( ref_log != h.approx_log_32() )
{
std::cerr << "got error on log(" << str_h << ")" << std::endl;
++errors;
}
double d_ilog_h_test = h.inverse_approx_log_32_double( ref_log );
h.set_to_inverse_approx_log_32( ref_log );
if( ref_log != h.approx_log_32() )
{
std::cerr << "got error on ilog(" << ref_log << ")" << std::endl;
++errors;
}
std::string str_ilog_h = h.str();
boost::multiprecision::uint256_t u256_ilog_h( "0x" + str_ilog_h );
double d_ilog_h_ref = u256_ilog_h.template convert_to<double>();
if( d_ilog_h_ref != d_ilog_h_test )
{
std::cerr << "got error on d_ilog(" << ref_log << ")" << std::endl;
++errors;
}
if( h != fc::sha256() )
{
fc::sha256 h_before = h;
if( h._hash[3] == 0 )
{
if( h._hash[2] == 0 )
{
if( h._hash[1] == 0 )
{
h._hash[0] = endian_reverse( endian_reverse( h._hash[0] )-1 );
}
h._hash[1] = endian_reverse( endian_reverse( h._hash[1] )-1 );
}
h._hash[2] = endian_reverse( endian_reverse( h._hash[2] )-1 );
}
h._hash[3] = endian_reverse( endian_reverse( h._hash[3] )-1 );
bool ok = (h.approx_log_32() < ref_log);
if( !ok )
{
std::cerr << "got error on logm1 for " << ref_log << std::endl;
std::cerr << "h0:" << str_h << std::endl;
std::cerr << "h1:" << h_before.str() << std::endl;
std::cerr << "h2:" << h.str() << std::endl;
std::cerr << "ref_log:" << std::hex << std::setw(8) << ref_log << std::endl;
std::cerr << "log(h) :" << std::hex << std::setw(8) << h.approx_log_32() << std::endl;
std::cerr << std::endl;
++errors;
}
}
++cases;
}
std::cerr << "sha256_log_test checked " << cases << " cases, got " << errors << " errors" << std::endl;
if( errors )
return 1;
return 0;
}

View file

@ -1,29 +0,0 @@
#!/usr/bin/env python3
# Independent implementation of algorithm
# To create log_test.txt, run ./log_test.py > log_test.txt
import random
rand = random.Random(1234)
result = set()
result.add((0, 256))
result.add(((1 << 256)-1, 0))
for i in range(256):
y = (1 << i)
result.add((y, 255-i))
for j in range(32):
result.add((y+rand.randrange(0, y), 255-i))
def get_sem_32(y):
bs = "{:0256b}".format(y)
if "1" not in bs:
return 0
bs += 32*"0"
i = bs.index("1")
return ((255-i) << 24) | int(bs[i+1:i+25], 2)
for y, lz in sorted(result):
print("{:02x}".format(lz), "{:064x}".format(y), "{:08x}".format(get_sem_32(y)))