From 6313f15079cbcf84aa2853c462ecb3f00e44d37d Mon Sep 17 00:00:00 2001 From: maramihali Date: Mon, 23 Oct 2023 14:47:27 +0000 Subject: [PATCH 01/86] wip wip wip --- .../honk/proof_system/protogalaxy_prover.cpp | 37 +++++++++++++- .../honk/proof_system/protogalaxy_prover.hpp | 37 ++++++++++---- .../proof_system/protogalaxy_verifier.cpp | 51 +++++++++++++++++-- .../proof_system/flavor/flavor.hpp | 2 +- 4 files changed, 111 insertions(+), 16 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 913b4868d73..82898134467 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp @@ -31,6 +31,7 @@ template void ProtoGalaxyProver_::prepa instance->compute_sorted_accumulator_polynomials(eta); instance->compute_grand_product_polynomials(beta, gamma); } + // need to check all instances have the same circuit size!! } // TODO(#https://github.com/AztecProtocol/barretenberg/issues/689): finalise implementation this function @@ -46,11 +47,45 @@ 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[0] == accumulator->folding_parameters->target_sum); for (size_t idx = 0; idx <= log_instance_size; idx++) { transcript.send_to_verifier("perturbator_" + std::to_string(idx), perturbator[idx]); } + auto perturbator_challenge = transcript.get_challenge("perturbator_challenge"); + auto compressed_perturbator = perturbator.evaluate(perturbator_challenge); // horner + static_cast(compressed_perturbator); + + std::vector lagrange_first(log_instance_size, FF(0)); + lagrange_first[0] = FF(1); + + std::vector vanishing_set; + vanishing_set.reserve(log_instance_size); + std::iota(vanishing_set.begin(), vanishing_set.end(), FF::zero()); + // need to be built not on the vanishing set H!!!!! + + // sanity check: i think we don't care about elemnt 0th element of beta, it is 1 + std::vector betas_star(log_instance_size); + betas_star[0] = 1; + auto betas = accumulator->folding_parameters.gate_separation_challenges; + for (size_t idx = 1; idx <= log_instance_size; idx++) { + betas_star[idx] = betas[idx] + perturbator_challenge * deltas[idx - 1]; + } + + auto pow_betas_star = compute_pow_polynomials_at_values(betas_star, instance_size); + + // compute pow, work around combiner problems + + // compute \vec{\beta*} + // sanity check this is correc + + // auto combiner = compute_combiner(instances, accumulator->relation_parameters, const PowUnivariate &pow_univariate, alpha) + + // auto vanishing_polynomial_at_challenge = combiner_challenge * (combiner_challenge - FF(1)); + // auto lagrange_0_at_challenge = FF(1) - combiner_challenge; + // auto lagrange_1_at_challenge = combiner_challenge; + 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 a5ae4cd5506..c9d601476ca 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp @@ -24,6 +24,7 @@ template class ProtoGalaxyProver_ { using Relations = typename Flavor::Relations; using BaseUnivariate = Univariate; using ExtendedUnivariate = Univariate; + // ProverInstances::NUM containts the accumulator as well hence the -1 using RandomExtendedUnivariate = Univariate; using ExtendedUnivariates = typename Flavor::template ProverUnivariates; @@ -47,6 +48,21 @@ template class ProtoGalaxyProver_ { */ void prepare_for_folding(); + std::vector compute_pow_polynomials_at_values(const std::vector betas, const size_t instance_size) + { + std::vector pow_betas(instance_size); + for (size_t i = 0; i < instance_size; i++) { + auto res = FF(1); + for (size_t j = i, beta_idx = 0; j > 0; j >>= 1, beta_idx++) { + if ((j & 1) == 1) { + res *= betas[beta_idx]; + } + } + pow_betas[i] = res; + } + return pow_betas; + } + /** * @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. @@ -214,21 +230,20 @@ template class ProtoGalaxyProver_ { * * @todo TODO(https://github.com/AztecProtocol/barretenberg/issues/754) Provide the right challenge to here */ - RandomExtendedUnivariate compute_combiner( - const ProverInstances& instances, - const proof_system::RelationParameters& relation_parameters, - const PowUnivariate& pow_univariate, - const typename Flavor::FF alpha) + RandomExtendedUnivariate compute_combiner(const ProverInstances& instances, + const proof_system::RelationParameters& relation_parameters, + const std::vector pow_betas_star, + const FF alpha) { size_t common_circuit_size = instances[0]->prover_polynomials._data[0].size(); // Precompute the vector of required powers of zeta // TODO(https://github.com/AztecProtocol/barretenberg/issues/751): Parallelize this. // NB: there is a similar TODO in the sumcheck function `compute_univariate`. - std::vector pow_challenges(common_circuit_size); - pow_challenges[0] = pow_univariate.partial_evaluation_constant; - for (size_t i = 1; i < common_circuit_size; ++i) { - pow_challenges[i] = pow_challenges[i - 1] * pow_univariate.zeta_pow; - } + // std::vector pow_challenges(common_circuit_size); + // pow_challenges[0] = pow_univariate.partial_evaluation_constant; + // for (size_t i = 1; i < common_circuit_size; ++i) { + // pow_challenges[i] = pow_challenges[i - 1] * pow_univariate.zeta_pow; + // } // Determine number of threads for multithreading. // Note: Multithreading is "on" for every round but we reduce the number of threads from the max available based @@ -259,7 +274,7 @@ template class ProtoGalaxyProver_ { for (size_t idx = start; idx < end; idx++) { extend_univariates(extended_univariates[thread_idx], instances, idx); - FF pow_challenge = pow_challenges[idx]; + FF pow_challenge = pow_betas_star[idx]; // Accumulate the i-th row's univariate contribution accumulate_relation_univariates(thread_univariate_accumulators[thread_idx], 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 57397318541..921fe323de1 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.cpp @@ -5,6 +5,9 @@ template VerifierFoldingResult ProtoGalaxyVerifier_< VerifierInstances>::fold_public_parameters(std::vector fold_data) { + using Flavor = typename VerifierInstances::Flavor; + using VerificationKey = typename Flavor::VerificationKey; + transcript = VerifierTranscript{ fold_data }; auto index = 0; for (auto it = verifier_instances.begin(); it != verifier_instances.end(); it++, index++) { @@ -35,13 +38,55 @@ 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 perturbator(log_instance_size + 1); + std::vector perturbator_coeffs(log_instance_size + 1); for (size_t idx = 0; idx <= log_instance_size; idx++) { - perturbator[idx] = transcript.template receive_from_prover("perturbator_" + std::to_string(idx)); + perturbator_coeffs[idx] = transcript.template receive_from_prover("perturbator_" + std::to_string(idx)); + } + assert(perturbator_coeffs[0] == accumulator->folding_parameters->target_sum); + auto perturbator = Polynomial(perturbator_coeffs); + auto perturbator_challenge = transcript.get_challenge("perturbator_challenge"); + auto perturbator_at_challenge = perturbator.evaluate(perturbator_challenge); // horner + static_cast(perturbator_at_challenge); + // get the coefficient of combiner quotient (K(X) polynomial in the paper) + // + 2 because we need one extra eval to rep a poly of certain degree + auto combiner_quotient_size = Flavor::MAX_RANDOM_RELATION_LENGTH * (VerifierInstances::NUM - 1) + 2; + std::vector combiner_quotient_coeffs(combiner_quotient_size); + for (size_t idx = 0; idx < combiner_quotient_size; idx++) { + combiner_quotient_coeffs[idx] = + transcript.template receive_from_prover("combiner_quotient_idx" + std::to_string(idx)); + } + auto combiner_quotient = Polynomial(combiner_quotient_coeffs); + auto combiner_challenge = transcript.get_challenge("degree_reduction"); + static_cast(combiner_challenge); + + // fix k = 1 which means k+1 = 2 is a power of two + auto combiner_quotient_at_challenge = combiner_quotient.evaluate(combiner_challenge); // K(\gamma) + auto vanishing_polynomial_at_challenge = combiner_challenge * (combiner_challenge - FF(1)); + auto lagrange_0_at_challenge = FF(1) - combiner_challenge; + auto lagrange_1_at_challenge = combiner_challenge; + auto updated_target_sum = perturbator_at_challenge * lagrange_0_at_challenge + + vanishing_polynomial_at_challenge * combiner_quotient_at_challenge; + + // do public input stuff with goblin (well I guess first without) + // fold public inputs (field elements) and the commitment in verification key to obtain a new verification key! + // TODO: extend for more instances; + auto accumulator_public_inputs = accumulator->public_inputs; + auto other_public_inputs = verifier_instances[1]->public_inputs; + std::vector folded_public_inputs(accumulator->public_input_size); + // extend either with 0s if the sizes are different + for (size_t idx = 0; idx < folded_public_inputs.size(); idx++) { + folded_public_inputs[idx] = lagrange_0_at_challenge * accumulator->public_inputs[idx] + + lagrange_1_at_challenge * other_public_inputs[idx]; } + // all verification keys have the same size + auto folded_verification_key = VerificationKey(accumulator->instance_size, accumulator->public_input_size); - // TODO(https://github.com/AztecProtocol/barretenberg/issues/690): finalise the Protogalaxy verifier logic + for (size_t idx = 0; idx < folded_verification_key.size(); idx++) { + folded_verification_key[idx] = (*accumulator->verification_key)[idx] * lagrange_0_at_challenge + + (*verifier_instances[1]->verification_key)[idx] * lagrange_1_at_challenge; + } VerifierFoldingResult res; + res.parameters.target_sum = updated_target_sum; return res; } diff --git a/barretenberg/cpp/src/barretenberg/proof_system/flavor/flavor.hpp b/barretenberg/cpp/src/barretenberg/proof_system/flavor/flavor.hpp index 9db88b2c41f..9ca7577bc02 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/flavor/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/flavor/flavor.hpp @@ -15,7 +15,7 @@ * relationships between these. We aim for a more uniform treatment, to enfore identical and informative naming, and to * prevent the developer having to think very much about the ordering of protocol entities in disparate places. * - * Another motivation is iterate on the polynomial manifest of plonk, which is nice in its compatness, but which feels + * Another motivation is iterate on the polynomial manifest of plonk, which is nice in its compactness, but which feels * needlessly manual and low-level. In the past, this contained even more boolean parameters, making it quite hard to * parse. A typical construction is to loop over the polynomial manifest by extracting a globally-defined * "FOO_MANIFEST_SIZE" (the use of "manifest" here is distinct from the manifests in the transcript) to loop From 40cedd0705c75cb374d886898c6d6bcecb0cd488 Mon Sep 17 00:00:00 2001 From: maramihali Date: Tue, 24 Oct 2023 11:17:12 +0000 Subject: [PATCH 02/86] styuff --- .../honk/proof_system/protogalaxy_prover.cpp | 3 +-- .../honk/proof_system/protogalaxy_prover.hpp | 2 +- .../src/barretenberg/honk/sumcheck/sumcheck_round.hpp | 2 +- .../barretenberg/honk/sumcheck/sumcheck_round.test.cpp | 2 +- .../src/barretenberg/proof_system/relations/utils.hpp | 9 +++++---- 5 files changed, 9 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 82898134467..049331affb2 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp @@ -79,8 +79,7 @@ ProverFoldingResult ProtoGalaxyProver_relation_parameters, const PowUnivariate &pow_univariate, alpha) + auto combiner = compute_combiner(instances, accumulator->relation_parameters, pow_betas_star, alpha); // auto vanishing_polynomial_at_challenge = combiner_challenge * (combiner_challenge - FF(1)); // auto lagrange_0_at_challenge = FF(1) - combiner_challenge; 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 c9d601476ca..fe5757c3fcd 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp @@ -290,7 +290,7 @@ template class ProtoGalaxyProver_ { } // Batch the univariate contributions from each sub-relation to obtain the round univariate return Utils::template batch_over_relations( - univariate_accumulators, alpha, pow_univariate); + univariate_accumulators, alpha, FF(1)); // not sure what this should be, should it be 1????? } }; diff --git a/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.hpp b/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.hpp index c03d0968129..1a0bbbfefe5 100644 --- a/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.hpp @@ -166,7 +166,7 @@ template class SumcheckProverRound { } // Batch the univariate contributions from each sub-relation to obtain the round univariate return Utils::template batch_over_relations>( - univariate_accumulators, alpha, pow_univariate); + univariate_accumulators, alpha, pow_univariate.zeta_pow); } private: 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 2b4b4cb4c48..231b1c97f53 100644 --- a/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.test.cpp @@ -43,7 +43,7 @@ TEST(SumcheckRound, SumcheckTupleOfTuplesOfUnivariates) // Use extend_and_batch_univariates to extend to MAX_LENGTH then accumulate PowUnivariate pow_univariate(1); auto result = Univariate(); - Utils::extend_and_batch_univariates(tuple_of_tuples, pow_univariate, result); + Utils::extend_and_batch_univariates(tuple_of_tuples, pow_univariate.zeta_pow, result); // Repeat the batching process manually auto result_expected = univariate_1.template extend_to() * 1 + diff --git a/barretenberg/cpp/src/barretenberg/proof_system/relations/utils.hpp b/barretenberg/cpp/src/barretenberg/proof_system/relations/utils.hpp index eb4fb3a56af..f040d02872f 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/relations/utils.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/relations/utils.hpp @@ -123,11 +123,11 @@ template class RelationUtils { */ template static void extend_and_batch_univariates(const OfTuplesOfUnivariates& tuple, - const PowUnivariate& pow_univariate, + const FF zeta, ExtendedUnivariate& result) { // Random poly R(X) = (1-X) + X.zeta_pow - auto random_polynomial = Univariate({ 1, pow_univariate.zeta_pow }); + auto random_polynomial = Univariate({ 1, zeta }); auto extended_random_polynomial = random_polynomial.template extend_to(); auto extend_and_sum = [&](Element& element) { @@ -141,6 +141,7 @@ template class RelationUtils { result += extended * extended_random_polynomial; } else { // if subrelation is pure sum over hypercube, don't multiply by random polynomial + // make these comments more relevant result += extended; } }; @@ -154,13 +155,13 @@ template class RelationUtils { template static ExtendedUnivariate batch_over_relations(ContainerOverSubrelations& univariate_accumulators, const FF& challenge, - const PowUnivariate& pow_univariate) + const FF& zeta) { FF running_challenge = 1; scale_univariates(univariate_accumulators, challenge, running_challenge); auto result = ExtendedUnivariate(0); - extend_and_batch_univariates(univariate_accumulators, pow_univariate, result); + extend_and_batch_univariates(univariate_accumulators, zeta, result); // Reset all univariate accumulators to 0 before beginning accumulation in the next round zero_univariates(univariate_accumulators); From c7cc93602cc4e59011955875f8dcea7535e58313 Mon Sep 17 00:00:00 2001 From: maramihali Date: Tue, 24 Oct 2023 18:07:46 +0000 Subject: [PATCH 03/86] how do I do this? --- .../honk/proof_system/combiner.test.cpp | 378 +++++++++--------- .../honk/proof_system/protogalaxy_prover.cpp | 60 ++- .../honk/proof_system/protogalaxy_prover.hpp | 3 +- .../proof_system/protogalaxy_verifier.cpp | 4 +- .../honk/sumcheck/sumcheck_round.hpp | 2 +- .../honk/sumcheck/sumcheck_round.test.cpp | 2 +- .../barretenberg/polynomials/univariate.hpp | 1 + .../proof_system/relations/utils.hpp | 30 +- 8 files changed, 256 insertions(+), 224 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/combiner.test.cpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/combiner.test.cpp index 328045b335f..5733c79e6da 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/combiner.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/combiner.test.cpp @@ -1,189 +1,189 @@ -#include "barretenberg/honk/flavor/ultra.hpp" -#include "barretenberg/honk/instance/instances.hpp" -#include "barretenberg/honk/proof_system/protogalaxy_prover.hpp" -#include "barretenberg/honk/utils/testing.hpp" -#include "barretenberg/proof_system/relations/relation_parameters.hpp" -#include - -using namespace proof_system::honk; -namespace barretenberg::test_protogalaxy_prover { -using Flavor = proof_system::honk::flavor::Ultra; -using Polynomial = typename Flavor::Polynomial; -using FF = typename Flavor::FF; -using RelationParameters = proof_system::RelationParameters; - -TEST(Protogalaxy, CombinerOn2Instances) -{ - constexpr size_t NUM_INSTANCES = 2; - using ProverInstance = ProverInstance_; - using ProverInstances = ProverInstances_; - using ProtoGalaxyProver = ProtoGalaxyProver_; - - const auto restrict_to_standard_arithmetic_relation = [](auto& polys) { - std::fill(polys.q_arith.begin(), polys.q_arith.end(), 1); - std::fill(polys.q_sort.begin(), polys.q_sort.end(), 0); - std::fill(polys.q_elliptic.begin(), polys.q_elliptic.end(), 0); - std::fill(polys.q_aux.begin(), polys.q_aux.end(), 0); - std::fill(polys.q_lookup.begin(), polys.q_lookup.end(), 0); - std::fill(polys.q_4.begin(), polys.q_4.end(), 0); - std::fill(polys.w_4.begin(), polys.w_4.end(), 0); - std::fill(polys.w_4_shift.begin(), polys.w_4_shift.end(), 0); - }; - - auto run_test = [&](bool is_random_input) { - if (is_random_input) { - std::vector> instance_data(NUM_INSTANCES); - std::array, NUM_INSTANCES> storage_arrays; - auto relation_parameters = RelationParameters::get_random(); - ProtoGalaxyProver prover; - auto pow_univariate = PowUnivariate(/*zeta_pow=*/2); - auto alpha = FF(0); // focus on the arithmetic relation only - - for (size_t idx = 0; idx < NUM_INSTANCES; idx++) { - auto instance = std::make_shared(); - auto [storage, prover_polynomials] = proof_system::honk::get_sequential_prover_polynomials( - /*log_circuit_size=*/1, idx * 128); - restrict_to_standard_arithmetic_relation(prover_polynomials); - storage_arrays[idx] = std::move(storage); - instance->prover_polynomials = prover_polynomials; - instance_data[idx] = instance; - } - - ProverInstances instances{ instance_data }; - - auto result = prover.compute_combiner(instances, relation_parameters, pow_univariate, alpha); - auto expected_result = - barretenberg::Univariate(std::array{ 87706, - 27289140, - 229355214, - 905031784, - static_cast(2504059650), - static_cast(5627174556), - static_cast(11026107190) }); - - EXPECT_EQ(result, expected_result); - } else { - std::vector> instance_data(NUM_INSTANCES); - std::array, NUM_INSTANCES> storage_arrays; - auto relation_parameters = RelationParameters::get_random(); - ProtoGalaxyProver prover; - auto pow_univariate = PowUnivariate(/*zeta_pow=*/2); - auto alpha = FF(0); // focus on the arithmetic relation only - - for (size_t idx = 0; idx < NUM_INSTANCES; idx++) { - auto instance = std::make_shared(); - auto [storage, prover_polynomials] = proof_system::honk::get_zero_prover_polynomials( - /*log_circuit_size=*/1); - restrict_to_standard_arithmetic_relation(prover_polynomials); - storage_arrays[idx] = std::move(storage); - instance->prover_polynomials = prover_polynomials; - instance_data[idx] = instance; - } - - ProverInstances instances{ instance_data }; - - const auto create_add_gate = [](auto& polys, const size_t idx, FF w_l, FF w_r) { - polys.w_l[idx] = w_l; - polys.w_r[idx] = w_r; - polys.w_o[idx] = w_l + w_r; - polys.q_l[idx] = 1; - polys.q_r[idx] = 1; - polys.q_o[idx] = -1; - }; - - const auto create_mul_gate = [](auto& polys, const size_t idx, FF w_l, FF w_r) { - polys.w_l[idx] = w_l; - polys.w_r[idx] = w_r; - polys.w_o[idx] = w_l * w_r; - polys.q_m[idx] = 1; - polys.q_o[idx] = -1; - }; - - create_add_gate(instances[0]->prover_polynomials, 0, 1, 2); - create_add_gate(instances[0]->prover_polynomials, 1, 0, 4); - create_add_gate(instances[1]->prover_polynomials, 0, 3, 4); - create_mul_gate(instances[1]->prover_polynomials, 1, 1, 4); - - restrict_to_standard_arithmetic_relation(instances[0]->prover_polynomials); - restrict_to_standard_arithmetic_relation(instances[1]->prover_polynomials); - - /* Instance 0 Instance 1 - w_l w_r w_o q_m q_l q_r q_o q_c w_l w_r w_o q_m q_l q_r q_o q_c - 1 2 3 0 1 1 -1 0 3 4 7 0 1 1 -1 0 - 0 4 4 0 1 1 -1 0 1 4 4 1 0 0 -1 0 */ - - /* Lagrange-combined values, row index 0 Lagrange-combined values, row index 1 - in 0 1 2 3 4 5 6 in 0 1 2 3 4 5 6 - w_l 1 3 5 7 9 11 13 w_l 0 1 2 3 4 5 6 - w_r 2 4 6 8 10 12 14 w_r 4 4 4 4 4 4 4 - w_o 3 7 11 15 19 23 27 w_o 4 4 4 4 4 4 0 - q_m 0 0 0 0 0 0 0 q_m 0 1 2 3 4 5 6 - q_l 1 1 1 1 1 1 1 q_l 1 0 -1 -2 -3 -4 -5 - q_r 1 1 1 1 1 1 1 q_r 1 0 -1 -2 -3 -4 -5 - q_o -1 -1 -1 -1 -1 -1 -1 q_o -1 -1 -1 -1 -1 -1 -1 - q_c 0 0 0 0 0 0 0 q_c 0 0 0 0 0 0 0 - - relation value: - 0 0 0 0 0 0 0 0 0 6 18 36 60 90 */ - - auto result = prover.compute_combiner(instances, relation_parameters, pow_univariate, alpha); - auto expected_result = barretenberg::Univariate(std::array{ 0, 0, 36, 144, 360, 720, 1260 }); - EXPECT_EQ(result, expected_result); - } - }; - run_test(true); - run_test(false); -}; - -TEST(Protogalaxy, CombinerOn4Instances) -{ - constexpr size_t NUM_INSTANCES = 4; - using ProverInstance = ProverInstance_; - using ProverInstances = ProverInstances_; - using ProtoGalaxyProver = ProtoGalaxyProver_; - - const auto zero_all_selectors = [](auto& polys) { - std::fill(polys.q_arith.begin(), polys.q_arith.end(), 0); - std::fill(polys.q_sort.begin(), polys.q_sort.end(), 0); - std::fill(polys.q_elliptic.begin(), polys.q_elliptic.end(), 0); - std::fill(polys.q_aux.begin(), polys.q_aux.end(), 0); - std::fill(polys.q_lookup.begin(), polys.q_lookup.end(), 0); - std::fill(polys.q_4.begin(), polys.q_4.end(), 0); - std::fill(polys.w_4.begin(), polys.w_4.end(), 0); - std::fill(polys.w_4_shift.begin(), polys.w_4_shift.end(), 0); - }; - - auto run_test = [&]() { - std::vector> instance_data(NUM_INSTANCES); - std::array, NUM_INSTANCES> storage_arrays; - auto relation_parameters = RelationParameters::get_random(); - ProtoGalaxyProver prover; - auto pow_univariate = PowUnivariate(/*zeta_pow=*/2); - auto alpha = FF(0); // focus on the arithmetic relation only - - for (size_t idx = 0; idx < NUM_INSTANCES; idx++) { - auto instance = std::make_shared(); - auto [storage, prover_polynomials] = proof_system::honk::get_zero_prover_polynomials( - /*log_circuit_size=*/1); - storage_arrays[idx] = std::move(storage); - instance->prover_polynomials = prover_polynomials; - instance_data[idx] = instance; - } - - ProverInstances instances{ instance_data }; - - zero_all_selectors(instances[0]->prover_polynomials); - zero_all_selectors(instances[1]->prover_polynomials); - zero_all_selectors(instances[2]->prover_polynomials); - zero_all_selectors(instances[3]->prover_polynomials); - - auto result = prover.compute_combiner(instances, relation_parameters, pow_univariate, alpha); - std::array zeroes; - std::fill(zeroes.begin(), zeroes.end(), 0); - auto expected_result = barretenberg::Univariate(zeroes); - EXPECT_EQ(result, expected_result); - }; - run_test(); -}; - -} // namespace barretenberg::test_protogalaxy_prover +// #include "barretenberg/honk/flavor/ultra.hpp" +// #include "barretenberg/honk/instance/instances.hpp" +// #include "barretenberg/honk/proof_system/protogalaxy_prover.hpp" +// #include "barretenberg/honk/utils/testing.hpp" +// #include "barretenberg/proof_system/relations/relation_parameters.hpp" +// #include + +// using namespace proof_system::honk; +// namespace barretenberg::test_protogalaxy_prover { +// using Flavor = proof_system::honk::flavor::Ultra; +// using Polynomial = typename Flavor::Polynomial; +// using FF = typename Flavor::FF; +// using RelationParameters = proof_system::RelationParameters; + +// TEST(Protogalaxy, CombinerOn2Instances) +// { +// constexpr size_t NUM_INSTANCES = 2; +// using ProverInstance = ProverInstance_; +// using ProverInstances = ProverInstances_; +// using ProtoGalaxyProver = ProtoGalaxyProver_; + +// const auto restrict_to_standard_arithmetic_relation = [](auto& polys) { +// std::fill(polys.q_arith.begin(), polys.q_arith.end(), 1); +// std::fill(polys.q_sort.begin(), polys.q_sort.end(), 0); +// std::fill(polys.q_elliptic.begin(), polys.q_elliptic.end(), 0); +// std::fill(polys.q_aux.begin(), polys.q_aux.end(), 0); +// std::fill(polys.q_lookup.begin(), polys.q_lookup.end(), 0); +// std::fill(polys.q_4.begin(), polys.q_4.end(), 0); +// std::fill(polys.w_4.begin(), polys.w_4.end(), 0); +// std::fill(polys.w_4_shift.begin(), polys.w_4_shift.end(), 0); +// }; + +// auto run_test = [&](bool is_random_input) { +// if (is_random_input) { +// std::vector> instance_data(NUM_INSTANCES); +// std::array, NUM_INSTANCES> storage_arrays; +// auto relation_parameters = RelationParameters::get_random(); +// ProtoGalaxyProver prover; +// auto pow_univariate = PowUnivariate(/*zeta_pow=*/2); +// auto alpha = FF(0); // focus on the arithmetic relation only + +// for (size_t idx = 0; idx < NUM_INSTANCES; idx++) { +// auto instance = std::make_shared(); +// auto [storage, prover_polynomials] = proof_system::honk::get_sequential_prover_polynomials( +// /*log_circuit_size=*/1, idx * 128); +// restrict_to_standard_arithmetic_relation(prover_polynomials); +// storage_arrays[idx] = std::move(storage); +// instance->prover_polynomials = prover_polynomials; +// instance_data[idx] = instance; +// } + +// ProverInstances instances{ instance_data }; + +// auto result = prover.compute_combiner(instances, relation_parameters, pow_univariate, alpha); +// auto expected_result = +// barretenberg::Univariate(std::array{ 87706, +// 27289140, +// 229355214, +// 905031784, +// static_cast(2504059650), +// static_cast(5627174556), +// static_cast(11026107190) }); + +// EXPECT_EQ(result, expected_result); +// } else { +// std::vector> instance_data(NUM_INSTANCES); +// std::array, NUM_INSTANCES> storage_arrays; +// auto relation_parameters = RelationParameters::get_random(); +// ProtoGalaxyProver prover; +// auto pow_univariate = PowUnivariate(/*zeta_pow=*/2); +// auto alpha = FF(0); // focus on the arithmetic relation only + +// for (size_t idx = 0; idx < NUM_INSTANCES; idx++) { +// auto instance = std::make_shared(); +// auto [storage, prover_polynomials] = proof_system::honk::get_zero_prover_polynomials( +// /*log_circuit_size=*/1); +// restrict_to_standard_arithmetic_relation(prover_polynomials); +// storage_arrays[idx] = std::move(storage); +// instance->prover_polynomials = prover_polynomials; +// instance_data[idx] = instance; +// } + +// ProverInstances instances{ instance_data }; + +// const auto create_add_gate = [](auto& polys, const size_t idx, FF w_l, FF w_r) { +// polys.w_l[idx] = w_l; +// polys.w_r[idx] = w_r; +// polys.w_o[idx] = w_l + w_r; +// polys.q_l[idx] = 1; +// polys.q_r[idx] = 1; +// polys.q_o[idx] = -1; +// }; + +// const auto create_mul_gate = [](auto& polys, const size_t idx, FF w_l, FF w_r) { +// polys.w_l[idx] = w_l; +// polys.w_r[idx] = w_r; +// polys.w_o[idx] = w_l * w_r; +// polys.q_m[idx] = 1; +// polys.q_o[idx] = -1; +// }; + +// create_add_gate(instances[0]->prover_polynomials, 0, 1, 2); +// create_add_gate(instances[0]->prover_polynomials, 1, 0, 4); +// create_add_gate(instances[1]->prover_polynomials, 0, 3, 4); +// create_mul_gate(instances[1]->prover_polynomials, 1, 1, 4); + +// restrict_to_standard_arithmetic_relation(instances[0]->prover_polynomials); +// restrict_to_standard_arithmetic_relation(instances[1]->prover_polynomials); + +// /* Instance 0 Instance 1 +// w_l w_r w_o q_m q_l q_r q_o q_c w_l w_r w_o q_m q_l q_r q_o q_c +// 1 2 3 0 1 1 -1 0 3 4 7 0 1 1 -1 0 +// 0 4 4 0 1 1 -1 0 1 4 4 1 0 0 -1 0 */ + +// /* Lagrange-combined values, row index 0 Lagrange-combined values, row index 1 +// in 0 1 2 3 4 5 6 in 0 1 2 3 4 5 6 +// w_l 1 3 5 7 9 11 13 w_l 0 1 2 3 4 5 6 +// w_r 2 4 6 8 10 12 14 w_r 4 4 4 4 4 4 4 +// w_o 3 7 11 15 19 23 27 w_o 4 4 4 4 4 4 0 +// q_m 0 0 0 0 0 0 0 q_m 0 1 2 3 4 5 6 +// q_l 1 1 1 1 1 1 1 q_l 1 0 -1 -2 -3 -4 -5 +// q_r 1 1 1 1 1 1 1 q_r 1 0 -1 -2 -3 -4 -5 +// q_o -1 -1 -1 -1 -1 -1 -1 q_o -1 -1 -1 -1 -1 -1 -1 +// q_c 0 0 0 0 0 0 0 q_c 0 0 0 0 0 0 0 + +// relation value: +// 0 0 0 0 0 0 0 0 0 6 18 36 60 90 */ + +// auto result = prover.compute_combiner(instances, relation_parameters, pow_univariate, alpha); +// auto expected_result = barretenberg::Univariate(std::array{ 0, 0, 36, 144, 360, 720, 1260 +// }); EXPECT_EQ(result, expected_result); +// } +// }; +// run_test(true); +// run_test(false); +// }; + +// TEST(Protogalaxy, CombinerOn4Instances) +// { +// constexpr size_t NUM_INSTANCES = 4; +// using ProverInstance = ProverInstance_; +// using ProverInstances = ProverInstances_; +// using ProtoGalaxyProver = ProtoGalaxyProver_; + +// const auto zero_all_selectors = [](auto& polys) { +// std::fill(polys.q_arith.begin(), polys.q_arith.end(), 0); +// std::fill(polys.q_sort.begin(), polys.q_sort.end(), 0); +// std::fill(polys.q_elliptic.begin(), polys.q_elliptic.end(), 0); +// std::fill(polys.q_aux.begin(), polys.q_aux.end(), 0); +// std::fill(polys.q_lookup.begin(), polys.q_lookup.end(), 0); +// std::fill(polys.q_4.begin(), polys.q_4.end(), 0); +// std::fill(polys.w_4.begin(), polys.w_4.end(), 0); +// std::fill(polys.w_4_shift.begin(), polys.w_4_shift.end(), 0); +// }; + +// auto run_test = [&]() { +// std::vector> instance_data(NUM_INSTANCES); +// std::array, NUM_INSTANCES> storage_arrays; +// auto relation_parameters = RelationParameters::get_random(); +// ProtoGalaxyProver prover; +// auto pow_univariate = PowUnivariate(/*zeta_pow=*/2); +// auto alpha = FF(0); // focus on the arithmetic relation only + +// for (size_t idx = 0; idx < NUM_INSTANCES; idx++) { +// auto instance = std::make_shared(); +// auto [storage, prover_polynomials] = proof_system::honk::get_zero_prover_polynomials( +// /*log_circuit_size=*/1); +// storage_arrays[idx] = std::move(storage); +// instance->prover_polynomials = prover_polynomials; +// instance_data[idx] = instance; +// } + +// ProverInstances instances{ instance_data }; + +// zero_all_selectors(instances[0]->prover_polynomials); +// zero_all_selectors(instances[1]->prover_polynomials); +// zero_all_selectors(instances[2]->prover_polynomials); +// zero_all_selectors(instances[3]->prover_polynomials); + +// auto result = prover.compute_combiner(instances, relation_parameters, pow_univariate, alpha); +// std::array zeroes; +// std::fill(zeroes.begin(), zeroes.end(), 0); +// auto expected_result = barretenberg::Univariate(zeroes); +// EXPECT_EQ(result, expected_result); +// }; +// run_test(); +// }; + +// } // namespace barretenberg::test_protogalaxy_prover 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 049331affb2..638557681f0 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)); + const auto log_instance_size = static_cast(numeric::get_msb(instance_size)); auto deltas = compute_round_challenge_pows(log_instance_size, delta); auto perturbator = compute_perturbator(accumulator, deltas, alpha); assert(perturbator[0] == accumulator->folding_parameters->target_sum); @@ -56,14 +56,6 @@ ProverFoldingResult ProtoGalaxyProver_(compressed_perturbator); - std::vector lagrange_first(log_instance_size, FF(0)); - lagrange_first[0] = FF(1); - - std::vector vanishing_set; - vanishing_set.reserve(log_instance_size); - std::iota(vanishing_set.begin(), vanishing_set.end(), FF::zero()); - // need to be built not on the vanishing set H!!!!! - // sanity check: i think we don't care about elemnt 0th element of beta, it is 1 std::vector betas_star(log_instance_size); betas_star[0] = 1; @@ -74,18 +66,54 @@ ProverFoldingResult ProtoGalaxyProver_relation_parameters, pow_betas_star, alpha); + const auto combiner_quotient_size = (log_instance_size - 1) * Flavor::MAX_RELATION_LENGTH; + std::vector lagrange_0(combiner_quotient_size); + std::vector vanishing_polynomial(combiner_quotient_size); + // combiner_quotient evaluations from k to dk + 1 + // TODO: make this univariates + // WARNING: barycentric evaluations might not work here ???? + std::array combiner_quotient_coeffs; + for (size_t point = log_instance_size; point < combiner.size(); point++) { + auto idx = point - log_instance_size; + lagrange_0[idx] = FF(1) - FF(point); + vanishing_polynomial[idx] = FF(point) * (FF(point) - 1); + combiner_quotient_coeffs[idx] = + (combiner.value_at(point) - compressed_perturbator * lagrange_0[idx]) / vanishing_polynomial[idx]; + } - // compute \vec{\beta*} - // sanity check this is correc + for (size_t idx = 0; idx < combiner_quotient_size; idx++) { + transcript.send_to_verifier("combiner_quotient_" + std::to_string(idx), combiner_quotient_coeffs[idx]); + } - auto combiner = compute_combiner(instances, accumulator->relation_parameters, pow_betas_star, alpha); + RandomExtendedUnivariate combiner_quotient = Univariate(combiner_quotient_coeffs); + auto combiner_challenge = transcript.get_challenge("combiner_qoutient_challenge"); + auto combiner_quotient_at_challenge = combiner_quotient.evaluate(combiner_challenge); + auto vanishing_polynomial_at_challenge = combiner_challenge * (combiner_challenge - FF(1)); + auto lagrange_0_at_challenge = FF(1) - combiner_challenge; + auto lagrange_1_at_challenge = combiner_challenge; + auto new_target_sum = compressed_perturbator * lagrange_0_at_challenge + vanishing_polynomial_at_challenge + + combiner_quotient_at_challenge; + + for (size_t idx = 0; idx < accumulator->prover_polynomials.size(); idx++) { + auto accumulator_poly = accumulator->prover_polynomials[idx]; + auto instance_poly = accumulator->prover_polynomials[idx]; + assert(accumulator_poly.size() == instance_poly.size()); + for (size_t j = 0; j < accumulator_poly.size(); j++) { + accumulator_poly[j] = + accumulator_poly[j] * lagrange_0_at_challenge + instance_poly * lagrange_1_at_challenge; + } + } + + // i have dk evaluations out of which the first k are not good so we evaluate the rest of the polynomials from + // k+1 - // auto vanishing_polynomial_at_challenge = combiner_challenge * (combiner_challenge - FF(1)); - // auto lagrange_0_at_challenge = FF(1) - combiner_challenge; - // auto lagrange_1_at_challenge = combiner_challenge; + // we do barycentric evaluation on the combiner ProverFoldingResult res; + res.folded_prover_polynomials = accumalator->prover_polynomials; + res.params.target_sum = new_target_sum; + res.params.gate_separation_challenges = betas_star; 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 fe5757c3fcd..d83a28e9207 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp @@ -289,8 +289,7 @@ template class ProtoGalaxyProver_ { Utils::add_nested_tuples(univariate_accumulators, accumulators); } // Batch the univariate contributions from each sub-relation to obtain the round univariate - return Utils::template batch_over_relations( - univariate_accumulators, alpha, FF(1)); // not sure what this should be, should it be 1????? + return Utils::template batch_over_relations(univariate_accumulators, alpha); } }; 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 921fe323de1..129d104f55e 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.cpp @@ -53,10 +53,10 @@ VerifierFoldingResult ProtoGalaxyVerifier_< std::vector combiner_quotient_coeffs(combiner_quotient_size); for (size_t idx = 0; idx < combiner_quotient_size; idx++) { combiner_quotient_coeffs[idx] = - transcript.template receive_from_prover("combiner_quotient_idx" + std::to_string(idx)); + transcript.template receive_from_prover("combiner_quotient_" + std::to_string(idx)); } auto combiner_quotient = Polynomial(combiner_quotient_coeffs); - auto combiner_challenge = transcript.get_challenge("degree_reduction"); + auto combiner_challenge = transcript.get_challenge("combiner_quotient_challenge"); static_cast(combiner_challenge); // fix k = 1 which means k+1 = 2 is a power of two diff --git a/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.hpp b/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.hpp index 1a0bbbfefe5..c03d0968129 100644 --- a/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.hpp @@ -166,7 +166,7 @@ template class SumcheckProverRound { } // Batch the univariate contributions from each sub-relation to obtain the round univariate return Utils::template batch_over_relations>( - univariate_accumulators, alpha, pow_univariate.zeta_pow); + univariate_accumulators, alpha, pow_univariate); } private: 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 231b1c97f53..6c71ed95c5f 100644 --- a/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.test.cpp @@ -43,7 +43,7 @@ TEST(SumcheckRound, SumcheckTupleOfTuplesOfUnivariates) // Use extend_and_batch_univariates to extend to MAX_LENGTH then accumulate PowUnivariate pow_univariate(1); auto result = Univariate(); - Utils::extend_and_batch_univariates(tuple_of_tuples, pow_univariate.zeta_pow, result); + Utils::extend_and_batch_univariates(tuple_of_tuples, result, pow_univariate); // Repeat the batching process manually auto result_expected = univariate_1.template extend_to() * 1 + diff --git a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp index ca3701f9b9f..0ca83be0654 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp @@ -55,6 +55,7 @@ template class Univariate { Fr& value_at(size_t i) { return evaluations[i]; }; const Fr& value_at(size_t i) const { return evaluations[i]; }; + size_t size() { return evaluations.size(); }; // Write the Univariate evaluations to a buffer std::vector to_buffer() const { return ::to_buffer(evaluations); } diff --git a/barretenberg/cpp/src/barretenberg/proof_system/relations/utils.hpp b/barretenberg/cpp/src/barretenberg/proof_system/relations/utils.hpp index f040d02872f..4ce9df182d2 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/relations/utils.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/relations/utils.hpp @@ -123,12 +123,15 @@ template class RelationUtils { */ template static void extend_and_batch_univariates(const OfTuplesOfUnivariates& tuple, - const FF zeta, - ExtendedUnivariate& result) + ExtendedUnivariate& result, + const std::optional>& pow_univariate = std::nullopt) { + ExtendedUnivariate extended_random_polynomial; // Random poly R(X) = (1-X) + X.zeta_pow - auto random_polynomial = Univariate({ 1, zeta }); - auto extended_random_polynomial = random_polynomial.template extend_to(); + if (pow_univariate.has_value()) { + auto random_polynomial = Univariate({ 1, pow_univariate.value().zeta_pow }); + extended_random_polynomial = random_polynomial.template extend_to(); + } auto extend_and_sum = [&](Element& element) { auto extended = element.template extend_to(); @@ -136,13 +139,13 @@ template class RelationUtils { using Relation = typename std::tuple_element_t; const bool is_subrelation_linearly_independent = proof_system::subrelation_is_linearly_independent(); - if (is_subrelation_linearly_independent) { - // if subrelation is linearly independent, multiply by random polynomial - result += extended * extended_random_polynomial; - } else { - // if subrelation is pure sum over hypercube, don't multiply by random polynomial + if (!is_subrelation_linearly_independent || !pow_univariate.has_value()) { + // if subrelation is pure um over hypercube, don't multiply by random polynomial // make these comments more relevant result += extended; + } else { + // if subrelation is linearly independent, multiply by random polynomial + result += extended * extended_random_polynomial; } }; apply_to_tuple_of_tuples(tuple, extend_and_sum); @@ -153,15 +156,16 @@ template class RelationUtils { * return t_0 + αt_1 + ... + α^{NUM_RELATIONS-1}t_{NUM_RELATIONS-1}). */ template - static ExtendedUnivariate batch_over_relations(ContainerOverSubrelations& univariate_accumulators, - const FF& challenge, - const FF& zeta) + static ExtendedUnivariate batch_over_relations( + ContainerOverSubrelations& univariate_accumulators, + const FF& challenge, + const std::optional>& pow_univariate = std::nullopt) { FF running_challenge = 1; scale_univariates(univariate_accumulators, challenge, running_challenge); auto result = ExtendedUnivariate(0); - extend_and_batch_univariates(univariate_accumulators, zeta, result); + extend_and_batch_univariates(univariate_accumulators, result, pow_univariate); // Reset all univariate accumulators to 0 before beginning accumulation in the next round zero_univariates(univariate_accumulators); From 59c69f22ddf226e9f72eb17a39ab2b5d845083af Mon Sep 17 00:00:00 2001 From: maramihali Date: Wed, 25 Oct 2023 12:18:33 +0000 Subject: [PATCH 04/86] pain --- .../honk/instance/verifier_instance.hpp | 2 +- .../honk/proof_system/combiner.test.cpp | 382 +++++++++--------- .../honk/proof_system/combiner_example_gen.py | 11 +- .../honk/proof_system/protogalaxy.test.cpp | 17 +- .../honk/proof_system/protogalaxy_prover.cpp | 97 ++--- .../honk/proof_system/protogalaxy_prover.hpp | 2 +- .../proof_system/protogalaxy_verifier.cpp | 82 ++-- 7 files changed, 296 insertions(+), 297 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/instance/verifier_instance.hpp b/barretenberg/cpp/src/barretenberg/honk/instance/verifier_instance.hpp index 2e8ac9a0210..f2d1afc1136 100644 --- a/barretenberg/cpp/src/barretenberg/honk/instance/verifier_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/instance/verifier_instance.hpp @@ -14,6 +14,6 @@ template class VerifierInstance_ { size_t public_input_size; size_t instance_size; RelationParameters relation_parameters; - FoldingParameters folding_params; + FoldingParameters folding_parameters; }; } // namespace proof_system::honk \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/combiner.test.cpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/combiner.test.cpp index 5733c79e6da..24ecfd81a23 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/combiner.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/combiner.test.cpp @@ -1,189 +1,193 @@ -// #include "barretenberg/honk/flavor/ultra.hpp" -// #include "barretenberg/honk/instance/instances.hpp" -// #include "barretenberg/honk/proof_system/protogalaxy_prover.hpp" -// #include "barretenberg/honk/utils/testing.hpp" -// #include "barretenberg/proof_system/relations/relation_parameters.hpp" -// #include - -// using namespace proof_system::honk; -// namespace barretenberg::test_protogalaxy_prover { -// using Flavor = proof_system::honk::flavor::Ultra; -// using Polynomial = typename Flavor::Polynomial; -// using FF = typename Flavor::FF; -// using RelationParameters = proof_system::RelationParameters; - -// TEST(Protogalaxy, CombinerOn2Instances) -// { -// constexpr size_t NUM_INSTANCES = 2; -// using ProverInstance = ProverInstance_; -// using ProverInstances = ProverInstances_; -// using ProtoGalaxyProver = ProtoGalaxyProver_; - -// const auto restrict_to_standard_arithmetic_relation = [](auto& polys) { -// std::fill(polys.q_arith.begin(), polys.q_arith.end(), 1); -// std::fill(polys.q_sort.begin(), polys.q_sort.end(), 0); -// std::fill(polys.q_elliptic.begin(), polys.q_elliptic.end(), 0); -// std::fill(polys.q_aux.begin(), polys.q_aux.end(), 0); -// std::fill(polys.q_lookup.begin(), polys.q_lookup.end(), 0); -// std::fill(polys.q_4.begin(), polys.q_4.end(), 0); -// std::fill(polys.w_4.begin(), polys.w_4.end(), 0); -// std::fill(polys.w_4_shift.begin(), polys.w_4_shift.end(), 0); -// }; - -// auto run_test = [&](bool is_random_input) { -// if (is_random_input) { -// std::vector> instance_data(NUM_INSTANCES); -// std::array, NUM_INSTANCES> storage_arrays; -// auto relation_parameters = RelationParameters::get_random(); -// ProtoGalaxyProver prover; -// auto pow_univariate = PowUnivariate(/*zeta_pow=*/2); -// auto alpha = FF(0); // focus on the arithmetic relation only - -// for (size_t idx = 0; idx < NUM_INSTANCES; idx++) { -// auto instance = std::make_shared(); -// auto [storage, prover_polynomials] = proof_system::honk::get_sequential_prover_polynomials( -// /*log_circuit_size=*/1, idx * 128); -// restrict_to_standard_arithmetic_relation(prover_polynomials); -// storage_arrays[idx] = std::move(storage); -// instance->prover_polynomials = prover_polynomials; -// instance_data[idx] = instance; -// } - -// ProverInstances instances{ instance_data }; - -// auto result = prover.compute_combiner(instances, relation_parameters, pow_univariate, alpha); -// auto expected_result = -// barretenberg::Univariate(std::array{ 87706, -// 27289140, -// 229355214, -// 905031784, -// static_cast(2504059650), -// static_cast(5627174556), -// static_cast(11026107190) }); - -// EXPECT_EQ(result, expected_result); -// } else { -// std::vector> instance_data(NUM_INSTANCES); -// std::array, NUM_INSTANCES> storage_arrays; -// auto relation_parameters = RelationParameters::get_random(); -// ProtoGalaxyProver prover; -// auto pow_univariate = PowUnivariate(/*zeta_pow=*/2); -// auto alpha = FF(0); // focus on the arithmetic relation only - -// for (size_t idx = 0; idx < NUM_INSTANCES; idx++) { -// auto instance = std::make_shared(); -// auto [storage, prover_polynomials] = proof_system::honk::get_zero_prover_polynomials( -// /*log_circuit_size=*/1); -// restrict_to_standard_arithmetic_relation(prover_polynomials); -// storage_arrays[idx] = std::move(storage); -// instance->prover_polynomials = prover_polynomials; -// instance_data[idx] = instance; -// } - -// ProverInstances instances{ instance_data }; - -// const auto create_add_gate = [](auto& polys, const size_t idx, FF w_l, FF w_r) { -// polys.w_l[idx] = w_l; -// polys.w_r[idx] = w_r; -// polys.w_o[idx] = w_l + w_r; -// polys.q_l[idx] = 1; -// polys.q_r[idx] = 1; -// polys.q_o[idx] = -1; -// }; - -// const auto create_mul_gate = [](auto& polys, const size_t idx, FF w_l, FF w_r) { -// polys.w_l[idx] = w_l; -// polys.w_r[idx] = w_r; -// polys.w_o[idx] = w_l * w_r; -// polys.q_m[idx] = 1; -// polys.q_o[idx] = -1; -// }; - -// create_add_gate(instances[0]->prover_polynomials, 0, 1, 2); -// create_add_gate(instances[0]->prover_polynomials, 1, 0, 4); -// create_add_gate(instances[1]->prover_polynomials, 0, 3, 4); -// create_mul_gate(instances[1]->prover_polynomials, 1, 1, 4); - -// restrict_to_standard_arithmetic_relation(instances[0]->prover_polynomials); -// restrict_to_standard_arithmetic_relation(instances[1]->prover_polynomials); - -// /* Instance 0 Instance 1 -// w_l w_r w_o q_m q_l q_r q_o q_c w_l w_r w_o q_m q_l q_r q_o q_c -// 1 2 3 0 1 1 -1 0 3 4 7 0 1 1 -1 0 -// 0 4 4 0 1 1 -1 0 1 4 4 1 0 0 -1 0 */ - -// /* Lagrange-combined values, row index 0 Lagrange-combined values, row index 1 -// in 0 1 2 3 4 5 6 in 0 1 2 3 4 5 6 -// w_l 1 3 5 7 9 11 13 w_l 0 1 2 3 4 5 6 -// w_r 2 4 6 8 10 12 14 w_r 4 4 4 4 4 4 4 -// w_o 3 7 11 15 19 23 27 w_o 4 4 4 4 4 4 0 -// q_m 0 0 0 0 0 0 0 q_m 0 1 2 3 4 5 6 -// q_l 1 1 1 1 1 1 1 q_l 1 0 -1 -2 -3 -4 -5 -// q_r 1 1 1 1 1 1 1 q_r 1 0 -1 -2 -3 -4 -5 -// q_o -1 -1 -1 -1 -1 -1 -1 q_o -1 -1 -1 -1 -1 -1 -1 -// q_c 0 0 0 0 0 0 0 q_c 0 0 0 0 0 0 0 - -// relation value: -// 0 0 0 0 0 0 0 0 0 6 18 36 60 90 */ - -// auto result = prover.compute_combiner(instances, relation_parameters, pow_univariate, alpha); -// auto expected_result = barretenberg::Univariate(std::array{ 0, 0, 36, 144, 360, 720, 1260 -// }); EXPECT_EQ(result, expected_result); -// } -// }; -// run_test(true); -// run_test(false); -// }; - -// TEST(Protogalaxy, CombinerOn4Instances) -// { -// constexpr size_t NUM_INSTANCES = 4; -// using ProverInstance = ProverInstance_; -// using ProverInstances = ProverInstances_; -// using ProtoGalaxyProver = ProtoGalaxyProver_; - -// const auto zero_all_selectors = [](auto& polys) { -// std::fill(polys.q_arith.begin(), polys.q_arith.end(), 0); -// std::fill(polys.q_sort.begin(), polys.q_sort.end(), 0); -// std::fill(polys.q_elliptic.begin(), polys.q_elliptic.end(), 0); -// std::fill(polys.q_aux.begin(), polys.q_aux.end(), 0); -// std::fill(polys.q_lookup.begin(), polys.q_lookup.end(), 0); -// std::fill(polys.q_4.begin(), polys.q_4.end(), 0); -// std::fill(polys.w_4.begin(), polys.w_4.end(), 0); -// std::fill(polys.w_4_shift.begin(), polys.w_4_shift.end(), 0); -// }; - -// auto run_test = [&]() { -// std::vector> instance_data(NUM_INSTANCES); -// std::array, NUM_INSTANCES> storage_arrays; -// auto relation_parameters = RelationParameters::get_random(); -// ProtoGalaxyProver prover; -// auto pow_univariate = PowUnivariate(/*zeta_pow=*/2); -// auto alpha = FF(0); // focus on the arithmetic relation only - -// for (size_t idx = 0; idx < NUM_INSTANCES; idx++) { -// auto instance = std::make_shared(); -// auto [storage, prover_polynomials] = proof_system::honk::get_zero_prover_polynomials( -// /*log_circuit_size=*/1); -// storage_arrays[idx] = std::move(storage); -// instance->prover_polynomials = prover_polynomials; -// instance_data[idx] = instance; -// } - -// ProverInstances instances{ instance_data }; - -// zero_all_selectors(instances[0]->prover_polynomials); -// zero_all_selectors(instances[1]->prover_polynomials); -// zero_all_selectors(instances[2]->prover_polynomials); -// zero_all_selectors(instances[3]->prover_polynomials); - -// auto result = prover.compute_combiner(instances, relation_parameters, pow_univariate, alpha); -// std::array zeroes; -// std::fill(zeroes.begin(), zeroes.end(), 0); -// auto expected_result = barretenberg::Univariate(zeroes); -// EXPECT_EQ(result, expected_result); -// }; -// run_test(); -// }; - -// } // namespace barretenberg::test_protogalaxy_prover +#include "barretenberg/honk/flavor/ultra.hpp" +#include "barretenberg/honk/instance/instances.hpp" +#include "barretenberg/honk/proof_system/protogalaxy_prover.hpp" +#include "barretenberg/honk/utils/testing.hpp" +#include "barretenberg/proof_system/relations/relation_parameters.hpp" +#include + +using namespace proof_system::honk; +namespace barretenberg::test_protogalaxy_prover { +using Flavor = proof_system::honk::flavor::Ultra; +using Polynomial = typename Flavor::Polynomial; +using FF = typename Flavor::FF; +using RelationParameters = proof_system::RelationParameters; + +TEST(Protogalaxy, CombinerOn2Instances) +{ + constexpr size_t NUM_INSTANCES = 2; + using ProverInstance = ProverInstance_; + using ProverInstances = ProverInstances_; + using ProtoGalaxyProver = ProtoGalaxyProver_; + + const auto restrict_to_standard_arithmetic_relation = [](auto& polys) { + std::fill(polys.q_arith.begin(), polys.q_arith.end(), 1); + std::fill(polys.q_sort.begin(), polys.q_sort.end(), 0); + std::fill(polys.q_elliptic.begin(), polys.q_elliptic.end(), 0); + std::fill(polys.q_aux.begin(), polys.q_aux.end(), 0); + std::fill(polys.q_lookup.begin(), polys.q_lookup.end(), 0); + std::fill(polys.q_4.begin(), polys.q_4.end(), 0); + std::fill(polys.w_4.begin(), polys.w_4.end(), 0); + std::fill(polys.w_4_shift.begin(), polys.w_4_shift.end(), 0); + }; + + auto run_test = [&](bool is_random_input) { + if (is_random_input) { + std::vector> instance_data(NUM_INSTANCES); + std::array, NUM_INSTANCES> storage_arrays; + auto relation_parameters = RelationParameters::get_random(); + ProtoGalaxyProver prover; + // auto pow_univariate = PowUnivariate(/*zeta_pow=*/2); + std::vector pow_betas = { FF(1), FF(2) }; + auto alpha = FF(0); // focus on the arithmetic relation only + + for (size_t idx = 0; idx < NUM_INSTANCES; idx++) { + auto instance = std::make_shared(); + auto [storage, prover_polynomials] = proof_system::honk::get_sequential_prover_polynomials( + /*log_circuit_size=*/1, idx * 128); + restrict_to_standard_arithmetic_relation(prover_polynomials); + storage_arrays[idx] = std::move(storage); + instance->prover_polynomials = prover_polynomials; + instance_data[idx] = instance; + } + + ProverInstances instances{ instance_data }; + + auto result = prover.compute_combiner(instances, relation_parameters, pow_betas, alpha); + auto expected_result = + barretenberg::Univariate(std::array{ 87706, + 13644570, + 76451738, + 226257946, + static_cast(500811930), + static_cast(937862426), + static_cast(1575158170) }); + + EXPECT_EQ(result, expected_result); + } else { + std::vector> instance_data(NUM_INSTANCES); + std::array, NUM_INSTANCES> storage_arrays; + auto relation_parameters = RelationParameters::get_random(); + ProtoGalaxyProver prover; + // auto pow_univariate = PowUnivariate(/*zeta_pow=*/2); + std::vector pow_betas = { FF(1), FF(2) }; + auto alpha = FF(0); // focus on the arithmetic relation only + + for (size_t idx = 0; idx < NUM_INSTANCES; idx++) { + auto instance = std::make_shared(); + auto [storage, prover_polynomials] = proof_system::honk::get_zero_prover_polynomials( + /*log_circuit_size=*/1); + restrict_to_standard_arithmetic_relation(prover_polynomials); + storage_arrays[idx] = std::move(storage); + instance->prover_polynomials = prover_polynomials; + instance_data[idx] = instance; + } + + ProverInstances instances{ instance_data }; + + const auto create_add_gate = [](auto& polys, const size_t idx, FF w_l, FF w_r) { + polys.w_l[idx] = w_l; + polys.w_r[idx] = w_r; + polys.w_o[idx] = w_l + w_r; + polys.q_l[idx] = 1; + polys.q_r[idx] = 1; + polys.q_o[idx] = -1; + }; + + const auto create_mul_gate = [](auto& polys, const size_t idx, FF w_l, FF w_r) { + polys.w_l[idx] = w_l; + polys.w_r[idx] = w_r; + polys.w_o[idx] = w_l * w_r; + polys.q_m[idx] = 1; + polys.q_o[idx] = -1; + }; + + create_add_gate(instances[0]->prover_polynomials, 0, 1, 2); + create_add_gate(instances[0]->prover_polynomials, 1, 0, 4); + create_add_gate(instances[1]->prover_polynomials, 0, 3, 4); + create_mul_gate(instances[1]->prover_polynomials, 1, 1, 4); + + restrict_to_standard_arithmetic_relation(instances[0]->prover_polynomials); + restrict_to_standard_arithmetic_relation(instances[1]->prover_polynomials); + + /* Instance 0 Instance 1 + w_l w_r w_o q_m q_l q_r q_o q_c w_l w_r w_o q_m q_l q_r q_o q_c + 1 2 3 0 1 1 -1 0 3 4 7 0 1 1 -1 0 + 0 4 4 0 1 1 -1 0 1 4 4 1 0 0 -1 0 */ + + /* Lagrange-combined values, row index 0 Lagrange-combined values, row index 1 + in 0 1 2 3 4 5 6 in 0 1 2 3 4 5 6 + w_l 1 3 5 7 9 11 13 w_l 0 1 2 3 4 5 6 + w_r 2 4 6 8 10 12 14 w_r 4 4 4 4 4 4 4 + w_o 3 7 11 15 19 23 27 w_o 4 4 4 4 4 4 0 + q_m 0 0 0 0 0 0 0 q_m 0 1 2 3 4 5 6 + q_l 1 1 1 1 1 1 1 q_l 1 0 -1 -2 -3 -4 -5 + q_r 1 1 1 1 1 1 1 q_r 1 0 -1 -2 -3 -4 -5 + q_o -1 -1 -1 -1 -1 -1 -1 q_o -1 -1 -1 -1 -1 -1 -1 + q_c 0 0 0 0 0 0 0 q_c 0 0 0 0 0 0 0 + + relation value: + 0 0 0 0 0 0 0 0 0 6 18 36 60 90 */ + + auto result = prover.compute_combiner(instances, relation_parameters, pow_betas, alpha); + auto expected_result = barretenberg::Univariate(std::array{ 0, 0, 12, 36, 72, 120, 180 }); + // static_cast(result); + // static_cast(expected_result); + EXPECT_EQ(result, expected_result); + } + }; + run_test(true); + run_test(false); +}; + +TEST(Protogalaxy, CombinerOn4Instances) +{ + constexpr size_t NUM_INSTANCES = 4; + using ProverInstance = ProverInstance_; + using ProverInstances = ProverInstances_; + using ProtoGalaxyProver = ProtoGalaxyProver_; + + const auto zero_all_selectors = [](auto& polys) { + std::fill(polys.q_arith.begin(), polys.q_arith.end(), 0); + std::fill(polys.q_sort.begin(), polys.q_sort.end(), 0); + std::fill(polys.q_elliptic.begin(), polys.q_elliptic.end(), 0); + std::fill(polys.q_aux.begin(), polys.q_aux.end(), 0); + std::fill(polys.q_lookup.begin(), polys.q_lookup.end(), 0); + std::fill(polys.q_4.begin(), polys.q_4.end(), 0); + std::fill(polys.w_4.begin(), polys.w_4.end(), 0); + std::fill(polys.w_4_shift.begin(), polys.w_4_shift.end(), 0); + }; + + auto run_test = [&]() { + std::vector> instance_data(NUM_INSTANCES); + std::array, NUM_INSTANCES> storage_arrays; + auto relation_parameters = RelationParameters::get_random(); + ProtoGalaxyProver prover; + auto alpha = FF(0); // focus on the arithmetic relation only + + for (size_t idx = 0; idx < NUM_INSTANCES; idx++) { + auto instance = std::make_shared(); + auto [storage, prover_polynomials] = proof_system::honk::get_zero_prover_polynomials( + /*log_circuit_size=*/1); + storage_arrays[idx] = std::move(storage); + instance->prover_polynomials = prover_polynomials; + instance_data[idx] = instance; + } + + ProverInstances instances{ instance_data }; + + zero_all_selectors(instances[0]->prover_polynomials); + zero_all_selectors(instances[1]->prover_polynomials); + zero_all_selectors(instances[2]->prover_polynomials); + zero_all_selectors(instances[3]->prover_polynomials); + + std::vector pow_betas = { FF(1), FF(2) }; + auto result = prover.compute_combiner(instances, relation_parameters, pow_betas, alpha); + std::array zeroes; + std::fill(zeroes.begin(), zeroes.end(), 0); + auto expected_result = barretenberg::Univariate(zeroes); + EXPECT_EQ(result, expected_result); + }; + run_test(); +}; + +} // namespace barretenberg::test_protogalaxy_prover diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/combiner_example_gen.py b/barretenberg/cpp/src/barretenberg/honk/proof_system/combiner_example_gen.py index 2c37304ae97..5fa39aff9d8 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/combiner_example_gen.py +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/combiner_example_gen.py @@ -103,8 +103,9 @@ def compute_first_example(): row.q_l, row.q_r, row.q_o, row.q_c) accumulator += zeta_pow * relation_value zeta_pow *= zeta + print(zeta_pow) - accumulator *= extend_one_entity([1, 2]) + # accumulator *= extend_one_entity([1, 2]) return accumulator @@ -133,10 +134,12 @@ def compute_second_example(): result += rel(w_l, w_r, w_o, q_m, q_l, q_r, q_o, q_c) result *= 2 - result *= extend_one_entity([1, 2]) + # result *= extend_one_entity([1, 2]) return result if __name__ == "__main__": - print(f"First example: \n {compute_first_example()}") - print(f"Second example:\n {compute_second_example()}") + # print(f"First example: \n {compute_first_example()}") + # print(f"Second example:\n {compute_second_example()}") + print(compute_first_example()) + print(compute_second_example()) 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 8c35ce4d40b..eafbd1ff410 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp @@ -127,7 +127,7 @@ TEST_F(ProtoGalaxyTests, PerturbatorCoefficients) } } -TEST_F(ProtoGalaxyTests, PowPerturbatorPolynomial) +TEST_F(ProtoGalaxyTests, PerturbatorPolynomial) { const size_t log_instance_size(3); const size_t instance_size(1 << log_instance_size); @@ -147,17 +147,8 @@ TEST_F(ProtoGalaxyTests, PowPerturbatorPolynomial) 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 res = FF(1); - for (size_t j = i, beta_idx = 0; j > 0; j >>= 1, beta_idx++) { - if ((j & 1) == 1) { - res *= betas[beta_idx]; - } - } - pow_beta[i] = res; - } + // Construct pow(\vec{betas}) as in the paper + auto pow_beta = ProtoGalaxyProver::compute_pow_polynomial_at_values(betas, instance_size); // Compute the corresponding target sum and create a dummy accumulator auto target_sum = FF(0); @@ -178,4 +169,6 @@ 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); } + +TEST_F(ProtoGalaxyTests, PowCorrectness) {} } // 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 638557681f0..1282dd948d2 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp @@ -47,7 +47,7 @@ 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[0] == accumulator->folding_parameters->target_sum); + assert(perturbator[0] == accumulator->folding_parameters.target_sum); for (size_t idx = 0; idx <= log_instance_size; idx++) { transcript.send_to_verifier("perturbator_" + std::to_string(idx), perturbator[idx]); } @@ -64,57 +64,58 @@ ProverFoldingResult ProtoGalaxyProver_relation_parameters, pow_betas_star, alpha); - const auto combiner_quotient_size = (log_instance_size - 1) * Flavor::MAX_RELATION_LENGTH; - std::vector lagrange_0(combiner_quotient_size); - std::vector vanishing_polynomial(combiner_quotient_size); - // combiner_quotient evaluations from k to dk + 1 - // TODO: make this univariates - // WARNING: barycentric evaluations might not work here ???? - std::array combiner_quotient_coeffs; - for (size_t point = log_instance_size; point < combiner.size(); point++) { - auto idx = point - log_instance_size; - lagrange_0[idx] = FF(1) - FF(point); - vanishing_polynomial[idx] = FF(point) * (FF(point) - 1); - combiner_quotient_coeffs[idx] = - (combiner.value_at(point) - compressed_perturbator * lagrange_0[idx]) / vanishing_polynomial[idx]; - } - - for (size_t idx = 0; idx < combiner_quotient_size; idx++) { - transcript.send_to_verifier("combiner_quotient_" + std::to_string(idx), combiner_quotient_coeffs[idx]); - } - - RandomExtendedUnivariate combiner_quotient = Univariate(combiner_quotient_coeffs); - auto combiner_challenge = transcript.get_challenge("combiner_qoutient_challenge"); - auto combiner_quotient_at_challenge = combiner_quotient.evaluate(combiner_challenge); - auto vanishing_polynomial_at_challenge = combiner_challenge * (combiner_challenge - FF(1)); - auto lagrange_0_at_challenge = FF(1) - combiner_challenge; - auto lagrange_1_at_challenge = combiner_challenge; - auto new_target_sum = compressed_perturbator * lagrange_0_at_challenge + vanishing_polynomial_at_challenge + - combiner_quotient_at_challenge; - - for (size_t idx = 0; idx < accumulator->prover_polynomials.size(); idx++) { - auto accumulator_poly = accumulator->prover_polynomials[idx]; - auto instance_poly = accumulator->prover_polynomials[idx]; - assert(accumulator_poly.size() == instance_poly.size()); - for (size_t j = 0; j < accumulator_poly.size(); j++) { - accumulator_poly[j] = - accumulator_poly[j] * lagrange_0_at_challenge + instance_poly * lagrange_1_at_challenge; - } - } - - // i have dk evaluations out of which the first k are not good so we evaluate the rest of the polynomials from - // k+1 - - // we do barycentric evaluation on the combiner + static_cast(combiner); + // const auto combiner_quotient_size = (log_instance_size - 1) * Flavor::MAX_RELATION_LENGTH; + // std::vector lagrange_0(combiner_quotient_size); + // std::vector vanishing_polynomial(combiner_quotient_size); + // // combiner_quotient evaluations from k to dk + 1 + // // TODO: make this univariates + // // WARNING: barycentric evaluations might not work here ???? + // std::array + // combiner_quotient_coeffs; for (size_t point = log_instance_size; point < combiner.size(); point++) { + // auto idx = point - log_instance_size; + // lagrange_0[idx] = FF(1) - FF(point); + // vanishing_polynomial[idx] = FF(point) * (FF(point) - 1); + // combiner_quotient_coeffs[idx] = + // (combiner.value_at(point) - compressed_perturbator * lagrange_0[idx]) / vanishing_polynomial[idx]; + // } + + // for (size_t idx = 0; idx < combiner_quotient_size; idx++) { + // transcript.send_to_verifier("combiner_quotient_" + std::to_string(idx), combiner_quotient_coeffs[idx]); + // } + + // RandomExtendedUnivariate combiner_quotient = Univariate(combiner_quotient_coeffs); + // auto combiner_challenge = transcript.get_challenge("combiner_qoutient_challenge"); + // auto combiner_quotient_at_challenge = combiner_quotient.evaluate(combiner_challenge); + // auto vanishing_polynomial_at_challenge = combiner_challenge * (combiner_challenge - FF(1)); + // auto lagrange_0_at_challenge = FF(1) - combiner_challenge; + // auto lagrange_1_at_challenge = combiner_challenge; + // auto new_target_sum = compressed_perturbator * lagrange_0_at_challenge + vanishing_polynomial_at_challenge + + // combiner_quotient_at_challenge; + + // for (size_t idx = 0; idx < accumulator->prover_polynomials.size(); idx++) { + // auto accumulator_poly = accumulator->prover_polynomials[idx]; + // auto instance_poly = accumulator->prover_polynomials[idx]; + // assert(accumulator_poly.size() == instance_poly.size()); + // for (size_t j = 0; j < accumulator_poly.size(); j++) { + // accumulator_poly[j] = + // accumulator_poly[j] * lagrange_0_at_challenge + instance_poly * lagrange_1_at_challenge; + // } + // } + + // // i have dk evaluations out of which the first k are not good so we evaluate the rest of the polynomials from + // // k+1 + + // // we do barycentric evaluation on the combiner ProverFoldingResult res; - res.folded_prover_polynomials = accumalator->prover_polynomials; - res.params.target_sum = new_target_sum; - res.params.gate_separation_challenges = betas_star; - res.folding_data = transcript.proof_data; + // res.folded_prover_polynomials = accumulator->prover_polynomials; + // res.params.target_sum = new_target_sum; + // res.params.gate_separation_challenges = betas_star; + // res.folding_data = transcript.proof_data; return res; } template class ProtoGalaxyProver_>; 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 d83a28e9207..30f0954254d 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp @@ -48,7 +48,7 @@ template class ProtoGalaxyProver_ { */ void prepare_for_folding(); - std::vector compute_pow_polynomials_at_values(const std::vector betas, const size_t instance_size) + static std::vector compute_pow_polynomial_at_values(const std::vector betas, const size_t instance_size) { std::vector pow_betas(instance_size); for (size_t i = 0; i < instance_size; i++) { 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 129d104f55e..36201b2d0e6 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.cpp @@ -6,7 +6,7 @@ VerifierFoldingResult ProtoGalaxyVerifier_< VerifierInstances>::fold_public_parameters(std::vector fold_data) { using Flavor = typename VerifierInstances::Flavor; - using VerificationKey = typename Flavor::VerificationKey; + // using VerificationKey = typename Flavor::VerificationKey; transcript = VerifierTranscript{ fold_data }; auto index = 0; @@ -42,51 +42,49 @@ VerifierFoldingResult ProtoGalaxyVerifier_< for (size_t idx = 0; idx <= log_instance_size; idx++) { perturbator_coeffs[idx] = transcript.template receive_from_prover("perturbator_" + std::to_string(idx)); } - assert(perturbator_coeffs[0] == accumulator->folding_parameters->target_sum); - auto perturbator = Polynomial(perturbator_coeffs); - auto perturbator_challenge = transcript.get_challenge("perturbator_challenge"); - auto perturbator_at_challenge = perturbator.evaluate(perturbator_challenge); // horner - static_cast(perturbator_at_challenge); - // get the coefficient of combiner quotient (K(X) polynomial in the paper) - // + 2 because we need one extra eval to rep a poly of certain degree - auto combiner_quotient_size = Flavor::MAX_RANDOM_RELATION_LENGTH * (VerifierInstances::NUM - 1) + 2; - std::vector combiner_quotient_coeffs(combiner_quotient_size); - for (size_t idx = 0; idx < combiner_quotient_size; idx++) { - combiner_quotient_coeffs[idx] = - transcript.template receive_from_prover("combiner_quotient_" + std::to_string(idx)); - } - auto combiner_quotient = Polynomial(combiner_quotient_coeffs); - auto combiner_challenge = transcript.get_challenge("combiner_quotient_challenge"); - static_cast(combiner_challenge); + assert(perturbator_coeffs[0] == accumulator->folding_parameters.target_sum); + // auto perturbator = Polynomial(perturbator_coeffs); + // auto perturbator_challenge = transcript.get_challenge("perturbator_challenge"); + // auto perturbator_at_challenge = perturbator.evaluate(perturbator_challenge); // horner - // fix k = 1 which means k+1 = 2 is a power of two - auto combiner_quotient_at_challenge = combiner_quotient.evaluate(combiner_challenge); // K(\gamma) - auto vanishing_polynomial_at_challenge = combiner_challenge * (combiner_challenge - FF(1)); - auto lagrange_0_at_challenge = FF(1) - combiner_challenge; - auto lagrange_1_at_challenge = combiner_challenge; - auto updated_target_sum = perturbator_at_challenge * lagrange_0_at_challenge + - vanishing_polynomial_at_challenge * combiner_quotient_at_challenge; + // auto combiner_quotient_size = Flavor::MAX_RANDOM_RELATION_LENGTH * (VerifierInstances::NUM - 1) + 2; + // std::vector combiner_quotient_coeffs(combiner_quotient_size); + // for (size_t idx = 0; idx < combiner_quotient_size; idx++) { + // combiner_quotient_coeffs[idx] = + // transcript.template receive_from_prover("combiner_quotient_" + std::to_string(idx)); + // } + // auto combiner_quotient = Polynomial(combiner_quotient_coeffs); + // auto combiner_challenge = transcript.get_challenge("combiner_quotient_challenge"); + // static_cast(combiner_challenge); - // do public input stuff with goblin (well I guess first without) - // fold public inputs (field elements) and the commitment in verification key to obtain a new verification key! - // TODO: extend for more instances; - auto accumulator_public_inputs = accumulator->public_inputs; - auto other_public_inputs = verifier_instances[1]->public_inputs; - std::vector folded_public_inputs(accumulator->public_input_size); - // extend either with 0s if the sizes are different - for (size_t idx = 0; idx < folded_public_inputs.size(); idx++) { - folded_public_inputs[idx] = lagrange_0_at_challenge * accumulator->public_inputs[idx] + - lagrange_1_at_challenge * other_public_inputs[idx]; - } - // all verification keys have the same size - auto folded_verification_key = VerificationKey(accumulator->instance_size, accumulator->public_input_size); + // // fix k = 1 which means k+1 = 2 is a power of two + // auto combiner_quotient_at_challenge = combiner_quotient.evaluate(combiner_challenge); // K(\gamma) + // auto vanishing_polynomial_at_challenge = combiner_challenge * (combiner_challenge - FF(1)); + // auto lagrange_0_at_challenge = FF(1) - combiner_challenge; + // auto lagrange_1_at_challenge = combiner_challenge; + // auto updated_target_sum = perturbator_at_challenge * lagrange_0_at_challenge + + // vanishing_polynomial_at_challenge * combiner_quotient_at_challenge; - for (size_t idx = 0; idx < folded_verification_key.size(); idx++) { - folded_verification_key[idx] = (*accumulator->verification_key)[idx] * lagrange_0_at_challenge + - (*verifier_instances[1]->verification_key)[idx] * lagrange_1_at_challenge; - } + // // do public input stuff with goblin (well I guess first without) + // // fold public inputs (field elements) and the commitment in verification key to obtain a new verification key! + // // TODO: extend for more instances; + // auto accumulator_public_inputs = accumulator->public_inputs; + // auto other_public_inputs = verifier_instances[1]->public_inputs; + // std::vector folded_public_inputs(accumulator->public_input_size); + // // extend either with 0s if the sizes are different + // for (size_t idx = 0; idx < folded_public_inputs.size(); idx++) { + // folded_public_inputs[idx] = lagrange_0_at_challenge * accumulator->public_inputs[idx] + + // lagrange_1_at_challenge * other_public_inputs[idx]; + // } + // // all verification keys have the same size + // auto folded_verification_key = VerificationKey(accumulator->instance_size, accumulator->public_input_size); + + // for (size_t idx = 0; idx < folded_verification_key.size(); idx++) { + // folded_verification_key[idx] = (*accumulator->verification_key)[idx] * lagrange_0_at_challenge + + // (*verifier_instances[1]->verification_key)[idx] * lagrange_1_at_challenge; + // } VerifierFoldingResult res; - res.parameters.target_sum = updated_target_sum; + // res.parameters.target_sum = updated_target_sum; return res; } From aed27df0492ce976286268f5862469e9c921ada8 Mon Sep 17 00:00:00 2001 From: maramihali Date: Wed, 25 Oct 2023 12:18:33 +0000 Subject: [PATCH 05/86] pain --- .../honk/instance/verifier_instance.hpp | 2 +- .../honk/proof_system/combiner.test.cpp | 382 +++++++++--------- .../honk/proof_system/combiner_example_gen.py | 71 ++-- .../honk/proof_system/protogalaxy.test.cpp | 17 +- .../honk/proof_system/protogalaxy_prover.cpp | 19 +- .../honk/proof_system/protogalaxy_prover.hpp | 2 +- .../proof_system/protogalaxy_verifier.cpp | 19 +- 7 files changed, 260 insertions(+), 252 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/instance/verifier_instance.hpp b/barretenberg/cpp/src/barretenberg/honk/instance/verifier_instance.hpp index 2e8ac9a0210..f2d1afc1136 100644 --- a/barretenberg/cpp/src/barretenberg/honk/instance/verifier_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/instance/verifier_instance.hpp @@ -14,6 +14,6 @@ template class VerifierInstance_ { size_t public_input_size; size_t instance_size; RelationParameters relation_parameters; - FoldingParameters folding_params; + FoldingParameters folding_parameters; }; } // namespace proof_system::honk \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/combiner.test.cpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/combiner.test.cpp index 5733c79e6da..24ecfd81a23 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/combiner.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/combiner.test.cpp @@ -1,189 +1,193 @@ -// #include "barretenberg/honk/flavor/ultra.hpp" -// #include "barretenberg/honk/instance/instances.hpp" -// #include "barretenberg/honk/proof_system/protogalaxy_prover.hpp" -// #include "barretenberg/honk/utils/testing.hpp" -// #include "barretenberg/proof_system/relations/relation_parameters.hpp" -// #include - -// using namespace proof_system::honk; -// namespace barretenberg::test_protogalaxy_prover { -// using Flavor = proof_system::honk::flavor::Ultra; -// using Polynomial = typename Flavor::Polynomial; -// using FF = typename Flavor::FF; -// using RelationParameters = proof_system::RelationParameters; - -// TEST(Protogalaxy, CombinerOn2Instances) -// { -// constexpr size_t NUM_INSTANCES = 2; -// using ProverInstance = ProverInstance_; -// using ProverInstances = ProverInstances_; -// using ProtoGalaxyProver = ProtoGalaxyProver_; - -// const auto restrict_to_standard_arithmetic_relation = [](auto& polys) { -// std::fill(polys.q_arith.begin(), polys.q_arith.end(), 1); -// std::fill(polys.q_sort.begin(), polys.q_sort.end(), 0); -// std::fill(polys.q_elliptic.begin(), polys.q_elliptic.end(), 0); -// std::fill(polys.q_aux.begin(), polys.q_aux.end(), 0); -// std::fill(polys.q_lookup.begin(), polys.q_lookup.end(), 0); -// std::fill(polys.q_4.begin(), polys.q_4.end(), 0); -// std::fill(polys.w_4.begin(), polys.w_4.end(), 0); -// std::fill(polys.w_4_shift.begin(), polys.w_4_shift.end(), 0); -// }; - -// auto run_test = [&](bool is_random_input) { -// if (is_random_input) { -// std::vector> instance_data(NUM_INSTANCES); -// std::array, NUM_INSTANCES> storage_arrays; -// auto relation_parameters = RelationParameters::get_random(); -// ProtoGalaxyProver prover; -// auto pow_univariate = PowUnivariate(/*zeta_pow=*/2); -// auto alpha = FF(0); // focus on the arithmetic relation only - -// for (size_t idx = 0; idx < NUM_INSTANCES; idx++) { -// auto instance = std::make_shared(); -// auto [storage, prover_polynomials] = proof_system::honk::get_sequential_prover_polynomials( -// /*log_circuit_size=*/1, idx * 128); -// restrict_to_standard_arithmetic_relation(prover_polynomials); -// storage_arrays[idx] = std::move(storage); -// instance->prover_polynomials = prover_polynomials; -// instance_data[idx] = instance; -// } - -// ProverInstances instances{ instance_data }; - -// auto result = prover.compute_combiner(instances, relation_parameters, pow_univariate, alpha); -// auto expected_result = -// barretenberg::Univariate(std::array{ 87706, -// 27289140, -// 229355214, -// 905031784, -// static_cast(2504059650), -// static_cast(5627174556), -// static_cast(11026107190) }); - -// EXPECT_EQ(result, expected_result); -// } else { -// std::vector> instance_data(NUM_INSTANCES); -// std::array, NUM_INSTANCES> storage_arrays; -// auto relation_parameters = RelationParameters::get_random(); -// ProtoGalaxyProver prover; -// auto pow_univariate = PowUnivariate(/*zeta_pow=*/2); -// auto alpha = FF(0); // focus on the arithmetic relation only - -// for (size_t idx = 0; idx < NUM_INSTANCES; idx++) { -// auto instance = std::make_shared(); -// auto [storage, prover_polynomials] = proof_system::honk::get_zero_prover_polynomials( -// /*log_circuit_size=*/1); -// restrict_to_standard_arithmetic_relation(prover_polynomials); -// storage_arrays[idx] = std::move(storage); -// instance->prover_polynomials = prover_polynomials; -// instance_data[idx] = instance; -// } - -// ProverInstances instances{ instance_data }; - -// const auto create_add_gate = [](auto& polys, const size_t idx, FF w_l, FF w_r) { -// polys.w_l[idx] = w_l; -// polys.w_r[idx] = w_r; -// polys.w_o[idx] = w_l + w_r; -// polys.q_l[idx] = 1; -// polys.q_r[idx] = 1; -// polys.q_o[idx] = -1; -// }; - -// const auto create_mul_gate = [](auto& polys, const size_t idx, FF w_l, FF w_r) { -// polys.w_l[idx] = w_l; -// polys.w_r[idx] = w_r; -// polys.w_o[idx] = w_l * w_r; -// polys.q_m[idx] = 1; -// polys.q_o[idx] = -1; -// }; - -// create_add_gate(instances[0]->prover_polynomials, 0, 1, 2); -// create_add_gate(instances[0]->prover_polynomials, 1, 0, 4); -// create_add_gate(instances[1]->prover_polynomials, 0, 3, 4); -// create_mul_gate(instances[1]->prover_polynomials, 1, 1, 4); - -// restrict_to_standard_arithmetic_relation(instances[0]->prover_polynomials); -// restrict_to_standard_arithmetic_relation(instances[1]->prover_polynomials); - -// /* Instance 0 Instance 1 -// w_l w_r w_o q_m q_l q_r q_o q_c w_l w_r w_o q_m q_l q_r q_o q_c -// 1 2 3 0 1 1 -1 0 3 4 7 0 1 1 -1 0 -// 0 4 4 0 1 1 -1 0 1 4 4 1 0 0 -1 0 */ - -// /* Lagrange-combined values, row index 0 Lagrange-combined values, row index 1 -// in 0 1 2 3 4 5 6 in 0 1 2 3 4 5 6 -// w_l 1 3 5 7 9 11 13 w_l 0 1 2 3 4 5 6 -// w_r 2 4 6 8 10 12 14 w_r 4 4 4 4 4 4 4 -// w_o 3 7 11 15 19 23 27 w_o 4 4 4 4 4 4 0 -// q_m 0 0 0 0 0 0 0 q_m 0 1 2 3 4 5 6 -// q_l 1 1 1 1 1 1 1 q_l 1 0 -1 -2 -3 -4 -5 -// q_r 1 1 1 1 1 1 1 q_r 1 0 -1 -2 -3 -4 -5 -// q_o -1 -1 -1 -1 -1 -1 -1 q_o -1 -1 -1 -1 -1 -1 -1 -// q_c 0 0 0 0 0 0 0 q_c 0 0 0 0 0 0 0 - -// relation value: -// 0 0 0 0 0 0 0 0 0 6 18 36 60 90 */ - -// auto result = prover.compute_combiner(instances, relation_parameters, pow_univariate, alpha); -// auto expected_result = barretenberg::Univariate(std::array{ 0, 0, 36, 144, 360, 720, 1260 -// }); EXPECT_EQ(result, expected_result); -// } -// }; -// run_test(true); -// run_test(false); -// }; - -// TEST(Protogalaxy, CombinerOn4Instances) -// { -// constexpr size_t NUM_INSTANCES = 4; -// using ProverInstance = ProverInstance_; -// using ProverInstances = ProverInstances_; -// using ProtoGalaxyProver = ProtoGalaxyProver_; - -// const auto zero_all_selectors = [](auto& polys) { -// std::fill(polys.q_arith.begin(), polys.q_arith.end(), 0); -// std::fill(polys.q_sort.begin(), polys.q_sort.end(), 0); -// std::fill(polys.q_elliptic.begin(), polys.q_elliptic.end(), 0); -// std::fill(polys.q_aux.begin(), polys.q_aux.end(), 0); -// std::fill(polys.q_lookup.begin(), polys.q_lookup.end(), 0); -// std::fill(polys.q_4.begin(), polys.q_4.end(), 0); -// std::fill(polys.w_4.begin(), polys.w_4.end(), 0); -// std::fill(polys.w_4_shift.begin(), polys.w_4_shift.end(), 0); -// }; - -// auto run_test = [&]() { -// std::vector> instance_data(NUM_INSTANCES); -// std::array, NUM_INSTANCES> storage_arrays; -// auto relation_parameters = RelationParameters::get_random(); -// ProtoGalaxyProver prover; -// auto pow_univariate = PowUnivariate(/*zeta_pow=*/2); -// auto alpha = FF(0); // focus on the arithmetic relation only - -// for (size_t idx = 0; idx < NUM_INSTANCES; idx++) { -// auto instance = std::make_shared(); -// auto [storage, prover_polynomials] = proof_system::honk::get_zero_prover_polynomials( -// /*log_circuit_size=*/1); -// storage_arrays[idx] = std::move(storage); -// instance->prover_polynomials = prover_polynomials; -// instance_data[idx] = instance; -// } - -// ProverInstances instances{ instance_data }; - -// zero_all_selectors(instances[0]->prover_polynomials); -// zero_all_selectors(instances[1]->prover_polynomials); -// zero_all_selectors(instances[2]->prover_polynomials); -// zero_all_selectors(instances[3]->prover_polynomials); - -// auto result = prover.compute_combiner(instances, relation_parameters, pow_univariate, alpha); -// std::array zeroes; -// std::fill(zeroes.begin(), zeroes.end(), 0); -// auto expected_result = barretenberg::Univariate(zeroes); -// EXPECT_EQ(result, expected_result); -// }; -// run_test(); -// }; - -// } // namespace barretenberg::test_protogalaxy_prover +#include "barretenberg/honk/flavor/ultra.hpp" +#include "barretenberg/honk/instance/instances.hpp" +#include "barretenberg/honk/proof_system/protogalaxy_prover.hpp" +#include "barretenberg/honk/utils/testing.hpp" +#include "barretenberg/proof_system/relations/relation_parameters.hpp" +#include + +using namespace proof_system::honk; +namespace barretenberg::test_protogalaxy_prover { +using Flavor = proof_system::honk::flavor::Ultra; +using Polynomial = typename Flavor::Polynomial; +using FF = typename Flavor::FF; +using RelationParameters = proof_system::RelationParameters; + +TEST(Protogalaxy, CombinerOn2Instances) +{ + constexpr size_t NUM_INSTANCES = 2; + using ProverInstance = ProverInstance_; + using ProverInstances = ProverInstances_; + using ProtoGalaxyProver = ProtoGalaxyProver_; + + const auto restrict_to_standard_arithmetic_relation = [](auto& polys) { + std::fill(polys.q_arith.begin(), polys.q_arith.end(), 1); + std::fill(polys.q_sort.begin(), polys.q_sort.end(), 0); + std::fill(polys.q_elliptic.begin(), polys.q_elliptic.end(), 0); + std::fill(polys.q_aux.begin(), polys.q_aux.end(), 0); + std::fill(polys.q_lookup.begin(), polys.q_lookup.end(), 0); + std::fill(polys.q_4.begin(), polys.q_4.end(), 0); + std::fill(polys.w_4.begin(), polys.w_4.end(), 0); + std::fill(polys.w_4_shift.begin(), polys.w_4_shift.end(), 0); + }; + + auto run_test = [&](bool is_random_input) { + if (is_random_input) { + std::vector> instance_data(NUM_INSTANCES); + std::array, NUM_INSTANCES> storage_arrays; + auto relation_parameters = RelationParameters::get_random(); + ProtoGalaxyProver prover; + // auto pow_univariate = PowUnivariate(/*zeta_pow=*/2); + std::vector pow_betas = { FF(1), FF(2) }; + auto alpha = FF(0); // focus on the arithmetic relation only + + for (size_t idx = 0; idx < NUM_INSTANCES; idx++) { + auto instance = std::make_shared(); + auto [storage, prover_polynomials] = proof_system::honk::get_sequential_prover_polynomials( + /*log_circuit_size=*/1, idx * 128); + restrict_to_standard_arithmetic_relation(prover_polynomials); + storage_arrays[idx] = std::move(storage); + instance->prover_polynomials = prover_polynomials; + instance_data[idx] = instance; + } + + ProverInstances instances{ instance_data }; + + auto result = prover.compute_combiner(instances, relation_parameters, pow_betas, alpha); + auto expected_result = + barretenberg::Univariate(std::array{ 87706, + 13644570, + 76451738, + 226257946, + static_cast(500811930), + static_cast(937862426), + static_cast(1575158170) }); + + EXPECT_EQ(result, expected_result); + } else { + std::vector> instance_data(NUM_INSTANCES); + std::array, NUM_INSTANCES> storage_arrays; + auto relation_parameters = RelationParameters::get_random(); + ProtoGalaxyProver prover; + // auto pow_univariate = PowUnivariate(/*zeta_pow=*/2); + std::vector pow_betas = { FF(1), FF(2) }; + auto alpha = FF(0); // focus on the arithmetic relation only + + for (size_t idx = 0; idx < NUM_INSTANCES; idx++) { + auto instance = std::make_shared(); + auto [storage, prover_polynomials] = proof_system::honk::get_zero_prover_polynomials( + /*log_circuit_size=*/1); + restrict_to_standard_arithmetic_relation(prover_polynomials); + storage_arrays[idx] = std::move(storage); + instance->prover_polynomials = prover_polynomials; + instance_data[idx] = instance; + } + + ProverInstances instances{ instance_data }; + + const auto create_add_gate = [](auto& polys, const size_t idx, FF w_l, FF w_r) { + polys.w_l[idx] = w_l; + polys.w_r[idx] = w_r; + polys.w_o[idx] = w_l + w_r; + polys.q_l[idx] = 1; + polys.q_r[idx] = 1; + polys.q_o[idx] = -1; + }; + + const auto create_mul_gate = [](auto& polys, const size_t idx, FF w_l, FF w_r) { + polys.w_l[idx] = w_l; + polys.w_r[idx] = w_r; + polys.w_o[idx] = w_l * w_r; + polys.q_m[idx] = 1; + polys.q_o[idx] = -1; + }; + + create_add_gate(instances[0]->prover_polynomials, 0, 1, 2); + create_add_gate(instances[0]->prover_polynomials, 1, 0, 4); + create_add_gate(instances[1]->prover_polynomials, 0, 3, 4); + create_mul_gate(instances[1]->prover_polynomials, 1, 1, 4); + + restrict_to_standard_arithmetic_relation(instances[0]->prover_polynomials); + restrict_to_standard_arithmetic_relation(instances[1]->prover_polynomials); + + /* Instance 0 Instance 1 + w_l w_r w_o q_m q_l q_r q_o q_c w_l w_r w_o q_m q_l q_r q_o q_c + 1 2 3 0 1 1 -1 0 3 4 7 0 1 1 -1 0 + 0 4 4 0 1 1 -1 0 1 4 4 1 0 0 -1 0 */ + + /* Lagrange-combined values, row index 0 Lagrange-combined values, row index 1 + in 0 1 2 3 4 5 6 in 0 1 2 3 4 5 6 + w_l 1 3 5 7 9 11 13 w_l 0 1 2 3 4 5 6 + w_r 2 4 6 8 10 12 14 w_r 4 4 4 4 4 4 4 + w_o 3 7 11 15 19 23 27 w_o 4 4 4 4 4 4 0 + q_m 0 0 0 0 0 0 0 q_m 0 1 2 3 4 5 6 + q_l 1 1 1 1 1 1 1 q_l 1 0 -1 -2 -3 -4 -5 + q_r 1 1 1 1 1 1 1 q_r 1 0 -1 -2 -3 -4 -5 + q_o -1 -1 -1 -1 -1 -1 -1 q_o -1 -1 -1 -1 -1 -1 -1 + q_c 0 0 0 0 0 0 0 q_c 0 0 0 0 0 0 0 + + relation value: + 0 0 0 0 0 0 0 0 0 6 18 36 60 90 */ + + auto result = prover.compute_combiner(instances, relation_parameters, pow_betas, alpha); + auto expected_result = barretenberg::Univariate(std::array{ 0, 0, 12, 36, 72, 120, 180 }); + // static_cast(result); + // static_cast(expected_result); + EXPECT_EQ(result, expected_result); + } + }; + run_test(true); + run_test(false); +}; + +TEST(Protogalaxy, CombinerOn4Instances) +{ + constexpr size_t NUM_INSTANCES = 4; + using ProverInstance = ProverInstance_; + using ProverInstances = ProverInstances_; + using ProtoGalaxyProver = ProtoGalaxyProver_; + + const auto zero_all_selectors = [](auto& polys) { + std::fill(polys.q_arith.begin(), polys.q_arith.end(), 0); + std::fill(polys.q_sort.begin(), polys.q_sort.end(), 0); + std::fill(polys.q_elliptic.begin(), polys.q_elliptic.end(), 0); + std::fill(polys.q_aux.begin(), polys.q_aux.end(), 0); + std::fill(polys.q_lookup.begin(), polys.q_lookup.end(), 0); + std::fill(polys.q_4.begin(), polys.q_4.end(), 0); + std::fill(polys.w_4.begin(), polys.w_4.end(), 0); + std::fill(polys.w_4_shift.begin(), polys.w_4_shift.end(), 0); + }; + + auto run_test = [&]() { + std::vector> instance_data(NUM_INSTANCES); + std::array, NUM_INSTANCES> storage_arrays; + auto relation_parameters = RelationParameters::get_random(); + ProtoGalaxyProver prover; + auto alpha = FF(0); // focus on the arithmetic relation only + + for (size_t idx = 0; idx < NUM_INSTANCES; idx++) { + auto instance = std::make_shared(); + auto [storage, prover_polynomials] = proof_system::honk::get_zero_prover_polynomials( + /*log_circuit_size=*/1); + storage_arrays[idx] = std::move(storage); + instance->prover_polynomials = prover_polynomials; + instance_data[idx] = instance; + } + + ProverInstances instances{ instance_data }; + + zero_all_selectors(instances[0]->prover_polynomials); + zero_all_selectors(instances[1]->prover_polynomials); + zero_all_selectors(instances[2]->prover_polynomials); + zero_all_selectors(instances[3]->prover_polynomials); + + std::vector pow_betas = { FF(1), FF(2) }; + auto result = prover.compute_combiner(instances, relation_parameters, pow_betas, alpha); + std::array zeroes; + std::fill(zeroes.begin(), zeroes.end(), 0); + auto expected_result = barretenberg::Univariate(zeroes); + EXPECT_EQ(result, expected_result); + }; + run_test(); +}; + +} // namespace barretenberg::test_protogalaxy_prover diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/combiner_example_gen.py b/barretenberg/cpp/src/barretenberg/honk/proof_system/combiner_example_gen.py index 2c37304ae97..ec8d90a25dd 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/combiner_example_gen.py +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/combiner_example_gen.py @@ -87,6 +87,13 @@ def get_extended_univariates(instances, row_idx): result = np.array(extend_one_entity(result)) return result + +def compute_lagrange(points){ + lagrange_0 = np.array([]) + lagrange_1 = np.array([]) + +} + def compute_first_example(): i0 = Instance([Row(0), Row(1)]) i1 = Instance([Row(128), Row(129)]) @@ -104,39 +111,43 @@ def compute_first_example(): accumulator += zeta_pow * relation_value zeta_pow *= zeta - accumulator *= extend_one_entity([1, 2]) + + + # accumulator *= extend_one_entity([1, 2]) return accumulator -def compute_second_example(): - result = 0 - w_l = np.array([ 1, 3, 5, 7, 9, 11, 13]) - w_r = np.array([ 2, 4, 6, 8, 10, 12, 14]) - w_o = np.array([ 3, 7, 11, 15, 19, 23, 27]) - q_m = np.array([ 0, 0, 0, 0, 0, 0, 0]) - q_l = np.array([ 1, 1, 1, 1, 1, 1, 1]) - q_r = np.array([ 1, 1, 1, 1, 1, 1, 1]) - q_o = np.array([-1, -1, -1, -1, -1, -1, -1]) - q_c = np.array([ 0, 0, 0, 0, 0, 0, 0]) - # contribution is zero, but why not? - result += rel(w_l, w_r, w_o, q_m, q_l, q_r, q_o, q_c) - - w_l = np.array([ 0, 1, 2, 3, 4, 5, 6]) - w_r = np.array([ 4, 4, 4, 4, 4, 4, 4]) - w_o = np.array([ 4, 4, 4, 4, 4, 4, 4]) - q_m = np.array([ 0, 1, 2, 3, 4, 5, 6]) - q_l = np.array([ 1, 0, -1, -2, -3, -4, -5]) - q_r = np.array([ 1, 0, -1, -2, -3, -4, -5]) - q_o = np.array([-1, -1, -1, -1, -1, -1, -1]) - q_c = np.array([ 0, 0, 0, 0, 0, 0, 0]) - - result += rel(w_l, w_r, w_o, q_m, q_l, q_r, q_o, q_c) - result *= 2 - - result *= extend_one_entity([1, 2]) - return result +# def compute_second_example(): +# result = 0 +# w_l = np.array([ 1, 3, 5, 7, 9, 11, 13]) +# w_r = np.array([ 2, 4, 6, 8, 10, 12, 14]) +# w_o = np.array([ 3, 7, 11, 15, 19, 23, 27]) +# q_m = np.array([ 0, 0, 0, 0, 0, 0, 0]) +# q_l = np.array([ 1, 1, 1, 1, 1, 1, 1]) +# q_r = np.array([ 1, 1, 1, 1, 1, 1, 1]) +# q_o = np.array([-1, -1, -1, -1, -1, -1, -1]) +# q_c = np.array([ 0, 0, 0, 0, 0, 0, 0]) +# # contribution is zero, but why not? +# result += rel(w_l, w_r, w_o, q_m, q_l, q_r, q_o, q_c) + +# w_l = np.array([ 0, 1, 2, 3, 4, 5, 6]) +# w_r = np.array([ 4, 4, 4, 4, 4, 4, 4]) +# w_o = np.array([ 4, 4, 4, 4, 4, 4, 4]) +# q_m = np.array([ 0, 1, 2, 3, 4, 5, 6]) +# q_l = np.array([ 1, 0, -1, -2, -3, -4, -5]) +# q_r = np.array([ 1, 0, -1, -2, -3, -4, -5]) +# q_o = np.array([-1, -1, -1, -1, -1, -1, -1]) +# q_c = np.array([ 0, 0, 0, 0, 0, 0, 0]) + +# result += rel(w_l, w_r, w_o, q_m, q_l, q_r, q_o, q_c) +# result *= 2 + +# # result *= extend_one_entity([1, 2]) +# return result if __name__ == "__main__": - print(f"First example: \n {compute_first_example()}") - print(f"Second example:\n {compute_second_example()}") + # print(f"First example: \n {compute_first_example()}") + # print(f"Second example:\n {compute_second_example()}") + print(compute_first_example()) + # print(compute_second_example()) 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 8c35ce4d40b..eafbd1ff410 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp @@ -127,7 +127,7 @@ TEST_F(ProtoGalaxyTests, PerturbatorCoefficients) } } -TEST_F(ProtoGalaxyTests, PowPerturbatorPolynomial) +TEST_F(ProtoGalaxyTests, PerturbatorPolynomial) { const size_t log_instance_size(3); const size_t instance_size(1 << log_instance_size); @@ -147,17 +147,8 @@ TEST_F(ProtoGalaxyTests, PowPerturbatorPolynomial) 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 res = FF(1); - for (size_t j = i, beta_idx = 0; j > 0; j >>= 1, beta_idx++) { - if ((j & 1) == 1) { - res *= betas[beta_idx]; - } - } - pow_beta[i] = res; - } + // Construct pow(\vec{betas}) as in the paper + auto pow_beta = ProtoGalaxyProver::compute_pow_polynomial_at_values(betas, instance_size); // Compute the corresponding target sum and create a dummy accumulator auto target_sum = FF(0); @@ -178,4 +169,6 @@ 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); } + +TEST_F(ProtoGalaxyTests, PowCorrectness) {} } // 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 638557681f0..495c3b9ba18 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp @@ -47,14 +47,13 @@ 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[0] == accumulator->folding_parameters->target_sum); + assert(perturbator[0] == accumulator->folding_parameters.target_sum); for (size_t idx = 0; idx <= log_instance_size; idx++) { transcript.send_to_verifier("perturbator_" + std::to_string(idx), perturbator[idx]); } auto perturbator_challenge = transcript.get_challenge("perturbator_challenge"); auto compressed_perturbator = perturbator.evaluate(perturbator_challenge); // horner - static_cast(compressed_perturbator); // sanity check: i think we don't care about elemnt 0th element of beta, it is 1 std::vector betas_star(log_instance_size); @@ -64,16 +63,17 @@ ProverFoldingResult ProtoGalaxyProver_relation_parameters, pow_betas_star, alpha); const auto combiner_quotient_size = (log_instance_size - 1) * Flavor::MAX_RELATION_LENGTH; std::vector lagrange_0(combiner_quotient_size); std::vector vanishing_polynomial(combiner_quotient_size); - // combiner_quotient evaluations from k to dk + 1 - // TODO: make this univariates - // WARNING: barycentric evaluations might not work here ???? + + // degree dk - k = d(k - 1) so length is d(k-1) + 1 std::array combiner_quotient_coeffs; + + // we need to evaluate at values not part in the vanishing set for (size_t point = log_instance_size; point < combiner.size(); point++) { auto idx = point - log_instance_size; lagrange_0[idx] = FF(1) - FF(point); @@ -86,7 +86,8 @@ ProverFoldingResult ProtoGalaxyProver_ combiner_quotient( + combiner_quotient_coeffs); auto combiner_challenge = transcript.get_challenge("combiner_qoutient_challenge"); auto combiner_quotient_at_challenge = combiner_quotient.evaluate(combiner_challenge); auto vanishing_polynomial_at_challenge = combiner_challenge * (combiner_challenge - FF(1)); @@ -101,7 +102,7 @@ ProverFoldingResult ProtoGalaxyProver_ ProtoGalaxyProver_ res; - res.folded_prover_polynomials = accumalator->prover_polynomials; + res.folded_prover_polynomials = accumulator->prover_polynomials; res.params.target_sum = new_target_sum; res.params.gate_separation_challenges = betas_star; res.folding_data = transcript.proof_data; 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 d83a28e9207..30f0954254d 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp @@ -48,7 +48,7 @@ template class ProtoGalaxyProver_ { */ void prepare_for_folding(); - std::vector compute_pow_polynomials_at_values(const std::vector betas, const size_t instance_size) + static std::vector compute_pow_polynomial_at_values(const std::vector betas, const size_t instance_size) { std::vector pow_betas(instance_size); for (size_t i = 0; i < instance_size; i++) { 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 129d104f55e..b3e937847e0 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.cpp @@ -6,7 +6,7 @@ VerifierFoldingResult ProtoGalaxyVerifier_< VerifierInstances>::fold_public_parameters(std::vector fold_data) { using Flavor = typename VerifierInstances::Flavor; - using VerificationKey = typename Flavor::VerificationKey; + // using VerificationKey = typename Flavor::VerificationKey; transcript = VerifierTranscript{ fold_data }; auto index = 0; @@ -42,25 +42,24 @@ VerifierFoldingResult ProtoGalaxyVerifier_< for (size_t idx = 0; idx <= log_instance_size; idx++) { perturbator_coeffs[idx] = transcript.template receive_from_prover("perturbator_" + std::to_string(idx)); } - assert(perturbator_coeffs[0] == accumulator->folding_parameters->target_sum); + assert(perturbator_coeffs[0] == accumulator->folding_parameters.target_sum); auto perturbator = Polynomial(perturbator_coeffs); auto perturbator_challenge = transcript.get_challenge("perturbator_challenge"); auto perturbator_at_challenge = perturbator.evaluate(perturbator_challenge); // horner - static_cast(perturbator_at_challenge); - // get the coefficient of combiner quotient (K(X) polynomial in the paper) - // + 2 because we need one extra eval to rep a poly of certain degree - auto combiner_quotient_size = Flavor::MAX_RANDOM_RELATION_LENGTH * (VerifierInstances::NUM - 1) + 2; - std::vector combiner_quotient_coeffs(combiner_quotient_size); + + std::array + combiner_quotient_coeffs; + auto combiner_quotient_size = (Flavor::MAX_RANDOM_RELATION_LENGTH - 1) * (VerifierInstances::NUM - 1) + 1; for (size_t idx = 0; idx < combiner_quotient_size; idx++) { combiner_quotient_coeffs[idx] = transcript.template receive_from_prover("combiner_quotient_" + std::to_string(idx)); } - auto combiner_quotient = Polynomial(combiner_quotient_coeffs); + Univariate combiner_quotient( + combiner_quotient_coeffs); auto combiner_challenge = transcript.get_challenge("combiner_quotient_challenge"); - static_cast(combiner_challenge); - // fix k = 1 which means k+1 = 2 is a power of two auto combiner_quotient_at_challenge = combiner_quotient.evaluate(combiner_challenge); // K(\gamma) + // WORKTODO make functions for bigger Z and more lagrange basis auto vanishing_polynomial_at_challenge = combiner_challenge * (combiner_challenge - FF(1)); auto lagrange_0_at_challenge = FF(1) - combiner_challenge; auto lagrange_1_at_challenge = combiner_challenge; From 265f2485c15de3cb1d59e9307a31f71e232cd3f0 Mon Sep 17 00:00:00 2001 From: maramihali Date: Mon, 6 Nov 2023 12:02:31 +0000 Subject: [PATCH 06/86] wip that works --- .../honk/proof_system/folding_result.hpp | 2 +- .../honk/proof_system/protogalaxy.test.cpp | 93 +++++++++++- .../honk/proof_system/protogalaxy_prover.cpp | 68 +++------ .../honk/proof_system/protogalaxy_prover.hpp | 25 +++ .../proof_system/protogalaxy_verifier.cpp | 80 +++++----- .../proof_system/protogalaxy_verifier.hpp | 2 + .../honk/proof_system/ultra_verifier.hpp | 2 +- .../honk/transcript/transcript.test.cpp | 77 +++++----- .../barretenberg/polynomials/barycentric.hpp | 26 ++-- .../barretenberg/polynomials/univariate.hpp | 143 +++++++++--------- .../polynomials/univariate.test.cpp | 8 + .../relations/nested_containers.hpp | 26 ++-- .../transcript/transcript.test.cpp | 2 +- 13 files changed, 338 insertions(+), 216 deletions(-) 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 5888d866b04..490cc62c8a3 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/folding_result.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/folding_result.hpp @@ -17,7 +17,7 @@ template struct VerifierFoldingResult { using VerificationKey = typename Flavor::VerificationKey; using FoldingParameters = typename Flavor::FoldingParameters; std::vector folded_public_inputs; - VerificationKey folded_verification_key; + std::shared_ptr folded_verification_key; FoldingParameters parameters; }; 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 eafbd1ff410..ff95f2630fe 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy.test.cpp @@ -1,5 +1,6 @@ // Note these tests are a bit hacky #include "barretenberg/honk/composer/ultra_composer.hpp" +#include "barretenberg/honk/utils/testing.hpp" #include "protogalaxy_prover.hpp" #include using namespace proof_system::honk; @@ -10,7 +11,9 @@ using Instances = ProverInstances_; using ProtoGalaxyProver = ProtoGalaxyProver_; using FF = Flavor::FF; using Builder = Flavor::CircuitBuilder; +using Polynomial = typename Flavor::Polynomial; using ProverPolynomials = Flavor::ProverPolynomials; +using RelationParameters = proof_system::RelationParameters; const size_t NUM_POLYNOMIALS = Flavor::NUM_ALL_ENTITIES; namespace protogalaxy_tests { @@ -170,5 +173,93 @@ TEST_F(ProtoGalaxyTests, PerturbatorPolynomial) EXPECT_EQ(perturbator[0], target_sum); } -TEST_F(ProtoGalaxyTests, PowCorrectness) {} +TEST_F(ProtoGalaxyTests, CombinerQuotient) +{ + auto compressed_perturbator = FF(2); + auto combiner = barretenberg::Univariate(std::array{ + 20, + 21, + 22, + 23, + 24, + 25, + 26, + }); + auto combiner_quotient = ProtoGalaxyProver::compute_combiner_quotient(compressed_perturbator, combiner); + + auto expected_evals = barretenberg::Univariate(std::array{ + (FF(22) - (FF(1) - FF(2)) * compressed_perturbator) / (FF(2) * FF(2 - 1)), + (FF(23) - (FF(1) - FF(3)) * compressed_perturbator) / (FF(3) * FF(3 - 1)), + (FF(24) - (FF(1) - FF(4)) * compressed_perturbator) / (FF(4) * FF(4 - 1)), + (FF(25) - (FF(1) - FF(5)) * compressed_perturbator) / (FF(5) * FF(5 - 1)), + (FF(26) - (FF(1) - FF(6)) * compressed_perturbator) / (FF(6) * FF(6 - 1)), + }); + + for (size_t idx = 2; idx < 7; idx++) { + EXPECT_EQ(combiner_quotient.value_at(idx), expected_evals.value_at(idx)); + } +} + +// TEST_F(ProtoGalaxyTests, Galaxify) +// { +// auto composer = UltraComposer(); + +// // Create instance from actual circuit +// std::vector>> insts(2); +// auto builder = proof_system::UltraCircuitBuilder(); +// auto a = FF::random_element(); +// auto b = FF::random_element(); +// builder.add_variable(a); +// builder.add_public_variable(a); +// builder.add_public_variable(b); +// insts[1] = composer.create_instance(builder); + +// auto instance_size = insts[1]->proving_key->circuit_size; +// auto log_instance_size = static_cast(numeric::get_msb(instance_size)); + +// // Create fake accumulator +// std::array, NUM_POLYNOMIALS> random_polynomials; +// for (auto& poly : random_polynomials) { +// poly = get_random_polynomial(instance_size); +// } +// auto full_polynomials = construct_ultra_full_polynomials(random_polynomials); +// 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); +// 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}) as in the paper +// auto pow_beta = ProtoGalaxyProver::compute_pow_polynomial_at_values(betas, instance_size); + +// // Compute the corresponding target sum and create a dummy accumulator +// auto target_sum = FF(0); +// for (size_t i = 0; i < instance_size; i++) { +// target_sum += full_honk_evals[i] * pow_beta[i]; +// } + +// insts[0] = std::make_shared( +// FoldingResult{ .folded_prover_polynomials = full_polynomials, +// .folded_public_inputs = std::vector{}, +// .verification_key = std::make_shared(), +// .folding_parameters = { betas, target_sum } }); +// insts[0]->relation_parameters = relation_parameters; + +// // artificially make first instance relaxed + +// auto prover = composer.create_folding_prover(insts); +// auto verifier = composer.create_folding_verifier(insts); +// prover.prepare_for_folding(); +// auto new_target_sum_prover = prover.galaxify(alpha)[0]; + +// verifier.prepare_for_folding(prover.transcript.proof_data); +// auto new_target_sum_verifier = verifier.galaxify(alpha)[0]; +// info(new_target_sum_prover); +// info(new_target_sum_verifier); +// } + } // 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 495c3b9ba18..8c4f3d65b5a 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.cpp @@ -4,7 +4,6 @@ namespace proof_system::honk { template void ProtoGalaxyProver_::prepare_for_folding() { - // this doesnt work in the current format auto idx = 0; for (auto it = instances.begin(); it != instances.end(); it++, idx++) { auto instance = *it; @@ -24,14 +23,13 @@ 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 + // 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); instance->compute_grand_product_polynomials(beta, gamma); } - // need to check all instances have the same circuit size!! } // TODO(#https://github.com/AztecProtocol/barretenberg/issues/689): finalise implementation this function @@ -46,65 +44,45 @@ ProverFoldingResult ProtoGalaxyProver_prover_polynomials[0].size(); const auto log_instance_size = static_cast(numeric::get_msb(instance_size)); auto deltas = compute_round_challenge_pows(log_instance_size, delta); + // This is not OK here auto perturbator = compute_perturbator(accumulator, deltas, alpha); - assert(perturbator[0] == accumulator->folding_parameters.target_sum); for (size_t idx = 0; idx <= log_instance_size; idx++) { transcript.send_to_verifier("perturbator_" + std::to_string(idx), perturbator[idx]); } auto perturbator_challenge = transcript.get_challenge("perturbator_challenge"); - auto compressed_perturbator = perturbator.evaluate(perturbator_challenge); // horner - - // sanity check: i think we don't care about elemnt 0th element of beta, it is 1 + auto compressed_perturbator = perturbator.evaluate(perturbator_challenge); std::vector betas_star(log_instance_size); betas_star[0] = 1; auto betas = accumulator->folding_parameters.gate_separation_challenges; - for (size_t idx = 1; idx <= log_instance_size; idx++) { + for (size_t idx = 1; idx < log_instance_size; idx++) { betas_star[idx] = betas[idx] + perturbator_challenge * deltas[idx - 1]; } auto pow_betas_star = compute_pow_polynomial_at_values(betas_star, instance_size); auto combiner = compute_combiner(instances, accumulator->relation_parameters, pow_betas_star, alpha); - const auto combiner_quotient_size = (log_instance_size - 1) * Flavor::MAX_RELATION_LENGTH; - std::vector lagrange_0(combiner_quotient_size); - std::vector vanishing_polynomial(combiner_quotient_size); - - // degree dk - k = d(k - 1) so length is d(k-1) + 1 - std::array combiner_quotient_coeffs; - - // we need to evaluate at values not part in the vanishing set - for (size_t point = log_instance_size; point < combiner.size(); point++) { - auto idx = point - log_instance_size; - lagrange_0[idx] = FF(1) - FF(point); - vanishing_polynomial[idx] = FF(point) * (FF(point) - 1); - combiner_quotient_coeffs[idx] = - (combiner.value_at(point) - compressed_perturbator * lagrange_0[idx]) / vanishing_polynomial[idx]; - } - - for (size_t idx = 0; idx < combiner_quotient_size; idx++) { - transcript.send_to_verifier("combiner_quotient_" + std::to_string(idx), combiner_quotient_coeffs[idx]); + auto combiner_quotient = compute_combiner_quotient(compressed_perturbator, combiner); + for (size_t idx = ProverInstances::NUM; idx < combiner.size(); idx++) { + transcript.send_to_verifier("combiner_quotient_" + std::to_string(idx), combiner_quotient.value_at(idx)); } - - Univariate combiner_quotient( - combiner_quotient_coeffs); auto combiner_challenge = transcript.get_challenge("combiner_qoutient_challenge"); auto combiner_quotient_at_challenge = combiner_quotient.evaluate(combiner_challenge); auto vanishing_polynomial_at_challenge = combiner_challenge * (combiner_challenge - FF(1)); auto lagrange_0_at_challenge = FF(1) - combiner_challenge; - auto lagrange_1_at_challenge = combiner_challenge; - auto new_target_sum = compressed_perturbator * lagrange_0_at_challenge + vanishing_polynomial_at_challenge + - combiner_quotient_at_challenge; - - for (size_t idx = 0; idx < accumulator->prover_polynomials.size(); idx++) { - auto accumulator_poly = accumulator->prover_polynomials[idx]; - auto instance_poly = accumulator->prover_polynomials[idx]; - assert(accumulator_poly.size() == instance_poly.size()); - for (size_t j = 0; j < accumulator_poly.size(); j++) { - accumulator_poly[j] = - accumulator_poly[j] * lagrange_0_at_challenge + instance_poly[j] * lagrange_1_at_challenge; - } - } + // auto lagrange_1_at_challenge = combiner_challenge; + auto new_target_sum = compressed_perturbator * lagrange_0_at_challenge + + vanishing_polynomial_at_challenge * combiner_quotient_at_challenge; + + // for (size_t idx = 0; idx < accumulator->prover_polynomials.size(); idx++) { + // auto accumulator_poly = accumulator->prover_polynomials[idx]; + // auto instance_poly = accumulator->prover_polynomials[idx]; + // assert(accumulator_poly.size() == instance_poly.size()); + // for (size_t j = 0; j < accumulator_poly.size(); j++) { + // accumulator_poly[j] = + // accumulator_poly[j] * lagrange_0_at_challenge + instance_poly[j] * lagrange_1_at_challenge; + // } + // } // i have dk evaluations out of which the first k are not good so we evaluate the rest of the polynomials from // k+1 @@ -112,9 +90,9 @@ ProverFoldingResult ProtoGalaxyProver_ res; - res.folded_prover_polynomials = accumulator->prover_polynomials; + // res.folded_prover_polynomials = accumulator->prover_polynomials; res.params.target_sum = new_target_sum; - res.params.gate_separation_challenges = betas_star; + // res.params.gate_separation_challenges = betas_star; 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 30f0954254d..5037161968a 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_prover.hpp @@ -48,6 +48,8 @@ template class ProtoGalaxyProver_ { */ void prepare_for_folding(); + std::array galaxify(FF); + static std::vector compute_pow_polynomial_at_values(const std::vector betas, const size_t instance_size) { std::vector pow_betas(instance_size); @@ -291,6 +293,29 @@ template class ProtoGalaxyProver_ { // Batch the univariate contributions from each sub-relation to obtain the round univariate return Utils::template batch_over_relations(univariate_accumulators, alpha); } + + static Univariate + compute_combiner_quotient(FF compressed_perturbator, RandomExtendedUnivariate combiner) + { + // degree dk - k - 1 = d(k - 1) - 1 + std::array + combiner_quotient_evals = {}; + + // we need to evaluate at values not part in the vanishing set + for (size_t point = ProverInstances::NUM; point < combiner.size(); point++) { + auto idx = point - ProverInstances::NUM; + auto lagrange_0 = FF(1) - FF(point); + auto vanishing_polynomial = FF(point) * (FF(point) - 1); + combiner_quotient_evals[idx] = + (combiner.value_at(point) - compressed_perturbator * lagrange_0) / vanishing_polynomial; + } + + Univariate + combiner_quotient(combiner_quotient_evals); + return combiner_quotient; + } }; extern template class ProtoGalaxyProver_>; 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 b3e937847e0..b3db9945e50 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.cpp @@ -1,13 +1,10 @@ #include "protogalaxy_verifier.hpp" #include "barretenberg/honk/utils/grand_product_delta.hpp" namespace proof_system::honk { + template -VerifierFoldingResult ProtoGalaxyVerifier_< - VerifierInstances>::fold_public_parameters(std::vector fold_data) +void ProtoGalaxyVerifier_::prepare_for_folding(std::vector fold_data) { - using Flavor = typename VerifierInstances::Flavor; - // using VerificationKey = typename Flavor::VerificationKey; - transcript = VerifierTranscript{ fold_data }; auto index = 0; for (auto it = verifier_instances.begin(); it != verifier_instances.end(); it++, index++) { @@ -32,9 +29,16 @@ VerifierFoldingResult ProtoGalaxyVerifier_< inst->relation_parameters = RelationParameters{ eta, beta, gamma, public_input_delta, lookup_grand_product_delta }; } +} + +template +VerifierFoldingResult ProtoGalaxyVerifier_< + VerifierInstances>::fold_public_parameters(std::vector fold_data) +{ + using Flavor = typename VerifierInstances::Flavor; - auto [alpha, delta] = - transcript.get_challenges("alpha", "delta"); // what does verifier do with this alpha which is from plonk paper? + prepare_for_folding(fold_data); + auto [alpha, delta] = transcript.get_challenges("alpha", "delta"); 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); @@ -42,50 +46,46 @@ VerifierFoldingResult ProtoGalaxyVerifier_< for (size_t idx = 0; idx <= log_instance_size; idx++) { perturbator_coeffs[idx] = transcript.template receive_from_prover("perturbator_" + std::to_string(idx)); } - assert(perturbator_coeffs[0] == accumulator->folding_parameters.target_sum); auto perturbator = Polynomial(perturbator_coeffs); auto perturbator_challenge = transcript.get_challenge("perturbator_challenge"); - auto perturbator_at_challenge = perturbator.evaluate(perturbator_challenge); // horner - - std::array - combiner_quotient_coeffs; - auto combiner_quotient_size = (Flavor::MAX_RANDOM_RELATION_LENGTH - 1) * (VerifierInstances::NUM - 1) + 1; - for (size_t idx = 0; idx < combiner_quotient_size; idx++) { - combiner_quotient_coeffs[idx] = - transcript.template receive_from_prover("combiner_quotient_" + std::to_string(idx)); + auto perturbator_at_challenge = perturbator.evaluate(perturbator_challenge); + std::array + combiner_quotient_evals = {}; + for (size_t idx = 0; idx < (Flavor::MAX_RANDOM_RELATION_LENGTH - 2) * (VerifierInstances::NUM - 1); idx++) { + combiner_quotient_evals[idx] = transcript.template receive_from_prover( + "combiner_quotient_" + std::to_string(idx + VerifierInstances::NUM)); } - Univariate combiner_quotient( - combiner_quotient_coeffs); + Univariate + combiner_quotient(combiner_quotient_evals); auto combiner_challenge = transcript.get_challenge("combiner_quotient_challenge"); - auto combiner_quotient_at_challenge = combiner_quotient.evaluate(combiner_challenge); // K(\gamma) // WORKTODO make functions for bigger Z and more lagrange basis auto vanishing_polynomial_at_challenge = combiner_challenge * (combiner_challenge - FF(1)); auto lagrange_0_at_challenge = FF(1) - combiner_challenge; - auto lagrange_1_at_challenge = combiner_challenge; - auto updated_target_sum = perturbator_at_challenge * lagrange_0_at_challenge + - vanishing_polynomial_at_challenge * combiner_quotient_at_challenge; + // auto lagrange_1_at_challenge = combiner_challenge; + auto new_target_sum = perturbator_at_challenge * lagrange_0_at_challenge + + vanishing_polynomial_at_challenge * combiner_quotient_at_challenge; - // do public input stuff with goblin (well I guess first without) - // fold public inputs (field elements) and the commitment in verification key to obtain a new verification key! - // TODO: extend for more instances; - auto accumulator_public_inputs = accumulator->public_inputs; - auto other_public_inputs = verifier_instances[1]->public_inputs; - std::vector folded_public_inputs(accumulator->public_input_size); - // extend either with 0s if the sizes are different - for (size_t idx = 0; idx < folded_public_inputs.size(); idx++) { - folded_public_inputs[idx] = lagrange_0_at_challenge * accumulator->public_inputs[idx] + - lagrange_1_at_challenge * other_public_inputs[idx]; - } - // all verification keys have the same size - auto folded_verification_key = VerificationKey(accumulator->instance_size, accumulator->public_input_size); + // auto accumulator_public_inputs = accumulator->public_inputs; + // auto other_public_inputs = verifier_instances[1]->public_inputs; + // std::vector folded_public_inputs(accumulator->public_input_size); + // // extend either with 0s if the sizes are different + // for (size_t idx = 0; idx < folded_public_inputs.size(); idx++) { + // folded_public_inputs[idx] = lagrange_0_at_challenge * accumulator->public_inputs[idx] + + // lagrange_1_at_challenge * other_public_inputs[idx]; + // } + // // all verification keys have the same size + // auto folded_verification_key = + // std::make_shared(accumulator->instance_size, accumulator->public_input_size); - for (size_t idx = 0; idx < folded_verification_key.size(); idx++) { - folded_verification_key[idx] = (*accumulator->verification_key)[idx] * lagrange_0_at_challenge + - (*verifier_instances[1]->verification_key)[idx] * lagrange_1_at_challenge; - } + // for (size_t idx = 0; idx < (*folded_verification_key).size(); idx++) { + // (*folded_verification_key)[idx] = (*accumulator->verification_key)[idx] * lagrange_0_at_challenge + + // (*verifier_instances[1]->verification_key)[idx] * lagrange_1_at_challenge; + // } VerifierFoldingResult res; - res.parameters.target_sum = updated_target_sum; + res.parameters.target_sum = new_target_sum; + // res.folded_verification_key = folded_verification_key; + // res.folded_public_inputs = folded_public_inputs; 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 309fcadcdd5..590d336869c 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/protogalaxy_verifier.hpp @@ -35,6 +35,8 @@ template class ProtoGalaxyVerifier_ { } std::shared_ptr get_accumulator() { return verifier_instances[0]; } + void prepare_for_folding(std::vector fold_data); + VerifierFoldingResult fold_public_parameters(std::vector fold_data); }; diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/ultra_verifier.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/ultra_verifier.hpp index 34c524672d5..32e4c0f1fb7 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/ultra_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/ultra_verifier.hpp @@ -14,7 +14,7 @@ template class UltraVerifier_ { public: explicit UltraVerifier_(std::shared_ptr verifier_key = nullptr); UltraVerifier_(UltraVerifier_&& other); - UltraVerifier_(const UltraVerifier_& other) = delete; + UltraVerifier_& operator=(const UltraVerifier_& other) = delete; UltraVerifier_& operator=(UltraVerifier_&& other); diff --git a/barretenberg/cpp/src/barretenberg/honk/transcript/transcript.test.cpp b/barretenberg/cpp/src/barretenberg/honk/transcript/transcript.test.cpp index 3a0271bdd8d..2060a93df14 100644 --- a/barretenberg/cpp/src/barretenberg/honk/transcript/transcript.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/transcript/transcript.test.cpp @@ -197,41 +197,42 @@ TEST_F(UltraTranscriptTests, ChallengeGenerationTest) ASSERT_NE(b, 0) << "Challenge a is 0"; } -TEST_F(UltraTranscriptTests, FoldingManifestTest) -{ - using Flavor = flavor::Ultra; - auto composer = UltraComposer(); - - std::vector>> insts(2); - std::generate(insts.begin(), insts.end(), [&]() { - auto builder = proof_system::UltraCircuitBuilder(); - auto a = FF::random_element(); - auto b = FF::random_element(); - builder.add_variable(a); - builder.add_public_variable(a); - builder.add_public_variable(b); - return composer.create_instance(builder); - }); - - // artificially make first instance relaxed - auto log_instance_size = static_cast(numeric::get_msb(insts[0]->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(); - } - insts[0]->folding_parameters = { betas, FF(1) }; - - auto prover = composer.create_folding_prover(insts); - auto verifier = composer.create_folding_verifier(insts); - - auto prover_res = prover.fold_instances(); - verifier.fold_public_parameters(prover_res.folding_data); - - // Check consistency between the manifests generated by the prover and verifier - auto prover_manifest = prover.transcript.get_manifest(); - auto verifier_manifest = verifier.transcript.get_manifest(); - for (size_t round = 0; round < prover_manifest.size(); ++round) { - ASSERT_EQ(prover_manifest[round], verifier_manifest[round]) - << "Prover/Verifier manifest discrepency in round " << round; - } -} +// TEST_F(UltraTranscriptTests, FoldingManifestTest) +// { +// using Flavor = flavor::Ultra; +// auto composer = UltraComposer(); + +// std::vector>> insts(2); +// std::generate(insts.begin(), insts.end(), [&]() { +// auto builder = proof_system::UltraCircuitBuilder(); +// auto a = FF::random_element(); +// auto b = FF::random_element(); +// builder.add_variable(a); +// builder.add_public_variable(a); +// builder.add_public_variable(b); +// return composer.create_instance(builder); +// }); + +// // artificially make first instance relaxed +// auto log_instance_size = static_cast(numeric::get_msb(insts[0]->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(); +// } +// insts[0]->folding_parameters = { betas, FF(1) }; + +// auto prover = composer.create_folding_prover(insts); +// auto verifier = composer.create_folding_verifier(insts); + +// auto prover_res = prover.fold_instances(); +// verifier.fold_public_parameters(prover_res.folding_data); + +// // Check consistency between the manifests generated by the prover and verifier +// auto prover_manifest = prover.transcript.get_manifest(); +// auto verifier_manifest = verifier.transcript.get_manifest(); + +// for (size_t round = 0; round < prover_manifest.size(); ++round) { +// ASSERT_EQ(prover_manifest[round], verifier_manifest[round]) +// << "Prover/Verifier manifest discrepency in round " << round; +// } +// } diff --git a/barretenberg/cpp/src/barretenberg/polynomials/barycentric.hpp b/barretenberg/cpp/src/barretenberg/polynomials/barycentric.hpp index a8ddb6d30d3..27cd1c8631b 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/barycentric.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/barycentric.hpp @@ -20,22 +20,25 @@ namespace barretenberg { /** * @todo: TODO(https://github.com/AztecProtocol/barretenberg/issues/713) Optimize with lookup tables? + * @tparam domain_end, domain_start specify the given evaluation domain {domain_start,..., domain_end - 1} + * @tparam num_evals the number of evaluations that are computable with specific barycentric extension formula */ -template class BarycentricDataCompileTime { +template class BarycentricDataCompileTime { public: + static constexpr size_t domain_size = domain_end - domain_start; static constexpr size_t big_domain_size = std::max(domain_size, num_evals); /** * Static constexpr methods for computing arrays of precomputable data used for barycentric extension and evaluation */ - // build big_domain, currently the set of x_i in {0, 1, ..., t-1} + // build big_domain, currently the set of x_i in {domain_start, ..., big_domain_end - 1 } static constexpr std::array construct_big_domain() { std::array result; for (size_t i = 0; i < big_domain_size; ++i) { - result[i] = static_cast(i); + result[i] = static_cast(i + domain_start); } return result; } @@ -109,7 +112,7 @@ template class BarycentricDataC std::array result; for (size_t i = 0; i != num_evals; ++i) { result[i] = 1; - Fr v_i = i; + Fr v_i = i + domain_start; for (size_t j = 0; j != domain_size; ++j) { result[i] *= v_i - big_domain[j]; } @@ -124,20 +127,21 @@ template class BarycentricDataC static constexpr auto full_numerator_values = construct_full_numerator_values(big_domain); }; -template class BarycentricDataRunTime { +template class BarycentricDataRunTime { public: + static constexpr size_t domain_size = domain_end - domain_start; static constexpr size_t big_domain_size = std::max(domain_size, num_evals); /** * Static constexpr methods for computing arrays of precomputable data used for barycentric extension and evaluation */ - // build big_domain, currently the set of x_i in {0, 1, ..., t-1} + // build big_domain, currently the set of x_i in {domain_start, ..., big_domain_end - 1 } static std::array construct_big_domain() { std::array result; for (size_t i = 0; i < big_domain_size; ++i) { - result[i] = static_cast(i); + result[i] = static_cast(i + domain_start); } return result; } @@ -210,7 +214,7 @@ template class BarycentricDataR std::array result; for (size_t i = 0; i != num_evals; ++i) { result[i] = 1; - Fr v_i = i; + Fr v_i = i + domain_start; for (size_t j = 0; j != domain_size; ++j) { result[i] *= v_i - big_domain[j]; } @@ -247,9 +251,9 @@ template inline constexpr bool is_field_type_v = is_field_type:: * @tparam domain_size * @tparam num_evals */ -template +template using BarycentricData = std::conditional_t, - BarycentricDataCompileTime, - BarycentricDataRunTime>; + BarycentricDataCompileTime, + BarycentricDataRunTime>; } // namespace barretenberg diff --git a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp index 0ca83be0654..93773dd5685 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp @@ -13,22 +13,24 @@ namespace barretenberg { * of the data in those univariates. We do that by taking a view of those elements and then, as needed, using this to * populate new containers. */ -template class UnivariateView; +template class UnivariateView; /** - * @brief A univariate polynomial represented by its values on {0,1,..., _length-1} + * @brief A univariate polynomial represented by its values on {domain_start, domain_start + 1,..., domain_end - 1}. For + * memory efficiency purposes, we store the evaluations in an array starting from 0 and make the mapping to the right + * domain under the hood. */ -template class Univariate { +template class Univariate { public: - static constexpr size_t LENGTH = _length; - using View = UnivariateView; + static constexpr size_t LENGTH = domain_end - domain_start; + using View = UnivariateView; // TODO(https://github.com/AztecProtocol/barretenberg/issues/714) Try out std::valarray? - std::array evaluations; + std::array evaluations; Univariate() = default; - explicit Univariate(std::array evaluations) + explicit Univariate(std::array evaluations) : evaluations(evaluations) {} ~Univariate() = default; @@ -40,12 +42,12 @@ template class Univariate { explicit Univariate(Fr value) : evaluations{} { - for (size_t i = 0; i < _length; ++i) { + for (size_t i = 0; i < LENGTH; ++i) { evaluations[i] = value; } } // Construct Univariate from UnivariateView - explicit Univariate(UnivariateView in) + explicit Univariate(UnivariateView in) : evaluations{} { for (size_t i = 0; i < in.evaluations.size(); ++i) { @@ -53,8 +55,8 @@ template class Univariate { } } - Fr& value_at(size_t i) { return evaluations[i]; }; - const Fr& value_at(size_t i) const { return evaluations[i]; }; + Fr& value_at(size_t i) { return evaluations[i - domain_start]; }; + const Fr& value_at(size_t i) const { return evaluations[i - domain_start]; }; size_t size() { return evaluations.size(); }; // Write the Univariate evaluations to a buffer @@ -72,8 +74,8 @@ template class Univariate { static Univariate get_random() { - auto output = Univariate(); - for (size_t i = 0; i != _length; ++i) { + auto output = Univariate(); + for (size_t i = 0; i != LENGTH; ++i) { output.value_at(i) = Fr::random_element(); } return output; @@ -84,21 +86,21 @@ template class Univariate { Univariate& operator+=(const Univariate& other) { - for (size_t i = 0; i < _length; ++i) { + for (size_t i = 0; i < LENGTH; ++i) { evaluations[i] += other.evaluations[i]; } return *this; } Univariate& operator-=(const Univariate& other) { - for (size_t i = 0; i < _length; ++i) { + for (size_t i = 0; i < LENGTH; ++i) { evaluations[i] -= other.evaluations[i]; } return *this; } Univariate& operator*=(const Univariate& other) { - for (size_t i = 0; i < _length; ++i) { + for (size_t i = 0; i < LENGTH; ++i) { evaluations[i] *= other.evaluations[i]; } return *this; @@ -178,45 +180,45 @@ template class Univariate { } // Operations between Univariate and UnivariateView - Univariate& operator+=(const UnivariateView& view) + Univariate& operator+=(const UnivariateView& view) { - for (size_t i = 0; i < _length; ++i) { + for (size_t i = 0; i < LENGTH; ++i) { evaluations[i] += view.evaluations[i]; } return *this; } - Univariate& operator-=(const UnivariateView& view) + Univariate& operator-=(const UnivariateView& view) { - for (size_t i = 0; i < _length; ++i) { + for (size_t i = 0; i < LENGTH; ++i) { evaluations[i] -= view.evaluations[i]; } return *this; } - Univariate& operator*=(const UnivariateView& view) + Univariate& operator*=(const UnivariateView& view) { - for (size_t i = 0; i < _length; ++i) { + for (size_t i = 0; i < LENGTH; ++i) { evaluations[i] *= view.evaluations[i]; } return *this; } - Univariate operator+(const UnivariateView& view) const + Univariate operator+(const UnivariateView& view) const { Univariate res(*this); res += view; return res; } - Univariate operator-(const UnivariateView& view) const + Univariate operator-(const UnivariateView& view) const { Univariate res(*this); res -= view; return res; } - Univariate operator*(const UnivariateView& view) const + Univariate operator*(const UnivariateView& view) const { Univariate res(*this); res *= view; @@ -240,23 +242,25 @@ template class Univariate { } /** - * @brief Given a univariate f represented by {f(0), ..., f(t-1)}, compute {f(t), ..., f(u-1)} - * and return the Univariate represented by {f(0), ..., f(u-1)}. + * @brief Given a univariate f represented by {f(domain_start), ..., f(domain_end - 1)}, compute the evaluations + * {f(domain_end),..., f(extended_domain_end -1)} and return the Univariate represented by {f(domain_start),..., + * f(extended_domain_end -1)} * - * @details Write v_i = f(x_i) on a the domain {x_0, ..., x_{t-1}}. To efficiently compute the needed values of f, - * we use the barycentric formula - * - f(x) = B(x) Σ_{i=0}^{t-1} v_i / (d_i*(x-x_i)) + * @details Write v_i = f(x_i) on a the domain {x_{domain_start}, ..., x_{domain_end-1}}. To efficiently compute the + * needed values of f, we use the barycentric formula + * - f(x) = B(x) Σ_{i=domain_start}^{domain_end-1} v_i / (d_i*(x-x_i)) * where - * - B(x) = Π_{i=0}^{t-1} (x-x_i) - * - d_i = Π_{j ∈ {0, ..., t-1}, j≠i} (x_i-x_j) for i ∈ {0, ..., t-1} + * - B(x) = Π_{i=domain_start}^{domain_end-1} (x-x_i) + * - d_i = Π_{j ∈ {domain_start, ..., domain_end-1}, j≠i} (x_i-x_j) for i ∈ {domain_start, ..., domain_end-1} * * When the domain size is two, extending f = v0(1-X) + v1X to a new value involves just one addition and a * subtraction: setting Δ = v1-v0, the values of f(X) are f(0)=v0, f(1)= v0 + Δ, v2 = f(1) + Δ, v3 = f(2) + Δ... * */ - template Univariate extend_to() const + template Univariate extend_to() const { - using Data = BarycentricData; + const size_t EXTENDED_LENGTH = EXTENDED_DOMAIN_END - domain_start; + using Data = BarycentricData; // ? static_assert(EXTENDED_LENGTH >= LENGTH); Univariate result; @@ -266,15 +270,15 @@ template class Univariate { if constexpr (LENGTH == 2) { Fr delta = value_at(1) - value_at(0); static_assert(EXTENDED_LENGTH != 0); - for (size_t idx = 1; idx < EXTENDED_LENGTH - 1; idx++) { + for (size_t idx = domain_start; idx < EXTENDED_DOMAIN_END - 1; idx++) { result.value_at(idx + 1) = result.value_at(idx) + delta; } return result; } else { - for (size_t k = LENGTH; k != EXTENDED_LENGTH; ++k) { + for (size_t k = domain_end; k != EXTENDED_DOMAIN_END; ++k) { result.value_at(k) = 0; // compute each term v_j / (d_j*(x-x_j)) of the sum - for (size_t j = 0; j != LENGTH; ++j) { + for (size_t j = domain_start; j != domain_end; ++j) { Fr term = value_at(j); term *= Data::precomputed_denominator_inverses[LENGTH * k + j]; result.value_at(k) += term; @@ -294,9 +298,9 @@ template class Univariate { */ Fr evaluate(const Fr& u) { - using Data = BarycentricData; + using Data = BarycentricData; Fr full_numerator_value = 1; - for (size_t i = 0; i != LENGTH; ++i) { + for (size_t i = domain_start; i != domain_end; ++i) { full_numerator_value *= u - i; } @@ -312,9 +316,9 @@ template class Univariate { Fr result = 0; // compute each term v_j / (d_j*(x-x_j)) of the sum - for (size_t i = 0; i != LENGTH; ++i) { + for (size_t i = domain_start; i != domain_end; ++i) { Fr term = value_at(i); - term *= denominator_inverses[i]; + term *= denominator_inverses[i - domain_start]; result += term; } // scale the sum by the the value of of B(x) @@ -323,98 +327,101 @@ template class Univariate { }; }; -template inline void read(B& it, Univariate& univariate) +template +inline void read(B& it, Univariate& univariate) { using serialize::read; read(it, univariate.evaluations); } -template inline void write(B& it, Univariate const& univariate) +template +inline void write(B& it, Univariate const& univariate) { using serialize::write; write(it, univariate.evaluations); } -template class UnivariateView { +template class UnivariateView { public: - std::span evaluations; + static constexpr size_t LENGTH = domain_end - domain_start; + std::span evaluations; UnivariateView() = default; const Fr& value_at(size_t i) const { return evaluations[i]; }; - template - explicit UnivariateView(const Univariate& univariate_in) - : evaluations(std::span(univariate_in.evaluations.data(), view_length)){}; + template + explicit UnivariateView(const Univariate& univariate_in) + : evaluations(std::span(univariate_in.evaluations.data(), LENGTH)){}; - Univariate operator+(const UnivariateView& other) const + Univariate operator+(const UnivariateView& other) const { - Univariate res(*this); + Univariate res(*this); res += other; return res; } - Univariate operator-(const UnivariateView& other) const + Univariate operator-(const UnivariateView& other) const { - Univariate res(*this); + Univariate res(*this); res -= other; return res; } - Univariate operator-() const + Univariate operator-() const { - Univariate res(*this); + Univariate res(*this); for (auto& eval : res.evaluations) { eval = -eval; } return res; } - Univariate operator*(const UnivariateView& other) const + Univariate operator*(const UnivariateView& other) const { - Univariate res(*this); + Univariate res(*this); res *= other; return res; } - Univariate operator*(const Univariate& other) const + Univariate operator*(const Univariate& other) const { - Univariate res(*this); + Univariate res(*this); res *= other; return res; } - Univariate operator+(const Univariate& other) const + Univariate operator+(const Univariate& other) const { - Univariate res(*this); + Univariate res(*this); res += other; return res; } - Univariate operator+(const Fr& other) const + Univariate operator+(const Fr& other) const { - Univariate res(*this); + Univariate res(*this); res += other; return res; } - Univariate operator-(const Fr& other) const + Univariate operator-(const Fr& other) const { - Univariate res(*this); + Univariate res(*this); res -= other; return res; } - Univariate operator*(const Fr& other) const + Univariate operator*(const Fr& other) const { - Univariate res(*this); + Univariate res(*this); res *= other; return res; } - Univariate operator-(const Univariate& other) const + Univariate operator-(const Univariate& other) const { - Univariate res(*this); + Univariate res(*this); res -= other; return res; } diff --git a/barretenberg/cpp/src/barretenberg/polynomials/univariate.test.cpp b/barretenberg/cpp/src/barretenberg/polynomials/univariate.test.cpp index 5138a51167a..01382baf50d 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/univariate.test.cpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/univariate.test.cpp @@ -158,4 +158,12 @@ TYPED_TEST(UnivariateTest, Serialization) } } +TYPED_TEST(UnivariateTest, EvaluationCustomDomain) +{ + UNIVARIATE_TESTS_ALIASES + + auto poly = Univariate(std::array{ 1, 2 }); + EXPECT_EQ(poly.evaluate(FF(5)), FF(5)); +} + } // namespace barretenberg::test_univariate diff --git a/barretenberg/cpp/src/barretenberg/proof_system/relations/nested_containers.hpp b/barretenberg/cpp/src/barretenberg/proof_system/relations/nested_containers.hpp index 601d4f35a83..c8cf2c7f315 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/relations/nested_containers.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/relations/nested_containers.hpp @@ -10,29 +10,35 @@ namespace proof_system { * * @details Credit: https://stackoverflow.com/a/60440611 */ -template