Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
bb::stdlib::field_t< Builder_ > Class Template Reference

#include <field.hpp>

Public Types

using Builder = Builder_
 
using View = field_t
 
using CoefficientAccumulator = field_t
 
using native = bb::fr
 

Public Member Functions

 field_t (Builder *parent_context=nullptr)
 
 field_t (Builder *parent_context, const bb::fr &value)
 
 field_t (const int value)
 
 field_t (const unsigned long long value)
 
 field_t (const unsigned int value)
 
 field_t (const unsigned long value)
 
 field_t (const bb::fr &value)
 
 field_t (const uint256_t &value)
 
 field_t (const witness_t< Builder > &value)
 
 field_t (const field_t &other)
 
 field_t (field_t &&other) noexcept
 
 field_t (const bool_t< Builder > &other)
 
 ~field_t ()=default
 
 operator bool_t< Builder > () const
 Convert field_t element to bool_t and enforce bool constraints.
 
field_toperator= (const field_t &other)
 
field_toperator= (field_t &&other) noexcept
 
field_t operator+ (const field_t &other) const
 Field addition operator.
 
field_t operator- (const field_t &other) const
 Subtraction operator deduced from the addition operator.
 
field_t operator* (const field_t &other) const
 Field multiplication operator.
 
field_t operator/ (const field_t &other) const
 Since in divide_no_zero_check, we check \( a / b = q \) by the constraint \( a = b \cdot q\), if \( a = b= 0\), we can set \( q \) to any value and it will pass the constraint. Hence, when not having prior knowledge of \( b \) not being zero it is essential to check.
 
bool_t< Builderoperator== (const field_t &other) const
 Compute a bool_t equal to (a == b)
 
bool_t< Builderoperator!= (const field_t &other) const
 Compute a bool_t equal to (a != b)
 
field_t divide_no_zero_check (const field_t &other) const
 Given field elements a = *this and b = other, output a / b without checking whether b = 0.
 
field_t sqr () const
 
field_t pow (const uint32_t &exponent) const
 Raise this field element to the power of the provided uint32_t exponent.
 
field_t pow (const field_t &exponent) const
 Raise a field_t to a power of an exponent (field_t). Note that the exponent must not exceed 32 bits and is implicitly range constrained.
 
field_t operator+= (const field_t &other)
 
field_t operator-= (const field_t &other)
 
field_t operator*= (const field_t &other)
 
field_t operator/= (const field_t &other)
 
field_toperator++ ()
 
field_t operator++ (const int)
 
field_t invert () const
 
field_t operator- () const
 
void set_origin_tag (const OriginTag &new_tag) const
 
OriginTag get_origin_tag () const
 
void set_free_witness_tag ()
 Set the free witness flag for the field element's tag.
 
void unset_free_witness_tag () const
 Unset the free witness flag for the field element's tag.
 
void clear_round_provenance () const
 
field_t conditional_negate (const bool_t< Builder > &predicate) const
 If predicate's value == true, negate the value, else keep it unchanged.
 
void assert_equal (const field_t &rhs, std::string const &msg="field_t::assert_equal") const
 Copy constraint: constrain that *this field is equal to rhs element.
 
void assert_not_equal (const field_t &rhs, std::string const &msg="field_t::assert_not_equal") const
 Constrain *this to be not equal to rhs.
 
void assert_is_in_set (const std::vector< field_t > &set, std::string const &msg="field_t::assert_not_in_set") const
 Constrain *this \in set by enforcing that P(X) = \prod_{s \in set} (X - s) is 0 at X = *this.
 
field_t madd (const field_t &to_mul, const field_t &to_add) const
 
field_t add_two (const field_t &add_b, const field_t &add_c) const
 Efficiently compute (this + a + b) using big_mul gate.
 
field_t normalize () const
 Return a new element, where the in-circuit witness contains the actual represented value (multiplicative constant is 1 and additive_constant is 0)
 
bb::fr get_value () const
 Given a := *this, compute its value given by a.v * a.mul + a.add.
 
Builderget_context () const
 
std::pair< field_t< Builder >, field_t< Builder > > no_wrap_split_at (const size_t lsb_index, const size_t num_bits=grumpkin::MAX_NO_WRAP_INTEGER_BIT_LENGTH) const
 Splits the field element into (lo, hi), where:
 
bool_t< Builderis_zero () const
 Validate whether a field_t element is zero.
 
void create_range_constraint (size_t num_bits, std::string const &msg="field_t::range_constraint") const
 Let x = *this.normalize(), constrain x.v < 2^{num_bits}.
 
void assert_is_not_zero (std::string const &msg="field_t::assert_is_not_zero") const
 Constrain *this to be non-zero by establishing that it has an inverse.
 
void assert_is_zero (std::string const &msg="field_t::assert_is_zero") const
 Enforce a copy constraint between *this and 0 stored at zero_idx of the Builder.
 
bool is_constant () const
 
bool is_normalized () const
 
uint32_t set_public () const
 
void convert_constant_to_fixed_witness (Builder *ctx)
 
void fix_witness ()
 
