14 #define BTC_EXT_PUB_MAGIC (0x0488B21E) 15 #define BTC_EXT_PRIV_MAGIC (0x0488ADE4) 17 namespace fc {
namespace ecc {
25 memcpy( result.
data(), v.
data(), 32 );
32 memcpy( result.
data(), v.
data() + 32, 32 );
36 static void _put(
unsigned char** dest,
unsigned int i)
38 *(*dest)++ = (i >> 24) & 0xff;
39 *(*dest)++ = (i >> 16) & 0xff;
40 *(*dest)++ = (i >> 8) & 0xff;
41 *(*dest)++ = i & 0xff;
44 static unsigned int _get(
unsigned char** src )
46 unsigned int result = *(*src)++ << 24;
47 result |= *(*src)++ << 16;
48 result |= *(*src)++ << 8;
53 static chr37 _derive_message(
unsigned char first,
const unsigned char* key32,
int i )
56 unsigned char* dest = result.data();
58 memcpy( dest, key32, 32 ); dest += 32;
65 return _derive_message( *key.data(), key.data() + 1, i );
70 return _derive_message( 0, (
unsigned char*) key.
data(), i );
75 static const ec_group secp256k1( EC_GROUP_new_by_curve_name( NID_secp256k1 ) );
82 bn_ctx ctx(BN_CTX_new());
84 FC_ASSERT( EC_GROUP_get_order( group, order, ctx ) );
100 bn_ctx ctx(BN_CTX_new());
102 FC_ASSERT( EC_GROUP_get_order( group, order, ctx ) );
103 BN_rshift1( order, order );
127 return add( enc.
result() );
135 return generate_from_seed( get_secret(), enc.
result() );
141 static_assert(
sizeof(key) + 4 == 37,
"Elliptic public key size (or its hash) is incorrect");
143 memcpy(data.data(), key.data(), key.size());
144 memcpy(data.data() + key.size(), (
const char*)check.
_hash, 4);
156 FC_ASSERT( memcmp( (
char*)check.
_hash, data.data() + key.size(), 4 ) == 0 );
157 memcpy( (
char*)key.data(), data.data(), key.size() );
158 return from_key_data(key);
165 unsigned char* fp = (
unsigned char*) hash.
_hash;
166 return (fp[0] << 24) | (fp[1] << 16) | (fp[2] << 8) | fp[3];
170 return !(c[1] & 0x80)
171 && !(c[1] == 0 && !(c[2] & 0x80))
173 && !(c[33] == 0 && !(c[34] & 0x80));
179 BN_bin2bn((
unsigned char*)&offset,
sizeof(offset), z);
181 ec_group group(EC_GROUP_new_by_curve_name(NID_secp256k1));
182 bn_ctx ctx(BN_CTX_new());
184 EC_GROUP_get_order(group, order, ctx);
188 BN_bin2bn((
unsigned char*)&seed,
sizeof(seed), secexp);
189 BN_add(secexp, secexp, z);
190 BN_mod(secexp, secexp, order, ctx);
193 FC_ASSERT(BN_num_bytes(secexp) <= int64_t(
sizeof(secret)));
194 auto shift =
sizeof(secret) - BN_num_bytes(secexp);
195 BN_bn2bin(secexp, ((
unsigned char*)&secret)+shift);
196 return regenerate( secret );
207 const BIGNUM* bn = EC_KEY_get0_private_key(k);
212 int nbytes = BN_num_bytes(bn);
213 BN_bn2bin(bn, &((
unsigned char*)&sec)[32-nbytes] );
219 EC_KEY* k = EC_KEY_new_by_curve_name( NID_secp256k1 );
221 if( !EC_KEY_generate_key( k ) )
232 char buffer[std::tuple_size<extended_key_data>::value + 4];
233 memcpy( buffer, key.data(), key.size() );
235 memcpy( buffer + key.size(), double_hash.data(), 4 );
239 static void _parse_extended_data(
unsigned char* buffer, std::string base58 )
241 memset( buffer, 0, 78 );
244 for (
char c : decoded )
246 if ( i >= 78 || i > decoded.size() - 4 ) {
break; }
253 FC_ASSERT( !(i&0x80000000),
"Can't derive hardened public key!" );
254 return derive_normal_child(i);
260 unsigned char* dest = (
unsigned char*) result.data();
263 detail::_put( &dest, parent_fp );
264 detail::_put( &dest, child_num );
265 memcpy( dest, c.data(), c.data_size() ); dest += 32;
267 memcpy( dest, key.data(), key.size() );
278 return _to_base58( serialize_extended() );
283 unsigned char buffer[78];
284 unsigned char* ptr = buffer;
285 _parse_extended_data( buffer, base58 );
288 int fp = detail::_get( &ptr );
289 int cn = detail::_get( &ptr );
293 memcpy( key.data(), ptr, key.size() );
304 return i < 0 ? derive_hardened_child(i) : derive_normal_child(i);
309 const detail::chr37 data = detail::_derive_message( get_public_key().serialize(), i );
311 fc::sha512 l = mac.
digest( c.data(), c.data_size(), (
char*) data.data(), data.size() );
312 return private_derive_rest( l, i );
319 const detail::chr37 data = detail::_derive_message( key, i );
320 fc::sha512 l = mac.
digest( c.data(), c.data_size(), (
char*) data.data(), data.size() );
321 return private_derive_rest( l, i );
327 unsigned char* dest = (
unsigned char*) result.data();
330 detail::_put( &dest, parent_fp );
331 detail::_put( &dest, child_num );
332 memcpy( dest, c.data(), c.data_size() ); dest += 32;
346 return _to_base58( serialize_extended() );
351 unsigned char buffer[78];
352 unsigned char* ptr = buffer;
353 _parse_extended_data( buffer, base58 );
356 int fp = detail::_get( &ptr );
357 int cn = detail::_get( &ptr );
368 return generate_master( seed.c_str(), seed.size() );
boost::endian::little_uint32_buf_t _hash[5]
#define BTC_EXT_PRIV_MAGIC
static extended_public_key deserialize(const extended_key_data &data)
private_key child(const fc::sha256 &offset) const
extended_private_key derive_child(int i) const
std::string to_base58(const char *d, size_t s)
void pack(Stream &s, const flat_set< T, A... > &value, uint32_t _max_depth)
static constexpr size_t data_size()
const ec_group & get_curve()
public_key_data serialize() const
unsigned int fingerprint() const
Used to generate a useful error report when an exception is thrown.At each level in the stack where t...
const private_key_secret & get_half_curve_order()
static ripemd160 hash(const fc::sha512 &h)
fc::sha256 _left(const fc::sha512 &v)
H digest(const char *c, uint32_t c_len, const char *d, uint32_t d_len)
static sha256 hash(const char *d, uint32_t dlen)
boost::endian::little_uint64_buf_t _hash[4]
public_key child(const fc::sha256 &offset) const
static private_key generate()
void to_variant(const flat_set< T, A... > &var, variant &vo, uint32_t _max_depth)
std::string to_base58() const
Allows to convert current public key object into base58 number.
contains only the public point of an elliptic curve key.
static extended_private_key deserialize(const extended_key_data &data)
extended_private_key derive_normal_child(int i) const
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
fc::sha256 _right(const fc::sha512 &v)
static extended_public_key from_base58(const std::string &base58)
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object's.
static private_key regenerate(const fc::sha256 &secret)
#define FC_THROW_EXCEPTION(EXCEPTION, FORMAT,...)
const private_key_secret & get_curve_order()
at< List, 0 > first
Get the type at the beginning of the list.
extended_public_key get_extended_public_key() const
zero_initialized_array< unsigned char, 37 > chr37
private_key_secret get_secret() const
static private_key generate_from_seed(const fc::sha256 &seed, const fc::sha256 &offset=fc::sha256())
void from_variant(const variant &var, flat_set< T, A... > &vo, uint32_t _max_depth)
extended_public_key derive_child(int i) const
extended_key_data serialize_extended() const
std::vector< char > from_base58(const std::string &base58_str)
#define BTC_EXT_PUB_MAGIC
extended_private_key derive_hardened_child(int i) const
static extended_private_key generate_master(const std::string &seed)
extended_key_data serialize_extended() const
static public_key from_base58(const std::string &b58)
an elliptic curve private key.
static extended_private_key from_base58(const std::string &base58)