示例#1
0
// Optimize reads by short-circuiting what is unnecessary.
// Invalid returns are conflated with skipped, but are store only.
bool stealth_record::from_data(reader& source, size_t start_height,
    const binary& filter)
{
    height_ = source.read_4_bytes_little_endian();

    if (height_ < start_height)
    {
        reset();
        source.skip(serialized_size(false) - sizeof(uint32_t));
        return false;
    }

    prefix_ = source.read_4_bytes_little_endian();

    if (!filter.is_prefix_of(prefix_))
    {
        reset();
        source.skip(serialized_size(false) - 2 * sizeof(uint32_t));
        return false;
    }

    unsigned_ephemeral_ = source.read_hash();
    public_key_hash_ = source.read_short_hash();
    transaction_hash_ = source.read_hash();

    if (!source)
        reset();

    return source;
}
示例#2
0
// Mine a filter into the leftmost bytes of sha256(sha256(output-script)).
bool create_stealth_data(data_chunk& out_stealth_data, ec_secret& out_secret,
    const binary& filter, const data_chunk& seed)
{
    // Create a valid ephemeral key pair.
    ec_secret secret;
    ec_compressed point;
    if (!create_ephemeral_keys(secret, point, seed))
        return false;

    // [ephemeral-public-key-hash:32][pad:0-44][nonce:4]
    static const size_t max_pad_size = operation::max_null_data_size -
        hash_size - sizeof(uint32_t);

    // Derive our initial nonce data from the provided seed.
    const auto bytes = sha512_hash(seed);

    // Create a pad size of 0-44 using the last of bytes (avoiding pad/nonce).
    const auto pad_size = bytes.back() % max_pad_size;

    // Allocate data of target size (36-80 bytes)
    data_chunk data(hash_size + pad_size + sizeof(uint32_t));

    // Copy the unsigned portion of the ephemeral public key into data.
    std::copy(point.begin() + 1, point.end(), data.begin());

    // Copy arbitrary pad bytes into data.
    const auto pad_begin = data.begin() + hash_size;
    std::copy(bytes.begin(), bytes.begin() + pad_size, pad_begin);

    // Create an initial 32 bit nonce value from last byte (avoiding pad).
    const auto start = from_little_endian_unsafe<uint32_t>(bytes.begin() +
        max_pad_size);

    // Mine a prefix into the double sha256 hash of the stealth script.
    // This will iterate up to 2^32 times before giving up.
    for (uint32_t nonce = start + 1; nonce != start; ++nonce)
    {
        // Create the stealth script with the current data.
        const auto ops = operation::to_null_data_pattern(data);
        const auto stealth_script = script{ ops };

        // Test for match of filter to stealth script hash prefix.
        uint32_t field;
        if (to_stealth_prefix(field, stealth_script) &&
            filter.is_prefix_of(field))
        {
            out_stealth_data = data;
            out_secret = secret;
            return true;
        }
    }

    return false;
}