uint32_t get_witness_index () const
 Get the witness index of the current field element.
 
template<size_t num_bits>
bool_t< Builderranged_less_than (const field_t< Builder > &other) const
 Return (a < b) as bool circuit type. This method assumes that both a and b are < 2^{num_bits} i.e. it is not checked here, we assume this has been done previously.
 

Static Public Member Functions

static field_t from_witness_index (Builder *ctx, uint32_t witness_index)
 
static field_t copy_as_new_witness (Builder &context, field_t const &other)
 
static field_t conditional_assign_internal (const bool_t< Builder > &predicate, const field_t &lhs, const field_t &rhs)
 If predicate == true then return lhs, else return rhs.
 
static field_t conditional_assign (const bool_t< Builder > &predicate, const field_t &lhs, const field_t &rhs)
 
static std::array< field_t, 4 > preprocess_two_bit_table (const field_t &T0, const field_t &T1, const field_t &T2, const field_t &T3)
 Given a table T of size 4, outputs the monomial coefficients of the multilinear polynomial in t0, t1 that on a input binary string b of length 2, equals T_b. In the Lagrange basis, the desired polynomial is given by the formula (1 - t0)(1 - t1).T0 + t0(1 - t1).T1 + (1 - t0)t1.T2 + t0.t1.T3.
 
static field_t select_from_two_bit_table (const std::array< field_t, 4 > &table, const bool_t< Builder > &t1, const bool_t< Builder > &t0)
 Given a multilinear polynomial in 2 variables, which is represented by a table of monomial coefficients, compute its evaluation at the point (t0, t1) using minimal number of gates.
 
static std::array< field_t, 8 > preprocess_three_bit_table (const field_t &T0, const field_t &T1, const field_t &T2, const field_t &T3, const field_t &T4, const field_t &T5, const field_t &T6, const field_t &T7)
 Given a table T of size 8, outputs the monomial coefficients of the multilinear polynomial in t0, t1, t2, that on a input binary string b of length 3, equals T_b.
 
static field_t select_from_three_bit_table (const std::array< field_t, 8 > &table, const bool_t< Builder > &t2, const bool_t< Builder > &t1, const bool_t< Builder > &t0)
 Given a multilinear polynomial in 3 variables, which is represented by a table of monomial coefficients, compute its evaluation at (t0, t1, t2) using minimal number of gates.
 
static void evaluate_linear_identity (const field_t &a, const field_t &b, const field_t &c, const field_t &d, const std::string &msg="field_t::evaluate_linear_identity")
 Constrain a + b + c + d to be equal to 0.
 
static void evaluate_polynomial_identity (const field_t &a, const field_t &b, const field_t &c, const field_t &d, const std::string &msg="field_t::evaluate_polynomial_identity")
 Given a, b, c, d, constrain a * b + c + d = 0 by creating a big_mul_gate.
 
static field_t accumulate (const std::vector< field_t > &input)
 Efficiently compute the sum of vector entries. Using big_add_gate we reduce the number of gates needed to compute from input.size() to input_size.size() / 3.
 
static field_t from_witness (Builder *ctx, const bb::fr &input)
 
template<typename T >
static field_t from_witness (Builder *ctx, const T &input)=delete
 
static field_t reconstruct_from_public (const std::span< const field_t, PUBLIC_INPUTS_SIZE > &limbs)
 
static bool witness_indices_match (const field_t &a, const field_t &b)
 Check if two field elements have the same witness index (for identity checks).
 

Public Attributes

Buildercontext = nullptr
 
bb::fr additive_constant
 
bb::fr multiplicative_constant
 
OriginTag tag {}
 

Static Public Attributes

static constexpr size_t PUBLIC_INPUTS_SIZE = FR_PUBLIC_INPUTS_SIZE
 
static constexpr bool is_composite = false
 
static constexpr uint256_t modulus = bb::fr::modulus
 

Private Attributes

uint32_t witness_index = IS_CONSTANT
 

Friends

template<typename B >
class bool_t
 
template<typename B , typename T >
class bigfield
 
template<typename B >
void mark_witness_as_used (const field_t< B > &field)
 

Detailed Description

template<typename Builder_>
class bb::stdlib::field_t< Builder_ >

Definition at line 45 of file field.hpp.

Member Typedef Documentation

◆ Builder

template<typename Builder_ >
using bb::stdlib::field_t< Builder_ >::Builder = Builder_

Definition at line 47 of file field.hpp.

◆ CoefficientAccumulator

template<typename Builder_ >
using bb::stdlib::field_t< Builder_ >::CoefficientAccumulator = field_t

Definition at line 562 of file field.hpp.

◆ native

template<typename Builder_ >
using bb::stdlib::field_t< Builder_ >::native = bb::fr

Definition at line 565 of file field.hpp.

◆ View

template<typename Builder_ >
using bb::stdlib::field_t< Builder_ >::View = field_t

Definition at line 561 of file field.hpp.

Constructor & Destructor Documentation

◆ field_t() [1/12]

template<typename Builder >
bb::stdlib::field_t< Builder >::field_t ( Builder parent_context = nullptr)

