14template <
typename Builder>
32 (lo + hi * shift).assert_equal(in);
35 validate_scalar_is_in_field();
51template <
typename Builder>
74template <
typename Builder>
77 const size_t num_bits)
100template <
typename Builder>
118 cycle_scalar result{ lo, hi, NUM_BITS, skip_primality_test,
true };
132 auto* ctx = get_context() ? get_context() : scalar.
get_context();
181 if (scalar.
binary_basis_limbs[0].maximum_value > BigScalarField::DEFAULT_MAXIMUM_LIMB) {
183 const uint256_t lo_v = limb.
slice(0, BigScalarField::NUM_LIMB_BITS);
184 const uint256_t hi_v = limb >> BigScalarField::NUM_LIMB_BITS;
189 const uint64_t hi_bits = hi_max.
get_msb() + 1;
200 BB_ASSERT_GT(BigScalarField::NUM_LIMB_BITS * 2, LO_BITS);
208 const size_t lo_bits_in_limb_1 = LO_BITS - BigScalarField::NUM_LIMB_BITS;
209 const size_t hi_bits_in_limb_1 = (
static_cast<size_t>(limb1_max.
get_msb()) + 1) - lo_bits_in_limb_1;
214 const uint256_t limb_1_hi_v = limb_1 >> lo_bits_in_limb_1;
215 const uint256_t limb_1_lo_v = limb_1 - (limb_1_hi_v << lo_bits_in_limb_1);
224 limb1.
assert_equal(limb_1_hi * limb_1_hi_multiplicand + limb_1_lo);
228 limb_1_lo.create_range_constraint(lo_bits_in_limb_1);
234 lo = limb0 + (limb_1_lo * BigScalarField::shift_1);
236 const uint256_t limb_2_shift =
uint256_t(1) << (BigScalarField::NUM_LIMB_BITS - lo_bits_in_limb_1);
238 uint256_t(1) << ((BigScalarField::NUM_LIMB_BITS - lo_bits_in_limb_1) + BigScalarField::NUM_LIMB_BITS);
241 hi = limb_1_hi.
add_two(limb2 * limb_2_shift, limb3 * limb_3_shift);
250 return (lo.is_constant() && hi.is_constant());
272 if (!is_constant() && !skip_primality_test()) {
275 use_bn254_scalar_field_for_primality_test() ?
FF::modulus : ScalarField::modulus;
277 const uint256_t r_hi = cycle_group_modulus.
slice(LO_BITS, HI_BITS);
279 bool need_borrow =
uint256_t(lo.get_value()) > r_lo;
283 if (!lo.is_constant()) {
286 if constexpr (IS_ULTRA) {
287 get_context()->create_new_range_constraint(borrow.
get_witness_index(), 1,
"borrow");
294 field_t hi_diff = (-hi + r_hi) - borrow;
#define BB_ASSERT_GT(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
Builder * get_context() const
uint512_t get_value() const
uint512_t get_maximum_value() const
bb::OriginTag get_origin_tag() const
bool is_constant() const
Check if the bigfield is constant, i.e. its prime limb is constant.
std::array< Limb, NUM_LIMBS > binary_basis_limbs
Represents a bigfield element in the binary basis. A bigfield element is represented as a combination...
cycle_scalar represents a member of the cycle curve SCALAR FIELD. This is NOT the native circuit fiel...
typename Curve::ScalarField ScalarField
static cycle_scalar create_from_bn254_scalar(const field_t &_in, bool skip_primality_test=false)
Use when we want to multiply a group element by a string of bits of known size. N....
ScalarField get_value() const
cycle_scalar(const field_t &_lo, const field_t &_hi, const size_t bits, const bool skip_primality_test, const bool use_bn254_scalar_field_for_primality_test)
static cycle_scalar from_witness(Builder *context, const ScalarField &value)
static cycle_scalar from_witness_bitstring(Builder *context, const uint256_t &bitstring, size_t num_bits)
Use when we want to multiply a group element by a string of bits of known size. N....
void validate_scalar_is_in_field() const
Checks that a cycle_scalar value is smaller than a prime field modulus when evaluated over the INTEGE...
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 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}.
Builder * get_context() const
OriginTag get_origin_tag() const
bb::fr get_value() const
Given a := *this, compute its value given by a.v * a.mul + a.add.
static field_t from_witness(Builder *ctx, const bb::fr &input)
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
field_t add_two(const field_t &add_b, const field_t &add_c) const
Efficiently compute (this + a + b) using big_mul gate.
uint32_t get_witness_index() const
Get the witness index of the current field element.
StrictMock< MockContext > context
static constexpr uint256_t modulus