Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

draft: Added Random Access Machine components #5

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions examples/proof_systems/zksnark/ram_zksnark/run_ram_zksnark.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
//---------------------------------------------------------------------------//
// Copyright (c) 2018-2020 Mikhail Komarov <[email protected]>
// Copyright (c) 2020 Nikita Kaskov <[email protected]>
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//---------------------------------------------------------------------------//

#ifndef CRYPTO3_RUN_RAM_ZKSNARK_HPP
#define CRYPTO3_RUN_RAM_ZKSNARK_HPP

#include <nil/crypto3/zk/snark/relations/ram_computations/rams/examples/ram_examples.hpp>
#include <nil/crypto3/zk/snark/proof_systems/zksnark/ram_zksnark/ram_zksnark_params.hpp>

namespace nil {
namespace crypto3 {
namespace zk {
namespace snark {

/**
* Runs the zkSNARK (generator, prover, and verifier) for a given
* RAM example (specified by an architecture, boot trace, auxiliary input, and time bound).
*/
template<typename ram_zksnark_ppT>
bool run_ram_zksnark(const ram_example<ram_zksnark_machine_pp<ram_zksnark_ppT>> &example);

/**
* The code below provides an example of all stages of running a RAM zkSNARK.
*
* Of course, in a real-life scenario, we would have three distinct entities,
* mangled into one in the demonstration below. The three entities are as follows.
* (1) The "generator", which runs the zkSNARK generator on input a given
* architecture.
* (2) The "prover", which runs the zkSNARK prover on input the proving key,
* a boot trace, and an auxiliary input.
* (3) The "verifier", which runs the zkSNARK verifier on input the verification key,
* a boot trace, a time bound, and a proof.
*/
template<typename ram_zksnark_ppT>
bool run_ram_zksnark(const ram_example<ram_zksnark_machine_pp<ram_zksnark_ppT>> &example) {
std::cout << "Call to run_ram_zksnark" << std::endl;

printf("This run uses an example with the following parameters:\n");
example.ap.print();
printf("* Time bound (T): %zu\n", example.time_bound);

std::cout << "RAM zkSNARK Generator" << std::endl;
ram_zksnark_keypair<ram_zksnark_ppT> keypair = ram_zksnark_generator<ram_zksnark_ppT>(example.ap);

std::cout << "RAM zkSNARK Prover" << std::endl;
ram_zksnark_proof<ram_zksnark_ppT> proof = ram_zksnark_prover<ram_zksnark_ppT>(
keypair.pk, example.boot_trace, example.time_bound, example.auxiliary_input);

std::cout << "RAM zkSNARK Verifier" << std::endl;
bool ans = ram_zksnark_verifier<ram_zksnark_ppT>(
keypair.vk, example.boot_trace, example.time_bound, proof);

printf("* The verification result is: %s\n", (ans ? "PASS" : "FAIL"));

return ans;
}

} // namespace snark
} // namespace zk
} // namespace crypto3
} // namespace nil

#endif // CRYPTO3_RUN_RAM_ZKSNARK_HPP
154 changes: 154 additions & 0 deletions examples/reductions/ram_to_r1cs/demo_arithmetization.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
//---------------------------------------------------------------------------//
// Copyright (c) 2018-2020 Mikhail Komarov <[email protected]>
// Copyright (c) 2020 Nikita Kaskov <[email protected]>
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//---------------------------------------------------------------------------//

#include <algorithm>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#ifndef MINDEPS
#include <boost/program_options.hpp>
#endif

#include <nil/crypto3/algebra/common/default_types/ec_pp.hpp>
#include <nil/crypto3/algebra/common/profiling.hpp>

#include <nil/crypto3/zk/snark/default_types/tinyram_ppzksnark_pp.hpp>
#include <nil/crypto3/zk/snark/reductions/ram_to_r1cs/ram_to_r1cs.hpp>
#include <nil/crypto3/zk/snark/relations/ram_computations/rams/tinyram/tinyram_params.hpp>
#include <nil/crypto3/zk/snark/proof_systems/ppzksnark/ram_ppzksnark/ram_ppzksnark.hpp>

#ifndef MINDEPS
namespace po = boost::program_options;

bool process_arithm_command_line(const int argc, const char **argv, std::string &assembly_fn,
std::string &processed_assembly_fn, std::string &architecture_params_fn,
std::string &computation_bounds_fn, std::string &primary_input_fn,
std::string &auxiliary_input_fn) {
try {
po::options_description desc("Usage");
desc.add_options()("help", "print this help message")("assembly",
po::value<std::string>(&assembly_fn)->required())(
"processed_assembly", po::value<std::string>(&processed_assembly_fn)->required())(
"architecture_params", po::value<std::string>(&architecture_params_fn)->required())(
"computation_bounds", po::value<std::string>(&computation_bounds_fn)->required())(
"primary_input", po::value<std::string>(&primary_input_fn)->required())(
"auxiliary_input", po::value<std::string>(&auxiliary_input_fn)->required());

po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);

if (vm.count("help")) {
std::cout << desc << "\n";
return false;
}

po::notify(vm);
} catch (std::exception &e) {
std::cerr << "Error: " << e.what() << "\n";
return false;
}

return true;
}
#endif

using namespace nil::crypto3::zk::snark;

