9#include "../byte_array/byte_array.hpp"
10#include "../circuit_builders/circuit_builders_fwd.hpp"
11#include "../field/field.hpp"
21template <
typename Builder,
typename T>
class bigfield {
58 os <<
"{ " <<
a.element <<
" < " <<
a.maximum_value <<
" }";
98 const bool can_overflow =
false,
99 const size_t maximum_bitlength = 0);
161 const bool can_overflow =
false)
189 const bool can_overflow =
false)
195 auto ctx =
a.context;
208 ctx->range_constrain_two_limbs(result.
binary_basis_limbs[0].element.get_normalized_witness_index(),
215 ctx->range_constrain_two_limbs(result.
binary_basis_limbs[2].element.get_normalized_witness_index(),
218 static_cast<size_t>(num_last_limb_bits));
235 const bool can_overflow =
false)
291 const bool can_overflow =
false,
292 const size_t maximum_bitlength = 0);
300 result.set_free_witness_tag();
310 static constexpr uint64_t
NUM_LIMB_BITS = NUM_LIMB_BITS_IN_FIELD_SIMULATION;
557 bool fix_remainder_to_zero =
false);
571 bool enable_divisor_nz_check =
false);
576 bool check_for_zero);
625 BB_ASSERT_EQ(is_limb_3_constant, is_prime_limb_constant);
626 return is_prime_limb_constant;
663 auto msb = multiple_of_modulus.
get_msb();
681 limb.element.convert_constant_to_fixed_witness(
context);
693 limb.element.fix_witness();
726 limb.element.set_free_witness_tag();
737 limb.element.unset_free_witness_tag();
749 const uint32_t start_index =
static_cast<uint32_t
>(ctx->num_public_inputs());
751 ctx->set_public_input(limb.element.normalize().witness_index);
789 uint64_t maximum_product_bits = maximum_product.
get_msb() - 1;
790 return (
uint512_t(1) << (maximum_product_bits >> 1));
797 uint64_t maximum_product_bits = maximum_product.
get_msb() - 1;
798 const size_t arbitrary_secure_margin = 20;
799 return (
uint512_t(1) << ((maximum_product_bits >> 1) + arbitrary_secure_margin)) -
uint512_t(1);
814 return maximum_product;
831 for (
const auto& r : remainders_max) {
835 return static_cast<size_t>(base.
get_msb() - 1);
853 for (
const auto& add : to_add) {
854 add_term += add.get_maximum_value();
882 for (
size_t i = 0; i < as_max.size(); i++) {
885 for (
const auto& add : to_add) {
886 add_term += add.get_maximum_value();
952 limb_witness_indices[i] =
binary_basis_limbs[i].element.get_normalized_witness_index();
954 return limb_witness_indices;
1016 const bigfield& input_to_mul,
1018 const bigfield& input_quotient,
1043 const bigfield& input_quotient,
1062 const bigfield& quotient,
1063 const bigfield& remainder);
1103 for (
size_t i = 0; i <
NUM_LIMBS; i++) {
1106 return limb_maximums;
#define BB_ASSERT_EQ(actual, expected,...)
#define BB_ASSERT_LTE(left, right,...)
#define BB_ASSERT_LT(left, right,...)
constexpr uint256_t slice(uint64_t start, uint64_t end) const
constexpr uint64_t get_msb() const
constexpr uintx slice(const uint64_t start, const uint64_t end) const
constexpr uint64_t get_msb() const
static constexpr uint256_t DEFAULT_MAXIMUM_MOST_SIGNIFICANT_LIMB
static size_t get_quotient_max_bits(const std::vector< uint1024_t > &remainders_max)
Compute the maximum number of bits for quotient range proof to protect against CRT underflow.
static bigfield unsafe_construct_from_limbs(const field_t< Builder > &a, const field_t< Builder > &b, const field_t< Builder > &c, const field_t< Builder > &d, const field_t< Builder > &prime_limb, const bool can_overflow=false)
Construct a bigfield element from binary limbs and a prime basis limb that are already reduced.
static constexpr uint512_t get_maximum_unreduced_value()
static constexpr uint256_t get_prohibited_limb_value()
static constexpr uint256_t prime_basis_maximum_limb
static constexpr uint64_t NUM_LIMB_BITS
static constexpr Basis binary_basis
static void unsafe_evaluate_multiple_multiply_add(const std::vector< bigfield > &input_left, const std::vector< bigfield > &input_right, const std::vector< bigfield > &to_add, const bigfield &input_quotient, const std::vector< bigfield > &input_remainders)
Evaluate a relation involving multiple multiplications and additions.
static constexpr uint64_t MAX_ADDITION_LOG
static bigfield conditional_assign(const bool_t< Builder > &predicate, const bigfield &lhs, const bigfield &rhs)
static constexpr uint64_t MAX_UNREDUCED_LIMB_BITS
static constexpr size_t MAXIMUM_SUMMAND_COUNT_LOG
static bool mul_product_overflows_crt_modulus(const uint1024_t &a_max, const uint1024_t &b_max, const std::vector< bigfield > &to_add)
void assert_is_not_equal(const bigfield &other) const
Builder * get_context() const
static constexpr uint1024_t get_maximum_crt_product()
Compute the maximum product of two bigfield elements in CRT: M = 2^t * n.
bigfield operator*(const bigfield &other) const
Evaluate a non-native field multiplication: (a * b = c mod p) where p == target_basis....
bigfield conditional_select(const bigfield &other, const bool_t< Builder > &predicate) const
Create an element which is equal to either this or other based on the predicate.
static bigfield div_check_denominator_nonzero(const std::vector< bigfield > &numerators, const bigfield &denominator)
static bigfield sum(const std::vector< bigfield > &terms)
Create constraints for summing these terms.
static void unsafe_evaluate_square_add(const bigfield &left, const std::vector< bigfield > &to_add, const bigfield "ient, const bigfield &remainder)
Evaluate a square with several additions.
static constexpr uint64_t MAXIMUM_LIMB_SIZE_THAT_WOULDNT_OVERFLOW
static bigfield construct_from_limbs(const field_t< Builder > &a, const field_t< Builder > &b, const field_t< Builder > &c, const field_t< Builder > &d, const bool can_overflow=false)
Construct a bigfield element from binary limbs that are already reduced and ensure they are range con...
bigfield madd(const bigfield &to_mul, const std::vector< bigfield > &to_add) const
Compute a * b + ...to_add = c mod p.
byte_array< Builder > to_byte_array() const
Convert the bigfield element to a byte array. Concatenates byte arrays of the high (2L bits) and low ...
bigfield conditional_negate(const bool_t< Builder > &predicate) const
static bigfield mult_madd(const std::vector< bigfield > &mul_left, const std::vector< bigfield > &mul_right, const std::vector< bigfield > &to_add, bool fix_remainder_to_zero=false)
void set_origin_tag(const bb::OriginTag &tag) const
uint512_t get_value() const
static bigfield internal_div(const std::vector< bigfield > &numerators, const bigfield &denominator, bool check_for_zero)
static bigfield msub_div(const std::vector< bigfield > &mul_left, const std::vector< bigfield > &mul_right, const bigfield &divisor, const std::vector< bigfield > &to_sub, bool enable_divisor_nz_check=false)
static constexpr size_t PUBLIC_INPUTS_SIZE
static constexpr bb::fr shift_right_2
static constexpr uint512_t negative_prime_modulus
static constexpr Basis target_basis
static constexpr uint64_t PROHIBITED_LIMB_BITS
static constexpr Basis prime_basis
static const uint1024_t DEFAULT_MAXIMUM_REMAINDER
void assert_equal(const bigfield &other) const
bigfield add_to_lower_limb(const field_t< Builder > &other, const uint256_t &other_maximum_value) const
Add a field element to the lower limb. CAUTION (the element has to be constrained before using this f...
bigfield(const native value)
Construct a new bigfield object from bb::fq. We first convert to uint256_t as field elements are in M...
static constexpr uint256_t get_maximum_unreduced_limb_value()
static constexpr bb::fr negative_prime_modulus_mod_binary_basis
static constexpr uint64_t NUM_LAST_LIMB_BITS
void set_free_witness_tag()
Set the free witness flag for the bigfield.
static constexpr uint512_t get_prohibited_value()
bigfield & operator=(const bigfield &other)
void convert_constant_to_fixed_witness(Builder *builder)
void assert_is_in_field() const
uint512_t get_maximum_value() const
std::array< uint256_t, NUM_LIMBS > get_binary_basis_limb_maximums()
Get the maximum values of the binary basis limbs.
static uint512_t compute_maximum_quotient_value(const std::vector< uint512_t > &as, const std::vector< uint512_t > &bs, const std::vector< uint512_t > &to_add)
Compute the maximum possible value of quotient of a*b+\sum(to_add)
bigfield sqradd(const std::vector< bigfield > &to_add) const
Square and add operator, computes a * a + ...to_add = c mod p.
static constexpr size_t NUM_LIMBS
bigfield operator*=(const bigfield &other)
static constexpr uint256_t DEFAULT_MAXIMUM_LIMB
bigfield add_two(const bigfield &add_a, const bigfield &add_b) const
Create constraints for summing three bigfield elements efficiently.
std::array< uint32_t, NUM_LIMBS > get_binary_basis_limb_witness_indices() const
Get the witness indices of the (normalized) binary basis limbs.
bigfield(const unsigned long long value)
static constexpr size_t MAXIMUM_SUMMAND_COUNT
static bigfield reconstruct_from_public(const std::span< const field_ct, PUBLIC_INPUTS_SIZE > &limbs)
Reconstruct a bigfield from limbs (generally stored in the public inputs)
bb::OriginTag get_origin_tag() const
bigfield operator-=(const bigfield &other)
static bigfield from_witness(Builder *ctx, const bb::field< T > &input)
void reduction_check() const
Check if the bigfield element needs to be reduced.
static constexpr uint256_t modulus
static constexpr bb::fr shift_2
bigfield(const int value)
Constructs a new bigfield object from an int value. We first need to to construct a field element fro...
static bigfield dual_madd(const bigfield &left_a, const bigfield &right_a, const bigfield &left_b, const bigfield &right_b, const std::vector< bigfield > &to_add)
bigfield sqr() const
Square operator, computes a * a = c mod p.
static constexpr bb::fr shift_right_1
static void perform_reductions_for_mult_madd(std::vector< bigfield > &mul_left, std::vector< bigfield > &mul_right, const std::vector< bigfield > &to_add)
Performs individual reductions on the supplied elements as well as more complex reductions to prevent...
static constexpr bb::fr shift_3
bool is_constant() const
Check if the bigfield is constant, i.e. its prime limb is constant.
static std::pair< uint512_t, uint512_t > compute_quotient_remainder_values(const bigfield &a, const bigfield &b, const std::vector< bigfield > &to_add)
Compute the quotient and remainder values for dividing (a * b + (to_add[0] + ... + to_add[-1])) with ...
static constexpr std::array< uint256_t, NUM_LIMBS > neg_modulus_limbs_u256
bigfield operator+(const bigfield &other) const
Adds two bigfield elements. Inputs are reduced to the modulus if necessary. Requires 4 gates if both ...
static constexpr std::array< bb::fr, NUM_LIMBS > neg_modulus_limbs
static constexpr uint64_t LOG2_BINARY_MODULUS
static bigfield create_from_u512_as_witness(Builder *ctx, const uint512_t &value, const bool can_overflow=false, const size_t maximum_bitlength=0)
Creates a bigfield element from a uint512_t. Bigfield element is constructed as a witness and not a c...
bigfield pow(const uint32_t exponent) const
Raise the bigfield element to the power of (out-of-circuit) exponent.
static std::pair< bool, size_t > get_quotient_reduction_info(const std::vector< uint512_t > &as_max, const std::vector< uint512_t > &bs_max, const std::vector< bigfield > &to_add, const std::vector< uint1024_t > &remainders_max={ DEFAULT_MAXIMUM_REMAINDER })
Check for 2 conditions (CRT modulus is overflown or the maximum quotient doesn't fit into range proof...
static bigfield unsafe_construct_from_limbs(const field_t< Builder > &a, const field_t< Builder > &b, const field_t< Builder > &c, const field_t< Builder > &d, const bool can_overflow=false)
Construct a bigfield element from binary limbs that are already reduced.
static constexpr bigfield unreduced_zero()
Create an unreduced 0 ~ p*k, where p*k is the minimal multiple of modulus that should be reduced.
void sanity_check() const
Perform a sanity check on a value that is about to interact with another value.
void assert_less_than(const uint256_t &upper_limit) const
static void unsafe_evaluate_multiply_add(const bigfield &input_left, const bigfield &input_to_mul, const std::vector< bigfield > &to_add, const bigfield &input_quotient, const std::vector< bigfield > &input_remainders)
Evaluate a multiply add identity with several added elements and several remainders.
field_t< Builder > prime_basis_limb
Represents a bigfield element in the prime basis: (a mod n) where n is the native modulus.
static bigfield div_without_denominator_check(const std::vector< bigfield > &numerators, const bigfield &denominator)
std::array< Limb, NUM_LIMBS > binary_basis_limbs
Represents a bigfield element in the binary basis. A bigfield element is represented as a combination...
uint32_t set_public() const
Set the witness indices of the binary basis limbs to public.
bool_t< Builder > operator==(const bigfield &other) const
Validate whether two bigfield elements are equal to each other.
bigfield operator/=(const bigfield &other)
bigfield operator-() const
Negation operator, works by subtracting this from zero.
static constexpr bool is_composite
bigfield operator+=(const bigfield &other)
static std::pair< uint512_t, uint512_t > compute_partial_schoolbook_multiplication(const std::array< uint256_t, NUM_LIMBS > &a_limbs, const std::array< uint256_t, NUM_LIMBS > &b_limbs)
Compute the partial multiplication of two uint256_t arrays using schoolbook multiplication.
static constexpr bb::fr shift_1
void unset_free_witness_tag()
Unset the free witness flag for the bigfield.
bigfield(const unsigned long value)
bigfield invert() const
Inverting function with the assumption that the bigfield element we are calling invert on is not zero...
bigfield(const uint256_t &value)
static bool mul_product_overflows_crt_modulus(const std::vector< uint512_t > &as_max, const std::vector< uint512_t > &bs_max, const std::vector< bigfield > &to_add)
static constexpr uint512_t modulus_u512
bigfield operator/(const bigfield &other) const
Implements boolean logic in-circuit.
Represents a dynamic array of bytes in-circuit.
byte_array & write(byte_array const &other)
Appends the contents of another byte_array (other) to the end of this one.
void unset_free_witness_tag() const
Unset the free witness flag for the field element's tag.
void convert_constant_to_fixed_witness(Builder *ctx)
void set_free_witness_tag()
Set the free witness flag for the field element's tag.
void set_origin_tag(const OriginTag &new_tag) const
std::ostream & operator<<(std::ostream &os, uint256_t const &a)
uintx< uint256_t > uint512_t
uintx< uint512_t > uint1024_t
std::conditional_t< IsGoblinBigGroup< C, Fq, Fr, G >, element_goblin::goblin_element< C, goblin_field< C >, Fr, G >, element_default::element< C, Fq, Fr, G > > element
element wraps either element_default::element or element_goblin::goblin_element depending on parametr...
field< Bn254FrParams > fr
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
General class for prime fields see Prime field documentation["field documentation"] for general imple...
static constexpr uint256_t modulus
Represents a single limb of a bigfield element, with its value and maximum value.
Limb & operator=(Limb &&other) noexcept=default
Limb(Limb &&other) noexcept=default
Limb(const field_t< Builder > &input, const uint256_t &max=DEFAULT_MAXIMUM_LIMB)
Limb & operator=(const Limb &other)=default
field_t< Builder > element
friend std::ostream & operator<<(std::ostream &os, const Limb &a)
Limb(const Limb &other)=default