From b5456e3509170626227b22c0b240441e6d0595f0 Mon Sep 17 00:00:00 2001 From: codygunton Date: Tue, 11 Apr 2023 02:54:58 +0000 Subject: [PATCH] WIP on building Honk. --- .../standard_honk_composer_helper.cpp | 85 ++-- .../standard_honk_composer_helper.hpp | 19 +- .../honk/composer/standard_honk_composer.hpp | 5 +- .../composer/standard_honk_composer.test.cpp | 25 +- .../honk/proof_system/verifier.test.cpp | 459 +++++++++--------- .../standard_plonk_composer_helper.cpp | 3 +- .../turbo_plonk_composer_helper.cpp | 3 +- .../ultra_plonk_composer_helper.cpp | 3 +- .../composer/composer_helper_lib.test.cpp | 4 +- .../composer/permutation_helper.hpp | 148 +++--- .../composer/permutation_helper.test.cpp | 83 ++++ .../proof_system/flavor/flavor.hpp | 29 +- 12 files changed, 477 insertions(+), 389 deletions(-) create mode 100644 cpp/src/barretenberg/proof_system/composer/permutation_helper.test.cpp diff --git a/cpp/src/barretenberg/honk/composer/composer_helper/standard_honk_composer_helper.cpp b/cpp/src/barretenberg/honk/composer/composer_helper/standard_honk_composer_helper.cpp index 30f0f3c3f6..7b27e4a0a8 100644 --- a/cpp/src/barretenberg/honk/composer/composer_helper/standard_honk_composer_helper.cpp +++ b/cpp/src/barretenberg/honk/composer/composer_helper/standard_honk_composer_helper.cpp @@ -1,9 +1,11 @@ #include "standard_honk_composer_helper.hpp" +#include "barretenberg/plonk/proof_system/proving_key/proving_key.hpp" #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/honk/flavor/flavor.hpp" #include "barretenberg/proof_system/flavor/flavor.hpp" #include "barretenberg/honk/pcs/commitment_key.hpp" #include "barretenberg/numeric/bitop/get_msb.hpp" +#include "barretenberg/srs/reference_string/reference_string.hpp" #include #include @@ -23,7 +25,7 @@ namespace proof_system::honk { * @param num_reserved_gates The number of reserved gates. * @return Pointer to the initialized proving key updated with selector polynomials. * */ -std::shared_ptr StandardHonkComposerHelper::compute_proving_key_base( +std::shared_ptr StandardHonkComposerHelper::compute_proving_key_base( const CircuitConstructor& constructor, const size_t minimum_circuit_size, const size_t num_randomized_gates) { // Initialize circuit_proving_key @@ -31,7 +33,7 @@ std::shared_ptr StandardHonkComposerHelper::compute_proving_ circuit_proving_key = initialize_proving_key( constructor, crs_factory_.get(), minimum_circuit_size, num_randomized_gates, ComposerType::STANDARD_HONK); // Compute lagrange selectors - construct_selector_polynomials(constructor, circuit_proving_key.get()); + construct_selector_polynomials(constructor, circuit_proving_key.get()); return circuit_proving_key; } @@ -42,29 +44,30 @@ std::shared_ptr StandardHonkComposerHelper::compute_proving_ * (2) sets the polynomial manifest using the data from proving key. */ -template -std::shared_ptr StandardHonkComposerHelper::compute_verification_key_base( - std::shared_ptr const& proving_key, std::shared_ptr const& vrs) +std::shared_ptr StandardHonkComposerHelper::compute_verification_key_base( + std::shared_ptr const& proving_key, + std::shared_ptr const& vrs) { auto key = std::make_shared( proving_key->circuit_size, proving_key->num_public_inputs, vrs, proving_key->composer_type); // TODO(kesha): Dirty hack for now. Need to actually make commitment-agnositc auto commitment_key = pcs::kzg::CommitmentKey(proving_key->circuit_size, "../srs_db/ignition"); - // Compute and store commitments to all precomputed polynomials - key->commitments["Q_M"] = commitment_key.commit(proving_key->polynomial_store.get("q_m_lagrange")); - key->commitments["Q_1"] = commitment_key.commit(proving_key->polynomial_store.get("q_1_lagrange")); - key->commitments["Q_2"] = commitment_key.commit(proving_key->polynomial_store.get("q_2_lagrange")); - key->commitments["Q_3"] = commitment_key.commit(proving_key->polynomial_store.get("q_3_lagrange")); - key->commitments["Q_C"] = commitment_key.commit(proving_key->polynomial_store.get("q_c_lagrange")); - key->commitments["SIGMA_1"] = commitment_key.commit(proving_key->polynomial_store.get("sigma_1_lagrange")); - key->commitments["SIGMA_2"] = commitment_key.commit(proving_key->polynomial_store.get("sigma_2_lagrange")); - key->commitments["SIGMA_3"] = commitment_key.commit(proving_key->polynomial_store.get("sigma_3_lagrange")); - key->commitments["ID_1"] = commitment_key.commit(proving_key->polynomial_store.get("id_1_lagrange")); - key->commitments["ID_2"] = commitment_key.commit(proving_key->polynomial_store.get("id_2_lagrange")); - key->commitments["ID_3"] = commitment_key.commit(proving_key->polynomial_store.get("id_3_lagrange")); - key->commitments["LAGRANGE_FIRST"] = commitment_key.commit(proving_key->polynomial_store.get("L_first_lagrange")); - key->commitments["LAGRANGE_LAST"] = commitment_key.commit(proving_key->polynomial_store.get("L_last_lagrange")); + // // Compute and store commitments to all precomputed polynomials + // key->commitments["Q_M"] = commitment_key.commit(proving_key->polynomial_store.get("q_m_lagrange")); + // key->commitments["Q_1"] = commitment_key.commit(proving_key->polynomial_store.get("q_1_lagrange")); + // key->commitments["Q_2"] = commitment_key.commit(proving_key->polynomial_store.get("q_2_lagrange")); + // key->commitments["Q_3"] = commitment_key.commit(proving_key->polynomial_store.get("q_3_lagrange")); + // key->commitments["Q_C"] = commitment_key.commit(proving_key->polynomial_store.get("q_c_lagrange")); + // key->commitments["SIGMA_1"] = commitment_key.commit(proving_key->polynomial_store.get("sigma_1_lagrange")); + // key->commitments["SIGMA_2"] = commitment_key.commit(proving_key->polynomial_store.get("sigma_2_lagrange")); + // key->commitments["SIGMA_3"] = commitment_key.commit(proving_key->polynomial_store.get("sigma_3_lagrange")); + // key->commitments["ID_1"] = commitment_key.commit(proving_key->polynomial_store.get("id_1_lagrange")); + // key->commitments["ID_2"] = commitment_key.commit(proving_key->polynomial_store.get("id_2_lagrange")); + // key->commitments["ID_3"] = commitment_key.commit(proving_key->polynomial_store.get("id_3_lagrange")); + // key->commitments["LAGRANGE_FIRST"] = + // commitment_key.commit(proving_key->polynomial_store.get("L_first_lagrange")); key->commitments["LAGRANGE_LAST"] = + // commitment_key.commit(proving_key->polynomial_store.get("L_last_lagrange")); return key; } @@ -78,14 +81,14 @@ std::shared_ptr StandardHonkComposerHelper -void StandardHonkComposerHelper::compute_witness(const CircuitConstructor& circuit_constructor, - const size_t minimum_circuit_size) +void StandardHonkComposerHelper::compute_witness(const CircuitConstructor& circuit_constructor, + const size_t minimum_circuit_size) { if (computed_witness) { return; } - wire_polynomials = compute_witness_base(circuit_constructor, minimum_circuit_size, NUM_RANDOMIZED_GATES); + wire_polynomials = + construct_wire_polynomials_base(circuit_constructor, minimum_circuit_size, NUM_RANDOMIZED_GATES); computed_witness = true; } @@ -97,20 +100,19 @@ void StandardHonkComposerHelper::compute_witness(const Circu * @return Proving key with saved computed polynomials. * */ -template -std::shared_ptr StandardHonkComposerHelper::compute_proving_key( +std::shared_ptr StandardHonkComposerHelper::compute_proving_key( const CircuitConstructor& circuit_constructor) { if (circuit_proving_key) { return circuit_proving_key; } // Compute q_l, q_r, q_o, etc polynomials + // TODO(Cody): meaningless constructor here StandardHonkComposerHelper::compute_proving_key_base(circuit_constructor, ComposerType::STANDARD_HONK); // Compute sigma polynomials (we should update that late) - compute_standard_honk_sigma_permutations(circuit_constructor, - circuit_proving_key.get()); - compute_standard_honk_id_polynomials(circuit_proving_key.get()); + compute_standard_honk_sigma_permutations(circuit_constructor, circuit_proving_key.get()); + compute_standard_honk_id_polynomials(circuit_proving_key.get()); compute_first_and_last_lagrange_polynomials(circuit_proving_key.get()); @@ -122,8 +124,7 @@ std::shared_ptr StandardHonkComposerHelper -std::shared_ptr StandardHonkComposerHelper::compute_verification_key( +std::shared_ptr StandardHonkComposerHelper::compute_verification_key( const CircuitConstructor& circuit_constructor) { if (circuit_verification_key) { @@ -140,9 +141,7 @@ std::shared_ptr StandardHonkComposerHelper -StandardVerifier StandardHonkComposerHelper::create_verifier( - const CircuitConstructor& circuit_constructor) +StandardVerifier StandardHonkComposerHelper::create_verifier(const CircuitConstructor& circuit_constructor) { compute_verification_key(circuit_constructor); StandardVerifier output_state(circuit_verification_key); @@ -155,22 +154,20 @@ StandardVerifier StandardHonkComposerHelper::create_verifier return output_state; } -// template -template -// TODO(Cody): this file should be generic with regard to flavor/arithmetization/whatever. -StandardProver StandardHonkComposerHelper::create_prover( - const CircuitConstructor& circuit_constructor) +// +StandardProver StandardHonkComposerHelper::create_prover(const CircuitConstructor& circuit_constructor) { compute_proving_key(circuit_constructor); compute_witness(circuit_constructor); - size_t num_sumcheck_rounds(circuit_proving_key->log_circuit_size); - // auto manifest = Flavor::create_manifest(circuit_constructor.public_inputs.size(), num_sumcheck_rounds); - StandardProver output_state(std::move(wire_polynomials), circuit_proving_key); + // size_t num_sumcheck_rounds(circuit_proving_key->log_circuit_size); + // StandardProver output_state(std::move(wire_polynomials), circuit_proving_key); + auto crs_factory = ReferenceStringFactory(); + auto crs = crs_factory.get_prover_crs(999); + auto pk_ptr = std::make_shared(12, 2, crs, ComposerType::STANDARD); + + StandardProver output_state(std::move(wire_polynomials), pk_ptr); return output_state; } -template class StandardHonkComposerHelper; -template StandardProver StandardHonkComposerHelper::create_prover( - const StandardCircuitConstructor& circuit_constructor); } // namespace proof_system::honk diff --git a/cpp/src/barretenberg/honk/composer/composer_helper/standard_honk_composer_helper.hpp b/cpp/src/barretenberg/honk/composer/composer_helper/standard_honk_composer_helper.hpp index 8ff6cc39a6..17c9e7447b 100644 --- a/cpp/src/barretenberg/honk/composer/composer_helper/standard_honk_composer_helper.hpp +++ b/cpp/src/barretenberg/honk/composer/composer_helper/standard_honk_composer_helper.hpp @@ -19,11 +19,12 @@ namespace proof_system::honk { class StandardHonkComposerHelper { public: using Flavor = flavor::Standard; - using CircuitConstructor = typename Flavor::CircuitConstructor; + using CircuitConstructor = Flavor::CircuitConstructor; + using ProvingKey = Flavor::ProvingKey; static constexpr size_t NUM_RANDOMIZED_GATES = 2; // equal to the number of multilinear evaluations leaked static constexpr size_t num_wires = CircuitConstructor::num_wires; - std::shared_ptr circuit_proving_key; + std::shared_ptr circuit_proving_key; std::vector wire_polynomials; std::shared_ptr circuit_verification_key; // TODO(#218)(kesha): we need to put this into the commitment key, so that the composer doesn't have to handle srs @@ -42,8 +43,7 @@ class StandardHonkComposerHelper { StandardHonkComposerHelper(std::unique_ptr&& crs_factory) : crs_factory_(std::move(crs_factory)) {} - StandardHonkComposerHelper(std::shared_ptr p_key, - std::shared_ptr v_key) + StandardHonkComposerHelper(std::shared_ptr p_key, std::shared_ptr v_key) : circuit_proving_key(std::move(p_key)) , circuit_verification_key(std::move(v_key)) {} @@ -53,7 +53,7 @@ class StandardHonkComposerHelper { StandardHonkComposerHelper& operator=(const StandardHonkComposerHelper& other) = delete; ~StandardHonkComposerHelper() = default; - std::shared_ptr compute_proving_key(const CircuitConstructor& circuit_constructor); + std::shared_ptr compute_proving_key(const CircuitConstructor& circuit_constructor); std::shared_ptr compute_verification_key(const CircuitConstructor& circuit_constructor); StandardVerifier create_verifier(const CircuitConstructor& circuit_constructor); @@ -62,14 +62,13 @@ class StandardHonkComposerHelper { // TODO(#216)(Adrian): Seems error prone to provide the number of randomized gates // Cody: Where should this go? In the flavor (or whatever that becomes)? - std::shared_ptr compute_proving_key_base( - const CircuitConstructor& circuit_constructor, - const size_t minimum_ciricut_size = 0, - const size_t num_randomized_gates = NUM_RANDOMIZED_GATES); + std::shared_ptr compute_proving_key_base(const CircuitConstructor& circuit_constructor, + const size_t minimum_ciricut_size = 0, + const size_t num_randomized_gates = NUM_RANDOMIZED_GATES); // This needs to be static as it may be used only to compute the selector commitments. static std::shared_ptr compute_verification_key_base( - std::shared_ptr const& proving_key, std::shared_ptr const& vrs); + std::shared_ptr const& proving_key, std::shared_ptr const& vrs); void compute_witness(const CircuitConstructor& circuit_constructor, const size_t minimum_circuit_size = 0); }; diff --git a/cpp/src/barretenberg/honk/composer/standard_honk_composer.hpp b/cpp/src/barretenberg/honk/composer/standard_honk_composer.hpp index 0f15c44963..b985666f23 100644 --- a/cpp/src/barretenberg/honk/composer/standard_honk_composer.hpp +++ b/cpp/src/barretenberg/honk/composer/standard_honk_composer.hpp @@ -19,6 +19,7 @@ class StandardHonkComposer { public: using Flavor = flavor::Standard; using CircuitConstructor = StandardCircuitConstructor; + using ProvingKey = typename Flavor::ProvingKey; static constexpr ComposerType type = ComposerType::STANDARD_HONK; // TODO(Cody): Get rid of this. static constexpr size_t UINT_LOG2_BASE = 2; @@ -61,7 +62,7 @@ class StandardHonkComposer { {} - StandardHonkComposer(std::shared_ptr const& p_key, + StandardHonkComposer(std::shared_ptr const& p_key, std::shared_ptr const& v_key, size_t size_hint = 0) : circuit_constructor(size_hint) @@ -165,7 +166,7 @@ class StandardHonkComposer { /**Proof and verification-related methods*/ - std::shared_ptr compute_proving_key() + std::shared_ptr compute_proving_key() { return composer_helper.compute_proving_key(circuit_constructor); } diff --git a/cpp/src/barretenberg/honk/composer/standard_honk_composer.test.cpp b/cpp/src/barretenberg/honk/composer/standard_honk_composer.test.cpp index 453d11edb0..186a8b30ba 100644 --- a/cpp/src/barretenberg/honk/composer/standard_honk_composer.test.cpp +++ b/cpp/src/barretenberg/honk/composer/standard_honk_composer.test.cpp @@ -8,6 +8,7 @@ #include "barretenberg/honk/sumcheck/relations/grand_product_computation_relation.hpp" #include "barretenberg/honk/sumcheck/relations/grand_product_initialization_relation.hpp" #include "barretenberg/honk/utils/public_inputs.hpp" +#include "barretenberg/polynomials/polynomial.hpp" #include @@ -89,7 +90,9 @@ TEST(StandardHonkComposer, SigmaIDCorrectness) // Let's check that indices are the same and nothing is lost, first for (size_t j = 0; j < composer.num_wires; ++j) { std::string index = std::to_string(j + 1); - const auto& sigma_j = proving_key->polynomial_store.get("sigma_" + index + "_lagrange"); + const auto& sigma_j = barretenberg::polynomial(); + // WORKTODO + // const auto& sigma_j = proving_key->polynomial_store.get("sigma_" + index + "_lagrange"); for (size_t i = 0; i < n; ++i) { left *= (gamma + j * n + i); right *= (gamma + sigma_j[i]); @@ -115,9 +118,13 @@ TEST(StandardHonkComposer, SigmaIDCorrectness) for (size_t j = 0; j < composer.num_wires; ++j) { std::string index = std::to_string(j + 1); - const auto& permutation_polynomial = proving_key->polynomial_store.get("sigma_" + index + "_lagrange"); + const auto& permutation_polynomial = barretenberg::polynomial(10); + // WORKTODO + // const auto& permutation_polynomial = proving_key->polynomial_store.get("sigma_" + index + "_lagrange"); const auto& witness_polynomial = composer.composer_helper.wire_polynomials[j]; - const auto& id_polynomial = proving_key->polynomial_store.get("id_" + index + "_lagrange"); + const auto& id_polynomial = barretenberg::polynomial(10); + // WORKTODO + // const auto& id_polynomial = proving_key->polynomial_store.get("id_" + index + "_lagrange"); // left = ∏ᵢ,ⱼ(ωᵢ,ⱼ + β⋅ind(i,j) + γ) // right = ∏ᵢ,ⱼ(ωᵢ,ⱼ + β⋅σ(i,j) + γ) for (size_t i = 0; i < proving_key->circuit_size; ++i) { @@ -203,7 +210,10 @@ TEST(StandardHonkComposer, LagrangeCorrectness) random_polynomial[i] = barretenberg::fr::random_element(); } // Compute inner product of random polynomial and the first lagrange polynomial - barretenberg::polynomial first_lagrange_polynomial = proving_key->polynomial_store.get("L_first_lagrange"); + + auto first_lagrange_polynomial = barretenberg::polynomial(10); + // WORKTODO + // barretenberg::polynomial first_lagrange_polynomial = proving_key->polynomial_store.get("L_first_lagrange"); barretenberg::fr first_product(0); for (size_t i = 0; i < proving_key->circuit_size; i++) { first_product += random_polynomial[i] * first_lagrange_polynomial[i]; @@ -211,7 +221,9 @@ TEST(StandardHonkComposer, LagrangeCorrectness) EXPECT_EQ(first_product, random_polynomial[0]); // Compute inner product of random polynomial and the last lagrange polynomial - barretenberg::polynomial last_lagrange_polynomial = proving_key->polynomial_store.get("L_last_lagrange"); + auto last_lagrange_polynomial = barretenberg::polynomial(10); + // WORKTODO + // barretenberg::polynomial last_lagrange_polynomial = proving_key->polynomial_store.get("L_last_lagrange"); barretenberg::fr last_product(0); for (size_t i = 0; i < proving_key->circuit_size; i++) { last_product += random_polynomial[i] * last_lagrange_polynomial[i]; @@ -260,7 +272,8 @@ TEST(StandardHonkComposer, AssertEquals) // Put the sigma polynomials into a vector for easy access for (size_t i = 0; i < composer.num_wires; i++) { std::string index = std::to_string(i + 1); - sigma_polynomials.push_back(proving_key->polynomial_store.get("sigma_" + index + "_lagrange")); + // WORKTODO + // sigma_polynomials.push_back(proving_key->polynomial_store.get("sigma_" + index + "_lagrange")); } // Let's compute the maximum cycle diff --git a/cpp/src/barretenberg/honk/proof_system/verifier.test.cpp b/cpp/src/barretenberg/honk/proof_system/verifier.test.cpp index b98d39e893..585f76521b 100644 --- a/cpp/src/barretenberg/honk/proof_system/verifier.test.cpp +++ b/cpp/src/barretenberg/honk/proof_system/verifier.test.cpp @@ -1,229 +1,230 @@ -#include "barretenberg/numeric/bitop/get_msb.hpp" -#include "barretenberg/plonk/proof_system/constants.hpp" -#include "barretenberg/polynomials/polynomial.hpp" -#include "barretenberg/honk/flavor/flavor.hpp" -#include "prover.hpp" -#include "barretenberg/plonk/proof_system/proving_key/proving_key.hpp" -#include "barretenberg/transcript/transcript.hpp" -#include "verifier.hpp" -#include "barretenberg/ecc/curves/bn254/scalar_multiplication/scalar_multiplication.hpp" -#include -#include "barretenberg/srs/reference_string/file_reference_string.hpp" -#include "barretenberg/polynomials/polynomial_arithmetic.hpp" -#include "barretenberg/plonk/proof_system/commitment_scheme/kate_commitment_scheme.hpp" -#include "barretenberg/proof_system/composer/permutation_helper.hpp" -#include - -using namespace barretenberg; -using namespace proof_system::honk; - -namespace test_honk_verifier { - -template class VerifierTests : public testing::Test { - public: - static transcript::Manifest create_manifest(const size_t num_public_inputs, const size_t num_sumcheck_rounds) - { - return honk::StandardHonk::create_manifest(num_public_inputs, num_sumcheck_rounds); - } - - static StandardVerifier generate_verifier(std::shared_ptr circuit_proving_key) - { - std::array poly_coefficients; - poly_coefficients[0] = circuit_proving_key->polynomial_store.get("q_1_lagrange").get_coefficients(); - poly_coefficients[1] = circuit_proving_key->polynomial_store.get("q_2_lagrange").get_coefficients(); - poly_coefficients[2] = circuit_proving_key->polynomial_store.get("q_3_lagrange").get_coefficients(); - poly_coefficients[3] = circuit_proving_key->polynomial_store.get("q_m_lagrange").get_coefficients(); - poly_coefficients[4] = circuit_proving_key->polynomial_store.get("q_c_lagrange").get_coefficients(); - poly_coefficients[5] = circuit_proving_key->polynomial_store.get("sigma_1_lagrange").get_coefficients(); - poly_coefficients[6] = circuit_proving_key->polynomial_store.get("sigma_2_lagrange").get_coefficients(); - poly_coefficients[7] = circuit_proving_key->polynomial_store.get("sigma_3_lagrange").get_coefficients(); - - std::vector commitments; - scalar_multiplication::pippenger_runtime_state prover(circuit_proving_key->circuit_size); - commitments.resize(8); - - for (size_t i = 0; i < 8; ++i) { - commitments[i] = g1::affine_element( - scalar_multiplication::pippenger(poly_coefficients[i], - circuit_proving_key->reference_string->get_monomial_points(), - circuit_proving_key->circuit_size, - prover)); - } - - auto crs = std::make_shared("../srs_db/ignition"); - auto circuit_verification_key = - std::make_shared(circuit_proving_key->circuit_size, - circuit_proving_key->num_public_inputs, - crs, - circuit_proving_key->composer_type); - - circuit_verification_key->commitments.insert({ "Q_1", commitments[0] }); - circuit_verification_key->commitments.insert({ "Q_2", commitments[1] }); - circuit_verification_key->commitments.insert({ "Q_3", commitments[2] }); - circuit_verification_key->commitments.insert({ "Q_M", commitments[3] }); - circuit_verification_key->commitments.insert({ "Q_C", commitments[4] }); - - circuit_verification_key->commitments.insert({ "SIGMA_1", commitments[5] }); - circuit_verification_key->commitments.insert({ "SIGMA_2", commitments[6] }); - circuit_verification_key->commitments.insert({ "SIGMA_3", commitments[7] }); - - StandardVerifier verifier(circuit_verification_key); - - // std::unique_ptr> kate_commitment_scheme = - // std::make_unique>(); - // verifier.commitment_scheme = std::move(kate_commitment_scheme); - - return verifier; - } - - // Note: this example is adapted from a corresponding PlonK verifier test. - static StandardProver generate_test_data(const size_t n) - { - // Create some constraints that satisfy our arithmetic circuit relation - // even indices = mul gates, odd incides = add gates - - auto crs = std::make_shared(n + 1, "../srs_db/ignition"); - std::shared_ptr proving_key = - std::make_shared(n, 0, crs, ComposerType::STANDARD_HONK); - - polynomial w_l(n); - polynomial w_r(n); - polynomial w_o(n); - polynomial q_l(n); - polynomial q_r(n); - polynomial q_o(n); - polynomial q_c(n); - polynomial q_m(n); - - fr T0; - for (size_t i = 0; i < n / 4; ++i) { - w_l.at(2 * i) = fr::random_element(); - w_r.at(2 * i) = fr::random_element(); - w_o.at(2 * i) = w_l.at(2 * i) * w_r.at(2 * i); - w_o[2 * i] = w_o[2 * i] + w_l[2 * i]; - w_o[2 * i] = w_o[2 * i] + w_r[2 * i]; - w_o[2 * i] = w_o[2 * i] + fr::one(); - q_l.at(2 * i) = fr::one(); - q_r.at(2 * i) = fr::one(); - q_o.at(2 * i) = fr::neg_one(); - q_c.at(2 * i) = fr::one(); - q_m.at(2 * i) = fr::one(); - - w_l.at(2 * i + 1) = fr::random_element(); - w_r.at(2 * i + 1) = fr::random_element(); - w_o.at(2 * i + 1) = fr::random_element(); - - T0 = w_l.at(2 * i + 1) + w_r.at(2 * i + 1); - q_c.at(2 * i + 1) = T0 + w_o.at(2 * i + 1); - q_c.at(2 * i + 1).self_neg(); - q_l.at(2 * i + 1) = fr::one(); - q_r.at(2 * i + 1) = fr::one(); - q_o.at(2 * i + 1) = fr::one(); - q_m.at(2 * i + 1) = fr::zero(); - } - size_t shift = n / 2; - polynomial_arithmetic::copy_polynomial(&w_l.at(0), &w_l.at(shift), shift, shift); - polynomial_arithmetic::copy_polynomial(&w_r.at(0), &w_r.at(shift), shift, shift); - polynomial_arithmetic::copy_polynomial(&w_o.at(0), &w_o.at(shift), shift, shift); - polynomial_arithmetic::copy_polynomial(&q_m.at(0), &q_m.at(shift), shift, shift); - polynomial_arithmetic::copy_polynomial(&q_l.at(0), &q_l.at(shift), shift, shift); - polynomial_arithmetic::copy_polynomial(&q_r.at(0), &q_r.at(shift), shift, shift); - polynomial_arithmetic::copy_polynomial(&q_o.at(0), &q_o.at(shift), shift, shift); - polynomial_arithmetic::copy_polynomial(&q_c.at(0), &q_c.at(shift), shift, shift); - - std::vector sigma_1_mapping; - std::vector sigma_2_mapping; - std::vector sigma_3_mapping; - // create basic permutation - second half of witness vector is a copy of the first half - sigma_1_mapping.resize(n); - sigma_2_mapping.resize(n); - sigma_3_mapping.resize(n); - - for (size_t i = 0; i < n / 2; ++i) { - sigma_1_mapping[shift + i] = (uint32_t)i; - sigma_2_mapping[shift + i] = (uint32_t)i + (1U << 30U); - sigma_3_mapping[shift + i] = (uint32_t)i + (1U << 31U); - sigma_1_mapping[i] = (uint32_t)(i + shift); - sigma_2_mapping[i] = (uint32_t)(i + shift) + (1U << 30U); - sigma_3_mapping[i] = (uint32_t)(i + shift) + (1U << 31U); - } - // make last permutation the same as identity permutation - // we are setting the permutation in the last 4 gates as identity permutation since - // we are cutting out 4 roots as of now. - size_t num_roots_cut_out_of_the_vanishing_polynomial = 4; - for (uint32_t j = 0; j < num_roots_cut_out_of_the_vanishing_polynomial; ++j) { - sigma_1_mapping[shift - 1 - j] = (uint32_t)shift - 1 - j; - sigma_2_mapping[shift - 1 - j] = (uint32_t)shift - 1 - j + (1U << 30U); - sigma_3_mapping[shift - 1 - j] = (uint32_t)shift - 1 - j + (1U << 31U); - sigma_1_mapping[n - 1 - j] = (uint32_t)n - 1 - j; - sigma_2_mapping[n - 1 - j] = (uint32_t)n - 1 - j + (1U << 30U); - sigma_3_mapping[n - 1 - j] = (uint32_t)n - 1 - j + (1U << 31U); - } - - polynomial sigma_1(proving_key->circuit_size); - polynomial sigma_2(proving_key->circuit_size); - polynomial sigma_3(proving_key->circuit_size); - - // plonk::compute_permutation_lagrange_base_single(sigma_1, sigma_1_mapping, - // proving_key->small_domain); plonk::compute_permutation_lagrange_base_single(sigma_2, - // sigma_2_mapping, proving_key->small_domain); - // plonk::compute_permutation_lagrange_base_single(sigma_3, sigma_3_mapping, - // proving_key->small_domain); - - polynomial sigma_1_lagrange_base(sigma_1, proving_key->circuit_size); - polynomial sigma_2_lagrange_base(sigma_2, proving_key->circuit_size); - polynomial sigma_3_lagrange_base(sigma_3, proving_key->circuit_size); - - proving_key->polynomial_store.put("sigma_1_lagrange", std::move(sigma_1_lagrange_base)); - proving_key->polynomial_store.put("sigma_2_lagrange", std::move(sigma_2_lagrange_base)); - proving_key->polynomial_store.put("sigma_3_lagrange", std::move(sigma_3_lagrange_base)); - - compute_standard_honk_id_polynomials<3>(proving_key); - compute_first_and_last_lagrange_polynomials(proving_key); - - proving_key->polynomial_store.put("w_1_lagrange", std::move(w_l)); - proving_key->polynomial_store.put("w_2_lagrange", std::move(w_r)); - proving_key->polynomial_store.put("w_3_lagrange", std::move(w_o)); - - proving_key->polynomial_store.put("q_1_lagrange", std::move(q_l)); - proving_key->polynomial_store.put("q_2_lagrange", std::move(q_r)); - proving_key->polynomial_store.put("q_3_lagrange", std::move(q_o)); - proving_key->polynomial_store.put("q_m_lagrange", std::move(q_m)); - proving_key->polynomial_store.put("q_c_lagrange", std::move(q_c)); - - // TODO(#223)(Cody): This should be more generic - std::vector witness_polynomials; - auto prover = StandardProver(std::move(witness_polynomials), proving_key); - - std::unique_ptr kate_commitment_key = - std::make_unique(proving_key->circuit_size, "../srs_db/ignition"); - - return prover; - } -}; - -using FieldTypes = testing::Types; -TYPED_TEST_SUITE(VerifierTests, FieldTypes); - -// This test is modeled after a corresponding test for the Plonk Verifier. As is the case there, this test relies on -// valid proof construction which makes the scope quite large. Not really a unit test but a nice test nonetheless. -// TODO(#223)(Luke/Cody): Make this a meaningful test (or remove altogether) -TYPED_TEST(VerifierTests, VerifyArithmeticProofSmall) -{ - GTEST_SKIP() << "It's good to have a standalone test, but for now we just rely on composer tests."; - size_t n = 8; - - StandardProver prover = TestFixture::generate_test_data(n); - - StandardVerifier verifier = TestFixture::generate_verifier(prover.key); - - // construct proof - plonk::proof proof = prover.construct_proof(); - - // verify proof - bool result = verifier.verify_proof(proof); - - EXPECT_EQ(result, true); -} - -} // namespace test_honk_verifier +// #include "barretenberg/numeric/bitop/get_msb.hpp" +// #include "barretenberg/plonk/proof_system/constants.hpp" +// #include "barretenberg/polynomials/polynomial.hpp" +// #include "barretenberg/honk/flavor/flavor.hpp" +// #include "barretenberg/proof_system/flavor/flavor.hpp" +// #include "prover.hpp" +// #include "barretenberg/plonk/proof_system/proving_key/proving_key.hpp" +// #include "barretenberg/transcript/transcript.hpp" +// #include "verifier.hpp" +// #include "barretenberg/ecc/curves/bn254/scalar_multiplication/scalar_multiplication.hpp" +// #include +// #include "barretenberg/srs/reference_string/file_reference_string.hpp" +// #include "barretenberg/polynomials/polynomial_arithmetic.hpp" +// #include "barretenberg/plonk/proof_system/commitment_scheme/kate_commitment_scheme.hpp" +// #include "barretenberg/proof_system/composer/permutation_helper.hpp" +// #include + +// using namespace barretenberg; +// using namespace proof_system::honk; + +// namespace test_honk_verifier { + +// template class VerifierTests : public testing::Test { +// public: +// static transcript::Manifest create_manifest(const size_t num_public_inputs, const size_t num_sumcheck_rounds) +// { +// return honk::StandardHonk::create_manifest(num_public_inputs, num_sumcheck_rounds); +// } + +// static StandardVerifier generate_verifier(std::shared_ptr circuit_proving_key) +// { +// std::array poly_coefficients; +// poly_coefficients[0] = circuit_proving_key->polynomial_store.get("q_1_lagrange").get_coefficients(); +// poly_coefficients[1] = circuit_proving_key->polynomial_store.get("q_2_lagrange").get_coefficients(); +// poly_coefficients[2] = circuit_proving_key->polynomial_store.get("q_3_lagrange").get_coefficients(); +// poly_coefficients[3] = circuit_proving_key->polynomial_store.get("q_m_lagrange").get_coefficients(); +// poly_coefficients[4] = circuit_proving_key->polynomial_store.get("q_c_lagrange").get_coefficients(); +// poly_coefficients[5] = circuit_proving_key->polynomial_store.get("sigma_1_lagrange").get_coefficients(); +// poly_coefficients[6] = circuit_proving_key->polynomial_store.get("sigma_2_lagrange").get_coefficients(); +// poly_coefficients[7] = circuit_proving_key->polynomial_store.get("sigma_3_lagrange").get_coefficients(); + +// std::vector commitments; +// scalar_multiplication::pippenger_runtime_state prover(circuit_proving_key->circuit_size); +// commitments.resize(8); + +// for (size_t i = 0; i < 8; ++i) { +// commitments[i] = g1::affine_element( +// scalar_multiplication::pippenger(poly_coefficients[i], +// circuit_proving_key->reference_string->get_monomial_points(), +// circuit_proving_key->circuit_size, +// prover)); +// } + +// auto crs = std::make_shared("../srs_db/ignition"); +// auto circuit_verification_key = +// std::make_shared(circuit_proving_key->circuit_size, +// circuit_proving_key->num_public_inputs, +// crs, +// circuit_proving_key->composer_type); + +// circuit_verification_key->commitments.insert({ "Q_1", commitments[0] }); +// circuit_verification_key->commitments.insert({ "Q_2", commitments[1] }); +// circuit_verification_key->commitments.insert({ "Q_3", commitments[2] }); +// circuit_verification_key->commitments.insert({ "Q_M", commitments[3] }); +// circuit_verification_key->commitments.insert({ "Q_C", commitments[4] }); + +// circuit_verification_key->commitments.insert({ "SIGMA_1", commitments[5] }); +// circuit_verification_key->commitments.insert({ "SIGMA_2", commitments[6] }); +// circuit_verification_key->commitments.insert({ "SIGMA_3", commitments[7] }); + +// StandardVerifier verifier(circuit_verification_key); + +// // std::unique_ptr> kate_commitment_scheme = +// // std::make_unique>(); +// // verifier.commitment_scheme = std::move(kate_commitment_scheme); + +// return verifier; +// } + +// // Note: this example is adapted from a corresponding PlonK verifier test. +// static StandardProver generate_test_data(const size_t n) +// { +// // Create some constraints that satisfy our arithmetic circuit relation +// // even indices = mul gates, odd incides = add gates + +// auto crs = std::make_shared(n + 1, "../srs_db/ignition"); +// std::shared_ptr proving_key = +// std::make_shared(n, 0, crs, ComposerType::STANDARD_HONK); + +// polynomial w_l(n); +// polynomial w_r(n); +// polynomial w_o(n); +// polynomial q_l(n); +// polynomial q_r(n); +// polynomial q_o(n); +// polynomial q_c(n); +// polynomial q_m(n); + +// fr T0; +// for (size_t i = 0; i < n / 4; ++i) { +// w_l.at(2 * i) = fr::random_element(); +// w_r.at(2 * i) = fr::random_element(); +// w_o.at(2 * i) = w_l.at(2 * i) * w_r.at(2 * i); +// w_o[2 * i] = w_o[2 * i] + w_l[2 * i]; +// w_o[2 * i] = w_o[2 * i] + w_r[2 * i]; +// w_o[2 * i] = w_o[2 * i] + fr::one(); +// q_l.at(2 * i) = fr::one(); +// q_r.at(2 * i) = fr::one(); +// q_o.at(2 * i) = fr::neg_one(); +// q_c.at(2 * i) = fr::one(); +// q_m.at(2 * i) = fr::one(); + +// w_l.at(2 * i + 1) = fr::random_element(); +// w_r.at(2 * i + 1) = fr::random_element(); +// w_o.at(2 * i + 1) = fr::random_element(); + +// T0 = w_l.at(2 * i + 1) + w_r.at(2 * i + 1); +// q_c.at(2 * i + 1) = T0 + w_o.at(2 * i + 1); +// q_c.at(2 * i + 1).self_neg(); +// q_l.at(2 * i + 1) = fr::one(); +// q_r.at(2 * i + 1) = fr::one(); +// q_o.at(2 * i + 1) = fr::one(); +// q_m.at(2 * i + 1) = fr::zero(); +// } +// size_t shift = n / 2; +// polynomial_arithmetic::copy_polynomial(&w_l.at(0), &w_l.at(shift), shift, shift); +// polynomial_arithmetic::copy_polynomial(&w_r.at(0), &w_r.at(shift), shift, shift); +// polynomial_arithmetic::copy_polynomial(&w_o.at(0), &w_o.at(shift), shift, shift); +// polynomial_arithmetic::copy_polynomial(&q_m.at(0), &q_m.at(shift), shift, shift); +// polynomial_arithmetic::copy_polynomial(&q_l.at(0), &q_l.at(shift), shift, shift); +// polynomial_arithmetic::copy_polynomial(&q_r.at(0), &q_r.at(shift), shift, shift); +// polynomial_arithmetic::copy_polynomial(&q_o.at(0), &q_o.at(shift), shift, shift); +// polynomial_arithmetic::copy_polynomial(&q_c.at(0), &q_c.at(shift), shift, shift); + +// std::vector sigma_1_mapping; +// std::vector sigma_2_mapping; +// std::vector sigma_3_mapping; +// // create basic permutation - second half of witness vector is a copy of the first half +// sigma_1_mapping.resize(n); +// sigma_2_mapping.resize(n); +// sigma_3_mapping.resize(n); + +// for (size_t i = 0; i < n / 2; ++i) { +// sigma_1_mapping[shift + i] = (uint32_t)i; +// sigma_2_mapping[shift + i] = (uint32_t)i + (1U << 30U); +// sigma_3_mapping[shift + i] = (uint32_t)i + (1U << 31U); +// sigma_1_mapping[i] = (uint32_t)(i + shift); +// sigma_2_mapping[i] = (uint32_t)(i + shift) + (1U << 30U); +// sigma_3_mapping[i] = (uint32_t)(i + shift) + (1U << 31U); +// } +// // make last permutation the same as identity permutation +// // we are setting the permutation in the last 4 gates as identity permutation since +// // we are cutting out 4 roots as of now. +// size_t num_roots_cut_out_of_the_vanishing_polynomial = 4; +// for (uint32_t j = 0; j < num_roots_cut_out_of_the_vanishing_polynomial; ++j) { +// sigma_1_mapping[shift - 1 - j] = (uint32_t)shift - 1 - j; +// sigma_2_mapping[shift - 1 - j] = (uint32_t)shift - 1 - j + (1U << 30U); +// sigma_3_mapping[shift - 1 - j] = (uint32_t)shift - 1 - j + (1U << 31U); +// sigma_1_mapping[n - 1 - j] = (uint32_t)n - 1 - j; +// sigma_2_mapping[n - 1 - j] = (uint32_t)n - 1 - j + (1U << 30U); +// sigma_3_mapping[n - 1 - j] = (uint32_t)n - 1 - j + (1U << 31U); +// } + +// polynomial sigma_1(proving_key->circuit_size); +// polynomial sigma_2(proving_key->circuit_size); +// polynomial sigma_3(proving_key->circuit_size); + +// // plonk::compute_permutation_lagrange_base_single(sigma_1, sigma_1_mapping, +// // proving_key->small_domain); plonk::compute_permutation_lagrange_base_single(sigma_2, +// // sigma_2_mapping, proving_key->small_domain); +// // plonk::compute_permutation_lagrange_base_single(sigma_3, sigma_3_mapping, +// // proving_key->small_domain); + +// polynomial sigma_1_lagrange_base(sigma_1, proving_key->circuit_size); +// polynomial sigma_2_lagrange_base(sigma_2, proving_key->circuit_size); +// polynomial sigma_3_lagrange_base(sigma_3, proving_key->circuit_size); + +// proving_key->polynomial_store.put("sigma_1_lagrange", std::move(sigma_1_lagrange_base)); +// proving_key->polynomial_store.put("sigma_2_lagrange", std::move(sigma_2_lagrange_base)); +// proving_key->polynomial_store.put("sigma_3_lagrange", std::move(sigma_3_lagrange_base)); + +// compute_standard_honk_id_polynomials(proving_key); +// compute_first_and_last_lagrange_polynomials(proving_key); + +// proving_key->polynomial_store.put("w_1_lagrange", std::move(w_l)); +// proving_key->polynomial_store.put("w_2_lagrange", std::move(w_r)); +// proving_key->polynomial_store.put("w_3_lagrange", std::move(w_o)); + +// proving_key->polynomial_store.put("q_1_lagrange", std::move(q_l)); +// proving_key->polynomial_store.put("q_2_lagrange", std::move(q_r)); +// proving_key->polynomial_store.put("q_3_lagrange", std::move(q_o)); +// proving_key->polynomial_store.put("q_m_lagrange", std::move(q_m)); +// proving_key->polynomial_store.put("q_c_lagrange", std::move(q_c)); + +// // TODO(#223)(Cody): This should be more generic +// std::vector witness_polynomials; +// auto prover = StandardProver(std::move(witness_polynomials), proving_key); + +// std::unique_ptr kate_commitment_key = +// std::make_unique(proving_key->circuit_size, "../srs_db/ignition"); + +// return prover; +// } +// }; + +// using FieldTypes = testing::Types; +// TYPED_TEST_SUITE(VerifierTests, FieldTypes); + +// // This test is modeled after a corresponding test for the Plonk Verifier. As is the case there, this test relies on +// // valid proof construction which makes the scope quite large. Not really a unit test but a nice test nonetheless. +// // TODO(#223)(Luke/Cody): Make this a meaningful test (or remove altogether) +// TYPED_TEST(VerifierTests, VerifyArithmeticProofSmall) +// { +// GTEST_SKIP() << "It's good to have a standalone test, but for now we just rely on composer tests."; +// size_t n = 8; + +// StandardProver prover = TestFixture::generate_test_data(n); + +// StandardVerifier verifier = TestFixture::generate_verifier(prover.key); + +// // construct proof +// plonk::proof proof = prover.construct_proof(); + +// // verify proof +// bool result = verifier.verify_proof(proof); + +// EXPECT_EQ(result, true); +// } + +// } // namespace test_honk_verifier diff --git a/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/standard_plonk_composer_helper.cpp b/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/standard_plonk_composer_helper.cpp index b8feab27d3..13575a3514 100644 --- a/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/standard_plonk_composer_helper.cpp +++ b/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/standard_plonk_composer_helper.cpp @@ -73,8 +73,7 @@ std::shared_ptr StandardPlonkComposerHelper::compute_proving compute_monomial_and_coset_selector_forms(circuit_proving_key.get(), standard_selector_properties()); // Compute sigma polynomials (we should update that late) - compute_standard_plonk_sigma_permutations(circuit_constructor, - circuit_proving_key.get()); + compute_standard_plonk_sigma_permutations(circuit_constructor, circuit_proving_key.get()); circuit_proving_key->recursive_proof_public_input_indices = std::vector(recursive_proof_public_input_indices.begin(), recursive_proof_public_input_indices.end()); diff --git a/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/turbo_plonk_composer_helper.cpp b/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/turbo_plonk_composer_helper.cpp index 5877225a38..352931866c 100644 --- a/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/turbo_plonk_composer_helper.cpp +++ b/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/turbo_plonk_composer_helper.cpp @@ -49,8 +49,7 @@ std::shared_ptr TurboPlonkComposerHelper::compute_proving_ke compute_monomial_and_coset_selector_forms(circuit_proving_key.get(), turbo_selector_properties()); // Compute sigma polynomials (TODO(kesha): we should update that late) - compute_standard_plonk_sigma_permutations(circuit_constructor, - circuit_proving_key.get()); + compute_standard_plonk_sigma_permutations(circuit_constructor, circuit_proving_key.get()); circuit_proving_key->recursive_proof_public_input_indices = std::vector(recursive_proof_public_input_indices.begin(), recursive_proof_public_input_indices.end()); circuit_proving_key->contains_recursive_proof = contains_recursive_proof; diff --git a/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/ultra_plonk_composer_helper.cpp b/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/ultra_plonk_composer_helper.cpp index ccf3d77351..5a9b9a7fc6 100644 --- a/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/ultra_plonk_composer_helper.cpp +++ b/cpp/src/barretenberg/plonk/composer/splitting_tmp/composer_helper/ultra_plonk_composer_helper.cpp @@ -235,8 +235,7 @@ std::shared_ptr UltraPlonkComposerHelper::compute_proving_key( compute_monomial_and_coset_selector_forms(circuit_proving_key.get(), ultra_selector_properties()); - compute_plonk_generalized_sigma_permutations(circuit_constructor, - circuit_proving_key.get()); + compute_plonk_generalized_sigma_permutations(circuit_constructor, circuit_proving_key.get()); const size_t subgroup_size = circuit_proving_key->circuit_size; diff --git a/cpp/src/barretenberg/proof_system/composer/composer_helper_lib.test.cpp b/cpp/src/barretenberg/proof_system/composer/composer_helper_lib.test.cpp index 8449d99ed0..0f0e6fc1e0 100644 --- a/cpp/src/barretenberg/proof_system/composer/composer_helper_lib.test.cpp +++ b/cpp/src/barretenberg/proof_system/composer/composer_helper_lib.test.cpp @@ -15,7 +15,7 @@ class ComposerLibTests : public ::testing::Test { Flavor::ProvingKey proving_key = []() { auto crs_factory = ReferenceStringFactory(); auto crs = crs_factory.get_prover_crs(4); - return Flavor::ProvingKey(/*circuit_size=*/4, /*num_inputs=*/0, crs, ComposerType::STANDARD); + return Flavor::ProvingKey(/*circuit_size=*/4, /*num_public_inputs=*/0, crs, ComposerType::STANDARD); }(); }; @@ -33,7 +33,7 @@ TEST_F(ComposerLibTests, InitializeProvingKey) /*num_randomized_gates=*/2, ComposerType::STANDARD); EXPECT_EQ(pk->circuit_size, 8); - EXPECT_EQ(pk->num_inputs, 0); + EXPECT_EQ(pk->num_public_inputs, 0); } TEST_F(ComposerLibTests, ConstructSelectors) diff --git a/cpp/src/barretenberg/proof_system/composer/permutation_helper.hpp b/cpp/src/barretenberg/proof_system/composer/permutation_helper.hpp index 73039533fc..f279c704d4 100644 --- a/cpp/src/barretenberg/proof_system/composer/permutation_helper.hpp +++ b/cpp/src/barretenberg/proof_system/composer/permutation_helper.hpp @@ -5,12 +5,12 @@ * @details It is structured to reuse similar components in Honk and Plonk * */ - #pragma once #include "barretenberg/ecc/curves/bn254/fr.hpp" #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/plonk/proof_system/proving_key/proving_key.hpp" +#include "barretenberg/polynomials/iterate_over_domain.hpp" #include #include @@ -21,6 +21,8 @@ #include #include +// TODO(Cody): very little code is shared; should split this up into plonk/honk files. + namespace proof_system { /** @@ -48,8 +50,8 @@ struct permutation_subgroup_element { bool is_tag = false; }; -template struct PermutationMapping { - using Mapping = std::array, program_width>; +template struct PermutationMapping { + using Mapping = std::array, num_wires>; Mapping sigmas; Mapping ids; }; @@ -64,24 +66,14 @@ namespace { * * @tparam program_width Program width * */ -template -std::vector compute_wire_copy_cycles(const CircuitConstructor& circuit_constructor) +template +std::vector compute_wire_copy_cycles(const typename Flavor::CircuitConstructor& circuit_constructor) { // Reference circuit constructor members 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(); - // Get references to the wires containing the index of the value inside constructor.variables - // These wires only contain the "real" gate constraints, and are not padded. - std::array, program_width> wire_indices; - wire_indices[0] = circuit_constructor.w_l; - wire_indices[1] = circuit_constructor.w_r; - wire_indices[2] = circuit_constructor.w_o; - if constexpr (program_width > 3) { - wire_indices[3] = circuit_constructor.w_4; - } - // Each variable represents one cycle const size_t number_of_cycles = circuit_constructor.variables.size(); std::vector copy_cycles(number_of_cycles); @@ -111,13 +103,13 @@ std::vector compute_wire_copy_cycles(const CircuitConstructor // Iterate over all variables of the "real" gates, and add a corresponding node to the cycle for that variable for (size_t i = 0; i < num_gates; ++i) { - for (size_t j = 0; j < program_width; ++j) { + for (size_t j = 0; j < Flavor::num_wires; ++j) { // We are looking at the j-th wire in the i-th row. // The value in this position should be equal to the value of the element at index `var_index` // 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_indices[j][i]]; + const uint32_t var_index = circuit_constructor.real_variable_index[circuit_constructor.wires[j][i]]; const auto wire_index = static_cast(j); const auto gate_index = static_cast(i + num_public_inputs); copy_cycles[var_index].emplace_back(cycle_node{ wire_index, gate_index }); @@ -139,28 +131,32 @@ std::vector compute_wire_copy_cycles(const CircuitConstructor * @param key Pointer to the proving key * @return PermutationMapping sigma mapping (and id mapping if generalized == true) */ -template -PermutationMapping compute_permutation_mapping(const CircuitConstructor& circuit_constructor, - plonk::proving_key* key) +template +PermutationMapping compute_permutation_mapping( + const typename Flavor::CircuitConstructor& circuit_constructor, typename Flavor::ProvingKey* key) { // 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); - PermutationMapping mapping; + PermutationMapping mapping; // Initialize the table of permutations so that every element points to itself - for (size_t i = 0; i < program_width; ++i) { + for (size_t i = 0; i < Flavor::num_wires; ++i) { mapping.sigmas[i].reserve(key->circuit_size); - if (generalized) { + if constexpr (generalized) { mapping.ids[i].reserve(key->circuit_size); } for (size_t j = 0; j < key->circuit_size; ++j) { - mapping.sigmas[i].emplace_back(permutation_subgroup_element{ - .row_index = (uint32_t)j, .column_index = (uint8_t)i, .is_public_input = false, .is_tag = false }); - if (generalized) { - mapping.ids[i].emplace_back(permutation_subgroup_element{ - .row_index = (uint32_t)j, .column_index = (uint8_t)i, .is_public_input = false, .is_tag = false }); + mapping.sigmas[i].emplace_back(permutation_subgroup_element{ .row_index = static_cast(j), + .column_index = static_cast(i), + .is_public_input = false, + .is_tag = false }); + if constexpr (generalized) { + mapping.ids[i].emplace_back(permutation_subgroup_element{ .row_index = static_cast(j), + .column_index = static_cast(i), + .is_public_input = false, + .is_tag = false }); } } } @@ -187,7 +183,7 @@ PermutationMapping compute_permutation_mapping(const CircuitConst .row_index = next_row, .column_index = next_column, .is_public_input = false, .is_tag = false }; - if (generalized) { + if constexpr (generalized) { bool first_node = (node_idx == 0); bool last_node = (next_cycle_node_index == 0); @@ -232,18 +228,20 @@ PermutationMapping compute_permutation_mapping(const CircuitConst * @param sigma_mappings A table with information about permuting each element * @param key Pointer to the proving key */ -template +template void compute_honk_style_sigma_lagrange_polynomials_from_mapping( - std::array, program_width>& sigma_mappings, plonk::proving_key* key) + std::array, Flavor::num_wires>& sigma_mappings, + typename Flavor::ProvingKey* key) { const size_t num_gates = key->circuit_size; - std::array sigma; + std::array sigma; - for (size_t wire_index = 0; wire_index < program_width; wire_index++) { - sigma[wire_index] = barretenberg::polynomial(num_gates); - auto& current_sigma_polynomial = sigma[wire_index]; - ITERATE_OVER_DOMAIN_START(key->small_domain) + size_t wire_index = 0; + for (auto& sigma_polynomial : key->get_sigma_polynomials()) { + auto new_poly = barretenberg::polynomial(num_gates); + sigma_polynomial = new_poly; + ITERATE_OVER_DOMAIN_START(key->evaluation_domain); const auto& current_mapping = sigma_mappings[wire_index][i]; if (current_mapping.is_public_input) { // We intentionally want to break the cycles of the public input variables. @@ -254,21 +252,16 @@ void compute_honk_style_sigma_lagrange_polynomials_from_mapping( // -(i+1) -> (n+i) // These indices are chosen so they can easily be computed by the verifier. They can expect the running // product to be equal to the "public input delta" that is computed in - current_sigma_polynomial[i] = + sigma_polynomial[i] = -barretenberg::fr(current_mapping.row_index + 1 + num_gates * current_mapping.column_index); } else { ASSERT(!current_mapping.is_tag); // For the regular permutation we simply point to the next location by setting the evaluation to its // index - current_sigma_polynomial[i] = - barretenberg::fr(current_mapping.row_index + num_gates * current_mapping.column_index); + barretenberg::fr(current_mapping.row_index + num_gates * current_mapping.column_index); } ITERATE_OVER_DOMAIN_END; - } - // Save to polynomial cache - for (size_t j = 0; j < program_width; j++) { - std::string index = std::to_string(j + 1); - key->polynomial_store.put("sigma_" + index + "_lagrange", std::move(sigma[j])); + wire_index++; } } @@ -401,8 +394,6 @@ void compute_monomial_and_coset_fft_polynomials_from_lagrange(std::string label, } } -} // namespace - /** * @brief Compute standard honk id polynomials and put them into cache * @@ -412,19 +403,18 @@ void compute_monomial_and_coset_fft_polynomials_from_lagrange(std::string label, * @tparam program_width The number of witness polynomials * @param key Proving key where we will save the polynomials */ -template -void compute_standard_honk_id_polynomials(auto key) // proving_key* and shared_ptr +template +void compute_standard_honk_id_polynomials(auto proving_key) // proving_key* and shared_ptr { - const size_t n = key->circuit_size; // Fill id polynomials with default values - for (size_t j = 0; j < program_width; ++j) { - // Construct permutation polynomials in lagrange base - barretenberg::polynomial id_j(n); - for (size_t i = 0; i < key->circuit_size; ++i) { - id_j[i] = (j * n + i); + // TODO(Cody): Allocate polynomial space in proving key constructor. + size_t coset_idx = 0; + for (auto& id_poly : proving_key->get_id_polynomials()) { + barretenberg::polynomial new_poly(proving_key->circuit_size); + for (size_t i = 0; i < proving_key->circuit_size; ++i) { + new_poly[i] = coset_idx * proving_key->circuit_size + i; } - std::string index = std::to_string(j + 1); - key->polynomial_store.put("id_" + index + "_lagrange", std::move(id_j)); + id_poly = new_poly; } } @@ -432,7 +422,8 @@ void compute_standard_honk_id_polynomials(auto key) // proving_key* and shared_p * @brief Compute sigma permutations for standard honk and put them into polynomial cache * * @details These permutations don't involve sets. We only care about equating one witness value to another. The - * sequences don't use cosets unlike FFT-based Plonk, because there is no need for them. We simply use indices based on + * sequences don't use cosets unlike FFT-based Plonk, because there is no need for them. We simply use indices based + on * the witness vector and index within the vector. These values are permuted to account for wire copy cycles * * @tparam program_width @@ -441,13 +432,14 @@ void compute_standard_honk_id_polynomials(auto key) // proving_key* and shared_p * @param key */ // TODO(#293): Update this (and all similar functions) to take a smart pointer. -template -void compute_standard_honk_sigma_permutations(CircuitConstructor& circuit_constructor, plonk::proving_key* key) +template +void compute_standard_honk_sigma_permutations(const typename Flavor::CircuitConstructor& circuit_constructor, + typename Flavor::ProvingKey* key) { // Compute the permutation table specifying which element becomes which - auto mapping = compute_permutation_mapping(circuit_constructor, key); + auto mapping = compute_permutation_mapping(circuit_constructor, key); // Compute Honk-style sigma polynomial fromt the permutation table - compute_honk_style_sigma_lagrange_polynomials_from_mapping(mapping.sigmas, key); + compute_honk_style_sigma_lagrange_polynomials_from_mapping(mapping.sigmas, key); } /** @@ -458,15 +450,16 @@ void compute_standard_honk_sigma_permutations(CircuitConstructor& circuit_constr * @param circuit_constructor An object holdingt he circuit * @param key Pointer to a proving key */ -template -void compute_standard_plonk_sigma_permutations(CircuitConstructor& circuit_constructor, plonk::proving_key* key) +template +void compute_standard_plonk_sigma_permutations(const typename Flavor::CircuitConstructor& circuit_constructor, + typename Flavor::ProvingKey* key) { // Compute the permutation table specifying which element becomes which - auto mapping = compute_permutation_mapping(circuit_constructor, key); + auto mapping = compute_permutation_mapping(circuit_constructor, key); // Compute Plonk-style sigma polynomials from the mapping compute_plonk_permutation_lagrange_polynomials_from_mapping("sigma", mapping.sigmas, key); // Compute their monomial and coset versions - compute_monomial_and_coset_fft_polynomials_from_lagrange("sigma", key); + compute_monomial_and_coset_fft_polynomials_from_lagrange("sigma", key); } /** @@ -474,15 +467,16 @@ void compute_standard_plonk_sigma_permutations(CircuitConstructor& circuit_const * * @param key Proving key where we will save the polynomials */ -inline void compute_first_and_last_lagrange_polynomials(auto key) // proving_key* and share_ptr +inline void compute_first_and_last_lagrange_polynomials(auto proving_key) // proving_key* and share_ptr { - const size_t n = key->circuit_size; + const size_t n = proving_key->circuit_size; barretenberg::polynomial lagrange_polynomial_0(n); barretenberg::polynomial lagrange_polynomial_n_min_1(n); lagrange_polynomial_0[0] = 1; + proving_key->lagrange_first = lagrange_polynomial_0; + lagrange_polynomial_n_min_1[n - 1] = 1; - key->polynomial_store.put("L_first_lagrange", std::move(lagrange_polynomial_0)); - key->polynomial_store.put("L_last_lagrange", std::move(lagrange_polynomial_n_min_1)); + proving_key->lagrange_last = lagrange_polynomial_n_min_1; } /** @@ -494,18 +488,18 @@ inline void compute_first_and_last_lagrange_polynomials(auto key) // proving_key * @param key * @return std::array, program_width> */ -template -void compute_plonk_generalized_sigma_permutations(const CircuitConstructor& circuit_constructor, - plonk::proving_key* key) +template +void compute_plonk_generalized_sigma_permutations(const typename Flavor::CircuitConstructor& circuit_constructor, + typename Flavor::ProvingKey* key) { - auto mapping = compute_permutation_mapping(circuit_constructor, key); + auto mapping = compute_permutation_mapping(circuit_constructor, key); // Compute Plonk-style sigma and ID polynomials from the corresponding mappings compute_plonk_permutation_lagrange_polynomials_from_mapping("sigma", mapping.sigmas, key); compute_plonk_permutation_lagrange_polynomials_from_mapping("id", mapping.ids, key); // Compute the monomial and coset-ffts for sigmas and IDs - compute_monomial_and_coset_fft_polynomials_from_lagrange("sigma", key); - compute_monomial_and_coset_fft_polynomials_from_lagrange("id", key); + compute_monomial_and_coset_fft_polynomials_from_lagrange("sigma", key); + compute_monomial_and_coset_fft_polynomials_from_lagrange("id", key); } - +} // namespace } // namespace proof_system diff --git a/cpp/src/barretenberg/proof_system/composer/permutation_helper.test.cpp b/cpp/src/barretenberg/proof_system/composer/permutation_helper.test.cpp new file mode 100644 index 0000000000..ea3d845d17 --- /dev/null +++ b/cpp/src/barretenberg/proof_system/composer/permutation_helper.test.cpp @@ -0,0 +1,83 @@ +#include +#include +#include "barretenberg/proof_system/flavor/flavor.hpp" // TODO: needed? +#include "barretenberg/proof_system/composer/composer_helper_lib.hpp" +#include "barretenberg/proof_system/composer/permutation_helper.hpp" +#include "barretenberg/proof_system/types/composer_type.hpp" +#include "barretenberg/srs/reference_string/reference_string.hpp" + +namespace proof_system::test_composer_lib { + +class PermutationHelperTests : public ::testing::Test { + protected: + using Flavor = honk::flavor::Standard; + using FF = typename Flavor::FF; + Flavor::CircuitConstructor circuit_constructor; + ReferenceStringFactory crs_factory = ReferenceStringFactory(); + std::shared_ptr proving_key = [&]() { + return initialize_proving_key(circuit_constructor, &crs_factory, 0, 2, ComposerType::STANDARD); + }(); + + 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); + + 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 + + */} +}; + +TEST_F(PermutationHelperTests, ComputeWireCopyCycles) +{ + compute_wire_copy_cycles(circuit_constructor); +} + +TEST_F(PermutationHelperTests, ComputePermutationMapping) +{ + compute_permutation_mapping(circuit_constructor, proving_key.get()); +} + +TEST_F(PermutationHelperTests, ComputeHonkStyleSigmaLagrangePolynomialsFromMapping) +{ + auto mapping = compute_permutation_mapping(circuit_constructor, proving_key.get()); + compute_honk_style_sigma_lagrange_polynomials_from_mapping(mapping.sigmas, proving_key.get()); +} + +TEST_F(PermutationHelperTests, ComputeStandardAuxPolynomials) +{ + 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 diff --git a/cpp/src/barretenberg/proof_system/flavor/flavor.hpp b/cpp/src/barretenberg/proof_system/flavor/flavor.hpp index 5583da4668..d83167a2ac 100644 --- a/cpp/src/barretenberg/proof_system/flavor/flavor.hpp +++ b/cpp/src/barretenberg/proof_system/flavor/flavor.hpp @@ -7,6 +7,7 @@ #include "barretenberg/honk/sumcheck/polynomials/univariate.hpp" #include "barretenberg/ecc/curves/bn254/g1.hpp" #include "barretenberg/plonk/proof_system/proving_key/proving_key.hpp" +#include "barretenberg/polynomials/evaluation_domain.hpp" #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/proof_system/circuit_constructors/standard_circuit_constructor.hpp" #include "barretenberg/proof_system/circuit_constructors/turbo_circuit_constructor.hpp" @@ -28,18 +29,12 @@ template class Data { typename DataType::iterator end() { return _data.end(); }; consteval size_t size() { return _data.size(); }; - - // Data(size_t initial_size) - // { - // for (auto& entity : _data) { - // entity = T(initial_size); - // }; - // } }; class Standard { public: using CircuitConstructor = proof_system::StandardCircuitConstructor; + static constexpr size_t num_wires = CircuitConstructor::num_wires; static constexpr size_t NUM_ALL_ENTITIES = 18; static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 13; @@ -68,6 +63,8 @@ class Standard { T& lagrange_last = std::get<12>(this->_data); // = LAGRANGE_N-1 whithout ZK, but can be less std::array, 5> get_selectors() { return { q_m, q_l, q_r, q_o, q_c }; }; + std::array, 3> get_sigma_polynomials() { return { sigma_1, sigma_2, sigma_3 }; }; + std::array, 3> get_id_polynomials() { return { id_1, id_2, id_3 }; }; }; // TODO(Cody): Made this public derivation so that I could iterate through the selectors @@ -75,18 +72,21 @@ class Standard { class ProvingKey : public PrecomputedData { public: const size_t circuit_size; - const size_t num_inputs; + const size_t log_circuit_size = 0; // TODO(Cody) + const size_t num_public_inputs; std::shared_ptr crs; - const ComposerType type; // TODO(Cody): Get rid of this + EvaluationDomain evaluation_domain; + const ComposerType composer_type; // TODO(Cody): Get rid of this ProvingKey(const size_t circuit_size, - const size_t num_inputs, + const size_t num_public_inputs, std::shared_ptr const& crs, - ComposerType type) + ComposerType composer_type) : circuit_size(circuit_size) - , num_inputs(num_inputs) + , num_public_inputs(num_public_inputs) , crs(crs) - , type(type){}; + , evaluation_domain(circuit_size, circuit_size) + , composer_type(composer_type){}; }; using VerificationKey = PrecomputedData; @@ -161,16 +161,19 @@ namespace proof_system::plonk::flavor { struct Standard { using CircuitConstructor = proof_system::StandardCircuitConstructor; using ProvingKey = plonk::proving_key; + static constexpr size_t num_wires = CircuitConstructor::num_wires; }; struct Turbo { using CircuitConstructor = proof_system::TurboCircuitConstructor; using ProvingKey = plonk::proving_key; + static constexpr size_t num_wires = CircuitConstructor::num_wires; }; struct Ultra { using CircuitConstructor = proof_system::UltraCircuitConstructor; using ProvingKey = plonk::proving_key; + static constexpr size_t num_wires = CircuitConstructor::num_wires; }; } // namespace proof_system::plonk::flavor