9#include "../bigfield/bigfield.hpp"
10#include "../bigfield/goblin_field.hpp"
11#include "../circuit_builders/circuit_builders_fwd.hpp"
12#include "../field/field.hpp"
13#include "../memory/rom_table.hpp"
14#include "../memory/twin_rom_table.hpp"
38template <
class Builder_,
class Fq,
class Fr,
class NativeGroup>
class goblin_element {
86 const std::string msg =
"goblin_element::incomplete_assert_equal")
const
89 _x.assert_equal(other.
_x, msg +
" (x coordinate)");
90 _y.assert_equal(other.
_y, msg +
" (y coordinate)");
97 if (input.is_point_at_infinity()) {
103 Fq x = Fq::from_witness(ctx, input.x);
104 Fq y = Fq::from_witness(ctx, input.y);
118 this->
_x.convert_constant_to_fixed_witness(builder);
119 this->
_y.convert_constant_to_fixed_witness(builder);
129 this->
_x.fix_witness();
130 this->
_y.fix_witness();
152 Fr zero = Fr::from_witness_index(ctx, ctx->zero_idx());
153 zero.unset_free_witness_tag();
177 typename NativeGroup::affine_element result_value =
typename NativeGroup::affine_element(
178 typename NativeGroup::element(
get_value()) -
typename NativeGroup::element(other.
get_value()));
183 auto x_lo = Fr::from_witness_index(
builder, op_tuple.
x_lo);
184 auto x_hi = Fr::from_witness_index(
builder, op_tuple.
x_hi);
185 auto y_lo = Fr::from_witness_index(
builder, op_tuple.
y_lo);
186 auto y_hi = Fr::from_witness_index(
builder, op_tuple.
y_hi);
187 x_lo.assert_equal(other.
_x.limbs[0]);
188 x_hi.assert_equal(other.
_x.limbs[1]);
189 y_lo.assert_equal(other.
_y.limbs[0]);
190 y_hi.assert_equal(other.
_y.limbs[1]);
195 builder->update_used_witnesses({ op_tuple.
z_1, op_tuple.
z_2 });
198 auto x_lo = Fr::from_witness_index(
builder, op_tuple2.
x_lo);
199 auto x_hi = Fr::from_witness_index(
builder, op_tuple2.
x_hi);
200 auto y_lo = Fr::from_witness_index(
builder, op_tuple2.
y_lo);
201 auto y_hi = Fr::from_witness_index(
builder, op_tuple2.
y_hi);
206 builder->update_used_witnesses({ op_tuple2.
z_1, op_tuple2.
z_2 });
208 Fq result_x(x_lo, x_hi);
209 Fq result_y(y_lo, y_hi);
214 auto op2_is_infinity = (x_lo.add_two(x_hi, y_lo) + y_hi).is_zero();
218 auto x_lo = Fr::from_witness_index(
builder, op_tuple3.
x_lo);
219 auto x_hi = Fr::from_witness_index(
builder, op_tuple3.
x_hi);
220 auto y_lo = Fr::from_witness_index(
builder, op_tuple3.
y_lo);
221 auto y_hi = Fr::from_witness_index(
builder, op_tuple3.
y_hi);
223 x_lo.assert_equal(
_x.limbs[0]);
224 x_hi.assert_equal(
_x.limbs[1]);
225 y_lo.assert_equal(
_y.limbs[0]);
226 y_hi.assert_equal(
_y.limbs[1]);
242 *
this = *
this + other;
247 *
this = *
this - other;
261 result.
_y = Fq::conditional_assign(predicate, negated.
_y, result.
_y);
275 result.
_x = Fq::conditional_assign(predicate, other.
_x, result.
_x);
276 result.
_y = Fq::conditional_assign(predicate, other.
_y, result.
_y);
304 const std::vector<Fr>& scalars,
305 const size_t max_num_bits = 0,
306 const bool handle_edge_cases =
false,
307 const Fr& masking_scalar =
Fr(1));
316 auto result =
typename NativeGroup::affine_element(x_val, y_val);
318 result.self_set_infinity();
325 if (
_x.get_context() !=
nullptr) {
326 return _x.get_context();
328 if (
_y.get_context() !=
nullptr) {
329 return _y.get_context();
336 if (
_x.get_context() !=
nullptr) {
337 return _x.get_context();
339 if (
_y.get_context() !=
nullptr) {
340 return _y.get_context();
342 if (other.
_x.get_context() !=
nullptr) {
343 return other.
_x.get_context();
345 if (other.
_y.get_context() !=
nullptr) {
346 return other.
_y.get_context();
365 result.
_x = Fq::conditional_assign(is_infinity, zero, result.
_x);
366 result.
_y = Fq::conditional_assign(is_infinity, zero, result.
_y);
377 _x.set_origin_tag(
tag);
378 _y.set_origin_tag(
tag);
387 _x.set_free_witness_tag();
388 _y.set_free_witness_tag();
397 _x.unset_free_witness_tag();
398 _y.unset_free_witness_tag();
412 const uint32_t start_idx =
_x.set_public();
453template <
typename C,
typename Fq,
typename Fr,
typename G>
456 return os <<
"{ " << v.
x() <<
" , " << v.
y() <<
" }";
#define BB_ASSERT(expression,...)
group class. Represents an elliptic curve group element. Group is parametrised by Fq and Fr
Implements boolean logic in-circuit.
void set_origin_tag(const OriginTag &new_tag) const
void set_free_witness_tag()
static bool_t conditional_assign(const bool_t< Builder > &predicate, const bool_t &lhs, const bool_t &rhs)
Conditionally assign lhs or rhs based on predicate, always returns normalized result.
void unset_free_witness_tag()
void assert_equal(const bool_t &rhs, std::string const &msg="bool_t::assert_equal") const
Implements copy constraint for bool_t elements.
OriginTag get_origin_tag() const
Custom element class for when using goblin.
bool_ct is_point_at_infinity() const
goblin_element operator+(const goblin_element &other) const
goblin_element normalize() const
void set_origin_tag(const OriginTag &tag) const
goblin_element operator-(const goblin_element &other) const
goblin_element conditional_negate(const bool_ct &predicate) const
goblin_element(const Fq &x, const Fq &y, const bool_ct is_infinity, bool assert_on_curve=true)
OriginTag get_origin_tag() const
goblin_element checked_unconditional_add(const goblin_element &other) const
goblin_element conditional_select(const goblin_element &other, const bool_ct &predicate) const
Selects this if predicate is false, other if predicate is true.
Builder * get_context() const
static goblin_element one(Builder *ctx)
static goblin_element batch_mul(const std::vector< goblin_element > &points, const std::vector< Fr > &scalars, const size_t max_num_bits=0, const bool handle_edge_cases=false, const Fr &masking_scalar=Fr(1))
Goblin style batch multiplication.
goblin_element operator*(const Fr &scalar) const
uint32_t set_public() const
Set the witness indices representing the goblin element to public.
goblin_element(goblin_element &&other) noexcept=default
std::array< goblin_element, 2 > checked_unconditional_add_sub(const goblin_element &other) const
goblin_element checked_unconditional_subtract(const goblin_element &other) const
goblin_element operator+=(const goblin_element &other)
void incomplete_assert_equal(const goblin_element &other, const std::string msg="goblin_element::incomplete_assert_equal") const
Asserts that two goblin elements are equal (i.e., x, y coordinates and infinity flag are all equal).
NativeGroup::affine_element get_value() const
void set_free_witness_tag()
Set the free witness flag for the goblin element's tags.
void convert_constant_to_fixed_witness(Builder *builder)
Creates fixed witnesses from a constant element.
goblin_element reduce() const
goblin_element get_standard_form() const
Enforce x and y coordinates of a point to be (0,0) in the case of point at infinity.
goblin_element dbl() const
goblin_element operator-() const
static goblin_element reconstruct_from_public(const std::span< const Fr, PUBLIC_INPUTS_SIZE > &limbs)
Reconstruct a goblin element from its representation as limbs stored in the public inputs.
goblin_element(const Fq &x, const Fq &y, bool assert_on_curve=true)
~goblin_element()=default
Builder * get_context(const goblin_element &other) const
static goblin_element point_at_infinity(Builder *ctx)
goblin_element(const typename NativeGroup::affine_element &input)
goblin_element operator-=(const goblin_element &other)
void validate_on_curve() const
goblin_element & operator=(const goblin_element &other)=default
static goblin_element from_witness(Builder *ctx, const typename NativeGroup::affine_element &input)
void unset_free_witness_tag()
Unset the free witness flag for the goblin element's tags.
static constexpr size_t PUBLIC_INPUTS_SIZE
goblin_element & operator=(goblin_element &&other) noexcept=default
void set_point_at_infinity(const bool_ct &is_infinity)
goblin_element(const goblin_element &other)=default
goblin_field wraps x/y coordinates of bn254 group elements when using goblin
std::ostream & operator<<(std::ostream &os, goblin_element< C, Fq, Fr, G > const &v)
MegaCircuitBuilder_< field< Bn254FrParams > > MegaCircuitBuilder
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
This file contains part of the logic for the Origin Tag mechanism that tracks the use of in-circuit p...
static constexpr size_t PUBLIC_INPUTS_SIZE
static field reconstruct_from_public(const std::span< const field< V >, PUBLIC_INPUTS_SIZE > &limbs)
static constexpr field zero()
curve::BN254::BaseField Fq