Refactoring, step 2

This commit is contained in:
Peter Conrad 2015-03-10 14:47:53 +01:00
parent 55c5773a46
commit 414617d8e3
4 changed files with 241 additions and 431 deletions

View file

@ -1,15 +1,17 @@
#include <fc/crypto/elliptic.hpp>
#include <fc/crypto/base58.hpp>
#include <fc/crypto/openssl.hpp>
#include <fc/fwd_impl.hpp>
#include <fc/exception/exception.hpp>
#include <fc/log/logger.hpp>
#include <assert.h>
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);
}
}
}

View file

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

View file

@ -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;
}
}
}

View file

@ -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;
}
}
}