Definition at line 20 of file field.cpp.

◆ field_t() [2/12]

template<typename Builder >
bb::stdlib::field_t< Builder >::field_t ( Builder parent_context,
const bb::fr value 
)

Definition at line 38 of file field.cpp.

◆ field_t() [3/12]

template<typename Builder_ >
bb::stdlib::field_t< Builder_ >::field_t ( const int  value)
inline

Definition at line 152 of file field.hpp.

◆ field_t() [4/12]

template<typename Builder_ >
bb::stdlib::field_t< Builder_ >::field_t ( const unsigned long long  value)
inline

Definition at line 160 of file field.hpp.

◆ field_t() [5/12]

template<typename Builder_ >
bb::stdlib::field_t< Builder_ >::field_t ( const unsigned int  value)
inline

Definition at line 167 of file field.hpp.

◆ field_t() [6/12]

template<typename Builder_ >
bb::stdlib::field_t< Builder_ >::field_t ( const unsigned long  value)
inline

Definition at line 176 of file field.hpp.

◆ field_t() [7/12]

template<typename Builder_ >
bb::stdlib::field_t< Builder_ >::field_t ( const bb::fr value)
inline

Definition at line 184 of file field.hpp.

◆ field_t() [8/12]

template<typename Builder_ >
bb::stdlib::field_t< Builder_ >::field_t ( const uint256_t value)
inline

Definition at line 192 of file field.hpp.

◆ field_t() [9/12]

template<typename Builder >
bb::stdlib::field_t< Builder >::field_t ( const witness_t< Builder > &  value)

Definition at line 28 of file field.cpp.

◆ field_t() [10/12]

template<typename Builder_ >
bb::stdlib::field_t< Builder_ >::field_t ( const field_t< Builder_ > &  other)
inline

Definition at line 202 of file field.hpp.

◆ field_t() [11/12]

template<typename Builder_ >
bb::stdlib::field_t< Builder_ >::field_t ( field_t< Builder_ > &&  other)
inlinenoexcept

Definition at line 211 of file field.hpp.

◆ field_t() [12/12]

template<typename Builder >
bb::stdlib::field_t< Builder >::field_t ( const bool_t< Builder > &  other)

Definition at line 46 of file field.cpp.

◆ ~field_t()

template<typename Builder_ >
bb::stdlib::field_t< Builder_ >::~field_t ( )
default

Member Function Documentation

◆ accumulate()

template<typename Builder >
field_t< Builder > bb::stdlib::field_t< Builder >::accumulate ( const std::vector< field_t< Builder_ > > &  input)
static

Efficiently compute the sum of vector entries. Using big_add_gate we reduce the number of gates needed to compute from input.size() to input_size.size() / 3.

Note that if the size of the input vector is not a multiple of 3, the final gate will be padded with zero_idx wires

Definition at line 1167 of file field.cpp.

◆ add_two()

template<typename Builder >
field_t< Builder > bb::stdlib::field_t< Builder >::add_two ( const field_t< Builder_ > &  add_b,
const field_t< Builder_ > &  add_c 
) const

Efficiently compute (this + a + b) using big_mul gate.

Definition at line 575 of file field.cpp.

◆ assert_equal()

template<typename Builder >
void bb::stdlib::field_t< Builder >::assert_equal ( const field_t< Builder_ > &  rhs,
std::string const &  msg = "field_t< Builder_ >::assert_equal" 
) const

Copy constraint: constrain that *this field is equal to rhs element.

Warning
: After calling this method, both field values will be equal, regardless of whether the constraint succeeds or fails. This can lead to confusion when debugging. If you want to log the inputs, do so before calling this method.

Definition at line 930 of file field.cpp.

◆ assert_is_in_set()

template<typename Builder >
void bb::stdlib::field_t< Builder >::assert_is_in_set ( const std::vector< field_t< Builder_ > > &  set,
std::string const &  msg = "field_t< Builder_ >::assert_not_in_set" 
) const

Constrain *this \in set by enforcing that P(X) = \prod_{s \in set} (X - s) is 0 at X = *this.

Definition at line 985 of file field.cpp.

◆ assert_is_not_zero()

template<typename Builder >
void bb::stdlib::field_t< Builder >::assert_is_not_zero ( std::string const &  msg = "field_t< Builder_ >::assert_is_not_zero") const

Constrain *this to be non-zero by establishing that it has an inverse.

Definition at line 710 of file field.cpp.

◆ assert_is_zero()

template<typename Builder >
void bb::stdlib::field_t< Builder >::assert_is_zero ( std::string const &  msg = "field_t< Builder_ >::assert_is_zero") const

Enforce a copy constraint between *this and 0 stored at zero_idx of the Builder.

Definition at line 679 of file field.cpp.

◆ assert_not_equal()

template<typename Builder >
void bb::stdlib::field_t< Builder >::assert_not_equal ( const field_t< Builder_ > &  rhs,
std::string const &  msg = "field_t< Builder_ >::assert_not_equal" 
) const

Constrain *this to be not equal to rhs.

Definition at line 975 of file field.cpp.

