From e0d955f946aafb1be3983fd0b25ebad18b6b83db Mon Sep 17 00:00:00 2001 From: Iluvmagick Date: Thu, 12 Sep 2024 16:30:56 +0400 Subject: [PATCH] Added challenge aggregation stage. --- .../nil/proof-generator/arg_parser.hpp | 2 + .../include/nil/proof-generator/prover.hpp | 57 +++++++++++++++++-- bin/proof-producer/src/arg_parser.cpp | 8 ++- bin/proof-producer/src/main.cpp | 20 ++++--- 4 files changed, 72 insertions(+), 15 deletions(-) diff --git a/bin/proof-producer/include/nil/proof-generator/arg_parser.hpp b/bin/proof-producer/include/nil/proof-generator/arg_parser.hpp index 5a87924..fdb0acb 100644 --- a/bin/proof-producer/include/nil/proof-generator/arg_parser.hpp +++ b/bin/proof-producer/include/nil/proof-generator/arg_parser.hpp @@ -43,6 +43,8 @@ namespace nil { boost::filesystem::path circuit_file_path; boost::filesystem::path assignment_table_file_path; boost::filesystem::path assignment_description_file_path; + std::vector challenge_value_files; + boost::filesystem::path output_challenge_file = "aggregated_challenge.dat"; boost::log::trivial::severity_level log_level = boost::log::trivial::severity_level::info; CurvesVariant elliptic_curve_type = type_identity{}; HashesVariant hash_type = type_identity>{}; diff --git a/bin/proof-producer/include/nil/proof-generator/prover.hpp b/bin/proof-producer/include/nil/proof-generator/prover.hpp index 518747f..88386ac 100644 --- a/bin/proof-producer/include/nil/proof-generator/prover.hpp +++ b/bin/proof-producer/include/nil/proof-generator/prover.hpp @@ -50,6 +50,7 @@ #include #include #include +#include #include @@ -102,7 +103,8 @@ namespace nil { ALL = 0, PREPROCESS = 1, PROVE = 2, - VERIFY = 3 + VERIFY = 3, + GENERATE_AGGREGATED_CHALLENGE = 4 }; ProverStage prover_stage_from_string(const std::string& stage) { @@ -110,7 +112,8 @@ namespace nil { {"all", ProverStage::ALL}, {"preprocess", ProverStage::PREPROCESS}, {"prove", ProverStage::PROVE}, - {"verify", ProverStage::VERIFY} + {"verify", ProverStage::VERIFY}, + {"generate-aggregated-challenge", ProverStage::GENERATE_AGGREGATED_CHALLENGE} }; auto it = stage_map.find(stage); if (it == stage_map.end()) { @@ -276,12 +279,12 @@ namespace nil { return true; } - // This includes not only the common data, but also merkle trees, polynomials, etc, everything that a + // 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 " << + BOOST_LOG_TRIVIAL(info) << "Writing all preprocessed public data to " << preprocessed_data_file << std::endl; using PreprocessedPublicDataType = typename PublicPreprocessedData::preprocessed_data_type; @@ -322,7 +325,7 @@ namespace nil { 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 " << + BOOST_LOG_TRIVIAL(info) << "Writing commitment_state to " << commitment_scheme_state_file << std::endl; auto marshalled_lpc_state = fill_commitment_scheme( @@ -415,7 +418,7 @@ namespace nil { auto marshalled_assignment_description = nil::crypto3::marshalling::types::fill_assignment_table_description( - *table_description_ + *table_description_ ); bool res = nil::proof_generator::detail::encode_marshalling_to_file( assignment_description_file, @@ -485,6 +488,48 @@ namespace nil { return true; } + bool generate_aggregated_challenge_to_file( + const std::vector &aggregate_input_files, + const boost::filesystem::path &output_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 " << output_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 + return detail::encode_marshalling_to_file + (output_challenge_file, marshalled_challenge); + } + private: const std::size_t expand_factor_; const std::size_t max_quotient_chunks_; diff --git a/bin/proof-producer/src/arg_parser.cpp b/bin/proof-producer/src/arg_parser.cpp index 1244b29..be5cef6 100644 --- a/bin/proof-producer/src/arg_parser.cpp +++ b/bin/proof-producer/src/arg_parser.cpp @@ -73,7 +73,7 @@ namespace nil { // clang-format off auto options_appender = config.add_options() ("stage", make_defaulted_option(prover_options.stage), - "Stage of the prover to run, one of (all, preprocess, prove, verify). Defaults to 'all'.") + "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", make_defaulted_option(prover_options.preprocessed_common_data_path), "Preprocessed common data file") @@ -88,7 +88,11 @@ namespace nil { ("lambda-param", make_defaulted_option(prover_options.lambda), "Lambda param (9)") ("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"); + ("max-quotient-chunks,q", make_defaulted_option(prover_options.max_quotient_chunks), "Maximum quotient polynomial parts amount") + ("challenge-value-file,u", po::value>(&prover_options.challenge_value_files)->multitoken(), + "Challenge value files. Used with 'generate-aggregated-challenge' stage.") + ("output-challenge-file", po::value(&prover_options.output_challenge_file), + "Output challenge file. Used with 'generate-aggregated-challenge' stage"); // clang-format on po::options_description cmdline_options("nil; Proof Producer"); diff --git a/bin/proof-producer/src/main.cpp b/bin/proof-producer/src/main.cpp index 6810e5f..5dbb60e 100644 --- a/bin/proof-producer/src/main.cpp +++ b/bin/proof-producer/src/main.cpp @@ -42,21 +42,21 @@ int run_prover(const nil::proof_generator::ProverOptions& prover_options) { try { switch (nil::proof_generator::detail::prover_stage_from_string(prover_options.stage)) { case nil::proof_generator::detail::ProverStage::ALL: - prover_result = + 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.proof_file_path, prover_options.json_file_path, - false/*don't skip verification*/) && + 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_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) && @@ -72,20 +72,26 @@ int run_prover(const nil::proof_generator::ProverOptions& prover_options) { 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.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_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.challenge_value_files, + prover_options.output_challenge_file + ); + } } catch (const std::exception& e) { BOOST_LOG_TRIVIAL(error) << e.what(); return 1;