From 37a625e0639b63a763e7af9f9c3b6cfd427f80db Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Wed, 5 Jul 2023 15:59:24 +0000 Subject: [PATCH 01/13] Cleaning up circuit size params in honk composers --- .../honk/composer/standard_composer.cpp | 40 +--- .../honk/composer/standard_composer.hpp | 10 +- .../honk/composer/ultra_composer.cpp | 90 ++------- .../honk/composer/ultra_composer.hpp | 6 +- .../honk/composer/ultra_composer.test.cpp | 23 +++ .../honk/transcript/transcript.test.cpp | 16 +- .../composer/composer_helper_lib.hpp | 179 ------------------ .../proof_system/composer/composer_lib.hpp | 5 +- 8 files changed, 73 insertions(+), 296 deletions(-) delete mode 100644 cpp/src/barretenberg/proof_system/composer/composer_helper_lib.hpp diff --git a/cpp/src/barretenberg/honk/composer/standard_composer.cpp b/cpp/src/barretenberg/honk/composer/standard_composer.cpp index 3b89a158b3..edc123c1a9 100644 --- a/cpp/src/barretenberg/honk/composer/standard_composer.cpp +++ b/cpp/src/barretenberg/honk/composer/standard_composer.cpp @@ -10,32 +10,6 @@ namespace proof_system::honk { -/** - * Compute proving key base. - * - * 1. Load crs. - * 2. Initialize this->proving_key. - * 3. Create constraint selector polynomials from each of this composer's `selectors` vectors and add them to the - * proving key. - * - * @param minimum_circuit_size Used as the total number of gates when larger than n + count of public inputs. - * @param num_reserved_gates The number of reserved gates. - * @return Pointer to the initialized proving key updated with selector polynomials. - * */ -template -std::shared_ptr StandardComposer_::compute_proving_key_base( - const CircuitBuilder& constructor, const size_t minimum_circuit_size, const size_t num_randomized_gates) -{ - // Initialize proving_key - // TODO(#392)(Kesha): replace composer types. - proving_key = - initialize_proving_key(constructor, crs_factory_.get(), minimum_circuit_size, num_randomized_gates); - // Compute lagrange selectors - construct_selector_polynomials(constructor, proving_key.get()); - - return proving_key; -} - /** * Compute witness polynomials (w_1, w_2, w_3, w_4). * @@ -52,8 +26,7 @@ void StandardComposer_::compute_witness(const CircuitBuilder& circuit_co if (computed_witness) { return; } - auto wire_polynomials = - construct_wire_polynomials_base(circuit_constructor, minimum_circuit_size, NUM_RESERVED_GATES); + auto wire_polynomials = construct_wire_polynomials_base(circuit_constructor, minimum_circuit_size); proving_key->w_l = wire_polynomials[0]; proving_key->w_r = wire_polynomials[1]; @@ -76,8 +49,15 @@ std::shared_ptr StandardComposer_::compute_ if (proving_key) { return proving_key; } - // Compute q_l, q_r, q_o, etc polynomials - StandardComposer_::compute_proving_key_base(circuit_constructor, /*minimum_circuit_size=*/0, NUM_RESERVED_GATES); + + num_public_inputs = circuit_constructor.public_inputs.size(); + total_num_gates = circuit_constructor.num_gates + num_public_inputs; + dyadic_circuit_size = circuit_constructor.get_circuit_subgroup_size(total_num_gates); + + proving_key = std::make_shared(dyadic_circuit_size, num_public_inputs); + + // Compute lagrange selectors + construct_selector_polynomials(circuit_constructor, proving_key.get()); // Compute sigma polynomials (we should update that late) compute_standard_honk_sigma_permutations(circuit_constructor, proving_key.get()); diff --git a/cpp/src/barretenberg/honk/composer/standard_composer.hpp b/cpp/src/barretenberg/honk/composer/standard_composer.hpp index b12a8bac23..4cc562e0bc 100644 --- a/cpp/src/barretenberg/honk/composer/standard_composer.hpp +++ b/cpp/src/barretenberg/honk/composer/standard_composer.hpp @@ -21,7 +21,6 @@ template class StandardComposer_ { using PCSCommitmentKey = typename PCSParams::CommitmentKey; static constexpr std::string_view NAME_STRING = "StandardHonk"; - static constexpr size_t NUM_RESERVED_GATES = 2; // equal to the number of multilinear evaluations leaked static constexpr size_t NUM_WIRES = CircuitBuilder::NUM_WIRES; std::shared_ptr proving_key; std::shared_ptr verification_key; @@ -32,6 +31,10 @@ template class StandardComposer_ { // The commitment key is passed to the prover but also used herein to compute the verfication key commitments std::shared_ptr commitment_key; + size_t total_num_gates; // total num gates prior to computing dyadic size + size_t dyadic_circuit_size; // final dyadic circuit size + size_t num_public_inputs; + bool computed_witness = false; // TODO(Luke): use make_shared StandardComposer_() @@ -62,11 +65,6 @@ template class StandardComposer_ { StandardProver_ create_prover(const CircuitBuilder& circuit_constructor); - // TODO(#216)(Adrian): Seems error prone to provide the number of randomized gates - std::shared_ptr compute_proving_key_base(const CircuitBuilder& circuit_constructor, - const size_t minimum_circuit_size = 0, - const size_t num_randomized_gates = NUM_RESERVED_GATES); - void compute_witness(const CircuitBuilder& circuit_constructor, const size_t minimum_circuit_size = 0); void compute_commitment_key(size_t circuit_size, std::shared_ptr crs_factory) diff --git a/cpp/src/barretenberg/honk/composer/ultra_composer.cpp b/cpp/src/barretenberg/honk/composer/ultra_composer.cpp index 9a7c54c19e..b7947e4a82 100644 --- a/cpp/src/barretenberg/honk/composer/ultra_composer.cpp +++ b/cpp/src/barretenberg/honk/composer/ultra_composer.cpp @@ -16,21 +16,10 @@ template void UltraComposer_::compute_witness(Circu return; } - size_t tables_size = 0; - size_t lookups_size = 0; - for (const auto& table : circuit_constructor.lookup_tables) { - tables_size += table.size; - lookups_size += table.lookup_gates.size(); - } - const size_t filled_gates = circuit_constructor.num_gates + circuit_constructor.public_inputs.size(); - const size_t total_num_gates = std::max(filled_gates, tables_size + lookups_size); - - const size_t subgroup_size = circuit_constructor.get_circuit_subgroup_size(total_num_gates + NUM_RESERVED_GATES); // Pad the wires (pointers to `witness_indices` of the `variables` vector). - // Note: the remaining NUM_RESERVED_GATES indices are padded with zeros within `construct_wire_polynomials_base` - // (called next). + // Note: total_num_gates = filled_gates + tables_size for (size_t i = filled_gates; i < total_num_gates; ++i) { circuit_constructor.w_l.emplace_back(circuit_constructor.zero_idx); circuit_constructor.w_r.emplace_back(circuit_constructor.zero_idx); @@ -38,30 +27,24 @@ template void UltraComposer_::compute_witness(Circu circuit_constructor.w_4.emplace_back(circuit_constructor.zero_idx); } - // TODO(#340)(luke): within construct_wire_polynomials_base, the 3rd argument is used in the calculation of the - // dyadic circuit size (subgroup_size). Here (and in other split composers) we're passing in NUM_RESERVED_GATES, - // but elsewhere, e.g. directly above, we use NUM_RESERVED_GATES in a similar role. Therefore, these two constants - // must be equal for everything to be consistent. What we should do is compute the dyadic circuit size once and for - // all then pass that around rather than computing in multiple places. - auto wire_polynomials = - construct_wire_polynomials_base(circuit_constructor, total_num_gates, NUM_RESERVED_GATES); + auto wire_polynomials = construct_wire_polynomials_base(circuit_constructor, total_num_gates); proving_key->w_l = wire_polynomials[0]; proving_key->w_r = wire_polynomials[1]; proving_key->w_o = wire_polynomials[2]; proving_key->w_4 = wire_polynomials[3]; - polynomial s_1(subgroup_size); - polynomial s_2(subgroup_size); - polynomial s_3(subgroup_size); - polynomial s_4(subgroup_size); + polynomial s_1(dyadic_circuit_size); + polynomial s_2(dyadic_circuit_size); + polynomial s_3(dyadic_circuit_size); + polynomial s_4(dyadic_circuit_size); // TODO(luke): The +1 size for z_lookup is not necessary and can lead to confusion. Resolve. - polynomial z_lookup(subgroup_size + 1); // Only instantiated in this function; nothing assigned. + polynomial z_lookup(dyadic_circuit_size + 1); // Only instantiated in this function; nothing assigned. // TODO(kesha): Look at this once we figure out how we do ZK (previously we had roots cut out, so just added // randomness) // The size of empty space in sorted polynomials - size_t count = subgroup_size - tables_size - lookups_size; + size_t count = dyadic_circuit_size - tables_size - lookups_size; ASSERT(count > 0); // We need at least 1 row of zeroes for the permutation argument for (size_t i = 0; i < count; ++i) { s_1[i] = 0; @@ -189,38 +172,32 @@ std::shared_ptr UltraComposer_::compute_pro return proving_key; } - size_t tables_size = 0; - size_t lookups_size = 0; for (const auto& table : circuit_constructor.lookup_tables) { tables_size += table.size; lookups_size += table.lookup_gates.size(); } const size_t minimum_circuit_size = tables_size + lookups_size; - const size_t num_randomized_gates = NUM_RESERVED_GATES; - // Initialize proving_key - // TODO(#392)(Kesha): replace composer types. - proving_key = initialize_proving_key( - circuit_constructor, crs_factory_.get(), minimum_circuit_size, num_randomized_gates); - construct_selector_polynomials(circuit_constructor, proving_key.get()); + num_public_inputs = circuit_constructor.public_inputs.size(); + const size_t num_constraints = circuit_constructor.num_gates + num_public_inputs; + total_num_gates = std::max(minimum_circuit_size, num_constraints); + dyadic_circuit_size = circuit_constructor.get_circuit_subgroup_size(total_num_gates); + + proving_key = std::make_shared(dyadic_circuit_size, num_public_inputs); - // TODO(#217)(luke): Naively enforcing non-zero selectors for Honk will result in some relations not being - // satisfied. - // enforce_nonzero_polynomial_selectors(circuit_constructor, proving_key.get()); + construct_selector_polynomials(circuit_constructor, proving_key.get()); compute_honk_generalized_sigma_permutations(circuit_constructor, proving_key.get()); compute_first_and_last_lagrange_polynomials(proving_key.get()); - const size_t subgroup_size = proving_key->circuit_size; + polynomial poly_q_table_column_1(dyadic_circuit_size); + polynomial poly_q_table_column_2(dyadic_circuit_size); + polynomial poly_q_table_column_3(dyadic_circuit_size); + polynomial poly_q_table_column_4(dyadic_circuit_size); - polynomial poly_q_table_column_1(subgroup_size); - polynomial poly_q_table_column_2(subgroup_size); - polynomial poly_q_table_column_3(subgroup_size); - polynomial poly_q_table_column_4(subgroup_size); - - size_t offset = subgroup_size - tables_size; + size_t offset = dyadic_circuit_size - tables_size; // Create lookup selector polynomials which interpolate each table column. // Our selector polys always need to interpolate the full subgroup size, so here we offset so as to @@ -251,33 +228,6 @@ std::shared_ptr UltraComposer_::compute_pro // Polynomial memory is zeroed out when constructed with size hint, so we don't have to initialize trailing space - // // In the case of using UltraPlonkComposer for a circuit which does _not_ make use of any lookup tables, all - // four - // // table columns would be all zeros. This would result in these polys' commitments all being the point at - // infinity - // // (which is bad because our point arithmetic assumes we'll never operate on the point at infinity). To avoid - // this, - // // we set the last evaluation of each poly to be nonzero. The last `num_roots_cut_out_of_vanishing_poly = 4` - // // evaluations are ignored by constraint checks; we arbitrarily choose the very-last evaluation to be nonzero. - // See - // // ComposerBase::compute_proving_key_base for further explanation, as a similar trick is done there. We could - // // have chosen `1` for each such evaluation here, but that would have resulted in identical commitments for - // // all four columns. We don't want to have equal commitments, because biggroup operations assume no points are - // // equal, so if we tried to verify an ultra proof in a circuit, the biggroup operations would fail. To combat - // // this, we just choose distinct values: - - // TODO(#217)(luke): Similar to the selectors, enforcing non-zero values by inserting an arbitrary final element - // in the table polys will result in lookup relations not being satisfied. Address this with issue #217. - // size_t num_selectors = circuit_constructor.num_selectors; - // ASSERT(offset == subgroup_size - 1); - // auto unique_last_value = num_selectors + 1; // Note: in compute_proving_key_base, moments earlier, each selector - // // vector was given a unique last value from 1..num_selectors. So we - // // avoid those values and continue the count, to ensure uniqueness. - // poly_q_table_column_1[subgroup_size - 1] = unique_last_value; - // poly_q_table_column_2[subgroup_size - 1] = ++unique_last_value; - // poly_q_table_column_3[subgroup_size - 1] = ++unique_last_value; - // poly_q_table_column_4[subgroup_size - 1] = ++unique_last_value; - proving_key->table_1 = poly_q_table_column_1; proving_key->table_2 = poly_q_table_column_2; proving_key->table_3 = poly_q_table_column_3; diff --git a/cpp/src/barretenberg/honk/composer/ultra_composer.hpp b/cpp/src/barretenberg/honk/composer/ultra_composer.hpp index f72eb22c52..e3f4bbf815 100644 --- a/cpp/src/barretenberg/honk/composer/ultra_composer.hpp +++ b/cpp/src/barretenberg/honk/composer/ultra_composer.hpp @@ -22,7 +22,6 @@ template class UltraComposer_ { using PCSVerificationKey = typename PCSParams::VerificationKey; static constexpr std::string_view NAME_STRING = "UltraHonk"; - static constexpr size_t NUM_RESERVED_GATES = 4; // equal to the number of multilinear evaluations leaked static constexpr size_t NUM_WIRES = CircuitBuilder::NUM_WIRES; std::shared_ptr proving_key; std::shared_ptr verification_key; @@ -36,6 +35,11 @@ template class UltraComposer_ { std::vector recursive_proof_public_input_indices; bool contains_recursive_proof = false; bool computed_witness = false; + size_t total_num_gates = 0; // total num gates (the number used to compute dyadic size) + size_t dyadic_circuit_size = 0; // final dyadic circuit size + size_t lookups_size = 0; // total number of lookup gates + size_t tables_size = 0; // total number of table entries + size_t num_public_inputs = 0; UltraComposer_() : crs_factory_(barretenberg::srs::get_crs_factory()){}; diff --git a/cpp/src/barretenberg/honk/composer/ultra_composer.test.cpp b/cpp/src/barretenberg/honk/composer/ultra_composer.test.cpp index 07b35aa259..57b54e1fd2 100644 --- a/cpp/src/barretenberg/honk/composer/ultra_composer.test.cpp +++ b/cpp/src/barretenberg/honk/composer/ultra_composer.test.cpp @@ -85,6 +85,29 @@ TEST_F(UltraHonkComposerTests, ANonZeroPolynomialIsAGoodPolynomial) } } +TEST_F(UltraHonkComposerTests, PublicInputs) +{ + auto builder = UltraCircuitBuilder(); + size_t num_gates = 10; + // TODO(luke): If were going to add any PI, the first has to be zero to ensure shiftable wires. + builder.add_public_variable(0); + + for (size_t i = 0; i < num_gates; ++i) { + fr a = fr::random_element(); + uint32_t a_idx = builder.add_public_variable(a); + fr b = fr::one(); + fr c = fr::random_element(); + fr d = a + b + c; + uint32_t b_idx = builder.add_variable(b); + uint32_t c_idx = builder.add_variable(c); + uint32_t d_idx = builder.add_variable(d); + builder.create_big_add_gate({ a_idx, b_idx, c_idx, d_idx, fr(1), fr(1), fr(1), fr(-1), fr(0) }); + } + + auto composer = UltraComposer(); + prove_and_verify(builder, composer, /*expected_result=*/true); +} + TEST_F(UltraHonkComposerTests, XorConstraint) { auto circuit_constructor = UltraCircuitBuilder(); diff --git a/cpp/src/barretenberg/honk/transcript/transcript.test.cpp b/cpp/src/barretenberg/honk/transcript/transcript.test.cpp index 2749bb1011..4be6488ecb 100644 --- a/cpp/src/barretenberg/honk/transcript/transcript.test.cpp +++ b/cpp/src/barretenberg/honk/transcript/transcript.test.cpp @@ -21,12 +21,12 @@ template class TranscriptTests : public testing::Test { /** * @brief Construct a manifest for a standard Honk proof * - * @details This is where we define the "Manifest" for a Standard Honk proof. The tests in this suite are - intented - * to warn the developer if the Prover/Verifier has deviated from this manifest, however, the Transcript class - is + * @details This is where we define the "Manifest" for a Standard Honk proof. The tests in this suite are intented + * to warn the developer if the Prover/Verifier has deviated from this manifest, however, the Transcript class is * not otherwise contrained to follow the manifest. * + * @note Entries in the manifest consist of a name and a size (bytes), NOT actual data. + * * @return TranscriptManifest */ TranscriptManifest construct_standard_honk_manifest(size_t circuit_size) @@ -40,10 +40,12 @@ template class TranscriptTests : public testing::Test { size_t size_G = 2 * size_FF; size_t size_uni = max_relation_length * size_FF; size_t size_evals = (Flavor::NUM_ALL_ENTITIES)*size_FF; + size_t size_uint32 = 4; + size_t size_uint64 = 8; size_t round = 0; - manifest_expected.add_entry(round, "circuit_size", 4); - manifest_expected.add_entry(round, "public_input_size", 4); + manifest_expected.add_entry(round, "circuit_size", size_uint32); + manifest_expected.add_entry(round, "public_input_size", size_uint32); manifest_expected.add_entry(round, "public_input_0", size_FF); manifest_expected.add_entry(round, "W_1", size_G); manifest_expected.add_entry(round, "W_2", size_G); @@ -87,7 +89,7 @@ template class TranscriptTests : public testing::Test { round++; // TODO(Mara): Make testing more flavor agnostic so we can test this with all flavors if constexpr (IsGrumpkinFlavor) { - manifest_expected.add_entry(round, "IPA:poly_degree", circuit_size); + manifest_expected.add_entry(round, "IPA:poly_degree", size_uint64); manifest_expected.add_challenge(round, "IPA:generator_challenge"); for (size_t i = 0; i < log_n; i++) { diff --git a/cpp/src/barretenberg/proof_system/composer/composer_helper_lib.hpp b/cpp/src/barretenberg/proof_system/composer/composer_helper_lib.hpp deleted file mode 100644 index 9544179766..0000000000 --- a/cpp/src/barretenberg/proof_system/composer/composer_helper_lib.hpp +++ /dev/null @@ -1,179 +0,0 @@ -#pragma once -#include "barretenberg/plonk/proof_system/proving_key/proving_key.hpp" -#include "barretenberg/proof_system/flavor/flavor.hpp" -#include "barretenberg/srs/factories/crs_factory.hpp" -#include - -namespace proof_system { - -/** - * @brief Initilalize proving key and load the crs - * - * @tparam Flavor - * @param circuit_constructor Object containing the circuit - * @param crs_factory Produces the prover's reference string - * @param minimum_circuit_size The minimum size of polynomials without randomized elements - * @param num_randomized_gates Number of gates with randomized witnesses - * @param circuit_type This is passed in the case of Plonk since we use flavor-independent proving and verification keys - * in that case. - * @return std::shared_ptr - */ -template -std::shared_ptr initialize_proving_key( - const typename Flavor::CircuitBuilder& circuit_constructor, - barretenberg::srs::factories::CrsFactory* crs_factory, - const size_t minimum_circuit_size, - const size_t num_randomized_gates, - CircuitType circuit_type = CircuitType::UNDEFINED) -{ - const size_t num_gates = circuit_constructor.num_gates; - std::span public_inputs = circuit_constructor.public_inputs; - - const size_t num_public_inputs = public_inputs.size(); - const size_t num_constraints = num_gates + num_public_inputs; - const size_t total_num_constraints = std::max(minimum_circuit_size, num_constraints); - const size_t subgroup_size = - circuit_constructor.get_circuit_subgroup_size(total_num_constraints + num_randomized_gates); // next power of 2 - - // Differentiate between Honk and Plonk here since Plonk pkey requires crs whereas Honk pkey does not - std::shared_ptr proving_key; - if constexpr (IsHonkFlavor) { - proving_key = std::make_shared(subgroup_size, num_public_inputs); - } else if constexpr (IsPlonkFlavor) { - auto crs = crs_factory->get_prover_crs(subgroup_size + 1); - proving_key = - std::make_shared(subgroup_size, num_public_inputs, crs, circuit_type); - } - - return proving_key; -} - -/** - * @brief Construct selector polynomials from ciruit selector information and put into polynomial cache - * - * @tparam Flavor - * @param circuit_constructor The object holding the circuit - * @param key Pointer to the proving key - */ -template -void construct_selector_polynomials(const typename Flavor::CircuitBuilder& circuit_constructor, - typename Flavor::ProvingKey* proving_key) -{ - const size_t num_public_inputs = circuit_constructor.public_inputs.size(); - // TODO(#398): Loose coupling here! Would rather build up pk from arithmetization - size_t selector_idx = 0; // TODO(#391) zip - for (auto& selector_values : circuit_constructor.selectors) { - ASSERT(proving_key->circuit_size >= selector_values.size()); - - // Copy the selector values for all gates, keeping the rows at which we store public inputs as 0. - // Initializing the polynomials in this way automatically applies 0-padding to the selectors. - barretenberg::polynomial selector_poly_lagrange(proving_key->circuit_size); - for (size_t i = 0; i < selector_values.size(); ++i) { - selector_poly_lagrange[num_public_inputs + i] = selector_values[i]; - } - if constexpr (IsHonkFlavor) { - // TODO(#398): Loose coupling here of arithmetization and flavor. - proving_key->_precomputed_polynomials[selector_idx] = selector_poly_lagrange; - } else if constexpr (IsPlonkFlavor) { - // TODO(Cody): Loose coupling here of selector_names and selector_properties. - proving_key->polynomial_store.put(circuit_constructor.selector_names_[selector_idx] + "_lagrange", - std::move(selector_poly_lagrange)); - } - ++selector_idx; - } -} - -/** - * @brief Fill the last index of each selector polynomial in lagrange form with a non-zero value - * - * @tparam Flavor - * @param circuit_constructor The object holding the circuit - * @param key Pointer to the proving key - * - * @warning We should ensure that this does not clash with any other values we want to place at the end of of the - * witness vectors. In later iterations of the Sumcheck, we will be able to efficiently cancel out any checks in the - * last 2^k rows, so any randomness or unique values should be placed there. -@adr1anh - */ -template -void enforce_nonzero_selector_polynomials(const typename Flavor::CircuitBuilder& circuit_constructor, - typename Flavor::ProvingKey* proving_key) -{ - if constexpr (IsHonkFlavor) { - size_t idx = 1; - for (auto selector : proving_key->get_selectors()) { - selector[selector.size() - 1] = idx; - ++idx; - } - } else if constexpr (IsPlonkFlavor) { - for (size_t idx = 0; idx < circuit_constructor.num_selectors; ++idx) { - auto current_selector = - proving_key->polynomial_store.get(circuit_constructor.selector_names_[idx] + "_lagrange"); - current_selector[current_selector.size() - 1] = idx + 1; - proving_key->polynomial_store.put(circuit_constructor.selector_names_[idx] + "_lagrange", - std::move(current_selector)); - } - } -} - -/** - * @brief Construct the witness polynomials from the witness vectors in the circuit constructor. - * - * @details The first two witness polynomials begin with the public input values. - * - * - * @tparam Flavor provides the circuit constructor type and the number of wires. - * @param circuit_constructor - * @param minimum_circuit_size - * @param number_of_randomized_gates - * - * @return std::vector - * */ -template -std::vector construct_wire_polynomials_base( - const typename Flavor::CircuitBuilder& circuit_constructor, - const size_t minimum_circuit_size, - const size_t number_of_randomized_gates) -{ - const size_t num_gates = circuit_constructor.num_gates; - std::span public_inputs = circuit_constructor.public_inputs; - const size_t num_public_inputs = public_inputs.size(); - - const size_t num_constraints = std::max(minimum_circuit_size, num_gates + num_public_inputs); - // TODO(#216)(Adrian): Not a fan of specifying NUM_RESERVED_GATES everywhere, - // Each flavor of Honk should have a "fixed" number of random places to add randomness to. - // It should be taken care of in as few places possible. - const size_t subgroup_size = - circuit_constructor.get_circuit_subgroup_size(num_constraints + number_of_randomized_gates); - - // construct a view over all the wire's variable indices - // w[j][i] is the index of the variable in the j-th wire, at gate i - // Each array should be of size `num_gates` - - std::vector wire_polynomials; - // Note: randomness is added to 3 of the last 4 positions in plonk/proof_system/prover/prover.cpp - // StandardProverBase::execute_preamble_round(). - size_t wire_idx = 0; // TODO(#391) zip - for (auto& wire : circuit_constructor.wires) { - // Initialize the polynomial with all the actual copies variable values - // Expect all values to be set to 0 initially - barretenberg::polynomial w_lagrange(subgroup_size); - - // Place all public inputs at the start of the first two wires. - // All selectors at these indices are set to 0, so these values are not constrained at all. - if (wire_idx < 2) { - for (size_t i = 0; i < num_public_inputs; ++i) { - w_lagrange[i] = circuit_constructor.get_variable(public_inputs[i]); - } - ++wire_idx; - } - - // Assign the variable values (which are pointed-to by the `w_` wire_polynomials) to the wire witness - // polynomials `poly_w_`, shifted to make room for the public inputs at the beginning. - for (size_t i = 0; i < num_gates; ++i) { - w_lagrange[num_public_inputs + i] = circuit_constructor.get_variable(wire[i]); - } - wire_polynomials.push_back(std::move(w_lagrange)); - } - return wire_polynomials; -} -} // namespace proof_system diff --git a/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp b/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp index 9544179766..babe3e1d43 100644 --- a/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp +++ b/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp @@ -27,9 +27,8 @@ std::shared_ptr initialize_proving_key( CircuitType circuit_type = CircuitType::UNDEFINED) { const size_t num_gates = circuit_constructor.num_gates; - std::span public_inputs = circuit_constructor.public_inputs; - const size_t num_public_inputs = public_inputs.size(); + const size_t num_public_inputs = circuit_constructor.public_inputs.size(); const size_t num_constraints = num_gates + num_public_inputs; const size_t total_num_constraints = std::max(minimum_circuit_size, num_constraints); const size_t subgroup_size = @@ -132,7 +131,7 @@ template std::vector construct_wire_polynomials_base( const typename Flavor::CircuitBuilder& circuit_constructor, const size_t minimum_circuit_size, - const size_t number_of_randomized_gates) + const size_t number_of_randomized_gates = 0) { const size_t num_gates = circuit_constructor.num_gates; std::span public_inputs = circuit_constructor.public_inputs; From 39acaf08a5cee8883540648db847e830dcb5f2be Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Wed, 5 Jul 2023 23:00:57 +0000 Subject: [PATCH 02/13] move init pkey fctn from shared to plonk specific --- .../honk/composer/ultra_composer.test.cpp | 2 +- .../honk/transcript/transcript.test.cpp | 2 +- .../plonk/composer/composer_lib.hpp | 33 +++++++++++++++ .../plonk/composer/standard_composer.cpp | 2 +- .../plonk/composer/turbo_composer.cpp | 2 +- .../plonk/composer/ultra_composer.cpp | 3 +- .../proof_system/composer/composer_lib.hpp | 42 +------------------ 7 files changed, 40 insertions(+), 46 deletions(-) diff --git a/cpp/src/barretenberg/honk/composer/ultra_composer.test.cpp b/cpp/src/barretenberg/honk/composer/ultra_composer.test.cpp index 57b54e1fd2..c24b4d0fef 100644 --- a/cpp/src/barretenberg/honk/composer/ultra_composer.test.cpp +++ b/cpp/src/barretenberg/honk/composer/ultra_composer.test.cpp @@ -89,7 +89,7 @@ TEST_F(UltraHonkComposerTests, PublicInputs) { auto builder = UltraCircuitBuilder(); size_t num_gates = 10; - // TODO(luke): If were going to add any PI, the first has to be zero to ensure shiftable wires. + // TODO(#597)(luke): If were going to add any PI, the first has to be zero to ensure shiftable wires. builder.add_public_variable(0); for (size_t i = 0; i < num_gates; ++i) { diff --git a/cpp/src/barretenberg/honk/transcript/transcript.test.cpp b/cpp/src/barretenberg/honk/transcript/transcript.test.cpp index 4be6488ecb..f3c46576f5 100644 --- a/cpp/src/barretenberg/honk/transcript/transcript.test.cpp +++ b/cpp/src/barretenberg/honk/transcript/transcript.test.cpp @@ -25,7 +25,7 @@ template class TranscriptTests : public testing::Test { * to warn the developer if the Prover/Verifier has deviated from this manifest, however, the Transcript class is * not otherwise contrained to follow the manifest. * - * @note Entries in the manifest consist of a name and a size (bytes), NOT actual data. + * @note Entries in the manifest consist of a name string and a size (bytes), NOT actual data. * * @return TranscriptManifest */ diff --git a/cpp/src/barretenberg/plonk/composer/composer_lib.hpp b/cpp/src/barretenberg/plonk/composer/composer_lib.hpp index 21d32b8ad8..885a52e7b9 100644 --- a/cpp/src/barretenberg/plonk/composer/composer_lib.hpp +++ b/cpp/src/barretenberg/plonk/composer/composer_lib.hpp @@ -9,6 +9,39 @@ struct SelectorProperties { bool requires_lagrange_base_polynomial = false; }; +/** + * @brief Initilalize proving key and load the crs + * + * @param circuit_constructor Object containing the circuit + * @param crs_factory Produces the prover's reference string + * @param minimum_circuit_size The minimum size of polynomials without randomized elements + * @param num_randomized_gates Number of gates with randomized witnesses + * @param circuit_type This is passed in the case of Plonk since we use flavor-independent proving and verification keys + * in that case. + * @return std::shared_ptr + */ +std::shared_ptr initialize_proving_key(const auto& circuit_constructor, + barretenberg::srs::factories::CrsFactory* crs_factory, + const size_t minimum_circuit_size, + const size_t num_randomized_gates, + CircuitType circuit_type) +{ + const size_t num_gates = circuit_constructor.num_gates; + + const size_t num_public_inputs = circuit_constructor.public_inputs.size(); + const size_t num_constraints = num_gates + num_public_inputs; + const size_t total_num_constraints = std::max(minimum_circuit_size, num_constraints); + const size_t subgroup_size = + circuit_constructor.get_circuit_subgroup_size(total_num_constraints + num_randomized_gates); // next power of 2 + + auto crs = crs_factory->get_prover_crs(subgroup_size + 1); + + // Differentiate between Honk and Plonk here since Plonk pkey requires crs whereas Honk pkey does not + auto proving_key = std::make_shared(subgroup_size, num_public_inputs, crs, circuit_type); + + return proving_key; +} + /** * @brief Retrieve lagrange forms of selector polynomials and compute monomial and coset-monomial forms and put into * cache diff --git a/cpp/src/barretenberg/plonk/composer/standard_composer.cpp b/cpp/src/barretenberg/plonk/composer/standard_composer.cpp index c14107dfcc..cbc923ff4f 100644 --- a/cpp/src/barretenberg/plonk/composer/standard_composer.cpp +++ b/cpp/src/barretenberg/plonk/composer/standard_composer.cpp @@ -61,7 +61,7 @@ std::shared_ptr StandardComposer::compute_proving_key(const const size_t num_randomized_gates = NUM_RESERVED_GATES; // Initialize circuit_proving_key // TODO(#392)(Kesha): replace composer types. - circuit_proving_key = proof_system::initialize_proving_key( + circuit_proving_key = initialize_proving_key( circuit_constructor, crs_factory_.get(), minimum_circuit_size, num_randomized_gates, CircuitType::STANDARD); // Compute lagrange selectors construct_selector_polynomials(circuit_constructor, circuit_proving_key.get()); diff --git a/cpp/src/barretenberg/plonk/composer/turbo_composer.cpp b/cpp/src/barretenberg/plonk/composer/turbo_composer.cpp index b4c741d9fa..3583d20bdd 100644 --- a/cpp/src/barretenberg/plonk/composer/turbo_composer.cpp +++ b/cpp/src/barretenberg/plonk/composer/turbo_composer.cpp @@ -36,7 +36,7 @@ std::shared_ptr TurboComposer::compute_proving_key(const Cir const size_t num_randomized_gates = NUM_RESERVED_GATES; // Initialize circuit_proving_key // TODO(#392)(Kesha): replace composer types. - circuit_proving_key = initialize_proving_key( + circuit_proving_key = initialize_proving_key( circuit_constructor, crs_factory_.get(), minimum_circuit_size, num_randomized_gates, CircuitType::TURBO); construct_selector_polynomials(circuit_constructor, circuit_proving_key.get()); diff --git a/cpp/src/barretenberg/plonk/composer/ultra_composer.cpp b/cpp/src/barretenberg/plonk/composer/ultra_composer.cpp index 244bf770a2..c3460efe13 100644 --- a/cpp/src/barretenberg/plonk/composer/ultra_composer.cpp +++ b/cpp/src/barretenberg/plonk/composer/ultra_composer.cpp @@ -1,4 +1,5 @@ #include "ultra_composer.hpp" +#include "barretenberg/plonk/composer/composer_lib.hpp" #include "barretenberg/plonk/proof_system/commitment_scheme/kate_commitment_scheme.hpp" #include "barretenberg/plonk/proof_system/types/program_settings.hpp" #include "barretenberg/plonk/proof_system/types/prover_settings.hpp" @@ -379,7 +380,7 @@ std::shared_ptr UltraComposer::compute_proving_key(CircuitBuilder& const size_t num_randomized_gates = NUM_RESERVED_GATES; // Initialize circuit_proving_key // TODO(#392)(Kesha): replace composer types. - circuit_proving_key = initialize_proving_key( + circuit_proving_key = initialize_proving_key( circuit_constructor, crs_factory_.get(), minimum_circuit_size, num_randomized_gates, CircuitType::ULTRA); construct_selector_polynomials(circuit_constructor, circuit_proving_key.get()); diff --git a/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp b/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp index babe3e1d43..0e6b1d5ab1 100644 --- a/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp +++ b/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp @@ -6,47 +6,6 @@ namespace proof_system { -/** - * @brief Initilalize proving key and load the crs - * - * @tparam Flavor - * @param circuit_constructor Object containing the circuit - * @param crs_factory Produces the prover's reference string - * @param minimum_circuit_size The minimum size of polynomials without randomized elements - * @param num_randomized_gates Number of gates with randomized witnesses - * @param circuit_type This is passed in the case of Plonk since we use flavor-independent proving and verification keys - * in that case. - * @return std::shared_ptr - */ -template -std::shared_ptr initialize_proving_key( - const typename Flavor::CircuitBuilder& circuit_constructor, - barretenberg::srs::factories::CrsFactory* crs_factory, - const size_t minimum_circuit_size, - const size_t num_randomized_gates, - CircuitType circuit_type = CircuitType::UNDEFINED) -{ - const size_t num_gates = circuit_constructor.num_gates; - - const size_t num_public_inputs = circuit_constructor.public_inputs.size(); - const size_t num_constraints = num_gates + num_public_inputs; - const size_t total_num_constraints = std::max(minimum_circuit_size, num_constraints); - const size_t subgroup_size = - circuit_constructor.get_circuit_subgroup_size(total_num_constraints + num_randomized_gates); // next power of 2 - - // Differentiate between Honk and Plonk here since Plonk pkey requires crs whereas Honk pkey does not - std::shared_ptr proving_key; - if constexpr (IsHonkFlavor) { - proving_key = std::make_shared(subgroup_size, num_public_inputs); - } else if constexpr (IsPlonkFlavor) { - auto crs = crs_factory->get_prover_crs(subgroup_size + 1); - proving_key = - std::make_shared(subgroup_size, num_public_inputs, crs, circuit_type); - } - - return proving_key; -} - /** * @brief Construct selector polynomials from ciruit selector information and put into polynomial cache * @@ -59,6 +18,7 @@ void construct_selector_polynomials(const typename Flavor::CircuitBuilder& circu typename Flavor::ProvingKey* proving_key) { const size_t num_public_inputs = circuit_constructor.public_inputs.size(); + // const size_t offset = num_public_inputs + // TODO(#398): Loose coupling here! Would rather build up pk from arithmetization size_t selector_idx = 0; // TODO(#391) zip for (auto& selector_values : circuit_constructor.selectors) { From 77ab4044dcb545d6ce0d67a00be69f9c9b59e41a Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Thu, 6 Jul 2023 10:29:42 +0000 Subject: [PATCH 03/13] clean up witness base --- .../honk/composer/standard_composer.cpp | 2 +- .../honk/composer/ultra_composer.cpp | 2 +- .../plonk/composer/standard_composer.cpp | 10 +- .../plonk/composer/turbo_composer.cpp | 9 +- .../plonk/composer/ultra_composer.cpp | 5 +- .../proof_system/composer/composer_lib.hpp | 23 +-- .../composer/composer_lib.test.cpp | 29 ++-- .../composer/permutation_lib.test.cpp | 136 +++++++++--------- 8 files changed, 106 insertions(+), 110 deletions(-) diff --git a/cpp/src/barretenberg/honk/composer/standard_composer.cpp b/cpp/src/barretenberg/honk/composer/standard_composer.cpp index edc123c1a9..e6d4e7bf3d 100644 --- a/cpp/src/barretenberg/honk/composer/standard_composer.cpp +++ b/cpp/src/barretenberg/honk/composer/standard_composer.cpp @@ -26,7 +26,7 @@ void StandardComposer_::compute_witness(const CircuitBuilder& circuit_co if (computed_witness) { return; } - auto wire_polynomials = construct_wire_polynomials_base(circuit_constructor, minimum_circuit_size); + auto wire_polynomials = construct_wire_polynomials_base(circuit_constructor, dyadic_circuit_size); proving_key->w_l = wire_polynomials[0]; proving_key->w_r = wire_polynomials[1]; diff --git a/cpp/src/barretenberg/honk/composer/ultra_composer.cpp b/cpp/src/barretenberg/honk/composer/ultra_composer.cpp index b7947e4a82..290e8e76f6 100644 --- a/cpp/src/barretenberg/honk/composer/ultra_composer.cpp +++ b/cpp/src/barretenberg/honk/composer/ultra_composer.cpp @@ -27,7 +27,7 @@ template void UltraComposer_::compute_witness(Circu circuit_constructor.w_4.emplace_back(circuit_constructor.zero_idx); } - auto wire_polynomials = construct_wire_polynomials_base(circuit_constructor, total_num_gates); + auto wire_polynomials = construct_wire_polynomials_base(circuit_constructor, dyadic_circuit_size); proving_key->w_l = wire_polynomials[0]; proving_key->w_r = wire_polynomials[1]; diff --git a/cpp/src/barretenberg/plonk/composer/standard_composer.cpp b/cpp/src/barretenberg/plonk/composer/standard_composer.cpp index cbc923ff4f..75e4cd5454 100644 --- a/cpp/src/barretenberg/plonk/composer/standard_composer.cpp +++ b/cpp/src/barretenberg/plonk/composer/standard_composer.cpp @@ -30,8 +30,14 @@ void StandardComposer::compute_witness(const CircuitBuilder& circuit_constructor if (computed_witness) { return; } - auto wire_polynomial_evaluations = - construct_wire_polynomials_base(circuit_constructor, minimum_circuit_size, NUM_RESERVED_GATES); + const size_t num_gates = circuit_constructor.num_gates; + const size_t num_public_inputs = circuit_constructor.public_inputs.size(); + + const size_t num_constraints = std::max(minimum_circuit_size, num_gates + num_public_inputs); + + const size_t subgroup_size = circuit_constructor.get_circuit_subgroup_size(num_constraints + NUM_RESERVED_GATES); + + auto wire_polynomial_evaluations = construct_wire_polynomials_base(circuit_constructor, subgroup_size); for (size_t j = 0; j < program_width; ++j) { std::string index = std::to_string(j + 1); diff --git a/cpp/src/barretenberg/plonk/composer/turbo_composer.cpp b/cpp/src/barretenberg/plonk/composer/turbo_composer.cpp index 3583d20bdd..cf7427cc02 100644 --- a/cpp/src/barretenberg/plonk/composer/turbo_composer.cpp +++ b/cpp/src/barretenberg/plonk/composer/turbo_composer.cpp @@ -94,8 +94,13 @@ void TurboComposer::compute_witness(const CircuitBuilder& circuit_constructor, c if (computed_witness) { return; } - auto wire_polynomial_evaluations = - construct_wire_polynomials_base(circuit_constructor, minimum_circuit_size, NUM_RESERVED_GATES); + const size_t num_gates = circuit_constructor.num_gates; + const size_t num_public_inputs = circuit_constructor.public_inputs.size(); + + const size_t num_constraints = std::max(minimum_circuit_size, num_gates + num_public_inputs); + const size_t subgroup_size = circuit_constructor.get_circuit_subgroup_size(num_constraints + NUM_RESERVED_GATES); + + auto wire_polynomial_evaluations = construct_wire_polynomials_base(circuit_constructor, subgroup_size); for (size_t j = 0; j < program_width; ++j) { std::string index = std::to_string(j + 1); diff --git a/cpp/src/barretenberg/plonk/composer/ultra_composer.cpp b/cpp/src/barretenberg/plonk/composer/ultra_composer.cpp index c3460efe13..7bb519a53c 100644 --- a/cpp/src/barretenberg/plonk/composer/ultra_composer.cpp +++ b/cpp/src/barretenberg/plonk/composer/ultra_composer.cpp @@ -49,10 +49,7 @@ void UltraComposer::compute_witness(CircuitBuilder& circuit_constructor) circuit_constructor.w_4.emplace_back(circuit_constructor.zero_idx); } - // TODO(luke): subgroup size was already computed above but compute_witness_base computes it again. If we pass in - // NUM_RESERVED_GATES (as in the other split composers) the resulting sizes can differ. Reconcile this. - auto wire_polynomial_evaluations = - construct_wire_polynomials_base(circuit_constructor, total_num_gates, NUM_RESERVED_GATES); + auto wire_polynomial_evaluations = construct_wire_polynomials_base(circuit_constructor, subgroup_size); for (size_t j = 0; j < program_width; ++j) { std::string index = std::to_string(j + 1); diff --git a/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp b/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp index 0e6b1d5ab1..cdcc41e7b3 100644 --- a/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp +++ b/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp @@ -82,32 +82,17 @@ void enforce_nonzero_selector_polynomials(const typename Flavor::CircuitBuilder& * * @tparam Flavor provides the circuit constructor type and the number of wires. * @param circuit_constructor - * @param minimum_circuit_size - * @param number_of_randomized_gates + * @param dyadic_circuit_size Power of 2 circuit size * * @return std::vector * */ template std::vector construct_wire_polynomials_base( - const typename Flavor::CircuitBuilder& circuit_constructor, - const size_t minimum_circuit_size, - const size_t number_of_randomized_gates = 0) + const typename Flavor::CircuitBuilder& circuit_constructor, const size_t dyadic_circuit_size) { - const size_t num_gates = circuit_constructor.num_gates; std::span public_inputs = circuit_constructor.public_inputs; const size_t num_public_inputs = public_inputs.size(); - const size_t num_constraints = std::max(minimum_circuit_size, num_gates + num_public_inputs); - // TODO(#216)(Adrian): Not a fan of specifying NUM_RESERVED_GATES everywhere, - // Each flavor of Honk should have a "fixed" number of random places to add randomness to. - // It should be taken care of in as few places possible. - const size_t subgroup_size = - circuit_constructor.get_circuit_subgroup_size(num_constraints + number_of_randomized_gates); - - // construct a view over all the wire's variable indices - // w[j][i] is the index of the variable in the j-th wire, at gate i - // Each array should be of size `num_gates` - std::vector wire_polynomials; // Note: randomness is added to 3 of the last 4 positions in plonk/proof_system/prover/prover.cpp // StandardProverBase::execute_preamble_round(). @@ -115,7 +100,7 @@ std::vector construct_wire_polynomials_base( for (auto& wire : circuit_constructor.wires) { // Initialize the polynomial with all the actual copies variable values // Expect all values to be set to 0 initially - barretenberg::polynomial w_lagrange(subgroup_size); + barretenberg::polynomial w_lagrange(dyadic_circuit_size); // Place all public inputs at the start of the first two wires. // All selectors at these indices are set to 0, so these values are not constrained at all. @@ -128,7 +113,7 @@ std::vector construct_wire_polynomials_base( // Assign the variable values (which are pointed-to by the `w_` wire_polynomials) to the wire witness // polynomials `poly_w_`, shifted to make room for the public inputs at the beginning. - for (size_t i = 0; i < num_gates; ++i) { + for (size_t i = 0; i < circuit_constructor.num_gates; ++i) { w_lagrange[num_public_inputs + i] = circuit_constructor.get_variable(wire[i]); } wire_polynomials.push_back(std::move(w_lagrange)); diff --git a/cpp/src/barretenberg/proof_system/composer/composer_lib.test.cpp b/cpp/src/barretenberg/proof_system/composer/composer_lib.test.cpp index 45d1a81844..1dbbde6987 100644 --- a/cpp/src/barretenberg/proof_system/composer/composer_lib.test.cpp +++ b/cpp/src/barretenberg/proof_system/composer/composer_lib.test.cpp @@ -20,21 +20,21 @@ class ComposerLibTests : public ::testing::Test { }(); }; -TEST_F(ComposerLibTests, InitializeProvingKey) -{ - static_assert(IsHonkFlavor); +// TEST_F(ComposerLibTests, InitializeProvingKey) +// { +// static_assert(IsHonkFlavor); - EXPECT_EQ(circuit_constructor.get_circuit_subgroup_size(7), 8); +// EXPECT_EQ(circuit_constructor.get_circuit_subgroup_size(7), 8); - barretenberg::srs::factories::CrsFactory crs_factory; +// barretenberg::srs::factories::CrsFactory crs_factory; - auto pk = initialize_proving_key(circuit_constructor, - &crs_factory, - /*minimum_circuit_size=*/0, - /*num_randomized_gates=*/2); - EXPECT_EQ(pk->circuit_size, 8); - EXPECT_EQ(pk->num_public_inputs, 0); -} +// auto pk = initialize_proving_key(circuit_constructor, +// &crs_factory, +// /*minimum_circuit_size=*/0, +// /*num_randomized_gates=*/2); +// EXPECT_EQ(pk->circuit_size, 8); +// EXPECT_EQ(pk->num_public_inputs, 0); +// } TEST_F(ComposerLibTests, ConstructSelectors) { @@ -128,7 +128,10 @@ TEST_F(ComposerLibTests, ConstructWitnessPolynomialsBase) */ - auto wires = construct_wire_polynomials_base(circuit_constructor, 1, 2); + const size_t dyadic_circuit_size = circuit_constructor.get_circuit_subgroup_size( + circuit_constructor.num_gates + circuit_constructor.public_inputs.size()); + + auto wires = construct_wire_polynomials_base(circuit_constructor, dyadic_circuit_size); auto& w_l = wires[0]; auto& w_r = wires[1]; auto& w_o = wires[2]; diff --git a/cpp/src/barretenberg/proof_system/composer/permutation_lib.test.cpp b/cpp/src/barretenberg/proof_system/composer/permutation_lib.test.cpp index 80aa86f13b..12cdf7c47a 100644 --- a/cpp/src/barretenberg/proof_system/composer/permutation_lib.test.cpp +++ b/cpp/src/barretenberg/proof_system/composer/permutation_lib.test.cpp @@ -8,84 +8,84 @@ namespace proof_system::test_composer_lib { -class PermutationHelperTests : public ::testing::Test { - protected: - using Flavor = honk::flavor::Standard; - using FF = typename Flavor::FF; - Flavor::CircuitBuilder circuit_constructor; - barretenberg::srs::factories::CrsFactory crs_factory = barretenberg::srs::factories::CrsFactory(); - std::shared_ptr proving_key; +// class PermutationHelperTests : public ::testing::Test { +// protected: +// using Flavor = honk::flavor::Standard; +// using FF = typename Flavor::FF; +// Flavor::CircuitBuilder circuit_constructor; +// barretenberg::srs::factories::CrsFactory crs_factory = barretenberg::srs::factories::CrsFactory(); +// std::shared_ptr proving_key; - virtual void SetUp() - { - circuit_constructor.add_public_variable(1024); - circuit_constructor.add_public_variable(1025); +// virtual void SetUp() +// { +// circuit_constructor.add_public_variable(1024); +// circuit_constructor.add_public_variable(1025); - uint32_t v_1 = circuit_constructor.add_variable(16 + 1); - uint32_t v_2 = circuit_constructor.add_variable(16 + 2); - uint32_t v_3 = circuit_constructor.add_variable(16 + 3); - uint32_t v_4 = circuit_constructor.add_variable(16 + 4); - uint32_t v_5 = circuit_constructor.add_variable(16 + 5); - uint32_t v_6 = circuit_constructor.add_variable(16 + 6); - uint32_t v_7 = circuit_constructor.add_variable(16 + 7); - uint32_t v_8 = circuit_constructor.add_variable(16 + 8); - uint32_t v_9 = circuit_constructor.add_variable(16 + 9); - uint32_t v_10 = circuit_constructor.add_variable(16 + 10); - uint32_t v_11 = circuit_constructor.add_variable(16 + 11); - uint32_t v_12 = circuit_constructor.add_variable(16 + 12); +// uint32_t v_1 = circuit_constructor.add_variable(16 + 1); +// uint32_t v_2 = circuit_constructor.add_variable(16 + 2); +// uint32_t v_3 = circuit_constructor.add_variable(16 + 3); +// uint32_t v_4 = circuit_constructor.add_variable(16 + 4); +// uint32_t v_5 = circuit_constructor.add_variable(16 + 5); +// uint32_t v_6 = circuit_constructor.add_variable(16 + 6); +// uint32_t v_7 = circuit_constructor.add_variable(16 + 7); +// uint32_t v_8 = circuit_constructor.add_variable(16 + 8); +// uint32_t v_9 = circuit_constructor.add_variable(16 + 9); +// uint32_t v_10 = circuit_constructor.add_variable(16 + 10); +// uint32_t v_11 = circuit_constructor.add_variable(16 + 11); +// uint32_t v_12 = circuit_constructor.add_variable(16 + 12); - circuit_constructor.create_add_gate({ v_1, v_5, v_9, 0, 0, 0, 0 }); - circuit_constructor.create_add_gate({ v_2, v_6, v_10, 0, 0, 0, 0 }); - circuit_constructor.create_add_gate({ v_3, v_7, v_11, 0, 0, 0, 0 }); - circuit_constructor.create_add_gate({ v_4, v_8, v_12, 0, 0, 0, 0 }); +// circuit_constructor.create_add_gate({ v_1, v_5, v_9, 0, 0, 0, 0 }); +// circuit_constructor.create_add_gate({ v_2, v_6, v_10, 0, 0, 0, 0 }); +// circuit_constructor.create_add_gate({ v_3, v_7, v_11, 0, 0, 0, 0 }); +// circuit_constructor.create_add_gate({ v_4, v_8, v_12, 0, 0, 0, 0 }); - /* Execution trace: - w_l w_r w_o - ------------------------------ - pub1_idx | pub1_idx | 0 <-- public inputs - pub2_idx | pub2_idx | 0 <-/ - zero_idx | zero_idx | zero_idx <-- fix witness for 0 - one_idx | zero_idx | zero_idx <-- fix witness for 1 - one_idx | one_idx | one_idx <-- ensure nonzero selectors... TODO(Cody): redundant now - v_1 | v_5 | v_9 - v_2 | v_6 | v_10 - v_3 | v_7 | v_11 - v_4 | v_8 | v_12 +// /* Execution trace: +// w_l w_r w_o +// ------------------------------ +// pub1_idx | pub1_idx | 0 <-- public inputs +// pub2_idx | pub2_idx | 0 <-/ +// zero_idx | zero_idx | zero_idx <-- fix witness for 0 +// one_idx | zero_idx | zero_idx <-- fix witness for 1 +// one_idx | one_idx | one_idx <-- ensure nonzero selectors... TODO(Cody): redundant now +// v_1 | v_5 | v_9 +// v_2 | v_6 | v_10 +// v_3 | v_7 | v_11 +// v_4 | v_8 | v_12 - */ +// */ - proving_key = initialize_proving_key(circuit_constructor, &crs_factory, 0, 2); +// proving_key = initialize_proving_key(circuit_constructor, &crs_factory, 0, 2); - // construct_selector_polynomials(circuit_constructor, proving_key.get()); - } -}; +// // construct_selector_polynomials(circuit_constructor, proving_key.get()); +// } +// }; -TEST_F(PermutationHelperTests, ComputeWireCopyCycles) -{ - // TODO(#425) Flesh out these tests - compute_wire_copy_cycles(circuit_constructor); -} +// TEST_F(PermutationHelperTests, ComputeWireCopyCycles) +// { +// // TODO(#425) Flesh out these tests +// compute_wire_copy_cycles(circuit_constructor); +// } -TEST_F(PermutationHelperTests, ComputePermutationMapping) -{ - // TODO(#425) Flesh out these tests - compute_permutation_mapping(circuit_constructor, proving_key.get()); -} +// TEST_F(PermutationHelperTests, ComputePermutationMapping) +// { +// // TODO(#425) Flesh out these tests +// compute_permutation_mapping(circuit_constructor, proving_key.get()); +// } -TEST_F(PermutationHelperTests, ComputeHonkStyleSigmaLagrangePolynomialsFromMapping) -{ - // TODO(#425) Flesh out these tests - auto mapping = compute_permutation_mapping(circuit_constructor, proving_key.get()); - compute_honk_style_permutation_lagrange_polynomials_from_mapping( - proving_key->get_sigma_polynomials(), mapping.sigmas, proving_key.get()); -} +// TEST_F(PermutationHelperTests, ComputeHonkStyleSigmaLagrangePolynomialsFromMapping) +// { +// // TODO(#425) Flesh out these tests +// auto mapping = compute_permutation_mapping(circuit_constructor, +// proving_key.get()); compute_honk_style_permutation_lagrange_polynomials_from_mapping( +// proving_key->get_sigma_polynomials(), mapping.sigmas, proving_key.get()); +// } -TEST_F(PermutationHelperTests, ComputeStandardAuxPolynomials) -{ - // TODO(#425) Flesh out these tests - compute_standard_honk_id_polynomials(proving_key); - compute_standard_honk_sigma_permutations(circuit_constructor, proving_key.get()); - compute_first_and_last_lagrange_polynomials(proving_key); -} +// TEST_F(PermutationHelperTests, ComputeStandardAuxPolynomials) +// { +// // TODO(#425) Flesh out these tests +// compute_standard_honk_id_polynomials(proving_key); +// compute_standard_honk_sigma_permutations(circuit_constructor, proving_key.get()); +// compute_first_and_last_lagrange_polynomials(proving_key); +// } } // namespace proof_system::test_composer_lib From a286c857e030b2f59edbcb46b59c18a51d887f6d Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Thu, 6 Jul 2023 10:46:37 +0000 Subject: [PATCH 04/13] move size param setting outside pkey --- .../honk/composer/standard_composer.cpp | 8 +++---- .../honk/composer/standard_composer.test.cpp | 15 +++++++----- .../honk/composer/ultra_composer.cpp | 24 +++++++++---------- 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/cpp/src/barretenberg/honk/composer/standard_composer.cpp b/cpp/src/barretenberg/honk/composer/standard_composer.cpp index e6d4e7bf3d..e3a528feae 100644 --- a/cpp/src/barretenberg/honk/composer/standard_composer.cpp +++ b/cpp/src/barretenberg/honk/composer/standard_composer.cpp @@ -50,10 +50,6 @@ std::shared_ptr StandardComposer_::compute_ return proving_key; } - num_public_inputs = circuit_constructor.public_inputs.size(); - total_num_gates = circuit_constructor.num_gates + num_public_inputs; - dyadic_circuit_size = circuit_constructor.get_circuit_subgroup_size(total_num_gates); - proving_key = std::make_shared(dyadic_circuit_size, num_public_inputs); // Compute lagrange selectors @@ -119,6 +115,10 @@ StandardVerifier_ StandardComposer_::create_verifier(const Circu template StandardProver_ StandardComposer_::create_prover(const CircuitBuilder& circuit_constructor) { + num_public_inputs = circuit_constructor.public_inputs.size(); + total_num_gates = circuit_constructor.num_gates + num_public_inputs; + dyadic_circuit_size = circuit_constructor.get_circuit_subgroup_size(total_num_gates); + compute_proving_key(circuit_constructor); compute_witness(circuit_constructor); diff --git a/cpp/src/barretenberg/honk/composer/standard_composer.test.cpp b/cpp/src/barretenberg/honk/composer/standard_composer.test.cpp index c58426f69f..36dce4e305 100644 --- a/cpp/src/barretenberg/honk/composer/standard_composer.test.cpp +++ b/cpp/src/barretenberg/honk/composer/standard_composer.test.cpp @@ -33,7 +33,9 @@ class StandardHonkComposerTests : public ::testing::Test { TEST_F(StandardHonkComposerTests, SigmaIDCorrectness) { auto test_permutation = [](StandardCircuitBuilder& circuit_constructor, StandardComposer& composer) { - auto proving_key = composer.compute_proving_key(circuit_constructor); + auto prover = composer.create_prover(circuit_constructor); + auto proving_key = prover.key; + const auto n = proving_key->circuit_size; auto public_inputs = circuit_constructor.get_public_inputs(); @@ -71,9 +73,6 @@ TEST_F(StandardHonkComposerTests, SigmaIDCorrectness) left = barretenberg::fr::one(); right = barretenberg::fr::one(); - // Now let's check that witness values correspond to the permutation - composer.compute_witness(circuit_constructor); - auto permutation_polynomials = proving_key->get_sigma_polynomials(); auto id_polynomials = proving_key->get_id_polynomials(); auto wire_polynomials = proving_key->get_wires(); @@ -164,7 +163,9 @@ TEST_F(StandardHonkComposerTests, LagrangeCorrectness) // Generate proving key auto composer = StandardComposer(); - auto proving_key = composer.compute_proving_key(circuit_constructor); + auto prover = composer.create_prover(circuit_constructor); + auto proving_key = prover.key; + // Generate a random polynomial barretenberg::polynomial random_polynomial = barretenberg::polynomial(proving_key->circuit_size); for (size_t i = 0; i < proving_key->circuit_size; i++) { @@ -225,7 +226,9 @@ TEST_F(StandardHonkComposerTests, AssertEquals) */ auto get_maximum_cycle = [](auto& circuit_constructor, auto& composer) { // Compute the proving key for sigma polynomials - auto proving_key = composer.compute_proving_key(circuit_constructor); + auto prover = composer.create_prover(circuit_constructor); + auto proving_key = prover.key; + auto permutation_length = composer.NUM_WIRES * proving_key->circuit_size; auto sigma_polynomials = proving_key->get_sigma_polynomials(); diff --git a/cpp/src/barretenberg/honk/composer/ultra_composer.cpp b/cpp/src/barretenberg/honk/composer/ultra_composer.cpp index 290e8e76f6..3edaf6df94 100644 --- a/cpp/src/barretenberg/honk/composer/ultra_composer.cpp +++ b/cpp/src/barretenberg/honk/composer/ultra_composer.cpp @@ -134,6 +134,18 @@ UltraProver_ UltraComposer_::create_prover(CircuitBuilder& circu circuit_constructor.add_gates_to_ensure_all_polys_are_non_zero(); circuit_constructor.finalize_circuit(); + for (const auto& table : circuit_constructor.lookup_tables) { + tables_size += table.size; + lookups_size += table.lookup_gates.size(); + } + + const size_t minimum_circuit_size = tables_size + lookups_size; + + num_public_inputs = circuit_constructor.public_inputs.size(); + const size_t num_constraints = circuit_constructor.num_gates + num_public_inputs; + total_num_gates = std::max(minimum_circuit_size, num_constraints); + dyadic_circuit_size = circuit_constructor.get_circuit_subgroup_size(total_num_gates); + compute_proving_key(circuit_constructor); compute_witness(circuit_constructor); @@ -172,18 +184,6 @@ std::shared_ptr UltraComposer_::compute_pro return proving_key; } - for (const auto& table : circuit_constructor.lookup_tables) { - tables_size += table.size; - lookups_size += table.lookup_gates.size(); - } - - const size_t minimum_circuit_size = tables_size + lookups_size; - - num_public_inputs = circuit_constructor.public_inputs.size(); - const size_t num_constraints = circuit_constructor.num_gates + num_public_inputs; - total_num_gates = std::max(minimum_circuit_size, num_constraints); - dyadic_circuit_size = circuit_constructor.get_circuit_subgroup_size(total_num_gates); - proving_key = std::make_shared(dyadic_circuit_size, num_public_inputs); construct_selector_polynomials(circuit_constructor, proving_key.get()); From 0ed5ebb24a6be4ec0f9a1b1b2b2eb5e3d2e1e333 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Thu, 6 Jul 2023 12:21:29 +0000 Subject: [PATCH 05/13] move enforce zero to plonk --- .../plonk/composer/composer_lib.hpp | 18 ++++++++++ .../plonk/composer/standard_composer.cpp | 2 +- .../plonk/composer/turbo_composer.cpp | 2 +- .../plonk/composer/ultra_composer.cpp | 2 +- .../proof_system/composer/composer_lib.hpp | 32 ----------------- .../composer/composer_lib.test.cpp | 34 +++++++++---------- 6 files changed, 38 insertions(+), 52 deletions(-) diff --git a/cpp/src/barretenberg/plonk/composer/composer_lib.hpp b/cpp/src/barretenberg/plonk/composer/composer_lib.hpp index 885a52e7b9..d24ca45279 100644 --- a/cpp/src/barretenberg/plonk/composer/composer_lib.hpp +++ b/cpp/src/barretenberg/plonk/composer/composer_lib.hpp @@ -42,6 +42,24 @@ std::shared_ptr initialize_proving_key(const auto& circuit_c return proving_key; } +/** + * @brief Fill the last index of each selector polynomial in lagrange form with a non-zero value + * + * @tparam Flavor + * @param circuit_constructor The object holding the circuit + * @param key Pointer to the proving key + */ +void enforce_nonzero_selector_polynomials(const auto& circuit_constructor, auto* proving_key) +{ + for (size_t idx = 0; idx < circuit_constructor.num_selectors; ++idx) { + auto current_selector = + proving_key->polynomial_store.get(circuit_constructor.selector_names_[idx] + "_lagrange"); + current_selector[current_selector.size() - 1] = idx + 1; + proving_key->polynomial_store.put(circuit_constructor.selector_names_[idx] + "_lagrange", + std::move(current_selector)); + } +} + /** * @brief Retrieve lagrange forms of selector polynomials and compute monomial and coset-monomial forms and put into * cache diff --git a/cpp/src/barretenberg/plonk/composer/standard_composer.cpp b/cpp/src/barretenberg/plonk/composer/standard_composer.cpp index 75e4cd5454..97439bf798 100644 --- a/cpp/src/barretenberg/plonk/composer/standard_composer.cpp +++ b/cpp/src/barretenberg/plonk/composer/standard_composer.cpp @@ -72,7 +72,7 @@ std::shared_ptr StandardComposer::compute_proving_key(const // Compute lagrange selectors construct_selector_polynomials(circuit_constructor, circuit_proving_key.get()); // Make all selectors nonzero - enforce_nonzero_selector_polynomials(circuit_constructor, circuit_proving_key.get()); + enforce_nonzero_selector_polynomials(circuit_constructor, circuit_proving_key.get()); // Compute selectors in monomial form compute_monomial_and_coset_selector_forms(circuit_proving_key.get(), standard_selector_properties()); diff --git a/cpp/src/barretenberg/plonk/composer/turbo_composer.cpp b/cpp/src/barretenberg/plonk/composer/turbo_composer.cpp index cf7427cc02..9c6937adb8 100644 --- a/cpp/src/barretenberg/plonk/composer/turbo_composer.cpp +++ b/cpp/src/barretenberg/plonk/composer/turbo_composer.cpp @@ -41,7 +41,7 @@ std::shared_ptr TurboComposer::compute_proving_key(const Cir construct_selector_polynomials(circuit_constructor, circuit_proving_key.get()); - enforce_nonzero_selector_polynomials(circuit_constructor, circuit_proving_key.get()); + enforce_nonzero_selector_polynomials(circuit_constructor, circuit_proving_key.get()); compute_monomial_and_coset_selector_forms(circuit_proving_key.get(), turbo_selector_properties()); diff --git a/cpp/src/barretenberg/plonk/composer/ultra_composer.cpp b/cpp/src/barretenberg/plonk/composer/ultra_composer.cpp index 7bb519a53c..7b0ded945c 100644 --- a/cpp/src/barretenberg/plonk/composer/ultra_composer.cpp +++ b/cpp/src/barretenberg/plonk/composer/ultra_composer.cpp @@ -382,7 +382,7 @@ std::shared_ptr UltraComposer::compute_proving_key(CircuitBuilder& construct_selector_polynomials(circuit_constructor, circuit_proving_key.get()); - enforce_nonzero_selector_polynomials(circuit_constructor, circuit_proving_key.get()); + enforce_nonzero_selector_polynomials(circuit_constructor, circuit_proving_key.get()); compute_monomial_and_coset_selector_forms(circuit_proving_key.get(), ultra_selector_properties()); diff --git a/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp b/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp index cdcc41e7b3..e64da42ffa 100644 --- a/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp +++ b/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp @@ -42,38 +42,6 @@ void construct_selector_polynomials(const typename Flavor::CircuitBuilder& circu } } -/** - * @brief Fill the last index of each selector polynomial in lagrange form with a non-zero value - * - * @tparam Flavor - * @param circuit_constructor The object holding the circuit - * @param key Pointer to the proving key - * - * @warning We should ensure that this does not clash with any other values we want to place at the end of of the - * witness vectors. In later iterations of the Sumcheck, we will be able to efficiently cancel out any checks in the - * last 2^k rows, so any randomness or unique values should be placed there. -@adr1anh - */ -template -void enforce_nonzero_selector_polynomials(const typename Flavor::CircuitBuilder& circuit_constructor, - typename Flavor::ProvingKey* proving_key) -{ - if constexpr (IsHonkFlavor) { - size_t idx = 1; - for (auto selector : proving_key->get_selectors()) { - selector[selector.size() - 1] = idx; - ++idx; - } - } else if constexpr (IsPlonkFlavor) { - for (size_t idx = 0; idx < circuit_constructor.num_selectors; ++idx) { - auto current_selector = - proving_key->polynomial_store.get(circuit_constructor.selector_names_[idx] + "_lagrange"); - current_selector[current_selector.size() - 1] = idx + 1; - proving_key->polynomial_store.put(circuit_constructor.selector_names_[idx] + "_lagrange", - std::move(current_selector)); - } - } -} - /** * @brief Construct the witness polynomials from the witness vectors in the circuit constructor. * diff --git a/cpp/src/barretenberg/proof_system/composer/composer_lib.test.cpp b/cpp/src/barretenberg/proof_system/composer/composer_lib.test.cpp index 1dbbde6987..0ac0c6910e 100644 --- a/cpp/src/barretenberg/proof_system/composer/composer_lib.test.cpp +++ b/cpp/src/barretenberg/proof_system/composer/composer_lib.test.cpp @@ -72,23 +72,23 @@ TEST_F(ComposerLibTests, ConstructSelectors) EXPECT_EQ(proving_key.q_c[3], 20); } -TEST_F(ComposerLibTests, EnforceNonzeroSelectors) -{ - circuit_constructor.q_m = { 0, 0, 0, 0 }; - circuit_constructor.q_1 = { 0, 0, 0, 0 }; - circuit_constructor.q_2 = { 0, 0, 0, 0 }; - circuit_constructor.q_3 = { 0, 0, 0, 0 }; - circuit_constructor.q_c = { 0, 0, 0, 0 }; - - construct_selector_polynomials(circuit_constructor, &proving_key); - enforce_nonzero_selector_polynomials(circuit_constructor, &proving_key); - - EXPECT_EQ(proving_key.q_m[3], 1); - EXPECT_EQ(proving_key.q_l[3], 2); - EXPECT_EQ(proving_key.q_r[3], 3); - EXPECT_EQ(proving_key.q_o[3], 4); - EXPECT_EQ(proving_key.q_c[3], 5); -} +// TEST_F(ComposerLibTests, EnforceNonzeroSelectors) +// { +// circuit_constructor.q_m = { 0, 0, 0, 0 }; +// circuit_constructor.q_1 = { 0, 0, 0, 0 }; +// circuit_constructor.q_2 = { 0, 0, 0, 0 }; +// circuit_constructor.q_3 = { 0, 0, 0, 0 }; +// circuit_constructor.q_c = { 0, 0, 0, 0 }; + +// construct_selector_polynomials(circuit_constructor, &proving_key); +// enforce_nonzero_selector_polynomials(circuit_constructor, &proving_key); + +// EXPECT_EQ(proving_key.q_m[3], 1); +// EXPECT_EQ(proving_key.q_l[3], 2); +// EXPECT_EQ(proving_key.q_r[3], 3); +// EXPECT_EQ(proving_key.q_o[3], 4); +// EXPECT_EQ(proving_key.q_c[3], 5); +// } TEST_F(ComposerLibTests, ConstructWitnessPolynomialsBase) { From 841a7b5c681418493dca66f5f62944d235d44331 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Thu, 6 Jul 2023 13:42:02 +0000 Subject: [PATCH 06/13] add pub input 0 by default --- cpp/src/barretenberg/honk/composer/ultra_composer.test.cpp | 2 +- .../proof_system/circuit_builder/ultra_circuit_builder.hpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/cpp/src/barretenberg/honk/composer/ultra_composer.test.cpp b/cpp/src/barretenberg/honk/composer/ultra_composer.test.cpp index c24b4d0fef..c534965a79 100644 --- a/cpp/src/barretenberg/honk/composer/ultra_composer.test.cpp +++ b/cpp/src/barretenberg/honk/composer/ultra_composer.test.cpp @@ -90,7 +90,7 @@ TEST_F(UltraHonkComposerTests, PublicInputs) auto builder = UltraCircuitBuilder(); size_t num_gates = 10; // TODO(#597)(luke): If were going to add any PI, the first has to be zero to ensure shiftable wires. - builder.add_public_variable(0); + // builder.add_public_variable(0); for (size_t i = 0; i < num_gates; ++i) { fr a = fr::random_element(); diff --git a/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp b/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp index 5fd3e06da1..cdc886b9ca 100644 --- a/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp +++ b/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp @@ -587,6 +587,7 @@ template class UltraCircuitBuilder_ : public CircuitBuilderBaseadd_public_variable(FF::zero()); this->zero_idx = put_constant_variable(FF::zero()); this->tau.insert({ DUMMY_TAG, DUMMY_TAG }); // TODO(luke): explain this }; From de27e4dab8bdb04843c924a6fd5962fe539c9ff4 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Thu, 6 Jul 2023 21:48:40 +0000 Subject: [PATCH 07/13] set circuit size params within a function --- .../honk/composer/ultra_composer.cpp | 47 ++++++++++++++----- .../honk/composer/ultra_composer.hpp | 4 ++ 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/cpp/src/barretenberg/honk/composer/ultra_composer.cpp b/cpp/src/barretenberg/honk/composer/ultra_composer.cpp index 3edaf6df94..704502d217 100644 --- a/cpp/src/barretenberg/honk/composer/ultra_composer.cpp +++ b/cpp/src/barretenberg/honk/composer/ultra_composer.cpp @@ -6,6 +6,38 @@ namespace proof_system::honk { +/** + * @brief Helper method to compute quantities like total number of gates and dyadic circuit size + * + * @tparam Flavor + * @param circuit_constructor + */ +template +void UltraComposer_::compute_circuit_size_parameters(CircuitBuilder& circuit_constructor) +{ + // Compute total length of the tables and the number of lookup gates; their sum is the minimum circuit size + for (const auto& table : circuit_constructor.lookup_tables) { + tables_size += table.size; + lookups_size += table.lookup_gates.size(); + } + + const size_t num_gates = circuit_constructor.num_gates; + num_public_inputs = circuit_constructor.public_inputs.size(); + + // minimum circuit size due to the length of lookups plus tables + const size_t minimum_circuit_size = tables_size + lookups_size + zero_wire_offset; + + // number of populated rows in the execution trace + filled_gates = circuit_constructor.num_gates + circuit_constructor.public_inputs.size() + zero_wire_offset; + + // The number of gates is max(lookup gates + tables, all gates) + 1, where the +1 is due to the addition of a + // "zero row" at the top of the execution trace to ensure wire and other polynomials are shiftable. + total_num_gates = std::max(minimum_circuit_size, filled_gates); + + // Next power of 2 + dyadic_circuit_size = circuit_constructor.get_circuit_subgroup_size(total_num_gates); +} + /** * @brief Compute witness polynomials * @@ -16,8 +48,6 @@ template void UltraComposer_::compute_witness(Circu return; } - const size_t filled_gates = circuit_constructor.num_gates + circuit_constructor.public_inputs.size(); - // Pad the wires (pointers to `witness_indices` of the `variables` vector). // Note: total_num_gates = filled_gates + tables_size for (size_t i = filled_gates; i < total_num_gates; ++i) { @@ -134,17 +164,8 @@ UltraProver_ UltraComposer_::create_prover(CircuitBuilder& circu circuit_constructor.add_gates_to_ensure_all_polys_are_non_zero(); circuit_constructor.finalize_circuit(); - for (const auto& table : circuit_constructor.lookup_tables) { - tables_size += table.size; - lookups_size += table.lookup_gates.size(); - } - - const size_t minimum_circuit_size = tables_size + lookups_size; - - num_public_inputs = circuit_constructor.public_inputs.size(); - const size_t num_constraints = circuit_constructor.num_gates + num_public_inputs; - total_num_gates = std::max(minimum_circuit_size, num_constraints); - dyadic_circuit_size = circuit_constructor.get_circuit_subgroup_size(total_num_gates); + // Compute total number of gates, dyadic circuit size, etc. + compute_circuit_size_parameters(circuit_constructor); compute_proving_key(circuit_constructor); compute_witness(circuit_constructor); diff --git a/cpp/src/barretenberg/honk/composer/ultra_composer.hpp b/cpp/src/barretenberg/honk/composer/ultra_composer.hpp index e3f4bbf815..a08f58225d 100644 --- a/cpp/src/barretenberg/honk/composer/ultra_composer.hpp +++ b/cpp/src/barretenberg/honk/composer/ultra_composer.hpp @@ -36,10 +36,12 @@ template class UltraComposer_ { bool contains_recursive_proof = false; bool computed_witness = false; size_t total_num_gates = 0; // total num gates (the number used to compute dyadic size) + size_t filled_gates = 0; // num_gates + num_public_inputs + zero_wire_offset size_t dyadic_circuit_size = 0; // final dyadic circuit size size_t lookups_size = 0; // total number of lookup gates size_t tables_size = 0; // total number of table entries size_t num_public_inputs = 0; + const size_t zero_wire_offset = 1; // offset due to placing zero wires at the start of execution trace UltraComposer_() : crs_factory_(barretenberg::srs::get_crs_factory()){}; @@ -62,6 +64,8 @@ template class UltraComposer_ { std::shared_ptr compute_proving_key(const CircuitBuilder& circuit_constructor); std::shared_ptr compute_verification_key(const CircuitBuilder& circuit_constructor); + void compute_circuit_size_parameters(CircuitBuilder& circuit_constructor); + void compute_witness(CircuitBuilder& circuit_constructor); UltraProver_ create_prover(CircuitBuilder& circuit_constructor); From fc062a32b8ce98e0636cc4abc6ab258828a03ecf Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Fri, 7 Jul 2023 10:32:04 +0000 Subject: [PATCH 08/13] WiP failing with offset greater than 0 --- .../honk/composer/ultra_composer.cpp | 31 ++++++++--------- .../honk/composer/ultra_composer.hpp | 6 ++-- .../circuit_builder/ultra_circuit_builder.hpp | 2 +- .../proof_system/composer/composer_lib.hpp | 22 ++++++++----- .../proof_system/composer/permutation_lib.hpp | 33 ++++++++++++++----- 5 files changed, 59 insertions(+), 35 deletions(-) diff --git a/cpp/src/barretenberg/honk/composer/ultra_composer.cpp b/cpp/src/barretenberg/honk/composer/ultra_composer.cpp index 704502d217..d15f825129 100644 --- a/cpp/src/barretenberg/honk/composer/ultra_composer.cpp +++ b/cpp/src/barretenberg/honk/composer/ultra_composer.cpp @@ -25,14 +25,15 @@ void UltraComposer_::compute_circuit_size_parameters(CircuitBuilder& cir num_public_inputs = circuit_constructor.public_inputs.size(); // minimum circuit size due to the length of lookups plus tables - const size_t minimum_circuit_size = tables_size + lookups_size + zero_wire_offset; + const size_t minimum_circuit_size_due_to_lookups = tables_size + lookups_size + zero_wire_offset; // number of populated rows in the execution trace - filled_gates = circuit_constructor.num_gates + circuit_constructor.public_inputs.size() + zero_wire_offset; + const size_t num_rows_populated_in_execution_trace = + circuit_constructor.num_gates + circuit_constructor.public_inputs.size() + zero_wire_offset; - // The number of gates is max(lookup gates + tables, all gates) + 1, where the +1 is due to the addition of a - // "zero row" at the top of the execution trace to ensure wire and other polynomials are shiftable. - total_num_gates = std::max(minimum_circuit_size, filled_gates); + // The number of gates is max(lookup gates + tables, rows already populated in trace) + 1, where the +1 is due to + // addition of a "zero row" at top of the execution trace to ensure wires and other polys are shiftable. + total_num_gates = std::max(minimum_circuit_size_due_to_lookups, num_rows_populated_in_execution_trace); // Next power of 2 dyadic_circuit_size = circuit_constructor.get_circuit_subgroup_size(total_num_gates); @@ -48,16 +49,17 @@ template void UltraComposer_::compute_witness(Circu return; } - // Pad the wires (pointers to `witness_indices` of the `variables` vector). - // Note: total_num_gates = filled_gates + tables_size - for (size_t i = filled_gates; i < total_num_gates; ++i) { + // At this point, the wires have been populated with as many values as rows in the execution trace. We need to pad + // with zeros up to the full length, i.e. total_num_gates = already populated rows of execution trace + tables_size. + for (size_t i = 0; i < tables_size; ++i) { circuit_constructor.w_l.emplace_back(circuit_constructor.zero_idx); circuit_constructor.w_r.emplace_back(circuit_constructor.zero_idx); circuit_constructor.w_o.emplace_back(circuit_constructor.zero_idx); circuit_constructor.w_4.emplace_back(circuit_constructor.zero_idx); } - auto wire_polynomials = construct_wire_polynomials_base(circuit_constructor, dyadic_circuit_size); + auto wire_polynomials = + construct_wire_polynomials_base(circuit_constructor, dyadic_circuit_size, zero_wire_offset); proving_key->w_l = wire_polynomials[0]; proving_key->w_r = wire_polynomials[1]; @@ -137,11 +139,10 @@ template void UltraComposer_::compute_witness(Circu // Copy memory read/write record data into proving key. Prover needs to know which gates contain a read/write // 'record' witness on the 4th wire. This wire value can only be fully computed once the first 3 wire polynomials // have been committed to. The 4th wire on these gates will be a random linear combination of the first 3 wires, - // using the plookup challenge `eta`. Because we shift the gates by the number of public inputs, we need to update - // the records with the public_inputs offset - const uint32_t public_inputs_count = static_cast(circuit_constructor.public_inputs.size()); - auto add_public_inputs_offset = [public_inputs_count](uint32_t gate_index) { - return gate_index + public_inputs_count; + // using the plookup challenge `eta`. We need to update the records with an offset Because we shift the gates by + // the number of public inputs plus an additional offset for a zero row. + auto add_public_inputs_offset = [this](uint32_t gate_index) { + return gate_index + num_public_inputs + zero_wire_offset; }; proving_key->memory_read_records = std::vector(); proving_key->memory_write_records = std::vector(); @@ -209,7 +210,7 @@ std::shared_ptr UltraComposer_::compute_pro construct_selector_polynomials(circuit_constructor, proving_key.get()); - compute_honk_generalized_sigma_permutations(circuit_constructor, proving_key.get()); + compute_honk_generalized_sigma_permutations(circuit_constructor, proving_key.get(), zero_wire_offset); compute_first_and_last_lagrange_polynomials(proving_key.get()); diff --git a/cpp/src/barretenberg/honk/composer/ultra_composer.hpp b/cpp/src/barretenberg/honk/composer/ultra_composer.hpp index a08f58225d..a1d44b3827 100644 --- a/cpp/src/barretenberg/honk/composer/ultra_composer.hpp +++ b/cpp/src/barretenberg/honk/composer/ultra_composer.hpp @@ -35,13 +35,13 @@ template class UltraComposer_ { std::vector recursive_proof_public_input_indices; bool contains_recursive_proof = false; bool computed_witness = false; - size_t total_num_gates = 0; // total num gates (the number used to compute dyadic size) - size_t filled_gates = 0; // num_gates + num_public_inputs + zero_wire_offset + size_t total_num_gates = 0; // num_gates + num_pub_inputs + tables + zero_wire_offset (used to compute dyadic size) size_t dyadic_circuit_size = 0; // final dyadic circuit size size_t lookups_size = 0; // total number of lookup gates size_t tables_size = 0; // total number of table entries size_t num_public_inputs = 0; - const size_t zero_wire_offset = 1; // offset due to placing zero wires at the start of execution trace + // WORKTODO: set as the length of an object zero_wires in circuit constructor? + const size_t zero_wire_offset = 0; // offset due to placing zero wires at the start of execution trace UltraComposer_() : crs_factory_(barretenberg::srs::get_crs_factory()){}; diff --git a/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp b/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp index cdc886b9ca..4ad0d645ba 100644 --- a/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp +++ b/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp @@ -587,7 +587,7 @@ template class UltraCircuitBuilder_ : public CircuitBuilderBaseadd_public_variable(FF::zero()); + // this->add_public_variable(FF::zero()); // WORKTODO: possible hack to make shifts work w/ PI this->zero_idx = put_constant_variable(FF::zero()); this->tau.insert({ DUMMY_TAG, DUMMY_TAG }); // TODO(luke): explain this }; diff --git a/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp b/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp index e64da42ffa..4bd887509d 100644 --- a/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp +++ b/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp @@ -15,9 +15,11 @@ namespace proof_system { */ template void construct_selector_polynomials(const typename Flavor::CircuitBuilder& circuit_constructor, - typename Flavor::ProvingKey* proving_key) + typename Flavor::ProvingKey* proving_key, + const size_t offset = 0) { - const size_t num_public_inputs = circuit_constructor.public_inputs.size(); + // Offset for starting to write selectors is input offset + num public inputs + const size_t gate_offset = offset + circuit_constructor.public_inputs.size(); // const size_t offset = num_public_inputs + // TODO(#398): Loose coupling here! Would rather build up pk from arithmetization size_t selector_idx = 0; // TODO(#391) zip @@ -28,7 +30,7 @@ void construct_selector_polynomials(const typename Flavor::CircuitBuilder& circu // Initializing the polynomials in this way automatically applies 0-padding to the selectors. barretenberg::polynomial selector_poly_lagrange(proving_key->circuit_size); for (size_t i = 0; i < selector_values.size(); ++i) { - selector_poly_lagrange[num_public_inputs + i] = selector_values[i]; + selector_poly_lagrange[i + gate_offset] = selector_values[i]; } if constexpr (IsHonkFlavor) { // TODO(#398): Loose coupling here of arithmetization and flavor. @@ -56,7 +58,9 @@ void construct_selector_polynomials(const typename Flavor::CircuitBuilder& circu * */ template std::vector construct_wire_polynomials_base( - const typename Flavor::CircuitBuilder& circuit_constructor, const size_t dyadic_circuit_size) + const typename Flavor::CircuitBuilder& circuit_constructor, + const size_t dyadic_circuit_size, + const size_t offset = 0) { std::span public_inputs = circuit_constructor.public_inputs; const size_t num_public_inputs = public_inputs.size(); @@ -70,19 +74,21 @@ std::vector construct_wire_polynomials_base( // Expect all values to be set to 0 initially barretenberg::polynomial w_lagrange(dyadic_circuit_size); - // Place all public inputs at the start of the first two wires. + // Place all public inputs at the start of the first two wires, possibly offset by some value > 0. // All selectors at these indices are set to 0, so these values are not constrained at all. + const size_t pub_input_offset = offset; // offset at which to start writing pub inputs if (wire_idx < 2) { for (size_t i = 0; i < num_public_inputs; ++i) { - w_lagrange[i] = circuit_constructor.get_variable(public_inputs[i]); + w_lagrange[i + pub_input_offset] = circuit_constructor.get_variable(public_inputs[i]); } ++wire_idx; } // Assign the variable values (which are pointed-to by the `w_` wire_polynomials) to the wire witness - // polynomials `poly_w_`, shifted to make room for the public inputs at the beginning. + // polynomials `poly_w_`, shifted to make room for public inputs and the specified offset (possibly 0). + const size_t gate_offset = num_public_inputs + offset; // offset at which to start writing gates for (size_t i = 0; i < circuit_constructor.num_gates; ++i) { - w_lagrange[num_public_inputs + i] = circuit_constructor.get_variable(wire[i]); + w_lagrange[i + gate_offset] = circuit_constructor.get_variable(wire[i]); } wire_polynomials.push_back(std::move(w_lagrange)); } diff --git a/cpp/src/barretenberg/proof_system/composer/permutation_lib.hpp b/cpp/src/barretenberg/proof_system/composer/permutation_lib.hpp index ab63a82834..b865628973 100644 --- a/cpp/src/barretenberg/proof_system/composer/permutation_lib.hpp +++ b/cpp/src/barretenberg/proof_system/composer/permutation_lib.hpp @@ -60,13 +60,14 @@ using CyclicPermutation = std::vector; namespace { /** - * Compute all CyclicPermutations of the circuit. Each CyclicPermutation represents the indices of the values in the - * witness wires that must have the same value. + * @brief Compute all CyclicPermutations of the circuit. Each CyclicPermutation represents the indices of the values in + * the witness wires that must have the same value. * * @tparam program_width Program width * */ template -std::vector compute_wire_copy_cycles(const typename Flavor::CircuitBuilder& circuit_constructor) +std::vector compute_wire_copy_cycles(const typename Flavor::CircuitBuilder& circuit_constructor, + const size_t offset = 0) { // Reference circuit constructor members const size_t num_gates = circuit_constructor.num_gates; @@ -81,6 +82,17 @@ std::vector compute_wire_copy_cycles(const typename Flavor::C // Represents the index of a variable in circuit_constructor.variables std::span real_variable_index = circuit_constructor.real_variable_index; + // Add 'offset' many rows of wires to the zero index cycle. This will be used to ensure there are offset-many rows + // of zeros at the start of the execution trace. + for (size_t gate_idx = 0; gate_idx < offset; ++gate_idx) { + for (size_t wire_idx = 0; wire_idx < Flavor::NUM_WIRES; ++wire_idx) { + const auto wire_index = static_cast(wire_idx); + const auto gate_index = static_cast(gate_idx); + const uint32_t zero_idx = circuit_constructor.zero_idx; // index of constant zero in variables + copy_cycles[zero_idx].emplace_back(cycle_node{ wire_index, gate_index }); + } + } + // We use the permutation argument to enforce the public input variables to be equal to values provided by the // verifier. The convension we use is to place the public input values as the first rows of witness vectors. // More specifically, we set the LEFT and RIGHT wires to be the public inputs and set the other elements of the row @@ -135,10 +147,12 @@ std::vector compute_wire_copy_cycles(const typename Flavor::C */ template PermutationMapping compute_permutation_mapping( - const typename Flavor::CircuitBuilder& circuit_constructor, typename Flavor::ProvingKey* proving_key) + const typename Flavor::CircuitBuilder& circuit_constructor, + typename Flavor::ProvingKey* proving_key, + const size_t offset = 0) { // Compute wire copy cycles (cycles of permutations) - auto wire_copy_cycles = compute_wire_copy_cycles(circuit_constructor); + auto wire_copy_cycles = compute_wire_copy_cycles(circuit_constructor, offset); PermutationMapping mapping; @@ -208,7 +222,9 @@ PermutationMapping compute_permutation_mapping( // Add information about public inputs to the computation const uint32_t num_public_inputs = static_cast(circuit_constructor.public_inputs.size()); - for (size_t i = 0; i < num_public_inputs; ++i) { + // The public inputs are placed at the top of the execution trace, potentially offset by some value. + // WORKTODO: we're now offsetting the sigmas; is there a corresponding thing for ids? I think not. + for (size_t i = offset; i < num_public_inputs + offset; ++i) { mapping.sigmas[0][i].row_index = static_cast(i); mapping.sigmas[0][i].column_index = 0; mapping.sigmas[0][i].is_public_input = true; @@ -515,9 +531,10 @@ void compute_plonk_generalized_sigma_permutations(const typename Flavor::Circuit */ template void compute_honk_generalized_sigma_permutations(const typename Flavor::CircuitBuilder& circuit_constructor, - typename Flavor::ProvingKey* proving_key) + typename Flavor::ProvingKey* proving_key, + const size_t offset = 0) { - auto mapping = compute_permutation_mapping(circuit_constructor, proving_key); + auto mapping = compute_permutation_mapping(circuit_constructor, proving_key, offset); // Compute Honk-style sigma and ID polynomials from the corresponding mappings compute_honk_style_permutation_lagrange_polynomials_from_mapping( From abcb18590253e279fc289acc78b5a731f262c703 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Sun, 16 Jul 2023 20:42:59 +0000 Subject: [PATCH 09/13] everything working with offset 1 --- .../honk/composer/ultra_composer.cpp | 2 +- .../honk/composer/ultra_composer.hpp | 2 +- .../honk/composer/ultra_composer.test.cpp | 16 ++++++++++------ .../honk/proof_system/ultra_prover.cpp | 5 +++-- .../honk/proof_system/ultra_verifier.cpp | 2 +- .../relations/relation_correctness.test.cpp | 3 ++- .../barretenberg/honk/sumcheck/sumcheck.test.cpp | 6 +++--- .../honk/utils/grand_product_delta.hpp | 7 ++++--- .../proof_system/composer/permutation_lib.hpp | 16 ++++++++++------ 9 files changed, 35 insertions(+), 24 deletions(-) diff --git a/cpp/src/barretenberg/honk/composer/ultra_composer.cpp b/cpp/src/barretenberg/honk/composer/ultra_composer.cpp index d15f825129..6157648bef 100644 --- a/cpp/src/barretenberg/honk/composer/ultra_composer.cpp +++ b/cpp/src/barretenberg/honk/composer/ultra_composer.cpp @@ -208,7 +208,7 @@ std::shared_ptr UltraComposer_::compute_pro proving_key = std::make_shared(dyadic_circuit_size, num_public_inputs); - construct_selector_polynomials(circuit_constructor, proving_key.get()); + construct_selector_polynomials(circuit_constructor, proving_key.get(), zero_wire_offset); compute_honk_generalized_sigma_permutations(circuit_constructor, proving_key.get(), zero_wire_offset); diff --git a/cpp/src/barretenberg/honk/composer/ultra_composer.hpp b/cpp/src/barretenberg/honk/composer/ultra_composer.hpp index a1d44b3827..7984425dc7 100644 --- a/cpp/src/barretenberg/honk/composer/ultra_composer.hpp +++ b/cpp/src/barretenberg/honk/composer/ultra_composer.hpp @@ -41,7 +41,7 @@ template class UltraComposer_ { size_t tables_size = 0; // total number of table entries size_t num_public_inputs = 0; // WORKTODO: set as the length of an object zero_wires in circuit constructor? - const size_t zero_wire_offset = 0; // offset due to placing zero wires at the start of execution trace + const size_t zero_wire_offset = 1; // offset due to placing zero wires at the start of execution trace UltraComposer_() : crs_factory_(barretenberg::srs::get_crs_factory()){}; diff --git a/cpp/src/barretenberg/honk/composer/ultra_composer.test.cpp b/cpp/src/barretenberg/honk/composer/ultra_composer.test.cpp index c534965a79..7767113872 100644 --- a/cpp/src/barretenberg/honk/composer/ultra_composer.test.cpp +++ b/cpp/src/barretenberg/honk/composer/ultra_composer.test.cpp @@ -59,14 +59,13 @@ class UltraHonkComposerTests : public ::testing::Test { /** * @brief A quick test to ensure that none of our polynomials are identically zero * - * @note This test assumes that gates have been added by default in the circuit - * constructor to achieve non-zero polynomials + * @note This test assumes that gates have been added by default in the composer + * to achieve non-zero polynomials * */ TEST_F(UltraHonkComposerTests, ANonZeroPolynomialIsAGoodPolynomial) { auto circuit_constructor = UltraCircuitBuilder(); - circuit_constructor.add_gates_to_ensure_all_polys_are_non_zero(); auto composer = UltraComposer(); auto prover = composer.create_prover(circuit_constructor); @@ -85,22 +84,27 @@ TEST_F(UltraHonkComposerTests, ANonZeroPolynomialIsAGoodPolynomial) } } +/** + * @brief Test simple circuit with public inputs + * + */ TEST_F(UltraHonkComposerTests, PublicInputs) { auto builder = UltraCircuitBuilder(); size_t num_gates = 10; - // TODO(#597)(luke): If were going to add any PI, the first has to be zero to ensure shiftable wires. - // builder.add_public_variable(0); + // Add some arbitrary arithmetic gates that utilize public inputs for (size_t i = 0; i < num_gates; ++i) { fr a = fr::random_element(); uint32_t a_idx = builder.add_public_variable(a); - fr b = fr::one(); + + fr b = fr::random_element(); fr c = fr::random_element(); fr d = a + b + c; uint32_t b_idx = builder.add_variable(b); uint32_t c_idx = builder.add_variable(c); uint32_t d_idx = builder.add_variable(d); + builder.create_big_add_gate({ a_idx, b_idx, c_idx, d_idx, fr(1), fr(1), fr(1), fr(-1), fr(0) }); } diff --git a/cpp/src/barretenberg/honk/proof_system/ultra_prover.cpp b/cpp/src/barretenberg/honk/proof_system/ultra_prover.cpp index 09f2a451e7..f96683b206 100644 --- a/cpp/src/barretenberg/honk/proof_system/ultra_prover.cpp +++ b/cpp/src/barretenberg/honk/proof_system/ultra_prover.cpp @@ -73,8 +73,9 @@ UltraProver_::UltraProver_(std::shared_ptr // Add public inputs to transcript from the second wire polynomial std::span public_wires_source = prover_polynomials.w_r; + const size_t pub_input_offset = 1; - for (size_t i = 0; i < key->num_public_inputs; ++i) { + for (size_t i = pub_input_offset; i < key->num_public_inputs + pub_input_offset; ++i) { public_inputs.emplace_back(public_wires_source[i]); } } @@ -156,7 +157,7 @@ template void UltraProver_::execute_grand_product_c // Compute and store parameters required by relations in Sumcheck auto [beta, gamma] = transcript.get_challenges("beta", "gamma"); - auto public_input_delta = compute_public_input_delta(public_inputs, beta, gamma, key->circuit_size); + auto public_input_delta = compute_public_input_delta(public_inputs, beta, gamma, key->circuit_size, 1); auto lookup_grand_product_delta = compute_lookup_grand_product_delta(beta, gamma, key->circuit_size); relation_parameters.beta = beta; diff --git a/cpp/src/barretenberg/honk/proof_system/ultra_verifier.cpp b/cpp/src/barretenberg/honk/proof_system/ultra_verifier.cpp index 4608d9017b..98bd911227 100644 --- a/cpp/src/barretenberg/honk/proof_system/ultra_verifier.cpp +++ b/cpp/src/barretenberg/honk/proof_system/ultra_verifier.cpp @@ -84,7 +84,7 @@ template bool UltraVerifier_::verify_proof(const plonk // Get permutation challenges auto [beta, gamma] = transcript.get_challenges("beta", "gamma"); - const FF public_input_delta = compute_public_input_delta(public_inputs, beta, gamma, circuit_size); + const FF public_input_delta = compute_public_input_delta(public_inputs, beta, gamma, circuit_size, 1); const FF lookup_grand_product_delta = compute_lookup_grand_product_delta(beta, gamma, circuit_size); relation_parameters.beta = beta; diff --git a/cpp/src/barretenberg/honk/sumcheck/relations/relation_correctness.test.cpp b/cpp/src/barretenberg/honk/sumcheck/relations/relation_correctness.test.cpp index 44b30d808b..1b3358b45b 100644 --- a/cpp/src/barretenberg/honk/sumcheck/relations/relation_correctness.test.cpp +++ b/cpp/src/barretenberg/honk/sumcheck/relations/relation_correctness.test.cpp @@ -303,8 +303,9 @@ TEST_F(RelationCorrectnessTests, UltraRelationCorrectness) // Compute public input delta const auto public_inputs = circuit_constructor.get_public_inputs(); + const size_t pub_inputs_offset = 1; auto public_input_delta = - honk::compute_public_input_delta(public_inputs, beta, gamma, prover.key->circuit_size); + honk::compute_public_input_delta(public_inputs, beta, gamma, prover.key->circuit_size, pub_inputs_offset); auto lookup_grand_product_delta = honk::compute_lookup_grand_product_delta(beta, gamma, prover.key->circuit_size); diff --git a/cpp/src/barretenberg/honk/sumcheck/sumcheck.test.cpp b/cpp/src/barretenberg/honk/sumcheck/sumcheck.test.cpp index 4109e6152c..a8449c4dc0 100644 --- a/cpp/src/barretenberg/honk/sumcheck/sumcheck.test.cpp +++ b/cpp/src/barretenberg/honk/sumcheck/sumcheck.test.cpp @@ -511,8 +511,8 @@ TEST_F(SumcheckTests, RealCircuitUltra) auto circuit_constructor = UltraCircuitBuilder(); fr a = fr::one(); - // Add some basic add gates - uint32_t a_idx = circuit_constructor.add_variable(a); + // Add some basic add gates, with a public input for good measure + uint32_t a_idx = circuit_constructor.add_public_variable(a); fr b = fr::one(); fr c = a + b; fr d = a + c; @@ -632,7 +632,7 @@ TEST_F(SumcheckTests, RealCircuitUltra) // Compute public input delta const auto public_inputs = circuit_constructor.get_public_inputs(); auto public_input_delta = - honk::compute_public_input_delta(public_inputs, beta, gamma, prover.key->circuit_size); + honk::compute_public_input_delta(public_inputs, beta, gamma, prover.key->circuit_size, 1); auto lookup_grand_product_delta = honk::compute_lookup_grand_product_delta(beta, gamma, prover.key->circuit_size); diff --git a/cpp/src/barretenberg/honk/utils/grand_product_delta.hpp b/cpp/src/barretenberg/honk/utils/grand_product_delta.hpp index 674ab15c2a..2fda6a2a02 100644 --- a/cpp/src/barretenberg/honk/utils/grand_product_delta.hpp +++ b/cpp/src/barretenberg/honk/utils/grand_product_delta.hpp @@ -17,7 +17,8 @@ template Field compute_public_input_delta(std::span public_inputs, const Field& beta, const Field& gamma, - const size_t domain_size) + const size_t domain_size, + const size_t offset = 0) { Field numerator = Field::one(); Field denominator = Field::one(); @@ -41,8 +42,8 @@ Field compute_public_input_delta(std::span public_inputs, // denominator_acc = γ - β⋅(1+i) = γ - β - β⋅i // at the end of the loop, add and subtract β to each term respectively to // set the expected value for the start of iteration i+1. - Field numerator_acc = gamma + (beta * Field(domain_size)); - Field denominator_acc = gamma - beta; + Field numerator_acc = gamma + (beta * Field(domain_size + offset)); + Field denominator_acc = gamma - beta * Field(1 + offset); for (const auto& x_i : public_inputs) { numerator *= (numerator_acc + x_i); // γ + xᵢ + β(n+i) diff --git a/cpp/src/barretenberg/proof_system/composer/permutation_lib.hpp b/cpp/src/barretenberg/proof_system/composer/permutation_lib.hpp index b865628973..33ade04c53 100644 --- a/cpp/src/barretenberg/proof_system/composer/permutation_lib.hpp +++ b/cpp/src/barretenberg/proof_system/composer/permutation_lib.hpp @@ -74,6 +74,10 @@ std::vector compute_wire_copy_cycles(const typename Flavor::C std::span public_inputs = circuit_constructor.public_inputs; const size_t num_public_inputs = public_inputs.size(); + // Define offsets for placement of public inputs and gates in execution trace + const size_t pub_inputs_offset = offset; + const size_t gates_offset = num_public_inputs + pub_inputs_offset; + // Each variable represents one cycle const size_t number_of_cycles = circuit_constructor.variables.size(); std::vector copy_cycles(number_of_cycles); @@ -107,14 +111,14 @@ std::vector compute_wire_copy_cycles(const typename Flavor::C // for all i s.t. row i defines a public input. for (size_t i = 0; i < num_public_inputs; ++i) { const uint32_t public_input_index = real_variable_index[public_inputs[i]]; - const auto gate_index = static_cast(i); + const auto gate_index = static_cast(i + pub_inputs_offset); // These two nodes must be in adjacent locations in the cycle for correct handling of public inputs copy_cycles[public_input_index].emplace_back(cycle_node{ 0, gate_index }); copy_cycles[public_input_index].emplace_back(cycle_node{ 1, gate_index }); } // Iterate over all variables of the "real" gates, and add a corresponding node to the cycle for that variable - for (size_t gate_idx = 0; gate_idx < num_gates; ++gate_idx) { + for (size_t i = 0; i < num_gates; ++i) { size_t wire_idx = 0; for (auto& wire : circuit_constructor.wires) { // We are looking at the j-th wire in the i-th row. @@ -122,10 +126,10 @@ std::vector compute_wire_copy_cycles(const typename Flavor::C // of the `constructor.variables` vector. // Therefore, we add (i,j) to the cycle at index `var_index` to indicate that w^j_i should have the values // constructor.variables[var_index]. - const uint32_t var_index = circuit_constructor.real_variable_index[wire[gate_idx]]; + const uint32_t var_index = circuit_constructor.real_variable_index[wire[i]]; const auto wire_index = static_cast(wire_idx); - const auto shifted_gate_idx = static_cast(gate_idx + num_public_inputs); - copy_cycles[var_index].emplace_back(cycle_node{ wire_index, shifted_gate_idx }); + const auto gate_idx = static_cast(i + gates_offset); + copy_cycles[var_index].emplace_back(cycle_node{ wire_index, gate_idx }); ++wire_idx; } } @@ -220,7 +224,7 @@ PermutationMapping compute_permutation_mapping( } // Add information about public inputs to the computation - const uint32_t num_public_inputs = static_cast(circuit_constructor.public_inputs.size()); + const auto num_public_inputs = static_cast(circuit_constructor.public_inputs.size()); // The public inputs are placed at the top of the execution trace, potentially offset by some value. // WORKTODO: we're now offsetting the sigmas; is there a corresponding thing for ids? I think not. From 60fc7f426a810aa119ef420727646e65ceec792b Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Sun, 16 Jul 2023 21:23:10 +0000 Subject: [PATCH 10/13] move zero row spec to flavor --- .../honk/composer/ultra_composer.cpp | 7 ++-- .../honk/composer/ultra_composer.hpp | 5 +-- cpp/src/barretenberg/honk/flavor/standard.hpp | 3 ++ .../honk/flavor/standard_grumpkin.hpp | 4 +-- cpp/src/barretenberg/honk/flavor/ultra.hpp | 3 ++ .../honk/flavor/ultra_grumpkin.hpp | 3 ++ cpp/src/barretenberg/plonk/flavor/flavor.hpp | 6 ++++ .../proof_system/composer/composer_lib.hpp | 15 ++++----- .../proof_system/composer/permutation_lib.hpp | 33 +++++++++---------- 9 files changed, 45 insertions(+), 34 deletions(-) diff --git a/cpp/src/barretenberg/honk/composer/ultra_composer.cpp b/cpp/src/barretenberg/honk/composer/ultra_composer.cpp index 6157648bef..774066caa5 100644 --- a/cpp/src/barretenberg/honk/composer/ultra_composer.cpp +++ b/cpp/src/barretenberg/honk/composer/ultra_composer.cpp @@ -58,8 +58,7 @@ template void UltraComposer_::compute_witness(Circu circuit_constructor.w_4.emplace_back(circuit_constructor.zero_idx); } - auto wire_polynomials = - construct_wire_polynomials_base(circuit_constructor, dyadic_circuit_size, zero_wire_offset); + auto wire_polynomials = construct_wire_polynomials_base(circuit_constructor, dyadic_circuit_size); proving_key->w_l = wire_polynomials[0]; proving_key->w_r = wire_polynomials[1]; @@ -208,9 +207,9 @@ std::shared_ptr UltraComposer_::compute_pro proving_key = std::make_shared(dyadic_circuit_size, num_public_inputs); - construct_selector_polynomials(circuit_constructor, proving_key.get(), zero_wire_offset); + construct_selector_polynomials(circuit_constructor, proving_key.get()); - compute_honk_generalized_sigma_permutations(circuit_constructor, proving_key.get(), zero_wire_offset); + compute_honk_generalized_sigma_permutations(circuit_constructor, proving_key.get()); compute_first_and_last_lagrange_polynomials(proving_key.get()); diff --git a/cpp/src/barretenberg/honk/composer/ultra_composer.hpp b/cpp/src/barretenberg/honk/composer/ultra_composer.hpp index 7984425dc7..40ebddc2a1 100644 --- a/cpp/src/barretenberg/honk/composer/ultra_composer.hpp +++ b/cpp/src/barretenberg/honk/composer/ultra_composer.hpp @@ -21,6 +21,9 @@ template class UltraComposer_ { using PCSCommitmentKey = typename PCSParams::CommitmentKey; using PCSVerificationKey = typename PCSParams::VerificationKey; + // offset due to placing zero wires at the start of execution trace + static constexpr size_t zero_wire_offset = Flavor::zero_row ? 1 : 0; + static constexpr std::string_view NAME_STRING = "UltraHonk"; static constexpr size_t NUM_WIRES = CircuitBuilder::NUM_WIRES; std::shared_ptr proving_key; @@ -40,8 +43,6 @@ template class UltraComposer_ { size_t lookups_size = 0; // total number of lookup gates size_t tables_size = 0; // total number of table entries size_t num_public_inputs = 0; - // WORKTODO: set as the length of an object zero_wires in circuit constructor? - const size_t zero_wire_offset = 1; // offset due to placing zero wires at the start of execution trace UltraComposer_() : crs_factory_(barretenberg::srs::get_crs_factory()){}; diff --git a/cpp/src/barretenberg/honk/flavor/standard.hpp b/cpp/src/barretenberg/honk/flavor/standard.hpp index fefdb293ba..9997637779 100644 --- a/cpp/src/barretenberg/honk/flavor/standard.hpp +++ b/cpp/src/barretenberg/honk/flavor/standard.hpp @@ -66,6 +66,9 @@ class Standard { using RelationUnivariates = decltype(create_relation_univariates_container()); using RelationValues = decltype(create_relation_values_container()); + // Whether or not the first row of the execution trace is reserved for 0s to enable shifts + static constexpr bool zero_row = false; + private: /** * @brief A base class labelling precomputed entities and (ordered) subsets of interest. diff --git a/cpp/src/barretenberg/honk/flavor/standard_grumpkin.hpp b/cpp/src/barretenberg/honk/flavor/standard_grumpkin.hpp index cd75dd4817..036faae5c5 100644 --- a/cpp/src/barretenberg/honk/flavor/standard_grumpkin.hpp +++ b/cpp/src/barretenberg/honk/flavor/standard_grumpkin.hpp @@ -57,8 +57,8 @@ class StandardGrumpkin { using RelationUnivariates = decltype(create_relation_univariates_container()); using RelationValues = decltype(create_relation_values_container()); - // define utilities to extend univarates from RELATION_LENGTH to MAX_RELATION_LENGTH for each Relation - // using BarycentricUtils = decltype(create_barycentric_utils()); + // Whether or not the first row of the execution trace is reserved for 0s to enable shifts + static constexpr bool zero_row = false; private: /** diff --git a/cpp/src/barretenberg/honk/flavor/ultra.hpp b/cpp/src/barretenberg/honk/flavor/ultra.hpp index ec2d05b862..28c80eef2d 100644 --- a/cpp/src/barretenberg/honk/flavor/ultra.hpp +++ b/cpp/src/barretenberg/honk/flavor/ultra.hpp @@ -71,6 +71,9 @@ class Ultra { using RelationUnivariates = decltype(create_relation_univariates_container()); using RelationValues = decltype(create_relation_values_container()); + // Whether or not the first row of the execution trace is reserved for 0s to enable shifts + static constexpr bool zero_row = true; + private: template /** diff --git a/cpp/src/barretenberg/honk/flavor/ultra_grumpkin.hpp b/cpp/src/barretenberg/honk/flavor/ultra_grumpkin.hpp index a8f0f4021e..9144699c89 100644 --- a/cpp/src/barretenberg/honk/flavor/ultra_grumpkin.hpp +++ b/cpp/src/barretenberg/honk/flavor/ultra_grumpkin.hpp @@ -69,6 +69,9 @@ class UltraGrumpkin { using RelationUnivariates = decltype(create_relation_univariates_container()); using RelationValues = decltype(create_relation_values_container()); + // Whether or not the first row of the execution trace is reserved for 0s to enable shifts + static constexpr bool zero_row = true; + private: template /** diff --git a/cpp/src/barretenberg/plonk/flavor/flavor.hpp b/cpp/src/barretenberg/plonk/flavor/flavor.hpp index b50fccf33d..bb202e517b 100644 --- a/cpp/src/barretenberg/plonk/flavor/flavor.hpp +++ b/cpp/src/barretenberg/plonk/flavor/flavor.hpp @@ -11,6 +11,8 @@ class Standard { using CircuitBuilder = proof_system::StandardCircuitBuilder; using ProvingKey = plonk::proving_key; static constexpr size_t NUM_WIRES = CircuitBuilder::NUM_WIRES; + // Whether or not the first row of the execution trace is reserved for 0s to enable shifts + static constexpr bool zero_row = false; }; class Turbo { @@ -18,6 +20,8 @@ class Turbo { using CircuitBuilder = proof_system::TurboCircuitBuilder; using ProvingKey = plonk::proving_key; static constexpr size_t NUM_WIRES = CircuitBuilder::NUM_WIRES; + // Whether or not the first row of the execution trace is reserved for 0s to enable shifts + static constexpr bool zero_row = false; }; class Ultra { @@ -25,6 +29,8 @@ class Ultra { using CircuitBuilder = proof_system::UltraCircuitBuilder; using ProvingKey = plonk::proving_key; static constexpr size_t NUM_WIRES = CircuitBuilder::NUM_WIRES; + // Whether or not the first row of the execution trace is reserved for 0s to enable shifts + static constexpr bool zero_row = false; /** * @brief Create a manifest object diff --git a/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp b/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp index 4bd887509d..7121c2ae73 100644 --- a/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp +++ b/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp @@ -15,11 +15,11 @@ namespace proof_system { */ template void construct_selector_polynomials(const typename Flavor::CircuitBuilder& circuit_constructor, - typename Flavor::ProvingKey* proving_key, - const size_t offset = 0) + typename Flavor::ProvingKey* proving_key) { + const size_t zero_row_offset = Flavor::zero_row ? 1 : 0; // Offset for starting to write selectors is input offset + num public inputs - const size_t gate_offset = offset + circuit_constructor.public_inputs.size(); + const size_t gate_offset = zero_row_offset + circuit_constructor.public_inputs.size(); // const size_t offset = num_public_inputs + // TODO(#398): Loose coupling here! Would rather build up pk from arithmetization size_t selector_idx = 0; // TODO(#391) zip @@ -58,10 +58,9 @@ void construct_selector_polynomials(const typename Flavor::CircuitBuilder& circu * */ template std::vector construct_wire_polynomials_base( - const typename Flavor::CircuitBuilder& circuit_constructor, - const size_t dyadic_circuit_size, - const size_t offset = 0) + const typename Flavor::CircuitBuilder& circuit_constructor, const size_t dyadic_circuit_size) { + const size_t zero_row_offset = Flavor::zero_row ? 1 : 0; std::span public_inputs = circuit_constructor.public_inputs; const size_t num_public_inputs = public_inputs.size(); @@ -76,7 +75,7 @@ std::vector construct_wire_polynomials_base( // Place all public inputs at the start of the first two wires, possibly offset by some value > 0. // All selectors at these indices are set to 0, so these values are not constrained at all. - const size_t pub_input_offset = offset; // offset at which to start writing pub inputs + const size_t pub_input_offset = zero_row_offset; // offset at which to start writing pub inputs if (wire_idx < 2) { for (size_t i = 0; i < num_public_inputs; ++i) { w_lagrange[i + pub_input_offset] = circuit_constructor.get_variable(public_inputs[i]); @@ -86,7 +85,7 @@ std::vector construct_wire_polynomials_base( // Assign the variable values (which are pointed-to by the `w_` wire_polynomials) to the wire witness // polynomials `poly_w_`, shifted to make room for public inputs and the specified offset (possibly 0). - const size_t gate_offset = num_public_inputs + offset; // offset at which to start writing gates + const size_t gate_offset = num_public_inputs + pub_input_offset; // offset at which to start writing gates for (size_t i = 0; i < circuit_constructor.num_gates; ++i) { w_lagrange[i + gate_offset] = circuit_constructor.get_variable(wire[i]); } diff --git a/cpp/src/barretenberg/proof_system/composer/permutation_lib.hpp b/cpp/src/barretenberg/proof_system/composer/permutation_lib.hpp index 33ade04c53..5ebb87495e 100644 --- a/cpp/src/barretenberg/proof_system/composer/permutation_lib.hpp +++ b/cpp/src/barretenberg/proof_system/composer/permutation_lib.hpp @@ -66,8 +66,7 @@ namespace { * @tparam program_width Program width * */ template -std::vector compute_wire_copy_cycles(const typename Flavor::CircuitBuilder& circuit_constructor, - const size_t offset = 0) +std::vector compute_wire_copy_cycles(const typename Flavor::CircuitBuilder& circuit_constructor) { // Reference circuit constructor members const size_t num_gates = circuit_constructor.num_gates; @@ -75,7 +74,7 @@ std::vector compute_wire_copy_cycles(const typename Flavor::C const size_t num_public_inputs = public_inputs.size(); // Define offsets for placement of public inputs and gates in execution trace - const size_t pub_inputs_offset = offset; + const size_t pub_inputs_offset = Flavor::zero_row ? 1 : 0; const size_t gates_offset = num_public_inputs + pub_inputs_offset; // Each variable represents one cycle @@ -88,10 +87,10 @@ std::vector compute_wire_copy_cycles(const typename Flavor::C // Add 'offset' many rows of wires to the zero index cycle. This will be used to ensure there are offset-many rows // of zeros at the start of the execution trace. - for (size_t gate_idx = 0; gate_idx < offset; ++gate_idx) { + if (Flavor::zero_row) { for (size_t wire_idx = 0; wire_idx < Flavor::NUM_WIRES; ++wire_idx) { const auto wire_index = static_cast(wire_idx); - const auto gate_index = static_cast(gate_idx); + const uint32_t gate_index = 0; // place zeros at 0th index const uint32_t zero_idx = circuit_constructor.zero_idx; // index of constant zero in variables copy_cycles[zero_idx].emplace_back(cycle_node{ wire_index, gate_index }); } @@ -151,12 +150,10 @@ std::vector compute_wire_copy_cycles(const typename Flavor::C */ template PermutationMapping compute_permutation_mapping( - const typename Flavor::CircuitBuilder& circuit_constructor, - typename Flavor::ProvingKey* proving_key, - const size_t offset = 0) + const typename Flavor::CircuitBuilder& circuit_constructor, typename Flavor::ProvingKey* proving_key) { // Compute wire copy cycles (cycles of permutations) - auto wire_copy_cycles = compute_wire_copy_cycles(circuit_constructor, offset); + auto wire_copy_cycles = compute_wire_copy_cycles(circuit_constructor); PermutationMapping mapping; @@ -227,12 +224,13 @@ PermutationMapping compute_permutation_mapping( const auto num_public_inputs = static_cast(circuit_constructor.public_inputs.size()); // The public inputs are placed at the top of the execution trace, potentially offset by some value. - // WORKTODO: we're now offsetting the sigmas; is there a corresponding thing for ids? I think not. - for (size_t i = offset; i < num_public_inputs + offset; ++i) { - mapping.sigmas[0][i].row_index = static_cast(i); - mapping.sigmas[0][i].column_index = 0; - mapping.sigmas[0][i].is_public_input = true; - if (mapping.sigmas[0][i].is_tag) { + const size_t zero_row_offset = Flavor::zero_row ? 1 : 0; + for (size_t i = 0; i < num_public_inputs; ++i) { + size_t idx = i + zero_row_offset; + mapping.sigmas[0][idx].row_index = static_cast(idx); + mapping.sigmas[0][idx].column_index = 0; + mapping.sigmas[0][idx].is_public_input = true; + if (mapping.sigmas[0][idx].is_tag) { std::cerr << "MAPPING IS BOTH A TAG AND A PUBLIC INPUT" << std::endl; } } @@ -535,10 +533,9 @@ void compute_plonk_generalized_sigma_permutations(const typename Flavor::Circuit */ template void compute_honk_generalized_sigma_permutations(const typename Flavor::CircuitBuilder& circuit_constructor, - typename Flavor::ProvingKey* proving_key, - const size_t offset = 0) + typename Flavor::ProvingKey* proving_key) { - auto mapping = compute_permutation_mapping(circuit_constructor, proving_key, offset); + auto mapping = compute_permutation_mapping(circuit_constructor, proving_key); // Compute Honk-style sigma and ID polynomials from the corresponding mappings compute_honk_style_permutation_lagrange_polynomials_from_mapping( From 6d59260012bbe7a4d126d809ff2f15988ce032eb Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Sun, 16 Jul 2023 21:43:16 +0000 Subject: [PATCH 11/13] template by flav to acces zero row bool --- .../honk/composer/standard_composer.test.cpp | 2 +- cpp/src/barretenberg/honk/proof_system/prover.cpp | 2 +- .../honk/proof_system/ultra_prover.cpp | 4 ++-- .../honk/proof_system/ultra_verifier.cpp | 2 +- .../barretenberg/honk/proof_system/verifier.cpp | 2 +- .../relations/relation_correctness.test.cpp | 5 ++--- .../barretenberg/honk/sumcheck/sumcheck.test.cpp | 4 ++-- .../honk/utils/grand_product_delta.hpp | 15 +++++++++------ 8 files changed, 19 insertions(+), 17 deletions(-) diff --git a/cpp/src/barretenberg/honk/composer/standard_composer.test.cpp b/cpp/src/barretenberg/honk/composer/standard_composer.test.cpp index 36dce4e305..3f3043d09d 100644 --- a/cpp/src/barretenberg/honk/composer/standard_composer.test.cpp +++ b/cpp/src/barretenberg/honk/composer/standard_composer.test.cpp @@ -103,7 +103,7 @@ TEST_F(StandardHonkComposerTests, SigmaIDCorrectness) } // test correctness of the public input delta - auto delta = proof_system::honk::compute_public_input_delta(public_inputs, beta, gamma, n); + auto delta = proof_system::honk::compute_public_input_delta(public_inputs, beta, gamma, n); EXPECT_EQ(left / right, delta); for (size_t i = 0; i < num_public_inputs; ++i) { diff --git a/cpp/src/barretenberg/honk/proof_system/prover.cpp b/cpp/src/barretenberg/honk/proof_system/prover.cpp index 9407fe95f6..df49db3111 100644 --- a/cpp/src/barretenberg/honk/proof_system/prover.cpp +++ b/cpp/src/barretenberg/honk/proof_system/prover.cpp @@ -104,7 +104,7 @@ template void StandardProver_::execute_grand_pro // Compute and store parameters required by relations in Sumcheck auto [beta, gamma] = transcript.get_challenges("beta", "gamma"); - auto public_input_delta = compute_public_input_delta(public_inputs, beta, gamma, key->circuit_size); + auto public_input_delta = compute_public_input_delta(public_inputs, beta, gamma, key->circuit_size); relation_parameters = sumcheck::RelationParameters{ .beta = beta, diff --git a/cpp/src/barretenberg/honk/proof_system/ultra_prover.cpp b/cpp/src/barretenberg/honk/proof_system/ultra_prover.cpp index f96683b206..4c4e146488 100644 --- a/cpp/src/barretenberg/honk/proof_system/ultra_prover.cpp +++ b/cpp/src/barretenberg/honk/proof_system/ultra_prover.cpp @@ -73,7 +73,7 @@ UltraProver_::UltraProver_(std::shared_ptr // Add public inputs to transcript from the second wire polynomial std::span public_wires_source = prover_polynomials.w_r; - const size_t pub_input_offset = 1; + const size_t pub_input_offset = Flavor::zero_row ? 1 : 0; for (size_t i = pub_input_offset; i < key->num_public_inputs + pub_input_offset; ++i) { public_inputs.emplace_back(public_wires_source[i]); @@ -157,7 +157,7 @@ template void UltraProver_::execute_grand_product_c // Compute and store parameters required by relations in Sumcheck auto [beta, gamma] = transcript.get_challenges("beta", "gamma"); - auto public_input_delta = compute_public_input_delta(public_inputs, beta, gamma, key->circuit_size, 1); + auto public_input_delta = compute_public_input_delta(public_inputs, beta, gamma, key->circuit_size); auto lookup_grand_product_delta = compute_lookup_grand_product_delta(beta, gamma, key->circuit_size); relation_parameters.beta = beta; diff --git a/cpp/src/barretenberg/honk/proof_system/ultra_verifier.cpp b/cpp/src/barretenberg/honk/proof_system/ultra_verifier.cpp index 98bd911227..0a149ac791 100644 --- a/cpp/src/barretenberg/honk/proof_system/ultra_verifier.cpp +++ b/cpp/src/barretenberg/honk/proof_system/ultra_verifier.cpp @@ -84,7 +84,7 @@ template bool UltraVerifier_::verify_proof(const plonk // Get permutation challenges auto [beta, gamma] = transcript.get_challenges("beta", "gamma"); - const FF public_input_delta = compute_public_input_delta(public_inputs, beta, gamma, circuit_size, 1); + const FF public_input_delta = compute_public_input_delta(public_inputs, beta, gamma, circuit_size); const FF lookup_grand_product_delta = compute_lookup_grand_product_delta(beta, gamma, circuit_size); relation_parameters.beta = beta; diff --git a/cpp/src/barretenberg/honk/proof_system/verifier.cpp b/cpp/src/barretenberg/honk/proof_system/verifier.cpp index 452e2e0c3a..a109f02ca1 100644 --- a/cpp/src/barretenberg/honk/proof_system/verifier.cpp +++ b/cpp/src/barretenberg/honk/proof_system/verifier.cpp @@ -95,7 +95,7 @@ template bool StandardVerifier_::verify_proof(const pl // Get permutation challenges auto [beta, gamma] = transcript.get_challenges("beta", "gamma"); - const FF public_input_delta = compute_public_input_delta(public_inputs, beta, gamma, circuit_size); + const FF public_input_delta = compute_public_input_delta(public_inputs, beta, gamma, circuit_size); sumcheck::RelationParameters relation_parameters{ .beta = beta, diff --git a/cpp/src/barretenberg/honk/sumcheck/relations/relation_correctness.test.cpp b/cpp/src/barretenberg/honk/sumcheck/relations/relation_correctness.test.cpp index 1b3358b45b..50065bb606 100644 --- a/cpp/src/barretenberg/honk/sumcheck/relations/relation_correctness.test.cpp +++ b/cpp/src/barretenberg/honk/sumcheck/relations/relation_correctness.test.cpp @@ -109,7 +109,7 @@ TEST_F(RelationCorrectnessTests, StandardRelationCorrectness) // Compute public input delta const auto public_inputs = circuit_constructor.get_public_inputs(); auto public_input_delta = - honk::compute_public_input_delta(public_inputs, beta, gamma, prover.key->circuit_size); + honk::compute_public_input_delta(public_inputs, beta, gamma, prover.key->circuit_size); sumcheck::RelationParameters params{ .beta = beta, @@ -303,9 +303,8 @@ TEST_F(RelationCorrectnessTests, UltraRelationCorrectness) // Compute public input delta const auto public_inputs = circuit_constructor.get_public_inputs(); - const size_t pub_inputs_offset = 1; auto public_input_delta = - honk::compute_public_input_delta(public_inputs, beta, gamma, prover.key->circuit_size, pub_inputs_offset); + honk::compute_public_input_delta(public_inputs, beta, gamma, prover.key->circuit_size); auto lookup_grand_product_delta = honk::compute_lookup_grand_product_delta(beta, gamma, prover.key->circuit_size); diff --git a/cpp/src/barretenberg/honk/sumcheck/sumcheck.test.cpp b/cpp/src/barretenberg/honk/sumcheck/sumcheck.test.cpp index a8449c4dc0..80504cd2a9 100644 --- a/cpp/src/barretenberg/honk/sumcheck/sumcheck.test.cpp +++ b/cpp/src/barretenberg/honk/sumcheck/sumcheck.test.cpp @@ -450,7 +450,7 @@ TEST_F(SumcheckTests, RealCircuitStandard) // Compute public input delta const auto public_inputs = circuit_constructor.get_public_inputs(); auto public_input_delta = - honk::compute_public_input_delta(public_inputs, beta, gamma, prover.key->circuit_size); + honk::compute_public_input_delta(public_inputs, beta, gamma, prover.key->circuit_size); sumcheck::RelationParameters relation_parameters{ .beta = beta, @@ -632,7 +632,7 @@ TEST_F(SumcheckTests, RealCircuitUltra) // Compute public input delta const auto public_inputs = circuit_constructor.get_public_inputs(); auto public_input_delta = - honk::compute_public_input_delta(public_inputs, beta, gamma, prover.key->circuit_size, 1); + honk::compute_public_input_delta(public_inputs, beta, gamma, prover.key->circuit_size); auto lookup_grand_product_delta = honk::compute_lookup_grand_product_delta(beta, gamma, prover.key->circuit_size); diff --git a/cpp/src/barretenberg/honk/utils/grand_product_delta.hpp b/cpp/src/barretenberg/honk/utils/grand_product_delta.hpp index 2fda6a2a02..552b76c99a 100644 --- a/cpp/src/barretenberg/honk/utils/grand_product_delta.hpp +++ b/cpp/src/barretenberg/honk/utils/grand_product_delta.hpp @@ -13,13 +13,13 @@ namespace proof_system::honk { * @param domain_size Total number of rows required for the circuit (power of 2) * @return Field Public input Δ */ -template -Field compute_public_input_delta(std::span public_inputs, - const Field& beta, - const Field& gamma, - const size_t domain_size, - const size_t offset = 0) +template +typename Flavor::FF compute_public_input_delta(std::span public_inputs, + const typename Flavor::FF& beta, + const typename Flavor::FF& gamma, + const size_t domain_size) { + using Field = typename Flavor::FF; Field numerator = Field::one(); Field denominator = Field::one(); @@ -42,6 +42,9 @@ Field compute_public_input_delta(std::span public_inputs, // denominator_acc = γ - β⋅(1+i) = γ - β - β⋅i // at the end of the loop, add and subtract β to each term respectively to // set the expected value for the start of iteration i+1. + // Note: If a zero row is included at the start of the execution + // trace, the indices of the PI are offset by 1. + const size_t offset = Flavor::zero_row ? 1 : 0; Field numerator_acc = gamma + (beta * Field(domain_size + offset)); Field denominator_acc = gamma - beta * Field(1 + offset); From 71901acc8850d96f72d013ec6b925bd9b9b014c9 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Mon, 17 Jul 2023 15:52:08 +0000 Subject: [PATCH 12/13] comments and renaming --- .../honk/composer/standard_composer.cpp | 2 + .../honk/composer/ultra_composer.cpp | 6 +- .../honk/composer/ultra_composer.hpp | 4 +- cpp/src/barretenberg/honk/flavor/standard.hpp | 2 +- .../honk/flavor/standard_grumpkin.hpp | 2 +- cpp/src/barretenberg/honk/flavor/ultra.hpp | 2 +- .../honk/flavor/ultra_grumpkin.hpp | 2 +- .../honk/proof_system/ultra_prover.cpp | 10 +- .../honk/utils/grand_product_delta.hpp | 2 +- cpp/src/barretenberg/plonk/flavor/flavor.hpp | 6 +- .../circuit_builder/ultra_circuit_builder.hpp | 1 - .../proof_system/composer/composer_lib.hpp | 9 +- .../composer/composer_lib.test.cpp | 34 ----- .../proof_system/composer/permutation_lib.hpp | 12 +- .../composer/permutation_lib.test.cpp | 140 +++++++++--------- 15 files changed, 103 insertions(+), 131 deletions(-) diff --git a/cpp/src/barretenberg/honk/composer/standard_composer.cpp b/cpp/src/barretenberg/honk/composer/standard_composer.cpp index e3a528feae..a189c3fb95 100644 --- a/cpp/src/barretenberg/honk/composer/standard_composer.cpp +++ b/cpp/src/barretenberg/honk/composer/standard_composer.cpp @@ -50,6 +50,7 @@ std::shared_ptr StandardComposer_::compute_ return proving_key; } + // Construct a proving key proving_key = std::make_shared(dyadic_circuit_size, num_public_inputs); // Compute lagrange selectors @@ -115,6 +116,7 @@ StandardVerifier_ StandardComposer_::create_verifier(const Circu template StandardProver_ StandardComposer_::create_prover(const CircuitBuilder& circuit_constructor) { + // Compute some key cicuit size paramaters num_public_inputs = circuit_constructor.public_inputs.size(); total_num_gates = circuit_constructor.num_gates + num_public_inputs; dyadic_circuit_size = circuit_constructor.get_circuit_subgroup_size(total_num_gates); diff --git a/cpp/src/barretenberg/honk/composer/ultra_composer.cpp b/cpp/src/barretenberg/honk/composer/ultra_composer.cpp index 774066caa5..86e3a6b579 100644 --- a/cpp/src/barretenberg/honk/composer/ultra_composer.cpp +++ b/cpp/src/barretenberg/honk/composer/ultra_composer.cpp @@ -25,11 +25,11 @@ void UltraComposer_::compute_circuit_size_parameters(CircuitBuilder& cir num_public_inputs = circuit_constructor.public_inputs.size(); // minimum circuit size due to the length of lookups plus tables - const size_t minimum_circuit_size_due_to_lookups = tables_size + lookups_size + zero_wire_offset; + const size_t minimum_circuit_size_due_to_lookups = tables_size + lookups_size + zero_row_offset; // number of populated rows in the execution trace const size_t num_rows_populated_in_execution_trace = - circuit_constructor.num_gates + circuit_constructor.public_inputs.size() + zero_wire_offset; + circuit_constructor.num_gates + circuit_constructor.public_inputs.size() + zero_row_offset; // The number of gates is max(lookup gates + tables, rows already populated in trace) + 1, where the +1 is due to // addition of a "zero row" at top of the execution trace to ensure wires and other polys are shiftable. @@ -141,7 +141,7 @@ template void UltraComposer_::compute_witness(Circu // using the plookup challenge `eta`. We need to update the records with an offset Because we shift the gates by // the number of public inputs plus an additional offset for a zero row. auto add_public_inputs_offset = [this](uint32_t gate_index) { - return gate_index + num_public_inputs + zero_wire_offset; + return gate_index + num_public_inputs + zero_row_offset; }; proving_key->memory_read_records = std::vector(); proving_key->memory_write_records = std::vector(); diff --git a/cpp/src/barretenberg/honk/composer/ultra_composer.hpp b/cpp/src/barretenberg/honk/composer/ultra_composer.hpp index 40ebddc2a1..e58583f169 100644 --- a/cpp/src/barretenberg/honk/composer/ultra_composer.hpp +++ b/cpp/src/barretenberg/honk/composer/ultra_composer.hpp @@ -22,7 +22,7 @@ template class UltraComposer_ { using PCSVerificationKey = typename PCSParams::VerificationKey; // offset due to placing zero wires at the start of execution trace - static constexpr size_t zero_wire_offset = Flavor::zero_row ? 1 : 0; + static constexpr size_t zero_row_offset = Flavor::has_zero_row ? 1 : 0; static constexpr std::string_view NAME_STRING = "UltraHonk"; static constexpr size_t NUM_WIRES = CircuitBuilder::NUM_WIRES; @@ -38,7 +38,7 @@ template class UltraComposer_ { std::vector recursive_proof_public_input_indices; bool contains_recursive_proof = false; bool computed_witness = false; - size_t total_num_gates = 0; // num_gates + num_pub_inputs + tables + zero_wire_offset (used to compute dyadic size) + size_t total_num_gates = 0; // num_gates + num_pub_inputs + tables + zero_row_offset (used to compute dyadic size) size_t dyadic_circuit_size = 0; // final dyadic circuit size size_t lookups_size = 0; // total number of lookup gates size_t tables_size = 0; // total number of table entries diff --git a/cpp/src/barretenberg/honk/flavor/standard.hpp b/cpp/src/barretenberg/honk/flavor/standard.hpp index 9997637779..a0205be2b2 100644 --- a/cpp/src/barretenberg/honk/flavor/standard.hpp +++ b/cpp/src/barretenberg/honk/flavor/standard.hpp @@ -67,7 +67,7 @@ class Standard { using RelationValues = decltype(create_relation_values_container()); // Whether or not the first row of the execution trace is reserved for 0s to enable shifts - static constexpr bool zero_row = false; + static constexpr bool has_zero_row = false; private: /** diff --git a/cpp/src/barretenberg/honk/flavor/standard_grumpkin.hpp b/cpp/src/barretenberg/honk/flavor/standard_grumpkin.hpp index 036faae5c5..87ad545d62 100644 --- a/cpp/src/barretenberg/honk/flavor/standard_grumpkin.hpp +++ b/cpp/src/barretenberg/honk/flavor/standard_grumpkin.hpp @@ -58,7 +58,7 @@ class StandardGrumpkin { using RelationValues = decltype(create_relation_values_container()); // Whether or not the first row of the execution trace is reserved for 0s to enable shifts - static constexpr bool zero_row = false; + static constexpr bool has_zero_row = false; private: /** diff --git a/cpp/src/barretenberg/honk/flavor/ultra.hpp b/cpp/src/barretenberg/honk/flavor/ultra.hpp index 28c80eef2d..31a9af032d 100644 --- a/cpp/src/barretenberg/honk/flavor/ultra.hpp +++ b/cpp/src/barretenberg/honk/flavor/ultra.hpp @@ -72,7 +72,7 @@ class Ultra { using RelationValues = decltype(create_relation_values_container()); // Whether or not the first row of the execution trace is reserved for 0s to enable shifts - static constexpr bool zero_row = true; + static constexpr bool has_zero_row = true; private: template diff --git a/cpp/src/barretenberg/honk/flavor/ultra_grumpkin.hpp b/cpp/src/barretenberg/honk/flavor/ultra_grumpkin.hpp index 9144699c89..c5dc82f41a 100644 --- a/cpp/src/barretenberg/honk/flavor/ultra_grumpkin.hpp +++ b/cpp/src/barretenberg/honk/flavor/ultra_grumpkin.hpp @@ -70,7 +70,7 @@ class UltraGrumpkin { using RelationValues = decltype(create_relation_values_container()); // Whether or not the first row of the execution trace is reserved for 0s to enable shifts - static constexpr bool zero_row = true; + static constexpr bool has_zero_row = true; private: template diff --git a/cpp/src/barretenberg/honk/proof_system/ultra_prover.cpp b/cpp/src/barretenberg/honk/proof_system/ultra_prover.cpp index 4c4e146488..b382064f3a 100644 --- a/cpp/src/barretenberg/honk/proof_system/ultra_prover.cpp +++ b/cpp/src/barretenberg/honk/proof_system/ultra_prover.cpp @@ -71,12 +71,14 @@ UltraProver_::UltraProver_(std::shared_ptr prover_polynomials.w_r_shift = key->w_r.shifted(); prover_polynomials.w_o_shift = key->w_o.shifted(); - // Add public inputs to transcript from the second wire polynomial + // Add public inputs to transcript from the second wire polynomial; The PI have been written into the wires at the + // 0th or 1st index depending on whether or not a zero row is utilized. std::span public_wires_source = prover_polynomials.w_r; - const size_t pub_input_offset = Flavor::zero_row ? 1 : 0; + const size_t pub_input_offset = Flavor::has_zero_row ? 1 : 0; - for (size_t i = pub_input_offset; i < key->num_public_inputs + pub_input_offset; ++i) { - public_inputs.emplace_back(public_wires_source[i]); + for (size_t i = 0; i < key->num_public_inputs; ++i) { + size_t idx = i + pub_input_offset; + public_inputs.emplace_back(public_wires_source[idx]); } } diff --git a/cpp/src/barretenberg/honk/utils/grand_product_delta.hpp b/cpp/src/barretenberg/honk/utils/grand_product_delta.hpp index 552b76c99a..1860026639 100644 --- a/cpp/src/barretenberg/honk/utils/grand_product_delta.hpp +++ b/cpp/src/barretenberg/honk/utils/grand_product_delta.hpp @@ -44,7 +44,7 @@ typename Flavor::FF compute_public_input_delta(std::span class UltraCircuitBuilder_ : public CircuitBuilderBaseadd_public_variable(FF::zero()); // WORKTODO: possible hack to make shifts work w/ PI this->zero_idx = put_constant_variable(FF::zero()); this->tau.insert({ DUMMY_TAG, DUMMY_TAG }); // TODO(luke): explain this }; diff --git a/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp b/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp index 7121c2ae73..e1802456d0 100644 --- a/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp +++ b/cpp/src/barretenberg/proof_system/composer/composer_lib.hpp @@ -17,10 +17,9 @@ template void construct_selector_polynomials(const typename Flavor::CircuitBuilder& circuit_constructor, typename Flavor::ProvingKey* proving_key) { - const size_t zero_row_offset = Flavor::zero_row ? 1 : 0; - // Offset for starting to write selectors is input offset + num public inputs + // Offset for starting to write selectors is zero row offset + num public inputs + const size_t zero_row_offset = Flavor::has_zero_row ? 1 : 0; const size_t gate_offset = zero_row_offset + circuit_constructor.public_inputs.size(); - // const size_t offset = num_public_inputs + // TODO(#398): Loose coupling here! Would rather build up pk from arithmetization size_t selector_idx = 0; // TODO(#391) zip for (auto& selector_values : circuit_constructor.selectors) { @@ -60,7 +59,7 @@ template std::vector construct_wire_polynomials_base( const typename Flavor::CircuitBuilder& circuit_constructor, const size_t dyadic_circuit_size) { - const size_t zero_row_offset = Flavor::zero_row ? 1 : 0; + const size_t zero_row_offset = Flavor::has_zero_row ? 1 : 0; std::span public_inputs = circuit_constructor.public_inputs; const size_t num_public_inputs = public_inputs.size(); @@ -73,7 +72,7 @@ std::vector construct_wire_polynomials_base( // Expect all values to be set to 0 initially barretenberg::polynomial w_lagrange(dyadic_circuit_size); - // Place all public inputs at the start of the first two wires, possibly offset by some value > 0. + // Place all public inputs at the start of the first two wires, possibly offset by a zero row. // All selectors at these indices are set to 0, so these values are not constrained at all. const size_t pub_input_offset = zero_row_offset; // offset at which to start writing pub inputs if (wire_idx < 2) { diff --git a/cpp/src/barretenberg/proof_system/composer/composer_lib.test.cpp b/cpp/src/barretenberg/proof_system/composer/composer_lib.test.cpp index 0ac0c6910e..0df8d50666 100644 --- a/cpp/src/barretenberg/proof_system/composer/composer_lib.test.cpp +++ b/cpp/src/barretenberg/proof_system/composer/composer_lib.test.cpp @@ -20,22 +20,6 @@ class ComposerLibTests : public ::testing::Test { }(); }; -// TEST_F(ComposerLibTests, InitializeProvingKey) -// { -// static_assert(IsHonkFlavor); - -// EXPECT_EQ(circuit_constructor.get_circuit_subgroup_size(7), 8); - -// barretenberg::srs::factories::CrsFactory crs_factory; - -// auto pk = initialize_proving_key(circuit_constructor, -// &crs_factory, -// /*minimum_circuit_size=*/0, -// /*num_randomized_gates=*/2); -// EXPECT_EQ(pk->circuit_size, 8); -// EXPECT_EQ(pk->num_public_inputs, 0); -// } - TEST_F(ComposerLibTests, ConstructSelectors) { circuit_constructor.q_m = { 1, 2, 3, 4 }; @@ -72,24 +56,6 @@ TEST_F(ComposerLibTests, ConstructSelectors) EXPECT_EQ(proving_key.q_c[3], 20); } -// TEST_F(ComposerLibTests, EnforceNonzeroSelectors) -// { -// circuit_constructor.q_m = { 0, 0, 0, 0 }; -// circuit_constructor.q_1 = { 0, 0, 0, 0 }; -// circuit_constructor.q_2 = { 0, 0, 0, 0 }; -// circuit_constructor.q_3 = { 0, 0, 0, 0 }; -// circuit_constructor.q_c = { 0, 0, 0, 0 }; - -// construct_selector_polynomials(circuit_constructor, &proving_key); -// enforce_nonzero_selector_polynomials(circuit_constructor, &proving_key); - -// EXPECT_EQ(proving_key.q_m[3], 1); -// EXPECT_EQ(proving_key.q_l[3], 2); -// EXPECT_EQ(proving_key.q_r[3], 3); -// EXPECT_EQ(proving_key.q_o[3], 4); -// EXPECT_EQ(proving_key.q_c[3], 5); -// } - TEST_F(ComposerLibTests, ConstructWitnessPolynomialsBase) { circuit_constructor.add_public_variable(1024); diff --git a/cpp/src/barretenberg/proof_system/composer/permutation_lib.hpp b/cpp/src/barretenberg/proof_system/composer/permutation_lib.hpp index 5ebb87495e..1c7c1eeda4 100644 --- a/cpp/src/barretenberg/proof_system/composer/permutation_lib.hpp +++ b/cpp/src/barretenberg/proof_system/composer/permutation_lib.hpp @@ -74,7 +74,7 @@ std::vector compute_wire_copy_cycles(const typename Flavor::C const size_t num_public_inputs = public_inputs.size(); // Define offsets for placement of public inputs and gates in execution trace - const size_t pub_inputs_offset = Flavor::zero_row ? 1 : 0; + const size_t pub_inputs_offset = Flavor::has_zero_row ? 1 : 0; const size_t gates_offset = num_public_inputs + pub_inputs_offset; // Each variable represents one cycle @@ -85,9 +85,9 @@ std::vector compute_wire_copy_cycles(const typename Flavor::C // Represents the index of a variable in circuit_constructor.variables std::span real_variable_index = circuit_constructor.real_variable_index; - // Add 'offset' many rows of wires to the zero index cycle. This will be used to ensure there are offset-many rows - // of zeros at the start of the execution trace. - if (Flavor::zero_row) { + // For some flavors, we need to ensure the value in the 0th index of each wire is 0 to allow for left-shift by 1. To + // do this, we add the wires of the first gate in the execution trace to the "zero index" copy cycle. + if (Flavor::has_zero_row) { for (size_t wire_idx = 0; wire_idx < Flavor::NUM_WIRES; ++wire_idx) { const auto wire_index = static_cast(wire_idx); const uint32_t gate_index = 0; // place zeros at 0th index @@ -223,8 +223,8 @@ PermutationMapping compute_permutation_mapping( // Add information about public inputs to the computation const auto num_public_inputs = static_cast(circuit_constructor.public_inputs.size()); - // The public inputs are placed at the top of the execution trace, potentially offset by some value. - const size_t zero_row_offset = Flavor::zero_row ? 1 : 0; + // The public inputs are placed at the top of the execution trace, potentially offset by a zero row. + const size_t zero_row_offset = Flavor::has_zero_row ? 1 : 0; for (size_t i = 0; i < num_public_inputs; ++i) { size_t idx = i + zero_row_offset; mapping.sigmas[0][idx].row_index = static_cast(idx); diff --git a/cpp/src/barretenberg/proof_system/composer/permutation_lib.test.cpp b/cpp/src/barretenberg/proof_system/composer/permutation_lib.test.cpp index 12cdf7c47a..ee9125606a 100644 --- a/cpp/src/barretenberg/proof_system/composer/permutation_lib.test.cpp +++ b/cpp/src/barretenberg/proof_system/composer/permutation_lib.test.cpp @@ -8,84 +8,88 @@ namespace proof_system::test_composer_lib { -// class PermutationHelperTests : public ::testing::Test { -// protected: -// using Flavor = honk::flavor::Standard; -// using FF = typename Flavor::FF; -// Flavor::CircuitBuilder circuit_constructor; -// barretenberg::srs::factories::CrsFactory crs_factory = barretenberg::srs::factories::CrsFactory(); -// std::shared_ptr proving_key; +class PermutationHelperTests : public ::testing::Test { + protected: + using Flavor = honk::flavor::Standard; + using FF = typename Flavor::FF; + using ProvingKey = Flavor::ProvingKey; + Flavor::CircuitBuilder circuit_constructor; + barretenberg::srs::factories::CrsFactory crs_factory = barretenberg::srs::factories::CrsFactory(); + std::shared_ptr proving_key; -// virtual void SetUp() -// { -// circuit_constructor.add_public_variable(1024); -// circuit_constructor.add_public_variable(1025); + virtual void SetUp() + { + circuit_constructor.add_public_variable(1024); + circuit_constructor.add_public_variable(1025); -// uint32_t v_1 = circuit_constructor.add_variable(16 + 1); -// uint32_t v_2 = circuit_constructor.add_variable(16 + 2); -// uint32_t v_3 = circuit_constructor.add_variable(16 + 3); -// uint32_t v_4 = circuit_constructor.add_variable(16 + 4); -// uint32_t v_5 = circuit_constructor.add_variable(16 + 5); -// uint32_t v_6 = circuit_constructor.add_variable(16 + 6); -// uint32_t v_7 = circuit_constructor.add_variable(16 + 7); -// uint32_t v_8 = circuit_constructor.add_variable(16 + 8); -// uint32_t v_9 = circuit_constructor.add_variable(16 + 9); -// uint32_t v_10 = circuit_constructor.add_variable(16 + 10); -// uint32_t v_11 = circuit_constructor.add_variable(16 + 11); -// uint32_t v_12 = circuit_constructor.add_variable(16 + 12); + uint32_t v_1 = circuit_constructor.add_variable(16 + 1); + uint32_t v_2 = circuit_constructor.add_variable(16 + 2); + uint32_t v_3 = circuit_constructor.add_variable(16 + 3); + uint32_t v_4 = circuit_constructor.add_variable(16 + 4); + uint32_t v_5 = circuit_constructor.add_variable(16 + 5); + uint32_t v_6 = circuit_constructor.add_variable(16 + 6); + uint32_t v_7 = circuit_constructor.add_variable(16 + 7); + uint32_t v_8 = circuit_constructor.add_variable(16 + 8); + uint32_t v_9 = circuit_constructor.add_variable(16 + 9); + uint32_t v_10 = circuit_constructor.add_variable(16 + 10); + uint32_t v_11 = circuit_constructor.add_variable(16 + 11); + uint32_t v_12 = circuit_constructor.add_variable(16 + 12); -// circuit_constructor.create_add_gate({ v_1, v_5, v_9, 0, 0, 0, 0 }); -// circuit_constructor.create_add_gate({ v_2, v_6, v_10, 0, 0, 0, 0 }); -// circuit_constructor.create_add_gate({ v_3, v_7, v_11, 0, 0, 0, 0 }); -// circuit_constructor.create_add_gate({ v_4, v_8, v_12, 0, 0, 0, 0 }); + circuit_constructor.create_add_gate({ v_1, v_5, v_9, 0, 0, 0, 0 }); + circuit_constructor.create_add_gate({ v_2, v_6, v_10, 0, 0, 0, 0 }); + circuit_constructor.create_add_gate({ v_3, v_7, v_11, 0, 0, 0, 0 }); + circuit_constructor.create_add_gate({ v_4, v_8, v_12, 0, 0, 0, 0 }); -// /* Execution trace: -// w_l w_r w_o -// ------------------------------ -// pub1_idx | pub1_idx | 0 <-- public inputs -// pub2_idx | pub2_idx | 0 <-/ -// zero_idx | zero_idx | zero_idx <-- fix witness for 0 -// one_idx | zero_idx | zero_idx <-- fix witness for 1 -// one_idx | one_idx | one_idx <-- ensure nonzero selectors... TODO(Cody): redundant now -// v_1 | v_5 | v_9 -// v_2 | v_6 | v_10 -// v_3 | v_7 | v_11 -// v_4 | v_8 | v_12 + /* Execution trace: + w_l w_r w_o + ------------------------------ + pub1_idx | pub1_idx | 0 <-- public inputs + pub2_idx | pub2_idx | 0 <-/ + zero_idx | zero_idx | zero_idx <-- fix witness for 0 + one_idx | zero_idx | zero_idx <-- fix witness for 1 + one_idx | one_idx | one_idx <-- ensure nonzero selectors... TODO(Cody): redundant now + v_1 | v_5 | v_9 + v_2 | v_6 | v_10 + v_3 | v_7 | v_11 + v_4 | v_8 | v_12 -// */ + */ -// proving_key = initialize_proving_key(circuit_constructor, &crs_factory, 0, 2); + size_t num_public_inputs = circuit_constructor.public_inputs.size(); + size_t dyadic_circuit_size = + circuit_constructor.get_circuit_subgroup_size(circuit_constructor.num_gates + num_public_inputs); + proving_key = std::make_shared(dyadic_circuit_size, num_public_inputs); -// // construct_selector_polynomials(circuit_constructor, proving_key.get()); -// } -// }; + // construct_selector_polynomials(circuit_constructor, proving_key.get()); + } +}; -// TEST_F(PermutationHelperTests, ComputeWireCopyCycles) -// { -// // TODO(#425) Flesh out these tests -// compute_wire_copy_cycles(circuit_constructor); -// } +TEST_F(PermutationHelperTests, ComputeWireCopyCycles) +{ + // TODO(#425) Flesh out these tests + compute_wire_copy_cycles(circuit_constructor); +} -// TEST_F(PermutationHelperTests, ComputePermutationMapping) -// { -// // TODO(#425) Flesh out these tests -// compute_permutation_mapping(circuit_constructor, proving_key.get()); -// } +TEST_F(PermutationHelperTests, ComputePermutationMapping) +{ + // TODO(#425) Flesh out these tests + compute_permutation_mapping(circuit_constructor, proving_key.get()); +} -// TEST_F(PermutationHelperTests, ComputeHonkStyleSigmaLagrangePolynomialsFromMapping) -// { -// // TODO(#425) Flesh out these tests -// auto mapping = compute_permutation_mapping(circuit_constructor, -// proving_key.get()); compute_honk_style_permutation_lagrange_polynomials_from_mapping( -// proving_key->get_sigma_polynomials(), mapping.sigmas, proving_key.get()); -// } +TEST_F(PermutationHelperTests, ComputeHonkStyleSigmaLagrangePolynomialsFromMapping) +{ + // TODO(#425) Flesh out these tests + auto mapping = compute_permutation_mapping(circuit_constructor, proving_key.get()); + compute_honk_style_permutation_lagrange_polynomials_from_mapping( + proving_key->get_sigma_polynomials(), mapping.sigmas, proving_key.get()); +} -// TEST_F(PermutationHelperTests, ComputeStandardAuxPolynomials) -// { -// // TODO(#425) Flesh out these tests -// compute_standard_honk_id_polynomials(proving_key); -// compute_standard_honk_sigma_permutations(circuit_constructor, proving_key.get()); -// compute_first_and_last_lagrange_polynomials(proving_key); -// } +TEST_F(PermutationHelperTests, ComputeStandardAuxPolynomials) +{ + // TODO(#425) Flesh out these tests + compute_standard_honk_id_polynomials(proving_key); + compute_standard_honk_sigma_permutations(circuit_constructor, proving_key.get()); + compute_first_and_last_lagrange_polynomials(proving_key); +} } // namespace proof_system::test_composer_lib From 4a1f18a7374d47212b9fd2ab8175b09c4aebd860 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Tue, 18 Jul 2023 20:08:23 +0000 Subject: [PATCH 13/13] power of 2 clarification --- cpp/src/barretenberg/honk/composer/ultra_composer.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/src/barretenberg/honk/composer/ultra_composer.hpp b/cpp/src/barretenberg/honk/composer/ultra_composer.hpp index e58583f169..25ed13cc68 100644 --- a/cpp/src/barretenberg/honk/composer/ultra_composer.hpp +++ b/cpp/src/barretenberg/honk/composer/ultra_composer.hpp @@ -39,7 +39,7 @@ template class UltraComposer_ { bool contains_recursive_proof = false; bool computed_witness = false; size_t total_num_gates = 0; // num_gates + num_pub_inputs + tables + zero_row_offset (used to compute dyadic size) - size_t dyadic_circuit_size = 0; // final dyadic circuit size + size_t dyadic_circuit_size = 0; // final power-of-2 circuit size size_t lookups_size = 0; // total number of lookup gates size_t tables_size = 0; // total number of table entries size_t num_public_inputs = 0;