예제 #1
0
BCW_API hd_public_key hd_public_key::generate_public_key(uint32_t i) const
{
    if (!valid_)
        return hd_private_key();
    if (first_hardened_key <= i)
        return hd_public_key();

    data_chunk data;
    data.reserve(33 + 4);
    extend_data(data, K_);
    extend_data(data, to_big_endian(i));
    auto I = split(hmac_sha512_hash(data, to_data_chunk(c_)));

    // The returned child key Ki is point(parse256(IL)) + Kpar.
    ec_point Ki = K_;
    if (!ec_tweak_add(Ki, I.L))
        return hd_public_key();

    hd_key_lineage lineage
    {
        lineage_.testnet,
        static_cast<uint8_t>(lineage_.depth + 1),
        fingerprint(), i
    };
    return hd_public_key(Ki, I.R, lineage);
}
예제 #2
0
BCW_API hd_private_key hd_private_key::generate_private_key(uint32_t i) const
{
    if (!valid_)
        return hd_private_key();

    data_chunk data;
    data.reserve(33 + 4);
    if (first_hardened_key <= i)
    {
        data.push_back(0x00);
        extend_data(data, k_);
        extend_data(data, to_big_endian(i));
    }
    else
    {
        extend_data(data, K_);
        extend_data(data, to_big_endian(i));
    }
    auto I = split(hmac_sha512_hash(data, to_data_chunk(c_)));

    // The child key ki is (parse256(IL) + kpar) mod n:
    ec_secret ki = k_;
    if (!ec_add(ki, I.L))
        return hd_private_key();

    hd_key_lineage lineage
    {
        lineage_.testnet,
        static_cast<uint8_t>(lineage_.depth + 1),
        fingerprint(),
        i
    };
    return hd_private_key(ki, I.R, lineage);
}
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;
}
예제 #4
0
hash_digest deterministic_wallet::get_sequence(size_t n, bool for_change)
{
    data_chunk chunk;
    extend_data(chunk, std::to_string(n));
    chunk.push_back(':');
    chunk.push_back(for_change ? '1' : '0');
    chunk.push_back(':');
    extend_data(chunk, master_public_key_);
    hash_digest result = generate_sha256_hash(chunk);
    std::reverse(result.begin(), result.end());
    return result;
}
예제 #5
0
std::string payment_address::encoded(uint8_t version_byte) const
{
    data_chunk unencoded_address;
    BITCOIN_ASSERT(
        type_ == payment_type::pubkey_hash ||
        type_ == payment_type::script_hash);
    // Type, Hash, Checksum doth make thy address
    unencoded_address.push_back(version_byte);
    extend_data(unencoded_address, hash_);
    uint32_t checksum = generate_sha256_checksum(unencoded_address);
    extend_data(unencoded_address, uncast_type(checksum));
    BITCOIN_ASSERT(unencoded_address.size() == 25);
    return encode_base58(unencoded_address);
}
예제 #6
0
data_chunk wrap(uint8_t version, data_slice payload)
{
    data_chunk wrapped;
    wrapped.push_back(version);
    extend_data(wrapped, payload);
    append_checksum(wrapped);
    return wrapped;
}
예제 #7
0
BCW_API std::string hd_public_key::serialize() const
{
    data_chunk data;
    data.reserve(serialized_length);
    auto prefix = mainnet_public_prefix;
    if (lineage_.testnet)
        prefix = testnet_public_prefix;

    extend_data(data, to_big_endian(prefix));
    data.push_back(lineage_.depth);
    extend_data(data, to_little_endian(lineage_.parent_fingerprint));
    extend_data(data, to_big_endian(lineage_.child_number));
    extend_data(data, c_);
    extend_data(data, K_);

    append_checksum(data);
    return encode_base58(data);
}
예제 #8
0
hash_digest hash_transaction_impl(const transaction_type& tx,
    uint32_t* hash_type_code)
{
    data_chunk serialized_tx(satoshi_raw_size(tx));
    satoshi_save(tx, serialized_tx.begin());
    if (hash_type_code != nullptr)
        extend_data(serialized_tx, to_little_endian(*hash_type_code));
    return bitcoin_hash(serialized_tx);
}
예제 #9
0
hash_digest hash_transaction_impl(const message::transaction& tx, 
    uint32_t* hash_type_code)
{
    data_chunk serialized_tx(satoshi_raw_size(tx));
    satoshi_save(tx, serialized_tx.begin());
    if (hash_type_code != nullptr)
        extend_data(serialized_tx, uncast_type(*hash_type_code));
    return generate_sha256_hash(serialized_tx);
}
예제 #10
0
		std::string payment_address::encoded() const
		{
			data_chunk unencoded_address;
			unencoded_address.reserve(25);
			// Type, Hash, Checksum doth make thy address
			unencoded_address.push_back(version_);
			extend_data(unencoded_address, hash_);
			append_checksum(unencoded_address);
			BITCOIN_ASSERT(unencoded_address.size() == 25);
			return encode_base58(unencoded_address);
		}
