From ef10d6576aa9e89eece5a40669c425ae7987ee8a Mon Sep 17 00:00:00 2001 From: Lucas Xia Date: Tue, 12 Mar 2024 10:18:45 -0600 Subject: [PATCH] refactor: share code between provers (#4655) A lot of code is repeated between the Decider prover, folding prover, and ultra honk prover. This PR aims to reduce duplication by creating a OinkProver, which supports the 5 round functions before sumcheck. The OinkProver is used in the folding and ultra honk provers. It does not address the shared code between verifiers or the shared code between prover and verifier. It also is an initial step at a round abstraction, where each round is implemented as a separate class and the data being used/modified in each round is clearly defined. Resolves https://github.com/AztecProtocol/barretenberg/issues/795. --- .../ultra_bench/ultra_honk_rounds.bench.cpp | 13 +- .../protogalaxy/protogalaxy_prover.cpp | 90 ++--------- .../protogalaxy/protogalaxy_verifier.cpp | 7 +- .../protogalaxy_recursive_verifier.cpp | 11 +- .../barretenberg/ultra_honk/oink_prover.cpp | 133 +++++++++++++++++ .../barretenberg/ultra_honk/oink_prover.hpp | 49 ++++++ .../barretenberg/ultra_honk/ultra_prover.cpp | 141 ++---------------- .../barretenberg/ultra_honk/ultra_prover.hpp | 32 ++-- 8 files changed, 236 insertions(+), 240 deletions(-) create mode 100644 barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp create mode 100644 barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.hpp diff --git a/barretenberg/cpp/src/barretenberg/benchmark/ultra_bench/ultra_honk_rounds.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/ultra_bench/ultra_honk_rounds.bench.cpp index 11ad5e6e15f..aebc60b1912 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/ultra_bench/ultra_honk_rounds.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/ultra_bench/ultra_honk_rounds.bench.cpp @@ -45,11 +45,11 @@ BB_PROFILE static void test_round_inner(State& state, GoblinUltraProver& prover, } }; - time_if_index(PREAMBLE, [&] { prover.execute_preamble_round(); }); - time_if_index(WIRE_COMMITMENTS, [&] { prover.execute_wire_commitments_round(); }); - time_if_index(SORTED_LIST_ACCUMULATOR, [&] { prover.execute_sorted_list_accumulator_round(); }); - time_if_index(LOG_DERIVATIVE_INVERSE, [&] { prover.execute_log_derivative_inverse_round(); }); - time_if_index(GRAND_PRODUCT_COMPUTATION, [&] { prover.execute_grand_product_computation_round(); }); + time_if_index(PREAMBLE, [&] { prover.oink_prover.execute_preamble_round(); }); + time_if_index(WIRE_COMMITMENTS, [&] { prover.oink_prover.execute_wire_commitments_round(); }); + time_if_index(SORTED_LIST_ACCUMULATOR, [&] { prover.oink_prover.execute_sorted_list_accumulator_round(); }); + time_if_index(LOG_DERIVATIVE_INVERSE, [&] { prover.oink_prover.execute_log_derivative_inverse_round(); }); + time_if_index(GRAND_PRODUCT_COMPUTATION, [&] { prover.oink_prover.execute_grand_product_computation_round(); }); time_if_index(RELATION_CHECK, [&] { prover.execute_relation_check_rounds(); }); time_if_index(ZEROMORPH, [&] { prover.execute_zeromorph_rounds(); }); } @@ -62,7 +62,10 @@ BB_PROFILE static void test_round(State& state, size_t index) noexcept auto prover = bb::mock_proofs::get_prover( &bb::mock_proofs::generate_basic_arithmetic_circuit, log2_num_gates); for (auto _ : state) { + state.PauseTiming(); test_round_inner(state, prover, index); + state.ResumeTiming(); + // NOTE: google bench is very finnicky, must end in ResumeTiming() for correctness } } #define ROUND_BENCHMARK(round) \ diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp index 65df1840efa..131f52d4c8b 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp @@ -1,93 +1,29 @@ #include "protogalaxy_prover.hpp" #include "barretenberg/flavor/flavor.hpp" +#include "barretenberg/ultra_honk/oink_prover.hpp" namespace bb { template void ProtoGalaxyProver_::finalise_and_send_instance(std::shared_ptr instance, const std::string& domain_separator) { - instance->initialize_prover_polynomials(); + OinkProver oink_prover(instance, commitment_key, transcript, domain_separator + '_'); - const auto instance_size = static_cast(instance->proving_key->circuit_size); - const auto num_public_inputs = static_cast(instance->proving_key->num_public_inputs); - transcript->send_to_verifier(domain_separator + "_instance_size", instance_size); - transcript->send_to_verifier(domain_separator + "_public_input_size", num_public_inputs); + // Add circuit size public input size and public inputs to transcript + oink_prover.execute_preamble_round(); - for (size_t i = 0; i < instance->proving_key->public_inputs.size(); ++i) { - auto public_input_i = instance->proving_key->public_inputs[i]; - transcript->send_to_verifier(domain_separator + "_public_input_" + std::to_string(i), public_input_i); - } - transcript->send_to_verifier(domain_separator + "_pub_inputs_offset", - static_cast(instance->proving_key->pub_inputs_offset)); - - auto& witness_commitments = instance->witness_commitments; - - // Commit to the first three wire polynomials of the instance - // We only commit to the fourth wire polynomial after adding memory recordss - witness_commitments.w_l = commitment_key->commit(instance->proving_key->w_l); - witness_commitments.w_r = commitment_key->commit(instance->proving_key->w_r); - witness_commitments.w_o = commitment_key->commit(instance->proving_key->w_o); - - auto wire_comms = witness_commitments.get_wires(); - auto commitment_labels = instance->commitment_labels; - auto wire_labels = commitment_labels.get_wires(); - for (size_t idx = 0; idx < 3; ++idx) { - transcript->send_to_verifier(domain_separator + "_" + wire_labels[idx], wire_comms[idx]); - } - - if constexpr (IsGoblinFlavor) { - // Commit to Goblin ECC op wires - witness_commitments.ecc_op_wire_1 = commitment_key->commit(instance->proving_key->ecc_op_wire_1); - witness_commitments.ecc_op_wire_2 = commitment_key->commit(instance->proving_key->ecc_op_wire_2); - witness_commitments.ecc_op_wire_3 = commitment_key->commit(instance->proving_key->ecc_op_wire_3); - witness_commitments.ecc_op_wire_4 = commitment_key->commit(instance->proving_key->ecc_op_wire_4); - - auto op_wire_comms = instance->witness_commitments.get_ecc_op_wires(); - auto labels = commitment_labels.get_ecc_op_wires(); - for (size_t idx = 0; idx < Flavor::NUM_WIRES; ++idx) { - transcript->send_to_verifier(domain_separator + "_" + labels[idx], op_wire_comms[idx]); - } - // Commit to DataBus columns - witness_commitments.calldata = commitment_key->commit(instance->proving_key->calldata); - witness_commitments.calldata_read_counts = commitment_key->commit(instance->proving_key->calldata_read_counts); - transcript->send_to_verifier(domain_separator + "_" + commitment_labels.calldata, - instance->witness_commitments.calldata); - transcript->send_to_verifier(domain_separator + "_" + commitment_labels.calldata_read_counts, - instance->witness_commitments.calldata_read_counts); - } - - auto eta = transcript->template get_challenge(domain_separator + "_eta"); - instance->compute_sorted_accumulator_polynomials(eta); - - // Commit to the sorted witness-table accumulator and the finalized (i.e. with memory records) fourth wire - // polynomial - witness_commitments.sorted_accum = commitment_key->commit(instance->prover_polynomials.sorted_accum); - witness_commitments.w_4 = commitment_key->commit(instance->prover_polynomials.w_4); + // Compute first three wire commitments + oink_prover.execute_wire_commitments_round(); - transcript->send_to_verifier(domain_separator + "_" + commitment_labels.sorted_accum, - witness_commitments.sorted_accum); - transcript->send_to_verifier(domain_separator + "_" + commitment_labels.w_4, witness_commitments.w_4); - - auto [beta, gamma] = - transcript->template get_challenges(domain_separator + "_beta", domain_separator + "_gamma"); - - if constexpr (IsGoblinFlavor) { - // Compute and commit to the logderivative inverse used in DataBus - instance->compute_logderivative_inverse(beta, gamma); - instance->witness_commitments.lookup_inverses = - commitment_key->commit(instance->prover_polynomials.lookup_inverses); - transcript->send_to_verifier(domain_separator + "_" + commitment_labels.lookup_inverses, - instance->witness_commitments.lookup_inverses); - } + // Compute sorted list accumulator and commitment + oink_prover.execute_sorted_list_accumulator_round(); - instance->compute_grand_product_polynomials(beta, gamma); + // Fiat-Shamir: beta & gamma + oink_prover.execute_log_derivative_inverse_round(); - witness_commitments.z_perm = commitment_key->commit(instance->prover_polynomials.z_perm); - witness_commitments.z_lookup = commitment_key->commit(instance->prover_polynomials.z_lookup); + // Compute grand product(s) and commitments. + oink_prover.execute_grand_product_computation_round(); - transcript->send_to_verifier(domain_separator + "_" + commitment_labels.z_perm, - instance->witness_commitments.z_perm); - transcript->send_to_verifier(domain_separator + "_" + commitment_labels.z_lookup, - instance->witness_commitments.z_lookup); + // Generate relation separators alphas for sumcheck for (size_t idx = 0; idx < NUM_SUBRELATIONS - 1; idx++) { instance->alphas[idx] = transcript->template get_challenge(domain_separator + "_alpha_" + std::to_string(idx)); diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp index 667460b5b20..cf08f67d30a 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp @@ -8,11 +8,13 @@ void ProtoGalaxyVerifier_::receive_and_finalise_instance(cons { // Get circuit parameters and the public inputs inst->verification_key->circuit_size = - transcript->template receive_from_prover(domain_separator + "_instance_size"); + transcript->template receive_from_prover(domain_separator + "_circuit_size"); inst->verification_key->log_circuit_size = static_cast(numeric::get_msb(inst->verification_key->circuit_size)); inst->verification_key->num_public_inputs = transcript->template receive_from_prover(domain_separator + "_public_input_size"); + inst->verification_key->pub_inputs_offset = + transcript->template receive_from_prover(domain_separator + "_pub_inputs_offset"); inst->verification_key->public_inputs.clear(); for (size_t i = 0; i < inst->verification_key->num_public_inputs; ++i) { auto public_input_i = @@ -20,9 +22,6 @@ void ProtoGalaxyVerifier_::receive_and_finalise_instance(cons inst->verification_key->public_inputs.emplace_back(public_input_i); } - inst->verification_key->pub_inputs_offset = - transcript->template receive_from_prover(domain_separator + "_pub_inputs_offset"); - // Get commitments to first three wire polynomials auto labels = inst->commitment_labels; auto& witness_commitments = inst->witness_commitments; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.cpp index b460fe76b5b..2eb8fd4f209 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.cpp @@ -9,13 +9,17 @@ void ProtoGalaxyRecursiveVerifier_::receive_and_finalise_inst const std::shared_ptr& inst, const std::string& domain_separator) { // Get circuit parameters and the public inputs - const auto instance_size = transcript->template receive_from_prover(domain_separator + "_instance_size"); + const auto instance_size = transcript->template receive_from_prover(domain_separator + "_circuit_size"); const auto public_input_size = transcript->template receive_from_prover(domain_separator + "_public_input_size"); inst->verification_key->circuit_size = uint32_t(instance_size.get_value()); inst->verification_key->log_circuit_size = static_cast(numeric::get_msb(inst->verification_key->circuit_size)); inst->verification_key->num_public_inputs = uint32_t(public_input_size.get_value()); + const auto pub_inputs_offset = + transcript->template receive_from_prover(domain_separator + "_pub_inputs_offset"); + inst->verification_key->pub_inputs_offset = uint32_t(pub_inputs_offset.get_value()); + inst->verification_key->public_inputs.clear(); for (size_t i = 0; i < inst->verification_key->num_public_inputs; ++i) { auto public_input_i = @@ -23,11 +27,6 @@ void ProtoGalaxyRecursiveVerifier_::receive_and_finalise_inst inst->verification_key->public_inputs.emplace_back(public_input_i); } - const auto pub_inputs_offset = - transcript->template receive_from_prover(domain_separator + "_pub_inputs_offset"); - - inst->verification_key->pub_inputs_offset = uint32_t(pub_inputs_offset.get_value()); - // Get commitments to first three wire polynomials auto labels = inst->commitment_labels; auto& witness_commitments = inst->witness_commitments; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp new file mode 100644 index 00000000000..bfb1d0ad97f --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp @@ -0,0 +1,133 @@ +#include "barretenberg/ultra_honk/oink_prover.hpp" + +namespace bb { + +/** + * @brief Add circuit size, public input size, and public inputs to transcript + * + */ +template void OinkProver::execute_preamble_round() +{ + const auto circuit_size = static_cast(instance->proving_key->circuit_size); + const auto num_public_inputs = static_cast(instance->proving_key->num_public_inputs); + transcript->send_to_verifier(domain_separator + "circuit_size", circuit_size); + transcript->send_to_verifier(domain_separator + "public_input_size", num_public_inputs); + transcript->send_to_verifier(domain_separator + "pub_inputs_offset", + static_cast(instance->proving_key->pub_inputs_offset)); + + ASSERT(instance->proving_key->num_public_inputs == instance->proving_key->public_inputs.size()); + + for (size_t i = 0; i < instance->proving_key->num_public_inputs; ++i) { + auto public_input_i = instance->proving_key->public_inputs[i]; + transcript->send_to_verifier(domain_separator + "public_input_" + std::to_string(i), public_input_i); + } +} + +/** + * @brief Commit to the wire polynomials (part of the witness), with the exception of the fourth wire, which is + * only commited to after adding memory records. In the Goblin Flavor, we also commit to the ECC OP wires and the + * DataBus columns. + */ +template void OinkProver::execute_wire_commitments_round() +{ + auto& witness_commitments = instance->witness_commitments; + + // Commit to the first three wire polynomials of the instance + // We only commit to the fourth wire polynomial after adding memory recordss + witness_commitments.w_l = commitment_key->commit(instance->proving_key->w_l); + witness_commitments.w_r = commitment_key->commit(instance->proving_key->w_r); + witness_commitments.w_o = commitment_key->commit(instance->proving_key->w_o); + + auto wire_comms = witness_commitments.get_wires(); + auto& commitment_labels = instance->commitment_labels; + auto wire_labels = commitment_labels.get_wires(); + for (size_t idx = 0; idx < 3; ++idx) { + transcript->send_to_verifier(domain_separator + wire_labels[idx], wire_comms[idx]); + } + + if constexpr (IsGoblinFlavor) { + // Commit to Goblin ECC op wires + witness_commitments.ecc_op_wire_1 = commitment_key->commit(instance->proving_key->ecc_op_wire_1); + witness_commitments.ecc_op_wire_2 = commitment_key->commit(instance->proving_key->ecc_op_wire_2); + witness_commitments.ecc_op_wire_3 = commitment_key->commit(instance->proving_key->ecc_op_wire_3); + witness_commitments.ecc_op_wire_4 = commitment_key->commit(instance->proving_key->ecc_op_wire_4); + + auto op_wire_comms = witness_commitments.get_ecc_op_wires(); + auto labels = commitment_labels.get_ecc_op_wires(); + for (size_t idx = 0; idx < Flavor::NUM_WIRES; ++idx) { + transcript->send_to_verifier(domain_separator + labels[idx], op_wire_comms[idx]); + } + // Commit to DataBus columns + witness_commitments.calldata = commitment_key->commit(instance->proving_key->calldata); + witness_commitments.calldata_read_counts = commitment_key->commit(instance->proving_key->calldata_read_counts); + transcript->send_to_verifier(domain_separator + commitment_labels.calldata, witness_commitments.calldata); + transcript->send_to_verifier(domain_separator + commitment_labels.calldata_read_counts, + witness_commitments.calldata_read_counts); + } +} + +/** + * @brief Compute sorted witness-table accumulator and commit to the resulting polynomials. + * + */ +template void OinkProver::execute_sorted_list_accumulator_round() +{ + auto& witness_commitments = instance->witness_commitments; + const auto& commitment_labels = instance->commitment_labels; + + auto eta = transcript->template get_challenge(domain_separator + "eta"); + instance->compute_sorted_accumulator_polynomials(eta); + + // Commit to the sorted witness-table accumulator and the finalized (i.e. with memory records) fourth wire + // polynomial + witness_commitments.sorted_accum = commitment_key->commit(instance->prover_polynomials.sorted_accum); + witness_commitments.w_4 = commitment_key->commit(instance->prover_polynomials.w_4); + + transcript->send_to_verifier(domain_separator + commitment_labels.sorted_accum, witness_commitments.sorted_accum); + transcript->send_to_verifier(domain_separator + commitment_labels.w_4, witness_commitments.w_4); +} + +/** + * @brief Compute log derivative inverse polynomial and its commitment, if required + * + */ +template void OinkProver::execute_log_derivative_inverse_round() +{ + auto& witness_commitments = instance->witness_commitments; + const auto& commitment_labels = instance->commitment_labels; + + auto [beta, gamma] = transcript->template get_challenges(domain_separator + "beta", domain_separator + "gamma"); + instance->relation_parameters.beta = beta; + instance->relation_parameters.gamma = gamma; + if constexpr (IsGoblinFlavor) { + // Compute and commit to the logderivative inverse used in DataBus + instance->compute_logderivative_inverse(beta, gamma); + witness_commitments.lookup_inverses = commitment_key->commit(instance->prover_polynomials.lookup_inverses); + transcript->send_to_verifier(domain_separator + commitment_labels.lookup_inverses, + witness_commitments.lookup_inverses); + } +} + +/** + * @brief Compute permutation and lookup grand product polynomials and their commitments + * + */ +template void OinkProver::execute_grand_product_computation_round() +{ + auto& witness_commitments = instance->witness_commitments; + const auto& commitment_labels = instance->commitment_labels; + + instance->compute_grand_product_polynomials(instance->relation_parameters.beta, + instance->relation_parameters.gamma); + + witness_commitments.z_perm = commitment_key->commit(instance->prover_polynomials.z_perm); + witness_commitments.z_lookup = commitment_key->commit(instance->prover_polynomials.z_lookup); + + transcript->send_to_verifier(domain_separator + commitment_labels.z_perm, witness_commitments.z_perm); + transcript->send_to_verifier(domain_separator + commitment_labels.z_lookup, witness_commitments.z_lookup); +} + +template class OinkProver; +template class OinkProver; + +} // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.hpp new file mode 100644 index 00000000000..470794d8237 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.hpp @@ -0,0 +1,49 @@ +#pragma once +#include + +#include "barretenberg/flavor/goblin_ultra.hpp" +#include "barretenberg/flavor/ultra.hpp" +#include "barretenberg/sumcheck/instance/prover_instance.hpp" +#include "barretenberg/transcript/transcript.hpp" + +namespace bb { + +/** + * @brief Class for all the oink rounds, which are shared between the folding prover and ultra prover. + * @details This class contains execute_preamble_round(), execute_wire_commitments_round(), + * execute_sorted_list_accumulator_round(), execute_log_derivative_inverse_round(), and + * execute_grand_product_computation_round(). + * + * @tparam Flavor + */ +template class OinkProver { + using CommitmentKey = typename Flavor::CommitmentKey; + using Instance = ProverInstance_; + using Transcript = typename Flavor::Transcript; + using FF = typename Flavor::FF; + + public: + std::shared_ptr instance; + std::shared_ptr transcript; + std::shared_ptr commitment_key; + std::string domain_separator; + + OinkProver(const std::shared_ptr>& inst, + const std::shared_ptr& commitment_key, + const std::shared_ptr& transcript, + std::string domain_separator = "") + : instance(inst) + , transcript(transcript) + , commitment_key(commitment_key) + , domain_separator(std::move(domain_separator)) + { + instance->initialize_prover_polynomials(); + } + + void execute_preamble_round(); + void execute_wire_commitments_round(); + void execute_sorted_list_accumulator_round(); + void execute_log_derivative_inverse_round(); + void execute_grand_product_computation_round(); +}; +} // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp index f6d800558b5..fe78a0d7d88 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp @@ -15,9 +15,8 @@ UltraProver_::UltraProver_(const std::shared_ptr& inst, const : instance(std::move(inst)) , transcript(transcript) , commitment_key(instance->proving_key->commitment_key) -{ - instance->initialize_prover_polynomials(); -} + , oink_prover(inst, commitment_key, transcript, "") +{} /** * Create UltraProver_ from a circuit. @@ -31,130 +30,8 @@ UltraProver_::UltraProver_(Builder& circuit) : instance(std::make_shared(circuit)) , transcript(std::make_shared()) , commitment_key(instance->proving_key->commitment_key) -{ - instance->initialize_prover_polynomials(); -} - -/** - * @brief Add circuit size, public input size, and public inputs to transcript - * - */ -template void UltraProver_::execute_preamble_round() -{ - auto proving_key = instance->proving_key; - const auto circuit_size = static_cast(proving_key->circuit_size); - const auto num_public_inputs = static_cast(proving_key->num_public_inputs); - - transcript->send_to_verifier("circuit_size", circuit_size); - transcript->send_to_verifier("public_input_size", num_public_inputs); - transcript->send_to_verifier("pub_inputs_offset", static_cast(proving_key->pub_inputs_offset)); - - for (size_t i = 0; i < proving_key->num_public_inputs; ++i) { - auto public_input_i = proving_key->public_inputs[i]; - transcript->send_to_verifier("public_input_" + std::to_string(i), public_input_i); - } -} - -/** - * @brief Commit to the wire polynomials (part of the witness), with the exception of the fourth wire, which is - * only commited to after adding memory records. In the Goblin Flavor, we also commit to the ECC OP wires and the - * DataBus columns. - */ -template void UltraProver_::execute_wire_commitments_round() -{ - auto& witness_commitments = instance->witness_commitments; - auto& proving_key = instance->proving_key; - - // Commit to the first three wire polynomials - // We only commit to the fourth wire polynomial after adding memory recordss - witness_commitments.w_l = commitment_key->commit(proving_key->w_l); - witness_commitments.w_r = commitment_key->commit(proving_key->w_r); - witness_commitments.w_o = commitment_key->commit(proving_key->w_o); - - auto wire_comms = witness_commitments.get_wires(); - auto labels = commitment_labels.get_wires(); - for (size_t idx = 0; idx < 3; ++idx) { - transcript->send_to_verifier(labels[idx], wire_comms[idx]); - } - - if constexpr (IsGoblinFlavor) { - // Commit to Goblin ECC op wires - witness_commitments.ecc_op_wire_1 = commitment_key->commit(proving_key->ecc_op_wire_1); - witness_commitments.ecc_op_wire_2 = commitment_key->commit(proving_key->ecc_op_wire_2); - witness_commitments.ecc_op_wire_3 = commitment_key->commit(proving_key->ecc_op_wire_3); - witness_commitments.ecc_op_wire_4 = commitment_key->commit(proving_key->ecc_op_wire_4); - - auto op_wire_comms = instance->witness_commitments.get_ecc_op_wires(); - auto labels = commitment_labels.get_ecc_op_wires(); - for (size_t idx = 0; idx < Flavor::NUM_WIRES; ++idx) { - transcript->send_to_verifier(labels[idx], op_wire_comms[idx]); - } - - // Commit to DataBus columns - witness_commitments.calldata = commitment_key->commit(proving_key->calldata); - witness_commitments.calldata_read_counts = commitment_key->commit(proving_key->calldata_read_counts); - transcript->send_to_verifier(commitment_labels.calldata, instance->witness_commitments.calldata); - transcript->send_to_verifier(commitment_labels.calldata_read_counts, - instance->witness_commitments.calldata_read_counts); - } -} - -/** - * @brief Compute sorted witness-table accumulator and commit to the resulting polynomials. - * - */ -template void UltraProver_::execute_sorted_list_accumulator_round() -{ - FF eta = transcript->template get_challenge("eta"); - - instance->compute_sorted_accumulator_polynomials(eta); - - auto& witness_commitments = instance->witness_commitments; - // Commit to the sorted witness-table accumulator and the finalized (i.e. with memory records) fourth wire - // polynomial - witness_commitments.sorted_accum = commitment_key->commit(instance->prover_polynomials.sorted_accum); - witness_commitments.w_4 = commitment_key->commit(instance->prover_polynomials.w_4); - - transcript->send_to_verifier(commitment_labels.sorted_accum, instance->witness_commitments.sorted_accum); - transcript->send_to_verifier(commitment_labels.w_4, instance->witness_commitments.w_4); -} - -/** - * @brief Compute log derivative inverse polynomial and its commitment, if required - * - */ -template void UltraProver_::execute_log_derivative_inverse_round() -{ - auto& proving_key = instance->proving_key; - - // Compute and store challenges beta and gamma - auto [beta, gamma] = transcript->template get_challenges("beta", "gamma"); - relation_parameters.beta = beta; - relation_parameters.gamma = gamma; - - if constexpr (IsGoblinFlavor) { - instance->compute_logderivative_inverse(beta, gamma); - instance->witness_commitments.lookup_inverses = commitment_key->commit(proving_key->lookup_inverses); - transcript->send_to_verifier(commitment_labels.lookup_inverses, instance->witness_commitments.lookup_inverses); - } -} - -/** - * @brief Compute permutation and lookup grand product polynomials and their commitments - * - */ -template void UltraProver_::execute_grand_product_computation_round() -{ - auto& proving_key = instance->proving_key; - - instance->compute_grand_product_polynomials(relation_parameters.beta, relation_parameters.gamma); - - auto& witness_commitments = instance->witness_commitments; - witness_commitments.z_perm = commitment_key->commit(proving_key->z_perm); - witness_commitments.z_lookup = commitment_key->commit(proving_key->z_lookup); - transcript->send_to_verifier(commitment_labels.z_perm, instance->witness_commitments.z_perm); - transcript->send_to_verifier(commitment_labels.z_lookup, instance->witness_commitments.z_lookup); -} + , oink_prover(instance, commitment_key, transcript, "") +{} /** * @brief Run Sumcheck resulting in u = (u_1,...,u_d) challenges and all evaluations at u being calculated. @@ -203,19 +80,19 @@ template HonkProof& UltraProver_::export_proof() template HonkProof& UltraProver_::construct_proof() { // Add circuit size public input size and public inputs to transcript-> - execute_preamble_round(); + oink_prover.execute_preamble_round(); // Compute first three wire commitments - execute_wire_commitments_round(); + oink_prover.execute_wire_commitments_round(); // Compute sorted list accumulator and commitment - execute_sorted_list_accumulator_round(); + oink_prover.execute_sorted_list_accumulator_round(); // Fiat-Shamir: beta & gamma - execute_log_derivative_inverse_round(); + oink_prover.execute_log_derivative_inverse_round(); // Compute grand product(s) and commitments. - execute_grand_product_computation_round(); + oink_prover.execute_grand_product_computation_round(); // Fiat-Shamir: alpha // Run sumcheck subprotocol. diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.hpp index dd822986f11..46aa631f6cb 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.hpp @@ -7,6 +7,7 @@ #include "barretenberg/sumcheck/instance/prover_instance.hpp" #include "barretenberg/sumcheck/sumcheck_output.hpp" #include "barretenberg/transcript/transcript.hpp" +#include "barretenberg/ultra_honk/oink_prover.hpp" namespace bb { @@ -25,6 +26,21 @@ template class UltraProver_ { using Instance = ProverInstance; using Transcript = typename Flavor::Transcript; using RelationSeparator = typename Flavor::RelationSeparator; + using ZeroMorph = ZeroMorphProver_; + + std::shared_ptr instance; + + std::shared_ptr transcript; + + bb::RelationParameters relation_parameters; + + Polynomial quotient_W; + + SumcheckOutput sumcheck_output; + + std::shared_ptr commitment_key; + + OinkProver oink_prover; explicit UltraProver_(const std::shared_ptr&, const std::shared_ptr& transcript = std::make_shared()); @@ -42,22 +58,6 @@ template class UltraProver_ { HonkProof& export_proof(); HonkProof& construct_proof(); - std::shared_ptr instance; - - std::shared_ptr transcript; - - bb::RelationParameters relation_parameters; - - CommitmentLabels commitment_labels; - - Polynomial quotient_W; - - SumcheckOutput sumcheck_output; - - std::shared_ptr commitment_key; - - using ZeroMorph = ZeroMorphProver_; - private: HonkProof proof; };