diff --git a/src/crypto/_elliptic_common.cpp b/src/crypto/_elliptic_common.cpp index 66d19d7..12c8c63 100644 --- a/src/crypto/_elliptic_common.cpp +++ b/src/crypto/_elliptic_common.cpp @@ -1,15 +1,17 @@ -#include - -#include -#include - -#include -#include -#include - -#include - namespace fc { namespace ecc { + public_key::public_key() {} + + public_key::~public_key() {} + + public_key::public_key( const public_key& pk ) : my( pk.my ) {} + + public_key::public_key( public_key&& pk ) : my( std::move(pk.my) ) {} + + bool public_key::valid()const + { + return my->_key != nullptr; + } + std::string public_key::to_base58( const public_key_data &key ) { uint32_t check = (uint32_t)sha256::hash(key.data, sizeof(key))._hash[0]; @@ -40,6 +42,14 @@ namespace fc { namespace ecc { && !(c.data[33] == 0 && !(c.data[34] & 0x80)); } + private_key::private_key() {} + + private_key::~private_key() {} + + private_key::private_key( const private_key& pk ) : my(pk.my) {} + + private_key::private_key( private_key&& pk ) : my( std::move( pk.my) ) {} + private_key private_key::generate_from_seed( const fc::sha256& seed, const fc::sha256& offset ) { ssl_bignum z; @@ -93,26 +103,53 @@ namespace fc { namespace ecc { return private_key( k ); } + + private_key& private_key::operator=( private_key&& pk ) + { + my = std::move(pk.my); + return *this; + } + + public_key& public_key::operator=( public_key&& pk ) + { + my = std::move(pk.my); + return *this; + } + + public_key& public_key::operator=( const public_key& pk ) + { + my = pk.my; + return *this; + } + + private_key& private_key::operator=( const private_key& pk ) + { + my = pk.my; + return *this; + } } - void to_variant( const ecc::private_key& var, variant& vo ) - { + +void to_variant( const ecc::private_key& var, variant& vo ) +{ vo = var.get_secret(); - } - void from_variant( const variant& var, ecc::private_key& vo ) - { +} + +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 ) - { +void to_variant( const ecc::public_key& var, variant& vo ) +{ vo = var.serialize(); - } - void from_variant( const variant& var, ecc::public_key& vo ) - { +} + +void from_variant( const variant& var, ecc::public_key& vo ) +{ ecc::public_key_data dat; from_variant( var, dat ); vo = ecc::public_key(dat); - } +} } diff --git a/src/crypto/_elliptic_impl.cpp b/src/crypto/_elliptic_impl.cpp new file mode 100644 index 0000000..916e0a1 --- /dev/null +++ b/src/crypto/_elliptic_impl.cpp @@ -0,0 +1,107 @@ +class public_key_impl +{ + public: + public_key_impl() : _key(nullptr) + { + init_lib(); + } + + public_key_impl( const public_key_impl& cpy ) : _key(nullptr) + { + init_lib(); + *this = cpy; + } + + public_key_impl( public_key_impl&& cpy ) : _key(nullptr) + { + init_lib(); + *this = cpy; + } + + ~public_key_impl() + { + free_key(); + } + + public_key_impl& operator=( const public_key_impl& pk ) + { + if (pk._key == nullptr) + { + free_key(); + } else if ( _key == nullptr ) { + _key = dup_key( pk._key ); + } else { + copy_key( _key, pk._key ); + } + return *this; + } + + public_key_impl& operator=( public_key_impl&& pk ) + { + free_key(); + _key = pk._key; + pk._key = nullptr; + return *this; + } + + pub_data_type* _key; + + private: + void free_key(); + pub_data_type* dup_key( const pub_data_type* cpy ); + void copy_key( pub_data_type* to, const pub_data_type* from ); +}; + +class private_key_impl +{ + public: + private_key_impl() : _key(nullptr) + { + init_lib(); + } + + private_key_impl( const private_key_impl& cpy ) : _key(nullptr) + { + init_lib(); + *this = cpy; + } + + private_key_impl( private_key_impl&& cpy ) : _key(nullptr) + { + init_lib(); + *this = cpy; + } + + ~private_key_impl() + { + free_key(); + } + + private_key_impl& operator=( const private_key_impl& pk ) + { + if (pk._key == nullptr) + { + free_key(); + } else if ( _key == nullptr ) { + _key = dup_key( pk._key ); + } else { + copy_key( _key, pk._key ); + } + return *this; + } + + private_key_impl& operator=( private_key_impl&& pk ) + { + free_key(); + _key = pk._key; + pk._key = nullptr; + return *this; + } + + priv_data_type* _key; + + private: + void free_key(); + priv_data_type* dup_key( const priv_data_type* cpy ); + void copy_key( priv_data_type* to, const priv_data_type* from ); +}; diff --git a/src/crypto/elliptic_openssl.cpp b/src/crypto/elliptic_openssl.cpp index eef3d9e..6a67788 100644 --- a/src/crypto/elliptic_openssl.cpp +++ b/src/crypto/elliptic_openssl.cpp @@ -12,50 +12,59 @@ namespace fc { namespace ecc { namespace detail { - class public_key_impl - { - public: - public_key_impl() - :_key(nullptr) - { - static int init = init_openssl(); - } + static void init_lib() + { + static int init = init_openssl(); + } - ~public_key_impl() - { + typedef EC_KEY pub_data_type; + typedef EC_KEY priv_data_type; + + #include "_elliptic_impl.cpp" + + void public_key_impl::free_key() + { if( _key != nullptr ) { - EC_KEY_free(_key); + EC_KEY_free(_key); + _key = nullptr; } - } - public_key_impl( const public_key_impl& cpy ) - { - _key = cpy._key ? EC_KEY_dup( cpy._key ) : nullptr; - } - EC_KEY* _key; - }; - class private_key_impl - { - public: - private_key_impl() - :_key(nullptr) - { - static int init = init_openssl(); - } - ~private_key_impl() - { + } + + EC_KEY* public_key_impl::dup_key( const EC_KEY* cpy ) + { + return EC_KEY_dup( cpy ); + } + + void public_key_impl::copy_key( EC_KEY* to, const EC_KEY* from ) + { + // Group parameters etc. never change + EC_KEY_set_public_key( to, EC_KEY_get0_public_key( from ) ); + EC_KEY_set_private_key( to, EC_KEY_get0_private_key( from ) ); + } + + void private_key_impl::free_key() + { if( _key != nullptr ) { - EC_KEY_free(_key); + EC_KEY_free(_key); + _key = nullptr; } - } - private_key_impl( const private_key_impl& cpy ) - { - _key = cpy._key ? EC_KEY_dup( cpy._key ) : nullptr; - } - EC_KEY* _key; - }; + } + + EC_KEY* private_key_impl::dup_key( const EC_KEY* cpy ) + { + return EC_KEY_dup( cpy ); + } + + void private_key_impl::copy_key( EC_KEY* to, const EC_KEY* from ) + { + // Group parameters etc. never change + EC_KEY_set_public_key( to, EC_KEY_get0_public_key( from ) ); + EC_KEY_set_private_key( to, EC_KEY_get0_private_key( from ) ); + } } + static void * ecies_key_derivation(const void *input, size_t ilen, void *output, size_t *olen) { if (*olen < SHA512_DIGEST_LENGTH) { @@ -204,10 +213,6 @@ namespace fc { namespace ecc { // // return rtn; // } - bool public_key::valid()const - { - return my->_key != nullptr; - } public_key public_key::add( const fc::sha256& digest )const { try { @@ -259,9 +264,6 @@ namespace fc { namespace ecc { return to_base58( key ); } - private_key::private_key() - {} - private_key private_key::regenerate( const fc::sha256& secret ) { private_key self; @@ -336,14 +338,6 @@ namespace fc { namespace ecc { return dat; } - public_key::public_key() - { - } - - public_key::~public_key() - { - } - public_key::public_key( const public_key_point_data& dat ) { const char* front = &dat.data[0]; @@ -396,10 +390,6 @@ namespace fc { namespace ecc { return buf; } - private_key::~private_key() - { - } - public_key::public_key( const compact_signature& c, const fc::sha256& digest, bool check_canonical ) { int nV = c.data[0]; @@ -500,66 +490,6 @@ namespace fc { namespace ecc { } // while true } FC_RETHROW_EXCEPTIONS( warn, "sign ${digest}", ("digest", digest)("private_key",*this) ); } - - 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; - } } } diff --git a/src/crypto/elliptic_secp256k1.cpp b/src/crypto/elliptic_secp256k1.cpp index 73ecf24..dca9d99 100644 --- a/src/crypto/elliptic_secp256k1.cpp +++ b/src/crypto/elliptic_secp256k1.cpp @@ -22,265 +22,54 @@ namespace fc { namespace ecc { } } - class public_key_impl - { - public: - public_key_impl() : _key(nullptr) - { - init_lib(); - } + typedef public_key_data pub_data_type; + typedef private_key_secret priv_data_type; - public_key_impl( const public_key_impl& cpy ) - { - init_lib(); - _key = nullptr; - *this = cpy; - } + #include "_elliptic_impl.cpp" - public_key_impl( public_key_impl&& cpy ) - { - init_lib(); - _key = nullptr; - *this = cpy; - } - - ~public_key_impl() - { + void public_key_impl::free_key() + { if( _key != nullptr ) { - delete _key; - _key = nullptr; + delete _key; + _key = nullptr; } - } + } - public_key_impl& operator=( const public_key_impl& pk ) - { - if (pk._key == nullptr) - { - if (_key != nullptr) - { - delete _key; - _key = nullptr; - } - } else if ( _key == nullptr ) { - _key = new public_key_data(*pk._key); - } else { - *_key = *pk._key; - } - return *this; - } + public_key_data* public_key_impl::dup_key( const public_key_data* cpy ) + { + return new public_key_data( *cpy ); + } - public_key_impl& operator=( public_key_impl&& pk ) - { - if (_key != nullptr) - { - delete _key; - } - _key = pk._key; - pk._key = nullptr; - return *this; - } + void public_key_impl::copy_key( public_key_data* to, const public_key_data* from ) + { + *to = *from; + } - public_key_data *_key; - }; - class private_key_impl - { - public: - private_key_impl() : _key(nullptr) - { - init_lib(); - } - - private_key_impl( const private_key_impl& cpy ) - { - init_lib(); - _key = nullptr; - *this = cpy; - } - - private_key_impl( private_key_impl&& cpy ) - { - init_lib(); - _key = nullptr; - *this = cpy; - } - - ~private_key_impl() - { + void private_key_impl::free_key() + { if( _key != nullptr ) { - delete _key; - _key = nullptr; + delete _key; + _key = nullptr; } - } + } - private_key_impl& operator=( const private_key_impl& pk ) - { - if (pk._key == nullptr) - { - if (_key != nullptr) - { - delete _key; - _key = nullptr; - } - } else if ( _key == nullptr ) { - _key = new private_key_secret(*pk._key); - } else { - *_key = *pk._key; - } - return *this; - } + private_key_secret* private_key_impl::dup_key( const private_key_secret* cpy ) + { + return new private_key_secret( *cpy ); + } - private_key_impl& operator=( private_key_impl&& pk ) - { - if (_key != nullptr) - { - delete _key; - } - _key = pk._key; - pk._key = nullptr; - return *this; - } - - private_key_secret *_key; - }; + void private_key_impl::copy_key( private_key_secret* to, const private_key_secret* from ) + { + *to = *from; + } } -// static void * ecies_key_derivation(const void *input, size_t ilen, void *output, size_t *olen) -// { -// if (*olen < SHA512_DIGEST_LENGTH) { -// return NULL; -// } -// *olen = SHA512_DIGEST_LENGTH; -// return (void*)SHA512((const unsigned char*)input, ilen, (unsigned char*)output); -// } -// -// // Perform ECDSA key recovery (see SEC1 4.1.6) for curves over (mod p)-fields -// // recid selects which key is recovered -// // if check is non-zero, additional checks are performed -// static int ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned char *msg, int msglen, int recid, int check) -// { -// if (!eckey) FC_THROW_EXCEPTION( exception, "null key" ); -// -// int ret = 0; -// BN_CTX *ctx = NULL; -// -// BIGNUM *x = NULL; -// BIGNUM *e = NULL; -// BIGNUM *order = NULL; -// BIGNUM *sor = NULL; -// BIGNUM *eor = NULL; -// BIGNUM *field = NULL; -// EC_POINT *R = NULL; -// EC_POINT *O = NULL; -// EC_POINT *Q = NULL; -// BIGNUM *rr = NULL; -// BIGNUM *zero = NULL; -// int n = 0; -// int i = recid / 2; -// -// const EC_GROUP *group = EC_KEY_get0_group(eckey); -// if ((ctx = BN_CTX_new()) == NULL) { ret = -1; goto err; } -// BN_CTX_start(ctx); -// order = BN_CTX_get(ctx); -// if (!EC_GROUP_get_order(group, order, ctx)) { ret = -2; goto err; } -// x = BN_CTX_get(ctx); -// if (!BN_copy(x, order)) { ret=-1; goto err; } -// if (!BN_mul_word(x, i)) { ret=-1; goto err; } -// if (!BN_add(x, x, ecsig->r)) { ret=-1; goto err; } -// field = BN_CTX_get(ctx); -// if (!EC_GROUP_get_curve_GFp(group, field, NULL, NULL, ctx)) { ret=-2; goto err; } -// if (BN_cmp(x, field) >= 0) { ret=0; goto err; } -// if ((R = EC_POINT_new(group)) == NULL) { ret = -2; goto err; } -// if (!EC_POINT_set_compressed_coordinates_GFp(group, R, x, recid % 2, ctx)) { ret=0; goto err; } -// if (check) -// { -// if ((O = EC_POINT_new(group)) == NULL) { ret = -2; goto err; } -// if (!EC_POINT_mul(group, O, NULL, R, order, ctx)) { ret=-2; goto err; } -// if (!EC_POINT_is_at_infinity(group, O)) { ret = 0; goto err; } -// } -// if ((Q = EC_POINT_new(group)) == NULL) { ret = -2; goto err; } -// n = EC_GROUP_get_degree(group); -// e = BN_CTX_get(ctx); -// if (!BN_bin2bn(msg, msglen, e)) { ret=-1; goto err; } -// if (8*msglen > n) BN_rshift(e, e, 8-(n & 7)); -// zero = BN_CTX_get(ctx); -// if (!BN_zero(zero)) { ret=-1; goto err; } -// if (!BN_mod_sub(e, zero, e, order, ctx)) { ret=-1; goto err; } -// rr = BN_CTX_get(ctx); -// if (!BN_mod_inverse(rr, ecsig->r, order, ctx)) { ret=-1; goto err; } -// sor = BN_CTX_get(ctx); -// if (!BN_mod_mul(sor, ecsig->s, rr, order, ctx)) { ret=-1; goto err; } -// eor = BN_CTX_get(ctx); -// if (!BN_mod_mul(eor, e, rr, order, ctx)) { ret=-1; goto err; } -// if (!EC_POINT_mul(group, Q, eor, R, sor, ctx)) { ret=-2; goto err; } -// if (!EC_KEY_set_public_key(eckey, Q)) { ret=-2; goto err; } -// -// ret = 1; -// -// err: -// if (ctx) { -// BN_CTX_end(ctx); -// BN_CTX_free(ctx); -// } -// if (R != NULL) EC_POINT_free(R); -// if (O != NULL) EC_POINT_free(O); -// if (Q != NULL) EC_POINT_free(Q); -// return ret; -// } -// -// -// int static inline EC_KEY_regenerate_key(EC_KEY *eckey, const BIGNUM *priv_key) -// { -// int ok = 0; -// BN_CTX *ctx = NULL; -// EC_POINT *pub_key = NULL; -// -// if (!eckey) return 0; -// -// const EC_GROUP *group = EC_KEY_get0_group(eckey); -// -// if ((ctx = BN_CTX_new()) == NULL) -// goto err; -// -// pub_key = EC_POINT_new(group); -// -// if (pub_key == NULL) -// goto err; -// -// if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) -// goto err; -// -// EC_KEY_set_private_key(eckey,priv_key); -// EC_KEY_set_public_key(eckey,pub_key); -// -// ok = 1; -// -// err: -// -// if (pub_key) EC_POINT_free(pub_key); -// if (ctx != NULL) BN_CTX_free(ctx); -// -// return(ok); -// } public_key public_key::from_key_data( const public_key_data &data ) { return public_key(data); } -// public_key public_key::mult( const fc::sha256& digest )const -// { -// FC_ASSERT( my->_key != nullptr ); -// public_key_data new_key; -// memcpy( new_key.begin(), my->_key->begin(), new_key.size() ); -// FC_ASSERT( secp256k1_ec_pubkey_tweak_mul( (unsigned char*) new_key.begin(), new_key.size(), (unsigned char*) digest.data() ) ); -// return public_key( new_key ); -// } - - bool public_key::valid()const - { - return my->_key != nullptr; - } - public_key public_key::add( const fc::sha256& digest )const { FC_ASSERT( my->_key != nullptr ); @@ -296,9 +85,6 @@ namespace fc { namespace ecc { return to_base58( *my->_key ); } - private_key::private_key() - {} - private_key private_key::regenerate( const fc::sha256& secret ) { private_key self; @@ -334,14 +120,6 @@ namespace fc { namespace ecc { return dat; } - public_key::public_key() - { - } - - public_key::~public_key() - { - } - public_key::public_key( const public_key_point_data& dat ) { const char* front = &dat.data[0]; @@ -382,10 +160,6 @@ namespace fc { namespace ecc { return fc::sha512::hash( pub.begin() + 1, pub.size() - 1 ); } - private_key::~private_key() - { - } - public_key::public_key( const compact_signature& c, const fc::sha256& digest, bool check_canonical ) { int nV = c.data[0]; @@ -415,44 +189,6 @@ namespace fc { namespace ecc { result.begin()[0] = 27 + 4 + recid; return result; } - - private_key& private_key::operator=( private_key&& pk ) - { - my = std::move(pk.my); - return *this; - } - public_key::public_key( const public_key& pk ) - :my(pk.my) - { - } - public_key::public_key( public_key&& pk ) - :my( std::move(pk.my) ) - { - } - private_key::private_key( const private_key& pk ) - :my(pk.my) - { - } - private_key::private_key( private_key&& pk ) - :my( std::move( pk.my) ) - { - } - - public_key& public_key::operator=( public_key&& pk ) - { - my = std::move(pk.my); - return *this; - } - public_key& public_key::operator=( const public_key& pk ) - { - my = pk.my; - return *this; - } - private_key& private_key::operator=( const private_key& pk ) - { - my = pk.my; - return *this; - } } }