Skip to content

Commit

Permalink
splitting goblin builder into its own class
Browse files Browse the repository at this point in the history
  • Loading branch information
ledwards2225 committed Sep 13, 2023
1 parent 9bb5889 commit 61cae4a
Show file tree
Hide file tree
Showing 22 changed files with 809 additions and 249 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ TEST_F(GoblinUltraHonkComposerTests, SingleCircuit)
// Add mock data to op queue to simulate interaction with a previous circuit
populate_ecc_op_queue_with_mock_data(op_queue);

auto builder = UltraCircuitBuilder(op_queue);
auto builder = GoblinUltraCircuitBuilder(op_queue);

generate_test_circuit(builder);

Expand Down Expand Up @@ -124,7 +124,7 @@ TEST_F(GoblinUltraHonkComposerTests, MultipleCircuits)

// Construct first circuit and its proof
{
auto builder = UltraCircuitBuilder(op_queue);
auto builder = GoblinUltraCircuitBuilder(op_queue);

generate_test_circuit(builder);
expected_op_queue_size += builder.num_ecc_op_gates;
Expand All @@ -139,7 +139,7 @@ TEST_F(GoblinUltraHonkComposerTests, MultipleCircuits)

// Construct second circuit
{
auto builder = UltraCircuitBuilder(op_queue);
auto builder = GoblinUltraCircuitBuilder(op_queue);

generate_test_circuit(builder);
expected_op_queue_size += builder.num_ecc_op_gates;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ void UltraComposer_<Flavor>::compute_circuit_size_parameters(CircuitBuilder& cir
// Get num conventional gates, num public inputs and num Goblin style ECC op gates
const size_t num_gates = circuit_constructor.num_gates;
num_public_inputs = circuit_constructor.public_inputs.size();
num_ecc_op_gates = circuit_constructor.num_ecc_op_gates;
num_ecc_op_gates = 0;
if constexpr (IsGoblinFlavor<Flavor>) {
num_ecc_op_gates = circuit_constructor.num_ecc_op_gates;
}

// minimum circuit size due to the length of lookups plus tables
const size_t minimum_circuit_size_due_to_lookups = tables_size + lookups_size + num_zero_rows;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#include "barretenberg/honk/pcs/kzg/kzg.hpp"
#include "barretenberg/honk/transcript/transcript.hpp"
#include "barretenberg/polynomials/univariate.hpp"
#include "barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp"
#include "barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp"
#include "barretenberg/proof_system/flavor/flavor.hpp"
#include "barretenberg/proof_system/relations/auxiliary_relation.hpp"
#include "barretenberg/proof_system/relations/ecc_op_queue_relation.hpp"
Expand All @@ -16,7 +16,7 @@ namespace proof_system::honk::flavor {

class GoblinUltra {
public:
using CircuitBuilder = UltraCircuitBuilder;
using CircuitBuilder = GoblinUltraCircuitBuilder;
using Curve = curve::BN254;
using PCS = pcs::kzg::KZG<Curve>;
using GroupElement = Curve::Element;
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ template <typename Curve> class GeminiProver_ {
const Fr& r_challenge);
}; // namespace proof_system::honk::pcs::gemini

template <typename Curve, bool goblin_flag = false> class GeminiVerifier_ {
template <typename Curve> class GeminiVerifier_ {
using Fr = typename Curve::ScalarField;
using GroupElement = typename Curve::Element;
using Commitment = typename Curve::AffineElement;
Expand Down Expand Up @@ -247,8 +247,8 @@ template <typename Curve, bool goblin_flag = false> class GeminiVerifier_ {
// TODO(#707): these batch muls include the use of 1 as a scalar. This is handled appropriately as a non-mul
// (add-accumulate) in the goblin batch_mul but is done inefficiently as a scalar mul in the conventional
// emulated batch mul.
C0_r_pos = GroupElement::template batch_mul<goblin_flag>(commitments, { one, r_inv });
C0_r_neg = GroupElement::template batch_mul<goblin_flag>(commitments, { one, -r_inv });
C0_r_pos = GroupElement::batch_mul(commitments, { one, r_inv });
C0_r_neg = GroupElement::batch_mul(commitments, { one, -r_inv });
} else {
C0_r_pos = batched_f;
C0_r_neg = batched_f;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

namespace proof_system::honk::pcs::kzg {

template <typename Curve, bool goblin_flag = false> class KZG {
template <typename Curve> class KZG {
using CK = CommitmentKey<Curve>;
using VK = VerifierCommitmentKey<Curve>;
using Fr = typename Curve::ScalarField;
Expand Down Expand Up @@ -88,7 +88,7 @@ template <typename Curve, bool goblin_flag = false> class KZG {
auto one = Fr(builder, 1);
std::vector<GroupElement> commitments = { claim.commitment, quotient_commitment };
std::vector<Fr> scalars = { one, claim.opening_pair.challenge };
P_0 = GroupElement::template batch_mul<goblin_flag>(commitments, scalars);
P_0 = GroupElement::batch_mul(commitments, scalars);
// Note: This implementation assumes the evaluation is zero (as is the case for shplonk).
ASSERT(claim.opening_pair.evaluation.get_value() == 0);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ template <typename Curve> class ShplonkProver_ {
* @brief Shplonk Verifier
*
*/
template <typename Curve, bool goblin_flag = false> class ShplonkVerifier_ {
template <typename Curve> class ShplonkVerifier_ {
using Fr = typename Curve::ScalarField;
using GroupElement = typename Curve::Element;
using Commitment = typename Curve::AffineElement;
Expand Down Expand Up @@ -231,7 +231,7 @@ template <typename Curve, bool goblin_flag = false> class ShplonkVerifier_ {
scalars.emplace_back(G_commitment_constant);

// [G] += G₀⋅[1] = [G] + (∑ⱼ ρʲ ⋅ vⱼ / ( r − xⱼ ))⋅[1]
G_commitment = GroupElement::template batch_mul<goblin_flag>(commitments, scalars);
G_commitment = GroupElement::batch_mul(commitments, scalars);

} else {
// [G] = [Q] - ∑ⱼ ρʲ / ( r − xⱼ )⋅[fⱼ] + G₀⋅[1]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ TEST_F(RelationCorrectnessTests, GoblinUltraRelationCorrectness)

// Create a composer and then add an assortment of gates designed to ensure that the constraint(s) represented
// by each relation are non-trivially exercised.
auto builder = UltraCircuitBuilder();
auto builder = GoblinUltraCircuitBuilder();

// Create an assortment of representative gates
create_some_add_gates<Flavor>(builder);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
#include "goblin_ultra_circuit_builder.hpp"
#include <barretenberg/plonk/proof_system/constants.hpp>
#include <unordered_map>
#include <unordered_set>

using namespace barretenberg;

namespace proof_system {

template <typename FF> void GoblinUltraCircuitBuilder_<FF>::finalize_circuit()
{
UltraCircuitBuilder_<FF>::finalize_circuit();

// Set internally the current and previous size of the aggregate op queue transcript
op_queue->set_size_data();
}

/**
* @brief Ensure all polynomials have at least one non-zero coefficient to avoid commiting to the zero-polynomial
*
* @param in Structure containing variables and witness selectors
*/
// TODO(#423): This function adds valid (but arbitrary) gates to ensure that the circuit which includes
// them will not result in any zero-polynomials. It also ensures that the first coefficient of the wire
// polynomials is zero, which is required for them to be shiftable.
// TODO(luke): Add ECC op gate to ensure op wires are non-zero?
template <typename FF> void GoblinUltraCircuitBuilder_<FF>::add_gates_to_ensure_all_polys_are_non_zero()
{
UltraCircuitBuilder_<FF>::add_gates_to_ensure_all_polys_are_non_zero();
}

/**
* @brief Add gates for simple point addition without scalar and compute corresponding op natively
*
* @param point
*/
template <typename FF>
ecc_op_tuple GoblinUltraCircuitBuilder_<FF>::queue_ecc_add_accum(const barretenberg::g1::affine_element& point)
{
// Add raw op to queue
op_queue->add_accumulate(point);

// Decompose operation inputs into width-four form and add ecc op gates
auto op_tuple = decompose_ecc_operands(add_accum_op_idx, point);
populate_ecc_op_wires(op_tuple);

return op_tuple;
}

/**
* @brief Add gates for point mul and add and compute corresponding op natively
*
* @tparam FF
* @param point
* @param scalar
* @return ecc_op_tuple encoding the point and scalar inputs to the mul accum
*/
template <typename FF>
ecc_op_tuple GoblinUltraCircuitBuilder_<FF>::queue_ecc_mul_accum(const barretenberg::g1::affine_element& point,
const FF& scalar)
{
// Add raw op to op queue
op_queue->mul_accumulate(point, scalar);

// Decompose operation inputs into width-four form and add ecc op gates
auto op_tuple = decompose_ecc_operands(mul_accum_op_idx, point, scalar);
populate_ecc_op_wires(op_tuple);

return op_tuple;
}

/**
* @brief Add point equality gates
*
* @return ecc_op_tuple encoding the point to which equality has been asserted
*/
template <typename FF> ecc_op_tuple GoblinUltraCircuitBuilder_<FF>::queue_ecc_eq()
{
// Add raw op to op queue
auto point = op_queue->eq();

// Decompose operation inputs into width-four form and add ecc op gates
auto op_tuple = decompose_ecc_operands(equality_op_idx, point);
populate_ecc_op_wires(op_tuple);

return op_tuple;
}

/**
* @brief Decompose ecc operands into components, add corresponding variables, return ecc op tuple
*
* @param op_idx Index of op code in variables array
* @param point
* @param scalar
* @return ecc_op_tuple Tuple of indices into variables array used to construct pair of ecc op gates
*/
template <typename FF>
ecc_op_tuple GoblinUltraCircuitBuilder_<FF>::decompose_ecc_operands(uint32_t op_idx, const g1::affine_element& point, const FF& scalar)
{
// Decompose point coordinates (Fq) into hi-lo chunks (Fr)
const size_t CHUNK_SIZE = 2 * DEFAULT_NON_NATIVE_FIELD_LIMB_BITS;
auto x_256 = uint256_t(point.x);
auto y_256 = uint256_t(point.y);
auto x_lo = FF(x_256.slice(0, CHUNK_SIZE));
auto x_hi = FF(x_256.slice(CHUNK_SIZE, CHUNK_SIZE * 2));
auto y_lo = FF(y_256.slice(0, CHUNK_SIZE));
auto y_hi = FF(y_256.slice(CHUNK_SIZE, CHUNK_SIZE * 2));

// Split scalar into 128 bit endomorphism scalars
FF z_1 = 0;
FF z_2 = 0;
auto converted = scalar.from_montgomery_form();
FF::split_into_endomorphism_scalars(converted, z_1, z_2);
z_1 = z_1.to_montgomery_form();
z_2 = z_2.to_montgomery_form();

// Populate ultra ops in OpQueue with the decomposed operands
op_queue->ultra_ops[0].emplace_back(this->variables[op_idx]);
op_queue->ultra_ops[1].emplace_back(x_lo);
op_queue->ultra_ops[2].emplace_back(x_hi);
op_queue->ultra_ops[3].emplace_back(y_lo);

op_queue->ultra_ops[0].emplace_back(this->variables[op_idx]);
op_queue->ultra_ops[1].emplace_back(y_hi);
op_queue->ultra_ops[2].emplace_back(z_1);
op_queue->ultra_ops[3].emplace_back(z_2);

// Add variables for decomposition and get indices needed for op wires
auto x_lo_idx = this->add_variable(x_lo);
auto x_hi_idx = this->add_variable(x_hi);
auto y_lo_idx = this->add_variable(y_lo);
auto y_hi_idx = this->add_variable(y_hi);
auto z_1_idx = this->add_variable(z_1);
auto z_2_idx = this->add_variable(z_2);

return { op_idx, x_lo_idx, x_hi_idx, y_lo_idx, y_hi_idx, z_1_idx, z_2_idx };
}

/**
* @brief Add ecc operation to queue
*
* @param in Variables array indices corresponding to operation inputs
* @note We dont explicitly set values for the selectors here since their values are fully determined by
* num_ecc_op_gates. E.g. in the composer we can reconstruct q_ecc_op as the indicator on the first num_ecc_op_gates
* indices. All other selectors are simply 0 on this domain.
*/
template <typename FF> void GoblinUltraCircuitBuilder_<FF>::populate_ecc_op_wires(const ecc_op_tuple& in)
{
ecc_op_wire_1.emplace_back(in.op);
ecc_op_wire_2.emplace_back(in.x_lo);
ecc_op_wire_3.emplace_back(in.x_hi);
ecc_op_wire_4.emplace_back(in.y_lo);

ecc_op_wire_1.emplace_back(in.op); // TODO(luke): second op val is sort of a dummy. use "op" again?
ecc_op_wire_2.emplace_back(in.y_hi);
ecc_op_wire_3.emplace_back(in.z_1);
ecc_op_wire_4.emplace_back(in.z_2);

num_ecc_op_gates += 2;
};

template class GoblinUltraCircuitBuilder_<barretenberg::fr>;
} // namespace proof_system
Loading

0 comments on commit 61cae4a

Please sign in to comment.