Exemple #1
0
BCW_API bool hd_private_key::set_serialized(std::string encoded)
{
    if (!is_base58(encoded))
        return false;
    const data_chunk decoded = decode_base58(encoded);
    if (decoded.size() != serialized_length)
        return false;
    if (!verify_checksum(decoded))
        return false;

    auto ds = make_deserializer(decoded.begin(), decoded.end());
    auto prefix = ds.read_big_endian<uint32_t>();
    if (prefix != mainnet_private_prefix && prefix != testnet_private_prefix)
        return false;

    valid_ = true;
    lineage_.testnet = prefix == testnet_private_prefix;
    lineage_.depth = ds.read_byte();
    lineage_.parent_fingerprint = ds.read_little_endian<uint32_t>();
    lineage_.child_number = ds.read_big_endian<uint32_t>();
    c_ = ds.read_bytes<chain_code_size>();
    ds.read_byte();
    k_ = ds.read_bytes<ec_secret_size>();
    K_ = secret_to_public_key(k_);
    return true;
}
Exemple #2
0
ec_secret wif_to_secret(const std::string& wif)
{
    data_chunk decoded;
    if (!decode_base58(decoded, wif))
        return ec_secret();

    // 1 marker, 32 byte secret, optional 1 compressed flag, 4 checksum bytes
    if (decoded.size() != 1 + hash_size + 4 &&
        decoded.size() != 1 + hash_size + 1 + 4)
        return ec_secret();

    if (!verify_checksum(decoded))
        return ec_secret();

    // Check first byte is valid
    if (decoded[0] != payment_address::wif_version)
        return ec_secret();

    // Checks passed. Drop the 0x80 start byte and checksum.
    decoded.erase(decoded.begin());
    decoded.erase(decoded.end() - 4, decoded.end());

    // If length is still 33 and last byte is 0x01, drop it.
    if (decoded.size() == 33 && decoded[32] == (uint8_t)0x01)
        decoded.erase(decoded.begin()+32);

    ec_secret secret;
    BITCOIN_ASSERT(secret.size() == decoded.size());
    std::copy(decoded.begin(), decoded.end(), secret.begin());
    return secret;
}
bool is_wif_compressed(const std::string& wif)
{
    data_chunk decoded;
    if (!decode_base58(decoded, wif))
        return false;
    return decoded.size() == (1 + hash_size + 1 + 4) &&
        decoded[33] == (uint8_t)0x01;
}
bool payment_address::set_encoded(const std::string& encoded_address)
{
    data_chunk decoded_address;
    if (!decode_base58(decoded_address, encoded_address))
        return false;
    uint32_t checksum;
    return unwrap(version_, hash_, checksum, decoded_address);
}
Exemple #5
0
// For support of template implementation only, do not call directly.
bool decode_base58_private(uint8_t* out, size_t out_size, const char* in)
{
    data_chunk buffer;
    if (!decode_base58(buffer, in) || buffer.size() != out_size)
        return false;

    for (size_t i = 0; i < out_size; ++i)
        out[i] = buffer[i];

    return true;
}
		bool payment_address::set_encoded(const std::string& encoded_address)
		{
			if (!is_base58(encoded_address))
				return false;
			const data_chunk decoded_address = decode_base58(encoded_address);
			// version + 20 bytes short hash + 4 bytes checksum
			if (decoded_address.size() != 25)
				return false;
			if (!verify_checksum(decoded_address))
				return false;

			version_ = decoded_address[0];
			std::copy_n(decoded_address.begin() + 1, hash_.size(), hash_.begin());
			return true;
		}