◆ clear_round_provenance()

template<typename Builder_ >
void bb::stdlib::field_t< Builder_ >::clear_round_provenance ( ) const
inline

Definition at line 358 of file field.hpp.

◆ conditional_assign()

template<typename Builder_ >
static field_t bb::stdlib::field_t< Builder_ >::conditional_assign ( const bool_t< Builder > &  predicate,
const field_t< Builder_ > &  lhs,
const field_t< Builder_ > &  rhs 
)
inlinestatic

Definition at line 372 of file field.hpp.

◆ conditional_assign_internal()

template<typename Builder >
field_t< Builder > bb::stdlib::field_t< Builder >::conditional_assign_internal ( const bool_t< Builder > &  predicate,
const field_t< Builder_ > &  lhs,
const field_t< Builder_ > &  rhs 
)
static

If predicate == true then return lhs, else return rhs.

Conditional assign x = (predicate) ? lhs : rhs can be expressed arithmetically as follows x = predciate * lhs + (1 - predicate) * rhs which is equivalent to x = (lhs - rhs) * predicate + rhs = (lhs - rhs)*madd(predicate, rhs) where take advantage of madd() to create less gates.

Returns
field_t<Builder>

Definition at line 885 of file field.cpp.

◆ conditional_negate()

template<typename Builder >
field_t< Builder > bb::stdlib::field_t< Builder >::conditional_negate ( const bool_t< Builder > &  predicate) const

If predicate's value == true, negate the value, else keep it unchanged.

Definition at line 859 of file field.cpp.

◆ convert_constant_to_fixed_witness()

template<typename Builder_ >
void bb::stdlib::field_t< Builder_ >::convert_constant_to_fixed_witness ( Builder ctx)
inline

Create a witness from a constant. This way the value of the witness is fixed and public (public, because the value becomes hard-coded as an element of the q_c selector vector).

Definition at line 444 of file field.hpp.

◆ copy_as_new_witness()

template<typename Builder_ >
static field_t bb::stdlib::field_t< Builder_ >::copy_as_new_witness ( Builder context,
field_t< Builder_ > const &  other 
)
inlinestatic

Definition at line 254 of file field.hpp.

◆ create_range_constraint()

template<typename Builder >
void bb::stdlib::field_t< Builder >::create_range_constraint ( size_t  num_bits,
std::string const &  msg = "field_t< Builder_ >::range_constraint" 
) const

Let x = *this.normalize(), constrain x.v < 2^{num_bits}.

Definition at line 909 of file field.cpp.

◆ divide_no_zero_check()

template<typename Builder >
field_t< Builder > bb::stdlib::field_t< Builder >::divide_no_zero_check ( const field_t< Builder_ > &  other) const

Given field elements a = *this and b = other, output a / b without checking whether b = 0.

Definition at line 312 of file field.cpp.

◆ evaluate_linear_identity()

template<typename Builder >
void bb::stdlib::field_t< Builder >::evaluate_linear_identity ( const field_t< Builder_ > &  a,
const field_t< Builder_ > &  b,
const field_t< Builder_ > &  c,
const field_t< Builder_ > &  d,
const std::string &  msg = "field_t< Builder_ >::evaluate_linear_identity" 
)
static

Constrain a + b + c + d to be equal to 0.

Definition at line 1088 of file field.cpp.

◆ evaluate_polynomial_identity()

template<typename Builder >
void bb::stdlib::field_t< Builder >::evaluate_polynomial_identity ( const field_t< Builder_ > &  a,
const field_t< Builder_ > &  b,
const field_t< Builder_ > &  c,
const field_t< Builder_ > &  d,
const std::string &  msg = "field_t< Builder_ >::evaluate_polynomial_identity" 
)
static

Given a, b, c, d, constrain a * b + c + d = 0 by creating a big_mul_gate.

Definition at line 1124 of file field.cpp.

◆ fix_witness()

template<typename Builder_ >
void bb::stdlib::field_t< Builder_ >::fix_witness ( )
inline

Fix a witness. The value of a witness is constrained with a selector. This means that any attempt to change the value of a fixed witness would lead to changing the q_c selector and its commitment.

Definition at line 475 of file field.hpp.

◆ from_witness() [1/2]

template<typename Builder_ >
static field_t bb::stdlib::field_t< Builder_ >::from_witness ( Builder ctx,
const bb::fr input 
)
inlinestatic

Definition at line 454 of file field.hpp.

◆ from_witness() [2/2]

template<typename Builder_ >
template<typename T >
static field_t bb::stdlib::field_t< Builder_ >::from_witness ( Builder ctx,
const T &  input 
)
staticdelete

◆ from_witness_index()

template<typename Builder >
field_t< Builder > bb::stdlib::field_t< Builder >::from_witness_index ( Builder ctx,
uint32_t  witness_index 
)
static

Definition at line 62 of file field.cpp.

◆ get_context()

template<typename Builder_ >
Builder * bb::stdlib::field_t< Builder_ >::get_context ( ) const
inline

Definition at line 419 of file field.hpp.

◆ get_origin_tag()

