From 6c11165a7e3a74800407d964bb5a9c5c1fd84413 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Wed, 1 Nov 2023 18:57:53 +0000 Subject: [PATCH 01/15] builds w UCB inheritance w new arith --- .../src/barretenberg/flavor/goblin_ultra.hpp | 183 +++++++++++------- .../honk/composer/databus_composer.test.cpp | 99 ++++++++++ .../plonk/composer/ultra_composer.test.cpp | 2 +- .../arithmetization/arithmetization.hpp | 29 ++- .../goblin_ultra_circuit_builder.cpp | 24 ++- .../goblin_ultra_circuit_builder.hpp | 36 +++- .../standard_circuit_builder.hpp | 2 +- .../circuit_builder/ultra_circuit_builder.cpp | 40 +++- .../circuit_builder/ultra_circuit_builder.hpp | 31 +-- .../ultra_circuit_builder.test.cpp | 2 +- .../primitives/bigfield/bigfield_impl.hpp | 6 +- .../circuit_builders/circuit_builders.hpp | 12 +- .../circuit_builders/circuit_builders_fwd.hpp | 9 + .../sumcheck/instance/prover_instance.cpp | 4 + .../ultra_honk/ultra_composer.test.cpp | 2 +- 15 files changed, 368 insertions(+), 113 deletions(-) create mode 100644 barretenberg/cpp/src/barretenberg/honk/composer/databus_composer.test.cpp diff --git a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp index 2c195baea85..461a096ea1b 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp @@ -32,12 +32,13 @@ class GoblinUltra { // 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`. // Note: this number does not include the individual sorted list polynomials. - static constexpr size_t NUM_ALL_ENTITIES = 48; // 43 (UH) + 4 op wires + 1 op wire "selector" + // NUM = 43 (UH) + 4 op wires + 1 op wire "selector" + 3 (calldata + calldata_read_counts + q_busread) + static constexpr size_t NUM_ALL_ENTITIES = 51; // 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 = 26; // 25 (UH) + 1 op wire "selector" + static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 27; // 25 (UH) + 1 op wire "selector" + q_busread // The total number of witness entities not including shifts. - static constexpr size_t NUM_WITNESS_ENTITIES = 15; // 11 (UH) + 4 op wires + static constexpr size_t NUM_WITNESS_ENTITIES = 17; // 11 (UH) + 4 op wires + (calldata + calldata_read_counts) using GrandProductRelations = std::tuple, proof_system::LookupRelation>; @@ -50,6 +51,7 @@ class GoblinUltra { proof_system::EllipticRelation, proof_system::AuxiliaryRelation, proof_system::EccOpQueueRelation>; + // WORKTODO: add bus lookup relation! static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length(); static constexpr size_t MAX_TOTAL_RELATION_LENGTH = compute_max_total_relation_length(); @@ -89,27 +91,28 @@ class GoblinUltra { DataType& q_elliptic = std::get<8>(this->_data); DataType& q_aux = std::get<9>(this->_data); DataType& q_lookup = std::get<10>(this->_data); - DataType& sigma_1 = std::get<11>(this->_data); - DataType& sigma_2 = std::get<12>(this->_data); - DataType& sigma_3 = std::get<13>(this->_data); - DataType& sigma_4 = std::get<14>(this->_data); - DataType& id_1 = std::get<15>(this->_data); - DataType& id_2 = std::get<16>(this->_data); - DataType& id_3 = std::get<17>(this->_data); - DataType& id_4 = std::get<18>(this->_data); - DataType& table_1 = std::get<19>(this->_data); - DataType& table_2 = std::get<20>(this->_data); - DataType& table_3 = std::get<21>(this->_data); - DataType& table_4 = std::get<22>(this->_data); - DataType& lagrange_first = std::get<23>(this->_data); - DataType& lagrange_last = std::get<24>(this->_data); - DataType& lagrange_ecc_op = std::get<25>(this->_data); // indicator poly for ecc op gates + DataType& q_busread = std::get<11>(this->_data); + DataType& sigma_1 = std::get<12>(this->_data); + DataType& sigma_2 = std::get<13>(this->_data); + DataType& sigma_3 = std::get<14>(this->_data); + DataType& sigma_4 = std::get<15>(this->_data); + DataType& id_1 = std::get<16>(this->_data); + DataType& id_2 = std::get<17>(this->_data); + DataType& id_3 = std::get<18>(this->_data); + DataType& id_4 = std::get<19>(this->_data); + DataType& table_1 = std::get<20>(this->_data); + DataType& table_2 = std::get<21>(this->_data); + DataType& table_3 = std::get<22>(this->_data); + DataType& table_4 = std::get<23>(this->_data); + DataType& lagrange_first = std::get<24>(this->_data); + DataType& lagrange_last = std::get<25>(this->_data); + DataType& lagrange_ecc_op = std::get<26>(this->_data); // indicator poly for ecc op gates static constexpr CircuitType CIRCUIT_TYPE = CircuitBuilder::CIRCUIT_TYPE; std::vector get_selectors() override { - return { q_m, q_c, q_l, q_r, q_o, q_4, q_arith, q_sort, q_elliptic, q_aux, q_lookup }; + return { q_m, q_c, q_l, q_r, q_o, q_4, q_arith, q_sort, q_elliptic, q_aux, q_lookup, q_busread }; }; std::vector get_sigma_polynomials() override { return { sigma_1, sigma_2, sigma_3, sigma_4 }; }; std::vector get_id_polynomials() override { return { id_1, id_2, id_3, id_4 }; }; @@ -139,6 +142,8 @@ class GoblinUltra { DataType& ecc_op_wire_2 = std::get<12>(this->_data); DataType& ecc_op_wire_3 = std::get<13>(this->_data); DataType& ecc_op_wire_4 = std::get<14>(this->_data); + DataType& calldata = std::get<15>(this->_data); + DataType& calldata_read_counts = std::get<16>(this->_data); std::vector get_wires() override { return { w_l, w_r, w_o, w_4 }; }; std::vector get_ecc_op_wires() @@ -172,43 +177,46 @@ class GoblinUltra { DataType& q_elliptic = std::get<8>(this->_data); DataType& q_aux = std::get<9>(this->_data); DataType& q_lookup = std::get<10>(this->_data); - DataType& sigma_1 = std::get<11>(this->_data); - DataType& sigma_2 = std::get<12>(this->_data); - DataType& sigma_3 = std::get<13>(this->_data); - DataType& sigma_4 = std::get<14>(this->_data); - DataType& id_1 = std::get<15>(this->_data); - DataType& id_2 = std::get<16>(this->_data); - DataType& id_3 = std::get<17>(this->_data); - DataType& id_4 = std::get<18>(this->_data); - DataType& table_1 = std::get<19>(this->_data); - DataType& table_2 = std::get<20>(this->_data); - DataType& table_3 = std::get<21>(this->_data); - DataType& table_4 = std::get<22>(this->_data); - DataType& lagrange_first = std::get<23>(this->_data); - DataType& lagrange_last = std::get<24>(this->_data); - DataType& lagrange_ecc_op = std::get<25>(this->_data); - DataType& w_l = std::get<26>(this->_data); - DataType& w_r = std::get<27>(this->_data); - DataType& w_o = std::get<28>(this->_data); - DataType& w_4 = std::get<29>(this->_data); - DataType& sorted_accum = std::get<30>(this->_data); - DataType& z_perm = std::get<31>(this->_data); - DataType& z_lookup = std::get<32>(this->_data); - DataType& ecc_op_wire_1 = std::get<33>(this->_data); - DataType& ecc_op_wire_2 = std::get<34>(this->_data); - DataType& ecc_op_wire_3 = std::get<35>(this->_data); - DataType& ecc_op_wire_4 = std::get<36>(this->_data); - DataType& table_1_shift = std::get<37>(this->_data); - DataType& table_2_shift = std::get<38>(this->_data); - DataType& table_3_shift = std::get<39>(this->_data); - DataType& table_4_shift = std::get<40>(this->_data); - DataType& w_l_shift = std::get<41>(this->_data); - DataType& w_r_shift = std::get<42>(this->_data); - DataType& w_o_shift = std::get<43>(this->_data); - DataType& w_4_shift = std::get<44>(this->_data); - DataType& sorted_accum_shift = std::get<45>(this->_data); - DataType& z_perm_shift = std::get<46>(this->_data); - DataType& z_lookup_shift = std::get<47>(this->_data); + DataType& q_busread = std::get<11>(this->_data); + DataType& sigma_1 = std::get<12>(this->_data); + DataType& sigma_2 = std::get<13>(this->_data); + DataType& sigma_3 = std::get<14>(this->_data); + DataType& sigma_4 = std::get<15>(this->_data); + DataType& id_1 = std::get<16>(this->_data); + DataType& id_2 = std::get<17>(this->_data); + DataType& id_3 = std::get<18>(this->_data); + DataType& id_4 = std::get<19>(this->_data); + DataType& table_1 = std::get<20>(this->_data); + DataType& table_2 = std::get<21>(this->_data); + DataType& table_3 = std::get<22>(this->_data); + DataType& table_4 = std::get<23>(this->_data); + DataType& lagrange_first = std::get<24>(this->_data); + DataType& lagrange_last = std::get<25>(this->_data); + DataType& lagrange_ecc_op = std::get<26>(this->_data); + DataType& w_l = std::get<27>(this->_data); + DataType& w_r = std::get<28>(this->_data); + DataType& w_o = std::get<29>(this->_data); + DataType& w_4 = std::get<30>(this->_data); + DataType& sorted_accum = std::get<31>(this->_data); + DataType& z_perm = std::get<32>(this->_data); + DataType& z_lookup = std::get<33>(this->_data); + DataType& ecc_op_wire_1 = std::get<34>(this->_data); + DataType& ecc_op_wire_2 = std::get<35>(this->_data); + DataType& ecc_op_wire_3 = std::get<36>(this->_data); + DataType& ecc_op_wire_4 = std::get<37>(this->_data); + DataType& calldata = std::get<38>(this->_data); + DataType& calldata_read_counts = std::get<39>(this->_data); + DataType& table_1_shift = std::get<40>(this->_data); + DataType& table_2_shift = std::get<41>(this->_data); + DataType& table_3_shift = std::get<42>(this->_data); + DataType& table_4_shift = std::get<43>(this->_data); + DataType& w_l_shift = std::get<44>(this->_data); + DataType& w_r_shift = std::get<45>(this->_data); + DataType& w_o_shift = std::get<46>(this->_data); + DataType& w_4_shift = std::get<47>(this->_data); + DataType& sorted_accum_shift = std::get<48>(this->_data); + DataType& z_perm_shift = std::get<49>(this->_data); + DataType& z_lookup_shift = std::get<50>(this->_data); std::vector get_wires() override { return { w_l, w_r, w_o, w_4 }; }; std::vector get_ecc_op_wires() @@ -218,25 +226,46 @@ class GoblinUltra { // Gemini-specific getters. std::vector get_unshifted() override { - return { q_c, q_l, - q_r, q_o, - q_4, q_m, - q_arith, q_sort, - q_elliptic, q_aux, - q_lookup, sigma_1, - sigma_2, sigma_3, - sigma_4, id_1, - id_2, id_3, - id_4, table_1, - table_2, table_3, - table_4, lagrange_first, - lagrange_last, lagrange_ecc_op, - w_l, w_r, - w_o, w_4, - sorted_accum, z_perm, - z_lookup, ecc_op_wire_1, - ecc_op_wire_2, ecc_op_wire_3, - ecc_op_wire_4 }; + return { q_c, + q_l, + q_r, + q_o, + q_4, + q_m, + q_arith, + q_sort, + q_elliptic, + q_aux, + q_lookup, + q_busread, + sigma_1, + sigma_2, + sigma_3, + sigma_4, + id_1, + id_2, + id_3, + id_4, + table_1, + table_2, + table_3, + table_4, + lagrange_first, + lagrange_last, + lagrange_ecc_op, + w_l, + w_r, + w_o, + w_4, + sorted_accum, + z_perm, + z_lookup, + ecc_op_wire_1, + ecc_op_wire_2, + ecc_op_wire_3, + ecc_op_wire_4, + calldata, + calldata_read_counts }; }; std::vector get_to_be_shifted() override { @@ -384,6 +413,8 @@ class GoblinUltra { ecc_op_wire_2 = "ECC_OP_WIRE_2"; ecc_op_wire_3 = "ECC_OP_WIRE_3"; ecc_op_wire_4 = "ECC_OP_WIRE_4"; + calldata = "CALLDATA"; + calldata_read_counts = "CALLDATA_READ_COUNTS"; // The ones beginning with "__" are only used for debugging q_c = "__Q_C"; @@ -397,6 +428,7 @@ class GoblinUltra { q_elliptic = "__Q_ELLIPTIC"; q_aux = "__Q_AUX"; q_lookup = "__Q_LOOKUP"; + q_busread = "__Q_BUSREAD"; sigma_1 = "__SIGMA_1"; sigma_2 = "__SIGMA_2"; sigma_3 = "__SIGMA_3"; @@ -432,6 +464,7 @@ class GoblinUltra { q_elliptic = verification_key->q_elliptic; q_aux = verification_key->q_aux; q_lookup = verification_key->q_lookup; + q_busread = verification_key->q_busread; sigma_1 = verification_key->sigma_1; sigma_2 = verification_key->sigma_2; sigma_3 = verification_key->sigma_3; diff --git a/barretenberg/cpp/src/barretenberg/honk/composer/databus_composer.test.cpp b/barretenberg/cpp/src/barretenberg/honk/composer/databus_composer.test.cpp new file mode 100644 index 00000000000..fbad88661b4 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/honk/composer/databus_composer.test.cpp @@ -0,0 +1,99 @@ +#include +#include +#include + +#include "barretenberg/common/log.hpp" +#include "barretenberg/honk/composer/ultra_composer.hpp" +#include "barretenberg/honk/proof_system/ultra_prover.hpp" +#include "barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp" +#include "barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp" + +using namespace proof_system::honk; + +namespace test_ultra_honk_composer { + +namespace { +auto& engine = numeric::random::get_debug_engine(); +} + +class DataBusComposerTests : public ::testing::Test { + protected: + static void SetUpTestSuite() { barretenberg::srs::init_crs_factory("../srs_db/ignition"); } + + using Curve = curve::BN254; + using FF = Curve::ScalarField; + using Point = Curve::AffineElement; + using CommitmentKey = pcs::CommitmentKey; + + /** + * @brief Generate a simple test circuit with some ECC op gates and conventional arithmetic gates + * + * @param builder + */ + void generate_test_circuit(auto& builder) + { + // Add some ecc op gates + for (size_t i = 0; i < 3; ++i) { + auto point = Point::one() * FF::random_element(); + auto scalar = FF::random_element(); + builder.queue_ecc_mul_accum(point, scalar); + } + builder.queue_ecc_eq(); + + // Add some conventional gates that utilize public inputs + for (size_t i = 0; i < 10; ++i) { + FF a = FF::random_element(); + FF b = FF::random_element(); + FF c = FF::random_element(); + FF d = a + b + c; + uint32_t a_idx = builder.add_public_variable(a); + uint32_t b_idx = builder.add_variable(b); + uint32_t c_idx = builder.add_variable(c); + uint32_t d_idx = builder.add_variable(d); + + builder.create_big_add_gate({ a_idx, b_idx, c_idx, d_idx, FF(1), FF(1), FF(1), FF(-1), FF(0) }); + } + } + + /** + * @brief Construct and a verify a Honk proof + * + */ + bool construct_and_verify_honk_proof(auto& composer, auto& builder) + { + auto instance = composer.create_instance(builder); + auto prover = composer.create_prover(instance); + auto verifier = composer.create_verifier(instance); + auto proof = prover.construct_proof(); + bool verified = verifier.verify_proof(proof); + + return verified; + } +}; + +/** + * @brief Test proof construction/verification for a circuit with ECC op gates, public inputs, and basic arithmetic + * gates + * @note We simulate op queue interactions with a previous circuit so the actual circuit under test utilizes an op queue + * with non-empty 'previous' data. This avoid complications with zero-commitments etc. + * + */ +TEST_F(DataBusComposerTests, SingleCircuit) +{ + auto op_queue = std::make_shared(); + + // Add mock data to op queue to simulate interaction with a previous circuit + op_queue->populate_with_mock_initital_data(); + + auto builder = proof_system::GoblinUltraCircuitBuilder(op_queue); + + generate_test_circuit(builder); + + auto composer = GoblinUltraComposer(); + + // Construct and verify Honk proof + auto honk_verified = construct_and_verify_honk_proof(composer, builder); + EXPECT_TRUE(honk_verified); +} + +} // namespace test_ultra_honk_composer diff --git a/barretenberg/cpp/src/barretenberg/plonk/composer/ultra_composer.test.cpp b/barretenberg/cpp/src/barretenberg/plonk/composer/ultra_composer.test.cpp index e58bb4b9fbe..f5fd968ca36 100644 --- a/barretenberg/cpp/src/barretenberg/plonk/composer/ultra_composer.test.cpp +++ b/barretenberg/cpp/src/barretenberg/plonk/composer/ultra_composer.test.cpp @@ -647,7 +647,7 @@ TYPED_TEST(ultra_plonk_composer, non_native_field_multiplication) const auto q_indices = get_limb_witness_indices(split_into_limbs(uint256_t(q))); const auto r_indices = get_limb_witness_indices(split_into_limbs(uint256_t(r))); - proof_system::UltraCircuitBuilder::non_native_field_witnesses inputs{ + proof_system::non_native_field_witnesses inputs{ a_indices, b_indices, q_indices, r_indices, modulus_limbs, fr(uint256_t(modulus)), }; const auto [lo_1_idx, hi_1_idx] = builder.evaluate_non_native_field_multiplication(inputs); diff --git a/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/arithmetization.hpp b/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/arithmetization.hpp index d62bc2b52e0..ec3b20b4bad 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/arithmetization.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/arithmetization.hpp @@ -35,7 +35,7 @@ namespace arithmetization { template class Standard { public: static constexpr size_t NUM_WIRES = 3; - static constexpr size_t num_selectors = 5; + static constexpr size_t NUM_SELECTORS = 5; using FF = FF_; using SelectorType = std::vector>; @@ -48,7 +48,7 @@ template class Standard { SelectorType& q_c() { return selectors[4]; }; Standard() - : selectors(num_selectors) + : selectors(NUM_SELECTORS) {} const auto& get() const { return selectors; }; @@ -67,7 +67,7 @@ template class Standard { template class Ultra { public: static constexpr size_t NUM_WIRES = 4; - static constexpr size_t num_selectors = 11; + static constexpr size_t NUM_SELECTORS = 11; using FF = FF_; using SelectorType = std::vector>; @@ -85,7 +85,7 @@ template class Ultra { SelectorType& q_aux() { return selectors[9]; }; SelectorType& q_lookup_type() { return selectors[10]; }; - Ultra() + Ultra(size_t num_selectors = NUM_SELECTORS) : selectors(num_selectors) {} @@ -104,9 +104,28 @@ template class Ultra { "q_elliptic", "q_aux", "table_type" }; }; +template class UltraHonk : public Ultra { + public: + static constexpr size_t NUM_SELECTORS = 11; // 12; + using FF = FF_; + using SelectorType = std::vector>; + + // SelectorType& q_busread() { return this->selectors[11]; }; + + UltraHonk() + : Ultra(NUM_SELECTORS) + {} + + // // Note: These are needed for Plonk only (for poly storage in a std::map). Must be in same order as above struct. + // inline static const std::vector selector_names = { "q_m", "q_c", "q_1", "q_2", + // "q_3", "q_4", "q_arith", "q_sort", + // "q_elliptic", "q_aux", "table_type", "q_busread" + // }; +}; + class GoblinTranslator { public: static constexpr size_t NUM_WIRES = 81; - static constexpr size_t num_selectors = 0; + static constexpr size_t NUM_SELECTORS = 0; }; } // namespace arithmetization \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.cpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.cpp index 9ef30610de8..d5912d343aa 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.cpp @@ -9,7 +9,7 @@ namespace proof_system { template void GoblinUltraCircuitBuilder_::finalize_circuit() { - UltraCircuitBuilder_>::finalize_circuit(); + UltraCircuitBuilder_>::finalize_circuit(); } /** @@ -22,7 +22,27 @@ template void GoblinUltraCircuitBuilder_::finalize_circuit() // polynomials is zero, which is required for them to be shiftable. template void GoblinUltraCircuitBuilder_::add_gates_to_ensure_all_polys_are_non_zero() { - UltraCircuitBuilder_>::add_gates_to_ensure_all_polys_are_non_zero(); + UltraCircuitBuilder_>::add_gates_to_ensure_all_polys_are_non_zero(); + + // WORKTODO: addtional logic to take care of q_busread selector + // this->w_l.emplace_back(this->zero_idx); + // this->w_r.emplace_back(this->zero_idx); + // this->w_o.emplace_back(this->zero_idx); + // this->w_4.emplace_back(this->zero_idx); + // this->q_m.emplace_back(1); + // this->q_1.emplace_back(1); + // this->q_2.emplace_back(1); + // this->q_3.emplace_back(1); + // this->q_c.emplace_back(0); + // this->q_sort.emplace_back(1); + + // this->q_arith.emplace_back(1); + // this->q_4.emplace_back(1); + // this->q_lookup_type.emplace_back(0); + // this->q_elliptic.emplace_back(1); + // this->q_aux.emplace_back(1); + // pad_additional_selectors(); + // ++this->num_gates; } /** diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp index b7a60f03f1e..32f78274e0c 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp @@ -13,12 +13,12 @@ namespace proof_system { using namespace barretenberg; -template class GoblinUltraCircuitBuilder_ : public UltraCircuitBuilder_> { +template class GoblinUltraCircuitBuilder_ : public UltraCircuitBuilder_> { public: static constexpr std::string_view NAME_STRING = "GoblinUltraArithmetization"; static constexpr CircuitType CIRCUIT_TYPE = CircuitType::ULTRA; static constexpr size_t DEFAULT_NON_NATIVE_FIELD_LIMB_BITS = - UltraCircuitBuilder_>::DEFAULT_NON_NATIVE_FIELD_LIMB_BITS; + UltraCircuitBuilder_>::DEFAULT_NON_NATIVE_FIELD_LIMB_BITS; size_t num_ecc_op_gates = 0; // number of ecc op "gates" (rows); these are placed at the start of the circuit @@ -34,13 +34,17 @@ template class GoblinUltraCircuitBuilder_ : public UltraCircuitBui using WireVector = std::vector>; // Wires storing ecc op queue data; values are indices into the variables array - std::array::NUM_WIRES> ecc_op_wires; + std::array::NUM_WIRES> ecc_op_wires; WireVector& ecc_op_wire_1 = std::get<0>(ecc_op_wires); WireVector& ecc_op_wire_2 = std::get<1>(ecc_op_wires); WireVector& ecc_op_wire_3 = std::get<2>(ecc_op_wires); WireVector& ecc_op_wire_4 = std::get<3>(ecc_op_wires); + // DataBus call/return data arrays + std::vector public_calldata; + std::vector public_return_data; + // Functions for adding ECC op queue "gates" ecc_op_tuple queue_ecc_add_accum(const g1::affine_element& point); ecc_op_tuple queue_ecc_mul_accum(const g1::affine_element& point, const FF& scalar); @@ -53,7 +57,7 @@ template class GoblinUltraCircuitBuilder_ : public UltraCircuitBui public: GoblinUltraCircuitBuilder_(const size_t size_hint = 0, std::shared_ptr op_queue_in = std::make_shared()) - : UltraCircuitBuilder_>(size_hint) + : UltraCircuitBuilder_>(size_hint) , op_queue(op_queue_in) { // Set indices to constants corresponding to Goblin ECC op codes @@ -69,6 +73,8 @@ template class GoblinUltraCircuitBuilder_ : public UltraCircuitBui void finalize_circuit(); void add_gates_to_ensure_all_polys_are_non_zero(); + void pad_additional_selectors() override{}; + size_t get_num_constant_gates() const override { return 0; } /** @@ -83,7 +89,7 @@ template class GoblinUltraCircuitBuilder_ : public UltraCircuitBui */ size_t get_num_gates() const override { - auto num_ultra_gates = UltraCircuitBuilder_>::get_num_gates(); + auto num_ultra_gates = UltraCircuitBuilder_>::get_num_gates(); return num_ultra_gates + num_ecc_op_gates; } @@ -98,7 +104,7 @@ template class GoblinUltraCircuitBuilder_ : public UltraCircuitBui size_t romcount = 0; size_t ramcount = 0; size_t nnfcount = 0; - UltraCircuitBuilder_>::get_num_gates_split_into_components( + UltraCircuitBuilder_>::get_num_gates_split_into_components( count, rangecount, romcount, ramcount, nnfcount); size_t total = count + romcount + ramcount + rangecount + num_ecc_op_gates; @@ -106,6 +112,24 @@ template class GoblinUltraCircuitBuilder_ : public UltraCircuitBui << ", range " << rangecount << ", non native field gates " << nnfcount << ", goblin ecc op gates " << num_ecc_op_gates << "), pubinp = " << this->public_inputs.size() << std::endl; } + + /** + * Make a witness variable a member of the public calldata. + * + * @param witness_index The index of the witness. + * */ + void set_public_calldata(const uint32_t witness_index) + { + for (const uint32_t calldata : public_calldata) { + if (calldata == witness_index) { + if (!this->failed()) { + this->failure("Attempted to redundantly set a public calldata!"); + } + return; + } + } + public_calldata.emplace_back(witness_index); + } }; extern template class GoblinUltraCircuitBuilder_; using GoblinUltraCircuitBuilder = GoblinUltraCircuitBuilder_; diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/standard_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/standard_circuit_builder.hpp index 015fcb3a143..819bc5a3c51 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/standard_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/standard_circuit_builder.hpp @@ -15,7 +15,7 @@ template class StandardCircuitBuilder_ : public CircuitBuilderBase static constexpr size_t NUM_WIRES = Arithmetization::NUM_WIRES; // Keeping NUM_WIRES, at least temporarily, for backward compatibility static constexpr size_t program_width = Arithmetization::NUM_WIRES; - static constexpr size_t num_selectors = Arithmetization::num_selectors; + static constexpr size_t num_selectors = Arithmetization::NUM_SELECTORS; std::vector selector_names = Arithmetization::selector_names; static constexpr std::string_view NAME_STRING = "StandardArithmetization"; diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp index 9a31f23f015..cd4a0188185 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp @@ -79,6 +79,7 @@ void UltraCircuitBuilder_::add_gates_to_ensure_all_polys_are_no q_lookup_type.emplace_back(0); q_elliptic.emplace_back(1); q_aux.emplace_back(1); + pad_additional_selectors(); ++this->num_gates; // Some relations depend on wire shifts so we add another gate with @@ -138,6 +139,7 @@ void UltraCircuitBuilder_::create_add_gate(const add_triple_num_gates; } @@ -169,6 +171,7 @@ void UltraCircuitBuilder_::create_big_add_gate(const add_quad_< q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); q_aux.emplace_back(0); + pad_additional_selectors(); ++this->num_gates; } @@ -262,6 +265,7 @@ void UltraCircuitBuilder_::create_big_mul_gate(const mul_quad_< q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); q_aux.emplace_back(0); + pad_additional_selectors(); ++this->num_gates; } @@ -287,6 +291,7 @@ void UltraCircuitBuilder_::create_balanced_add_gate(const add_q q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); q_aux.emplace_back(0); + pad_additional_selectors(); ++this->num_gates; // Why 3? TODO: return to this // The purpose of this gate is to do enable lazy 32-bit addition. @@ -328,6 +333,7 @@ void UltraCircuitBuilder_::create_mul_gate(const mul_triple_num_gates; } /** @@ -356,6 +362,7 @@ void UltraCircuitBuilder_::create_bool_gate(const uint32_t vari q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); q_aux.emplace_back(0); + pad_additional_selectors(); ++this->num_gates; } @@ -386,6 +393,7 @@ void UltraCircuitBuilder_::create_poly_gate(const poly_triple_< q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); q_aux.emplace_back(0); + pad_additional_selectors(); ++this->num_gates; } @@ -439,6 +447,7 @@ void UltraCircuitBuilder_::create_ecc_add_gate(const ecc_add_ga q_lookup_type.emplace_back(0); q_elliptic.emplace_back(1); q_aux.emplace_back(0); + pad_additional_selectors(); ++this->num_gates; } w_l.emplace_back(in.x2); @@ -456,6 +465,7 @@ void UltraCircuitBuilder_::create_ecc_add_gate(const ecc_add_ga q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); q_aux.emplace_back(0); + pad_additional_selectors(); ++this->num_gates; } @@ -501,6 +511,7 @@ void UltraCircuitBuilder_::create_ecc_dbl_gate(const ecc_dbl_ga q_sort.emplace_back(0); q_lookup_type.emplace_back(0); q_aux.emplace_back(0); + pad_additional_selectors(); ++this->num_gates; } @@ -519,6 +530,7 @@ void UltraCircuitBuilder_::create_ecc_dbl_gate(const ecc_dbl_ga q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); q_aux.emplace_back(0); + pad_additional_selectors(); ++this->num_gates; } @@ -548,6 +560,7 @@ void UltraCircuitBuilder_::fix_witness(const uint32_t witness_i q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); q_aux.emplace_back(0); + pad_additional_selectors(); ++this->num_gates; } @@ -622,6 +635,7 @@ plookup::ReadData UltraCircuitBuilder_::create_gates_ q_sort.emplace_back(0); q_elliptic.emplace_back(0); q_aux.emplace_back(0); + pad_additional_selectors(); ++this->num_gates; } return read_data; @@ -930,6 +944,7 @@ void UltraCircuitBuilder_::create_sort_constraint(const std::ve q_elliptic.emplace_back(0); q_lookup_type.emplace_back(0); q_aux.emplace_back(0); + pad_additional_selectors(); } // dummy gate needed because of sort widget's check of next row w_l.emplace_back(variable_index[variable_index.size() - 1]); @@ -948,6 +963,7 @@ void UltraCircuitBuilder_::create_sort_constraint(const std::ve q_elliptic.emplace_back(0); q_lookup_type.emplace_back(0); q_aux.emplace_back(0); + pad_additional_selectors(); } // useful to put variables in the witness that aren't already used - e.g. the dummy variables of the range constraint in @@ -981,6 +997,7 @@ void UltraCircuitBuilder_::create_dummy_constraints(const std:: q_elliptic.emplace_back(0); q_lookup_type.emplace_back(0); q_aux.emplace_back(0); + pad_additional_selectors(); } } @@ -1011,6 +1028,7 @@ void UltraCircuitBuilder_::create_sort_constraint_with_edges( q_elliptic.emplace_back(0); q_lookup_type.emplace_back(0); q_aux.emplace_back(0); + pad_additional_selectors(); // enforce range check for middle rows for (size_t i = gate_width; i < variable_index.size() - gate_width; i += gate_width) { @@ -1030,6 +1048,7 @@ void UltraCircuitBuilder_::create_sort_constraint_with_edges( q_elliptic.emplace_back(0); q_lookup_type.emplace_back(0); q_aux.emplace_back(0); + pad_additional_selectors(); } // enforce range checks of last row and ending at end if (variable_index.size() > gate_width) { @@ -1049,6 +1068,7 @@ void UltraCircuitBuilder_::create_sort_constraint_with_edges( q_elliptic.emplace_back(0); q_lookup_type.emplace_back(0); q_aux.emplace_back(0); + pad_additional_selectors(); } // dummy gate needed because of sort widget's check of next row @@ -1069,6 +1089,7 @@ void UltraCircuitBuilder_::create_sort_constraint_with_edges( q_elliptic.emplace_back(0); q_lookup_type.emplace_back(0); q_aux.emplace_back(0); + pad_additional_selectors(); } // range constraint a value by decomposing it into limbs whose size should be the default range constraint size @@ -1184,6 +1205,7 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m.emplace_back(0); q_c.emplace_back(0); q_arith.emplace_back(0); + pad_additional_selectors(); break; } case AUX_SELECTORS::LIMB_ACCUMULATE_2: { @@ -1194,6 +1216,7 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m.emplace_back(1); q_c.emplace_back(0); q_arith.emplace_back(0); + pad_additional_selectors(); break; } case AUX_SELECTORS::NON_NATIVE_FIELD_1: { @@ -1204,6 +1227,7 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m.emplace_back(0); q_c.emplace_back(0); q_arith.emplace_back(0); + pad_additional_selectors(); break; } case AUX_SELECTORS::NON_NATIVE_FIELD_2: { @@ -1214,6 +1238,7 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m.emplace_back(0); q_c.emplace_back(0); q_arith.emplace_back(0); + pad_additional_selectors(); break; } case AUX_SELECTORS::NON_NATIVE_FIELD_3: { @@ -1224,6 +1249,7 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m.emplace_back(1); q_c.emplace_back(0); q_arith.emplace_back(0); + pad_additional_selectors(); break; } case AUX_SELECTORS::ROM_CONSISTENCY_CHECK: { @@ -1238,6 +1264,7 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m.emplace_back(0); q_c.emplace_back(0); q_arith.emplace_back(0); + pad_additional_selectors(); break; } case AUX_SELECTORS::RAM_CONSISTENCY_CHECK: { @@ -1253,6 +1280,7 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m.emplace_back(0); q_c.emplace_back(0); q_arith.emplace_back(1); + pad_additional_selectors(); break; } case AUX_SELECTORS::RAM_TIMESTAMP_CHECK: { @@ -1265,6 +1293,7 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m.emplace_back(0); q_c.emplace_back(0); q_arith.emplace_back(0); + pad_additional_selectors(); break; } case AUX_SELECTORS::ROM_READ: { @@ -1278,6 +1307,7 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m.emplace_back(1); // validate record witness is correctly computed q_c.emplace_back(0); // read/write flag stored in q_c q_arith.emplace_back(0); + pad_additional_selectors(); break; } case AUX_SELECTORS::RAM_READ: { @@ -1291,6 +1321,7 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m.emplace_back(1); // validate record witness is correctly computed q_c.emplace_back(0); // read/write flag stored in q_c q_arith.emplace_back(0); + pad_additional_selectors(); break; } case AUX_SELECTORS::RAM_WRITE: { @@ -1304,6 +1335,7 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m.emplace_back(1); // validate record witness is correctly computed q_c.emplace_back(1); // read/write flag stored in q_c q_arith.emplace_back(0); + pad_additional_selectors(); break; } default: { @@ -1314,6 +1346,7 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m.emplace_back(0); q_c.emplace_back(0); q_arith.emplace_back(0); + pad_additional_selectors(); break; } } @@ -1461,7 +1494,7 @@ std::array UltraCircuitBuilder_::decompose_non_nat template std::array UltraCircuitBuilder_::evaluate_non_native_field_multiplication( - const non_native_field_witnesses& input, const bool range_constrain_quotient_and_remainder) + const non_native_field_witnesses& input, const bool range_constrain_quotient_and_remainder) { std::array a{ @@ -1682,7 +1715,7 @@ void UltraCircuitBuilder_::process_non_native_field_multiplicat template std::array UltraCircuitBuilder_::queue_partial_non_native_field_multiplication( - const non_native_field_witnesses& input) + const non_native_field_witnesses& input) { std::array a{ @@ -1842,6 +1875,7 @@ std::array UltraCircuitBuilder_::evaluate_non_nati q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); q_aux.emplace_back(0); + pad_additional_selectors(); } this->num_gates += 4; @@ -1963,6 +1997,7 @@ std::array UltraCircuitBuilder_::evaluate_non_nati q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); q_aux.emplace_back(0); + pad_additional_selectors(); } this->num_gates += 4; @@ -3423,6 +3458,7 @@ template bool UltraCircuitBuilder_:: return result; } template class UltraCircuitBuilder_>; +template class UltraCircuitBuilder_>; // To enable this we need to template plookup // template class UltraCircuitBuilder_; diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp index 059934bc93d..6ce3c73891d 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp @@ -14,6 +14,17 @@ namespace proof_system { +template struct non_native_field_witnesses { + // first 4 array elements = limbs + // 5th element = prime basis limb + std::array a; + std::array b; + std::array q; + std::array r; + std::array neg_modulus; + FF modulus; +}; + using namespace barretenberg; template @@ -23,7 +34,7 @@ class UltraCircuitBuilder_ : public CircuitBuilderBase selector_names = Arithmetization::selector_names; static constexpr std::string_view NAME_STRING = "UltraArithmetization"; @@ -45,17 +56,6 @@ class UltraCircuitBuilder_ : public CircuitBuilderBase a; - std::array b; - std::array q; - std::array r; - std::array neg_modulus; - FF modulus; - }; - enum AUX_SELECTORS { NONE, LIMB_ACCUMULATE_1, @@ -641,6 +641,8 @@ class UltraCircuitBuilder_ : public CircuitBuilderBase& in) override; void create_big_add_gate(const add_quad_& in, const bool use_next_gate_w_4 = false); @@ -946,8 +948,8 @@ class UltraCircuitBuilder_ : public CircuitBuilderBase decompose_non_native_field_double_width_limb( const uint32_t limb_idx, const size_t num_limb_bits = (2 * DEFAULT_NON_NATIVE_FIELD_LIMB_BITS)); std::array evaluate_non_native_field_multiplication( - const non_native_field_witnesses& input, const bool range_constrain_quotient_and_remainder = true); - std::array queue_partial_non_native_field_multiplication(const non_native_field_witnesses& input); + const non_native_field_witnesses& input, const bool range_constrain_quotient_and_remainder = true); + std::array queue_partial_non_native_field_multiplication(const non_native_field_witnesses& input); typedef std::pair scaled_witness; typedef std::tuple add_simple; std::array evaluate_non_native_field_subtraction(add_simple limb0, @@ -1049,5 +1051,6 @@ class UltraCircuitBuilder_ : public CircuitBuilderBase>; +extern template class UltraCircuitBuilder_>; using UltraCircuitBuilder = UltraCircuitBuilder_>; } // namespace proof_system \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.test.cpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.test.cpp index bce39f0535c..608727c812a 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.test.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.test.cpp @@ -620,7 +620,7 @@ TEST(ultra_circuit_constructor, non_native_field_multiplication) const auto q_indices = get_limb_witness_indices(split_into_limbs(uint256_t(q))); const auto r_indices = get_limb_witness_indices(split_into_limbs(uint256_t(r))); - proof_system::UltraCircuitBuilder::non_native_field_witnesses inputs{ + proof_system::non_native_field_witnesses inputs{ a_indices, b_indices, q_indices, r_indices, modulus_limbs, fr(uint256_t(modulus)), }; const auto [lo_1_idx, hi_1_idx] = circuit_constructor.evaluate_non_native_field_multiplication(inputs); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_impl.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_impl.hpp index 42177e199bb..5d78358dfe3 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_impl.hpp @@ -2026,7 +2026,7 @@ void bigfield::unsafe_evaluate_multiply_add(const bigfield& input_le }; field_t remainder_prime_limb = field_t::accumulate(prime_limb_accumulator); - proof_system::UltraCircuitBuilder::non_native_field_witnesses witnesses{ + proof_system::non_native_field_witnesses witnesses{ { left.binary_basis_limbs[0].element.normalize().witness_index, left.binary_basis_limbs[1].element.normalize().witness_index, @@ -2366,7 +2366,7 @@ void bigfield::unsafe_evaluate_multiple_multiply_add(const std::vect } if (i > 0) { - proof_system::UltraCircuitBuilder::non_native_field_witnesses mul_witnesses = { + proof_system::non_native_field_witnesses mul_witnesses = { { left[i].binary_basis_limbs[0].element.normalize().witness_index, left[i].binary_basis_limbs[1].element.normalize().witness_index, @@ -2462,7 +2462,7 @@ void bigfield::unsafe_evaluate_multiple_multiply_add(const std::vect }; field_t remainder_prime_limb = field_t::accumulate(prime_limb_accumulator); - proof_system::UltraCircuitBuilder::non_native_field_witnesses witnesses{ + proof_system::non_native_field_witnesses witnesses{ { left[0].binary_basis_limbs[0].element.normalize().witness_index, left[0].binary_basis_limbs[1].element.normalize().witness_index, diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/circuit_builders/circuit_builders.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/circuit_builders/circuit_builders.hpp index d748baa72a8..e1fbb2b65f2 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/circuit_builders/circuit_builders.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/circuit_builders/circuit_builders.hpp @@ -8,8 +8,10 @@ #include "barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp" template -concept HasPlookup = - proof_system::IsAnyOf; +concept HasPlookup = proof_system::IsAnyOf; template concept IsGoblinBuilder = proof_system::IsAnyOf; @@ -17,16 +19,19 @@ concept IsGoblinBuilder = proof_system::IsAnyOf; \ template class stdlib_type; \ + template class stdlib_type; \ template class stdlib_type; #define INSTANTIATE_STDLIB_TYPE_VA(stdlib_type, ...) \ template class stdlib_type; \ template class stdlib_type; \ + template class stdlib_type; \ template class stdlib_type; #define INSTANTIATE_STDLIB_BASIC_TYPE(stdlib_type) template class stdlib_type; @@ -36,12 +41,15 @@ concept IsGoblinBuilder = proof_system::IsAnyOf; \ + template class stdlib_type; \ template class stdlib_type; #define INSTANTIATE_STDLIB_ULTRA_TYPE_VA(stdlib_type, ...) \ template class stdlib_type; \ + template class stdlib_type; \ template class stdlib_type; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/circuit_builders/circuit_builders_fwd.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/circuit_builders/circuit_builders_fwd.hpp index 5b46b4c25d5..093351cae5c 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/circuit_builders/circuit_builders_fwd.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/circuit_builders/circuit_builders_fwd.hpp @@ -23,6 +23,7 @@ template struct alignas(32) field; } // namespace barretenberg namespace arithmetization { template class Ultra; +template class UltraHonk; } // namespace arithmetization namespace proof_system { template class StandardCircuitBuilder_; @@ -31,6 +32,8 @@ using StandardGrumpkinCircuitBuilder = StandardCircuitBuilder_ class UltraCircuitBuilder_; using UltraCircuitBuilder = UltraCircuitBuilder_>>; +using UltraHonkCircuitBuilder = + UltraCircuitBuilder_>>; template class GoblinUltraCircuitBuilder_; using GoblinUltraCircuitBuilder = GoblinUltraCircuitBuilder_>; } // namespace proof_system @@ -38,15 +41,18 @@ using GoblinUltraCircuitBuilder = GoblinUltraCircuitBuilder_; \ extern template class stdlib_type; \ + extern template class stdlib_type; \ extern template class stdlib_type; #define EXTERN_STDLIB_METHOD(stdlib_method) \ extern template stdlib_method(proof_system::StandardCircuitBuilder); \ extern template stdlib_method(proof_system::UltraCircuitBuilder); \ + extern template stdlib_method(proof_system::UltraHonkCircuitBuilder); \ extern template stdlib_method(proof_system::GoblinUltraCircuitBuilder); #define EXTERN_STDLIB_TYPE_VA(stdlib_type, ...) \ extern template class stdlib_type; \ + extern template class stdlib_type; \ extern template class stdlib_type; \ extern template class stdlib_type; @@ -57,12 +63,15 @@ using GoblinUltraCircuitBuilder = GoblinUltraCircuitBuilder_; \ + extern template class stdlib_type; \ extern template class stdlib_type; #define EXTERN_STDLIB_ULTRA_TYPE_VA(stdlib_type, ...) \ extern template class stdlib_type; \ + extern template class stdlib_type; \ extern template class stdlib_type; #define EXTERN_STDLIB_ULTRA_METHOD(stdlib_method) \ extern template stdlib_method(proof_system::UltraCircuitBuilder); \ + extern template stdlib_method(proof_system::UltraHonkCircuitBuilder); \ extern template stdlib_method(proof_system::GoblinUltraCircuitBuilder); diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp index 29e5de759de..e12e900b7af 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp @@ -300,6 +300,10 @@ template void ProverInstance_::initialise_prover_polynomi prover_polynomials.ecc_op_wire_3 = proving_key->ecc_op_wire_3; prover_polynomials.ecc_op_wire_4 = proving_key->ecc_op_wire_4; prover_polynomials.lagrange_ecc_op = proving_key->lagrange_ecc_op; + // DataBus polynomials + prover_polynomials.calldata = proving_key->calldata; + prover_polynomials.calldata_read_counts = proving_key->calldata_read_counts; + prover_polynomials.q_busread = proving_key->q_busread; } std::span public_wires_source = prover_polynomials.w_r; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.test.cpp index 6b9cdbd7484..0f1e0e274a8 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.test.cpp @@ -716,7 +716,7 @@ TEST_F(UltraHonkComposerTests, non_native_field_multiplication) const auto q_indices = get_limb_witness_indices(split_into_limbs(uint256_t(q))); const auto r_indices = get_limb_witness_indices(split_into_limbs(uint256_t(r))); - proof_system::UltraCircuitBuilder::non_native_field_witnesses inputs{ + proof_system::non_native_field_witnesses inputs{ a_indices, b_indices, q_indices, r_indices, modulus_limbs, fr(uint256_t(modulus)), }; const auto [lo_1_idx, hi_1_idx] = circuit_builder.evaluate_non_native_field_multiplication(inputs); From 89d062935491660acefb921393c40b5b405f6265 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Wed, 1 Nov 2023 22:33:33 +0000 Subject: [PATCH 02/15] tests passing with databus additions to goblin --- .../src/barretenberg/flavor/goblin_ultra.hpp | 6 + .../flavor/goblin_ultra_recursive.hpp | 211 ++++++++++-------- .../arithmetization/arithmetization.hpp | 4 +- .../goblin_ultra_circuit_builder.cpp | 43 ++-- .../goblin_ultra_circuit_builder.hpp | 6 +- .../proof_system/composer/composer_lib.hpp | 9 +- .../verifier/ultra_recursive_verifier.cpp | 5 +- .../sumcheck/instance/prover_instance.cpp | 28 ++- .../sumcheck/instance/prover_instance.hpp | 2 + .../goblin_ultra_transcript.test.cpp | 2 + .../barretenberg/ultra_honk/ultra_prover.cpp | 6 + .../ultra_honk/ultra_verifier.cpp | 5 +- 12 files changed, 204 insertions(+), 123 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp index 461a096ea1b..2f0878a9640 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp @@ -506,6 +506,8 @@ class GoblinUltra { Commitment ecc_op_wire_2_comm; Commitment ecc_op_wire_3_comm; Commitment ecc_op_wire_4_comm; + Commitment calldata_comm; + Commitment calldata_read_counts_comm; Commitment sorted_accum_comm; Commitment w_4_comm; Commitment z_perm_comm; @@ -540,6 +542,8 @@ class GoblinUltra { ecc_op_wire_2_comm = deserialize_from_buffer(proof_data, num_bytes_read); ecc_op_wire_3_comm = deserialize_from_buffer(proof_data, num_bytes_read); ecc_op_wire_4_comm = deserialize_from_buffer(proof_data, num_bytes_read); + calldata_comm = deserialize_from_buffer(proof_data, num_bytes_read); + calldata_read_counts_comm = deserialize_from_buffer(proof_data, num_bytes_read); sorted_accum_comm = deserialize_from_buffer(proof_data, num_bytes_read); w_4_comm = deserialize_from_buffer(proof_data, num_bytes_read); z_perm_comm = deserialize_from_buffer(proof_data, num_bytes_read); @@ -576,6 +580,8 @@ class GoblinUltra { serialize_to_buffer(ecc_op_wire_2_comm, proof_data); serialize_to_buffer(ecc_op_wire_3_comm, proof_data); serialize_to_buffer(ecc_op_wire_4_comm, proof_data); + serialize_to_buffer(calldata_comm, proof_data); + serialize_to_buffer(calldata_read_counts_comm, proof_data); serialize_to_buffer(sorted_accum_comm, proof_data); serialize_to_buffer(w_4_comm, proof_data); serialize_to_buffer(z_perm_comm, proof_data); diff --git a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp index 9fcdbfcba3b..0e452c3ff62 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp @@ -61,12 +61,13 @@ template class GoblinUltraRecursive_ { // 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`. // Note: this number does not include the individual sorted list polynomials. - static constexpr size_t NUM_ALL_ENTITIES = 48; // 43 (UH) + 4 op wires + 1 op wire "selector" + // NUM = 43 (UH) + 4 op wires + 1 op wire "selector" + 3 (calldata + calldata_read_counts + q_busread) + static constexpr size_t NUM_ALL_ENTITIES = 51; // 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 = 26; // 25 (UH) + 1 op wire "selector" + static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 27; // 25 (UH) + 1 op wire "selector" + q_busread // The total number of witness entities not including shifts. - static constexpr size_t NUM_WITNESS_ENTITIES = 15; // 11 (UH) + 4 op wires + static constexpr size_t NUM_WITNESS_ENTITIES = 17; // 11 (UH) + 4 op wires + (calldata + calldata_read_counts) // define the tuple of Relations that comprise the Sumcheck relation using Relations = std::tuple, @@ -108,27 +109,28 @@ template class GoblinUltraRecursive_ { DataType& q_elliptic = std::get<8>(this->_data); DataType& q_aux = std::get<9>(this->_data); DataType& q_lookup = std::get<10>(this->_data); - DataType& sigma_1 = std::get<11>(this->_data); - DataType& sigma_2 = std::get<12>(this->_data); - DataType& sigma_3 = std::get<13>(this->_data); - DataType& sigma_4 = std::get<14>(this->_data); - DataType& id_1 = std::get<15>(this->_data); - DataType& id_2 = std::get<16>(this->_data); - DataType& id_3 = std::get<17>(this->_data); - DataType& id_4 = std::get<18>(this->_data); - DataType& table_1 = std::get<19>(this->_data); - DataType& table_2 = std::get<20>(this->_data); - DataType& table_3 = std::get<21>(this->_data); - DataType& table_4 = std::get<22>(this->_data); - DataType& lagrange_first = std::get<23>(this->_data); - DataType& lagrange_last = std::get<24>(this->_data); - DataType& lagrange_ecc_op = std::get<25>(this->_data); // indicator poly for ecc op gates + DataType& q_busread = std::get<11>(this->_data); + DataType& sigma_1 = std::get<12>(this->_data); + DataType& sigma_2 = std::get<13>(this->_data); + DataType& sigma_3 = std::get<14>(this->_data); + DataType& sigma_4 = std::get<15>(this->_data); + DataType& id_1 = std::get<16>(this->_data); + DataType& id_2 = std::get<17>(this->_data); + DataType& id_3 = std::get<18>(this->_data); + DataType& id_4 = std::get<19>(this->_data); + DataType& table_1 = std::get<20>(this->_data); + DataType& table_2 = std::get<21>(this->_data); + DataType& table_3 = std::get<22>(this->_data); + DataType& table_4 = std::get<23>(this->_data); + DataType& lagrange_first = std::get<24>(this->_data); + DataType& lagrange_last = std::get<25>(this->_data); + DataType& lagrange_ecc_op = std::get<26>(this->_data); // indicator poly for ecc op gates static constexpr CircuitType CIRCUIT_TYPE = CircuitBuilder::CIRCUIT_TYPE; std::vector get_selectors() override { - return { q_m, q_c, q_l, q_r, q_o, q_4, q_arith, q_sort, q_elliptic, q_aux, q_lookup }; + return { q_m, q_c, q_l, q_r, q_o, q_4, q_arith, q_sort, q_elliptic, q_aux, q_lookup, q_busread }; }; std::vector get_sigma_polynomials() override { return { sigma_1, sigma_2, sigma_3, sigma_4 }; }; std::vector get_id_polynomials() override { return { id_1, id_2, id_3, id_4 }; }; @@ -158,6 +160,8 @@ template class GoblinUltraRecursive_ { DataType& ecc_op_wire_2 = std::get<12>(this->_data); DataType& ecc_op_wire_3 = std::get<13>(this->_data); DataType& ecc_op_wire_4 = std::get<14>(this->_data); + DataType& calldata = std::get<15>(this->_data); + DataType& calldata_read_counts = std::get<16>(this->_data); std::vector get_wires() override { return { w_l, w_r, w_o, w_4 }; }; std::vector get_ecc_op_wires() @@ -191,43 +195,46 @@ template class GoblinUltraRecursive_ { DataType& q_elliptic = std::get<8>(this->_data); DataType& q_aux = std::get<9>(this->_data); DataType& q_lookup = std::get<10>(this->_data); - DataType& sigma_1 = std::get<11>(this->_data); - DataType& sigma_2 = std::get<12>(this->_data); - DataType& sigma_3 = std::get<13>(this->_data); - DataType& sigma_4 = std::get<14>(this->_data); - DataType& id_1 = std::get<15>(this->_data); - DataType& id_2 = std::get<16>(this->_data); - DataType& id_3 = std::get<17>(this->_data); - DataType& id_4 = std::get<18>(this->_data); - DataType& table_1 = std::get<19>(this->_data); - DataType& table_2 = std::get<20>(this->_data); - DataType& table_3 = std::get<21>(this->_data); - DataType& table_4 = std::get<22>(this->_data); - DataType& lagrange_first = std::get<23>(this->_data); - DataType& lagrange_last = std::get<24>(this->_data); - DataType& lagrange_ecc_op = std::get<25>(this->_data); - DataType& w_l = std::get<26>(this->_data); - DataType& w_r = std::get<27>(this->_data); - DataType& w_o = std::get<28>(this->_data); - DataType& w_4 = std::get<29>(this->_data); - DataType& sorted_accum = std::get<30>(this->_data); - DataType& z_perm = std::get<31>(this->_data); - DataType& z_lookup = std::get<32>(this->_data); - DataType& ecc_op_wire_1 = std::get<33>(this->_data); - DataType& ecc_op_wire_2 = std::get<34>(this->_data); - DataType& ecc_op_wire_3 = std::get<35>(this->_data); - DataType& ecc_op_wire_4 = std::get<36>(this->_data); - DataType& table_1_shift = std::get<37>(this->_data); - DataType& table_2_shift = std::get<38>(this->_data); - DataType& table_3_shift = std::get<39>(this->_data); - DataType& table_4_shift = std::get<40>(this->_data); - DataType& w_l_shift = std::get<41>(this->_data); - DataType& w_r_shift = std::get<42>(this->_data); - DataType& w_o_shift = std::get<43>(this->_data); - DataType& w_4_shift = std::get<44>(this->_data); - DataType& sorted_accum_shift = std::get<45>(this->_data); - DataType& z_perm_shift = std::get<46>(this->_data); - DataType& z_lookup_shift = std::get<47>(this->_data); + DataType& q_busread = std::get<11>(this->_data); + DataType& sigma_1 = std::get<12>(this->_data); + DataType& sigma_2 = std::get<13>(this->_data); + DataType& sigma_3 = std::get<14>(this->_data); + DataType& sigma_4 = std::get<15>(this->_data); + DataType& id_1 = std::get<16>(this->_data); + DataType& id_2 = std::get<17>(this->_data); + DataType& id_3 = std::get<18>(this->_data); + DataType& id_4 = std::get<19>(this->_data); + DataType& table_1 = std::get<20>(this->_data); + DataType& table_2 = std::get<21>(this->_data); + DataType& table_3 = std::get<22>(this->_data); + DataType& table_4 = std::get<23>(this->_data); + DataType& lagrange_first = std::get<24>(this->_data); + DataType& lagrange_last = std::get<25>(this->_data); + DataType& lagrange_ecc_op = std::get<26>(this->_data); + DataType& w_l = std::get<27>(this->_data); + DataType& w_r = std::get<28>(this->_data); + DataType& w_o = std::get<29>(this->_data); + DataType& w_4 = std::get<30>(this->_data); + DataType& sorted_accum = std::get<31>(this->_data); + DataType& z_perm = std::get<32>(this->_data); + DataType& z_lookup = std::get<33>(this->_data); + DataType& ecc_op_wire_1 = std::get<34>(this->_data); + DataType& ecc_op_wire_2 = std::get<35>(this->_data); + DataType& ecc_op_wire_3 = std::get<36>(this->_data); + DataType& ecc_op_wire_4 = std::get<37>(this->_data); + DataType& calldata = std::get<38>(this->_data); + DataType& calldata_read_counts = std::get<39>(this->_data); + DataType& table_1_shift = std::get<40>(this->_data); + DataType& table_2_shift = std::get<41>(this->_data); + DataType& table_3_shift = std::get<42>(this->_data); + DataType& table_4_shift = std::get<43>(this->_data); + DataType& w_l_shift = std::get<44>(this->_data); + DataType& w_r_shift = std::get<45>(this->_data); + DataType& w_o_shift = std::get<46>(this->_data); + DataType& w_4_shift = std::get<47>(this->_data); + DataType& sorted_accum_shift = std::get<48>(this->_data); + DataType& z_perm_shift = std::get<49>(this->_data); + DataType& z_lookup_shift = std::get<50>(this->_data); std::vector get_wires() override { return { w_l, w_r, w_o, w_4 }; }; std::vector get_ecc_op_wires() @@ -237,25 +244,46 @@ template class GoblinUltraRecursive_ { // Gemini-specific getters. std::vector get_unshifted() override { - return { q_c, q_l, - q_r, q_o, - q_4, q_m, - q_arith, q_sort, - q_elliptic, q_aux, - q_lookup, sigma_1, - sigma_2, sigma_3, - sigma_4, id_1, - id_2, id_3, - id_4, table_1, - table_2, table_3, - table_4, lagrange_first, - lagrange_last, lagrange_ecc_op, - w_l, w_r, - w_o, w_4, - sorted_accum, z_perm, - z_lookup, ecc_op_wire_1, - ecc_op_wire_2, ecc_op_wire_3, - ecc_op_wire_4 }; + return { q_c, + q_l, + q_r, + q_o, + q_4, + q_m, + q_arith, + q_sort, + q_elliptic, + q_aux, + q_lookup, + q_busread, + sigma_1, + sigma_2, + sigma_3, + sigma_4, + id_1, + id_2, + id_3, + id_4, + table_1, + table_2, + table_3, + table_4, + lagrange_first, + lagrange_last, + lagrange_ecc_op, + w_l, + w_r, + w_o, + w_4, + sorted_accum, + z_perm, + z_lookup, + ecc_op_wire_1, + ecc_op_wire_2, + ecc_op_wire_3, + ecc_op_wire_4, + calldata, + calldata_read_counts }; }; std::vector get_to_be_shifted() override { @@ -325,6 +353,7 @@ template class GoblinUltraRecursive_ { this->q_elliptic = Commitment::from_witness(builder, native_key->q_elliptic); this->q_aux = Commitment::from_witness(builder, native_key->q_aux); this->q_lookup = Commitment::from_witness(builder, native_key->q_lookup); + this->q_busread = Commitment::from_witness(builder, native_key->q_busread); this->sigma_1 = Commitment::from_witness(builder, native_key->sigma_1); this->sigma_2 = Commitment::from_witness(builder, native_key->sigma_2); this->sigma_3 = Commitment::from_witness(builder, native_key->sigma_3); @@ -375,6 +404,8 @@ template class GoblinUltraRecursive_ { this->ecc_op_wire_2 = "ECC_OP_WIRE_2"; this->ecc_op_wire_3 = "ECC_OP_WIRE_3"; this->ecc_op_wire_4 = "ECC_OP_WIRE_4"; + this->calldata = "CALLDATA"; + this->calldata_read_counts = "CALLDATA_READ_COUNTS"; // The ones beginning with "__" are only used for debugging this->q_c = "__Q_C"; @@ -388,6 +419,7 @@ template class GoblinUltraRecursive_ { this->q_elliptic = "__Q_ELLIPTIC"; this->q_aux = "__Q_AUX"; this->q_lookup = "__Q_LOOKUP"; + this->q_busread = "__Q_BUSREAD"; this->sigma_1 = "__SIGMA_1"; this->sigma_2 = "__SIGMA_2"; this->sigma_3 = "__SIGMA_3"; @@ -421,6 +453,7 @@ template class GoblinUltraRecursive_ { this->q_elliptic = verification_key->q_elliptic; this->q_aux = verification_key->q_aux; this->q_lookup = verification_key->q_lookup; + this->q_busread = verification_key->q_busread; this->sigma_1 = verification_key->sigma_1; this->sigma_2 = verification_key->sigma_2; this->sigma_3 = verification_key->sigma_3; @@ -446,7 +479,6 @@ template class GoblinUltraRecursive_ { */ class Transcript : public BaseTranscript { public: - // Transcript objects defined as public member variables for easy access and modification uint32_t circuit_size; uint32_t public_input_size; uint32_t pub_inputs_offset; @@ -458,6 +490,8 @@ template class GoblinUltraRecursive_ { Commitment ecc_op_wire_2_comm; Commitment ecc_op_wire_3_comm; Commitment ecc_op_wire_4_comm; + Commitment calldata_comm; + Commitment calldata_read_counts_comm; Commitment sorted_accum_comm; Commitment w_4_comm; Commitment z_perm_comm; @@ -470,26 +504,9 @@ template class GoblinUltraRecursive_ { Transcript() = default; - // Used by verifier to initialize the transcript Transcript(const std::vector& proof) : BaseTranscript(proof) {} - - static Transcript prover_init_empty() - { - Transcript transcript; - constexpr uint32_t init{ 42 }; // arbitrary - transcript.send_to_verifier("Init", init); - return transcript; - }; - - static Transcript verifier_init_empty(const Transcript& transcript) - { - Transcript verifier_transcript{ transcript.proof_data }; - [[maybe_unused]] auto _ = verifier_transcript.template receive_from_prover("Init"); - return verifier_transcript; - }; - /** * @brief Takes a FULL GoblinUltraRecursive proof and deserializes it into the public member variables that * compose the structure. Must be called in order to access the structure of the proof. @@ -514,6 +531,9 @@ template class GoblinUltraRecursive_ { ecc_op_wire_2_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); ecc_op_wire_3_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); ecc_op_wire_4_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); + calldata_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); + calldata_read_counts_comm = + deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); sorted_accum_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); w_4_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); z_perm_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); @@ -532,6 +552,7 @@ template class GoblinUltraRecursive_ { zm_cq_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); zm_pi_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); } + /** * @brief Serializes the structure variables into a FULL GoblinUltraRecursive proof. Should be called only if * deserialize_full_transcript() was called and some transcript variable was modified. @@ -540,7 +561,7 @@ template class GoblinUltraRecursive_ { void serialize_full_transcript() override { size_t old_proof_length = BaseTranscript::proof_data.size(); - BaseTranscript::proof_data.clear(); // clear proof_data so the rest of the function can replace it + BaseTranscript::proof_data.clear(); size_t log_n = numeric::get_msb(circuit_size); serialize_to_buffer(circuit_size, BaseTranscript::proof_data); serialize_to_buffer(public_input_size, BaseTranscript::proof_data); @@ -555,6 +576,8 @@ template class GoblinUltraRecursive_ { serialize_to_buffer(ecc_op_wire_2_comm, BaseTranscript::proof_data); serialize_to_buffer(ecc_op_wire_3_comm, BaseTranscript::proof_data); serialize_to_buffer(ecc_op_wire_4_comm, BaseTranscript::proof_data); + serialize_to_buffer(calldata_comm, BaseTranscript::proof_data); + serialize_to_buffer(calldata_read_counts_comm, BaseTranscript::proof_data); serialize_to_buffer(sorted_accum_comm, BaseTranscript::proof_data); serialize_to_buffer(w_4_comm, BaseTranscript::proof_data); serialize_to_buffer(z_perm_comm, BaseTranscript::proof_data); diff --git a/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/arithmetization.hpp b/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/arithmetization.hpp index ec3b20b4bad..ae5b8d172d2 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/arithmetization.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/arithmetization.hpp @@ -106,11 +106,11 @@ template class Ultra { template class UltraHonk : public Ultra { public: - static constexpr size_t NUM_SELECTORS = 11; // 12; + static constexpr size_t NUM_SELECTORS = 12; using FF = FF_; using SelectorType = std::vector>; - // SelectorType& q_busread() { return this->selectors[11]; }; + SelectorType& q_busread() { return this->selectors[11]; }; UltraHonk() : Ultra(NUM_SELECTORS) diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.cpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.cpp index d5912d343aa..131876d4b21 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.cpp @@ -24,25 +24,30 @@ template void GoblinUltraCircuitBuilder_::add_gates_to_ensure_ { UltraCircuitBuilder_>::add_gates_to_ensure_all_polys_are_non_zero(); - // WORKTODO: addtional logic to take care of q_busread selector - // this->w_l.emplace_back(this->zero_idx); - // this->w_r.emplace_back(this->zero_idx); - // this->w_o.emplace_back(this->zero_idx); - // this->w_4.emplace_back(this->zero_idx); - // this->q_m.emplace_back(1); - // this->q_1.emplace_back(1); - // this->q_2.emplace_back(1); - // this->q_3.emplace_back(1); - // this->q_c.emplace_back(0); - // this->q_sort.emplace_back(1); - - // this->q_arith.emplace_back(1); - // this->q_4.emplace_back(1); - // this->q_lookup_type.emplace_back(0); - // this->q_elliptic.emplace_back(1); - // this->q_aux.emplace_back(1); - // pad_additional_selectors(); - // ++this->num_gates; + // Additional gate to add a nonzero value to q_busread + this->w_l.emplace_back(this->zero_idx); + this->w_r.emplace_back(this->zero_idx); + this->w_o.emplace_back(this->zero_idx); + this->w_4.emplace_back(this->zero_idx); + this->q_m.emplace_back(0); + this->q_1.emplace_back(0); + this->q_2.emplace_back(0); + this->q_3.emplace_back(0); + this->q_c.emplace_back(0); + this->q_sort.emplace_back(0); + + this->q_arith.emplace_back(0); + this->q_4.emplace_back(0); + this->q_lookup_type.emplace_back(0); + this->q_elliptic.emplace_back(0); + this->q_aux.emplace_back(0); + q_busread.emplace_back(1); + ++this->num_gates; + + // Add some nonzero values to the calldata and corresponding read counts + // WORKTODO: will need to do this more carefully once we actually have a databus lookup relation + public_calldata.emplace_back(this->one_idx); + calldata_read_counts.emplace_back(this->one_idx); } /** diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp index 32f78274e0c..0e29557b81f 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp @@ -32,6 +32,7 @@ template class GoblinUltraCircuitBuilder_ : public UltraCircuitBui uint32_t equality_op_idx; using WireVector = std::vector>; + using SelectorVector = std::vector>; // Wires storing ecc op queue data; values are indices into the variables array std::array::NUM_WIRES> ecc_op_wires; @@ -41,8 +42,11 @@ template class GoblinUltraCircuitBuilder_ : public UltraCircuitBui WireVector& ecc_op_wire_3 = std::get<2>(ecc_op_wires); WireVector& ecc_op_wire_4 = std::get<3>(ecc_op_wires); + SelectorVector& q_busread = this->selectors.q_busread(); + // DataBus call/return data arrays std::vector public_calldata; + std::vector calldata_read_counts; std::vector public_return_data; // Functions for adding ECC op queue "gates" @@ -73,7 +77,7 @@ template class GoblinUltraCircuitBuilder_ : public UltraCircuitBui void finalize_circuit(); void add_gates_to_ensure_all_polys_are_non_zero(); - void pad_additional_selectors() override{}; + void pad_additional_selectors() override { q_busread.emplace_back(0); }; size_t get_num_constant_gates() const override { return 0; } diff --git a/barretenberg/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp b/barretenberg/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp index 3ab74f3b439..07e400b3774 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp @@ -22,7 +22,8 @@ void construct_selector_polynomials(const typename Flavor::CircuitBuilder& circu size_t gate_offset = zero_row_offset + circuit_constructor.public_inputs.size(); // If Goblin, (1) update the conventional gate offset to account for ecc op gates at the top of the execution trace, - // and (2) construct ecc op gate selector polynomial. + // and (2) construct ecc op gate selector polynomial. This selector is handled separately from the others since it + // is computable based simply on num_ecc_op_gates and thus is not constructed explicitly in the builder. // Note 1: All other selectors will be automatically and correctly initialized to 0 on this domain. // Note 2: If applicable, the ecc op gates are shifted down by 1 to account for a zero row. if constexpr (IsGoblinFlavor) { @@ -30,11 +31,11 @@ void construct_selector_polynomials(const typename Flavor::CircuitBuilder& circu gate_offset += num_ecc_op_gates; const size_t op_gate_offset = zero_row_offset; // The op gate selector is simply the indicator on the domain [offset, num_ecc_op_gates + offset - 1] - barretenberg::polynomial selector_poly_lagrange(proving_key->circuit_size); + barretenberg::polynomial ecc_op_selector(proving_key->circuit_size); for (size_t i = 0; i < num_ecc_op_gates; ++i) { - selector_poly_lagrange[i + op_gate_offset] = 1; + ecc_op_selector[i + op_gate_offset] = 1; } - proving_key->lagrange_ecc_op = selector_poly_lagrange; + proving_key->lagrange_ecc_op = ecc_op_selector; } // TODO(#398): Loose coupling here! Would rather build up pk from arithmetization diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/ultra_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/ultra_recursive_verifier.cpp index 53ce85d0108..c4d91dbf987 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/ultra_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/ultra_recursive_verifier.cpp @@ -57,7 +57,7 @@ std::array UltraRecursiveVerifier_::ve commitments.w_r = transcript.template receive_from_prover(commitment_labels.w_r); commitments.w_o = transcript.template receive_from_prover(commitment_labels.w_o); - // If Goblin, get commitments to ECC op wire polynomials + // If Goblin, get commitments to ECC op wire polynomials and DataBus columns if constexpr (IsGoblinFlavor) { commitments.ecc_op_wire_1 = transcript.template receive_from_prover(commitment_labels.ecc_op_wire_1); @@ -67,6 +67,9 @@ std::array UltraRecursiveVerifier_::ve transcript.template receive_from_prover(commitment_labels.ecc_op_wire_3); commitments.ecc_op_wire_4 = transcript.template receive_from_prover(commitment_labels.ecc_op_wire_4); + commitments.calldata = transcript.template receive_from_prover(commitment_labels.calldata); + commitments.calldata_read_counts = + transcript.template receive_from_prover(commitment_labels.calldata_read_counts); } // Get challenge for sorted list batching and wire four memory records diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp index e12e900b7af..4e4955535bb 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp @@ -59,9 +59,10 @@ template void ProverInstance_::compute_witness(Circuit& c proving_key->w_o = wire_polynomials[2]; proving_key->w_4 = wire_polynomials[3]; - // If Goblin, construct the ECC op queue wire polynomials + // If Goblin, construct the ECC op queue wire and databus polynomials if constexpr (IsGoblinFlavor) { construct_ecc_op_wire_polynomials(wire_polynomials); + construct_databus_polynomials(circuit); } // Construct the sorted concatenated list polynomials for the lookup argument @@ -184,6 +185,30 @@ template void ProverInstance_::construct_ecc_op_wire_poly proving_key->ecc_op_wire_4 = op_wire_polynomials[3]; } +/** + * @brief + * @details + * + * @tparam Flavor + * @param circuit + */ +template void ProverInstance_::construct_databus_polynomials(Circuit& circuit) +{ + if constexpr (IsGoblinFlavor) { + polynomial public_calldata(dyadic_circuit_size); + polynomial calldata_read_counts(dyadic_circuit_size); + + const size_t offset = Flavor::has_zero_row ? 1 : 0; + for (size_t idx = 0; idx < circuit.public_calldata.size(); ++idx) { + public_calldata[idx + offset] = circuit.get_variable(circuit.public_calldata[idx]); + calldata_read_counts[idx + offset] = circuit.get_variable(circuit.calldata_read_counts[idx]); + } + + proving_key->calldata = public_calldata; + proving_key->calldata_read_counts = calldata_read_counts; + } +} + template std::shared_ptr ProverInstance_::compute_proving_key(Circuit& circuit) { @@ -468,6 +493,7 @@ std::shared_ptr ProverInstance_::compu // due to its simple structure. Handling it in the same way as the lagrange polys for now for simplicity. if constexpr (IsGoblinFlavor) { verification_key->lagrange_ecc_op = commitment_key->commit(proving_key->lagrange_ecc_op); + verification_key->q_busread = commitment_key->commit(proving_key->q_busread); } // // See `add_recusrive_proof()` for how this recursive data is assigned. diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp index b54ee42ae2d..c7a6808fd2e 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp @@ -93,6 +93,8 @@ template class ProverInstance_ { void construct_ecc_op_wire_polynomials(auto&); + void construct_databus_polynomials(Circuit&); + void add_table_column_selector_poly_to_proving_key(barretenberg::polynomial& small, const std::string& tag); void add_plookup_memory_records_to_wire_4(FF); diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_transcript.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_transcript.test.cpp index 02dcb467a28..611110de27d 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_transcript.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_transcript.test.cpp @@ -51,6 +51,8 @@ class GoblinUltraTranscriptTests : public ::testing::Test { manifest_expected.add_entry(round, "ECC_OP_WIRE_2", size_G); manifest_expected.add_entry(round, "ECC_OP_WIRE_3", size_G); manifest_expected.add_entry(round, "ECC_OP_WIRE_4", size_G); + manifest_expected.add_entry(round, "CALLDATA", size_G); + manifest_expected.add_entry(round, "CALLDATA_READ_COUNTS", size_G); manifest_expected.add_challenge(round, "eta"); round++; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp index e29f3c63be3..d7fe84acf87 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp @@ -54,11 +54,17 @@ template void UltraProver_::execute_wire_commitment } if constexpr (IsGoblinFlavor) { + // Commit to Goblin ECC op wires auto op_wire_polys = instance->proving_key->get_ecc_op_wires(); auto labels = commitment_labels.get_ecc_op_wires(); for (size_t idx = 0; idx < Flavor::NUM_WIRES; ++idx) { transcript.send_to_verifier(labels[idx], commitment_key->commit(op_wire_polys[idx])); } + // Commit to DataBus columns + transcript.send_to_verifier(commitment_labels.calldata, + commitment_key->commit(instance->proving_key->calldata)); + transcript.send_to_verifier(commitment_labels.calldata_read_counts, + commitment_key->commit(instance->proving_key->calldata_read_counts)); } } diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp index 4bdcde80193..3dc1bcafa67 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp @@ -70,7 +70,7 @@ template bool UltraVerifier_::verify_proof(const plonk commitments.w_r = transcript.template receive_from_prover(commitment_labels.w_r); commitments.w_o = transcript.template receive_from_prover(commitment_labels.w_o); - // If Goblin, get commitments to ECC op wire polynomials + // If Goblin, get commitments to ECC op wire polynomials and DataBus columns if constexpr (IsGoblinFlavor) { commitments.ecc_op_wire_1 = transcript.template receive_from_prover(commitment_labels.ecc_op_wire_1); @@ -80,6 +80,9 @@ template bool UltraVerifier_::verify_proof(const plonk transcript.template receive_from_prover(commitment_labels.ecc_op_wire_3); commitments.ecc_op_wire_4 = transcript.template receive_from_prover(commitment_labels.ecc_op_wire_4); + commitments.calldata = transcript.template receive_from_prover(commitment_labels.calldata); + commitments.calldata_read_counts = + transcript.template receive_from_prover(commitment_labels.calldata_read_counts); } // Get challenge for sorted list batching and wire four memory records From 701a696350a4a2985b9a28bbbfd7f66ad6048237 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Wed, 1 Nov 2023 23:06:04 +0000 Subject: [PATCH 03/15] cleanup and remove unneeded forward decs --- .../proof_system/arithmetization/arithmetization.hpp | 12 ++++++------ .../circuit_builder/goblin_ultra_circuit_builder.hpp | 4 ++++ .../circuit_builder/ultra_circuit_builder.hpp | 6 ++++++ .../primitives/circuit_builders/circuit_builders.hpp | 12 ++---------- .../circuit_builders/circuit_builders_fwd.hpp | 9 --------- 5 files changed, 18 insertions(+), 25 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/arithmetization.hpp b/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/arithmetization.hpp index ae5b8d172d2..6697cee6aae 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/arithmetization.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/arithmetization.hpp @@ -104,6 +104,12 @@ template class Ultra { "q_elliptic", "q_aux", "table_type" }; }; +/** + * @brief Ultra Honk arithmetization + * @details Extends the conventional Ultra arithmetization with a new selector related to databus lookups + * + * @tparam FF_ + */ template class UltraHonk : public Ultra { public: static constexpr size_t NUM_SELECTORS = 12; @@ -115,12 +121,6 @@ template class UltraHonk : public Ultra { UltraHonk() : Ultra(NUM_SELECTORS) {} - - // // Note: These are needed for Plonk only (for poly storage in a std::map). Must be in same order as above struct. - // inline static const std::vector selector_names = { "q_m", "q_c", "q_1", "q_2", - // "q_3", "q_4", "q_arith", "q_sort", - // "q_elliptic", "q_aux", "table_type", "q_busread" - // }; }; class GoblinTranslator { diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp index 0e29557b81f..1b7c6e6eb15 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp @@ -77,6 +77,10 @@ template class GoblinUltraCircuitBuilder_ : public UltraCircuitBui void finalize_circuit(); void add_gates_to_ensure_all_polys_are_non_zero(); + /** + * @brief Utility for adding zeros to selectors which are not part of the conventional Ultra arithmetization + * + */ void pad_additional_selectors() override { q_busread.emplace_back(0); }; size_t get_num_constant_gates() const override { return 0; } diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp index 6ce3c73891d..3d36484a288 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp @@ -641,6 +641,12 @@ class UltraCircuitBuilder_ : public CircuitBuilderBase& in) override; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/circuit_builders/circuit_builders.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/circuit_builders/circuit_builders.hpp index e1fbb2b65f2..d748baa72a8 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/circuit_builders/circuit_builders.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/circuit_builders/circuit_builders.hpp @@ -8,10 +8,8 @@ #include "barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp" template -concept HasPlookup = proof_system::IsAnyOf; +concept HasPlookup = + proof_system::IsAnyOf; template concept IsGoblinBuilder = proof_system::IsAnyOf; @@ -19,19 +17,16 @@ concept IsGoblinBuilder = proof_system::IsAnyOf; \ template class stdlib_type; \ - template class stdlib_type; \ template class stdlib_type; #define INSTANTIATE_STDLIB_TYPE_VA(stdlib_type, ...) \ template class stdlib_type; \ template class stdlib_type; \ - template class stdlib_type; \ template class stdlib_type; #define INSTANTIATE_STDLIB_BASIC_TYPE(stdlib_type) template class stdlib_type; @@ -41,15 +36,12 @@ concept IsGoblinBuilder = proof_system::IsAnyOf; \ - template class stdlib_type; \ template class stdlib_type; #define INSTANTIATE_STDLIB_ULTRA_TYPE_VA(stdlib_type, ...) \ template class stdlib_type; \ - template class stdlib_type; \ template class stdlib_type; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/circuit_builders/circuit_builders_fwd.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/circuit_builders/circuit_builders_fwd.hpp index 093351cae5c..5b46b4c25d5 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/circuit_builders/circuit_builders_fwd.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/circuit_builders/circuit_builders_fwd.hpp @@ -23,7 +23,6 @@ template struct alignas(32) field; } // namespace barretenberg namespace arithmetization { template class Ultra; -template class UltraHonk; } // namespace arithmetization namespace proof_system { template class StandardCircuitBuilder_; @@ -32,8 +31,6 @@ using StandardGrumpkinCircuitBuilder = StandardCircuitBuilder_ class UltraCircuitBuilder_; using UltraCircuitBuilder = UltraCircuitBuilder_>>; -using UltraHonkCircuitBuilder = - UltraCircuitBuilder_>>; template class GoblinUltraCircuitBuilder_; using GoblinUltraCircuitBuilder = GoblinUltraCircuitBuilder_>; } // namespace proof_system @@ -41,18 +38,15 @@ using GoblinUltraCircuitBuilder = GoblinUltraCircuitBuilder_; \ extern template class stdlib_type; \ - extern template class stdlib_type; \ extern template class stdlib_type; #define EXTERN_STDLIB_METHOD(stdlib_method) \ extern template stdlib_method(proof_system::StandardCircuitBuilder); \ extern template stdlib_method(proof_system::UltraCircuitBuilder); \ - extern template stdlib_method(proof_system::UltraHonkCircuitBuilder); \ extern template stdlib_method(proof_system::GoblinUltraCircuitBuilder); #define EXTERN_STDLIB_TYPE_VA(stdlib_type, ...) \ extern template class stdlib_type; \ - extern template class stdlib_type; \ extern template class stdlib_type; \ extern template class stdlib_type; @@ -63,15 +57,12 @@ using GoblinUltraCircuitBuilder = GoblinUltraCircuitBuilder_; \ - extern template class stdlib_type; \ extern template class stdlib_type; #define EXTERN_STDLIB_ULTRA_TYPE_VA(stdlib_type, ...) \ extern template class stdlib_type; \ - extern template class stdlib_type; \ extern template class stdlib_type; #define EXTERN_STDLIB_ULTRA_METHOD(stdlib_method) \ extern template stdlib_method(proof_system::UltraCircuitBuilder); \ - extern template stdlib_method(proof_system::UltraHonkCircuitBuilder); \ extern template stdlib_method(proof_system::GoblinUltraCircuitBuilder); From 3ef4a84d0d6a790aea7f4e0c28e966848dc343e7 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Thu, 2 Nov 2023 17:11:51 +0000 Subject: [PATCH 04/15] define pad directly in arith to avoid virtual --- .../arithmetization/arithmetization.hpp | 59 +++++++++++++--- .../goblin_ultra_circuit_builder.hpp | 6 -- .../circuit_builder/ultra_circuit_builder.cpp | 70 +++++++++---------- .../circuit_builder/ultra_circuit_builder.hpp | 8 --- 4 files changed, 83 insertions(+), 60 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/arithmetization.hpp b/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/arithmetization.hpp index 6697cee6aae..c6dffdeaa3a 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/arithmetization.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/arithmetization.hpp @@ -71,8 +71,10 @@ template class Ultra { using FF = FF_; using SelectorType = std::vector>; - std::vector selectors; + private: + std::array selectors; + public: SelectorType& q_m() { return selectors[0]; }; SelectorType& q_c() { return selectors[1]; }; SelectorType& q_1() { return selectors[2]; }; @@ -85,19 +87,22 @@ template class Ultra { SelectorType& q_aux() { return selectors[9]; }; SelectorType& q_lookup_type() { return selectors[10]; }; - Ultra(size_t num_selectors = NUM_SELECTORS) - : selectors(num_selectors) - {} - const auto& get() const { return selectors; }; void reserve(size_t size_hint) { - for (auto& p : selectors) { - p.reserve(size_hint); + for (auto& vec : selectors) { + vec.reserve(size_hint); } } + /** + * @brief Add zeros to all selectors which are not part of the conventional Ultra arithmetization + * @details Does nothing for this class since this IS the conventional Ultra arithmetization + * + */ + void pad_additional(){}; + // Note: These are needed for Plonk only (for poly storage in a std::map). Must be in same order as above struct. inline static const std::vector selector_names = { "q_m", "q_c", "q_1", "q_2", "q_3", "q_4", "q_arith", "q_sort", @@ -110,17 +115,49 @@ template class Ultra { * * @tparam FF_ */ -template class UltraHonk : public Ultra { +template class UltraHonk { public: + static constexpr size_t NUM_WIRES = 4; static constexpr size_t NUM_SELECTORS = 12; using FF = FF_; using SelectorType = std::vector>; + private: + std::array selectors; + + public: + SelectorType& q_m() { return selectors[0]; }; + SelectorType& q_c() { return selectors[1]; }; + SelectorType& q_1() { return selectors[2]; }; + SelectorType& q_2() { return selectors[3]; }; + SelectorType& q_3() { return selectors[4]; }; + SelectorType& q_4() { return selectors[5]; }; + SelectorType& q_arith() { return selectors[6]; }; + SelectorType& q_sort() { return selectors[7]; }; + SelectorType& q_elliptic() { return selectors[8]; }; + SelectorType& q_aux() { return selectors[9]; }; + SelectorType& q_lookup_type() { return selectors[10]; }; SelectorType& q_busread() { return this->selectors[11]; }; - UltraHonk() - : Ultra(NUM_SELECTORS) - {} + const auto& get() const { return selectors; }; + + void reserve(size_t size_hint) + { + for (auto& vec : selectors) { + vec.reserve(size_hint); + } + } + + /** + * @brief Add zeros to all selectors which are not part of the conventional Ultra arithmetization + * @details Facilitates reuse of Ultra gate construction functions in arithmetizations which extend the conventional + * Ultra arithmetization + * + */ + void pad_additional() { q_busread().emplace_back(0); }; + + // Note: Unused. Needed only for consistency with Ultra arith (which is used by Plonk) + inline static const std::vector selector_names = {}; }; class GoblinTranslator { diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp index 1b7c6e6eb15..f4532a31895 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp @@ -77,12 +77,6 @@ template class GoblinUltraCircuitBuilder_ : public UltraCircuitBui void finalize_circuit(); void add_gates_to_ensure_all_polys_are_non_zero(); - /** - * @brief Utility for adding zeros to selectors which are not part of the conventional Ultra arithmetization - * - */ - void pad_additional_selectors() override { q_busread.emplace_back(0); }; - size_t get_num_constant_gates() const override { return 0; } /** diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp index cd4a0188185..da96bd1cf86 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp @@ -79,7 +79,7 @@ void UltraCircuitBuilder_::add_gates_to_ensure_all_polys_are_no q_lookup_type.emplace_back(0); q_elliptic.emplace_back(1); q_aux.emplace_back(1); - pad_additional_selectors(); + selectors.pad_additional(); ++this->num_gates; // Some relations depend on wire shifts so we add another gate with @@ -139,7 +139,7 @@ void UltraCircuitBuilder_::create_add_gate(const add_triple_num_gates; } @@ -171,7 +171,7 @@ void UltraCircuitBuilder_::create_big_add_gate(const add_quad_< q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); q_aux.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); ++this->num_gates; } @@ -265,7 +265,7 @@ void UltraCircuitBuilder_::create_big_mul_gate(const mul_quad_< q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); q_aux.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); ++this->num_gates; } @@ -291,7 +291,7 @@ void UltraCircuitBuilder_::create_balanced_add_gate(const add_q q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); q_aux.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); ++this->num_gates; // Why 3? TODO: return to this // The purpose of this gate is to do enable lazy 32-bit addition. @@ -333,7 +333,7 @@ void UltraCircuitBuilder_::create_mul_gate(const mul_triple_num_gates; } /** @@ -362,7 +362,7 @@ void UltraCircuitBuilder_::create_bool_gate(const uint32_t vari q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); q_aux.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); ++this->num_gates; } @@ -393,7 +393,7 @@ void UltraCircuitBuilder_::create_poly_gate(const poly_triple_< q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); q_aux.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); ++this->num_gates; } @@ -447,7 +447,7 @@ void UltraCircuitBuilder_::create_ecc_add_gate(const ecc_add_ga q_lookup_type.emplace_back(0); q_elliptic.emplace_back(1); q_aux.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); ++this->num_gates; } w_l.emplace_back(in.x2); @@ -465,7 +465,7 @@ void UltraCircuitBuilder_::create_ecc_add_gate(const ecc_add_ga q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); q_aux.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); ++this->num_gates; } @@ -511,7 +511,7 @@ void UltraCircuitBuilder_::create_ecc_dbl_gate(const ecc_dbl_ga q_sort.emplace_back(0); q_lookup_type.emplace_back(0); q_aux.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); ++this->num_gates; } @@ -530,7 +530,7 @@ void UltraCircuitBuilder_::create_ecc_dbl_gate(const ecc_dbl_ga q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); q_aux.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); ++this->num_gates; } @@ -560,7 +560,7 @@ void UltraCircuitBuilder_::fix_witness(const uint32_t witness_i q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); q_aux.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); ++this->num_gates; } @@ -635,7 +635,7 @@ plookup::ReadData UltraCircuitBuilder_::create_gates_ q_sort.emplace_back(0); q_elliptic.emplace_back(0); q_aux.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); ++this->num_gates; } return read_data; @@ -944,7 +944,7 @@ void UltraCircuitBuilder_::create_sort_constraint(const std::ve q_elliptic.emplace_back(0); q_lookup_type.emplace_back(0); q_aux.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); } // dummy gate needed because of sort widget's check of next row w_l.emplace_back(variable_index[variable_index.size() - 1]); @@ -963,7 +963,7 @@ void UltraCircuitBuilder_::create_sort_constraint(const std::ve q_elliptic.emplace_back(0); q_lookup_type.emplace_back(0); q_aux.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); } // useful to put variables in the witness that aren't already used - e.g. the dummy variables of the range constraint in @@ -997,7 +997,7 @@ void UltraCircuitBuilder_::create_dummy_constraints(const std:: q_elliptic.emplace_back(0); q_lookup_type.emplace_back(0); q_aux.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); } } @@ -1028,7 +1028,7 @@ void UltraCircuitBuilder_::create_sort_constraint_with_edges( q_elliptic.emplace_back(0); q_lookup_type.emplace_back(0); q_aux.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); // enforce range check for middle rows for (size_t i = gate_width; i < variable_index.size() - gate_width; i += gate_width) { @@ -1048,7 +1048,7 @@ void UltraCircuitBuilder_::create_sort_constraint_with_edges( q_elliptic.emplace_back(0); q_lookup_type.emplace_back(0); q_aux.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); } // enforce range checks of last row and ending at end if (variable_index.size() > gate_width) { @@ -1068,7 +1068,7 @@ void UltraCircuitBuilder_::create_sort_constraint_with_edges( q_elliptic.emplace_back(0); q_lookup_type.emplace_back(0); q_aux.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); } // dummy gate needed because of sort widget's check of next row @@ -1089,7 +1089,7 @@ void UltraCircuitBuilder_::create_sort_constraint_with_edges( q_elliptic.emplace_back(0); q_lookup_type.emplace_back(0); q_aux.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); } // range constraint a value by decomposing it into limbs whose size should be the default range constraint size @@ -1205,7 +1205,7 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m.emplace_back(0); q_c.emplace_back(0); q_arith.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); break; } case AUX_SELECTORS::LIMB_ACCUMULATE_2: { @@ -1216,7 +1216,7 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m.emplace_back(1); q_c.emplace_back(0); q_arith.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); break; } case AUX_SELECTORS::NON_NATIVE_FIELD_1: { @@ -1227,7 +1227,7 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m.emplace_back(0); q_c.emplace_back(0); q_arith.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); break; } case AUX_SELECTORS::NON_NATIVE_FIELD_2: { @@ -1238,7 +1238,7 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m.emplace_back(0); q_c.emplace_back(0); q_arith.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); break; } case AUX_SELECTORS::NON_NATIVE_FIELD_3: { @@ -1249,7 +1249,7 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m.emplace_back(1); q_c.emplace_back(0); q_arith.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); break; } case AUX_SELECTORS::ROM_CONSISTENCY_CHECK: { @@ -1264,7 +1264,7 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m.emplace_back(0); q_c.emplace_back(0); q_arith.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); break; } case AUX_SELECTORS::RAM_CONSISTENCY_CHECK: { @@ -1280,7 +1280,7 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m.emplace_back(0); q_c.emplace_back(0); q_arith.emplace_back(1); - pad_additional_selectors(); + selectors.pad_additional(); break; } case AUX_SELECTORS::RAM_TIMESTAMP_CHECK: { @@ -1293,7 +1293,7 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m.emplace_back(0); q_c.emplace_back(0); q_arith.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); break; } case AUX_SELECTORS::ROM_READ: { @@ -1307,7 +1307,7 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m.emplace_back(1); // validate record witness is correctly computed q_c.emplace_back(0); // read/write flag stored in q_c q_arith.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); break; } case AUX_SELECTORS::RAM_READ: { @@ -1321,7 +1321,7 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m.emplace_back(1); // validate record witness is correctly computed q_c.emplace_back(0); // read/write flag stored in q_c q_arith.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); break; } case AUX_SELECTORS::RAM_WRITE: { @@ -1335,7 +1335,7 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m.emplace_back(1); // validate record witness is correctly computed q_c.emplace_back(1); // read/write flag stored in q_c q_arith.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); break; } default: { @@ -1346,7 +1346,7 @@ void UltraCircuitBuilder_::apply_aux_selectors(const AUX_SELECT q_m.emplace_back(0); q_c.emplace_back(0); q_arith.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); break; } } @@ -1875,7 +1875,7 @@ std::array UltraCircuitBuilder_::evaluate_non_nati q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); q_aux.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); } this->num_gates += 4; @@ -1997,7 +1997,7 @@ std::array UltraCircuitBuilder_::evaluate_non_nati q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); q_aux.emplace_back(0); - pad_additional_selectors(); + selectors.pad_additional(); } this->num_gates += 4; diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp index 3d36484a288..ae3b25ab436 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp @@ -641,14 +641,6 @@ class UltraCircuitBuilder_ : public CircuitBuilderBase& in) override; void create_big_add_gate(const add_quad_& in, const bool use_next_gate_w_4 = false); From 0f509e31142d178c3af17f2abea265e599ae6c36 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Mon, 6 Nov 2023 11:25:56 +0000 Subject: [PATCH 05/15] define accum directly in relation for now --- .../src/barretenberg/flavor/goblin_ultra.hpp | 64 +++--- .../honk/proof_system/lookup_library.hpp | 2 +- .../relations/databus_lookup_relation.cpp | 31 +++ .../relations/databus_lookup_relation.hpp | 193 ++++++++++++++++++ .../relations/ecc_vm/ecc_lookup_relation.hpp | 14 ++ 5 files changed, 279 insertions(+), 25 deletions(-) create mode 100644 barretenberg/cpp/src/barretenberg/proof_system/relations/databus_lookup_relation.cpp create mode 100644 barretenberg/cpp/src/barretenberg/proof_system/relations/databus_lookup_relation.hpp diff --git a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp index 2f0878a9640..755544c05ba 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp @@ -3,14 +3,16 @@ #include "barretenberg/flavor/flavor.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp" -#include "barretenberg/relations/auxiliary_relation.hpp" -#include "barretenberg/relations/ecc_op_queue_relation.hpp" -#include "barretenberg/relations/elliptic_relation.hpp" -#include "barretenberg/relations/gen_perm_sort_relation.hpp" -#include "barretenberg/relations/lookup_relation.hpp" -#include "barretenberg/relations/permutation_relation.hpp" -#include "barretenberg/relations/ultra_arithmetic_relation.hpp" +#include "barretenberg/proof_system/relations/auxiliary_relation.hpp" +#include "barretenberg/proof_system/relations/databus_lookup_relation.hpp" +#include "barretenberg/proof_system/relations/ecc_op_queue_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 "barretenberg/transcript/transcript.hpp" +#include "relation_definitions_fwd.hpp" namespace proof_system::honk::flavor { @@ -32,13 +34,13 @@ class GoblinUltra { // 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`. // Note: this number does not include the individual sorted list polynomials. - // NUM = 43 (UH) + 4 op wires + 1 op wire "selector" + 3 (calldata + calldata_read_counts + q_busread) - static constexpr size_t NUM_ALL_ENTITIES = 51; + // NUM = 43 (UH) + 4 op wires + 1 op wire "selector" + 3+1 (bus) + static constexpr size_t NUM_ALL_ENTITIES = 52; // 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 = 27; // 25 (UH) + 1 op wire "selector" + q_busread // The total number of witness entities not including shifts. - static constexpr size_t NUM_WITNESS_ENTITIES = 17; // 11 (UH) + 4 op wires + (calldata + calldata_read_counts) + static constexpr size_t NUM_WITNESS_ENTITIES = 18; // 11 (UH) + 4 op wires + 3 (bus) using GrandProductRelations = std::tuple, proof_system::LookupRelation>; @@ -50,8 +52,10 @@ class GoblinUltra { proof_system::GenPermSortRelation, proof_system::EllipticRelation, proof_system::AuxiliaryRelation, - proof_system::EccOpQueueRelation>; - // WORKTODO: add bus lookup relation! + proof_system::EccOpQueueRelation, + proof_system::DatabusLookupRelation>; + + using LookupRelation = proof_system::DatabusLookupRelation; static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length(); static constexpr size_t MAX_TOTAL_RELATION_LENGTH = compute_max_total_relation_length(); @@ -144,6 +148,7 @@ class GoblinUltra { DataType& ecc_op_wire_4 = std::get<14>(this->_data); DataType& calldata = std::get<15>(this->_data); DataType& calldata_read_counts = std::get<16>(this->_data); + DataType& lookup_inverses = std::get<17>(this->_data); std::vector get_wires() override { return { w_l, w_r, w_o, w_4 }; }; std::vector get_ecc_op_wires() @@ -206,17 +211,18 @@ class GoblinUltra { DataType& ecc_op_wire_4 = std::get<37>(this->_data); DataType& calldata = std::get<38>(this->_data); DataType& calldata_read_counts = std::get<39>(this->_data); - DataType& table_1_shift = std::get<40>(this->_data); - DataType& table_2_shift = std::get<41>(this->_data); - DataType& table_3_shift = std::get<42>(this->_data); - DataType& table_4_shift = std::get<43>(this->_data); - DataType& w_l_shift = std::get<44>(this->_data); - DataType& w_r_shift = std::get<45>(this->_data); - DataType& w_o_shift = std::get<46>(this->_data); - DataType& w_4_shift = std::get<47>(this->_data); - DataType& sorted_accum_shift = std::get<48>(this->_data); - DataType& z_perm_shift = std::get<49>(this->_data); - DataType& z_lookup_shift = std::get<50>(this->_data); + DataType& lookup_inverses = std::get<40>(this->_data); + DataType& table_1_shift = std::get<41>(this->_data); + DataType& table_2_shift = std::get<42>(this->_data); + DataType& table_3_shift = std::get<43>(this->_data); + DataType& table_4_shift = std::get<44>(this->_data); + DataType& w_l_shift = std::get<45>(this->_data); + DataType& w_r_shift = std::get<46>(this->_data); + DataType& w_o_shift = std::get<47>(this->_data); + DataType& w_4_shift = std::get<48>(this->_data); + DataType& sorted_accum_shift = std::get<49>(this->_data); + DataType& z_perm_shift = std::get<50>(this->_data); + DataType& z_lookup_shift = std::get<51>(this->_data); std::vector get_wires() override { return { w_l, w_r, w_o, w_4 }; }; std::vector get_ecc_op_wires() @@ -265,7 +271,8 @@ class GoblinUltra { ecc_op_wire_3, ecc_op_wire_4, calldata, - calldata_read_counts }; + calldata_read_counts, + lookup_inverses }; }; std::vector get_to_be_shifted() override { @@ -415,6 +422,7 @@ class GoblinUltra { ecc_op_wire_4 = "ECC_OP_WIRE_4"; calldata = "CALLDATA"; calldata_read_counts = "CALLDATA_READ_COUNTS"; + lookup_inverses = "LOOKUP_INVERSES"; // The ones beginning with "__" are only used for debugging q_c = "__Q_C"; @@ -508,6 +516,7 @@ class GoblinUltra { Commitment ecc_op_wire_4_comm; Commitment calldata_comm; Commitment calldata_read_counts_comm; + Commitment lookup_inverses_comm; Commitment sorted_accum_comm; Commitment w_4_comm; Commitment z_perm_comm; @@ -523,6 +532,7 @@ class GoblinUltra { Transcript(const std::vector& proof) : BaseTranscript(proof) {} + // WORKTODO: add lookup inverses once its being computed void deserialize_full_transcript() override { // take current proof and put them into the struct @@ -602,3 +612,9 @@ class GoblinUltra { }; } // namespace proof_system::honk::flavor + +namespace proof_system { +// extern template class DatabusLookupRelationImpl; + +// DECLARE_SUMCHECK_RELATION_CLASS(DatabusLookupRelationImpl, honk::flavor::GoblinUltra); +} // namespace proof_system diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/lookup_library.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/lookup_library.hpp index b8770040beb..d009d8cc586 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/lookup_library.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/lookup_library.hpp @@ -150,7 +150,7 @@ void accumulate_logderivative_lookup_subrelation_contributions(ContainerOverSubr // degree of relation = NUM_TOTAL_TERMS + 2 barretenberg::constexpr_for<0, WRITE_TERMS, 1>([&]() { const auto p = lookup_relation.template compute_write_term_predicate(in); - const auto lookup_read_count = View(in.template lookup_read_counts()); + const auto lookup_read_count = lookup_relation.template lookup_read_counts(in); std::get<1>(accumulator) -= p * (denominator_accumulator[i + READ_TERMS] * lookup_read_count); }); } diff --git a/barretenberg/cpp/src/barretenberg/proof_system/relations/databus_lookup_relation.cpp b/barretenberg/cpp/src/barretenberg/proof_system/relations/databus_lookup_relation.cpp new file mode 100644 index 00000000000..aca1b0689e6 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/proof_system/relations/databus_lookup_relation.cpp @@ -0,0 +1,31 @@ +// #include "databus_lookup_relation.hpp" +// #include "barretenberg/flavor/relation_definitions_fwd.hpp" +// #include "barretenberg/honk/proof_system/lookup_library.hpp" + +// namespace proof_system { + +// /** +// * @brief +// * @details +// * +// * @param evals transformed to `evals + C(in(X)...)*scaling_factor` +// * @param in an std::array containing the fully extended Accumulator edges. +// * @param parameters contains beta, gamma, and public_input_delta, .... +// * @param scaling_factor optional term to scale the evaluation before adding to evals. +// */ +// template +// template +// void DatabusLookupRelationImpl::accumulate(ContainerOverSubrelations& accumulator, +// const AllEntities& in, +// const Parameters& params, +// [[maybe_unused]] const FF& scaling_factor) +// { +// honk::lookup_library::accumulate_logderivative_lookup_subrelation_contributions>( +// accumulator, in, params, scaling_factor); +// } + +// template class DatabusLookupRelationImpl; +// DEFINE_SUMCHECK_RELATION_CLASS(DatabusLookupRelationImpl, honk::flavor::GoblinUltra); + +// } // namespace proof_system diff --git a/barretenberg/cpp/src/barretenberg/proof_system/relations/databus_lookup_relation.hpp b/barretenberg/cpp/src/barretenberg/proof_system/relations/databus_lookup_relation.hpp new file mode 100644 index 00000000000..9f0816a0d58 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/proof_system/relations/databus_lookup_relation.hpp @@ -0,0 +1,193 @@ +#pragma once +#include +#include + +#include "barretenberg/common/constexpr_utils.hpp" +#include "barretenberg/polynomials/polynomial.hpp" +#include "barretenberg/polynomials/univariate.hpp" +#include "barretenberg/proof_system/relations/relation_types.hpp" + +namespace proof_system { + +template class DatabusLookupRelationImpl { + public: + using FF = FF_; + static constexpr size_t READ_TERMS = 1; + static constexpr size_t WRITE_TERMS = 1; + // 1 + polynomial degree of this relation + // WORKTODO + static constexpr size_t LENGTH = READ_TERMS + WRITE_TERMS + 3; + + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ + LENGTH, // inverse polynomial correctness subrelation + LENGTH // log-derivative lookup argument subrelation + }; + + // The second subrelation is "linearly dependant" in the sense that it establishes the value of a sum across the + // entire execution trace rather than a per-row identity. + static constexpr std::array SUBRELATION_LINEARLY_INDEPENDENT = { true, false }; + + template static bool lookup_exists_at_row(const AllValues& row) + { + return (row.q_busread == 1); + } + + template + static Accumulator compute_inverse_exists(const AllEntities& in) + { + using View = typename Accumulator::View; + // return View(in.q_busread); + return Accumulator(View(in.q_busread)); + } + + template + static Accumulator lookup_read_counts(const AllEntities& in) + { + using View = typename Accumulator::View; + + if constexpr (index == 0) { + return Accumulator(View(in.calldata_read_counts)); + } + return Accumulator(1); + } + + template + static Accumulator compute_read_term_predicate([[maybe_unused]] const AllEntities& /*unused*/) + + { + return Accumulator(1); + } + + template + static Accumulator compute_write_term_predicate(const AllEntities& in) + { + using View = typename Accumulator::View; + + if constexpr (write_index == 0) { + return Accumulator(View(in.q_busread)); + } + return Accumulator(1); + } + + template + static Accumulator compute_write_term(const AllEntities& in, const Parameters& params) + { + using View = typename Accumulator::View; + using ParameterView = GetParameterView; + + static_assert(write_index < WRITE_TERMS); + + const auto& calldata = View(in.calldata); + const auto& id_1 = View(in.id_1); + + const auto& gamma = ParameterView(params.gamma); + const auto& beta = ParameterView(params.beta); + + // Construct b_i + idx_i*\beta + \gamma + if constexpr (write_index == 0) { + return calldata + id_1 * beta + gamma; // degree 1 + } + + return Accumulator(1); + } + + template + static Accumulator compute_read_term(const AllEntities& in, const Parameters& params) + { + using View = typename Accumulator::View; + using ParameterView = GetParameterView; + + static_assert(read_index < READ_TERMS); + + // Bus value stored in w_1, index into bus column stored in w_2 + const auto& value = View(in.w_l); + const auto& index = View(in.w_r); + + const auto& gamma = ParameterView(params.gamma); + const auto& beta = ParameterView(params.beta); + + const auto read_term1 = value + gamma + index * beta; // degree 1 + + // Construct value + index*\beta + \gamma + if constexpr (read_index == 0) { + return read_term1; + } + + return Accumulator(1); + } + + /** + * @brief + * @details + * @param accumulator transformed to `evals + C(in(X)...)*scaling_factor` + * @param in an std::array containing the fully extended Accumulator edges. + * @param params contains beta, gamma, and public_input_delta, .... + * @param scaling_factor optional term to scale the evaluation before adding to evals. + */ + template + static void accumulate(ContainerOverSubrelations& accumulator, + const AllEntities& in, + const Parameters& params, + const FF& scaling_factor) + { + + using Accumulator = typename std::tuple_element_t<0, ContainerOverSubrelations>; + using View = typename Accumulator::View; + + auto lookup_inverses = View(in.lookup_inverses); + + constexpr size_t NUM_TOTAL_TERMS = READ_TERMS + WRITE_TERMS; + std::array lookup_terms; + std::array denominator_accumulator; + + // The lookup relation = \sum_j (1 / read_term[j]) - \sum_k (read_counts[k] / write_term[k]) + // To get the inverses (1 / read_term[i]), (1 / write_term[i]), we have a commitment to the product of all + // inverses i.e. lookup_inverse = \prod_j (1 / read_term[j]) * \prod_k (1 / write_term[k]) The purpose of this + // next section is to derive individual inverse terms using `lookup_inverses` i.e. (1 / read_term[i]) = + // lookup_inverse * \prod_{j /ne i} (read_term[j]) * \prod_k (write_term[k]) + // (1 / write_term[i]) = lookup_inverse * \prod_j (read_term[j]) * \prod_{k ne i} (write_term[k]) + barretenberg::constexpr_for<0, READ_TERMS, 1>( + [&]() { lookup_terms[i] = compute_read_term(in, params); }); + barretenberg::constexpr_for<0, WRITE_TERMS, 1>( + [&]() { lookup_terms[i + READ_TERMS] = compute_write_term(in, params); }); + + barretenberg::constexpr_for<0, NUM_TOTAL_TERMS, 1>( + [&]() { denominator_accumulator[i] = lookup_terms[i]; }); + + barretenberg::constexpr_for<0, NUM_TOTAL_TERMS - 1, 1>( + [&]() { denominator_accumulator[i + 1] *= denominator_accumulator[i]; }); + + auto inverse_accumulator = Accumulator(lookup_inverses); // denominator_accumulator[NUM_TOTAL_TERMS - 1]; + + const auto inverse_exists = compute_inverse_exists(in); + + std::get<0>(accumulator) += + (denominator_accumulator[NUM_TOTAL_TERMS - 1] * lookup_inverses - inverse_exists) * scaling_factor; + + // After this algo, total degree of denominator_accumulator = NUM_TOTAL_TERMS + for (size_t i = 0; i < NUM_TOTAL_TERMS - 1; ++i) { + denominator_accumulator[NUM_TOTAL_TERMS - 1 - i] = + denominator_accumulator[NUM_TOTAL_TERMS - 2 - i] * inverse_accumulator; + inverse_accumulator = inverse_accumulator * lookup_terms[NUM_TOTAL_TERMS - 1 - i]; + } + denominator_accumulator[0] = inverse_accumulator; + + // each predicate is degree-1 + // degree of relation at this point = NUM_TOTAL_TERMS + 1 + barretenberg::constexpr_for<0, READ_TERMS, 1>([&]() { + std::get<1>(accumulator) += compute_read_term_predicate(in) * denominator_accumulator[i]; + }); + + // each predicate is degree-1, `lookup_read_counts` is degree-1 + // degree of relation = NUM_TOTAL_TERMS + 2 + barretenberg::constexpr_for<0, WRITE_TERMS, 1>([&]() { + const auto p = compute_write_term_predicate(in); + const auto lookup_read_count = lookup_read_counts(in); + std::get<1>(accumulator) -= p * (denominator_accumulator[i + READ_TERMS] * lookup_read_count); + }); + } +}; + +template using DatabusLookupRelation = Relation>; + +} // namespace proof_system diff --git a/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_lookup_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_lookup_relation.hpp index 1b5884db7a3..485891e44e6 100644 --- a/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_lookup_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_lookup_relation.hpp @@ -40,6 +40,20 @@ template class ECCVMLookupRelationBase { return row_has_write + row_has_read - (row_has_write * row_has_read); } + template + static Accumulator lookup_read_counts(const AllEntities& in) + { + using View = typename Accumulator::View; + + if constexpr (index == 0) { + return Accumulator(View(in.lookup_read_counts_0)); + } + if constexpr (index == 1) { + return Accumulator(View(in.lookup_read_counts_1)); + } + return Accumulator(1); + } + template static Accumulator compute_read_term_predicate(const AllEntities& in) From 24cf9cf4875e301c51e3f6367d9af28fd91af437 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Tue, 7 Nov 2023 16:47:11 +0000 Subject: [PATCH 06/15] databus log deriv relation passing correctness --- .../src/barretenberg/flavor/goblin_ultra.hpp | 65 +++++++++-------- .../goblin_ultra_circuit_builder.cpp | 27 ++++--- .../relations/databus_lookup_relation.hpp | 39 +++++----- .../sumcheck/instance/prover_instance.cpp | 34 ++++++++- .../sumcheck/instance/prover_instance.hpp | 2 + .../goblin_ultra_transcript.test.cpp | 5 +- .../ultra_honk/relation_correctness.test.cpp | 71 +++++++++++++++++++ .../barretenberg/ultra_honk/ultra_prover.cpp | 23 +++++- .../barretenberg/ultra_honk/ultra_prover.hpp | 3 + .../ultra_honk/ultra_verifier.cpp | 6 ++ 10 files changed, 214 insertions(+), 61 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp index 755544c05ba..6f6d4682b91 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp @@ -34,11 +34,11 @@ class GoblinUltra { // 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`. // Note: this number does not include the individual sorted list polynomials. - // NUM = 43 (UH) + 4 op wires + 1 op wire "selector" + 3+1 (bus) - static constexpr size_t NUM_ALL_ENTITIES = 52; + // NUM = 43 (UH) + 4 op wires + 1 op wire "selector" + 3+1+1 (bus) + static constexpr size_t NUM_ALL_ENTITIES = 53; // 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 = 27; // 25 (UH) + 1 op wire "selector" + q_busread + static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 28; // 25 (UH) + 1 op wire "selector" + q_busread + databus_id // The total number of witness entities not including shifts. static constexpr size_t NUM_WITNESS_ENTITIES = 18; // 11 (UH) + 4 op wires + 3 (bus) @@ -55,7 +55,7 @@ class GoblinUltra { proof_system::EccOpQueueRelation, proof_system::DatabusLookupRelation>; - using LookupRelation = proof_system::DatabusLookupRelation; + using LogDerivLookupRelation = proof_system::DatabusLookupRelation; static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length(); static constexpr size_t MAX_TOTAL_RELATION_LENGTH = compute_max_total_relation_length(); @@ -111,7 +111,7 @@ class GoblinUltra { DataType& lagrange_first = std::get<24>(this->_data); DataType& lagrange_last = std::get<25>(this->_data); DataType& lagrange_ecc_op = std::get<26>(this->_data); // indicator poly for ecc op gates - + DataType& databus_id = std::get<27>(this->_data); // id polynomial, i.e. id_i = i static constexpr CircuitType CIRCUIT_TYPE = CircuitBuilder::CIRCUIT_TYPE; std::vector get_selectors() override @@ -198,31 +198,32 @@ class GoblinUltra { DataType& lagrange_first = std::get<24>(this->_data); DataType& lagrange_last = std::get<25>(this->_data); DataType& lagrange_ecc_op = std::get<26>(this->_data); - DataType& w_l = std::get<27>(this->_data); - DataType& w_r = std::get<28>(this->_data); - DataType& w_o = std::get<29>(this->_data); - DataType& w_4 = std::get<30>(this->_data); - DataType& sorted_accum = std::get<31>(this->_data); - DataType& z_perm = std::get<32>(this->_data); - DataType& z_lookup = std::get<33>(this->_data); - DataType& ecc_op_wire_1 = std::get<34>(this->_data); - DataType& ecc_op_wire_2 = std::get<35>(this->_data); - DataType& ecc_op_wire_3 = std::get<36>(this->_data); - DataType& ecc_op_wire_4 = std::get<37>(this->_data); - DataType& calldata = std::get<38>(this->_data); - DataType& calldata_read_counts = std::get<39>(this->_data); - DataType& lookup_inverses = std::get<40>(this->_data); - DataType& table_1_shift = std::get<41>(this->_data); - DataType& table_2_shift = std::get<42>(this->_data); - DataType& table_3_shift = std::get<43>(this->_data); - DataType& table_4_shift = std::get<44>(this->_data); - DataType& w_l_shift = std::get<45>(this->_data); - DataType& w_r_shift = std::get<46>(this->_data); - DataType& w_o_shift = std::get<47>(this->_data); - DataType& w_4_shift = std::get<48>(this->_data); - DataType& sorted_accum_shift = std::get<49>(this->_data); - DataType& z_perm_shift = std::get<50>(this->_data); - DataType& z_lookup_shift = std::get<51>(this->_data); + DataType& databus_id = std::get<27>(this->_data); + DataType& w_l = std::get<28>(this->_data); + DataType& w_r = std::get<29>(this->_data); + DataType& w_o = std::get<30>(this->_data); + DataType& w_4 = std::get<31>(this->_data); + DataType& sorted_accum = std::get<32>(this->_data); + DataType& z_perm = std::get<33>(this->_data); + DataType& z_lookup = std::get<34>(this->_data); + DataType& ecc_op_wire_1 = std::get<35>(this->_data); + DataType& ecc_op_wire_2 = std::get<36>(this->_data); + DataType& ecc_op_wire_3 = std::get<37>(this->_data); + DataType& ecc_op_wire_4 = std::get<38>(this->_data); + DataType& calldata = std::get<39>(this->_data); + DataType& calldata_read_counts = std::get<40>(this->_data); + DataType& lookup_inverses = std::get<41>(this->_data); + DataType& table_1_shift = std::get<42>(this->_data); + DataType& table_2_shift = std::get<43>(this->_data); + DataType& table_3_shift = std::get<44>(this->_data); + DataType& table_4_shift = std::get<45>(this->_data); + DataType& w_l_shift = std::get<46>(this->_data); + DataType& w_r_shift = std::get<47>(this->_data); + DataType& w_o_shift = std::get<48>(this->_data); + DataType& w_4_shift = std::get<49>(this->_data); + DataType& sorted_accum_shift = std::get<50>(this->_data); + DataType& z_perm_shift = std::get<51>(this->_data); + DataType& z_lookup_shift = std::get<52>(this->_data); std::vector get_wires() override { return { w_l, w_r, w_o, w_4 }; }; std::vector get_ecc_op_wires() @@ -259,6 +260,7 @@ class GoblinUltra { lagrange_first, lagrange_last, lagrange_ecc_op, + databus_id, w_l, w_r, w_o, @@ -488,6 +490,7 @@ class GoblinUltra { lagrange_first = verification_key->lagrange_first; lagrange_last = verification_key->lagrange_last; lagrange_ecc_op = verification_key->lagrange_ecc_op; + databus_id = verification_key->databus_id; } }; @@ -554,6 +557,7 @@ class GoblinUltra { ecc_op_wire_4_comm = deserialize_from_buffer(proof_data, num_bytes_read); calldata_comm = deserialize_from_buffer(proof_data, num_bytes_read); calldata_read_counts_comm = deserialize_from_buffer(proof_data, num_bytes_read); + lookup_inverses_comm = deserialize_from_buffer(proof_data, num_bytes_read); sorted_accum_comm = deserialize_from_buffer(proof_data, num_bytes_read); w_4_comm = deserialize_from_buffer(proof_data, num_bytes_read); z_perm_comm = deserialize_from_buffer(proof_data, num_bytes_read); @@ -592,6 +596,7 @@ class GoblinUltra { serialize_to_buffer(ecc_op_wire_4_comm, proof_data); serialize_to_buffer(calldata_comm, proof_data); serialize_to_buffer(calldata_read_counts_comm, proof_data); + serialize_to_buffer(lookup_inverses_comm, proof_data); serialize_to_buffer(sorted_accum_comm, proof_data); serialize_to_buffer(w_4_comm, proof_data); serialize_to_buffer(z_perm_comm, proof_data); diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.cpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.cpp index 131876d4b21..7b94f0f27dc 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.cpp @@ -24,9 +24,24 @@ template void GoblinUltraCircuitBuilder_::add_gates_to_ensure_ { UltraCircuitBuilder_>::add_gates_to_ensure_all_polys_are_non_zero(); - // Additional gate to add a nonzero value to q_busread - this->w_l.emplace_back(this->zero_idx); - this->w_r.emplace_back(this->zero_idx); + // Populate the calldata with some data + public_calldata.emplace_back(this->add_variable(FF(5))); + public_calldata.emplace_back(this->add_variable(FF(7))); + public_calldata.emplace_back(this->add_variable(FF(9))); + + // Construct read counts with length of calldata + calldata_read_counts.resize(public_calldata.size()); + for (auto& val : calldata_read_counts) { + val = 0; + } + + // Construct gate corresponding to a single calldata read + this->w_l.emplace_back(public_calldata[1]); // index for 7 in variables + this->w_r.emplace_back(this->add_variable(FF(1))); // idx 1 into calldata + calldata_read_counts[1]++; // increment read count at index 1 + q_busread.emplace_back(1); // read selector on + + // populate all other components with zero this->w_o.emplace_back(this->zero_idx); this->w_4.emplace_back(this->zero_idx); this->q_m.emplace_back(0); @@ -41,13 +56,7 @@ template void GoblinUltraCircuitBuilder_::add_gates_to_ensure_ this->q_lookup_type.emplace_back(0); this->q_elliptic.emplace_back(0); this->q_aux.emplace_back(0); - q_busread.emplace_back(1); ++this->num_gates; - - // Add some nonzero values to the calldata and corresponding read counts - // WORKTODO: will need to do this more carefully once we actually have a databus lookup relation - public_calldata.emplace_back(this->one_idx); - calldata_read_counts.emplace_back(this->one_idx); } /** diff --git a/barretenberg/cpp/src/barretenberg/proof_system/relations/databus_lookup_relation.hpp b/barretenberg/cpp/src/barretenberg/proof_system/relations/databus_lookup_relation.hpp index 9f0816a0d58..c9667549499 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/relations/databus_lookup_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/relations/databus_lookup_relation.hpp @@ -29,15 +29,16 @@ template class DatabusLookupRelationImpl { template static bool lookup_exists_at_row(const AllValues& row) { - return (row.q_busread == 1); + return (row.q_busread == 1 || row.calldata_read_counts > 0); } template static Accumulator compute_inverse_exists(const AllEntities& in) { using View = typename Accumulator::View; - // return View(in.q_busread); - return Accumulator(View(in.q_busread)); + // WORKTODO: really what we need instead of calldata_read_counts is a boolean equivalent that says > 0 counts or + // not.. or possibly just "is this a row in the calldata" + return Accumulator(View(in.q_busread) + View(in.calldata_read_counts)); } template @@ -52,20 +53,20 @@ template class DatabusLookupRelationImpl { } template - static Accumulator compute_read_term_predicate([[maybe_unused]] const AllEntities& /*unused*/) + static Accumulator compute_read_term_predicate([[maybe_unused]] const AllEntities& in) { + using View = typename Accumulator::View; + + if constexpr (read_index == 0) { + return Accumulator(View(in.q_busread)); + } return Accumulator(1); } template - static Accumulator compute_write_term_predicate(const AllEntities& in) + static Accumulator compute_write_term_predicate(const AllEntities& /*unused*/) { - using View = typename Accumulator::View; - - if constexpr (write_index == 0) { - return Accumulator(View(in.q_busread)); - } return Accumulator(1); } @@ -78,14 +79,14 @@ template class DatabusLookupRelationImpl { static_assert(write_index < WRITE_TERMS); const auto& calldata = View(in.calldata); - const auto& id_1 = View(in.id_1); + const auto& id = View(in.databus_id); const auto& gamma = ParameterView(params.gamma); const auto& beta = ParameterView(params.beta); // Construct b_i + idx_i*\beta + \gamma if constexpr (write_index == 0) { - return calldata + id_1 * beta + gamma; // degree 1 + return calldata + gamma + id * beta; // degree 1 } return Accumulator(1); @@ -100,17 +101,17 @@ template class DatabusLookupRelationImpl { static_assert(read_index < READ_TERMS); // Bus value stored in w_1, index into bus column stored in w_2 - const auto& value = View(in.w_l); - const auto& index = View(in.w_r); + const auto& w_1 = View(in.w_l); + const auto& w_2 = View(in.w_r); const auto& gamma = ParameterView(params.gamma); const auto& beta = ParameterView(params.beta); - const auto read_term1 = value + gamma + index * beta; // degree 1 + // const auto read_term1 = w_1 + gamma + w_2 * beta; // degree 1 // Construct value + index*\beta + \gamma if constexpr (read_index == 0) { - return read_term1; + return w_1 + gamma + w_2 * beta; } return Accumulator(1); @@ -172,6 +173,12 @@ template class DatabusLookupRelationImpl { } denominator_accumulator[0] = inverse_accumulator; + // auto read_result = denominator_accumulator[0] * compute_read_term(in, params); + // info(read_result); + // auto write_result = denominator_accumulator[1] * compute_write_term(in, params); + // info(write_result); + // info(denominator_accumulator[1]); + // each predicate is degree-1 // degree of relation at this point = NUM_TOTAL_TERMS + 1 barretenberg::constexpr_for<0, READ_TERMS, 1>([&]() { diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp index 4e4955535bb..7213592e02b 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp @@ -1,4 +1,5 @@ #include "prover_instance.hpp" +#include "barretenberg/honk/proof_system/lookup_library.hpp" #include "barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp" #include "barretenberg/proof_system/composer/permutation_lib.hpp" #include "barretenberg/proof_system/library/grand_product_delta.hpp" @@ -198,10 +199,10 @@ template void ProverInstance_::construct_databus_polynomi polynomial public_calldata(dyadic_circuit_size); polynomial calldata_read_counts(dyadic_circuit_size); - const size_t offset = Flavor::has_zero_row ? 1 : 0; + // We do not utilize a zero row for databus columns for (size_t idx = 0; idx < circuit.public_calldata.size(); ++idx) { - public_calldata[idx + offset] = circuit.get_variable(circuit.public_calldata[idx]); - calldata_read_counts[idx + offset] = circuit.get_variable(circuit.calldata_read_counts[idx]); + public_calldata[idx] = circuit.get_variable(circuit.public_calldata[idx]); + calldata_read_counts[idx] = circuit.get_variable(circuit.calldata_read_counts[idx]); } proving_key->calldata = public_calldata; @@ -275,6 +276,12 @@ std::shared_ptr ProverInstance_::compute_pr if constexpr (IsGoblinFlavor) { proving_key->num_ecc_op_gates = num_ecc_op_gates; + // Construct simple ID polynomial for databus indexing + typename Flavor::Polynomial databus_id(proving_key->circuit_size); + for (size_t i = 0; i < databus_id.size(); ++i) { + databus_id[i] = i; + } + proving_key->databus_id = databus_id; } return proving_key; @@ -328,9 +335,18 @@ template void ProverInstance_::initialise_prover_polynomi // DataBus polynomials prover_polynomials.calldata = proving_key->calldata; prover_polynomials.calldata_read_counts = proving_key->calldata_read_counts; + prover_polynomials.lookup_inverses = proving_key->lookup_inverses; prover_polynomials.q_busread = proving_key->q_busread; + prover_polynomials.databus_id = proving_key->databus_id; } + // These polynomials have not yet been computed; initialize them so prover_polynomials is "full" and we can use + // utilities like get_row() + prover_polynomials.z_perm = proving_key->z_perm; + prover_polynomials.z_lookup = proving_key->z_lookup; + prover_polynomials.z_perm_shift = proving_key->z_perm.shifted(); + prover_polynomials.z_lookup_shift = proving_key->z_lookup.shifted(); + std::span public_wires_source = prover_polynomials.w_r; // Determine public input offsets in the circuit relative to the 0th index for Ultra flavors @@ -430,6 +446,18 @@ template void ProverInstance_::add_plookup_memory_records } } +template void ProverInstance_::compute_logderivative_inverse(FF beta, FF gamma) +{ + if constexpr (IsGoblinFlavor) { + relation_parameters.beta = beta; + relation_parameters.gamma = gamma; + + // Compute permutation and lookup grand product polynomials + lookup_library::compute_logderivative_inverse( + prover_polynomials, relation_parameters, proving_key->circuit_size); + } +} + template void ProverInstance_::compute_grand_product_polynomials(FF beta, FF gamma) { auto public_input_delta = diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp index c7a6808fd2e..1af886caa54 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp @@ -71,6 +71,8 @@ template class ProverInstance_ { void compute_sorted_list_accumulator(FF); + void compute_logderivative_inverse(FF, FF); + void compute_grand_product_polynomials(FF, FF); private: diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_transcript.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_transcript.test.cpp index 611110de27d..27837ac6466 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_transcript.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_transcript.test.cpp @@ -10,7 +10,7 @@ using namespace proof_system::honk; class GoblinUltraTranscriptTests : public ::testing::Test { public: - // static void SetUpTestSuite() { barretenberg::srs::init_crs_factory("../srs_db/ignition"); } + static void SetUpTestSuite() { barretenberg::srs::init_crs_factory("../srs_db/ignition"); } using Flavor = proof_system::honk::flavor::GoblinUltra; using FF = Flavor::FF; @@ -61,6 +61,7 @@ class GoblinUltraTranscriptTests : public ::testing::Test { manifest_expected.add_challenge(round, "beta", "gamma"); round++; + manifest_expected.add_entry(round, "LOOKUP_INVERSES", size_G); manifest_expected.add_entry(round, "Z_PERM", size_G); manifest_expected.add_entry(round, "Z_LOOKUP", size_G); manifest_expected.add_challenge(round, "Sumcheck:alpha", "Sumcheck:zeta"); @@ -171,6 +172,8 @@ TEST_F(GoblinUltraTranscriptTests, VerifierManifestConsistency) auto prover_manifest = prover.transcript.get_manifest(); auto verifier_manifest = verifier.transcript.get_manifest(); + prover_manifest.print(); + verifier_manifest.print(); // 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]) diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp index a40555af5b4..39ad1809550 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp @@ -59,6 +59,43 @@ template void check_relation(auto circuit_s } } +/** + * @brief Check that a given linearly dependent relation is satisfied for a set of polynomials + * + * @tparam relation_idx Index into a tuple of provided relations + * @tparam Flavor + */ +template +void check_linearly_dependent_relation(auto circuit_size, auto polynomials, auto params) +{ + using AllValues = typename Flavor::AllValues; + // Define the appropriate SumcheckArrayOfValuesOverSubrelations type for this relation and initialize to zero + using SumcheckArrayOfValuesOverSubrelations = typename Relation::SumcheckArrayOfValuesOverSubrelations; + SumcheckArrayOfValuesOverSubrelations result; + for (auto& element : result) { + element = 0; + } + + for (size_t i = 0; i < circuit_size; i++) { + + // Extract an array containing all the polynomial evaluations at a given row i + AllValues evaluations_at_index_i; + size_t poly_idx = 0; + for (auto& poly : polynomials) { + evaluations_at_index_i[poly_idx] = poly[i]; + ++poly_idx; + } + + // Evaluate each constraint in the relation and check that each is satisfied + Relation::accumulate(result, evaluations_at_index_i, params, 1); + } + + // Result accumulated across entire execution trace should be zero + for (auto& element : result) { + ASSERT_EQ(element, 0); + } +} + template void create_some_add_gates(auto& circuit_builder) { using FF = typename Flavor::FF; @@ -297,6 +334,7 @@ TEST_F(RelationCorrectnessTests, GoblinUltraRelationCorrectness) instance->initialise_prover_polynomials(); instance->compute_sorted_accumulator_polynomials(eta); + instance->compute_logderivative_inverse(beta, gamma); instance->compute_grand_product_polynomials(beta, gamma); // Check that selectors are nonzero to ensure corresponding relation has nontrivial contribution @@ -305,12 +343,43 @@ TEST_F(RelationCorrectnessTests, GoblinUltraRelationCorrectness) ensure_non_zero(proving_key->q_lookup); ensure_non_zero(proving_key->q_elliptic); ensure_non_zero(proving_key->q_aux); + ensure_non_zero(proving_key->q_busread); + + ensure_non_zero(proving_key->calldata); + ensure_non_zero(proving_key->calldata_read_counts); + ensure_non_zero(proving_key->lookup_inverses); // Construct the round for applying sumcheck relations and results for storing computed results using Relations = typename Flavor::Relations; auto prover_polynomials = instance->prover_polynomials; auto params = instance->relation_parameters; + // size_t idx = 0; + // for (auto& coeff : prover_polynomials.calldata_read_counts) { + // if (!coeff.is_zero()) { + // info("idx = ", idx); + // info("counts = ", coeff); + // info("calldata = ", prover_polynomials.calldata[idx]); + // info("id = ", prover_polynomials.databus_id[idx]); + // } + // idx++; + // } + + // idx = 0; + // for (auto& coeff : prover_polynomials.q_busread) { + // if (!coeff.is_zero()) { + // info("idx = ", idx); + // info("q_busread = ", coeff); + // info("w_1 = ", prover_polynomials.w_l[idx]); + // info("w_2 = ", prover_polynomials.w_r[idx]); + // } + // idx++; + // } + + // for (size_t i = 0; i < 5; ++i) { + // info("id_1_i = ", prover_polynomials.databus_id[i]); + // } + // Check that each relation is satisfied across each row of the prover polynomials check_relation>(circuit_size, prover_polynomials, params); check_relation>(circuit_size, prover_polynomials, params); @@ -319,6 +388,8 @@ TEST_F(RelationCorrectnessTests, GoblinUltraRelationCorrectness) check_relation>(circuit_size, prover_polynomials, params); check_relation>(circuit_size, prover_polynomials, params); check_relation>(circuit_size, prover_polynomials, params); + check_linearly_dependent_relation>( + circuit_size, prover_polynomials, params); } /** diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp index d7fe84acf87..86c799a98d3 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp @@ -90,12 +90,29 @@ template void UltraProver_::execute_sorted_list_acc * @brief Compute permutation and lookup grand product polynomials and their commitments * */ -template void UltraProver_::execute_grand_product_computation_round() +template void UltraProver_::execute_log_derivative_inverse_round() { // Compute and store parameters required by relations in Sumcheck auto [beta, gamma] = transcript.get_challenges("beta", "gamma"); + relation_parameters.beta = beta; + relation_parameters.gamma = gamma; + + if constexpr (IsGoblinFlavor) { + instance->compute_logderivative_inverse(beta, gamma); + + auto lookup_inverses_commitment = commitment_key->commit(instance->proving_key->lookup_inverses); + transcript.send_to_verifier(commitment_labels.lookup_inverses, lookup_inverses_commitment); + } +} + +/** + * @brief Compute permutation and lookup grand product polynomials and their commitments + * + */ +template void UltraProver_::execute_grand_product_computation_round() +{ - instance->compute_grand_product_polynomials(beta, gamma); + instance->compute_grand_product_polynomials(relation_parameters.beta, relation_parameters.gamma); auto z_perm_commitment = commitment_key->commit(instance->proving_key->z_perm); auto z_lookup_commitment = commitment_key->commit(instance->proving_key->z_lookup); @@ -149,6 +166,8 @@ template plonk::proof& UltraProver_::construct_proo execute_sorted_list_accumulator_round(); // Fiat-Shamir: beta & gamma + execute_log_derivative_inverse_round(); + // Compute grand product(s) and commitments. execute_grand_product_computation_round(); diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.hpp index 058f5852c0e..fe50c8e0c80 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.hpp @@ -27,6 +27,7 @@ template class UltraProver_ { BBERG_PROFILE void execute_preamble_round(); BBERG_PROFILE void execute_wire_commitments_round(); BBERG_PROFILE void execute_sorted_list_accumulator_round(); + BBERG_PROFILE void execute_log_derivative_inverse_round(); BBERG_PROFILE void execute_grand_product_computation_round(); BBERG_PROFILE void execute_relation_check_rounds(); BBERG_PROFILE void execute_zeromorph_rounds(); @@ -39,6 +40,8 @@ template class UltraProver_ { std::vector public_inputs; size_t pub_inputs_offset; + proof_system::RelationParameters relation_parameters; + CommitmentLabels commitment_labels; Polynomial quotient_W; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp index 3dc1bcafa67..2c9d2ba85d2 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp @@ -96,6 +96,12 @@ template bool UltraVerifier_::verify_proof(const plonk // Get permutation challenges auto [beta, gamma] = transcript.get_challenges("beta", "gamma"); + // If Goblin (i.e. using DataBus) receive commitments to log-deriv inverses polynomial + if constexpr (IsGoblinFlavor) { + commitments.lookup_inverses = + transcript.template receive_from_prover(commitment_labels.lookup_inverses); + } + const FF public_input_delta = compute_public_input_delta(public_inputs, beta, gamma, circuit_size, pub_inputs_offset); const FF lookup_grand_product_delta = compute_lookup_grand_product_delta(beta, gamma, circuit_size); From 1a7d2b441fef9c5aba98ac8f4f9bb834b2e4390b Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Tue, 7 Nov 2023 17:08:48 +0000 Subject: [PATCH 07/15] fix linker issues after master merge --- .../cpp/src/barretenberg/flavor/goblin_ultra.hpp | 16 ++++++++-------- .../relations/databus_lookup_relation.cpp | 0 .../relations/databus_lookup_relation.hpp | 2 +- .../databus_composer.test.cpp | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) rename barretenberg/cpp/src/barretenberg/{proof_system => }/relations/databus_lookup_relation.cpp (100%) rename barretenberg/cpp/src/barretenberg/{proof_system => }/relations/databus_lookup_relation.hpp (99%) rename barretenberg/cpp/src/barretenberg/{honk/composer => ultra_honk}/databus_composer.test.cpp (96%) diff --git a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp index 6f6d4682b91..430fd9d7dad 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp @@ -3,14 +3,14 @@ #include "barretenberg/flavor/flavor.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp" -#include "barretenberg/proof_system/relations/auxiliary_relation.hpp" -#include "barretenberg/proof_system/relations/databus_lookup_relation.hpp" -#include "barretenberg/proof_system/relations/ecc_op_queue_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 "barretenberg/relations/auxiliary_relation.hpp" +#include "barretenberg/relations/databus_lookup_relation.hpp" +#include "barretenberg/relations/ecc_op_queue_relation.hpp" +#include "barretenberg/relations/elliptic_relation.hpp" +#include "barretenberg/relations/gen_perm_sort_relation.hpp" +#include "barretenberg/relations/lookup_relation.hpp" +#include "barretenberg/relations/permutation_relation.hpp" +#include "barretenberg/relations/ultra_arithmetic_relation.hpp" #include "barretenberg/transcript/transcript.hpp" #include "relation_definitions_fwd.hpp" diff --git a/barretenberg/cpp/src/barretenberg/proof_system/relations/databus_lookup_relation.cpp b/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.cpp similarity index 100% rename from barretenberg/cpp/src/barretenberg/proof_system/relations/databus_lookup_relation.cpp rename to barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.cpp diff --git a/barretenberg/cpp/src/barretenberg/proof_system/relations/databus_lookup_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp similarity index 99% rename from barretenberg/cpp/src/barretenberg/proof_system/relations/databus_lookup_relation.hpp rename to barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp index c9667549499..4c3a81f5c4d 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/relations/databus_lookup_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp @@ -5,7 +5,7 @@ #include "barretenberg/common/constexpr_utils.hpp" #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/polynomials/univariate.hpp" -#include "barretenberg/proof_system/relations/relation_types.hpp" +#include "barretenberg/relations/relation_types.hpp" namespace proof_system { diff --git a/barretenberg/cpp/src/barretenberg/honk/composer/databus_composer.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/databus_composer.test.cpp similarity index 96% rename from barretenberg/cpp/src/barretenberg/honk/composer/databus_composer.test.cpp rename to barretenberg/cpp/src/barretenberg/ultra_honk/databus_composer.test.cpp index fbad88661b4..54b4e38281b 100644 --- a/barretenberg/cpp/src/barretenberg/honk/composer/databus_composer.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/databus_composer.test.cpp @@ -3,10 +3,10 @@ #include #include "barretenberg/common/log.hpp" -#include "barretenberg/honk/composer/ultra_composer.hpp" -#include "barretenberg/honk/proof_system/ultra_prover.hpp" #include "barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp" #include "barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp" +#include "barretenberg/ultra_honk/ultra_composer.hpp" +#include "barretenberg/ultra_honk/ultra_prover.hpp" using namespace proof_system::honk; From d05d2742340d85e0fa68a7ee81c34401246f704f Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Thu, 9 Nov 2023 13:56:31 +0000 Subject: [PATCH 08/15] use requires instead --- .../sumcheck/instance/prover_instance.cpp | 24 +++++++++---------- .../sumcheck/instance/prover_instance.hpp | 3 ++- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp index 7213592e02b..e4715364924 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp @@ -193,21 +193,21 @@ template void ProverInstance_::construct_ecc_op_wire_poly * @tparam Flavor * @param circuit */ -template void ProverInstance_::construct_databus_polynomials(Circuit& circuit) +template +void ProverInstance_::construct_databus_polynomials(Circuit& circuit) + requires IsGoblinFlavor { - if constexpr (IsGoblinFlavor) { - polynomial public_calldata(dyadic_circuit_size); - polynomial calldata_read_counts(dyadic_circuit_size); + polynomial public_calldata(dyadic_circuit_size); + polynomial calldata_read_counts(dyadic_circuit_size); - // We do not utilize a zero row for databus columns - for (size_t idx = 0; idx < circuit.public_calldata.size(); ++idx) { - public_calldata[idx] = circuit.get_variable(circuit.public_calldata[idx]); - calldata_read_counts[idx] = circuit.get_variable(circuit.calldata_read_counts[idx]); - } - - proving_key->calldata = public_calldata; - proving_key->calldata_read_counts = calldata_read_counts; + // We do not utilize a zero row for databus columns + for (size_t idx = 0; idx < circuit.public_calldata.size(); ++idx) { + public_calldata[idx] = circuit.get_variable(circuit.public_calldata[idx]); + calldata_read_counts[idx] = circuit.get_variable(circuit.calldata_read_counts[idx]); } + + proving_key->calldata = public_calldata; + proving_key->calldata_read_counts = calldata_read_counts; } template diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp index 1af886caa54..52de9dc14db 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp @@ -95,7 +95,8 @@ template class ProverInstance_ { void construct_ecc_op_wire_polynomials(auto&); - void construct_databus_polynomials(Circuit&); + void construct_databus_polynomials(Circuit&) + requires IsGoblinFlavor; void add_table_column_selector_poly_to_proving_key(barretenberg::polynomial& small, const std::string& tag); From 77d6d3a1900007643cf9adfd1e5849af53dcf0f7 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Fri, 10 Nov 2023 16:22:43 +0000 Subject: [PATCH 09/15] WiP builds with lookup lib function in relation --- .../src/barretenberg/flavor/goblin_ultra.hpp | 1 + .../honk/proof_system/lookup_library.hpp | 4 +- .../relations/databus_lookup_relation.hpp | 65 ++----------------- 3 files changed, 7 insertions(+), 63 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp index 430fd9d7dad..3d555341403 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp @@ -10,6 +10,7 @@ #include "barretenberg/relations/gen_perm_sort_relation.hpp" #include "barretenberg/relations/lookup_relation.hpp" #include "barretenberg/relations/permutation_relation.hpp" +#include "barretenberg/relations/relation_parameters.hpp" #include "barretenberg/relations/ultra_arithmetic_relation.hpp" #include "barretenberg/transcript/transcript.hpp" #include "relation_definitions_fwd.hpp" diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/lookup_library.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/lookup_library.hpp index d009d8cc586..b30c7770b3a 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/lookup_library.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/lookup_library.hpp @@ -1,5 +1,4 @@ #pragma once -#include "barretenberg/sumcheck/sumcheck.hpp" #include namespace proof_system::honk::lookup_library { @@ -25,7 +24,8 @@ namespace proof_system::honk::lookup_library { */ template void compute_logderivative_inverse(Polynomials& polynomials, - proof_system::RelationParameters& relation_parameters, + // proof_system::RelationParameters& relation_parameters, + auto& relation_parameters, const size_t circuit_size) { using FF = typename Flavor::FF; diff --git a/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp index 4c3a81f5c4d..97237916a15 100644 --- a/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp @@ -3,6 +3,7 @@ #include #include "barretenberg/common/constexpr_utils.hpp" +#include "barretenberg/honk/proof_system/lookup_library.hpp" #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/relations/relation_types.hpp" @@ -131,67 +132,9 @@ template class DatabusLookupRelationImpl { const Parameters& params, const FF& scaling_factor) { - - using Accumulator = typename std::tuple_element_t<0, ContainerOverSubrelations>; - using View = typename Accumulator::View; - - auto lookup_inverses = View(in.lookup_inverses); - - constexpr size_t NUM_TOTAL_TERMS = READ_TERMS + WRITE_TERMS; - std::array lookup_terms; - std::array denominator_accumulator; - - // The lookup relation = \sum_j (1 / read_term[j]) - \sum_k (read_counts[k] / write_term[k]) - // To get the inverses (1 / read_term[i]), (1 / write_term[i]), we have a commitment to the product of all - // inverses i.e. lookup_inverse = \prod_j (1 / read_term[j]) * \prod_k (1 / write_term[k]) The purpose of this - // next section is to derive individual inverse terms using `lookup_inverses` i.e. (1 / read_term[i]) = - // lookup_inverse * \prod_{j /ne i} (read_term[j]) * \prod_k (write_term[k]) - // (1 / write_term[i]) = lookup_inverse * \prod_j (read_term[j]) * \prod_{k ne i} (write_term[k]) - barretenberg::constexpr_for<0, READ_TERMS, 1>( - [&]() { lookup_terms[i] = compute_read_term(in, params); }); - barretenberg::constexpr_for<0, WRITE_TERMS, 1>( - [&]() { lookup_terms[i + READ_TERMS] = compute_write_term(in, params); }); - - barretenberg::constexpr_for<0, NUM_TOTAL_TERMS, 1>( - [&]() { denominator_accumulator[i] = lookup_terms[i]; }); - - barretenberg::constexpr_for<0, NUM_TOTAL_TERMS - 1, 1>( - [&]() { denominator_accumulator[i + 1] *= denominator_accumulator[i]; }); - - auto inverse_accumulator = Accumulator(lookup_inverses); // denominator_accumulator[NUM_TOTAL_TERMS - 1]; - - const auto inverse_exists = compute_inverse_exists(in); - - std::get<0>(accumulator) += - (denominator_accumulator[NUM_TOTAL_TERMS - 1] * lookup_inverses - inverse_exists) * scaling_factor; - - // After this algo, total degree of denominator_accumulator = NUM_TOTAL_TERMS - for (size_t i = 0; i < NUM_TOTAL_TERMS - 1; ++i) { - denominator_accumulator[NUM_TOTAL_TERMS - 1 - i] = - denominator_accumulator[NUM_TOTAL_TERMS - 2 - i] * inverse_accumulator; - inverse_accumulator = inverse_accumulator * lookup_terms[NUM_TOTAL_TERMS - 1 - i]; - } - denominator_accumulator[0] = inverse_accumulator; - - // auto read_result = denominator_accumulator[0] * compute_read_term(in, params); - // info(read_result); - // auto write_result = denominator_accumulator[1] * compute_write_term(in, params); - // info(write_result); - // info(denominator_accumulator[1]); - - // each predicate is degree-1 - // degree of relation at this point = NUM_TOTAL_TERMS + 1 - barretenberg::constexpr_for<0, READ_TERMS, 1>([&]() { - std::get<1>(accumulator) += compute_read_term_predicate(in) * denominator_accumulator[i]; - }); - - // each predicate is degree-1, `lookup_read_counts` is degree-1 - // degree of relation = NUM_TOTAL_TERMS + 2 - barretenberg::constexpr_for<0, WRITE_TERMS, 1>([&]() { - const auto p = compute_write_term_predicate(in); - const auto lookup_read_count = lookup_read_counts(in); - std::get<1>(accumulator) -= p * (denominator_accumulator[i + READ_TERMS] * lookup_read_count); - }); + honk::lookup_library::accumulate_logderivative_lookup_subrelation_contributions>( + accumulator, in, params, scaling_factor); } }; From 4773666de962ae0dcc2bfc4db557d28b6fcc446b Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Sat, 11 Nov 2023 07:43:23 +0000 Subject: [PATCH 10/15] cleanup --- .../src/barretenberg/flavor/goblin_ultra.hpp | 8 +---- .../goblin/full_goblin_composer.test.cpp | 6 ++-- .../relations/databus_lookup_relation.cpp | 31 ------------------- .../sumcheck/instance/prover_instance.cpp | 23 +++++++++----- .../sumcheck/instance/prover_instance.hpp | 3 +- .../ultra_honk/databus_composer.test.cpp | 2 +- .../ultra_honk/goblin_ultra_composer.test.cpp | 8 ++--- .../ultra_honk/relation_correctness.test.cpp | 26 ---------------- 8 files changed, 26 insertions(+), 81 deletions(-) delete mode 100644 barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.cpp diff --git a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp index 3d555341403..02f296cb632 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp @@ -617,10 +617,4 @@ class GoblinUltra { }; }; -} // namespace proof_system::honk::flavor - -namespace proof_system { -// extern template class DatabusLookupRelationImpl; - -// DECLARE_SUMCHECK_RELATION_CLASS(DatabusLookupRelationImpl, honk::flavor::GoblinUltra); -} // namespace proof_system +} // namespace proof_system::honk::flavor \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/goblin/full_goblin_composer.test.cpp b/barretenberg/cpp/src/barretenberg/goblin/full_goblin_composer.test.cpp index 19f4ceb9ece..76e7d337b09 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/full_goblin_composer.test.cpp +++ b/barretenberg/cpp/src/barretenberg/goblin/full_goblin_composer.test.cpp @@ -80,7 +80,7 @@ class FullGoblinComposerTests : public ::testing::Test { static void perform_op_queue_interactions_for_mock_first_circuit( std::shared_ptr& op_queue) { - auto builder = GoblinUltraBuilder(op_queue); + auto builder = GoblinUltraBuilder{ op_queue }; // Add a mul accum op and an equality op auto point = Point::one() * FF::random_element(); @@ -163,7 +163,7 @@ TEST_F(FullGoblinComposerTests, SimpleCircuit) // Construct a series of simple Goblin circuits; generate and verify their proofs size_t NUM_CIRCUITS = 3; for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { - auto builder = GoblinUltraBuilder(op_queue); + auto builder = GoblinUltraBuilder{ op_queue }; generate_test_circuit(builder); @@ -205,7 +205,7 @@ TEST_F(FullGoblinComposerTests, SimpleCircuitFailureCase) // Construct a series of simple Goblin circuits; generate and verify their proofs size_t NUM_CIRCUITS = 3; for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { - auto builder = GoblinUltraBuilder(op_queue); + auto builder = GoblinUltraBuilder{ op_queue }; generate_test_circuit(builder); diff --git a/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.cpp b/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.cpp deleted file mode 100644 index aca1b0689e6..00000000000 --- a/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// #include "databus_lookup_relation.hpp" -// #include "barretenberg/flavor/relation_definitions_fwd.hpp" -// #include "barretenberg/honk/proof_system/lookup_library.hpp" - -// namespace proof_system { - -// /** -// * @brief -// * @details -// * -// * @param evals transformed to `evals + C(in(X)...)*scaling_factor` -// * @param in an std::array containing the fully extended Accumulator edges. -// * @param parameters contains beta, gamma, and public_input_delta, .... -// * @param scaling_factor optional term to scale the evaluation before adding to evals. -// */ -// template -// template -// void DatabusLookupRelationImpl::accumulate(ContainerOverSubrelations& accumulator, -// const AllEntities& in, -// const Parameters& params, -// [[maybe_unused]] const FF& scaling_factor) -// { -// honk::lookup_library::accumulate_logderivative_lookup_subrelation_contributions>( -// accumulator, in, params, scaling_factor); -// } - -// template class DatabusLookupRelationImpl; -// DEFINE_SUMCHECK_RELATION_CLASS(DatabusLookupRelationImpl, honk::flavor::GoblinUltra); - -// } // namespace proof_system diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp index e4715364924..b18044b7d65 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp @@ -446,16 +446,23 @@ template void ProverInstance_::add_plookup_memory_records } } -template void ProverInstance_::compute_logderivative_inverse(FF beta, FF gamma) +/** + * @brief Compute the inverse polynomial used in the log derivative lookup argument + * + * @tparam Flavor + * @param beta + * @param gamma + */ +template +void ProverInstance_::compute_logderivative_inverse(FF beta, FF gamma) + requires IsGoblinFlavor { - if constexpr (IsGoblinFlavor) { - relation_parameters.beta = beta; - relation_parameters.gamma = gamma; + relation_parameters.beta = beta; + relation_parameters.gamma = gamma; - // Compute permutation and lookup grand product polynomials - lookup_library::compute_logderivative_inverse( - prover_polynomials, relation_parameters, proving_key->circuit_size); - } + // Compute permutation and lookup grand product polynomials + lookup_library::compute_logderivative_inverse( + prover_polynomials, relation_parameters, proving_key->circuit_size); } template void ProverInstance_::compute_grand_product_polynomials(FF beta, FF gamma) diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp index 52de9dc14db..9e437b74e4c 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp @@ -71,7 +71,8 @@ template class ProverInstance_ { void compute_sorted_list_accumulator(FF); - void compute_logderivative_inverse(FF, FF); + void compute_logderivative_inverse(FF, FF) + requires IsGoblinFlavor; void compute_grand_product_polynomials(FF, FF); diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/databus_composer.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/databus_composer.test.cpp index 54b4e38281b..4ee34bab917 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/databus_composer.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/databus_composer.test.cpp @@ -85,7 +85,7 @@ TEST_F(DataBusComposerTests, SingleCircuit) // Add mock data to op queue to simulate interaction with a previous circuit op_queue->populate_with_mock_initital_data(); - auto builder = proof_system::GoblinUltraCircuitBuilder(op_queue); + auto builder = proof_system::GoblinUltraCircuitBuilder{ op_queue }; generate_test_circuit(builder); diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_composer.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_composer.test.cpp index d23b2f6b393..a09a822085b 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_composer.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_composer.test.cpp @@ -99,7 +99,7 @@ TEST_F(GoblinUltraHonkComposerTests, SingleCircuit) // Add mock data to op queue to simulate interaction with a previous circuit op_queue->populate_with_mock_initital_data(); - auto builder = proof_system::GoblinUltraCircuitBuilder(op_queue); + auto builder = proof_system::GoblinUltraCircuitBuilder{ op_queue }; generate_test_circuit(builder); @@ -130,7 +130,7 @@ TEST_F(GoblinUltraHonkComposerTests, MultipleCircuitsMergeOnly) // Construct multiple test circuits that share an ECC op queue. Generate and verify a proof for each. size_t NUM_CIRCUITS = 3; for (size_t i = 0; i < NUM_CIRCUITS; ++i) { - auto builder = proof_system::GoblinUltraCircuitBuilder(op_queue); + auto builder = proof_system::GoblinUltraCircuitBuilder{ op_queue }; generate_test_circuit(builder); @@ -158,7 +158,7 @@ TEST_F(GoblinUltraHonkComposerTests, MultipleCircuitsHonkOnly) // Construct multiple test circuits that share an ECC op queue. Generate and verify a proof for each. size_t NUM_CIRCUITS = 3; for (size_t i = 0; i < NUM_CIRCUITS; ++i) { - auto builder = proof_system::GoblinUltraCircuitBuilder(op_queue); + auto builder = proof_system::GoblinUltraCircuitBuilder{ op_queue }; generate_test_circuit(builder); @@ -186,7 +186,7 @@ TEST_F(GoblinUltraHonkComposerTests, MultipleCircuitsHonkAndMerge) // Construct multiple test circuits that share an ECC op queue. Generate and verify a proof for each. size_t NUM_CIRCUITS = 3; for (size_t i = 0; i < NUM_CIRCUITS; ++i) { - auto builder = proof_system::GoblinUltraCircuitBuilder(op_queue); + auto builder = proof_system::GoblinUltraCircuitBuilder{ op_queue }; generate_test_circuit(builder); diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp index 60f837e23cd..fa8b6e07639 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp @@ -354,32 +354,6 @@ TEST_F(RelationCorrectnessTests, GoblinUltraRelationCorrectness) auto prover_polynomials = instance->prover_polynomials; auto params = instance->relation_parameters; - // size_t idx = 0; - // for (auto& coeff : prover_polynomials.calldata_read_counts) { - // if (!coeff.is_zero()) { - // info("idx = ", idx); - // info("counts = ", coeff); - // info("calldata = ", prover_polynomials.calldata[idx]); - // info("id = ", prover_polynomials.databus_id[idx]); - // } - // idx++; - // } - - // idx = 0; - // for (auto& coeff : prover_polynomials.q_busread) { - // if (!coeff.is_zero()) { - // info("idx = ", idx); - // info("q_busread = ", coeff); - // info("w_1 = ", prover_polynomials.w_l[idx]); - // info("w_2 = ", prover_polynomials.w_r[idx]); - // } - // idx++; - // } - - // for (size_t i = 0; i < 5; ++i) { - // info("id_1_i = ", prover_polynomials.databus_id[i]); - // } - // Check that each relation is satisfied across each row of the prover polynomials check_relation>(circuit_size, prover_polynomials, params); check_relation>(circuit_size, prover_polynomials, params); From 99a70c86be5dbc5a46aca2fc94f2bfffb5737399 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Sat, 11 Nov 2023 07:58:56 +0000 Subject: [PATCH 11/15] ultra honk verifies with databus relation --- .../sumcheck/instance/prover_instance.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp index b18044b7d65..6b90f97d834 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp @@ -524,20 +524,14 @@ std::shared_ptr ProverInstance_::compu verification_key->table_3 = commitment_key->commit(proving_key->table_3); verification_key->table_4 = commitment_key->commit(proving_key->table_4); - // TODO(luke): Similar to the lagrange_first/last polynomials, we dont really need to commit to this polynomial - // due to its simple structure. Handling it in the same way as the lagrange polys for now for simplicity. + // TODO(luke): Similar to the lagrange_first/last polynomials, we dont really need to commit to these polynomials + // due to their simple structure. if constexpr (IsGoblinFlavor) { verification_key->lagrange_ecc_op = commitment_key->commit(proving_key->lagrange_ecc_op); verification_key->q_busread = commitment_key->commit(proving_key->q_busread); + verification_key->databus_id = commitment_key->commit(proving_key->databus_id); } - // // See `add_recusrive_proof()` for how this recursive data is assigned. - // verification_key->recursive_proof_public_input_indices = - // std::vector(recursive_proof_public_input_indices.begin(), - // recursive_proof_public_input_indices.end()); - - // verification_key->contains_recursive_proof = contains_recursive_proof; - return verification_key; } From 5022b7cb45685644832b253f60e98672c92125f7 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Sat, 11 Nov 2023 08:15:00 +0000 Subject: [PATCH 12/15] updates after merge --- barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp | 2 ++ .../barretenberg/ultra_honk/relation_correctness.test.cpp | 6 ++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp index 5745c345c3d..b9378aa83b2 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp @@ -255,6 +255,7 @@ class GoblinUltra { &lagrange_first, &lagrange_last, &lagrange_ecc_op, + &databus_id, &w_l, &w_r, &w_o, @@ -268,6 +269,7 @@ class GoblinUltra { &ecc_op_wire_4, &calldata, &calldata_read_counts, + &lookup_inverses, &table_1_shift, &table_2_shift, &table_3_shift, diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp index b4e1600f39a..6402d0fdc34 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp @@ -78,10 +78,8 @@ void check_linearly_dependent_relation(auto circuit_size, auto polynomials, auto // Extract an array containing all the polynomial evaluations at a given row i AllValues evaluations_at_index_i; - size_t poly_idx = 0; - for (auto& poly : polynomials) { - evaluations_at_index_i[poly_idx] = poly[i]; - ++poly_idx; + for (auto [eval, poly] : zip_view(evaluations_at_index_i.pointer_view(), polynomials.pointer_view())) { + *eval = (*poly)[i]; } // Evaluate each constraint in the relation and check that each is satisfied From 235dfcd620307473a070efa63390952ac2b8ec16 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Wed, 15 Nov 2023 17:08:58 +0000 Subject: [PATCH 13/15] update recursive verifier --- .../flavor/goblin_ultra_recursive.hpp | 112 ++++++++++++------ .../verifier/ultra_recursive_verifier.cpp | 16 +-- 2 files changed, 85 insertions(+), 43 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp index e85e9578ce2..f37d26b3adc 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp @@ -61,13 +61,12 @@ template class GoblinUltraRecursive_ { // 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`. // Note: this number does not include the individual sorted list polynomials. - // NUM = 43 (UH) + 4 op wires + 1 op wire "selector" + 3 (calldata + calldata_read_counts + q_busread) - static constexpr size_t NUM_ALL_ENTITIES = 51; + static constexpr size_t NUM_ALL_ENTITIES = 53; // 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 = 27; // 25 (UH) + 1 op wire "selector" + q_busread + static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 28; // The total number of witness entities not including shifts. - static constexpr size_t NUM_WITNESS_ENTITIES = 17; // 11 (UH) + 4 op wires + (calldata + calldata_read_counts) + static constexpr size_t NUM_WITNESS_ENTITIES = 18; // define the tuple of Relations that comprise the Sumcheck relation using Relations = std::tuple, @@ -76,7 +75,8 @@ template class GoblinUltraRecursive_ { proof_system::GenPermSortRelation, proof_system::EllipticRelation, proof_system::AuxiliaryRelation, - proof_system::EccOpQueueRelation>; + proof_system::EccOpQueueRelation, + proof_system::DatabusLookupRelation>; static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length(); @@ -125,6 +125,37 @@ template class GoblinUltraRecursive_ { DataType lagrange_first; // column 24 DataType lagrange_last; // column 25 DataType lagrange_ecc_op; // column 26 // indicator poly for ecc op gates + DataType databus_id; // column 27 // id polynomial, i.e. id_i = i + + DEFINE_POINTER_VIEW(NUM_PRECOMPUTED_ENTITIES, + &q_m, + &q_c, + &q_l, + &q_r, + &q_o, + &q_4, + &q_arith, + &q_sort, + &q_elliptic, + &q_aux, + &q_lookup, + &q_busread, + &sigma_1, + &sigma_2, + &sigma_3, + &sigma_4, + &id_1, + &id_2, + &id_3, + &id_4, + &table_1, + &table_2, + &table_3, + &table_4, + &lagrange_first, + &lagrange_last, + &lagrange_ecc_op, + &databus_id) static constexpr CircuitType CIRCUIT_TYPE = CircuitBuilder::CIRCUIT_TYPE; @@ -162,6 +193,7 @@ template class GoblinUltraRecursive_ { DataType ecc_op_wire_4; // column 14 DataType calldata; // column 15 DataType calldata_read_counts; // column 16 + DataType lookup_inverses; // column 17 DEFINE_POINTER_VIEW(NUM_WITNESS_ENTITIES, &w_l, @@ -180,7 +212,8 @@ template class GoblinUltraRecursive_ { &ecc_op_wire_3, &ecc_op_wire_4, &calldata, - &calldata_read_counts) + &calldata_read_counts, + &lookup_inverses) std::vector get_wires() override { return { w_l, w_r, w_o, w_4 }; }; std::vector get_ecc_op_wires() @@ -230,31 +263,34 @@ template class GoblinUltraRecursive_ { DataType lagrange_first; // column 24 DataType lagrange_last; // column 25 DataType lagrange_ecc_op; // column 26 - DataType w_l; // column 27 - DataType w_r; // column 28 - DataType w_o; // column 29 - DataType w_4; // column 30 - DataType sorted_accum; // column 31 - DataType z_perm; // column 32 - DataType z_lookup; // column 33 - DataType ecc_op_wire_1; // column 34 - DataType ecc_op_wire_2; // column 35 - DataType ecc_op_wire_3; // column 36 - DataType ecc_op_wire_4; // column 37 - DataType calldata; // column 38 - DataType calldata_read_counts; // column 39 - DataType table_1_shift; // column 40 - DataType table_2_shift; // column 41 - DataType table_3_shift; // column 42 - DataType table_4_shift; // column 43 - DataType w_l_shift; // column 44 - DataType w_r_shift; // column 45 - DataType w_o_shift; // column 46 - DataType w_4_shift; // column 47 - DataType sorted_accum_shift; // column 48 - DataType z_perm_shift; // column 49 - DataType z_lookup_shift; // column 50 - + DataType databus_id; // column 27 + DataType w_l; // column 28 + DataType w_r; // column 29 + DataType w_o; // column 30 + DataType w_4; // column 31 + DataType sorted_accum; // column 32 + DataType z_perm; // column 33 + DataType z_lookup; // column 34 + DataType ecc_op_wire_1; // column 35 + DataType ecc_op_wire_2; // column 36 + DataType ecc_op_wire_3; // column 37 + DataType ecc_op_wire_4; // column 38 + DataType calldata; // column 39 + DataType calldata_read_counts; // column 40 + DataType lookup_inverses; // column 41 + DataType table_1_shift; // column 42 + DataType table_2_shift; // column 43 + DataType table_3_shift; // column 44 + DataType table_4_shift; // column 45 + DataType w_l_shift; // column 46 + DataType w_r_shift; // column 47 + DataType w_o_shift; // column 48 + DataType w_4_shift; // column 49 + DataType sorted_accum_shift; // column 50 + DataType z_perm_shift; // column 51 + DataType z_lookup_shift; // column 52 + + // defines a method pointer_view that returns the following, with const and non-const variants DEFINE_POINTER_VIEW(NUM_ALL_ENTITIES, &q_c, &q_l, @@ -283,6 +319,7 @@ template class GoblinUltraRecursive_ { &lagrange_first, &lagrange_last, &lagrange_ecc_op, + &databus_id, &w_l, &w_r, &w_o, @@ -296,6 +333,7 @@ template class GoblinUltraRecursive_ { &ecc_op_wire_4, &calldata, &calldata_read_counts, + &lookup_inverses, &table_1_shift, &table_2_shift, &table_3_shift, @@ -306,7 +344,7 @@ template class GoblinUltraRecursive_ { &w_4_shift, &sorted_accum_shift, &z_perm_shift, - &z_lookup_shift) + &z_lookup_shift); std::vector get_wires() override { return { w_l, w_r, w_o, w_4 }; }; std::vector get_ecc_op_wires() @@ -343,6 +381,7 @@ template class GoblinUltraRecursive_ { lagrange_first, lagrange_last, lagrange_ecc_op, + databus_id, w_l, w_r, w_o, @@ -355,7 +394,8 @@ template class GoblinUltraRecursive_ { ecc_op_wire_3, ecc_op_wire_4, calldata, - calldata_read_counts }; + calldata_read_counts, + lookup_inverses }; }; std::vector get_to_be_shifted() override { @@ -416,6 +456,7 @@ template class GoblinUltraRecursive_ { this->lagrange_first = Commitment::from_witness(builder, native_key->lagrange_first); this->lagrange_last = Commitment::from_witness(builder, native_key->lagrange_last); this->lagrange_ecc_op = Commitment::from_witness(builder, native_key->lagrange_ecc_op); + this->databus_id = Commitment::from_witness(builder, native_key->databus_id); }; }; @@ -453,6 +494,7 @@ template class GoblinUltraRecursive_ { this->ecc_op_wire_4 = "ECC_OP_WIRE_4"; this->calldata = "CALLDATA"; this->calldata_read_counts = "CALLDATA_READ_COUNTS"; + this->lookup_inverses = "LOOKUP_INVERSES"; // The ones beginning with "__" are only used for debugging this->q_c = "__Q_C"; @@ -516,6 +558,7 @@ template class GoblinUltraRecursive_ { this->lagrange_first = verification_key->lagrange_first; this->lagrange_last = verification_key->lagrange_last; this->lagrange_ecc_op = verification_key->lagrange_ecc_op; + this->databus_id = verification_key->databus_id; } }; @@ -539,6 +582,7 @@ template class GoblinUltraRecursive_ { Commitment ecc_op_wire_4_comm; Commitment calldata_comm; Commitment calldata_read_counts_comm; + Commitment lookup_inverses_comm; Commitment sorted_accum_comm; Commitment w_4_comm; Commitment z_perm_comm; @@ -581,6 +625,7 @@ template class GoblinUltraRecursive_ { calldata_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); calldata_read_counts_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); + lookup_inverses_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); sorted_accum_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); w_4_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); z_perm_comm = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); @@ -625,6 +670,7 @@ template class GoblinUltraRecursive_ { serialize_to_buffer(ecc_op_wire_4_comm, BaseTranscript::proof_data); serialize_to_buffer(calldata_comm, BaseTranscript::proof_data); serialize_to_buffer(calldata_read_counts_comm, BaseTranscript::proof_data); + serialize_to_buffer(lookup_inverses_comm, BaseTranscript::proof_data); serialize_to_buffer(sorted_accum_comm, BaseTranscript::proof_data); serialize_to_buffer(w_4_comm, BaseTranscript::proof_data); serialize_to_buffer(z_perm_comm, BaseTranscript::proof_data); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/ultra_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/ultra_recursive_verifier.cpp index c4d91dbf987..d94df58d62a 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/ultra_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/ultra_recursive_verifier.cpp @@ -30,9 +30,6 @@ std::array UltraRecursiveVerifier_::ve RelationParams relation_parameters; - info("Initial: num gates = ", builder->get_num_gates()); - size_t prev_num_gates = builder->get_num_gates(); - transcript = Transcript{ builder, proof.proof_data }; auto commitments = VerifierCommitments(key); @@ -83,6 +80,12 @@ std::array UltraRecursiveVerifier_::ve // Get permutation challenges auto [beta, gamma] = transcript.get_challenges("beta", "gamma"); + // If Goblin (i.e. using DataBus) receive commitments to log-deriv inverses polynomial + if constexpr (IsGoblinFlavor) { + commitments.lookup_inverses = + transcript.template receive_from_prover(commitment_labels.lookup_inverses); + } + const FF public_input_delta = proof_system::honk::compute_public_input_delta( public_inputs, beta, gamma, circuit_size, static_cast(pub_inputs_offset.get_value())); const FF lookup_grand_product_delta = @@ -102,13 +105,6 @@ std::array UltraRecursiveVerifier_::ve auto sumcheck = Sumcheck(key->circuit_size); auto [multivariate_challenge, claimed_evaluations, verified] = sumcheck.verify(relation_parameters, transcript); - info("Sumcheck: num gates = ", - builder->get_num_gates() - prev_num_gates, - ", (total = ", - builder->get_num_gates(), - ")"); - prev_num_gates = builder->get_num_gates(); - // Execute ZeroMorph multilinear PCS evaluation verifier auto pairing_points = ZeroMorph::verify(commitments, claimed_evaluations, multivariate_challenge, transcript); From 923cfa91c31fd38a9a70e6c3af7d92cec190e49c Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Thu, 16 Nov 2023 17:59:58 +0000 Subject: [PATCH 14/15] WiP --- .../src/barretenberg/flavor/goblin_ultra.hpp | 7 ++-- .../honk/proof_system/lookup_library.hpp | 5 +-- .../goblin_ultra_circuit_builder.cpp | 15 +++++--- .../relations/databus_lookup_relation.hpp | 34 ++++++++++++++++--- 4 files changed, 43 insertions(+), 18 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp index ff330c991ec..ad09352b917 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp @@ -35,13 +35,12 @@ class GoblinUltra { // 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`. // Note: this number does not include the individual sorted list polynomials. - // NUM = 43 (UH) + 4 op wires + 1 op wire "selector" + 3+1+1 (bus) static constexpr size_t NUM_ALL_ENTITIES = 53; // 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 = 28; // 25 (UH) + 1 op wire "selector" + q_busread + databus_id + static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 28; // The total number of witness entities not including shifts. - static constexpr size_t NUM_WITNESS_ENTITIES = 18; // 11 (UH) + 4 op wires + 3 (bus) + static constexpr size_t NUM_WITNESS_ENTITIES = 18; using GrandProductRelations = std::tuple, proof_system::LookupRelation>; @@ -616,7 +615,7 @@ class GoblinUltra { Transcript(const std::vector& proof) : BaseTranscript(proof) {} - // WORKTODO: add lookup inverses once its being computed + void deserialize_full_transcript() override { // take current proof and put them into the struct diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/lookup_library.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/lookup_library.hpp index b30c7770b3a..e875c0de5c0 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/lookup_library.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/lookup_library.hpp @@ -23,10 +23,7 @@ namespace proof_system::honk::lookup_library { * */ template -void compute_logderivative_inverse(Polynomials& polynomials, - // proof_system::RelationParameters& relation_parameters, - auto& relation_parameters, - const size_t circuit_size) +void compute_logderivative_inverse(Polynomials& polynomials, auto& relation_parameters, const size_t circuit_size) { using FF = typename Flavor::FF; using Accumulator = typename Relation::ValueAccumulator0; diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.cpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.cpp index 7b94f0f27dc..610aefccf09 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.cpp @@ -22,8 +22,12 @@ template void GoblinUltraCircuitBuilder_::finalize_circuit() // polynomials is zero, which is required for them to be shiftable. template void GoblinUltraCircuitBuilder_::add_gates_to_ensure_all_polys_are_non_zero() { + // Most polynomials are handled via the conventional Ultra method UltraCircuitBuilder_>::add_gates_to_ensure_all_polys_are_non_zero(); + // All that remains is to handle databus related polynomials. In what follows we populate the calldata with some + // mock data then constuct a single calldata read gate + // Populate the calldata with some data public_calldata.emplace_back(this->add_variable(FF(5))); public_calldata.emplace_back(this->add_variable(FF(7))); @@ -36,10 +40,11 @@ template void GoblinUltraCircuitBuilder_::add_gates_to_ensure_ } // Construct gate corresponding to a single calldata read - this->w_l.emplace_back(public_calldata[1]); // index for 7 in variables - this->w_r.emplace_back(this->add_variable(FF(1))); // idx 1 into calldata - calldata_read_counts[1]++; // increment read count at index 1 - q_busread.emplace_back(1); // read selector on + size_t read_idx = 1; // index into calldata array at which we want to read + this->w_l.emplace_back(public_calldata[read_idx]); // populate with value of calldata at read index + this->w_r.emplace_back(this->add_variable(FF(read_idx))); // populate with read index as witness + calldata_read_counts[read_idx]++; // increment read count at read index + q_busread.emplace_back(1); // read selector on // populate all other components with zero this->w_o.emplace_back(this->zero_idx); @@ -50,12 +55,12 @@ template void GoblinUltraCircuitBuilder_::add_gates_to_ensure_ this->q_3.emplace_back(0); this->q_c.emplace_back(0); this->q_sort.emplace_back(0); - this->q_arith.emplace_back(0); this->q_4.emplace_back(0); this->q_lookup_type.emplace_back(0); this->q_elliptic.emplace_back(0); this->q_aux.emplace_back(0); + ++this->num_gates; } diff --git a/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp index 97237916a15..9733a1429f2 100644 --- a/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp @@ -16,7 +16,6 @@ template class DatabusLookupRelationImpl { static constexpr size_t READ_TERMS = 1; static constexpr size_t WRITE_TERMS = 1; // 1 + polynomial degree of this relation - // WORKTODO static constexpr size_t LENGTH = READ_TERMS + WRITE_TERMS + 3; static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ @@ -28,6 +27,16 @@ template class DatabusLookupRelationImpl { // entire execution trace rather than a per-row identity. static constexpr std::array SUBRELATION_LINEARLY_INDEPENDENT = { true, false }; + /** + * @brief Determine whether the inverse I needs to be computed at a given row + * @details The value of the inverse polynomial I(X) only needs to be computed when the databus lookup gate is + * "active". Otherwise it is set to 0. This method allows for determination of when the inverse should be computed. + * + * @tparam AllValues + * @param row + * @return true + * @return false + */ template static bool lookup_exists_at_row(const AllValues& row) { return (row.q_busread == 1 || row.calldata_read_counts > 0); @@ -53,6 +62,10 @@ template class DatabusLookupRelationImpl { return Accumulator(1); } + /** + * @brief Compute scalar for read term in log derivative lookup argument + * + */ template static Accumulator compute_read_term_predicate([[maybe_unused]] const AllEntities& in) @@ -65,12 +78,20 @@ template class DatabusLookupRelationImpl { return Accumulator(1); } + /** + * @brief Compute scalar for write term in log derivative lookup argument + * + */ template static Accumulator compute_write_term_predicate(const AllEntities& /*unused*/) { return Accumulator(1); } + /** + * @brief Compute write term denominator in log derivative lookup argument + * + */ template static Accumulator compute_write_term(const AllEntities& in, const Parameters& params) { @@ -93,6 +114,10 @@ template class DatabusLookupRelationImpl { return Accumulator(1); } + /** + * @brief Compute read term denominator in log derivative lookup argument + * + */ template static Accumulator compute_read_term(const AllEntities& in, const Parameters& params) { @@ -108,8 +133,6 @@ template class DatabusLookupRelationImpl { const auto& gamma = ParameterView(params.gamma); const auto& beta = ParameterView(params.beta); - // const auto read_term1 = w_1 + gamma + w_2 * beta; // degree 1 - // Construct value + index*\beta + \gamma if constexpr (read_index == 0) { return w_1 + gamma + w_2 * beta; @@ -119,8 +142,9 @@ template class DatabusLookupRelationImpl { } /** - * @brief - * @details + * @brief Accumulate the contribution from two surelations for the log derivative databus lookup argument + * @details See lookup_library.hpp for details of the generic log-derivative lookup argument + * * @param accumulator transformed to `evals + C(in(X)...)*scaling_factor` * @param in an std::array containing the fully extended Accumulator edges. * @param params contains beta, gamma, and public_input_delta, .... From d5d3a31e6707f494d30134ded6d3cd7051bf7a42 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Thu, 16 Nov 2023 19:19:50 +0000 Subject: [PATCH 15/15] cleanup --- .../honk/proof_system/lookup_library.hpp | 1 + .../relations/databus_lookup_relation.hpp | 15 +++++++++++++-- .../sumcheck/instance/prover_instance.cpp | 2 +- .../ultra_honk/goblin_ultra_transcript.test.cpp | 4 +--- .../ultra_honk/relation_correctness.test.cpp | 3 +++ .../src/barretenberg/ultra_honk/ultra_prover.cpp | 4 ++-- 6 files changed, 21 insertions(+), 8 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/lookup_library.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/lookup_library.hpp index e875c0de5c0..820bc2907a5 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/lookup_library.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/lookup_library.hpp @@ -125,6 +125,7 @@ void accumulate_logderivative_lookup_subrelation_contributions(ContainerOverSubr const auto inverse_exists = lookup_relation.template compute_inverse_exists(in); + // Note: the lookup_inverses are computed so that the value is 0 if !inverse_exists std::get<0>(accumulator) += (denominator_accumulator[NUM_TOTAL_TERMS - 1] * lookup_inverses - inverse_exists) * scaling_factor; diff --git a/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp index 9733a1429f2..da659a321e9 100644 --- a/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/databus_lookup_relation.hpp @@ -42,12 +42,23 @@ template class DatabusLookupRelationImpl { return (row.q_busread == 1 || row.calldata_read_counts > 0); } + /** + * @brief Compute the Accumulator whose values indicate whether the inverse is computed or not + * @details This is needed for efficiency since we don't need to compute the inverse unless the log derivative + * lookup relation is active at a given row. + * + */ template static Accumulator compute_inverse_exists(const AllEntities& in) { using View = typename Accumulator::View; - // WORKTODO: really what we need instead of calldata_read_counts is a boolean equivalent that says > 0 counts or - // not.. or possibly just "is this a row in the calldata" + // TODO(luke): row_has_read should really be a boolean object thats equal to 1 when counts > 0 and 0 otherwise. + // This current structure will lead to failure if call_data_read_counts > 1. + const auto row_has_write = View(in.q_busread); + const auto row_has_read = View(in.calldata_read_counts); + + return row_has_write + row_has_read - (row_has_write * row_has_read); + return Accumulator(View(in.q_busread) + View(in.calldata_read_counts)); } diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp index 7e177b2d767..34f2842eede 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp @@ -200,7 +200,7 @@ void ProverInstance_::construct_databus_polynomials(Circuit& circuit) polynomial public_calldata(dyadic_circuit_size); polynomial calldata_read_counts(dyadic_circuit_size); - // We do not utilize a zero row for databus columns + // Note: We do not utilize a zero row for databus columns for (size_t idx = 0; idx < circuit.public_calldata.size(); ++idx) { public_calldata[idx] = circuit.get_variable(circuit.public_calldata[idx]); calldata_read_counts[idx] = circuit.get_variable(circuit.calldata_read_counts[idx]); diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_transcript.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_transcript.test.cpp index 27837ac6466..ee79064a5eb 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_transcript.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_transcript.test.cpp @@ -26,7 +26,7 @@ class GoblinUltraTranscriptTests : public ::testing::Test { * * @return TranscriptManifest */ - TranscriptManifest construct_goblin_ultra_honk_manifest(size_t circuit_size) + static TranscriptManifest construct_goblin_ultra_honk_manifest(size_t circuit_size) { TranscriptManifest manifest_expected; @@ -172,8 +172,6 @@ TEST_F(GoblinUltraTranscriptTests, VerifierManifestConsistency) auto prover_manifest = prover.transcript.get_manifest(); auto verifier_manifest = verifier.transcript.get_manifest(); - prover_manifest.print(); - verifier_manifest.print(); // 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]) diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp index 58bbcb54ae1..aac5c124212 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp @@ -59,6 +59,9 @@ template void check_relation(auto circuit_s /** * @brief Check that a given linearly dependent relation is satisfied for a set of polynomials + * @details We refer to a relation as linearly dependent if it defines a constraint on the sum across the full execution + * trace rather than at each individual row. For example, a subrelation of this type arises in the log derivative lookup + * argument. * * @tparam relation_idx Index into a tuple of provided relations * @tparam Flavor diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp index f79493b6dc6..f2ec19befbd 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp @@ -87,12 +87,12 @@ template void UltraProver_::execute_sorted_list_acc } /** - * @brief Compute permutation and lookup grand product polynomials and their commitments + * @brief Compute log derivative inverse polynomial and its commitment, if required * */ template void UltraProver_::execute_log_derivative_inverse_round() { - // Compute and store parameters required by relations in Sumcheck + // Compute and store challenges beta and gamma auto [beta, gamma] = transcript.get_challenges("beta", "gamma"); relation_parameters.beta = beta; relation_parameters.gamma = gamma;