diff --git a/barretenberg/cpp/src/aztec/honk/proof_system/prover.cpp b/barretenberg/cpp/src/aztec/honk/proof_system/prover.cpp index 272235a19432..c567ce20da88 100644 --- a/barretenberg/cpp/src/aztec/honk/proof_system/prover.cpp +++ b/barretenberg/cpp/src/aztec/honk/proof_system/prover.cpp @@ -295,7 +295,7 @@ template void Prover::execute_relation_check_round using Sumcheck = sumcheck::Sumcheck; // Compute alpha challenge diff --git a/barretenberg/cpp/src/aztec/honk/proof_system/verifier.cpp b/barretenberg/cpp/src/aztec/honk/proof_system/verifier.cpp index 1a59358af531..0f1b513ae7c8 100644 --- a/barretenberg/cpp/src/aztec/honk/proof_system/verifier.cpp +++ b/barretenberg/cpp/src/aztec/honk/proof_system/verifier.cpp @@ -135,7 +135,7 @@ template bool Verifier::verify_pro auto sumcheck = Sumcheck(transcript); bool sumcheck_result = sumcheck.execute_verifier(); diff --git a/barretenberg/cpp/src/aztec/honk/sumcheck/relations/arithmetic_relation.hpp b/barretenberg/cpp/src/aztec/honk/sumcheck/relations/arithmetic_relation.hpp index 824e1748b61b..fb903c78043b 100644 --- a/barretenberg/cpp/src/aztec/honk/sumcheck/relations/arithmetic_relation.hpp +++ b/barretenberg/cpp/src/aztec/honk/sumcheck/relations/arithmetic_relation.hpp @@ -27,8 +27,11 @@ template class ArithmeticRelation : public Relation { * * @param extended_edges Contain inputs for the relation * @param evals Contains the resulting univariate polynomial + * + * The final parameter is left to conform to the general argument structure (input,output, challenges) even though + * we don't need challenges in this relation. */ - void add_edge_contribution(auto& extended_edges, Univariate& evals) + template void add_edge_contribution(auto& extended_edges, Univariate& evals, T) { add_edge_contribution_internal(extended_edges, evals); }; @@ -70,7 +73,8 @@ template class ArithmeticRelation : public Relation { evals += q_c; }; - void add_full_relation_value_contribution(auto& purported_evaluations, FF& full_honk_relation_value) + template + void add_full_relation_value_contribution(auto& purported_evaluations, FF& full_honk_relation_value, T) { auto w_l = purported_evaluations[MULTIVARIATE::W_L]; auto w_r = purported_evaluations[MULTIVARIATE::W_R]; diff --git a/barretenberg/cpp/src/aztec/honk/sumcheck/relations/grand_product_computation_relation.hpp b/barretenberg/cpp/src/aztec/honk/sumcheck/relations/grand_product_computation_relation.hpp index 4e9d62136799..34bc98505ae9 100644 --- a/barretenberg/cpp/src/aztec/honk/sumcheck/relations/grand_product_computation_relation.hpp +++ b/barretenberg/cpp/src/aztec/honk/sumcheck/relations/grand_product_computation_relation.hpp @@ -12,19 +12,20 @@ template class GrandProductComputationRelation : public Relation& evals) + void add_edge_contribution(auto& extended_edges, + Univariate& evals, + const RelationParameters& relation_parameters) { - add_edge_contribution_internal(extended_edges, evals, beta_default, gamma_default, public_input_delta_default); + add_edge_contribution_internal(extended_edges, + evals, + relation_parameters.beta, + relation_parameters.gamma, + relation_parameters.public_input_delta); }; /** @@ -53,8 +54,11 @@ template class GrandProductComputationRelation : public Relation& evals, FF beta, FF gamma, FF public_input_delta) + inline void add_edge_contribution_internal(auto& extended_edges, + Univariate& evals, + const FF& beta, + const FF& gamma, + const FF& public_input_delta) { auto w_1 = UnivariateView(extended_edges[MULTIVARIATE::W_L]); auto w_2 = UnivariateView(extended_edges[MULTIVARIATE::W_R]); @@ -77,7 +81,9 @@ template class GrandProductComputationRelation : public Relation& relation_parameters) { auto w_1 = purported_evaluations[MULTIVARIATE::W_L]; auto w_2 = purported_evaluations[MULTIVARIATE::W_R]; @@ -86,20 +92,22 @@ template class GrandProductComputationRelation : public Relation class GrandProductInitializationRelation : public Relatio * This file handles the relation Z_perm_shift(n_last) = 0 via the relation: * * C(X) = L_LAST(X) * Z_perm_shift(X) + * + * + * The final parameter is left to conform to the general argument structure (input,output, challenges) even though + * we don't need challenges in this relation. + * */ - void add_edge_contribution(auto& extended_edges, Univariate& evals) + template void add_edge_contribution(auto& extended_edges, Univariate& evals, T) { add_edge_contribution_internal(extended_edges, evals); }; @@ -55,7 +60,8 @@ template class GrandProductInitializationRelation : public Relatio add_edge_contribution_internal(extended_edges, evals); } - void add_full_relation_value_contribution(auto& purported_evaluations, FF& full_honk_relation_value) + template + void add_full_relation_value_contribution(auto& purported_evaluations, FF& full_honk_relation_value, T) { auto z_perm_shift = purported_evaluations[MULTIVARIATE::Z_PERM_SHIFT]; auto lagrange_last = purported_evaluations[MULTIVARIATE::LAGRANGE_LAST]; diff --git a/barretenberg/cpp/src/aztec/honk/sumcheck/relations/relation.hpp b/barretenberg/cpp/src/aztec/honk/sumcheck/relations/relation.hpp index bbf505e6b835..b7af6d8d1ca0 100644 --- a/barretenberg/cpp/src/aztec/honk/sumcheck/relations/relation.hpp +++ b/barretenberg/cpp/src/aztec/honk/sumcheck/relations/relation.hpp @@ -4,4 +4,10 @@ namespace honk::sumcheck { template class Relation {}; // TODO(Cody): Use or eventually remove. +template struct RelationParameters { + FF alpha; + FF beta; + FF gamma; + FF public_input_delta; +}; } // namespace honk::sumcheck diff --git a/barretenberg/cpp/src/aztec/honk/sumcheck/relations/relation.test.cpp b/barretenberg/cpp/src/aztec/honk/sumcheck/relations/relation.test.cpp index c4e4a7c33f81..af1cf5832d34 100644 --- a/barretenberg/cpp/src/aztec/honk/sumcheck/relations/relation.test.cpp +++ b/barretenberg/cpp/src/aztec/honk/sumcheck/relations/relation.test.cpp @@ -83,7 +83,7 @@ TYPED_TEST(SumcheckRelation, ArithmeticRelation) Univariate expected_evals = (q_m * w_r * w_l) + (q_r * w_r) + (q_l * w_l) + (q_o * w_o) + (q_c); auto evals = Univariate(); - relation.add_edge_contribution(extended_edges, evals); + relation.add_edge_contribution(extended_edges, evals, 0); EXPECT_EQ(evals, expected_evals); }; @@ -120,9 +120,12 @@ TYPED_TEST(SumcheckRelation, GrandProductComputationRelation) auto lagrange_first = UnivariateView(extended_edges[MULTIVARIATE::LAGRANGE_FIRST]); auto lagrange_last = UnivariateView(extended_edges[MULTIVARIATE::LAGRANGE_LAST]); // TODO(luke): use real transcript/challenges once manifest is done - FF beta = FF::one(); - FF gamma = FF::one(); - FF public_input_delta = FF::one(); + FF beta = FF::random_element(); + FF gamma = FF::random_element(); + FF public_input_delta = FF::random_element(); + const RelationParameters relation_parameters = RelationParameters{ + .alpha = FF ::zero(), .beta = beta, .gamma = gamma, .public_input_delta = public_input_delta + }; auto expected_evals = Univariate(); // expected_evals in the below step { { 27, 250, 1029, 2916, 6655 } } @@ -133,7 +136,7 @@ TYPED_TEST(SumcheckRelation, GrandProductComputationRelation) (w_2 + sigma_2 * beta + gamma) * (w_3 + sigma_3 * beta + gamma); auto evals = Univariate(); - relation.add_edge_contribution(extended_edges, evals); + relation.add_edge_contribution(extended_edges, evals, relation_parameters); EXPECT_EQ(evals, expected_evals); }; @@ -157,7 +160,7 @@ TYPED_TEST(SumcheckRelation, GrandProductInitializationRelation) // Compute the edge contribution using add_edge_contribution auto evals = Univariate(); - relation.add_edge_contribution(extended_edges, evals); + relation.add_edge_contribution(extended_edges, evals, 0); EXPECT_EQ(evals, expected_evals); }; diff --git a/barretenberg/cpp/src/aztec/honk/sumcheck/sumcheck.hpp b/barretenberg/cpp/src/aztec/honk/sumcheck/sumcheck.hpp index 759ea95d4853..5a3c8d80d9f0 100644 --- a/barretenberg/cpp/src/aztec/honk/sumcheck/sumcheck.hpp +++ b/barretenberg/cpp/src/aztec/honk/sumcheck/sumcheck.hpp @@ -1,6 +1,7 @@ #pragma once #include "common/serialize.hpp" #include "proof_system/types/polynomial_manifest.hpp" +#include #include "common/throw_or_abort.hpp" #include "ecc/curves/bn254/fr.hpp" #include "sumcheck_round.hpp" @@ -35,6 +36,34 @@ template class... Relat , transcript(transcript) , round(std::tuple(Relations()...)){}; + /** + * @brief Get all the challenges and computed parameters used in sumcheck in a convenient format + * + * @return RelationParameters + */ + RelationParameters retrieve_proof_parameters() + { + const FF alpha = FF::serialize_from_buffer(transcript.get_challenge("alpha").begin()); + const FF beta = FF::serialize_from_buffer(transcript.get_challenge("beta").begin()); + const FF gamma = FF::serialize_from_buffer(transcript.get_challenge("beta", 1).begin()); + const auto public_input_size_vector = transcript.get_element("public_input_size"); + const size_t public_input_size = (static_cast(public_input_size_vector[0]) << 24) | + (static_cast(public_input_size_vector[1]) << 16) | + (static_cast(public_input_size_vector[2]) << 8) | + + static_cast(public_input_size_vector[3]); + const auto circut_size_vector = transcript.get_element("circuit_size"); + const size_t n = (static_cast(circut_size_vector[0]) << 24) | + (static_cast(circut_size_vector[1]) << 16) | + (static_cast(circut_size_vector[2]) << 8) | static_cast(circut_size_vector[3]); + std::vector public_inputs = many_from_buffer(transcript.get_element("public_inputs")); + ASSERT(public_inputs.size() == public_input_size); + FF public_input_delta = honk::compute_public_input_delta(public_inputs, beta, gamma, n); + const RelationParameters relation_parameters = RelationParameters{ + .alpha = alpha, .beta = beta, .gamma = gamma, .public_input_delta = public_input_delta + }; + return relation_parameters; + } /** * @brief Compute univariate restriction place in transcript, generate challenge, fold,... repeat until final round, * then compute multivariate evaluations and place in transcript. @@ -45,8 +74,9 @@ template class... Relat { // First round // This populates multivariates.folded_polynomials. - FF alpha = FF::serialize_from_buffer(transcript.get_challenge("alpha").begin()); - auto round_univariate = round.compute_univariate(multivariates.full_polynomials, alpha); + + const auto relation_parameters = retrieve_proof_parameters(); + auto round_univariate = round.compute_univariate(multivariates.full_polynomials, relation_parameters); transcript.add_element("univariate_" + std::to_string(multivariates.multivariate_d), round_univariate.to_buffer()); std::string challenge_label = "u_" + std::to_string(multivariates.multivariate_d); @@ -59,7 +89,7 @@ template class... Relat // We operate on multivariates.folded_polynomials in place. for (size_t round_idx = 1; round_idx < multivariates.multivariate_d; round_idx++) { // Write the round univariate to the transcript - round_univariate = round.compute_univariate(multivariates.folded_polynomials, alpha); + round_univariate = round.compute_univariate(multivariates.folded_polynomials, relation_parameters); transcript.add_element("univariate_" + std::to_string(multivariates.multivariate_d - round_idx), round_univariate.to_buffer()); challenge_label = "u_" + std::to_string(multivariates.multivariate_d - round_idx); @@ -102,6 +132,7 @@ template class... Relat { bool verified(true); + const auto relation_parameters = retrieve_proof_parameters(); // All but final round. // target_total_sum is initialized to zero then mutated in place. @@ -127,9 +158,8 @@ template class... Relat // Final round auto purported_evaluations = transcript.get_field_element_vector("multivariate_evaluations"); - FF alpha = FF::serialize_from_buffer(transcript.get_challenge("alpha").begin()); FF full_honk_relation_purported_value = - round.compute_full_honk_relation_purported_value(purported_evaluations, alpha); + round.compute_full_honk_relation_purported_value(purported_evaluations, relation_parameters); verified = verified && (full_honk_relation_purported_value == round.target_total_sum); return verified; }; diff --git a/barretenberg/cpp/src/aztec/honk/sumcheck/sumcheck.test.cpp b/barretenberg/cpp/src/aztec/honk/sumcheck/sumcheck.test.cpp index b1d5efb864bf..6df35e09ef4a 100644 --- a/barretenberg/cpp/src/aztec/honk/sumcheck/sumcheck.test.cpp +++ b/barretenberg/cpp/src/aztec/honk/sumcheck/sumcheck.test.cpp @@ -29,11 +29,68 @@ namespace test_sumcheck_round { using Transcript = transcript::StandardTranscript; using FF = barretenberg::fr; +Transcript produce_mocked_transcript(size_t multivariate_d, size_t num_public_inputs) +{ + // Create a mock manifest containing only elements needed for testing Sumcheck + constexpr size_t fr_size = 32; + const size_t multivariate_n(1 << multivariate_d); + const size_t public_input_size = fr_size * num_public_inputs; + std::vector manifest_rounds; + manifest_rounds.emplace_back(transcript::Manifest::RoundManifest( + { { .name = "circuit_size", .num_bytes = 4, .derived_by_verifier = true }, + { .name = "public_input_size", .num_bytes = 4, .derived_by_verifier = true } }, + /* challenge_name = */ "init", + /* num_challenges_in = */ 1)); + + manifest_rounds.emplace_back(transcript::Manifest::RoundManifest({ /* this is a noop */ }, + /* challenge_name = */ "alpha", + /* num_challenges_in = */ 1)); + manifest_rounds.emplace_back(transcript::Manifest::RoundManifest( + { { .name = "public_inputs", .num_bytes = public_input_size, .derived_by_verifier = false } }, + /* challenge_name = */ "beta", + /* num_challenges_in = */ 2) // also produce "gamma" + ); + + for (size_t i = 0; i < multivariate_d; i++) { + auto label = std::to_string(multivariate_d - i); + manifest_rounds.emplace_back( + transcript::Manifest::RoundManifest({ { .name = "univariate_" + label, + .num_bytes = fr_size * honk::StandardHonk::MAX_RELATION_LENGTH, + .derived_by_verifier = false } }, + /* challenge_name = */ "u_" + label, + /* num_challenges_in = */ 1)); + } + + // Create a transcript from the mock manifest + auto transcript = Transcript(transcript::Manifest(manifest_rounds)); + + transcript.add_element("circuit_size", + { static_cast(multivariate_n >> 24), + static_cast(multivariate_n >> 16), + static_cast(multivariate_n >> 8), + static_cast(multivariate_n) }); + + transcript.add_element("public_input_size", + { static_cast(num_public_inputs >> 24), + static_cast(num_public_inputs >> 16), + static_cast(num_public_inputs >> 8), + static_cast(num_public_inputs) }); + + transcript.apply_fiat_shamir("init"); + transcript.apply_fiat_shamir("alpha"); + std::vector public_inputs_buf(public_input_size, 1); // arbitrary buffer of 1's + transcript.add_element("public_inputs", public_inputs_buf); + transcript.apply_fiat_shamir("beta"); + + return transcript; +} + TEST(Sumcheck, PolynomialNormalization) { const size_t num_polys(bonk::StandardArithmetization::NUM_POLYNOMIALS); const size_t multivariate_d(3); const size_t multivariate_n(1 << multivariate_d); + const size_t num_public_inputs(1); constexpr size_t fr_size = 32; @@ -66,22 +123,7 @@ TEST(Sumcheck, PolynomialNormalization) sigma_3, id_1, id_2, id_3, lagrange_first, lagrange_last }; - std::vector manifest_rounds; - manifest_rounds.emplace_back(transcript::Manifest::RoundManifest({ /* this is a noop */ }, - /* challenge_name = */ "alpha", - /* num_challenges_in = */ 1)); - for (size_t i = 0; i < multivariate_d; i++) { - auto label = std::to_string(multivariate_d - i); - manifest_rounds.emplace_back(transcript::Manifest::RoundManifest( - { { .name = "univariate_" + label, - .num_bytes = fr_size * 5 /* honk::StandardHonk::MAX_RELATION_LENGTH */, - .derived_by_verifier = false } }, - /* challenge_name = */ "u_" + label, - /* num_challenges_in = */ 1)); - } - - auto transcript = Transcript(transcript::Manifest(manifest_rounds)); - transcript.apply_fiat_shamir("alpha"); + auto transcript = produce_mocked_transcript(multivariate_d, num_public_inputs); auto multivariates = Multivariates(full_polynomials); @@ -129,6 +171,7 @@ TEST(Sumcheck, Prover) const size_t num_polys(bonk::StandardArithmetization::NUM_POLYNOMIALS); const size_t multivariate_d(2); const size_t multivariate_n(1 << multivariate_d); + const size_t num_public_inputs(1); // const size_t max_relation_length = 4; constexpr size_t fr_size = 32; @@ -162,22 +205,7 @@ TEST(Sumcheck, Prover) sigma_3, id_1, id_2, id_3, lagrange_first, lagrange_last }; - std::vector manifest_rounds; - manifest_rounds.emplace_back(transcript::Manifest::RoundManifest({ /* this is a noop */ }, - /* challenge_name = */ "alpha", - /* num_challenges_in = */ 1)); - for (size_t i = 0; i < multivariate_d; i++) { - auto label = std::to_string(multivariate_d - i); - manifest_rounds.emplace_back(transcript::Manifest::RoundManifest( - { { .name = "univariate_" + label, - .num_bytes = fr_size * 5 /* honk::StandardHonk::MAX_RELATION_LENGTH */, - .derived_by_verifier = false } }, - /* challenge_name = */ "u_" + label, - /* num_challenges_in = */ 1)); - } - - auto transcript = Transcript(transcript::Manifest(manifest_rounds)); - transcript.apply_fiat_shamir("alpha"); + auto transcript = produce_mocked_transcript(multivariate_d, num_public_inputs); auto multivariates = Multivariates(full_polynomials); @@ -207,37 +235,37 @@ TEST(Sumcheck, Prover) } // TODO(Cody): write standalone test of the verifier. - +// TODO(luke): test possibly made obsolete by test ProverAndVerifierLonger TEST(Sumcheck, ProverAndVerifier) { const size_t num_polys(bonk::StandardArithmetization::NUM_POLYNOMIALS); const size_t multivariate_d(1); const size_t multivariate_n(1 << multivariate_d); - // const size_t max_relation_length = 5; + const size_t num_public_inputs(1); const size_t max_relation_length = 4 /* honk::StandardHonk::MAX_RELATION_LENGTH */; constexpr size_t fr_size = 32; using Multivariates = ::Multivariates; - std::array w_l = { 1, 2 }; - std::array w_r = { 1, 2 }; - std::array w_o = { 2, 4 }; - std::array z_perm = { 0, 1 }; - std::array z_perm_shift = { 1, 0 }; // NOTE: Not set up to be valid. - std::array q_m = { 0, 1 }; - std::array q_l = { 1, 0 }; - std::array q_r = { 1, 0 }; - std::array q_o = { -1, -1 }; + std::array w_l = { 0, 1 }; + std::array w_r = { 0, 1 }; + std::array w_o = { 0, 2 }; + std::array z_perm = { 0, 0 }; + std::array z_perm_shift = { 0, 0 }; // NOTE: Not set up to be valid. + std::array q_m = { 0, 0 }; + std::array q_l = { 1, 1 }; + std::array q_r = { 0, 1 }; + std::array q_o = { 0, -1 }; std::array q_c = { 0, 0 }; - std::array sigma_1 = { 1, 2 }; // NOTE: Not set up to be valid. - std::array sigma_2 = { 1, 2 }; // NOTE: Not set up to be valid. - std::array sigma_3 = { 1, 2 }; // NOTE: Not set up to be valid. - std::array id_1 = { 1, 2 }; // NOTE: Not set up to be valid. - std::array id_2 = { 1, 2 }; // NOTE: Not set up to be valid. - std::array id_3 = { 1, 2 }; // NOTE: Not set up to be valid. - std::array lagrange_first = { 1, 0 }; - std::array lagrange_last = { 0, 1 }; // NOTE: Not set up to be valid. + std::array sigma_1 = { 0, 0 }; // NOTE: Not set up to be valid. + std::array sigma_2 = { 0, 0 }; // NOTE: Not set up to be valid. + std::array sigma_3 = { 0, 0 }; // NOTE: Not set up to be valid. + std::array id_1 = { 0, 0 }; // NOTE: Not set up to be valid. + std::array id_2 = { 0, 0 }; // NOTE: Not set up to be valid. + std::array id_3 = { 0, 0 }; // NOTE: Not set up to be valid. + std::array lagrange_first = { 0, 0 }; + std::array lagrange_last = { 0, 0 }; // NOTE: Not set up to be valid. // These will be owned outside the class, probably by the composer. std::array, Multivariates::num> full_polynomials = { @@ -245,39 +273,14 @@ TEST(Sumcheck, ProverAndVerifier) sigma_3, id_1, id_2, id_3, lagrange_first, lagrange_last }; - std::vector manifest_rounds; - manifest_rounds.emplace_back(transcript::Manifest::RoundManifest({ /* this is a noop */ }, - /* challenge_name = */ "alpha", - /* num_challenges_in = */ 1)); - for (size_t i = 0; i < multivariate_d; i++) { - auto label = std::to_string(multivariate_d - i); - manifest_rounds.emplace_back(transcript::Manifest::RoundManifest({ { .name = "univariate_" + label, - .num_bytes = fr_size * max_relation_length, - .derived_by_verifier = false } }, - /* challenge_name = */ "u_" + label, - /* num_challenges_in = */ 1)); - } - - auto transcript = Transcript(transcript::Manifest(manifest_rounds)); - auto mock_transcript = [](Transcript& transcript) { - static_assert(multivariate_d < 64); - uint64_t multivariate_n = 1 << multivariate_d; - transcript.add_element("circuit_size", - { static_cast(multivariate_n >> 24), - static_cast(multivariate_n >> 16), - static_cast(multivariate_n >> 8), - static_cast(multivariate_n) }); - }; - - mock_transcript(transcript); - transcript.apply_fiat_shamir("alpha"); + auto transcript = produce_mocked_transcript(multivariate_d, num_public_inputs); auto multivariates = Multivariates(full_polynomials); auto sumcheck_prover = Sumcheck(multivariates, transcript); sumcheck_prover.execute_prover(); @@ -285,39 +288,40 @@ TEST(Sumcheck, ProverAndVerifier) auto sumcheck_verifier = Sumcheck(transcript); bool verified = sumcheck_verifier.execute_verifier(); ASSERT_TRUE(verified); } +// TODO: make the inputs to this test more interesting, e.g. num_public_inputs > 0 and non-trivial permutations TEST(Sumcheck, ProverAndVerifierLonger) { auto run_test = [](bool expect_verified) { const size_t num_polys(bonk::StandardArithmetization::NUM_POLYNOMIALS); const size_t multivariate_d(2); const size_t multivariate_n(1 << multivariate_d); - // const size_t max_relation_length = 5; + const size_t num_public_inputs(0); - const size_t max_relation_length = 4 /* honk::StandardHonk::MAX_RELATION_LENGTH */; + const size_t max_relation_length = honk::StandardHonk::MAX_RELATION_LENGTH; constexpr size_t fr_size = 32; using Multivariates = ::Multivariates; // clang-format off std::array w_l; - if (expect_verified) { w_l = { 0, 1, 0, 0 }; - } else { w_l = { 0, 0, 0, 0 }; + if (expect_verified) { w_l = { 0, 1, 2, 0 }; + } else { w_l = { 0, 0, 2, 0 }; } - std::array w_r = { 0, 1, 0, 0 }; - std::array w_o = { 0, 2, 0, 0 }; + std::array w_r = { 0, 1, 2, 0 }; + std::array w_o = { 0, 2, 4, 0 }; std::array z_perm = { 0, 0, 0, 0 }; std::array z_perm_shift = { 0, 0, 0, 0 }; - std::array q_m = { 0, 0, 0, 0 }; + std::array q_m = { 0, 0, 1, 0 }; std::array q_l = { 1, 1, 0, 0 }; std::array q_r = { 0, 1, 0, 0 }; - std::array q_o = { 0, -1, 0, 0 }; + std::array q_o = { 0, -1, -1, 0 }; std::array q_c = { 0, 0, 0, 0 }; std::array sigma_1 = { 0, 0, 0, 0 }; std::array sigma_2 = { 0, 0, 0, 0 }; @@ -325,8 +329,8 @@ TEST(Sumcheck, ProverAndVerifierLonger) std::array id_1 = { 0, 0, 0, 0 }; std::array id_2 = { 0, 0, 0, 0 }; std::array id_3 = { 0, 0, 0, 0 }; - std::array lagrange_first = { 0, 0, 0, 0 }; - std::array lagrange_last = { 0, 0, 0, 0 }; + std::array lagrange_first = { 1, 0, 0, 0 }; + std::array lagrange_last = { 0, 0, 0, 1 }; // clang-format on // These will be owned outside the class, probably by the composer. @@ -335,40 +339,14 @@ TEST(Sumcheck, ProverAndVerifierLonger) sigma_3, id_1, id_2, id_3, lagrange_first, lagrange_last }; - std::vector manifest_rounds; - manifest_rounds.emplace_back(transcript::Manifest::RoundManifest({ /* this is a noop */ }, - /* challenge_name = */ "alpha", - /* num_challenges_in = */ 1)); - for (size_t i = 0; i < multivariate_d; i++) { - auto label = std::to_string(multivariate_d - i); - manifest_rounds.emplace_back( - transcript::Manifest::RoundManifest({ { .name = "univariate_" + label, - .num_bytes = fr_size * max_relation_length, - .derived_by_verifier = false } }, - /* challenge_name = */ "u_" + label, - /* num_challenges_in = */ 1)); - } - - auto transcript = Transcript(transcript::Manifest(manifest_rounds)); - auto mock_transcript = [](Transcript& transcript) { - static_assert(multivariate_d < 64); - uint64_t multivariate_n = 1 << multivariate_d; - transcript.add_element("circuit_size", - { static_cast(multivariate_n >> 24), - static_cast(multivariate_n >> 16), - static_cast(multivariate_n >> 8), - static_cast(multivariate_n) }); - }; - - mock_transcript(transcript); - transcript.apply_fiat_shamir("alpha"); + auto transcript = produce_mocked_transcript(multivariate_d, num_public_inputs); auto multivariates = Multivariates(full_polynomials); auto sumcheck_prover = Sumcheck(multivariates, transcript); sumcheck_prover.execute_prover(); @@ -376,7 +354,7 @@ TEST(Sumcheck, ProverAndVerifierLonger) auto sumcheck_verifier = Sumcheck(transcript); bool verified = sumcheck_verifier.execute_verifier(); diff --git a/barretenberg/cpp/src/aztec/honk/sumcheck/sumcheck_round.hpp b/barretenberg/cpp/src/aztec/honk/sumcheck/sumcheck_round.hpp index 765716f3ef95..89434508234e 100644 --- a/barretenberg/cpp/src/aztec/honk/sumcheck/sumcheck_round.hpp +++ b/barretenberg/cpp/src/aztec/honk/sumcheck/sumcheck_round.hpp @@ -5,6 +5,7 @@ #include #include "polynomials/barycentric_data.hpp" #include "polynomials/univariate.hpp" +#include "relations/relation.hpp" namespace honk::sumcheck { /* @@ -186,14 +187,15 @@ template class... Relation * group of edges. These are stored in `univariate_accumulators`. Adding these univariates together, with * appropriate scaling factors, produces S_l. */ - template void accumulate_relation_univariates() + template + void accumulate_relation_univariates(const RelationParameters& relation_parameters) { - std::get(relations).add_edge_contribution(extended_edges, - std::get(univariate_accumulators)); + std::get(relations).add_edge_contribution( + extended_edges, std::get(univariate_accumulators), relation_parameters); // Repeat for the next relation. if constexpr (relation_idx + 1 < NUM_RELATIONS) { - accumulate_relation_univariates(); + accumulate_relation_univariates(relation_parameters); } } @@ -209,14 +211,15 @@ template class... Relation */ template // TODO(Cody): Input should be an array? Then challenge container has to know array length. - void accumulate_relation_evaluations(std::vector& purported_evaluations) + void accumulate_relation_evaluations(std::vector& purported_evaluations, + const RelationParameters& relation_parameters) { - std::get(relations).add_full_relation_value_contribution(purported_evaluations, - evaluations[relation_idx]); + std::get(relations).add_full_relation_value_contribution( + purported_evaluations, evaluations[relation_idx], relation_parameters); // Repeat for the next relation. if constexpr (relation_idx + 1 < NUM_RELATIONS) { - accumulate_relation_evaluations(purported_evaluations); + accumulate_relation_evaluations(purported_evaluations, relation_parameters); } } @@ -242,14 +245,16 @@ template class... Relation * values. Most likely this will end up being S_l(0), ... , S_l(t-1) where t is around 12. At the end, reset all * univariate accumulators to be zero. */ - Univariate compute_univariate(auto& polynomials, FF& relation_separator_challenge) + Univariate compute_univariate(auto& polynomials, + const RelationParameters& relation_parameters) { for (size_t edge_idx = 0; edge_idx < round_size; edge_idx += 2) { extend_edges(polynomials, edge_idx); - accumulate_relation_univariates<>(); + + accumulate_relation_univariates<>(relation_parameters); } - auto result = batch_over_relations>(relation_separator_challenge); + auto result = batch_over_relations>(relation_parameters.alpha); reset_accumulators<>(); @@ -257,16 +262,16 @@ template class... Relation } FF compute_full_honk_relation_purported_value(std::vector& purported_evaluations, - FF& relation_separator_challenge) + const RelationParameters& relation_parameters) { - accumulate_relation_evaluations<>(purported_evaluations); + accumulate_relation_evaluations<>(purported_evaluations, relation_parameters); // IMPROVEMENT(Cody): Reuse functions from univariate_accumulators batching? FF running_challenge = 1; FF output = 0; for (auto& evals : evaluations) { output += evals * running_challenge; - running_challenge *= relation_separator_challenge; + running_challenge *= relation_parameters.alpha; } return output; diff --git a/barretenberg/cpp/src/aztec/honk/sumcheck/sumcheck_round.test.cpp b/barretenberg/cpp/src/aztec/honk/sumcheck/sumcheck_round.test.cpp index e681a304737b..23dd30fa5544 100644 --- a/barretenberg/cpp/src/aztec/honk/sumcheck/sumcheck_round.test.cpp +++ b/barretenberg/cpp/src/aztec/honk/sumcheck/sumcheck_round.test.cpp @@ -62,9 +62,10 @@ TEST(SumcheckRound, ComputeUnivariateProver) ArithmeticRelation, GrandProductComputationRelation, GrandProductInitializationRelation>(round_size, relations); - FF relation_separator_challenge = 1; + const RelationParameters relation_parameters = + RelationParameters{ .alpha = 1, .beta = 1, .gamma = 1, .public_input_delta = 1 }; Univariate round_univariate = - round.compute_univariate(full_polynomials, relation_separator_challenge); + round.compute_univariate(full_polynomials, relation_parameters); Univariate expected_round_univariate{ { 32, 149, 406, 857, 1556 } }; EXPECT_EQ(round_univariate, expected_round_univariate); @@ -115,9 +116,10 @@ TEST(SumcheckRound, ComputeUnivariateVerifier) ArithmeticRelation, GrandProductComputationRelation, GrandProductInitializationRelation>(relations); - FF relation_separator_challenge = -1; + const RelationParameters relation_parameters = + RelationParameters{ .alpha = -1, .beta = 1, .gamma = 1, .public_input_delta = 1 }; FF full_purported_value = - round.compute_full_honk_relation_purported_value(purported_evaluations, relation_separator_challenge); + round.compute_full_honk_relation_purported_value(purported_evaluations, relation_parameters); EXPECT_EQ(full_purported_value, expected_full_purported_value); } diff --git a/barretenberg/cpp/src/aztec/proof_system/flavor/flavor.hpp b/barretenberg/cpp/src/aztec/proof_system/flavor/flavor.hpp index bef1b94334f6..4fe49ff7a7d7 100644 --- a/barretenberg/cpp/src/aztec/proof_system/flavor/flavor.hpp +++ b/barretenberg/cpp/src/aztec/proof_system/flavor/flavor.hpp @@ -40,7 +40,7 @@ struct StandardHonk { using MULTIVARIATE = Arithmetization::POLYNOMIAL; // // TODO(Cody): Where to specify? is this polynomial manifest size? // static constexpr size_t STANDARD_HONK_MANIFEST_SIZE = 16; - static constexpr size_t MAX_RELATION_LENGTH = 4; // TODO(Cody): increment after fixing add_edge_contribution; kill + static constexpr size_t MAX_RELATION_LENGTH = 5; // TODO(Cody): increment after fixing add_edge_contribution; kill // after moving barycentric class out of relations // TODO(Cody): should extract this from the parameter pack. Maybe that should be done here?