template<typename Builder_ >
OriginTag bb::stdlib::field_t< Builder_ >::get_origin_tag ( ) const
inline

Definition at line 346 of file field.hpp.

◆ get_value()

template<typename Builder >
bb::fr bb::stdlib::field_t< Builder >::get_value ( ) const

Given a := *this, compute its value given by a.v * a.mul + a.add.

Warning
The result of this operation is a native field element. Ensure its value is properly constrained or only used for debugging purposes.

Definition at line 828 of file field.cpp.

◆ get_witness_index()

template<typename Builder_ >
uint32_t bb::stdlib::field_t< Builder_ >::get_witness_index ( ) const
inline

Get the witness index of the current field element.

This method normalizes the field element in place and returns the witness index of the normalized representation, such that the witness actually contains the value it represents (multiplicative_constant = 1, additive_constant = 0).

Note: the normalization may add gates to the circuit, but this is the safest option that prevents soundness vulnerabilities from using witness indices that don't contain the actual field value.

Within the field_t class implementation, the raw witness_index member can be accessed directly when needed (e.g., for checking if two fields share the exact same representation).

Returns
uint32_t The witness index of the normalized element

Definition at line 506 of file field.hpp.

◆ invert()

template<typename Builder_ >
field_t bb::stdlib::field_t< Builder_ >::invert ( ) const
inline

Compute 1 / (*this)

Definition at line 317 of file field.hpp.

◆ is_constant()

template<typename Builder_ >
bool bb::stdlib::field_t< Builder_ >::is_constant ( ) const
inline

Definition at line 429 of file field.hpp.

◆ is_normalized()

template<typename Builder_ >
bool bb::stdlib::field_t< Builder_ >::is_normalized ( ) const
inline

Definition at line 430 of file field.hpp.

◆ is_zero()

template<typename Builder >
bool_t< Builder > bb::stdlib::field_t< Builder >::is_zero ( ) const

Validate whether a field_t element is zero.

Let a := (*this).normalize() is_zero := (a == 0)

To check whether a = 0, we use the fact that, if a != 0, it has a modular inverse I, such that a * I = 1.

We reduce the check to the following algebraic constraints 1) a * I - 1 + is_zero = 0 2) -is_zero * I + is_zero = 0

If the value of is_zero is false, the first equation reduces to a * I = 1 then I must be the modular inverse of a, therefore a != 0. This explains the first constraint.

If is_zero = true, then either a or I is zero (or both). To ensure that a = 0 && I != 0 we use the second constraint, it validates that (is_zero.v = true) ==> (I = 1) This way, if a * I = 0, we know that a = 0.

Warning
If you want to ENFORCE that a field_t object is zero, use assert_is_zero

Definition at line 775 of file field.cpp.

◆ madd()

template<typename Builder >
field_t< Builder > bb::stdlib::field_t< Builder >::madd ( const field_t< Builder_ > &  to_mul,
const field_t< Builder_ > &  to_add 
) const
Returns
Efficiently compute this * to_mul + to_add using custom big_mul gate.

Definition at line 510 of file field.cpp.

◆ no_wrap_split_at()

template<typename Builder >
std::pair< field_t< Builder >, field_t< Builder > > bb::stdlib::field_t< Builder >::no_wrap_split_at ( const size_t  lsb_index,
const size_t  num_bits = grumpkin::MAX_NO_WRAP_INTEGER_BIT_LENGTH 
) const

Splits the field element into (lo, hi), where:

Definition at line 1291 of file field.cpp.

◆ normalize()

template<typename Builder >
field_t< Builder > bb::stdlib::field_t< Builder >::normalize ( ) const

Return a new element, where the in-circuit witness contains the actual represented value (multiplicative constant is 1 and additive_constant is 0)

If the element is a constant or it is already normalized, just return the element itself

Definition at line 638 of file field.cpp.

◆ operator bool_t< Builder >()

template<typename Builder >
bb::stdlib::field_t< Builder >::operator bool_t< Builder > ( ) const
explicit

Convert field_t element to bool_t and enforce bool constraints.

Template Parameters
Builder
Returns
bool_t<Builder>

Definition at line 75 of file field.cpp.

◆ operator!=()

template<typename Builder >
bool_t< Builder > bb::stdlib::field_t< Builder >::operator!= ( const field_t< Builder_ > &  other) const

Compute a bool_t equal to (a != b)

Definition at line 850 of file field.cpp.

◆ operator*()

template<typename Builder >
field_t< Builder > bb::stdlib::field_t< Builder >::operator* ( const field_t< Builder_ > &  other) const

Field multiplication operator.

Optimized to not create extra gates when at least one of the multiplicands is constant.

Both inputs are circuit variables: create a * b constraint.

Value of this = a.v * a.mul + a.add; Value of other = b.v * b.mul + b.add; Value of result = a * b = [a.v * b.v] * [a.mul * b.mul] + a.v * [a.mul * b.add] + b.v * [a.add * b.mul] + [a.ac * b.add] = [a.v * b.v] * [ q_m ] + a.v * [ q_l ] + b.v * [ q_r ] + [ q_c ] ^ ^Notice the add/mul_constants are placed into selectors when a gate is created. | Only the witnesses (pointed-to by the witness_indexes) form the wires in/out of | the gate. ^This entire value is pushed to ctx->variables as a new witness. The implied additive & multiplicative constants of the new witness are 0 & 1 resp. Left wire value: a.v Right wire value: b.v Output wire value: result.v (with q_o = -1)

