From f2b1d2be38e2280d3456e3126f54cb99b1761f0f Mon Sep 17 00:00:00 2001 From: maramihali Date: Tue, 26 Sep 2023 15:46:29 +0000 Subject: [PATCH 01/13] wip --- .../src/barretenberg/honk/flavor/ultra.hpp | 5 +- .../honk/instance/prover_instance.hpp | 6 +- .../honk/proof_system/protogalaxy_prover.hpp | 32 ++++- .../barretenberg/honk/sumcheck/sumcheck.hpp | 3 +- .../honk/sumcheck/sumcheck_round.hpp | 109 +----------------- .../cpp/src/barretenberg/polynomials/pow.hpp | 1 + .../proof_system/flavor/flavor.hpp | 2 - 7 files changed, 43 insertions(+), 115 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/flavor/ultra.hpp b/barretenberg/cpp/src/barretenberg/honk/flavor/ultra.hpp index 2e1ca263dfe..a5fadf236d3 100644 --- a/barretenberg/cpp/src/barretenberg/honk/flavor/ultra.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/flavor/ultra.hpp @@ -301,7 +301,7 @@ class Ultra { barretenberg::Univariate>; /** - * @brief A container for the polynomials evaluations produced during sumcheck, which are purported to be the + * @brief A container for the polynomials evaluations produced during sumcheck, which are claimed to be the * evaluations of polynomials committed in earlier rounds. */ class ClaimedEvaluations : public AllEntities { @@ -393,7 +393,8 @@ class Ultra { class FoldingParameters { public: - FF gate_separation_challenge; + // we need this because the nice relation between deltas does not apply to beta as well + std::vector gate_separation_challenges; FF target_sum; }; }; diff --git a/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.hpp b/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.hpp index 042566a3358..6b9a1d6c938 100644 --- a/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.hpp @@ -29,8 +29,6 @@ template class ProverInstance_ { using Polynomial = typename Flavor::Polynomial; public: - // offset due to placing zero wires at the start of execution trace - std::shared_ptr proving_key; std::shared_ptr verification_key; std::shared_ptr commitment_key; @@ -40,9 +38,13 @@ template class ProverInstance_ { // The number of public inputs has to be the same for all instances because they are // folded element by element. std::vector public_inputs; + // offset due to placing zero wires at the start of execution trace + // this value is only set for Instances constructed from circuits, this concept doesn't exist for accumulated + // instances size_t pub_inputs_offset = 0; proof_system::RelationParameters relation_parameters; std::vector recursive_proof_public_input_indices; + // only set for the accumulated instances FoldingParameters folding_params; ProverInstance_(Circuit& circuit) diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp index 3874e77d7bd..9866bf463f2 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp @@ -9,11 +9,11 @@ namespace proof_system::honk { template class ProtoGalaxyProver_ { public: using Flavor = typename ProverInstances::Flavor; + using Instance = typename ProverInstances::Instance; using FF = typename Flavor::FF; using ProverPolynomials = typename Flavor::ProverPolynomials; ProverInstances instances; - ProverTranscript transcript; ProtoGalaxyProver_(ProverInstances insts) @@ -22,6 +22,36 @@ template class ProtoGalaxyProver_ { void prepare_for_folding(); + std::vector compute_round_challenge_pows(size_t instance_size, FF round_challenge) + { + std::vector pows(instance_size); + pows[0] = round_challenge; + for (size_t i = 1; i < instance_size; i++) { + pows[i] = pows[i - 1].sqr(); + } + return pows; + } + + // degree of G can be found at compile time but that is not the case for degree of F + // need a function that returns me all the f_i(prover polynomials of inst i) + // I guess in perturbator we just take stuff from the first instance which would make the most sense + // and then \vec{beta} is part of instance? + // retur + std::vector compute_perturbator([[maybe_unused]] std::vector round_challenge_pows) + { + auto accumulator = instances[0]; + // all the prover polynomials should have the same length + auto instance_size = accumulator.prover_polynomials[0].size(); + auto log_instance_size = static_cast(numeric::get_msb(instance_size)); + std::vector perturbator_univariate(log_instance_size); + for (size_t idx = 0; idx < instance_size; idx++) { + + // AccumulatorAndViews because all relations are extended to the highest degree but there's no need for + // it(?) + // f_i(w) cant be only one value, it's actually a vector ??? + } + }; + ProverFoldingResult fold_instances(); }; diff --git a/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck.hpp b/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck.hpp index 48f2283700e..1b9585c77ea 100644 --- a/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck.hpp @@ -149,6 +149,7 @@ template class SumcheckProver { template class SumcheckVerifier { public: + using Utils = barretenberg::RelationUtils; using FF = typename Flavor::FF; using ClaimedEvaluations = typename Flavor::ClaimedEvaluations; @@ -209,7 +210,7 @@ template class SumcheckVerifier { ClaimedEvaluations purported_evaluations = transcript.template receive_from_prover>("Sumcheck:evaluations"); - FF full_honk_relation_purported_value = round.compute_full_honk_relation_purported_value( + FF full_honk_relation_purported_value = Utils::compute_full_honk_relation_purported_value( purported_evaluations._data, relation_parameters, pow_univariate, alpha); bool checked = false; diff --git a/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.hpp b/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.hpp index 353433c756f..2a81ca009c8 100644 --- a/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.hpp @@ -6,6 +6,7 @@ #include "barretenberg/polynomials/pow.hpp" #include "barretenberg/proof_system/flavor/flavor.hpp" #include "barretenberg/proof_system/relations/relation_parameters.hpp" +#include "barretenberg/proof_system/relations/utils.hpp" namespace proof_system::honk::sumcheck { @@ -366,7 +367,7 @@ template class SumcheckProverRound { }; template class SumcheckVerifierRound { - + using Utils = barretenberg::RelationUtils; using Relations = typename Flavor::Relations; using RelationEvaluations = typename Flavor::RelationValues; @@ -376,7 +377,6 @@ template class SumcheckVerifierRound { bool round_failed = false; - Relations relations; static constexpr size_t NUM_RELATIONS = Flavor::NUM_RELATIONS; static constexpr size_t MAX_RANDOM_RELATION_LENGTH = Flavor::MAX_RANDOM_RELATION_LENGTH; @@ -387,33 +387,6 @@ template class SumcheckVerifierRound { // Verifier constructor explicit SumcheckVerifierRound() { zero_elements(relation_evaluations); }; - /** - * @brief Calculate the contribution of each relation to the expected value of the full Honk relation. - * - * @details For each relation, use the purported values (supplied by the prover) of the multivariates to calculate - * a contribution to the purported value of the full Honk relation. These are stored in `evaluations`. Adding these - * together, with appropriate scaling factors, produces the expected value of the full Honk relation. This value is - * checked against the final value of the target total sum, defined as sigma_d. - */ - FF compute_full_honk_relation_purported_value(ClaimedEvaluations purported_evaluations, - const proof_system::RelationParameters& relation_parameters, - const barretenberg::PowUnivariate& pow_univariate, - const FF alpha) - { - accumulate_relation_evaluations<>( - purported_evaluations, relation_parameters, pow_univariate.partial_evaluation_constant); - - auto running_challenge = FF(1); - auto output = FF(0); - scale_and_batch_elements(relation_evaluations, alpha, running_challenge, output); - return output; - } - - /** - * @brief check if S^{l}(0) + S^{l}(1) = S^{l-1}(u_{l-1}) = sigma_{l} (or 0 if l=0) - * - * @param univariate T^{l}(X), the round univariate that is equal to S^{l}(X)/( (1−X) + X⋅ζ^{ 2^l } ) - */ bool check_sum(barretenberg::Univariate& univariate) { // S^{l}(0) = ( (1−0) + 0⋅ζ^{ 2^l } ) ⋅ T^{l}(0) = T^{l}(0) @@ -453,83 +426,5 @@ template class SumcheckVerifierRound { return target_total_sum; } - - private: - // TODO(#224)(Cody): make uniform with accumulate_relation_univariates - /** - * @brief Calculate the contribution of each relation to the expected value of the full Honk relation. - * - * @details For each relation, use the purported values (supplied by the prover) of the multivariates to calculate - * a contribution to the purported value of the full Honk relation. These are stored in `evaluations`. Adding these - * together, with appropriate scaling factors, produces the expected value of the full Honk relation. This value is - * checked against the final value of the target total sum (called sigma_0 in the thesis). - */ - template - // TODO(#224)(Cody): Input should be an array? - void accumulate_relation_evaluations(ClaimedEvaluations purported_evaluations, - const proof_system::RelationParameters& relation_parameters, - const FF& partial_evaluation_constant) - { - std::get(relations).add_full_relation_value_contribution( - std::get(relation_evaluations), - purported_evaluations, - relation_parameters, - partial_evaluation_constant); - - // Repeat for the next relation. - if constexpr (relation_idx + 1 < NUM_RELATIONS) { - accumulate_relation_evaluations( - purported_evaluations, relation_parameters, partial_evaluation_constant); - } - } - - public: - /** - * Utility methods for tuple of arrays - */ - - /** - * @brief Set each element in a tuple of arrays to zero. - * @details FF's default constructor may not initialize to zero (e.g., barretenberg::fr), hence we can't rely on - * aggregate initialization of the evaluations array. - */ - template static void zero_elements(auto& tuple) - { - auto set_to_zero = [](auto& element) { std::fill(element.begin(), element.end(), FF(0)); }; - apply_to_tuple_of_arrays(set_to_zero, tuple); - }; - - /** - * @brief Scale elements by consecutive powers of the challenge then sum - * @param result Batched result - */ - static void scale_and_batch_elements(auto& tuple, const FF& challenge, FF current_scalar, FF& result) - { - auto scale_by_challenge_and_accumulate = [&](auto& element) { - for (auto& entry : element) { - result += entry * current_scalar; - current_scalar *= challenge; - } - }; - apply_to_tuple_of_arrays(scale_by_challenge_and_accumulate, tuple); - } - - /** - * @brief General purpose method for applying a tuple of arrays (of FFs) - * - * @tparam Operation Any operation valid on elements of the inner arrays (FFs) - * @param tuple Tuple of arrays (of FFs) - */ - template - static void apply_to_tuple_of_arrays(Operation&& operation, std::tuple& tuple) - { - auto& element = std::get(tuple); - - std::invoke(std::forward(operation), element); - - if constexpr (idx + 1 < sizeof...(Ts)) { - apply_to_tuple_of_arrays(operation, tuple); - } - } }; } // namespace proof_system::honk::sumcheck diff --git a/barretenberg/cpp/src/barretenberg/polynomials/pow.hpp b/barretenberg/cpp/src/barretenberg/polynomials/pow.hpp index 9039266cac0..77a0a53030f 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/pow.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/pow.hpp @@ -90,6 +90,7 @@ namespace barretenberg { * = pow(u_{0}, ..., u_{d-1}) // Full evaluation of pow * - σ_{ d } =?= c_{d}⋅P(u_{0}, ..., u_{d-1}) // Compare against real evaluation of P'(u) */ +// this can be used to compute deltas for each round as it is template struct PowUnivariate { // ζ_{l}, initialized as ζ_{0} = ζ // At round l, equals ζ^{ 2^l } diff --git a/barretenberg/cpp/src/barretenberg/proof_system/flavor/flavor.hpp b/barretenberg/cpp/src/barretenberg/proof_system/flavor/flavor.hpp index 093f5ab8123..d981da35ca8 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/flavor/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/flavor/flavor.hpp @@ -252,8 +252,6 @@ template static constexpr auto // Forward declare honk flavors namespace proof_system::honk::flavor { -class Standard; -class StandardGrumpkin; class Ultra; class UltraGrumpkin; class ECCVM; From 26ddcb8fcad77dea2143c604cb41933a2fd72dad Mon Sep 17 00:00:00 2001 From: maramihali Date: Fri, 29 Sep 2023 11:57:15 +0000 Subject: [PATCH 02/13] more wip --- .../relations_bench/relations.bench.cpp | 2 +- .../src/barretenberg/honk/flavor/ecc_vm.hpp | 12 ++- .../barretenberg/honk/flavor/flavor.test.cpp | 2 +- .../barretenberg/honk/flavor/goblin_ultra.hpp | 12 ++- .../honk/flavor/goblin_ultra_recursive.hpp | 12 ++- .../src/barretenberg/honk/flavor/ultra.hpp | 13 ++- .../honk/flavor/ultra_grumpkin.hpp | 12 ++- .../honk/flavor/ultra_recursive.hpp | 12 ++- .../proof_system/grand_product_library.hpp | 2 +- .../honk/proof_system/permutation_library.hpp | 2 +- .../honk/proof_system/protogalaxy_prover.cpp | 6 ++ .../honk/proof_system/protogalaxy_prover.hpp | 79 ++++++++++++--- .../sumcheck/relation_correctness.test.cpp | 2 +- .../sumcheck/relation_definitions_fwd.hpp | 2 +- .../barretenberg/honk/sumcheck/sumcheck.hpp | 6 +- .../honk/sumcheck/sumcheck_output.hpp | 2 +- .../honk/sumcheck/sumcheck_round.hpp | 32 +++++- .../honk/sumcheck/sumcheck_round.test.cpp | 5 +- .../ecc_vm/ecc_transcript_relation.hpp | 4 +- .../proof_system/relations/relation_types.hpp | 8 +- .../proof_system/relations/utils.hpp | 97 +++++++++++++++++++ 21 files changed, 267 insertions(+), 57 deletions(-) create mode 100644 barretenberg/cpp/src/barretenberg/proof_system/relations/utils.hpp diff --git a/barretenberg/cpp/src/barretenberg/benchmark/relations_bench/relations.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/relations_bench/relations.bench.cpp index df0be6fe25a..d2f9d611040 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/relations_bench/relations.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/relations_bench/relations.bench.cpp @@ -30,7 +30,7 @@ template void execute_relation(::benchmark: .public_input_delta = public_input_delta, }; - using ClaimedEvaluations = typename Flavor::ClaimedEvaluations; + using ClaimedEvaluations = typename Flavor::ProverPolynomialsEvaluations; using RelationValues = typename Relation::RelationValues; // Extract an array containing all the polynomial evaluations at a given row i diff --git a/barretenberg/cpp/src/barretenberg/honk/flavor/ecc_vm.hpp b/barretenberg/cpp/src/barretenberg/honk/flavor/ecc_vm.hpp index 7cceb23abba..a73c9d429a2 100644 --- a/barretenberg/cpp/src/barretenberg/honk/flavor/ecc_vm.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/flavor/ecc_vm.hpp @@ -693,14 +693,18 @@ template class ECCVMBa barretenberg::Univariate>; /** - * @brief A container for the polynomials evaluations produced during sumcheck, which are purported to be the - * evaluations of polynomials committed in earlier rounds. + * @brief A container storing evaluations of all prover polynomials at one point. + * In sumcheck, this data structure represents the evaluations produced during sumcheck, which are claimed to be the + * evaluations of prover polynomials commited in earilier rounds + * In protogalaxy, it's used to store the evaluations for each point on the boolean hypercurbe, so one + * ProverPolynomailsEvaluation object represents evaluations of one row in the execution trace. + * */ - class ClaimedEvaluations : public AllEntities { + class ProverPolynomialsEvaluations : public AllEntities { public: using Base = AllEntities; using Base::Base; - ClaimedEvaluations(std::array _data_in) { this->_data = _data_in; } + ProverPolynomialsEvaluations(std::array _data_in) { this->_data = _data_in; } }; /** diff --git a/barretenberg/cpp/src/barretenberg/honk/flavor/flavor.test.cpp b/barretenberg/cpp/src/barretenberg/honk/flavor/flavor.test.cpp index 01508f4fb70..d574dd9563b 100644 --- a/barretenberg/cpp/src/barretenberg/honk/flavor/flavor.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/flavor/flavor.test.cpp @@ -34,7 +34,7 @@ TEST(Flavor, Getters) Flavor::VerificationKey verification_key; Flavor::ProverPolynomials prover_polynomials; Flavor::ExtendedEdges edges; - Flavor::ClaimedEvaluations evals; + Flavor::ProverPolynomialsEvaluations evals; Flavor::CommitmentLabels commitment_labels; // Globals are also available through STL container sizes diff --git a/barretenberg/cpp/src/barretenberg/honk/flavor/goblin_ultra.hpp b/barretenberg/cpp/src/barretenberg/honk/flavor/goblin_ultra.hpp index 006bba75d6e..54e7a9f9198 100644 --- a/barretenberg/cpp/src/barretenberg/honk/flavor/goblin_ultra.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/flavor/goblin_ultra.hpp @@ -334,14 +334,18 @@ class GoblinUltra { barretenberg::Univariate>; /** - * @brief A container for the polynomials evaluations produced during sumcheck, which are purported to be the - * evaluations of polynomials committed in earlier rounds. + * @brief A container storing evaluations of all prover polynomials at one point. + * In sumcheck, this data structure represents the evaluations produced during sumcheck, which are claimed to be the + * evaluations of prover polynomials commited in earilier rounds + * In protogalaxy, it's used to store the evaluations for each point on the boolean hypercurbe, so one + * ProverPolynomailsEvaluation object represents evaluations of one row in the execution trace. + * */ - class ClaimedEvaluations : public AllEntities { + class ProverPolynomialsEvaluations : public AllEntities { public: using Base = AllEntities; using Base::Base; - ClaimedEvaluations(std::array _data_in) { this->_data = _data_in; } + ProverPolynomialsEvaluations(std::array _data_in) { this->_data = _data_in; } }; /** diff --git a/barretenberg/cpp/src/barretenberg/honk/flavor/goblin_ultra_recursive.hpp b/barretenberg/cpp/src/barretenberg/honk/flavor/goblin_ultra_recursive.hpp index 12f96ff105c..a657f08e021 100644 --- a/barretenberg/cpp/src/barretenberg/honk/flavor/goblin_ultra_recursive.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/flavor/goblin_ultra_recursive.hpp @@ -343,14 +343,18 @@ template class GoblinUltraRecursive_ { }; /** - * @brief A container for the polynomials evaluations produced during sumcheck, which are purported to be the - * evaluations of polynomials committed in earlier rounds. + * @brief A container storing evaluations of all prover polynomials at one point. + * In sumcheck, this data structure represents the evaluations produced during sumcheck, which are claimed to be the + * evaluations of prover polynomials commited in earilier rounds + * In protogalaxy, it's used to store the evaluations for each point on the boolean hypercurbe, so one + * ProverPolynomailsEvaluation object represents evaluations of one row in the execution trace. + * */ - class ClaimedEvaluations : public AllEntities { + class ProverPolynomialsEvaluations : public AllEntities { public: using Base = AllEntities; using Base::Base; - ClaimedEvaluations(std::array _data_in) { this->_data = _data_in; } + ProverPolynomialsEvaluations(std::array _data_in) { this->_data = _data_in; } }; /** diff --git a/barretenberg/cpp/src/barretenberg/honk/flavor/ultra.hpp b/barretenberg/cpp/src/barretenberg/honk/flavor/ultra.hpp index a5fadf236d3..4ff13851d40 100644 --- a/barretenberg/cpp/src/barretenberg/honk/flavor/ultra.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/flavor/ultra.hpp @@ -301,14 +301,18 @@ class Ultra { barretenberg::Univariate>; /** - * @brief A container for the polynomials evaluations produced during sumcheck, which are claimed to be the - * evaluations of polynomials committed in earlier rounds. + * @brief A container storing evaluations of all prover polynomials at one point. + * In sumcheck, this data structure represents the evaluations produced during sumcheck, which are claimed to be the + * evaluations of prover polynomials commited in earilier rounds + * In protogalaxy, it's used to store the evaluations for each point on the boolean hypercurbe, so one + * ProverPolynomailsEvaluation object represents evaluations of one row in the execution trace. + * */ - class ClaimedEvaluations : public AllEntities { + class ProverPolynomialsEvaluations : public AllEntities { public: using Base = AllEntities; using Base::Base; - ClaimedEvaluations(std::array _data_in) { this->_data = _data_in; } + ProverPolynomialsEvaluations(std::array _data_in) { this->_data = _data_in; } }; /** @@ -394,6 +398,7 @@ class Ultra { class FoldingParameters { public: // we need this because the nice relation between deltas does not apply to beta as well + // these are the betas std::vector gate_separation_challenges; FF target_sum; }; diff --git a/barretenberg/cpp/src/barretenberg/honk/flavor/ultra_grumpkin.hpp b/barretenberg/cpp/src/barretenberg/honk/flavor/ultra_grumpkin.hpp index 979aaceed7b..7b58cec2362 100644 --- a/barretenberg/cpp/src/barretenberg/honk/flavor/ultra_grumpkin.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/flavor/ultra_grumpkin.hpp @@ -308,14 +308,18 @@ class UltraGrumpkin { barretenberg::Univariate>; /** - * @brief A container for the polynomials evaluations produced during sumcheck, which are purported to be the - * evaluations of polynomials committed in earlier rounds. + * @brief A container storing evaluations of all prover polynomials at one point. + * In sumcheck, this data structure represents the evaluations produced during sumcheck, which are claimed to be the + * evaluations of prover polynomials commited in earilier rounds + * In protogalaxy, it's used to store the evaluations for each point on the boolean hypercurbe, so one + * ProverPolynomailsEvaluation object represents evaluations of one row in the execution trace. + * */ - class ClaimedEvaluations : public AllEntities { + class ProverPolynomialsEvaluations : public AllEntities { public: using Base = AllEntities; using Base::Base; - ClaimedEvaluations(std::array _data_in) { this->_data = _data_in; } + ProverPolynomialsEvaluations(std::array _data_in) { this->_data = _data_in; } }; /** diff --git a/barretenberg/cpp/src/barretenberg/honk/flavor/ultra_recursive.hpp b/barretenberg/cpp/src/barretenberg/honk/flavor/ultra_recursive.hpp index 5168265cc08..63479fa0635 100644 --- a/barretenberg/cpp/src/barretenberg/honk/flavor/ultra_recursive.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/flavor/ultra_recursive.hpp @@ -308,14 +308,18 @@ template class UltraRecursive_ { }; /** - * @brief A container for the polynomials evaluations produced during sumcheck, which are purported to be the - * evaluations of polynomials committed in earlier rounds. + * @brief A container storing evaluations of all prover polynomials at one point. + * In sumcheck, this data structure represents the evaluations produced during sumcheck, which are claimed to be the + * evaluations of prover polynomials commited in earilier rounds + * In protogalaxy, it's used to store the evaluations for each point on the boolean hypercurbe, so one + * ProverPolynomailsEvaluation object represents evaluations of one row in the execution trace. + * */ - class ClaimedEvaluations : public AllEntities { + class ProverPolynomialsEvaluations : public AllEntities { public: using Base = AllEntities; using Base::Base; - ClaimedEvaluations(std::array _data_in) { this->_data = _data_in; } + ProverPolynomialsEvaluations(std::array _data_in) { this->_data = _data_in; } }; /** diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/grand_product_library.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/grand_product_library.hpp index acb530965c6..cd15a36c1f4 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/grand_product_library.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/grand_product_library.hpp @@ -68,7 +68,7 @@ void compute_grand_product(const size_t circuit_size, const size_t end = (thread_idx + 1) * block_size; for (size_t i = start; i < end; ++i) { - typename Flavor::ClaimedEvaluations evaluations; + typename Flavor::ProverPolynomialsEvaluations evaluations; for (size_t k = 0; k < Flavor::NUM_ALL_ENTITIES; ++k) { evaluations[k] = full_polynomials[k].size() > i ? full_polynomials[k][i] : 0; } diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/permutation_library.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/permutation_library.hpp index f2a46e2c1dc..91c72d224b5 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/permutation_library.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/permutation_library.hpp @@ -69,7 +69,7 @@ void compute_permutation_grand_product(const size_t circuit_size, const size_t end = (thread_idx + 1) * block_size; for (size_t i = start; i < end; ++i) { - typename Flavor::ClaimedEvaluations evaluations; + typename Flavor::ProverPolynomialsEvaluations evaluations; for (size_t k = 0; k < Flavor::NUM_ALL_ENTITIES; ++k) { evaluations[k] = full_polynomials[k].size() > i ? full_polynomials[k][i] : 0; } diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp index 0fb90be5d06..fd7b0f391ac 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp @@ -42,6 +42,12 @@ template ProverFoldingResult ProtoGalaxyProver_::fold_instances() { prepare_for_folding(); + auto [alpha, delta] = transcript.get_challenges("alpha", "delta"); + auto accumulator = get_accumulator(); + auto instance_size = accumulator.prover_polynomials[0].size(); + auto log_instance_size = static_cast(numeric::get_msb(instance_size)); + auto deltas = compute_round_challenge_pows(log_instance_size, delta); + auto perturbator_evaluations = compute_perturbator(accumulator, deltas, alpha); ProverFoldingResult res; res.folding_data = transcript.proof_data; return res; diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp index 9866bf463f2..93ce056aa13 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp @@ -5,11 +5,15 @@ #include "barretenberg/honk/instance/instances.hpp" #include "barretenberg/honk/proof_system/folding_result.hpp" #include "barretenberg/proof_system/flavor/flavor.hpp" +#include "barretenberg/proof_system/relations/utils.hpp" namespace proof_system::honk { template class ProtoGalaxyProver_ { public: using Flavor = typename ProverInstances::Flavor; using Instance = typename ProverInstances::Instance; + using Utils = barretenberg::RelationUtils; + using RowEvaluations = typename Flavor::ProverPolynomialsEvaluations; + using RelationEvaluations = typename Flavor::RelationValues; using FF = typename Flavor::FF; using ProverPolynomials = typename Flavor::ProverPolynomials; @@ -22,34 +26,83 @@ template class ProtoGalaxyProver_ { void prepare_for_folding(); - std::vector compute_round_challenge_pows(size_t instance_size, FF round_challenge) + // compute the deltas in the paper + std::vector compute_round_challenge_pows(size_t size, FF round_challenge) { - std::vector pows(instance_size); + std::vector pows(size); pows[0] = round_challenge; - for (size_t i = 1; i < instance_size; i++) { + for (size_t i = 1; i < size; i++) { pows[i] = pows[i - 1].sqr(); } return pows; } - // degree of G can be found at compile time but that is not the case for degree of F - // need a function that returns me all the f_i(prover polynomials of inst i) - // I guess in perturbator we just take stuff from the first instance which would make the most sense - // and then \vec{beta} is part of instance? - // retur - std::vector compute_perturbator([[maybe_unused]] std::vector round_challenge_pows) + RowEvaluations get_row(Instance accumulator, size_t row) + { + RowEvaluations row_evals; + size_t idx = 0; + for (auto& poly : accumulator.prover_polynomials) { + row_evals[idx] = poly[row]; + idx++; + } + return row_evals; + } + + Instance get_accumulator() { return instances[0]; } + + // the pow in sumcheck will be replaced with the pow in protogalaxy!!!!!!!! + // here we don't have the pow polynomial extra parameter because the gate separation challenge is a polynomial for + // perturbator and it's going to be added later + FF compute_full_honk_relation_row_value(RowEvaluations row_evaluations, + FF alpha, + const proof_system::RelationParameters& relation_parameters) + { + RelationEvaluations relation_evaluations; + Utils::zero_elements(relation_evaluations); + + // TODO: we add the gate separation challenge as a univariate later + // We will have to change the power polynomial in sumcheck to respect the structure of PG rather than what we + // currently have + Utils::template accumulate_relation_evaluations<>( + row_evaluations, relation_evaluations, relation_parameters, FF(1)); + + // Not sure what this running challenge is we have to investigate + auto running_challenge = FF(1); + auto output = FF(0); + Utils::scale_and_batch_elements(relation_evaluations, alpha, running_challenge, output); + return output; + } + + // We return the evaluate of perturbator at 0,..,log(n) where n is the circuit size + std::vector compute_perturbator(Instance accumulator, std::vector deltas, FF alpha) { - auto accumulator = instances[0]; // all the prover polynomials should have the same length auto instance_size = accumulator.prover_polynomials[0].size(); auto log_instance_size = static_cast(numeric::get_msb(instance_size)); std::vector perturbator_univariate(log_instance_size); + std::vector full_honk_evaluations(instance_size); for (size_t idx = 0; idx < instance_size; idx++) { - // AccumulatorAndViews because all relations are extended to the highest degree but there's no need for - // it(?) - // f_i(w) cant be only one value, it's actually a vector ??? + auto row_evaluations = get_row(accumulator, idx); + auto full_honk_at_row = + compute_full_honk_relation_row_value(row_evaluations, alpha, accumulator.relation_parameters); + // this is f_i(w) where idx=i + full_honk_evaluations[idx] = full_honk_at_row; + } + + auto betas = accumulator.folding_params.gate_separation_challenges; + + // note: the tree technique can probably/maybe be done with apply tuples sth but + + auto point = FF(1); + std::vector labels(log_instance_size); + for (size_t idx = 0; idx < log_instance_size; idx++) { + labels[idx] = betas[idx] + point * deltas[idx]; + } + auto eval_at_point = FF(0); + for (size_t idx = 0; idx < instance_size; idx++) { } + return perturbator_univariate; }; ProverFoldingResult fold_instances(); diff --git a/barretenberg/cpp/src/barretenberg/honk/sumcheck/relation_correctness.test.cpp b/barretenberg/cpp/src/barretenberg/honk/sumcheck/relation_correctness.test.cpp index d73918737cc..8e713ac7dfe 100644 --- a/barretenberg/cpp/src/barretenberg/honk/sumcheck/relation_correctness.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/sumcheck/relation_correctness.test.cpp @@ -31,7 +31,7 @@ void ensure_non_zero(auto& polynomial) */ template void check_relation(auto relation, auto circuit_size, auto polynomials, auto params) { - using ClaimedEvaluations = typename Flavor::ClaimedEvaluations; + using ClaimedEvaluations = typename Flavor::ProverPolynomialsEvaluations; for (size_t i = 0; i < circuit_size; i++) { // Extract an array containing all the polynomial evaluations at a given row i diff --git a/barretenberg/cpp/src/barretenberg/honk/sumcheck/relation_definitions_fwd.hpp b/barretenberg/cpp/src/barretenberg/honk/sumcheck/relation_definitions_fwd.hpp index f6ced1d7aa5..73fa459a4fa 100644 --- a/barretenberg/cpp/src/barretenberg/honk/sumcheck/relation_definitions_fwd.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/sumcheck/relation_definitions_fwd.hpp @@ -3,7 +3,7 @@ #include "barretenberg/proof_system/relations/relation_types.hpp" #define ExtendedEdge(Flavor) Flavor::ExtendedEdges -#define EvaluationEdge(Flavor) Flavor::ClaimedEvaluations +#define EvaluationEdge(Flavor) Flavor::ProverPolynomialsEvaluations #define EntityEdge(Flavor) Flavor::AllEntities #define ADD_EDGE_CONTRIBUTION(...) _ADD_EDGE_CONTRIBUTION(__VA_ARGS__) diff --git a/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck.hpp b/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck.hpp index 1b9585c77ea..de28b079279 100644 --- a/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck.hpp @@ -15,7 +15,7 @@ template class SumcheckProver { public: using FF = typename Flavor::FF; using PartiallyEvaluatedMultivariates = typename Flavor::PartiallyEvaluatedMultivariates; - using ClaimedEvaluations = typename Flavor::ClaimedEvaluations; + using ClaimedEvaluations = typename Flavor::ProverPolynomialsEvaluations; ProverTranscript& transcript; const size_t multivariate_n; @@ -151,7 +151,7 @@ template class SumcheckVerifier { public: using Utils = barretenberg::RelationUtils; using FF = typename Flavor::FF; - using ClaimedEvaluations = typename Flavor::ClaimedEvaluations; + using ClaimedEvaluations = typename Flavor::ProverPolynomialsEvaluations; static constexpr size_t MAX_RANDOM_RELATION_LENGTH = Flavor::MAX_RANDOM_RELATION_LENGTH; static constexpr size_t NUM_POLYNOMIALS = Flavor::NUM_ALL_ENTITIES; @@ -210,7 +210,7 @@ template class SumcheckVerifier { ClaimedEvaluations purported_evaluations = transcript.template receive_from_prover>("Sumcheck:evaluations"); - FF full_honk_relation_purported_value = Utils::compute_full_honk_relation_purported_value( + FF full_honk_relation_purported_value = round.compute_full_honk_relation_purported_value( purported_evaluations._data, relation_parameters, pow_univariate, alpha); bool checked = false; diff --git a/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_output.hpp b/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_output.hpp index a274c9df3ab..38b4311a946 100644 --- a/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_output.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_output.hpp @@ -11,7 +11,7 @@ namespace proof_system::honk::sumcheck { */ template struct SumcheckOutput { using FF = typename Flavor::FF; - using ClaimedEvaluations = typename Flavor::ClaimedEvaluations; + using ClaimedEvaluations = typename Flavor::ProverPolynomialsEvaluations; // u = (u_0, ..., u_{d-1}) std::vector challenge; // Evaluations in `u` of the polynomials used in Sumcheck diff --git a/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.hpp b/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.hpp index 2a81ca009c8..8a6722777ff 100644 --- a/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.hpp @@ -373,7 +373,7 @@ template class SumcheckVerifierRound { public: using FF = typename Flavor::FF; - using ClaimedEvaluations = typename Flavor::ClaimedEvaluations; + using ClaimedEvaluations = typename Flavor::ProverPolynomialsEvaluations; bool round_failed = false; @@ -382,10 +382,11 @@ template class SumcheckVerifierRound { FF target_total_sum = 0; + Relations relations; RelationEvaluations relation_evaluations; // Verifier constructor - explicit SumcheckVerifierRound() { zero_elements(relation_evaluations); }; + explicit SumcheckVerifierRound() { Utils::zero_elements(relation_evaluations); }; bool check_sum(barretenberg::Univariate& univariate) { @@ -426,5 +427,32 @@ template class SumcheckVerifierRound { return target_total_sum; } + + /** + * @brief Calculate the contribution of each relation to the expected value of the full Honk relation. + * + * @details For each relation, use the purported values (supplied by the prover) of the multivariates to calculate + * a contribution to the purported value of the full Honk relation. These are stored in `evaluations`. Adding these + * together, with appropriate scaling factors, produces the expected value of the full Honk relation. This value is + * checked against the final value of the target total sum, defined as sigma_d. + */ + // also copy paste in PG + // so instead of having claimed evaluations of each relation in part you have the actual evaluations + // kill the pow_univariat + FF compute_full_honk_relation_purported_value(ClaimedEvaluations purported_evaluations, + const proof_system::RelationParameters& relation_parameters, + const barretenberg::PowUnivariate& pow_univariate, + const FF alpha) + { + Utils::template accumulate_relation_evaluations<>(purported_evaluations, + relation_evaluations, + relation_parameters, + pow_univariate.partial_evaluation_constant); + + auto running_challenge = FF(1); + auto output = FF(0); + Utils::scale_and_batch_elements(relation_evaluations, alpha, running_challenge, output); + return output; + } }; } // namespace proof_system::honk::sumcheck diff --git a/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.test.cpp b/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.test.cpp index a5f3e2cd57b..fd0c3fd39aa 100644 --- a/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.test.cpp @@ -75,6 +75,7 @@ TEST(SumcheckRound, TupleOfTuplesOfUnivariates) TEST(SumcheckRound, TuplesOfEvaluationArrays) { using Flavor = proof_system::honk::flavor::Ultra; + using Utils = barretenberg::RelationUtils; using FF = typename Flavor::FF; // Define two arrays of arbitrary elements @@ -88,7 +89,7 @@ TEST(SumcheckRound, TuplesOfEvaluationArrays) FF challenge = 5; FF running_challenge = 1; FF result = 0; - SumcheckVerifierRound::scale_and_batch_elements(tuple_of_arrays, challenge, running_challenge, result); + Utils::scale_and_batch_elements(tuple_of_arrays, challenge, running_challenge, result); // Repeat the batching process manually auto result_expected = @@ -98,7 +99,7 @@ TEST(SumcheckRound, TuplesOfEvaluationArrays) EXPECT_EQ(result, result_expected); // Reinitialize univariate accumulators to zero - SumcheckVerifierRound::zero_elements(tuple_of_arrays); + Utils::zero_elements(tuple_of_arrays); EXPECT_EQ(std::get<0>(tuple_of_arrays)[0], 0); EXPECT_EQ(std::get<1>(tuple_of_arrays)[0], 0); diff --git a/barretenberg/cpp/src/barretenberg/proof_system/relations/ecc_vm/ecc_transcript_relation.hpp b/barretenberg/cpp/src/barretenberg/proof_system/relations/ecc_vm/ecc_transcript_relation.hpp index 86d5dc5e738..eded697fafa 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/relations/ecc_vm/ecc_transcript_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/relations/ecc_vm/ecc_transcript_relation.hpp @@ -69,9 +69,9 @@ template class ECCVMTranscriptRelationBase { LEN_1, LEN_1>; - template + template static void accumulate(typename AccumulatorTypes::Accumulators& /*unused*/, - const PolynomialTypes& /*unused*/, + const auto& /*unused*/, const RelationParameters& /*unused*/, const FF& /*unused*/); diff --git a/barretenberg/cpp/src/barretenberg/proof_system/relations/relation_types.hpp b/barretenberg/cpp/src/barretenberg/proof_system/relations/relation_types.hpp index ca9a8cfa1bf..4ccc69ab1eb 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/relations/relation_types.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/relations/relation_types.hpp @@ -117,10 +117,10 @@ template class Relation : public RelationImpl { accumulator, input, relation_parameters, scaling_factor); } - static void add_full_relation_value_contribution(RelationValues& accumulator, - auto& input, - const RelationParameters& relation_parameters, - const FF& scaling_factor = 1) + static inline void add_full_relation_value_contribution(RelationValues& accumulator, + auto& input, + const RelationParameters& relation_parameters, + const FF& scaling_factor = 1) { Relation::template accumulate( accumulator, input, relation_parameters, scaling_factor); diff --git a/barretenberg/cpp/src/barretenberg/proof_system/relations/utils.hpp b/barretenberg/cpp/src/barretenberg/proof_system/relations/utils.hpp new file mode 100644 index 00000000000..a75f1aef82d --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/proof_system/relations/utils.hpp @@ -0,0 +1,97 @@ +#pragma once + +#include "barretenberg/polynomials/pow.hpp" +#include "barretenberg/proof_system/relations/relation_parameters.hpp" +#include +#include +#include +namespace barretenberg { +template class RelationUtils { + using FF = typename Flavor::FF; + using PolynomialEvaluations = typename Flavor::ProverPolynomialsEvaluations; + using Relations = typename Flavor::Relations; + using RelationEvaluations = typename Flavor::RelationValues; + + static constexpr size_t NUM_RELATIONS = Flavor::NUM_RELATIONS; + + public: + /** + * Utility methods for tuple of arrays + */ + + /** + * @brief Set each element in a tuple of arrays to zero. + * @details FF's default constructor may not initialize to zero (e.g., barretenberg::fr), hence we can't rely on + * aggregate initialization of the evaluations array. + */ + template static void zero_elements(auto& tuple) + { + auto set_to_zero = [](auto& element) { std::fill(element.begin(), element.end(), FF(0)); }; + apply_to_tuple_of_arrays(set_to_zero, tuple); + }; + + /** + * @brief Scale elements by consecutive powers of the challenge then sum + * @param result Batched result + */ + static void scale_and_batch_elements(auto& tuple, const FF& challenge, FF current_scalar, FF& result) + { + auto scale_by_challenge_and_accumulate = [&](auto& element) { + for (auto& entry : element) { + result += entry * current_scalar; + current_scalar *= challenge; + } + }; + apply_to_tuple_of_arrays(scale_by_challenge_and_accumulate, tuple); + } + + /** + * @brief General purpose method for applying a tuple of arrays (of FFs) + * + * @tparam Operation Any operation valid on elements of the inner arrays (FFs) + * @param tuple Tuple of arrays (of FFs) + */ + template + static void apply_to_tuple_of_arrays(Operation&& operation, std::tuple& tuple) + { + auto& element = std::get(tuple); + + std::invoke(std::forward(operation), element); + + if constexpr (idx + 1 < sizeof...(Ts)) { + apply_to_tuple_of_arrays(operation, tuple); + } + } + + // TODO(#224)(Cody): make uniform with accumulate_relation_univariates + /** + * @brief Calculate the contribution of each relation to the expected value of the full Honk relation. + * + * @details For each relation, use the purported values (supplied by the prover) of the multivariates to calculate + * a contribution to the purported value of the full Honk relation. These are stored in `evaluations`. Adding these + * together, with appropriate scaling factors, produces the expected value of the full Honk relation. This value is + * checked against the final value of the target total sum (called sigma_0 in the thesis). + */ + template + // TODO(#224)(Cody): Input should be an array? + // These claimed evaluations would be Claimed evaluations for sumcheck and proper evaluation for ProtoGalaxy + // copy paste in pg no other choice + static void accumulate_relation_evaluations(PolynomialEvaluations purported_evaluations, + RelationEvaluations& relation_evaluations, + const proof_system::RelationParameters& relation_parameters, + const FF& partial_evaluation_constant) + { + using Relation = std::tuple_element_t; + Relation::add_full_relation_value_contribution(std::get(relation_evaluations), + purported_evaluations, + relation_parameters, + partial_evaluation_constant); + + // Repeat for the next relation. + if constexpr (relation_idx + 1 < NUM_RELATIONS) { + accumulate_relation_evaluations( + purported_evaluations, relation_evaluations, relation_parameters, partial_evaluation_constant); + } + } +}; +} // namespace barretenberg \ No newline at end of file From 06b87c52ed2556b622522f1d0ad2e9f0c11520c9 Mon Sep 17 00:00:00 2001 From: maramihali Date: Mon, 2 Oct 2023 15:51:14 +0000 Subject: [PATCH 03/13] more wip --- .../honk/proof_system/protogalaxy_prover.cpp | 2 ++ .../honk/proof_system/protogalaxy_prover.hpp | 31 +++++++++++++------ 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp index fd7b0f391ac..1cc819eca86 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp @@ -48,6 +48,8 @@ ProverFoldingResult ProtoGalaxyProver_(numeric::get_msb(instance_size)); auto deltas = compute_round_challenge_pows(log_instance_size, delta); auto perturbator_evaluations = compute_perturbator(accumulator, deltas, alpha); + // auto evaluation_point = transcript.get_challenge("evaluation_point"); + // apply barycentric evaluation to get F(alpha) ProverFoldingResult res; res.folding_data = transcript.proof_data; return res; diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp index 93ce056aa13..59c3fd9f43d 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp @@ -92,15 +92,28 @@ template class ProtoGalaxyProver_ { auto betas = accumulator.folding_params.gate_separation_challenges; - // note: the tree technique can probably/maybe be done with apply tuples sth but - - auto point = FF(1); - std::vector labels(log_instance_size); - for (size_t idx = 0; idx < log_instance_size; idx++) { - labels[idx] = betas[idx] + point * deltas[idx]; - } - auto eval_at_point = FF(0); - for (size_t idx = 0; idx < instance_size; idx++) { + // note: the tree technique can probably/maybe be done with apply tuples sth, check later + for (size_t point = 1; point <= log_instance_size; point++) { + std::vector labels(log_instance_size, 0); + for (size_t idx = 0; idx < log_instance_size; idx++) { + labels[idx] = betas[idx] + point * deltas[idx]; + } + auto eval_at_point = FF(0); + for (size_t idx = 0; idx < instance_size; idx++) { + auto res = full_honk_evaluations[idx]; + auto j = idx; + auto iter = 0; + while (j > 0) { + if ((j & 1) == 1) { + res *= labels[iter]; + iter++; + j >>= 1; + } + } + eval_at_point += res; + } + perturbator_univariate[point] = eval_at_point; + transcript.send_to_verifier("perturbator_eval_" + std::to_string(point), point); } return perturbator_univariate; }; From 8f49838ef030946da3a4b1868c46193a68328615 Mon Sep 17 00:00:00 2001 From: maramihali Date: Tue, 3 Oct 2023 10:30:28 +0000 Subject: [PATCH 04/13] compiles --- .../barretenberg/honk/flavor/goblin_ultra.hpp | 2 +- .../honk/flavor/ultra_grumpkin.hpp | 2 +- .../barretenberg/honk/instance/instances.hpp | 4 ++-- .../honk/proof_system/protogalaxy_prover.cpp | 2 +- .../honk/proof_system/protogalaxy_prover.hpp | 20 +++++++++---------- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/flavor/goblin_ultra.hpp b/barretenberg/cpp/src/barretenberg/honk/flavor/goblin_ultra.hpp index 54e7a9f9198..374fa33521a 100644 --- a/barretenberg/cpp/src/barretenberg/honk/flavor/goblin_ultra.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/flavor/goblin_ultra.hpp @@ -436,7 +436,7 @@ class GoblinUltra { class FoldingParameters { public: - FF gate_separation_challenge; + std::vector gate_separation_challenges; FF target_sum; }; }; diff --git a/barretenberg/cpp/src/barretenberg/honk/flavor/ultra_grumpkin.hpp b/barretenberg/cpp/src/barretenberg/honk/flavor/ultra_grumpkin.hpp index 7b58cec2362..c08e20b4167 100644 --- a/barretenberg/cpp/src/barretenberg/honk/flavor/ultra_grumpkin.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/flavor/ultra_grumpkin.hpp @@ -403,7 +403,7 @@ class UltraGrumpkin { }; class FoldingParameters { public: - FF gate_separation_challenge; + std::vector gate_separation_challenges; FF target_sum; }; }; diff --git a/barretenberg/cpp/src/barretenberg/honk/instance/instances.hpp b/barretenberg/cpp/src/barretenberg/honk/instance/instances.hpp index 565757ebb86..30abcf99760 100644 --- a/barretenberg/cpp/src/barretenberg/honk/instance/instances.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/instance/instances.hpp @@ -11,7 +11,7 @@ template struct ProverInstances_ { public: static constexpr size_t NUM = NUM_; ArrayType _data; - Instance const& operator[](size_t idx) const { return _data[idx]; } + std::shared_ptr const& operator[](size_t idx) const { return _data[idx]; } typename ArrayType::iterator begin() { return _data.begin(); }; typename ArrayType::iterator end() { return _data.end(); }; ProverInstances_(std::vector> data) @@ -32,7 +32,7 @@ template struct VerifierInstances_ { public: static constexpr size_t NUM = NUM_; ArrayType _data; - Instance const& operator[](size_t idx) const { return _data[idx]; } + std::shared_ptr const& operator[](size_t idx) const { return _data[idx]; } typename ArrayType::iterator begin() { return _data.begin(); }; typename ArrayType::iterator end() { return _data.end(); }; VerifierInstances_(std::vector> vks) diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp index 1cc819eca86..437856e9c4d 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp @@ -44,7 +44,7 @@ ProverFoldingResult ProtoGalaxyProver_prover_polynomials[0].size(); auto log_instance_size = static_cast(numeric::get_msb(instance_size)); auto deltas = compute_round_challenge_pows(log_instance_size, delta); auto perturbator_evaluations = compute_perturbator(accumulator, deltas, alpha); diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp index 59c3fd9f43d..3cd66637465 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp @@ -37,18 +37,18 @@ template class ProtoGalaxyProver_ { return pows; } - RowEvaluations get_row(Instance accumulator, size_t row) + RowEvaluations get_row(std::shared_ptr accumulator, size_t row) { RowEvaluations row_evals; size_t idx = 0; - for (auto& poly : accumulator.prover_polynomials) { + for (auto& poly : accumulator->prover_polynomials) { row_evals[idx] = poly[row]; idx++; } return row_evals; } - Instance get_accumulator() { return instances[0]; } + std::shared_ptr get_accumulator() { return instances[0]; } // the pow in sumcheck will be replaced with the pow in protogalaxy!!!!!!!! // here we don't have the pow polynomial extra parameter because the gate separation challenge is a polynomial for @@ -74,10 +74,10 @@ template class ProtoGalaxyProver_ { } // We return the evaluate of perturbator at 0,..,log(n) where n is the circuit size - std::vector compute_perturbator(Instance accumulator, std::vector deltas, FF alpha) + std::vector compute_perturbator(std::shared_ptr accumulator, std::vector deltas, FF alpha) { // all the prover polynomials should have the same length - auto instance_size = accumulator.prover_polynomials[0].size(); + auto instance_size = accumulator->prover_polynomials[0].size(); auto log_instance_size = static_cast(numeric::get_msb(instance_size)); std::vector perturbator_univariate(log_instance_size); std::vector full_honk_evaluations(instance_size); @@ -85,24 +85,24 @@ template class ProtoGalaxyProver_ { auto row_evaluations = get_row(accumulator, idx); auto full_honk_at_row = - compute_full_honk_relation_row_value(row_evaluations, alpha, accumulator.relation_parameters); + compute_full_honk_relation_row_value(row_evaluations, alpha, accumulator->relation_parameters); // this is f_i(w) where idx=i full_honk_evaluations[idx] = full_honk_at_row; } - auto betas = accumulator.folding_params.gate_separation_challenges; + auto betas = accumulator->folding_params.gate_separation_challenges; // note: the tree technique can probably/maybe be done with apply tuples sth, check later for (size_t point = 1; point <= log_instance_size; point++) { std::vector labels(log_instance_size, 0); for (size_t idx = 0; idx < log_instance_size; idx++) { - labels[idx] = betas[idx] + point * deltas[idx]; + labels[idx] = betas[idx] + FF(point) * deltas[idx]; } auto eval_at_point = FF(0); for (size_t idx = 0; idx < instance_size; idx++) { auto res = full_honk_evaluations[idx]; auto j = idx; - auto iter = 0; + size_t iter = 0; while (j > 0) { if ((j & 1) == 1) { res *= labels[iter]; @@ -113,7 +113,7 @@ template class ProtoGalaxyProver_ { eval_at_point += res; } perturbator_univariate[point] = eval_at_point; - transcript.send_to_verifier("perturbator_eval_" + std::to_string(point), point); + transcript.send_to_verifier("perturbator_eval_" + std::to_string(point), eval_at_point); } return perturbator_univariate; }; From ecb1a3cba27dca9ebf6e4621e59b78c51f02d276 Mon Sep 17 00:00:00 2001 From: maramihali Date: Thu, 5 Oct 2023 19:45:39 +0000 Subject: [PATCH 05/13] perturbator with coeffs --- .../honk/proof_system/protogalaxy.test.cpp | 69 ++++++++++ .../honk/proof_system/protogalaxy_prover.cpp | 26 +++- .../honk/proof_system/protogalaxy_prover.hpp | 120 +++++++++--------- 3 files changed, 157 insertions(+), 58 deletions(-) create mode 100644 barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp new file mode 100644 index 00000000000..8fd526c7144 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp @@ -0,0 +1,69 @@ +// Note these tests are a bit hacky +#include "barretenberg/honk/composer/ultra_composer.hpp" +#include "protogalaxy_prover.hpp" +#include +using namespace proof_system::honk; + +namespace protogalaxy_utils_tests { +namespace { +auto& engine = numeric::random::get_debug_engine(); +} +class ProtoGalaxyTests : public ::testing::Test { + public: + using Flavor = flavor::Ultra; + using Instances = ProverInstances_; + using ProtoGalaxyProver = ProtoGalaxyProver_; + using FF = Flavor::FF; + using Builder = Flavor::CircuitBuilder; + + static void SetUpTestSuite() { barretenberg::srs::init_crs_factory("../srs_db/ignition"); } +}; +TEST_F(ProtoGalaxyTests, PerturbatorCoefficients) +{ + std::vector betas = { FF(5), FF(8), FF(11) }; + std::vector deltas = { FF(2), FF(4), FF(8) }; + std::vector full_honk_evaluations = { FF(1), FF(1), FF(1), FF(1), FF(1), FF(1), FF(1), FF(1) }; + auto perturbator = ProtoGalaxyProver::construct_perturbator_coeffs(betas, deltas, full_honk_evaluations); + std::vector expected_values = { FF(648), FF(936), FF(432), FF(64) }; + EXPECT_EQ(perturbator.size(), 4); // log_2(instance_size) + 1 + for (size_t i = 0; i < perturbator.size(); i++) { + EXPECT_EQ(perturbator[i], expected_values[i]); + } +} + +TEST_F(ProtoGalaxyTests, PowPerturbatorPolynomial) +{ + + auto builder = Builder(); + FF a = FF::one(); + + // Add some basic add gates, with a public input for good measure + uint32_t a_idx = builder.add_public_variable(a); + FF b = FF::one(); + FF c = a + b; + uint32_t b_idx = builder.add_variable(b); + uint32_t c_idx = builder.add_variable(c); + builder.create_add_gate({ a_idx, b_idx, c_idx, 1, 1, -1, 0 }); + + auto composer = UltraComposer(); + auto instance = composer.create_instance(builder); + instance->folding_params = { { FF(5), FF(8), FF(11), FF(10) }, FF(1) }; + + auto delta = FF::random_element(); + auto alpha = FF::random_element(); + + std::vector>> insts; + insts.emplace_back(instance); + insts.emplace_back(instance); + auto prover = composer.create_folding_prover(insts); + prover.prepare_for_folding(); + + auto log_instance_size = static_cast(numeric::get_msb(instance->prover_polynomials[0].size())); + auto deltas = ProtoGalaxyProver::compute_round_challenge_pows(log_instance_size, delta); + + auto perturbator_coeffs = ProtoGalaxyProver::compute_perturbator(instance, deltas, alpha); + for (size_t i = 0; i < perturbator_coeffs.size(); i++) { + info(perturbator_coeffs[i]); + } +} +} // namespace protogalaxy_utils_tests \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp index 437856e9c4d..fdfe475e035 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp @@ -37,6 +37,26 @@ template void ProtoGalaxyProver_::prepa } } +template +typename ProverInstances::Flavor::FF ProtoGalaxyProver_::compute_full_honk_relation_row_value( + RowEvaluations row_evaluations, FF alpha, const proof_system::RelationParameters& relation_parameters) +{ + RelationEvaluations relation_evaluations; + Utils::zero_elements(relation_evaluations); + + // TODO: we add the gate separation challenge as a univariate later + // We will have to change the power polynomial in sumcheck to respect the structure of PG rather than what we + // currently have + Utils::template accumulate_relation_evaluations<>( + row_evaluations, relation_evaluations, relation_parameters, FF(1)); + + // Not sure what this running challenge is we have to investigate + auto running_challenge = FF(1); + auto output = FF(0); + Utils::scale_and_batch_elements(relation_evaluations, alpha, running_challenge, output); + return output; +} + // TODO(#689): implement this function template ProverFoldingResult ProtoGalaxyProver_::fold_instances() @@ -47,9 +67,13 @@ ProverFoldingResult ProtoGalaxyProver_prover_polynomials[0].size(); auto log_instance_size = static_cast(numeric::get_msb(instance_size)); auto deltas = compute_round_challenge_pows(log_instance_size, delta); + // deltas need to be added to transcript auto perturbator_evaluations = compute_perturbator(accumulator, deltas, alpha); + // evals are added to the transcript asw well // auto evaluation_point = transcript.get_challenge("evaluation_point"); - // apply barycentric evaluation to get F(alpha) + // apply barycentric evaluation to get F(alpha)- this is on the verifier side as well and it's okay cus it's only + // logarithm work + ProverFoldingResult res; res.folding_data = transcript.proof_data; return res; diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp index 3cd66637465..c7cf406d08a 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp @@ -26,18 +26,21 @@ template class ProtoGalaxyProver_ { void prepare_for_folding(); - // compute the deltas in the paper - std::vector compute_round_challenge_pows(size_t size, FF round_challenge) + /** + * @brief For a new round challenge δ at each iteration of the ProtoGalaxy protocol, compute the vector + * [δ, δ^2,..., δ^t] where t = logn and n is the size of the instance. + */ + static std::vector compute_round_challenge_pows(size_t log_instance_size, FF round_challenge) { - std::vector pows(size); + std::vector pows(log_instance_size); pows[0] = round_challenge; - for (size_t i = 1; i < size; i++) { + for (size_t i = 1; i < log_instance_size; i++) { pows[i] = pows[i - 1].sqr(); } return pows; } - RowEvaluations get_row(std::shared_ptr accumulator, size_t row) + static RowEvaluations get_execution_row(std::shared_ptr accumulator, size_t row) { RowEvaluations row_evals; size_t idx = 0; @@ -50,73 +53,76 @@ template class ProtoGalaxyProver_ { std::shared_ptr get_accumulator() { return instances[0]; } - // the pow in sumcheck will be replaced with the pow in protogalaxy!!!!!!!! - // here we don't have the pow polynomial extra parameter because the gate separation challenge is a polynomial for - // perturbator and it's going to be added later - FF compute_full_honk_relation_row_value(RowEvaluations row_evaluations, - FF alpha, - const proof_system::RelationParameters& relation_parameters) + /** + * @brief Given the evaluations of all the prover polynomials at row i and the parameters that help establish each + * subrelation is independently valid, compute the value of the full Honk relation for that specific row (this is + * f_i(ω) in the paper) + */ + static FF compute_full_honk_relation_row_value(RowEvaluations row_evaluations, + FF alpha, + const proof_system::RelationParameters& relation_parameters); + // TODO: make this more memory efficient + static std::vector compute_level(size_t level, + std::vector betas, + std::vector deltas, + std::vector> prev_level_coeffs) { - RelationEvaluations relation_evaluations; - Utils::zero_elements(relation_evaluations); + // if we are at level t in the tree, where t = logn and n is the instance size we have reached the root which + // contains the coefficients of the perturbator polynomial + if (level == betas.size()) { + return prev_level_coeffs[0]; + } - // TODO: we add the gate separation challenge as a univariate later - // We will have to change the power polynomial in sumcheck to respect the structure of PG rather than what we - // currently have - Utils::template accumulate_relation_evaluations<>( - row_evaluations, relation_evaluations, relation_parameters, FF(1)); + auto degree = level + 1; + auto prev_level_width = prev_level_coeffs.size(); + // we need degree + 1 terms to represent intermediate polynomials + std::vector> level_coeffs(prev_level_width / 2, std::vector(degree + 1, 0)); + for (size_t node = 0; node < prev_level_width; node += 2) { + auto parent = node / 2; + std::copy(prev_level_coeffs[node].begin(), prev_level_coeffs[node].end(), level_coeffs[parent].begin()); + for (size_t d = 0; d < degree; d++) { + level_coeffs[parent][d] += prev_level_coeffs[node + 1][d] * betas[level]; + level_coeffs[parent][d + 1] += prev_level_coeffs[node + 1][d] * deltas[level]; + } + } + return compute_level(level + 1, betas, deltas, level_coeffs); + } - // Not sure what this running challenge is we have to investigate - auto running_challenge = FF(1); - auto output = FF(0); - Utils::scale_and_batch_elements(relation_evaluations, alpha, running_challenge, output); - return output; + static std::vector construct_perturbator_coeffs(std::vector betas, + std::vector deltas, + std::vector full_honk_evaluations) + { + // figure out how to make this not take so much memory + auto width = full_honk_evaluations.size(); + std::vector> first_level_coeffs(width / 2, std::vector(2, 0)); + for (size_t node = 0; node < width; node += 2) { + auto idx = node / 2; + first_level_coeffs[idx][0] = full_honk_evaluations[node] + full_honk_evaluations[node + 1] * betas[0]; + first_level_coeffs[idx][1] = full_honk_evaluations[node + 1] * deltas[0]; + } + return compute_level(1, betas, deltas, first_level_coeffs); } - // We return the evaluate of perturbator at 0,..,log(n) where n is the circuit size - std::vector compute_perturbator(std::shared_ptr accumulator, std::vector deltas, FF alpha) + // Compute the power perturbator polynomial in coefficient form + static std::vector compute_perturbator(std::shared_ptr accumulator, std::vector deltas, FF alpha) { - // all the prover polynomials should have the same length auto instance_size = accumulator->prover_polynomials[0].size(); - auto log_instance_size = static_cast(numeric::get_msb(instance_size)); - std::vector perturbator_univariate(log_instance_size); + auto const log_instance_size = static_cast(numeric::get_msb(instance_size)); + assert(deltas.size() == log_instance_size); + std::vector full_honk_evaluations(instance_size); for (size_t idx = 0; idx < instance_size; idx++) { - auto row_evaluations = get_row(accumulator, idx); + auto row_evaluations = get_execution_row(accumulator, idx); auto full_honk_at_row = compute_full_honk_relation_row_value(row_evaluations, alpha, accumulator->relation_parameters); - // this is f_i(w) where idx=i full_honk_evaluations[idx] = full_honk_at_row; } - + info(full_honk_evaluations); auto betas = accumulator->folding_params.gate_separation_challenges; - - // note: the tree technique can probably/maybe be done with apply tuples sth, check later - for (size_t point = 1; point <= log_instance_size; point++) { - std::vector labels(log_instance_size, 0); - for (size_t idx = 0; idx < log_instance_size; idx++) { - labels[idx] = betas[idx] + FF(point) * deltas[idx]; - } - auto eval_at_point = FF(0); - for (size_t idx = 0; idx < instance_size; idx++) { - auto res = full_honk_evaluations[idx]; - auto j = idx; - size_t iter = 0; - while (j > 0) { - if ((j & 1) == 1) { - res *= labels[iter]; - iter++; - j >>= 1; - } - } - eval_at_point += res; - } - perturbator_univariate[point] = eval_at_point; - transcript.send_to_verifier("perturbator_eval_" + std::to_string(point), eval_at_point); - } - return perturbator_univariate; - }; + assert(betas.size() == log_instance_size); + return construct_perturbator_coeffs(betas, deltas, full_honk_evaluations); + } ProverFoldingResult fold_instances(); }; From e4a677062e51a54926e658c5ec4b73ddf9ab4d2e Mon Sep 17 00:00:00 2001 From: maramihali Date: Fri, 6 Oct 2023 11:09:53 +0000 Subject: [PATCH 06/13] add comments --- .../honk/proof_system/protogalaxy.test.cpp | 7 ++- .../honk/proof_system/protogalaxy_prover.cpp | 36 ++++----------- .../honk/proof_system/protogalaxy_prover.hpp | 44 +++++++++++++++---- 3 files changed, 47 insertions(+), 40 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp index 8fd526c7144..8fddd3c27c8 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp @@ -44,6 +44,7 @@ TEST_F(ProtoGalaxyTests, PowPerturbatorPolynomial) uint32_t b_idx = builder.add_variable(b); uint32_t c_idx = builder.add_variable(c); builder.create_add_gate({ a_idx, b_idx, c_idx, 1, 1, -1, 0 }); + builder.create_add_gate({ a_idx, b_idx, c_idx, 1, 1, -1, 0 }); auto composer = UltraComposer(); auto instance = composer.create_instance(builder); @@ -61,9 +62,7 @@ TEST_F(ProtoGalaxyTests, PowPerturbatorPolynomial) auto log_instance_size = static_cast(numeric::get_msb(instance->prover_polynomials[0].size())); auto deltas = ProtoGalaxyProver::compute_round_challenge_pows(log_instance_size, delta); - auto perturbator_coeffs = ProtoGalaxyProver::compute_perturbator(instance, deltas, alpha); - for (size_t i = 0; i < perturbator_coeffs.size(); i++) { - info(perturbator_coeffs[i]); - } + auto perturbator = ProtoGalaxyProver::compute_perturbator(instance, deltas, alpha); + info(perturbator); } } // namespace protogalaxy_utils_tests \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp index fdfe475e035..54df9594ad9 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp @@ -37,26 +37,6 @@ template void ProtoGalaxyProver_::prepa } } -template -typename ProverInstances::Flavor::FF ProtoGalaxyProver_::compute_full_honk_relation_row_value( - RowEvaluations row_evaluations, FF alpha, const proof_system::RelationParameters& relation_parameters) -{ - RelationEvaluations relation_evaluations; - Utils::zero_elements(relation_evaluations); - - // TODO: we add the gate separation challenge as a univariate later - // We will have to change the power polynomial in sumcheck to respect the structure of PG rather than what we - // currently have - Utils::template accumulate_relation_evaluations<>( - row_evaluations, relation_evaluations, relation_parameters, FF(1)); - - // Not sure what this running challenge is we have to investigate - auto running_challenge = FF(1); - auto output = FF(0); - Utils::scale_and_batch_elements(relation_evaluations, alpha, running_challenge, output); - return output; -} - // TODO(#689): implement this function template ProverFoldingResult ProtoGalaxyProver_::fold_instances() @@ -67,13 +47,15 @@ ProverFoldingResult ProtoGalaxyProver_prover_polynomials[0].size(); auto log_instance_size = static_cast(numeric::get_msb(instance_size)); auto deltas = compute_round_challenge_pows(log_instance_size, delta); - // deltas need to be added to transcript - auto perturbator_evaluations = compute_perturbator(accumulator, deltas, alpha); - // evals are added to the transcript asw well - // auto evaluation_point = transcript.get_challenge("evaluation_point"); - // apply barycentric evaluation to get F(alpha)- this is on the verifier side as well and it's okay cus it's only - // logarithm work - + auto perturbator = compute_perturbator(accumulator, deltas, alpha); + // assert(perturbator_coeffs[0] == accumulator.folding_params.target_sum); + for (size_t idx = 1; idx < perturbator.size(); idx++) { + transcript.send_to_verifier("perturbator_" + std::to_string(idx), perturbator[idx]); + } + auto value = transcript.get_challenge("evaluation_point"); + // Compute F(α) + auto evalutation = perturbator.evaluate(value); + transcript.send_to_verifier("perturbator_eval", evalutation); ProverFoldingResult res; res.folding_data = transcript.proof_data; return res; diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp index c7cf406d08a..4553915b8dc 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp @@ -40,6 +40,7 @@ template class ProtoGalaxyProver_ { return pows; } + // Compute the value of the full Honk relation at a row in the execution trace. static RowEvaluations get_execution_row(std::shared_ptr accumulator, size_t row) { RowEvaluations row_evals; @@ -60,14 +61,30 @@ template class ProtoGalaxyProver_ { */ static FF compute_full_honk_relation_row_value(RowEvaluations row_evaluations, FF alpha, - const proof_system::RelationParameters& relation_parameters); - // TODO: make this more memory efficient + const proof_system::RelationParameters& relation_parameters) + { + RelationEvaluations relation_evaluations; + Utils::zero_elements(relation_evaluations); + + // Note that the evaluations are accumulated with the gate separation challenge being 1 at this stage, as this + // randomness is added later through the power polynomial univariate + Utils::template accumulate_relation_evaluations<>( + row_evaluations, relation_evaluations, relation_parameters, FF(1)); + + auto running_challenge = FF(1); + auto output = FF(0); + Utils::scale_and_batch_elements(relation_evaluations, alpha, running_challenge, output); + return output; + } + + // Compute the parent nodes at the current level. Note that the resulting parent nodes will be polynomials of degree + // (level + 1) as at each level we multiply by an additional factor of X. static std::vector compute_level(size_t level, std::vector betas, std::vector deltas, std::vector> prev_level_coeffs) { - // if we are at level t in the tree, where t = logn and n is the instance size we have reached the root which + // if we are at level t in the tree, where t = logn and n is the instance size, we have reached the root which // contains the coefficients of the perturbator polynomial if (level == betas.size()) { return prev_level_coeffs[0]; @@ -75,7 +92,7 @@ template class ProtoGalaxyProver_ { auto degree = level + 1; auto prev_level_width = prev_level_coeffs.size(); - // we need degree + 1 terms to represent intermediate polynomials + // we need degree + 1 terms to represent the intermediate polynomials std::vector> level_coeffs(prev_level_width / 2, std::vector(degree + 1, 0)); for (size_t node = 0; node < prev_level_width; node += 2) { auto parent = node / 2; @@ -88,11 +105,20 @@ template class ProtoGalaxyProver_ { return compute_level(level + 1, betas, deltas, level_coeffs); } + /** + * @brief We construct the coefficients of the perturbator polynomial in O(n) time following the technique in + * Claim 4.4. Consider a binary tree whose leaves are the evaluations of the full Honk relation at each row in the + * execution trace. The subsequent levels in the tree are constructed using the following technique: At level i in + * the tree, label the branch connecting the left node n_l to its parent by 1 and for the right node n_r by β_i + + * δ_i X. The value of the parent node n will be constructed as n = n_l + n_r * (β_i + δ_i X). Recurse over each + * layer until the root is reached which will correspond to the perturbator polynomial F(X). + * TODO(insert issue): make this more memory efficient + */ static std::vector construct_perturbator_coeffs(std::vector betas, std::vector deltas, std::vector full_honk_evaluations) { - // figure out how to make this not take so much memory + auto width = full_honk_evaluations.size(); std::vector> first_level_coeffs(width / 2, std::vector(2, 0)); for (size_t node = 0; node < width; node += 2) { @@ -103,8 +129,8 @@ template class ProtoGalaxyProver_ { return compute_level(1, betas, deltas, first_level_coeffs); } - // Compute the power perturbator polynomial in coefficient form - static std::vector compute_perturbator(std::shared_ptr accumulator, std::vector deltas, FF alpha) + // Compute the power perturbator polynomial F(X) in coefficient form + static Polynomial compute_perturbator(std::shared_ptr accumulator, std::vector deltas, FF alpha) { auto instance_size = accumulator->prover_polynomials[0].size(); auto const log_instance_size = static_cast(numeric::get_msb(instance_size)); @@ -118,10 +144,10 @@ template class ProtoGalaxyProver_ { compute_full_honk_relation_row_value(row_evaluations, alpha, accumulator->relation_parameters); full_honk_evaluations[idx] = full_honk_at_row; } - info(full_honk_evaluations); auto betas = accumulator->folding_params.gate_separation_challenges; assert(betas.size() == log_instance_size); - return construct_perturbator_coeffs(betas, deltas, full_honk_evaluations); + auto coeffs = construct_perturbator_coeffs(betas, deltas, full_honk_evaluations); + return Polynomial(coeffs); } ProverFoldingResult fold_instances(); From 41e24fd7a86dc1663a0ac0712d6aab1e4deadd68 Mon Sep 17 00:00:00 2001 From: maramihali Date: Fri, 6 Oct 2023 14:06:17 +0000 Subject: [PATCH 07/13] polish --- .../src/barretenberg/honk/flavor/ecc_vm.hpp | 2 +- .../barretenberg/honk/instance/instances.hpp | 4 +-- .../honk/instance/prover_instance.hpp | 4 +-- .../honk/instance/verifier_instance.hpp | 2 +- .../honk/proof_system/protogalaxy_prover.cpp | 15 ++++++----- .../proof_system/protogalaxy_verifier.cpp | 26 +++++++++++++------ .../proof_system/protogalaxy_verifier.hpp | 15 +++++++++++ .../honk/transcript/transcript.test.cpp | 7 +++++ .../proof_system/relations/utils.hpp | 2 +- 9 files changed, 56 insertions(+), 21 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/flavor/ecc_vm.hpp b/barretenberg/cpp/src/barretenberg/honk/flavor/ecc_vm.hpp index a73c9d429a2..b061663e270 100644 --- a/barretenberg/cpp/src/barretenberg/honk/flavor/ecc_vm.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/flavor/ecc_vm.hpp @@ -696,7 +696,7 @@ template class ECCVMBa * @brief A container storing evaluations of all prover polynomials at one point. * In sumcheck, this data structure represents the evaluations produced during sumcheck, which are claimed to be the * evaluations of prover polynomials commited in earilier rounds - * In protogalaxy, it's used to store the evaluations for each point on the boolean hypercurbe, so one + * In ProtoGalaxy, it's used to store the evaluations for each point on the boolean hypercurbe, so one * ProverPolynomailsEvaluation object represents evaluations of one row in the execution trace. * */ diff --git a/barretenberg/cpp/src/barretenberg/honk/instance/instances.hpp b/barretenberg/cpp/src/barretenberg/honk/instance/instances.hpp index 30abcf99760..6179d81aa51 100644 --- a/barretenberg/cpp/src/barretenberg/honk/instance/instances.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/instance/instances.hpp @@ -27,7 +27,7 @@ template struct VerifierInstances_ { using Flavor = Flavor_; using VerificationKey = typename Flavor::VerificationKey; using Instance = VerifierInstance_; - using ArrayType = std::array; + using ArrayType = std::array, NUM_>; public: static constexpr size_t NUM = NUM_; @@ -41,7 +41,7 @@ template struct VerifierInstances_ { for (size_t idx = 0; idx < vks.size(); idx++) { Instance inst; inst.verification_key = std::move(vks[idx]); - _data[idx] = inst; + _data[idx] = std::make_unique(inst); } }; }; diff --git a/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.hpp b/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.hpp index 6b9a1d6c938..6ad2132dd7b 100644 --- a/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.hpp @@ -39,12 +39,12 @@ template class ProverInstance_ { // folded element by element. std::vector public_inputs; // offset due to placing zero wires at the start of execution trace - // this value is only set for Instances constructed from circuits, this concept doesn't exist for accumulated + // non-zero for Instances constructed from circuits, this concept doesn't exist for accumulated // instances size_t pub_inputs_offset = 0; proof_system::RelationParameters relation_parameters; std::vector recursive_proof_public_input_indices; - // only set for the accumulated instances + // non-empty for the accumulated instances FoldingParameters folding_params; ProverInstance_(Circuit& circuit) diff --git a/barretenberg/cpp/src/barretenberg/honk/instance/verifier_instance.hpp b/barretenberg/cpp/src/barretenberg/honk/instance/verifier_instance.hpp index 3ba7979103a..2e8ac9a0210 100644 --- a/barretenberg/cpp/src/barretenberg/honk/instance/verifier_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/instance/verifier_instance.hpp @@ -12,7 +12,7 @@ template class VerifierInstance_ { std::vector public_inputs; size_t pub_inputs_offset; size_t public_input_size; - size_t circuit_size; + size_t instance_size; RelationParameters relation_parameters; FoldingParameters folding_params; }; diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp index 54df9594ad9..6e6a27b0fa1 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp @@ -37,7 +37,7 @@ template void ProtoGalaxyProver_::prepa } } -// TODO(#689): implement this function +// TODO(#689): finalise implementation this function template ProverFoldingResult ProtoGalaxyProver_::fold_instances() { @@ -48,14 +48,17 @@ ProverFoldingResult ProtoGalaxyProver_(numeric::get_msb(instance_size)); auto deltas = compute_round_challenge_pows(log_instance_size, delta); auto perturbator = compute_perturbator(accumulator, deltas, alpha); - // assert(perturbator_coeffs[0] == accumulator.folding_params.target_sum); - for (size_t idx = 1; idx < perturbator.size(); idx++) { + + // TODO: we shouldn't have to send the 0 coefficient as this is equal to target sum and should instead have the + // assertion in place once protogalaxy is finalised assert(perturbator_coeffs[0] == + // accumulator.folding_params.target_sum); + for (size_t idx = 0; idx <= log_instance_size; idx++) { transcript.send_to_verifier("perturbator_" + std::to_string(idx), perturbator[idx]); } - auto value = transcript.get_challenge("evaluation_point"); + // auto value = transcript.get_challenge("evaluation_point"); // Compute F(α) - auto evalutation = perturbator.evaluate(value); - transcript.send_to_verifier("perturbator_eval", evalutation); + // auto evalutation = perturbator.evaluate(value); + // transcript.send_to_verifier("perturbator_eval", evalutation); ProverFoldingResult res; res.folding_data = transcript.proof_data; return res; diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.cpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.cpp index d9b8393d120..db4383f2a42 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.cpp @@ -10,26 +10,36 @@ VerifierFoldingResult ProtoGalaxyVerifier_< for (auto it = verifier_instances.begin(); it != verifier_instances.end(); it++, index++) { auto inst = *it; auto domain_separator = std::to_string(index); - inst.circuit_size = transcript.template receive_from_prover(domain_separator + "_circuit_size"); - inst.public_input_size = + inst->instance_size = transcript.template receive_from_prover(domain_separator + "_circuit_size"); + inst->public_input_size = transcript.template receive_from_prover(domain_separator + "_public_input_size"); - inst.pub_inputs_offset = + inst->pub_inputs_offset = transcript.template receive_from_prover(domain_separator + "_pub_inputs_offset"); - for (size_t i = 0; i < inst.public_input_size; ++i) { + for (size_t i = 0; i < inst->public_input_size; ++i) { auto public_input_i = transcript.template receive_from_prover(domain_separator + "_public_input_" + std::to_string(i)); - inst.public_inputs.emplace_back(public_input_i); + inst->public_inputs.emplace_back(public_input_i); } auto [eta, beta, gamma] = transcript.get_challenges( domain_separator + "_eta", domain_separator + "_beta", domain_separator + "_gamma"); const FF public_input_delta = compute_public_input_delta( - inst.public_inputs, beta, gamma, inst.circuit_size, inst.pub_inputs_offset); - const FF lookup_grand_product_delta = compute_lookup_grand_product_delta(beta, gamma, inst.circuit_size); - inst.relation_parameters = + inst->public_inputs, beta, gamma, inst->instance_size, inst->pub_inputs_offset); + const FF lookup_grand_product_delta = compute_lookup_grand_product_delta(beta, gamma, inst->instance_size); + inst->relation_parameters = RelationParameters{ eta, beta, gamma, public_input_delta, lookup_grand_product_delta }; } + auto [alpha, delta] = + transcript.get_challenges("alpha", "delta"); // what does verifier do with this alpha which is from plonk paper? + auto accumulator = get_accumulator(); + auto log_instance_size = static_cast(numeric::get_msb(accumulator->instance_size)); + auto deltas = compute_round_challenge_pows(log_instance_size, delta); + std::vector coeffs(log_instance_size + 1); + for (size_t idx = 0; idx <= log_instance_size; idx++) { + coeffs[idx] = transcript.template receive_from_prover("perturbator_" + std::to_string(idx)); + } + // TODO(#690): implement the Protogalaxy verifier logic VerifierFoldingResult res; return res; diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.hpp index eeb64a44c0e..81b026acf03 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.hpp @@ -21,6 +21,21 @@ template class ProtoGalaxyVerifier_ { ProtoGalaxyVerifier_(VerifierInstances insts) : verifier_instances(insts){}; ~ProtoGalaxyVerifier_() = default; + /** + * @brief For a new round challenge δ at each iteration of the ProtoGalaxy protocol, compute the vector + * [δ, δ^2,..., δ^t] where t = logn and n is the size of the instance. + */ + static std::vector compute_round_challenge_pows(size_t log_instance_size, FF round_challenge) + { + std::vector pows(log_instance_size); + pows[0] = round_challenge; + for (size_t i = 1; i < log_instance_size; i++) { + pows[i] = pows[i - 1].sqr(); + } + return pows; + } + std::shared_ptr get_accumulator() { return verifier_instances[0]; } + VerifierFoldingResult fold_public_parameters(std::vector fold_data); }; diff --git a/barretenberg/cpp/src/barretenberg/honk/transcript/transcript.test.cpp b/barretenberg/cpp/src/barretenberg/honk/transcript/transcript.test.cpp index df3ca8526dd..b2e8127180b 100644 --- a/barretenberg/cpp/src/barretenberg/honk/transcript/transcript.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/transcript/transcript.test.cpp @@ -224,6 +224,13 @@ TEST_F(UltraTranscriptTests, FoldingManifestTest) auto composer = UltraComposer(); auto instance_one = composer.create_instance(builder_one); + // artificially make first instance relaxed + auto log_instance_size = static_cast(numeric::get_msb(instance_one->proving_key->circuit_size)); + std::vector betas(log_instance_size); + for (size_t idx = 0; idx < log_instance_size; idx++) { + betas[idx] = FF::random_element(); + } + instance_one->folding_params = { betas, FF(1) }; auto instance_two = composer.create_instance(builder_two); std::vector>> insts; diff --git a/barretenberg/cpp/src/barretenberg/proof_system/relations/utils.hpp b/barretenberg/cpp/src/barretenberg/proof_system/relations/utils.hpp index a75f1aef82d..5f3af005452 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/relations/utils.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/relations/utils.hpp @@ -16,7 +16,7 @@ template class RelationUtils { public: /** - * Utility methods for tuple of arrays + * Shared utility methods for tuple of arrays and accumulating relations. */ /** From ac47b18b21c331609bdf938f829ab0da8cde693f Mon Sep 17 00:00:00 2001 From: maramihali Date: Sat, 7 Oct 2023 10:50:41 +0000 Subject: [PATCH 08/13] looking for bug:( --- .../honk/instance/prover_instance.hpp | 1 + .../honk/proof_system/protogalaxy.test.cpp | 173 ++++++++++++++---- .../honk/proof_system/protogalaxy_prover.cpp | 4 +- .../honk/proof_system/protogalaxy_prover.hpp | 80 ++++---- 4 files changed, 190 insertions(+), 68 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.hpp b/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.hpp index 6ad2132dd7b..71eab4fca99 100644 --- a/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.hpp @@ -42,6 +42,7 @@ template class ProverInstance_ { // non-zero for Instances constructed from circuits, this concept doesn't exist for accumulated // instances size_t pub_inputs_offset = 0; + // TODO: how do we fold relation parameters? proof_system::RelationParameters relation_parameters; std::vector recursive_proof_public_input_indices; // non-empty for the accumulated instances diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp index 8fddd3c27c8..6475477cd8d 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp @@ -4,40 +4,87 @@ #include using namespace proof_system::honk; +using Flavor = flavor::Ultra; +using Instance = ProverInstance_; +using Instances = ProverInstances_; +using ProtoGalaxyProver = ProtoGalaxyProver_; +using FF = Flavor::FF; +using Builder = Flavor::CircuitBuilder; +using ProverPolynomials = Flavor::ProverPolynomials; +const size_t NUM_POLYNOMIALS = Flavor::NUM_ALL_ENTITIES; + namespace protogalaxy_utils_tests { namespace { auto& engine = numeric::random::get_debug_engine(); } -class ProtoGalaxyTests : public ::testing::Test { - public: - using Flavor = flavor::Ultra; - using Instances = ProverInstances_; - using ProtoGalaxyProver = ProtoGalaxyProver_; - using FF = Flavor::FF; - using Builder = Flavor::CircuitBuilder; - static void SetUpTestSuite() { barretenberg::srs::init_crs_factory("../srs_db/ignition"); } -}; -TEST_F(ProtoGalaxyTests, PerturbatorCoefficients) +barretenberg::Polynomial random_poly(size_t size) { - std::vector betas = { FF(5), FF(8), FF(11) }; - std::vector deltas = { FF(2), FF(4), FF(8) }; - std::vector full_honk_evaluations = { FF(1), FF(1), FF(1), FF(1), FF(1), FF(1), FF(1), FF(1) }; - auto perturbator = ProtoGalaxyProver::construct_perturbator_coeffs(betas, deltas, full_honk_evaluations); - std::vector expected_values = { FF(648), FF(936), FF(432), FF(64) }; - EXPECT_EQ(perturbator.size(), 4); // log_2(instance_size) + 1 - for (size_t i = 0; i < perturbator.size(); i++) { - EXPECT_EQ(perturbator[i], expected_values[i]); + auto poly = barretenberg::Polynomial(size); + for (auto& coeff : poly) { + coeff = FF::random_element(); } + return poly; } -TEST_F(ProtoGalaxyTests, PowPerturbatorPolynomial) +ProverPolynomials construct_ultra_full_polynomials(auto& input_polynomials) { + ProverPolynomials full_polynomials; + full_polynomials.q_c = input_polynomials[0]; + full_polynomials.q_l = input_polynomials[1]; + full_polynomials.q_r = input_polynomials[2]; + full_polynomials.q_o = input_polynomials[3]; + full_polynomials.q_4 = input_polynomials[4]; + full_polynomials.q_m = input_polynomials[5]; + full_polynomials.q_arith = input_polynomials[6]; + full_polynomials.q_sort = input_polynomials[7]; + full_polynomials.q_elliptic = input_polynomials[8]; + full_polynomials.q_aux = input_polynomials[9]; + full_polynomials.q_lookup = input_polynomials[10]; + full_polynomials.sigma_1 = input_polynomials[11]; + full_polynomials.sigma_2 = input_polynomials[12]; + full_polynomials.sigma_3 = input_polynomials[13]; + full_polynomials.sigma_4 = input_polynomials[14]; + full_polynomials.id_1 = input_polynomials[15]; + full_polynomials.id_2 = input_polynomials[16]; + full_polynomials.id_3 = input_polynomials[17]; + full_polynomials.id_4 = input_polynomials[18]; + full_polynomials.table_1 = input_polynomials[19]; + full_polynomials.table_2 = input_polynomials[20]; + full_polynomials.table_3 = input_polynomials[21]; + full_polynomials.table_4 = input_polynomials[22]; + full_polynomials.lagrange_first = input_polynomials[23]; + full_polynomials.lagrange_last = input_polynomials[24]; + full_polynomials.w_l = input_polynomials[25]; + full_polynomials.w_r = input_polynomials[26]; + full_polynomials.w_o = input_polynomials[27]; + full_polynomials.w_4 = input_polynomials[28]; + full_polynomials.sorted_accum = input_polynomials[29]; + full_polynomials.z_perm = input_polynomials[30]; + full_polynomials.z_lookup = input_polynomials[31]; + full_polynomials.table_1_shift = input_polynomials[32]; + full_polynomials.table_2_shift = input_polynomials[33]; + full_polynomials.table_3_shift = input_polynomials[34]; + full_polynomials.table_4_shift = input_polynomials[35]; + full_polynomials.w_l_shift = input_polynomials[36]; + full_polynomials.w_r_shift = input_polynomials[37]; + full_polynomials.w_o_shift = input_polynomials[38]; + full_polynomials.w_4_shift = input_polynomials[39]; + full_polynomials.sorted_accum_shift = input_polynomials[40]; + full_polynomials.z_perm_shift = input_polynomials[41]; + full_polynomials.z_lookup_shift = input_polynomials[42]; + return full_polynomials; +} +class ProtoGalaxyTests : public ::testing::Test { + public: + static void SetUpTestSuite() { barretenberg::srs::init_crs_factory("../srs_db/ignition"); } +}; + +TEST_F(ProtoGalaxyTests, FullHonkEvaluationsValidCircuit) +{ auto builder = Builder(); FF a = FF::one(); - - // Add some basic add gates, with a public input for good measure uint32_t a_idx = builder.add_public_variable(a); FF b = FF::one(); FF c = a + b; @@ -48,21 +95,85 @@ TEST_F(ProtoGalaxyTests, PowPerturbatorPolynomial) auto composer = UltraComposer(); auto instance = composer.create_instance(builder); - instance->folding_params = { { FF(5), FF(8), FF(11), FF(10) }, FF(1) }; + instance->initialise_prover_polynomials(); + + auto eta = FF::random_element(); + auto beta = FF::random_element(); + auto gamma = FF::random_element(); + instance->compute_sorted_accumulator_polynomials(eta); + instance->compute_grand_product_polynomials(beta, gamma); - auto delta = FF::random_element(); auto alpha = FF::random_element(); + auto full_honk_evals = ProtoGalaxyProver::compute_full_honk_evaluations( + instance->prover_polynomials, alpha, instance->relation_parameters); + + // Evaluations should be 0 for valid circuit + for (const auto& eval : full_honk_evals) { + EXPECT_EQ(eval, FF(0)); + } +} +TEST_F(ProtoGalaxyTests, PerturbatorCoefficients) +{ + std::vector betas = { FF(5), FF(8), FF(11) }; + std::vector deltas = { FF(2), FF(4), FF(8) }; + std::vector full_honk_evaluations = { FF(1), FF(1), FF(1), FF(1), FF(1), FF(1), FF(1), FF(1) }; + auto perturbator = ProtoGalaxyProver::construct_perturbator_coeffs(betas, deltas, full_honk_evaluations); + std::vector expected_values = { FF(648), FF(936), FF(432), FF(64) }; + EXPECT_EQ(perturbator.size(), 4); // log(instance_size) + 1 + for (size_t i = 0; i < perturbator.size(); i++) { + EXPECT_EQ(perturbator[i], expected_values[i]); + } +} - std::vector>> insts; - insts.emplace_back(instance); - insts.emplace_back(instance); - auto prover = composer.create_folding_prover(insts); - prover.prepare_for_folding(); +TEST_F(ProtoGalaxyTests, PowPerturbatorPolynomial) +{ + const size_t log_instance_size(3); + const size_t instance_size(1 << log_instance_size); - auto log_instance_size = static_cast(numeric::get_msb(instance->prover_polynomials[0].size())); - auto deltas = ProtoGalaxyProver::compute_round_challenge_pows(log_instance_size, delta); + // Randomly construct the prover polynomials that are input to Sumcheck. + // Note: ProverPolynomials are defined as spans so the polynomials they point to need to exist in memory. + std::array, NUM_POLYNOMIALS> random_polynomials; + for (auto& poly : random_polynomials) { + poly = random_poly(instance_size); + } + auto full_polynomials = construct_ultra_full_polynomials(random_polynomials); + proof_system::RelationParameters relation_parameters{ + .eta = FF::random_element(), + .beta = FF::random_element(), + .gamma = FF::random_element(), + .public_input_delta = FF::one(), + }; + auto alpha = FF::random_element(); + auto full_honk_evals = + ProtoGalaxyProver::compute_full_honk_evaluations(full_polynomials, alpha, relation_parameters); + info(full_honk_evals); + std::vector betas = { FF(2), FF(4), FF(16) }; + std::vector pow_beta(instance_size); + for (size_t i = 0; i < instance_size; i++) { + auto j = i; + size_t idx = 0; + auto res = FF(1); + while (j > 0) { + if ((j & 1) == 1) { - auto perturbator = ProtoGalaxyProver::compute_perturbator(instance, deltas, alpha); + res *= betas[idx]; + } + j >>= 1; + idx++; + } + pow_beta[i] = res; + } + info(pow_beta); + auto expected_target_sum = FF(0); + for (size_t i = 0; i < instance_size; i++) { + expected_target_sum += full_honk_evals[i] * pow_beta[i]; + } + info(expected_target_sum); + auto folding_result = FoldingResult{ .folded_prover_polynomials = full_polynomials, + .params = { betas, expected_target_sum } }; + auto accumulator = std::make_shared(folding_result); + std::vector deltas = { FF(2), FF(4), FF(8) }; + auto perturbator = ProtoGalaxyProver::compute_perturbator(accumulator, deltas, alpha); info(perturbator); } } // namespace protogalaxy_utils_tests \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp index 6e6a27b0fa1..e3558eedd97 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp @@ -49,8 +49,8 @@ ProverFoldingResult ProtoGalaxyProver_ class ProtoGalaxyProver_ { return pows; } - // Compute the value of the full Honk relation at a row in the execution trace. - static RowEvaluations get_execution_row(std::shared_ptr accumulator, size_t row) + std::shared_ptr get_accumulator() { return instances[0]; } + + /** + * @brief Compute the value of the full Honk relation at a row in the execution trace. + */ + static RowEvaluations get_execution_row(ProverPolynomials instance_polynomials, size_t row) { RowEvaluations row_evals; size_t idx = 0; - for (auto& poly : accumulator->prover_polynomials) { + for (auto& poly : instance_polynomials) { row_evals[idx] = poly[row]; idx++; } return row_evals; } - std::shared_ptr get_accumulator() { return instances[0]; } - /** - * @brief Given the evaluations of all the prover polynomials at row i and the parameters that help establish each - * subrelation is independently valid, compute the value of the full Honk relation for that specific row (this is - * f_i(ω) in the paper) + * @brief Compute the values of the full Honk relation at each row in the execution trace, f_i(ω) in the + * ProtoGalaxy paper, given the evaluations of all the prover polynomials and α (the parameter that helps establish + * each subrelation is independently valid in Honk - from the Plonk paper, DO NOT confuse with α in ProtoGalaxy), */ - static FF compute_full_honk_relation_row_value(RowEvaluations row_evaluations, - FF alpha, - const proof_system::RelationParameters& relation_parameters) + static std::vector compute_full_honk_evaluations(ProverPolynomials instance_polynomials, + FF alpha, + RelationParameters relation_parameters) { - RelationEvaluations relation_evaluations; - Utils::zero_elements(relation_evaluations); - - // Note that the evaluations are accumulated with the gate separation challenge being 1 at this stage, as this - // randomness is added later through the power polynomial univariate - Utils::template accumulate_relation_evaluations<>( - row_evaluations, relation_evaluations, relation_parameters, FF(1)); - - auto running_challenge = FF(1); - auto output = FF(0); - Utils::scale_and_batch_elements(relation_evaluations, alpha, running_challenge, output); - return output; + auto instance_size = instance_polynomials[0].size(); + info(instance_size); + std::vector full_honk_evaluations(instance_size); + for (size_t row = 0; row < instance_size; row++) { + auto row_evaluations = get_execution_row(instance_polynomials, row); + RelationEvaluations relation_evaluations; + Utils::zero_elements(relation_evaluations); + + // Note that the evaluations are accumulated with the gate separation challenge being 1 at this stage, as + // this specific randomness is added later through the power polynomial univariate specific to ProtoGalaxy + Utils::template accumulate_relation_evaluations<>( + row_evaluations, relation_evaluations, relation_parameters, FF(1)); + + auto running_challenge = FF(1); + auto output = FF(0); + Utils::scale_and_batch_elements(relation_evaluations, alpha, running_challenge, output); + full_honk_evaluations[row] = output; + } + info("in compute"); + info(full_honk_evaluations); + return full_honk_evaluations; } - // Compute the parent nodes at the current level. Note that the resulting parent nodes will be polynomials of degree - // (level + 1) as at each level we multiply by an additional factor of X. + /** + * @brief Compute the parent nodes at the current level. Note that the resulting parent nodes will be polynomials + * degree (level + 1) as at each level we multiply by an additional factor of X. + */ static std::vector compute_level(size_t level, std::vector betas, std::vector deltas, @@ -129,21 +142,18 @@ template class ProtoGalaxyProver_ { return compute_level(1, betas, deltas, first_level_coeffs); } - // Compute the power perturbator polynomial F(X) in coefficient form + /** + * @brief Construct the power perturbator polynomial F(X) in coefficient form from the accumulator, represing the + * relaxed instance. + */ static Polynomial compute_perturbator(std::shared_ptr accumulator, std::vector deltas, FF alpha) { auto instance_size = accumulator->prover_polynomials[0].size(); auto const log_instance_size = static_cast(numeric::get_msb(instance_size)); assert(deltas.size() == log_instance_size); - - std::vector full_honk_evaluations(instance_size); - for (size_t idx = 0; idx < instance_size; idx++) { - - auto row_evaluations = get_execution_row(accumulator, idx); - auto full_honk_at_row = - compute_full_honk_relation_row_value(row_evaluations, alpha, accumulator->relation_parameters); - full_honk_evaluations[idx] = full_honk_at_row; - } + auto full_honk_evaluations = + compute_full_honk_evaluations(accumulator->prover_polynomials, alpha, accumulator->relation_parameters); + info(full_honk_evaluations); auto betas = accumulator->folding_params.gate_separation_challenges; assert(betas.size() == log_instance_size); auto coeffs = construct_perturbator_coeffs(betas, deltas, full_honk_evaluations); From dd258af6fcdd69391c440b444c840eccde4b07b4 Mon Sep 17 00:00:00 2001 From: maramihali Date: Sat, 7 Oct 2023 12:28:21 +0000 Subject: [PATCH 09/13] works --- .../honk/instance/prover_instance.hpp | 4 +- .../honk/proof_system/folding_result.hpp | 4 +- .../honk/proof_system/protogalaxy.test.cpp | 55 +++++++++---------- .../honk/proof_system/protogalaxy_prover.cpp | 4 +- .../honk/proof_system/protogalaxy_prover.hpp | 12 ++-- .../proof_system/protogalaxy_verifier.cpp | 4 +- 6 files changed, 40 insertions(+), 43 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.hpp b/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.hpp index 71eab4fca99..85836331169 100644 --- a/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.hpp @@ -42,7 +42,6 @@ template class ProverInstance_ { // non-zero for Instances constructed from circuits, this concept doesn't exist for accumulated // instances size_t pub_inputs_offset = 0; - // TODO: how do we fold relation parameters? proof_system::RelationParameters relation_parameters; std::vector recursive_proof_public_input_indices; // non-empty for the accumulated instances @@ -59,7 +58,8 @@ template class ProverInstance_ { : verification_key(std::move(result.verification_key)) , prover_polynomials(result.folded_prover_polynomials) , public_inputs(result.folded_public_inputs) - , folding_params(result.params){}; + , relation_parameters(result.folded_relation_parameters) + , folding_params(result.folding_parameters){}; ~ProverInstance_() = default; diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/folding_result.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/folding_result.hpp index 5448f97c2b2..6b67979eecf 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/folding_result.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/folding_result.hpp @@ -1,5 +1,6 @@ #pragma once #include "barretenberg/proof_system/flavor/flavor.hpp" +#include "barretenberg/proof_system/relations/relation_parameters.hpp" namespace proof_system::honk { template struct ProverFoldingResult { public: @@ -33,6 +34,7 @@ template struct FoldingResult { ProverPolynomials folded_prover_polynomials; std::vector folded_public_inputs; std::shared_ptr verification_key; - FoldingParameters params; + proof_system::RelationParameters folded_relation_parameters; + FoldingParameters folding_parameters; }; } // namespace proof_system::honk \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp index 6475477cd8d..7556e261821 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp @@ -18,7 +18,7 @@ namespace { auto& engine = numeric::random::get_debug_engine(); } -barretenberg::Polynomial random_poly(size_t size) +barretenberg::Polynomial get_random_polynomial(size_t size) { auto poly = barretenberg::Polynomial(size); for (auto& coeff : poly) { @@ -76,6 +76,7 @@ ProverPolynomials construct_ultra_full_polynomials(auto& input_polynomials) return full_polynomials; } + class ProtoGalaxyTests : public ::testing::Test { public: static void SetUpTestSuite() { barretenberg::srs::init_crs_factory("../srs_db/ignition"); } @@ -130,50 +131,48 @@ TEST_F(ProtoGalaxyTests, PowPerturbatorPolynomial) const size_t log_instance_size(3); const size_t instance_size(1 << log_instance_size); - // Randomly construct the prover polynomials that are input to Sumcheck. - // Note: ProverPolynomials are defined as spans so the polynomials they point to need to exist in memory. std::array, NUM_POLYNOMIALS> random_polynomials; for (auto& poly : random_polynomials) { - poly = random_poly(instance_size); + poly = get_random_polynomial(instance_size); } auto full_polynomials = construct_ultra_full_polynomials(random_polynomials); - proof_system::RelationParameters relation_parameters{ - .eta = FF::random_element(), - .beta = FF::random_element(), - .gamma = FF::random_element(), - .public_input_delta = FF::one(), - }; + auto relation_parameters = proof_system::RelationParameters::get_random(); auto alpha = FF::random_element(); + auto full_honk_evals = ProtoGalaxyProver::compute_full_honk_evaluations(full_polynomials, alpha, relation_parameters); - info(full_honk_evals); - std::vector betas = { FF(2), FF(4), FF(16) }; + std::vector betas(log_instance_size); + for (size_t idx = 0; idx < log_instance_size; idx++) { + betas[idx] = FF::random_element(); + } + + // Construct pow(\vec{betas}) manually as in the paper std::vector pow_beta(instance_size); for (size_t i = 0; i < instance_size; i++) { - auto j = i; - size_t idx = 0; auto res = FF(1); - while (j > 0) { + for (size_t j = i, beta_idx = 0; j > 0; j >>= 1, beta_idx++) { if ((j & 1) == 1) { - - res *= betas[idx]; + res *= betas[beta_idx]; } - j >>= 1; - idx++; } pow_beta[i] = res; } - info(pow_beta); - auto expected_target_sum = FF(0); + + // Compute the corresponding target sum and create a dummy accumulator + auto target_sum = FF(0); for (size_t i = 0; i < instance_size; i++) { - expected_target_sum += full_honk_evals[i] * pow_beta[i]; + target_sum += full_honk_evals[i] * pow_beta[i]; } - info(expected_target_sum); - auto folding_result = FoldingResult{ .folded_prover_polynomials = full_polynomials, - .params = { betas, expected_target_sum } }; - auto accumulator = std::make_shared(folding_result); - std::vector deltas = { FF(2), FF(4), FF(8) }; + + auto accumulator = + std::make_shared(FoldingResult{ .folded_prover_polynomials = full_polynomials, + .folded_relation_parameters = relation_parameters, + .folding_parameters = { betas, target_sum } }); + + auto deltas = ProtoGalaxyProver::compute_round_challenge_pows(log_instance_size, FF::random_element()); auto perturbator = ProtoGalaxyProver::compute_perturbator(accumulator, deltas, alpha); - info(perturbator); + + // Ensure the constant coefficient of the perturbator is equal to the target sum as indicated by the paper + EXPECT_EQ(perturbator[0], target_sum); } } // namespace protogalaxy_utils_tests \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp index e3558eedd97..37814d86d85 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp @@ -42,6 +42,7 @@ template ProverFoldingResult ProtoGalaxyProver_::fold_instances() { prepare_for_folding(); + // TODO(#740): Handle the case where we are folding for the first time and accumulator is 0 auto [alpha, delta] = transcript.get_challenges("alpha", "delta"); auto accumulator = get_accumulator(); auto instance_size = accumulator->prover_polynomials[0].size(); @@ -49,9 +50,6 @@ ProverFoldingResult ProtoGalaxyProver_ class ProtoGalaxyProver_ { RelationParameters relation_parameters) { auto instance_size = instance_polynomials[0].size(); - info(instance_size); + std::vector full_honk_evaluations(instance_size); for (size_t row = 0; row < instance_size; row++) { auto row_evaluations = get_execution_row(instance_polynomials, row); @@ -83,8 +83,6 @@ template class ProtoGalaxyProver_ { Utils::scale_and_batch_elements(relation_evaluations, alpha, running_challenge, output); full_honk_evaluations[row] = output; } - info("in compute"); - info(full_honk_evaluations); return full_honk_evaluations; } @@ -135,9 +133,9 @@ template class ProtoGalaxyProver_ { auto width = full_honk_evaluations.size(); std::vector> first_level_coeffs(width / 2, std::vector(2, 0)); for (size_t node = 0; node < width; node += 2) { - auto idx = node / 2; - first_level_coeffs[idx][0] = full_honk_evaluations[node] + full_honk_evaluations[node + 1] * betas[0]; - first_level_coeffs[idx][1] = full_honk_evaluations[node + 1] * deltas[0]; + auto parent = node / 2; + first_level_coeffs[parent][0] = full_honk_evaluations[node] + full_honk_evaluations[node + 1] * betas[0]; + first_level_coeffs[parent][1] = full_honk_evaluations[node + 1] * deltas[0]; } return compute_level(1, betas, deltas, first_level_coeffs); } @@ -153,7 +151,7 @@ template class ProtoGalaxyProver_ { assert(deltas.size() == log_instance_size); auto full_honk_evaluations = compute_full_honk_evaluations(accumulator->prover_polynomials, alpha, accumulator->relation_parameters); - info(full_honk_evaluations); + info("evals from compute", full_honk_evaluations); auto betas = accumulator->folding_params.gate_separation_challenges; assert(betas.size() == log_instance_size); auto coeffs = construct_perturbator_coeffs(betas, deltas, full_honk_evaluations); diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.cpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.cpp index db4383f2a42..049e11051c2 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.cpp @@ -35,9 +35,9 @@ VerifierFoldingResult ProtoGalaxyVerifier_< auto accumulator = get_accumulator(); auto log_instance_size = static_cast(numeric::get_msb(accumulator->instance_size)); auto deltas = compute_round_challenge_pows(log_instance_size, delta); - std::vector coeffs(log_instance_size + 1); + std::vector perturbator(log_instance_size + 1); for (size_t idx = 0; idx <= log_instance_size; idx++) { - coeffs[idx] = transcript.template receive_from_prover("perturbator_" + std::to_string(idx)); + perturbator[idx] = transcript.template receive_from_prover("perturbator_" + std::to_string(idx)); } // TODO(#690): implement the Protogalaxy verifier logic From bf18f8e6473f1e259be7424d641e434a2c53ce43 Mon Sep 17 00:00:00 2001 From: maramihali Date: Sat, 7 Oct 2023 12:36:14 +0000 Subject: [PATCH 10/13] link issues properly --- .../honk/proof_system/protogalaxy.test.cpp | 17 ++++++++++------- .../honk/proof_system/protogalaxy_prover.cpp | 5 +++-- .../honk/proof_system/protogalaxy_prover.hpp | 9 +++------ .../honk/proof_system/protogalaxy_verifier.cpp | 2 +- .../cpp/src/barretenberg/polynomials/pow.hpp | 1 - 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp index 7556e261821..dacd2da3070 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp @@ -13,11 +13,12 @@ using Builder = Flavor::CircuitBuilder; using ProverPolynomials = Flavor::ProverPolynomials; const size_t NUM_POLYNOMIALS = Flavor::NUM_ALL_ENTITIES; -namespace protogalaxy_utils_tests { +namespace protogalaxy_tests { namespace { auto& engine = numeric::random::get_debug_engine(); } - +// TODO(https://github.com/AztecProtocol/barretenberg/issues/744): make testing utility with functionality shared +// amongst test files in the proof system barretenberg::Polynomial get_random_polynomial(size_t size) { auto poly = barretenberg::Polynomial(size); @@ -164,10 +165,12 @@ TEST_F(ProtoGalaxyTests, PowPerturbatorPolynomial) target_sum += full_honk_evals[i] * pow_beta[i]; } - auto accumulator = - std::make_shared(FoldingResult{ .folded_prover_polynomials = full_polynomials, - .folded_relation_parameters = relation_parameters, - .folding_parameters = { betas, target_sum } }); + auto accumulator = std::make_shared( + FoldingResult{ .folded_prover_polynomials = full_polynomials, + .folded_public_inputs = std::vector{}, + .verification_key = std::make_shared(), + .folded_relation_parameters = relation_parameters, + .folding_parameters = { betas, target_sum } }); auto deltas = ProtoGalaxyProver::compute_round_challenge_pows(log_instance_size, FF::random_element()); auto perturbator = ProtoGalaxyProver::compute_perturbator(accumulator, deltas, alpha); @@ -175,4 +178,4 @@ TEST_F(ProtoGalaxyTests, PowPerturbatorPolynomial) // Ensure the constant coefficient of the perturbator is equal to the target sum as indicated by the paper EXPECT_EQ(perturbator[0], target_sum); } -} // namespace protogalaxy_utils_tests \ No newline at end of file +} // namespace protogalaxy_tests \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp index 37814d86d85..d14858bd80a 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp @@ -37,12 +37,13 @@ template void ProtoGalaxyProver_::prepa } } -// TODO(#689): finalise implementation this function +// TODO(#https://github.com/AztecProtocol/barretenberg/issues/689): finalise implementation this function template ProverFoldingResult ProtoGalaxyProver_::fold_instances() { prepare_for_folding(); - // TODO(#740): Handle the case where we are folding for the first time and accumulator is 0 + // TODO(#https://github.com/AztecProtocol/barretenberg/issues/740): Handle the case where we are folding for the + // first time and accumulator is 0 auto [alpha, delta] = transcript.get_challenges("alpha", "delta"); auto accumulator = get_accumulator(); auto instance_size = accumulator->prover_polynomials[0].size(); diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp index 54a7af56b37..95e36f65902 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp @@ -123,7 +123,8 @@ template class ProtoGalaxyProver_ { * the tree, label the branch connecting the left node n_l to its parent by 1 and for the right node n_r by β_i + * δ_i X. The value of the parent node n will be constructed as n = n_l + n_r * (β_i + δ_i X). Recurse over each * layer until the root is reached which will correspond to the perturbator polynomial F(X). - * TODO(insert issue): make this more memory efficient + * TODO(https://github.com/AztecProtocol/barretenberg/issues/745): make computation of perturbator more memory + * efficient */ static std::vector construct_perturbator_coeffs(std::vector betas, std::vector deltas, @@ -146,14 +147,10 @@ template class ProtoGalaxyProver_ { */ static Polynomial compute_perturbator(std::shared_ptr accumulator, std::vector deltas, FF alpha) { - auto instance_size = accumulator->prover_polynomials[0].size(); - auto const log_instance_size = static_cast(numeric::get_msb(instance_size)); - assert(deltas.size() == log_instance_size); auto full_honk_evaluations = compute_full_honk_evaluations(accumulator->prover_polynomials, alpha, accumulator->relation_parameters); - info("evals from compute", full_honk_evaluations); auto betas = accumulator->folding_params.gate_separation_challenges; - assert(betas.size() == log_instance_size); + assert(betas.size() == deltas.size()); auto coeffs = construct_perturbator_coeffs(betas, deltas, full_honk_evaluations); return Polynomial(coeffs); } diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.cpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.cpp index 049e11051c2..b04cd7ad7d4 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.cpp @@ -40,7 +40,7 @@ VerifierFoldingResult ProtoGalaxyVerifier_< perturbator[idx] = transcript.template receive_from_prover("perturbator_" + std::to_string(idx)); } - // TODO(#690): implement the Protogalaxy verifier logic + // TODO(https://github.com/AztecProtocol/barretenberg/issues/690): finalise the Protogalaxy verifier logic VerifierFoldingResult res; return res; } diff --git a/barretenberg/cpp/src/barretenberg/polynomials/pow.hpp b/barretenberg/cpp/src/barretenberg/polynomials/pow.hpp index 77a0a53030f..9039266cac0 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/pow.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/pow.hpp @@ -90,7 +90,6 @@ namespace barretenberg { * = pow(u_{0}, ..., u_{d-1}) // Full evaluation of pow * - σ_{ d } =?= c_{d}⋅P(u_{0}, ..., u_{d-1}) // Compare against real evaluation of P'(u) */ -// this can be used to compute deltas for each round as it is template struct PowUnivariate { // ζ_{l}, initialized as ζ_{0} = ζ // At round l, equals ζ^{ 2^l } From be146f79f69ff34a89dba49a6492bd509afab0f6 Mon Sep 17 00:00:00 2001 From: maramihali Date: Mon, 16 Oct 2023 14:33:48 +0000 Subject: [PATCH 11/13] fix review comments --- .../src/barretenberg/honk/flavor/ultra.hpp | 2 - .../honk/instance/prover_instance.hpp | 1 - .../honk/proof_system/folding_result.hpp | 1 - .../honk/proof_system/protogalaxy.test.cpp | 4 +- .../honk/proof_system/protogalaxy_prover.cpp | 2 + .../honk/proof_system/protogalaxy_prover.hpp | 39 ++++++++++--------- 6 files changed, 25 insertions(+), 24 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/flavor/ultra.hpp b/barretenberg/cpp/src/barretenberg/honk/flavor/ultra.hpp index 7330662bc85..d41b8772d1f 100644 --- a/barretenberg/cpp/src/barretenberg/honk/flavor/ultra.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/flavor/ultra.hpp @@ -404,8 +404,6 @@ class Ultra { class FoldingParameters { public: - // we need this because the nice relation between deltas does not apply to beta as well - // these are the betas std::vector gate_separation_challenges; FF target_sum; }; diff --git a/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.hpp b/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.hpp index 0edfc45ff6c..483ddeba6ea 100644 --- a/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.hpp @@ -57,7 +57,6 @@ template class ProverInstance_ { : verification_key(std::move(result.verification_key)) , prover_polynomials(result.folded_prover_polynomials) , public_inputs(result.folded_public_inputs) - , relation_parameters(result.folded_relation_parameters) , folding_parameters(result.folding_parameters){}; ~ProverInstance_() = default; diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/folding_result.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/folding_result.hpp index 6b67979eecf..5888d866b04 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/folding_result.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/folding_result.hpp @@ -34,7 +34,6 @@ template struct FoldingResult { ProverPolynomials folded_prover_polynomials; std::vector folded_public_inputs; std::shared_ptr verification_key; - proof_system::RelationParameters folded_relation_parameters; FoldingParameters folding_parameters; }; } // namespace proof_system::honk \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp index dacd2da3070..8c35ce4d40b 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp @@ -119,7 +119,7 @@ TEST_F(ProtoGalaxyTests, PerturbatorCoefficients) std::vector betas = { FF(5), FF(8), FF(11) }; std::vector deltas = { FF(2), FF(4), FF(8) }; std::vector full_honk_evaluations = { FF(1), FF(1), FF(1), FF(1), FF(1), FF(1), FF(1), FF(1) }; - auto perturbator = ProtoGalaxyProver::construct_perturbator_coeffs(betas, deltas, full_honk_evaluations); + auto perturbator = ProtoGalaxyProver::construct_perturbator_coefficients(betas, deltas, full_honk_evaluations); std::vector expected_values = { FF(648), FF(936), FF(432), FF(64) }; EXPECT_EQ(perturbator.size(), 4); // log(instance_size) + 1 for (size_t i = 0; i < perturbator.size(); i++) { @@ -169,8 +169,8 @@ TEST_F(ProtoGalaxyTests, PowPerturbatorPolynomial) FoldingResult{ .folded_prover_polynomials = full_polynomials, .folded_public_inputs = std::vector{}, .verification_key = std::make_shared(), - .folded_relation_parameters = relation_parameters, .folding_parameters = { betas, target_sum } }); + accumulator->relation_parameters = relation_parameters; auto deltas = ProtoGalaxyProver::compute_round_challenge_pows(log_instance_size, FF::random_element()); auto perturbator = ProtoGalaxyProver::compute_perturbator(accumulator, deltas, alpha); diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp index ceea8fc7863..913b4868d73 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp @@ -24,6 +24,8 @@ template void ProtoGalaxyProver_::prepa transcript.send_to_verifier(domain_separator + "_public_input_" + std::to_string(i), public_input_i); } + // TODO(https://github.com/AztecProtocol/barretenberg/issues/752): establish whether we can use the same grand + // product parameters for all instances securely auto [eta, beta, gamma] = transcript.get_challenges( domain_separator + "_eta", domain_separator + "_beta", domain_separator + "_gamma"); instance->compute_sorted_accumulator_polynomials(eta); diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp index 7dc2f192a33..7533b73f408 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp @@ -14,7 +14,7 @@ template class ProtoGalaxyProver_ { using RowEvaluations = typename Flavor::AllValues; using ProverPolynomials = typename Flavor::ProverPolynomials; using FF = typename Flavor::FF; - using TupleOfArraysOfValues = typename Flavor::TupleOfArraysOfValues; + using RelationEvaluations = typename Flavor::TupleOfArraysOfValues; ProverInstances instances; ProverTranscript transcript; @@ -57,7 +57,7 @@ template class ProtoGalaxyProver_ { * each subrelation is independently valid in Honk - from the Plonk paper, DO NOT confuse with α in ProtoGalaxy), */ static std::vector compute_full_honk_evaluations(ProverPolynomials instance_polynomials, - FF alpha, + const FF alpha, RelationParameters relation_parameters) { auto instance_size = instance_polynomials[0].size(); @@ -65,7 +65,7 @@ template class ProtoGalaxyProver_ { std::vector full_honk_evaluations(instance_size); for (size_t row = 0; row < instance_size; row++) { auto row_evaluations = instance_polynomials.get_row(row); - TupleOfArraysOfValues relation_evaluations; + RelationEvaluations relation_evaluations; Utils::zero_elements(relation_evaluations); // Note that the evaluations are accumulated with the gate separation challenge being 1 at this stage, as @@ -86,10 +86,10 @@ template class ProtoGalaxyProver_ { * level, the resulting parent nodes will be polynomials of degree (level + 1) because we multiply by an additional * factor of X. */ - static std::vector compute_coefficients_tree(size_t level, - std::vector betas, - std::vector deltas, - std::vector> prev_level_coeffs) + static std::vector compute_coefficients_tree(const std::vector& betas, + const std::vector& deltas, + const std::vector>& prev_level_coeffs, + size_t level = 1) { // if we are at level t in the tree, where t = logn and n is the instance size, we have reached the root which // contains the coefficients of the perturbator polynomial @@ -109,7 +109,7 @@ template class ProtoGalaxyProver_ { level_coeffs[parent][d + 1] += prev_level_coeffs[node + 1][d] * deltas[level]; } } - return compute_coefficients_tree(level + 1, betas, deltas, level_coeffs); + return compute_coefficients_tree(betas, deltas, level_coeffs, level + 1); } /** @@ -120,13 +120,12 @@ template class ProtoGalaxyProver_ { * δ_i X. The value of the parent node n will be constructed as n = n_l + n_r * (β_i + δ_i X). Recurse over each * layer until the root is reached which will correspond to the perturbator polynomial F(X). * TODO(https://github.com/AztecProtocol/barretenberg/issues/745): make computation of perturbator more memory - * efficient + * efficient, potentially use std::resize and add multithreading */ - static std::vector construct_perturbator_coeffs(std::vector betas, - std::vector deltas, - std::vector full_honk_evaluations) + static std::vector construct_perturbator_coefficients(const std::vector& betas, + const std::vector& deltas, + const std::vector& full_honk_evaluations) { - auto width = full_honk_evaluations.size(); std::vector> first_level_coeffs(width >> 1, std::vector(2, 0)); for (size_t node = 0; node < width; node += 2) { @@ -134,20 +133,24 @@ template class ProtoGalaxyProver_ { first_level_coeffs[parent][0] = full_honk_evaluations[node] + full_honk_evaluations[node + 1] * betas[0]; first_level_coeffs[parent][1] = full_honk_evaluations[node + 1] * deltas[0]; } - return compute_coefficients_tree(1, betas, deltas, first_level_coeffs); + return compute_coefficients_tree(betas, deltas, first_level_coeffs); } /** - * @brief Construct the power perturbator polynomial F(X) in coefficient form from the accumulator, represing the + * @brief Construct the power perturbator polynomial F(X) in coefficient form from the accumulator, representing the * relaxed instance. + * + * */ - static Polynomial compute_perturbator(std::shared_ptr accumulator, std::vector deltas, FF alpha) + static Polynomial compute_perturbator(const std::shared_ptr accumulator, + const std::vector& deltas, + const FF alpha) { auto full_honk_evaluations = compute_full_honk_evaluations(accumulator->prover_polynomials, alpha, accumulator->relation_parameters); - auto betas = accumulator->folding_parameters.gate_separation_challenges; + const auto betas = accumulator->folding_parameters.gate_separation_challenges; assert(betas.size() == deltas.size()); - auto coeffs = construct_perturbator_coeffs(betas, deltas, full_honk_evaluations); + auto coeffs = construct_perturbator_coefficients(betas, deltas, full_honk_evaluations); return Polynomial(coeffs); } From 7ab3a50d5d2fbf8e17273268948b6d5c347c876f Mon Sep 17 00:00:00 2001 From: maramihali Date: Tue, 17 Oct 2023 14:21:29 +0000 Subject: [PATCH 12/13] naming fix --- .../honk/proof_system/protogalaxy_prover.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp index b54c0e3b559..39e2e99287d 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp @@ -86,10 +86,10 @@ template class ProtoGalaxyProver_ { * level, the resulting parent nodes will be polynomials of degree (level + 1) because we multiply by an additional * factor of X. */ - static std::vector compute_coefficients_tree(const std::vector& betas, - const std::vector& deltas, - const std::vector>& prev_level_coeffs, - size_t level = 1) + static std::vector construct_coefficients_tree(const std::vector& betas, + const std::vector& deltas, + const std::vector>& prev_level_coeffs, + size_t level = 1) { // if we are at level t in the tree, where t = logn and n is the instance size, we have reached the root which // contains the coefficients of the perturbator polynomial @@ -109,7 +109,7 @@ template class ProtoGalaxyProver_ { level_coeffs[parent][d + 1] += prev_level_coeffs[node + 1][d] * deltas[level]; } } - return compute_coefficients_tree(betas, deltas, level_coeffs, level + 1); + return construct_coefficients_tree(betas, deltas, level_coeffs, level + 1); } /** @@ -133,7 +133,7 @@ template class ProtoGalaxyProver_ { first_level_coeffs[parent][0] = full_honk_evaluations[node] + full_honk_evaluations[node + 1] * betas[0]; first_level_coeffs[parent][1] = full_honk_evaluations[node + 1] * deltas[0]; } - return compute_coefficients_tree(betas, deltas, first_level_coeffs); + return construct_coefficients_tree(betas, deltas, first_level_coeffs); } /** From d7e9ee757b247664546329eddcf6c88150a6a239 Mon Sep 17 00:00:00 2001 From: codygunton Date: Tue, 17 Oct 2023 16:08:37 +0000 Subject: [PATCH 13/13] More const& --- .../cpp/src/barretenberg/honk/flavor/ecc_vm.hpp | 2 +- .../src/barretenberg/honk/flavor/goblin_ultra.hpp | 2 +- .../cpp/src/barretenberg/honk/flavor/ultra.hpp | 2 +- .../honk/proof_system/protogalaxy_prover.hpp | 12 ++++++------ 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/flavor/ecc_vm.hpp b/barretenberg/cpp/src/barretenberg/honk/flavor/ecc_vm.hpp index 11f1eb64d1f..e04f31be3df 100644 --- a/barretenberg/cpp/src/barretenberg/honk/flavor/ecc_vm.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/flavor/ecc_vm.hpp @@ -679,7 +679,7 @@ template class ECCVMBa */ class AllPolynomials : public AllEntities { public: - AllValues get_row(const size_t row_idx) + AllValues get_row(const size_t row_idx) const { AllValues result; size_t column_idx = 0; // // TODO(https://github.com/AztecProtocol/barretenberg/issues/391) zip diff --git a/barretenberg/cpp/src/barretenberg/honk/flavor/goblin_ultra.hpp b/barretenberg/cpp/src/barretenberg/honk/flavor/goblin_ultra.hpp index df9ba6b7aba..8a2c272322c 100644 --- a/barretenberg/cpp/src/barretenberg/honk/flavor/goblin_ultra.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/flavor/goblin_ultra.hpp @@ -342,7 +342,7 @@ class GoblinUltra { */ class ProverPolynomials : public AllEntities { public: - AllValues get_row(const size_t row_idx) + AllValues get_row(const size_t row_idx) const { AllValues result; size_t column_idx = 0; // TODO(https://github.com/AztecProtocol/barretenberg/issues/391) zip diff --git a/barretenberg/cpp/src/barretenberg/honk/flavor/ultra.hpp b/barretenberg/cpp/src/barretenberg/honk/flavor/ultra.hpp index 9ab8206cf6d..c319e38e7f2 100644 --- a/barretenberg/cpp/src/barretenberg/honk/flavor/ultra.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/flavor/ultra.hpp @@ -287,7 +287,7 @@ class Ultra { */ class ProverPolynomials : public AllEntities { public: - AllValues get_row(const size_t row_idx) + AllValues get_row(const size_t row_idx) const { AllValues result; size_t column_idx = 0; // TODO(https://github.com/AztecProtocol/barretenberg/issues/391) zip diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp index 39e2e99287d..57c6c9b822c 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp @@ -35,7 +35,7 @@ template class ProtoGalaxyProver_ { * @brief For a new round challenge δ at each iteration of the ProtoGalaxy protocol, compute the vector * [δ, δ^2,..., δ^t] where t = logn and n is the size of the instance. */ - static std::vector compute_round_challenge_pows(const size_t log_instance_size, const FF round_challenge) + static std::vector compute_round_challenge_pows(const size_t log_instance_size, const FF& round_challenge) { std::vector pows(log_instance_size); pows[0] = round_challenge; @@ -56,11 +56,11 @@ template class ProtoGalaxyProver_ { * ProtoGalaxy paper, given the evaluations of all the prover polynomials and α (the parameter that helps establish * each subrelation is independently valid in Honk - from the Plonk paper, DO NOT confuse with α in ProtoGalaxy), */ - static std::vector compute_full_honk_evaluations(ProverPolynomials instance_polynomials, - const FF alpha, - RelationParameters relation_parameters) + static std::vector compute_full_honk_evaluations(const ProverPolynomials& instance_polynomials, + const FF& alpha, + const RelationParameters& relation_parameters) { - auto instance_size = instance_polynomials[0].size(); + auto instance_size = std::get<0>(instance_polynomials._data).size(); std::vector full_honk_evaluations(instance_size); for (size_t row = 0; row < instance_size; row++) { @@ -144,7 +144,7 @@ template class ProtoGalaxyProver_ { */ static Polynomial compute_perturbator(const std::shared_ptr accumulator, const std::vector& deltas, - const FF alpha) + const FF& alpha) { auto full_honk_evaluations = compute_full_honk_evaluations(accumulator->prover_polynomials, alpha, accumulator->relation_parameters);