From 94f77ffc8521bca352f93c1e9d9b3248ee82eb8a Mon Sep 17 00:00:00 2001 From: John Jones Date: Tue, 23 Jul 2019 17:14:01 -0500 Subject: [PATCH 01/13] Add hash160 md algo --- CMakeLists.txt | 1 + include/fc/crypto/hash160.hpp | 134 ++++++++++++++++++++++++++++++++ src/crypto/hash160.cpp | 140 ++++++++++++++++++++++++++++++++++ 3 files changed, 275 insertions(+) create mode 100644 include/fc/crypto/hash160.hpp create mode 100644 src/crypto/hash160.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 1d28877..f923083 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -247,6 +247,7 @@ set( fc_sources src/crypto/hex.cpp src/crypto/sha1.cpp src/crypto/ripemd160.cpp + src/crypto/hash160.cpp src/crypto/sha256.cpp src/crypto/sha224.cpp src/crypto/sha512.cpp diff --git a/include/fc/crypto/hash160.hpp b/include/fc/crypto/hash160.hpp new file mode 100644 index 0000000..3b59ded --- /dev/null +++ b/include/fc/crypto/hash160.hpp @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2018 jmjatlanta and contributors. + * + * The MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#pragma once +#include +#include +#include +#include + +namespace fc{ +class sha512; +class sha256; +class ripemd160; + +class hash160 +{ + public: + hash160(); + explicit hash160( const string& hex_str ); + + string str()const; + explicit operator string()const; + + char* data() const; + size_t data_size() const { return 160/8; } + + static hash160 hash( const char* d, uint32_t dlen ); + static hash160 hash( const string& ); + + template + static hash160 hash( const T& t ) + { + hash160::encoder e; + fc::raw::pack(e,t); + return e.result(); + } + + class encoder + { + public: + encoder(); + ~encoder(); + + void write( const char* d, uint32_t dlen ); + void put( char c ) { write( &c, 1 ); } + void reset(); + hash160 result(); + + private: + class impl; + fc::fwd my; + std::vector bytes; + }; + + template + inline friend T& operator<<( T& ds, const hash160& ep ) { + ds.write( ep.data(), sizeof(ep) ); + return ds; + } + + template + inline friend T& operator>>( T& ds, hash160& ep ) { + ds.read( ep.data(), sizeof(ep) ); + return ds; + } + friend hash160 operator << ( const hash160& h1, uint32_t i ); + friend bool operator == ( const hash160& h1, const hash160& h2 ); + friend bool operator != ( const hash160& h1, const hash160& h2 ); + friend hash160 operator ^ ( const hash160& h1, const hash160& h2 ); + friend bool operator >= ( const hash160& h1, const hash160& h2 ); + friend bool operator > ( const hash160& h1, const hash160& h2 ); + friend bool operator < ( const hash160& h1, const hash160& h2 ); + + boost::endian::little_uint32_buf_t _hash[5]; +}; + +namespace raw { + + template + inline void pack( T& ds, const hash160& ep, uint32_t _max_depth ) { + ds << ep; + } + + template + inline void unpack( T& ds, hash160& ep, uint32_t _max_depth ) { + ds >> ep; + } + +} + + class variant; + void to_variant( const hash160& bi, variant& v, uint32_t max_depth ); + void from_variant( const variant& v, hash160& bi, uint32_t max_depth ); + + /* + typedef hash160 uint160_t; + typedef hash160 uint160; + + template<> struct get_typename { static const char* name() { return "uint160_t"; } }; + */ + template<> struct get_typename { static const char* name() { return "hash160"; } }; +} // namespace fc + +namespace std +{ + template<> + struct hash + { + size_t operator()( const fc::hash160& s )const + { + return *((size_t*)&s); + } + }; +} diff --git a/src/crypto/hash160.cpp b/src/crypto/hash160.cpp new file mode 100644 index 0000000..ab131e5 --- /dev/null +++ b/src/crypto/hash160.cpp @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2018 jmjatlanta and contributors. + * + * The MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "_digest_common.hpp" + +namespace fc +{ + +hash160::hash160() { memset( _hash, 0, sizeof(_hash) ); } + +hash160::hash160( const string& hex_str ) { + fc::from_hex( hex_str, (char*)_hash, sizeof(_hash) ); +} + +string hash160::str()const { + return fc::to_hex( (char*)_hash, sizeof(_hash) ); +} + +hash160::operator string()const { return str(); } + +char* hash160::data()const { return (char*)&_hash[0]; } + + +class hash160::encoder::impl { +public: + impl() + { + } + +}; + +hash160::encoder::~encoder() {} +hash160::encoder::encoder() {} + +hash160 hash160::hash( const char* d, uint32_t dlen ) { + encoder e; + e.write(d,dlen); + return e.result(); +} +hash160 hash160::hash( const string& s ) { + return hash( s.c_str(), s.size() ); +} + +void hash160::encoder::write( const char* d, uint32_t dlen ) +{ + for(uint32_t i = 0; i < dlen; ++i) + bytes.push_back(d[i]); +} + +hash160 hash160::encoder::result() { + // perform the first hashing function + SHA256_CTX sha_ctx; + SHA256_Init(&sha_ctx); + SHA256_Update( &sha_ctx, bytes.data(), bytes.size()); + unsigned char sha_hash[SHA256_DIGEST_LENGTH]; + SHA256_Final( sha_hash, &sha_ctx ); + // perform the second hashing function + RIPEMD160_CTX ripe_ctx; + RIPEMD160_Init(&ripe_ctx); + RIPEMD160_Update( &ripe_ctx, sha_hash, SHA256_DIGEST_LENGTH ); + hash160 h; + RIPEMD160_Final( (uint8_t *)h.data(), &ripe_ctx ); + return h; +} + +hash160 operator << ( const hash160& h1, uint32_t i ) { + hash160 result; + fc::detail::shift_l( h1.data(), result.data(), result.data_size(), i ); + return result; +} +hash160 operator ^ ( const hash160& h1, const hash160& h2 ) { + hash160 result; + 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 hash160& h1, const hash160& h2 ) { + return memcmp( h1._hash, h2._hash, sizeof(h1._hash) ) >= 0; +} +bool operator > ( const hash160& h1, const hash160& h2 ) { + return memcmp( h1._hash, h2._hash, sizeof(h1._hash) ) > 0; +} +bool operator < ( const hash160& h1, const hash160& h2 ) { + return memcmp( h1._hash, h2._hash, sizeof(h1._hash) ) < 0; +} +bool operator != ( const hash160& h1, const hash160& h2 ) { + return memcmp( h1._hash, h2._hash, sizeof(h1._hash) ) != 0; +} +bool operator == ( const hash160& h1, const hash160& h2 ) { + return memcmp( h1._hash, h2._hash, sizeof(h1._hash) ) == 0; +} + + void to_variant( const hash160& bi, variant& v, uint32_t max_depth ) + { + to_variant( std::vector( (const char*)&bi, ((const char*)&bi) + sizeof(bi) ), v, max_depth ); + } + void from_variant( const variant& v, hash160& bi, uint32_t max_depth ) + { + std::vector ve = v.as< std::vector >( max_depth ); + memset( &bi, char(0), sizeof(bi) ); + if( ve.size() ) + memcpy( &bi, ve.data(), std::min(ve.size(),sizeof(bi)) ); + } + +} // fc From ea9128257cca8f951cc9de0c346ecfbbcdf4668f Mon Sep 17 00:00:00 2001 From: John Jones Date: Tue, 23 Jul 2019 17:25:02 -0500 Subject: [PATCH 02/13] Remove unnecessary predeclarations --- include/fc/crypto/hash160.hpp | 9 --------- src/crypto/hash160.cpp | 3 --- 2 files changed, 12 deletions(-) diff --git a/include/fc/crypto/hash160.hpp b/include/fc/crypto/hash160.hpp index 3b59ded..75604f8 100644 --- a/include/fc/crypto/hash160.hpp +++ b/include/fc/crypto/hash160.hpp @@ -28,9 +28,6 @@ #include namespace fc{ -class sha512; -class sha256; -class ripemd160; class hash160 { @@ -112,12 +109,6 @@ namespace raw { void to_variant( const hash160& bi, variant& v, uint32_t max_depth ); void from_variant( const variant& v, hash160& bi, uint32_t max_depth ); - /* - typedef hash160 uint160_t; - typedef hash160 uint160; - - template<> struct get_typename { static const char* name() { return "uint160_t"; } }; - */ template<> struct get_typename { static const char* name() { return "hash160"; } }; } // namespace fc diff --git a/src/crypto/hash160.cpp b/src/crypto/hash160.cpp index ab131e5..d4b390a 100644 --- a/src/crypto/hash160.cpp +++ b/src/crypto/hash160.cpp @@ -28,9 +28,6 @@ #include #include #include -#include -#include -#include #include #include #include "_digest_common.hpp" From 55e2abe7d59d3b462af013f19cea6b373d846258 Mon Sep 17 00:00:00 2001 From: John Jones Date: Tue, 23 Jul 2019 17:32:29 -0500 Subject: [PATCH 03/13] Fix spacing --- src/crypto/hash160.cpp | 80 ++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 38 deletions(-) diff --git a/src/crypto/hash160.cpp b/src/crypto/hash160.cpp index d4b390a..68c4191 100644 --- a/src/crypto/hash160.cpp +++ b/src/crypto/hash160.cpp @@ -38,36 +38,33 @@ namespace fc hash160::hash160() { memset( _hash, 0, sizeof(_hash) ); } hash160::hash160( const string& hex_str ) { - fc::from_hex( hex_str, (char*)_hash, sizeof(_hash) ); + fc::from_hex( hex_str, (char*)_hash, sizeof(_hash) ); } string hash160::str()const { - return fc::to_hex( (char*)_hash, sizeof(_hash) ); + return fc::to_hex( (char*)_hash, sizeof(_hash) ); } hash160::operator string()const { return str(); } char* hash160::data()const { return (char*)&_hash[0]; } - class hash160::encoder::impl { -public: - impl() - { - } - + public: + impl() { } }; hash160::encoder::~encoder() {} hash160::encoder::encoder() {} hash160 hash160::hash( const char* d, uint32_t dlen ) { - encoder e; - e.write(d,dlen); - return e.result(); + encoder e; + e.write(d,dlen); + return e.result(); } + hash160 hash160::hash( const string& s ) { - return hash( s.c_str(), s.size() ); + return hash( s.c_str(), s.size() ); } void hash160::encoder::write( const char* d, uint32_t dlen ) @@ -93,45 +90,52 @@ hash160 hash160::encoder::result() { } hash160 operator << ( const hash160& h1, uint32_t i ) { - hash160 result; - fc::detail::shift_l( h1.data(), result.data(), result.data_size(), i ); - return result; + hash160 result; + fc::detail::shift_l( h1.data(), result.data(), result.data_size(), i ); + return result; } + hash160 operator ^ ( const hash160& h1, const hash160& h2 ) { - hash160 result; - 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; + hash160 result; + 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 hash160& h1, const hash160& h2 ) { - return memcmp( h1._hash, h2._hash, sizeof(h1._hash) ) >= 0; + return memcmp( h1._hash, h2._hash, sizeof(h1._hash) ) >= 0; } + bool operator > ( const hash160& h1, const hash160& h2 ) { - return memcmp( h1._hash, h2._hash, sizeof(h1._hash) ) > 0; + return memcmp( h1._hash, h2._hash, sizeof(h1._hash) ) > 0; } + bool operator < ( const hash160& h1, const hash160& h2 ) { - return memcmp( h1._hash, h2._hash, sizeof(h1._hash) ) < 0; + return memcmp( h1._hash, h2._hash, sizeof(h1._hash) ) < 0; } + bool operator != ( const hash160& h1, const hash160& h2 ) { - return memcmp( h1._hash, h2._hash, sizeof(h1._hash) ) != 0; + return memcmp( h1._hash, h2._hash, sizeof(h1._hash) ) != 0; } + bool operator == ( const hash160& h1, const hash160& h2 ) { - return memcmp( h1._hash, h2._hash, sizeof(h1._hash) ) == 0; + return memcmp( h1._hash, h2._hash, sizeof(h1._hash) ) == 0; } - void to_variant( const hash160& bi, variant& v, uint32_t max_depth ) - { - to_variant( std::vector( (const char*)&bi, ((const char*)&bi) + sizeof(bi) ), v, max_depth ); - } - void from_variant( const variant& v, hash160& bi, uint32_t max_depth ) - { - std::vector ve = v.as< std::vector >( max_depth ); - memset( &bi, char(0), sizeof(bi) ); - if( ve.size() ) - memcpy( &bi, ve.data(), std::min(ve.size(),sizeof(bi)) ); - } +void to_variant( const hash160& bi, variant& v, uint32_t max_depth ) +{ + to_variant( std::vector( (const char*)&bi, ((const char*)&bi) + sizeof(bi) ), v, max_depth ); +} + +void from_variant( const variant& v, hash160& bi, uint32_t max_depth ) +{ + std::vector ve = v.as< std::vector >( max_depth ); + memset( &bi, char(0), sizeof(bi) ); + if( ve.size() ) + memcpy( &bi, ve.data(), std::min(ve.size(),sizeof(bi)) ); +} } // fc From 5681dd1c0e80058781e722723703d5de2fa202c6 Mon Sep 17 00:00:00 2001 From: John Jones Date: Wed, 24 Jul 2019 10:15:10 -0500 Subject: [PATCH 04/13] Add hash160 test --- tests/crypto/sha_tests.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/crypto/sha_tests.cpp b/tests/crypto/sha_tests.cpp index 9a5665c..7e3d572 100644 --- a/tests/crypto/sha_tests.cpp +++ b/tests/crypto/sha_tests.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -108,6 +109,18 @@ BOOST_AUTO_TEST_CASE(ripemd160_test) test_stream(); } +BOOST_AUTO_TEST_CASE( hash160_test ) +{ + + test( TEST1, "bb1be98c142444d7a56aa3981c3942a978e4dc33" ); + test( TEST2, "b472a266d0bd89c13706a4132ccfb16f7c3b9fcb" ); + test( TEST3, "69dda8a60e0cfc2353aa776864092c0e5ccb4834" ); + test( TEST4, "dfcc6db6ea54d85d2e3a76573183f7a037a729b0" ); + init_5(); + test( TEST5, "f9be0e104ef2ed83a7ddb4765780951405e56ba4" ); + test( TEST6, "3eca00d3b1fcafb0b74fa07fe890bea9b053a17e" ); +} + BOOST_AUTO_TEST_CASE(sha1_test) { init_5(); From 9763d1c1945b1c246d947cae69094e91e5b14e9c Mon Sep 17 00:00:00 2001 From: abitmore Date: Thu, 26 Mar 2020 16:27:59 +0000 Subject: [PATCH 05/13] Update bool serialization Make the logic clearer, to avoid issues on some compilers. Thanks to @pureland and team. --- include/fc/io/raw.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/fc/io/raw.hpp b/include/fc/io/raw.hpp index 6b0371b..ffd1ad5 100644 --- a/include/fc/io/raw.hpp +++ b/include/fc/io/raw.hpp @@ -307,7 +307,7 @@ namespace fc { template inline void pack( Stream& s, const bool& v, uint32_t _max_depth ) { FC_ASSERT( _max_depth > 0 ); - fc::raw::pack( s, uint8_t(v), _max_depth - 1 ); + fc::raw::pack( s, v ? uint8_t(1) : uint8_t(0), _max_depth - 1 ); } template inline void unpack( Stream& s, bool& v, uint32_t _max_depth ) { From cc1103fe454b4aedc161d08869381cc77e397615 Mon Sep 17 00:00:00 2001 From: abitmore Date: Sat, 28 Mar 2020 16:05:03 +0000 Subject: [PATCH 06/13] Fix potential infinity loop Fix exception::to_detail_string(...) --- src/exception.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/exception.cpp b/src/exception.cpp index 01d2615..aff58c9 100644 --- a/src/exception.cpp +++ b/src/exception.cpp @@ -205,12 +205,12 @@ namespace fc ss << "ERROR: Failed to convert log data to string!\n"; } ss << " " << itr->get_context().to_string(); - ++itr; } catch( std::bad_alloc& ) { throw; } catch( ... ) { ss << "<- exception in to_detail_string."; } + ++itr; if( itr != my->_elog.end() ) ss<<"\n"; } } catch( std::bad_alloc& ) { From 34ddc2b859a7f40367d9928c09d1fedbaa95f13c Mon Sep 17 00:00:00 2001 From: abitmore Date: Sat, 28 Mar 2020 17:12:43 +0000 Subject: [PATCH 07/13] Update to_variant(size_t) for macOS and OpenBSD Fix to_variant(size_t) for OpenBSD, move implementation for macOS to cpp file --- include/fc/variant.hpp | 4 +--- src/variant.cpp | 5 ++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/include/fc/variant.hpp b/include/fc/variant.hpp index 79d0a04..f0c8f25 100644 --- a/include/fc/variant.hpp +++ b/include/fc/variant.hpp @@ -581,9 +581,7 @@ namespace fc memset( this, 0, sizeof(*this) ); to_variant( val, *this, max_depth ); } - #ifdef __APPLE__ - inline void to_variant( size_t s, variant& v, uint32_t max_depth ) { v = variant(uint64_t(s)); } - #endif + template void to_variant( const std::shared_ptr& var, variant& vo, uint32_t max_depth ) { diff --git a/src/variant.cpp b/src/variant.cpp index eaa12d3..a4d09b1 100644 --- a/src/variant.cpp +++ b/src/variant.cpp @@ -701,9 +701,8 @@ void from_variant( const variant& var, uint128_t& vo, uint32_t max_depth ) #endif } -#if defined(__APPLE__) -#elif defined(__OpenBSD__) - void to_variant( size_t s, variant& v, uint32_t max_depth ) { v = variant( int64_t(s) ); } +#if defined(__APPLE__) or defined(__OpenBSD__) + void to_variant( size_t s, variant& v, uint32_t max_depth ) { v = variant( uint64_t(s) ); } #elif !defined(_WIN32) void to_variant( long long int s, variant& v, uint32_t max_depth ) { v = variant( int64_t(s) ); } void to_variant( unsigned long long int s, variant& v, uint32_t max_depth ) { v = variant( uint64_t(s)); } From 98a16ce397a97a5ff0f950fb2cca29fabb2371f8 Mon Sep 17 00:00:00 2001 From: abitmore Date: Sun, 29 Mar 2020 20:40:16 +0000 Subject: [PATCH 08/13] Replace int with 64-bit types in static_variant --- include/fc/static_variant.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/fc/static_variant.hpp b/include/fc/static_variant.hpp index 88069d0..768231a 100644 --- a/include/fc/static_variant.hpp +++ b/include/fc/static_variant.hpp @@ -118,7 +118,7 @@ public: template> struct tag { - static constexpr int value = typelist::index_of(); + static constexpr tag_type value = typelist::index_of(); }; struct type_lt { @@ -302,7 +302,7 @@ public: }); } - static constexpr int count() { return typelist::length(); } + static constexpr size_t count() { return typelist::length(); } void set_which( tag_type w ) { FC_ASSERT( w >= 0 ); FC_ASSERT( w < count() ); From ca3e76d226a8d51369d503bb195e72ec42d314a7 Mon Sep 17 00:00:00 2001 From: abitmore Date: Mon, 6 Apr 2020 15:16:12 +0000 Subject: [PATCH 09/13] Fix compiler warnings about static_variant --- include/fc/static_variant.hpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/include/fc/static_variant.hpp b/include/fc/static_variant.hpp index 768231a..452b090 100644 --- a/include/fc/static_variant.hpp +++ b/include/fc/static_variant.hpp @@ -75,7 +75,7 @@ protected: void init_from_tag(tag_type tag) { FC_ASSERT( tag >= 0 ); - FC_ASSERT( tag < count() ); + FC_ASSERT( static_cast(tag) < count() ); _tag = tag; typelist::runtime::dispatch(list(), tag, [this](auto t) { using T = typename decltype(t)::type; @@ -269,7 +269,7 @@ public: template static typename visitor::result_type visit( tag_type tag, visitor& v, void* data ) { - FC_ASSERT( tag >= 0 && tag < count(), "Unsupported type ${tag}!", ("tag",tag) ); + FC_ASSERT( tag >= 0 && static_cast(tag) < count(), "Unsupported type ${tag}!", ("tag",tag) ); return typelist::runtime::dispatch(list(), tag, [&v, data](auto t) { return v(*reinterpret_cast(data)); }); @@ -278,7 +278,7 @@ public: template static typename visitor::result_type visit( tag_type tag, const visitor& v, void* data ) { - FC_ASSERT( tag >= 0 && tag < count(), "Unsupported type ${tag}!", ("tag",tag) ); + FC_ASSERT( tag >= 0 && static_cast(tag) < count(), "Unsupported type ${tag}!", ("tag",tag) ); return typelist::runtime::dispatch(list(), tag, [&v, data](auto t) { return v(*reinterpret_cast(data)); }); @@ -287,7 +287,7 @@ public: template static typename visitor::result_type visit( tag_type tag, visitor& v, const void* data ) { - FC_ASSERT( tag >= 0 && tag < count(), "Unsupported type ${tag}!", ("tag",tag) ); + FC_ASSERT( tag >= 0 && static_cast(tag) < count(), "Unsupported type ${tag}!", ("tag",tag) ); return typelist::runtime::dispatch(list(), tag, [&v, data](auto t) { return v(*reinterpret_cast(data)); }); @@ -296,18 +296,18 @@ public: template static typename visitor::result_type visit( tag_type tag, const visitor& v, const void* data ) { - FC_ASSERT( tag >= 0 && tag < count(), "Unsupported type ${tag}!", ("tag",tag) ); + FC_ASSERT( tag >= 0 && static_cast(tag) < count(), "Unsupported type ${tag}!", ("tag",tag) ); return typelist::runtime::dispatch(list(), tag, [&v, data](auto t) { return v(*reinterpret_cast(data)); }); } static constexpr size_t count() { return typelist::length(); } - void set_which( tag_type w ) { - FC_ASSERT( w >= 0 ); - FC_ASSERT( w < count() ); + void set_which( tag_type tag ) { + FC_ASSERT( tag >= 0 ); + FC_ASSERT( static_cast(tag) < count() ); clean(); - init_from_tag(w); + init_from_tag(tag); } tag_type which() const {return _tag;} From 9505342dbf64132f334169edb52f3ce1174167b7 Mon Sep 17 00:00:00 2001 From: John Jones Date: Tue, 14 Apr 2020 11:25:00 -0500 Subject: [PATCH 10/13] improve hash160 performance --- include/fc/crypto/hash160.hpp | 5 +++-- src/crypto/hash160.cpp | 11 +++-------- tests/stacktrace_test.cpp | 2 +- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/include/fc/crypto/hash160.hpp b/include/fc/crypto/hash160.hpp index 75604f8..4edb718 100644 --- a/include/fc/crypto/hash160.hpp +++ b/include/fc/crypto/hash160.hpp @@ -22,6 +22,7 @@ * THE SOFTWARE. */ #pragma once +#include #include #include #include @@ -39,7 +40,7 @@ class hash160 explicit operator string()const; char* data() const; - size_t data_size() const { return 160/8; } + static constexpr size_t data_size() { return 160/8; } static hash160 hash( const char* d, uint32_t dlen ); static hash160 hash( const string& ); @@ -66,7 +67,7 @@ class hash160 private: class impl; fc::fwd my; - std::vector bytes; + SHA256_CTX sha_ctx;; }; template diff --git a/src/crypto/hash160.cpp b/src/crypto/hash160.cpp index 68c4191..9d64503 100644 --- a/src/crypto/hash160.cpp +++ b/src/crypto/hash160.cpp @@ -24,7 +24,6 @@ #include #include -#include #include #include #include @@ -55,7 +54,7 @@ class hash160::encoder::impl { }; hash160::encoder::~encoder() {} -hash160::encoder::encoder() {} +hash160::encoder::encoder() { SHA256_Init(&sha_ctx); } hash160 hash160::hash( const char* d, uint32_t dlen ) { encoder e; @@ -69,15 +68,11 @@ hash160 hash160::hash( const string& s ) { void hash160::encoder::write( const char* d, uint32_t dlen ) { - for(uint32_t i = 0; i < dlen; ++i) - bytes.push_back(d[i]); + SHA256_Update( &sha_ctx, d, dlen); } hash160 hash160::encoder::result() { - // perform the first hashing function - SHA256_CTX sha_ctx; - SHA256_Init(&sha_ctx); - SHA256_Update( &sha_ctx, bytes.data(), bytes.size()); + // finalize the first hash unsigned char sha_hash[SHA256_DIGEST_LENGTH]; SHA256_Final( sha_hash, &sha_ctx ); // perform the second hashing function diff --git a/tests/stacktrace_test.cpp b/tests/stacktrace_test.cpp index 452a63e..ed99542 100644 --- a/tests/stacktrace_test.cpp +++ b/tests/stacktrace_test.cpp @@ -74,7 +74,7 @@ BOOST_AUTO_TEST_CASE(static_variant_depth_test) for( const auto& line : lines ) if( line.find("_svdt_visitor") != std::string::npos ) count++; BOOST_CHECK_LT( 2, count ); // test.visit(), static_variant::visit, function object, visitor - BOOST_CHECK_GT( 8, count ); // some is implementation-dependent + BOOST_CHECK_GT( 10, count ); // some is implementation-dependent } #endif From 5070d8d2fc8df1730ac3a7e00587a4c43d7c0f17 Mon Sep 17 00:00:00 2001 From: John Jones Date: Wed, 15 Apr 2020 09:20:39 -0500 Subject: [PATCH 11/13] define hash160 reset method --- src/crypto/hash160.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/crypto/hash160.cpp b/src/crypto/hash160.cpp index 9d64503..985f8ad 100644 --- a/src/crypto/hash160.cpp +++ b/src/crypto/hash160.cpp @@ -84,6 +84,11 @@ hash160 hash160::encoder::result() { return h; } +void hash160::encoder::reset() +{ + SHA256_Init(&sha_ctx); +} + hash160 operator << ( const hash160& h1, uint32_t i ) { hash160 result; fc::detail::shift_l( h1.data(), result.data(), result.data_size(), i ); From c554c7e56ddd88bde71cd26bef09c62c2444aec5 Mon Sep 17 00:00:00 2001 From: John Jones Date: Wed, 15 Apr 2020 09:52:18 -0500 Subject: [PATCH 12/13] add impl to hash160 --- include/fc/crypto/hash160.hpp | 6 ++---- src/crypto/hash160.cpp | 18 ++++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/include/fc/crypto/hash160.hpp b/include/fc/crypto/hash160.hpp index 4edb718..28121bc 100644 --- a/include/fc/crypto/hash160.hpp +++ b/include/fc/crypto/hash160.hpp @@ -22,11 +22,10 @@ * THE SOFTWARE. */ #pragma once -#include #include #include +#include #include -#include namespace fc{ @@ -66,8 +65,7 @@ class hash160 private: class impl; - fc::fwd my; - SHA256_CTX sha_ctx;; + fc::fwd my; }; template diff --git a/src/crypto/hash160.cpp b/src/crypto/hash160.cpp index 985f8ad..3c65e81 100644 --- a/src/crypto/hash160.cpp +++ b/src/crypto/hash160.cpp @@ -23,12 +23,15 @@ */ #include +#include #include +#include #include #include +#include #include #include -#include +#include #include "_digest_common.hpp" namespace fc @@ -48,13 +51,12 @@ hash160::operator string()const { return str(); } char* hash160::data()const { return (char*)&_hash[0]; } -class hash160::encoder::impl { - public: - impl() { } +struct hash160::encoder::impl { + SHA256_CTX ctx; }; hash160::encoder::~encoder() {} -hash160::encoder::encoder() { SHA256_Init(&sha_ctx); } +hash160::encoder::encoder() { SHA256_Init(&my->ctx); } hash160 hash160::hash( const char* d, uint32_t dlen ) { encoder e; @@ -68,13 +70,13 @@ hash160 hash160::hash( const string& s ) { void hash160::encoder::write( const char* d, uint32_t dlen ) { - SHA256_Update( &sha_ctx, d, dlen); + SHA256_Update( &my->ctx, d, dlen); } hash160 hash160::encoder::result() { // finalize the first hash unsigned char sha_hash[SHA256_DIGEST_LENGTH]; - SHA256_Final( sha_hash, &sha_ctx ); + SHA256_Final( sha_hash, &my->ctx ); // perform the second hashing function RIPEMD160_CTX ripe_ctx; RIPEMD160_Init(&ripe_ctx); @@ -86,7 +88,7 @@ hash160 hash160::encoder::result() { void hash160::encoder::reset() { - SHA256_Init(&sha_ctx); + SHA256_Init(&my->ctx); } hash160 operator << ( const hash160& h1, uint32_t i ) { From 377f8434784a171213e09ba3a3e0ebd0918f4231 Mon Sep 17 00:00:00 2001 From: Abit Date: Sun, 19 Apr 2020 18:03:37 +0200 Subject: [PATCH 13/13] Fix static_variant_depth_test --- tests/stacktrace_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/stacktrace_test.cpp b/tests/stacktrace_test.cpp index 6dcfb03..cc003d8 100644 --- a/tests/stacktrace_test.cpp +++ b/tests/stacktrace_test.cpp @@ -74,7 +74,7 @@ BOOST_AUTO_TEST_CASE(static_variant_depth_test) int count = 0; for( const auto& line : lines ) if( line.find("_svdt_visitor") != std::string::npos ) count++; - BOOST_CHECK_LT( 2, count ); // test.visit(), static_variant::visit, function object, visitor. + BOOST_CHECK_LT( 1, count ); // test.visit(), static_variant::visit, function object, visitor. // The actual count depends on compiler and optimization settings. BOOST_CHECK_GT( 10, count ); // It *should* be less than the number of static variant components. // some is implementation-dependent