int main(int argc, const char *argv[]) {
typedef typename algebra::default_ec_pp::scalar_field_type FieldType;
typedef ram_tinyram<FieldType> default_ram;



#ifdef MINDEPS
std::string assembly_fn = "assembly.s";
std::string processed_assembly_fn = "processed.txt";
std::string architecture_params_fn = "architecture_params.txt";
std::string computation_bounds_fn = "computation_bounds.txt";
std::string primary_input_fn = "primary_input.txt";
std::string auxiliary_input_fn = "auxiliary_input.txt";
#else
std::string assembly_fn;
std::string processed_assembly_fn;
std::string architecture_params_fn;
std::string computation_bounds_fn;
std::string primary_input_fn;
std::string auxiliary_input_fn;

if (!process_arithm_command_line(argc, argv, assembly_fn, processed_assembly_fn, architecture_params_fn,
computation_bounds_fn, primary_input_fn, auxiliary_input_fn)) {
return 1;
}
#endif


printf("================================================================================\n");
printf("TinyRAM example loader\n");
printf("================================================================================\n\n");

/* load everything */
ram_architecture_params<default_ram> ap;
std::ifstream f_ap(architecture_params_fn);
f_ap >> ap;

printf("Will run on %zu register machine (word size = %zu)\n", ap.k, ap.w);

std::ifstream f_rp(computation_bounds_fn);
std::size_t tinyram_input_size_bound, tinyram_program_size_bound, time_bound;
f_rp >> tinyram_input_size_bound >> tinyram_program_size_bound >> time_bound;

std::ifstream processed(processed_assembly_fn);
std::ifstream raw(assembly_fn);
tinyram_program program = load_preprocessed_program(ap, processed);
printf("Program:\n%s\n",
std::string((std::istreambuf_iterator<char>(raw)), std::istreambuf_iterator<char>()).c_str());

std::ifstream f_primary_input(primary_input_fn);
std::ifstream f_auxiliary_input(auxiliary_input_fn);

std::cout << "Loading primary input" << std::endl;
tinyram_input_tape primary_input(load_tape(f_primary_input));

std::cout << "Loading auxiliary input" << std::endl;
tinyram_input_tape auxiliary_input = load_tape(f_auxiliary_input);

const std::size_t boot_trace_size_bound = tinyram_input_size_bound + tinyram_program_size_bound;
const ram_boot_trace<default_ram> boot_trace =
tinyram_boot_trace_from_program_and_input(ap, boot_trace_size_bound, program, primary_input);

typedef ram_ppzksnark_machine_pp<default_tinyram_ppzksnark_pp> default_ram;

ram_to_r1cs<default_ram> r(ap, boot_trace_size_bound, time_bound);
r.instance_map();

const r1cs_primary_input<FieldType> r1cs_primary_input =
ram_to_r1cs<default_ram>::primary_input_map(ap, boot_trace_size_bound, boot_trace);
const r1cs_auxiliary_input<FieldType> r1cs_auxiliary_input = r.auxiliary_input_map(boot_trace, auxiliary_input);
const r1cs_constraint_system<FieldType> constraint_system = r.get_constraint_system();

r.print_execution_trace();
assert(constraint_system.is_satisfied(r1cs_primary_input, r1cs_auxiliary_input));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
//---------------------------------------------------------------------------//
// Copyright (c) 2018-2020 Mikhail Komarov <[email protected]>
// Copyright (c) 2020 Nikita Kaskov <[email protected]>
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//---------------------------------------------------------------------------//

#ifndef CRYPTO3_ZK_MEMORY_CONTENTS_EXAMPLES_HPP
#define CRYPTO3_ZK_MEMORY_CONTENTS_EXAMPLES_HPP

#include <nil/crypto3/zk/snark/relations/ram_computations/memory/memory_interface.hpp>

namespace nil {
namespace crypto3 {
namespace zk {
namespace snark {

/**
* Sample memory contents consisting of two blocks of random values;
* the first block is located at the beginning of memory, while
* the second block is located half-way through memory.
*/
memory_contents block_memory_contents(const std::size_t num_addresses,
const std::size_t value_size,
const std::size_t block1_size,
const std::size_t block2_size);

/**
* Sample memory contents having a given number of non-zero entries;
* each non-zero entry is a random value at a random address (approximately).
*/
memory_contents random_memory_contents(const std::size_t num_addresses,
const std::size_t value_size,
const std::size_t num_filled);

memory_contents block_memory_contents(const std::size_t num_addresses,
const std::size_t value_size,
const std::size_t block1_size,
const std::size_t block2_size) {
const std::size_t max_unit = 1ul << value_size;

memory_contents result;
for (std::size_t i = 0; i < block1_size; ++i) {
result[i] = std::rand() % max_unit;
}

for (std::size_t i = 0; i < block2_size; ++i) {
result[num_addresses / 2 + i] = std::rand() % max_unit;
}

return result;
}

memory_contents random_memory_contents(const std::size_t num_addresses,
const std::size_t value_size,
const std::size_t num_filled) {
const std::size_t max_unit = 1ul << value_size;

std::set<std::size_t> unfilled;
for (std::size_t i = 0; i < num_addresses; ++i) {
unfilled.insert(i);
}

memory_contents result;
for (std::size_t i = 0; i < num_filled; ++i) {
auto it = unfilled.begin();
std::advance(it, std::rand() % unfilled.size());
result[*it] = std::rand() % max_unit;
unfilled.erase(it);
}

return result;
}

} // namespace snark
} // namespace zk
} // namespace crypto3
} // namespace nil

#endif // CRYPTO3_ZK_MEMORY_CONTENTS_EXAMPLES_HPP
Loading