From 639a0c795ae038eccd0ec71f4cfe8a7306ec5f96 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Thu, 6 Jun 2013 14:45:55 -0400 Subject: [PATCH 1/8] Updates to crypto/fc --- CMakeLists.txt | 1 + include/fc/crypto/elliptic.hpp | 3 ++- include/fc/io/raw.hpp | 18 +++++++++--------- include/fc/io/raw_fwd.hpp | 12 ++++++------ src/crypto/elliptic.cpp | 2 +- 5 files changed, 19 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b0db49..5d6fd2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,6 +105,7 @@ set( fc_sources src/crypto/hex.cpp src/crypto/sha1.cpp src/crypto/sha256.cpp + src/crypto/sha512.cpp src/crypto/dh.cpp src/crypto/blowfish.cpp src/network/tcp_socket.cpp diff --git a/include/fc/crypto/elliptic.hpp b/include/fc/crypto/elliptic.hpp index 167d663..86334e4 100644 --- a/include/fc/crypto/elliptic.hpp +++ b/include/fc/crypto/elliptic.hpp @@ -4,6 +4,7 @@ #include #include #include +#include namespace fc { namespace ecc { @@ -23,7 +24,7 @@ namespace fc { namespace ecc { ~public_key(); bool verify( const fc::sha256& digest, const signature& sig ); - std::vector serialize(); + std::vector serialize()const; public_key( const std::vector& v ); public_key( const compact_signature& c, const fc::sha256& digest ); private: diff --git a/include/fc/io/raw.hpp b/include/fc/io/raw.hpp index 52321bc..a328c00 100644 --- a/include/fc/io/raw.hpp +++ b/include/fc/io/raw.hpp @@ -106,13 +106,13 @@ namespace fc { if( b ) { v = T(); unpack( s, *v ); } } - // fc::vector - template inline void pack( Stream& s, const fc::vector& value ) { + // std::vector + template inline void pack( Stream& s, const std::vector& value ) { pack( s, unsigned_int(value.size()) ); if( value.size() ) s.write( &value.front(), value.size() ); } - template inline void unpack( Stream& s, fc::vector& value ) { + template inline void unpack( Stream& s, std::vector& value ) { unsigned_int size; unpack( s, size ); value.resize(size.value); if( value.size() ) @@ -126,7 +126,7 @@ namespace fc { } template inline void unpack( Stream& s, fc::string& v ) { - fc::vector tmp; unpack(s,tmp); + std::vector tmp; unpack(s,tmp); v = fc::string(tmp.begin(),tmp.end()); } @@ -211,7 +211,7 @@ namespace fc { template - inline void pack( Stream& s, const fc::vector& value ) { + inline void pack( Stream& s, const std::vector& value ) { pack( s, unsigned_int(value.size()) ); auto itr = value.begin(); auto end = value.end(); @@ -222,7 +222,7 @@ namespace fc { } template - inline void unpack( Stream& s, fc::vector& value ) { + inline void unpack( Stream& s, std::vector& value ) { unsigned_int size; unpack( s, size ); value.resize(size.value); auto itr = value.begin(); @@ -383,10 +383,10 @@ namespace fc { } template - inline fc::vector pack( const T& v ) { + inline std::vector pack( const T& v ) { datastream ps; raw::pack(ps,v ); - fc::vector vec(ps.tellp()); + std::vector vec(ps.tellp()); if( vec.size() ) { datastream ds( vec.data(), size_t(vec.size()) ); @@ -396,7 +396,7 @@ namespace fc { } template - inline T unpack( const fc::vector& s ) { + inline T unpack( const std::vector& s ) { T tmp; if( s.size() ) { datastream ds( s.data(), size_t(s.size()) ); diff --git a/include/fc/io/raw_fwd.hpp b/include/fc/io/raw_fwd.hpp index 24e1c1a..3cf02e5 100644 --- a/include/fc/io/raw_fwd.hpp +++ b/include/fc/io/raw_fwd.hpp @@ -12,8 +12,8 @@ namespace fc { namespace raw { template inline void pack( Stream& s, const T& v ); template inline void unpack( Stream& s, T& v ); - template inline void pack( Stream& s, const fc::vector& v ); - template inline void unpack( Stream& s, fc::vector& v ); + template inline void pack( Stream& s, const std::vector& v ); + template inline void unpack( Stream& s, std::vector& v ); template inline void pack( Stream& s, const signed_int& v ); template inline void unpack( Stream& s, signed_int& vi ); @@ -22,8 +22,8 @@ namespace fc { namespace raw { template inline void unpack( Stream& s, unsigned_int& vi ); template inline void pack( Stream& s, const char* v ); - template inline void pack( Stream& s, const fc::vector& value ); - template inline void unpack( Stream& s, fc::vector& value ); + template inline void pack( Stream& s, const std::vector& value ); + template inline void unpack( Stream& s, std::vector& value ); template inline void pack( Stream& s, const fc::array& v); template inline void unpack( Stream& s, fc::array& v); @@ -31,8 +31,8 @@ namespace fc { namespace raw { template inline void pack( Stream& s, const bool& v ); template inline void unpack( Stream& s, bool& v ); - template inline fc::vector pack( const T& v ); - template inline T unpack( const fc::vector& s ); + template inline std::vector pack( const T& v ); + template inline T unpack( const std::vector& s ); template inline T unpack( const char* d, uint32_t s ); template inline void unpack( const char* d, uint32_t s, T& v ); } } diff --git a/src/crypto/elliptic.cpp b/src/crypto/elliptic.cpp index 2c15abb..3c4f5bb 100644 --- a/src/crypto/elliptic.cpp +++ b/src/crypto/elliptic.cpp @@ -272,7 +272,7 @@ namespace fc { namespace ecc { return 1 == ECDSA_verify( 0, (unsigned char*)&digest, sizeof(digest), (unsigned char*)&sig, sizeof(sig), my->_key ); } - std::vector public_key::serialize() + std::vector public_key::serialize()const { EC_KEY_set_conv_form( my->_key, POINT_CONVERSION_COMPRESSED ); size_t nbytes = i2o_ECPublicKey( my->_key, nullptr ); From 0fd0574c05ad5304c1a8ba3f94e49e635f3fd5ff Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Thu, 6 Jun 2013 19:20:51 -0400 Subject: [PATCH 2/8] various updates to support bitshares --- include/fc/crypto/elliptic.hpp | 129 +++++++++++++++++++++------------ include/fc/io/raw.hpp | 4 +- include/fc/io/raw_fwd.hpp | 12 ++- 3 files changed, 97 insertions(+), 48 deletions(-) diff --git a/include/fc/crypto/elliptic.hpp b/include/fc/crypto/elliptic.hpp index 86334e4..6f37f78 100644 --- a/include/fc/crypto/elliptic.hpp +++ b/include/fc/crypto/elliptic.hpp @@ -5,58 +5,95 @@ #include #include #include +#include -namespace fc { namespace ecc { +namespace fc +{ + namespace ecc + { - namespace detail - { - class public_key_impl; - class private_key_impl; + namespace detail + { + class public_key_impl; + class private_key_impl; + } + + typedef fc::array signature; + typedef fc::array compact_signature; + + class public_key + { + public: + public_key(); + ~public_key(); + bool verify( const fc::sha256& digest, const signature& sig ); + + std::vector serialize()const; + public_key( const std::vector& v ); + public_key( const compact_signature& c, const fc::sha256& digest ); + private: + friend class private_key; + fc::fwd my; + }; + + + class private_key + { + public: + private_key(); + private_key( std::vector k ); + ~private_key(); + + static private_key generate(); + static private_key regenerate( const fc::sha256& secret ); + + fc::sha256 get_secret()const; // get the private key secret + + /** + * Given a public key, calculatse a 512 bit shared secret between that + * key and this private key. + */ + fc::sha512 get_shared_secret( const public_key& pub ); + + signature sign( const fc::sha256& digest ); + compact_signature sign_compact( const fc::sha256& digest ); + bool verify( const fc::sha256& digest, const signature& sig ); + + public_key get_public_key()const; + private: + fc::fwd my; + }; + } // namespace ecc + + namespace raw + { + template + inline void pack( Stream& s, const fc::ecc::public_key& v ) + { + pack( s, v.serialize() ); + } + template + inline void unpack( Stream& s, fc::ecc::public_key& v ) + { + std::vector d; + unpack( s, d ); + v = fc::ecc::public_key( fc::move(d) ); } - typedef fc::array signature; - typedef fc::array compact_signature; - - class public_key + template + inline void pack( Stream& s, const fc::ecc::private_key& v ) { - public: - public_key(); - ~public_key(); - bool verify( const fc::sha256& digest, const signature& sig ); + pack( s, v.get_secret() ); + } - std::vector serialize()const; - public_key( const std::vector& v ); - public_key( const compact_signature& c, const fc::sha256& digest ); - private: - friend class private_key; - fc::fwd my; - }; - - - class private_key + template + inline void unpack( Stream& s, fc::ecc::private_key& v ) { - public: - private_key(); - private_key( std::vector k ); - ~private_key(); + fc::sha256 secret; + unpack( s, secret ); + v = fc::ecc::private_key::regenerate( secret ); + } - static private_key generate(); - static private_key regenerate( const fc::sha256& secret ); + } // namespace raw - fc::sha256 get_secret()const; // get the private key secret - - /** - * Given a public key, calculatse a 512 bit shared secret between that - * key and this private key. - */ - fc::sha512 get_shared_secret( const public_key& pub ); - - signature sign( const fc::sha256& digest ); - compact_signature sign_compact( const fc::sha256& digest ); - bool verify( const fc::sha256& digest, const signature& sig ); - - public_key get_public_key()const; - private: - fc::fwd my; - }; -} } // fc::ecc +} // fc diff --git a/include/fc/io/raw.hpp b/include/fc/io/raw.hpp index a328c00..5d4b81f 100644 --- a/include/fc/io/raw.hpp +++ b/include/fc/io/raw.hpp @@ -127,7 +127,9 @@ namespace fc { template inline void unpack( Stream& s, fc::string& v ) { std::vector tmp; unpack(s,tmp); - v = fc::string(tmp.begin(),tmp.end()); + if( tmp.size() ) + v = fc::string(tmp.data(),tmp.data()+tmp.size()); + else v = fc::string(); } // bool diff --git a/include/fc/io/raw_fwd.hpp b/include/fc/io/raw_fwd.hpp index 3cf02e5..ce3159a 100644 --- a/include/fc/io/raw_fwd.hpp +++ b/include/fc/io/raw_fwd.hpp @@ -1,13 +1,23 @@ #pragma once #include #include +#include +#include -namespace fc { namespace raw { +namespace fc { + namespace ecc { class public_key; class private_key; } + namespace raw { template void unpack( Stream& s, fc::optional& v ); template void pack( Stream& s, const fc::optional& v ); template void unpack( Stream& s, fc::string& ); template void pack( Stream& s, const fc::string& ); + template void unpack( Stream& s, std::string& ); + template void pack( Stream& s, const std::string& ); + template void unpack( Stream& s, fc::ecc::public_key& ); + template void pack( Stream& s, const fc::ecc::public_key& ); + template void unpack( Stream& s, fc::ecc::private_key& ); + template void pack( Stream& s, const fc::ecc::private_key& ); template inline void pack( Stream& s, const T& v ); template inline void unpack( Stream& s, T& v ); From 6563c12f882acea576c6fb55cb60bc5968fddd2b Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Thu, 6 Jun 2013 20:37:04 -0400 Subject: [PATCH 3/8] bug fixes --- CMakeLists.txt | 1 + include/fc/crypto/elliptic.hpp | 179 ++++++++++++++++++--------------- src/crypto/elliptic.cpp | 96 ++++++++++++++++-- 3 files changed, 185 insertions(+), 91 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d6fd2b..dff9373 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -108,6 +108,7 @@ set( fc_sources src/crypto/sha512.cpp src/crypto/dh.cpp src/crypto/blowfish.cpp + src/crypto/elliptic.cpp src/network/tcp_socket.cpp src/network/udp_socket.cpp src/network/http/http_connection.cpp diff --git a/include/fc/crypto/elliptic.hpp b/include/fc/crypto/elliptic.hpp index 6f37f78..b6190e9 100644 --- a/include/fc/crypto/elliptic.hpp +++ b/include/fc/crypto/elliptic.hpp @@ -4,96 +4,109 @@ #include #include #include -#include #include -namespace fc -{ - namespace ecc - { - - namespace detail - { - class public_key_impl; - class private_key_impl; - } - - typedef fc::array signature; - typedef fc::array compact_signature; - - class public_key - { - public: - public_key(); - ~public_key(); - bool verify( const fc::sha256& digest, const signature& sig ); - - std::vector serialize()const; - public_key( const std::vector& v ); - public_key( const compact_signature& c, const fc::sha256& digest ); - private: - friend class private_key; - fc::fwd my; - }; - - - class private_key - { - public: - private_key(); - private_key( std::vector k ); - ~private_key(); - - static private_key generate(); - static private_key regenerate( const fc::sha256& secret ); - - fc::sha256 get_secret()const; // get the private key secret - - /** - * Given a public key, calculatse a 512 bit shared secret between that - * key and this private key. - */ - fc::sha512 get_shared_secret( const public_key& pub ); - - signature sign( const fc::sha256& digest ); - compact_signature sign_compact( const fc::sha256& digest ); - bool verify( const fc::sha256& digest, const signature& sig ); - - public_key get_public_key()const; - private: - fc::fwd my; - }; - } // namespace ecc +namespace fc { + + namespace ecc { + namespace detail + { + class public_key_impl; + class private_key_impl; + } + + typedef fc::array public_key_data; + typedef fc::array signature; + typedef fc::array compact_signature; + + class public_key + { + public: + public_key(); + public_key(const public_key& k); + ~public_key(); + bool verify( const fc::sha256& digest, const signature& sig ); + public_key_data serialize()const; + public_key( const public_key_data& v ); + public_key( const compact_signature& c, const fc::sha256& digest ); + + bool valid()const; + + public_key( public_key&& pk ); + public_key& operator=( public_key&& pk ); + public_key& operator=( const public_key& pk ); + private: + friend class private_key; + fc::fwd my; + }; + + + class private_key + { + public: + private_key(); + private_key( std::vector k ); + private_key( private_key&& pk ); + private_key( const private_key& pk ); + ~private_key(); + + private_key& operator=( private_key&& pk ); + private_key& operator=( const private_key& pk ); + + static private_key generate(); + static private_key regenerate( const fc::sha256& secret ); + + fc::sha256 get_secret()const; // get the private key secret + + /** + * Given a public key, calculatse a 512 bit shared secret between that + * key and this private key. + */ + fc::sha512 get_shared_secret( const public_key& pub ); + + signature sign( const fc::sha256& digest ); + compact_signature sign_compact( const fc::sha256& digest ); + bool verify( const fc::sha256& digest, const signature& sig ); + + public_key get_public_key()const; + private: + fc::fwd my; + }; + } // namespace ecc + void to_variant( const ecc::private_key& var, variant& vo ); + void from_variant( const variant& var, ecc::private_key& vo ); + void to_variant( const ecc::public_key& var, variant& vo ); + void from_variant( const variant& var, ecc::public_key& vo ); namespace raw { - template - inline void pack( Stream& s, const fc::ecc::public_key& v ) - { - pack( s, v.serialize() ); - } - template - inline void unpack( Stream& s, fc::ecc::public_key& v ) - { - std::vector d; - unpack( s, d ); - v = fc::ecc::public_key( fc::move(d) ); - } + template + void unpack( Stream& s, fc::ecc::public_key& pk) + { + ecc::public_key_data ser; + fc::raw::unpack(s,ser); + pk = fc::ecc::public_key( ser ); + } - template - inline void pack( Stream& s, const fc::ecc::private_key& v ) - { - pack( s, v.get_secret() ); - } + template + void pack( Stream& s, const fc::ecc::public_key& pk) + { + fc::raw::pack( s, pk.serialize() ); + } - template - inline void unpack( Stream& s, fc::ecc::private_key& v ) - { - fc::sha256 secret; - unpack( s, secret ); - v = fc::ecc::private_key::regenerate( secret ); - } + template + void unpack( Stream& s, fc::ecc::private_key& pk) + { + fc::sha256 sec; + unpack( s, sec ); + pk = ecc::private_key::regenerate(sec); + } + template + void pack( Stream& s, const fc::ecc::private_key& pk) + { + fc::raw::pack( s, pk.get_secret() ); + } } // namespace raw -} // fc +} // namespace fc diff --git a/src/crypto/elliptic.cpp b/src/crypto/elliptic.cpp index 3c4f5bb..bc918c5 100644 --- a/src/crypto/elliptic.cpp +++ b/src/crypto/elliptic.cpp @@ -272,14 +272,14 @@ namespace fc { namespace ecc { return 1 == ECDSA_verify( 0, (unsigned char*)&digest, sizeof(digest), (unsigned char*)&sig, sizeof(sig), my->_key ); } - std::vector public_key::serialize()const + public_key_data public_key::serialize()const { EC_KEY_set_conv_form( my->_key, POINT_CONVERSION_COMPRESSED ); size_t nbytes = i2o_ECPublicKey( my->_key, nullptr ); - std::vector dat(nbytes); - char* front = &dat[0]; + assert( nbytes == 33 ); + public_key_data dat; + char* front = &dat.data[0]; i2o_ECPublicKey( my->_key, (unsigned char**)&front ); - fprintf( stderr, "public key size: %lu\n", nbytes ); return dat; /* EC_POINT* pub = EC_KEY_get0_public_key( my->_key ); @@ -293,11 +293,11 @@ namespace fc { namespace ecc { public_key::~public_key() { } - public_key::public_key( const std::vector& v ) + public_key::public_key( const public_key_data& dat ) { - const char* front = &v[0]; + const char* front = &dat.data[0]; my->_key = EC_KEY_new_by_curve_name( NID_secp256k1 ); - my->_key = o2i_ECPublicKey( &my->_key, (const unsigned char**)&front, v.size() ); + my->_key = o2i_ECPublicKey( &my->_key, (const unsigned char**)&front, sizeof(public_key_data) ); if( !my->_key ) { fprintf( stderr, "decode error occurred??" ); @@ -426,4 +426,84 @@ namespace fc { namespace ecc { return csig; } -} } + private_key& private_key::operator=( private_key&& pk ) + { + if( my->_key ) + { + EC_KEY_free(my->_key); + } + my->_key = pk.my->_key; + pk.my->_key = nullptr; + return *this; + } + public_key::public_key( const public_key& pk ) + :my(pk.my) + { + } + public_key::public_key( public_key&& pk ) + :my( fc::move( pk.my) ) + { + } + private_key::private_key( const private_key& pk ) + :my(pk.my) + { + } + private_key::private_key( private_key&& pk ) + :my( fc::move( pk.my) ) + { + } + + public_key& public_key::operator=( public_key&& pk ) + { + if( my->_key ) + { + EC_KEY_free(my->_key); + } + my->_key = pk.my->_key; + pk.my->_key = nullptr; + return *this; + } + public_key& public_key::operator=( const public_key& pk ) + { + if( my->_key ) + { + EC_KEY_free(my->_key); + } + my->_key = EC_KEY_dup(pk.my->_key); + return *this; + } + private_key& private_key::operator=( const private_key& pk ) + { + if( my->_key ) + { + EC_KEY_free(my->_key); + } + my->_key = EC_KEY_dup(pk.my->_key); + return *this; + } + +} + void to_variant( const ecc::private_key& var, variant& vo ) + { + vo = var.get_secret(); + } + void from_variant( const variant& var, ecc::private_key& vo ) + { + fc::sha256 sec; + from_variant( var, sec ); + vo = ecc::private_key::regenerate(sec); + } + + void to_variant( const ecc::public_key& var, variant& vo ) + { + vo = var.serialize(); + } + void from_variant( const variant& var, ecc::public_key& vo ) + { + ecc::public_key_data dat; + from_variant( var, dat ); + vo = ecc::public_key(dat); + } + + +} From 1f3e6739c6885cbbb952f42bbc3ee19fbba1563a Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Thu, 6 Jun 2013 22:49:30 -0400 Subject: [PATCH 4/8] switch to std::vector from fc::vector --- include/fc/log/console_appender.hpp | 3 ++- include/fc/log/log_message.hpp | 2 +- include/fc/log/logger_config.hpp | 8 ++++---- include/fc/variant.hpp | 15 ++++++++------- include/fc/variant_object.hpp | 16 ++++++++-------- include/fc/vector.hpp | 9 +++++++++ src/crypto/base58.cpp | 4 ++-- src/crypto/sha256.cpp | 4 ++-- src/crypto/sha512.cpp | 4 ++-- src/network/resolve.cpp | 4 ++-- src/variant.cpp | 6 +++--- src/variant_object.cpp | 18 +++++++++--------- 12 files changed, 52 insertions(+), 41 deletions(-) diff --git a/include/fc/log/console_appender.hpp b/include/fc/log/console_appender.hpp index 9fe9f30..ddc54f2 100644 --- a/include/fc/log/console_appender.hpp +++ b/include/fc/log/console_appender.hpp @@ -1,6 +1,7 @@ #pragma once #include #include +#include namespace fc { @@ -41,7 +42,7 @@ namespace fc fc::string format; console_appender::stream::type stream; - fc::vector level_colors; + std::vector level_colors; bool flush; }; diff --git a/include/fc/log/log_message.hpp b/include/fc/log/log_message.hpp index c632cc6..4a6257a 100644 --- a/include/fc/log/log_message.hpp +++ b/include/fc/log/log_message.hpp @@ -127,7 +127,7 @@ namespace fc void to_variant( const log_message& l, variant& v ); void from_variant( const variant& l, log_message& c ); - typedef fc::vector log_messages; + typedef std::vector log_messages; } // namespace fc diff --git a/include/fc/log/logger_config.hpp b/include/fc/log/logger_config.hpp index c46accc..b31fefe 100644 --- a/include/fc/log/logger_config.hpp +++ b/include/fc/log/logger_config.hpp @@ -21,16 +21,16 @@ namespace fc { bool enabled; /// if any appenders are sepecified, then parent's appenders are not set. bool additivity; - fc::vector appenders; + std::vector appenders; logger_config& add_appender( const string& s ); }; struct logging_config { static logging_config default_config(); - fc::vector includes; - fc::vector appenders; - fc::vector loggers; + std::vector includes; + std::vector appenders; + std::vector loggers; }; void configure_logging( const fc::path& log_config ); diff --git a/include/fc/variant.hpp b/include/fc/variant.hpp index 896a79d..cf4e64e 100644 --- a/include/fc/variant.hpp +++ b/include/fc/variant.hpp @@ -1,8 +1,9 @@ #pragma once -#include +#include #include #include #include +#include // memset namespace fc { @@ -35,8 +36,8 @@ namespace fc void from_variant( const variant& var, variant_object& vo ); void to_variant( const mutable_variant_object& var, variant& vo ); void from_variant( const variant& var, mutable_variant_object& vo ); - void to_variant( const vector& var, variant& vo ); - void from_variant( const variant& var, vector& vo ); + void to_variant( const std::vector& var, variant& vo ); + void from_variant( const variant& var, std::vector& vo ); void to_variant( const time_point& var, variant& vo ); void from_variant( const variant& var, time_point& vo ); #ifdef __APPLE__ @@ -50,7 +51,7 @@ namespace fc template void from_variant( const variant& var, std::shared_ptr& vo ); - typedef vector variants; + typedef std::vector variants; /** * @brief stores null, int64, uint64, double, bool, string, vector, @@ -246,7 +247,7 @@ namespace fc /** @ingroup Serializable */ template - void from_variant( const variant& var, vector& tmp ) + void from_variant( const variant& var, std::vector& tmp ) { const variants& vars = var.get_array(); tmp.clear(); @@ -257,9 +258,9 @@ namespace fc /** @ingroup Serializable */ template - void to_variant( const vector& t, variant& v ) + void to_variant( const std::vector& t, variant& v ) { - vector vars(t.size()); + std::vector vars(t.size()); for( size_t i = 0; i < t.size(); ++i ) vars[i] = variant(t[i]); v = vars; diff --git a/include/fc/variant_object.hpp b/include/fc/variant_object.hpp index a5942ce..735e69f 100644 --- a/include/fc/variant_object.hpp +++ b/include/fc/variant_object.hpp @@ -43,7 +43,7 @@ namespace fc variant _value; }; - typedef vector< entry >::const_iterator iterator; + typedef std::vector< entry >::const_iterator iterator; /** * @name Immutable Interface @@ -69,7 +69,7 @@ namespace fc template variant_object( string key, T&& val ) - :_key_value( std::make_shared >() ) + :_key_value( std::make_shared >() ) { *this = variant_object( move(key), variant(forward(val)) ); } @@ -86,7 +86,7 @@ namespace fc variant_object& operator=( const mutable_variant_object& ); private: - std::shared_ptr< vector< entry > > _key_value; + std::shared_ptr< std::vector< entry > > _key_value; friend class mutable_variant_object; }; /** @ingroup Serializable */ @@ -112,8 +112,8 @@ namespace fc /** @brief a key/value pair */ typedef variant_object::entry entry; - typedef vector< entry >::iterator iterator; - typedef vector< entry >::const_iterator const_iterator; + typedef std::vector< entry >::iterator iterator; + typedef std::vector< entry >::const_iterator const_iterator; /** * @name Immutable Interface @@ -181,7 +181,7 @@ namespace fc template explicit mutable_variant_object( T&& v ) - :_key_value( new vector() ) + :_key_value( new std::vector() ) { *this = variant(fc::forward(v)).get_object(); } @@ -192,7 +192,7 @@ namespace fc mutable_variant_object( string key, variant val ); template mutable_variant_object( string key, T&& val ) - :_key_value( new vector() ) + :_key_value( new std::vector() ) { set( move(key), variant(forward(val)) ); } @@ -205,7 +205,7 @@ namespace fc mutable_variant_object& operator=( const mutable_variant_object& ); mutable_variant_object& operator=( const variant_object& ); private: - std::unique_ptr< vector< entry > > _key_value; + std::unique_ptr< std::vector< entry > > _key_value; friend class variant_object; }; /** @ingroup Serializable */ diff --git a/include/fc/vector.hpp b/include/fc/vector.hpp index 9220777..bb43f62 100644 --- a/include/fc/vector.hpp +++ b/include/fc/vector.hpp @@ -3,7 +3,15 @@ #include #include #include +#include +namespace fc +{ + template + using vector = std::vector; +} + +#if 0 namespace fc { namespace detail { @@ -400,3 +408,4 @@ namespace fc { }; +#endif diff --git a/src/crypto/base58.cpp b/src/crypto/base58.cpp index aeffe3f..f86a983 100644 --- a/src/crypto/base58.cpp +++ b/src/crypto/base58.cpp @@ -609,12 +609,12 @@ fc::string to_base58( const char* d, size_t s ) { return EncodeBase58( (const unsigned char*)d, (const unsigned char*)d+s ).c_str(); } -fc::vector from_base58( const fc::string& base58_str ) { +std::vector from_base58( const fc::string& base58_str ) { std::vector out; if( !DecodeBase58( base58_str.c_str(), out ) ) { FC_THROW_EXCEPTION( exception, "Unable to decode base58 string ${base58_str}", ("base58_str",base58_str) ); } - return fc::vector((const char*)out.data(), ((const char*)out.data())+out.size() ); + return std::vector((const char*)out.data(), ((const char*)out.data())+out.size() ); } /** * @return the number of bytes decoded diff --git a/src/crypto/sha256.cpp b/src/crypto/sha256.cpp index 0e4526e..63b38cc 100644 --- a/src/crypto/sha256.cpp +++ b/src/crypto/sha256.cpp @@ -85,11 +85,11 @@ namespace fc { void to_variant( const sha256& bi, variant& v ) { - v = fc::vector( (const char*)&bi, ((const char*)&bi) + sizeof(bi) ); + v = std::vector( (const char*)&bi, ((const char*)&bi) + sizeof(bi) ); } void from_variant( const variant& v, sha256& bi ) { - fc::vector ve = v.as< vector >(); + std::vector ve = v.as< std::vector >(); if( ve.size() ) { memcpy(&bi, ve.data(), fc::min(ve.size(),sizeof(bi)) ); diff --git a/src/crypto/sha512.cpp b/src/crypto/sha512.cpp index 0c598c5..d177fe3 100644 --- a/src/crypto/sha512.cpp +++ b/src/crypto/sha512.cpp @@ -89,11 +89,11 @@ namespace fc { void to_variant( const sha512& bi, variant& v ) { - v = fc::vector( (const char*)&bi, ((const char*)&bi) + sizeof(bi) ); + v = std::vector( (const char*)&bi, ((const char*)&bi) + sizeof(bi) ); } void from_variant( const variant& v, sha512& bi ) { - fc::vector ve = v.as< vector >(); + std::vector ve = v.as< std::vector >(); if( ve.size() ) { memcpy(&bi, ve.data(), fc::min(ve.size(),sizeof(bi)) ); diff --git a/src/network/resolve.cpp b/src/network/resolve.cpp index ec6b159..f5cbaf8 100644 --- a/src/network/resolve.cpp +++ b/src/network/resolve.cpp @@ -3,10 +3,10 @@ namespace fc { - fc::vector resolve( const fc::string& host, uint16_t port ) + std::vector resolve( const fc::string& host, uint16_t port ) { auto ep = fc::asio::tcp::resolve( host, std::to_string(uint64_t(port)) ); - fc::vector eps; + std::vector eps; eps.reserve(ep.size()); for( auto itr = ep.begin(); itr != ep.end(); ++itr ) eps.push_back( fc::ip::endpoint(itr->address().to_v4().to_ulong(), itr->port()) ); diff --git a/src/variant.cpp b/src/variant.cpp index 90e4cf7..8adab43 100644 --- a/src/variant.cpp +++ b/src/variant.cpp @@ -14,16 +14,16 @@ namespace fc void to_variant( const uint16_t& var, variant& vo ) { vo = uint64_t(var); } // TODO: warn on overflow? void from_variant( const variant& var, uint16_t& vo ){ vo = static_cast(var.as_uint64()); } -void to_variant( const vector& var, variant& vo ) +void to_variant( const std::vector& var, variant& vo ) { if( var.size() ) vo = variant(base64_encode((unsigned char*)var.data(),var.size())); else vo = ""; } -void from_variant( const variant& var, vector& vo ) +void from_variant( const variant& var, std::vector& vo ) { std::string b64 = base64_decode( var.as_string() ); - vo = fc::vector( b64.c_str(), b64.c_str() + b64.size() ); + vo = std::vector( b64.c_str(), b64.c_str() + b64.size() ); } /** * The TypeID is stored in the 'last byte' of the variant. diff --git a/src/variant_object.cpp b/src/variant_object.cpp index 6f5428e..f3cb488 100644 --- a/src/variant_object.cpp +++ b/src/variant_object.cpp @@ -96,12 +96,12 @@ namespace fc } variant_object::variant_object() - :_key_value(std::make_shared>() ) + :_key_value(std::make_shared>() ) { } variant_object::variant_object( string key, variant val ) - : _key_value(std::make_shared>()) + : _key_value(std::make_shared>()) { //_key_value->push_back(entry(fc::move(key), fc::move(val))); _key_value->emplace_back(entry(fc::move(key), fc::move(val))); @@ -116,12 +116,12 @@ namespace fc variant_object::variant_object( variant_object&& obj) : _key_value( fc::move(obj._key_value) ) { - obj._key_value = std::make_shared>(); + obj._key_value = std::make_shared>(); assert( _key_value != nullptr ); } variant_object::variant_object( const mutable_variant_object& obj ) - : _key_value(std::make_shared>(*obj._key_value)) + : _key_value(std::make_shared>(*obj._key_value)) { } @@ -153,7 +153,7 @@ namespace fc variant_object& variant_object::operator=( mutable_variant_object&& obj ) { _key_value = fc::move(obj._key_value); - obj._key_value.reset( new fc::vector() ); + obj._key_value.reset( new std::vector() ); return *this; } @@ -260,23 +260,23 @@ namespace fc } mutable_variant_object::mutable_variant_object() - :_key_value(new fc::vector) + :_key_value(new std::vector) { } mutable_variant_object::mutable_variant_object( string key, variant val ) - : _key_value(new fc::vector()) + : _key_value(new std::vector()) { _key_value->push_back(entry(fc::move(key), fc::move(val))); } mutable_variant_object::mutable_variant_object( const variant_object& obj ) - : _key_value( new fc::vector(*obj._key_value) ) + : _key_value( new std::vector(*obj._key_value) ) { } mutable_variant_object::mutable_variant_object( const mutable_variant_object& obj ) - : _key_value( new fc::vector(*obj._key_value) ) + : _key_value( new std::vector(*obj._key_value) ) { } From a4a00717efcf0941c37baf8df187bcb6a316d2e2 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Thu, 6 Jun 2013 23:42:20 -0400 Subject: [PATCH 5/8] restore json pretty print --- src/io/json.cpp | 87 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) diff --git a/src/io/json.cpp b/src/io/json.cpp index c2fa1a8..f280447 100644 --- a/src/io/json.cpp +++ b/src/io/json.cpp @@ -443,9 +443,94 @@ namespace fc return ss.str(); } + + fc::string pretty_print( const fc::string& v, uint8_t indent ) { + int level = 0; + fc::stringstream ss; + bool first = false; + bool quote = false; + bool escape = false; + for( uint32_t i = 0; i < v.size(); ++i ) { + switch( v[i] ) { + case '\\': + if( !escape ) { + if( quote ) + escape = true; + } else { escape = false; } + ss< Date: Fri, 7 Jun 2013 15:59:01 -0400 Subject: [PATCH 6/8] adding variant support to sha1 --- include/fc/crypto/sha1.hpp | 4 ++++ src/crypto/sha1.cpp | 17 +++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/include/fc/crypto/sha1.hpp b/include/fc/crypto/sha1.hpp index e91503e..568dacf 100644 --- a/include/fc/crypto/sha1.hpp +++ b/include/fc/crypto/sha1.hpp @@ -64,4 +64,8 @@ class sha1 uint32_t _hash[5]; }; + class variant; + void to_variant( const sha1& bi, variant& v ); + void from_variant( const variant& v, sha1& bi ); + } // namespace fc diff --git a/src/crypto/sha1.cpp b/src/crypto/sha1.cpp index 2617d97..479d1ed 100644 --- a/src/crypto/sha1.cpp +++ b/src/crypto/sha1.cpp @@ -3,6 +3,8 @@ #include #include #include +#include +#include namespace fc { @@ -84,4 +86,19 @@ bool operator == ( const sha1& h1, const sha1& h2 ) { return memcmp( h1._hash, h2._hash, sizeof(h1._hash) ) == 0; } + void to_variant( const sha1& bi, variant& v ) + { + v = std::vector( (const char*)&bi, ((const char*)&bi) + sizeof(bi) ); + } + void from_variant( const variant& v, sha1& bi ) + { + std::vector ve = v.as< std::vector >(); + if( ve.size() ) + { + memcpy(&bi, ve.data(), fc::min(ve.size(),sizeof(bi)) ); + } + else + memset( &bi, char(0), sizeof(bi) ); + } + } // fc From 726e25d5378bd4311d9ea723eca5e70667e8a4a3 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Fri, 7 Jun 2013 18:59:08 -0400 Subject: [PATCH 7/8] adding sha224 --- CMakeLists.txt | 1 + include/fc/crypto/sha224.hpp | 73 +++++++++++++++++++++++++ src/crypto/sha224.cpp | 100 +++++++++++++++++++++++++++++++++++ 3 files changed, 174 insertions(+) create mode 100644 include/fc/crypto/sha224.hpp create mode 100644 src/crypto/sha224.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index dff9373..fba76e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,6 +105,7 @@ set( fc_sources src/crypto/hex.cpp src/crypto/sha1.cpp src/crypto/sha256.cpp + src/crypto/sha224.cpp src/crypto/sha512.cpp src/crypto/dh.cpp src/crypto/blowfish.cpp diff --git a/include/fc/crypto/sha224.hpp b/include/fc/crypto/sha224.hpp new file mode 100644 index 0000000..bc70146 --- /dev/null +++ b/include/fc/crypto/sha224.hpp @@ -0,0 +1,73 @@ +#pragma once +#include +#include + +namespace fc +{ + +class sha224 +{ + public: + sha224(); + explicit sha224( const string& hex_str ); + + string str()const; + operator string()const; + + char* data()const; + + static sha224 hash( const char* d, uint32_t dlen ); + static sha224 hash( const string& ); + + template + static sha224 hash( const T& t ) + { + sha224::encoder e; + 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(); + sha224 result(); + + private: + struct impl; + fc::fwd my; + }; + + template + inline friend T& operator<<( T& ds, const sha224& ep ) { + ds.write( ep.data(), sizeof(ep) ); + return ds; + } + + template + inline friend T& operator>>( T& ds, sha224& ep ) { + ds.read( ep.data(), sizeof(ep) ); + return ds; + } + friend sha224 operator << ( const sha224& h1, uint32_t i ); + friend bool operator == ( const sha224& h1, const sha224& h2 ); + friend bool operator != ( const sha224& h1, const sha224& h2 ); + friend sha224 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 bool operator < ( const sha224& h1, const sha224& h2 ); + + uint64_t _hash[3]; + uint32_t _hash4; +}; + + class variant; + void to_variant( const sha224& bi, variant& v ); + void from_variant( const variant& v, sha224& bi ); + +} // fc diff --git a/src/crypto/sha224.cpp b/src/crypto/sha224.cpp new file mode 100644 index 0000000..cc8056e --- /dev/null +++ b/src/crypto/sha224.cpp @@ -0,0 +1,100 @@ +#include +#include +#include +#include +#include +#include + +namespace fc { + + sha224::sha224() { memset( _hash, 0, sizeof(_hash) ); } + sha224::sha224( const string& hex_str ) { + fc::from_hex( hex_str, (char*)_hash, sizeof(_hash) ); + } + + string sha224::str()const { + return fc::to_hex( (char*)_hash, sizeof(_hash) ); + } + sha224::operator string()const { return str(); } + + char* sha224::data()const { return (char*)&_hash[0]; } + + + struct sha224::encoder::impl { + SHA256_CTX ctx; + }; + + sha224::encoder::~encoder() {} + sha224::encoder::encoder() { + reset(); + } + + sha224 sha224::hash( const char* d, uint32_t dlen ) { + encoder e; + e.write(d,dlen); + return e.result(); + } + sha224 sha224::hash( const string& s ) { + return hash( s.c_str(), s.size() ); + } + + void sha224::encoder::write( const char* d, uint32_t dlen ) { + SHA224_Update( &my->ctx, d, dlen); + } + sha224 sha224::encoder::result() { + sha224 h; + SHA224_Final((uint8_t*)h.data(), &my->ctx ); + return h; + } + void sha224::encoder::reset() { + SHA224_Init( &my->ctx); + } + + sha224 operator << ( const sha224& h1, uint32_t i ) { + sha224 result; + uint8_t* r = (uint8_t*)&result;//result._hash; + uint8_t* s = (uint8_t*)&h1;//h1._hash; + for( uint32_t p = 0; p < sizeof(sha224)-1; ++p ) + r[p] = s[p] << i | (s[p+1]>>(8-i)); + r[sizeof(sha224)-1] = s[sizeof(sha224)-1] << i; + return result; + } + sha224 operator ^ ( const sha224& h1, const sha224& h2 ) { + sha224 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._hash4 = h1._hash4 ^ h2._hash4; + return result; + } + bool operator >= ( const sha224& h1, const sha224& h2 ) { + return memcmp( h1._hash, h2._hash, sizeof(sha224) ) >= 0; + } + bool operator > ( const sha224& h1, const sha224& h2 ) { + return memcmp( h1._hash, h2._hash, sizeof(sha224) ) > 0; + } + bool operator < ( const sha224& h1, const sha224& h2 ) { + return memcmp( h1._hash, h2._hash, sizeof(sha224) ) < 0; + } + bool operator != ( const sha224& h1, const sha224& h2 ) { + return memcmp( h1._hash, h2._hash, sizeof(sha224) ) != 0; + } + bool operator == ( const sha224& h1, const sha224& h2 ) { + return memcmp( h1._hash, h2._hash, sizeof(sha224) ) == 0; + } + + void to_variant( const sha224& bi, variant& v ) + { + v = std::vector( (const char*)&bi, ((const char*)&bi) + sizeof(bi) ); + } + void from_variant( const variant& v, sha224& bi ) + { + std::vector ve = v.as< std::vector >(); + if( ve.size() ) + { + memcpy(&bi, ve.data(), fc::min(ve.size(),sizeof(bi)) ); + } + else + memset( &bi, char(0), sizeof(bi) ); + } +} From cd28770debf4e243a2854b1f77290e3d8a4fd068 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Thu, 27 Jun 2013 14:18:02 -0400 Subject: [PATCH 8/8] Updating crypto functions. --- include/fc/crypto/elliptic.hpp | 3 +- include/fc/crypto/sha1.hpp | 14 +++++++ include/fc/crypto/sha224.hpp | 13 ++++++ include/fc/reflect/reflect.hpp | 1 + include/fc/variant.hpp | 25 ++++++++++++ src/crypto/elliptic.cpp | 72 +++++++++++++++++++++++++++++++++- 6 files changed, 125 insertions(+), 3 deletions(-) diff --git a/include/fc/crypto/elliptic.hpp b/include/fc/crypto/elliptic.hpp index b6190e9..7aac348 100644 --- a/include/fc/crypto/elliptic.hpp +++ b/include/fc/crypto/elliptic.hpp @@ -31,6 +31,7 @@ namespace fc { public_key( const compact_signature& c, const fc::sha256& digest ); bool valid()const; + public_key mult( const fc::sha256& digest ); public_key( public_key&& pk ); public_key& operator=( public_key&& pk ); @@ -65,7 +66,7 @@ namespace fc { fc::sha512 get_shared_secret( const public_key& pub ); signature sign( const fc::sha256& digest ); - compact_signature sign_compact( const fc::sha256& digest ); + compact_signature sign_compact( const fc::sha256& digest )const; bool verify( const fc::sha256& digest, const signature& sig ); public_key get_public_key()const; diff --git a/include/fc/crypto/sha1.hpp b/include/fc/crypto/sha1.hpp index 568dacf..991ae57 100644 --- a/include/fc/crypto/sha1.hpp +++ b/include/fc/crypto/sha1.hpp @@ -69,3 +69,17 @@ class sha1 void from_variant( const variant& v, sha1& bi ); } // namespace fc + +namespace std +{ + template struct hash; + + template<> + struct hash + { + size_t operator()( const fc::sha1& s )const + { + return *((size_t*)&s); + } + }; +} diff --git a/include/fc/crypto/sha224.hpp b/include/fc/crypto/sha224.hpp index bc70146..4097e1d 100644 --- a/include/fc/crypto/sha224.hpp +++ b/include/fc/crypto/sha224.hpp @@ -71,3 +71,16 @@ class sha224 void from_variant( const variant& v, sha224& bi ); } // fc +namespace std +{ + template struct hash; + + template<> + struct hash + { + size_t operator()( const fc::sha224& s )const + { + return *((size_t*)&s); + } + }; +} diff --git a/include/fc/reflect/reflect.hpp b/include/fc/reflect/reflect.hpp index 57bf64a..502e5f4 100644 --- a/include/fc/reflect/reflect.hpp +++ b/include/fc/reflect/reflect.hpp @@ -13,6 +13,7 @@ #include #include #include +#include #include diff --git a/include/fc/variant.hpp b/include/fc/variant.hpp index cf4e64e..4ab20eb 100644 --- a/include/fc/variant.hpp +++ b/include/fc/variant.hpp @@ -4,6 +4,7 @@ #include #include #include // memset +#include namespace fc { @@ -38,6 +39,12 @@ namespace fc void from_variant( const variant& var, mutable_variant_object& vo ); void to_variant( const std::vector& var, variant& vo ); void from_variant( const variant& var, std::vector& vo ); + + template + void to_variant( const std::unordered_set& var, variant& vo ); + template + void from_variant( const variant& var, std::unordered_set& vo ); + void to_variant( const time_point& var, variant& vo ); void from_variant( const variant& var, time_point& vo ); #ifdef __APPLE__ @@ -244,6 +251,24 @@ namespace fc from_variant( var, *vo ); } } + template + void to_variant( const std::unordered_set& var, variant& vo ) + { + std::vector vars(var.size()); + size_t i = 0; + for( auto itr = var.begin(); itr != var.end(); ++itr ) + vars[i] = variant(*itr); + vo = vars; + } + template + void from_variant( const variant& var, std::unordered_set& vo ) + { + const variants& vars = var.get_array(); + vo.clear(); + vo.reserve( vars.size() ); + for( auto itr = vars.begin(); itr != vars.end(); ++itr ) + vo.insert( itr->as() ); + } /** @ingroup Serializable */ template diff --git a/src/crypto/elliptic.cpp b/src/crypto/elliptic.cpp index bc918c5..572989b 100644 --- a/src/crypto/elliptic.cpp +++ b/src/crypto/elliptic.cpp @@ -11,6 +11,50 @@ #include namespace fc { namespace ecc { + +template +struct ssl_wrapper +{ + ssl_wrapper(ssl_type* obj) + : obj(obj) {} + virtual ~ssl_wrapper() + { + } + operator ssl_type*() + { + return obj; + } + + ssl_type* obj; +}; + +struct ssl_bignum + : public ssl_wrapper +{ + ssl_bignum() + : ssl_wrapper(BN_new()) {} + ~ssl_bignum() + { + BN_free(obj); + } +}; + + #define SSL_TYPE(name, ssl_type, free_func) \ + struct name \ + : public ssl_wrapper \ + { \ + name(ssl_type* obj) \ + : ssl_wrapper(obj) {} \ + ~name() \ + { \ + free_func(obj); \ + } \ + }; + + SSL_TYPE(ec_group, EC_GROUP, EC_GROUP_free) + SSL_TYPE(ec_point, EC_POINT, EC_POINT_free) + SSL_TYPE(bn_ctx, BN_CTX, BN_CTX_free) + namespace detail { class public_key_impl @@ -188,6 +232,30 @@ namespace fc { namespace ecc { } */ + public_key public_key::mult( const fc::sha256& digest ) + { + // get point from this public key + const EC_POINT* master_pub = EC_KEY_get0_public_key( my->_key ); + ec_group group(EC_GROUP_new_by_curve_name(NID_secp256k1)); + + ssl_bignum z; + BN_bin2bn((unsigned char*)&digest, sizeof(digest), z); + + // multiply by digest + ssl_bignum one; + bn_ctx ctx(BN_CTX_new()); + BN_one(one); + + ec_point result(EC_POINT_new(group)); + EC_POINT_mul(group, result, z, master_pub, one, ctx); + + public_key rtn; + rtn.my->_key = EC_KEY_new_by_curve_name( NID_secp256k1 ); + EC_KEY_set_public_key(rtn.my->_key,result); + + return rtn; + } + private_key::private_key() {} @@ -275,7 +343,7 @@ namespace fc { namespace ecc { public_key_data public_key::serialize()const { EC_KEY_set_conv_form( my->_key, POINT_CONVERSION_COMPRESSED ); - size_t nbytes = i2o_ECPublicKey( my->_key, nullptr ); + /*size_t nbytes = */i2o_ECPublicKey( my->_key, nullptr ); assert( nbytes == 33 ); public_key_data dat; char* front = &dat.data[0]; @@ -384,7 +452,7 @@ namespace fc { namespace ecc { FC_THROW_EXCEPTION( exception, "unable to reconstruct public key from signature" ); } - compact_signature private_key::sign_compact( const fc::sha256& digest ) + compact_signature private_key::sign_compact( const fc::sha256& digest )const { ECDSA_SIG *sig = ECDSA_do_sign((unsigned char*)&digest, sizeof(digest), my->_key);