Definition at line 192 of file field.cpp.

◆ operator*=()

template<typename Builder_ >
field_t bb::stdlib::field_t< Builder_ >::operator*= ( const field_t< Builder_ > &  other)
inline

Definition at line 287 of file field.hpp.

◆ operator+()

template<typename Builder >
field_t< Builder > bb::stdlib::field_t< Builder >::operator+ ( const field_t< Builder_ > &  other) const

Field addition operator.

Optimized to not create extra gates when at least one of the summands is constant.

Definition at line 124 of file field.cpp.

◆ operator++() [1/2]

template<typename Builder_ >
field_t & bb::stdlib::field_t< Builder_ >::operator++ ( )
inline

Definition at line 299 of file field.hpp.

◆ operator++() [2/2]

template<typename Builder_ >
field_t bb::stdlib::field_t< Builder_ >::operator++ ( const int  )
inline

Definition at line 307 of file field.hpp.

◆ operator+=()

template<typename Builder_ >
field_t bb::stdlib::field_t< Builder_ >::operator+= ( const field_t< Builder_ > &  other)
inline

Definition at line 277 of file field.hpp.

◆ operator-() [1/2]

template<typename Builder_ >
field_t bb::stdlib::field_t< Builder_ >::operator- ( ) const
inline

Definition at line 335 of file field.hpp.

◆ operator-() [2/2]

template<typename Builder >
field_t< Builder > bb::stdlib::field_t< Builder >::operator- ( const field_t< Builder_ > &  other) const

Subtraction operator deduced from the addition operator.

Definition at line 177 of file field.cpp.

◆ operator-=()

template<typename Builder_ >
field_t bb::stdlib::field_t< Builder_ >::operator-= ( const field_t< Builder_ > &  other)
inline

Definition at line 282 of file field.hpp.

◆ operator/()

template<typename Builder >
field_t< Builder > bb::stdlib::field_t< Builder >::operator/ ( const field_t< Builder_ > &  other) const

Since in divide_no_zero_check, we check \( a / b = q \) by the constraint \( a = b \cdot q\), if \( a = b= 0\), we can set \( q \) to any value and it will pass the constraint. Hence, when not having prior knowledge of \( b \) not being zero it is essential to check.

If \( b = 0 \) and is constant, this method aborts due to failed BB_ASSERT( b !=0 ) condition inside assert_is_not_zero(). If \( b = 0 \) and is not constant, a Builder failure is set and an unsatisfiable constraint 1 = 0 is created.

Definition at line 302 of file field.cpp.

◆ operator/=()

template<typename Builder_ >
field_t bb::stdlib::field_t< Builder_ >::operator/= ( const field_t< Builder_ > &  other)
inline

Definition at line 292 of file field.hpp.

◆ operator=() [1/2]

template<typename Builder_ >
field_t & bb::stdlib::field_t< Builder_ >::operator= ( const field_t< Builder_ > &  other)
inline

Definition at line 231 of file field.hpp.

◆ operator=() [2/2]

template<typename Builder_ >
field_t & bb::stdlib::field_t< Builder_ >::operator= ( field_t< Builder_ > &&  other)
inlinenoexcept

Definition at line 244 of file field.hpp.

◆ operator==()

template<typename Builder >
bool_t< Builder > bb::stdlib::field_t< Builder >::operator== ( const field_t< Builder_ > &  other) const

Compute a bool_t equal to (a == b)

Definition at line 842 of file field.cpp.

◆ pow() [1/2]

template<typename Builder >
field_t< Builder > bb::stdlib::field_t< Builder >::pow ( const field_t< Builder_ > &  exponent) const

Raise a field_t to a power of an exponent (field_t). Note that the exponent must not exceed 32 bits and is implicitly range constrained.

Definition at line 459 of file field.cpp.

◆ pow() [2/2]

template<typename Builder >
field_t< Builder > bb::stdlib::field_t< Builder >::pow ( const uint32_t &  exponent) const

Raise this field element to the power of the provided uint32_t exponent.

Definition at line 422 of file field.cpp.

◆ preprocess_three_bit_table()

template<typename Builder >
std::array< field_t< Builder >, 8 > bb::stdlib::field_t< Builder >::preprocess_three_bit_table ( const field_t< Builder_ > &  T0,
const field_t< Builder_ > &  T1,
const field_t< Builder_ > &  T2,
const field_t< Builder_ > &  T3,
const field_t< Builder_ > &  T4,
const field_t< Builder_ > &  T5,
const field_t< Builder_ > &  T6,
const field_t< Builder_ > &  T7 
)
static

Given a table T of size 8, outputs the monomial coefficients of the multilinear polynomial in t0, t1, t2, that on a input binary string b of length 3, equals T_b.

