Some refactoring
This commit is contained in:
parent
0f67ca751e
commit
5ecdcba4b6
6 changed files with 222 additions and 210 deletions
|
|
@ -54,14 +54,9 @@ namespace fc {
|
||||||
typename H::encoder encoder;
|
typename H::encoder encoder;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
typedef hmac<fc::sha224> hmac_sha224;
|
||||||
unsigned int hmac<sha224>::internal_block_size() const { return 64; }
|
typedef hmac<fc::sha256> hmac_sha256;
|
||||||
|
typedef hmac<fc::sha512> hmac_sha512;
|
||||||
template<>
|
|
||||||
unsigned int hmac<sha256>::internal_block_size() const { return 64; }
|
|
||||||
|
|
||||||
template<>
|
|
||||||
unsigned int hmac<sha512>::internal_block_size() const { return 128; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HMAC_HPP */
|
#endif /* HMAC_HPP */
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,71 @@
|
||||||
#include <fc/crypto/base58.hpp>
|
#include <fc/crypto/base58.hpp>
|
||||||
#include <fc/crypto/elliptic.hpp>
|
#include <fc/crypto/elliptic.hpp>
|
||||||
#include <fc/io/raw.hpp>
|
#include <fc/io/raw.hpp>
|
||||||
|
#include <fc/crypto/hmac.hpp>
|
||||||
#include <fc/crypto/ripemd160.hpp>
|
#include <fc/crypto/ripemd160.hpp>
|
||||||
|
|
||||||
/* stuff common to all ecc implementations */
|
/* stuff common to all ecc implementations */
|
||||||
|
|
||||||
|
#define BTC_EXT_PUB_MAGIC (0x0488B21E)
|
||||||
|
#define BTC_EXT_PRIV_MAGIC (0x0488ADE4)
|
||||||
|
|
||||||
namespace fc { namespace ecc {
|
namespace fc { namespace ecc {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
typedef fc::array<char,37> chr37;
|
||||||
|
|
||||||
|
fc::sha256 _left( const fc::sha512& v )
|
||||||
|
{
|
||||||
|
fc::sha256 result;
|
||||||
|
memcpy( result.data(), v.data(), 32 );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
fc::sha256 _right( const fc::sha512& v )
|
||||||
|
{
|
||||||
|
fc::sha256 result;
|
||||||
|
memcpy( result.data(), v.data() + 32, 32 );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _put( unsigned char** dest, unsigned int i)
|
||||||
|
{
|
||||||
|
*(*dest)++ = (i >> 24) & 0xff;
|
||||||
|
*(*dest)++ = (i >> 16) & 0xff;
|
||||||
|
*(*dest)++ = (i >> 8) & 0xff;
|
||||||
|
*(*dest)++ = i & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int _get( unsigned char** src )
|
||||||
|
{
|
||||||
|
unsigned int result = *(*src)++ << 24;
|
||||||
|
result |= *(*src)++ << 16;
|
||||||
|
result |= *(*src)++ << 8;
|
||||||
|
result |= *(*src)++;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static chr37 _derive_message( char first, const char* key32, int i )
|
||||||
|
{
|
||||||
|
chr37 result;
|
||||||
|
unsigned char* dest = (unsigned char*) result.begin();
|
||||||
|
*dest++ = first;
|
||||||
|
memcpy( dest, key32, 32 ); dest += 32;
|
||||||
|
_put( &dest, i );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
chr37 _derive_message( const public_key_data& key, int i )
|
||||||
|
{
|
||||||
|
return _derive_message( *key.begin(), key.begin() + 1, i );
|
||||||
|
}
|
||||||
|
|
||||||
|
static chr37 _derive_message( const private_key_secret& key, int i )
|
||||||
|
{
|
||||||
|
return _derive_message( 0, key.data(), i );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public_key public_key::from_key_data( const public_key_data &data ) {
|
public_key public_key::from_key_data( const public_key_data &data ) {
|
||||||
return public_key(data);
|
return public_key(data);
|
||||||
}
|
}
|
||||||
|
|
@ -120,6 +179,145 @@ namespace fc { namespace ecc {
|
||||||
return private_key( k );
|
return private_key( k );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static fc::string _to_base58( const extended_key_data& key )
|
||||||
|
{
|
||||||
|
char buffer[key.size() + 4];
|
||||||
|
memcpy( buffer, key.begin(), key.size() );
|
||||||
|
fc::sha256 double_hash = fc::sha256::hash( fc::sha256::hash( key.begin(), key.size() ));
|
||||||
|
memcpy( buffer + key.size(), double_hash.data(), 4 );
|
||||||
|
return fc::to_base58( buffer, sizeof(buffer) );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _parse_extended_data( unsigned char* buffer, fc::string base58 )
|
||||||
|
{
|
||||||
|
memset( buffer, 0, 78 );
|
||||||
|
std::vector<char> decoded = fc::from_base58( base58 );
|
||||||
|
unsigned int i = 0;
|
||||||
|
for ( char c : decoded )
|
||||||
|
{
|
||||||
|
if ( i >= 78 || i > decoded.size() - 4 ) { break; }
|
||||||
|
buffer[i++] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extended_public_key extended_public_key::derive_child(int i) const
|
||||||
|
{
|
||||||
|
FC_ASSERT( !(i&0x80000000), "Can't derive hardened public key!" );
|
||||||
|
return derive_normal_child(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
extended_key_data extended_public_key::serialize_extended() const
|
||||||
|
{
|
||||||
|
extended_key_data result;
|
||||||
|
unsigned char* dest = (unsigned char*) result.begin();
|
||||||
|
detail::_put( &dest, BTC_EXT_PUB_MAGIC );
|
||||||
|
*dest++ = depth;
|
||||||
|
detail::_put( &dest, parent_fp );
|
||||||
|
detail::_put( &dest, child_num );
|
||||||
|
memcpy( dest, c.data(), c.data_size() ); dest += 32;
|
||||||
|
public_key_data key = serialize();
|
||||||
|
memcpy( dest, key.begin(), key.size() );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
fc::string extended_public_key::str() const
|
||||||
|
{
|
||||||
|
return _to_base58( serialize_extended() );
|
||||||
|
}
|
||||||
|
|
||||||
|
extended_public_key extended_public_key::from_base58( const fc::string& base58 )
|
||||||
|
{
|
||||||
|
unsigned char buffer[78];
|
||||||
|
unsigned char* ptr = buffer;
|
||||||
|
_parse_extended_data( buffer, base58 );
|
||||||
|
FC_ASSERT( detail::_get( &ptr ) == BTC_EXT_PUB_MAGIC, "Invalid extended private key" );
|
||||||
|
uint8_t d = *ptr++;
|
||||||
|
int fp = detail::_get( &ptr );
|
||||||
|
int cn = detail::_get( &ptr );
|
||||||
|
fc::sha256 chain;
|
||||||
|
memcpy( chain.data(), ptr, chain.data_size() ); ptr += chain.data_size();
|
||||||
|
public_key_data key;
|
||||||
|
memcpy( key.begin(), ptr, key.size() );
|
||||||
|
return extended_public_key( key, chain, cn, fp, d );
|
||||||
|
}
|
||||||
|
|
||||||
|
extended_public_key extended_private_key::get_extended_public_key() const
|
||||||
|
{
|
||||||
|
return extended_public_key( get_public_key(), c, child_num, parent_fp, depth );
|
||||||
|
}
|
||||||
|
|
||||||
|
extended_private_key extended_private_key::derive_child(int i) const
|
||||||
|
{
|
||||||
|
return i < 0 ? derive_hardened_child(i) : derive_normal_child(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
extended_private_key extended_private_key::derive_normal_child(int i) const
|
||||||
|
{
|
||||||
|
const detail::chr37 data = detail::_derive_message( get_public_key().serialize(), i );
|
||||||
|
hmac_sha512 mac;
|
||||||
|
fc::sha512 l = mac.digest( c.data(), c.data_size(), data.begin(), data.size() );
|
||||||
|
return private_derive_rest( l, i );
|
||||||
|
}
|
||||||
|
|
||||||
|
extended_private_key extended_private_key::derive_hardened_child(int i) const
|
||||||
|
{
|
||||||
|
hmac_sha512 mac;
|
||||||
|
private_key_secret key = get_secret();
|
||||||
|
const detail::chr37 data = detail::_derive_message( key, i );
|
||||||
|
fc::sha512 l = mac.digest( c.data(), c.data_size(), data.begin(), data.size() );
|
||||||
|
return private_derive_rest( l, i );
|
||||||
|
}
|
||||||
|
|
||||||
|
extended_key_data extended_private_key::serialize_extended() const
|
||||||
|
{
|
||||||
|
extended_key_data result;
|
||||||
|
unsigned char* dest = (unsigned char*) result.begin();
|
||||||
|
detail::_put( &dest, BTC_EXT_PRIV_MAGIC );
|
||||||
|
*dest++ = depth;
|
||||||
|
detail::_put( &dest, parent_fp );
|
||||||
|
detail::_put( &dest, child_num );
|
||||||
|
memcpy( dest, c.data(), c.data_size() ); dest += 32;
|
||||||
|
*dest++ = 0;
|
||||||
|
private_key_secret key = get_secret();
|
||||||
|
memcpy( dest, key.data(), key.data_size() );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
fc::string extended_private_key::str() const
|
||||||
|
{
|
||||||
|
return _to_base58( serialize_extended() );
|
||||||
|
}
|
||||||
|
|
||||||
|
extended_private_key extended_private_key::from_base58( const fc::string& base58 )
|
||||||
|
{
|
||||||
|
unsigned char buffer[78];
|
||||||
|
unsigned char* ptr = buffer;
|
||||||
|
_parse_extended_data( buffer, base58 );
|
||||||
|
FC_ASSERT( detail::_get( &ptr ) == BTC_EXT_PRIV_MAGIC, "Invalid extended private key" );
|
||||||
|
uint8_t d = *ptr++;
|
||||||
|
int fp = detail::_get( &ptr );
|
||||||
|
int cn = detail::_get( &ptr );
|
||||||
|
fc::sha256 chain;
|
||||||
|
memcpy( chain.data(), ptr, chain.data_size() ); ptr += chain.data_size();
|
||||||
|
ptr++;
|
||||||
|
private_key_secret key;
|
||||||
|
memcpy( key.data(), ptr, key.data_size() );
|
||||||
|
return extended_private_key( private_key::regenerate(key), chain, cn, fp, d );
|
||||||
|
}
|
||||||
|
|
||||||
|
extended_private_key extended_private_key::generate_master( const fc::string& seed )
|
||||||
|
{
|
||||||
|
return generate_master( seed.c_str(), seed.size() );
|
||||||
|
}
|
||||||
|
|
||||||
|
extended_private_key extended_private_key::generate_master( const char* seed, uint32_t seed_len )
|
||||||
|
{
|
||||||
|
hmac_sha512 mac;
|
||||||
|
fc::sha512 hash = mac.digest( "Bitcoin seed", 12, seed, seed_len );
|
||||||
|
extended_private_key result( private_key::regenerate( detail::_left(hash) ),
|
||||||
|
detail::_right(hash) );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void to_variant( const ecc::private_key& var, variant& vo )
|
void to_variant( const ecc::private_key& var, variant& vo )
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,6 @@
|
||||||
|
|
||||||
#include "_elliptic_impl_priv.hpp"
|
#include "_elliptic_impl_priv.hpp"
|
||||||
|
|
||||||
#define BTC_EXT_PUB_MAGIC (0x0488B21E)
|
|
||||||
#define BTC_EXT_PRIV_MAGIC (0x0488ADE4)
|
|
||||||
|
|
||||||
namespace fc { namespace ecc {
|
namespace fc { namespace ecc {
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
@ -47,6 +44,11 @@ namespace fc { namespace ecc {
|
||||||
|
|
||||||
public_key_data _key;
|
public_key_data _key;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef fc::array<char,37> chr37;
|
||||||
|
chr37 _derive_message( const public_key_data& key, int i );
|
||||||
|
fc::sha256 _left( const fc::sha512& v );
|
||||||
|
fc::sha256 _right( const fc::sha512& v );
|
||||||
}
|
}
|
||||||
|
|
||||||
static const public_key_data empty_pub;
|
static const public_key_data empty_pub;
|
||||||
|
|
@ -156,230 +158,36 @@ namespace fc { namespace ecc {
|
||||||
FC_ASSERT( pk_len == my->_key.size() );
|
FC_ASSERT( pk_len == my->_key.size() );
|
||||||
}
|
}
|
||||||
|
|
||||||
static fc::sha256 _left( const fc::sha512& v )
|
|
||||||
{
|
|
||||||
fc::sha256 result;
|
|
||||||
memcpy( result.data(), v.data(), 32 );
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static fc::sha256 _right( const fc::sha512& v )
|
|
||||||
{
|
|
||||||
fc::sha256 result;
|
|
||||||
memcpy( result.data(), v.data() + 32, 32 );
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef fc::array<char,37> chr37;
|
|
||||||
|
|
||||||
static void _put( unsigned char** dest, unsigned int i)
|
|
||||||
{
|
|
||||||
*(*dest)++ = (i >> 24) & 0xff;
|
|
||||||
*(*dest)++ = (i >> 16) & 0xff;
|
|
||||||
*(*dest)++ = (i >> 8) & 0xff;
|
|
||||||
*(*dest)++ = i & 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int _get( unsigned char** src )
|
|
||||||
{
|
|
||||||
unsigned int result = *(*src)++ << 24;
|
|
||||||
result |= *(*src)++ << 16;
|
|
||||||
result |= *(*src)++ << 8;
|
|
||||||
result |= *(*src)++;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static chr37 _derive_message( char first, const char* key32, int i )
|
|
||||||
{
|
|
||||||
chr37 result;
|
|
||||||
unsigned char* dest = (unsigned char*) result.begin();
|
|
||||||
*dest++ = first;
|
|
||||||
memcpy( dest, key32, 32 ); dest += 32;
|
|
||||||
_put( &dest, i );
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static chr37 _derive_message( const public_key_data& key, int i )
|
|
||||||
{
|
|
||||||
return _derive_message( *key.begin(), key.begin() + 1, i );
|
|
||||||
}
|
|
||||||
|
|
||||||
static chr37 _derive_message( const private_key_secret& key, int i )
|
|
||||||
{
|
|
||||||
return _derive_message( 0, key.data(), i );
|
|
||||||
}
|
|
||||||
|
|
||||||
static fc::string _to_base58( const extended_key_data& key )
|
|
||||||
{
|
|
||||||
char buffer[key.size() + 4];
|
|
||||||
memcpy( buffer, key.begin(), key.size() );
|
|
||||||
fc::sha256 double_hash = fc::sha256::hash( fc::sha256::hash( key.begin(), key.size() ));
|
|
||||||
memcpy( buffer + key.size(), double_hash.data(), 4 );
|
|
||||||
return fc::to_base58( buffer, sizeof(buffer) );
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _parse_extended_data( unsigned char* buffer, fc::string base58 )
|
|
||||||
{
|
|
||||||
memset( buffer, 0, 78 );
|
|
||||||
std::vector<char> decoded = fc::from_base58( base58 );
|
|
||||||
unsigned int i = 0;
|
|
||||||
for ( char c : decoded )
|
|
||||||
{
|
|
||||||
if ( i >= 78 || i > decoded.size() - 4 ) { break; }
|
|
||||||
buffer[i++] = c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef hmac<fc::sha512> hmac_sha512;
|
|
||||||
|
|
||||||
extended_public_key::extended_public_key( const public_key& k, const fc::sha256& c,
|
extended_public_key::extended_public_key( const public_key& k, const fc::sha256& c,
|
||||||
int child, int parent, uint8_t depth )
|
int child, int parent, uint8_t depth )
|
||||||
: public_key(k), c(c), child_num(child), parent_fp(parent), depth(depth) { }
|
: public_key(k), c(c), child_num(child), parent_fp(parent), depth(depth) { }
|
||||||
|
|
||||||
extended_public_key extended_public_key::derive_child(int i) const
|
|
||||||
{
|
|
||||||
FC_ASSERT( !(i&0x80000000), "Can't derive hardened public key!" );
|
|
||||||
return derive_normal_child(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
extended_public_key extended_public_key::derive_normal_child(int i) const
|
extended_public_key extended_public_key::derive_normal_child(int i) const
|
||||||
{
|
{
|
||||||
hmac_sha512 mac;
|
hmac_sha512 mac;
|
||||||
public_key_data key = serialize();
|
public_key_data key = serialize();
|
||||||
const chr37 data = _derive_message( key, i );
|
const detail::chr37 data = detail::_derive_message( key, i );
|
||||||
fc::sha512 l = mac.digest( c.data(), c.data_size(), data.begin(), data.size() );
|
fc::sha512 l = mac.digest( c.data(), c.data_size(), data.begin(), data.size() );
|
||||||
fc::sha256 left = _left(l);
|
fc::sha256 left = detail::_left(l);
|
||||||
FC_ASSERT( secp256k1_ec_pubkey_tweak_add( detail::_get_context(), (unsigned char*) key.begin(), key.size(), (unsigned char*) left.data() ) > 0 );
|
FC_ASSERT( secp256k1_ec_pubkey_tweak_add( detail::_get_context(), (unsigned char*) key.begin(), key.size(), (unsigned char*) left.data() ) > 0 );
|
||||||
extended_public_key result( key, _right(l), i, fingerprint(), depth + 1 );
|
extended_public_key result( key, detail::_right(l), i, fingerprint(), depth + 1 );
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
extended_key_data extended_public_key::serialize_extended() const
|
|
||||||
{
|
|
||||||
extended_key_data result;
|
|
||||||
unsigned char* dest = (unsigned char*) result.begin();
|
|
||||||
_put( &dest, BTC_EXT_PUB_MAGIC );
|
|
||||||
*dest++ = depth;
|
|
||||||
_put( &dest, parent_fp );
|
|
||||||
_put( &dest, child_num );
|
|
||||||
memcpy( dest, c.data(), c.data_size() ); dest += 32;
|
|
||||||
public_key_data key = serialize();
|
|
||||||
memcpy( dest, key.begin(), key.size() );
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
fc::string extended_public_key::str() const
|
|
||||||
{
|
|
||||||
return _to_base58( serialize_extended() );
|
|
||||||
}
|
|
||||||
|
|
||||||
extended_public_key extended_public_key::from_base58( const fc::string& base58 )
|
|
||||||
{
|
|
||||||
unsigned char buffer[78];
|
|
||||||
unsigned char* ptr = buffer;
|
|
||||||
_parse_extended_data( buffer, base58 );
|
|
||||||
FC_ASSERT( _get( &ptr ) == BTC_EXT_PUB_MAGIC, "Invalid extended private key" );
|
|
||||||
uint8_t d = *ptr++;
|
|
||||||
int fp = _get( &ptr );
|
|
||||||
int cn = _get( &ptr );
|
|
||||||
fc::sha256 chain;
|
|
||||||
memcpy( chain.data(), ptr, chain.data_size() ); ptr += chain.data_size();
|
|
||||||
public_key_data key;
|
|
||||||
memcpy( key.begin(), ptr, key.size() );
|
|
||||||
return extended_public_key( key, chain, cn, fp, d );
|
|
||||||
}
|
|
||||||
|
|
||||||
extended_private_key::extended_private_key( const private_key& k, const sha256& c,
|
extended_private_key::extended_private_key( const private_key& k, const sha256& c,
|
||||||
int child, int parent, uint8_t depth )
|
int child, int parent, uint8_t depth )
|
||||||
: private_key(k), c(c), child_num(child), parent_fp(parent), depth(depth) { }
|
: private_key(k), c(c), child_num(child), parent_fp(parent), depth(depth) { }
|
||||||
|
|
||||||
extended_public_key extended_private_key::get_extended_public_key() const
|
|
||||||
{
|
|
||||||
return extended_public_key( get_public_key(), c, child_num, parent_fp, depth );
|
|
||||||
}
|
|
||||||
|
|
||||||
extended_private_key extended_private_key::derive_child(int i) const
|
|
||||||
{
|
|
||||||
return i < 0 ? derive_hardened_child(i) : derive_normal_child(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
extended_private_key extended_private_key::derive_normal_child(int i) const
|
|
||||||
{
|
|
||||||
const chr37 data = _derive_message( get_public_key().serialize(), i );
|
|
||||||
hmac_sha512 mac;
|
|
||||||
fc::sha512 l = mac.digest( c.data(), c.data_size(), data.begin(), data.size() );
|
|
||||||
return private_derive_rest( l, i );
|
|
||||||
}
|
|
||||||
|
|
||||||
extended_private_key extended_private_key::derive_hardened_child(int i) const
|
|
||||||
{
|
|
||||||
hmac_sha512 mac;
|
|
||||||
private_key_secret key = get_secret();
|
|
||||||
const chr37 data = _derive_message( key, i );
|
|
||||||
fc::sha512 l = mac.digest( c.data(), c.data_size(), data.begin(), data.size() );
|
|
||||||
return private_derive_rest( l, i );
|
|
||||||
}
|
|
||||||
|
|
||||||
extended_private_key extended_private_key::private_derive_rest( const fc::sha512& hash,
|
extended_private_key extended_private_key::private_derive_rest( const fc::sha512& hash,
|
||||||
int i) const
|
int i) const
|
||||||
{
|
{
|
||||||
fc::sha256 left = _left(hash);
|
fc::sha256 left = detail::_left(hash);
|
||||||
FC_ASSERT( secp256k1_ec_privkey_tweak_add( detail::_get_context(), (unsigned char*) left.data(), (unsigned char*) get_secret().data() ) > 0 );
|
FC_ASSERT( secp256k1_ec_privkey_tweak_add( detail::_get_context(), (unsigned char*) left.data(), (unsigned char*) get_secret().data() ) > 0 );
|
||||||
extended_private_key result( private_key::regenerate( left ), _right(hash),
|
extended_private_key result( private_key::regenerate( left ), detail::_right(hash),
|
||||||
i, fingerprint(), depth + 1 );
|
i, fingerprint(), depth + 1 );
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
extended_key_data extended_private_key::serialize_extended() const
|
|
||||||
{
|
|
||||||
extended_key_data result;
|
|
||||||
unsigned char* dest = (unsigned char*) result.begin();
|
|
||||||
_put( &dest, BTC_EXT_PRIV_MAGIC );
|
|
||||||
*dest++ = depth;
|
|
||||||
_put( &dest, parent_fp );
|
|
||||||
_put( &dest, child_num );
|
|
||||||
memcpy( dest, c.data(), c.data_size() ); dest += 32;
|
|
||||||
*dest++ = 0;
|
|
||||||
private_key_secret key = get_secret();
|
|
||||||
memcpy( dest, key.data(), key.data_size() );
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
fc::string extended_private_key::str() const
|
|
||||||
{
|
|
||||||
return _to_base58( serialize_extended() );
|
|
||||||
}
|
|
||||||
|
|
||||||
extended_private_key extended_private_key::from_base58( const fc::string& base58 )
|
|
||||||
{
|
|
||||||
unsigned char buffer[78];
|
|
||||||
unsigned char* ptr = buffer;
|
|
||||||
_parse_extended_data( buffer, base58 );
|
|
||||||
FC_ASSERT( _get( &ptr ) == BTC_EXT_PRIV_MAGIC, "Invalid extended private key" );
|
|
||||||
uint8_t d = *ptr++;
|
|
||||||
int fp = _get( &ptr );
|
|
||||||
int cn = _get( &ptr );
|
|
||||||
fc::sha256 chain;
|
|
||||||
memcpy( chain.data(), ptr, chain.data_size() ); ptr += chain.data_size();
|
|
||||||
ptr++;
|
|
||||||
private_key_secret key;
|
|
||||||
memcpy( key.data(), ptr, key.data_size() );
|
|
||||||
return extended_private_key( private_key::regenerate(key), chain, cn, fp, d );
|
|
||||||
}
|
|
||||||
|
|
||||||
extended_private_key extended_private_key::generate_master( const fc::string& seed )
|
|
||||||
{
|
|
||||||
return generate_master( seed.c_str(), seed.size() );
|
|
||||||
}
|
|
||||||
|
|
||||||
extended_private_key extended_private_key::generate_master( const char* seed, uint32_t seed_len )
|
|
||||||
{
|
|
||||||
hmac_sha512 mac;
|
|
||||||
fc::sha512 hash = mac.digest( "Bitcoin seed", 12, seed, seed_len );
|
|
||||||
extended_private_key result( private_key::regenerate( _left(hash) ), _right(hash) );
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
commitment_type blind( const blind_factor_type& blind, uint64_t value )
|
commitment_type blind( const blind_factor_type& blind, uint64_t value )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#include <fc/crypto/hex.hpp>
|
#include <fc/crypto/hex.hpp>
|
||||||
|
#include <fc/crypto/hmac.hpp>
|
||||||
#include <fc/fwd_impl.hpp>
|
#include <fc/fwd_impl.hpp>
|
||||||
#include <openssl/sha.h>
|
#include <openssl/sha.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
@ -95,4 +96,7 @@ namespace fc {
|
||||||
else
|
else
|
||||||
memset( &bi, char(0), sizeof(bi) );
|
memset( &bi, char(0), sizeof(bi) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
unsigned int hmac<sha224>::internal_block_size() const { return 64; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#include <fc/crypto/hex.hpp>
|
#include <fc/crypto/hex.hpp>
|
||||||
|
#include <fc/crypto/hmac.hpp>
|
||||||
#include <fc/fwd_impl.hpp>
|
#include <fc/fwd_impl.hpp>
|
||||||
#include <openssl/sha.h>
|
#include <openssl/sha.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
@ -116,4 +117,6 @@ namespace fc {
|
||||||
return sha_value._hash[0];
|
return sha_value._hash[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
unsigned int hmac<sha256>::internal_block_size() const { return 64; }
|
||||||
} //end namespace fc
|
} //end namespace fc
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#include <fc/crypto/hex.hpp>
|
#include <fc/crypto/hex.hpp>
|
||||||
|
#include <fc/crypto/hmac.hpp>
|
||||||
#include <fc/fwd_impl.hpp>
|
#include <fc/fwd_impl.hpp>
|
||||||
#include <openssl/sha.h>
|
#include <openssl/sha.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
@ -101,4 +102,7 @@ namespace fc {
|
||||||
else
|
else
|
||||||
memset( &bi, char(0), sizeof(bi) );
|
memset( &bi, char(0), sizeof(bi) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
unsigned int hmac<sha512>::internal_block_size() const { return 128; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue