Exemplo n.º 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;
}
Exemplo n.º 2
0
script parse_script(const data_chunk& raw_script)
{
    script script_object;
    for (auto it = raw_script.begin(); it != raw_script.end(); ++it)
    {
        byte raw_byte = *it;
        operation op;
        op.code = static_cast<opcode>(raw_byte);
        // raw_byte is unsigned so it's always >= 0
        if (raw_byte <= 75)
            op.code = opcode::special;
        size_t read_n_bytes = number_of_bytes_from_opcode(op.code, raw_byte);

        for (size_t byte_count = 0; byte_count < read_n_bytes; ++byte_count)
        {
            ++it;
            if (it == raw_script.cend())
            {
                log_warning() << "Premature end of script.";
                return script();
            }
            op.data.push_back(*it);
        }

        script_object.push_operation(op);

    }
    return script_object;
}
BC_API void obelisk_codec::message(const data_chunk& data, bool more)
{
    switch (next_part_)
    {
        case command_part:
            wip_message_.command = std::string(data.begin(), data.end());
            break;

        case id_part:
            if (4 != data.size())
            {
                next_part_ = error_part;
                break;
            }
            wip_message_.id = from_little_endian<uint32_t>(data.begin(), data.end());
            break;

        case payload_part:
            wip_message_.payload = data;
            break;

        case error_part:
            break;
    }
    if (!more)
    {
        if (next_part_ == payload_part)
            receive(wip_message_);
        else
            on_unknown_(wip_message_.command);
        next_part_ = command_part;
    }
    else if (next_part_ < error_part)
        next_part_ = static_cast<message_part>(next_part_ + 1);
}
Exemplo n.º 4
0
		std::string encode_base58(const data_chunk& unencoded)
		{
			size_t leading_zeros = count_leading_zeros(unencoded);

			// size = log(256) / log(58), rounded up.
			const size_t number_nonzero = unencoded.size() - leading_zeros;
			const size_t indexes_size = number_nonzero * 138 / 100 + 1;
			// Allocate enough space in big-endian base58 representation.
			data_chunk indexes(indexes_size);

			// Process the bytes.
			for (auto it = unencoded.begin() + leading_zeros;
				it != unencoded.end(); ++it)
			{
				pack_value(indexes, *it);
			}

			// Skip leading zeroes in base58 result.
			auto first_nonzero = search_first_nonzero(indexes);

			// Translate the result into a string.
			std::string encoded;
			const size_t estimated_size =
				leading_zeros + (indexes.end() - first_nonzero);
			encoded.reserve(estimated_size);
			encoded.assign(leading_zeros, '1');
			// Set actual main bytes.
			for (auto it = first_nonzero; it != indexes.end(); ++it)
			{
				const size_t index = *it;
				encoded += base58_chars[index];
			}
			return encoded;
		}