Definition at line 1021 of file field.cpp.

◆ preprocess_two_bit_table()

template<typename Builder >
std::array< field_t< Builder >, 4 > bb::stdlib::field_t< Builder >::preprocess_two_bit_table ( const field_t< Builder_ > &  T0,
const field_t< Builder_ > &  T1,
const field_t< Builder_ > &  T2,
const field_t< Builder_ > &  T3 
)
static

Given a table T of size 4, outputs the monomial coefficients of the multilinear polynomial in t0, t1 that on a input binary string b of length 2, equals T_b. In the Lagrange basis, the desired polynomial is given by the formula (1 - t0)(1 - t1).T0 + t0(1 - t1).T1 + (1 - t0)t1.T2 + t0.t1.T3.

Expand the coefficients to obtain the coefficients in the monomial basis.

Definition at line 1003 of file field.cpp.

◆ ranged_less_than()

template<typename Builder_ >
template<size_t num_bits>
bool_t< Builder > bb::stdlib::field_t< Builder_ >::ranged_less_than ( const field_t< Builder > &  other) const
inline

Return (a < b) as bool circuit type. This method assumes that both a and b are < 2^{num_bits} i.e. it is not checked here, we assume this has been done previously.

Definition at line 527 of file field.hpp.

◆ reconstruct_from_public()

template<typename Builder_ >
static field_t bb::stdlib::field_t< Builder_ >::reconstruct_from_public ( const std::span< const field_t< Builder_ >, PUBLIC_INPUTS_SIZE > &  limbs)
inlinestatic

Definition at line 465 of file field.hpp.

◆ select_from_three_bit_table()

template<typename Builder >
field_t< Builder > bb::stdlib::field_t< Builder >::select_from_three_bit_table ( const std::array< field_t< Builder_ >, 8 > &  table,
const bool_t< Builder > &  t2,
const bool_t< Builder > &  t1,
const bool_t< Builder > &  t0 
)
static

Given a multilinear polynomial in 3 variables, which is represented by a table of monomial coefficients, compute its evaluation at (t0, t1, t2) using minimal number of gates.

The straightforward thing would be eight multiplications to get the monomials and several additions between them. It turns out you can do it in 7 madd gates using the formulas X := ((t0*a_012 + a12)*t1 + a2)*t2 + a_const // - 3 gates Y := (t0*a01 + a1)*t1 + X // - 2 gates Z := (t2*a02 + a0)*t0 + Y // - 2 gates

Definition at line 1069 of file field.cpp.

◆ select_from_two_bit_table()

template<typename Builder >
field_t< Builder > bb::stdlib::field_t< Builder >::select_from_two_bit_table ( const std::array< field_t< Builder_ >, 4 > &  table,
const bool_t< Builder > &  t1,
const bool_t< Builder > &  t0 
)
static

Given a multilinear polynomial in 2 variables, which is represented by a table of monomial coefficients, compute its evaluation at the point (t0, t1) using minimal number of gates.

Definition at line 1047 of file field.cpp.

◆ set_free_witness_tag()

template<typename Builder_ >
void bb::stdlib::field_t< Builder_ >::set_free_witness_tag ( )
inline

Set the free witness flag for the field element's tag.

Definition at line 351 of file field.hpp.

◆ set_origin_tag()

template<typename Builder_ >
void bb::stdlib::field_t< Builder_ >::set_origin_tag ( const OriginTag new_tag) const
inline

Definition at line 345 of file field.hpp.

◆ set_public()

template<typename Builder_ >
uint32_t bb::stdlib::field_t< Builder_ >::set_public ( ) const
inline

Definition at line 434 of file field.hpp.

◆ sqr()

template<typename Builder_ >
field_t bb::stdlib::field_t< Builder_ >::sqr ( ) const
inline

Definition at line 271 of file field.hpp.

◆ unset_free_witness_tag()

template<typename Builder_ >
void bb::stdlib::field_t< Builder_ >::unset_free_witness_tag ( ) const
inline

Unset the free witness flag for the field element's tag.

Definition at line 356 of file field.hpp.

◆ witness_indices_match()

template<typename Builder_ >
static bool bb::stdlib::field_t< Builder_ >::witness_indices_match ( const field_t< Builder_ > &  a,
const field_t< Builder_ > &  b 
)
inlinestatic

Check if two field elements have the same witness index (for identity checks).

Checks if two field elements share the exact same witness_index representation. Used for optimization checks like "if inputs are identical, skip computation". Does NOT check value equality - use operator== for that.

Parameters
aFirst field element
bSecond field element
Returns
bool True if both elements reference the same witness

Definition at line 519 of file field.hpp.

Friends And Related Symbol Documentation

◆ bigfield

template<typename Builder_ >
template<typename B , typename T >
friend class bigfield
friend

Definition at line 53 of file field.hpp.

◆ bool_t

template<typename Builder_ >
template<typename B >
friend class bool_t
friend

Definition at line 52 of file field.hpp.

◆ mark_witness_as_used

template<typename Builder_ >
template<typename B >
void mark_witness_as_used ( const field_t< B > &  field)
friend

