From 06d50de33a7f510dd861f56baff18718bf01c34c Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Wed, 1 Nov 2023 18:57:53 +0000 Subject: [PATCH 1/7] 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 6cad5e2ef57056753fbc13197f5f6992e9e11480 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Wed, 1 Nov 2023 22:33:33 +0000 Subject: [PATCH 2/7] 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 8abf38073216a96c6c01e360114c8c1889f91b04 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Wed, 1 Nov 2023 23:06:04 +0000 Subject: [PATCH 3/7] 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 cb7dedcf5de97361b059376ebe4e28d60f192958 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Thu, 2 Nov 2023 17:11:51 +0000 Subject: [PATCH 4/7] 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 2f5c3cd1b706ffb80e2ef7853f4ad90a9bf0ab44 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Wed, 8 Nov 2023 10:07:46 +0000 Subject: [PATCH 5/7] rebase build fix --- .../{honk/composer => ultra_honk}/databus_composer.test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename barretenberg/cpp/src/barretenberg/{honk/composer => ultra_honk}/databus_composer.test.cpp (96%) 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 117ae9e489c841578225b4ec59ab0b3f1d1b354c Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Thu, 9 Nov 2023 12:18:16 +0000 Subject: [PATCH 6/7] cleanup comments --- barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp | 1 - .../circuit_builder/goblin_ultra_circuit_builder.cpp | 1 - .../cpp/src/barretenberg/ultra_honk/databus_composer.test.cpp | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp index 2f0878a9640..bf94b36b65d 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp @@ -51,7 +51,6 @@ 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(); 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..5611b7ec5a0 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 @@ -45,7 +45,6 @@ template void GoblinUltraCircuitBuilder_::add_gates_to_ensure_ ++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/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); From c922cb32f0c513a54def456a77b0e3d0341cdc0b Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Thu, 9 Nov 2023 14:03:40 +0000 Subject: [PATCH 7/7] 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 4e4955535bb..d64ae7629aa 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp @@ -192,21 +192,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); - 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; + 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 diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp index c7a6808fd2e..a004587fefc 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp @@ -93,7 +93,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);