Exemplo n.º 5
0
void wrap_fetch_transaction_args(data_chunk& data, const hash_digest& tx_hash)
{
    data.resize(hash_digest_size);
    auto serial = make_serializer(data.begin());
    serial.write_hash(tx_hash);
    BITCOIN_ASSERT(serial.iterator() == data.end());
}
bool validate_block::coinbase_height_match()
{
    // There are old blocks with version incorrectly set to 2. Ignore them.
    if (height_ < max_version1_height)
        return true;

    // Checks whether the block height is in the coinbase tx input script.
    // Version 2 blocks and onwards.
    BITCOIN_ASSERT(current_block_.header.version >= 2);
    BITCOIN_ASSERT(current_block_.transactions.size() > 0);
    BITCOIN_ASSERT(current_block_.transactions[0].inputs.size() > 0);

    // First get the serialized coinbase input script as a series of bytes.
    const auto& coinbase_tx = current_block_.transactions[0];
    const auto& coinbase_script = coinbase_tx.inputs[0].script;
    const auto raw_coinbase = save_script(coinbase_script);

    // Try to recreate the expected bytes.
    script_type expect_coinbase;
    script_number expect_number(height_);
    expect_coinbase.push_operation({opcode::special, expect_number.data()});

    // Save the expected coinbase script.
    const data_chunk expect = save_script(expect_coinbase);

    // Perform comparison of the first bytes with raw_coinbase.
    BITCOIN_ASSERT(expect.size() <= raw_coinbase.size());
    return std::equal(expect.begin(), expect.end(), raw_coinbase.begin());
}
Exemplo n.º 7
0
unsigned int BIO::doWrite(const data_chunk& data_to_write, int offset) const
{
	int written = 0;
	int num2wr = data_to_write.size() - offset;
	assert(num2wr > 0);

	DBG << "Writing " << num2wr << "B - " << Utils::DataToString(data_to_write)
			<< std::endl;
	if (num2wr == 0) {
		return 0;
	}

	for (;;) {
		written = BIO_write(itsBIO, &data_to_write.at(offset), num2wr);
		if (written <= 0) {
			if (this->ShouldRetry()) {
				std::string s("Recoverable error when writing to BIO");
				if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
					throw RecoverableException(s);
				}
			}

			std::string s("Fatal error when writing to BIO; ");
			s += Utils::getLastErrorSSL();
			throw RemoteDiedException(s);
		}
		break;
	}
	DBG << "Written " << written << "B" << std::endl;
	return written;
}
Exemplo n.º 8
0
// Accepts only strings bounded to 5 characters.
bool decode_base85(data_chunk& out, const std::string& in)
{
    const size_t length = in.size();
    if (length % 5 != 0)
        return false;

    const size_t decoded_size = length * 4 / 5;
    data_chunk decoded;
    decoded.reserve(decoded_size);
    size_t char_index = 0;
    uint32_t accumulator = 0;

    for (const uint8_t encoded_character: in)
    {
        const auto position = encoded_character - 32;
        if (position < 0 || position > 96)
            return false;

        accumulator = accumulator * 85 + decoder[position];
        if (++char_index % 5 == 0)
        {
            for (uint32_t divise = 256 * 256 * 256; divise > 0; divise /= 256)
                decoded.push_back(accumulator / divise % 256);

            accumulator = 0;
        }
    }

    out.assign(decoded.begin(), decoded.end());
    BITCOIN_ASSERT(out.size() == decoded_size);
    return true;
}
Exemplo n.º 9
0
data_chunk read_ephemkey(const data_chunk& stealth_data)
{
    // Read ephemkey
    BITCOIN_ASSERT(stealth_data.size() == 1 + 4 + 33);
    data_chunk ephemkey(stealth_data.begin() + 5, stealth_data.end());
    BITCOIN_ASSERT(ephemkey.size() == 33);
    return ephemkey;
}
Exemplo n.º 10
0
long_hash hmac_sha512_hash(const data_chunk& chunk, 
    const data_chunk& key)
{
    long_hash hash;
    HMACSHA512(chunk.data(), chunk.size(), key.data(),
        key.size(), hash.data());
    return hash;
}
Exemplo n.º 11
0
long_hash single_sha512_hash(const data_chunk& chunk)
{
    long_hash digest;
    SHA512_CTX ctx;
    SHA512_Init(&ctx);
    SHA512_Update(&ctx, chunk.data(), chunk.size());
    SHA512_Final(digest.data(), &ctx);
    return digest;
}
Exemplo n.º 12
0
bool VerifyChecksum(const data_chunk& data)
{
    if (data.size() < 4)
        return false;
    
    uint32_t checksum = from_little_endian<uint32_t>(data.end() - 4);
    
    return BitcoinChecksum((uint8_t*)&data[0], data.size()-4) == checksum;
};
Exemplo n.º 13
0
void BIO::Write(const data_chunk& data2wr) const
{
	unsigned int written = 0;
	do {
		data_chunk tmp;
		tmp.insert(tmp.end(), data2wr.begin() + written, data2wr.end());
		written += doWrite(tmp, written);
	} while(written < data2wr.size());
}
Exemplo n.º 14
0
bool read_hash(hash_digest& hash, const data_chunk& raw_hash)
{
    if (raw_hash.size() != hash.size())
    {
        log_warning(LOG_SUBSCRIBER) << "Wrong size for hash. Dropping.";
        return false;
    }
    std::copy(raw_hash.begin(), raw_hash.end(), hash.begin());
    return true;
}
Exemplo n.º 15
0
short_hash bitcoin_short_hash(const data_chunk& chunk)
{
    hash_digest sha_hash;
    SHA256__(chunk.data(), chunk.size(), sha_hash.data());

    short_hash ripemd_hash;
    RMD160(sha_hash.data(), sha_hash.size(), ripemd_hash.data());

    return ripemd_hash;
}
Exemplo n.º 16
0
		void unpack_char(data_chunk& data, int carry)
		{
			for (auto it = data.rbegin(); it != data.rend(); it++)
			{
				carry += 58 * (*it);
				*it = carry % 256;
				carry /= 256;
			}
			BITCOIN_ASSERT(carry == 0);
		}
