diff --git a/proof-producer/README.md b/proof-producer/README.md index 0ad37485a4..e9b180507d 100644 --- a/proof-producer/README.md +++ b/proof-producer/README.md @@ -57,3 +57,34 @@ proof-generator --circuit --assignment --proof cmake .. make -j $(nrpoc) ``` + +# Sample calls to proof-producer + +In all the calls you can change the executable name from proof-producer-single-threaded to proof-producer-multi-threaded to run on all the CPUs of your machine. + +Generate a proof and verify it: +```bash +./build/bin/proof-producer/proof-producer-single-threaded --circuit="circuit.crct" --assignment-table="assignment.tbl" --proof="proof.bin" -q 10 +``` + +Making a call to preprocessor: + +```bash +./build/bin/proof-producer/proof-producer-single-threaded --stage="preprocess" --circuit="circuit.crct" --assignment-table="assignment.tbl" --common-data="preprocessed_common_data.dat" --preprocessed-data="preprocessed.dat" --commitment-state-file="commitment_state.dat" --assignment-description-file="assignment-description.dat" -q 10 +``` + +Making a call to prover: + +```bash +./build/bin/proof-producer/proof-producer-single-threaded --stage="prove" --circuit="circuit.crct" --assignment-table="assignment.tbl" --common-data="preprocessed_common_data.dat" --preprocessed-data="preprocessed.dat" --commitment-state-file="commitment_state.dat" --proof="proof.bin" -q 10 +``` + +Verify generated proof: +```bash +./build/bin/proof-producer/proof-producer-single-threaded --stage="verify" --circuit="circuit.crct" --common-data="preprocessed_common_data.dat" --proof="proof.bin" --assignment-description-file="assignment-description.dat" -q 10 +``` + +Aggregate challenges +```bash +./build/bin/proof-producer/proof-producer-single-threaded --stage="generate-aggregated-challenge" --input-challenge-files challenge1.dat challenge2.dat --aggregated-challenge-file="aggregated_challenge.dat" +``` \ No newline at end of file diff --git a/proof-producer/bin/proof-producer/include/nil/proof-generator/arg_parser.hpp b/proof-producer/bin/proof-producer/include/nil/proof-generator/arg_parser.hpp index fe00a924e1..2194f46613 100644 --- a/proof-producer/bin/proof-producer/include/nil/proof-generator/arg_parser.hpp +++ b/proof-producer/bin/proof-producer/include/nil/proof-generator/arg_parser.hpp @@ -34,14 +34,18 @@ namespace nil { typename tuple_to_variant::type>::type; struct ProverOptions { + std::string stage = "all"; boost::filesystem::path proof_file_path = "proof.bin"; boost::filesystem::path json_file_path = "proof.json"; boost::filesystem::path preprocessed_common_data_path = "preprocessed_common_data.dat"; + boost::filesystem::path preprocessed_public_data_path = "preprocessed_data.dat"; + boost::filesystem::path commitment_scheme_state_path = "commitment_scheme_state.dat"; boost::filesystem::path circuit_file_path; boost::filesystem::path assignment_table_file_path; + boost::filesystem::path assignment_description_file_path; + std::vector input_challenge_files; + boost::filesystem::path aggregated_challenge_file = "aggregated_challenge.dat"; boost::log::trivial::severity_level log_level = boost::log::trivial::severity_level::info; - bool skip_verification = false; - bool verification_only = false; CurvesVariant elliptic_curve_type = type_identity{}; HashesVariant hash_type = type_identity>{}; diff --git a/proof-producer/bin/proof-producer/include/nil/proof-generator/prover.hpp b/proof-producer/bin/proof-producer/include/nil/proof-generator/prover.hpp index ac6fbcad4c..ab88ecd573 100644 --- a/proof-producer/bin/proof-producer/include/nil/proof-generator/prover.hpp +++ b/proof-producer/bin/proof-producer/include/nil/proof-generator/prover.hpp @@ -26,14 +26,21 @@ #include +#include +#include +#include + #include #include #include #include +#include #include #include #include + #include + #include #include #include @@ -43,11 +50,11 @@ #include #include #include +#include #include -#include -#include -#include + + #include #include @@ -68,7 +75,7 @@ namespace nil { auto read_iter = v->begin(); auto status = marshalled_data.read(read_iter, v->size()); if (status != nil::marshalling::status_type::success) { - BOOST_LOG_TRIVIAL(error) << "Marshalled structure decoding failed"; + BOOST_LOG_TRIVIAL(error) << "When reading a Marshalled structure from file " << path << ", decoding step failed"; return std::nullopt; } return marshalled_data; @@ -92,68 +99,82 @@ namespace nil { return hex ? write_vector_to_hex_file(v, path.c_str()) : write_vector_to_file(v, path.c_str()); } - std::vector generate_random_step_list(const std::size_t r, const int max_step) { - using Distribution = std::uniform_int_distribution; - static std::random_device random_engine; - - std::vector step_list; - std::size_t steps_sum = 0; - while (steps_sum != r) { - if (r - steps_sum <= max_step) { - while (r - steps_sum != 1) { - step_list.emplace_back(r - steps_sum - 1); - steps_sum += step_list.back(); - } - step_list.emplace_back(1); - steps_sum += step_list.back(); - } else { - step_list.emplace_back(Distribution(1, max_step)(random_engine)); - steps_sum += step_list.back(); - } + enum class ProverStage { + ALL = 0, + PREPROCESS = 1, + PROVE = 2, + VERIFY = 3, + GENERATE_AGGREGATED_CHALLENGE = 4 + }; + + ProverStage prover_stage_from_string(const std::string& stage) { + static std::unordered_map stage_map = { + {"all", ProverStage::ALL}, + {"preprocess", ProverStage::PREPROCESS}, + {"prove", ProverStage::PROVE}, + {"verify", ProverStage::VERIFY}, + {"generate-aggregated-challenge", ProverStage::GENERATE_AGGREGATED_CHALLENGE} + }; + auto it = stage_map.find(stage); + if (it == stage_map.end()) { + throw std::invalid_argument("Invalid stage: " + stage); } - return step_list; + return it->second; } + } // namespace detail + template class Prover { public: + using BlueprintField = typename CurveType::base_field_type; + using LpcParams = nil::crypto3::zk::commitments::list_polynomial_commitment_params; + using Lpc = nil::crypto3::zk::commitments::list_polynomial_commitment; + using LpcScheme = typename nil::crypto3::zk::commitments::lpc_commitment_scheme; + using CircuitParams = nil::crypto3::zk::snark::placeholder_circuit_params; + using PlaceholderParams = nil::crypto3::zk::snark::placeholder_params; + using Proof = nil::crypto3::zk::snark::placeholder_proof; + using PublicPreprocessedData = typename nil::crypto3::zk::snark:: + placeholder_public_preprocessor::preprocessed_data_type; + using CommonData = typename PublicPreprocessedData::common_data_type; + using PrivatePreprocessedData = typename nil::crypto3::zk::snark:: + placeholder_private_preprocessor::preprocessed_data_type; + using ConstraintSystem = nil::crypto3::zk::snark::plonk_constraint_system; + using TableDescription = nil::crypto3::zk::snark::plonk_table_description; + using Endianness = nil::marshalling::option::big_endian; + using FriParams = typename Lpc::fri_type::params_type; + using Column = nil::crypto3::zk::snark::plonk_column; + using AssignmentTable = nil::crypto3::zk::snark::plonk_table; + using TTypeBase = nil::marshalling::field_type; + Prover( - boost::filesystem::path circuit_file_name, - boost::filesystem::path preprocessed_common_data_file_name, - boost::filesystem::path assignment_table_file_name, - boost::filesystem::path proof_file, - boost::filesystem::path json_file, std::size_t lambda, std::size_t expand_factor, std::size_t max_q_chunks, std::size_t grind ) - : circuit_file_(circuit_file_name) - , preprocessed_common_data_file_(preprocessed_common_data_file_name) - , assignment_table_file_(assignment_table_file_name) - , proof_file_(proof_file) - , json_file_(json_file) - , lambda_(lambda) + : lambda_(lambda) , expand_factor_(expand_factor) , max_quotient_chunks_(max_q_chunks) , grind_(grind) { } - bool generate_to_file(bool skip_verification) { + // The caller must call the preprocessor or load the preprocessed data before calling this function. + bool generate_to_file( + boost::filesystem::path proof_file_, + boost::filesystem::path json_file_, + bool skip_verification) { if (!nil::proof_generator::can_write_to_file(proof_file_.string())) { BOOST_LOG_TRIVIAL(error) << "Can't write to file " << proof_file_; return false; } - prepare_for_operation(); - BOOST_ASSERT(public_preprocessed_data_); BOOST_ASSERT(private_preprocessed_data_); BOOST_ASSERT(table_description_); BOOST_ASSERT(constraint_system_); BOOST_ASSERT(lpc_scheme_); - BOOST_ASSERT(fri_params_); BOOST_LOG_TRIVIAL(info) << "Generating proof..."; Proof proof = nil::crypto3::zk::snark::placeholder_prover::process( @@ -175,14 +196,16 @@ namespace nil { BOOST_LOG_TRIVIAL(info) << "Writing proof to " << proof_file_; auto filled_placeholder_proof = - nil::crypto3::marshalling::types::fill_placeholder_proof(proof, *fri_params_); + nil::crypto3::marshalling::types::fill_placeholder_proof(proof, lpc_scheme_->get_fri_params()); bool res = nil::proof_generator::detail::encode_marshalling_to_file( proof_file_, filled_placeholder_proof, true ); if (res) { - BOOST_LOG_TRIVIAL(info) << "Proof written"; + BOOST_LOG_TRIVIAL(info) << "Proof written."; + } else { + BOOST_LOG_TRIVIAL(error) << "Failed to write proof to file."; } BOOST_LOG_TRIVIAL(info) << "Writing json proof to " << json_file_; @@ -204,67 +227,140 @@ namespace nil { return res; } - bool verify_from_file() { - prepare_for_operation(); + bool verify_from_file(boost::filesystem::path proof_file_) { + create_lpc_scheme(); + using ProofMarshalling = nil::crypto3::marshalling::types:: placeholder_proof, Proof>; + BOOST_LOG_TRIVIAL(info) << "Reading proof from file"; auto marshalled_proof = detail::decode_marshalling_from_file(proof_file_, true); if (!marshalled_proof) { return false; } - bool res = - verify(nil::crypto3::marshalling::types::make_placeholder_proof(*marshalled_proof - )); + bool res = verify(nil::crypto3::marshalling::types::make_placeholder_proof( + *marshalled_proof)); if (res) { - BOOST_LOG_TRIVIAL(info) << "Proof verified"; + BOOST_LOG_TRIVIAL(info) << "Proof verification passed."; } return res; } - bool save_preprocessed_common_data_to_file() { - BOOST_LOG_TRIVIAL(info) << "Writing preprocessed common data to file..."; - using Endianness = nil::marshalling::option::big_endian; - using TTypeBase = nil::marshalling::field_type; - using CommonData = typename PublicPreprocessedData::preprocessed_data_type::common_data_type; + bool save_preprocessed_common_data_to_file(boost::filesystem::path preprocessed_common_data_file) { + BOOST_LOG_TRIVIAL(info) << "Writing preprocessed common data to " << preprocessed_common_data_file << std::endl; auto marshalled_common_data = nil::crypto3::marshalling::types::fill_placeholder_common_data( public_preprocessed_data_->common_data ); bool res = nil::proof_generator::detail::encode_marshalling_to_file( - preprocessed_common_data_file_, + preprocessed_common_data_file, marshalled_common_data ); if (res) { - BOOST_LOG_TRIVIAL(info) << "Preprocessed common data written"; + BOOST_LOG_TRIVIAL(info) << "Preprocessed common data written."; } return res; } - private: - using BlueprintField = typename CurveType::base_field_type; - using LpcParams = nil::crypto3::zk::commitments::list_polynomial_commitment_params; - using Lpc = nil::crypto3::zk::commitments::list_polynomial_commitment; - using LpcScheme = typename nil::crypto3::zk::commitments::lpc_commitment_scheme; - using CircuitParams = nil::crypto3::zk::snark::placeholder_circuit_params; - using PlaceholderParams = nil::crypto3::zk::snark::placeholder_params; - using Proof = nil::crypto3::zk::snark::placeholder_proof; - using PublicPreprocessedData = typename nil::crypto3::zk::snark:: - placeholder_public_preprocessor::preprocessed_data_type; - using PrivatePreprocessedData = typename nil::crypto3::zk::snark:: - placeholder_private_preprocessor::preprocessed_data_type; - using ConstraintSystem = nil::crypto3::zk::snark::plonk_constraint_system; - using TableDescription = nil::crypto3::zk::snark::plonk_table_description; - using Endianness = nil::marshalling::option::big_endian; - using FriParams = typename Lpc::fri_type::params_type; - using Column = nil::crypto3::zk::snark::plonk_column; - using AssignmentTable = nil::crypto3::zk::snark::plonk_table; + bool read_preprocessed_common_data_from_file(boost::filesystem::path preprocessed_common_data_file) { + BOOST_LOG_TRIVIAL(info) << "Read preprocessed common data from " << preprocessed_common_data_file << std::endl; + + using CommonDataMarshalling = nil::crypto3::marshalling::types::placeholder_common_data; + + auto marshalled_value = detail::decode_marshalling_from_file( + preprocessed_common_data_file); + + if (!marshalled_value) { + return false; + } + common_data_.emplace(nil::crypto3::marshalling::types::make_placeholder_common_data( + *marshalled_value)); + + return true; + } + + // This includes not only the common data, but also merkle trees, polynomials, etc, everything that a + // public preprocessor generates. + bool save_public_preprocessed_data_to_file(boost::filesystem::path preprocessed_data_file) { + using namespace nil::crypto3::marshalling::types; + + BOOST_LOG_TRIVIAL(info) << "Writing all preprocessed public data to " << + preprocessed_data_file << std::endl; + using PreprocessedPublicDataType = typename PublicPreprocessedData::preprocessed_data_type; + + auto marshalled_preprocessed_public_data = + fill_placeholder_preprocessed_public_data( + *public_preprocessed_data_ + ); + bool res = nil::proof_generator::detail::encode_marshalling_to_file( + preprocessed_data_file, + marshalled_preprocessed_public_data + ); + if (res) { + BOOST_LOG_TRIVIAL(info) << "Preprocessed public data written."; + } + return res; + } + + bool read_public_preprocessed_data_from_file(boost::filesystem::path preprocessed_data_file) { + BOOST_LOG_TRIVIAL(info) << "Read preprocessed data from " << preprocessed_data_file << std::endl; + + using namespace nil::crypto3::marshalling::types; + + using PreprocessedPublicDataType = typename PublicPreprocessedData::preprocessed_data_type; + using PublicPreprocessedDataMarshalling = + placeholder_preprocessed_public_data; + + auto marshalled_value = detail::decode_marshalling_from_file( + preprocessed_data_file); + if (!marshalled_value) { + return false; + } + public_preprocessed_data_.emplace( + make_placeholder_preprocessed_public_data(*marshalled_value) + ); + return true; + } + + bool save_commitment_state_to_file(boost::filesystem::path commitment_scheme_state_file) { + using namespace nil::crypto3::marshalling::types; + + BOOST_LOG_TRIVIAL(info) << "Writing commitment_state to " << + commitment_scheme_state_file << std::endl; + + auto marshalled_lpc_state = fill_commitment_scheme( + *lpc_scheme_); + bool res = nil::proof_generator::detail::encode_marshalling_to_file( + commitment_scheme_state_file, + marshalled_lpc_state + ); + if (res) { + BOOST_LOG_TRIVIAL(info) << "Commitment scheme written."; + } + return res; + } + + bool read_commitment_scheme_from_file(boost::filesystem::path commitment_scheme_state_file) { + BOOST_LOG_TRIVIAL(info) << "Read commitment scheme from " << commitment_scheme_state_file << std::endl; + + using namespace nil::crypto3::marshalling::types; + + using CommitmentStateMarshalling = typename commitment_scheme_state::type; + + auto marshalled_value = detail::decode_marshalling_from_file( + commitment_scheme_state_file); + if (!marshalled_value) { + return false; + } + lpc_scheme_.emplace(make_commitment_scheme(*marshalled_value)); + return true; + } bool verify(const Proof& proof) const { BOOST_LOG_TRIVIAL(info) << "Verifying proof..."; bool verification_result = nil::crypto3::zk::snark::placeholder_verifier::process( - public_preprocessed_data_->common_data, + public_preprocessed_data_.has_value() ? public_preprocessed_data_->common_data : *common_data_, proof, *table_description_, *constraint_system_, @@ -280,23 +376,26 @@ namespace nil { return verification_result; } - bool prepare_for_operation() { - using BlueprintField = typename CurveType::base_field_type; - using TTypeBase = nil::marshalling::field_type; + bool read_circuit(const boost::filesystem::path& circuit_file_) { + BOOST_LOG_TRIVIAL(info) << "Read circuit from " << circuit_file_ << std::endl; + using ConstraintMarshalling = nil::crypto3::marshalling::types::plonk_constraint_system; - { - auto marshalled_value = detail::decode_marshalling_from_file(circuit_file_); - if (!marshalled_value) { - return false; - } - constraint_system_.emplace( - nil::crypto3::marshalling::types::make_plonk_constraint_system( - *marshalled_value - ) - ); + auto marshalled_value = detail::decode_marshalling_from_file(circuit_file_); + if (!marshalled_value) { + return false; } + constraint_system_.emplace( + nil::crypto3::marshalling::types::make_plonk_constraint_system( + *marshalled_value + ) + ); + return true; + } + + bool read_assignment_table(const boost::filesystem::path& assignment_table_file_) { + BOOST_LOG_TRIVIAL(info) << "Read assignment table from " << assignment_table_file_ << std::endl; using TableValueMarshalling = nil::crypto3::marshalling::types::plonk_assignment_table; @@ -309,53 +408,146 @@ namespace nil { nil::crypto3::marshalling::types::make_assignment_table( *marshalled_table ); + table_description_.emplace(table_description); + assignment_table_.emplace(std::move(assignment_table)); + return true; + } + + bool save_assignment_description(const boost::filesystem::path& assignment_description_file) { + BOOST_LOG_TRIVIAL(info) << "Writing assignment description to " << assignment_description_file << std::endl; + + auto marshalled_assignment_description = + nil::crypto3::marshalling::types::fill_assignment_table_description( + *table_description_ + ); + bool res = nil::proof_generator::detail::encode_marshalling_to_file( + assignment_description_file, + marshalled_assignment_description + ); + if (res) { + BOOST_LOG_TRIVIAL(info) << "Assignment description written."; + } + return res; + } + + bool read_assignment_description(const boost::filesystem::path& assignment_description_file_) { + BOOST_LOG_TRIVIAL(info) << "Read assignment description from " << assignment_description_file_ << std::endl; - public_inputs_.emplace(assignment_table.public_inputs()); + using TableDescriptionMarshalling = + nil::crypto3::marshalling::types::plonk_assignment_table_description; + auto marshalled_description = + detail::decode_marshalling_from_file(assignment_description_file_); + if (!marshalled_description) { + return false; + } + auto table_description = + nil::crypto3::marshalling::types::make_assignment_table_description( + *marshalled_description + ); table_description_.emplace(table_description); + return true; + } - // Lambdas and grinding bits should be passed threw preprocessor directives + void create_lpc_scheme() { + // Lambdas and grinding bits should be passed through preprocessor directives std::size_t table_rows_log = std::ceil(std::log2(table_description_->rows_amount)); - fri_params_.emplace(FriParams(1, table_rows_log, lambda_, expand_factor_)); - lpc_scheme_.emplace(*fri_params_); + lpc_scheme_.emplace(FriParams(1, table_rows_log, lambda_, expand_factor_)); + } + + bool preprocess_public_data() { + public_inputs_.emplace(assignment_table_->public_inputs()); + + create_lpc_scheme(); BOOST_LOG_TRIVIAL(info) << "Preprocessing public data"; public_preprocessed_data_.emplace( nil::crypto3::zk::snark::placeholder_public_preprocessor:: process( *constraint_system_, - assignment_table.move_public_table(), + assignment_table_->move_public_table(), *table_description_, *lpc_scheme_, max_quotient_chunks_ ) ); + return true; + } + + bool preprocess_private_data() { BOOST_LOG_TRIVIAL(info) << "Preprocessing private data"; private_preprocessed_data_.emplace( nil::crypto3::zk::snark::placeholder_private_preprocessor:: - process(*constraint_system_, assignment_table.move_private_table(), *table_description_) + process(*constraint_system_, assignment_table_->move_private_table(), *table_description_) ); + + // This is the last stage of preprocessor, and the assignment table is not used after this function call. + assignment_table_.reset(); + return true; } - const boost::filesystem::path circuit_file_; - const boost::filesystem::path preprocessed_common_data_file_; - const boost::filesystem::path assignment_table_file_; - const boost::filesystem::path proof_file_; - const boost::filesystem::path json_file_; + bool generate_aggregated_challenge_to_file( + const std::vector &aggregate_input_files, + const boost::filesystem::path &aggregated_challenge_file + ) { + if (aggregate_input_files.empty()) { + BOOST_LOG_TRIVIAL(error) << "No input files for challenge aggregation"; + return false; + } + BOOST_LOG_TRIVIAL(info) << "Generating aggregated challenge to " << aggregated_challenge_file; + // check that we can access all input files + for (const auto &input_file : aggregate_input_files) { + BOOST_LOG_TRIVIAL(info) << "Reading challenge from " << input_file; + if (!nil::proof_generator::can_read_from_file(input_file.string())) { + BOOST_LOG_TRIVIAL(error) << "Can't read file " << input_file; + return false; + } + } + // create the transcript + using transcript_hash_type = typename PlaceholderParams::transcript_hash_type; + using transcript_type = crypto3::zk::transcript::fiat_shamir_heuristic_sequential; + using challenge_marshalling_type = + nil::crypto3::marshalling::types::field_element< + TTypeBase, typename BlueprintField::value_type>; + transcript_type transcript; + // read challenges from input files and add them to the transcript + for (const auto &input_file : aggregate_input_files) { + auto challenge = detail::decode_marshalling_from_file(input_file); + if (!challenge) { + BOOST_LOG_TRIVIAL(error) << "Failed to read challenge from " << input_file; + return false; + } + transcript(challenge->value()); + } + // produce the aggregated challenge + auto output_challenge = transcript.template challenge(); + // marshall the challenge + challenge_marshalling_type marshalled_challenge(output_challenge); + // write the challenge to the output file + BOOST_LOG_TRIVIAL(info) << "Writing aggregated challenge to " << aggregated_challenge_file; + return detail::encode_marshalling_to_file + (aggregated_challenge_file, marshalled_challenge); + } + + private: const std::size_t expand_factor_; const std::size_t max_quotient_chunks_; const std::size_t lambda_; const std::size_t grind_; - // All set on prepare_for_operation() std::optional public_preprocessed_data_; + + // TODO: This is used in verifier, since it does not need the whole preprocessed data. + // It makes sence to separate prover class from verifier later. + std::optional common_data_; + std::optional private_preprocessed_data_; std::optional public_inputs_; std::optional table_description_; std::optional constraint_system_; - std::optional fri_params_; + std::optional assignment_table_; std::optional lpc_scheme_; }; diff --git a/proof-producer/bin/proof-producer/src/arg_parser.cpp b/proof-producer/bin/proof-producer/src/arg_parser.cpp index 06bf3b9f29..efd8ced431 100644 --- a/proof-producer/bin/proof-producer/src/arg_parser.cpp +++ b/proof-producer/bin/proof-producer/src/arg_parser.cpp @@ -72,11 +72,16 @@ namespace nil { ); // clang-format off auto options_appender = config.add_options() - ("proof,p", make_defaulted_option(prover_options.proof_file_path), "Output proof file") + ("stage", make_defaulted_option(prover_options.stage), + "Stage of the prover to run, one of (all, preprocess, prove, verify, generate-aggregated-challenge). Defaults to 'all'.") + ("proof,p", make_defaulted_option(prover_options.proof_file_path), "Proof file") ("json,j", make_defaulted_option(prover_options.json_file_path), "JSON proof file") - ("common-data,d", make_defaulted_option(prover_options.preprocessed_common_data_path), "Output preprocessed common data file") - ("circuit", po::value(&prover_options.circuit_file_path)->required(), "Circuit input file") - ("assignment-table,t", po::value(&prover_options.assignment_table_file_path)->required(), "Assignment table input file") + ("common-data", make_defaulted_option(prover_options.preprocessed_common_data_path), "Preprocessed common data file") + ("preprocessed-data", make_defaulted_option(prover_options.preprocessed_public_data_path), "Preprocessed public data file") + ("commitment-state-file", make_defaulted_option(prover_options.commitment_scheme_state_path), "Commitment state data file") + ("circuit", po::value(&prover_options.circuit_file_path), "Circuit input file") + ("assignment-table,t", po::value(&prover_options.assignment_table_file_path), "Assignment table input file") + ("assignment-description-file", po::value(&prover_options.assignment_description_file_path), "Assignment description file") ("log-level,l", make_defaulted_option(prover_options.log_level), "Log level (trace, debug, info, warning, error, fatal)") ("elliptic-curve-type,e", make_defaulted_option(prover_options.elliptic_curve_type), "Elliptic curve type (pallas)") ("hash-type", make_defaulted_option(prover_options.hash_type), "Hash type (keccak, poseidon, sha256)") @@ -84,8 +89,11 @@ namespace nil { ("grind-param", make_defaulted_option(prover_options.grind), "Grind param (69)") ("expand-factor,x", make_defaulted_option(prover_options.expand_factor), "Expand factor") ("max-quotient-chunks,q", make_defaulted_option(prover_options.max_quotient_chunks), "Maximum quotient polynomial parts amount") - ("skip-verification", po::bool_switch(&prover_options.skip_verification), "Skip generated proof verifying step") - ("verification-only", po::bool_switch(&prover_options.verification_only), "Read proof for verification instead of writing to it"); + ("input-challenge-files,u", po::value>(&prover_options.input_challenge_files)->multitoken(), + "Input challenge files. Used with 'generate-aggregated-challenge' stage.") + ("aggregated-challenge-file", po::value(&prover_options.aggregated_challenge_file), + "Aggregated challenge file. Used with 'generate-aggregated-challenge' stage"); + // clang-format on po::options_description cmdline_options("nil; Proof Producer"); cmdline_options.add(generic).add(config); diff --git a/proof-producer/bin/proof-producer/src/main.cpp b/proof-producer/bin/proof-producer/src/main.cpp index 15d37be392..41a5fad19d 100644 --- a/proof-producer/bin/proof-producer/src/main.cpp +++ b/proof-producer/bin/proof-producer/src/main.cpp @@ -33,11 +33,6 @@ template int run_prover(const nil::proof_generator::ProverOptions& prover_options) { auto prover_task = [&] { auto prover = nil::proof_generator::Prover( - prover_options.circuit_file_path, - prover_options.preprocessed_common_data_path, - prover_options.assignment_table_file_path, - prover_options.proof_file_path, - prover_options.json_file_path, prover_options.lambda, prover_options.expand_factor, prover_options.max_quotient_chunks, @@ -45,9 +40,58 @@ int run_prover(const nil::proof_generator::ProverOptions& prover_options) { ); bool prover_result; try { - prover_result = prover_options.verification_only ? prover.verify_from_file() - : prover.generate_to_file(prover_options.skip_verification) - && prover.save_preprocessed_common_data_to_file(); + switch (nil::proof_generator::detail::prover_stage_from_string(prover_options.stage)) { + case nil::proof_generator::detail::ProverStage::ALL: + prover_result = + prover.read_circuit(prover_options.circuit_file_path) && + prover.read_assignment_table(prover_options.assignment_table_file_path) && + prover.preprocess_public_data() && + prover.preprocess_private_data() && + prover.generate_to_file( + prover_options.proof_file_path, + prover_options.json_file_path, + false/*don't skip verification*/) && + prover.save_preprocessed_common_data_to_file(prover_options.preprocessed_common_data_path) && + prover.save_public_preprocessed_data_to_file(prover_options.preprocessed_public_data_path) && + prover.save_commitment_state_to_file(prover_options.commitment_scheme_state_path); + break; + case nil::proof_generator::detail::ProverStage::PREPROCESS: + prover_result = + prover.read_circuit(prover_options.circuit_file_path) && + prover.read_assignment_table(prover_options.assignment_table_file_path) && + prover.save_assignment_description(prover_options.assignment_description_file_path) && + prover.preprocess_public_data() && + prover.save_preprocessed_common_data_to_file(prover_options.preprocessed_common_data_path) && + prover.save_public_preprocessed_data_to_file(prover_options.preprocessed_public_data_path) && + prover.save_commitment_state_to_file(prover_options.commitment_scheme_state_path); + break; + case nil::proof_generator::detail::ProverStage::PROVE: + // Load preprocessed data from file and generate the proof. + prover_result = + prover.read_circuit(prover_options.circuit_file_path) && + prover.read_assignment_table(prover_options.assignment_table_file_path) && + prover.read_public_preprocessed_data_from_file(prover_options.preprocessed_public_data_path) && + prover.read_commitment_scheme_from_file(prover_options.commitment_scheme_state_path) && + prover.preprocess_private_data() && + prover.generate_to_file( + prover_options.proof_file_path, + prover_options.json_file_path, + true/*skip verification*/); + break; + case nil::proof_generator::detail::ProverStage::VERIFY: + prover_result = + prover.read_circuit(prover_options.circuit_file_path) && + prover.read_preprocessed_common_data_from_file(prover_options.preprocessed_common_data_path) && + prover.read_assignment_description(prover_options.assignment_description_file_path) && + prover.verify_from_file(prover_options.proof_file_path); + break; + case nil::proof_generator::detail::ProverStage::GENERATE_AGGREGATED_CHALLENGE: + prover_result = + prover.generate_aggregated_challenge_to_file( + prover_options.input_challenge_files, + prover_options.aggregated_challenge_file + ); + } } catch (const std::exception& e) { BOOST_LOG_TRIVIAL(error) << e.what(); return 1;