From cf214c4f17d64a5558e2fd5f8985e1428027964f Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Wed, 20 Sep 2023 16:04:29 +0000 Subject: [PATCH 01/13] building but a bunch of old tests disabled --- .../benchmark/honk_bench/CMakeLists.txt | 1 - .../honk_bench/benchmark_utilities.hpp | 18 +- .../compare_honk_to_plonk_standard.sh | 41 - .../benchmark/honk_bench/honk.bench.cpp | 116 -- .../honk_bench/standard_honk.bench.cpp | 33 - .../relations_bench/relations.bench.cpp | 14 +- .../honk/composer/eccvm_composer.hpp | 7 +- .../honk/composer/eccvm_composer.test.cpp | 1 - .../honk/composer/standard_composer.cpp | 42 - .../honk/composer/standard_composer.hpp | 83 -- .../honk/composer/standard_composer.test.cpp | 448 ------- .../barretenberg/honk/flavor/flavor.test.cpp | 282 ++-- .../src/barretenberg/honk/flavor/standard.hpp | 309 ----- .../honk/flavor/standard_grumpkin.hpp | 306 ----- .../honk/instance/prover_instance.cpp | 9 - .../honk/instance/prover_instance.hpp | 4 - .../honk/proof_system/eccvm_verifier.cpp | 3 +- .../grand_product_library.test.cpp | 18 +- .../barretenberg/honk/proof_system/prover.cpp | 248 ---- .../barretenberg/honk/proof_system/prover.hpp | 86 -- .../honk/proof_system/ultra_verifier.cpp | 3 +- .../honk/proof_system/verifier.cpp | 171 --- .../honk/proof_system/verifier.hpp | 34 - .../honk/sumcheck/partial_evaluation.test.cpp | 630 ++++----- .../sumcheck/relation_correctness.test.cpp | 45 - .../barretenberg/honk/sumcheck/sumcheck.hpp | 1 - .../honk/sumcheck/sumcheck.test.cpp | 1132 ++++++++--------- .../honk/sumcheck/sumcheck_round.test.cpp | 815 ++++++------ .../honk/transcript/transcript.test.cpp | 281 ---- .../composer/composer_lib.test.cpp | 276 ++-- .../composer/permutation_lib.test.cpp | 164 +-- .../proof_system/flavor/flavor.hpp | 6 +- .../relations/arithmetic_relation.hpp | 57 - .../relations/permutation_relation.hpp | 107 -- .../standard_relation_consistency.test.cpp | 147 --- .../verifier/ultra_recursive_verifier.cpp | 4 +- 36 files changed, 1652 insertions(+), 4290 deletions(-) delete mode 100755 barretenberg/cpp/src/barretenberg/benchmark/honk_bench/compare_honk_to_plonk_standard.sh delete mode 100644 barretenberg/cpp/src/barretenberg/benchmark/honk_bench/honk.bench.cpp delete mode 100644 barretenberg/cpp/src/barretenberg/benchmark/honk_bench/standard_honk.bench.cpp delete mode 100644 barretenberg/cpp/src/barretenberg/honk/composer/standard_composer.cpp delete mode 100644 barretenberg/cpp/src/barretenberg/honk/composer/standard_composer.hpp delete mode 100644 barretenberg/cpp/src/barretenberg/honk/composer/standard_composer.test.cpp delete mode 100644 barretenberg/cpp/src/barretenberg/honk/flavor/standard.hpp delete mode 100644 barretenberg/cpp/src/barretenberg/honk/flavor/standard_grumpkin.hpp delete mode 100644 barretenberg/cpp/src/barretenberg/honk/proof_system/prover.cpp delete mode 100644 barretenberg/cpp/src/barretenberg/honk/proof_system/prover.hpp delete mode 100644 barretenberg/cpp/src/barretenberg/honk/proof_system/verifier.cpp delete mode 100644 barretenberg/cpp/src/barretenberg/honk/proof_system/verifier.hpp delete mode 100644 barretenberg/cpp/src/barretenberg/proof_system/relations/arithmetic_relation.hpp delete mode 100644 barretenberg/cpp/src/barretenberg/proof_system/relations/standard_relation_consistency.test.cpp diff --git a/barretenberg/cpp/src/barretenberg/benchmark/honk_bench/CMakeLists.txt b/barretenberg/cpp/src/barretenberg/benchmark/honk_bench/CMakeLists.txt index d9a995e7cfb..916d590cd15 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/honk_bench/CMakeLists.txt +++ b/barretenberg/cpp/src/barretenberg/benchmark/honk_bench/CMakeLists.txt @@ -1,6 +1,5 @@ # Each source represents a separate benchmark suite set(BENCHMARK_SOURCES -standard_honk.bench.cpp standard_plonk.bench.cpp ultra_honk.bench.cpp ultra_plonk.bench.cpp diff --git a/barretenberg/cpp/src/barretenberg/benchmark/honk_bench/benchmark_utilities.hpp b/barretenberg/cpp/src/barretenberg/benchmark/honk_bench/benchmark_utilities.hpp index e2727fb5f17..21e3513fd84 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/honk_bench/benchmark_utilities.hpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/honk_bench/benchmark_utilities.hpp @@ -1,6 +1,5 @@ #include -#include "barretenberg/honk/composer/standard_composer.hpp" #include "barretenberg/honk/composer/ultra_composer.hpp" #include "barretenberg/proof_system/types/circuit_type.hpp" #include "barretenberg/stdlib/encryption/ecdsa/ecdsa.hpp" @@ -195,20 +194,11 @@ void construct_proof_with_specified_num_gates(State& state, test_circuit_function(builder, num_gates); auto composer = Composer(); - if constexpr (proof_system::IsAnyOf) { - auto instance = composer.create_instance(builder); - auto ext_prover = composer.create_prover(instance); - state.ResumeTiming(); - - // Construct proof - auto proof = ext_prover.construct_proof(); - } else { - auto ext_prover = composer.create_prover(builder); - state.ResumeTiming(); + auto ext_prover = composer.create_prover(builder); + state.ResumeTiming(); - // Construct proof - auto proof = ext_prover.construct_proof(); - } + // Construct proof + auto proof = ext_prover.construct_proof(); } } diff --git a/barretenberg/cpp/src/barretenberg/benchmark/honk_bench/compare_honk_to_plonk_standard.sh b/barretenberg/cpp/src/barretenberg/benchmark/honk_bench/compare_honk_to_plonk_standard.sh deleted file mode 100755 index ad7ecc1f22d..00000000000 --- a/barretenberg/cpp/src/barretenberg/benchmark/honk_bench/compare_honk_to_plonk_standard.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash - -# This script is used to compare the results of honk_bench between baseline (master) and -# the branch from which the script is run. Simply check out the branch of interest, ensure -# it is up to date with local master, and run the script. - -echo -e '\nComparing Standard Plonk/Honk benchmarks.' -# Set some directories -BASE_DIR="$HOME/barretenberg/cpp" -BUILD_DIR="$BASE_DIR/build-bench" -BENCH_RESULTS_DIR="$BASE_DIR/tmp_bench_results" -BENCH_TOOLS_DIR="$BUILD_DIR/_deps/benchmark-src/tools" - -# Install requirements (numpy + scipy) for comparison script if necessary. -# Note: By default, installation will occur in $HOME/.local/bin. -pip3 install --user -r $BUILD_DIR/_deps/benchmark-src/requirements.txt - -# Create temporary directory for honk_bench results (json) -cd $BASE_DIR -mkdir $BENCH_RESULTS_DIR - -# -echo -e '\nBuilding and running Standard benchmarks..' -# rm -rf $BUILD_DIR -cmake --preset bench > /dev/null && cmake --build --preset bench --target standard_plonk_bench -cd build-bench -PLONK_BENCH_RESULTS="$BENCH_RESULTS_DIR/plonk_bench.json" -./bin/standard_plonk_bench --benchmark_format=json > $PLONK_BENCH_RESULTS - -cd .. -cmake --preset bench > /dev/null && cmake --build --preset bench --target standard_honk_bench -cd build-bench -HONK_BENCH_RESULTS="$BENCH_RESULTS_DIR/honk_bench.json" -./bin/standard_honk_bench --benchmark_format=json > $HONK_BENCH_RESULTS - -# Call compare.py on the results (json) to get high level statistics. -# See docs at https://github.com/google/benchmark/blob/main/docs/tools.md for more details. -$BENCH_TOOLS_DIR/compare.py benchmarks $PLONK_BENCH_RESULTS $HONK_BENCH_RESULTS - -# # Delete the temporary results directory and its contents -rm -r $BENCH_RESULTS_DIR \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/benchmark/honk_bench/honk.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/honk_bench/honk.bench.cpp deleted file mode 100644 index 87b8c5a2845..00000000000 --- a/barretenberg/cpp/src/barretenberg/benchmark/honk_bench/honk.bench.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#include "barretenberg/honk/composer/standard_composer.hpp" -#include "barretenberg/stdlib/primitives/field/field.hpp" -#include "barretenberg/stdlib/primitives/witness/witness.hpp" -#include -#include - -using namespace benchmark; -using namespace proof_system::plonk::stdlib; - -namespace standard_honk_bench { - -using Builder = proof_system::StandardCircuitBuilder; -using Composer = proof_system::honk::StandardComposer; - -constexpr size_t MIN_LOG_NUM_GATES = 16; -constexpr size_t MAX_LOG_NUM_GATES = 16; -// To get good statistics, number of Repetitions must be sufficient. ~30 Repetitions gives good results. -constexpr size_t NUM_REPETITIONS = 5; - -void generate_test_circuit(auto& builder, size_t num_gates) -{ - barretenberg::srs::init_crs_factory("../srs_db/ignition"); - field_t a(witness_t(&builder, barretenberg::fr::random_element())); - field_t b(witness_t(&builder, barretenberg::fr::random_element())); - field_t c(&builder); - for (size_t i = 0; i < (num_gates / 4) - 4; ++i) { - c = a + b; - c = a * c; - a = b * b; - b = c * c; - } -} - -/** - * @brief Benchmark: Creation of a Standard Honk prover - */ -void create_prover_standard(State& state) noexcept -{ - for (auto _ : state) { - state.PauseTiming(); - auto num_gates = 1 << (size_t)state.range(0); - auto builder = Builder(static_cast(num_gates)); - generate_test_circuit(builder, static_cast(num_gates)); - state.ResumeTiming(); - - auto composer = Composer(); - composer.create_prover(builder); - } -} -BENCHMARK(create_prover_standard)->DenseRange(MIN_LOG_NUM_GATES, MAX_LOG_NUM_GATES, 1)->Repetitions(NUM_REPETITIONS); - -/** - * @brief Benchmark: Construction of a Standard Honk proof - */ -void construct_proof_standard(State& state) noexcept -{ - auto num_gates = 1 << (size_t)state.range(0); - for (auto _ : state) { - state.PauseTiming(); - auto builder = Builder(static_cast(num_gates)); - generate_test_circuit(builder, static_cast(num_gates)); - - auto composer = Composer(); - auto ext_prover = composer.create_prover(builder); - state.ResumeTiming(); - - auto proof = ext_prover.construct_proof(); - } - state.SetComplexityN(num_gates); // Set up for computation of constant C where prover ~ C*N -} -BENCHMARK(construct_proof_standard) - ->DenseRange(MIN_LOG_NUM_GATES, MAX_LOG_NUM_GATES, 1) - ->Repetitions(NUM_REPETITIONS) - ->Complexity(oN); - -/** - * @brief Benchmark: Creation of a Standard Honk verifier - */ -void create_verifier_standard(State& state) noexcept -{ - for (auto _ : state) { - state.PauseTiming(); - auto num_gates = 1 << (size_t)state.range(0); - auto builder = Builder(static_cast(num_gates)); - generate_test_circuit(builder, static_cast(num_gates)); - state.ResumeTiming(); - - auto composer = Composer(); - composer.create_verifier(builder); - } -} -// BENCHMARK(create_verifier_standard)->DenseRange(MIN_LOG_NUM_GATES, MAX_LOG_NUM_GATES, -// 1)->Repetitions(NUM_REPETITIONS); - -/** - * @brief Benchmark: Verification of a Standard Honk proof - */ -void verify_proof_standard(State& state) noexcept -{ - for (auto _ : state) { - state.PauseTiming(); - auto num_gates = (size_t)state.range(0); - auto builder = Builder(static_cast(num_gates)); - generate_test_circuit(builder, static_cast(num_gates)); - - auto composer = Composer(); - auto prover = composer.create_prover(builder); - auto proof = prover.construct_proof(); - auto verifier = composer.create_verifier(builder); - state.ResumeTiming(); - - verifier.verify_proof(proof); - } -} -// BENCHMARK(verify_proof_standard)->DenseRange(MIN_LOG_NUM_GATES, MAX_LOG_NUM_GATES, 1)->Iterations(1); -} // namespace standard_honk_bench \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/benchmark/honk_bench/standard_honk.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/honk_bench/standard_honk.bench.cpp deleted file mode 100644 index 42fed512ffc..00000000000 --- a/barretenberg/cpp/src/barretenberg/benchmark/honk_bench/standard_honk.bench.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "barretenberg/benchmark/honk_bench/benchmark_utilities.hpp" -#include "barretenberg/honk/composer/standard_composer.hpp" -#include "barretenberg/proof_system/circuit_builder/standard_circuit_builder.hpp" - -using namespace benchmark; - -namespace standard_honk_bench { - -using StandardBuilder = proof_system::StandardCircuitBuilder; -using StandardHonk = proof_system::honk::StandardComposer; - -// Log number of gates for test circuit -constexpr size_t MIN_LOG_NUM_GATES = bench_utils::BenchParams::MIN_LOG_NUM_GATES; -constexpr size_t MAX_LOG_NUM_GATES = bench_utils::BenchParams::MAX_LOG_NUM_GATES; -// Number of times to repeat each benchmark -constexpr size_t NUM_REPETITIONS = bench_utils::BenchParams::NUM_REPETITIONS; - -/** - * @brief Benchmark: Construction of a Standard proof for a circuit determined by the provided circuit function - */ -void construct_proof_standard(State& state, void (*test_circuit_function)(StandardBuilder&, size_t)) noexcept -{ - bench_utils::construct_proof_with_specified_num_gates(state, test_circuit_function); -} - -BENCHMARK_CAPTURE(construct_proof_standard, - arithmetic, - &bench_utils::generate_basic_arithmetic_circuit) - ->DenseRange(MIN_LOG_NUM_GATES, MAX_LOG_NUM_GATES) - ->Repetitions(NUM_REPETITIONS) - ->Unit(::benchmark::kSecond); - -} // namespace standard_honk_bench \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/benchmark/relations_bench/relations.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/relations_bench/relations.bench.cpp index 362d5b15b6c..df0be6fe25a 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/relations_bench/relations.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/relations_bench/relations.bench.cpp @@ -1,7 +1,5 @@ #include "barretenberg/honk/flavor/goblin_ultra.hpp" -#include "barretenberg/honk/flavor/standard.hpp" #include "barretenberg/honk/flavor/ultra.hpp" -#include "barretenberg/proof_system/relations/arithmetic_relation.hpp" #include "barretenberg/proof_system/relations/auxiliary_relation.hpp" #include "barretenberg/proof_system/relations/ecc_op_queue_relation.hpp" #include "barretenberg/proof_system/relations/elliptic_relation.hpp" @@ -47,12 +45,6 @@ template void execute_relation(::benchmark: } } -void arithmetic_relation(::benchmark::State& state) noexcept -{ - execute_relation>(state); -} -BENCHMARK(arithmetic_relation); - void auxiliary_relation(::benchmark::State& state) noexcept { execute_relation>(state); @@ -83,11 +75,11 @@ void lookup_relation(::benchmark::State& state) noexcept } BENCHMARK(lookup_relation); -void permutation_relation(::benchmark::State& state) noexcept +void ultra_permutation_relation(::benchmark::State& state) noexcept { - execute_relation>(state); + execute_relation>(state); } -BENCHMARK(permutation_relation); +BENCHMARK(ultra_permutation_relation); void ultra_arithmetic_relation(::benchmark::State& state) noexcept { diff --git a/barretenberg/cpp/src/barretenberg/honk/composer/eccvm_composer.hpp b/barretenberg/cpp/src/barretenberg/honk/composer/eccvm_composer.hpp index bd72d44bb6c..93b3b991461 100644 --- a/barretenberg/cpp/src/barretenberg/honk/composer/eccvm_composer.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/composer/eccvm_composer.hpp @@ -23,7 +23,7 @@ template class ECCVMComposer_ { std::shared_ptr verification_key; // The crs_factory holds the path to the srs and exposes methods to extract the srs elements - std::shared_ptr> crs_factory_; + std::shared_ptr> crs_factory_; // The commitment key is passed to the prover but also used herein to compute the verfication key commitments std::shared_ptr commitment_key; @@ -42,7 +42,8 @@ template class ECCVMComposer_ { crs_factory_ = barretenberg::srs::get_crs_factory(); }; - explicit ECCVMComposer_(std::shared_ptr> crs_factory) + explicit ECCVMComposer_( + std::shared_ptr> crs_factory) : crs_factory_(std::move(crs_factory)) {} @@ -65,7 +66,7 @@ template class ECCVMComposer_ { ECCVMProver_ create_prover(CircuitConstructor& circuit_constructor); ECCVMVerifier_ create_verifier(CircuitConstructor& circuit_constructor); - void add_table_column_selector_poly_to_proving_key(polynomial& small, const std::string& tag); + void add_table_column_selector_poly_to_proving_key(barretenberg::polynomial& small, const std::string& tag); void compute_commitment_key(size_t circuit_size) { diff --git a/barretenberg/cpp/src/barretenberg/honk/composer/eccvm_composer.test.cpp b/barretenberg/cpp/src/barretenberg/honk/composer/eccvm_composer.test.cpp index 9b4d520b7d3..75f8fead781 100644 --- a/barretenberg/cpp/src/barretenberg/honk/composer/eccvm_composer.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/composer/eccvm_composer.test.cpp @@ -4,7 +4,6 @@ #include #include "barretenberg/honk/composer/eccvm_composer.hpp" -#include "barretenberg/honk/proof_system/prover.hpp" #include "barretenberg/honk/sumcheck/sumcheck_round.hpp" #include "barretenberg/honk/utils/grand_product_delta.hpp" #include "barretenberg/numeric/uint256/uint256.hpp" diff --git a/barretenberg/cpp/src/barretenberg/honk/composer/standard_composer.cpp b/barretenberg/cpp/src/barretenberg/honk/composer/standard_composer.cpp deleted file mode 100644 index d7d8b55b1e8..00000000000 --- a/barretenberg/cpp/src/barretenberg/honk/composer/standard_composer.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include "standard_composer.hpp" -#include "barretenberg/numeric/bitop/get_msb.hpp" -#include "barretenberg/polynomials/polynomial.hpp" -#include "barretenberg/srs/factories/crs_factory.hpp" - -#include -#include -#include - -namespace proof_system::honk { - -template -std::shared_ptr> StandardComposer_::create_instance(CircuitBuilder& circuit) -{ - auto instance = std::make_shared(circuit); - instance->commitment_key = compute_commitment_key(instance->proving_key->circuit_size); - return instance; -} - -template -StandardVerifier_ StandardComposer_::create_verifier(std::shared_ptr instance) -{ - auto verification_key = instance->compute_verification_key(); - StandardVerifier_ output_state(verification_key); - auto pcs_verification_key = - std::make_unique(verification_key->circuit_size, crs_factory_); - output_state.pcs_verification_key = std::move(pcs_verification_key); - - return output_state; -} - -template -StandardProver_ StandardComposer_::create_prover(std::shared_ptr instance) -{ - StandardProver_ output_state(instance); - - return output_state; -} - -template class StandardComposer_; -template class StandardComposer_; -} // namespace proof_system::honk \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/honk/composer/standard_composer.hpp b/barretenberg/cpp/src/barretenberg/honk/composer/standard_composer.hpp deleted file mode 100644 index 6763a4a29d1..00000000000 --- a/barretenberg/cpp/src/barretenberg/honk/composer/standard_composer.hpp +++ /dev/null @@ -1,83 +0,0 @@ -#pragma once - -#include "barretenberg/honk/instance/prover_instance.hpp" -#include "barretenberg/honk/proof_system/prover.hpp" -#include "barretenberg/honk/proof_system/verifier.hpp" -#include "barretenberg/proof_system/circuit_builder/standard_circuit_builder.hpp" -#include "barretenberg/proof_system/composer/composer_lib.hpp" -#include "barretenberg/proof_system/composer/permutation_lib.hpp" -#include "barretenberg/srs/factories/file_crs_factory.hpp" -#include - -#include "barretenberg/honk/flavor/standard.hpp" -#include "barretenberg/honk/flavor/standard_grumpkin.hpp" - -namespace proof_system::honk { -template class StandardComposer_ { - public: - using CircuitBuilder = typename Flavor::CircuitBuilder; - using ProvingKey = typename Flavor::ProvingKey; - using VerificationKey = typename Flavor::VerificationKey; - using CommitmentKey = typename Flavor::CommitmentKey; - using Instance = ProverInstance_; - - static constexpr std::string_view NAME_STRING = "StandardHonk"; - static constexpr size_t NUM_WIRES = CircuitBuilder::NUM_WIRES; - std::shared_ptr proving_key; - std::shared_ptr verification_key; - - // The crs_factory holds the path to the srs and exposes methods to extract the srs elements - std::shared_ptr> crs_factory_; - - // The commitment key is passed to the prover but also used herein to compute the verfication key commitments - std::shared_ptr commitment_key; - ; - - bool computed_witness = false; - // TODO(Luke): use make_shared - // TODO(https://github.com/AztecProtocol/barretenberg/issues/637): design the crs factory better - StandardComposer_() - { - if constexpr (IsGrumpkinFlavor) { - crs_factory_ = barretenberg::srs::get_grumpkin_crs_factory(); - - } else { - crs_factory_ = barretenberg::srs::get_crs_factory(); - } - } - - StandardComposer_(std::shared_ptr> crs_factory) - : crs_factory_(std::move(crs_factory)) - {} - - StandardComposer_(std::unique_ptr>&& crs_factory) - : crs_factory_(std::move(crs_factory)) - {} - StandardComposer_(std::shared_ptr p_key, std::shared_ptr v_key) - : proving_key(std::move(p_key)) - , verification_key(std::move(v_key)) - {} - StandardComposer_(StandardComposer_&& other) noexcept = default; - StandardComposer_(const StandardComposer_& other) = delete; - StandardComposer_& operator=(StandardComposer_&& other) noexcept = default; - StandardComposer_& operator=(const StandardComposer_& other) = delete; - ~StandardComposer_() = default; - - std::shared_ptr create_instance(CircuitBuilder& circuit); - - StandardProver_ create_prover(std::shared_ptr); - StandardVerifier_ create_verifier(std::shared_ptr); - - std::shared_ptr compute_commitment_key(size_t circuit_size) - { - commitment_key = std::make_shared(circuit_size, crs_factory_); - return commitment_key; - }; -}; - -extern template class StandardComposer_; -extern template class StandardComposer_; -// TODO(#532): this pattern is weird; is this not instantiating the templates? -using StandardComposer = StandardComposer_; -using StandardGrumpkinComposer = StandardComposer_; -} // namespace proof_system::honk diff --git a/barretenberg/cpp/src/barretenberg/honk/composer/standard_composer.test.cpp b/barretenberg/cpp/src/barretenberg/honk/composer/standard_composer.test.cpp deleted file mode 100644 index 7a5efaede99..00000000000 --- a/barretenberg/cpp/src/barretenberg/honk/composer/standard_composer.test.cpp +++ /dev/null @@ -1,448 +0,0 @@ -#include -#include -#include -#include - -#include "barretenberg/honk/composer/standard_composer.hpp" -#include "barretenberg/honk/proof_system/prover.hpp" -#include "barretenberg/honk/sumcheck/sumcheck_round.hpp" -#include "barretenberg/honk/utils/grand_product_delta.hpp" -#include "barretenberg/numeric/uint256/uint256.hpp" -#include "barretenberg/polynomials/polynomial.hpp" -#include "barretenberg/proof_system/circuit_builder/standard_circuit_builder.hpp" -#include "barretenberg/proof_system/relations/permutation_relation.hpp" -#include "barretenberg/proof_system/relations/relation_parameters.hpp" - -using namespace proof_system::honk; - -#define TYPE_ALIASES \ - using Flavor = TypeParam; \ - using FF = typename Flavor::FF; \ - using CircuitBuilder = proof_system::StandardCircuitBuilder_; \ - using Composer = StandardComposer_; - -namespace test_standard_honk_composer { - -template class StandardHonkComposerTests : public ::testing::Test { - protected: - // TODO(640): The Standard Honk on Grumpkin test suite fails unless the SRS is initialised for every test. - virtual void SetUp() - { - if constexpr (proof_system::IsGrumpkinFlavor) { - barretenberg::srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); - } else { - barretenberg::srs::init_crs_factory("../srs_db/ignition"); - } - }; -}; - -using FlavorTypes = ::testing::Types; -TYPED_TEST_SUITE(StandardHonkComposerTests, FlavorTypes); - -/** - * @brief The goal of this test is to check that the sigma permutation vectors for honk are generated correctly. - * - * @details Specifically: - * 1) That they are indeed a permutation of all initial indices - * 2) That if the permutation argument is computed with witness values, the values from the identity permutation and - * sigma permutation are equal - */ -TYPED_TEST(StandardHonkComposerTests, SigmaIDCorrectness) -{ - TYPE_ALIASES - auto test_permutation = [](CircuitBuilder& builder, Composer& composer) { - auto instance = composer.create_instance(builder); - auto prover = composer.create_prover(instance); - auto proving_key = instance->proving_key; - - const auto n = proving_key->circuit_size; - - auto public_inputs = builder.get_public_inputs(); - auto num_public_inputs = public_inputs.size(); - auto num_gates = builder.get_num_gates(); - - // Using the same random beta and gamma as in the permutation argument - FF beta = FF::random_element(); - FF gamma = FF::random_element(); - - FF left = FF::one(); - FF right = FF::one(); - - // Let's check that indices are the same and nothing is lost, first - size_t wire_idx = 0; - for (auto& sigma_polynomial : proving_key->get_sigma_polynomials()) { - for (size_t i = 0; i < n; ++i) { - left *= (gamma + wire_idx * n + i); - right *= (gamma + sigma_polynomial[i]); - } - // Ensure that the public inputs cycles are correctly broken - // and fix the cycle by adding the extra terms - if (wire_idx == 0) { - for (size_t i = 0; i < num_public_inputs; ++i) { - EXPECT_EQ(sigma_polynomial[i], -FF(i + 1)); - left *= (gamma - (i + 1)); - right *= (gamma + (n + i)); - } - } - ++wire_idx; - } - - EXPECT_EQ(left, right); - - left = FF::one(); - right = FF::one(); - - auto permutation_polynomials = proving_key->get_sigma_polynomials(); - auto id_polynomials = proving_key->get_id_polynomials(); - auto wire_polynomials = proving_key->get_wires(); - for (size_t j = 0; j < Composer::NUM_WIRES; ++j) { - std::string index = std::to_string(j + 1); - const auto& permutation_polynomial = permutation_polynomials[j]; - const auto& witness_polynomial = wire_polynomials[j]; - const auto& id_polynomial = id_polynomials[j]; - // left = ∏ᵢ,ⱼ(ωᵢ,ⱼ + β⋅ind(i,j) + γ) - // right = ∏ᵢ,ⱼ(ωᵢ,ⱼ + β⋅σ(i,j) + γ) - for (size_t i = 0; i < proving_key->circuit_size; ++i) { - const auto current_witness = witness_polynomial[i]; - left *= current_witness + beta * id_polynomial[i] + gamma; - right *= current_witness + beta * permutation_polynomial[i] + gamma; - } - // check that the first rows are correctly set to handle public inputs. - for (size_t i = 0; i < num_public_inputs; ++i) { - if ((j == 0) || (j == 1)) { - EXPECT_EQ(witness_polynomial[i], public_inputs[i]); - } else { - EXPECT_EQ(witness_polynomial[i], 0); - } - } - // Check that the last rows are all 0 - for (size_t i = num_public_inputs + num_gates; i < n; ++i) { - EXPECT_EQ(witness_polynomial[i], 0); - } - } - - // test correctness of the public input delta - auto delta = proof_system::honk::compute_public_input_delta(public_inputs, beta, gamma, n); - EXPECT_EQ(left / right, delta); - - for (size_t i = 0; i < num_public_inputs; ++i) { - left *= public_inputs[i] - beta * (i + 1) + gamma; - right *= public_inputs[i] + beta * (n + i) + gamma; - } - EXPECT_EQ(left, right); - }; - - auto builder = CircuitBuilder(); - FF a = FF::one(); - uint32_t a_idx = builder.add_variable(a); - FF b = FF::one(); - FF c = a + b; - uint32_t b_idx = builder.add_variable(b); - uint32_t c_idx = builder.add_variable(c); - FF d = a + c; - uint32_t d_idx = builder.add_public_variable(d); - - uint32_t e_idx = builder.put_constant_variable(d); - builder.assert_equal(e_idx, d_idx, ""); - - builder.create_add_gate({ a_idx, b_idx, c_idx, FF::one(), FF::one(), FF::neg_one(), FF::zero() }); - builder.create_add_gate({ d_idx, c_idx, a_idx, FF::one(), FF::neg_one(), FF::neg_one(), FF::zero() }); - builder.create_add_gate({ a_idx, b_idx, c_idx, FF::one(), FF::one(), FF::neg_one(), FF::zero() }); - builder.create_add_gate({ a_idx, b_idx, c_idx, FF::one(), FF::one(), FF::neg_one(), FF::zero() }); - builder.create_add_gate({ b_idx, a_idx, c_idx, FF::one(), FF::one(), FF::neg_one(), FF::zero() }); - for (size_t i = 0; i < 30; ++i) { - builder.create_add_gate({ a_idx, b_idx, c_idx, FF::one(), FF::one(), FF::neg_one(), FF::zero() }); - } - - auto composer = Composer(); - test_permutation(builder, composer); -} - -/** - * @brief Check the correctness of lagrange polynomials generated during proving key computation - * - */ -TYPED_TEST(StandardHonkComposerTests, LagrangeCorrectness) -{ - TYPE_ALIASES - using Polynomial = typename Flavor::Polynomial; - // Create a dummy circuit with a few gates - auto builder = CircuitBuilder(); - FF a = FF::one(); - uint32_t a_idx = builder.add_variable(a); - FF b = FF::one(); - FF c = a + b; - FF d = a + c; - uint32_t b_idx = builder.add_variable(b); - uint32_t c_idx = builder.add_variable(c); - uint32_t d_idx = builder.add_variable(d); - for (size_t i = 0; i < 16; i++) { - builder.create_add_gate({ a_idx, b_idx, c_idx, FF::one(), FF::one(), FF::neg_one(), FF::zero() }); - builder.create_add_gate({ d_idx, c_idx, a_idx, FF::one(), FF::neg_one(), FF::neg_one(), FF::zero() }); - } - - // Generate proving key - auto composer = Composer(); - auto instance = composer.create_instance(builder); - auto prover = composer.create_prover(instance); - auto proving_key = instance->proving_key; - - // Generate a random polynomial - Polynomial random_polynomial = Polynomial(proving_key->circuit_size); - for (size_t i = 0; i < proving_key->circuit_size; i++) { - random_polynomial[i] = FF::random_element(); - } - // Compute inner product of random polynomial and the first lagrange polynomial - - Polynomial first_lagrange_polynomial = proving_key->lagrange_first; - FF first_product(0); - for (size_t i = 0; i < proving_key->circuit_size; i++) { - first_product += random_polynomial[i] * first_lagrange_polynomial[i]; - } - EXPECT_EQ(first_product, random_polynomial[0]); - - // Compute inner product of random polynomial and the last lagrange polynomial - auto last_lagrange_polynomial = proving_key->lagrange_last; - FF last_product(0); - for (size_t i = 0; i < proving_key->circuit_size; i++) { - last_product += random_polynomial[i] * last_lagrange_polynomial[i]; - } - EXPECT_EQ(last_product, random_polynomial[proving_key->circuit_size - 1]); -} - -/** - * @brief Test that the assert_equal method in composer is working as intended - * - * @details We show equality of witness values through permutation arguments, so the assert_equal method changes the - * underlying variable structure. If we bind two real variables through it, we expect their wire copy cycles to be - * merged. - * In this test we create two almost identical circuits. They differ because one - */ -TYPED_TEST(StandardHonkComposerTests, AssertEquals) -{ - TYPE_ALIASES - - /** - * @brief A function that creates a simple circuit with repeated gates, leading to large permutation cycles - * - */ - auto create_simple_circuit = [](auto& builder) { - FF a = FF::one(); - uint32_t a_idx = builder.add_variable(a); - FF b = FF::one(); - FF c = a + b; - uint32_t b_idx = builder.add_variable(b); - uint32_t c_idx = builder.add_variable(c); - - for (size_t i = 0; i < 10; i++) { - builder.create_add_gate({ a_idx, b_idx, c_idx, FF::one(), FF::one(), FF::neg_one(), FF::zero() }); - builder.create_add_gate({ b_idx, a_idx, c_idx, FF::one(), FF::one(), FF::neg_one(), FF::zero() }); - } - return std::make_tuple(a_idx, b_idx); - }; - /** - * @brief A function that computes the largest cycle from the sigma permutation generated by the composer - * - */ - auto get_maximum_cycle = [](auto& builder, auto& composer) { - // Compute the proving key for sigma polynomials - auto instance = composer.create_instance(builder); - auto prover = composer.create_prover(instance); - auto proving_key = instance->proving_key; - - auto permutation_length = composer.NUM_WIRES * proving_key->circuit_size; - auto sigma_polynomials = proving_key->get_sigma_polynomials(); - - // Let's compute the maximum cycle - size_t maximum_cycle = 0; - - std::vector visited_indices; - - visited_indices.resize(permutation_length, false); - - for (size_t i = 0; i < permutation_length;) { - // Jump to first unvisited member in the cycle - // We check that i is limited by permutation_length - while (visited_indices[i] && (i < permutation_length)) { - i++; - } - if (i >= permutation_length) { - break; - } - auto starting_element = i; - auto next_element_big = - static_cast(sigma_polynomials[i / proving_key->circuit_size][i % proving_key->circuit_size]); - EXPECT_LE(next_element_big, uint256_t(UINT32_MAX)); - auto next_element = static_cast(next_element_big.data[0]); - size_t cycle_length = 1; - visited_indices[i] = true; - - // Jump through the cycle untill we reach the start or the permutation length exceeds the possible - // maximum - while ((next_element != starting_element) && cycle_length < (permutation_length + 1)) { - // Update cycle length and visited index infromation - cycle_length++; - visited_indices[next_element] = true; - // Get next index - next_element_big = static_cast(sigma_polynomials[next_element / proving_key->circuit_size] - [next_element % proving_key->circuit_size]); - EXPECT_LE(next_element_big, uint256_t(UINT32_MAX)); - next_element = static_cast(next_element_big.data[0]); - } - // If cycle_length is larger than permutation length, then instead of just a cycle we have a runway,too, - // which is incorrect - EXPECT_LE(cycle_length, permutation_length); - - // Update the maximum cycle - if (cycle_length > maximum_cycle) { - maximum_cycle = cycle_length; - } - } - return maximum_cycle; - }; - - // Get 2 circuits - auto builder_no_assert_equal = CircuitBuilder(); - auto builder_with_assert_equal = CircuitBuilder(); - - // Construct circuits - create_simple_circuit(builder_no_assert_equal); - auto assert_eq_params = create_simple_circuit(builder_with_assert_equal); - - // Use assert_equal on one of them - builder_with_assert_equal.assert_equal(std::get<0>(assert_eq_params), - std::get<1>(assert_eq_params), - "Equality asssertion in standard honk composer test"); - - // Check that the maximum cycle in the one, where we used assert_equal, is twice as long - auto composer_no_assert_equal = Composer(); - auto composer_with_assert_equal = Composer(); - EXPECT_EQ(get_maximum_cycle(builder_with_assert_equal, composer_with_assert_equal), - get_maximum_cycle(builder_no_assert_equal, composer_no_assert_equal) * 2); -} - -TYPED_TEST(StandardHonkComposerTests, VerificationKeyCreation) -{ - TYPE_ALIASES - - // Create a composer and a dummy circuit with a few gates - auto builder = CircuitBuilder(); - FF a = FF::one(); - uint32_t a_idx = builder.add_variable(a); - FF b = FF::one(); - FF c = a + b; - FF d = a + c; - uint32_t b_idx = builder.add_variable(b); - uint32_t c_idx = builder.add_variable(c); - uint32_t d_idx = builder.add_variable(d); - for (size_t i = 0; i < 16; i++) { - builder.create_add_gate({ a_idx, b_idx, c_idx, FF::one(), FF::one(), FF::neg_one(), FF::zero() }); - builder.create_add_gate({ d_idx, c_idx, a_idx, FF::one(), FF::neg_one(), FF::neg_one(), FF::zero() }); - } - - auto composer = Composer(); - auto instance = composer.create_instance(builder); - auto verification_key = instance->compute_verification_key(); - // There is nothing we can really check apart from the fact that constraint selectors and permutation selectors - // were committed to, we simply check that the verification key now contains the appropriate number of - // constraint and permutation selector commitments. This method should work with any future arithemtization. - EXPECT_EQ(verification_key->size(), builder.selectors.size() + composer.NUM_WIRES * 2 + 2); -} - -TYPED_TEST(StandardHonkComposerTests, BaseCase) -{ - TYPE_ALIASES - auto builder = CircuitBuilder(); - FF a = 1; - builder.add_variable(a); - - auto composer = Composer(); - auto instance = composer.create_instance(builder); - auto prover = composer.create_prover(instance); - auto proof = prover.construct_proof(); - auto verifier = composer.create_verifier(instance); - bool verified = verifier.verify_proof(proof); - ASSERT_TRUE(verified); -} - -TYPED_TEST(StandardHonkComposerTests, TwoGates) -{ - TYPE_ALIASES - auto run_test = [](bool expect_verified) { - if constexpr (proof_system::IsGrumpkinFlavor) { - barretenberg::srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); - } - auto builder = CircuitBuilder(); - // 1 + 1 - 2 = 0 - uint32_t w_l_1_idx; - if (expect_verified) { - w_l_1_idx = builder.add_variable(1); - } else { - w_l_1_idx = builder.add_variable(0); - } - uint32_t w_r_1_idx = builder.add_variable(1); - uint32_t w_o_1_idx = builder.add_variable(2); - builder.create_add_gate({ w_l_1_idx, w_r_1_idx, w_o_1_idx, 1, 1, -1, 0 }); - - // 2 * 2 - 4 = 0 - uint32_t w_l_2_idx = builder.add_variable(2); - uint32_t w_r_2_idx = builder.add_variable(2); - uint32_t w_o_2_idx = builder.add_variable(4); - builder.create_mul_gate({ w_l_2_idx, w_r_2_idx, w_o_2_idx, 1, -1, 0 }); - - auto composer = Composer(); - auto instance = composer.create_instance(builder); - auto prover = composer.create_prover(instance); - auto proof = prover.construct_proof(); - - auto verifier = composer.create_verifier(instance); - bool verified = verifier.verify_proof(proof); - - EXPECT_EQ(verified, expect_verified); - }; - - run_test(/* expect_verified=*/true); - run_test(/* expect_verified=*/false); -} - -TYPED_TEST(StandardHonkComposerTests, SumcheckEvaluations) -{ - TYPE_ALIASES - auto run_test = [](bool expected_result) { - if constexpr (proof_system::IsGrumpkinFlavor) { - barretenberg::srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); - } else { - barretenberg::srs::init_crs_factory("../srs_db/ignition"); - } - auto builder = CircuitBuilder(); - FF a = FF::one(); - // Construct a small but non-trivial circuit - uint32_t a_idx = builder.add_public_variable(a); - FF b = FF::one(); - FF c = a + b; - FF d = a + c; - - if (expected_result == false) { - d += 1; - }; - - uint32_t b_idx = builder.add_variable(b); - uint32_t c_idx = builder.add_variable(c); - uint32_t d_idx = builder.add_variable(d); - for (size_t i = 0; i < 4; i++) { - builder.create_add_gate({ a_idx, b_idx, c_idx, FF::one(), FF::one(), FF::neg_one(), FF::zero() }); - builder.create_add_gate({ d_idx, c_idx, a_idx, FF::one(), FF::neg_one(), FF::neg_one(), FF::zero() }); - } - - auto composer = Composer(); - auto instance = composer.create_instance(builder); - auto prover = composer.create_prover(instance); - auto proof = prover.construct_proof(); - auto verifier = composer.create_verifier(instance); - bool verified = verifier.verify_proof(proof); - ASSERT_EQ(verified, expected_result); - }; - run_test(/*expected_result=*/true); - run_test(/*expected_result=*/false); -} -} // namespace test_standard_honk_composer diff --git a/barretenberg/cpp/src/barretenberg/honk/flavor/flavor.test.cpp b/barretenberg/cpp/src/barretenberg/honk/flavor/flavor.test.cpp index 6a227e33f45..6c441842666 100644 --- a/barretenberg/cpp/src/barretenberg/honk/flavor/flavor.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/flavor/flavor.test.cpp @@ -1,141 +1,141 @@ -#include "barretenberg/honk/flavor/standard.hpp" -#include "barretenberg/polynomials/polynomial.hpp" -#include "barretenberg/srs/factories/crs_factory.hpp" -#include -#include - -#pragma GCC diagnostic ignored "-Wunused-local-typedefs" -#pragma GCC diagnostic ignored "-Wunused-variable" - -namespace proof_system::test_flavor { -TEST(Flavor, StandardGetters) -{ - using Flavor = proof_system::honk::flavor::Standard; - using FF = Flavor::FF; - using ProvingKey = typename Flavor::ProvingKey; - - ProvingKey proving_key = []() { return Flavor::ProvingKey(/*circuit_size=*/4, /*num_public_inputs=*/0); }(); - - // set - size_t coset_idx = 0; - for (auto& id_poly : proving_key.get_id_polynomials()) { - typename Flavor::Polynomial new_poly(proving_key.circuit_size); - for (size_t i = 0; i < proving_key.circuit_size; ++i) { - id_poly[i] = coset_idx * proving_key.circuit_size + i; - } - ++coset_idx; - } - - // Polynomials in the proving key can be set through loops over subsets produced by the getters - EXPECT_EQ(proving_key.id_1[0], FF(0)); - EXPECT_EQ(proving_key.id_2[0], FF(4)); - EXPECT_EQ(proving_key.id_3[0], FF(8)); - - Flavor::VerificationKey verification_key; - Flavor::ProverPolynomials prover_polynomials; - Flavor::ExtendedEdges edges; - Flavor::ClaimedEvaluations evals; - Flavor::CommitmentLabels commitment_labels; - - // Globals are also available through STL container sizes - EXPECT_EQ(prover_polynomials.size(), Flavor::NUM_ALL_ENTITIES); - // Shited polynomials have the righ tsize - EXPECT_EQ(prover_polynomials.size(), prover_polynomials.get_unshifted_then_shifted().size()); - // Commitment lables are stored in the flavor. - EXPECT_EQ(commitment_labels.w_r, "W_2"); - - auto get_test_polynomial = [](size_t& idx) { - Flavor::Polynomial poly(4); - for (size_t i = 0; i < 4; i++) { - poly[i] = idx++; - }; - return poly; - }; - - size_t idx = 0; - auto w_l = get_test_polynomial(idx); - auto w_r = get_test_polynomial(idx); - auto w_o = get_test_polynomial(idx); - auto z_perm = get_test_polynomial(idx); - auto z_perm_shift = get_test_polynomial(idx); - auto q_m = get_test_polynomial(idx); - auto q_l = get_test_polynomial(idx); - auto q_r = get_test_polynomial(idx); - auto q_o = get_test_polynomial(idx); - auto q_c = get_test_polynomial(idx); - auto sigma_1 = get_test_polynomial(idx); - auto sigma_2 = get_test_polynomial(idx); - auto sigma_3 = get_test_polynomial(idx); - auto id_1 = get_test_polynomial(idx); - auto id_2 = get_test_polynomial(idx); - auto id_3 = get_test_polynomial(idx); - auto lagrange_first = get_test_polynomial(idx); - auto lagrange_last = get_test_polynomial(idx); - - prover_polynomials.w_l = w_l; - prover_polynomials.w_r = w_r; - prover_polynomials.w_o = w_o; - prover_polynomials.z_perm = z_perm; - prover_polynomials.z_perm_shift = z_perm_shift; - prover_polynomials.q_m = q_m; - prover_polynomials.q_l = q_l; - prover_polynomials.q_r = q_r; - prover_polynomials.q_o = q_o; - prover_polynomials.q_c = q_c; - prover_polynomials.sigma_1 = sigma_1; - prover_polynomials.sigma_2 = sigma_2; - prover_polynomials.sigma_3 = sigma_3; - prover_polynomials.id_1 = id_1; - prover_polynomials.id_2 = id_2; - prover_polynomials.id_3 = id_3; - prover_polynomials.lagrange_first = lagrange_first; - prover_polynomials.lagrange_last = lagrange_last; - - // You can set polynomial values directly through the symbol names - // and then access the values through the getters. - idx = 0; - for (auto& poly : prover_polynomials.get_wires()) { - EXPECT_EQ(poly[0], 4 * idx); - EXPECT_EQ(poly[1], 4 * idx + 1); - EXPECT_EQ(poly[2], 4 * idx + 2); - EXPECT_EQ(poly[3], 4 * idx + 3); - ++idx; - }; - - idx = 4; // z_perm_shift is shifted - for (auto& poly : prover_polynomials.get_shifted()) { - EXPECT_EQ(poly[0], 4 * idx); - EXPECT_EQ(poly[1], 4 * idx + 1); - EXPECT_EQ(poly[2], 4 * idx + 2); - EXPECT_EQ(poly[3], 4 * idx + 3); - ++idx; - }; -} - -TEST(Flavor, AllEntitiesSpecialMemberFunctions) -{ - using Flavor = proof_system::honk::flavor::Standard; - using FF = Flavor::FF; - using PartiallyEvaluatedMultivariates = Flavor::PartiallyEvaluatedMultivariates; - using Polynomial = barretenberg::Polynomial; - - PartiallyEvaluatedMultivariates polynomials_A; - auto random_poly = Polynomial(10); - for (auto& coeff : random_poly) { - coeff = FF::random_element(); - } - - // Test some special member functions. - - polynomials_A.w_l = random_poly; - - ASSERT_EQ(random_poly, polynomials_A.w_l); - - PartiallyEvaluatedMultivariates polynomials_B(polynomials_A); - ASSERT_EQ(random_poly, polynomials_B.w_l); - - PartiallyEvaluatedMultivariates polynomials_C(std::move(polynomials_B)); - ASSERT_EQ(random_poly, polynomials_C.w_l); -} - -} // namespace proof_system::test_flavor +// #include "barretenberg/honk/flavor/standard.hpp" +// #include "barretenberg/polynomials/polynomial.hpp" +// #include "barretenberg/srs/factories/crs_factory.hpp" +// #include +// #include + +// #pragma GCC diagnostic ignored "-Wunused-local-typedefs" +// #pragma GCC diagnostic ignored "-Wunused-variable" + +// namespace proof_system::test_flavor { +// TEST(Flavor, StandardGetters) +// { +// using Flavor = proof_system::honk::flavor::Standard; +// using FF = Flavor::FF; +// using ProvingKey = typename Flavor::ProvingKey; + +// ProvingKey proving_key = []() { return Flavor::ProvingKey(/*circuit_size=*/4, /*num_public_inputs=*/0); }(); + +// // set +// size_t coset_idx = 0; +// for (auto& id_poly : proving_key.get_id_polynomials()) { +// typename Flavor::Polynomial new_poly(proving_key.circuit_size); +// for (size_t i = 0; i < proving_key.circuit_size; ++i) { +// id_poly[i] = coset_idx * proving_key.circuit_size + i; +// } +// ++coset_idx; +// } + +// // Polynomials in the proving key can be set through loops over subsets produced by the getters +// EXPECT_EQ(proving_key.id_1[0], FF(0)); +// EXPECT_EQ(proving_key.id_2[0], FF(4)); +// EXPECT_EQ(proving_key.id_3[0], FF(8)); + +// Flavor::VerificationKey verification_key; +// Flavor::ProverPolynomials prover_polynomials; +// Flavor::ExtendedEdges edges; +// Flavor::ClaimedEvaluations evals; +// Flavor::CommitmentLabels commitment_labels; + +// // Globals are also available through STL container sizes +// EXPECT_EQ(prover_polynomials.size(), Flavor::NUM_ALL_ENTITIES); +// // Shited polynomials have the righ tsize +// EXPECT_EQ(prover_polynomials.size(), prover_polynomials.get_unshifted_then_shifted().size()); +// // Commitment lables are stored in the flavor. +// EXPECT_EQ(commitment_labels.w_r, "W_2"); + +// auto get_test_polynomial = [](size_t& idx) { +// Flavor::Polynomial poly(4); +// for (size_t i = 0; i < 4; i++) { +// poly[i] = idx++; +// }; +// return poly; +// }; + +// size_t idx = 0; +// auto w_l = get_test_polynomial(idx); +// auto w_r = get_test_polynomial(idx); +// auto w_o = get_test_polynomial(idx); +// auto z_perm = get_test_polynomial(idx); +// auto z_perm_shift = get_test_polynomial(idx); +// auto q_m = get_test_polynomial(idx); +// auto q_l = get_test_polynomial(idx); +// auto q_r = get_test_polynomial(idx); +// auto q_o = get_test_polynomial(idx); +// auto q_c = get_test_polynomial(idx); +// auto sigma_1 = get_test_polynomial(idx); +// auto sigma_2 = get_test_polynomial(idx); +// auto sigma_3 = get_test_polynomial(idx); +// auto id_1 = get_test_polynomial(idx); +// auto id_2 = get_test_polynomial(idx); +// auto id_3 = get_test_polynomial(idx); +// auto lagrange_first = get_test_polynomial(idx); +// auto lagrange_last = get_test_polynomial(idx); + +// prover_polynomials.w_l = w_l; +// prover_polynomials.w_r = w_r; +// prover_polynomials.w_o = w_o; +// prover_polynomials.z_perm = z_perm; +// prover_polynomials.z_perm_shift = z_perm_shift; +// prover_polynomials.q_m = q_m; +// prover_polynomials.q_l = q_l; +// prover_polynomials.q_r = q_r; +// prover_polynomials.q_o = q_o; +// prover_polynomials.q_c = q_c; +// prover_polynomials.sigma_1 = sigma_1; +// prover_polynomials.sigma_2 = sigma_2; +// prover_polynomials.sigma_3 = sigma_3; +// prover_polynomials.id_1 = id_1; +// prover_polynomials.id_2 = id_2; +// prover_polynomials.id_3 = id_3; +// prover_polynomials.lagrange_first = lagrange_first; +// prover_polynomials.lagrange_last = lagrange_last; + +// // You can set polynomial values directly through the symbol names +// // and then access the values through the getters. +// idx = 0; +// for (auto& poly : prover_polynomials.get_wires()) { +// EXPECT_EQ(poly[0], 4 * idx); +// EXPECT_EQ(poly[1], 4 * idx + 1); +// EXPECT_EQ(poly[2], 4 * idx + 2); +// EXPECT_EQ(poly[3], 4 * idx + 3); +// ++idx; +// }; + +// idx = 4; // z_perm_shift is shifted +// for (auto& poly : prover_polynomials.get_shifted()) { +// EXPECT_EQ(poly[0], 4 * idx); +// EXPECT_EQ(poly[1], 4 * idx + 1); +// EXPECT_EQ(poly[2], 4 * idx + 2); +// EXPECT_EQ(poly[3], 4 * idx + 3); +// ++idx; +// }; +// } + +// TEST(Flavor, AllEntitiesSpecialMemberFunctions) +// { +// using Flavor = proof_system::honk::flavor::Standard; +// using FF = Flavor::FF; +// using PartiallyEvaluatedMultivariates = Flavor::PartiallyEvaluatedMultivariates; +// using Polynomial = barretenberg::Polynomial; + +// PartiallyEvaluatedMultivariates polynomials_A; +// auto random_poly = Polynomial(10); +// for (auto& coeff : random_poly) { +// coeff = FF::random_element(); +// } + +// // Test some special member functions. + +// polynomials_A.w_l = random_poly; + +// ASSERT_EQ(random_poly, polynomials_A.w_l); + +// PartiallyEvaluatedMultivariates polynomials_B(polynomials_A); +// ASSERT_EQ(random_poly, polynomials_B.w_l); + +// PartiallyEvaluatedMultivariates polynomials_C(std::move(polynomials_B)); +// ASSERT_EQ(random_poly, polynomials_C.w_l); +// } + +// } // namespace proof_system::test_flavor diff --git a/barretenberg/cpp/src/barretenberg/honk/flavor/standard.hpp b/barretenberg/cpp/src/barretenberg/honk/flavor/standard.hpp deleted file mode 100644 index 0f503179a6a..00000000000 --- a/barretenberg/cpp/src/barretenberg/honk/flavor/standard.hpp +++ /dev/null @@ -1,309 +0,0 @@ -#pragma once -#include "barretenberg/ecc/curves/bn254/g1.hpp" -#include "barretenberg/honk/pcs/kzg/kzg.hpp" -#include "barretenberg/honk/transcript/transcript.hpp" -#include "barretenberg/polynomials/barycentric.hpp" -#include "barretenberg/polynomials/evaluation_domain.hpp" -#include "barretenberg/polynomials/polynomial.hpp" -#include "barretenberg/polynomials/univariate.hpp" -#include "barretenberg/proof_system/circuit_builder/standard_circuit_builder.hpp" -#include "barretenberg/proof_system/flavor/flavor.hpp" -#include "barretenberg/proof_system/relations/arithmetic_relation.hpp" -#include "barretenberg/proof_system/relations/permutation_relation.hpp" -#include "barretenberg/srs/factories/crs_factory.hpp" - -namespace proof_system::honk::flavor { - -/** - * @brief Standard Honk - * @details We built this flavor first because it is the most basic. Because of this, it will remain useful for testing - * various constructions. Future variants may exist with varying: underlying curve (here we use BN254); commitment - * scheme (here we use Gemini + Shplonk + KZG); zero knowlege property (it's not implemented yet, but in the future we - * will be able to toggle it on or off). - * - */ -class Standard { - public: - using CircuitBuilder = StandardCircuitBuilder; - using Curve = curve::BN254; - using PCS = pcs::kzg::KZG; - using GroupElement = Curve::Element; - using Commitment = Curve::AffineElement; - using CommitmentHandle = Curve::AffineElement; - using FF = Curve::ScalarField; - using Polynomial = barretenberg::Polynomial; - using PolynomialHandle = std::span; - using CommitmentKey = pcs::CommitmentKey; - using VerifierCommitmentKey = pcs::VerifierCommitmentKey; - - static constexpr size_t NUM_WIRES = CircuitBuilder::NUM_WIRES; - // The number of multivariate polynomials on which a sumcheck prover sumcheck operates (including shifts). We often - // need containers of this size to hold related data, so we choose a name more agnostic than `NUM_POLYNOMIALS` - static constexpr size_t NUM_ALL_ENTITIES = 18; - // The number of polynomials precomputed to describe a circuit and to aid a prover in constructing a satisfying - // assignment of witnesses. We again choose a neutral name. - static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 13; - // The total number of witness entities not including shifts. - static constexpr size_t NUM_WITNESS_ENTITIES = 4; - - using GrandProductRelations = std::tuple>; - // define the tuple of Relations that comprise the Sumcheck relation - using Relations = std::tuple, proof_system::PermutationRelation>; - - static constexpr size_t MAX_RELATION_LENGTH = get_max_relation_length(); - - // MAX_RANDOM_RELATION_LENGTH = algebraic degree of sumcheck relation *after* multiplying by the `pow_zeta` random - // polynomial e.g. For \sum(x) [A(x) * B(x) + C(x)] * PowZeta(X), relation length = 2 and random relation length = 3 - static constexpr size_t MAX_RANDOM_RELATION_LENGTH = MAX_RELATION_LENGTH + 1; - static constexpr size_t NUM_RELATIONS = std::tuple_size::value; - - // define the containers for storing the contributions from each relation in Sumcheck - using RelationUnivariates = decltype(create_relation_univariates_container()); - using RelationValues = decltype(create_relation_values_container()); - - // Whether or not the first row of the execution trace is reserved for 0s to enable shifts - static constexpr bool has_zero_row = false; - - private: - /** - * @brief A base class labelling precomputed entities and (ordered) subsets of interest. - * @details Used to build the proving key and verification key. - */ - template - class PrecomputedEntities : public PrecomputedEntities_ { - public: - DataType& q_m = std::get<0>(this->_data); - DataType& q_l = std::get<1>(this->_data); - DataType& q_r = std::get<2>(this->_data); - DataType& q_o = std::get<3>(this->_data); - DataType& q_c = std::get<4>(this->_data); - DataType& sigma_1 = std::get<5>(this->_data); - DataType& sigma_2 = std::get<6>(this->_data); - DataType& sigma_3 = std::get<7>(this->_data); - DataType& id_1 = std::get<8>(this->_data); - DataType& id_2 = std::get<9>(this->_data); - DataType& id_3 = std::get<10>(this->_data); - DataType& lagrange_first = std::get<11>(this->_data); - DataType& lagrange_last = std::get<12>(this->_data); // = LAGRANGE_N-1 whithout ZK, but can be less - - static constexpr CircuitType CIRCUIT_TYPE = CircuitBuilder::CIRCUIT_TYPE; - - std::vector get_selectors() override { return { q_m, q_l, q_r, q_o, q_c }; }; - std::vector get_sigma_polynomials() override { return { sigma_1, sigma_2, sigma_3 }; }; - std::vector get_id_polynomials() override { return { id_1, id_2, id_3 }; }; - }; - - /** - * @brief Container for all witness polynomials used/constructed by the prover. - * @details Shifts are not included here since they do not occupy their own memory. - */ - template - class WitnessEntities : public WitnessEntities_ { - public: - DataType& w_l = std::get<0>(this->_data); - DataType& w_r = std::get<1>(this->_data); - DataType& w_o = std::get<2>(this->_data); - DataType& z_perm = std::get<3>(this->_data); - - std::vector get_wires() override { return { w_l, w_r, w_o }; }; - }; - - /** - * @brief A base class labelling all entities (for instance, all of the polynomials used by the prover during - * sumcheck) in this Honk variant along with particular subsets of interest - * @details Used to build containers for: the prover's polynomial during sumcheck; the sumcheck's folded - * polynomials; the univariates consturcted during during sumcheck; the evaluations produced by sumcheck. - * - * Symbolically we have: AllEntities = PrecomputedEntities + WitnessEntities + "ShiftedEntities". It could be - * implemented as such, but we don't have this now. - */ - template - class AllEntities : public AllEntities_ { - public: - DataType& q_c = std::get<0>(this->_data); - DataType& q_l = std::get<1>(this->_data); - DataType& q_r = std::get<2>(this->_data); - DataType& q_o = std::get<3>(this->_data); - DataType& q_m = std::get<4>(this->_data); - DataType& sigma_1 = std::get<5>(this->_data); - DataType& sigma_2 = std::get<6>(this->_data); - DataType& sigma_3 = std::get<7>(this->_data); - DataType& id_1 = std::get<8>(this->_data); - DataType& id_2 = std::get<9>(this->_data); - DataType& id_3 = std::get<10>(this->_data); - DataType& lagrange_first = std::get<11>(this->_data); - DataType& lagrange_last = std::get<12>(this->_data); - DataType& w_l = std::get<13>(this->_data); - DataType& w_r = std::get<14>(this->_data); - DataType& w_o = std::get<15>(this->_data); - DataType& z_perm = std::get<16>(this->_data); - DataType& z_perm_shift = std::get<17>(this->_data); - - std::vector get_wires() override { return { w_l, w_r, w_o }; }; - - // Gemini-specific getters. - std::vector get_unshifted() override - { - return { q_c, q_l, q_r, q_o, q_m, sigma_1, sigma_2, sigma_3, id_1, id_2, id_3, lagrange_first, - lagrange_last, w_l, w_r, w_o, z_perm }; - }; - std::vector get_to_be_shifted() override { return { z_perm }; }; - std::vector get_shifted() override { return { z_perm_shift }; }; - - // TODO(Cody): It would be nice to define these constructors once in a base class template. - AllEntities() = default; - - AllEntities(const AllEntities& other) - : AllEntities_(other){}; - - AllEntities(AllEntities&& other) - : AllEntities_(other){}; - - AllEntities& operator=(const AllEntities& other) - { - if (this == &other) { - return *this; - } - AllEntities_::operator=(other); - return *this; - } - - AllEntities& operator=(AllEntities&& other) - { - AllEntities_::operator=(other); - return *this; - } - - ~AllEntities() = default; - }; - - public: - /** - * @brief The proving key is responsible for storing the polynomials used by the prover. - * @note TODO(Cody): Maybe multiple inheritance is the right thing here. In that case, nothing should eve inherit - * from ProvingKey. - */ - class ProvingKey : public ProvingKey_, - WitnessEntities> { - public: - // Expose constructors of the base class - using Base = ProvingKey_, - WitnessEntities>; - using Base::Base; - }; - - /** - * @brief The verification key is responsible for storing the the commitments to the precomputed (non-witness) - * polynomials used by the verifier. - * - * @note Note the discrepancy with what sort of data is stored here vs in the proving key. We may want to resolve - * that, and split out separate PrecomputedPolynomials/Commitments data for clarity but also for portability of our - * circuits. - */ - using VerificationKey = VerificationKey_>; - - /** - * @brief A container for polynomials handles; only stores spans. - */ - using ProverPolynomials = AllEntities; - - /** - * @brief A container for storing the partially evaluated multivariates produced by sumcheck. - */ - class PartiallyEvaluatedMultivariates : public AllEntities { - - public: - PartiallyEvaluatedMultivariates() = default; - PartiallyEvaluatedMultivariates(const size_t circuit_size) - { - // Storage is only needed after the first partial evaluation, hence polynomials of size (n / 2) - for (auto& poly : this->_data) { - poly = Polynomial(circuit_size / 2); - } - } - }; - - /** - * @brief A container for univariates produced during the hot loop in sumcheck. - * @todo TODO(#390): Simplify this by moving MAX_RELATION_LENGTH? - */ - template - using ExtendedEdges = AllEntities, - barretenberg::Univariate>; - - /** - * @brief A container for the polynomials evaluations produced during sumcheck, which are purported to be the - * evaluations of polynomials committed in earlier rounds. - */ - class ClaimedEvaluations : public AllEntities { - public: - using Base = AllEntities; - using Base::Base; - ClaimedEvaluations(std::array _data_in) { this->_data = _data_in; } - }; - - /** - * @brief A container for commitment labels. - * @note It's debatable whether this should inherit from AllEntities. since most entries are not strictly needed. It - * has, however, been useful during debugging to have these labels available. - * - */ - class CommitmentLabels : public AllEntities { - public: - CommitmentLabels() - : AllEntities() - { - w_l = "W_1"; - w_r = "W_2"; - w_o = "W_3"; - z_perm = "Z_PERM"; - // The ones beginning with "__" are only used for debugging - z_perm_shift = "__Z_PERM_SHIFT"; - q_m = "__Q_M"; - q_l = "__Q_L"; - q_r = "__Q_R"; - q_o = "__Q_O"; - q_c = "__Q_C"; - sigma_1 = "__SIGMA_1"; - sigma_2 = "__SIGMA_2"; - sigma_3 = "__SIGMA_3"; - id_1 = "__ID_1"; - id_2 = "__ID_2"; - id_3 = "__ID_3"; - lagrange_first = "__LAGRANGE_FIRST"; - lagrange_last = "__LAGRANGE_LAST"; - }; - }; - - /** - * @brief A container for all commitments used by the verifier. - */ - class VerifierCommitments : public AllEntities { - public: - VerifierCommitments(std::shared_ptr verification_key) - { - // Initialize pre-computed commitments here, witness commitments during proof verification. - q_m = verification_key->q_m; - q_l = verification_key->q_l; - q_r = verification_key->q_r; - q_o = verification_key->q_o; - q_c = verification_key->q_c; - sigma_1 = verification_key->sigma_1; - sigma_2 = verification_key->sigma_2; - sigma_3 = verification_key->sigma_3; - id_1 = verification_key->id_1; - id_2 = verification_key->id_2; - id_3 = verification_key->id_3; - lagrange_first = verification_key->lagrange_first; - lagrange_last = verification_key->lagrange_last; - } - }; - - class FoldingParameters { - public: - FF gate_separation_challenge; - FF target_sum; - }; -}; - -} // namespace proof_system::honk::flavor diff --git a/barretenberg/cpp/src/barretenberg/honk/flavor/standard_grumpkin.hpp b/barretenberg/cpp/src/barretenberg/honk/flavor/standard_grumpkin.hpp deleted file mode 100644 index bee22076a59..00000000000 --- a/barretenberg/cpp/src/barretenberg/honk/flavor/standard_grumpkin.hpp +++ /dev/null @@ -1,306 +0,0 @@ -#pragma once -#include "barretenberg/ecc/curves/bn254/g1.hpp" -#include "barretenberg/honk/pcs/ipa/ipa.hpp" -#include "barretenberg/polynomials/barycentric.hpp" -#include "barretenberg/polynomials/univariate.hpp" - -#include "barretenberg/honk/transcript/transcript.hpp" -#include "barretenberg/polynomials/evaluation_domain.hpp" -#include "barretenberg/polynomials/polynomial.hpp" -#include "barretenberg/proof_system/circuit_builder/standard_circuit_builder.hpp" -#include "barretenberg/proof_system/flavor/flavor.hpp" -#include "barretenberg/proof_system/relations/arithmetic_relation.hpp" -#include "barretenberg/proof_system/relations/permutation_relation.hpp" -#include -#include -#include -#include -#include -#include - -namespace proof_system::honk::flavor { -class StandardGrumpkin { - // TODO(Mara): At the moment this class is a duplicate of the Standard flavor with a different PCS for testing - // purposes. This will be changed to Grumpkin once generating Honk proofs over Grumpkin has been enabled. - public: - using CircuitBuilder = StandardGrumpkinCircuitBuilder; - using Curve = curve::Grumpkin; - using PCS = pcs::ipa::IPA; - using GroupElement = Curve::Element; - using Commitment = Curve::AffineElement; - using CommitmentHandle = Curve::AffineElement; - using FF = Curve::ScalarField; - using Polynomial = barretenberg::Polynomial; - using PolynomialHandle = std::span; - using CommitmentKey = pcs::CommitmentKey; - using VerifierCommitmentKey = pcs::VerifierCommitmentKey; - - static constexpr size_t NUM_WIRES = CircuitBuilder::NUM_WIRES; - // The number of multivariate polynomials on which a sumcheck prover sumcheck operates (including shifts). We often - // need containers of this size to hold related data, so we choose a name more agnostic than `NUM_POLYNOMIALS` - static constexpr size_t NUM_ALL_ENTITIES = 18; - // The number of polynomials precomputed to describe a circuit and to aid a prover in constructing a satisfying - // assignment of witnesses. We again choose a neutral name. - static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 13; - // The total number of witness entities not including shifts. - static constexpr size_t NUM_WITNESS_ENTITIES = 4; - - // define the tuple of Relations that require grand products - using GrandProductRelations = std::tuple>; - // define the tuple of Relations that comprise the Sumcheck relation - using Relations = std::tuple, proof_system::PermutationRelation>; - - static constexpr size_t MAX_RELATION_LENGTH = get_max_relation_length(); - - // MAX_RANDOM_RELATION_LENGTH = algebraic degree of sumcheck relation *after* multiplying by the `pow_zeta` random - // polynomial e.g. For \sum(x) [A(x) * B(x) + C(x)] * PowZeta(X), relation length = 2 and random relation length = 3 - static constexpr size_t MAX_RANDOM_RELATION_LENGTH = MAX_RELATION_LENGTH + 1; - static constexpr size_t NUM_RELATIONS = std::tuple_size::value; - - // define the containers for storing the contributions from each relation in Sumcheck - using RelationUnivariates = decltype(create_relation_univariates_container()); - using RelationValues = decltype(create_relation_values_container()); - - // Whether or not the first row of the execution trace is reserved for 0s to enable shifts - static constexpr bool has_zero_row = false; - - private: - /** - * @brief A base class labelling precomputed entities and (ordered) subsets of interest. - * @details Used to build the proving key and verification key. - */ - template - class PrecomputedEntities : public PrecomputedEntities_ { - public: - DataType& q_m = std::get<0>(this->_data); - DataType& q_l = std::get<1>(this->_data); - DataType& q_r = std::get<2>(this->_data); - DataType& q_o = std::get<3>(this->_data); - DataType& q_c = std::get<4>(this->_data); - DataType& sigma_1 = std::get<5>(this->_data); - DataType& sigma_2 = std::get<6>(this->_data); - DataType& sigma_3 = std::get<7>(this->_data); - DataType& id_1 = std::get<8>(this->_data); - DataType& id_2 = std::get<9>(this->_data); - DataType& id_3 = std::get<10>(this->_data); - DataType& lagrange_first = std::get<11>(this->_data); - DataType& lagrange_last = std::get<12>(this->_data); // = LAGRANGE_N-1 whithout ZK, but can be less - - std::vector get_selectors() override { return { q_m, q_l, q_r, q_o, q_c }; }; - std::vector get_sigma_polynomials() override { return { sigma_1, sigma_2, sigma_3 }; }; - std::vector get_id_polynomials() override { return { id_1, id_2, id_3 }; }; - }; - - /** - * @brief Container for all witness polynomials used/constructed by the prover. - * @details Shifts are not included here since they do not occupy their own memory. - */ - template - class WitnessEntities : public WitnessEntities_ { - public: - DataType& w_l = std::get<0>(this->_data); - DataType& w_r = std::get<1>(this->_data); - DataType& w_o = std::get<2>(this->_data); - DataType& z_perm = std::get<3>(this->_data); - - std::vector get_wires() override { return { w_l, w_r, w_o }; }; - }; - - /** - * @brief A base class labelling all entities (for instance, all of the polynomials used by the prover during - * sumcheck) in this Honk variant along with particular subsets of interest - * @details Used to build containers for: the prover's polynomial during sumcheck; the sumcheck's folded - * polynomials; the univariates consturcted during during sumcheck; the evaluations produced by sumcheck. - * - * Symbolically we have: AllEntities = PrecomputedEntities + WitnessEntities + "ShiftedEntities". It could be - * implemented as such, but we don't have this now. - */ - template - class AllEntities : public AllEntities_ { - public: - DataType& q_c = std::get<0>(this->_data); - DataType& q_l = std::get<1>(this->_data); - DataType& q_r = std::get<2>(this->_data); - DataType& q_o = std::get<3>(this->_data); - DataType& q_m = std::get<4>(this->_data); - DataType& sigma_1 = std::get<5>(this->_data); - DataType& sigma_2 = std::get<6>(this->_data); - DataType& sigma_3 = std::get<7>(this->_data); - DataType& id_1 = std::get<8>(this->_data); - DataType& id_2 = std::get<9>(this->_data); - DataType& id_3 = std::get<10>(this->_data); - DataType& lagrange_first = std::get<11>(this->_data); - DataType& lagrange_last = std::get<12>(this->_data); - DataType& w_l = std::get<13>(this->_data); - DataType& w_r = std::get<14>(this->_data); - DataType& w_o = std::get<15>(this->_data); - DataType& z_perm = std::get<16>(this->_data); - DataType& z_perm_shift = std::get<17>(this->_data); - - std::vector get_wires() override { return { w_l, w_r, w_o }; }; - - // Gemini-specific getters. - std::vector get_unshifted() override - { - return { q_c, q_l, q_r, q_o, q_m, sigma_1, sigma_2, sigma_3, id_1, id_2, id_3, lagrange_first, - lagrange_last, w_l, w_r, w_o, z_perm }; - }; - std::vector get_to_be_shifted() override { return { z_perm }; }; - std::vector get_shifted() override { return { z_perm_shift }; }; - - // TODO(Cody): It would be nice to define these constructors once in a base class template. - AllEntities() = default; - - AllEntities(const AllEntities& other) - : AllEntities_(other){}; - - AllEntities(AllEntities&& other) - : AllEntities_(other){}; - - AllEntities& operator=(const AllEntities& other) - { - if (this == &other) { - return *this; - } - AllEntities_::operator=(other); - return *this; - } - - AllEntities& operator=(AllEntities&& other) - { - AllEntities_::operator=(other); - return *this; - } - - ~AllEntities() = default; - }; - - public: - /** - * @brief The proving key is responsible for storing the polynomials used by the prover. - * @note TODO(Cody): Maybe multiple inheritance is the right thing here. In that case, nothing should eve inherit - * from ProvingKey. - */ - class ProvingKey : public ProvingKey_, - WitnessEntities> { - public: - // Expose constructors of the base class - using Base = ProvingKey_, - WitnessEntities>; - using Base::Base; - }; - - /** - * @brief The verification key is responsible for storing the the commitments to the precomputed (non-witness) - * polynomials used by the verifier. - * - * @note Note the discrepancy with what sort of data is stored here vs in the proving key. We may want to resolve - * that, and split out separate PrecomputedPolynomials/Commitments data for clarity but also for portability of our - * circuits. - */ - using VerificationKey = VerificationKey_>; - - /** - * @brief A container for polynomials handles; only stores spans. - */ - using ProverPolynomials = AllEntities; - - /** - * @brief A container for storing the partially evaluated multivariates produced by sumcheck. - */ - class PartiallyEvaluatedMultivariates : public AllEntities { - - public: - PartiallyEvaluatedMultivariates() = default; - PartiallyEvaluatedMultivariates(const size_t circuit_size) - { - // Storage is only needed after the first partial evaluation, hence polynomials of size (n / 2) - for (auto& poly : this->_data) { - poly = Polynomial(circuit_size / 2); - } - } - }; - - /** - * @brief A container for univariates produced during the hot loop in sumcheck. - * @todo TODO(#390): Simplify this by moving MAX_RELATION_LENGTH? - */ - template - using ExtendedEdges = AllEntities, - barretenberg::Univariate>; - - /** - * @brief A container for the polynomials evaluations produced during sumcheck, which are purported to be the - * evaluations of polynomials committed in earlier rounds. - */ - class ClaimedEvaluations : public AllEntities { - public: - using Base = AllEntities; - using Base::Base; - ClaimedEvaluations(std::array _data_in) { this->_data = _data_in; } - }; - - /** - * @brief A container for commitment labels. - * @note It's debatable whether this should inherit from AllEntities. since most entries are not strictly needed. It - * has, however, been useful during debugging to have these labels available. - * - */ - class CommitmentLabels : public AllEntities { - public: - CommitmentLabels() - : AllEntities() - { - w_l = "W_1"; - w_r = "W_2"; - w_o = "W_3"; - z_perm = "Z_PERM"; - // The ones beginning with "__" are only used for debugging - z_perm_shift = "__Z_PERM_SHIFT"; - q_m = "__Q_M"; - q_l = "__Q_L"; - q_r = "__Q_R"; - q_o = "__Q_O"; - q_c = "__Q_C"; - sigma_1 = "__SIGMA_1"; - sigma_2 = "__SIGMA_2"; - sigma_3 = "__SIGMA_3"; - id_1 = "__ID_1"; - id_2 = "__ID_2"; - id_3 = "__ID_3"; - lagrange_first = "__LAGRANGE_FIRST"; - lagrange_last = "__LAGRANGE_LAST"; - }; - }; - - /** - * @brief A container for all commitments used by the verifier. - */ - class VerifierCommitments : public AllEntities { - public: - VerifierCommitments(std::shared_ptr verification_key) - { - // Initialize pre-computed commitments here, witness commitments during proof verification. - q_m = verification_key->q_m; - q_l = verification_key->q_l; - q_r = verification_key->q_r; - q_o = verification_key->q_o; - q_c = verification_key->q_c; - sigma_1 = verification_key->sigma_1; - sigma_2 = verification_key->sigma_2; - sigma_3 = verification_key->sigma_3; - id_1 = verification_key->id_1; - id_2 = verification_key->id_2; - id_3 = verification_key->id_3; - lagrange_first = verification_key->lagrange_first; - lagrange_last = verification_key->lagrange_last; - } - }; - - class FoldingParameters { - public: - FF gate_separation_challenge; - FF target_sum; - }; -}; -} // namespace proof_system::honk::flavor \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.cpp b/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.cpp index 284f1616b68..c3dbe4cb464 100644 --- a/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.cpp @@ -202,13 +202,6 @@ std::shared_ptr ProverInstance_::compute_pr proving_key = std::make_shared(dyadic_circuit_size, num_public_inputs); construct_selector_polynomials(circuit, proving_key.get()); - if constexpr (StandardFlavor) { - // Compute sigma polynomials (we should update that late) - compute_standard_honk_sigma_permutations(circuit, proving_key.get()); - compute_standard_honk_id_polynomials(proving_key.get()); - compute_first_and_last_lagrange_polynomials(proving_key.get()); - } - if constexpr (IsUltraFlavor) { compute_honk_generalized_sigma_permutations(circuit, proving_key.get()); @@ -510,8 +503,6 @@ std::shared_ptr ProverInstance_::compu template class ProverInstance_; template class ProverInstance_; -template class ProverInstance_; -template class ProverInstance_; template class ProverInstance_; } // namespace proof_system::honk \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.hpp b/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.hpp index f65a06e79e9..830f0578837 100644 --- a/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.hpp @@ -1,7 +1,5 @@ #pragma once #include "barretenberg/honk/flavor/goblin_ultra.hpp" -#include "barretenberg/honk/flavor/standard.hpp" -#include "barretenberg/honk/flavor/standard_grumpkin.hpp" #include "barretenberg/honk/flavor/ultra.hpp" #include "barretenberg/honk/flavor/ultra_grumpkin.hpp" #include "barretenberg/honk/proof_system/folding_result.hpp" @@ -113,8 +111,6 @@ template class ProverInstance_ { extern template class ProverInstance_; extern template class ProverInstance_; extern template class ProverInstance_; -extern template class ProverInstance_; -extern template class ProverInstance_; using ProverInstance = ProverInstance_; diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/eccvm_verifier.cpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/eccvm_verifier.cpp index f1dc05345c2..74f35e6e4b1 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/eccvm_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/eccvm_verifier.cpp @@ -1,5 +1,6 @@ #include "./eccvm_verifier.hpp" -#include "barretenberg/honk/flavor/standard.hpp" +#include "barretenberg/honk/pcs/gemini/gemini.hpp" +#include "barretenberg/honk/pcs/shplonk/shplonk.hpp" #include "barretenberg/honk/transcript/transcript.hpp" #include "barretenberg/honk/utils/power_polynomial.hpp" #include "barretenberg/numeric/bitop/get_msb.hpp" diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/grand_product_library.test.cpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/grand_product_library.test.cpp index 807c27f7d0f..c66c876b98a 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/grand_product_library.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/grand_product_library.test.cpp @@ -1,7 +1,6 @@ #include "grand_product_library.hpp" #include "barretenberg/ecc/curves/bn254/bn254.hpp" -#include "barretenberg/honk/flavor/standard.hpp" #include "barretenberg/honk/flavor/ultra.hpp" #include "barretenberg/polynomials/polynomial.hpp" @@ -118,17 +117,11 @@ template class GrandProductTests : public testing::Test { constexpr size_t PERMUTATION_RELATION_INDEX = 0; using LHS = typename std::tuple_element::type; - if constexpr (Flavor::NUM_WIRES == 4) { - using RHS = typename proof_system::UltraPermutationRelation; - static_assert(std::same_as); - grand_product_library::compute_grand_product( - proving_key->circuit_size, prover_polynomials, params); - } else { - using RHS = proof_system::PermutationRelation; - static_assert(std::same_as); - grand_product_library::compute_grand_product( - proving_key->circuit_size, prover_polynomials, params); - } + ASSERT(Flavor::NUM_WIRES == 4); + using RHS = typename proof_system::UltraPermutationRelation; + static_assert(std::same_as); + grand_product_library::compute_grand_product( + proving_key->circuit_size, prover_polynomials, params); // Method 2: Compute z_perm locally using the simplest non-optimized syntax possible. The comment below, // which describes the computation in 4 steps, is adapted from a similar comment in @@ -376,7 +369,6 @@ TYPED_TEST_SUITE(GrandProductTests, FieldTypes); TYPED_TEST(GrandProductTests, GrandProductPermutation) { - TestFixture::template test_permutation_grand_product_construction(); TestFixture::template test_permutation_grand_product_construction(); } diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/prover.cpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/prover.cpp deleted file mode 100644 index 8df098e009f..00000000000 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/prover.cpp +++ /dev/null @@ -1,248 +0,0 @@ -#include "prover.hpp" -#include "barretenberg/honk/proof_system/grand_product_library.hpp" -#include "barretenberg/honk/sumcheck/sumcheck.hpp" -#include "barretenberg/honk/transcript/transcript.hpp" -#include "barretenberg/honk/utils/power_polynomial.hpp" - -namespace proof_system::honk { - -/** - * Create Prover from proving key, witness and manifest. - * - * @param input_key Proving key. - * @param input_manifest Input manifest - * - * @tparam settings Settings class. - * */ -template -StandardProver_::StandardProver_(std::shared_ptr inst) - : queue(inst->commitment_key, transcript) - , instance(std::move(inst)) - , pcs_commitment_key(instance->commitment_key) -{ - instance->initialise_prover_polynomials(); -} - -/** - * - Add circuit size, public input size, and public inputs to transcript - * - * */ -template void StandardProver_::execute_preamble_round() -{ - const auto circuit_size = static_cast(instance->proving_key->circuit_size); - const auto num_public_inputs = static_cast(instance->proving_key->num_public_inputs); - - transcript.send_to_verifier("circuit_size", circuit_size); - transcript.send_to_verifier("public_input_size", num_public_inputs); - - for (size_t i = 0; i < instance->proving_key->num_public_inputs; ++i) { - auto public_input_i = instance->public_inputs[i]; - transcript.send_to_verifier("public_input_" + std::to_string(i), public_input_i); - } -} - -/** - * - Add commitment to wires 1,2,3 to work queue - * - Add PI to transcript (I guess PI will stay in w_2 for now?) - * - * */ -template void StandardProver_::execute_wire_commitments_round() -{ - size_t wire_idx = 0; // TODO(#391) zip - auto wire_polys = instance->proving_key->get_wires(); - for (auto& label : commitment_labels.get_wires()) { - queue.add_commitment(wire_polys[wire_idx], label); - ++wire_idx; - } -} - -/** - * For Standard Honk, this is a non-op (just like for Standard/Turbo Plonk). - * */ -template void StandardProver_::execute_tables_round() -{ - // No operations are needed here for Standard Honk -} - -/** - * - Do Fiat-Shamir to get "beta" challenge (Note: gamma = beta^2) - * - Compute grand product polynomial (permutation only) and commitment - * */ -template void StandardProver_::execute_grand_product_computation_round() -{ - // Compute and store parameters required by relations in Sumcheck - auto [beta, gamma] = transcript.get_challenges("beta", "gamma"); - - instance->compute_grand_product_polynomials(beta, gamma); - - queue.add_commitment(instance->proving_key->z_perm, commitment_labels.z_perm); -} - -/** - * - Do Fiat-Shamir to get "alpha" challenge - * - Run Sumcheck resulting in u = (u_1,...,u_d) challenges and all - * evaluations at u being calculated. - * */ -template void StandardProver_::execute_relation_check_rounds() -{ - using Sumcheck = sumcheck::SumcheckProver; - - auto sumcheck = Sumcheck(instance->proving_key->circuit_size, transcript); - - sumcheck_output = sumcheck.prove(instance->prover_polynomials, instance->relation_parameters); -} - -/** - * - Get rho challenge - * - Compute d+1 Fold polynomials and their evaluations. - * - * */ -template void StandardProver_::execute_univariatization_round() -{ - const size_t NUM_POLYNOMIALS = Flavor::NUM_ALL_ENTITIES; - - // Generate batching challenge ρ and powers 1,ρ,…,ρᵐ⁻¹ - FF rho = transcript.get_challenge("rho"); - std::vector rhos = pcs::gemini::powers_of_rho(rho, NUM_POLYNOMIALS); - auto key = instance->proving_key; - auto prover_polynomials = instance->prover_polynomials; - - // Batch the unshifted polynomials and the to-be-shifted polynomials using ρ - Polynomial batched_poly_unshifted(key->circuit_size); // batched unshifted polynomials - size_t poly_idx = 0; // TODO(#391) zip - for (auto& unshifted_poly : prover_polynomials.get_unshifted()) { - batched_poly_unshifted.add_scaled(unshifted_poly, rhos[poly_idx]); - ++poly_idx; - } - - Polynomial batched_poly_to_be_shifted(key->circuit_size); // batched to-be-shifted polynomials - for (auto& to_be_shifted_poly : prover_polynomials.get_to_be_shifted()) { - batched_poly_to_be_shifted.add_scaled(to_be_shifted_poly, rhos[poly_idx]); - ++poly_idx; - }; - - // Compute d-1 polynomials Fold^(i), i = 1, ..., d-1. - gemini_polynomials = Gemini::compute_gemini_polynomials( - sumcheck_output.challenge_point, std::move(batched_poly_unshifted), std::move(batched_poly_to_be_shifted)); - - // Compute and add to trasnscript the commitments [Fold^(i)], i = 1, ..., d-1 - for (size_t l = 0; l < key->log_circuit_size - 1; ++l) { - queue.add_commitment(gemini_polynomials[l + 2], "Gemini:FOLD_" + std::to_string(l + 1)); - } -} - -/** - * - Do Fiat-Shamir to get "r" challenge - * - Compute remaining two partially evaluated Fold polynomials Fold_{r}^(0) and Fold_{-r}^(0). - * - Compute and aggregate opening pairs (challenge, evaluation) for each of d Fold polynomials. - * - Add d-many Fold evaluations a_i, i = 0, ..., d-1 to the transcript, excluding eval of Fold_{r}^(0) - * */ -template void StandardProver_::execute_pcs_evaluation_round() -{ - const FF r_challenge = transcript.get_challenge("Gemini:r"); - gemini_output = Gemini::compute_fold_polynomial_evaluations( - sumcheck_output.challenge_point, std::move(gemini_polynomials), r_challenge); - - for (size_t l = 0; l < instance->proving_key->log_circuit_size; ++l) { - std::string label = "Gemini:a_" + std::to_string(l); - const auto& evaluation = gemini_output.opening_pairs[l + 1].evaluation; - transcript.send_to_verifier(label, evaluation); - } -} - -/** - * - Do Fiat-Shamir to get "nu" challenge. - * - Compute commitment [Q]_1 - * */ -template void StandardProver_::execute_shplonk_batched_quotient_round() -{ - nu_challenge = transcript.get_challenge("Shplonk:nu"); - - batched_quotient_Q = - Shplonk::compute_batched_quotient(gemini_output.opening_pairs, gemini_output.witnesses, nu_challenge); - - // commit to Q(X) and add [Q] to the transcript - queue.add_commitment(batched_quotient_Q, "Shplonk:Q"); -} - -/** - * - Do Fiat-Shamir to get "z" challenge. - * - Compute polynomial Q(X) - Q_z(X) - * */ -template void StandardProver_::execute_shplonk_partial_evaluation_round() -{ - const FF z_challenge = transcript.get_challenge("Shplonk:z"); - shplonk_output = Shplonk::compute_partially_evaluated_batched_quotient( - gemini_output.opening_pairs, gemini_output.witnesses, std::move(batched_quotient_Q), nu_challenge, z_challenge); -} - -/** - * - Compute final PCS opening proof: - * - For KZG, this is the quotient commitment [W]_1 - * - For IPA, the vectors L and R - * */ -template void StandardProver_::execute_final_pcs_round() -{ - PCS::compute_opening_proof(pcs_commitment_key, shplonk_output.opening_pair, shplonk_output.witness, transcript); -} - -template plonk::proof& StandardProver_::export_proof() -{ - proof.proof_data = transcript.proof_data; - return proof; -} - -template plonk::proof& StandardProver_::construct_proof() -{ - // Add circuit size and public input size to transcript. - execute_preamble_round(); - - // Compute wire commitments; Add PI to transcript - execute_wire_commitments_round(); - queue.process_queue(); - - // Currently a no-op; may execute some "random widgets", commit to W_4, do RAM/ROM stuff - // if this prover structure is kept when we bring tables to Honk. - // Suggestion: Maybe we shouldn't mix and match proof creation for different systems and - // instead instatiate construct_proof differently for each? - execute_tables_round(); - - // Fiat-Shamir: beta & gamma - // Compute grand product(s) and commitments. - execute_grand_product_computation_round(); - queue.process_queue(); - - // Fiat-Shamir: alpha - // Run sumcheck subprotocol. - execute_relation_check_rounds(); - - // Fiat-Shamir: rho - // Compute Fold polynomials and their commitments. - execute_univariatization_round(); - queue.process_queue(); - - // Fiat-Shamir: r - // Compute Fold evaluations - execute_pcs_evaluation_round(); - - // Fiat-Shamir: nu - // Compute Shplonk batched quotient commitment Q - execute_shplonk_batched_quotient_round(); - queue.process_queue(); - - // Fiat-Shamir: z - // Compute partial evaluation Q_z - execute_shplonk_partial_evaluation_round(); - - // Fiat-Shamir: z - // Compute final PCS opening proof (this is KZG quotient commitment or IPA opening proof) - execute_final_pcs_round(); - // TODO(#479): queue.process_queue after the work_queue has been (re)added to KZG/IPA - - return export_proof(); -} - -template class StandardProver_; -template class StandardProver_; - -} // namespace proof_system::honk diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/prover.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/prover.hpp deleted file mode 100644 index a88e8db8b7b..00000000000 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/prover.hpp +++ /dev/null @@ -1,86 +0,0 @@ -#pragma once -#include "barretenberg/honk/flavor/standard.hpp" -#include "barretenberg/honk/flavor/standard_grumpkin.hpp" -#include "barretenberg/honk/instance/prover_instance.hpp" -#include "barretenberg/honk/pcs/gemini/gemini.hpp" -#include "barretenberg/honk/pcs/shplonk/shplonk.hpp" -#include "barretenberg/honk/proof_system/work_queue.hpp" -#include "barretenberg/honk/sumcheck/sumcheck.hpp" -#include "barretenberg/honk/sumcheck/sumcheck_output.hpp" -#include "barretenberg/honk/transcript/transcript.hpp" -#include "barretenberg/plonk/proof_system/types/proof.hpp" - -namespace proof_system::honk { - -// We won't compile this class with honk::flavor::Ultra, but we will like want to compile it (at least for testing) -// with a flavor that uses the curve Grumpkin, or a flavor that does/does not have zk, etc. -template class StandardProver_ { - - using FF = typename Flavor::FF; - using ProvingKey = typename Flavor::ProvingKey; - using Polynomial = typename Flavor::Polynomial; - using ProverPolynomials = typename Flavor::ProverPolynomials; - using CommitmentLabels = typename Flavor::CommitmentLabels; - using CommitmentKey = typename Flavor::CommitmentKey; - using PCS = typename Flavor::PCS; - using Curve = typename Flavor::Curve; - using Instance = ProverInstance_; - - public: - explicit StandardProver_(std::shared_ptr); - void execute_preamble_round(); - void execute_wire_commitments_round(); - void execute_tables_round(); - void execute_grand_product_computation_round(); - void execute_relation_check_rounds(); - void execute_univariatization_round(); - void execute_pcs_evaluation_round(); - void execute_shplonk_batched_quotient_round(); - void execute_shplonk_partial_evaluation_round(); - - void execute_final_pcs_round(); - - void compute_wire_commitments(); - - void construct_prover_polynomials(); - - plonk::proof& export_proof(); - plonk::proof& construct_proof(); - - ProverTranscript transcript; - - std::vector public_inputs; - - CommitmentLabels commitment_labels; - - // Container for d + 1 Fold polynomials produced by Gemini - std::vector gemini_polynomials; - - Polynomial batched_quotient_Q; // batched quotient poly computed by Shplonk - FF nu_challenge; // needed in both Shplonk rounds - - Polynomial quotient_W; - - work_queue queue; - - std::shared_ptr instance; - - sumcheck::SumcheckOutput sumcheck_output; - pcs::gemini::ProverOutput gemini_output; - pcs::shplonk::ProverOutput shplonk_output; - std::shared_ptr pcs_commitment_key; - - using Gemini = pcs::gemini::GeminiProver_; - using Shplonk = pcs::shplonk::ShplonkProver_; - - private: - plonk::proof proof; -}; - -extern template class StandardProver_; -extern template class StandardProver_; - -using StandardProver = StandardProver_; -// using GrumpkinStandardProver = StandardProver_; // e.g. - -} // namespace proof_system::honk diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/ultra_verifier.cpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/ultra_verifier.cpp index 19bfcab0a41..38dc6c2b8b1 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/ultra_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/ultra_verifier.cpp @@ -1,6 +1,7 @@ #include "./ultra_verifier.hpp" -#include "barretenberg/honk/flavor/standard.hpp" #include "barretenberg/honk/pcs/claim.hpp" +#include "barretenberg/honk/pcs/gemini/gemini.hpp" +#include "barretenberg/honk/pcs/shplonk/shplonk.hpp" #include "barretenberg/honk/transcript/transcript.hpp" #include "barretenberg/honk/utils/power_polynomial.hpp" #include "barretenberg/numeric/bitop/get_msb.hpp" diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/verifier.cpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/verifier.cpp deleted file mode 100644 index d708c17bd1e..00000000000 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/verifier.cpp +++ /dev/null @@ -1,171 +0,0 @@ -#include "./verifier.hpp" -#include "barretenberg/honk/transcript/transcript.hpp" -#include "barretenberg/honk/utils/power_polynomial.hpp" -#include "barretenberg/numeric/bitop/get_msb.hpp" - -using namespace barretenberg; -using namespace proof_system::honk::sumcheck; - -namespace proof_system::honk { -template -StandardVerifier_::StandardVerifier_(std::shared_ptr verifier_key) - : key(verifier_key) -{} - -template -StandardVerifier_::StandardVerifier_(StandardVerifier_&& other) - : key(other.key) - , pcs_verification_key(std::move(other.pcs_verification_key)) -{} - -template StandardVerifier_& StandardVerifier_::operator=(StandardVerifier_&& other) -{ - key = other.key; - pcs_verification_key = (std::move(other.pcs_verification_key)); - commitments.clear(); - return *this; -} - -/** -* @brief This function verifies a Honk proof for given program settings. -* -* @details A Standard Honk proof contains the following: - Multilinear evaluations: - w_i(X), i = 1,2,3 - sigma_i(X), i = 1,2,3 - q_i(X), i = 1,2,3,4,5 - z_perm(X), - L_0(X), - id(X) - - Univariate evaluations: - a_0 = Fold_{-r}^(0)(-r), - a_l = Fold^(l)(-r^{2^l}), i = 1,...,d-1 - - Univariate polynomials (evaluations over MAX_RELATION_LENGTH-many points): - S_l, l = 0,...,d-1 - - Commitments: - [w_i]_1, i = 1,2,3 - [z_perm]_1, - [Fold^(l)]_1, l = 1,...,d-1 - [Q]_1, - [W]_1 -*/ -template bool StandardVerifier_::verify_proof(const plonk::proof& proof) -{ - using FF = typename Flavor::FF; - using GroupElement = typename Flavor::GroupElement; - using Commitment = typename Flavor::Commitment; - using Curve = typename Flavor::Curve; - using Gemini = pcs::gemini::GeminiVerifier_; - using Shplonk = pcs::shplonk::ShplonkVerifier_; - using PCS = typename Flavor::PCS; - using VerifierCommitments = typename Flavor::VerifierCommitments; - using CommitmentLabels = typename Flavor::CommitmentLabels; - - transcript = VerifierTranscript{ proof.proof_data }; - - auto commitments = VerifierCommitments(key); - auto commitment_labels = CommitmentLabels(); - - // TODO(Adrian): Change the initialization of the transcript to take the VK hash? - const auto circuit_size = transcript.template receive_from_prover("circuit_size"); - const auto public_input_size = transcript.template receive_from_prover("public_input_size"); - - if (circuit_size != key->circuit_size) { - return false; - } - if (public_input_size != key->num_public_inputs) { - return false; - } - - std::vector public_inputs; - for (size_t i = 0; i < public_input_size; ++i) { - auto public_input_i = transcript.template receive_from_prover("public_input_" + std::to_string(i)); - public_inputs.emplace_back(public_input_i); - } - - // Get commitments to the wires - commitments.w_l = transcript.template receive_from_prover(commitment_labels.w_l); - commitments.w_r = transcript.template receive_from_prover(commitment_labels.w_r); - commitments.w_o = transcript.template receive_from_prover(commitment_labels.w_o); - - // Get permutation challenges - auto [beta, gamma] = transcript.get_challenges("beta", "gamma"); - - const FF public_input_delta = compute_public_input_delta(public_inputs, beta, gamma, circuit_size); - - proof_system::RelationParameters relation_parameters{ - .beta = beta, - .gamma = gamma, - .public_input_delta = public_input_delta, - }; - - // Get commitment to Z_PERM - commitments.z_perm = transcript.template receive_from_prover(commitment_labels.z_perm); - - // Execute Sumcheck Verifier - auto sumcheck = SumcheckVerifier(circuit_size); - std::optional sumcheck_output = sumcheck.verify(relation_parameters, transcript); - - // If Sumcheck does not return an output, sumcheck verification has failed - if (!sumcheck_output.has_value()) { - return false; - } - - auto [multivariate_challenge, purported_evaluations] = *sumcheck_output; - - // Execute Gemini/Shplonk verification: - - // Construct inputs for Gemini verifier: - // - Multivariate opening point u = (u_0, ..., u_{d-1}) - // - batched unshifted and to-be-shifted polynomial commitments - auto batched_commitment_unshifted = GroupElement::zero(); - auto batched_commitment_to_be_shifted = GroupElement::zero(); - - // Compute powers of batching challenge rho - FF rho = transcript.get_challenge("rho"); - std::vector rhos = pcs::gemini::powers_of_rho(rho, Flavor::NUM_ALL_ENTITIES); - - // Compute batched multivariate evaluation - FF batched_evaluation = FF::zero(); - size_t evaluation_idx = 0; - for (auto& value : purported_evaluations.get_unshifted_then_shifted()) { - batched_evaluation += value * rhos[evaluation_idx]; - ++evaluation_idx; - } - - // Construct batched commitment for NON-shifted polynomials - size_t commitment_idx = 0; - for (auto& commitment : commitments.get_unshifted()) { - batched_commitment_unshifted += commitment * rhos[commitment_idx]; - ++commitment_idx; - } - - // Construct batched commitment for to-be-shifted polynomials - for (auto& commitment : commitments.get_to_be_shifted()) { - batched_commitment_to_be_shifted += commitment * rhos[commitment_idx]; - ++commitment_idx; - } - - // Produce a Gemini claim consisting of: - // - d+1 commitments [Fold_{r}^(0)], [Fold_{-r}^(0)], and [Fold^(l)], l = 1:d-1 - // - d+1 evaluations a_0_pos, and a_l, l = 0:d-1 - auto gemini_claim = Gemini::reduce_verification(multivariate_challenge, - batched_evaluation, - batched_commitment_unshifted, - batched_commitment_to_be_shifted, - transcript); - - // Produce a Shplonk claim: commitment [Q] - [Q_z], evaluation zero (at random challenge z) - auto shplonk_claim = Shplonk::reduce_verification(pcs_verification_key, gemini_claim, transcript); - - // Verify the Shplonk claim with KZG or IPA - return PCS::verify(pcs_verification_key, shplonk_claim, transcript); -} - -template class StandardVerifier_; -template class StandardVerifier_; - -} // namespace proof_system::honk diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/verifier.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/verifier.hpp deleted file mode 100644 index d90cb61f863..00000000000 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/verifier.hpp +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once -#include "barretenberg/honk/flavor/standard.hpp" -#include "barretenberg/honk/flavor/standard_grumpkin.hpp" -#include "barretenberg/honk/sumcheck/sumcheck.hpp" -#include "barretenberg/plonk/proof_system/types/proof.hpp" - -namespace proof_system::honk { -template class StandardVerifier_ { - using FF = typename Flavor::FF; - using Commitment = typename Flavor::Commitment; - using VerificationKey = typename Flavor::VerificationKey; - using VerifierCommitmentKey = typename Flavor::VerifierCommitmentKey; - - public: - StandardVerifier_(std::shared_ptr verifier_key = nullptr); - StandardVerifier_(StandardVerifier_&& other); - StandardVerifier_(const StandardVerifier_& other) = delete; - StandardVerifier_& operator=(const StandardVerifier_& other) = delete; - StandardVerifier_& operator=(StandardVerifier_&& other); - - bool verify_proof(const plonk::proof& proof); - - std::shared_ptr key; - std::map commitments; - std::shared_ptr pcs_verification_key; - VerifierTranscript transcript; -}; - -extern template class StandardVerifier_; -extern template class StandardVerifier_; - -using StandardVerifier = StandardVerifier_; - -} // namespace proof_system::honk diff --git a/barretenberg/cpp/src/barretenberg/honk/sumcheck/partial_evaluation.test.cpp b/barretenberg/cpp/src/barretenberg/honk/sumcheck/partial_evaluation.test.cpp index 990376c5a8e..f63c4b507d9 100644 --- a/barretenberg/cpp/src/barretenberg/honk/sumcheck/partial_evaluation.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/sumcheck/partial_evaluation.test.cpp @@ -1,315 +1,315 @@ -#include "barretenberg/honk/flavor/standard.hpp" -#include "barretenberg/honk/sumcheck/sumcheck.hpp" -#include - -using namespace proof_system::honk::sumcheck; -namespace test_sumcheck_polynomials { - -template class PartialEvaluationTests : public testing::Test {}; - -using Flavors = testing::Types; - -TYPED_TEST_SUITE(PartialEvaluationTests, Flavors); - -/* - * We represent a bivariate f0 as f0(X0, X1). The indexing starts from 0 to match with the round number in sumcheck. - * The idea is variable X0 (lsb) will be folded at round 2 (the first sumcheck round), - * then the variable X1 (msb) will be folded at round 1 (the last rond in this case). Pictorially we have, - * v10 ------ v11 - * | | - * X0(lsb) | | - * | X1(msb) | - * v00 ------ v01 - * f0(X0, X1) = v00 * (1-X0) * (1-X1) - * + v10 * X0 * (1-X1) - * + v01 * (1-X0) * X1 - * + v11 * X0 * X1. - * - * To effectively represent folding we write, - * f0(X0, X1) = [v00 * (1-X0) + v10 * X0] * (1-X1) - * + [v01 * (1-X0) + v11 * X0] * X1. - * - * After folding at round 0 (round challenge u0), we have, - * f0(u0,X1) = (v00 * (1-u0) + v10 * u0) * (1-X1) - * + (v01 * (1-u0) + v11 * u0) * X1. - * - * After folding at round 1 (round challenge u1), we have, - * f0(u0,u1) = (v00 * (1-u0) + v10 * u0) * (1-u1) - * + (v01 * (1-u0) + v11 * u0) * u1. - */ -TYPED_TEST(PartialEvaluationTests, TwoRoundsSpecial) -{ - using Flavor = TypeParam; - using FF = typename Flavor::FF; - using Transcript = proof_system::honk::ProverTranscript; - - // values here are chosen to check another test - const size_t multivariate_d(2); - const size_t multivariate_n(1 << multivariate_d); - - FF v00 = 0; - FF v10 = 1; - FF v01 = 0; - FF v11 = 0; - - std::array f0 = { v00, v10, v01, v11 }; - - auto full_polynomials = std::array, 1>({ f0 }); - auto transcript = Transcript::init_empty(); - auto sumcheck = SumcheckProver(multivariate_n, transcript); - - FF round_challenge_0 = { 0x6c7301b49d85a46c, 0x44311531e39c64f6, 0xb13d66d8d6c1a24c, 0x04410c360230a295 }; - round_challenge_0.self_to_montgomery_form(); - FF expected_lo = v00 * (FF(1) - round_challenge_0) + v10 * round_challenge_0; - FF expected_hi = v01 * (FF(1) - round_challenge_0) + v11 * round_challenge_0; - - sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); - - EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], round_challenge_0); - EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][1], FF(0)); - - FF round_challenge_1 = 2; - FF expected_val = expected_lo * (FF(1) - round_challenge_1) + expected_hi * round_challenge_1; - - sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 1, round_challenge_1); - EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], expected_val); -} - -TYPED_TEST(PartialEvaluationTests, TwoRoundsGeneric) -{ - using Flavor = TypeParam; - using FF = typename Flavor::FF; - using Transcript = proof_system::honk::ProverTranscript; - - const size_t multivariate_d(2); - const size_t multivariate_n(1 << multivariate_d); - - FF v00 = FF::random_element(); - FF v10 = FF::random_element(); - FF v01 = FF::random_element(); - FF v11 = FF::random_element(); - - std::array f0 = { v00, v10, v01, v11 }; - - auto full_polynomials = std::array, 1>({ f0 }); - auto transcript = Transcript::init_empty(); - auto sumcheck = SumcheckProver(multivariate_n, transcript); - - FF round_challenge_0 = FF::random_element(); - FF expected_lo = v00 * (FF(1) - round_challenge_0) + v10 * round_challenge_0; - FF expected_hi = v01 * (FF(1) - round_challenge_0) + v11 * round_challenge_0; - - sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); - - EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], expected_lo); - EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][1], expected_hi); - - FF round_challenge_1 = FF::random_element(); - FF expected_val = expected_lo * (FF(1) - round_challenge_1) + expected_hi * round_challenge_1; - sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 1, round_challenge_1); - EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], expected_val); -} - -/* - * Similarly for a trivariate polynomial f0(X0, X1, X2), we have - * f0(X0, X1, X2) = v000 * (1-X0) * (1-X1) * (1-X2) - * + v100 * X0 * (1-X1) * (1-X2) - * + v010 * (1-X0) * X1 * (1-X2) - * + v110 * X0 * X1 * (1-X2) - * + v001 * (1-X0) * (1-X1) * X2 - * + v101 * X0 * (1-X1) * X2 - * + v011 * (1-X0) * X1 * X2 - * + v111 * X0 * X1 * X2. - * After round 0 (round challenge u0), we have - * f0(u0, X1, X2) = [v000 * (1-u0) + v100 * u0] * (1-X1) * (1-X2) - * + [v010 * (1-u0) + v110 * u0] * X1 * (1-X2) - * + [v001 * (1-u0) + v101 * u0] * (1-X1) * X2 - * + [v011 * (1-u0) + v111 * u0] * X1 * X2. - * After round 1 (round challenge u1), we have - * f0(u0, u1, X2) = [(v000 * (1-u0) + v100 * u0) * (1-u1) + (v010 * (1-u0) + v110 * u0) * u1] * (1-X2) - * + [(v001 * (1-u0) + v101 * u0) * (1-u1) + (v011 * (1-u0) + v111 * u0) * u1] * X2. - * After round 2 (round challenge u2), we have - * f0(u0, u1, u2) = [(v000 * (1-u0) + v100 * u0) * (1-u1) + (v010 * (1-u0) + v110 * u0) * u1] * (1-u2) - * + [(v001 * (1-u0) + v101 * u0) * (1-u1) + (v011 * (1-u0) + v111 * u0) * u1] * u2. - */ -TYPED_TEST(PartialEvaluationTests, ThreeRoundsSpecial) -{ - using Flavor = TypeParam; - using FF = typename Flavor::FF; - using Transcript = proof_system::honk::ProverTranscript; - - const size_t multivariate_d(3); - const size_t multivariate_n(1 << multivariate_d); - - FF v000 = 1; - FF v100 = 2; - FF v010 = 3; - FF v110 = 4; - FF v001 = 5; - FF v101 = 6; - FF v011 = 7; - FF v111 = 8; - - std::array f0 = { v000, v100, v010, v110, v001, v101, v011, v111 }; - - auto full_polynomials = std::array, 1>({ f0 }); - auto transcript = Transcript::init_empty(); - auto sumcheck = SumcheckProver(multivariate_n, transcript); - - FF round_challenge_0 = 1; - FF expected_q1 = v000 * (FF(1) - round_challenge_0) + v100 * round_challenge_0; // 2 - FF expected_q2 = v010 * (FF(1) - round_challenge_0) + v110 * round_challenge_0; // 4 - FF expected_q3 = v001 * (FF(1) - round_challenge_0) + v101 * round_challenge_0; // 6 - FF expected_q4 = v011 * (FF(1) - round_challenge_0) + v111 * round_challenge_0; // 8 - - sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); - - EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], expected_q1); - EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][1], expected_q2); - EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][2], expected_q3); - EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][3], expected_q4); - - FF round_challenge_1 = 2; - FF expected_lo = expected_q1 * (FF(1) - round_challenge_1) + expected_q2 * round_challenge_1; // 6 - FF expected_hi = expected_q3 * (FF(1) - round_challenge_1) + expected_q4 * round_challenge_1; // 10 - - sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 1, round_challenge_1); - EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], expected_lo); - EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][1], expected_hi); - - FF round_challenge_2 = 3; - FF expected_val = expected_lo * (FF(1) - round_challenge_2) + expected_hi * round_challenge_2; // 18 - sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 2, round_challenge_2); - EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], expected_val); -} - -TYPED_TEST(PartialEvaluationTests, ThreeRoundsGeneric) -{ - using Flavor = TypeParam; - using FF = typename Flavor::FF; - using Transcript = proof_system::honk::ProverTranscript; - - const size_t multivariate_d(3); - const size_t multivariate_n(1 << multivariate_d); - - FF v000 = FF::random_element(); - FF v100 = FF::random_element(); - FF v010 = FF::random_element(); - FF v110 = FF::random_element(); - FF v001 = FF::random_element(); - FF v101 = FF::random_element(); - FF v011 = FF::random_element(); - FF v111 = FF::random_element(); - - std::array f0 = { v000, v100, v010, v110, v001, v101, v011, v111 }; - - auto full_polynomials = std::array, 1>({ f0 }); - auto transcript = Transcript::init_empty(); - auto sumcheck = SumcheckProver(multivariate_n, transcript); - - FF round_challenge_0 = FF::random_element(); - FF expected_q1 = v000 * (FF(1) - round_challenge_0) + v100 * round_challenge_0; - FF expected_q2 = v010 * (FF(1) - round_challenge_0) + v110 * round_challenge_0; - FF expected_q3 = v001 * (FF(1) - round_challenge_0) + v101 * round_challenge_0; - FF expected_q4 = v011 * (FF(1) - round_challenge_0) + v111 * round_challenge_0; - - sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); - - EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], expected_q1); - EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][1], expected_q2); - EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][2], expected_q3); - EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][3], expected_q4); - - FF round_challenge_1 = FF::random_element(); - FF expected_lo = expected_q1 * (FF(1) - round_challenge_1) + expected_q2 * round_challenge_1; - FF expected_hi = expected_q3 * (FF(1) - round_challenge_1) + expected_q4 * round_challenge_1; - - sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 1, round_challenge_1); - EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], expected_lo); - EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][1], expected_hi); - - FF round_challenge_2 = FF::random_element(); - FF expected_val = expected_lo * (FF(1) - round_challenge_2) + expected_hi * round_challenge_2; - sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 2, round_challenge_2); - EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], expected_val); -} - -TYPED_TEST(PartialEvaluationTests, ThreeRoundsGenericMultiplePolys) -{ - using Flavor = TypeParam; - using FF = typename Flavor::FF; - using Transcript = proof_system::honk::ProverTranscript; - - const size_t multivariate_d(3); - const size_t multivariate_n(1 << multivariate_d); - std::array v000; - std::array v100; - std::array v010; - std::array v110; - std::array v001; - std::array v101; - std::array v011; - std::array v111; - - for (size_t i = 0; i < 3; i++) { - v000[i] = FF::random_element(); - v100[i] = FF::random_element(); - v010[i] = FF::random_element(); - v110[i] = FF::random_element(); - v001[i] = FF::random_element(); - v101[i] = FF::random_element(); - v011[i] = FF::random_element(); - v111[i] = FF::random_element(); - } - std::array f0 = { v000[0], v100[0], v010[0], v110[0], v001[0], v101[0], v011[0], v111[0] }; - std::array f1 = { v000[1], v100[1], v010[1], v110[1], v001[1], v101[1], v011[1], v111[1] }; - std::array f2 = { v000[2], v100[2], v010[2], v110[2], v001[2], v101[2], v011[2], v111[2] }; - - auto full_polynomials = std::array, 3>{ f0, f1, f2 }; - auto transcript = Transcript::init_empty(); - auto sumcheck = SumcheckProver(multivariate_n, transcript); - - std::array expected_q1; - std::array expected_q2; - std::array expected_q3; - std::array expected_q4; - FF round_challenge_0 = FF::random_element(); - for (size_t i = 0; i < 3; i++) { - expected_q1[i] = v000[i] * (FF(1) - round_challenge_0) + v100[i] * round_challenge_0; - expected_q2[i] = v010[i] * (FF(1) - round_challenge_0) + v110[i] * round_challenge_0; - expected_q3[i] = v001[i] * (FF(1) - round_challenge_0) + v101[i] * round_challenge_0; - expected_q4[i] = v011[i] * (FF(1) - round_challenge_0) + v111[i] * round_challenge_0; - } - - sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); - for (size_t i = 0; i < 3; i++) { - EXPECT_EQ(sumcheck.partially_evaluated_polynomials[i][0], expected_q1[i]); - EXPECT_EQ(sumcheck.partially_evaluated_polynomials[i][1], expected_q2[i]); - EXPECT_EQ(sumcheck.partially_evaluated_polynomials[i][2], expected_q3[i]); - EXPECT_EQ(sumcheck.partially_evaluated_polynomials[i][3], expected_q4[i]); - } - - FF round_challenge_1 = FF::random_element(); - std::array expected_lo; - std::array expected_hi; - for (size_t i = 0; i < 3; i++) { - expected_lo[i] = expected_q1[i] * (FF(1) - round_challenge_1) + expected_q2[i] * round_challenge_1; - expected_hi[i] = expected_q3[i] * (FF(1) - round_challenge_1) + expected_q4[i] * round_challenge_1; - } - sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 1, round_challenge_1); - for (size_t i = 0; i < 3; i++) { - EXPECT_EQ(sumcheck.partially_evaluated_polynomials[i][0], expected_lo[i]); - EXPECT_EQ(sumcheck.partially_evaluated_polynomials[i][1], expected_hi[i]); - } - FF round_challenge_2 = FF::random_element(); - std::array expected_val; - for (size_t i = 0; i < 3; i++) { - expected_val[i] = expected_lo[i] * (FF(1) - round_challenge_2) + expected_hi[i] * round_challenge_2; - } - sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 2, round_challenge_2); - for (size_t i = 0; i < 3; i++) { - EXPECT_EQ(sumcheck.partially_evaluated_polynomials[i][0], expected_val[i]); - } -} - -} // namespace test_sumcheck_polynomials +// #include "barretenberg/honk/flavor/standard.hpp" +// #include "barretenberg/honk/sumcheck/sumcheck.hpp" +// #include + +// using namespace proof_system::honk::sumcheck; +// namespace test_sumcheck_polynomials { + +// template class PartialEvaluationTests : public testing::Test {}; + +// using Flavors = testing::Types; + +// TYPED_TEST_SUITE(PartialEvaluationTests, Flavors); + +// /* +// * We represent a bivariate f0 as f0(X0, X1). The indexing starts from 0 to match with the round number in sumcheck. +// * The idea is variable X0 (lsb) will be folded at round 2 (the first sumcheck round), +// * then the variable X1 (msb) will be folded at round 1 (the last rond in this case). Pictorially we have, +// * v10 ------ v11 +// * | | +// * X0(lsb) | | +// * | X1(msb) | +// * v00 ------ v01 +// * f0(X0, X1) = v00 * (1-X0) * (1-X1) +// * + v10 * X0 * (1-X1) +// * + v01 * (1-X0) * X1 +// * + v11 * X0 * X1. +// * +// * To effectively represent folding we write, +// * f0(X0, X1) = [v00 * (1-X0) + v10 * X0] * (1-X1) +// * + [v01 * (1-X0) + v11 * X0] * X1. +// * +// * After folding at round 0 (round challenge u0), we have, +// * f0(u0,X1) = (v00 * (1-u0) + v10 * u0) * (1-X1) +// * + (v01 * (1-u0) + v11 * u0) * X1. +// * +// * After folding at round 1 (round challenge u1), we have, +// * f0(u0,u1) = (v00 * (1-u0) + v10 * u0) * (1-u1) +// * + (v01 * (1-u0) + v11 * u0) * u1. +// */ +// TYPED_TEST(PartialEvaluationTests, TwoRoundsSpecial) +// { +// using Flavor = TypeParam; +// using FF = typename Flavor::FF; +// using Transcript = proof_system::honk::ProverTranscript; + +// // values here are chosen to check another test +// const size_t multivariate_d(2); +// const size_t multivariate_n(1 << multivariate_d); + +// FF v00 = 0; +// FF v10 = 1; +// FF v01 = 0; +// FF v11 = 0; + +// std::array f0 = { v00, v10, v01, v11 }; + +// auto full_polynomials = std::array, 1>({ f0 }); +// auto transcript = Transcript::init_empty(); +// auto sumcheck = SumcheckProver(multivariate_n, transcript); + +// FF round_challenge_0 = { 0x6c7301b49d85a46c, 0x44311531e39c64f6, 0xb13d66d8d6c1a24c, 0x04410c360230a295 }; +// round_challenge_0.self_to_montgomery_form(); +// FF expected_lo = v00 * (FF(1) - round_challenge_0) + v10 * round_challenge_0; +// FF expected_hi = v01 * (FF(1) - round_challenge_0) + v11 * round_challenge_0; + +// sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); + +// EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], round_challenge_0); +// EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][1], FF(0)); + +// FF round_challenge_1 = 2; +// FF expected_val = expected_lo * (FF(1) - round_challenge_1) + expected_hi * round_challenge_1; + +// sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 1, round_challenge_1); +// EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], expected_val); +// } + +// TYPED_TEST(PartialEvaluationTests, TwoRoundsGeneric) +// { +// using Flavor = TypeParam; +// using FF = typename Flavor::FF; +// using Transcript = proof_system::honk::ProverTranscript; + +// const size_t multivariate_d(2); +// const size_t multivariate_n(1 << multivariate_d); + +// FF v00 = FF::random_element(); +// FF v10 = FF::random_element(); +// FF v01 = FF::random_element(); +// FF v11 = FF::random_element(); + +// std::array f0 = { v00, v10, v01, v11 }; + +// auto full_polynomials = std::array, 1>({ f0 }); +// auto transcript = Transcript::init_empty(); +// auto sumcheck = SumcheckProver(multivariate_n, transcript); + +// FF round_challenge_0 = FF::random_element(); +// FF expected_lo = v00 * (FF(1) - round_challenge_0) + v10 * round_challenge_0; +// FF expected_hi = v01 * (FF(1) - round_challenge_0) + v11 * round_challenge_0; + +// sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); + +// EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], expected_lo); +// EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][1], expected_hi); + +// FF round_challenge_1 = FF::random_element(); +// FF expected_val = expected_lo * (FF(1) - round_challenge_1) + expected_hi * round_challenge_1; +// sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 1, round_challenge_1); +// EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], expected_val); +// } + +// /* +// * Similarly for a trivariate polynomial f0(X0, X1, X2), we have +// * f0(X0, X1, X2) = v000 * (1-X0) * (1-X1) * (1-X2) +// * + v100 * X0 * (1-X1) * (1-X2) +// * + v010 * (1-X0) * X1 * (1-X2) +// * + v110 * X0 * X1 * (1-X2) +// * + v001 * (1-X0) * (1-X1) * X2 +// * + v101 * X0 * (1-X1) * X2 +// * + v011 * (1-X0) * X1 * X2 +// * + v111 * X0 * X1 * X2. +// * After round 0 (round challenge u0), we have +// * f0(u0, X1, X2) = [v000 * (1-u0) + v100 * u0] * (1-X1) * (1-X2) +// * + [v010 * (1-u0) + v110 * u0] * X1 * (1-X2) +// * + [v001 * (1-u0) + v101 * u0] * (1-X1) * X2 +// * + [v011 * (1-u0) + v111 * u0] * X1 * X2. +// * After round 1 (round challenge u1), we have +// * f0(u0, u1, X2) = [(v000 * (1-u0) + v100 * u0) * (1-u1) + (v010 * (1-u0) + v110 * u0) * u1] * (1-X2) +// * + [(v001 * (1-u0) + v101 * u0) * (1-u1) + (v011 * (1-u0) + v111 * u0) * u1] * X2. +// * After round 2 (round challenge u2), we have +// * f0(u0, u1, u2) = [(v000 * (1-u0) + v100 * u0) * (1-u1) + (v010 * (1-u0) + v110 * u0) * u1] * (1-u2) +// * + [(v001 * (1-u0) + v101 * u0) * (1-u1) + (v011 * (1-u0) + v111 * u0) * u1] * u2. +// */ +// TYPED_TEST(PartialEvaluationTests, ThreeRoundsSpecial) +// { +// using Flavor = TypeParam; +// using FF = typename Flavor::FF; +// using Transcript = proof_system::honk::ProverTranscript; + +// const size_t multivariate_d(3); +// const size_t multivariate_n(1 << multivariate_d); + +// FF v000 = 1; +// FF v100 = 2; +// FF v010 = 3; +// FF v110 = 4; +// FF v001 = 5; +// FF v101 = 6; +// FF v011 = 7; +// FF v111 = 8; + +// std::array f0 = { v000, v100, v010, v110, v001, v101, v011, v111 }; + +// auto full_polynomials = std::array, 1>({ f0 }); +// auto transcript = Transcript::init_empty(); +// auto sumcheck = SumcheckProver(multivariate_n, transcript); + +// FF round_challenge_0 = 1; +// FF expected_q1 = v000 * (FF(1) - round_challenge_0) + v100 * round_challenge_0; // 2 +// FF expected_q2 = v010 * (FF(1) - round_challenge_0) + v110 * round_challenge_0; // 4 +// FF expected_q3 = v001 * (FF(1) - round_challenge_0) + v101 * round_challenge_0; // 6 +// FF expected_q4 = v011 * (FF(1) - round_challenge_0) + v111 * round_challenge_0; // 8 + +// sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); + +// EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], expected_q1); +// EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][1], expected_q2); +// EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][2], expected_q3); +// EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][3], expected_q4); + +// FF round_challenge_1 = 2; +// FF expected_lo = expected_q1 * (FF(1) - round_challenge_1) + expected_q2 * round_challenge_1; // 6 +// FF expected_hi = expected_q3 * (FF(1) - round_challenge_1) + expected_q4 * round_challenge_1; // 10 + +// sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 1, round_challenge_1); +// EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], expected_lo); +// EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][1], expected_hi); + +// FF round_challenge_2 = 3; +// FF expected_val = expected_lo * (FF(1) - round_challenge_2) + expected_hi * round_challenge_2; // 18 +// sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 2, round_challenge_2); +// EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], expected_val); +// } + +// TYPED_TEST(PartialEvaluationTests, ThreeRoundsGeneric) +// { +// using Flavor = TypeParam; +// using FF = typename Flavor::FF; +// using Transcript = proof_system::honk::ProverTranscript; + +// const size_t multivariate_d(3); +// const size_t multivariate_n(1 << multivariate_d); + +// FF v000 = FF::random_element(); +// FF v100 = FF::random_element(); +// FF v010 = FF::random_element(); +// FF v110 = FF::random_element(); +// FF v001 = FF::random_element(); +// FF v101 = FF::random_element(); +// FF v011 = FF::random_element(); +// FF v111 = FF::random_element(); + +// std::array f0 = { v000, v100, v010, v110, v001, v101, v011, v111 }; + +// auto full_polynomials = std::array, 1>({ f0 }); +// auto transcript = Transcript::init_empty(); +// auto sumcheck = SumcheckProver(multivariate_n, transcript); + +// FF round_challenge_0 = FF::random_element(); +// FF expected_q1 = v000 * (FF(1) - round_challenge_0) + v100 * round_challenge_0; +// FF expected_q2 = v010 * (FF(1) - round_challenge_0) + v110 * round_challenge_0; +// FF expected_q3 = v001 * (FF(1) - round_challenge_0) + v101 * round_challenge_0; +// FF expected_q4 = v011 * (FF(1) - round_challenge_0) + v111 * round_challenge_0; + +// sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); + +// EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], expected_q1); +// EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][1], expected_q2); +// EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][2], expected_q3); +// EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][3], expected_q4); + +// FF round_challenge_1 = FF::random_element(); +// FF expected_lo = expected_q1 * (FF(1) - round_challenge_1) + expected_q2 * round_challenge_1; +// FF expected_hi = expected_q3 * (FF(1) - round_challenge_1) + expected_q4 * round_challenge_1; + +// sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 1, round_challenge_1); +// EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], expected_lo); +// EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][1], expected_hi); + +// FF round_challenge_2 = FF::random_element(); +// FF expected_val = expected_lo * (FF(1) - round_challenge_2) + expected_hi * round_challenge_2; +// sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 2, round_challenge_2); +// EXPECT_EQ(sumcheck.partially_evaluated_polynomials[0][0], expected_val); +// } + +// TYPED_TEST(PartialEvaluationTests, ThreeRoundsGenericMultiplePolys) +// { +// using Flavor = TypeParam; +// using FF = typename Flavor::FF; +// using Transcript = proof_system::honk::ProverTranscript; + +// const size_t multivariate_d(3); +// const size_t multivariate_n(1 << multivariate_d); +// std::array v000; +// std::array v100; +// std::array v010; +// std::array v110; +// std::array v001; +// std::array v101; +// std::array v011; +// std::array v111; + +// for (size_t i = 0; i < 3; i++) { +// v000[i] = FF::random_element(); +// v100[i] = FF::random_element(); +// v010[i] = FF::random_element(); +// v110[i] = FF::random_element(); +// v001[i] = FF::random_element(); +// v101[i] = FF::random_element(); +// v011[i] = FF::random_element(); +// v111[i] = FF::random_element(); +// } +// std::array f0 = { v000[0], v100[0], v010[0], v110[0], v001[0], v101[0], v011[0], v111[0] }; +// std::array f1 = { v000[1], v100[1], v010[1], v110[1], v001[1], v101[1], v011[1], v111[1] }; +// std::array f2 = { v000[2], v100[2], v010[2], v110[2], v001[2], v101[2], v011[2], v111[2] }; + +// auto full_polynomials = std::array, 3>{ f0, f1, f2 }; +// auto transcript = Transcript::init_empty(); +// auto sumcheck = SumcheckProver(multivariate_n, transcript); + +// std::array expected_q1; +// std::array expected_q2; +// std::array expected_q3; +// std::array expected_q4; +// FF round_challenge_0 = FF::random_element(); +// for (size_t i = 0; i < 3; i++) { +// expected_q1[i] = v000[i] * (FF(1) - round_challenge_0) + v100[i] * round_challenge_0; +// expected_q2[i] = v010[i] * (FF(1) - round_challenge_0) + v110[i] * round_challenge_0; +// expected_q3[i] = v001[i] * (FF(1) - round_challenge_0) + v101[i] * round_challenge_0; +// expected_q4[i] = v011[i] * (FF(1) - round_challenge_0) + v111[i] * round_challenge_0; +// } + +// sumcheck.partially_evaluate(full_polynomials, multivariate_n, round_challenge_0); +// for (size_t i = 0; i < 3; i++) { +// EXPECT_EQ(sumcheck.partially_evaluated_polynomials[i][0], expected_q1[i]); +// EXPECT_EQ(sumcheck.partially_evaluated_polynomials[i][1], expected_q2[i]); +// EXPECT_EQ(sumcheck.partially_evaluated_polynomials[i][2], expected_q3[i]); +// EXPECT_EQ(sumcheck.partially_evaluated_polynomials[i][3], expected_q4[i]); +// } + +// FF round_challenge_1 = FF::random_element(); +// std::array expected_lo; +// std::array expected_hi; +// for (size_t i = 0; i < 3; i++) { +// expected_lo[i] = expected_q1[i] * (FF(1) - round_challenge_1) + expected_q2[i] * round_challenge_1; +// expected_hi[i] = expected_q3[i] * (FF(1) - round_challenge_1) + expected_q4[i] * round_challenge_1; +// } +// sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 1, round_challenge_1); +// for (size_t i = 0; i < 3; i++) { +// EXPECT_EQ(sumcheck.partially_evaluated_polynomials[i][0], expected_lo[i]); +// EXPECT_EQ(sumcheck.partially_evaluated_polynomials[i][1], expected_hi[i]); +// } +// FF round_challenge_2 = FF::random_element(); +// std::array expected_val; +// for (size_t i = 0; i < 3; i++) { +// expected_val[i] = expected_lo[i] * (FF(1) - round_challenge_2) + expected_hi[i] * round_challenge_2; +// } +// sumcheck.partially_evaluate(sumcheck.partially_evaluated_polynomials, multivariate_n >> 2, round_challenge_2); +// for (size_t i = 0; i < 3; i++) { +// EXPECT_EQ(sumcheck.partially_evaluated_polynomials[i][0], expected_val[i]); +// } +// } + +// } // namespace test_sumcheck_polynomials diff --git a/barretenberg/cpp/src/barretenberg/honk/sumcheck/relation_correctness.test.cpp b/barretenberg/cpp/src/barretenberg/honk/sumcheck/relation_correctness.test.cpp index 1f86e061916..2c34ebab7c2 100644 --- a/barretenberg/cpp/src/barretenberg/honk/sumcheck/relation_correctness.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/sumcheck/relation_correctness.test.cpp @@ -1,7 +1,5 @@ -#include "barretenberg/honk/composer/standard_composer.hpp" #include "barretenberg/honk/composer/ultra_composer.hpp" #include "barretenberg/honk/proof_system/grand_product_library.hpp" -#include "barretenberg/proof_system/relations/arithmetic_relation.hpp" #include "barretenberg/proof_system/relations/auxiliary_relation.hpp" #include "barretenberg/proof_system/relations/ecc_op_queue_relation.hpp" #include "barretenberg/proof_system/relations/elliptic_relation.hpp" @@ -207,49 +205,6 @@ class RelationCorrectnessTests : public ::testing::Test { static void SetUpTestSuite() { barretenberg::srs::init_crs_factory("../srs_db/ignition"); } }; -/** - * @brief Test the correctness of the Standard Honk relations - * - * @details Check that the constraints encoded by the relations are satisfied by the polynomials produced by the - * Standard Honk Composer for a real circuit. - * - * TODO(Kesha): We'll have to update this function once we add zk, since the relation will be incorrect for he first few - * indices - * - */ -TEST_F(RelationCorrectnessTests, StandardRelationCorrectness) -{ - using Flavor = flavor::Standard; - using FF = typename Flavor::FF; - - // Create a composer and a dummy circuit with a few gates - auto builder = proof_system::StandardCircuitBuilder(); - - create_some_add_gates(builder); - - // Create a prover (it will compute proving key and witness) - auto composer = StandardComposer(); - auto instance = composer.create_instance(builder); - auto proving_key = instance->proving_key; - auto circuit_size = proving_key->circuit_size; - - // Generate beta and gamma - FF beta = FF::random_element(); - FF gamma = FF::random_element(); - - instance->initialise_prover_polynomials(); - instance->compute_grand_product_polynomials(beta, gamma); - - // Construct the round for applying sumcheck relations and results for storing computed results - auto relations = std::tuple(proof_system::ArithmeticRelation(), proof_system::PermutationRelation()); - - auto prover_polynomials = instance->prover_polynomials; - auto params = instance->relation_parameters; - // Check that each relation is satisfied across each row of the prover polynomials - check_relation(std::get<0>(relations), circuit_size, prover_polynomials, params); - check_relation(std::get<1>(relations), circuit_size, prover_polynomials, params); -} - /** * @brief Test the correctness of the Ultra Honk relations * diff --git a/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck.hpp b/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck.hpp index 7723864f4b0..06847d05509 100644 --- a/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck.hpp @@ -1,7 +1,6 @@ #pragma once #include "barretenberg/common/serialize.hpp" #include "barretenberg/common/throw_or_abort.hpp" -#include "barretenberg/honk/proof_system/prover.hpp" #include "barretenberg/honk/sumcheck/sumcheck_output.hpp" #include "barretenberg/honk/transcript/transcript.hpp" #include "barretenberg/honk/utils/grand_product_delta.hpp" diff --git a/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck.test.cpp b/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck.test.cpp index 37dfbf90771..94be32df4b3 100644 --- a/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck.test.cpp @@ -1,600 +1,552 @@ -#include "sumcheck.hpp" -#include "barretenberg/ecc/curves/bn254/fr.hpp" -#include "barretenberg/honk/composer/standard_composer.hpp" -#include "barretenberg/honk/composer/ultra_composer.hpp" -#include "barretenberg/honk/proof_system/grand_product_library.hpp" -#include "barretenberg/honk/transcript/transcript.hpp" -#include "barretenberg/proof_system/relations/arithmetic_relation.hpp" -#include "barretenberg/proof_system/relations/auxiliary_relation.hpp" -#include "barretenberg/proof_system/relations/elliptic_relation.hpp" -#include "barretenberg/proof_system/relations/gen_perm_sort_relation.hpp" -#include "barretenberg/proof_system/relations/lookup_relation.hpp" -#include "barretenberg/proof_system/relations/permutation_relation.hpp" -#include "barretenberg/proof_system/relations/ultra_arithmetic_relation.hpp" -#include - -using namespace proof_system::honk; -using namespace proof_system::honk::sumcheck; -using Flavor = proof_system::honk::flavor::Standard; // TODO(Cody): Generalize this test. -using FF = typename Flavor::FF; -using ProverPolynomials = typename Flavor::ProverPolynomials; -const size_t NUM_POLYNOMIALS = Flavor::NUM_ALL_ENTITIES; - -namespace test_sumcheck_round { - -template -ProverPolynomials construct_full_polynomials(std::array& w_l, - std::array& w_r, - std::array& w_o, - std::array& z_perm, - std::array& z_perm_shift, - std::array& q_m, - std::array& q_l, - std::array& q_r, - std::array& q_o, - std::array& q_c, - std::array& sigma_1, - std::array& sigma_2, - std::array& sigma_3, - std::array& id_1, - std::array& id_2, - std::array& id_3, - std::array& lagrange_first, - std::array& lagrange_last) -{ - ProverPolynomials full_polynomials; - full_polynomials.w_l = w_l; - full_polynomials.w_r = w_r; - full_polynomials.w_o = w_o; - full_polynomials.z_perm = z_perm; - full_polynomials.z_perm_shift = z_perm_shift; - full_polynomials.q_m = q_m; - full_polynomials.q_l = q_l; - full_polynomials.q_r = q_r; - full_polynomials.q_o = q_o; - full_polynomials.q_c = q_c; - full_polynomials.sigma_1 = sigma_1; - full_polynomials.sigma_2 = sigma_2; - full_polynomials.sigma_3 = sigma_3; - full_polynomials.id_1 = id_1; - full_polynomials.id_2 = id_2; - full_polynomials.id_3 = id_3; - full_polynomials.lagrange_first = lagrange_first; - full_polynomials.lagrange_last = lagrange_last; - - return full_polynomials; -} - -class SumcheckTests : public ::testing::Test { - protected: - static void SetUpTestSuite() { barretenberg::srs::init_crs_factory("../srs_db/ignition"); } -}; - -TEST_F(SumcheckTests, PolynomialNormalization) -{ - // TODO(#225)(Cody): We should not use real constants like this in the tests, at least not in so many of them. - const size_t multivariate_d(3); - const size_t multivariate_n(1 << multivariate_d); - - std::array w_l; - std::array w_r; - std::array w_o; - std::array z_perm; - std::array z_perm_shift; - std::array q_m; - std::array q_l; - std::array q_r; - std::array q_o; - std::array q_c; - std::array sigma_1; - std::array sigma_2; - std::array sigma_3; - std::array id_1; - std::array id_2; - std::array id_3; - std::array lagrange_first; - std::array lagrange_last; - for (size_t i = 0; i < multivariate_n; i++) { - w_l[i] = FF::random_element(); - w_r[i] = FF::random_element(); - w_o[i] = FF::random_element(); - z_perm[i] = FF::random_element(); - z_perm_shift[i] = FF::random_element(); - q_m[i] = FF::random_element(); - q_l[i] = FF::random_element(); - q_r[i] = FF::random_element(); - q_o[i] = FF::random_element(); - q_c[i] = FF::random_element(); - sigma_1[i] = FF::random_element(); - sigma_2[i] = FF::random_element(); - sigma_3[i] = FF::random_element(); - id_1[i] = FF::random_element(); - id_2[i] = FF::random_element(); - id_3[i] = FF::random_element(); - lagrange_first[i] = FF::random_element(); - lagrange_last[i] = FF::random_element(); - } - - auto full_polynomials = construct_full_polynomials(w_l, - w_r, - w_o, - z_perm, - z_perm_shift, - q_m, - q_l, - q_r, - q_o, - q_c, - sigma_1, - sigma_2, - sigma_3, - id_1, - id_2, - id_3, - lagrange_first, - lagrange_last); - - auto transcript = ProverTranscript::init_empty(); - - auto sumcheck = SumcheckProver(multivariate_n, transcript); - - auto [multivariate_challenge, evaluations] = sumcheck.prove(full_polynomials, {}); - - FF u_0 = multivariate_challenge[0]; - FF u_1 = multivariate_challenge[1]; - FF u_2 = multivariate_challenge[2]; - - /* sumcheck.prove() terminates with sumcheck.multivariates.folded_polynoimals as an array such that - * sumcheck.multivariates.folded_polynoimals[i][0] is the evaluatioin of the i'th multivariate at the vector of - challenges u_i. What does this mean? - - Here we show that if the multivariate is F(X0, X1, X2) defined as above, then what we get is F(u0, u1, u2) and - not, say F(u2, u1, u0). This is in accordance with Adrian's thesis (cf page 9). - */ - - // Get the values of the Lagrange basis polys L_i defined - // by: L_i(v) = 1 if i = v, 0 otherwise, for v from 0 to 7. - FF one{ 1 }; - // clang-format off - FF l_0 = (one - u_0) * (one - u_1) * (one - u_2); - FF l_1 = ( u_0) * (one - u_1) * (one - u_2); - FF l_2 = (one - u_0) * ( u_1) * (one - u_2); - FF l_3 = ( u_0) * ( u_1) * (one - u_2); - FF l_4 = (one - u_0) * (one - u_1) * ( u_2); - FF l_5 = ( u_0) * (one - u_1) * ( u_2); - FF l_6 = (one - u_0) * ( u_1) * ( u_2); - FF l_7 = ( u_0) * ( u_1) * ( u_2); - // clang-format on - FF hand_computed_value; - for (size_t i = 0; i < NUM_POLYNOMIALS; i++) { - // full_polynomials[0][0] = w_l[0], full_polynomials[1][1] = w_r[1], and so on. - hand_computed_value = l_0 * full_polynomials[i][0] + l_1 * full_polynomials[i][1] + - l_2 * full_polynomials[i][2] + l_3 * full_polynomials[i][3] + - l_4 * full_polynomials[i][4] + l_5 * full_polynomials[i][5] + - l_6 * full_polynomials[i][6] + l_7 * full_polynomials[i][7]; - EXPECT_EQ(hand_computed_value, sumcheck.partially_evaluated_polynomials[i][0]); - } -} - -TEST_F(SumcheckTests, Prover) -{ - auto run_test = [](bool is_random_input) { - const size_t multivariate_d(2); - const size_t multivariate_n(1 << multivariate_d); - std::array, NUM_POLYNOMIALS> input_polynomials; - if (is_random_input) { - for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { - input_polynomials[i] = { - FF::random_element(), FF::random_element(), FF::random_element(), FF::random_element() - }; - } - } else { - for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { - input_polynomials[i] = { 1, 2, 0, 0 }; - } - }; - std::array w_l = input_polynomials[0]; - std::array w_r = input_polynomials[1]; - std::array w_o = input_polynomials[2]; - std::array z_perm = input_polynomials[3]; - std::array z_perm_shift = input_polynomials[4]; - std::array q_m = input_polynomials[5]; - std::array q_l = input_polynomials[6]; - std::array q_r = input_polynomials[7]; - std::array q_o = input_polynomials[8]; - std::array q_c = input_polynomials[9]; - std::array sigma_1 = input_polynomials[10]; - std::array sigma_2 = input_polynomials[11]; - std::array sigma_3 = input_polynomials[12]; - std::array id_1 = input_polynomials[13]; - std::array id_2 = input_polynomials[14]; - std::array id_3 = input_polynomials[15]; - std::array lagrange_first = input_polynomials[16]; - std::array lagrange_last = input_polynomials[17]; - auto full_polynomials = construct_full_polynomials(w_l, - w_r, - w_o, - z_perm, - z_perm_shift, - q_m, - q_l, - q_r, - q_o, - q_c, - sigma_1, - sigma_2, - sigma_3, - id_1, - id_2, - id_3, - lagrange_first, - lagrange_last); - - auto transcript = ProverTranscript::init_empty(); - - auto sumcheck = SumcheckProver(multivariate_n, transcript); - - auto [multivariate_challenge, evaluations] = sumcheck.prove(full_polynomials, {}); - FF u_0 = multivariate_challenge[0]; - FF u_1 = multivariate_challenge[1]; - std::vector expected_values; - for (auto& polynomial : full_polynomials) { - // using knowledge of inputs here to derive the evaluation - FF expected_lo = polynomial[0] * (FF(1) - u_0) + polynomial[1] * u_0; - expected_lo *= (FF(1) - u_1); - FF expected_hi = polynomial[2] * (FF(1) - u_0) + polynomial[3] * u_0; - expected_hi *= u_1; - expected_values.emplace_back(expected_lo + expected_hi); - } - - for (size_t poly_idx = 0; poly_idx < NUM_POLYNOMIALS; poly_idx++) { - EXPECT_EQ(evaluations[poly_idx], expected_values[poly_idx]); - } - }; - run_test(/* is_random_input=*/false); - run_test(/* is_random_input=*/true); -} - -// TODO(#223)(Cody): write standalone test of the verifier. -// Note(luke): This test (and ProverAndVerifierLonger) are slighly misleading in that they include the grand product -// realtions but do not test their correctness due to the choice of zero polynomials for sigma, id etc. -TEST_F(SumcheckTests, ProverAndVerifier) -{ - const size_t multivariate_d(1); - const size_t multivariate_n(1 << multivariate_d); - - 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 = { 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. - - auto full_polynomials = construct_full_polynomials(w_l, - w_r, - w_o, - z_perm, - z_perm_shift, - q_m, - q_l, - q_r, - q_o, - q_c, - sigma_1, - sigma_2, - sigma_3, - id_1, - id_2, - id_3, - lagrange_first, - lagrange_last); - // Set aribitrary random relation parameters - proof_system::RelationParameters relation_parameters{ - .beta = FF::random_element(), - .gamma = FF::random_element(), - .public_input_delta = FF::one(), - }; - - auto prover_transcript = ProverTranscript::init_empty(); - - auto sumcheck_prover = SumcheckProver(multivariate_n, prover_transcript); - - auto prover_output = sumcheck_prover.prove(full_polynomials, relation_parameters); - - auto verifier_transcript = VerifierTranscript::init_empty(prover_transcript); - - auto sumcheck_verifier = SumcheckVerifier(multivariate_n); - - std::optional verifier_output = sumcheck_verifier.verify(relation_parameters, verifier_transcript); - - ASSERT_TRUE(verifier_output.has_value()); - ASSERT_EQ(prover_output, *verifier_output); -} - -// TODO(#225): make the inputs to this test more interesting, e.g. num_public_inputs > 0 and non-trivial permutations -TEST_F(SumcheckTests, ProverAndVerifierLonger) -{ - auto run_test = [](bool expect_verified) { - const size_t multivariate_d(2); - const size_t multivariate_n(1 << multivariate_d); - - // clang-format off - std::array w_l; - if (expect_verified) { w_l = { 0, 1, 2, 0 }; - } else { w_l = { 0, 0, 2, 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, 1, 0 }; - std::array q_l = { 1, 1, 0, 0 }; - std::array q_r = { 0, 1, 0, 0 }; - std::array q_o = { 0, -1, -1, 0 }; - std::array q_c = { 0, 0, 0, 0 }; - // Setting all of these to 0 ensures the GrandProductRelation is satisfied - std::array sigma_1 = { 0, 0, 0, 0 }; - std::array sigma_2 = { 0, 0, 0, 0 }; - std::array sigma_3 = { 0, 0, 0, 0 }; - 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 }; - // clang-format on - - auto full_polynomials = construct_full_polynomials(w_l, - w_r, - w_o, - z_perm, - z_perm_shift, - q_m, - q_l, - q_r, - q_o, - q_c, - sigma_1, - sigma_2, - sigma_3, - id_1, - id_2, - id_3, - lagrange_first, - lagrange_last); - - // Set aribitrary random relation parameters - proof_system::RelationParameters relation_parameters{ - .beta = FF::random_element(), - .gamma = FF::random_element(), - .public_input_delta = FF::one(), - }; - - auto prover_transcript = ProverTranscript::init_empty(); - - auto sumcheck_prover = SumcheckProver(multivariate_n, prover_transcript); - - auto prover_output = sumcheck_prover.prove(full_polynomials, relation_parameters); - - auto verifier_transcript = VerifierTranscript::init_empty(prover_transcript); - - auto sumcheck_verifier = SumcheckVerifier(multivariate_n); - - std::optional verifier_output = sumcheck_verifier.verify(relation_parameters, verifier_transcript); - - EXPECT_EQ(verifier_output.has_value(), expect_verified); - }; - - run_test(/* expect_verified=*/true); - run_test(/* expect_verified=*/false); -} - -/** - * @brief Test the Standard Sumcheck Prover and Verifier for a real circuit - * - */ -TEST_F(SumcheckTests, RealCircuitStandard) -{ - // Create a composer and a dummy circuit with a few gates - auto builder = proof_system::StandardCircuitBuilder(); - FF a = FF::one(); - // Using the public variable to check that public_input_delta is computed and added to the relation correctly - uint32_t a_idx = builder.add_public_variable(a); - FF b = FF::one(); - FF c = a + b; - FF d = a + c; - uint32_t b_idx = builder.add_variable(b); - uint32_t c_idx = builder.add_variable(c); - uint32_t d_idx = builder.add_variable(d); - for (size_t i = 0; i < 16; i++) { - builder.create_add_gate({ a_idx, b_idx, c_idx, FF::one(), FF::one(), FF::neg_one(), FF::zero() }); - builder.create_add_gate({ d_idx, c_idx, a_idx, FF::one(), FF::neg_one(), FF::neg_one(), FF::zero() }); - } - // Create a prover (it will compute proving key and witness) - auto composer = StandardComposer(); - auto instance = composer.create_instance(builder); - - // Generate beta and gamma - FF beta = FF::random_element(); - FF gamma = FF::random_element(); - - instance->initialise_prover_polynomials(); - instance->compute_grand_product_polynomials(beta, gamma); - - auto prover_transcript = ProverTranscript::init_empty(); - auto circuit_size = instance->proving_key->circuit_size; - - auto sumcheck_prover = SumcheckProver(circuit_size, prover_transcript); - - auto prover_output = sumcheck_prover.prove(instance->prover_polynomials, instance->relation_parameters); - - auto verifier_transcript = VerifierTranscript::init_empty(prover_transcript); - - auto sumcheck_verifier = SumcheckVerifier(circuit_size); - - std::optional verifier_output = sumcheck_verifier.verify(instance->relation_parameters, verifier_transcript); - - ASSERT_TRUE(verifier_output.has_value()); -} - -/** - * @brief Test the Ultra Sumcheck Prover and Verifier for a real circuit - * - */ -TEST_F(SumcheckTests, RealCircuitUltra) -{ - using Flavor = flavor::Ultra; - using FF = typename Flavor::FF; - - // Create a composer and a dummy circuit with a few gates - auto builder = proof_system::UltraCircuitBuilder(); - FF a = FF::one(); - - // Add some basic add gates, with a public input for good measure - uint32_t a_idx = builder.add_public_variable(a); - FF b = FF::one(); - FF c = a + b; - FF d = a + c; - uint32_t b_idx = builder.add_variable(b); - uint32_t c_idx = builder.add_variable(c); - uint32_t d_idx = builder.add_variable(d); - for (size_t i = 0; i < 16; i++) { - builder.create_add_gate({ a_idx, b_idx, c_idx, 1, 1, -1, 0 }); - builder.create_add_gate({ d_idx, c_idx, a_idx, 1, -1, -1, 0 }); - } - - // Add a big add gate with use of next row to test q_arith = 2 - FF e = a + b + c + d; - uint32_t e_idx = builder.add_variable(e); - - uint32_t zero_idx = builder.zero_idx; - builder.create_big_add_gate({ a_idx, b_idx, c_idx, d_idx, -1, -1, -1, -1, 0 }, true); // use next row - builder.create_big_add_gate({ zero_idx, zero_idx, zero_idx, e_idx, 0, 0, 0, 0, 0 }, false); - - // Add some lookup gates (related to pedersen hashing) - auto pedersen_input_value = FF::random_element(); - const FF input_hi = uint256_t(pedersen_input_value).slice(126, 256); - const FF input_lo = uint256_t(pedersen_input_value).slice(0, 126); - const auto input_hi_index = builder.add_variable(input_hi); - const auto input_lo_index = builder.add_variable(input_lo); - - const auto sequence_data_hi = plookup::get_lookup_accumulators(plookup::MultiTableId::PEDERSEN_LEFT_HI, input_hi); - const auto sequence_data_lo = plookup::get_lookup_accumulators(plookup::MultiTableId::PEDERSEN_LEFT_LO, input_lo); - - builder.create_gates_from_plookup_accumulators( - plookup::MultiTableId::PEDERSEN_LEFT_HI, sequence_data_hi, input_hi_index); - builder.create_gates_from_plookup_accumulators( - plookup::MultiTableId::PEDERSEN_LEFT_LO, sequence_data_lo, input_lo_index); - - // Add a sort gate (simply checks that consecutive inputs have a difference of < 4) - a_idx = builder.add_variable(FF(0)); - b_idx = builder.add_variable(FF(1)); - c_idx = builder.add_variable(FF(2)); - d_idx = builder.add_variable(FF(3)); - builder.create_sort_constraint({ a_idx, b_idx, c_idx, d_idx }); - - // Add an elliptic curve addition gate - grumpkin::g1::affine_element p1 = crypto::generators::get_generator_data({ 0, 0 }).generator; - grumpkin::g1::affine_element p2 = crypto::generators::get_generator_data({ 0, 1 }).generator; - - grumpkin::fq beta_scalar = grumpkin::fq::cube_root_of_unity(); - grumpkin::g1::affine_element p2_endo = p2; - p2_endo.x *= beta_scalar; - - grumpkin::g1::affine_element p3(grumpkin::g1::element(p1) - grumpkin::g1::element(p2_endo)); - - uint32_t x1 = builder.add_variable(p1.x); - uint32_t y1 = builder.add_variable(p1.y); - uint32_t x2 = builder.add_variable(p2.x); - uint32_t y2 = builder.add_variable(p2.y); - uint32_t x3 = builder.add_variable(p3.x); - uint32_t y3 = builder.add_variable(p3.y); - - builder.create_ecc_add_gate({ x1, y1, x2, y2, x3, y3, beta_scalar, -1 }); - - // Add some RAM gates - uint32_t ram_values[8]{ - builder.add_variable(FF::random_element()), builder.add_variable(FF::random_element()), - builder.add_variable(FF::random_element()), builder.add_variable(FF::random_element()), - builder.add_variable(FF::random_element()), builder.add_variable(FF::random_element()), - builder.add_variable(FF::random_element()), builder.add_variable(FF::random_element()), - }; - - size_t ram_id = builder.create_RAM_array(8); - - for (size_t i = 0; i < 8; ++i) { - builder.init_RAM_element(ram_id, i, ram_values[i]); - } - - a_idx = builder.read_RAM_array(ram_id, builder.add_variable(5)); - EXPECT_EQ(a_idx != ram_values[5], true); - - b_idx = builder.read_RAM_array(ram_id, builder.add_variable(4)); - c_idx = builder.read_RAM_array(ram_id, builder.add_variable(1)); - - builder.write_RAM_array(ram_id, builder.add_variable(4), builder.add_variable(500)); - d_idx = builder.read_RAM_array(ram_id, builder.add_variable(4)); - - EXPECT_EQ(builder.get_variable(d_idx), 500); - - // ensure these vars get used in another arithmetic gate - const auto e_value = builder.get_variable(a_idx) + builder.get_variable(b_idx) + builder.get_variable(c_idx) + - builder.get_variable(d_idx); - e_idx = builder.add_variable(e_value); - - builder.create_big_add_gate({ a_idx, b_idx, c_idx, d_idx, -1, -1, -1, -1, 0 }, true); - builder.create_big_add_gate( - { - builder.zero_idx, - builder.zero_idx, - builder.zero_idx, - e_idx, - 0, - 0, - 0, - 0, - 0, - }, - false); - - // Create a prover (it will compute proving key and witness) - auto composer = UltraComposer(); - auto instance = composer.create_instance(builder); +// #include "sumcheck.hpp" +// #include "barretenberg/ecc/curves/bn254/fr.hpp" +// #include "barretenberg/honk/composer/standard_composer.hpp" +// #include "barretenberg/honk/composer/ultra_composer.hpp" +// #include "barretenberg/honk/proof_system/grand_product_library.hpp" +// #include "barretenberg/honk/transcript/transcript.hpp" +// #include "barretenberg/proof_system/relations/auxiliary_relation.hpp" +// #include "barretenberg/proof_system/relations/elliptic_relation.hpp" +// #include "barretenberg/proof_system/relations/gen_perm_sort_relation.hpp" +// #include "barretenberg/proof_system/relations/lookup_relation.hpp" +// #include "barretenberg/proof_system/relations/permutation_relation.hpp" +// #include "barretenberg/proof_system/relations/ultra_arithmetic_relation.hpp" +// #include + +// using namespace proof_system::honk; +// using namespace proof_system::honk::sumcheck; +// using Flavor = proof_system::honk::flavor::Standard; // TODO(Cody): Generalize this test. +// using FF = typename Flavor::FF; +// using ProverPolynomials = typename Flavor::ProverPolynomials; +// const size_t NUM_POLYNOMIALS = Flavor::NUM_ALL_ENTITIES; + +// namespace test_sumcheck_round { + +// template +// ProverPolynomials construct_full_polynomials(std::array& w_l, +// std::array& w_r, +// std::array& w_o, +// std::array& z_perm, +// std::array& z_perm_shift, +// std::array& q_m, +// std::array& q_l, +// std::array& q_r, +// std::array& q_o, +// std::array& q_c, +// std::array& sigma_1, +// std::array& sigma_2, +// std::array& sigma_3, +// std::array& id_1, +// std::array& id_2, +// std::array& id_3, +// std::array& lagrange_first, +// std::array& lagrange_last) +// { +// ProverPolynomials full_polynomials; +// full_polynomials.w_l = w_l; +// full_polynomials.w_r = w_r; +// full_polynomials.w_o = w_o; +// full_polynomials.z_perm = z_perm; +// full_polynomials.z_perm_shift = z_perm_shift; +// full_polynomials.q_m = q_m; +// full_polynomials.q_l = q_l; +// full_polynomials.q_r = q_r; +// full_polynomials.q_o = q_o; +// full_polynomials.q_c = q_c; +// full_polynomials.sigma_1 = sigma_1; +// full_polynomials.sigma_2 = sigma_2; +// full_polynomials.sigma_3 = sigma_3; +// full_polynomials.id_1 = id_1; +// full_polynomials.id_2 = id_2; +// full_polynomials.id_3 = id_3; +// full_polynomials.lagrange_first = lagrange_first; +// full_polynomials.lagrange_last = lagrange_last; + +// return full_polynomials; +// } + +// class SumcheckTests : public ::testing::Test { +// protected: +// static void SetUpTestSuite() { barretenberg::srs::init_crs_factory("../srs_db/ignition"); } +// }; + +// TEST_F(SumcheckTests, PolynomialNormalization) +// { +// // TODO(#225)(Cody): We should not use real constants like this in the tests, at least not in so many of them. +// const size_t multivariate_d(3); +// const size_t multivariate_n(1 << multivariate_d); + +// std::array w_l; +// std::array w_r; +// std::array w_o; +// std::array z_perm; +// std::array z_perm_shift; +// std::array q_m; +// std::array q_l; +// std::array q_r; +// std::array q_o; +// std::array q_c; +// std::array sigma_1; +// std::array sigma_2; +// std::array sigma_3; +// std::array id_1; +// std::array id_2; +// std::array id_3; +// std::array lagrange_first; +// std::array lagrange_last; +// for (size_t i = 0; i < multivariate_n; i++) { +// w_l[i] = FF::random_element(); +// w_r[i] = FF::random_element(); +// w_o[i] = FF::random_element(); +// z_perm[i] = FF::random_element(); +// z_perm_shift[i] = FF::random_element(); +// q_m[i] = FF::random_element(); +// q_l[i] = FF::random_element(); +// q_r[i] = FF::random_element(); +// q_o[i] = FF::random_element(); +// q_c[i] = FF::random_element(); +// sigma_1[i] = FF::random_element(); +// sigma_2[i] = FF::random_element(); +// sigma_3[i] = FF::random_element(); +// id_1[i] = FF::random_element(); +// id_2[i] = FF::random_element(); +// id_3[i] = FF::random_element(); +// lagrange_first[i] = FF::random_element(); +// lagrange_last[i] = FF::random_element(); +// } + +// auto full_polynomials = construct_full_polynomials(w_l, +// w_r, +// w_o, +// z_perm, +// z_perm_shift, +// q_m, +// q_l, +// q_r, +// q_o, +// q_c, +// sigma_1, +// sigma_2, +// sigma_3, +// id_1, +// id_2, +// id_3, +// lagrange_first, +// lagrange_last); + +// auto transcript = ProverTranscript::init_empty(); + +// auto sumcheck = SumcheckProver(multivariate_n, transcript); + +// auto [multivariate_challenge, evaluations] = sumcheck.prove(full_polynomials, {}); + +// FF u_0 = multivariate_challenge[0]; +// FF u_1 = multivariate_challenge[1]; +// FF u_2 = multivariate_challenge[2]; + +// /* sumcheck.prove() terminates with sumcheck.multivariates.folded_polynoimals as an array such that +// * sumcheck.multivariates.folded_polynoimals[i][0] is the evaluatioin of the i'th multivariate at the vector of +// challenges u_i. What does this mean? + +// Here we show that if the multivariate is F(X0, X1, X2) defined as above, then what we get is F(u0, u1, u2) and +// not, say F(u2, u1, u0). This is in accordance with Adrian's thesis (cf page 9). +// */ + +// // Get the values of the Lagrange basis polys L_i defined +// // by: L_i(v) = 1 if i = v, 0 otherwise, for v from 0 to 7. +// FF one{ 1 }; +// // clang-format off +// FF l_0 = (one - u_0) * (one - u_1) * (one - u_2); +// FF l_1 = ( u_0) * (one - u_1) * (one - u_2); +// FF l_2 = (one - u_0) * ( u_1) * (one - u_2); +// FF l_3 = ( u_0) * ( u_1) * (one - u_2); +// FF l_4 = (one - u_0) * (one - u_1) * ( u_2); +// FF l_5 = ( u_0) * (one - u_1) * ( u_2); +// FF l_6 = (one - u_0) * ( u_1) * ( u_2); +// FF l_7 = ( u_0) * ( u_1) * ( u_2); +// // clang-format on +// FF hand_computed_value; +// for (size_t i = 0; i < NUM_POLYNOMIALS; i++) { +// // full_polynomials[0][0] = w_l[0], full_polynomials[1][1] = w_r[1], and so on. +// hand_computed_value = l_0 * full_polynomials[i][0] + l_1 * full_polynomials[i][1] + +// l_2 * full_polynomials[i][2] + l_3 * full_polynomials[i][3] + +// l_4 * full_polynomials[i][4] + l_5 * full_polynomials[i][5] + +// l_6 * full_polynomials[i][6] + l_7 * full_polynomials[i][7]; +// EXPECT_EQ(hand_computed_value, sumcheck.partially_evaluated_polynomials[i][0]); +// } +// } + +// TEST_F(SumcheckTests, Prover) +// { +// auto run_test = [](bool is_random_input) { +// const size_t multivariate_d(2); +// const size_t multivariate_n(1 << multivariate_d); +// std::array, NUM_POLYNOMIALS> input_polynomials; +// if (is_random_input) { +// for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { +// input_polynomials[i] = { +// FF::random_element(), FF::random_element(), FF::random_element(), FF::random_element() +// }; +// } +// } else { +// for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { +// input_polynomials[i] = { 1, 2, 0, 0 }; +// } +// }; +// std::array w_l = input_polynomials[0]; +// std::array w_r = input_polynomials[1]; +// std::array w_o = input_polynomials[2]; +// std::array z_perm = input_polynomials[3]; +// std::array z_perm_shift = input_polynomials[4]; +// std::array q_m = input_polynomials[5]; +// std::array q_l = input_polynomials[6]; +// std::array q_r = input_polynomials[7]; +// std::array q_o = input_polynomials[8]; +// std::array q_c = input_polynomials[9]; +// std::array sigma_1 = input_polynomials[10]; +// std::array sigma_2 = input_polynomials[11]; +// std::array sigma_3 = input_polynomials[12]; +// std::array id_1 = input_polynomials[13]; +// std::array id_2 = input_polynomials[14]; +// std::array id_3 = input_polynomials[15]; +// std::array lagrange_first = input_polynomials[16]; +// std::array lagrange_last = input_polynomials[17]; +// auto full_polynomials = construct_full_polynomials(w_l, +// w_r, +// w_o, +// z_perm, +// z_perm_shift, +// q_m, +// q_l, +// q_r, +// q_o, +// q_c, +// sigma_1, +// sigma_2, +// sigma_3, +// id_1, +// id_2, +// id_3, +// lagrange_first, +// lagrange_last); + +// auto transcript = ProverTranscript::init_empty(); + +// auto sumcheck = SumcheckProver(multivariate_n, transcript); + +// auto [multivariate_challenge, evaluations] = sumcheck.prove(full_polynomials, {}); +// FF u_0 = multivariate_challenge[0]; +// FF u_1 = multivariate_challenge[1]; +// std::vector expected_values; +// for (auto& polynomial : full_polynomials) { +// // using knowledge of inputs here to derive the evaluation +// FF expected_lo = polynomial[0] * (FF(1) - u_0) + polynomial[1] * u_0; +// expected_lo *= (FF(1) - u_1); +// FF expected_hi = polynomial[2] * (FF(1) - u_0) + polynomial[3] * u_0; +// expected_hi *= u_1; +// expected_values.emplace_back(expected_lo + expected_hi); +// } + +// for (size_t poly_idx = 0; poly_idx < NUM_POLYNOMIALS; poly_idx++) { +// EXPECT_EQ(evaluations[poly_idx], expected_values[poly_idx]); +// } +// }; +// run_test(/* is_random_input=*/false); +// run_test(/* is_random_input=*/true); +// } + +// // TODO(#223)(Cody): write standalone test of the verifier. +// // Note(luke): This test (and ProverAndVerifierLonger) are slighly misleading in that they include the grand product +// // realtions but do not test their correctness due to the choice of zero polynomials for sigma, id etc. +// TEST_F(SumcheckTests, ProverAndVerifier) +// { +// const size_t multivariate_d(1); +// const size_t multivariate_n(1 << multivariate_d); + +// 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 = { 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. + +// auto full_polynomials = construct_full_polynomials(w_l, +// w_r, +// w_o, +// z_perm, +// z_perm_shift, +// q_m, +// q_l, +// q_r, +// q_o, +// q_c, +// sigma_1, +// sigma_2, +// sigma_3, +// id_1, +// id_2, +// id_3, +// lagrange_first, +// lagrange_last); +// // Set aribitrary random relation parameters +// proof_system::RelationParameters relation_parameters{ +// .beta = FF::random_element(), +// .gamma = FF::random_element(), +// .public_input_delta = FF::one(), +// }; + +// auto prover_transcript = ProverTranscript::init_empty(); + +// auto sumcheck_prover = SumcheckProver(multivariate_n, prover_transcript); + +// auto prover_output = sumcheck_prover.prove(full_polynomials, relation_parameters); + +// auto verifier_transcript = VerifierTranscript::init_empty(prover_transcript); + +// auto sumcheck_verifier = SumcheckVerifier(multivariate_n); + +// std::optional verifier_output = sumcheck_verifier.verify(relation_parameters, verifier_transcript); + +// ASSERT_TRUE(verifier_output.has_value()); +// ASSERT_EQ(prover_output, *verifier_output); +// } + +// // TODO(#225): make the inputs to this test more interesting, e.g. num_public_inputs > 0 and non-trivial permutations +// TEST_F(SumcheckTests, ProverAndVerifierLonger) +// { +// auto run_test = [](bool expect_verified) { +// const size_t multivariate_d(2); +// const size_t multivariate_n(1 << multivariate_d); + +// // clang-format off +// std::array w_l; +// if (expect_verified) { w_l = { 0, 1, 2, 0 }; +// } else { w_l = { 0, 0, 2, 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, 1, 0 }; +// std::array q_l = { 1, 1, 0, 0 }; +// std::array q_r = { 0, 1, 0, 0 }; +// std::array q_o = { 0, -1, -1, 0 }; +// std::array q_c = { 0, 0, 0, 0 }; +// // Setting all of these to 0 ensures the GrandProductRelation is satisfied +// std::array sigma_1 = { 0, 0, 0, 0 }; +// std::array sigma_2 = { 0, 0, 0, 0 }; +// std::array sigma_3 = { 0, 0, 0, 0 }; +// 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 }; +// // clang-format on + +// auto full_polynomials = construct_full_polynomials(w_l, +// w_r, +// w_o, +// z_perm, +// z_perm_shift, +// q_m, +// q_l, +// q_r, +// q_o, +// q_c, +// sigma_1, +// sigma_2, +// sigma_3, +// id_1, +// id_2, +// id_3, +// lagrange_first, +// lagrange_last); + +// // Set aribitrary random relation parameters +// proof_system::RelationParameters relation_parameters{ +// .beta = FF::random_element(), +// .gamma = FF::random_element(), +// .public_input_delta = FF::one(), +// }; + +// auto prover_transcript = ProverTranscript::init_empty(); + +// auto sumcheck_prover = SumcheckProver(multivariate_n, prover_transcript); + +// auto prover_output = sumcheck_prover.prove(full_polynomials, relation_parameters); + +// auto verifier_transcript = VerifierTranscript::init_empty(prover_transcript); + +// auto sumcheck_verifier = SumcheckVerifier(multivariate_n); + +// std::optional verifier_output = sumcheck_verifier.verify(relation_parameters, verifier_transcript); + +// EXPECT_EQ(verifier_output.has_value(), expect_verified); +// }; + +// run_test(/* expect_verified=*/true); +// run_test(/* expect_verified=*/false); +// } + +// /** +// * @brief Test the Ultra Sumcheck Prover and Verifier for a real circuit +// * +// */ +// TEST_F(SumcheckTests, RealCircuitUltra) +// { +// using Flavor = flavor::Ultra; +// using FF = typename Flavor::FF; + +// // Create a composer and a dummy circuit with a few gates +// auto builder = proof_system::UltraCircuitBuilder(); +// FF a = FF::one(); + +// // Add some basic add gates, with a public input for good measure +// uint32_t a_idx = builder.add_public_variable(a); +// FF b = FF::one(); +// FF c = a + b; +// FF d = a + c; +// uint32_t b_idx = builder.add_variable(b); +// uint32_t c_idx = builder.add_variable(c); +// uint32_t d_idx = builder.add_variable(d); +// for (size_t i = 0; i < 16; i++) { +// builder.create_add_gate({ a_idx, b_idx, c_idx, 1, 1, -1, 0 }); +// builder.create_add_gate({ d_idx, c_idx, a_idx, 1, -1, -1, 0 }); +// } + +// // Add a big add gate with use of next row to test q_arith = 2 +// FF e = a + b + c + d; +// uint32_t e_idx = builder.add_variable(e); + +// uint32_t zero_idx = builder.zero_idx; +// builder.create_big_add_gate({ a_idx, b_idx, c_idx, d_idx, -1, -1, -1, -1, 0 }, true); // use next row +// builder.create_big_add_gate({ zero_idx, zero_idx, zero_idx, e_idx, 0, 0, 0, 0, 0 }, false); + +// // Add some lookup gates (related to pedersen hashing) +// auto pedersen_input_value = FF::random_element(); +// const FF input_hi = uint256_t(pedersen_input_value).slice(126, 256); +// const FF input_lo = uint256_t(pedersen_input_value).slice(0, 126); +// const auto input_hi_index = builder.add_variable(input_hi); +// const auto input_lo_index = builder.add_variable(input_lo); + +// const auto sequence_data_hi = plookup::get_lookup_accumulators(plookup::MultiTableId::PEDERSEN_LEFT_HI, +// input_hi); const auto sequence_data_lo = +// plookup::get_lookup_accumulators(plookup::MultiTableId::PEDERSEN_LEFT_LO, input_lo); + +// builder.create_gates_from_plookup_accumulators( +// plookup::MultiTableId::PEDERSEN_LEFT_HI, sequence_data_hi, input_hi_index); +// builder.create_gates_from_plookup_accumulators( +// plookup::MultiTableId::PEDERSEN_LEFT_LO, sequence_data_lo, input_lo_index); + +// // Add a sort gate (simply checks that consecutive inputs have a difference of < 4) +// a_idx = builder.add_variable(FF(0)); +// b_idx = builder.add_variable(FF(1)); +// c_idx = builder.add_variable(FF(2)); +// d_idx = builder.add_variable(FF(3)); +// builder.create_sort_constraint({ a_idx, b_idx, c_idx, d_idx }); + +// // Add an elliptic curve addition gate +// grumpkin::g1::affine_element p1 = crypto::generators::get_generator_data({ 0, 0 }).generator; +// grumpkin::g1::affine_element p2 = crypto::generators::get_generator_data({ 0, 1 }).generator; + +// grumpkin::fq beta_scalar = grumpkin::fq::cube_root_of_unity(); +// grumpkin::g1::affine_element p2_endo = p2; +// p2_endo.x *= beta_scalar; + +// grumpkin::g1::affine_element p3(grumpkin::g1::element(p1) - grumpkin::g1::element(p2_endo)); + +// uint32_t x1 = builder.add_variable(p1.x); +// uint32_t y1 = builder.add_variable(p1.y); +// uint32_t x2 = builder.add_variable(p2.x); +// uint32_t y2 = builder.add_variable(p2.y); +// uint32_t x3 = builder.add_variable(p3.x); +// uint32_t y3 = builder.add_variable(p3.y); + +// builder.create_ecc_add_gate({ x1, y1, x2, y2, x3, y3, beta_scalar, -1 }); + +// // Add some RAM gates +// uint32_t ram_values[8]{ +// builder.add_variable(FF::random_element()), builder.add_variable(FF::random_element()), +// builder.add_variable(FF::random_element()), builder.add_variable(FF::random_element()), +// builder.add_variable(FF::random_element()), builder.add_variable(FF::random_element()), +// builder.add_variable(FF::random_element()), builder.add_variable(FF::random_element()), +// }; + +// size_t ram_id = builder.create_RAM_array(8); + +// for (size_t i = 0; i < 8; ++i) { +// builder.init_RAM_element(ram_id, i, ram_values[i]); +// } + +// a_idx = builder.read_RAM_array(ram_id, builder.add_variable(5)); +// EXPECT_EQ(a_idx != ram_values[5], true); + +// b_idx = builder.read_RAM_array(ram_id, builder.add_variable(4)); +// c_idx = builder.read_RAM_array(ram_id, builder.add_variable(1)); + +// builder.write_RAM_array(ram_id, builder.add_variable(4), builder.add_variable(500)); +// d_idx = builder.read_RAM_array(ram_id, builder.add_variable(4)); + +// EXPECT_EQ(builder.get_variable(d_idx), 500); + +// // ensure these vars get used in another arithmetic gate +// const auto e_value = builder.get_variable(a_idx) + builder.get_variable(b_idx) + builder.get_variable(c_idx) + +// builder.get_variable(d_idx); +// e_idx = builder.add_variable(e_value); + +// builder.create_big_add_gate({ a_idx, b_idx, c_idx, d_idx, -1, -1, -1, -1, 0 }, true); +// builder.create_big_add_gate( +// { +// builder.zero_idx, +// builder.zero_idx, +// builder.zero_idx, +// e_idx, +// 0, +// 0, +// 0, +// 0, +// 0, +// }, +// false); + +// // Create a prover (it will compute proving key and witness) +// auto composer = UltraComposer(); +// auto instance = composer.create_instance(builder); - // Generate eta, beta and gamma - FF eta = FF::random_element(); - FF beta = FF::random_element(); - FF gamma = FF::random_element(); +// // Generate eta, beta and gamma +// FF eta = FF::random_element(); +// FF beta = FF::random_element(); +// FF gamma = FF::random_element(); - instance->initialise_prover_polynomials(); - instance->compute_sorted_accumulator_polynomials(eta); - instance->compute_grand_product_polynomials(beta, gamma); +// instance->initialise_prover_polynomials(); +// instance->compute_sorted_accumulator_polynomials(eta); +// instance->compute_grand_product_polynomials(beta, gamma); - auto prover_transcript = ProverTranscript::init_empty(); - auto circuit_size = instance->proving_key->circuit_size; +// auto prover_transcript = ProverTranscript::init_empty(); +// auto circuit_size = instance->proving_key->circuit_size; - auto sumcheck_prover = SumcheckProver(circuit_size, prover_transcript); +// auto sumcheck_prover = SumcheckProver(circuit_size, prover_transcript); - auto prover_output = sumcheck_prover.prove(instance->prover_polynomials, instance->relation_parameters); +// auto prover_output = sumcheck_prover.prove(instance->prover_polynomials, instance->relation_parameters); - auto verifier_transcript = VerifierTranscript::init_empty(prover_transcript); +// auto verifier_transcript = VerifierTranscript::init_empty(prover_transcript); - auto sumcheck_verifier = SumcheckVerifier(circuit_size); +// auto sumcheck_verifier = SumcheckVerifier(circuit_size); - std::optional verifier_output = sumcheck_verifier.verify(instance->relation_parameters, verifier_transcript); +// std::optional verifier_output = sumcheck_verifier.verify(instance->relation_parameters, verifier_transcript); - ASSERT_TRUE(verifier_output.has_value()); -} +// ASSERT_TRUE(verifier_output.has_value()); +// } -} // namespace test_sumcheck_round +// } // namespace test_sumcheck_round 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 68690080f7a..98aea3ebe0c 100644 --- a/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck_round.test.cpp @@ -1,405 +1,410 @@ -#include "sumcheck_round.hpp" -#include "barretenberg/ecc/curves/bn254/fr.hpp" -#include "barretenberg/honk/flavor/standard.hpp" -#include "barretenberg/numeric/random/engine.hpp" -#include "barretenberg/polynomials/univariate.hpp" - -#include - -#include "barretenberg/common/mem.hpp" -#include -/** - * We want to test if the univariate (S_l in the thesis) computed by the prover in a particular round is correct. We - * also want to verify given the purported evaluations of all the relevant polynomials, the verifer can correctly verify - * the purported evaluation of S_l. For the prover, we use a couple of methods to compute the univariate by the sumcheck - * method `compute_univariate` and by step by step manual computation respectively. For the verifier, we follow a - * similar approach. - */ - -using namespace proof_system::honk; -using namespace proof_system::honk::sumcheck; -using namespace proof_system; - -using barretenberg::BarycentricData; -using barretenberg::PowUnivariate; -using barretenberg::Univariate; - -using Flavor = flavor::Standard; -using FF = typename Flavor::FF; -using ProverPolynomials = typename Flavor::ProverPolynomials; -using ClaimedEvaluations = typename Flavor::ClaimedEvaluations; - -const size_t NUM_POLYNOMIALS = Flavor::NUM_ALL_ENTITIES; -const size_t max_relation_length = Flavor::MAX_RANDOM_RELATION_LENGTH; -const size_t input_polynomial_length = 2; - -namespace test_sumcheck_round { - -// The below two methods are used in the test ComputeUnivariateProver -static Univariate compute_round_univariate( - std::array, NUM_POLYNOMIALS>& input_polynomials, - const RelationParameters& relation_parameters, - const FF alpha) -{ - size_t round_size = 2; - // Improvement(Cody): This is ugly? Maye supply some/all of this data through "flavor" class? - auto round = SumcheckProverRound(round_size); - - ProverPolynomials full_polynomials; - full_polynomials.w_l = input_polynomials[0]; - full_polynomials.w_r = input_polynomials[1]; - full_polynomials.w_o = input_polynomials[2]; - full_polynomials.z_perm = input_polynomials[3]; - full_polynomials.z_perm_shift = input_polynomials[4]; - full_polynomials.q_m = input_polynomials[5]; - full_polynomials.q_l = input_polynomials[6]; - full_polynomials.q_r = input_polynomials[7]; - full_polynomials.q_o = input_polynomials[8]; - full_polynomials.q_c = input_polynomials[9]; - full_polynomials.sigma_1 = input_polynomials[10]; - full_polynomials.sigma_2 = input_polynomials[11]; - full_polynomials.sigma_3 = input_polynomials[12]; - full_polynomials.id_1 = input_polynomials[13]; - full_polynomials.id_2 = input_polynomials[14]; - full_polynomials.id_3 = input_polynomials[15]; - full_polynomials.lagrange_first = input_polynomials[16]; - full_polynomials.lagrange_last = input_polynomials[17]; - - PowUnivariate pow_zeta(1); - Univariate round_univariate = - round.compute_univariate(full_polynomials, relation_parameters, pow_zeta, alpha); - return round_univariate; -} - -static Univariate compute_expected_round_univariate( - std::array, NUM_POLYNOMIALS>& input_univariates, - const RelationParameters& relation_parameters, - const FF alpha) -{ - BarycentricData barycentric_2_to_max = - BarycentricData(); - std::array, NUM_POLYNOMIALS> extended_univariates; - for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { - extended_univariates[i] = barycentric_2_to_max.extend(input_univariates[i]); - } - auto w_l_univariate = Univariate(extended_univariates[0]); - auto w_r_univariate = Univariate(extended_univariates[1]); - auto w_o_univariate = Univariate(extended_univariates[2]); - auto z_perm_univariate = Univariate(extended_univariates[3]); - auto z_perm_shift_univariate = - Univariate(extended_univariates[4]); // this is not real shifted data - auto q_m_univariate = Univariate(extended_univariates[5]); - auto q_l_univariate = Univariate(extended_univariates[6]); - auto q_r_univariate = Univariate(extended_univariates[7]); - auto q_o_univariate = Univariate(extended_univariates[8]); - auto q_c_univariate = Univariate(extended_univariates[9]); - auto sigma_1_univariate = Univariate(extended_univariates[10]); - auto sigma_2_univariate = Univariate(extended_univariates[11]); - auto sigma_3_univariate = Univariate(extended_univariates[12]); - auto id_1_univariate = Univariate(extended_univariates[13]); - auto id_2_univariate = Univariate(extended_univariates[14]); - auto id_3_univariate = Univariate(extended_univariates[15]); - auto lagrange_first_univariate = Univariate(extended_univariates[16]); - auto lagrange_last_univariate = Univariate(extended_univariates[17]); - - auto expected_arithmetic_relation = - ((q_m_univariate * w_r_univariate * w_l_univariate) + (q_r_univariate * w_r_univariate) + - (q_l_univariate * w_l_univariate) + (q_o_univariate * w_o_univariate) + (q_c_univariate)); - auto expected_grand_product_computation_relation = - ((z_perm_univariate + lagrange_first_univariate) * - (w_l_univariate + id_1_univariate * relation_parameters.beta + relation_parameters.gamma) * - (w_r_univariate + id_2_univariate * relation_parameters.beta + relation_parameters.gamma) * - (w_o_univariate + id_3_univariate * relation_parameters.beta + relation_parameters.gamma)); - expected_grand_product_computation_relation -= - ((z_perm_shift_univariate + lagrange_last_univariate * relation_parameters.public_input_delta) * - (w_l_univariate + sigma_1_univariate * relation_parameters.beta + relation_parameters.gamma) * - (w_r_univariate + sigma_2_univariate * relation_parameters.beta + relation_parameters.gamma) * - (w_o_univariate + sigma_3_univariate * relation_parameters.beta + relation_parameters.gamma)); - auto expected_grand_product_initialization_relation = (z_perm_shift_univariate * lagrange_last_univariate); - Univariate expected_round_univariate = - expected_arithmetic_relation + expected_grand_product_computation_relation * alpha + - expected_grand_product_initialization_relation * alpha.sqr(); - return expected_round_univariate; -} - -// The below two methods are used in the test ComputeUnivariateVerifier -static FF compute_full_purported_value(std::array& input_values, - const RelationParameters& relation_parameters, - const FF alpha) -{ - ClaimedEvaluations purported_evaluations; - purported_evaluations.w_l = input_values[0]; - purported_evaluations.w_r = input_values[1]; - purported_evaluations.w_o = input_values[2]; - purported_evaluations.z_perm = input_values[3]; - purported_evaluations.z_perm_shift = input_values[4]; - purported_evaluations.q_m = input_values[5]; - purported_evaluations.q_l = input_values[6]; - purported_evaluations.q_r = input_values[7]; - purported_evaluations.q_o = input_values[8]; - purported_evaluations.q_c = input_values[9]; - purported_evaluations.sigma_1 = input_values[10]; - purported_evaluations.sigma_2 = input_values[11]; - purported_evaluations.sigma_3 = input_values[12]; - purported_evaluations.id_1 = input_values[13]; - purported_evaluations.id_2 = input_values[14]; - purported_evaluations.id_3 = input_values[15]; - purported_evaluations.lagrange_first = input_values[16]; - purported_evaluations.lagrange_last = input_values[17]; - - auto round = SumcheckVerifierRound(); - PowUnivariate pow_univariate(1); - FF full_purported_value = round.compute_full_honk_relation_purported_value( - purported_evaluations, relation_parameters, pow_univariate, alpha); - return full_purported_value; -} - -static FF compute_full_purported_value_expected(std::array& input_values, - const RelationParameters& relation_parameters, - const FF alpha) -{ - FF w_l = input_values[0]; - FF w_r = input_values[1]; - FF w_o = input_values[2]; - FF z_perm = input_values[3]; - FF z_perm_shift = input_values[4]; - FF q_m = input_values[5]; - FF q_l = input_values[6]; - FF q_r = input_values[7]; - FF q_o = input_values[8]; - FF q_c = input_values[9]; - FF sigma_1 = input_values[10]; - FF sigma_2 = input_values[11]; - FF sigma_3 = input_values[12]; - FF id_1 = input_values[13]; - FF id_2 = input_values[14]; - FF id_3 = input_values[15]; - FF lagrange_first = input_values[16]; - FF lagrange_last = input_values[17]; - auto expected_arithmetic_relation = (q_m * w_r * w_l) + (q_r * w_r) + (q_l * w_l) + (q_o * w_o) + q_c; - auto expected_grand_product_computation_relation = - (z_perm + lagrange_first) * (w_l + id_1 * relation_parameters.beta + relation_parameters.gamma) * - (w_r + id_2 * relation_parameters.beta + relation_parameters.gamma) * - (w_o + id_3 * relation_parameters.beta + relation_parameters.gamma); - expected_grand_product_computation_relation -= - (z_perm_shift + lagrange_last * relation_parameters.public_input_delta) * - (w_l + sigma_1 * relation_parameters.beta + relation_parameters.gamma) * - (w_r + sigma_2 * relation_parameters.beta + relation_parameters.gamma) * - (w_o + sigma_3 * relation_parameters.beta + relation_parameters.gamma); - auto expected_grand_product_initialization_relation = z_perm_shift * lagrange_last; - auto expected_full_purported_value = expected_arithmetic_relation + - expected_grand_product_computation_relation * alpha + - expected_grand_product_initialization_relation * alpha.sqr(); - return expected_full_purported_value; -} - -TEST(SumcheckRound, ComputeUnivariateProver) -{ - auto run_test = [](bool is_random_input) { - if (is_random_input) { - std::array, NUM_POLYNOMIALS> input_polynomials; - for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { - input_polynomials[i] = { FF::random_element(), FF::random_element() }; - } - - const FF alpha = FF::random_element(); - const RelationParameters relation_parameters = RelationParameters{ - .beta = FF::random_element(), .gamma = FF::random_element(), .public_input_delta = FF::random_element() - }; - - auto round_univariate = compute_round_univariate(input_polynomials, relation_parameters, alpha); - - // Compute round_univariate manually - std::array, NUM_POLYNOMIALS> input_univariates; - for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { - input_univariates[i] = Univariate(input_polynomials[i]); - } - auto expected_round_univariate = - compute_expected_round_univariate(input_univariates, relation_parameters, alpha); - EXPECT_EQ(round_univariate, expected_round_univariate); - } else { - std::array, NUM_POLYNOMIALS> input_polynomials; - for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { - input_polynomials[i] = { 1, 2 }; - } - const FF alpha = 1; - const RelationParameters relation_parameters = - RelationParameters{ .beta = 1, .gamma = 1, .public_input_delta = 1 }; - auto round_univariate = compute_round_univariate(input_polynomials, relation_parameters, alpha); - // Compute round_univariate manually - std::array, NUM_POLYNOMIALS> input_univariates; - for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { - input_univariates[i] = Univariate(input_polynomials[i]); - } - // expected_round_univariate = { 6, 26, 66, 132, 230, 366 } - auto expected_round_univariate = - compute_expected_round_univariate(input_univariates, relation_parameters, alpha); - EXPECT_EQ(round_univariate, expected_round_univariate); - }; - }; - run_test(/* is_random_input=*/false); - run_test(/* is_random_input=*/true); -} - -TEST(SumcheckRound, ComputeUnivariateVerifier) -{ - auto run_test = [](bool is_random_input) { - if (is_random_input) { - std::array input_values; - for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { - input_values[i] = FF::random_element(); - } - const FF alpha = FF::random_element(); - const RelationParameters relation_parameters = RelationParameters{ - .beta = FF::random_element(), .gamma = FF::random_element(), .public_input_delta = FF::random_element() - }; - auto full_purported_value = compute_full_purported_value(input_values, relation_parameters, alpha); - // Compute round_univariate manually - auto expected_full_purported_value = - compute_full_purported_value_expected(input_values, relation_parameters, alpha); - EXPECT_EQ(full_purported_value, expected_full_purported_value); - } else { - std::array input_values; - for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { - input_values[i] = FF(2); - } - const FF alpha = 1; - const RelationParameters relation_parameters = - RelationParameters{ .beta = 1, .gamma = 1, .public_input_delta = 1 }; - auto full_purported_value = compute_full_purported_value(input_values, relation_parameters, alpha); - // Compute round_univariate manually - auto expected_full_purported_value = - compute_full_purported_value_expected(input_values, relation_parameters, alpha); - EXPECT_EQ(full_purported_value, expected_full_purported_value); - }; - }; - run_test(/* is_random_input=*/false); - run_test(/* is_random_input=*/true); -} - -/** - * @brief Test utility functions for applying operations to tuple of tuple of Univariates - * - */ -TEST(SumcheckRound, TupleOfTuplesOfUnivariates) -{ - using Flavor = proof_system::honk::flavor::Standard; - using FF = typename Flavor::FF; - - // Define three linear univariates of different sizes - Univariate univariate_1({ 1, 2, 3 }); - Univariate univariate_2({ 2, 4 }); - Univariate univariate_3({ 3, 4, 5, 6, 7 }); - const size_t MAX_LENGTH = 5; - - // Instantiate some barycentric extension utility classes - auto barycentric_util_1 = BarycentricData(); - auto barycentric_util_2 = BarycentricData(); - auto barycentric_util_3 = BarycentricData(); - - // Construct a tuple of tuples of the form { {univariate_1}, {univariate_2, univariate_3} } - auto tuple_of_tuples = std::make_tuple(std::make_tuple(univariate_1), std::make_tuple(univariate_2, univariate_3)); - - // Use scale_univariate_accumulators to scale by challenge powers - FF challenge = 5; - FF running_challenge = 1; - SumcheckProverRound::scale_univariates(tuple_of_tuples, challenge, running_challenge); - - // Use extend_and_batch_univariates to extend to MAX_LENGTH then accumulate - PowUnivariate pow_univariate(1); - auto result = Univariate(); - SumcheckProverRound::extend_and_batch_univariates(tuple_of_tuples, pow_univariate, result); - - // Repeat the batching process manually - auto result_expected = barycentric_util_1.extend(univariate_1) * 1 + - barycentric_util_2.extend(univariate_2) * challenge + - barycentric_util_3.extend(univariate_3) * challenge * challenge; - - // Compare final batched univarites - EXPECT_EQ(result, result_expected); - - // Reinitialize univariate accumulators to zero - SumcheckProverRound::zero_univariates(tuple_of_tuples); - - // Check that reinitialization was successful - Univariate expected_1({ 0, 0, 0 }); - Univariate expected_2({ 0, 0 }); - Univariate expected_3({ 0, 0, 0, 0, 0 }); - EXPECT_EQ(std::get<0>(std::get<0>(tuple_of_tuples)), expected_1); - EXPECT_EQ(std::get<0>(std::get<1>(tuple_of_tuples)), expected_2); - EXPECT_EQ(std::get<1>(std::get<1>(tuple_of_tuples)), expected_3); -} - -/** - * @brief Test utility functions for applying operations to tuple of std::arrays of field elements - * - */ -TEST(SumcheckRound, TuplesOfEvaluationArrays) -{ - using Flavor = proof_system::honk::flavor::Standard; - using FF = typename Flavor::FF; - - // Define two arrays of arbitrary elements - std::array evaluations_1 = { 4 }; - std::array evaluations_2 = { 6, 2 }; - - // Construct a tuple - auto tuple_of_arrays = std::make_tuple(evaluations_1, evaluations_2); - - // Use scale_and_batch_elements to scale by challenge powers - FF challenge = 5; - FF running_challenge = 1; - FF result = 0; - SumcheckVerifierRound::scale_and_batch_elements(tuple_of_arrays, challenge, running_challenge, result); - - // Repeat the batching process manually - auto result_expected = - evaluations_1[0] * 1 + evaluations_2[0] * challenge + evaluations_2[1] * challenge * challenge; - - // Compare batched result - EXPECT_EQ(result, result_expected); - - // Reinitialize univariate accumulators to zero - SumcheckVerifierRound::zero_elements(tuple_of_arrays); - - EXPECT_EQ(std::get<0>(tuple_of_arrays)[0], 0); - EXPECT_EQ(std::get<1>(tuple_of_arrays)[0], 0); - EXPECT_EQ(std::get<1>(tuple_of_arrays)[1], 0); -} - -/** - * @brief Test utility functions for adding two tuples of tuples of Univariates - * - */ -TEST(SumcheckRound, AddTuplesOfTuplesOfUnivariates) -{ - using Flavor = proof_system::honk::flavor::Standard; - using FF = typename Flavor::FF; - - // Define some arbitrary univariates - Univariate univariate_1({ 1, 2 }); - Univariate univariate_2({ 2, 4 }); - Univariate univariate_3({ 3, 4, 5 }); - - Univariate univariate_4({ 3, 6 }); - Univariate univariate_5({ 8, 1 }); - Univariate univariate_6({ 3, 7, 1 }); - - Univariate expected_sum_1 = univariate_1 + univariate_4; - Univariate expected_sum_2 = univariate_2 + univariate_5; - Univariate expected_sum_3 = univariate_3 + univariate_6; - - // Construct two tuples of tuples - auto tuple_of_tuples_1 = - std::make_tuple(std::make_tuple(univariate_1), std::make_tuple(univariate_2, univariate_3)); - auto tuple_of_tuples_2 = - std::make_tuple(std::make_tuple(univariate_4), std::make_tuple(univariate_5, univariate_6)); - - SumcheckProverRound::add_nested_tuples(tuple_of_tuples_1, tuple_of_tuples_2); - - EXPECT_EQ(std::get<0>(std::get<0>(tuple_of_tuples_1)), expected_sum_1); - EXPECT_EQ(std::get<0>(std::get<1>(tuple_of_tuples_1)), expected_sum_2); - EXPECT_EQ(std::get<1>(std::get<1>(tuple_of_tuples_1)), expected_sum_3); -} - -} // namespace test_sumcheck_round +// #include "sumcheck_round.hpp" +// #include "barretenberg/ecc/curves/bn254/fr.hpp" +// #include "barretenberg/honk/flavor/standard.hpp" +// #include "barretenberg/numeric/random/engine.hpp" +// #include "barretenberg/polynomials/univariate.hpp" + +// #include + +// #include "barretenberg/common/mem.hpp" +// #include +// /** +// * We want to test if the univariate (S_l in the thesis) computed by the prover in a particular round is correct. We +// * also want to verify given the purported evaluations of all the relevant polynomials, the verifer can correctly +// verify +// * the purported evaluation of S_l. For the prover, we use a couple of methods to compute the univariate by the +// sumcheck +// * method `compute_univariate` and by step by step manual computation respectively. For the verifier, we follow a +// * similar approach. +// */ + +// using namespace proof_system::honk; +// using namespace proof_system::honk::sumcheck; +// using namespace proof_system; + +// using barretenberg::BarycentricData; +// using barretenberg::PowUnivariate; +// using barretenberg::Univariate; + +// using Flavor = flavor::Standard; +// using FF = typename Flavor::FF; +// using ProverPolynomials = typename Flavor::ProverPolynomials; +// using ClaimedEvaluations = typename Flavor::ClaimedEvaluations; + +// const size_t NUM_POLYNOMIALS = Flavor::NUM_ALL_ENTITIES; +// const size_t max_relation_length = Flavor::MAX_RANDOM_RELATION_LENGTH; +// const size_t input_polynomial_length = 2; + +// namespace test_sumcheck_round { + +// // The below two methods are used in the test ComputeUnivariateProver +// static Univariate compute_round_univariate( +// std::array, NUM_POLYNOMIALS>& input_polynomials, +// const RelationParameters& relation_parameters, +// const FF alpha) +// { +// size_t round_size = 2; +// // Improvement(Cody): This is ugly? Maye supply some/all of this data through "flavor" class? +// auto round = SumcheckProverRound(round_size); + +// ProverPolynomials full_polynomials; +// full_polynomials.w_l = input_polynomials[0]; +// full_polynomials.w_r = input_polynomials[1]; +// full_polynomials.w_o = input_polynomials[2]; +// full_polynomials.z_perm = input_polynomials[3]; +// full_polynomials.z_perm_shift = input_polynomials[4]; +// full_polynomials.q_m = input_polynomials[5]; +// full_polynomials.q_l = input_polynomials[6]; +// full_polynomials.q_r = input_polynomials[7]; +// full_polynomials.q_o = input_polynomials[8]; +// full_polynomials.q_c = input_polynomials[9]; +// full_polynomials.sigma_1 = input_polynomials[10]; +// full_polynomials.sigma_2 = input_polynomials[11]; +// full_polynomials.sigma_3 = input_polynomials[12]; +// full_polynomials.id_1 = input_polynomials[13]; +// full_polynomials.id_2 = input_polynomials[14]; +// full_polynomials.id_3 = input_polynomials[15]; +// full_polynomials.lagrange_first = input_polynomials[16]; +// full_polynomials.lagrange_last = input_polynomials[17]; + +// PowUnivariate pow_zeta(1); +// Univariate round_univariate = +// round.compute_univariate(full_polynomials, relation_parameters, pow_zeta, alpha); +// return round_univariate; +// } + +// static Univariate compute_expected_round_univariate( +// std::array, NUM_POLYNOMIALS>& input_univariates, +// const RelationParameters& relation_parameters, +// const FF alpha) +// { +// BarycentricData barycentric_2_to_max = +// BarycentricData(); +// std::array, NUM_POLYNOMIALS> extended_univariates; +// for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { +// extended_univariates[i] = barycentric_2_to_max.extend(input_univariates[i]); +// } +// auto w_l_univariate = Univariate(extended_univariates[0]); +// auto w_r_univariate = Univariate(extended_univariates[1]); +// auto w_o_univariate = Univariate(extended_univariates[2]); +// auto z_perm_univariate = Univariate(extended_univariates[3]); +// auto z_perm_shift_univariate = +// Univariate(extended_univariates[4]); // this is not real shifted data +// auto q_m_univariate = Univariate(extended_univariates[5]); +// auto q_l_univariate = Univariate(extended_univariates[6]); +// auto q_r_univariate = Univariate(extended_univariates[7]); +// auto q_o_univariate = Univariate(extended_univariates[8]); +// auto q_c_univariate = Univariate(extended_univariates[9]); +// auto sigma_1_univariate = Univariate(extended_univariates[10]); +// auto sigma_2_univariate = Univariate(extended_univariates[11]); +// auto sigma_3_univariate = Univariate(extended_univariates[12]); +// auto id_1_univariate = Univariate(extended_univariates[13]); +// auto id_2_univariate = Univariate(extended_univariates[14]); +// auto id_3_univariate = Univariate(extended_univariates[15]); +// auto lagrange_first_univariate = Univariate(extended_univariates[16]); +// auto lagrange_last_univariate = Univariate(extended_univariates[17]); + +// auto expected_arithmetic_relation = +// ((q_m_univariate * w_r_univariate * w_l_univariate) + (q_r_univariate * w_r_univariate) + +// (q_l_univariate * w_l_univariate) + (q_o_univariate * w_o_univariate) + (q_c_univariate)); +// auto expected_grand_product_computation_relation = +// ((z_perm_univariate + lagrange_first_univariate) * +// (w_l_univariate + id_1_univariate * relation_parameters.beta + relation_parameters.gamma) * +// (w_r_univariate + id_2_univariate * relation_parameters.beta + relation_parameters.gamma) * +// (w_o_univariate + id_3_univariate * relation_parameters.beta + relation_parameters.gamma)); +// expected_grand_product_computation_relation -= +// ((z_perm_shift_univariate + lagrange_last_univariate * relation_parameters.public_input_delta) * +// (w_l_univariate + sigma_1_univariate * relation_parameters.beta + relation_parameters.gamma) * +// (w_r_univariate + sigma_2_univariate * relation_parameters.beta + relation_parameters.gamma) * +// (w_o_univariate + sigma_3_univariate * relation_parameters.beta + relation_parameters.gamma)); +// auto expected_grand_product_initialization_relation = (z_perm_shift_univariate * lagrange_last_univariate); +// Univariate expected_round_univariate = +// expected_arithmetic_relation + expected_grand_product_computation_relation * alpha + +// expected_grand_product_initialization_relation * alpha.sqr(); +// return expected_round_univariate; +// } + +// // The below two methods are used in the test ComputeUnivariateVerifier +// static FF compute_full_purported_value(std::array& input_values, +// const RelationParameters& relation_parameters, +// const FF alpha) +// { +// ClaimedEvaluations purported_evaluations; +// purported_evaluations.w_l = input_values[0]; +// purported_evaluations.w_r = input_values[1]; +// purported_evaluations.w_o = input_values[2]; +// purported_evaluations.z_perm = input_values[3]; +// purported_evaluations.z_perm_shift = input_values[4]; +// purported_evaluations.q_m = input_values[5]; +// purported_evaluations.q_l = input_values[6]; +// purported_evaluations.q_r = input_values[7]; +// purported_evaluations.q_o = input_values[8]; +// purported_evaluations.q_c = input_values[9]; +// purported_evaluations.sigma_1 = input_values[10]; +// purported_evaluations.sigma_2 = input_values[11]; +// purported_evaluations.sigma_3 = input_values[12]; +// purported_evaluations.id_1 = input_values[13]; +// purported_evaluations.id_2 = input_values[14]; +// purported_evaluations.id_3 = input_values[15]; +// purported_evaluations.lagrange_first = input_values[16]; +// purported_evaluations.lagrange_last = input_values[17]; + +// auto round = SumcheckVerifierRound(); +// PowUnivariate pow_univariate(1); +// FF full_purported_value = round.compute_full_honk_relation_purported_value( +// purported_evaluations, relation_parameters, pow_univariate, alpha); +// return full_purported_value; +// } + +// static FF compute_full_purported_value_expected(std::array& input_values, +// const RelationParameters& relation_parameters, +// const FF alpha) +// { +// FF w_l = input_values[0]; +// FF w_r = input_values[1]; +// FF w_o = input_values[2]; +// FF z_perm = input_values[3]; +// FF z_perm_shift = input_values[4]; +// FF q_m = input_values[5]; +// FF q_l = input_values[6]; +// FF q_r = input_values[7]; +// FF q_o = input_values[8]; +// FF q_c = input_values[9]; +// FF sigma_1 = input_values[10]; +// FF sigma_2 = input_values[11]; +// FF sigma_3 = input_values[12]; +// FF id_1 = input_values[13]; +// FF id_2 = input_values[14]; +// FF id_3 = input_values[15]; +// FF lagrange_first = input_values[16]; +// FF lagrange_last = input_values[17]; +// auto expected_arithmetic_relation = (q_m * w_r * w_l) + (q_r * w_r) + (q_l * w_l) + (q_o * w_o) + q_c; +// auto expected_grand_product_computation_relation = +// (z_perm + lagrange_first) * (w_l + id_1 * relation_parameters.beta + relation_parameters.gamma) * +// (w_r + id_2 * relation_parameters.beta + relation_parameters.gamma) * +// (w_o + id_3 * relation_parameters.beta + relation_parameters.gamma); +// expected_grand_product_computation_relation -= +// (z_perm_shift + lagrange_last * relation_parameters.public_input_delta) * +// (w_l + sigma_1 * relation_parameters.beta + relation_parameters.gamma) * +// (w_r + sigma_2 * relation_parameters.beta + relation_parameters.gamma) * +// (w_o + sigma_3 * relation_parameters.beta + relation_parameters.gamma); +// auto expected_grand_product_initialization_relation = z_perm_shift * lagrange_last; +// auto expected_full_purported_value = expected_arithmetic_relation + +// expected_grand_product_computation_relation * alpha + +// expected_grand_product_initialization_relation * alpha.sqr(); +// return expected_full_purported_value; +// } + +// TEST(SumcheckRound, ComputeUnivariateProver) +// { +// auto run_test = [](bool is_random_input) { +// if (is_random_input) { +// std::array, NUM_POLYNOMIALS> input_polynomials; +// for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { +// input_polynomials[i] = { FF::random_element(), FF::random_element() }; +// } + +// const FF alpha = FF::random_element(); +// const RelationParameters relation_parameters = RelationParameters{ +// .beta = FF::random_element(), .gamma = FF::random_element(), .public_input_delta = +// FF::random_element() +// }; + +// auto round_univariate = compute_round_univariate(input_polynomials, relation_parameters, alpha); + +// // Compute round_univariate manually +// std::array, NUM_POLYNOMIALS> input_univariates; +// for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { +// input_univariates[i] = Univariate(input_polynomials[i]); +// } +// auto expected_round_univariate = +// compute_expected_round_univariate(input_univariates, relation_parameters, alpha); +// EXPECT_EQ(round_univariate, expected_round_univariate); +// } else { +// std::array, NUM_POLYNOMIALS> input_polynomials; +// for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { +// input_polynomials[i] = { 1, 2 }; +// } +// const FF alpha = 1; +// const RelationParameters relation_parameters = +// RelationParameters{ .beta = 1, .gamma = 1, .public_input_delta = 1 }; +// auto round_univariate = compute_round_univariate(input_polynomials, relation_parameters, alpha); +// // Compute round_univariate manually +// std::array, NUM_POLYNOMIALS> input_univariates; +// for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { +// input_univariates[i] = Univariate(input_polynomials[i]); +// } +// // expected_round_univariate = { 6, 26, 66, 132, 230, 366 } +// auto expected_round_univariate = +// compute_expected_round_univariate(input_univariates, relation_parameters, alpha); +// EXPECT_EQ(round_univariate, expected_round_univariate); +// }; +// }; +// run_test(/* is_random_input=*/false); +// run_test(/* is_random_input=*/true); +// } + +// TEST(SumcheckRound, ComputeUnivariateVerifier) +// { +// auto run_test = [](bool is_random_input) { +// if (is_random_input) { +// std::array input_values; +// for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { +// input_values[i] = FF::random_element(); +// } +// const FF alpha = FF::random_element(); +// const RelationParameters relation_parameters = RelationParameters{ +// .beta = FF::random_element(), .gamma = FF::random_element(), .public_input_delta = +// FF::random_element() +// }; +// auto full_purported_value = compute_full_purported_value(input_values, relation_parameters, alpha); +// // Compute round_univariate manually +// auto expected_full_purported_value = +// compute_full_purported_value_expected(input_values, relation_parameters, alpha); +// EXPECT_EQ(full_purported_value, expected_full_purported_value); +// } else { +// std::array input_values; +// for (size_t i = 0; i < NUM_POLYNOMIALS; ++i) { +// input_values[i] = FF(2); +// } +// const FF alpha = 1; +// const RelationParameters relation_parameters = +// RelationParameters{ .beta = 1, .gamma = 1, .public_input_delta = 1 }; +// auto full_purported_value = compute_full_purported_value(input_values, relation_parameters, alpha); +// // Compute round_univariate manually +// auto expected_full_purported_value = +// compute_full_purported_value_expected(input_values, relation_parameters, alpha); +// EXPECT_EQ(full_purported_value, expected_full_purported_value); +// }; +// }; +// run_test(/* is_random_input=*/false); +// run_test(/* is_random_input=*/true); +// } + +// /** +// * @brief Test utility functions for applying operations to tuple of tuple of Univariates +// * +// */ +// TEST(SumcheckRound, TupleOfTuplesOfUnivariates) +// { +// using Flavor = proof_system::honk::flavor::Standard; +// using FF = typename Flavor::FF; + +// // Define three linear univariates of different sizes +// Univariate univariate_1({ 1, 2, 3 }); +// Univariate univariate_2({ 2, 4 }); +// Univariate univariate_3({ 3, 4, 5, 6, 7 }); +// const size_t MAX_LENGTH = 5; + +// // Instantiate some barycentric extension utility classes +// auto barycentric_util_1 = BarycentricData(); +// auto barycentric_util_2 = BarycentricData(); +// auto barycentric_util_3 = BarycentricData(); + +// // Construct a tuple of tuples of the form { {univariate_1}, {univariate_2, univariate_3} } +// auto tuple_of_tuples = std::make_tuple(std::make_tuple(univariate_1), std::make_tuple(univariate_2, +// univariate_3)); + +// // Use scale_univariate_accumulators to scale by challenge powers +// FF challenge = 5; +// FF running_challenge = 1; +// SumcheckProverRound::scale_univariates(tuple_of_tuples, challenge, running_challenge); + +// // Use extend_and_batch_univariates to extend to MAX_LENGTH then accumulate +// PowUnivariate pow_univariate(1); +// auto result = Univariate(); +// SumcheckProverRound::extend_and_batch_univariates(tuple_of_tuples, pow_univariate, result); + +// // Repeat the batching process manually +// auto result_expected = barycentric_util_1.extend(univariate_1) * 1 + +// barycentric_util_2.extend(univariate_2) * challenge + +// barycentric_util_3.extend(univariate_3) * challenge * challenge; + +// // Compare final batched univarites +// EXPECT_EQ(result, result_expected); + +// // Reinitialize univariate accumulators to zero +// SumcheckProverRound::zero_univariates(tuple_of_tuples); + +// // Check that reinitialization was successful +// Univariate expected_1({ 0, 0, 0 }); +// Univariate expected_2({ 0, 0 }); +// Univariate expected_3({ 0, 0, 0, 0, 0 }); +// EXPECT_EQ(std::get<0>(std::get<0>(tuple_of_tuples)), expected_1); +// EXPECT_EQ(std::get<0>(std::get<1>(tuple_of_tuples)), expected_2); +// EXPECT_EQ(std::get<1>(std::get<1>(tuple_of_tuples)), expected_3); +// } + +// /** +// * @brief Test utility functions for applying operations to tuple of std::arrays of field elements +// * +// */ +// TEST(SumcheckRound, TuplesOfEvaluationArrays) +// { +// using Flavor = proof_system::honk::flavor::Standard; +// using FF = typename Flavor::FF; + +// // Define two arrays of arbitrary elements +// std::array evaluations_1 = { 4 }; +// std::array evaluations_2 = { 6, 2 }; + +// // Construct a tuple +// auto tuple_of_arrays = std::make_tuple(evaluations_1, evaluations_2); + +// // Use scale_and_batch_elements to scale by challenge powers +// FF challenge = 5; +// FF running_challenge = 1; +// FF result = 0; +// SumcheckVerifierRound::scale_and_batch_elements(tuple_of_arrays, challenge, running_challenge, result); + +// // Repeat the batching process manually +// auto result_expected = +// evaluations_1[0] * 1 + evaluations_2[0] * challenge + evaluations_2[1] * challenge * challenge; + +// // Compare batched result +// EXPECT_EQ(result, result_expected); + +// // Reinitialize univariate accumulators to zero +// SumcheckVerifierRound::zero_elements(tuple_of_arrays); + +// EXPECT_EQ(std::get<0>(tuple_of_arrays)[0], 0); +// EXPECT_EQ(std::get<1>(tuple_of_arrays)[0], 0); +// EXPECT_EQ(std::get<1>(tuple_of_arrays)[1], 0); +// } + +// /** +// * @brief Test utility functions for adding two tuples of tuples of Univariates +// * +// */ +// TEST(SumcheckRound, AddTuplesOfTuplesOfUnivariates) +// { +// using Flavor = proof_system::honk::flavor::Standard; +// using FF = typename Flavor::FF; + +// // Define some arbitrary univariates +// Univariate univariate_1({ 1, 2 }); +// Univariate univariate_2({ 2, 4 }); +// Univariate univariate_3({ 3, 4, 5 }); + +// Univariate univariate_4({ 3, 6 }); +// Univariate univariate_5({ 8, 1 }); +// Univariate univariate_6({ 3, 7, 1 }); + +// Univariate expected_sum_1 = univariate_1 + univariate_4; +// Univariate expected_sum_2 = univariate_2 + univariate_5; +// Univariate expected_sum_3 = univariate_3 + univariate_6; + +// // Construct two tuples of tuples +// auto tuple_of_tuples_1 = +// std::make_tuple(std::make_tuple(univariate_1), std::make_tuple(univariate_2, univariate_3)); +// auto tuple_of_tuples_2 = +// std::make_tuple(std::make_tuple(univariate_4), std::make_tuple(univariate_5, univariate_6)); + +// SumcheckProverRound::add_nested_tuples(tuple_of_tuples_1, tuple_of_tuples_2); + +// EXPECT_EQ(std::get<0>(std::get<0>(tuple_of_tuples_1)), expected_sum_1); +// EXPECT_EQ(std::get<0>(std::get<1>(tuple_of_tuples_1)), expected_sum_2); +// EXPECT_EQ(std::get<1>(std::get<1>(tuple_of_tuples_1)), expected_sum_3); +// } + +// } // namespace test_sumcheck_round diff --git a/barretenberg/cpp/src/barretenberg/honk/transcript/transcript.test.cpp b/barretenberg/cpp/src/barretenberg/honk/transcript/transcript.test.cpp index 7981a048503..f46bbef1f19 100644 --- a/barretenberg/cpp/src/barretenberg/honk/transcript/transcript.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/transcript/transcript.test.cpp @@ -1,8 +1,6 @@ #include "transcript.hpp" #include "barretenberg/ecc/curves/bn254/g1.hpp" -#include "barretenberg/honk/composer/standard_composer.hpp" #include "barretenberg/honk/composer/ultra_composer.hpp" -#include "barretenberg/honk/flavor/standard.hpp" #include "barretenberg/numeric/bitop/get_msb.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/proof_system/flavor/flavor.hpp" @@ -10,285 +8,6 @@ using namespace proof_system::honk; -template class TranscriptTests : public testing::Test { - protected: - // TODO(https://github.com/AztecProtocol/barretenberg/issues/640): The Standard Honk on Grumpkin test suite fails - // unless the SRS is initialised for every test. - virtual void SetUp() - { - if constexpr (proof_system::IsGrumpkinFlavor) { - barretenberg::srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); - } else { - barretenberg::srs::init_crs_factory("../srs_db/ignition"); - } - }; - - using FF = typename Flavor::FF; - - /** - * @brief Construct a manifest for a standard Honk proof - * - * @details This is where we define the "Manifest" for a Standard Honk proof. The tests in this suite are - * intented to warn the developer if the Prover/Verifier has deviated from this manifest, however, the - * Transcript class is not otherwise contrained to follow the manifest. - * - * @note Entries in the manifest consist of a name string and a size (bytes), NOT actual data. - * - * @return TranscriptManifest - */ - TranscriptManifest construct_standard_honk_manifest(size_t circuit_size) - { - TranscriptManifest manifest_expected; - - auto log_n = numeric::get_msb(circuit_size); - - size_t max_relation_length = Flavor::MAX_RANDOM_RELATION_LENGTH; - size_t size_FF = sizeof(FF); - size_t size_G = 2 * size_FF; - size_t size_uni = max_relation_length * size_FF; - size_t size_evals = (Flavor::NUM_ALL_ENTITIES)*size_FF; - size_t size_uint32 = 4; - size_t size_uint64 = 8; - - size_t round = 0; - manifest_expected.add_entry(round, "circuit_size", size_uint32); - manifest_expected.add_entry(round, "public_input_size", size_uint32); - manifest_expected.add_entry(round, "public_input_0", size_FF); - manifest_expected.add_entry(round, "W_1", size_G); - manifest_expected.add_entry(round, "W_2", size_G); - manifest_expected.add_entry(round, "W_3", size_G); - manifest_expected.add_challenge(round, "beta", "gamma"); - - round++; - manifest_expected.add_entry(round, "Z_PERM", size_G); - manifest_expected.add_challenge(round, "Sumcheck:alpha", "Sumcheck:zeta"); - - for (size_t i = 0; i < log_n; ++i) { - round++; - std::string idx = std::to_string(i); - manifest_expected.add_entry(round, "Sumcheck:univariate_" + idx, size_uni); - std::string label = "Sumcheck:u_" + idx; - manifest_expected.add_challenge(round, label); - } - - round++; - manifest_expected.add_entry(round, "Sumcheck:evaluations", size_evals); - manifest_expected.add_challenge(round, "rho"); - - round++; - for (size_t i = 1; i < log_n; ++i) { - std::string idx = std::to_string(i); - manifest_expected.add_entry(round, "Gemini:FOLD_" + idx, size_G); - } - manifest_expected.add_challenge(round, "Gemini:r"); - - round++; - for (size_t i = 0; i < log_n; ++i) { - std::string idx = std::to_string(i); - manifest_expected.add_entry(round, "Gemini:a_" + idx, size_FF); - } - manifest_expected.add_challenge(round, "Shplonk:nu"); - - round++; - manifest_expected.add_entry(round, "Shplonk:Q", size_G); - manifest_expected.add_challenge(round, "Shplonk:z"); - - round++; - // TODO(Mara): Make testing more flavor agnostic so we can test this with all flavors - if constexpr (proof_system::IsGrumpkinFlavor) { - manifest_expected.add_entry(round, "IPA:poly_degree", size_uint64); - manifest_expected.add_challenge(round, "IPA:generator_challenge"); - - for (size_t i = 0; i < log_n; i++) { - round++; - std::string idx = std::to_string(i); - manifest_expected.add_entry(round, "IPA:L_" + idx, size_G); - manifest_expected.add_entry(round, "IPA:R_" + idx, size_G); - std::string label = "IPA:round_challenge_" + idx; - manifest_expected.add_challenge(round, label); - } - - round++; - manifest_expected.add_entry(round, "IPA:a_0", size_FF); - } else { - manifest_expected.add_entry(round, "KZG:W", size_G); - } - - manifest_expected.add_challenge(round); // no challenge - - return manifest_expected; - } -}; - -using StandardFlavorTypes = testing::Types; -TYPED_TEST_SUITE(TranscriptTests, StandardFlavorTypes); - -/** - * @brief Ensure consistency between the manifest hard coded in this testing suite and the one generated by the - * standard honk prover over the course of proof construction. - */ -TYPED_TEST(TranscriptTests, ProverManifestConsistency) -{ - using Flavor = TypeParam; - // Construct a simple circuit of size n = 8 (i.e. the minimum circuit size) - typename Flavor::FF a = 1; - auto builder = typename Flavor::CircuitBuilder(); - builder.add_variable(a); - builder.add_public_variable(a); - - // Automatically generate a transcript manifest by constructing a proof - auto composer = StandardComposer_(); - auto instance = composer.create_instance(builder); - auto prover = composer.create_prover(instance); - auto proof = prover.construct_proof(); - - // Check that the prover generated manifest agrees with the manifest hard coded in this suite - auto manifest_expected = TestFixture::construct_standard_honk_manifest(instance->proving_key->circuit_size); - auto prover_manifest = prover.transcript.get_manifest(); - // Note: a manifest can be printed using manifest.print() - for (size_t round = 0; round < manifest_expected.size(); ++round) { - ASSERT_EQ(prover_manifest[round], manifest_expected[round]) << "Prover manifest discrepency in round " << round; - } -} - -/** - * @brief Ensure consistency between the manifest generated by the standard honk prover over the course of proof - * construction and the one generated by the verifier over the course of proof verification. - * - */ -TYPED_TEST(TranscriptTests, VerifierManifestConsistency) -{ - using Flavor = TypeParam; - // Construct a simple circuit of size n = 8 (i.e. the minimum circuit size) - typename Flavor::FF a = 1; - auto builder = typename Flavor::CircuitBuilder(); - builder.add_variable(a); - builder.add_public_variable(a); - - // Automatically generate a transcript manifest in the prover by constructing a proof - auto composer = StandardComposer_(); - auto instance = composer.create_instance(builder); - auto prover = composer.create_prover(instance); - auto proof = prover.construct_proof(); - - // Automatically generate a transcript manifest in the verifier by verifying a proof - auto verifier = composer.create_verifier(instance); - verifier.verify_proof(proof); - prover.transcript.print(); - verifier.transcript.print(); - - // 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(); - - // Note: a manifest can be printed using manifest.print() - 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; - } -} - -/** - * @brief Test and demonstrate the basic functionality of the prover and verifier transcript - * - */ -TYPED_TEST(TranscriptTests, ProverAndVerifierBasic) -{ - constexpr size_t LENGTH = 8; - - using Fr = barretenberg::fr; - using Univariate = barretenberg::Univariate; - using Commitment = barretenberg::g1::affine_element; - - std::array evaluations; - for (auto& eval : evaluations) { - eval = Fr::random_element(); - } - - // Add some junk to the transcript and compute challenges - uint32_t data = 25; - auto scalar = Fr::random_element(); - auto commitment = Commitment::one(); - auto univariate = Univariate(evaluations); - - // Instantiate a prover transcript and mock an example protocol - ProverTranscript prover_transcript; - - // round 0 - prover_transcript.send_to_verifier("data", data); - Fr alpha = prover_transcript.get_challenge("alpha"); - - // round 1 - prover_transcript.send_to_verifier("scalar", scalar); - prover_transcript.send_to_verifier("commitment", commitment); - Fr beta = prover_transcript.get_challenge("beta"); - - // round 2 - prover_transcript.send_to_verifier("univariate", univariate); - auto [gamma, delta] = prover_transcript.get_challenges("gamma", "delta"); - - // Instantiate a verifier transcript from the raw bytes of the prover transcript; receive data and generate - // challenges according to the example protocol - VerifierTranscript verifier_transcript(prover_transcript.proof_data); - - // round 0 - auto data_received = verifier_transcript.template receive_from_prover("data"); - Fr verifier_alpha = verifier_transcript.get_challenge("alpha"); - - // round 1 - auto scalar_received = verifier_transcript.template receive_from_prover("scalar"); - auto commitment_received = verifier_transcript.template receive_from_prover("commitment"); - Fr verifier_beta = verifier_transcript.get_challenge("beta"); - - // round 2 - auto univariate_received = verifier_transcript.template receive_from_prover("univariate"); - auto [verifier_gamma, verifier_delta] = verifier_transcript.get_challenges("gamma", "delta"); - - // Check the correctness of the elements received by the verifier - EXPECT_EQ(data_received, data); - EXPECT_EQ(scalar_received, scalar); - EXPECT_EQ(commitment_received, commitment); - EXPECT_EQ(univariate_received, univariate); - - // Check consistency of prover and verifier challenges - EXPECT_EQ(alpha, verifier_alpha); - EXPECT_EQ(beta, verifier_beta); - EXPECT_EQ(gamma, verifier_gamma); - EXPECT_EQ(delta, verifier_delta); - - // Check consistency of the generated manifests - EXPECT_EQ(prover_transcript.get_manifest(), verifier_transcript.get_manifest()); -} - -/** - * @brief Demonstrate extent to which verifier transcript is flexible / constrained - * - */ -TYPED_TEST(TranscriptTests, VerifierMistake) -{ - using Fr = barretenberg::fr; - - auto scalar_1 = Fr::random_element(); - auto scalar_2 = Fr::random_element(); - - ProverTranscript prover_transcript; - - prover_transcript.send_to_verifier("scalar1", scalar_1); - prover_transcript.send_to_verifier("scalar2", scalar_2); - auto prover_alpha = prover_transcript.get_challenge("alpha"); - - VerifierTranscript verifier_transcript(prover_transcript.proof_data); - - verifier_transcript.template receive_from_prover("scalar1"); - // accidentally skip receipt of "scalar2"... - // but then generate a challenge anyway - auto verifier_alpha = verifier_transcript.get_challenge("alpha"); - - // Challenges will not agree but neither will the manifests - EXPECT_NE(prover_alpha, verifier_alpha); - EXPECT_NE(prover_transcript.get_manifest(), verifier_transcript.get_manifest()); -} - class UltraTranscriptTests : public ::testing::Test { public: static void SetUpTestSuite() { barretenberg::srs::init_crs_factory("../srs_db/ignition"); } diff --git a/barretenberg/cpp/src/barretenberg/proof_system/composer/composer_lib.test.cpp b/barretenberg/cpp/src/barretenberg/proof_system/composer/composer_lib.test.cpp index fcec018acd3..7679cff0efa 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/composer/composer_lib.test.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/composer/composer_lib.test.cpp @@ -1,138 +1,138 @@ -#include "barretenberg/proof_system/composer/composer_lib.hpp" -#include "barretenberg/common/slab_allocator.hpp" -#include "barretenberg/honk/flavor/standard.hpp" // TODO: needed? -#include "barretenberg/proof_system/types/circuit_type.hpp" -#include "barretenberg/srs/factories/crs_factory.hpp" -#include -#include - -namespace proof_system::test_composer_lib { - -class ComposerLibTests : public ::testing::Test { - protected: - using Flavor = honk::flavor::Standard; - using FF = typename Flavor::FF; - Flavor::CircuitBuilder circuit_constructor; - Flavor::ProvingKey proving_key = []() { - auto crs_factory = barretenberg::srs::factories::CrsFactory(); - auto crs = crs_factory.get_prover_crs(4); - return Flavor::ProvingKey(/*circuit_size=*/4, /*num_public_inputs=*/0); - }(); -}; - -TEST_F(ComposerLibTests, ConstructSelectors) -{ - circuit_constructor.q_m = { 1, 2, 3, 4 }; - circuit_constructor.q_1 = { 5, 6, 7, 8 }; - circuit_constructor.q_2 = { 9, 10, 11, 12 }; - circuit_constructor.q_3 = { 13, 14, 15, 16 }; - circuit_constructor.q_c = { 17, 18, 19, 20 }; - - construct_selector_polynomials(circuit_constructor, &proving_key); - - EXPECT_EQ(proving_key.q_m[0], 1); - EXPECT_EQ(proving_key.q_m[1], 2); - EXPECT_EQ(proving_key.q_m[2], 3); - EXPECT_EQ(proving_key.q_m[3], 4); - - EXPECT_EQ(proving_key.q_l[0], 5); - EXPECT_EQ(proving_key.q_l[1], 6); - EXPECT_EQ(proving_key.q_l[2], 7); - EXPECT_EQ(proving_key.q_l[3], 8); - - EXPECT_EQ(proving_key.q_r[0], 9); - EXPECT_EQ(proving_key.q_r[1], 10); - EXPECT_EQ(proving_key.q_r[2], 11); - EXPECT_EQ(proving_key.q_r[3], 12); - - EXPECT_EQ(proving_key.q_o[0], 13); - EXPECT_EQ(proving_key.q_o[1], 14); - EXPECT_EQ(proving_key.q_o[2], 15); - EXPECT_EQ(proving_key.q_o[3], 16); - - EXPECT_EQ(proving_key.q_c[0], 17); - EXPECT_EQ(proving_key.q_c[1], 18); - EXPECT_EQ(proving_key.q_c[2], 19); - EXPECT_EQ(proving_key.q_c[3], 20); -} - -TEST_F(ComposerLibTests, ConstructWitnessPolynomialsBase) -{ - circuit_constructor.add_public_variable(1024); - circuit_constructor.add_public_variable(1025); - - uint32_t v_1 = circuit_constructor.add_variable(16 + 1); - uint32_t v_2 = circuit_constructor.add_variable(16 + 2); - uint32_t v_3 = circuit_constructor.add_variable(16 + 3); - uint32_t v_4 = circuit_constructor.add_variable(16 + 4); - uint32_t v_5 = circuit_constructor.add_variable(16 + 5); - uint32_t v_6 = circuit_constructor.add_variable(16 + 6); - uint32_t v_7 = circuit_constructor.add_variable(16 + 7); - uint32_t v_8 = circuit_constructor.add_variable(16 + 8); - uint32_t v_9 = circuit_constructor.add_variable(16 + 9); - uint32_t v_10 = circuit_constructor.add_variable(16 + 10); - uint32_t v_11 = circuit_constructor.add_variable(16 + 11); - uint32_t v_12 = circuit_constructor.add_variable(16 + 12); - - circuit_constructor.create_add_gate({ v_1, v_5, v_9, 0, 0, 0, 0 }); - circuit_constructor.create_add_gate({ v_2, v_6, v_10, 0, 0, 0, 0 }); - circuit_constructor.create_add_gate({ v_3, v_7, v_11, 0, 0, 0, 0 }); - circuit_constructor.create_add_gate({ v_4, v_8, v_12, 0, 0, 0, 0 }); - - /* Execution trace: - w_l w_r w_o - ------------------------------ - pub1_idx | pub1_idx | 0 <-- public inputs - pub2_idx | pub2_idx | 0 <-/ - zero_idx | zero_idx | zero_idx <-- fix witness for 0 - one_idx | zero_idx | zero_idx <-- fix witness for 1 - one_idx | one_idx | one_idx <-- ensure nonzero selectors... TODO(Cody): redundant now - v_1 | v_5 | v_9 - v_2 | v_6 | v_10 - v_3 | v_7 | v_11 - v_4 | v_8 | v_12 - - */ - - const size_t dyadic_circuit_size = circuit_constructor.get_circuit_subgroup_size( - circuit_constructor.num_gates + circuit_constructor.public_inputs.size()); - - auto wires = construct_wire_polynomials_base(circuit_constructor, dyadic_circuit_size); - auto& w_l = wires[0]; - auto& w_r = wires[1]; - auto& w_o = wires[2]; - auto& zero_idx = circuit_constructor.zero_idx; - auto& one_idx = circuit_constructor.one_idx; - - EXPECT_EQ(w_l[0], 1024); - EXPECT_EQ(w_l[1], 1025); - EXPECT_EQ(w_l[2], zero_idx); - EXPECT_EQ(w_l[3], one_idx); - EXPECT_EQ(w_l[4], one_idx); - EXPECT_EQ(w_l[5], 17); - EXPECT_EQ(w_l[6], 18); - EXPECT_EQ(w_l[7], 19); - EXPECT_EQ(w_l[8], 20); - - EXPECT_EQ(w_r[0], 1024); - EXPECT_EQ(w_r[1], 1025); - EXPECT_EQ(w_r[2], zero_idx); - EXPECT_EQ(w_r[3], zero_idx); - EXPECT_EQ(w_r[4], one_idx); - EXPECT_EQ(w_r[5], 21); - EXPECT_EQ(w_r[6], 22); - EXPECT_EQ(w_r[7], 23); - EXPECT_EQ(w_r[8], 24); - - EXPECT_EQ(w_o[0], 0); - EXPECT_EQ(w_o[1], 0); - EXPECT_EQ(w_o[2], zero_idx); - EXPECT_EQ(w_o[3], zero_idx); - EXPECT_EQ(w_o[4], one_idx); - EXPECT_EQ(w_o[5], 25); - EXPECT_EQ(w_o[6], 26); - EXPECT_EQ(w_o[7], 27); - EXPECT_EQ(w_o[8], 28); -} - -} // namespace proof_system::test_composer_lib +// #include "barretenberg/proof_system/composer/composer_lib.hpp" +// #include "barretenberg/common/slab_allocator.hpp" +// #include "barretenberg/honk/flavor/standard.hpp" // TODO: needed? +// #include "barretenberg/proof_system/types/circuit_type.hpp" +// #include "barretenberg/srs/factories/crs_factory.hpp" +// #include +// #include + +// namespace proof_system::test_composer_lib { + +// class ComposerLibTests : public ::testing::Test { +// protected: +// using Flavor = honk::flavor::Standard; +// using FF = typename Flavor::FF; +// Flavor::CircuitBuilder circuit_constructor; +// Flavor::ProvingKey proving_key = []() { +// auto crs_factory = barretenberg::srs::factories::CrsFactory(); +// auto crs = crs_factory.get_prover_crs(4); +// return Flavor::ProvingKey(/*circuit_size=*/4, /*num_public_inputs=*/0); +// }(); +// }; + +// TEST_F(ComposerLibTests, ConstructSelectors) +// { +// circuit_constructor.q_m = { 1, 2, 3, 4 }; +// circuit_constructor.q_1 = { 5, 6, 7, 8 }; +// circuit_constructor.q_2 = { 9, 10, 11, 12 }; +// circuit_constructor.q_3 = { 13, 14, 15, 16 }; +// circuit_constructor.q_c = { 17, 18, 19, 20 }; + +// construct_selector_polynomials(circuit_constructor, &proving_key); + +// EXPECT_EQ(proving_key.q_m[0], 1); +// EXPECT_EQ(proving_key.q_m[1], 2); +// EXPECT_EQ(proving_key.q_m[2], 3); +// EXPECT_EQ(proving_key.q_m[3], 4); + +// EXPECT_EQ(proving_key.q_l[0], 5); +// EXPECT_EQ(proving_key.q_l[1], 6); +// EXPECT_EQ(proving_key.q_l[2], 7); +// EXPECT_EQ(proving_key.q_l[3], 8); + +// EXPECT_EQ(proving_key.q_r[0], 9); +// EXPECT_EQ(proving_key.q_r[1], 10); +// EXPECT_EQ(proving_key.q_r[2], 11); +// EXPECT_EQ(proving_key.q_r[3], 12); + +// EXPECT_EQ(proving_key.q_o[0], 13); +// EXPECT_EQ(proving_key.q_o[1], 14); +// EXPECT_EQ(proving_key.q_o[2], 15); +// EXPECT_EQ(proving_key.q_o[3], 16); + +// EXPECT_EQ(proving_key.q_c[0], 17); +// EXPECT_EQ(proving_key.q_c[1], 18); +// EXPECT_EQ(proving_key.q_c[2], 19); +// EXPECT_EQ(proving_key.q_c[3], 20); +// } + +// TEST_F(ComposerLibTests, ConstructWitnessPolynomialsBase) +// { +// circuit_constructor.add_public_variable(1024); +// circuit_constructor.add_public_variable(1025); + +// uint32_t v_1 = circuit_constructor.add_variable(16 + 1); +// uint32_t v_2 = circuit_constructor.add_variable(16 + 2); +// uint32_t v_3 = circuit_constructor.add_variable(16 + 3); +// uint32_t v_4 = circuit_constructor.add_variable(16 + 4); +// uint32_t v_5 = circuit_constructor.add_variable(16 + 5); +// uint32_t v_6 = circuit_constructor.add_variable(16 + 6); +// uint32_t v_7 = circuit_constructor.add_variable(16 + 7); +// uint32_t v_8 = circuit_constructor.add_variable(16 + 8); +// uint32_t v_9 = circuit_constructor.add_variable(16 + 9); +// uint32_t v_10 = circuit_constructor.add_variable(16 + 10); +// uint32_t v_11 = circuit_constructor.add_variable(16 + 11); +// uint32_t v_12 = circuit_constructor.add_variable(16 + 12); + +// circuit_constructor.create_add_gate({ v_1, v_5, v_9, 0, 0, 0, 0 }); +// circuit_constructor.create_add_gate({ v_2, v_6, v_10, 0, 0, 0, 0 }); +// circuit_constructor.create_add_gate({ v_3, v_7, v_11, 0, 0, 0, 0 }); +// circuit_constructor.create_add_gate({ v_4, v_8, v_12, 0, 0, 0, 0 }); + +// /* Execution trace: +// w_l w_r w_o +// ------------------------------ +// pub1_idx | pub1_idx | 0 <-- public inputs +// pub2_idx | pub2_idx | 0 <-/ +// zero_idx | zero_idx | zero_idx <-- fix witness for 0 +// one_idx | zero_idx | zero_idx <-- fix witness for 1 +// one_idx | one_idx | one_idx <-- ensure nonzero selectors... TODO(Cody): redundant now +// v_1 | v_5 | v_9 +// v_2 | v_6 | v_10 +// v_3 | v_7 | v_11 +// v_4 | v_8 | v_12 + +// */ + +// const size_t dyadic_circuit_size = circuit_constructor.get_circuit_subgroup_size( +// circuit_constructor.num_gates + circuit_constructor.public_inputs.size()); + +// auto wires = construct_wire_polynomials_base(circuit_constructor, dyadic_circuit_size); +// auto& w_l = wires[0]; +// auto& w_r = wires[1]; +// auto& w_o = wires[2]; +// auto& zero_idx = circuit_constructor.zero_idx; +// auto& one_idx = circuit_constructor.one_idx; + +// EXPECT_EQ(w_l[0], 1024); +// EXPECT_EQ(w_l[1], 1025); +// EXPECT_EQ(w_l[2], zero_idx); +// EXPECT_EQ(w_l[3], one_idx); +// EXPECT_EQ(w_l[4], one_idx); +// EXPECT_EQ(w_l[5], 17); +// EXPECT_EQ(w_l[6], 18); +// EXPECT_EQ(w_l[7], 19); +// EXPECT_EQ(w_l[8], 20); + +// EXPECT_EQ(w_r[0], 1024); +// EXPECT_EQ(w_r[1], 1025); +// EXPECT_EQ(w_r[2], zero_idx); +// EXPECT_EQ(w_r[3], zero_idx); +// EXPECT_EQ(w_r[4], one_idx); +// EXPECT_EQ(w_r[5], 21); +// EXPECT_EQ(w_r[6], 22); +// EXPECT_EQ(w_r[7], 23); +// EXPECT_EQ(w_r[8], 24); + +// EXPECT_EQ(w_o[0], 0); +// EXPECT_EQ(w_o[1], 0); +// EXPECT_EQ(w_o[2], zero_idx); +// EXPECT_EQ(w_o[3], zero_idx); +// EXPECT_EQ(w_o[4], one_idx); +// EXPECT_EQ(w_o[5], 25); +// EXPECT_EQ(w_o[6], 26); +// EXPECT_EQ(w_o[7], 27); +// EXPECT_EQ(w_o[8], 28); +// } + +// } // namespace proof_system::test_composer_lib diff --git a/barretenberg/cpp/src/barretenberg/proof_system/composer/permutation_lib.test.cpp b/barretenberg/cpp/src/barretenberg/proof_system/composer/permutation_lib.test.cpp index e45c630d066..4da2c3b5bb1 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/composer/permutation_lib.test.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/composer/permutation_lib.test.cpp @@ -1,96 +1,96 @@ -#include "barretenberg/proof_system/composer/permutation_lib.hpp" -#include "barretenberg/honk/flavor/standard.hpp" // TODO: needed? -#include "barretenberg/proof_system/composer/composer_lib.hpp" -#include "barretenberg/proof_system/types/circuit_type.hpp" -#include "barretenberg/srs/factories/crs_factory.hpp" -#include -#include +// #include "barretenberg/proof_system/composer/permutation_lib.hpp" +// #include "barretenberg/honk/flavor/standard.hpp" // TODO: needed? +// #include "barretenberg/proof_system/composer/composer_lib.hpp" +// #include "barretenberg/proof_system/types/circuit_type.hpp" +// #include "barretenberg/srs/factories/crs_factory.hpp" +// #include +// #include -namespace proof_system::test_composer_lib { +// namespace proof_system::test_composer_lib { -class PermutationHelperTests : public ::testing::Test { - protected: - using Flavor = honk::flavor::Standard; - using FF = typename Flavor::FF; - using ProvingKey = Flavor::ProvingKey; - Flavor::CircuitBuilder circuit_constructor; - barretenberg::srs::factories::CrsFactory crs_factory = - barretenberg::srs::factories::CrsFactory(); - std::shared_ptr proving_key; +// class PermutationHelperTests : public ::testing::Test { +// protected: +// using Flavor = honk::flavor::Standard; +// using FF = typename Flavor::FF; +// using ProvingKey = Flavor::ProvingKey; +// Flavor::CircuitBuilder circuit_constructor; +// barretenberg::srs::factories::CrsFactory crs_factory = +// barretenberg::srs::factories::CrsFactory(); +// std::shared_ptr proving_key; - virtual void SetUp() - { - circuit_constructor.add_public_variable(1024); - circuit_constructor.add_public_variable(1025); +// virtual void SetUp() +// { +// circuit_constructor.add_public_variable(1024); +// circuit_constructor.add_public_variable(1025); - uint32_t v_1 = circuit_constructor.add_variable(16 + 1); - uint32_t v_2 = circuit_constructor.add_variable(16 + 2); - uint32_t v_3 = circuit_constructor.add_variable(16 + 3); - uint32_t v_4 = circuit_constructor.add_variable(16 + 4); - uint32_t v_5 = circuit_constructor.add_variable(16 + 5); - uint32_t v_6 = circuit_constructor.add_variable(16 + 6); - uint32_t v_7 = circuit_constructor.add_variable(16 + 7); - uint32_t v_8 = circuit_constructor.add_variable(16 + 8); - uint32_t v_9 = circuit_constructor.add_variable(16 + 9); - uint32_t v_10 = circuit_constructor.add_variable(16 + 10); - uint32_t v_11 = circuit_constructor.add_variable(16 + 11); - uint32_t v_12 = circuit_constructor.add_variable(16 + 12); +// uint32_t v_1 = circuit_constructor.add_variable(16 + 1); +// uint32_t v_2 = circuit_constructor.add_variable(16 + 2); +// uint32_t v_3 = circuit_constructor.add_variable(16 + 3); +// uint32_t v_4 = circuit_constructor.add_variable(16 + 4); +// uint32_t v_5 = circuit_constructor.add_variable(16 + 5); +// uint32_t v_6 = circuit_constructor.add_variable(16 + 6); +// uint32_t v_7 = circuit_constructor.add_variable(16 + 7); +// uint32_t v_8 = circuit_constructor.add_variable(16 + 8); +// uint32_t v_9 = circuit_constructor.add_variable(16 + 9); +// uint32_t v_10 = circuit_constructor.add_variable(16 + 10); +// uint32_t v_11 = circuit_constructor.add_variable(16 + 11); +// uint32_t v_12 = circuit_constructor.add_variable(16 + 12); - circuit_constructor.create_add_gate({ v_1, v_5, v_9, 0, 0, 0, 0 }); - circuit_constructor.create_add_gate({ v_2, v_6, v_10, 0, 0, 0, 0 }); - circuit_constructor.create_add_gate({ v_3, v_7, v_11, 0, 0, 0, 0 }); - circuit_constructor.create_add_gate({ v_4, v_8, v_12, 0, 0, 0, 0 }); +// circuit_constructor.create_add_gate({ v_1, v_5, v_9, 0, 0, 0, 0 }); +// circuit_constructor.create_add_gate({ v_2, v_6, v_10, 0, 0, 0, 0 }); +// circuit_constructor.create_add_gate({ v_3, v_7, v_11, 0, 0, 0, 0 }); +// circuit_constructor.create_add_gate({ v_4, v_8, v_12, 0, 0, 0, 0 }); - /* Execution trace: - w_l w_r w_o - ------------------------------ - pub1_idx | pub1_idx | 0 <-- public inputs - pub2_idx | pub2_idx | 0 <-/ - zero_idx | zero_idx | zero_idx <-- fix witness for 0 - one_idx | zero_idx | zero_idx <-- fix witness for 1 - one_idx | one_idx | one_idx <-- ensure nonzero selectors... TODO(Cody): redundant now - v_1 | v_5 | v_9 - v_2 | v_6 | v_10 - v_3 | v_7 | v_11 - v_4 | v_8 | v_12 +// /* Execution trace: +// w_l w_r w_o +// ------------------------------ +// pub1_idx | pub1_idx | 0 <-- public inputs +// pub2_idx | pub2_idx | 0 <-/ +// zero_idx | zero_idx | zero_idx <-- fix witness for 0 +// one_idx | zero_idx | zero_idx <-- fix witness for 1 +// one_idx | one_idx | one_idx <-- ensure nonzero selectors... TODO(Cody): redundant now +// v_1 | v_5 | v_9 +// v_2 | v_6 | v_10 +// v_3 | v_7 | v_11 +// v_4 | v_8 | v_12 - */ +// */ - size_t num_public_inputs = circuit_constructor.public_inputs.size(); - size_t dyadic_circuit_size = - circuit_constructor.get_circuit_subgroup_size(circuit_constructor.num_gates + num_public_inputs); - proving_key = std::make_shared(dyadic_circuit_size, num_public_inputs); +// size_t num_public_inputs = circuit_constructor.public_inputs.size(); +// size_t dyadic_circuit_size = +// circuit_constructor.get_circuit_subgroup_size(circuit_constructor.num_gates + num_public_inputs); +// proving_key = std::make_shared(dyadic_circuit_size, num_public_inputs); - // construct_selector_polynomials(circuit_constructor, proving_key.get()); - } -}; +// // construct_selector_polynomials(circuit_constructor, proving_key.get()); +// } +// }; -TEST_F(PermutationHelperTests, ComputeWireCopyCycles) -{ - // TODO(#425) Flesh out these tests - compute_wire_copy_cycles(circuit_constructor); -} +// TEST_F(PermutationHelperTests, ComputeWireCopyCycles) +// { +// // TODO(#425) Flesh out these tests +// compute_wire_copy_cycles(circuit_constructor); +// } -TEST_F(PermutationHelperTests, ComputePermutationMapping) -{ - // TODO(#425) Flesh out these tests - compute_permutation_mapping(circuit_constructor, proving_key.get()); -} +// TEST_F(PermutationHelperTests, ComputePermutationMapping) +// { +// // TODO(#425) Flesh out these tests +// compute_permutation_mapping(circuit_constructor, proving_key.get()); +// } -TEST_F(PermutationHelperTests, ComputeHonkStyleSigmaLagrangePolynomialsFromMapping) -{ - // TODO(#425) Flesh out these tests - auto mapping = compute_permutation_mapping(circuit_constructor, proving_key.get()); - compute_honk_style_permutation_lagrange_polynomials_from_mapping( - proving_key->get_sigma_polynomials(), mapping.sigmas, proving_key.get()); -} +// TEST_F(PermutationHelperTests, ComputeHonkStyleSigmaLagrangePolynomialsFromMapping) +// { +// // TODO(#425) Flesh out these tests +// auto mapping = compute_permutation_mapping(circuit_constructor, +// proving_key.get()); compute_honk_style_permutation_lagrange_polynomials_from_mapping( +// proving_key->get_sigma_polynomials(), mapping.sigmas, proving_key.get()); +// } -TEST_F(PermutationHelperTests, ComputeStandardAuxPolynomials) -{ - // TODO(#425) Flesh out these tests - compute_standard_honk_id_polynomials(proving_key); - compute_standard_honk_sigma_permutations(circuit_constructor, proving_key.get()); - compute_first_and_last_lagrange_polynomials(proving_key); -} +// TEST_F(PermutationHelperTests, ComputeStandardAuxPolynomials) +// { +// // TODO(#425) Flesh out these tests +// compute_standard_honk_id_polynomials(proving_key); +// compute_standard_honk_sigma_permutations(circuit_constructor, proving_key.get()); +// compute_first_and_last_lagrange_polynomials(proving_key); +// } -} // namespace proof_system::test_composer_lib +// } // namespace proof_system::test_composer_lib diff --git a/barretenberg/cpp/src/barretenberg/proof_system/flavor/flavor.hpp b/barretenberg/cpp/src/barretenberg/proof_system/flavor/flavor.hpp index e723ea1c792..c97c9e3c125 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/flavor/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/flavor/flavor.hpp @@ -284,7 +284,7 @@ template concept IsPlonkFlavor = IsAnyOf; template -concept IsHonkFlavor = IsAnyOf; +concept IsHonkFlavor = IsAnyOf; template concept IsUltraFlavor = IsAnyOf; @@ -300,9 +300,7 @@ concept IsRecursiveFlavor = IsAnyOf, honk::flavor::GoblinUltraRecursive_>; -template concept IsGrumpkinFlavor = IsAnyOf; - -template concept StandardFlavor = IsAnyOf; +template concept IsGrumpkinFlavor = IsAnyOf; template concept UltraFlavor = IsAnyOf; diff --git a/barretenberg/cpp/src/barretenberg/proof_system/relations/arithmetic_relation.hpp b/barretenberg/cpp/src/barretenberg/proof_system/relations/arithmetic_relation.hpp deleted file mode 100644 index b3bb4e84132..00000000000 --- a/barretenberg/cpp/src/barretenberg/proof_system/relations/arithmetic_relation.hpp +++ /dev/null @@ -1,57 +0,0 @@ -#pragma once -#include "relation_parameters.hpp" -#include "relation_types.hpp" - -namespace proof_system { - -template class ArithmeticRelationImpl { - public: - using FF = FF_; - - // 1 + polynomial degree of this relation - static constexpr size_t RELATION_LENGTH = 4; - - static constexpr size_t LEN_1 = 4; // arithmetic sub-relation - template