Exemplo n.º 17
0
void wrap_fetch_history_args(data_chunk& data,
    const payment_address& address, size_t from_height)
{
    data.resize(1 + short_hash_size + 4);
    auto serial = make_serializer(data.begin());
    serial.write_byte(address.version());
    serial.write_short_hash(address.hash());
    serial.write_4_bytes(from_height);
    BITCOIN_ASSERT(serial.iterator() == data.end());
}
Exemplo n.º 18
0
record_type get_record(htdb_record_header& header, record_allocator& alloc,
    const data_chunk& key_data)
{
    typedef byte_array<N> hash_type;
    htdb_record<hash_type> ht(header, alloc, "test");
    hash_type key;
    BITCOIN_ASSERT(key.size() == key_data.size());
    std::copy(key_data.begin(), key_data.end(), key.begin());
    return ht.get(key);
}
Exemplo n.º 19
0
bool parse_token(data_chunk& raw_script, std::string token)
{
    boost::algorithm::trim(token);
    // skip this
    if (token.empty())
        return true;
    static data_chunk hex_raw;
    if (token == "ENDING" || !is_hex_data(token))
    {
        if (!hex_raw.empty())
        {
            extend_data(raw_script, hex_raw);
            hex_raw.resize(0);
        }
    }
    if (token == "ENDING")
    {
        // Do nothing...
    }
    else if (is_number(token))
    {
        int64_t value = boost::lexical_cast<int64_t>(token);
        if (is_opx(value))
            push_literal(raw_script, value);
        else
        {
            script_number bignum(value);
            push_data(raw_script, bignum.data());
        }
    }
    else if (is_hex_data(token))
    {
        std::string hex_part(token.begin() + 2, token.end());
        data_chunk raw_data;
        if (!decode_base16(raw_data, hex_part))
            return false;
        extend_data(hex_raw, raw_data);
    }
    else if (is_quoted_string(token))
    {
        data_chunk inner_value(token.begin() + 1, token.end() - 1);
        push_data(raw_script, inner_value);
    }
    else if (is_opcode(token))
    {
        opcode tokenized_opcode = token_to_opcode(token);
        raw_script.push_back(static_cast<uint8_t>(tokenized_opcode));
    }
    else
    {
        log_error() << "Token parsing failed with: " << token;
        return false;
    }
    return true;
}
		bool elliptic_curve_key::set_public_key(const data_chunk& pubkey)
		{
			if (!initialize())
				return false;
			const unsigned char* pubkey_bytes = pubkey.data();
			if (!o2i_ECPublicKey(&key_, &pubkey_bytes, pubkey.size()))
				return false;
			if (pubkey.size() == 33)
				use_compressed();
			return true;
		}
		bool elliptic_curve_key::verify(hash_digest hash, const data_chunk& signature)
		{
			BITCOIN_ASSERT(key_ != nullptr);
			// SSL likes a reversed hash
			std::reverse(hash.begin(), hash.end());
			// -1 = error, 0 = bad sig, 1 = good
			if (ECDSA_verify(0, hash.data(), hash.size(),
				signature.data(), signature.size(), key_) == 1)
				return true;
			return false;
		}