Member Data Documentation

◆ additive_constant

template<typename Builder_ >
bb::fr bb::stdlib::field_t< Builder_ >::additive_constant
mutable

additive_constant and multiplicative_constant are constant scaling factors applied to a field_t object.

The 'value' represented by a field_t is calculated as:

  • For field_ts with witness_index = IS_CONSTANT: this.additive_constant
  • For non-constant field_ts: this.context->variables[this.witness_index] * this.multiplicative_constant + this.additive_constant

We track these scaling factors, because we can apply the same scaling factors to Plonk wires when creating gates. I.e. if we want to multiply a wire by a constant, or add a constant, we do not need to add extra gates to do this. Instead, we track the scaling factors, and apply them to the relevant wires when adding constraints.

This also makes constant field_t objects effectively free. (Where 'constant' is a circuit constant, not a C++ constant!). E.g. the following 3 lines of code add 0 constraints into a circuit:

field_t foo = 1; field_t bar = 5; field_t bar *= foo;

Similarly if we add in:

field_t zip = witness_t(context, 10); zip *= bar + foo;

The above adds 0 constraints, the only effect is that zip's scaling factors have been modified. However if we now add:

field_t zap = witness_t(context, 50); zip *= zap;

This will add a constraint, as both zip and zap map to circuit witnesses.

Definition at line 93 of file field.hpp.

◆ context

template<typename Builder_ >
Builder* bb::stdlib::field_t< Builder_ >::context = nullptr
mutable

Definition at line 56 of file field.hpp.

◆ is_composite

template<typename Builder_ >
constexpr bool bb::stdlib::field_t< Builder_ >::is_composite = false
staticconstexpr

Definition at line 224 of file field.hpp.

◆ modulus

template<typename Builder_ >
constexpr uint256_t bb::stdlib::field_t< Builder_ >::modulus = bb::fr::modulus
staticconstexpr

Definition at line 225 of file field.hpp.

◆ multiplicative_constant

template<typename Builder_ >
bb::fr bb::stdlib::field_t< Builder_ >::multiplicative_constant
mutable

Definition at line 94 of file field.hpp.

◆ PUBLIC_INPUTS_SIZE

template<typename Builder_ >
constexpr size_t bb::stdlib::field_t< Builder_ >::PUBLIC_INPUTS_SIZE = FR_PUBLIC_INPUTS_SIZE
staticconstexpr

Definition at line 49 of file field.hpp.

◆ tag

template<typename Builder_ >
OriginTag bb::stdlib::field_t< Builder_ >::tag {}
mutable

Definition at line 147 of file field.hpp.

◆ witness_index

template<typename Builder_ >
uint32_t bb::stdlib::field_t< Builder_ >::witness_index = IS_CONSTANT
mutableprivate

Every builder object contains a vector variables (a.k.a. 'witnesses'); circuit variables that can be assigned to wires when creating constraints. witness_index describes a location in this container. I.e. it 'points' to a circuit variable.

A witness is not the same thing as a 'wire' in a circuit. Multiple wires can be assigned to the same witness via Plonk's copy constraints. Alternatively, a witness might not be assigned to any wires! This case would be similar to an unused variable in a regular program

E.g. if we write field_t foo = witness_t(context, 100), this will add the value 100 into context's list of circuit variables. However if we do not use foo in any operations, then this value will never be assigned to a wire in a circuit.

For a more in depth example, consider the following code:

field_t foo = witness_t(context, 10); field_t bar = witness_t(context, 50); field_t baz = foo * (bar + 7);

This will add 3 new circuit witnesses (10, 50, 570) to variables. One constraint will also be created, that validates baz has been correctly constructed. The builder will assign foo, bar, baz to wires w_1, w_2, w_3 in a new gate which checks that:

 w_1 * w_2 + w_1 * 7 - w_3 = 0

If any of foo, bar, baz are used in future arithmetic, copy constraints will be automatically applied, this ensure that all gate wires that map to foo, for example, will contain the same value.

If witness_index == IS_CONSTANT, the object represents a constant value. i.e. a value that's hardcoded in the circuit, that a prover cannot change by modifying their witness transcript.

A Plonk gate is a mix of witness values and selector values. e.g. the regular PLONK arithmetic gate checks that:

 w_1 * w_2 * q_m + w_1 * q_1 + w_2 * q_2 + w_3 * q_3 + q_c = 0

The w value are wires, the q values are selector constants. If a field object contains a witness_index, it will be assigned to w values when constraints are applied. If it's a circuit constant, it will be assigned to q values.

TLDR: witness_index is a pseudo pointer to a circuit witness

Warning
Direct access to witness_index is for internal use only! External code should use get_witness_index() which returns a normalized witness index. Direct access may return a witness that doesn't contain the actual value due to non-trivial multiplicative_constant/additive_constant, which can lead to soundness bugs. Only access directly when you understand the implications (e.g., checking exact representation equality, or in performance-critical code like bigfield that carefully manages scaling factors).

Definition at line 144 of file field.hpp.


The documentation for this class was generated from the following files: