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_witness_index(),
212 "bigfield::construct_from_limbs: limb 0 or 1 too large");
216 ctx->range_constrain_two_limbs(result.
binary_basis_limbs[2].element.get_witness_index(),
219 static_cast<size_t>(num_last_limb_bits),
220 "bigfield::construct_from_limbs: limb 2 or 3 too large");
237 const bool can_overflow =
false)
293 const bool can_overflow =
false,
294 const size_t maximum_bitlength = 0);
302 result.set_free_witness_tag();
316 static constexpr uint64_t
NUM_LIMB_BITS = NUM_LIMB_BITS_IN_FIELD_SIMULATION;
530 bool fix_remainder_to_zero =
false);
544 bool enable_divisor_nz_check =
true);
549 bool check_for_zero);
574 void assert_is_in_field(std::string
const& msg =
"bigfield::assert_is_in_field")
const;
577 void assert_equal(
const bigfield& other, std::string
const& msg =
"bigfield::assert_equal")
const;
579 std::string
const& msg =
"bigfield: prime limb diff is zero, but expected non-zero")
const;
609 BB_ASSERT_EQ(is_limb_3_constant, is_prime_limb_constant);
610 return is_prime_limb_constant;
647 auto msb = multiple_of_modulus.
get_msb();
665 limb.element.convert_constant_to_fixed_witness(
context);
677 limb.element.fix_witness();
717 limb.element.set_free_witness_tag();
728 limb.element.unset_free_witness_tag();
740 const uint32_t start_index =
static_cast<uint32_t
>(ctx->num_public_inputs());
742 ctx->set_public_input(limb.element.get_witness_index());
780 uint64_t maximum_product_bits = maximum_product.
get_msb() - 1;
788 uint64_t maximum_product_bits = maximum_product.
get_msb() - 1;
789 const size_t arbitrary_secure_margin = 20;
790 return (
uint512_t(1) << ((maximum_product_bits >> 1) + arbitrary_secure_margin)) -
uint512_t(1);
805 return maximum_product;
822 for (
const auto& r : remainders_max) {
826 return static_cast<size_t>(base.
get_msb() - 1);
844 for (
const auto& add : to_add) {
845 add_term += add.get_maximum_value();
873 for (
size_t i = 0; i < as_max.size(); i++) {
876 for (
const auto& add : to_add) {
877 add_term += add.get_maximum_value();
947 std::string
const& msg =
"bigfield::unsafe_assert_less_than")
const;
960 return limb_witness_indices;
1036 const bigfield& input_to_mul,
1038 const bigfield& input_quotient,
1063 const bigfield& input_quotient,
1082 const bigfield& quotient,
1083 const bigfield& remainder);
1123 for (
size_t i = 0; i <
NUM_LIMBS; i++) {
1126 return limb_maximums;
1149 template <
typename bigfield>
1155 template <
typename bigfield>
1165 template <
typename bigfield>
1173 input_left, input_right, to_add, input_quotient, input_remainders);
#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 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)
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)
static void unsafe_assert_less_than(const bigfield &input, const uint256_t &upper_limit)
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 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)
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=true)
void clear_round_provenance() 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.
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
void assert_is_in_field(std::string const &msg="bigfield::assert_is_in_field") const
static bigfield internal_div(const std::vector< bigfield > &numerators, const bigfield &denominator, bool check_for_zero)
static constexpr std::array< bb::fr, NUM_LIMBS > neg_modulus_mod_binary_basis_limbs
void assert_less_than(const uint256_t &upper_limit, std::string const &msg="bigfield::assert_less_than") const
static constexpr size_t PUBLIC_INPUTS_SIZE
static constexpr Basis target_basis
static constexpr uint64_t PROHIBITED_LIMB_BITS
static constexpr Basis prime_basis
static const uint1024_t DEFAULT_MAXIMUM_REMAINDER
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 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)
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 uint512_t negative_prime_modulus_mod_binary_basis
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 bb::fr negative_prime_modulus_mod_native_basis
static constexpr uint256_t modulus
static bigfield from_witness(Builder *ctx, const OT &input)=delete
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 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::array< uint32_t, 2 > decompose_non_native_field_double_width_limb(Builder *ctx, const uint32_t limb_idx, const size_t num_limb_bits=(2 *NUM_LIMB_BITS))
Decompose a single witness into two limbs, range constrained to NUM_LIMB_BITS (68) and num_limb_bits ...
void reduce_mod_target_modulus() const
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 ...
void unsafe_assert_less_than(const uint256_t &upper_limit, std::string const &msg="bigfield::unsafe_assert_less_than") const
Assert that the current bigfield is less than the given upper limit.
bigfield operator+(const bigfield &other) const
Adds two bigfield elements. Inputs are reduced to the modulus if necessary. Requires 4 gates if both ...
void assert_equal(const bigfield &other, std::string const &msg="bigfield::assert_equal") const
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.
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)
void self_reduce() const
Reduce the bigfield element modulo the target modulus.
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)
void assert_is_not_equal(const bigfield &other, std::string const &msg="bigfield: prime limb diff is zero, but expected non-zero") const
static constexpr std::array< uint256_t, NUM_LIMBS > neg_modulus_mod_binary_basis_limbs_u256
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.
void clear_round_provenance() const
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