Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Added stdlib::cycle_group class to barretenberg #1577

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,11 @@ template <typename FF> struct ecc_add_gate_ {
FF endomorphism_coefficient;
FF sign_coefficient;
};

kevaundray marked this conversation as resolved.
Show resolved Hide resolved
template <typename FF> struct ecc_dbl_gate_ {
uint32_t x1;
uint32_t y1;
uint32_t x3;
uint32_t y3;
};
} // namespace proof_system
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once
#include "barretenberg/common/slab_allocator.hpp"
#include "barretenberg/ecc/curves/bn254/fr.hpp"
#include "barretenberg/ecc/curves/grumpkin/grumpkin.hpp"
#include "barretenberg/proof_system/arithmetization/arithmetization.hpp"
#include "barretenberg/proof_system/arithmetization/gate_data.hpp"
#include <utility>
Expand All @@ -11,6 +12,9 @@ static constexpr uint32_t DUMMY_TAG = 0;
template <typename Arithmetization> class CircuitBuilderBase {
public:
using FF = typename Arithmetization::FF;
using EmbeddedCurve =
std::conditional_t<std::same_as<FF, barretenberg::g1::coordinate_field>, barretenberg::g1, grumpkin::g1>;

static constexpr size_t NUM_WIRES = Arithmetization::NUM_WIRES;
// Keeping NUM_WIRES, at least temporarily, for backward compatibility
static constexpr size_t program_width = Arithmetization::NUM_WIRES;
Expand Down Expand Up @@ -86,6 +90,9 @@ template <typename Arithmetization> class CircuitBuilderBase {
virtual void create_mul_gate(const mul_triple_<FF>& in) = 0;
virtual void create_bool_gate(const uint32_t a) = 0;
virtual void create_poly_gate(const poly_triple_<FF>& in) = 0;
virtual void create_ecc_add_gate(const ecc_add_gate_<FF>& in) = 0;
virtual void create_ecc_dbl_gate(const ecc_dbl_gate_<FF>& in) = 0;

virtual size_t get_num_constant_gates() const = 0;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,237 @@ template <typename FF> void StandardCircuitBuilder_<FF>::create_poly_gate(const
++this->num_gates;
}

/**
* @brief Create a gate where we validate an elliptic curve point addition
* (x1, y1) + (x2, y2) = (x3, y3)
* N.B. uses incomplete addition formula. Use with caution
kevaundray marked this conversation as resolved.
Show resolved Hide resolved
* @tparam FF
* @param in
*/
template <typename FF> void StandardCircuitBuilder_<FF>::create_ecc_add_gate(const ecc_add_gate_<FF>& in)
{
const auto sign_coefficient = in.sign_coefficient;
const auto x1 = this->get_variable(in.x1);
const auto x2 = this->get_variable(in.x2);
const auto x3 = this->get_variable(in.x3);
const auto y1 = this->get_variable(in.y1);
const auto y2 = sign_coefficient * this->get_variable(in.y2);

bool collision = x2 == x1;
kevaundray marked this conversation as resolved.
Show resolved Hide resolved
if (collision) {
this->failure("create_ecc_add_gate incomplete formula collision");
kevaundray marked this conversation as resolved.
Show resolved Hide resolved
}
const auto lambda_v = collision ? 0 : (y2 - y1) / (x2 - x1);
const auto lambda = this->add_variable(lambda_v);

// (x2 - x1) * lambda - y2 + y1 = 0
const auto x2_minus_x1_v = x2 - x1;
const auto x2_minus_x1 = this->add_variable(x2_minus_x1_v);
create_poly_gate({
.a = in.x2,
.b = in.x1,
.c = x2_minus_x1,
.q_m = 0,
.q_l = 1,
.q_r = -1,
.q_o = -1,
.q_c = 0,
});
const auto t2_v = lambda_v * x2_minus_x1_v;
const auto t2 = this->add_variable(t2_v);
create_poly_gate({
.a = lambda,
.b = x2_minus_x1,
.c = t2,
.q_m = 1,
.q_l = 0,
.q_r = 0,
.q_o = -1,
.q_c = 0,
});
create_poly_gate({
.a = t2,
.b = in.y2,
.c = in.y1,
.q_m = 0,
.q_l = 1,
.q_r = -sign_coefficient,
.q_o = 1,
.q_c = 0,
});

// lambda * lambda - x2 - x1 = x3
const auto x2_plus_x1_v = x2 + x1;
const auto x2_plus_x1 = this->add_variable(x2_plus_x1_v);
create_poly_gate({
.a = in.x2,
.b = in.x1,
.c = x2_plus_x1,
.q_m = 0,
.q_l = 1,
.q_r = 1,
.q_o = -1,
.q_c = 0,
});
const auto lambda_sqr_v = lambda_v * lambda_v;
const auto lambda_sqr = this->add_variable(lambda_sqr_v);
create_poly_gate({
.a = lambda,
.b = lambda,
.c = lambda_sqr,
.q_m = 1,
.q_l = 0,
.q_r = 0,
.q_o = -1,
.q_c = 0,
});
create_poly_gate({
.a = lambda_sqr,
.b = x2_plus_x1,
.c = in.x3,
.q_m = 0,
.q_l = 1,
.q_r = -1,
.q_o = -1,
.q_c = 0,
});

// lambda * (x1 - x3) - y1 - y3 = 0
const auto x1_sub_x3_v = x1 - x3;
const auto x1_sub_x3 = this->add_variable(x1_sub_x3_v);
create_poly_gate({
.a = in.x1,
.b = in.x3,
.c = x1_sub_x3,
.q_m = 0,
.q_l = 1,
.q_r = -1,
.q_o = -1,
.q_c = 0,
});
const auto lambda_mul_x1_sub_x3_v = lambda_v * x1_sub_x3_v;
const auto lambda_mul_x1_sub_x3 = this->add_variable(lambda_mul_x1_sub_x3_v);
create_poly_gate({
.a = lambda,
.b = x1_sub_x3,
.c = lambda_mul_x1_sub_x3,
.q_m = 1,
.q_l = 0,
.q_r = 0,
.q_o = -1,
.q_c = 0,
});
create_poly_gate({
.a = lambda_mul_x1_sub_x3,
.b = in.y1,
.c = in.y3,
.q_m = 0,
.q_l = 1,
.q_r = -1,
.q_o = -1,
.q_c = 0,
});
}

/**
* @brief Create a gate where we validate an elliptic curve point doubling
* (x1, y1) * 2 = (x3, y3)
kevaundray marked this conversation as resolved.
Show resolved Hide resolved
* @tparam FF
* @param in
*/
template <typename FF> void StandardCircuitBuilder_<FF>::create_ecc_dbl_gate(const ecc_dbl_gate_<FF>& in)
{
const auto x1 = this->get_variable(in.x1);
const auto x3 = this->get_variable(in.x3);
const auto y1 = this->get_variable(in.y1);

// lambda = 3x^2 / 2y
const auto three_x1_sqr_v = x1 * x1 * 3;
const auto three_x1_sqr = this->add_variable(three_x1_sqr_v);
create_poly_gate({
.a = in.x1,
.b = in.x1,
.c = three_x1_sqr,
.q_m = 3,
.q_l = 0,
.q_r = 0,
.q_o = -1,
.q_c = 0,
});
const auto lambda_v = three_x1_sqr_v / (y1 + y1);
const auto lambda = this->add_variable(lambda_v);
create_poly_gate({
.a = lambda,
.b = in.y1,
.c = three_x1_sqr,
.q_m = 2,
.q_l = 0,
.q_r = 0,
.q_o = -1,
.q_c = 0,
});

// lambda * lambda - x2 - x1 = 0
const auto lambda_sqr_v = lambda_v * lambda_v;
const auto lambda_sqr = this->add_variable(lambda_sqr_v);
create_poly_gate({
.a = lambda,
.b = lambda,
.c = lambda_sqr,
.q_m = 1,
.q_l = 0,
.q_r = 0,
.q_o = -1,
.q_c = 0,
});
create_poly_gate({
.a = lambda_sqr,
.b = in.x1,
.c = this->zero_idx,
.q_m = 0,
.q_l = 1,
.q_r = -2,
.q_o = 0,
.q_c = 0,
});

// lambda * (x1 - x3) - y1 = 0
const auto x1_sub_x3_v = x1 - x3;
const auto x1_sub_x3 = this->add_variable(x1_sub_x3_v);
create_poly_gate({
.a = in.x1,
.b = in.x3,
.c = x1_sub_x3,
.q_m = 0,
.q_l = 1,
.q_r = -1,
.q_o = -1,
.q_c = 0,
});
const auto lambda_mul_x1_sub_x3_v = lambda_v * x1_sub_x3_v;
const auto lambda_mul_x1_sub_x3 = this->add_variable(lambda_mul_x1_sub_x3_v);
create_poly_gate({
.a = lambda,
.b = x1_sub_x3,
.c = lambda_mul_x1_sub_x3,
.q_m = 1,
.q_l = 0,
.q_r = 0,
.q_o = -1,
.q_c = 0,
});
create_poly_gate({
.a = lambda_mul_x1_sub_x3,
.b = in.y1,
.c = in.y3,
.q_m = 0,
.q_l = 1,
.q_r = -1,
.q_o = -1,
.q_c = 0,
});
}

template <typename FF>
std::vector<uint32_t> StandardCircuitBuilder_<FF>::decompose_into_base4_accumulators(const uint32_t witness_index,
const size_t num_bits,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ template <typename FF> class StandardCircuitBuilder_ : public CircuitBuilderBase
void create_fixed_group_add_gate_with_init(const fixed_group_add_quad_<FF>& in,
const fixed_group_init_quad_<FF>& init);
void create_fixed_group_add_gate_final(const add_quad_<FF>& in);
void create_ecc_add_gate(const ecc_add_gate_<FF>& in) override;
void create_ecc_dbl_gate(const ecc_dbl_gate_<FF>& in) override;

fixed_group_add_quad_<FF> previous_add_quad;

Expand Down
Loading