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);