diff --git a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp index c5bb2a10ab2..80d1ca652e9 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp @@ -12,6 +12,8 @@ #include "barretenberg/relations/gen_perm_sort_relation.hpp" #include "barretenberg/relations/lookup_relation.hpp" #include "barretenberg/relations/permutation_relation.hpp" +#include "barretenberg/relations/poseidon2_external_relation.hpp" +#include "barretenberg/relations/poseidon2_internal_relation.hpp" #include "barretenberg/relations/relation_parameters.hpp" #include "barretenberg/relations/ultra_arithmetic_relation.hpp" #include "barretenberg/transcript/transcript.hpp" @@ -37,10 +39,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 = 53; + static constexpr size_t NUM_ALL_ENTITIES = 55; // The number of polynomials precomputed to describe a circuit and to aid a prover in constructing a satisfying // assignment of witnesses. We again choose a neutral name. - static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 28; + static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 30; // The total number of witness entities not including shifts. static constexpr size_t NUM_WITNESS_ENTITIES = 14; @@ -57,7 +59,9 @@ class GoblinUltra { proof_system::EllipticRelation, proof_system::AuxiliaryRelation, proof_system::EccOpQueueRelation, - proof_system::DatabusLookupRelation>; + proof_system::DatabusLookupRelation, + proof_system::Poseidon2ExternalRelation, + proof_system::Poseidon2InternalRelation>; using Relations = Relations_; using LogDerivLookupRelation = proof_system::DatabusLookupRelation; @@ -90,40 +94,56 @@ class GoblinUltra { public: using DataType = DataType_; DEFINE_FLAVOR_MEMBERS(DataType, - q_m, // column 0 - q_c, // column 1 - q_l, // column 2 - q_r, // column 3 - q_o, // column 4 - q_4, // column 5 - q_arith, // column 6 - q_sort, // column 7 - q_elliptic, // column 8 - q_aux, // column 9 - q_lookup, // column 10 - q_busread, // column 11 - sigma_1, // column 12 - sigma_2, // column 13 - sigma_3, // column 14 - sigma_4, // column 15 - id_1, // column 16 - id_2, // column 17 - id_3, // column 18 - id_4, // column 19 - table_1, // column 20 - table_2, // column 21 - table_3, // column 22 - table_4, // column 23 - lagrange_first, // column 24 - lagrange_last, // column 25 - lagrange_ecc_op, // column 26 // indicator poly for ecc op gates - databus_id) // column 27 // id polynomial, i.e. id_i = i + q_m, // column 0 + q_c, // column 1 + q_l, // column 2 + q_r, // column 3 + q_o, // column 4 + q_4, // column 5 + q_arith, // column 6 + q_sort, // column 7 + q_elliptic, // column 8 + q_aux, // column 9 + q_lookup, // column 10 + q_busread, // column 11 + q_poseidon2_external, // column 12 + q_poseidon2_internal, // column 13 + sigma_1, // column 14 + sigma_2, // column 15 + sigma_3, // column 16 + sigma_4, // column 17 + id_1, // column 18 + id_2, // column 19 + id_3, // column 20 + id_4, // column 21 + table_1, // column 22 + table_2, // column 23 + table_3, // column 24 + table_4, // column 25 + lagrange_first, // column 26 + lagrange_last, // column 27 + lagrange_ecc_op, // column 28 // indicator poly for ecc op gates + databus_id // column 29 // id polynomial, i.e. id_i = i + ) static constexpr CircuitType CIRCUIT_TYPE = CircuitBuilder::CIRCUIT_TYPE; RefVector get_selectors() { - return { q_m, q_c, q_l, q_r, q_o, q_4, q_arith, q_sort, q_elliptic, q_aux, q_lookup, q_busread }; + return { q_m, + q_c, + q_l, + q_r, + q_o, + q_4, + q_arith, + q_sort, + q_elliptic, + q_aux, + q_lookup, + q_busread, + q_poseidon2_external, + q_poseidon2_internal }; }; RefVector get_sigma_polynomials() { return { sigma_1, sigma_2, sigma_3, sigma_4 }; }; RefVector get_id_polynomials() { return { id_1, id_2, id_3, id_4 }; }; @@ -237,6 +257,8 @@ class GoblinUltra { this->q_aux, this->q_lookup, this->q_busread, + this->q_poseidon2_external, + this->q_poseidon2_internal, this->sigma_1, this->sigma_2, this->sigma_3, @@ -402,6 +424,8 @@ class GoblinUltra { q_aux = "__Q_AUX"; q_lookup = "__Q_LOOKUP"; q_busread = "__Q_BUSREAD"; + q_poseidon2_external = "__Q_POSEIDON2_EXTERNAL"; + q_poseidon2_internal = "__Q_POSEIDON2_INTERNAL"; sigma_1 = "__SIGMA_1"; sigma_2 = "__SIGMA_2"; sigma_3 = "__SIGMA_3"; @@ -440,6 +464,8 @@ class GoblinUltra { this->q_aux = verification_key->q_aux; this->q_lookup = verification_key->q_lookup; this->q_busread = verification_key->q_busread; + this->q_poseidon2_external = verification_key->q_poseidon2_external; + this->q_poseidon2_internal = verification_key->q_poseidon2_internal; this->sigma_1 = verification_key->sigma_1; this->sigma_2 = verification_key->sigma_2; this->sigma_3 = verification_key->sigma_3; diff --git a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp index c9dfb4562e1..cbe48a27994 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp @@ -10,15 +10,7 @@ #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp" -#include "barretenberg/relations/auxiliary_relation.hpp" -#include "barretenberg/relations/ecc_op_queue_relation.hpp" -#include "barretenberg/relations/elliptic_relation.hpp" -#include "barretenberg/relations/gen_perm_sort_relation.hpp" -#include "barretenberg/relations/lookup_relation.hpp" -#include "barretenberg/relations/permutation_relation.hpp" -#include "barretenberg/relations/ultra_arithmetic_relation.hpp" #include "barretenberg/srs/factories/crs_factory.hpp" -#include "barretenberg/transcript/transcript.hpp" #include #include #include @@ -130,6 +122,8 @@ template class GoblinUltraRecursive_ { this->q_aux = Commitment::from_witness(builder, native_key->q_aux); this->q_lookup = Commitment::from_witness(builder, native_key->q_lookup); this->q_busread = Commitment::from_witness(builder, native_key->q_busread); + this->q_poseidon2_external = Commitment::from_witness(builder, native_key->q_poseidon2_external); + this->q_poseidon2_internal = Commitment::from_witness(builder, native_key->q_poseidon2_internal); this->sigma_1 = Commitment::from_witness(builder, native_key->sigma_1); this->sigma_2 = Commitment::from_witness(builder, native_key->sigma_2); this->sigma_3 = Commitment::from_witness(builder, native_key->sigma_3); diff --git a/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/arithmetization.hpp b/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/arithmetization.hpp index c6dffdeaa3a..c396301f7ba 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/arithmetization.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/arithmetization.hpp @@ -118,7 +118,7 @@ template class Ultra { template class UltraHonk { public: static constexpr size_t NUM_WIRES = 4; - static constexpr size_t NUM_SELECTORS = 12; + static constexpr size_t NUM_SELECTORS = 14; using FF = FF_; using SelectorType = std::vector>; @@ -138,6 +138,8 @@ template class UltraHonk { SelectorType& q_aux() { return selectors[9]; }; SelectorType& q_lookup_type() { return selectors[10]; }; SelectorType& q_busread() { return this->selectors[11]; }; + SelectorType& q_poseidon2_external() { return this->selectors[12]; }; + SelectorType& q_poseidon2_internal() { return this->selectors[13]; }; const auto& get() const { return selectors; }; @@ -154,7 +156,12 @@ template class UltraHonk { * Ultra arithmetization * */ - void pad_additional() { q_busread().emplace_back(0); }; + void pad_additional() + { + q_busread().emplace_back(0); + q_poseidon2_external().emplace_back(0); + q_poseidon2_internal().emplace_back(0); + }; // Note: Unused. Needed only for consistency with Ultra arith (which is used by Plonk) inline static const std::vector selector_names = {}; diff --git a/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/gate_data.hpp b/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/gate_data.hpp index 4f8f799c42b..91540d90d72 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/gate_data.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/arithmetization/gate_data.hpp @@ -132,4 +132,20 @@ template struct ecc_dbl_gate_ { uint32_t x3; uint32_t y3; }; + +template struct poseidon2_external_gate_ { + uint32_t a; + uint32_t b; + uint32_t c; + uint32_t d; + uint32_t round_idx; +}; + +template struct poseidon2_internal_gate_ { + uint32_t a; + uint32_t b; + uint32_t c; + uint32_t d; + uint32_t round_idx; +}; } // namespace proof_system diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.cpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.cpp index 610aefccf09..108e16471e0 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.cpp @@ -1,9 +1,12 @@ #include "goblin_ultra_circuit_builder.hpp" +#include "barretenberg/crypto/poseidon2/poseidon2_params.hpp" +#include "barretenberg/flavor/goblin_ultra.hpp" #include #include #include using namespace barretenberg; +using namespace crypto; namespace proof_system { @@ -25,8 +28,8 @@ template void GoblinUltraCircuitBuilder_::add_gates_to_ensure_ // Most polynomials are handled via the conventional Ultra method UltraCircuitBuilder_>::add_gates_to_ensure_all_polys_are_non_zero(); - // All that remains is to handle databus related polynomials. In what follows we populate the calldata with some - // mock data then constuct a single calldata read gate + // All that remains is to handle databus related and poseidon2 related polynomials. In what follows we populate the + // calldata with some mock data then constuct a single calldata read gate // Populate the calldata with some data public_calldata.emplace_back(this->add_variable(FF(5))); @@ -60,6 +63,52 @@ template void GoblinUltraCircuitBuilder_::add_gates_to_ensure_ this->q_lookup_type.emplace_back(0); this->q_elliptic.emplace_back(0); this->q_aux.emplace_back(0); + this->q_poseidon2_external.emplace_back(0); + this->q_poseidon2_internal.emplace_back(0); + + ++this->num_gates; + + // mock gates that use poseidon selectors, with all zeros as input + this->w_l.emplace_back(this->zero_idx); + this->w_r.emplace_back(this->zero_idx); + this->w_o.emplace_back(this->zero_idx); + this->w_4.emplace_back(this->zero_idx); + this->q_m.emplace_back(0); + this->q_1.emplace_back(0); + this->q_2.emplace_back(0); + this->q_3.emplace_back(0); + this->q_c.emplace_back(0); + this->q_arith.emplace_back(0); + this->q_4.emplace_back(0); + this->q_sort.emplace_back(0); + this->q_lookup_type.emplace_back(0); + this->q_elliptic.emplace_back(0); + this->q_aux.emplace_back(0); + this->q_busread.emplace_back(0); + this->q_poseidon2_external.emplace_back(1); + this->q_poseidon2_internal.emplace_back(1); + + ++this->num_gates; + + // second gate that stores the output of all zeros of the poseidon gates + this->w_l.emplace_back(this->zero_idx); + this->w_r.emplace_back(this->zero_idx); + this->w_o.emplace_back(this->zero_idx); + this->w_4.emplace_back(this->zero_idx); + this->q_m.emplace_back(0); + this->q_1.emplace_back(0); + this->q_2.emplace_back(0); + this->q_3.emplace_back(0); + this->q_c.emplace_back(0); + this->q_arith.emplace_back(0); + this->q_4.emplace_back(0); + this->q_sort.emplace_back(0); + this->q_lookup_type.emplace_back(0); + this->q_elliptic.emplace_back(0); + this->q_aux.emplace_back(0); + this->q_busread.emplace_back(0); + this->q_poseidon2_external.emplace_back(0); + this->q_poseidon2_internal.emplace_back(0); ++this->num_gates; } @@ -197,5 +246,249 @@ template void GoblinUltraCircuitBuilder_::populate_ecc_op_wire num_ecc_op_gates += 2; }; +template +void GoblinUltraCircuitBuilder_::create_poseidon2_external_gate(const poseidon2_external_gate_& in) +{ + this->w_l.emplace_back(in.a); + this->w_r.emplace_back(in.b); + this->w_o.emplace_back(in.c); + this->w_4.emplace_back(in.d); + this->q_m.emplace_back(0); + this->q_1.emplace_back(Poseidon2Bn254ScalarFieldParams::round_constants[in.round_idx][0]); + this->q_2.emplace_back(Poseidon2Bn254ScalarFieldParams::round_constants[in.round_idx][1]); + this->q_3.emplace_back(Poseidon2Bn254ScalarFieldParams::round_constants[in.round_idx][2]); + this->q_c.emplace_back(0); + this->q_arith.emplace_back(0); + this->q_4.emplace_back(Poseidon2Bn254ScalarFieldParams::round_constants[in.round_idx][3]); + this->q_sort.emplace_back(0); + this->q_lookup_type.emplace_back(0); + this->q_elliptic.emplace_back(0); + this->q_aux.emplace_back(0); + this->q_busread.emplace_back(0); + this->q_poseidon2_external.emplace_back(1); + this->q_poseidon2_internal.emplace_back(0); + ++this->num_gates; +} + +template +void GoblinUltraCircuitBuilder_::create_poseidon2_internal_gate(const poseidon2_internal_gate_& in) +{ + this->w_l.emplace_back(in.a); + this->w_r.emplace_back(in.b); + this->w_o.emplace_back(in.c); + this->w_4.emplace_back(in.d); + this->q_m.emplace_back(0); + this->q_1.emplace_back(Poseidon2Bn254ScalarFieldParams::round_constants[in.round_idx][0]); + this->q_2.emplace_back(0); + this->q_3.emplace_back(0); + this->q_c.emplace_back(0); + this->q_arith.emplace_back(0); + this->q_4.emplace_back(0); + this->q_sort.emplace_back(0); + this->q_lookup_type.emplace_back(0); + this->q_elliptic.emplace_back(0); + this->q_aux.emplace_back(0); + this->q_busread.emplace_back(0); + this->q_poseidon2_external.emplace_back(0); + this->q_poseidon2_internal.emplace_back(1); + ++this->num_gates; +} + +template +inline FF GoblinUltraCircuitBuilder_::compute_poseidon2_external_identity(FF q_poseidon2_external_value, + FF q_1_value, + FF q_2_value, + FF q_3_value, + FF q_4_value, + FF w_1_value, + FF w_2_value, + FF w_3_value, + FF w_4_value, + FF w_1_shifted_value, + FF w_2_shifted_value, + FF w_3_shifted_value, + FF w_4_shifted_value, + FF alpha_base, + FF alpha) const +{ + // Power of alpha to separate individual sub-relations + // TODO(kesha): This is a repeated computation which can be efficiently optimized + const FF alpha_a = alpha_base; + const FF alpha_b = alpha_a * alpha; + const FF alpha_c = alpha_b * alpha; + const FF alpha_d = alpha_c * alpha; + + FF s1 = w_1_value + q_1_value; + FF s2 = w_2_value + q_2_value; + FF s3 = w_3_value + q_3_value; + FF s4 = w_4_value + q_4_value; + + FF u1 = s1 * s1; + u1 *= u1; + u1 *= s1; + FF u2 = s2 * s2; + u2 *= u2; + u2 *= s2; + FF u3 = s3 * s3; + u3 *= u3; + u3 *= s3; + FF u4 = s4 * s4; + u4 *= u4; + u4 *= s4; + + auto t0 = u1 + u2; + auto t1 = u3 + u4; + auto t2 = u2 + u2; + t2 += t1; + auto t3 = u4 + u4; + t3 += t0; + auto v4 = t1 + t1; + v4 += v4; + v4 += t3; + auto v2 = t0 + t0; + v2 += v2; + v2 += t2; + auto v1 = t3 + v2; + auto v3 = t2 + v4; + + return q_poseidon2_external_value * (alpha_a * (v1 - w_1_shifted_value) + alpha_b * (v2 - w_2_shifted_value) + + alpha_c * (v3 - w_3_shifted_value) + alpha_d * (v4 - w_4_shifted_value)); +} + +template +inline FF GoblinUltraCircuitBuilder_::compute_poseidon2_internal_identity(FF q_poseidon2_internal_value, + FF q_1_value, + FF w_1_value, + FF w_2_value, + FF w_3_value, + FF w_4_value, + FF w_1_shifted_value, + FF w_2_shifted_value, + FF w_3_shifted_value, + FF w_4_shifted_value, + FF alpha_base, + FF alpha) const +{ + // Power of alpha to separate individual sub-relations + // TODO(kesha): This is a repeated computation which can be efficiently optimized + const FF alpha_a = alpha_base; + const FF alpha_b = alpha_a * alpha; + const FF alpha_c = alpha_b * alpha; + const FF alpha_d = alpha_c * alpha; + + auto s1 = w_1_value + q_1_value; + + auto u1 = s1 * s1; + u1 *= u1; + u1 *= s1; + + auto sum = u1 + w_2_value + w_3_value + w_4_value; + auto v1 = u1 * crypto::Poseidon2Bn254ScalarFieldParams::internal_matrix_diagonal[0]; + v1 += sum; + auto v2 = w_2_value * crypto::Poseidon2Bn254ScalarFieldParams::internal_matrix_diagonal[1]; + v2 += sum; + auto v3 = w_3_value * crypto::Poseidon2Bn254ScalarFieldParams::internal_matrix_diagonal[2]; + v3 += sum; + auto v4 = w_4_value * crypto::Poseidon2Bn254ScalarFieldParams::internal_matrix_diagonal[3]; + v4 += sum; + + return q_poseidon2_internal_value * (alpha_a * (v1 - w_1_shifted_value) + alpha_b * (v2 - w_2_shifted_value) + + alpha_c * (v3 - w_3_shifted_value) + alpha_d * (v4 - w_4_shifted_value)); +} + +template bool GoblinUltraCircuitBuilder_::check_circuit() +{ + bool result = true; + if (!UltraCircuitBuilder_>::check_circuit()) { + return false; + } + + const FF poseidon2_external_base = FF::random_element(); + const FF poseidon2_internal_base = FF::random_element(); + const FF alpha = FF::random_element(); + + // For each gate + for (size_t i = 0; i < this->num_gates; i++) { + FF q_poseidon2_external_value; + FF q_poseidon2_internal_value; + FF q_1_value; + FF q_2_value; + FF q_3_value; + FF q_4_value; + FF w_1_value; + FF w_2_value; + FF w_3_value; + FF w_4_value; + // Get the values of selectors and wires and update tag products along the way + q_poseidon2_external_value = this->q_poseidon2_external[i]; + q_poseidon2_internal_value = this->q_poseidon2_internal[i]; + q_1_value = this->q_1[i]; + q_2_value = this->q_2[i]; + q_3_value = this->q_3[i]; + q_4_value = this->q_4[i]; + w_1_value = this->get_variable(this->w_l[i]); + w_2_value = this->get_variable(this->w_r[i]); + w_3_value = this->get_variable(this->w_o[i]); + w_4_value = this->get_variable(this->w_4[i]); + FF w_1_shifted_value; + FF w_2_shifted_value; + FF w_3_shifted_value; + FF w_4_shifted_value; + if (i < (this->num_gates - 1)) { + w_1_shifted_value = this->get_variable(this->w_l[i + 1]); + w_2_shifted_value = this->get_variable(this->w_r[i + 1]); + w_3_shifted_value = this->get_variable(this->w_o[i + 1]); + w_4_shifted_value = this->get_variable(this->w_4[i + 1]); + } else { + w_1_shifted_value = FF::zero(); + w_2_shifted_value = FF::zero(); + w_3_shifted_value = FF::zero(); + w_4_shifted_value = FF::zero(); + } + if (!compute_poseidon2_external_identity(q_poseidon2_external_value, + q_1_value, + q_2_value, + q_3_value, + q_4_value, + w_1_value, + w_2_value, + w_3_value, + w_4_value, + w_1_shifted_value, + w_2_shifted_value, + w_3_shifted_value, + w_4_shifted_value, + poseidon2_external_base, + alpha) + .is_zero()) { +#ifndef FUZZING + info("Poseidon2External identity fails at gate ", i); +#endif + result = false; + break; + } + if (!compute_poseidon2_internal_identity(q_poseidon2_internal_value, + q_1_value, + w_1_value, + w_2_value, + w_3_value, + w_4_value, + w_1_shifted_value, + w_2_shifted_value, + w_3_shifted_value, + w_4_shifted_value, + poseidon2_internal_base, + alpha) + .is_zero()) { +#ifndef FUZZING + info("Poseidon2Internal identity fails at gate ", i); +#endif + result = false; + break; + } + } + return result; +} + template class GoblinUltraCircuitBuilder_; } // namespace proof_system \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp index f4532a31895..af7ba39c8a5 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp @@ -43,6 +43,8 @@ template class GoblinUltraCircuitBuilder_ : public UltraCircuitBui WireVector& ecc_op_wire_4 = std::get<3>(ecc_op_wires); SelectorVector& q_busread = this->selectors.q_busread(); + SelectorVector& q_poseidon2_external = this->selectors.q_poseidon2_external(); + SelectorVector& q_poseidon2_internal = this->selectors.q_poseidon2_internal(); // DataBus call/return data arrays std::vector public_calldata; @@ -132,6 +134,39 @@ template class GoblinUltraCircuitBuilder_ : public UltraCircuitBui } public_calldata.emplace_back(witness_index); } + void create_poseidon2_external_gate(const poseidon2_external_gate_& in); + void create_poseidon2_internal_gate(const poseidon2_internal_gate_& in); + + FF compute_poseidon2_external_identity(FF q_poseidon2_external_value, + FF q_1_value, + FF q_2_value, + FF q_3_value, + FF q_4_value, + FF w_1_value, + FF w_2_value, + FF w_3_value, + FF w_4_value, + FF w_1_shifted_value, + FF w_2_shifted_value, + FF w_3_shifted_value, + FF w_4_shifted_value, + FF alpha_base, + FF alpha) const; + + FF compute_poseidon2_internal_identity(FF q_poseidon2_internal_value, + FF q_1_value, + FF w_1_value, + FF w_2_value, + FF w_3_value, + FF w_4_value, + FF w_1_shifted_value, + FF w_2_shifted_value, + FF w_3_shifted_value, + FF w_4_shifted_value, + FF alpha_base, + FF alpha) const; + + bool check_circuit(); }; extern template class GoblinUltraCircuitBuilder_; using GoblinUltraCircuitBuilder = GoblinUltraCircuitBuilder_; diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.test.cpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.test.cpp index 5d95b57e39a..7a3424626ae 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.test.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.test.cpp @@ -8,6 +8,15 @@ auto& engine = numeric::random::get_debug_engine(); } namespace proof_system { +TEST(GoblinUltraCircuitBuilder, BaseCase) +{ + GoblinUltraCircuitBuilder circuit_constructor = GoblinUltraCircuitBuilder(); + fr a = fr::one(); + circuit_constructor.add_public_variable(a); + bool result = circuit_constructor.check_circuit(); + EXPECT_EQ(result, true); +} + /** * @brief Test the queueing of simple ecc ops via the Goblin builder * @details There are two things to check here: 1) When ecc ops are queued by the builder, the corresponding native @@ -15,7 +24,7 @@ namespace proof_system { * encoded in the op_wires, i.e. the operands can be reconstructed as expected. * */ -TEST(UltraCircuitBuilder, GoblinSimple) +TEST(GoblinUltraCircuitBuilder, GoblinSimple) { const size_t CHUNK_SIZE = plonk::NUM_LIMB_BITS_IN_FIELD_SIMULATION * 2; @@ -81,7 +90,7 @@ TEST(UltraCircuitBuilder, GoblinSimple) * @brief Check that the ultra ops are recorded correctly in the EccOpQueue * */ -TEST(UltraCircuitBuilder, GoblinEccOpQueueUltraOps) +TEST(GoblinUltraCircuitBuilder, GoblinEccOpQueueUltraOps) { // Construct a simple circuit with op gates auto builder = GoblinUltraCircuitBuilder(); 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 42ef656b807..bb4278a7dea 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 @@ -3363,7 +3363,7 @@ template bool UltraCircuitBuilder_:: alpha) .is_zero()) { #ifndef FUZZING - info("Arithemtic identity fails at gate ", i); + info("Arithmetic identity fails at gate ", i); #endif result = false; break; 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 a8186c477dc..8f332551832 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 @@ -708,7 +708,7 @@ class UltraCircuitBuilder_ : public CircuitBuilderBase size imbalance between sorted and non-sorted sets. Checking for this + * gates. No arithmetic gate => size imbalance between sorted and non-sorted sets. Checking for this * and throwing an error would require a refactor of the Composer to catelog all 'orphan' variables not * assigned to gates. * diff --git a/barretenberg/cpp/src/barretenberg/relations/poseidon2_external_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/poseidon2_external_relation.hpp index aba162e56af..dc150d545ea 100644 --- a/barretenberg/cpp/src/barretenberg/relations/poseidon2_external_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/poseidon2_external_relation.hpp @@ -114,4 +114,4 @@ template class Poseidon2ExternalRelationImpl { }; template using Poseidon2ExternalRelation = Relation>; -} // namespace proof_system \ No newline at end of file +} // namespace proof_system diff --git a/barretenberg/cpp/src/barretenberg/relations/poseidon2_internal_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/poseidon2_internal_relation.hpp index 1ec20c0956b..e67ee8519d9 100644 --- a/barretenberg/cpp/src/barretenberg/relations/poseidon2_internal_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/poseidon2_internal_relation.hpp @@ -94,4 +94,4 @@ template class Poseidon2InternalRelationImpl { }; // namespace proof_system template using Poseidon2InternalRelation = Relation>; -} // namespace proof_system \ No newline at end of file +} // namespace proof_system diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp index 41924b71875..3a62affd0ac 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.cpp @@ -330,6 +330,8 @@ template void ProverInstance_::initialize_prover_polynomi prover_polynomials.lookup_inverses = proving_key->lookup_inverses; prover_polynomials.q_busread = proving_key->q_busread; prover_polynomials.databus_id = proving_key->databus_id; + prover_polynomials.q_poseidon2_external = proving_key->q_poseidon2_external; + prover_polynomials.q_poseidon2_internal = proving_key->q_poseidon2_internal; } // These polynomials have not yet been computed; initialize them so prover_polynomials is "full" and we can use diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp index 67848bfecd4..6dfcbe4c4eb 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp @@ -343,6 +343,8 @@ TEST_F(RelationCorrectnessTests, GoblinUltraRelationCorrectness) ensure_non_zero(proving_key->q_elliptic); ensure_non_zero(proving_key->q_aux); ensure_non_zero(proving_key->q_busread); + ensure_non_zero(proving_key->q_poseidon2_external); + ensure_non_zero(proving_key->q_poseidon2_internal); ensure_non_zero(proving_key->calldata); ensure_non_zero(proving_key->calldata_read_counts); diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.cpp index 50f34044c29..7f318aa98a3 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.cpp @@ -57,6 +57,8 @@ void UltraComposer_::compute_verification_key(const std::shared_ptrlagrange_ecc_op = commitment_key->commit(proving_key->lagrange_ecc_op); verification_key->q_busread = commitment_key->commit(proving_key->q_busread); verification_key->databus_id = commitment_key->commit(proving_key->databus_id); + verification_key->q_poseidon2_external = commitment_key->commit(proving_key->q_poseidon2_external); + verification_key->q_poseidon2_internal = commitment_key->commit(proving_key->q_poseidon2_internal); } instance->verification_key = std::move(verification_key);