From a32f162af227411fe3e4154b839baab9073925ed Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Fri, 29 Sep 2023 12:43:07 +0000 Subject: [PATCH 01/15] added double gate relation to ultraplonk (smart contract still needs updating) --- .../plonk/composer/ultra_composer.hpp | 6 +- .../src/barretenberg/plonk/flavor/flavor.hpp | 1 + .../types/polynomial_manifest.hpp | 4 +- .../transition_widgets/elliptic_widget.hpp | 40 +++- .../arithmetization/arithmetization.hpp | 12 +- .../circuit_builder/ultra_circuit_builder.cpp | 60 +++--- .../circuit_builder/ultra_circuit_builder.hpp | 18 +- .../ultra_relation_consistency.test.cpp | 22 ++ .../primitives/group/cycle_group.test.cpp | 191 +++++++++--------- 9 files changed, 207 insertions(+), 147 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/plonk/composer/ultra_composer.hpp b/barretenberg/cpp/src/barretenberg/plonk/composer/ultra_composer.hpp index 1f71e1e2e9b9..d88046424567 100644 --- a/barretenberg/cpp/src/barretenberg/plonk/composer/ultra_composer.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk/composer/ultra_composer.hpp @@ -70,9 +70,9 @@ class UltraComposer { // { "q_3", true }, { "q_4", false }, { "q_arith", false }, { "q_sort", false }, // { "q_elliptic", false }, { "q_aux", false }, { "table_type", true }, std::vector result{ - { "q_m", true }, { "q_c", true }, { "q_1", true }, { "q_2", true }, - { "q_3", true }, { "q_4", true }, { "q_arith", true }, { "q_sort", true }, - { "q_elliptic", true }, { "q_aux", true }, { "table_type", true }, + { "q_m", true }, { "q_c", true }, { "q_1", true }, { "q_2", true }, + { "q_3", true }, { "q_4", true }, { "q_arith", true }, { "q_sort", true }, + { "q_elliptic", true }, { "q_double", true }, { "q_aux", true }, { "table_type", true }, }; return result; } diff --git a/barretenberg/cpp/src/barretenberg/plonk/flavor/flavor.hpp b/barretenberg/cpp/src/barretenberg/plonk/flavor/flavor.hpp index 967b0c1539af..dc5b9bb08aff 100644 --- a/barretenberg/cpp/src/barretenberg/plonk/flavor/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk/flavor/flavor.hpp @@ -108,6 +108,7 @@ class Ultra { { "q_arith", fr_size, false, 13 }, { "q_sort", fr_size, false, 14 }, // * { "q_elliptic", fr_size, false, 15 }, // * + { "q_double", fr_size, false, 30 }, // * { "q_aux", fr_size, false, 16 }, { "sigma_1", fr_size, false, 17 }, { "sigma_2", fr_size, false, 18 }, diff --git a/barretenberg/cpp/src/barretenberg/plonk/proof_system/types/polynomial_manifest.hpp b/barretenberg/cpp/src/barretenberg/plonk/proof_system/types/polynomial_manifest.hpp index d4148be017b2..cdd9fc2efa98 100644 --- a/barretenberg/cpp/src/barretenberg/plonk/proof_system/types/polynomial_manifest.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk/proof_system/types/polynomial_manifest.hpp @@ -31,6 +31,7 @@ enum PolynomialIndex { TABLE_INDEX, TABLE_TYPE, Q_ELLIPTIC, + Q_DOUBLE, Q_AUX, SIGMA_1, SIGMA_2, @@ -105,7 +106,7 @@ static constexpr PolynomialDescriptor standard_polynomial_manifest[STANDARD_MANI PolynomialDescriptor("SIGMA_3", "sigma_3", false, PERMUTATION, SIGMA_3), // }; -static constexpr size_t ULTRA_MANIFEST_SIZE = 30; +static constexpr size_t ULTRA_MANIFEST_SIZE = 31; static constexpr PolynomialDescriptor ultra_polynomial_manifest[ULTRA_MANIFEST_SIZE]{ PolynomialDescriptor("W_1", "w_1", true, WITNESS, W_1), // PolynomialDescriptor("W_2", "w_2", true, WITNESS, W_2), // @@ -123,6 +124,7 @@ static constexpr PolynomialDescriptor ultra_polynomial_manifest[ULTRA_MANIFEST_S PolynomialDescriptor("Q_ARITHMETIC", "q_arith", false, SELECTOR, Q_ARITHMETIC), // PolynomialDescriptor("Q_SORT", "q_sort", false, SELECTOR, Q_SORT), // PolynomialDescriptor("Q_ELLIPTIC", "q_elliptic", false, SELECTOR, Q_ELLIPTIC), // + PolynomialDescriptor("Q_DOUBLE", "q_double", false, SELECTOR, Q_DOUBLE), // PolynomialDescriptor("Q_AUX", "q_aux", false, SELECTOR, Q_AUX), // PolynomialDescriptor("SIGMA_1", "sigma_1", false, PERMUTATION, SIGMA_1), // PolynomialDescriptor("SIGMA_2", "sigma_2", false, PERMUTATION, SIGMA_2), // diff --git a/barretenberg/cpp/src/barretenberg/plonk/proof_system/widgets/transition_widgets/elliptic_widget.hpp b/barretenberg/cpp/src/barretenberg/plonk/proof_system/widgets/transition_widgets/elliptic_widget.hpp index 162ef536b222..9c37f91b1b98 100644 --- a/barretenberg/cpp/src/barretenberg/plonk/proof_system/widgets/transition_widgets/elliptic_widget.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk/proof_system/widgets/transition_widgets/elliptic_widget.hpp @@ -78,8 +78,9 @@ template class EllipticKern inline static std::set const& get_required_polynomial_ids() { static const std::set required_polynomial_ids = { - PolynomialIndex::Q_1, PolynomialIndex::Q_3, PolynomialIndex::Q_4, PolynomialIndex::Q_ELLIPTIC, - PolynomialIndex::W_1, PolynomialIndex::W_2, PolynomialIndex::W_3, PolynomialIndex::W_4 + PolynomialIndex::Q_1, PolynomialIndex::Q_3, PolynomialIndex::Q_4, + PolynomialIndex::Q_ELLIPTIC, PolynomialIndex::Q_DOUBLE, PolynomialIndex::W_1, + PolynomialIndex::W_2, PolynomialIndex::W_3, PolynomialIndex::W_4 }; return required_polynomial_ids; } @@ -106,6 +107,9 @@ template class EllipticKern const Field& x_3 = Getters::template get_value(polynomials, i); const Field& y_3 = Getters::template get_value(polynomials, i); + Field x_identity = 0; + Field y_identity = 0; + // Endomorphism coefficient for when we add and multiply by beta at the same time const Field& q_beta = Getters::template get_value(polynomials, i); @@ -130,11 +134,13 @@ template class EllipticKern beta_sqr_term *= q_beta_sqr; // β^2 * x_2^2 * (x_3 - x_1) sign_term *= q_sign; // 2 * y_1 * y_2 * sign leftovers *= x_2; // x_2^3 - leftovers += x_1.sqr() * (x_3 + x_1); // x_2^3 + x_1 * (x_3 + x_1) - leftovers -= (y_2.sqr() + y_1.sqr()); // x_2^3 + x_1 * (x_3 + x_1) - y_2^2 - y_1^2 + Field x_1_sqr = x_1.sqr(); + leftovers += x_1_sqr * (x_3 + x_1); // x_2^3 + x_1 * (x_3 + x_1) + Field y_1_sqr = y_1.sqr(); + leftovers -= (y_2.sqr() + y_1_sqr); // x_2^3 + x_1 * (x_3 + x_1) - y_2^2 - y_1^2 // Can be found in class description - Field x_identity = beta_term + beta_sqr_term + sign_term + leftovers; + x_identity = beta_term + beta_sqr_term + sign_term + leftovers; x_identity *= challenges.alpha_powers[0]; beta_term = x_2 * (y_3 + y_1) * q_beta; // β * x_2 * (y_3 + y_1) @@ -142,10 +148,26 @@ template class EllipticKern // TODO: remove extra additions if we decide to stay with this implementation leftovers = -x_1 * (y_3 + y_1) + y_1 * (x_1 - x_3); // -x_1 * y_3 - x_1 * y_1 + y_1 * x_1 - y_1 * x_3 - Field y_identity = beta_term + sign_term + leftovers; + y_identity = beta_term + sign_term + leftovers; y_identity *= challenges.alpha_powers[1]; + Field curve_b = grumpkin::g1::curve_b; + Field x_pow_4 = (y_1_sqr - curve_b) * x_1; + Field y_1_sqr_mul_4 = y_1_sqr + y_1_sqr; + y_1_sqr_mul_4 += y_1_sqr_mul_4; + Field x_1_pow_4_mul_9 = x_pow_4; + x_1_pow_4_mul_9 += x_1_pow_4_mul_9; + x_1_pow_4_mul_9 += x_1_pow_4_mul_9; + x_1_pow_4_mul_9 += x_1_pow_4_mul_9; + x_1_pow_4_mul_9 += x_pow_4; + Field x_1_sqr_mul_3 = x_1_sqr + x_1_sqr + x_1_sqr; + Field x_double_identity = (x_3 + x_1 + x_1) * y_1_sqr_mul_4 - x_1_pow_4_mul_9; + Field y_double_identity = x_1_sqr_mul_3 * (x_1 - x_3) - (y_1 + y_1) * (y_1 + y_3); + + x_double_identity *= challenges.alpha_powers[2]; + y_double_identity *= challenges.alpha_powers[3]; linear_terms[0] = x_identity + y_identity; + linear_terms[1] = x_double_identity + y_double_identity; } /** @@ -163,7 +185,10 @@ template class EllipticKern { const Field& q_elliptic = Getters::template get_value(polynomials, i); - return linear_terms[0] * q_elliptic; + const Field& q_double = + Getters::template get_value(polynomials, i); + + return linear_terms[0] * q_elliptic + linear_terms[1] * q_double; } inline static void compute_non_linear_terms(PolyContainer&, const challenge_array&, Field&, const size_t = 0) {} @@ -179,6 +204,7 @@ template class EllipticKern const challenge_array&) { scalars["Q_ELLIPTIC"] += linear_terms[0]; + scalars["Q_DOUBLE"] += linear_terms[1]; } }; diff --git a/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/arithmetization.hpp b/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/arithmetization.hpp index 969aac893fca..5f08ecf59123 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/arithmetization.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/arithmetization.hpp @@ -138,9 +138,9 @@ template class Ultra : public Arithmetization>& q_arith = std::get<6>(this->_data); std::vector>& q_sort = std::get<7>(this->_data); std::vector>& q_elliptic = std::get<8>(this->_data); - std::vector>& q_aux = std::get<9>(this->_data); - std::vector>& q_lookup_type = std::get<10>(this->_data); - std::vector>& q_elliptic_double = std::get<11>(this->_data); + std::vector>& q_double = std::get<9>(this->_data); + std::vector>& q_aux = std::get<10>(this->_data); + std::vector>& q_lookup_type = std::get<11>(this->_data); Selectors() : SelectorsBase(){}; Selectors(const Selectors& other) @@ -158,9 +158,9 @@ template class Ultra : public Arithmetizationq_arith = std::get<6>(this->_data); this->q_sort = std::get<7>(this->_data); this->q_elliptic = std::get<8>(this->_data); - this->q_aux = std::get<9>(this->_data); - this->q_lookup_type = std::get<10>(this->_data); - this->q_elliptic_double = std::get<11>(this->_data); + this->q_double = std::get<9>(this->_data); + this->q_aux = std::get<10>(this->_data); + this->q_lookup_type = std::get<11>(this->_data); }; Selectors& operator=(Selectors&& other) { diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp index 990982aefce6..5c1b0c9721c8 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp @@ -78,7 +78,7 @@ template void UltraCircuitBuilder_::add_gates_to_ensure_all_po q_lookup_type.emplace_back(0); q_elliptic.emplace_back(1); q_aux.emplace_back(1); - q_elliptic_double.emplace_back(1); + q_double.emplace_back(1); ++this->num_gates; // Some relations depend on wire shifts so we add another gate with @@ -136,7 +136,7 @@ template void UltraCircuitBuilder_::create_add_gate(const add_ q_sort.emplace_back(0); q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); - q_elliptic_double.emplace_back(0); + q_double.emplace_back(0); q_aux.emplace_back(0); ++this->num_gates; } @@ -167,7 +167,7 @@ void UltraCircuitBuilder_::create_big_add_gate(const add_quad_& in, cons q_sort.emplace_back(0); q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); - q_elliptic_double.emplace_back(0); + q_double.emplace_back(0); q_aux.emplace_back(0); ++this->num_gates; } @@ -259,7 +259,7 @@ template void UltraCircuitBuilder_::create_big_mul_gate(const q_sort.emplace_back(0); q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); - q_elliptic_double.emplace_back(0); + q_double.emplace_back(0); q_aux.emplace_back(0); ++this->num_gates; } @@ -284,7 +284,7 @@ template void UltraCircuitBuilder_::create_balanced_add_gate(c q_sort.emplace_back(0); q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); - q_elliptic_double.emplace_back(0); + q_double.emplace_back(0); q_aux.emplace_back(0); ++this->num_gates; // Why 3? TODO: return to this @@ -325,7 +325,7 @@ template void UltraCircuitBuilder_::create_mul_gate(const mul_ q_sort.emplace_back(0); q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); - q_elliptic_double.emplace_back(0); + q_double.emplace_back(0); q_aux.emplace_back(0); ++this->num_gates; } @@ -353,7 +353,7 @@ template void UltraCircuitBuilder_::create_bool_gate(const uin q_4.emplace_back(0); q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); - q_elliptic_double.emplace_back(0); + q_double.emplace_back(0); q_aux.emplace_back(0); ++this->num_gates; } @@ -383,7 +383,7 @@ template void UltraCircuitBuilder_::create_poly_gate(const pol q_4.emplace_back(0); q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); - q_elliptic_double.emplace_back(0); + q_double.emplace_back(0); q_aux.emplace_back(0); ++this->num_gates; } @@ -439,7 +439,7 @@ template void UltraCircuitBuilder_::create_ecc_add_gate(const q_sort.emplace_back(0); q_lookup_type.emplace_back(0); q_elliptic.emplace_back(1); - q_elliptic_double.emplace_back(0); + q_double.emplace_back(0); q_aux.emplace_back(0); ++this->num_gates; } @@ -457,7 +457,7 @@ template void UltraCircuitBuilder_::create_ecc_add_gate(const q_sort.emplace_back(0); q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); - q_elliptic_double.emplace_back(0); + q_double.emplace_back(0); q_aux.emplace_back(0); ++this->num_gates; } @@ -483,13 +483,13 @@ template void UltraCircuitBuilder_::create_ecc_dbl_gate(const can_fuse_into_previous_gate = can_fuse_into_previous_gate && (w_o[this->num_gates - 1] == in.y1); if (can_fuse_into_previous_gate) { - q_elliptic_double[this->num_gates - 1] = 1; + q_double[this->num_gates - 1] = 1; } else { w_r.emplace_back(in.x1); w_o.emplace_back(in.y1); w_l.emplace_back(this->zero_idx); w_4.emplace_back(this->zero_idx); - q_elliptic_double.emplace_back(1); + q_double.emplace_back(1); q_m.emplace_back(0); q_1.emplace_back(0); q_2.emplace_back(0); @@ -508,7 +508,7 @@ template void UltraCircuitBuilder_::create_ecc_dbl_gate(const w_o.emplace_back(in.y3); w_l.emplace_back(this->zero_idx); w_4.emplace_back(this->zero_idx); - q_elliptic_double.emplace_back(0); + q_double.emplace_back(0); q_m.emplace_back(0); q_1.emplace_back(0); q_2.emplace_back(0); @@ -547,7 +547,7 @@ template void UltraCircuitBuilder_::fix_witness(const uint32_t q_sort.emplace_back(0); q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); - q_elliptic_double.emplace_back(0); + q_double.emplace_back(0); q_aux.emplace_back(0); ++this->num_gates; } @@ -620,7 +620,7 @@ plookup::ReadData UltraCircuitBuilder_::create_gates_from_plookup_ q_4.emplace_back(0); q_sort.emplace_back(0); q_elliptic.emplace_back(0); - q_elliptic_double.emplace_back(0); + q_double.emplace_back(0); q_aux.emplace_back(0); ++this->num_gates; } @@ -930,7 +930,7 @@ void UltraCircuitBuilder_::create_sort_constraint(const std::vector::create_sort_constraint(const std::vector::create_dummy_constraints(const std::vector::create_sort_constraint_with_edges(const std::vect q_4.emplace_back(0); q_sort.emplace_back(1); q_elliptic.emplace_back(0); - q_elliptic_double.emplace_back(0); + q_double.emplace_back(0); q_lookup_type.emplace_back(0); q_aux.emplace_back(0); // enforce range check for middle rows @@ -1035,7 +1035,7 @@ void UltraCircuitBuilder_::create_sort_constraint_with_edges(const std::vect q_4.emplace_back(0); q_sort.emplace_back(1); q_elliptic.emplace_back(0); - q_elliptic_double.emplace_back(0); + q_double.emplace_back(0); q_lookup_type.emplace_back(0); q_aux.emplace_back(0); } @@ -1055,7 +1055,7 @@ void UltraCircuitBuilder_::create_sort_constraint_with_edges(const std::vect q_4.emplace_back(0); q_sort.emplace_back(1); q_elliptic.emplace_back(0); - q_elliptic_double.emplace_back(0); + q_double.emplace_back(0); q_lookup_type.emplace_back(0); q_aux.emplace_back(0); } @@ -1076,7 +1076,7 @@ void UltraCircuitBuilder_::create_sort_constraint_with_edges(const std::vect q_4.emplace_back(0); q_sort.emplace_back(0); q_elliptic.emplace_back(0); - q_elliptic_double.emplace_back(0); + q_double.emplace_back(0); q_lookup_type.emplace_back(0); q_aux.emplace_back(0); } @@ -1184,7 +1184,7 @@ template void UltraCircuitBuilder_::apply_aux_selectors(const q_sort.emplace_back(0); q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); - q_elliptic_double.emplace_back(0); + q_double.emplace_back(0); switch (type) { case AUX_SELECTORS::LIMB_ACCUMULATE_1: { q_1.emplace_back(0); @@ -1850,7 +1850,7 @@ std::array UltraCircuitBuilder_::evaluate_non_native_field_addi q_sort.emplace_back(0); q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); - q_elliptic_double.emplace_back(0); + q_double.emplace_back(0); q_aux.emplace_back(0); } @@ -1972,7 +1972,7 @@ std::array UltraCircuitBuilder_::evaluate_non_native_field_subt q_sort.emplace_back(0); q_lookup_type.emplace_back(0); q_elliptic.emplace_back(0); - q_elliptic_double.emplace_back(0); + q_double.emplace_back(0); q_aux.emplace_back(0); } @@ -3208,7 +3208,7 @@ inline FF UltraCircuitBuilder_::compute_auxilary_identity(FF q_aux_value, * @return fr */ template -inline FF UltraCircuitBuilder_::compute_elliptic_double_identity(FF q_elliptic_double_value, +inline FF UltraCircuitBuilder_::compute_elliptic_double_identity(FF q_double_value, FF w_2_value, FF w_3_value, FF w_2_shifted_value, @@ -3236,7 +3236,7 @@ inline FF UltraCircuitBuilder_::compute_elliptic_double_identity(FF q_ellipt const FF x_pow_2 = (x1 * x1); const FF y_relation = x_pow_2 * (x1 - x3) * 3 - (y1 + y1) * (y1 + y3); - return q_elliptic_double_value * alpha_base * (x_relation + y_relation * alpha); + return q_double_value * alpha_base * (x_relation + y_relation * alpha); } /** @@ -3342,7 +3342,7 @@ template bool UltraCircuitBuilder_::check_circuit() FF q_elliptic_value; FF q_sort_value; FF q_lookup_type_value; - FF q_elliptic_double_value; + FF q_double_value; FF q_1_value; FF q_2_value; FF q_3_value; @@ -3360,7 +3360,7 @@ template bool UltraCircuitBuilder_::check_circuit() q_elliptic_value = q_elliptic[i]; q_sort_value = q_sort[i]; q_lookup_type_value = q_lookup_type[i]; - q_elliptic_double_value = q_elliptic_double[i]; + q_double_value = q_double[i]; q_1_value = q_1[i]; q_2_value = q_2[i]; q_3_value = q_3[i]; @@ -3500,7 +3500,7 @@ template bool UltraCircuitBuilder_::check_circuit() break; } } - if (!compute_elliptic_double_identity(q_elliptic_double_value, + if (!compute_elliptic_double_identity(q_double_value, w_2_value, w_3_value, w_2_shifted_value, diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp index 0b6f64e3bf76..9856d703f16e 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp @@ -214,10 +214,8 @@ template class UltraCircuitBuilder_ : public CircuitBuilderBase ultra_selector_names() { - std::vector result{ - "q_m", "q_c", "q_1", "q_2", "q_3", "q_4", - "q_arith", "q_sort", "q_elliptic", "q_aux", "table_type", "q_elliptic_double" - }; + std::vector result{ "q_m", "q_c", "q_1", "q_2", "q_3", "q_4", + "q_arith", "q_sort", "q_elliptic", "q_double", "q_aux", "table_type" }; return result; } struct non_native_field_multiplication_cross_terms { @@ -266,7 +264,7 @@ template class UltraCircuitBuilder_ : public CircuitBuilderBase tau; @@ -319,7 +317,7 @@ template class UltraCircuitBuilder_ : public CircuitBuilderBase class UltraCircuitBuilder_ : public CircuitBuilderBaseq_elliptic.resize(num_gates); builder->q_aux.resize(num_gates); builder->q_lookup_type.resize(num_gates); - builder->q_elliptic_double.resize(num_gates); + builder->q_double.resize(num_gates); } /** * @brief Checks that the circuit state is the same as the stored circuit's one @@ -496,7 +494,7 @@ template class UltraCircuitBuilder_ : public CircuitBuilderBase class UltraCircuitBuilder_ : public CircuitBuilderBaseselectors.q_elliptic; SelectorVector& q_aux = this->selectors.q_aux; SelectorVector& q_lookup_type = this->selectors.q_lookup_type; - SelectorVector& q_elliptic_double = this->selectors.q_elliptic_double; + SelectorVector& q_double = this->selectors.q_double; // These are variables that we have used a gate on, to enforce that they are // equal to a defined value. @@ -1046,7 +1044,7 @@ template class UltraCircuitBuilder_ : public CircuitBuilderBase(_data); FF& q_sort = std::get<7>(_data); FF& q_elliptic = std::get<8>(_data); + FF& q_double = std::get<9>(_data); FF& q_aux = std::get<9>(_data); FF& q_lookup = std::get<10>(_data); FF& sigma_1 = std::get<11>(_data); @@ -335,6 +337,7 @@ TEST_F(UltraRelationConsistency, EllipticRelation) const auto& q_beta = input_elements.q_o; const auto& q_beta_sqr = input_elements.q_4; const auto& q_elliptic = input_elements.q_elliptic; + const auto& q_double = input_elements.q_double; RelationValues expected_values; // Compute x/y coordinate identities @@ -353,6 +356,25 @@ TEST_F(UltraRelationConsistency, EllipticRelation) expected_values[0] = x_identity * q_elliptic; expected_values[1] = y_identity * q_elliptic; + // Contribution 3 + auto x_1_sqr = x_1 * x_1; + auto y_1_sqr = y_1 * y_1; + auto curve_b = grumpkin::g1::curve_b; + auto x_pow_4 = (y_1_sqr - curve_b) * x_1; + auto y_1_sqr_mul_4 = y_1_sqr + y_1_sqr; + y_1_sqr_mul_4 += y_1_sqr_mul_4; + auto x_1_pow_4_mul_9 = x_pow_4; + x_1_pow_4_mul_9 += x_1_pow_4_mul_9; + x_1_pow_4_mul_9 += x_1_pow_4_mul_9; + x_1_pow_4_mul_9 += x_1_pow_4_mul_9; + x_1_pow_4_mul_9 += x_pow_4; + auto x_1_sqr_mul_3 = x_1_sqr + x_1_sqr + x_1_sqr; + auto x_double_identity = (x_3 + x_1 + x_1) * y_1_sqr_mul_4 - x_1_pow_4_mul_9; + auto y_double_identity = x_1_sqr_mul_3 * (x_1 - x_3) - (y_1 + y_1) * (y_1 + y_3); + + expected_values[0] = x_double_identity * q_double; + expected_values[1] = y_double_identity * q_double; + const auto parameters = RelationParameters::get_random(); validate_relation_execution(expected_values, input_elements, parameters); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/group/cycle_group.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/group/cycle_group.test.cpp index 65b722699dbf..2cffaab13905 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/group/cycle_group.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/group/cycle_group.test.cpp @@ -2,19 +2,20 @@ #include "barretenberg/crypto/pedersen_commitment/pedersen_refactor.hpp" #include "barretenberg/crypto/pedersen_hash/pedersen.hpp" #include "barretenberg/numeric/random/engine.hpp" +#include "barretenberg/plonk/composer/ultra_composer.hpp" #include "barretenberg/stdlib/primitives/field/field.hpp" #include "barretenberg/stdlib/primitives/witness/witness.hpp" #include #define STDLIB_TYPE_ALIASES \ - using Composer = TypeParam; \ - using cycle_group_ct = stdlib::cycle_group; \ - using Curve = typename stdlib::cycle_group::Curve; \ + using Builder = TypeParam; \ + using cycle_group_ct = stdlib::cycle_group; \ + using Curve = typename stdlib::cycle_group::Curve; \ using Element = typename Curve::Element; \ using AffineElement = typename Curve::AffineElement; \ using Group = typename Curve::Group; \ - using bool_ct = stdlib::bool_t; \ - using witness_ct = stdlib::witness_t; + using bool_ct = stdlib::bool_t; \ + using witness_ct = stdlib::witness_t; namespace stdlib_cycle_group_tests { using namespace barretenberg; @@ -26,9 +27,9 @@ auto& engine = numeric::random::get_debug_engine(); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-local-typedefs" -template class CycleGroupTest : public ::testing::Test { +template class CycleGroupTest : public ::testing::Test { public: - using Curve = typename stdlib::cycle_group::Curve; + using Curve = typename stdlib::cycle_group::Curve; using Group = typename Curve::Group; using Element = typename Curve::Element; @@ -52,28 +53,28 @@ TYPED_TEST_SUITE(CycleGroupTest, CircuitTypes); TYPED_TEST(CycleGroupTest, TestDbl) { STDLIB_TYPE_ALIASES; - auto composer = Composer(); + auto builder = Builder(); auto lhs = TestFixture::generators[0]; - cycle_group_ct a = cycle_group_ct::from_witness(&composer, lhs); + cycle_group_ct a = cycle_group_ct::from_witness(&builder, lhs); cycle_group_ct c = a.dbl(); AffineElement expected(Element(lhs).dbl()); AffineElement result = c.get_value(); EXPECT_EQ(result, expected); - bool proof_result = composer.check_circuit(); + bool proof_result = builder.check_circuit(); EXPECT_EQ(proof_result, true); } TYPED_TEST(CycleGroupTest, TestUnconditionalAdd) { STDLIB_TYPE_ALIASES; - auto composer = Composer(); + auto builder = Builder(); auto add = [&](const AffineElement& lhs, const AffineElement& rhs, const bool lhs_constant, const bool rhs_constant) { - cycle_group_ct a = lhs_constant ? cycle_group_ct(lhs) : cycle_group_ct::from_witness(&composer, lhs); - cycle_group_ct b = rhs_constant ? cycle_group_ct(rhs) : cycle_group_ct::from_witness(&composer, rhs); + cycle_group_ct a = lhs_constant ? cycle_group_ct(lhs) : cycle_group_ct::from_witness(&builder, lhs); + cycle_group_ct b = rhs_constant ? cycle_group_ct(rhs) : cycle_group_ct::from_witness(&builder, rhs); cycle_group_ct c = a.unconditional_add(b); AffineElement expected(Element(lhs) + Element(rhs)); AffineElement result = c.get_value(); @@ -85,64 +86,64 @@ TYPED_TEST(CycleGroupTest, TestUnconditionalAdd) add(TestFixture::generators[0], TestFixture::generators[1], true, false); add(TestFixture::generators[0], TestFixture::generators[1], true, true); - bool proof_result = composer.check_circuit(); + bool proof_result = builder.check_circuit(); EXPECT_EQ(proof_result, true); } TYPED_TEST(CycleGroupTest, TestConstrainedUnconditionalAddSucceed) { STDLIB_TYPE_ALIASES; - auto composer = Composer(); + auto builder = Builder(); auto lhs = TestFixture::generators[0]; auto rhs = TestFixture::generators[1]; // case 1. valid unconditional add - cycle_group_ct a = cycle_group_ct::from_witness(&composer, lhs); - cycle_group_ct b = cycle_group_ct::from_witness(&composer, rhs); + cycle_group_ct a = cycle_group_ct::from_witness(&builder, lhs); + cycle_group_ct b = cycle_group_ct::from_witness(&builder, rhs); cycle_group_ct c = a.checked_unconditional_add(b); AffineElement expected(Element(lhs) + Element(rhs)); AffineElement result = c.get_value(); EXPECT_EQ(result, expected); - bool proof_result = composer.check_circuit(); + bool proof_result = builder.check_circuit(); EXPECT_EQ(proof_result, true); } TYPED_TEST(CycleGroupTest, TestConstrainedUnconditionalAddFail) { STDLIB_TYPE_ALIASES; - auto composer = Composer(); + auto builder = Builder(); auto lhs = TestFixture::generators[0]; auto rhs = -TestFixture::generators[0]; // ruh roh // case 2. invalid unconditional add - cycle_group_ct a = cycle_group_ct::from_witness(&composer, lhs); - cycle_group_ct b = cycle_group_ct::from_witness(&composer, rhs); + cycle_group_ct a = cycle_group_ct::from_witness(&builder, lhs); + cycle_group_ct b = cycle_group_ct::from_witness(&builder, rhs); a.checked_unconditional_add(b); - EXPECT_TRUE(composer.failed()); + EXPECT_TRUE(builder.failed()); - bool proof_result = composer.check_circuit(); + bool proof_result = builder.check_circuit(); EXPECT_EQ(proof_result, false); } TYPED_TEST(CycleGroupTest, TestAdd) { STDLIB_TYPE_ALIASES; - auto composer = Composer(); + auto builder = Builder(); auto lhs = TestFixture::generators[0]; auto rhs = -TestFixture::generators[1]; - cycle_group_ct point_at_infinity = cycle_group_ct::from_witness(&composer, rhs); - point_at_infinity.set_point_at_infinity(bool_ct(witness_ct(&composer, true))); + cycle_group_ct point_at_infinity = cycle_group_ct::from_witness(&builder, rhs); + point_at_infinity.set_point_at_infinity(bool_ct(witness_ct(&builder, true))); // case 1. no edge-cases triggered { - cycle_group_ct a = cycle_group_ct::from_witness(&composer, lhs); - cycle_group_ct b = cycle_group_ct::from_witness(&composer, rhs); + cycle_group_ct a = cycle_group_ct::from_witness(&builder, lhs); + cycle_group_ct b = cycle_group_ct::from_witness(&builder, rhs); cycle_group_ct c = a + b; AffineElement expected(Element(lhs) + Element(rhs)); AffineElement result = c.get_value(); @@ -152,7 +153,7 @@ TYPED_TEST(CycleGroupTest, TestAdd) // case 2. lhs is point at infinity { cycle_group_ct a = point_at_infinity; - cycle_group_ct b = cycle_group_ct::from_witness(&composer, rhs); + cycle_group_ct b = cycle_group_ct::from_witness(&builder, rhs); cycle_group_ct c = a + b; AffineElement result = c.get_value(); EXPECT_EQ(result, rhs); @@ -160,7 +161,7 @@ TYPED_TEST(CycleGroupTest, TestAdd) // case 3. rhs is point at infinity { - cycle_group_ct a = cycle_group_ct::from_witness(&composer, lhs); + cycle_group_ct a = cycle_group_ct::from_witness(&builder, lhs); cycle_group_ct b = point_at_infinity; cycle_group_ct c = a + b; AffineElement result = c.get_value(); @@ -178,8 +179,8 @@ TYPED_TEST(CycleGroupTest, TestAdd) // case 5. lhs = -rhs { - cycle_group_ct a = cycle_group_ct::from_witness(&composer, lhs); - cycle_group_ct b = cycle_group_ct::from_witness(&composer, -lhs); + cycle_group_ct a = cycle_group_ct::from_witness(&builder, lhs); + cycle_group_ct b = cycle_group_ct::from_witness(&builder, -lhs); cycle_group_ct c = a + b; EXPECT_TRUE(c.is_point_at_infinity().get_value()); EXPECT_TRUE(c.get_value().is_point_at_infinity()); @@ -187,27 +188,27 @@ TYPED_TEST(CycleGroupTest, TestAdd) // case 6. lhs = rhs { - cycle_group_ct a = cycle_group_ct::from_witness(&composer, lhs); - cycle_group_ct b = cycle_group_ct::from_witness(&composer, lhs); + cycle_group_ct a = cycle_group_ct::from_witness(&builder, lhs); + cycle_group_ct b = cycle_group_ct::from_witness(&builder, lhs); cycle_group_ct c = a + b; AffineElement expected((Element(lhs)).dbl()); AffineElement result = c.get_value(); EXPECT_EQ(result, expected); } - bool proof_result = composer.check_circuit(); + bool proof_result = builder.check_circuit(); EXPECT_EQ(proof_result, true); } TYPED_TEST(CycleGroupTest, TestUnconditionalSubtract) { STDLIB_TYPE_ALIASES; - auto composer = Composer(); + auto builder = Builder(); auto add = [&](const AffineElement& lhs, const AffineElement& rhs, const bool lhs_constant, const bool rhs_constant) { - cycle_group_ct a = lhs_constant ? cycle_group_ct(lhs) : cycle_group_ct::from_witness(&composer, lhs); - cycle_group_ct b = rhs_constant ? cycle_group_ct(rhs) : cycle_group_ct::from_witness(&composer, rhs); + cycle_group_ct a = lhs_constant ? cycle_group_ct(lhs) : cycle_group_ct::from_witness(&builder, lhs); + cycle_group_ct b = rhs_constant ? cycle_group_ct(rhs) : cycle_group_ct::from_witness(&builder, rhs); cycle_group_ct c = a.unconditional_subtract(b); AffineElement expected(Element(lhs) - Element(rhs)); AffineElement result = c.get_value(); @@ -219,66 +220,66 @@ TYPED_TEST(CycleGroupTest, TestUnconditionalSubtract) add(TestFixture::generators[0], TestFixture::generators[1], true, false); add(TestFixture::generators[0], TestFixture::generators[1], true, true); - bool proof_result = composer.check_circuit(); + bool proof_result = builder.check_circuit(); EXPECT_EQ(proof_result, true); } TYPED_TEST(CycleGroupTest, TestConstrainedUnconditionalSubtractSucceed) { STDLIB_TYPE_ALIASES; - auto composer = Composer(); + auto builder = Builder(); auto lhs = TestFixture::generators[0]; auto rhs = TestFixture::generators[1]; // case 1. valid unconditional add - cycle_group_ct a = cycle_group_ct::from_witness(&composer, lhs); - cycle_group_ct b = cycle_group_ct::from_witness(&composer, rhs); + cycle_group_ct a = cycle_group_ct::from_witness(&builder, lhs); + cycle_group_ct b = cycle_group_ct::from_witness(&builder, rhs); cycle_group_ct c = a.checked_unconditional_subtract(b); AffineElement expected(Element(lhs) - Element(rhs)); AffineElement result = c.get_value(); EXPECT_EQ(result, expected); - bool proof_result = composer.check_circuit(); + bool proof_result = builder.check_circuit(); EXPECT_EQ(proof_result, true); } TYPED_TEST(CycleGroupTest, TestConstrainedUnconditionalSubtractFail) { STDLIB_TYPE_ALIASES; - auto composer = Composer(); + auto builder = Builder(); auto lhs = TestFixture::generators[0]; auto rhs = -TestFixture::generators[0]; // ruh roh // case 2. invalid unconditional add - cycle_group_ct a = cycle_group_ct::from_witness(&composer, lhs); - cycle_group_ct b = cycle_group_ct::from_witness(&composer, rhs); + cycle_group_ct a = cycle_group_ct::from_witness(&builder, lhs); + cycle_group_ct b = cycle_group_ct::from_witness(&builder, rhs); a.checked_unconditional_subtract(b); - EXPECT_TRUE(composer.failed()); + EXPECT_TRUE(builder.failed()); - bool proof_result = composer.check_circuit(); + bool proof_result = builder.check_circuit(); EXPECT_EQ(proof_result, false); } TYPED_TEST(CycleGroupTest, TestSubtract) { STDLIB_TYPE_ALIASES; - using bool_ct = stdlib::bool_t; - using witness_ct = stdlib::witness_t; - auto composer = Composer(); + using bool_ct = stdlib::bool_t; + using witness_ct = stdlib::witness_t; + auto builder = Builder(); auto lhs = TestFixture::generators[0]; auto rhs = -TestFixture::generators[1]; - cycle_group_ct point_at_infinity = cycle_group_ct::from_witness(&composer, rhs); - point_at_infinity.set_point_at_infinity(bool_ct(witness_ct(&composer, true))); + cycle_group_ct point_at_infinity = cycle_group_ct::from_witness(&builder, rhs); + point_at_infinity.set_point_at_infinity(bool_ct(witness_ct(&builder, true))); // case 1. no edge-cases triggered { - cycle_group_ct a = cycle_group_ct::from_witness(&composer, lhs); - cycle_group_ct b = cycle_group_ct::from_witness(&composer, rhs); + cycle_group_ct a = cycle_group_ct::from_witness(&builder, lhs); + cycle_group_ct b = cycle_group_ct::from_witness(&builder, rhs); cycle_group_ct c = a - b; AffineElement expected(Element(lhs) - Element(rhs)); AffineElement result = c.get_value(); @@ -288,7 +289,7 @@ TYPED_TEST(CycleGroupTest, TestSubtract) // case 2. lhs is point at infinity { cycle_group_ct a = point_at_infinity; - cycle_group_ct b = cycle_group_ct::from_witness(&composer, rhs); + cycle_group_ct b = cycle_group_ct::from_witness(&builder, rhs); cycle_group_ct c = a - b; AffineElement result = c.get_value(); EXPECT_EQ(result, -rhs); @@ -296,7 +297,7 @@ TYPED_TEST(CycleGroupTest, TestSubtract) // case 3. rhs is point at infinity { - cycle_group_ct a = cycle_group_ct::from_witness(&composer, lhs); + cycle_group_ct a = cycle_group_ct::from_witness(&builder, lhs); cycle_group_ct b = point_at_infinity; cycle_group_ct c = a - b; AffineElement result = c.get_value(); @@ -314,8 +315,8 @@ TYPED_TEST(CycleGroupTest, TestSubtract) // case 5. lhs = -rhs { - cycle_group_ct a = cycle_group_ct::from_witness(&composer, lhs); - cycle_group_ct b = cycle_group_ct::from_witness(&composer, -lhs); + cycle_group_ct a = cycle_group_ct::from_witness(&builder, lhs); + cycle_group_ct b = cycle_group_ct::from_witness(&builder, -lhs); cycle_group_ct c = a - b; AffineElement expected((Element(lhs)).dbl()); AffineElement result = c.get_value(); @@ -324,21 +325,21 @@ TYPED_TEST(CycleGroupTest, TestSubtract) // case 6. lhs = rhs { - cycle_group_ct a = cycle_group_ct::from_witness(&composer, lhs); - cycle_group_ct b = cycle_group_ct::from_witness(&composer, lhs); + cycle_group_ct a = cycle_group_ct::from_witness(&builder, lhs); + cycle_group_ct b = cycle_group_ct::from_witness(&builder, lhs); cycle_group_ct c = a - b; EXPECT_TRUE(c.is_point_at_infinity().get_value()); EXPECT_TRUE(c.get_value().is_point_at_infinity()); } - bool proof_result = composer.check_circuit(); + bool proof_result = builder.check_circuit(); EXPECT_EQ(proof_result, true); } TYPED_TEST(CycleGroupTest, TestBatchMul) { STDLIB_TYPE_ALIASES; - auto composer = Composer(); + auto builder = Builder(); const size_t num_muls = 1; @@ -354,17 +355,17 @@ TYPED_TEST(CycleGroupTest, TestBatchMul) // 1: add entry where point, scalar are witnesses expected += (element * scalar); - points.emplace_back(cycle_group_ct::from_witness(&composer, element)); - scalars.emplace_back(cycle_group_ct::cycle_scalar::from_witness(&composer, scalar)); + points.emplace_back(cycle_group_ct::from_witness(&builder, element)); + scalars.emplace_back(cycle_group_ct::cycle_scalar::from_witness(&builder, scalar)); // 2: add entry where point is constant, scalar is witness expected += (element * scalar); points.emplace_back(cycle_group_ct(element)); - scalars.emplace_back(cycle_group_ct::cycle_scalar::from_witness(&composer, scalar)); + scalars.emplace_back(cycle_group_ct::cycle_scalar::from_witness(&builder, scalar)); // 3: add entry where point is witness, scalar is constant expected += (element * scalar); - points.emplace_back(cycle_group_ct::from_witness(&composer, element)); + points.emplace_back(cycle_group_ct::from_witness(&builder, element)); scalars.emplace_back(typename cycle_group_ct::cycle_scalar(scalar)); // 4: add entry where point is constant, scalar is constant @@ -383,11 +384,11 @@ TYPED_TEST(CycleGroupTest, TestBatchMul) auto element = TestFixture::generators[0]; typename Group::subgroup_field scalar = Group::subgroup_field::random_element(&engine); - points.emplace_back(cycle_group_ct::from_witness(&composer, element)); - scalars.emplace_back(cycle_group_ct::cycle_scalar::from_witness(&composer, scalar)); + points.emplace_back(cycle_group_ct::from_witness(&builder, element)); + scalars.emplace_back(cycle_group_ct::cycle_scalar::from_witness(&builder, scalar)); - points.emplace_back(cycle_group_ct::from_witness(&composer, element)); - scalars.emplace_back(cycle_group_ct::cycle_scalar::from_witness(&composer, -scalar)); + points.emplace_back(cycle_group_ct::from_witness(&builder, element)); + scalars.emplace_back(cycle_group_ct::cycle_scalar::from_witness(&builder, -scalar)); auto result = cycle_group_ct::batch_mul(scalars, points); EXPECT_TRUE(result.is_point_at_infinity().get_value()); @@ -400,8 +401,8 @@ TYPED_TEST(CycleGroupTest, TestBatchMul) auto element = TestFixture::generators[0]; typename Group::subgroup_field scalar = 0; - points.emplace_back(cycle_group_ct::from_witness(&composer, element)); - scalars.emplace_back(cycle_group_ct::cycle_scalar::from_witness(&composer, scalar)); + points.emplace_back(cycle_group_ct::from_witness(&builder, element)); + scalars.emplace_back(cycle_group_ct::cycle_scalar::from_witness(&builder, scalar)); auto result = cycle_group_ct::batch_mul(scalars, points); EXPECT_TRUE(result.is_point_at_infinity().get_value()); } @@ -416,17 +417,17 @@ TYPED_TEST(CycleGroupTest, TestBatchMul) // is_infinity = witness { - cycle_group_ct point = cycle_group_ct::from_witness(&composer, element); - point.set_point_at_infinity(witness_ct(&composer, true)); + cycle_group_ct point = cycle_group_ct::from_witness(&builder, element); + point.set_point_at_infinity(witness_ct(&builder, true)); points.emplace_back(point); - scalars.emplace_back(cycle_group_ct::cycle_scalar::from_witness(&composer, scalar)); + scalars.emplace_back(cycle_group_ct::cycle_scalar::from_witness(&builder, scalar)); } // is_infinity = constant { - cycle_group_ct point = cycle_group_ct::from_witness(&composer, element); + cycle_group_ct point = cycle_group_ct::from_witness(&builder, element); point.set_point_at_infinity(true); points.emplace_back(point); - scalars.emplace_back(cycle_group_ct::cycle_scalar::from_witness(&composer, scalar)); + scalars.emplace_back(cycle_group_ct::cycle_scalar::from_witness(&builder, scalar)); } auto result = cycle_group_ct::batch_mul(scalars, points); EXPECT_TRUE(result.is_point_at_infinity().get_value()); @@ -446,7 +447,7 @@ TYPED_TEST(CycleGroupTest, TestBatchMul) // 1: add entry where point is constant, scalar is witness expected += (element * scalar); points.emplace_back(element); - scalars.emplace_back(cycle_group_ct::cycle_scalar::from_witness(&composer, scalar)); + scalars.emplace_back(cycle_group_ct::cycle_scalar::from_witness(&builder, scalar)); scalars_native.emplace_back(uint256_t(scalar)); // 2: add entry where point is constant, scalar is constant @@ -475,7 +476,7 @@ TYPED_TEST(CycleGroupTest, TestBatchMul) // 1: add entry where point is constant, scalar is witness expected += (element * scalar); points.emplace_back(element); - scalars.emplace_back(cycle_group_ct::cycle_scalar::from_witness(&composer, scalar)); + scalars.emplace_back(cycle_group_ct::cycle_scalar::from_witness(&builder, scalar)); scalars_native.emplace_back(scalar); // 2: add entry where point is constant, scalar is constant @@ -490,7 +491,7 @@ TYPED_TEST(CycleGroupTest, TestBatchMul) element = Group::one * Group::subgroup_field::random_element(&engine); expected += (element * scalar); points.emplace_back(element); - scalars.emplace_back(cycle_group_ct::cycle_scalar::from_witness(&composer, scalar)); + scalars.emplace_back(cycle_group_ct::cycle_scalar::from_witness(&builder, scalar)); scalars_native.emplace_back(scalar); } auto result = cycle_group_ct::batch_mul(scalars, points); @@ -508,7 +509,7 @@ TYPED_TEST(CycleGroupTest, TestBatchMul) // 1: add entry where point is constant, scalar is witness points.emplace_back((element)); - scalars.emplace_back(cycle_group_ct::cycle_scalar::from_witness(&composer, scalar)); + scalars.emplace_back(cycle_group_ct::cycle_scalar::from_witness(&builder, scalar)); // // 2: add entry where point is constant, scalar is constant points.emplace_back((element)); @@ -518,14 +519,24 @@ TYPED_TEST(CycleGroupTest, TestBatchMul) EXPECT_EQ(result.is_point_at_infinity().get_value(), true); } - bool proof_result = composer.check_circuit(); - EXPECT_EQ(proof_result, true); + bool check_result = builder.check_circuit(); + EXPECT_EQ(check_result, true); + + if constexpr (std::same_as) { + proof_system::plonk::UltraComposer composer = proof_system::plonk::UltraComposer(); + auto prover = composer.create_prover(builder); + // Construct proof + auto proof = prover.construct_proof(); + + auto verifier = composer.create_verifier(builder); + EXPECT_EQ(verifier.verify_proof(proof), true); + } } TYPED_TEST(CycleGroupTest, TestMul) { STDLIB_TYPE_ALIASES - auto composer = Composer(); + auto builder = Builder(); const size_t num_muls = 5; @@ -538,18 +549,18 @@ TYPED_TEST(CycleGroupTest, TestMul) typename Group::subgroup_field native_scalar = Group::subgroup_field::random_element(&engine); // 1: add entry where point, scalar are witnesses - point = (cycle_group_ct::from_witness(&composer, element)); - scalar = (cycle_group_ct::cycle_scalar::from_witness(&composer, native_scalar)); + point = (cycle_group_ct::from_witness(&builder, element)); + scalar = (cycle_group_ct::cycle_scalar::from_witness(&builder, native_scalar)); EXPECT_EQ((point * scalar).get_value(), (element * native_scalar)); // 2: add entry where point is constant, scalar is witness point = (cycle_group_ct(element)); - scalar = (cycle_group_ct::cycle_scalar::from_witness(&composer, native_scalar)); + scalar = (cycle_group_ct::cycle_scalar::from_witness(&builder, native_scalar)); EXPECT_EQ((point * scalar).get_value(), (element * native_scalar)); // 3: add entry where point is witness, scalar is constant - point = (cycle_group_ct::from_witness(&composer, element)); + point = (cycle_group_ct::from_witness(&builder, element)); EXPECT_EQ((point * scalar).get_value(), (element * native_scalar)); // 4: add entry where point is constant, scalar is constant @@ -558,7 +569,7 @@ TYPED_TEST(CycleGroupTest, TestMul) } } - bool proof_result = composer.check_circuit(); + bool proof_result = builder.check_circuit(); EXPECT_EQ(proof_result, true); } #pragma GCC diagnostic pop From 0256440e0866566b747e9126f09800137b53441d Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Sat, 30 Sep 2023 13:48:29 +0000 Subject: [PATCH 02/15] added ecc doubling gate into BaseUltraVerifier --- .../plonk/composer/ultra_composer.hpp | 6 +- .../proof_system/verification_key/sol_gen.hpp | 13 +- .../circuits/recursive_circuit.hpp | 192 ++++++++++++------ .../sol/src/ultra/BaseUltraVerifier.sol | 177 +++++++++++----- .../src/ultra/instance/Add2UltraVerifier.sol | 2 +- .../ultra/keys/Add2UltraVerificationKey.sol | 120 +++++------ .../ultra/keys/BlakeUltraVerificationKey.sol | 42 ++-- .../keys/RecursiveUltraVerificationKey.sol | 110 +++++----- 8 files changed, 405 insertions(+), 257 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/plonk/composer/ultra_composer.hpp b/barretenberg/cpp/src/barretenberg/plonk/composer/ultra_composer.hpp index d88046424567..a04d6ea6385c 100644 --- a/barretenberg/cpp/src/barretenberg/plonk/composer/ultra_composer.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk/composer/ultra_composer.hpp @@ -27,7 +27,8 @@ class UltraComposer { std::shared_ptr circuit_verification_key; // The crs_factory holds the path to the srs and exposes methods to extract the srs elements - std::shared_ptr> crs_factory_; + std::shared_ptr> crs_factory_ = + barretenberg::srs::get_crs_factory(); bool computed_witness = false; @@ -37,8 +38,7 @@ class UltraComposer { // vanishing_polynomial cannot be trivially fetched here, I am directly setting this to 4 - 1 = 3. static constexpr size_t s_randomness = 3; - UltraComposer() - : UltraComposer("../srs_db/ignition"){}; + UltraComposer() = default; UltraComposer(std::string const& crs_path) : UltraComposer(std::make_unique>(crs_path)){}; diff --git a/barretenberg/cpp/src/barretenberg/plonk/proof_system/verification_key/sol_gen.hpp b/barretenberg/cpp/src/barretenberg/plonk/proof_system/verification_key/sol_gen.hpp index 2f5822fec2ba..5174f1e5db95 100644 --- a/barretenberg/cpp/src/barretenberg/plonk/proof_system/verification_key/sol_gen.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk/proof_system/verification_key/sol_gen.hpp @@ -119,13 +119,14 @@ inline void output_vk_sol_ultra(std::ostream& os, std::shared_ptrcommitments.at("ID_2"), "vk.ID2"); print_g1("0x5c0", "0x5e0", key->commitments.at("ID_3"), "vk.ID3"); print_g1("0x600", "0x620", key->commitments.at("ID_4"), "vk.ID4"); + print_g1("0x640", "0x660", key->commitments.at("Q_DOUBLE"), "vk.Q_DOUBLE"); os << - " mstore(add(_vk, 0x640), " << (key->contains_recursive_proof ? "0x01" : "0x00") << ") // vk.contains_recursive_proof\n" - " mstore(add(_vk, 0x660), " << (key->contains_recursive_proof ? key->recursive_proof_public_input_indices[0] : 0) << ") // vk.recursive_proof_public_input_indices\n" - " mstore(add(_vk, 0x680), " << key->reference_string->get_g2x().x.c1 << ") // vk.g2_x.X.c1 \n" - " mstore(add(_vk, 0x6a0), " << key->reference_string->get_g2x().x.c0 << ") // vk.g2_x.X.c0 \n" - " mstore(add(_vk, 0x6c0), " << key->reference_string->get_g2x().y.c1 << ") // vk.g2_x.Y.c1 \n" - " mstore(add(_vk, 0x6e0), " << key->reference_string->get_g2x().y.c0 << ") // vk.g2_x.Y.c0 \n" + " mstore(add(_vk, 0x680), " << (key->contains_recursive_proof ? "0x01" : "0x00") << ") // vk.contains_recursive_proof\n" + " mstore(add(_vk, 0x6a0), " << (key->contains_recursive_proof ? key->recursive_proof_public_input_indices[0] : 0) << ") // vk.recursive_proof_public_input_indices\n" + " mstore(add(_vk, 0x6c0), " << key->reference_string->get_g2x().x.c1 << ") // vk.g2_x.X.c1 \n" + " mstore(add(_vk, 0x6e0), " << key->reference_string->get_g2x().x.c0 << ") // vk.g2_x.X.c0 \n" + " mstore(add(_vk, 0x700), " << key->reference_string->get_g2x().y.c1 << ") // vk.g2_x.Y.c1 \n" + " mstore(add(_vk, 0x720), " << key->reference_string->get_g2x().y.c0 << ") // vk.g2_x.Y.c0 \n" " mstore(_omegaInverseLoc, " << key->domain.root_inverse << ") // vk.work_root_inverse\n" " }\n" " }\n" diff --git a/barretenberg/cpp/src/barretenberg/solidity_helpers/circuits/recursive_circuit.hpp b/barretenberg/cpp/src/barretenberg/solidity_helpers/circuits/recursive_circuit.hpp index cb635c115005..286ecfdd344c 100644 --- a/barretenberg/cpp/src/barretenberg/solidity_helpers/circuits/recursive_circuit.hpp +++ b/barretenberg/cpp/src/barretenberg/solidity_helpers/circuits/recursive_circuit.hpp @@ -1,71 +1,71 @@ #pragma once #include "barretenberg/ecc/curves/bn254/fq12.hpp" #include "barretenberg/ecc/curves/bn254/pairing.hpp" +#include "barretenberg/plonk/composer/ultra_composer.hpp" #include "barretenberg/plonk/proof_system/proving_key/serialize.hpp" +#include "barretenberg/stdlib/primitives/circuit_builders/circuit_builders_fwd.hpp" #include "barretenberg/stdlib/primitives/curves/bn254.hpp" #include "barretenberg/stdlib/recursion/verifier/program_settings.hpp" #include "barretenberg/stdlib/recursion/verifier/verifier.hpp" #include "barretenberg/transcript/transcript.hpp" using namespace proof_system::plonk; - +using namespace stdlib; using numeric::uint256_t; -template class RecursiveCircuit { +template class RecursiveCircuit { using InnerComposer = UltraComposer; using InnerBuilder = typename InnerComposer::CircuitBuilder; - typedef stdlib::field_t field_ct; - typedef stdlib::bn254 inner_curve; - typedef stdlib::bn254 outer_curve; - typedef stdlib::recursion::verification_key verification_key_pt; - typedef stdlib::recursion::recursive_ultra_verifier_settings recursive_settings; - typedef stdlib::recursion::recursive_ultra_to_standard_verifier_settings - ultra_to_standard_recursive_settings; - typedef inner_curve::ScalarField fr_ct; - typedef inner_curve::public_witness_ct public_witness_ct; - typedef inner_curve::witness_ct witness_ct; + using inner_curve = bn254; + using outer_curve = bn254; + + using verification_key_pt = recursion::verification_key; + using recursive_settings = recursion::recursive_ultra_verifier_settings; + using ultra_to_standard_recursive_settings = recursion::recursive_ultra_to_standard_verifier_settings; + + using inner_scalar_field_ct = inner_curve::ScalarField; + using inner_ground_field_ct = inner_curve::BaseField; + using public_witness_ct = inner_curve::public_witness_ct; + using witness_ct = inner_curve::witness_ct; + using byte_array_ct = inner_curve::byte_array_ct; + + using inner_scalar_field = typename inner_curve::ScalarFieldNative; + using outer_scalar_field = typename outer_curve::BaseFieldNative; + using pairing_target_field = barretenberg::fq12; + static constexpr bool is_ultra_to_ultra = std::is_same_v; + using ProverOfInnerCircuit = + std::conditional_t; + using VerifierOfInnerProof = + std::conditional_t; + using RecursiveSettings = + std::conditional_t; struct circuit_outputs { stdlib::recursion::aggregation_state aggregation_state; std::shared_ptr verification_key; }; - static void create_inner_circuit_no_tables(InnerBuilder& builder, uint256_t inputs[]) + static void create_inner_circuit_no_tables(InnerBuilder& builder, uint256_t public_inputs[]) { - field_ct a(public_witness_ct(&builder, inputs[0])); - field_ct b(public_witness_ct(&builder, inputs[1])); - field_ct c(public_witness_ct(&builder, inputs[2])); + // A nice Pythagorean triples circuit example: "I know a & b s.t. a^2 + b^2 = c^2". + inner_scalar_field_ct a(witness_ct(&builder, public_inputs[0])); + inner_scalar_field_ct b(witness_ct(&builder, public_inputs[1])); + inner_scalar_field_ct c(witness_ct(&builder, public_inputs[2])); - // @note For some reason, if we don't have this line, the circuit fails to verify. + auto a_sq = a * a; + auto b_sq = b * b; auto c_sq = c * c; - c.assert_equal(a + b); - c_sq.assert_equal(c * c); + (c_sq).assert_equal(a_sq + b_sq); + + c_sq.set_public(); }; - static circuit_outputs create_outer_circuit(InnerBuilder& inner_circuit, OuterComposer& outer_composer) + static circuit_outputs create_outer_circuit(InnerBuilder& inner_circuit, OuterBuilder& outer_builder) { - // These constexpr definitions are to allow for the following: - // An Ultra Pedersen hash evaluates to a different value from the Standard version of the Pedersen hash. - // Therefore, the fiat-shamir challenges generated by the prover and verifier _could_ accidentally be different - // if an ultra proof is generated using ultra-pedersen challenges, but is being verified within a non-ultra - // circuit which uses non-ultra-pedersen challenges. We need the prover and verifier hashes to be the same. The - // solution is to select the relevant prover and verifier types (whose settings use the same hash for - // fiat-shamir), depending on the Inner-Outer combo. It's a bit clunky, but the alternative is to have a - // template argument for the hashtype, and that would pervade the entire UltraComposer, which would - // be horrendous. - constexpr bool is_ultra_to_ultra = std::is_same::value; - typedef - typename std::conditional::type ProverOfInnerCircuit; - typedef typename std::conditional::type - VerifierOfInnerProof; - typedef - typename std::conditional::type - RecursiveSettings; - - InnerComposer inner_composer; ProverOfInnerCircuit prover; + InnerComposer inner_composer; if constexpr (is_ultra_to_ultra) { prover = inner_composer.create_prover(inner_circuit); } else { @@ -73,12 +73,11 @@ template class RecursiveCircuit { } const auto verification_key_native = inner_composer.compute_verification_key(inner_circuit); - // Convert the verification key's elements into _circuit_ types, using the OUTER composer. std::shared_ptr verification_key = - verification_key_pt::from_witness(&outer_composer, verification_key_native); + verification_key_pt::from_witness(&outer_builder, verification_key_native); - proof recursive_proof = prover.construct_proof(); + plonk::proof proof_to_recursively_verify = prover.construct_proof(); { // Native check is mainly for comparison vs circuit version of the verifier. @@ -89,7 +88,8 @@ template class RecursiveCircuit { } else { native_verifier = inner_composer.create_ultra_to_standard_verifier(inner_circuit); } - auto native_result = native_verifier.verify_proof(recursive_proof); + + auto native_result = native_verifier.verify_proof(proof_to_recursively_verify); if (native_result == false) { throw_or_abort("Native verification failed"); } @@ -97,44 +97,102 @@ template class RecursiveCircuit { transcript::Manifest recursive_manifest = InnerComposer::create_manifest(prover.key->num_public_inputs); - // Verifying the ultra (inner) proof with CIRCUIT TYPES (i.e. within a standard or ultra plonk arithmetic - // circuit) - stdlib::recursion::aggregation_state output = - stdlib::recursion::verify_proof( - &outer_composer, verification_key, recursive_manifest, recursive_proof); + auto output = recursion::verify_proof( + &outer_builder, verification_key, recursive_manifest, proof_to_recursively_verify); return { output, verification_key }; }; + static bool check_recursive_proof_public_inputs(OuterBuilder& builder, + const barretenberg::pairing::miller_lines* lines) + { + if (builder.contains_recursive_proof && builder.recursive_proof_public_input_indices.size() == 16) { + const auto& inputs = builder.public_inputs; + const auto recover_fq_from_public_inputs = + [&inputs, &builder](const size_t idx0, const size_t idx1, const size_t idx2, const size_t idx3) { + const uint256_t l0 = builder.get_variable(inputs[idx0]); + const uint256_t l1 = builder.get_variable(inputs[idx1]); + const uint256_t l2 = builder.get_variable(inputs[idx2]); + const uint256_t l3 = builder.get_variable(inputs[idx3]); + + const uint256_t limb = l0 + (l1 << NUM_LIMB_BITS_IN_FIELD_SIMULATION) + + (l2 << (NUM_LIMB_BITS_IN_FIELD_SIMULATION * 2)) + + (l3 << (NUM_LIMB_BITS_IN_FIELD_SIMULATION * 3)); + return outer_scalar_field(limb); + }; + + const auto x0 = recover_fq_from_public_inputs(builder.recursive_proof_public_input_indices[0], + builder.recursive_proof_public_input_indices[1], + builder.recursive_proof_public_input_indices[2], + builder.recursive_proof_public_input_indices[3]); + const auto y0 = recover_fq_from_public_inputs(builder.recursive_proof_public_input_indices[4], + builder.recursive_proof_public_input_indices[5], + builder.recursive_proof_public_input_indices[6], + builder.recursive_proof_public_input_indices[7]); + const auto x1 = recover_fq_from_public_inputs(builder.recursive_proof_public_input_indices[8], + builder.recursive_proof_public_input_indices[9], + builder.recursive_proof_public_input_indices[10], + builder.recursive_proof_public_input_indices[11]); + const auto y1 = recover_fq_from_public_inputs(builder.recursive_proof_public_input_indices[12], + builder.recursive_proof_public_input_indices[13], + builder.recursive_proof_public_input_indices[14], + builder.recursive_proof_public_input_indices[15]); + g1::affine_element P_affine[2]{ + { x0, y0 }, + { x1, y1 }, + }; + + pairing_target_field result = + barretenberg::pairing::reduced_ate_pairing_batch_precomputed(P_affine, lines, 2); + + return (result == pairing_target_field::one()); + } + return true; + } + static void check_pairing(const circuit_outputs& circuit_output) + { + auto g2_lines = barretenberg::srs::get_crs_factory()->get_verifier_crs()->get_precomputed_g2_lines(); + g1::affine_element P[2]; + P[0].x = outer_scalar_field(circuit_output.aggregation_state.P0.x.get_value().lo); + P[0].y = outer_scalar_field(circuit_output.aggregation_state.P0.y.get_value().lo); + P[1].x = outer_scalar_field(circuit_output.aggregation_state.P1.x.get_value().lo); + P[1].y = outer_scalar_field(circuit_output.aggregation_state.P1.y.get_value().lo); + pairing_target_field inner_proof_result = + barretenberg::pairing::reduced_ate_pairing_batch_precomputed(P, g2_lines, 2); + if (inner_proof_result != pairing_target_field::one()) { + throw_or_abort("inner proof result != 1"); + } + } + static void check_recursive_verification_circuit(OuterBuilder& outer_circuit, bool expected_result) + { + bool result = outer_circuit.check_circuit(); + if (result != expected_result) { + throw_or_abort("outer circuit check failed"); + } + auto g2_lines = barretenberg::srs::get_crs_factory()->get_verifier_crs()->get_precomputed_g2_lines(); + if (!check_recursive_proof_public_inputs(outer_circuit, g2_lines)) { + throw_or_abort("outer circuit recursion public inputs check failed"); + } + } + public: - static OuterComposer generate(uint256_t inputs[]) + static OuterBuilder generate(uint256_t inputs[]) { InnerBuilder inner_circuit; - OuterComposer outer_composer; + OuterBuilder outer_circuit; create_inner_circuit_no_tables(inner_circuit, inputs); - auto circuit_output = create_outer_circuit(inner_circuit, outer_composer); - - g1::affine_element P[2]; - P[0].x = barretenberg::fq(circuit_output.aggregation_state.P0.x.get_value().lo); - P[0].y = barretenberg::fq(circuit_output.aggregation_state.P0.y.get_value().lo); - P[1].x = barretenberg::fq(circuit_output.aggregation_state.P1.x.get_value().lo); - P[1].y = barretenberg::fq(circuit_output.aggregation_state.P1.y.get_value().lo); - - barretenberg::fq12 inner_proof_result = barretenberg::pairing::reduced_ate_pairing_batch_precomputed( - P, circuit_output.verification_key->reference_string->get_precomputed_g2_lines(), 2); - - if (inner_proof_result != barretenberg::fq12::one()) { - throw_or_abort("inner proof result != 1"); - } + auto circuit_output = create_outer_circuit(inner_circuit, outer_circuit); circuit_output.aggregation_state.assign_object_to_proof_outputs(); - - if (outer_composer.failed()) { + if (outer_circuit.failed()) { throw_or_abort("outer composer failed"); } - return outer_composer; + check_pairing(circuit_output); + check_recursive_verification_circuit(outer_circuit, true); + + return outer_circuit; } }; diff --git a/barretenberg/sol/src/ultra/BaseUltraVerifier.sol b/barretenberg/sol/src/ultra/BaseUltraVerifier.sol index 1d2842c35e01..5477a834e436 100644 --- a/barretenberg/sol/src/ultra/BaseUltraVerifier.sol +++ b/barretenberg/sol/src/ultra/BaseUltraVerifier.sol @@ -58,12 +58,14 @@ abstract contract BaseUltraVerifier { uint256 internal constant ID3_Y_LOC = 0x960; uint256 internal constant ID4_X_LOC = 0x980; uint256 internal constant ID4_Y_LOC = 0x9a0; - uint256 internal constant CONTAINS_RECURSIVE_PROOF_LOC = 0x9c0; - uint256 internal constant RECURSIVE_PROOF_PUBLIC_INPUT_INDICES_LOC = 0x9e0; - uint256 internal constant G2X_X0_LOC = 0xa00; - uint256 internal constant G2X_X1_LOC = 0xa20; - uint256 internal constant G2X_Y0_LOC = 0xa40; - uint256 internal constant G2X_Y1_LOC = 0xa60; + uint256 internal constant QDOUBLE_X_LOC = 0x9c0; + uint256 internal constant QDOUBLE_Y_LOC = 0x9e0; + uint256 internal constant CONTAINS_RECURSIVE_PROOF_LOC = 0xa00; + uint256 internal constant RECURSIVE_PROOF_PUBLIC_INPUT_INDICES_LOC = 0xa20; + uint256 internal constant G2X_X0_LOC = 0xa40; + uint256 internal constant G2X_X1_LOC = 0xa60; + uint256 internal constant G2X_Y0_LOC = 0xa80; + uint256 internal constant G2X_Y1_LOC = 0xaa0; // ### PROOF DATA MEMORY LOCATIONS uint256 internal constant W1_X_LOC = 0x1200; @@ -130,6 +132,7 @@ abstract contract BaseUltraVerifier { uint256 internal constant TABLE2_OMEGA_EVAL_LOC = 0x20e0; uint256 internal constant TABLE3_OMEGA_EVAL_LOC = 0x2100; uint256 internal constant TABLE4_OMEGA_EVAL_LOC = 0x2120; + uint256 internal constant QDOUBLE_EVAL_LOC = 0x2140; uint256 internal constant PI_Z_X_LOC = 0x2300; uint256 internal constant PI_Z_Y_LOC = 0x2320; @@ -254,6 +257,7 @@ abstract contract BaseUltraVerifier { uint256 internal constant QUOTIENT_EVAL_LOC = 0x3760; uint256 internal constant ZERO_POLY_INVERSE_LOC = 0x3780; + // uint256 internal constant DOUBLE_IDENTITY = 0x37a0; // when hashing public inputs we use memory at NU_CHALLENGE_INPUT_LOC_A, as the hash input size is unknown at compile time uint256 internal constant NU_CHALLENGE_INPUT_LOC_A = 0x37a0; @@ -268,13 +272,13 @@ abstract contract BaseUltraVerifier { uint256 internal constant ETA_INPUT_LENGTH = 0xc0; // W1, W2, W3 = 6 * 0x20 bytes - // We need to hash 41 field elements when generating the NU challenge + // We need to hash 42 field elements when generating the NU challenge // w1, w2, w3, w4, s, z, z_lookup, q1, q2, q3, q4, qm, qc, qarith (14) - // qsort, qelliptic, qaux, sigma1, sigma2, sigma, sigma4, (7) + // qsort, qelliptic, q_double, qaux, sigma1, sigma2, sigma, sigma4, (7) // table1, table2, table3, table4, tabletype, id1, id2, id3, id4, (9) // w1_omega, w2_omega, w3_omega, w4_omega, s_omega, z_omega, z_lookup_omega, (7) // table1_omega, table2_omega, table3_omega, table4_omega (4) - uint256 internal constant NU_INPUT_LENGTH = 0x520; // 0x520 = 41 * 0x20 + uint256 internal constant NU_INPUT_LENGTH = 0x540; // 0x540 = 42 * 0x20 // There are ELEVEN G1 group elements added into the transcript in the `beta` round, that we need to skip over // W1, W2, W3, W4, S, Z, Z_LOOKUP, T1, T2, T3, T4 @@ -292,6 +296,9 @@ abstract contract BaseUltraVerifier { error EC_SCALAR_MUL_FAILURE(); error PROOF_FAILURE(); +bytes4 internal constant ERR_S = 0xf7b44074; +error ERR(bytes32,bytes32,bytes32); + function getVerificationKeyHash() public pure virtual returns (bytes32); function loadVerificationKey(uint256 _vk, uint256 _omegaInverseLoc) internal pure virtual; @@ -369,44 +376,45 @@ abstract contract BaseUltraVerifier { mstore(QARITH_EVAL_LOC, mod(calldataload(add(data_ptr, 0x460)), p)) mstore(QSORT_EVAL_LOC, mod(calldataload(add(data_ptr, 0x480)), p)) mstore(QELLIPTIC_EVAL_LOC, mod(calldataload(add(data_ptr, 0x4a0)), p)) - mstore(QAUX_EVAL_LOC, mod(calldataload(add(data_ptr, 0x4c0)), p)) + mstore(QDOUBLE_EVAL_LOC, mod(calldataload(add(data_ptr, 0x4c0)), p)) + mstore(QAUX_EVAL_LOC, mod(calldataload(add(data_ptr, 0x4e0)), p)) - mstore(SIGMA1_EVAL_LOC, mod(calldataload(add(data_ptr, 0x4e0)), p)) - mstore(SIGMA2_EVAL_LOC, mod(calldataload(add(data_ptr, 0x500)), p)) + mstore(SIGMA1_EVAL_LOC, mod(calldataload(add(data_ptr, 0x500)), p)) + mstore(SIGMA2_EVAL_LOC, mod(calldataload(add(data_ptr, 0x520)), p)) - mstore(SIGMA3_EVAL_LOC, mod(calldataload(add(data_ptr, 0x520)), p)) - mstore(SIGMA4_EVAL_LOC, mod(calldataload(add(data_ptr, 0x540)), p)) + mstore(SIGMA3_EVAL_LOC, mod(calldataload(add(data_ptr, 0x540)), p)) + mstore(SIGMA4_EVAL_LOC, mod(calldataload(add(data_ptr, 0x560)), p)) - mstore(TABLE1_EVAL_LOC, mod(calldataload(add(data_ptr, 0x560)), p)) - mstore(TABLE2_EVAL_LOC, mod(calldataload(add(data_ptr, 0x580)), p)) - mstore(TABLE3_EVAL_LOC, mod(calldataload(add(data_ptr, 0x5a0)), p)) - mstore(TABLE4_EVAL_LOC, mod(calldataload(add(data_ptr, 0x5c0)), p)) - mstore(TABLE_TYPE_EVAL_LOC, mod(calldataload(add(data_ptr, 0x5e0)), p)) + mstore(TABLE1_EVAL_LOC, mod(calldataload(add(data_ptr, 0x580)), p)) + mstore(TABLE2_EVAL_LOC, mod(calldataload(add(data_ptr, 0x5a0)), p)) + mstore(TABLE3_EVAL_LOC, mod(calldataload(add(data_ptr, 0x5c0)), p)) + mstore(TABLE4_EVAL_LOC, mod(calldataload(add(data_ptr, 0x5e0)), p)) + mstore(TABLE_TYPE_EVAL_LOC, mod(calldataload(add(data_ptr, 0x600)), p)) - mstore(ID1_EVAL_LOC, mod(calldataload(add(data_ptr, 0x600)), p)) - mstore(ID2_EVAL_LOC, mod(calldataload(add(data_ptr, 0x620)), p)) - mstore(ID3_EVAL_LOC, mod(calldataload(add(data_ptr, 0x640)), p)) - mstore(ID4_EVAL_LOC, mod(calldataload(add(data_ptr, 0x660)), p)) + mstore(ID1_EVAL_LOC, mod(calldataload(add(data_ptr, 0x620)), p)) + mstore(ID2_EVAL_LOC, mod(calldataload(add(data_ptr, 0x640)), p)) + mstore(ID3_EVAL_LOC, mod(calldataload(add(data_ptr, 0x660)), p)) + mstore(ID4_EVAL_LOC, mod(calldataload(add(data_ptr, 0x680)), p)) - mstore(W1_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x680)), p)) - mstore(W2_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x6a0)), p)) - mstore(W3_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x6c0)), p)) - mstore(W4_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x6e0)), p)) - mstore(S_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x700)), p)) + mstore(W1_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x6a0)), p)) + mstore(W2_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x6c0)), p)) + mstore(W3_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x6e0)), p)) + mstore(W4_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x700)), p)) + mstore(S_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x720)), p)) - mstore(Z_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x720)), p)) + mstore(Z_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x740)), p)) - mstore(Z_LOOKUP_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x740)), p)) - mstore(TABLE1_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x760)), p)) - mstore(TABLE2_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x780)), p)) - mstore(TABLE3_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x7a0)), p)) - mstore(TABLE4_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x7c0)), p)) + mstore(Z_LOOKUP_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x760)), p)) + mstore(TABLE1_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x780)), p)) + mstore(TABLE2_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x7a0)), p)) + mstore(TABLE3_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x7c0)), p)) + mstore(TABLE4_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x7e0)), p)) - mstore(PI_Z_Y_LOC, mod(calldataload(add(data_ptr, 0x7e0)), q)) - mstore(PI_Z_X_LOC, mod(calldataload(add(data_ptr, 0x800)), q)) + mstore(PI_Z_Y_LOC, mod(calldataload(add(data_ptr, 0x800)), q)) + mstore(PI_Z_X_LOC, mod(calldataload(add(data_ptr, 0x820)), q)) - mstore(PI_Z_OMEGA_Y_LOC, mod(calldataload(add(data_ptr, 0x820)), q)) - mstore(PI_Z_OMEGA_X_LOC, mod(calldataload(add(data_ptr, 0x840)), q)) + mstore(PI_Z_OMEGA_Y_LOC, mod(calldataload(add(data_ptr, 0x840)), q)) + mstore(PI_Z_OMEGA_X_LOC, mod(calldataload(add(data_ptr, 0x860)), q)) } /** @@ -509,6 +517,7 @@ abstract contract BaseUltraVerifier { challenge := keccak256(0x00, 0xa0) mstore(C_ALPHA_LOC, mod(challenge, p)) + /** * Compute and store some powers of alpha for future computations */ @@ -537,6 +546,7 @@ abstract contract BaseUltraVerifier { mstore(C_CURRENT_LOC, challenge) } + /** * EVALUATE FIELD OPERATIONS */ @@ -1245,8 +1255,64 @@ abstract contract BaseUltraVerifier { // ELLIPTIC_IDENTITY = (x_identity + y_identity) * Q_ELLIPTIC_EVAL mstore(ELLIPTIC_IDENTITY, mulmod(addmod(x_identity, y_identity, p), mload(QELLIPTIC_EVAL_LOC), p)) + + /** + * x_pow_4 = (y_1_sqr - curve_b) * x_1; + * y_1_sqr_mul_4 = y_1_sqr + y_1_sqr; + * y_1_sqr_mul_4 += y_1_sqr_mul_4; + * x_1_pow_4_mul_9 = x_pow_4; + * x_1_pow_4_mul_9 += x_1_pow_4_mul_9; + * x_1_pow_4_mul_9 += x_1_pow_4_mul_9; + * x_1_pow_4_mul_9 += x_1_pow_4_mul_9; + * x_1_pow_4_mul_9 += x_pow_4; + * x_1_sqr_mul_3 = x_1_sqr + x_1_sqr + x_1_sqr; + * x_double_identity = (x_3 + x_1 + x_1) * y_1_sqr_mul_4 - x_1_pow_4_mul_9; + * y_double_identity = x_1_sqr_mul_3 * (x_1 - x_3) - (y_1 + y_1) * (y_1 + y_3); + */ + { + let x1_sqr := mulmod(mload(X1_EVAL_LOC), mload(X1_EVAL_LOC), p) + let y1_sqr := mulmod(mload(Y1_EVAL_LOC), mload(Y1_EVAL_LOC), p) + let x_pow_4 := mulmod(addmod(y1_sqr, 17, p), mload(X1_EVAL_LOC), p) + let y1_sqr_mul_4 := mulmod(y1_sqr, 4, p) + let x1_pow_4_mul_9 := mulmod(x_pow_4, 9, p) + let x1_sqr_mul_3 := mulmod(x1_sqr, 3, p) + let x_double_identity := addmod( + mulmod(addmod(mload(X3_EVAL_LOC), addmod(mload(X1_EVAL_LOC), mload(X1_EVAL_LOC), p), p), y1_sqr_mul_4, p), + sub( + p, + x1_pow_4_mul_9 + ), + p + ) + let y_double_identity := addmod( + mulmod(x1_sqr_mul_3, addmod(mload(X1_EVAL_LOC), sub(p, mload(X3_EVAL_LOC)), p), p), + sub( + p, + mulmod( + addmod(mload(Y1_EVAL_LOC), mload(Y1_EVAL_LOC), p), + addmod(mload(Y1_EVAL_LOC), mload(Y3_EVAL_LOC), p), + p + ) + ), + p + ) + x_double_identity := + mulmod(x_double_identity, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_SQR_LOC), p), p) + y_double_identity := + mulmod(y_double_identity, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_CUBE_LOC), p), p) + + // ELLIPTIC_IDENTITY += (x_double_identity + y_double_identity) * Q_DOUBLE_EVAL + mstore( + ELLIPTIC_IDENTITY, + addmod( + mload(ELLIPTIC_IDENTITY), + mulmod(addmod(x_double_identity, y_double_identity, p), mload(QDOUBLE_EVAL_LOC), p), + p + ) + ) + } + // update alpha - // The paper says to use ALPHA^2, we use ALPHA^4 this is a small oversight in the prover protocol mstore(C_ALPHA_BASE_LOC, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_QUAD_LOC), p)) } @@ -1560,16 +1626,16 @@ abstract contract BaseUltraVerifier { addmod( addmod( addmod( - addmod(mload(PERMUTATION_IDENTITY), mload(PLOOKUP_IDENTITY), p), - mload(ARITHMETIC_IDENTITY), + addmod(mload(PERMUTATION_IDENTITY), mload(PLOOKUP_IDENTITY), p), + mload(ARITHMETIC_IDENTITY), + p + ), + mload(SORT_IDENTITY), p ), - mload(SORT_IDENTITY), + mload(ELLIPTIC_IDENTITY), p ), - mload(ELLIPTIC_IDENTITY), - p - ), mload(AUX_IDENTITY), p ), @@ -1658,8 +1724,7 @@ abstract contract BaseUltraVerifier { mstore8(0x20, 0x1d) mstore(C_V29_LOC, mod(keccak256(0x00, 0x21), p)) - // @follow-up - Why are both v29 and v30 using appending 0x1d to the prior challenge and hashing, should it not change? - mstore8(0x20, 0x1d) + mstore8(0x20, 0x1e) challenge := keccak256(0x00, 0x21) mstore(C_V30_LOC, mod(challenge, p)) @@ -1988,6 +2053,22 @@ abstract contract BaseUltraVerifier { // accumulator = accumulator + accumulator_2 success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + // VALIDATE QDOUBLE + { + let x := mload(QDOUBLE_X_LOC) + let y := mload(QDOUBLE_Y_LOC) + let xx := mulmod(x, x, q) + // validate on curve + success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))) + mstore(0x00, x) + mstore(0x20, y) + } + mstore(0x40, mload(C_V30_LOC)) + // accumulator_2 = v30.[DOUBLE] + success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40)) + // accumulator = accumulator + accumulator_2 + success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40)) + // VALIDATE QAUX { let x := mload(QAUX_X_LOC) @@ -2302,6 +2383,7 @@ abstract contract BaseUltraVerifier { * batch_evaluation += v13 * QARITH_EVAL * batch_evaluation += v14 * QSORT_EVAL_LOC * batch_evaluation += v15 * QELLIPTIC_EVAL_LOC + * batch_evaluation += v30 * QDOUBLE_EVAL_LOC * batch_evaluation += v16 * QAUX_EVAL_LOC * batch_evaluation += v17 * SIGMA1_EVAL_LOC * batch_evaluation += v18 * SIGMA2_EVAL_LOC @@ -2317,6 +2399,7 @@ abstract contract BaseUltraVerifier { batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V13_LOC), mload(QARITH_EVAL_LOC), p), p) batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V14_LOC), mload(QSORT_EVAL_LOC), p), p) batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V15_LOC), mload(QELLIPTIC_EVAL_LOC), p), p) + batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V30_LOC), mload(QDOUBLE_EVAL_LOC), p), p) batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V16_LOC), mload(QAUX_EVAL_LOC), p), p) batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V17_LOC), mload(SIGMA1_EVAL_LOC), p), p) batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V18_LOC), mload(SIGMA2_EVAL_LOC), p), p) diff --git a/barretenberg/sol/src/ultra/instance/Add2UltraVerifier.sol b/barretenberg/sol/src/ultra/instance/Add2UltraVerifier.sol index 1bbaed721670..44894f12f1d8 100644 --- a/barretenberg/sol/src/ultra/instance/Add2UltraVerifier.sol +++ b/barretenberg/sol/src/ultra/instance/Add2UltraVerifier.sol @@ -11,6 +11,6 @@ contract Add2UltraVerifier is BASE { } function loadVerificationKey(uint256 vk, uint256 _omegaInverseLoc) internal pure virtual override(BASE) { - VK.loadVerificationKey(vk, _omegaInverseLoc); + VK.loadVerificationKey(vk, _omegaInverseLoc); } } diff --git a/barretenberg/sol/src/ultra/keys/Add2UltraVerificationKey.sol b/barretenberg/sol/src/ultra/keys/Add2UltraVerificationKey.sol index 67c3b6080a15..66dbd735faa4 100644 --- a/barretenberg/sol/src/ultra/keys/Add2UltraVerificationKey.sol +++ b/barretenberg/sol/src/ultra/keys/Add2UltraVerificationKey.sol @@ -1,72 +1,74 @@ -// Verification Key Hash: a0e940165bfc708013d5b4f7940f3b07f3bcf3c0f57ee21d8b4bdb78630817a3 +// Verification Key Hash: d90f2c2749f4fdd455b5de629173d4e988ef1014f55791c46685d7c20c2dce4d // SPDX-License-Identifier: Apache-2.0 // Copyright 2022 Aztec pragma solidity >=0.8.4; library Add2UltraVerificationKey { - function verificationKeyHash() internal pure returns (bytes32) { - return 0xa0e940165bfc708013d5b4f7940f3b07f3bcf3c0f57ee21d8b4bdb78630817a3; + function verificationKeyHash() internal pure returns(bytes32) { + return 0xd90f2c2749f4fdd455b5de629173d4e988ef1014f55791c46685d7c20c2dce4d; } function loadVerificationKey(uint256 _vk, uint256 _omegaInverseLoc) internal pure { assembly { - mstore(add(_vk, 0x00), 0x0000000000000000000000000000000000000000000000000000000000000010) // vk.circuit_size + mstore(add(_vk, 0x00), 0x0000000000000000000000000000000000000000000000000000000000008000) // vk.circuit_size mstore(add(_vk, 0x20), 0x0000000000000000000000000000000000000000000000000000000000000003) // vk.num_inputs - mstore(add(_vk, 0x40), 0x21082ca216cbbf4e1c6e4f4594dd508c996dfbe1174efb98b11509c6e306460b) // vk.work_root - mstore(add(_vk, 0x60), 0x2d5e098bb31e86271ccb415b196942d755b0a9c3f21dd9882fa3d63ab1000001) // vk.domain_inverse - mstore(add(_vk, 0x80), 0x0fe8527a8494f827e4b332060e5569bdfe47aadc475cb1f03b4d222b0804e463) // vk.Q1.x - mstore(add(_vk, 0xa0), 0x2d051f6d8a9eec7ae2622b4b259fb91d942a8892632cffcdad4c03e2c9081593) // vk.Q1.y - mstore(add(_vk, 0xc0), 0x21be04985f898ef5e2a80f32fbaa16cd3eb8c451c243db46144b97113c8e556a) // vk.Q2.x - mstore(add(_vk, 0xe0), 0x2913bcdde62d6d2143aa6a0fed511ca527994df2cba6a780baa29dddac161de9) // vk.Q2.y - mstore(add(_vk, 0x100), 0x15bf0818d578953a624a127aa04d4b0aa1b09d3fe69b9a29e2546a41e9b08049) // vk.Q3.x - mstore(add(_vk, 0x120), 0x0148f0d2abf2ca1fe6cc20fdef0a8d4a88eb9602eaf48f0c1c02445c27cb9592) // vk.Q3.y - mstore(add(_vk, 0x140), 0x02d6fd9e84dbe74b7531e1801405a1c292117b1a17fefe9de0bfd9edf1a84bf9) // vk.Q4.x - mstore(add(_vk, 0x160), 0x293c6ab3c06a0669af13393a82c60a459a3b2a0b768da45ac7af7f2aec40fc42) // vk.Q4.y - mstore(add(_vk, 0x180), 0x2950076760523510abcfe90fa550b964e84b338f73af5222cdbbaefdacd4484e) // vk.Q_M.x - mstore(add(_vk, 0x1a0), 0x2e4e3e272c7b78ad894559812d7766e05615a8f7050a43d7ed1367adf30a9319) // vk.Q_M.y - mstore(add(_vk, 0x1c0), 0x1798c37010a4285e1774c1ad35779886380ee5ceee0ba183927e2a2103301a68) // vk.Q_C.x - mstore(add(_vk, 0x1e0), 0x2935f9e4d47a8e39aa0107f31a84584b47d903cfeb9690f6d850dc8ea7d2f4ea) // vk.Q_C.y - mstore(add(_vk, 0x200), 0x205aff7186f2cedc99e9cadb7930ef25f296991e5a7b574a33d6249f0a5db1f9) // vk.Q_ARITHMETIC.x - mstore(add(_vk, 0x220), 0x0beadc757bee3a2be1f6425385547099fc1eeeb1fed5a8552b07e997251d7c45) // vk.Q_ARITHMETIC.y - mstore(add(_vk, 0x240), 0x2cbce7beee3076b78dace04943d69d0d9e28aa6d00e046852781a5f20816645c) // vk.QSORT.x - mstore(add(_vk, 0x260), 0x2bc27ec2e1612ea284b08bcc55b6f2fd915d11bfedbdc0e59de09e5b28952080) // vk.QSORT.y - mstore(add(_vk, 0x280), 0x0ad34b5e8db72a5acf4427546c7294be6ed4f4d252a79059e505f9abc1bdf3ed) // vk.Q_ELLIPTIC.x - mstore(add(_vk, 0x2a0), 0x1e5b26790a26eb340217dd9ad28dbf90a049f42a3852acd45e6f521f24b4900e) // vk.Q_ELLIPTIC.y - mstore(add(_vk, 0x2c0), 0x155a0f51fec78c33ffceb7364d69d7ac27e570ae50bc180509764eb3fef94815) // vk.Q_AUX.x - mstore(add(_vk, 0x2e0), 0x1c1c4720bed44a591d97cbc72b6e44b644999713a8d3c66e9054aa5726324c76) // vk.Q_AUX.y - mstore(add(_vk, 0x300), 0x01d8b8ff3b1674e57a7d30ce1d9e07c686174c643eb20d38e604eec7095248a9) // vk.SIGMA1.x - mstore(add(_vk, 0x320), 0x261015d69327a58810e6eb1052ed694914b7a89034e1334c50b9e70a161489b7) // vk.SIGMA1.y - mstore(add(_vk, 0x340), 0x1987df111730a8a6a650423757dbf048f3f43860a7d24a5e2e8bd67b6931ca67) // vk.SIGMA2.x - mstore(add(_vk, 0x360), 0x1fe074ff24b35d7830bec2a3fad7e53038ffb5e2a3f718a23660d68daffc2953) // vk.SIGMA2.y - mstore(add(_vk, 0x380), 0x191d6881b9369e50141da3f2009a2f2dfc9adba276e874eb9f7f3183a0ea8f89) // vk.SIGMA3.x - mstore(add(_vk, 0x3a0), 0x2cbfbdd75526be7e9f2830cb1fd99457227f90fb024902635e342344cb6b2926) // vk.SIGMA3.y - mstore(add(_vk, 0x3c0), 0x2e7fe658b8f1f34dc561568e4ef6c74bb36330404967952b1e15390c1e2443cf) // vk.SIGMA4.x - mstore(add(_vk, 0x3e0), 0x293a5337eedc88329f10aa45a11e4adbb77f74717345987d70ed726e3e4556f1) // vk.SIGMA4.y - mstore(add(_vk, 0x400), 0x02c397073c8abce6d4140c9b961209dd783bff1a1cfc999bb29859cfb16c46fc) // vk.TABLE1.x - mstore(add(_vk, 0x420), 0x2b7bba2d1efffce0d033f596b4d030750599be670db593af86e1923fe8a1bb18) // vk.TABLE1.y - mstore(add(_vk, 0x440), 0x2c71c58b66498f903b3bbbda3d05ce8ffb571a4b3cf83533f3f71b99a04f6e6b) // vk.TABLE2.x - mstore(add(_vk, 0x460), 0x039dce37f94d1bbd97ccea32a224fe2afaefbcbd080c84dcea90b54f4e0a858f) // vk.TABLE2.y - mstore(add(_vk, 0x480), 0x27dc44977efe6b3746a290706f4f7275783c73cfe56847d848fd93b63bf32083) // vk.TABLE3.x - mstore(add(_vk, 0x4a0), 0x0a5366266dd7b71a10b356030226a2de0cbf2edc8f085b16d73652b15eced8f5) // vk.TABLE3.y - mstore(add(_vk, 0x4c0), 0x136097d79e1b0ae373255e8760c49900a7588ec4d6809c90bb451005a3de3077) // vk.TABLE4.x - mstore(add(_vk, 0x4e0), 0x13dd7515ccac4095302d204f06f0bff2595d77bdf72e4acdb0b0b43969860d98) // vk.TABLE4.y - mstore(add(_vk, 0x500), 0x16ff3501369121d410b445929239ba057fe211dad1b706e49a3b55920fac20ec) // vk.TABLE_TYPE.x - mstore(add(_vk, 0x520), 0x1e190987ebd9cf480f608b82134a00eb8007673c1ed10b834a695adf0068522a) // vk.TABLE_TYPE.y - mstore(add(_vk, 0x540), 0x0baaf073a203ba4ba0093c827bb5b3f7a55611765f111ecf80c456f631e99f29) // vk.ID1.x - mstore(add(_vk, 0x560), 0x27cd34cafd5735ec970278202765e0f1e9da3494b30b948ebce3414d078cef9e) // vk.ID1.y - mstore(add(_vk, 0x580), 0x0868357b28039385c5a5058b6d358ebb29f26f9890d6cc6401f4921d5884edca) // vk.ID2.x - mstore(add(_vk, 0x5a0), 0x1060afe929554ca473103f5e68193c36fb6e229dde8edf7ec858b12d7e8be485) // vk.ID2.y - mstore(add(_vk, 0x5c0), 0x0b1c02619282755533457230b19b4a15226e07e207744c0857074dcab883af4a) // vk.ID3.x - mstore(add(_vk, 0x5e0), 0x0d928deafed363659688ed4ccdef521f2a0277e4807e6e1cbabca21dde5eb5e1) // vk.ID3.y - mstore(add(_vk, 0x600), 0x2eea648c8732596b1314fe2a4d2f05363f0c994e91cecad25835338edee2294f) // vk.ID4.x - mstore(add(_vk, 0x620), 0x0ab49886c2b94bd0bd3f6ed1dbbe2cb2671d2ae51d31c1210433c3972bb64578) // vk.ID4.y - mstore(add(_vk, 0x640), 0x00) // vk.contains_recursive_proof - mstore(add(_vk, 0x660), 0) // vk.recursive_proof_public_input_indices - mstore(add(_vk, 0x680), 0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1) // vk.g2_x.X.c1 - mstore(add(_vk, 0x6a0), 0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0) // vk.g2_x.X.c0 - mstore(add(_vk, 0x6c0), 0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4) // vk.g2_x.Y.c1 - mstore(add(_vk, 0x6e0), 0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55) // vk.g2_x.Y.c0 - mstore(_omegaInverseLoc, 0x02e40daf409556c02bfc85eb303402b774954d30aeb0337eb85a71e6373428de) // vk.work_root_inverse + mstore(add(_vk, 0x40), 0x2d1ba66f5941dc91017171fa69ec2bd0022a2a2d4115a009a93458fd4e26ecfb) // vk.work_root + mstore(add(_vk, 0x60), 0x3063edaa444bddc677fcd515f614555a777997e0a9287d1e62bf6dd004d82001) // vk.domain_inverse + mstore(add(_vk, 0x80), 0x19964a2aa3b4b8e20d7a9d5ba1b29f5f00a1bdaed5cb382214f985d511cde966) // vk.Q1.x + mstore(add(_vk, 0xa0), 0x07b3eb155199738946625f996c8644a1b886b165034efc37ed491f953a575c95) // vk.Q1.y + mstore(add(_vk, 0xc0), 0x1e659c2178430c0b5ca7e15312612877aab3afcb8aef7a31fa45a88448ac4e36) // vk.Q2.x + mstore(add(_vk, 0xe0), 0x09187841f0ecfd2c93050a6c77e52e70e4f434359af7707567efe1a0e3c294bd) // vk.Q2.y + mstore(add(_vk, 0x100), 0x2c6da8b9ae520e7bfca581567fb4047063c4216551d9c5e19c2fb9601257158b) // vk.Q3.x + mstore(add(_vk, 0x120), 0x08ed376ef123ee394fc1ec3a1398504c6863622a409e1852a0c74ec3848dd6a4) // vk.Q3.y + mstore(add(_vk, 0x140), 0x22149a3f2b0c6c3aa79cccd27d5e1478caa30a3284fcff5b608166376f7ead19) // vk.Q4.x + mstore(add(_vk, 0x160), 0x2cf4413c9a82c95b86dc43a3adb8fc13f4a5c89c57cbfd8cb6d9d1ec644427fa) // vk.Q4.y + mstore(add(_vk, 0x180), 0x1c8c2d38482dbc8ac03b6779351aa8b8090eb94a7246fb762f090288e345259f) // vk.Q_M.x + mstore(add(_vk, 0x1a0), 0x26a5b4e66d65adcd4d32772f1fd72c80e138246d937b6b469a7a581ef7332143) // vk.Q_M.y + mstore(add(_vk, 0x1c0), 0x298412b13e530cdd803334a61cea7bd02bf2c49bcfaf6bf4fd6d338912f0523a) // vk.Q_C.x + mstore(add(_vk, 0x1e0), 0x27a28ec73fe5604698ff0a0c305ed24df5b690b96b4ad63c2e7237c671e2dfd3) // vk.Q_C.y + mstore(add(_vk, 0x200), 0x0eb50f484810d47cceb02f10d633344275e35f0c2d9480b082055d40652aecab) // vk.Q_ARITHMETIC.x + mstore(add(_vk, 0x220), 0x2341c79c0f01797611c6643ce5570c9f9c266be32519a838c493df71e308a2ce) // vk.Q_ARITHMETIC.y + mstore(add(_vk, 0x240), 0x10a219cf9e905e742bae0656be9a85d6d8f80b3ed599bcbfe5adbad4a006af9b) // vk.QSORT.x + mstore(add(_vk, 0x260), 0x1c01cdc18c29e812f36e9f7c756b2e4ef2eaf57ad0bf85b77f006c76b4e2ecaa) // vk.QSORT.y + mstore(add(_vk, 0x280), 0x2747b8cf43664363022e5b49b9425c963e5879af56dbff9ca38f6b9fa904a3a1) // vk.Q_ELLIPTIC.x + mstore(add(_vk, 0x2a0), 0x12dca9b754022b254b20c956dc6e177e686fe9e20bf353b8dbfe52d577a4c3a8) // vk.Q_ELLIPTIC.y + mstore(add(_vk, 0x2c0), 0x1a719b95265beabb4896c0ba0ae2e2ba912740dcd1ff1241f3916dc0fa60064e) // vk.Q_AUX.x + mstore(add(_vk, 0x2e0), 0x00ac90b81b7bee3403927a2eac2701e416939060d440048d2f337e78c0e68bf4) // vk.Q_AUX.y + mstore(add(_vk, 0x300), 0x05b2e53e9332f5fa5cc6f70e700eafbb88533915cdeb4b21b46725f187c232a5) // vk.SIGMA1.x + mstore(add(_vk, 0x320), 0x0dcdffc63e3a964b3ac2d7303343caa1d3763c25379241c73e03ba4fce96c0fc) // vk.SIGMA1.y + mstore(add(_vk, 0x340), 0x0f77287038c2d1ba828980a47e3a6e120e8d8be0a69d292b7a24ba1657b5f3ab) // vk.SIGMA2.x + mstore(add(_vk, 0x360), 0x0942a13c634674c125ac043700df118c0597b7c41ed1e8b751f4aec41cbc889d) // vk.SIGMA2.y + mstore(add(_vk, 0x380), 0x1b6ae9ac874c985b7b84bc90a87dff5effa6440d9ebbbd516af8cf668d46c8fd) // vk.SIGMA3.x + mstore(add(_vk, 0x3a0), 0x17b77f03f7681d65ffe750405345ac2762c6bad1887f179b2e1f49b44b84c241) // vk.SIGMA3.y + mstore(add(_vk, 0x3c0), 0x0a87235ffd0e72f310c131e243c3d461c8f429b4cf603df3ec29a243b9822fe7) // vk.SIGMA4.x + mstore(add(_vk, 0x3e0), 0x111008ff8e1efe82bbbb3b804e51c6f52d86ffe0e16b7486cc415b74b1c6eb07) // vk.SIGMA4.y + mstore(add(_vk, 0x400), 0x0c54103c5076b566a2e980d8c88cf32cd21e2f3e27067015fcd8da5ca41bbc5a) // vk.TABLE1.x + mstore(add(_vk, 0x420), 0x0cc85a3f7ab203e6a42e9f568ad65441754463100016779caba6430ab4418e09) // vk.TABLE1.y + mstore(add(_vk, 0x440), 0x263b9debf1d5b4cf0f6594bf8077c216d615cd93ae366382b3e53fdbe01c807a) // vk.TABLE2.x + mstore(add(_vk, 0x460), 0x1c755eedad1d74a8f0fee65618c2b7866128711b124e8aa517733f5101e7164e) // vk.TABLE2.y + mstore(add(_vk, 0x480), 0x29dbe4b32baef1a697973b20572fd995f4ba1dd66c3742082537085c32f28198) // vk.TABLE3.x + mstore(add(_vk, 0x4a0), 0x1bf12379b84f99d8e569fd1469f135daa356619de016f4b2873bdf3719932689) // vk.TABLE3.y + mstore(add(_vk, 0x4c0), 0x1567642efca7cda9eeabeba1b7f9c27c66704c66a5e4b9a766fb5b443c75792a) // vk.TABLE4.x + mstore(add(_vk, 0x4e0), 0x3028c2a1ed5f96c016655807d31f65dbfa1b3e24e41fb318ae460c571e0169ee) // vk.TABLE4.y + mstore(add(_vk, 0x500), 0x2249efd3e087a4935aacf144ca161201732553d2138e7b9d2d0b89272ebc319b) // vk.TABLE_TYPE.x + mstore(add(_vk, 0x520), 0x0f83d243781edc8524a191439c256255328743ae787998353f9b4eb1e6831238) // vk.TABLE_TYPE.y + mstore(add(_vk, 0x540), 0x19589ca000385db80087b150331bca67eb660a8e247cde3e991a4899daf49b49) // vk.ID1.x + mstore(add(_vk, 0x560), 0x1217621a37951221252cc4e13a7de552aa1e8e59074648167f9f9994bcf73c16) // vk.ID1.y + mstore(add(_vk, 0x580), 0x064e12279e35e9eec5ee20ccb64f011ac151ab00a4189ab111c0d43a03ca7cc3) // vk.ID2.x + mstore(add(_vk, 0x5a0), 0x2b4ce353dceef2621f8b71ae66f18bb152f18a3b45a301e392582730a7ba046d) // vk.ID2.y + mstore(add(_vk, 0x5c0), 0x2867ba25a1dc623c215a68c4d1627ce3b7f38677c7afe59897a5b3bf8924fad3) // vk.ID3.x + mstore(add(_vk, 0x5e0), 0x18c204513ed264bd438a2607d1aea0655ee07287b31606e627a9a0784d6ae32a) // vk.ID3.y + mstore(add(_vk, 0x600), 0x1d093bd126a96053040bee955e413fce8d1e8d2cc4c06fa4876bbb4631c34fad) // vk.ID4.x + mstore(add(_vk, 0x620), 0x1e6622021f2fc8e69a1351b3a72b98ed1a319a7f9bac52b64d2637e9851ab1e1) // vk.ID4.y + mstore(add(_vk, 0x640), 0x11ab7a1cae7edaf3641b1cf729afb2e0396d4649a9acb2127a05df56df21109c) // vk.Q_DOUBLE.x + mstore(add(_vk, 0x660), 0x0a5d2af029b68401792de001554c7513585523a1458a7d8152262f0ff5beb57d) // vk.Q_DOUBLE.y + mstore(add(_vk, 0x680), 0x00) // vk.contains_recursive_proof + mstore(add(_vk, 0x6a0), 0) // vk.recursive_proof_public_input_indices + mstore(add(_vk, 0x6c0), 0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1) // vk.g2_x.X.c1 + mstore(add(_vk, 0x6e0), 0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0) // vk.g2_x.X.c0 + mstore(add(_vk, 0x700), 0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4) // vk.g2_x.Y.c1 + mstore(add(_vk, 0x720), 0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55) // vk.g2_x.Y.c0 + mstore(_omegaInverseLoc, 0x05d33766e4590b3722701b6f2fa43d0dc3f028424d384e68c92a742fb2dbc0b4) // vk.work_root_inverse } } } diff --git a/barretenberg/sol/src/ultra/keys/BlakeUltraVerificationKey.sol b/barretenberg/sol/src/ultra/keys/BlakeUltraVerificationKey.sol index 0b8676e4dabc..96d018e1b04b 100644 --- a/barretenberg/sol/src/ultra/keys/BlakeUltraVerificationKey.sol +++ b/barretenberg/sol/src/ultra/keys/BlakeUltraVerificationKey.sol @@ -1,11 +1,11 @@ -// Verification Key Hash: ab0e7eca8953a659e04b83b3e1eb0525036ab76b5c6c53b090c8e3e568df3912 +// Verification Key Hash: ca57fde5485ce695701f872463e619387c431887fe0722dac2c4d430570e6e26 // SPDX-License-Identifier: Apache-2.0 // Copyright 2022 Aztec pragma solidity >=0.8.4; library BlakeUltraVerificationKey { function verificationKeyHash() internal pure returns (bytes32) { - return 0xab0e7eca8953a659e04b83b3e1eb0525036ab76b5c6c53b090c8e3e568df3912; + return 0xca57fde5485ce695701f872463e619387c431887fe0722dac2c4d430570e6e26; } function loadVerificationKey(uint256 _vk, uint256 _omegaInverseLoc) internal pure { @@ -32,8 +32,8 @@ library BlakeUltraVerificationKey { mstore(add(_vk, 0x260), 0x083b2abe0a5c29769ba8f427e7440a3dcb1ffcd86cb1b106f0aa27b6903655ba) // vk.QSORT.y mstore(add(_vk, 0x280), 0x21959276775cd4749236c8bf773a9b2403cecb45fbf70e6439f73d75442e8850) // vk.Q_ELLIPTIC.x mstore(add(_vk, 0x2a0), 0x017714509f01d1a9ee7ebaf4d50745e33a14150b4fe9850a27e44de56d88cb14) // vk.Q_ELLIPTIC.y - mstore(add(_vk, 0x2c0), 0x2e76c4474fcb457db84fb273ccc10a4647a1a37444369f2f275bb74540f5e2d0) // vk.Q_AUX.x - mstore(add(_vk, 0x2e0), 0x209035caddd02a78acd0ed617a85d782533bd142c6cad8e3338f3142b919c3a4) // vk.Q_AUX.y + mstore(add(_vk, 0x2c0), 0x254c7c79f29e6f05184889d52a7c01375832d53ea8dd60b93162a5805d715657) // vk.Q_AUX.x + mstore(add(_vk, 0x2e0), 0x23558713233600d8847c983db3c2771210aad83fc39e33f4821c4b483fe579c1) // vk.Q_AUX.y mstore(add(_vk, 0x300), 0x12922936896c92f4773be96aa6eced49c9e6973d091baca38bcd2ce7c2432b13) // vk.SIGMA1.x mstore(add(_vk, 0x320), 0x0195e866ae7531344bc2cec037b002d99caace033bdbdf98b4db64b1e23be236) // vk.SIGMA1.y mstore(add(_vk, 0x340), 0x136128a1e6bc7bc733fcb9343fe23760d8d8a08d4ba4cdfc8970429696720a85) // vk.SIGMA2.x @@ -42,16 +42,16 @@ library BlakeUltraVerificationKey { mstore(add(_vk, 0x3a0), 0x1fd05a799d3dfaba1bfed3145b27e4768be0bc0893b24962de96fdbce7cdc319) // vk.SIGMA3.y mstore(add(_vk, 0x3c0), 0x07f75bc93d92e6dccd6ba833a23aa5d1ba7c36cd2e2d6c2e6406c62480e19119) // vk.SIGMA4.x mstore(add(_vk, 0x3e0), 0x253f74ab6ef1778beba646f245c7dcd5e60cdaebcc37d2c5db22caf03ee7091f) // vk.SIGMA4.y - mstore(add(_vk, 0x400), 0x06c5d3c2a64587cf9dc278c6892854fc8f1aba4183115224cb2eda4c1aab64b8) // vk.TABLE1.x - mstore(add(_vk, 0x420), 0x132622df9222e04fa9c4cf2895212a49556038d4fdc6d0d7a15b1067bb446efa) // vk.TABLE1.y - mstore(add(_vk, 0x440), 0x2dbc1ac72b2f0c530b3bdbef307395e6059f82ce9f3beea34ff6c3a04ca112bc) // vk.TABLE2.x - mstore(add(_vk, 0x460), 0x23e9676a2c36926b3e10b1102f06aa3a9828d1422ae9e6ea77203025cd18ada0) // vk.TABLE2.y - mstore(add(_vk, 0x480), 0x298b6eb4baf5c75d4542a2089226886cc3ef984af332cae76356af6da70820fe) // vk.TABLE3.x - mstore(add(_vk, 0x4a0), 0x1bb16a4d3b60d47e572e02fac8bf861df5ba5f96942054e0896c7d4d602dc5c7) // vk.TABLE3.y - mstore(add(_vk, 0x4c0), 0x1f5976fc145f0524228ca90c221a21228ff9be92d487b56890a39c3bc0d22bf2) // vk.TABLE4.x - mstore(add(_vk, 0x4e0), 0x0f43d83a0d9eb36476e05c8d1280df98ec46ce93ae238597a687a4937ebec6cc) // vk.TABLE4.y - mstore(add(_vk, 0x500), 0x0b140556df3e8e29980eeae95a724d3c06c830707ce655b6bee64acc9be9e9c2) // vk.TABLE_TYPE.x - mstore(add(_vk, 0x520), 0x04de5162de4a6bea5e1e3b1386d87d41adef6c98203f749c98d2c2113ba12e9b) // vk.TABLE_TYPE.y + mstore(add(_vk, 0x400), 0x0f3dcb999cb48a5beae9b04ac2ee6ab8343aa6500140a8e7e7d3242d0c0186cf) // vk.TABLE1.x + mstore(add(_vk, 0x420), 0x28d5f0853c03284d61a6662a4257440af83b63c3ccc70bd56f0c0fb05ec95810) // vk.TABLE1.y + mstore(add(_vk, 0x440), 0x0e67ccae1e8b91f5b59a1510439797e093af1b474bb648ee04bc413fb159e0d0) // vk.TABLE2.x + mstore(add(_vk, 0x460), 0x14020d9e9b599a32148fe99f97db41e3014ab6fb590ceeddfdfd24170dda49e9) // vk.TABLE2.y + mstore(add(_vk, 0x480), 0x263f02f9cbc363345bf8060eeeb570e69a0d3e6d9fb17f84c5e09ca376b3cc77) // vk.TABLE3.x + mstore(add(_vk, 0x4a0), 0x0782a8a5715cb585204554f60ef98c0396a3a76ab2690677e0e57025775dd2bf) // vk.TABLE3.y + mstore(add(_vk, 0x4c0), 0x1549e7c1ef44c78dfcd7cca90a6b027a8f34227fb0f1a564abeb802717d87531) // vk.TABLE4.x + mstore(add(_vk, 0x4e0), 0x30495d6bdd8c78ea48d6232378befeece39a98e4a128d3103c4b981a6ed9dbb0) // vk.TABLE4.y + mstore(add(_vk, 0x500), 0x2dd93d20fc170d4f909f06f3f3570d3e8ccb3e4279146fd56e11e14feeecd868) // vk.TABLE_TYPE.x + mstore(add(_vk, 0x520), 0x169c9735eca5175e1379ce58f5ebfe100214c0afae135b15ed148516fe806bfc) // vk.TABLE_TYPE.y mstore(add(_vk, 0x540), 0x2e9d323290bebf84302163b43af960fde161663907a5e344ab62e3d0db9dc2a4) // vk.ID1.x mstore(add(_vk, 0x560), 0x282cbb41af3a18746f880f35caf350a0e653cc9ff266380f9dad6c8145fc8532) // vk.ID1.y mstore(add(_vk, 0x580), 0x29c73bc4fb55d00bb6b91bff171aaa98e3ab1d64829603b29a5364e510f692d7) // vk.ID2.x @@ -60,12 +60,14 @@ library BlakeUltraVerificationKey { mstore(add(_vk, 0x5e0), 0x0e05422e3bc394ae55128d83ed0087f1d18810c951f4d03b2f0eff6d5b2e74a2) // vk.ID3.y mstore(add(_vk, 0x600), 0x1b21ff32cadfbe3b43171ee3d0b14d1eed1c29e3719320d3e61f0e71c6aaf6d8) // vk.ID4.x mstore(add(_vk, 0x620), 0x04f57e846a88c4a0254841cf7b6226e878e7a4ea49c34c3732870f1d8c4f6c18) // vk.ID4.y - mstore(add(_vk, 0x640), 0x00) // vk.contains_recursive_proof - mstore(add(_vk, 0x660), 0) // vk.recursive_proof_public_input_indices - mstore(add(_vk, 0x680), 0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1) // vk.g2_x.X.c1 - mstore(add(_vk, 0x6a0), 0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0) // vk.g2_x.X.c0 - mstore(add(_vk, 0x6c0), 0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4) // vk.g2_x.Y.c1 - mstore(add(_vk, 0x6e0), 0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55) // vk.g2_x.Y.c0 + mstore(add(_vk, 0x640), 0x2e76c4474fcb457db84fb273ccc10a4647a1a37444369f2f275bb74540f5e2d0) // vk.Q_DOUBLE.x + mstore(add(_vk, 0x660), 0x209035caddd02a78acd0ed617a85d782533bd142c6cad8e3338f3142b919c3a4) // vk.Q_DOUBLE.y + mstore(add(_vk, 0x680), 0x00) // vk.contains_recursive_proof + mstore(add(_vk, 0x6a0), 0) // vk.recursive_proof_public_input_indices + mstore(add(_vk, 0x6c0), 0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1) // vk.g2_x.X.c1 + mstore(add(_vk, 0x6e0), 0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0) // vk.g2_x.X.c0 + mstore(add(_vk, 0x700), 0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4) // vk.g2_x.Y.c1 + mstore(add(_vk, 0x720), 0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55) // vk.g2_x.Y.c0 mstore(_omegaInverseLoc, 0x05d33766e4590b3722701b6f2fa43d0dc3f028424d384e68c92a742fb2dbc0b4) // vk.work_root_inverse } } diff --git a/barretenberg/sol/src/ultra/keys/RecursiveUltraVerificationKey.sol b/barretenberg/sol/src/ultra/keys/RecursiveUltraVerificationKey.sol index 748d20fcb909..eb7ba745bc1d 100644 --- a/barretenberg/sol/src/ultra/keys/RecursiveUltraVerificationKey.sol +++ b/barretenberg/sol/src/ultra/keys/RecursiveUltraVerificationKey.sol @@ -1,11 +1,11 @@ -// Verification Key Hash: b665bc769f274feb94ea7f9997fa684b414aa8b9b9bac0227c7ce2e1cbd3d115 +// Verification Key Hash: a8dabfb148c9d3399b50af1e3d715ffa30d3639eb93f140486f66fe2cc7656a2 // SPDX-License-Identifier: Apache-2.0 // Copyright 2022 Aztec pragma solidity >=0.8.4; library RecursiveUltraVerificationKey { function verificationKeyHash() internal pure returns (bytes32) { - return 0xb665bc769f274feb94ea7f9997fa684b414aa8b9b9bac0227c7ce2e1cbd3d115; + return 0xa8dabfb148c9d3399b50af1e3d715ffa30d3639eb93f140486f66fe2cc7656a2; } function loadVerificationKey(uint256 _vk, uint256 _omegaInverseLoc) internal pure { @@ -14,58 +14,60 @@ library RecursiveUltraVerificationKey { mstore(add(_vk, 0x20), 0x0000000000000000000000000000000000000000000000000000000000000010) // vk.num_inputs mstore(add(_vk, 0x40), 0x19ddbcaf3a8d46c15c0176fbb5b95e4dc57088ff13f4d1bd84c6bfa57dcdc0e0) // vk.work_root mstore(add(_vk, 0x60), 0x30644259cd94e7dd5045d7a27013b7fcd21c9e3b7fa75222e7bda49b729b0401) // vk.domain_inverse - mstore(add(_vk, 0x80), 0x16f7fc6133c8fb2dab06c57392df697a53357ecd918d749d1c981dcd0ee6d849) // vk.Q1.x - mstore(add(_vk, 0xa0), 0x2ba047103f9f86b84058d718a082e2faa53e50109e7cb880d2cbb7a1bf98da89) // vk.Q1.y - mstore(add(_vk, 0xc0), 0x1b9d146737dbb7759e0cad93ad4a7669880a062aceb7b46b8485327976d7285c) // vk.Q2.x - mstore(add(_vk, 0xe0), 0x11de7c3d638acc90e7f844c08658d0588da864268e00576d26aaca3cf49af350) // vk.Q2.y - mstore(add(_vk, 0x100), 0x1466840d8ad2dfde3a55d4c98412a05807bbe8aac33c27ba100c1e621fbebba0) // vk.Q3.x - mstore(add(_vk, 0x120), 0x2198ce44955b8ac6e21ddcbb66acd9df7596ad9e5fcf22f2227e8bbb51fe44ee) // vk.Q3.y - mstore(add(_vk, 0x140), 0x18b96a49db3644e2986f811b8c104e8eb88aa5eb9aec0ca109322a64885688bd) // vk.Q4.x - mstore(add(_vk, 0x160), 0x2ffec963826849cabd279a2b9f9a26f81518eb65d882f47a32470fc52f53def0) // vk.Q4.y - mstore(add(_vk, 0x180), 0x09dd725897471fddc177b241d7abc402705acfa452707388fa62666ad454598c) // vk.Q_M.x - mstore(add(_vk, 0x1a0), 0x03a46eb7ed69136e109e2761fb707da7cee18b3d05e581f24d77853b3b03581e) // vk.Q_M.y - mstore(add(_vk, 0x1c0), 0x304db51670cb2c59e3088431803e82bce8c81b38eefa267871ae2103ca7842ca) // vk.Q_C.x - mstore(add(_vk, 0x1e0), 0x1d7ec7d8d4a74e337de26b7adaecb8beb03d8cd647aa180bc08de840038710d5) // vk.Q_C.y - mstore(add(_vk, 0x200), 0x1db65122bf0f0a58fe07bd7342d3e26b07923041cb7d2158d13fb7b5328da40e) // vk.Q_ARITHMETIC.x - mstore(add(_vk, 0x220), 0x1691db1eeedbcb4f7646959cf363c00b7e26812a225edf5a6972d815270770f5) // vk.Q_ARITHMETIC.y - mstore(add(_vk, 0x240), 0x2a63b6a306e30d87f4b8597cbd1dcecff5fc7cacb774247fca6531e3d347ada4) // vk.QSORT.x - mstore(add(_vk, 0x260), 0x2849d2901fcd1f048924fb77e9451ad45d80f9f842418146b1fde0a7c752fc5f) // vk.QSORT.y - mstore(add(_vk, 0x280), 0x0e42866979ddac27ac729352dd0f844da4fb5a1c3e2480b5b940acd12304c700) // vk.Q_ELLIPTIC.x - mstore(add(_vk, 0x2a0), 0x017ac9a40547e866bdb914dc2b73661c0ec8aa67956c8c9bf406795f75e15c53) // vk.Q_ELLIPTIC.y - mstore(add(_vk, 0x2c0), 0x1ad08199bf79952adff0aa3a9c04a26f18ad7deed1fbed0548f2c83ddf913ef9) // vk.Q_AUX.x - mstore(add(_vk, 0x2e0), 0x151df9277b110c615c058f7f783105d03cab938f23884afed1897d0049715d21) // vk.Q_AUX.y - mstore(add(_vk, 0x300), 0x0bd26d62138b721fdc08fd7d52cd3dfaa37399eb416af0ec6237f9ec1a63a5c0) // vk.SIGMA1.x - mstore(add(_vk, 0x320), 0x103282cd2ef4210ac390d70a1cba58c6792a5d872ae0337615f8ac9997d300ef) // vk.SIGMA1.y - mstore(add(_vk, 0x340), 0x08abaa91c69ffa73d80d9a9562020c2a104771f07cf4099cbbe9a0071befb1cc) // vk.SIGMA2.x - mstore(add(_vk, 0x360), 0x1a82e5cd4a2c3de77afb2ca76c89b54991a4db3939a5c24806af01a0f69a2366) // vk.SIGMA2.y - mstore(add(_vk, 0x380), 0x26d50e2d19c429d1a2987d5249b88e388f93339fc05f52939fa2e1f4be653918) // vk.SIGMA3.x - mstore(add(_vk, 0x3a0), 0x0a49cd57e79633ea43cc3172e819327ce260682d8b571d0964678a153c17e959) // vk.SIGMA3.y - mstore(add(_vk, 0x3c0), 0x1c82f3e7c57b08ef90fda6fe39427b815a835c8559b64eac0a4b213998f6802c) // vk.SIGMA4.x - mstore(add(_vk, 0x3e0), 0x098bad014a270b6f5e4c90cbd299c15c5fd190457f0e78a5f849243e86688868) // vk.SIGMA4.y - mstore(add(_vk, 0x400), 0x215a055ec0bf7d7ab5e005b4260258aaadfd8ae9005a09060fdd0cee02dc3fea) // vk.TABLE1.x - mstore(add(_vk, 0x420), 0x1841eba177a34b1eb908727fe2e54bf33fc82b6e58dfd044acd4ba05ca80c837) // vk.TABLE1.y - mstore(add(_vk, 0x440), 0x018eb037682044ebf9cad76f777bf379b94c4d31d4351ce9677ff146a744555c) // vk.TABLE2.x - mstore(add(_vk, 0x460), 0x2bf87d72f0aef257c728503c900516f9274ab06eb54804651218438e40f06c25) // vk.TABLE2.y - mstore(add(_vk, 0x480), 0x13b003b384fb50e00994bf62a0057f44344be47383d59a7e9f1319d710ab5263) // vk.TABLE3.x - mstore(add(_vk, 0x4a0), 0x1a5f338a3d05fb46ea46855e6c36dbdb23c5f20a56acc795324fe2958189ec39) // vk.TABLE3.y - mstore(add(_vk, 0x4c0), 0x1365fd683dbad2c4c55b02dd33c4b96fde00e5bb3f52be20ead95484e130aee1) // vk.TABLE4.x - mstore(add(_vk, 0x4e0), 0x2da2ba1d27548e452cc863758acf156eb268f577b7d08ba58e7bbf2d28f6f23c) // vk.TABLE4.y - mstore(add(_vk, 0x500), 0x0ef908712f03ce2e4db3ef557abbde7c584d8c831165ba40ab43124526c53cc1) // vk.TABLE_TYPE.x - mstore(add(_vk, 0x520), 0x009dd642bc5eb1869048b59d2052645208cc5a14537814568d9c985c93319e55) // vk.TABLE_TYPE.y - mstore(add(_vk, 0x540), 0x0f973c9af1150675ae6dac1ea8ea366e5b8db13bb9c2237ab11c40dfb644ebf5) // vk.ID1.x - mstore(add(_vk, 0x560), 0x06b0c966f9edab490ac15a176d35d56996cc66854268197989a53ab0d1368188) // vk.ID1.y - mstore(add(_vk, 0x580), 0x09e719130bb46416efa070d08d82cc07fe0ed3bd8685616b92b4b9619e0807b2) // vk.ID2.x - mstore(add(_vk, 0x5a0), 0x18f35ee01438dda2443da27299404d09ccfff098a0ceac2e9a10bf2a96bc11ac) // vk.ID2.y - mstore(add(_vk, 0x5c0), 0x0cb835c737d324b9ff5bba45988dc4921104803b7e37649f8c628f0de26361ac) // vk.ID3.x - mstore(add(_vk, 0x5e0), 0x18ca0ac87859387aa32c6939f7a4a0d322879a3fdb1ef85d06addcddc13acea5) // vk.ID3.y - mstore(add(_vk, 0x600), 0x0047304b09efd9315a96d9e802c9a50c1964076026e5f17aff825d6cfc38d823) // vk.ID4.x - mstore(add(_vk, 0x620), 0x21c9f3aa4cbe8ee21422052f7c22d3d8a5a9a89c262a5a5cb52d8802f6106c49) // vk.ID4.y - mstore(add(_vk, 0x640), 0x01) // vk.contains_recursive_proof - mstore(add(_vk, 0x660), 0) // vk.recursive_proof_public_input_indices - mstore(add(_vk, 0x680), 0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1) // vk.g2_x.X.c1 - mstore(add(_vk, 0x6a0), 0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0) // vk.g2_x.X.c0 - mstore(add(_vk, 0x6c0), 0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4) // vk.g2_x.Y.c1 - mstore(add(_vk, 0x6e0), 0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55) // vk.g2_x.Y.c0 + mstore(add(_vk, 0x80), 0x2f2c90833604bd86de6481e803333729ec1dcd596a71739edefefee57817e992) // vk.Q1.x + mstore(add(_vk, 0xa0), 0x0ad2a1eb5e5a57a55048f2c60217216fa4e2422ec1f9b850e8a07ffe331d1b81) // vk.Q1.y + mstore(add(_vk, 0xc0), 0x2c70e5eee73ca1969c8512a2d84885a2bb0b890adb96f3a850ff7cbcb9a65b9c) // vk.Q2.x + mstore(add(_vk, 0xe0), 0x24c771c3028ebd2c07965a66e94078f65498303131c49a8e246ca2a078f10d60) // vk.Q2.y + mstore(add(_vk, 0x100), 0x105065ec980ad5ee684500b464f64c95958de691d9332cc6bdfb747a5bd1093d) // vk.Q3.x + mstore(add(_vk, 0x120), 0x15495341b86f7b1445267dcb4ca76dfddd1bff4e90f7cb19fc8b80633d6dce00) // vk.Q3.y + mstore(add(_vk, 0x140), 0x02316424c80b59722a41ac1c5f1ede7c3b95ef191d3db1899722d49f99013fdc) // vk.Q4.x + mstore(add(_vk, 0x160), 0x1a4e9a425b6bc79f450751a518a2c02a5c86b685dc911b846f8dc121ee8f9558) // vk.Q4.y + mstore(add(_vk, 0x180), 0x1ceb4161d0d9a399024bc19a3fd1a184650dfe0ccb37469bf9f32310196bb594) // vk.Q_M.x + mstore(add(_vk, 0x1a0), 0x2d70e55f7265db59f12fe29a4b02b663a7cdba8c7f2d63591daa6c54c2392b6e) // vk.Q_M.y + mstore(add(_vk, 0x1c0), 0x0ba551c12d9c22d637af327fafa554770ce46cd3cf15084f238d5813ba6e05ca) // vk.Q_C.x + mstore(add(_vk, 0x1e0), 0x26525a633d3dd0565239e7db3b2f6a6d96817b57d102567b964097f63aada6c1) // vk.Q_C.y + mstore(add(_vk, 0x200), 0x2f837b8a968e1b6d665b92060f96595fa8aa2a675a6630eff1112b60a0ac19d7) // vk.Q_ARITHMETIC.x + mstore(add(_vk, 0x220), 0x0764fac48c1b543d7c058b38f17a0f95405ac630f9b4daa7fe3acb4facd37ed3) // vk.Q_ARITHMETIC.y + mstore(add(_vk, 0x240), 0x23c6a34548f5989e63ec5cdc25bb05a47b969d5e5b0b4ef0bc1b0607e383926a) // vk.QSORT.x + mstore(add(_vk, 0x260), 0x080512a33b05eeb174062cbb5ab4dd2478112f1432a6337e87f8c0a189032c6c) // vk.QSORT.y + mstore(add(_vk, 0x280), 0x14adaaacd19a459bf15d18c5fc6ee9be611be715beb12108fc6d260c2c235f10) // vk.Q_ELLIPTIC.x + mstore(add(_vk, 0x2a0), 0x22134c82ca56ad624b6eb6358a4f8ecefed559ddf2d9522283c1da573a64aa7d) // vk.Q_ELLIPTIC.y + mstore(add(_vk, 0x2c0), 0x1ad25cef7959702475e235ccfd0e9e87370806ba6dbdd7f981282d1eaa48a9c4) // vk.Q_AUX.x + mstore(add(_vk, 0x2e0), 0x2ec523372693163ac5ef50b7dfae09eb9827c55bb2019dd6651a1e7db083a7bd) // vk.Q_AUX.y + mstore(add(_vk, 0x300), 0x0942025470e1f8f9be686f24005bafbeb9b0a7398d2e649a18f46d4736d0d8e7) // vk.SIGMA1.x + mstore(add(_vk, 0x320), 0x1c8786222727ba12528582d42407d33b9d766a078531f6870a95bf0414c91246) // vk.SIGMA1.y + mstore(add(_vk, 0x340), 0x13f058f4907e7300adbcf7971e9b2392410c691fa231908b89dfe57a48f0db2f) // vk.SIGMA2.x + mstore(add(_vk, 0x360), 0x0db38268d9096842729cf21b9370e61bb9c33802e8b7c43f4b30d198a0f3137d) // vk.SIGMA2.y + mstore(add(_vk, 0x380), 0x16c43a0a7fef44604e6bb65fe5ae112806114c10a2aa120f1150b696df13fd08) // vk.SIGMA3.x + mstore(add(_vk, 0x3a0), 0x2148dc36391535837f567f330ad87224c119ebdfa1044cf8e7e0e692d2e9c1c0) // vk.SIGMA3.y + mstore(add(_vk, 0x3c0), 0x130781ec1dfc6e8cd089c440ea04c5716e51e44fd03efbdda5a0decf6bf01754) // vk.SIGMA4.x + mstore(add(_vk, 0x3e0), 0x2e5607f269c888b9a9063a173691580cc793f43a82ebe6b33666aa7946bfba3c) // vk.SIGMA4.y + mstore(add(_vk, 0x400), 0x216ef2bf7bed0508c8d7ca99559246fb7265065fc21f16e69c1891d794c0e698) // vk.TABLE1.x + mstore(add(_vk, 0x420), 0x0e9565ad0eb5038d5cf58c9716d54067c4a73dbcf2e2eab2228735629bc64fb6) // vk.TABLE1.y + mstore(add(_vk, 0x440), 0x17652847af0b05a5776d27d831050ecd25c31bac7eb6ba3d832805b8dd05bd02) // vk.TABLE2.x + mstore(add(_vk, 0x460), 0x230ef10004f842fe992118e4d3c0d8e14bc9d57d5a4d63b7d9ff584cf2a968fe) // vk.TABLE2.y + mstore(add(_vk, 0x480), 0x11faa2e6cc341451219a77298be335966fcc01031221370fd59ec6fcf7ac719f) // vk.TABLE3.x + mstore(add(_vk, 0x4a0), 0x2146fa1eb5f133c4aa8598fa0c15c1886c6b2fd38c48a91b9a1238f18036734e) // vk.TABLE3.y + mstore(add(_vk, 0x4c0), 0x1022741f154d1d684bf4a3afc11ca74b23ab44557965943286d639e1a3fc9193) // vk.TABLE4.x + mstore(add(_vk, 0x4e0), 0x03a46a44158452a0558742da4a669e2c3c32e95fbfc159cbe9ed7dc7f92e16fe) // vk.TABLE4.y + mstore(add(_vk, 0x500), 0x23d4017903bdf2fee87100a78d994d994e6132134491138fd1db85c1431274a4) // vk.TABLE_TYPE.x + mstore(add(_vk, 0x520), 0x06318fd022ba9b51b046df289ee7d0d3e41460a6c919827b162c24209e791007) // vk.TABLE_TYPE.y + mstore(add(_vk, 0x540), 0x18e8c95df03c5789b033ca41f72a7c223aa5a7f125b133a9c992c484c8e51784) // vk.ID1.x + mstore(add(_vk, 0x560), 0x29671ef8ebc5cb6a7abae8ec76abc3dfabfe9d1cc149e5508481d739178cf6c6) // vk.ID1.y + mstore(add(_vk, 0x580), 0x2d548b87e1a1c2cb5687893a02280ad06c9c902f97471933f49fbf68a0e85ad4) // vk.ID2.x + mstore(add(_vk, 0x5a0), 0x1e5d9e43ce7a58507868502a0afd7ff9a3a7a842624e65c2fb5194bcfbd024b9) // vk.ID2.y + mstore(add(_vk, 0x5c0), 0x25bbe61f5f0e476d00e7a19c346bb5e2e51b3193aa46b97f641167ce31140323) // vk.ID3.x + mstore(add(_vk, 0x5e0), 0x2a32688b64a54dc6a77c5dce2ad76b916a1b50dc18c8cb9df95a8d91e8b9df0a) // vk.ID3.y + mstore(add(_vk, 0x600), 0x2ad02e4af57c8f6528ff199b2da2f393a7a34cfcdd5ce2bf9b2939525d35e2d1) // vk.ID4.x + mstore(add(_vk, 0x620), 0x16be74261bfb7a4490c65163f121103f5fcee2d8f259722ea1e76f96007eb0e6) // vk.ID4.y + mstore(add(_vk, 0x640), 0x286b5e87c07e6bfb9f1b4dd9b2758f6abbe43245a0e9e8e6a81778ffec9f3edb) // vk.Q_DOUBLE.x + mstore(add(_vk, 0x660), 0x2afe03cafd4700d14adecb1f54be2e983f0ee45d675e388cef839bba868ea2b2) // vk.Q_DOUBLE.y + mstore(add(_vk, 0x680), 0x01) // vk.contains_recursive_proof + mstore(add(_vk, 0x6a0), 0) // vk.recursive_proof_public_input_indices + mstore(add(_vk, 0x6c0), 0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1) // vk.g2_x.X.c1 + mstore(add(_vk, 0x6e0), 0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0) // vk.g2_x.X.c0 + mstore(add(_vk, 0x700), 0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4) // vk.g2_x.Y.c1 + mstore(add(_vk, 0x720), 0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55) // vk.g2_x.Y.c0 mstore(_omegaInverseLoc, 0x036853f083780e87f8d7c71d111119c57dbe118c22d5ad707a82317466c5174c) // vk.work_root_inverse } } From b5af4af562542ac91e1bf2d46b4ea65edd52ea31 Mon Sep 17 00:00:00 2001 From: zac-williamson Date: Sun, 1 Oct 2023 22:54:01 +0000 Subject: [PATCH 03/15] added doubling gate into honk flavor --- .../barretenberg/honk/flavor/goblin_ultra.hpp | 177 +++++++++-------- .../honk/flavor/goblin_ultra_recursive.hpp | 178 ++++++++++-------- .../src/barretenberg/honk/flavor/ultra.hpp | 119 ++++++------ .../honk/flavor/ultra_grumpkin.hpp | 119 ++++++------ .../honk/flavor/ultra_recursive.hpp | 120 ++++++------ .../honk/instance/prover_instance.cpp | 2 + .../honk/sumcheck/sumcheck.test.cpp | 69 +++---- .../ecc_vm/ecc_transcript_relation.hpp | 2 +- .../relations/elliptic_relation.hpp | 80 +++++++- 9 files changed, 505 insertions(+), 361 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/honk/flavor/goblin_ultra.hpp b/barretenberg/cpp/src/barretenberg/honk/flavor/goblin_ultra.hpp index 006bba75d6e5..2122006ee7c7 100644 --- a/barretenberg/cpp/src/barretenberg/honk/flavor/goblin_ultra.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/flavor/goblin_ultra.hpp @@ -32,10 +32,10 @@ class GoblinUltra { // The number of multivariate polynomials on which a sumcheck prover sumcheck operates (including shifts). We often // need containers of this size to hold related data, so we choose a name more agnostic than `NUM_POLYNOMIALS`. // Note: this number does not include the individual sorted list polynomials. - static constexpr size_t NUM_ALL_ENTITIES = 48; // 43 (UH) + 4 op wires + 1 op wire "selector" + static constexpr size_t NUM_ALL_ENTITIES = 49; // 43 (UH) + 4 op wires + 1 op wire "selector" // The number of polynomials precomputed to describe a circuit and to aid a prover in constructing a satisfying // assignment of witnesses. We again choose a neutral name. - static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 26; // 25 (UH) + 1 op wire "selector" + static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 27; // 25 (UH) + 1 op wire "selector" // The total number of witness entities not including shifts. static constexpr size_t NUM_WITNESS_ENTITIES = 15; // 11 (UH) + 4 op wires @@ -82,29 +82,30 @@ class GoblinUltra { DataType& q_arith = std::get<6>(this->_data); DataType& q_sort = std::get<7>(this->_data); DataType& q_elliptic = std::get<8>(this->_data); - DataType& q_aux = std::get<9>(this->_data); - DataType& q_lookup = std::get<10>(this->_data); - DataType& sigma_1 = std::get<11>(this->_data); - DataType& sigma_2 = std::get<12>(this->_data); - DataType& sigma_3 = std::get<13>(this->_data); - DataType& sigma_4 = std::get<14>(this->_data); - DataType& id_1 = std::get<15>(this->_data); - DataType& id_2 = std::get<16>(this->_data); - DataType& id_3 = std::get<17>(this->_data); - DataType& id_4 = std::get<18>(this->_data); - DataType& table_1 = std::get<19>(this->_data); - DataType& table_2 = std::get<20>(this->_data); - DataType& table_3 = std::get<21>(this->_data); - DataType& table_4 = std::get<22>(this->_data); - DataType& lagrange_first = std::get<23>(this->_data); - DataType& lagrange_last = std::get<24>(this->_data); - DataType& lagrange_ecc_op = std::get<25>(this->_data); // indicator poly for ecc op gates + DataType& q_double = std::get<9>(this->_data); + DataType& q_aux = std::get<10>(this->_data); + DataType& q_lookup = std::get<11>(this->_data); + DataType& sigma_1 = std::get<12>(this->_data); + DataType& sigma_2 = std::get<13>(this->_data); + DataType& sigma_3 = std::get<14>(this->_data); + DataType& sigma_4 = std::get<15>(this->_data); + DataType& id_1 = std::get<16>(this->_data); + DataType& id_2 = std::get<17>(this->_data); + DataType& id_3 = std::get<18>(this->_data); + DataType& id_4 = std::get<19>(this->_data); + DataType& table_1 = std::get<20>(this->_data); + DataType& table_2 = std::get<21>(this->_data); + DataType& table_3 = std::get<22>(this->_data); + DataType& table_4 = std::get<23>(this->_data); + DataType& lagrange_first = std::get<24>(this->_data); + DataType& lagrange_last = std::get<25>(this->_data); + DataType& lagrange_ecc_op = std::get<26>(this->_data); // indicator poly for ecc op gates static constexpr CircuitType CIRCUIT_TYPE = CircuitBuilder::CIRCUIT_TYPE; std::vector get_selectors() override { - return { q_m, q_c, q_l, q_r, q_o, q_4, q_arith, q_sort, q_elliptic, q_aux, q_lookup }; + return { q_m, q_c, q_l, q_r, q_o, q_4, q_arith, q_sort, q_elliptic, q_double, q_aux, q_lookup }; }; std::vector get_sigma_polynomials() override { return { sigma_1, sigma_2, sigma_3, sigma_4 }; }; std::vector get_id_polynomials() override { return { id_1, id_2, id_3, id_4 }; }; @@ -165,45 +166,46 @@ class GoblinUltra { DataType& q_arith = std::get<6>(this->_data); DataType& q_sort = std::get<7>(this->_data); DataType& q_elliptic = std::get<8>(this->_data); - DataType& q_aux = std::get<9>(this->_data); - DataType& q_lookup = std::get<10>(this->_data); - DataType& sigma_1 = std::get<11>(this->_data); - DataType& sigma_2 = std::get<12>(this->_data); - DataType& sigma_3 = std::get<13>(this->_data); - DataType& sigma_4 = std::get<14>(this->_data); - DataType& id_1 = std::get<15>(this->_data); - DataType& id_2 = std::get<16>(this->_data); - DataType& id_3 = std::get<17>(this->_data); - DataType& id_4 = std::get<18>(this->_data); - DataType& table_1 = std::get<19>(this->_data); - DataType& table_2 = std::get<20>(this->_data); - DataType& table_3 = std::get<21>(this->_data); - DataType& table_4 = std::get<22>(this->_data); - DataType& lagrange_first = std::get<23>(this->_data); - DataType& lagrange_last = std::get<24>(this->_data); - DataType& lagrange_ecc_op = std::get<25>(this->_data); - DataType& w_l = std::get<26>(this->_data); - DataType& w_r = std::get<27>(this->_data); - DataType& w_o = std::get<28>(this->_data); - DataType& w_4 = std::get<29>(this->_data); - DataType& sorted_accum = std::get<30>(this->_data); - DataType& z_perm = std::get<31>(this->_data); - DataType& z_lookup = std::get<32>(this->_data); - DataType& ecc_op_wire_1 = std::get<33>(this->_data); - DataType& ecc_op_wire_2 = std::get<34>(this->_data); - DataType& ecc_op_wire_3 = std::get<35>(this->_data); - DataType& ecc_op_wire_4 = std::get<36>(this->_data); - DataType& table_1_shift = std::get<37>(this->_data); - DataType& table_2_shift = std::get<38>(this->_data); - DataType& table_3_shift = std::get<39>(this->_data); - DataType& table_4_shift = std::get<40>(this->_data); - DataType& w_l_shift = std::get<41>(this->_data); - DataType& w_r_shift = std::get<42>(this->_data); - DataType& w_o_shift = std::get<43>(this->_data); - DataType& w_4_shift = std::get<44>(this->_data); - DataType& sorted_accum_shift = std::get<45>(this->_data); - DataType& z_perm_shift = std::get<46>(this->_data); - DataType& z_lookup_shift = std::get<47>(this->_data); + DataType& q_double = std::get<9>(this->_data); + DataType& q_aux = std::get<10>(this->_data); + DataType& q_lookup = std::get<11>(this->_data); + DataType& sigma_1 = std::get<12>(this->_data); + DataType& sigma_2 = std::get<13>(this->_data); + DataType& sigma_3 = std::get<14>(this->_data); + DataType& sigma_4 = std::get<15>(this->_data); + DataType& id_1 = std::get<16>(this->_data); + DataType& id_2 = std::get<17>(this->_data); + DataType& id_3 = std::get<18>(this->_data); + DataType& id_4 = std::get<19>(this->_data); + DataType& table_1 = std::get<20>(this->_data); + DataType& table_2 = std::get<21>(this->_data); + DataType& table_3 = std::get<22>(this->_data); + DataType& table_4 = std::get<23>(this->_data); + DataType& lagrange_first = std::get<24>(this->_data); + DataType& lagrange_last = std::get<25>(this->_data); + DataType& lagrange_ecc_op = std::get<26>(this->_data); + DataType& w_l = std::get<27>(this->_data); + DataType& w_r = std::get<28>(this->_data); + DataType& w_o = std::get<29>(this->_data); + DataType& w_4 = std::get<30>(this->_data); + DataType& sorted_accum = std::get<31>(this->_data); + DataType& z_perm = std::get<32>(this->_data); + DataType& z_lookup = std::get<33>(this->_data); + DataType& ecc_op_wire_1 = std::get<34>(this->_data); + DataType& ecc_op_wire_2 = std::get<35>(this->_data); + DataType& ecc_op_wire_3 = std::get<36>(this->_data); + DataType& ecc_op_wire_4 = std::get<37>(this->_data); + DataType& table_1_shift = std::get<38>(this->_data); + DataType& table_2_shift = std::get<39>(this->_data); + DataType& table_3_shift = std::get<40>(this->_data); + DataType& table_4_shift = std::get<41>(this->_data); + DataType& w_l_shift = std::get<42>(this->_data); + DataType& w_r_shift = std::get<43>(this->_data); + DataType& w_o_shift = std::get<44>(this->_data); + DataType& w_4_shift = std::get<45>(this->_data); + DataType& sorted_accum_shift = std::get<46>(this->_data); + DataType& z_perm_shift = std::get<47>(this->_data); + DataType& z_lookup_shift = std::get<48>(this->_data); std::vector get_wires() override { return { w_l, w_r, w_o, w_4 }; }; std::vector get_ecc_op_wires() @@ -213,24 +215,43 @@ class GoblinUltra { // Gemini-specific getters. std::vector get_unshifted() override { - return { q_c, q_l, - q_r, q_o, - q_4, q_m, - q_arith, q_sort, - q_elliptic, q_aux, - q_lookup, sigma_1, - sigma_2, sigma_3, - sigma_4, id_1, - id_2, id_3, - id_4, table_1, - table_2, table_3, - table_4, lagrange_first, - lagrange_last, lagrange_ecc_op, - w_l, w_r, - w_o, w_4, - sorted_accum, z_perm, - z_lookup, ecc_op_wire_1, - ecc_op_wire_2, ecc_op_wire_3, + return { q_c, + q_l, + q_r, + q_o, + q_4, + q_m, + q_arith, + q_sort, + q_elliptic, + q_double, + q_aux, + q_lookup, + sigma_1, + sigma_2, + sigma_3, + sigma_4, + id_1, + id_2, + id_3, + id_4, + table_1, + table_2, + table_3, + table_4, + lagrange_first, + lagrange_last, + lagrange_ecc_op, + w_l, + w_r, + w_o, + w_4, + sorted_accum, + z_perm, + z_lookup, + ecc_op_wire_1, + ecc_op_wire_2, + ecc_op_wire_3, ecc_op_wire_4 }; }; std::vector get_to_be_shifted() override @@ -376,6 +397,7 @@ class GoblinUltra { q_arith = "__Q_ARITH"; q_sort = "__Q_SORT"; q_elliptic = "__Q_ELLIPTIC"; + q_double = "__Q_DOUBLE"; q_aux = "__Q_AUX"; q_lookup = "__Q_LOOKUP"; sigma_1 = "__SIGMA_1"; @@ -410,6 +432,7 @@ class GoblinUltra { q_arith = verification_key->q_arith; q_sort = verification_key->q_sort; q_elliptic = verification_key->q_elliptic; + q_double = verification_key->q_double; q_aux = verification_key->q_aux; q_lookup = verification_key->q_lookup; sigma_1 = verification_key->sigma_1; diff --git a/barretenberg/cpp/src/barretenberg/honk/flavor/goblin_ultra_recursive.hpp b/barretenberg/cpp/src/barretenberg/honk/flavor/goblin_ultra_recursive.hpp index 12f96ff105cf..7d9e35db3806 100644 --- a/barretenberg/cpp/src/barretenberg/honk/flavor/goblin_ultra_recursive.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/flavor/goblin_ultra_recursive.hpp @@ -61,10 +61,10 @@ template class GoblinUltraRecursive_ { // The number of multivariate polynomials on which a sumcheck prover sumcheck operates (including shifts). We often // need containers of this size to hold related data, so we choose a name more agnostic than `NUM_POLYNOMIALS`. // Note: this number does not include the individual sorted list polynomials. - static constexpr size_t NUM_ALL_ENTITIES = 48; // 43 (UH) + 4 op wires + 1 op wire "selector" + static constexpr size_t NUM_ALL_ENTITIES = 49; // 43 (UH) + 4 op wires + 1 op wire "selector" // The number of polynomials precomputed to describe a circuit and to aid a prover in constructing a satisfying // assignment of witnesses. We again choose a neutral name. - static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 26; // 25 (UH) + 1 op wire "selector" + static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 27; // 25 (UH) + 1 op wire "selector" // The total number of witness entities not including shifts. static constexpr size_t NUM_WITNESS_ENTITIES = 15; // 11 (UH) + 4 op wires @@ -105,29 +105,30 @@ template class GoblinUltraRecursive_ { DataType& q_arith = std::get<6>(this->_data); DataType& q_sort = std::get<7>(this->_data); DataType& q_elliptic = std::get<8>(this->_data); - DataType& q_aux = std::get<9>(this->_data); - DataType& q_lookup = std::get<10>(this->_data); - DataType& sigma_1 = std::get<11>(this->_data); - DataType& sigma_2 = std::get<12>(this->_data); - DataType& sigma_3 = std::get<13>(this->_data); - DataType& sigma_4 = std::get<14>(this->_data); - DataType& id_1 = std::get<15>(this->_data); - DataType& id_2 = std::get<16>(this->_data); - DataType& id_3 = std::get<17>(this->_data); - DataType& id_4 = std::get<18>(this->_data); - DataType& table_1 = std::get<19>(this->_data); - DataType& table_2 = std::get<20>(this->_data); - DataType& table_3 = std::get<21>(this->_data); - DataType& table_4 = std::get<22>(this->_data); - DataType& lagrange_first = std::get<23>(this->_data); - DataType& lagrange_last = std::get<24>(this->_data); - DataType& lagrange_ecc_op = std::get<25>(this->_data); // indicator poly for ecc op gates + DataType& q_double = std::get<9>(this->_data); + DataType& q_aux = std::get<10>(this->_data); + DataType& q_lookup = std::get<11>(this->_data); + DataType& sigma_1 = std::get<12>(this->_data); + DataType& sigma_2 = std::get<13>(this->_data); + DataType& sigma_3 = std::get<14>(this->_data); + DataType& sigma_4 = std::get<15>(this->_data); + DataType& id_1 = std::get<16>(this->_data); + DataType& id_2 = std::get<17>(this->_data); + DataType& id_3 = std::get<18>(this->_data); + DataType& id_4 = std::get<19>(this->_data); + DataType& table_1 = std::get<20>(this->_data); + DataType& table_2 = std::get<21>(this->_data); + DataType& table_3 = std::get<22>(this->_data); + DataType& table_4 = std::get<23>(this->_data); + DataType& lagrange_first = std::get<24>(this->_data); + DataType& lagrange_last = std::get<25>(this->_data); + DataType& lagrange_ecc_op = std::get<26>(this->_data); // indicator poly for ecc op gates static constexpr CircuitType CIRCUIT_TYPE = CircuitBuilder::CIRCUIT_TYPE; std::vector get_selectors() override { - return { q_m, q_c, q_l, q_r, q_o, q_4, q_arith, q_sort, q_elliptic, q_aux, q_lookup }; + return { q_m, q_c, q_l, q_r, q_o, q_4, q_arith, q_sort, q_elliptic, q_double, q_aux, q_lookup }; }; std::vector get_sigma_polynomials() override { return { sigma_1, sigma_2, sigma_3, sigma_4 }; }; std::vector get_id_polynomials() override { return { id_1, id_2, id_3, id_4 }; }; @@ -188,45 +189,46 @@ template class GoblinUltraRecursive_ { DataType& q_arith = std::get<6>(this->_data); DataType& q_sort = std::get<7>(this->_data); DataType& q_elliptic = std::get<8>(this->_data); - DataType& q_aux = std::get<9>(this->_data); - DataType& q_lookup = std::get<10>(this->_data); - DataType& sigma_1 = std::get<11>(this->_data); - DataType& sigma_2 = std::get<12>(this->_data); - DataType& sigma_3 = std::get<13>(this->_data); - DataType& sigma_4 = std::get<14>(this->_data); - DataType& id_1 = std::get<15>(this->_data); - DataType& id_2 = std::get<16>(this->_data); - DataType& id_3 = std::get<17>(this->_data); - DataType& id_4 = std::get<18>(this->_data); - DataType& table_1 = std::get<19>(this->_data); - DataType& table_2 = std::get<20>(this->_data); - DataType& table_3 = std::get<21>(this->_data); - DataType& table_4 = std::get<22>(this->_data); - DataType& lagrange_first = std::get<23>(this->_data); - DataType& lagrange_last = std::get<24>(this->_data); - DataType& lagrange_ecc_op = std::get<25>(this->_data); - DataType& w_l = std::get<26>(this->_data); - DataType& w_r = std::get<27>(this->_data); - DataType& w_o = std::get<28>(this->_data); - DataType& w_4 = std::get<29>(this->_data); - DataType& sorted_accum = std::get<30>(this->_data); - DataType& z_perm = std::get<31>(this->_data); - DataType& z_lookup = std::get<32>(this->_data); - DataType& ecc_op_wire_1 = std::get<33>(this->_data); - DataType& ecc_op_wire_2 = std::get<34>(this->_data); - DataType& ecc_op_wire_3 = std::get<35>(this->_data); - DataType& ecc_op_wire_4 = std::get<36>(this->_data); - DataType& table_1_shift = std::get<37>(this->_data); - DataType& table_2_shift = std::get<38>(this->_data); - DataType& table_3_shift = std::get<39>(this->_data); - DataType& table_4_shift = std::get<40>(this->_data); - DataType& w_l_shift = std::get<41>(this->_data); - DataType& w_r_shift = std::get<42>(this->_data); - DataType& w_o_shift = std::get<43>(this->_data); - DataType& w_4_shift = std::get<44>(this->_data); - DataType& sorted_accum_shift = std::get<45>(this->_data); - DataType& z_perm_shift = std::get<46>(this->_data); - DataType& z_lookup_shift = std::get<47>(this->_data); + DataType& q_double = std::get<9>(this->_data); + DataType& q_aux = std::get<10>(this->_data); + DataType& q_lookup = std::get<11>(this->_data); + DataType& sigma_1 = std::get<12>(this->_data); + DataType& sigma_2 = std::get<13>(this->_data); + DataType& sigma_3 = std::get<14>(this->_data); + DataType& sigma_4 = std::get<15>(this->_data); + DataType& id_1 = std::get<16>(this->_data); + DataType& id_2 = std::get<17>(this->_data); + DataType& id_3 = std::get<18>(this->_data); + DataType& id_4 = std::get<19>(this->_data); + DataType& table_1 = std::get<20>(this->_data); + DataType& table_2 = std::get<21>(this->_data); + DataType& table_3 = std::get<22>(this->_data); + DataType& table_4 = std::get<23>(this->_data); + DataType& lagrange_first = std::get<24>(this->_data); + DataType& lagrange_last = std::get<25>(this->_data); + DataType& lagrange_ecc_op = std::get<26>(this->_data); + DataType& w_l = std::get<27>(this->_data); + DataType& w_r = std::get<28>(this->_data); + DataType& w_o = std::get<29>(this->_data); + DataType& w_4 = std::get<30>(this->_data); + DataType& sorted_accum = std::get<31>(this->_data); + DataType& z_perm = std::get<32>(this->_data); + DataType& z_lookup = std::get<33>(this->_data); + DataType& ecc_op_wire_1 = std::get<34>(this->_data); + DataType& ecc_op_wire_2 = std::get<35>(this->_data); + DataType& ecc_op_wire_3 = std::get<36>(this->_data); + DataType& ecc_op_wire_4 = std::get<37>(this->_data); + DataType& table_1_shift = std::get<38>(this->_data); + DataType& table_2_shift = std::get<39>(this->_data); + DataType& table_3_shift = std::get<40>(this->_data); + DataType& table_4_shift = std::get<41>(this->_data); + DataType& w_l_shift = std::get<42>(this->_data); + DataType& w_r_shift = std::get<43>(this->_data); + DataType& w_o_shift = std::get<44>(this->_data); + DataType& w_4_shift = std::get<45>(this->_data); + DataType& sorted_accum_shift = std::get<46>(this->_data); + DataType& z_perm_shift = std::get<47>(this->_data); + DataType& z_lookup_shift = std::get<48>(this->_data); std::vector get_wires() override { return { w_l, w_r, w_o, w_4 }; }; std::vector get_ecc_op_wires() @@ -236,24 +238,43 @@ template class GoblinUltraRecursive_ { // Gemini-specific getters. std::vector get_unshifted() override { - return { q_c, q_l, - q_r, q_o, - q_4, q_m, - q_arith, q_sort, - q_elliptic, q_aux, - q_lookup, sigma_1, - sigma_2, sigma_3, - sigma_4, id_1, - id_2, id_3, - id_4, table_1, - table_2, table_3, - table_4, lagrange_first, - lagrange_last, lagrange_ecc_op, - w_l, w_r, - w_o, w_4, - sorted_accum, z_perm, - z_lookup, ecc_op_wire_1, - ecc_op_wire_2, ecc_op_wire_3, + return { q_c, + q_l, + q_r, + q_o, + q_4, + q_m, + q_arith, + q_sort, + q_elliptic, + q_double, + q_aux, + q_lookup, + sigma_1, + sigma_2, + sigma_3, + sigma_4, + id_1, + id_2, + id_3, + id_4, + table_1, + table_2, + table_3, + table_4, + lagrange_first, + lagrange_last, + lagrange_ecc_op, + w_l, + w_r, + w_o, + w_4, + sorted_accum, + z_perm, + z_lookup, + ecc_op_wire_1, + ecc_op_wire_2, + ecc_op_wire_3, ecc_op_wire_4 }; }; std::vector get_to_be_shifted() override @@ -322,6 +343,7 @@ template class GoblinUltraRecursive_ { this->q_arith = Commitment::from_witness(builder, native_key->q_arith); this->q_sort = Commitment::from_witness(builder, native_key->q_sort); this->q_elliptic = Commitment::from_witness(builder, native_key->q_elliptic); + this->q_double = Commitment::from_witness(builder, native_key->q_double); this->q_aux = Commitment::from_witness(builder, native_key->q_aux); this->q_lookup = Commitment::from_witness(builder, native_key->q_lookup); this->sigma_1 = Commitment::from_witness(builder, native_key->sigma_1); @@ -385,6 +407,7 @@ template class GoblinUltraRecursive_ { this->q_arith = "__Q_ARITH"; this->q_sort = "__Q_SORT"; this->q_elliptic = "__Q_ELLIPTIC"; + this->q_double = "__Q_DOUBLE"; this->q_aux = "__Q_AUX"; this->q_lookup = "__Q_LOOKUP"; this->sigma_1 = "__SIGMA_1"; @@ -418,6 +441,7 @@ template class GoblinUltraRecursive_ { this->q_arith = verification_key->q_arith; this->q_sort = verification_key->q_sort; this->q_elliptic = verification_key->q_elliptic; + this->q_double = verification_key->q_double; this->q_aux = verification_key->q_aux; this->q_lookup = verification_key->q_lookup; this->sigma_1 = verification_key->sigma_1; diff --git a/barretenberg/cpp/src/barretenberg/honk/flavor/ultra.hpp b/barretenberg/cpp/src/barretenberg/honk/flavor/ultra.hpp index 2e1ca263dfe8..58eea456115c 100644 --- a/barretenberg/cpp/src/barretenberg/honk/flavor/ultra.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/flavor/ultra.hpp @@ -36,10 +36,10 @@ class Ultra { // The number of multivariate polynomials on which a sumcheck prover sumcheck operates (including shifts). We often // need containers of this size to hold related data, so we choose a name more agnostic than `NUM_POLYNOMIALS`. // Note: this number does not include the individual sorted list polynomials. - static constexpr size_t NUM_ALL_ENTITIES = 43; + static constexpr size_t NUM_ALL_ENTITIES = 44; // The number of polynomials precomputed to describe a circuit and to aid a prover in constructing a satisfying // assignment of witnesses. We again choose a neutral name. - static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 25; + static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 26; // The total number of witness entities not including shifts. static constexpr size_t NUM_WITNESS_ENTITIES = 11; @@ -84,28 +84,29 @@ class Ultra { DataType& q_arith = std::get<6>(this->_data); DataType& q_sort = std::get<7>(this->_data); DataType& q_elliptic = std::get<8>(this->_data); - DataType& q_aux = std::get<9>(this->_data); - DataType& q_lookup = std::get<10>(this->_data); - DataType& sigma_1 = std::get<11>(this->_data); - DataType& sigma_2 = std::get<12>(this->_data); - DataType& sigma_3 = std::get<13>(this->_data); - DataType& sigma_4 = std::get<14>(this->_data); - DataType& id_1 = std::get<15>(this->_data); - DataType& id_2 = std::get<16>(this->_data); - DataType& id_3 = std::get<17>(this->_data); - DataType& id_4 = std::get<18>(this->_data); - DataType& table_1 = std::get<19>(this->_data); - DataType& table_2 = std::get<20>(this->_data); - DataType& table_3 = std::get<21>(this->_data); - DataType& table_4 = std::get<22>(this->_data); - DataType& lagrange_first = std::get<23>(this->_data); - DataType& lagrange_last = std::get<24>(this->_data); + DataType& q_double = std::get<9>(this->_data); + DataType& q_aux = std::get<10>(this->_data); + DataType& q_lookup = std::get<11>(this->_data); + DataType& sigma_1 = std::get<12>(this->_data); + DataType& sigma_2 = std::get<13>(this->_data); + DataType& sigma_3 = std::get<14>(this->_data); + DataType& sigma_4 = std::get<15>(this->_data); + DataType& id_1 = std::get<16>(this->_data); + DataType& id_2 = std::get<17>(this->_data); + DataType& id_3 = std::get<18>(this->_data); + DataType& id_4 = std::get<19>(this->_data); + DataType& table_1 = std::get<20>(this->_data); + DataType& table_2 = std::get<21>(this->_data); + DataType& table_3 = std::get<22>(this->_data); + DataType& table_4 = std::get<23>(this->_data); + DataType& lagrange_first = std::get<24>(this->_data); + DataType& lagrange_last = std::get<25>(this->_data); static constexpr CircuitType CIRCUIT_TYPE = CircuitBuilder::CIRCUIT_TYPE; std::vector get_selectors() override { - return { q_m, q_c, q_l, q_r, q_o, q_4, q_arith, q_sort, q_elliptic, q_aux, q_lookup }; + return { q_m, q_c, q_l, q_r, q_o, q_4, q_arith, q_sort, q_elliptic, q_double, q_aux, q_lookup }; }; std::vector get_sigma_polynomials() override { return { sigma_1, sigma_2, sigma_3, sigma_4 }; }; std::vector get_id_polynomials() override { return { id_1, id_2, id_3, id_4 }; }; @@ -158,49 +159,51 @@ class Ultra { DataType& q_arith = std::get<6>(this->_data); DataType& q_sort = std::get<7>(this->_data); DataType& q_elliptic = std::get<8>(this->_data); - DataType& q_aux = std::get<9>(this->_data); - DataType& q_lookup = std::get<10>(this->_data); - DataType& sigma_1 = std::get<11>(this->_data); - DataType& sigma_2 = std::get<12>(this->_data); - DataType& sigma_3 = std::get<13>(this->_data); - DataType& sigma_4 = std::get<14>(this->_data); - DataType& id_1 = std::get<15>(this->_data); - DataType& id_2 = std::get<16>(this->_data); - DataType& id_3 = std::get<17>(this->_data); - DataType& id_4 = std::get<18>(this->_data); - DataType& table_1 = std::get<19>(this->_data); - DataType& table_2 = std::get<20>(this->_data); - DataType& table_3 = std::get<21>(this->_data); - DataType& table_4 = std::get<22>(this->_data); - DataType& lagrange_first = std::get<23>(this->_data); - DataType& lagrange_last = std::get<24>(this->_data); - DataType& w_l = std::get<25>(this->_data); - DataType& w_r = std::get<26>(this->_data); - DataType& w_o = std::get<27>(this->_data); - DataType& w_4 = std::get<28>(this->_data); - DataType& sorted_accum = std::get<29>(this->_data); - DataType& z_perm = std::get<30>(this->_data); - DataType& z_lookup = std::get<31>(this->_data); - DataType& table_1_shift = std::get<32>(this->_data); - DataType& table_2_shift = std::get<33>(this->_data); - DataType& table_3_shift = std::get<34>(this->_data); - DataType& table_4_shift = std::get<35>(this->_data); - DataType& w_l_shift = std::get<36>(this->_data); - DataType& w_r_shift = std::get<37>(this->_data); - DataType& w_o_shift = std::get<38>(this->_data); - DataType& w_4_shift = std::get<39>(this->_data); - DataType& sorted_accum_shift = std::get<40>(this->_data); - DataType& z_perm_shift = std::get<41>(this->_data); - DataType& z_lookup_shift = std::get<42>(this->_data); + DataType& q_double = std::get<9>(this->_data); + DataType& q_aux = std::get<10>(this->_data); + DataType& q_lookup = std::get<11>(this->_data); + DataType& sigma_1 = std::get<12>(this->_data); + DataType& sigma_2 = std::get<13>(this->_data); + DataType& sigma_3 = std::get<14>(this->_data); + DataType& sigma_4 = std::get<15>(this->_data); + DataType& id_1 = std::get<16>(this->_data); + DataType& id_2 = std::get<17>(this->_data); + DataType& id_3 = std::get<18>(this->_data); + DataType& id_4 = std::get<19>(this->_data); + DataType& table_1 = std::get<20>(this->_data); + DataType& table_2 = std::get<21>(this->_data); + DataType& table_3 = std::get<22>(this->_data); + DataType& table_4 = std::get<23>(this->_data); + DataType& lagrange_first = std::get<24>(this->_data); + DataType& lagrange_last = std::get<25>(this->_data); + DataType& w_l = std::get<26>(this->_data); + DataType& w_r = std::get<27>(this->_data); + DataType& w_o = std::get<28>(this->_data); + DataType& w_4 = std::get<29>(this->_data); + DataType& sorted_accum = std::get<30>(this->_data); + DataType& z_perm = std::get<31>(this->_data); + DataType& z_lookup = std::get<32>(this->_data); + DataType& table_1_shift = std::get<33>(this->_data); + DataType& table_2_shift = std::get<34>(this->_data); + DataType& table_3_shift = std::get<35>(this->_data); + DataType& table_4_shift = std::get<36>(this->_data); + DataType& w_l_shift = std::get<37>(this->_data); + DataType& w_r_shift = std::get<38>(this->_data); + DataType& w_o_shift = std::get<39>(this->_data); + DataType& w_4_shift = std::get<40>(this->_data); + DataType& sorted_accum_shift = std::get<41>(this->_data); + DataType& z_perm_shift = std::get<42>(this->_data); + DataType& z_lookup_shift = std::get<43>(this->_data); std::vector get_wires() override { return { w_l, w_r, w_o, w_4 }; }; // Gemini-specific getters. std::vector get_unshifted() override { - return { q_c, q_l, q_r, q_o, q_4, q_m, q_arith, q_sort, - q_elliptic, q_aux, q_lookup, sigma_1, sigma_2, sigma_3, sigma_4, id_1, - id_2, id_3, id_4, table_1, table_2, table_3, table_4, lagrange_first, - lagrange_last, w_l, w_r, w_o, w_4, sorted_accum, z_perm, z_lookup + return { + q_c, q_l, q_r, q_o, q_4, q_m, q_arith, q_sort, q_elliptic, + q_double, q_aux, q_lookup, sigma_1, sigma_2, sigma_3, sigma_4, id_1, id_2, + id_3, id_4, table_1, table_2, table_3, table_4, lagrange_first, lagrange_last, w_l, + w_r, w_o, w_4, sorted_accum, z_perm, z_lookup }; }; @@ -339,6 +342,7 @@ class Ultra { q_arith = "__Q_ARITH"; q_sort = "__Q_SORT"; q_elliptic = "__Q_ELLIPTIC"; + q_double = "__Q_DOUBLE"; q_aux = "__Q_AUX"; q_lookup = "__Q_LOOKUP"; sigma_1 = "__SIGMA_1"; @@ -372,6 +376,7 @@ class Ultra { q_arith = verification_key->q_arith; q_sort = verification_key->q_sort; q_elliptic = verification_key->q_elliptic; + q_double = verification_key->q_double; q_aux = verification_key->q_aux; q_lookup = verification_key->q_lookup; sigma_1 = verification_key->sigma_1; diff --git a/barretenberg/cpp/src/barretenberg/honk/flavor/ultra_grumpkin.hpp b/barretenberg/cpp/src/barretenberg/honk/flavor/ultra_grumpkin.hpp index 979aaceed7b5..0adb550adcd2 100644 --- a/barretenberg/cpp/src/barretenberg/honk/flavor/ultra_grumpkin.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/flavor/ultra_grumpkin.hpp @@ -45,10 +45,10 @@ class UltraGrumpkin { // The number of multivariate polynomials on which a sumcheck prover sumcheck operates (including shifts). We often // need containers of this size to hold related data, so we choose a name more agnostic than `NUM_POLYNOMIALS`. // Note: this number does not include the individual sorted list polynomials. - static constexpr size_t NUM_ALL_ENTITIES = 43; + static constexpr size_t NUM_ALL_ENTITIES = 44; // The number of polynomials precomputed to describe a circuit and to aid a prover in constructing a satisfying // assignment of witnesses. We again choose a neutral name. - static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 25; + static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 26; // The total number of witness entities not including shifts. static constexpr size_t NUM_WITNESS_ENTITIES = 11; @@ -93,26 +93,27 @@ class UltraGrumpkin { DataType& q_arith = std::get<6>(this->_data); DataType& q_sort = std::get<7>(this->_data); DataType& q_elliptic = std::get<8>(this->_data); - DataType& q_aux = std::get<9>(this->_data); - DataType& q_lookup = std::get<10>(this->_data); - DataType& sigma_1 = std::get<11>(this->_data); - DataType& sigma_2 = std::get<12>(this->_data); - DataType& sigma_3 = std::get<13>(this->_data); - DataType& sigma_4 = std::get<14>(this->_data); - DataType& id_1 = std::get<15>(this->_data); - DataType& id_2 = std::get<16>(this->_data); - DataType& id_3 = std::get<17>(this->_data); - DataType& id_4 = std::get<18>(this->_data); - DataType& table_1 = std::get<19>(this->_data); - DataType& table_2 = std::get<20>(this->_data); - DataType& table_3 = std::get<21>(this->_data); - DataType& table_4 = std::get<22>(this->_data); - DataType& lagrange_first = std::get<23>(this->_data); - DataType& lagrange_last = std::get<24>(this->_data); + DataType& q_double = std::get<9>(this->_data); + DataType& q_aux = std::get<10>(this->_data); + DataType& q_lookup = std::get<11>(this->_data); + DataType& sigma_1 = std::get<12>(this->_data); + DataType& sigma_2 = std::get<13>(this->_data); + DataType& sigma_3 = std::get<14>(this->_data); + DataType& sigma_4 = std::get<15>(this->_data); + DataType& id_1 = std::get<16>(this->_data); + DataType& id_2 = std::get<17>(this->_data); + DataType& id_3 = std::get<18>(this->_data); + DataType& id_4 = std::get<19>(this->_data); + DataType& table_1 = std::get<20>(this->_data); + DataType& table_2 = std::get<21>(this->_data); + DataType& table_3 = std::get<22>(this->_data); + DataType& table_4 = std::get<23>(this->_data); + DataType& lagrange_first = std::get<24>(this->_data); + DataType& lagrange_last = std::get<25>(this->_data); std::vector get_selectors() override { - return { q_m, q_c, q_l, q_r, q_o, q_4, q_arith, q_sort, q_elliptic, q_aux, q_lookup }; + return { q_m, q_c, q_l, q_r, q_o, q_4, q_arith, q_sort, q_elliptic, q_double, q_aux, q_lookup }; }; std::vector get_sigma_polynomials() override { return { sigma_1, sigma_2, sigma_3, sigma_4 }; }; std::vector get_id_polynomials() override { return { id_1, id_2, id_3, id_4 }; }; @@ -165,49 +166,51 @@ class UltraGrumpkin { DataType& q_arith = std::get<6>(this->_data); DataType& q_sort = std::get<7>(this->_data); DataType& q_elliptic = std::get<8>(this->_data); - DataType& q_aux = std::get<9>(this->_data); - DataType& q_lookup = std::get<10>(this->_data); - DataType& sigma_1 = std::get<11>(this->_data); - DataType& sigma_2 = std::get<12>(this->_data); - DataType& sigma_3 = std::get<13>(this->_data); - DataType& sigma_4 = std::get<14>(this->_data); - DataType& id_1 = std::get<15>(this->_data); - DataType& id_2 = std::get<16>(this->_data); - DataType& id_3 = std::get<17>(this->_data); - DataType& id_4 = std::get<18>(this->_data); - DataType& table_1 = std::get<19>(this->_data); - DataType& table_2 = std::get<20>(this->_data); - DataType& table_3 = std::get<21>(this->_data); - DataType& table_4 = std::get<22>(this->_data); - DataType& lagrange_first = std::get<23>(this->_data); - DataType& lagrange_last = std::get<24>(this->_data); - DataType& w_l = std::get<25>(this->_data); - DataType& w_r = std::get<26>(this->_data); - DataType& w_o = std::get<27>(this->_data); - DataType& w_4 = std::get<28>(this->_data); - DataType& sorted_accum = std::get<29>(this->_data); - DataType& z_perm = std::get<30>(this->_data); - DataType& z_lookup = std::get<31>(this->_data); - DataType& table_1_shift = std::get<32>(this->_data); - DataType& table_2_shift = std::get<33>(this->_data); - DataType& table_3_shift = std::get<34>(this->_data); - DataType& table_4_shift = std::get<35>(this->_data); - DataType& w_l_shift = std::get<36>(this->_data); - DataType& w_r_shift = std::get<37>(this->_data); - DataType& w_o_shift = std::get<38>(this->_data); - DataType& w_4_shift = std::get<39>(this->_data); - DataType& sorted_accum_shift = std::get<40>(this->_data); - DataType& z_perm_shift = std::get<41>(this->_data); - DataType& z_lookup_shift = std::get<42>(this->_data); + DataType& q_double = std::get<9>(this->_data); + DataType& q_aux = std::get<10>(this->_data); + DataType& q_lookup = std::get<11>(this->_data); + DataType& sigma_1 = std::get<12>(this->_data); + DataType& sigma_2 = std::get<13>(this->_data); + DataType& sigma_3 = std::get<14>(this->_data); + DataType& sigma_4 = std::get<15>(this->_data); + DataType& id_1 = std::get<16>(this->_data); + DataType& id_2 = std::get<17>(this->_data); + DataType& id_3 = std::get<18>(this->_data); + DataType& id_4 = std::get<19>(this->_data); + DataType& table_1 = std::get<20>(this->_data); + DataType& table_2 = std::get<21>(this->_data); + DataType& table_3 = std::get<22>(this->_data); + DataType& table_4 = std::get<23>(this->_data); + DataType& lagrange_first = std::get<24>(this->_data); + DataType& lagrange_last = std::get<25>(this->_data); + DataType& w_l = std::get<26>(this->_data); + DataType& w_r = std::get<27>(this->_data); + DataType& w_o = std::get<28>(this->_data); + DataType& w_4 = std::get<29>(this->_data); + DataType& sorted_accum = std::get<30>(this->_data); + DataType& z_perm = std::get<31>(this->_data); + DataType& z_lookup = std::get<32>(this->_data); + DataType& table_1_shift = std::get<33>(this->_data); + DataType& table_2_shift = std::get<34>(this->_data); + DataType& table_3_shift = std::get<35>(this->_data); + DataType& table_4_shift = std::get<36>(this->_data); + DataType& w_l_shift = std::get<37>(this->_data); + DataType& w_r_shift = std::get<38>(this->_data); + DataType& w_o_shift = std::get<39>(this->_data); + DataType& w_4_shift = std::get<40>(this->_data); + DataType& sorted_accum_shift = std::get<41>(this->_data); + DataType& z_perm_shift = std::get<42>(this->_data); + DataType& z_lookup_shift = std::get<43>(this->_data); std::vector get_wires() override { return { w_l, w_r, w_o, w_4 }; }; // Gemini-specific getters. std::vector get_unshifted() override { - return { q_c, q_l, q_r, q_o, q_4, q_m, q_arith, q_sort, - q_elliptic, q_aux, q_lookup, sigma_1, sigma_2, sigma_3, sigma_4, id_1, - id_2, id_3, id_4, table_1, table_2, table_3, table_4, lagrange_first, - lagrange_last, w_l, w_r, w_o, w_4, sorted_accum, z_perm, z_lookup + return { + q_c, q_l, q_r, q_o, q_4, q_m, q_arith, q_sort, q_elliptic, + q_double, q_aux, q_lookup, sigma_1, sigma_2, sigma_3, sigma_4, id_1, id_2, + id_3, id_4, table_1, table_2, table_3, table_4, lagrange_first, lagrange_last, w_l, + w_r, w_o, w_4, sorted_accum, z_perm, z_lookup }; }; @@ -346,6 +349,7 @@ class UltraGrumpkin { q_arith = "__Q_ARITH"; q_sort = "__Q_SORT"; q_elliptic = "__Q_ELLIPTIC"; + q_double = "__Q_DOUBLE"; q_aux = "__Q_AUX"; q_lookup = "__Q_LOOKUP"; sigma_1 = "__SIGMA_1"; @@ -379,6 +383,7 @@ class UltraGrumpkin { q_arith = verification_key->q_arith; q_sort = verification_key->q_sort; q_elliptic = verification_key->q_elliptic; + q_double = verification_key->q_double; q_aux = verification_key->q_aux; q_lookup = verification_key->q_lookup; sigma_1 = verification_key->sigma_1; diff --git a/barretenberg/cpp/src/barretenberg/honk/flavor/ultra_recursive.hpp b/barretenberg/cpp/src/barretenberg/honk/flavor/ultra_recursive.hpp index 5168265cc089..476fc9f69239 100644 --- a/barretenberg/cpp/src/barretenberg/honk/flavor/ultra_recursive.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/flavor/ultra_recursive.hpp @@ -61,10 +61,10 @@ template class UltraRecursive_ { // The number of multivariate polynomials on which a sumcheck prover sumcheck operates (including shifts). We often // need containers of this size to hold related data, so we choose a name more agnostic than `NUM_POLYNOMIALS`. // Note: this number does not include the individual sorted list polynomials. - static constexpr size_t NUM_ALL_ENTITIES = 43; + static constexpr size_t NUM_ALL_ENTITIES = 44; // The number of polynomials precomputed to describe a circuit and to aid a prover in constructing a satisfying // assignment of witnesses. We again choose a neutral name. - static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 25; + static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 26; // The total number of witness entities not including shifts. static constexpr size_t NUM_WITNESS_ENTITIES = 11; @@ -104,26 +104,27 @@ template class UltraRecursive_ { DataType& q_arith = std::get<6>(this->_data); DataType& q_sort = std::get<7>(this->_data); DataType& q_elliptic = std::get<8>(this->_data); - DataType& q_aux = std::get<9>(this->_data); - DataType& q_lookup = std::get<10>(this->_data); - DataType& sigma_1 = std::get<11>(this->_data); - DataType& sigma_2 = std::get<12>(this->_data); - DataType& sigma_3 = std::get<13>(this->_data); - DataType& sigma_4 = std::get<14>(this->_data); - DataType& id_1 = std::get<15>(this->_data); - DataType& id_2 = std::get<16>(this->_data); - DataType& id_3 = std::get<17>(this->_data); - DataType& id_4 = std::get<18>(this->_data); - DataType& table_1 = std::get<19>(this->_data); - DataType& table_2 = std::get<20>(this->_data); - DataType& table_3 = std::get<21>(this->_data); - DataType& table_4 = std::get<22>(this->_data); - DataType& lagrange_first = std::get<23>(this->_data); - DataType& lagrange_last = std::get<24>(this->_data); + DataType& q_double = std::get<9>(this->_data); + DataType& q_aux = std::get<10>(this->_data); + DataType& q_lookup = std::get<11>(this->_data); + DataType& sigma_1 = std::get<12>(this->_data); + DataType& sigma_2 = std::get<13>(this->_data); + DataType& sigma_3 = std::get<14>(this->_data); + DataType& sigma_4 = std::get<15>(this->_data); + DataType& id_1 = std::get<16>(this->_data); + DataType& id_2 = std::get<17>(this->_data); + DataType& id_3 = std::get<18>(this->_data); + DataType& id_4 = std::get<19>(this->_data); + DataType& table_1 = std::get<20>(this->_data); + DataType& table_2 = std::get<21>(this->_data); + DataType& table_3 = std::get<22>(this->_data); + DataType& table_4 = std::get<23>(this->_data); + DataType& lagrange_first = std::get<24>(this->_data); + DataType& lagrange_last = std::get<25>(this->_data); std::vector get_selectors() override { - return { q_m, q_c, q_l, q_r, q_o, q_4, q_arith, q_sort, q_elliptic, q_aux, q_lookup }; + return { q_m, q_c, q_l, q_r, q_o, q_4, q_arith, q_sort, q_elliptic, q_double, q_aux, q_lookup }; }; std::vector get_sigma_polynomials() override { return { sigma_1, sigma_2, sigma_3, sigma_4 }; }; std::vector get_id_polynomials() override { return { id_1, id_2, id_3, id_4 }; }; @@ -176,49 +177,51 @@ template class UltraRecursive_ { DataType& q_arith = std::get<6>(this->_data); DataType& q_sort = std::get<7>(this->_data); DataType& q_elliptic = std::get<8>(this->_data); - DataType& q_aux = std::get<9>(this->_data); - DataType& q_lookup = std::get<10>(this->_data); - DataType& sigma_1 = std::get<11>(this->_data); - DataType& sigma_2 = std::get<12>(this->_data); - DataType& sigma_3 = std::get<13>(this->_data); - DataType& sigma_4 = std::get<14>(this->_data); - DataType& id_1 = std::get<15>(this->_data); - DataType& id_2 = std::get<16>(this->_data); - DataType& id_3 = std::get<17>(this->_data); - DataType& id_4 = std::get<18>(this->_data); - DataType& table_1 = std::get<19>(this->_data); - DataType& table_2 = std::get<20>(this->_data); - DataType& table_3 = std::get<21>(this->_data); - DataType& table_4 = std::get<22>(this->_data); - DataType& lagrange_first = std::get<23>(this->_data); - DataType& lagrange_last = std::get<24>(this->_data); - DataType& w_l = std::get<25>(this->_data); - DataType& w_r = std::get<26>(this->_data); - DataType& w_o = std::get<27>(this->_data); - DataType& w_4 = std::get<28>(this->_data); - DataType& sorted_accum = std::get<29>(this->_data); - DataType& z_perm = std::get<30>(this->_data); - DataType& z_lookup = std::get<31>(this->_data); - DataType& table_1_shift = std::get<32>(this->_data); - DataType& table_2_shift = std::get<33>(this->_data); - DataType& table_3_shift = std::get<34>(this->_data); - DataType& table_4_shift = std::get<35>(this->_data); - DataType& w_l_shift = std::get<36>(this->_data); - DataType& w_r_shift = std::get<37>(this->_data); - DataType& w_o_shift = std::get<38>(this->_data); - DataType& w_4_shift = std::get<39>(this->_data); - DataType& sorted_accum_shift = std::get<40>(this->_data); - DataType& z_perm_shift = std::get<41>(this->_data); - DataType& z_lookup_shift = std::get<42>(this->_data); + DataType& q_double = std::get<9>(this->_data); + DataType& q_aux = std::get<10>(this->_data); + DataType& q_lookup = std::get<11>(this->_data); + DataType& sigma_1 = std::get<12>(this->_data); + DataType& sigma_2 = std::get<13>(this->_data); + DataType& sigma_3 = std::get<14>(this->_data); + DataType& sigma_4 = std::get<15>(this->_data); + DataType& id_1 = std::get<16>(this->_data); + DataType& id_2 = std::get<17>(this->_data); + DataType& id_3 = std::get<18>(this->_data); + DataType& id_4 = std::get<19>(this->_data); + DataType& table_1 = std::get<20>(this->_data); + DataType& table_2 = std::get<21>(this->_data); + DataType& table_3 = std::get<22>(this->_data); + DataType& table_4 = std::get<23>(this->_data); + DataType& lagrange_first = std::get<24>(this->_data); + DataType& lagrange_last = std::get<25>(this->_data); + DataType& w_l = std::get<26>(this->_data); + DataType& w_r = std::get<27>(this->_data); + DataType& w_o = std::get<28>(this->_data); + DataType& w_4 = std::get<29>(this->_data); + DataType& sorted_accum = std::get<30>(this->_data); + DataType& z_perm = std::get<31>(this->_data); + DataType& z_lookup = std::get<32>(this->_data); + DataType& table_1_shift = std::get<33>(this->_data); + DataType& table_2_shift = std::get<34>(this->_data); + DataType& table_3_shift = std::get<35>(this->_data); + DataType& table_4_shift = std::get<36>(this->_data); + DataType& w_l_shift = std::get<37>(this->_data); + DataType& w_r_shift = std::get<38>(this->_data); + DataType& w_o_shift = std::get<39>(this->_data); + DataType& w_4_shift = std::get<40>(this->_data); + DataType& sorted_accum_shift = std::get<41>(this->_data); + DataType& z_perm_shift = std::get<42>(this->_data); + DataType& z_lookup_shift = std::get<43>(this->_data); std::vector get_wires() override { return { w_l, w_r, w_o, w_4 }; }; // Gemini-specific getters. std::vector get_unshifted() override { - return { q_c, q_l, q_r, q_o, q_4, q_m, q_arith, q_sort, - q_elliptic, q_aux, q_lookup, sigma_1, sigma_2, sigma_3, sigma_4, id_1, - id_2, id_3, id_4, table_1, table_2, table_3, table_4, lagrange_first, - lagrange_last, w_l, w_r, w_o, w_4, sorted_accum, z_perm, z_lookup + return { + q_c, q_l, q_r, q_o, q_4, q_m, q_arith, q_sort, q_elliptic, + q_double, q_aux, q_lookup, sigma_1, sigma_2, sigma_3, sigma_4, id_1, id_2, + id_3, id_4, table_1, table_2, table_3, table_4, lagrange_first, lagrange_last, w_l, + w_r, w_o, w_4, sorted_accum, z_perm, z_lookup }; }; @@ -288,6 +291,7 @@ template class UltraRecursive_ { this->q_arith = Commitment::from_witness(builder, native_key->q_arith); this->q_sort = Commitment::from_witness(builder, native_key->q_sort); this->q_elliptic = Commitment::from_witness(builder, native_key->q_elliptic); + this->q_double = Commitment::from_witness(builder, native_key->q_double); this->q_aux = Commitment::from_witness(builder, native_key->q_aux); this->q_lookup = Commitment::from_witness(builder, native_key->q_lookup); this->sigma_1 = Commitment::from_witness(builder, native_key->sigma_1); @@ -346,6 +350,7 @@ template class UltraRecursive_ { this->q_arith = "__Q_ARITH"; this->q_sort = "__Q_SORT"; this->q_elliptic = "__Q_ELLIPTIC"; + this->q_double = "__Q_DOUBLE"; this->q_aux = "__Q_AUX"; this->q_lookup = "__Q_LOOKUP"; this->sigma_1 = "__SIGMA_1"; @@ -378,6 +383,7 @@ template class UltraRecursive_ { this->q_arith = verification_key->q_arith; this->q_sort = verification_key->q_sort; this->q_elliptic = verification_key->q_elliptic; + this->q_double = verification_key->q_double; this->q_aux = verification_key->q_aux; this->q_lookup = verification_key->q_lookup; this->sigma_1 = verification_key->sigma_1; diff --git a/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.cpp b/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.cpp index 961548373993..be73c6b82b0d 100644 --- a/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/instance/prover_instance.cpp @@ -278,6 +278,7 @@ template void ProverInstance_::initialise_prover_polynomi prover_polynomials.q_arith = proving_key->q_arith; prover_polynomials.q_sort = proving_key->q_sort; prover_polynomials.q_elliptic = proving_key->q_elliptic; + prover_polynomials.q_double = proving_key->q_double; prover_polynomials.q_aux = proving_key->q_aux; prover_polynomials.q_lookup = proving_key->q_lookup; prover_polynomials.sigma_4 = proving_key->sigma_4; @@ -451,6 +452,7 @@ std::shared_ptr ProverInstance_::compu verification_key->q_arith = commitment_key->commit(proving_key->q_arith); verification_key->q_sort = commitment_key->commit(proving_key->q_sort); verification_key->q_elliptic = commitment_key->commit(proving_key->q_elliptic); + verification_key->q_double = commitment_key->commit(proving_key->q_double); verification_key->q_aux = commitment_key->commit(proving_key->q_aux); verification_key->q_lookup = commitment_key->commit(proving_key->q_lookup); verification_key->sigma_4 = commitment_key->commit(proving_key->sigma_4); diff --git a/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck.test.cpp b/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck.test.cpp index f8ae29e46e33..751a887dc27f 100644 --- a/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck.test.cpp +++ b/barretenberg/cpp/src/barretenberg/honk/sumcheck/sumcheck.test.cpp @@ -41,40 +41,41 @@ ProverPolynomials construct_ultra_full_polynomials(auto& input_polynomials) full_polynomials.q_arith = input_polynomials[6]; full_polynomials.q_sort = input_polynomials[7]; full_polynomials.q_elliptic = input_polynomials[8]; - full_polynomials.q_aux = input_polynomials[9]; - full_polynomials.q_lookup = input_polynomials[10]; - full_polynomials.sigma_1 = input_polynomials[11]; - full_polynomials.sigma_2 = input_polynomials[12]; - full_polynomials.sigma_3 = input_polynomials[13]; - full_polynomials.sigma_4 = input_polynomials[14]; - full_polynomials.id_1 = input_polynomials[15]; - full_polynomials.id_2 = input_polynomials[16]; - full_polynomials.id_3 = input_polynomials[17]; - full_polynomials.id_4 = input_polynomials[18]; - full_polynomials.table_1 = input_polynomials[19]; - full_polynomials.table_2 = input_polynomials[20]; - full_polynomials.table_3 = input_polynomials[21]; - full_polynomials.table_4 = input_polynomials[22]; - full_polynomials.lagrange_first = input_polynomials[23]; - full_polynomials.lagrange_last = input_polynomials[24]; - full_polynomials.w_l = input_polynomials[25]; - full_polynomials.w_r = input_polynomials[26]; - full_polynomials.w_o = input_polynomials[27]; - full_polynomials.w_4 = input_polynomials[28]; - full_polynomials.sorted_accum = input_polynomials[29]; - full_polynomials.z_perm = input_polynomials[30]; - full_polynomials.z_lookup = input_polynomials[31]; - full_polynomials.table_1_shift = input_polynomials[32]; - full_polynomials.table_2_shift = input_polynomials[33]; - full_polynomials.table_3_shift = input_polynomials[34]; - full_polynomials.table_4_shift = input_polynomials[35]; - full_polynomials.w_l_shift = input_polynomials[36]; - full_polynomials.w_r_shift = input_polynomials[37]; - full_polynomials.w_o_shift = input_polynomials[38]; - full_polynomials.w_4_shift = input_polynomials[39]; - full_polynomials.sorted_accum_shift = input_polynomials[40]; - full_polynomials.z_perm_shift = input_polynomials[41]; - full_polynomials.z_lookup_shift = input_polynomials[42]; + full_polynomials.q_double = input_polynomials[9]; + full_polynomials.q_aux = input_polynomials[10]; + full_polynomials.q_lookup = input_polynomials[11]; + full_polynomials.sigma_1 = input_polynomials[12]; + full_polynomials.sigma_2 = input_polynomials[13]; + full_polynomials.sigma_3 = input_polynomials[14]; + full_polynomials.sigma_4 = input_polynomials[15]; + full_polynomials.id_1 = input_polynomials[16]; + full_polynomials.id_2 = input_polynomials[17]; + full_polynomials.id_3 = input_polynomials[18]; + full_polynomials.id_4 = input_polynomials[19]; + full_polynomials.table_1 = input_polynomials[20]; + full_polynomials.table_2 = input_polynomials[21]; + full_polynomials.table_3 = input_polynomials[22]; + full_polynomials.table_4 = input_polynomials[23]; + full_polynomials.lagrange_first = input_polynomials[24]; + full_polynomials.lagrange_last = input_polynomials[25]; + full_polynomials.w_l = input_polynomials[26]; + full_polynomials.w_r = input_polynomials[27]; + full_polynomials.w_o = input_polynomials[28]; + full_polynomials.w_4 = input_polynomials[29]; + full_polynomials.sorted_accum = input_polynomials[30]; + full_polynomials.z_perm = input_polynomials[31]; + full_polynomials.z_lookup = input_polynomials[32]; + full_polynomials.table_1_shift = input_polynomials[33]; + full_polynomials.table_2_shift = input_polynomials[34]; + full_polynomials.table_3_shift = input_polynomials[35]; + full_polynomials.table_4_shift = input_polynomials[36]; + full_polynomials.w_l_shift = input_polynomials[37]; + full_polynomials.w_r_shift = input_polynomials[38]; + full_polynomials.w_o_shift = input_polynomials[39]; + full_polynomials.w_4_shift = input_polynomials[40]; + full_polynomials.sorted_accum_shift = input_polynomials[41]; + full_polynomials.z_perm_shift = input_polynomials[42]; + full_polynomials.z_lookup_shift = input_polynomials[43]; return full_polynomials; } diff --git a/barretenberg/cpp/src/barretenberg/proof_system/relations/ecc_vm/ecc_transcript_relation.hpp b/barretenberg/cpp/src/barretenberg/proof_system/relations/ecc_vm/ecc_transcript_relation.hpp index 86d5dc5e738b..5205ec6fa926 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/relations/ecc_vm/ecc_transcript_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/relations/ecc_vm/ecc_transcript_relation.hpp @@ -75,7 +75,7 @@ template class ECCVMTranscriptRelationBase { const RelationParameters& /*unused*/, const FF& /*unused*/); - // TODO(@zac-williamson) find more generic way of doing this? + // TODO(@zac-williamson #2609 find more generic way of doing this) static constexpr FF get_curve_b() { if constexpr (FF::modulus == barretenberg::fq::modulus) { diff --git a/barretenberg/cpp/src/barretenberg/proof_system/relations/elliptic_relation.hpp b/barretenberg/cpp/src/barretenberg/proof_system/relations/elliptic_relation.hpp index 511f7f37a233..2a2d18241894 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/relations/elliptic_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/relations/elliptic_relation.hpp @@ -1,9 +1,24 @@ #pragma once +#include "barretenberg/ecc/curves/bn254/bn254.hpp" +#include "barretenberg/ecc/curves/grumpkin/grumpkin.hpp" + #include "relation_parameters.hpp" #include "relation_types.hpp" namespace proof_system { +// TODO(@zac-williamson #2609 find more generic way of doing this) +template static constexpr FF get_curve_b() +{ + if constexpr (FF::modulus == barretenberg::fq::modulus) { + return barretenberg::g1::curve_b; + } else if constexpr (FF::modulus == grumpkin::fq::modulus) { + return grumpkin::g1::curve_b; + } else { + return 0; + } +} + template class EllipticRelationImpl { public: using FF = FF_; @@ -13,8 +28,10 @@ template class EllipticRelationImpl { static constexpr size_t LEN_1 = 6; // x-coordinate sub-relation static constexpr size_t LEN_2 = 5; // y-coordinate sub-relation + static constexpr size_t LEN_3 = 5; // y-coordinate sub-relation + static constexpr size_t LEN_4 = 5; // y-coordinate sub-relation template