예제 #11
0
data_chunk save_script(const script& scr)
{
    data_chunk raw_script;
    for (operation op: scr.operations())
    {
        byte raw_byte = static_cast<byte>(op.code);
        if (op.code == opcode::special)
            raw_byte = op.data.size();
        raw_script.push_back(raw_byte);
        extend_data(raw_script, op.data);
    }
    return raw_script;
}
예제 #12
0
std::string stealth_address::encoded() const
{
    if (!valid_)
        return std::string();

    data_chunk raw_address;
    raw_address.push_back(get_version());
    raw_address.push_back(get_options());
    extend_data(raw_address, scan_pubkey_);

    // Spend_pubkeys must be guarded against a size greater than 255.
    auto number_spend_pubkeys = static_cast<uint8_t>(spend_pubkeys_.size());

    // Adjust for key reuse.
    if (get_reuse_key())
        --number_spend_pubkeys;

    raw_address.push_back(number_spend_pubkeys);

    // Serialize the spend keys, excluding any that match the scan key.
    for (const ec_point& pubkey: spend_pubkeys_)
        if (pubkey != scan_pubkey_)
            extend_data(raw_address, pubkey);

    raw_address.push_back(signatures_);

    // The prefix must be guarded against a size greater than 32
    // so that the bitfield can convert into uint32_t and sized by uint8_t.
    auto prefix_number_bits = static_cast<uint8_t>(prefix_.size());

    // Serialize the prefix bytes/blocks.
    raw_address.push_back(prefix_number_bits);
    extend_data(raw_address, prefix_.blocks());

    append_checksum(raw_address);
    return encode_base58(raw_address);
}
예제 #13
0
data_chunk create_raw_message(const Message& packet)
{
    data_chunk payload(satoshi_raw_size(packet));
    satoshi_save(packet, payload.begin());
    // Make the header packet and serialise it
    message::header head;
    head.magic = magic_value;
    head.command = satoshi_command(packet);
    head.payload_length = payload.size();
    head.checksum = generate_sha256_checksum(payload);
    data_chunk raw_header(satoshi_raw_size(head));
    satoshi_save(head, raw_header.begin());
    // Construct completed packet with header + payload
    data_chunk whole_message = raw_header;
    extend_data(whole_message, payload);
    // Probably not the right place for this
    // Networking output in an exporter
    log_info(log_domain::network) << "s: " << head.command
        << " (" << payload.size() << " bytes)";
    return whole_message;
}
예제 #14
0
파일: channel.hpp 프로젝트: veox/libbitcoin
data_chunk create_raw_message(const Message& packet)
{
    data_chunk payload(satoshi_raw_size(packet));
    satoshi_save(packet, payload.begin());
    // Make the header packet and serialise it
    header_type head;
    head.magic = magic_value();
    head.command = satoshi_command(packet);
    head.payload_length = static_cast<uint32_t>(payload.size());
    head.checksum = bitcoin_checksum(payload);
    data_chunk raw_header(satoshi_raw_size(head));
    satoshi_save(head, raw_header.begin());
    // Construct completed packet with header + payload
    data_chunk whole_message = raw_header;
    extend_data(whole_message, payload);
    // Probably not the right place for this
    // Networking output in an exporter
    log_debug(LOG_NETWORK) << "s: " << head.command
        << " (" << payload.size() << " bytes)";
    return whole_message;
}
예제 #15
0
void readable_data_type::set(const std::string& data)
{
    extend_data(data_buffer_, data);
    prepare();
}
예제 #16
0
void readable_data_type::set(const short_hash& data)
{
    extend_data(data_buffer_, data);
    prepare();
}
예제 #17
0
void readable_data_type::set(const hash_digest& data)
{
    extend_data(data_buffer_, data);
    prepare();
}
예제 #18
0
void readable_data_type::set(const data_chunk& data)
{
    extend_data(data_buffer_, data);
    prepare();
}
예제 #19
0
void append_checksum(data_chunk& data)
{
    const auto checksum = bitcoin_checksum(data);
    extend_data(data, to_little_endian(checksum));
}
예제 #20
0
hash_digest transaction::hash(uint32_t sighash_type) const
{
    auto serialized = to_data();
    extend_data(serialized, to_little_endian(sighash_type));
    return bitcoin_hash(serialized);
}
예제 #21
0
BC_API void append_checksum(data_chunk& data)
{
    uint32_t checksum = bitcoin_checksum(data);
    extend_data(data, to_little_endian(checksum));
}
예제 #22
0
hash_digest transaction::hash(uint32_t hash_type_code) const
{
    data_chunk serialized = to_data();
    extend_data(serialized, to_little_endian(hash_type_code));
    return bitcoin_hash(serialized);
}