data_chunk deterministic_wallet::generate_public_key( size_t n, bool for_change) const { hash_digest sequence = get_sequence(n, for_change); ssl_bignum x, y, z; BN_bin2bn(sequence.data(), sequence.size(), z); BN_bin2bn(master_public_key_.data(), 32, x); BN_bin2bn(master_public_key_.data() + 32, 32, y); // Create a point. ec_group group(EC_GROUP_new_by_curve_name(NID_secp256k1)); ec_point mpk(EC_POINT_new(group)); bn_ctx ctx(BN_CTX_new()); EC_POINT_set_affine_coordinates_GFp(group, mpk, x, y, ctx); ec_point result(EC_POINT_new(group)); // result pubkey_point = mpk_pubkey_point + z*curve.generator ssl_bignum one; BN_one(one); EC_POINT_mul(group, result, z, mpk, one, ctx); // Create the actual public key. EC_POINT_get_affine_coordinates_GFp(group, result, x, y, ctx); // 04 + x + y data_chunk raw_pubkey{0x04}; extend_data(raw_pubkey, bignum_data(x)); extend_data(raw_pubkey, bignum_data(y)); return raw_pubkey; }
void addkey_v4( int no, int n ) { // stretch key std::string oldseed = seed; std::string stretched = seed; for( int i=0; i<100000; i++ ) { if( i == 0 ) { stretched = fc::sha256::hash( stretched + oldseed ); } else { std::vector<char> bytes(stretched.size() / 2); fc::from_hex( stretched, &bytes[0], bytes.size() ); std::string tmp(bytes.begin(), bytes.end()); stretched = fc::sha256::hash( tmp + oldseed ); } } // compute Hash( 'n:no:' + mpk ) std::vector<char> mpk( masterkey.size() / 2); fc::from_hex( masterkey, &mpk[0], mpk.size()); std::string mpks(mpk.begin(), mpk.end()); fc::sha256 sequence( fc::sha256::hash( fc::sha256::hash( std::to_string( n ) + ":" + std::to_string ( no ) + ":" + mpks ) ) ); fc::sha256 secexp( stretched ); privatekeys.push_back( fc::ecc::private_key::generate_from_seed( secexp, sequence ) ); }