Exemplo n.º 1
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;
}
Exemplo n.º 2
0
int main(int argc, char** argv)
{
    if (argc != 4)
    {
        std::cerr << "Usage: pp_unlock CHUNKFILE BLOCK_HASH PUBKEY"
            << std::endl;
        return -1;
    }
    const std::string chunk_filename = argv[1];
    const data_chunk hash = decode_hex(argv[2]);
    if (hash.empty() || hash.size() != hash_size)
    {
        std::cerr << "pp_unlock: not a valid BLOCK_HASH." << std::endl;
        return -1;
    }
    const ec_point pubkey = decode_hex(argv[3]);
    if (pubkey.empty() || pubkey.size() != ec_compressed_size)
    {
        std::cerr << "pp_unlock: not a valid PUBKEY." << std::endl;
        return -1;
    }
    std::ifstream infile(chunk_filename, std::ifstream::binary);
    infile.seekg(0, std::ifstream::end);
    size_t file_size = infile.tellg();
    BITCOIN_ASSERT(file_size % 16 == 0);
    infile.seekg(0, std::ifstream::beg);
    // Read entire file in.
    data_chunk cipher(file_size);
    // Copy chunk to public chunk file.
    char* data = reinterpret_cast<char*>(cipher.data());
    infile.read(data, file_size);
    infile.close();
    // Get seed.
    payment_address bid_addr = bidding_address(pubkey);
    hash_digest seed = derive_seed(pubkey);
    // Decrypt chunk.
    aes256_context ctx; 
    BITCOIN_ASSERT(seed.size() == 32);
    aes256_init(&ctx, seed.data());
    BITCOIN_ASSERT(cipher.size() % 16 == 0);
    for (size_t i = 0; i < cipher.size(); i += 16)
        aes256_decrypt_ecb(&ctx, cipher.data() + i);
    aes256_done(&ctx);
    // Write out.
    const fs::path new_chunk_filename = (chunk_filename + ".decrypted");
    std::ofstream outfile(new_chunk_filename.native(), std::ifstream::binary);
    char* dec_data = reinterpret_cast<char*>(cipher.data());
    outfile.write(dec_data, cipher.size());
    return 0;
}
Exemplo n.º 3
0
bool parse_token(data_chunk& raw_script, const std::string& token)
{
    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
        {
            big_number bignum;
            bignum.set_int64(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 = bytes_from_pretty(hex_part);
        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<byte>(tokenized_opcode));
    }
    else
    {
        log_error() << "Token parsing failed with: " << token;
        return false;
    }
    return true;
}
Exemplo n.º 4
0
void push_data(data_chunk& raw_script, const data_chunk& data)
{
    operation op;
    // pushdata1 = 76
    if (data.empty())
        op.code = opcode::zero;
    else if (data.size() < 76)
        op.code = opcode::special;
    else if (data.size() <= 0xff)
        op.code = opcode::pushdata1;
    else if (data.size() <= 0xffff)
        op.code = opcode::pushdata2;
    else
    {
        BOOST_REQUIRE_LE(data.size(), 0xffffffffu);
        op.code = opcode::pushdata4;
    }
    op.data = data;
    script_type tmp_script;
    tmp_script.push_operation(op);
    extend_data(raw_script, save_script(tmp_script));
}
Exemplo n.º 5
0
int main(int argc, char** argv)
{
    if (argc != 5)
    {
        std::cerr << "Usage: pp_prove DOCUMENT CHUNKS BLOCK_HASH REVEAL"
            << std::endl;
        return -1;
    }
    const fs::path doc_path = argv[1];
    const std::string chunks_str = argv[2];
    const std::string reveal_str = argv[4];
    size_t chunks = 0, reveal = 0;
    try
    {
        chunks = boost::lexical_cast<size_t>(chunks_str);
        reveal = boost::lexical_cast<size_t>(reveal_str);
    }
    catch (const boost::bad_lexical_cast&)
    {
        std::cerr << "pp_start: bad CHUNKS or REVEAL provided." << std::endl;
        return -1;
    }
    const data_chunk hash = decode_hex(argv[3]);
    if (hash.empty() || hash.size() != hash_size)
    {
        std::cerr << "pp_prove: not a valid BLOCK_HASH." << std::endl;
        return -1;
    }
    std::ifstream infile(doc_path.native(), std::ifstream::binary);
    infile.seekg(0, std::ifstream::end);
    size_t file_size = infile.tellg();
    infile.seekg(0, std::ifstream::beg);
    size_t chunk_size = file_size / chunks;
    // AES works on blocks of 16 bytes. Round up to nearest multiple.
    chunk_size += 16 - (chunk_size % 16);
    BITCOIN_ASSERT(chunk_size % 16 == 0);
    //std::cout << "Creating chunks of "
    //    << chunk_size << " bytes each." << std::endl;
    ec_point_list all_pubkeys;
    while (infile)
    {
        data_chunk buffer(chunk_size);
        // Copy chunk to public chunk file.
        char* data = reinterpret_cast<char*>(buffer.data());
        infile.read(data, chunk_size);
        // Create a seed.
        BITCOIN_ASSERT(ec_secret_size == hash_size);
        ec_secret secret = bitcoin_hash(buffer);
        ec_point pubkey = secret_to_public_key(secret);
        // Once we spend funds, we reveal the decryption pubkey.
        all_pubkeys.push_back(pubkey);
    }
    // Beginning bytes of block hash are zero, so use end bytes.
    std::seed_seq seq(hash.rbegin(), hash.rend());
    index_list random_values(reveal);
    seq.generate(random_values.begin(), random_values.end());
    for (size_t value: random_values)
    {
        size_t index = value % all_pubkeys.size();
        std::cout << (index + 1) << " " << all_pubkeys[index] << std::endl;
    }
    return 0;
}