Exemplo n.º 22
0
bool verify_signature(const ec_point& public_key, hash_digest hash,
    const data_chunk& signature)
{
    std::reverse(hash.begin(), hash.end());
    init.init();
    return 1 == secp256k1_ecdsa_verify(
        hash.data(), hash.size(),
        signature.data(), signature.size(),
        public_key.data(), public_key.size()
    );
}
Exemplo n.º 23
0
		void pack_value(data_chunk& indexes, int carry)
		{
			// Apply "b58 = b58 * 256 + ch".
			for (auto it = indexes.rbegin(); it != indexes.rend(); ++it)
			{
				carry += 256 * (*it);
				*it = carry % 58;
				carry /= 58;
			}
			BITCOIN_ASSERT(carry == 0);
		}
Exemplo n.º 24
0
void receive_transaction_result(const data_chunk& data,
    blockchain::fetch_handler_transaction handle_fetch)
{
    std::error_code ec;
    auto deserial = make_deserializer(data.begin(), data.end());
    if (!read_error_code(deserial, data.size(), ec))
        return;
    BITCOIN_ASSERT(deserial.iterator() == data.begin() + 4);
    transaction_type tx;
    satoshi_load(deserial.iterator(), data.end(), tx);
    handle_fetch(ec, tx);
}
Exemplo n.º 25
0
void address_subscriber::decode_reply(
    const data_chunk& data, const worker_uuid& worker,
    subscribe_handler handle_subscribe)
{
    std::error_code ec;
    BITCOIN_ASSERT(data.size() == 4);
    auto deserial = make_deserializer(data.begin(), data.end());
    if (!read_error_code(deserial, data.size(), ec))
        return;
    BITCOIN_ASSERT(deserial.iterator() == data.end());
    handle_subscribe(ec, worker);
}
Exemplo n.º 26
0
hash_digest bitcoin_hash(const data_chunk& chunk)
{
    hash_digest first_hash;
    SHA256__(chunk.data(), chunk.size(), first_hash.data());

    hash_digest second_hash;
    SHA256__(first_hash.data(), first_hash.size(), second_hash.data());

    // The hash is in the reverse of the expected order.
    std::reverse(second_hash.begin(), second_hash.end());
    return second_hash;
}
Exemplo n.º 27
0
void BIO::WriteWithRetry(const data_chunk& data2wr) const
{
	unsigned int written = 0;
	do {
		try {
			data_chunk tmp;
			tmp.insert(tmp.end(), data2wr.begin() + written, data2wr.end());
			written += doWrite(tmp, written);
		} catch (RecoverableException& ex) {

		}
	} while (written < data2wr.size());
}
Exemplo n.º 28
0
 void attempt_load(const data_chunk& stream) const
 {
     Message result;
     try
     {
         satoshi_load(stream.begin(), stream.end(), result);
         handle_load_(std::error_code(), result);
     }
     catch (end_of_stream)
     {
         handle_load_(error::bad_stream, Message());
     }
 }
Exemplo n.º 29
0
hash_digest sha256_hash(const data_chunk& first_chunk,
    const data_chunk& second_chunk)
{
    hash_digest hash;

    SHA256CTX context;
    SHA256Init(&context);
    SHA256Update(&context, first_chunk.data(), first_chunk.size());
    SHA256Update(&context, second_chunk.data(), second_chunk.size());
    SHA256Final(&context, hash.data());

    return hash;
}
Exemplo n.º 30
0
bool validsig(transaction_type& tx, size_t input_index,
    elliptic_curve_key& key, const script_type& script_code,
    data_chunk signature)
{
    uint32_t hash_type = 0;
    hash_type = signature.back();
    signature.pop_back();

    hash_digest tx_hash =
        script_type::generate_signature_hash(
            tx, input_index, script_code, hash_type);
    return key.verify(tx_hash, signature);
}