Exemple #7
0
bool payment_address::set_encoded(const std::string& encoded_address)
{
    const data_chunk decoded_address = decode_base58(encoded_address);
    // version + 20 bytes short hash + 4 bytes checksum
    if (decoded_address.size() != 25)
        return false;
    const uint8_t version = decoded_address[0];
    if (!set_version(version))
        return false;
    const data_chunk checksum_bytes(
        decoded_address.end() - 4, decoded_address.end());
    // version + short hash
    const data_chunk main_body(
        decoded_address.begin(), decoded_address.end() - 4);
    // verify checksum bytes
    if (generate_sha256_checksum(main_body) !=
            cast_chunk<uint32_t>(checksum_bytes))
        return false;
    std::copy(main_body.begin() + 1, main_body.end(), hash_.begin());
    return true;
}
bool hd_public_key::set_encoded(const std::string& encoded)
{
    data_chunk decoded;
    if (!decode_base58(decoded, encoded))
        return false;
    if (decoded.size() != serialized_length)
        return false;
    if (!verify_checksum(decoded))
        return false;

    auto ds = make_deserializer(decoded.begin(), decoded.end());
    auto prefix = ds.read_big_endian<uint32_t>();
    if (prefix != mainnet_public_prefix && prefix != testnet_public_prefix)
        return false;

    valid_ = true;
    lineage_.testnet = prefix == testnet_public_prefix;
    lineage_.depth = ds.read_byte();
    lineage_.parent_fingerprint = ds.read_little_endian<uint32_t>();
    lineage_.child_number = ds.read_big_endian<uint32_t>();
    c_ = ds.read_bytes<chain_code_size>();
    K_ = ds.read_data(33);
    return true;
}
Exemple #9
0
bool stealth_address::set_encoded(const std::string& encoded_address)
{
    valid_ = false;
    data_chunk raw_address;
    if (!decode_base58(raw_address, encoded_address))
        return false;

    // Size is guarded until we get to N.
    auto required_size = min_address_size;
    if (raw_address.size() < required_size)
        return valid_;

    if (!verify_checksum(raw_address))
        return valid_;

    // Start walking the array.
    auto iter = raw_address.begin();

    // [version:1 = 0x2a]
    auto version = *iter;
    if (version != network::mainnet && version != network::testnet)
        return valid_;
    testnet_ = (version == network::testnet);
    ++iter;

    // [options:1]
    auto options = *iter;
    if (options != flags::none && options != flags::reuse_key)
        return valid_;
    ++iter;

    // [scan_pubkey:33]
    auto scan_key_begin = iter;
    iter += compressed_pubkey_size;
    scan_pubkey_ = ec_point(scan_key_begin, iter);

    // [N:1]
    auto number_spend_pubkeys = *iter;
    ++iter;

    // Adjust and retest required size. for pubkey list.
    required_size += number_spend_pubkeys * compressed_pubkey_size;
    if (raw_address.size() < required_size)
        return valid_;

    // We don't explicitly save 'reuse', instead we add to spend_pubkeys_.
    if (options == flags::reuse_key)
        spend_pubkeys_.emplace_back(scan_pubkey_);

    // [spend_pubkey_1:33]..[spend_pubkey_N:33]
    for (auto key = 0; key < number_spend_pubkeys; ++key)
    {
        auto spend_key_begin = iter;
        iter += compressed_pubkey_size;
        spend_pubkeys_.emplace_back(ec_point(spend_key_begin, iter));
    }

    // [number_signatures:1]
    signatures_ = *iter;
    ++iter;

    // [prefix_number_bits:1]
    auto prefix_number_bits = *iter;
    if (prefix_number_bits > max_prefix_bits)
        return valid_;
    ++iter;

    // [prefix:prefix_number_bits / 8, round up]
    // Adjust and retest required size for prefix bytes.
    auto prefix_bytes = (prefix_number_bits + (byte_bits - 1)) / byte_bits;
    required_size += prefix_bytes;
    if (raw_address.size() != required_size)
        return valid_;

    // Prefix not yet supported on server!
    //BITCOIN_ASSERT(prefix_number_bits == 0);
    //if (prefix_number_bits != 0)
    //    return valid_;

    // Deserialize the prefix bytes/blocks.
    data_chunk raw_prefix(iter, iter + prefix_bytes);
    prefix_ = binary_type(prefix_number_bits, raw_prefix);

    valid_ = true;
    return valid_;
}