53static constexpr uint64_t MODULUS_TOP_LIMB_LARGE_THRESHOLD = 0x4000000000000000ULL;
60template <
class Params_>
struct alignas(32)
field {
73#if defined(__wasm__) || !defined(__SIZEOF_INT128__)
74#define WASM_NUM_LIMBS 9
75#define WASM_LIMB_BITS 29
90 :
data{ input.
data[0], input.data[1], input.data[2], input.data[3] }
100 constexpr field(
const unsigned long input) noexcept
101 :
data{ input, 0, 0, 0 }
106 constexpr field(
const unsigned int input) noexcept
107 :
data{ input, 0, 0, 0 }
113 constexpr field(
const unsigned long long input) noexcept
114 :
data{ input, 0, 0, 0 }
119 constexpr field(
const int input) noexcept
123 data[0] =
static_cast<uint64_t
>(-input);
131 data[0] =
static_cast<uint64_t
>(input);
145 constexpr field(
const uint64_t
a,
const uint64_t
b,
const uint64_t c,
const uint64_t d) noexcept
164 constexpr explicit field(std::string input)
noexcept
175 constexpr explicit operator bool()
const
178 if ((out.
data[0] != 0 && out.
data[0] != 1) || out.
data[1] != 0 || out.
data[2] != 0 || out.
data[3] != 0) {
181 return static_cast<bool>(out.
data[0]);
184 constexpr explicit operator uint8_t()
const
187 return static_cast<uint8_t
>(out.
data[0]);
190 constexpr explicit operator uint16_t()
const
193 return static_cast<uint16_t
>(out.
data[0]);
196 constexpr explicit operator uint32_t()
const
199 return static_cast<uint32_t
>(out.
data[0]);
202 constexpr explicit operator uint64_t()
const
213 return (hi << 64) | lo;
235 uint256_t{ Params::modulus_0, Params::modulus_1, Params::modulus_2, Params::modulus_3 };
236#if defined(__SIZEOF_INT128__) && !defined(__wasm__)
238 Params_::r_squared_0, Params_::r_squared_1, Params_::r_squared_2, Params_::r_squared_3
242 Params_::r_squared_wasm_0, Params_::r_squared_wasm_1, Params_::r_squared_wasm_2, Params_::r_squared_wasm_3
244 static constexpr std::array<uint64_t, 9>
wasm_modulus = { Params::modulus_wasm_0, Params::modulus_wasm_1,
245 Params::modulus_wasm_2, Params::modulus_wasm_3,
246 Params::modulus_wasm_4, Params::modulus_wasm_5,
247 Params::modulus_wasm_6, Params::modulus_wasm_7,
248 Params::modulus_wasm_8 };
250 Params::r_inv_wasm_0, Params::r_inv_wasm_1, Params::r_inv_wasm_2, Params::r_inv_wasm_3, Params::r_inv_wasm_4,
251 Params::r_inv_wasm_5, Params::r_inv_wasm_6, Params::r_inv_wasm_7, Params::r_inv_wasm_8
258 if constexpr (Params::cube_root_0 != 0) {
259#if defined(__SIZEOF_INT128__) && !defined(__wasm__)
260 constexpr field result{
261 Params::cube_root_0, Params::cube_root_1, Params::cube_root_2, Params::cube_root_3
264 constexpr field result{
265 Params::cube_root_wasm_0, Params::cube_root_wasm_1, Params::cube_root_wasm_2, Params::cube_root_wasm_3
272 constexpr field result = two_inv * numerator;
283#if defined(__SIZEOF_INT128__) && !defined(__wasm__)
285 Params::coset_generator_0,
286 Params::coset_generator_1,
287 Params::coset_generator_2,
288 Params::coset_generator_3,
292 Params::coset_generator_0,
293 Params::coset_generator_1,
294 Params::coset_generator_2,
295 Params::coset_generator_3,
306 constexpr
field operator/(const
field& other) const noexcept;
317 constexpr
field& operator/=(const
field& other) & noexcept;
322 BB_INLINE constexpr
bool operator>(const
field& other) const noexcept;
323 BB_INLINE constexpr
bool operator<(const
field& other) const noexcept;
324 BB_INLINE constexpr
bool operator==(const
field& other) const noexcept;
325 BB_INLINE constexpr
bool operator!=(const
field& other) const noexcept;
343 template <typename
C>
345 requires requires(
C& c) {
358 requires((Params_::modulus_0 & 0x3UL) == 0x3UL);
360 requires((Params_::modulus_0 & 0x3UL) != 0x3UL);
436 constexpr field endo_g1 = { Params::endo_g1_lo, Params::endo_g1_mid, Params::endo_g1_hi, 0 };
437 constexpr field endo_g2 = { Params::endo_g2_lo, Params::endo_g2_mid, 0, 0 };
438 constexpr field endo_minus_b1 = { Params::endo_minus_b1_lo, Params::endo_minus_b1_mid, 0, 0 };
439 constexpr field endo_b2 = { Params::endo_b2_lo, Params::endo_b2_mid, 0, 0 };
456 return (q2_lo - q1_lo).reduce_once();
474 if constexpr (Params::modulus_3 < MODULUS_TOP_LIMB_LARGE_THRESHOLD) {
477 k1 = { ret.first[0], ret.first[1], 0, 0 };
478 k2 = { ret.second[0], ret.second[1], 0, 0 };
503 static_assert(Params::modulus_3 < MODULUS_TOP_LIMB_LARGE_THRESHOLD);
511 if (t1.
data[2] != 0 || t1.
data[3] != 0) {
512 constexpr field endo_minus_b1 = { Params::endo_minus_b1_lo, Params::endo_minus_b1_mid, 0, 0 };
526 std::ios_base::fmtflags f(os.flags());
539 void msgpack_schema(auto& packer)
const { packer.pack_alias(Params::schema_name,
"bin32"); }
545#if defined(__wasm__) || !defined(__SIZEOF_INT128__)
581 uint64_t
a, uint64_t
b, uint64_t c, uint64_t carry_in, uint64_t& carry_out)
noexcept;
584 uint64_t
a, uint64_t
b, uint64_t c, uint64_t carry_in, uint64_t& out, uint64_t& carry_out)
noexcept;
586 BB_INLINE static constexpr uint64_t
mac_mini(uint64_t
a, uint64_t
b, uint64_t c, uint64_t& out)
noexcept;
589 uint64_t
a, uint64_t
b, uint64_t c, uint64_t& out, uint64_t& carry_out)
noexcept;
593 BB_INLINE static constexpr uint64_t
addc(uint64_t
a, uint64_t
b, uint64_t carry_in, uint64_t& carry_out)
noexcept;
595 BB_INLINE static constexpr uint64_t
sbb(uint64_t
a, uint64_t
b, uint64_t borrow_in, uint64_t& borrow_out)
noexcept;
600 uint64_t carry_in_lo,
601 uint64_t carry_in_hi,
603 uint64_t& carry_hi)
noexcept;
617 if constexpr (
modulus.
data[3] < MODULUS_TOP_LIMB_LARGE_THRESHOLD) {
627#if (BBERG_NO_ASM == 0)
633 BB_INLINE static void asm_self_sqr_with_coarse_reduction(
field&
a)
noexcept;
637 BB_INLINE static void asm_conditional_negate(
field& r, uint64_t predicate)
noexcept;
640 static constexpr uint64_t zero_reference = 0x00ULL;
645#if defined(__SIZEOF_INT128__) && !defined(__wasm__)
646 static constexpr uint128_t lo_mask = 0xffffffffffffffffUL;
654 read(it, result.data[3]);
655 read(it, result.data[2]);
656 read(it, result.data[1]);
657 read(it, result.data[0]);
674template <
typename Params>
struct std::hash<
bb::field<Params>> {
678 auto reduced = ff.reduce_once();
#define BB_ASSERT_DEBUG(expression,...)
std::unique_ptr< uint8_t[]> buffer
size_t hash_as_tuple(const Ts &... ts)
Entry point for Barretenberg command-line interface.
void read(B &it, field2< base_field, Params > &value)
void write(B &buf, field2< base_field, Params > const &value)
void assert_failure(std::string const &err)
void read(auto &it, msgpack_concepts::HasMsgPack auto &obj)
Automatically derived read for any object that defines .msgpack() (implicitly defined by SERIALIZATIO...
void write(auto &buf, const msgpack_concepts::HasMsgPack auto &obj)
Automatically derived write for any object that defines .msgpack() (implicitly defined by SERIALIZATI...
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
unsigned __int128 uint128_t
General class for prime fields see Prime field documentation["field documentation"] for general imple...
static constexpr field cube_root_of_unity()
void assert_coarse_form() const noexcept
constexpr field(const int input) noexcept
constexpr ~field() noexcept=default
BB_INLINE constexpr field from_montgomery_form_reduced() const noexcept
static constexpr std::array< uint64_t, 9 > wasm_modulus
static constexpr field get_root_of_unity(size_t subgroup_size) noexcept
BB_INLINE constexpr void self_to_montgomery_form_reduced() &noexcept
static constexpr field neg_one()
static constexpr field one()
static constexpr uint256_t modulus
BB_INLINE constexpr void self_reduce_once() &noexcept
static BB_INLINE constexpr std::array< uint64_t, WASM_NUM_LIMBS > wasm_convert(const uint64_t *data)
Convert 4 64-bit limbs into 9 29-bit limbs.
constexpr field(const unsigned long long input) noexcept
BB_INLINE constexpr field operator*(const field &other) const noexcept
BB_INLINE constexpr field operator+(const field &other) const noexcept
constexpr field tonelli_shanks_sqrt() const noexcept
Implements an optimized variant of Tonelli-Shanks via lookup tables. Algorithm taken from https://cr....
constexpr field & operator=(const field &other) &noexcept=default
static constexpr field coset_generator()
BB_INLINE constexpr void self_from_montgomery_form_reduced() &noexcept
static BB_INLINE constexpr std::pair< uint64_t, uint64_t > mul_wide(uint64_t a, uint64_t b) noexcept
static constexpr uint256_t twice_not_modulus
BB_INLINE constexpr field to_montgomery_form() const noexcept
BB_INLINE constexpr wide_array mul_512(const field &other) const noexcept
static BB_INLINE constexpr uint64_t mac_discard_lo(uint64_t a, uint64_t b, uint64_t c) noexcept
static BB_INLINE constexpr uint64_t sbb(uint64_t a, uint64_t b, uint64_t borrow_in, uint64_t &borrow_out) noexcept
unsigned 64-bit subtract-with-borrow that takes in borrow_in value in the size-2 set {0,...
BB_INLINE constexpr field subtract(const field &other) const noexcept
BB_INLINE constexpr void self_conditional_negate(uint64_t predicate) &noexcept
void msgpack_schema(auto &packer) const
BB_INLINE constexpr field pow(const uint256_t &exponent) const noexcept
static BB_INLINE constexpr uint64_t mac(uint64_t a, uint64_t b, uint64_t c, uint64_t carry_in, uint64_t &carry_out) noexcept
Compute uint128_t(a * b + c + carry_in), where the inputs are all uint64_t. Return the top 64 bits.
static void split_into_endomorphism_scalars(const field &k, field &k1, field &k2)
Full-width endomorphism decomposition: k ≡ k1 - k2·λ (mod r). Modifies the field elements k1 and k2.
friend std::ostream & operator<<(std::ostream &os, const field &a)
static BB_INLINE constexpr uint64_t addc(uint64_t a, uint64_t b, uint64_t carry_in, uint64_t &carry_out) noexcept
unsigned 64-bit add-with-carry that takes in a carry_in and a carry_out bit and rewrites the latter.
static constexpr uint256_t r_squared_uint
static BB_INLINE constexpr void wasm_reduce(uint64_t &result_0, uint64_t &result_1, uint64_t &result_2, uint64_t &result_3, uint64_t &result_4, uint64_t &result_5, uint64_t &result_6, uint64_t &result_7, uint64_t &result_8)
Perform 29-bit Montgomery reduction on 1 limb (result_0 should be zero modulo 2^29 after calling this...
BB_INLINE constexpr field montgomery_mul_big(const field &other) const noexcept
Mongtomery multiplication for moduli > 2²⁵⁴
static constexpr size_t PUBLIC_INPUTS_SIZE
constexpr field & operator=(field &&other) &noexcept=default
constexpr field(const uint64_t a, const uint64_t b, const uint64_t c, const uint64_t d) noexcept
cast four uint64_t as a field
constexpr field(const uint128_t &input) noexcept
BB_INLINE constexpr void self_sqr() &noexcept
constexpr field(const uint512_t &input) noexcept
Convert a 512-bit big integer into a field element.
constexpr field invert() const noexcept
constexpr field(field &&other) noexcept=default
BB_INLINE constexpr void self_neg() &noexcept
BB_INLINE constexpr bool is_msb_set() const noexcept
static field random_element(numeric::RNG *engine=nullptr) noexcept
BB_INLINE constexpr field sqr() const noexcept
static BB_INLINE constexpr void wasm_madd(uint64_t &left_limb, const std::array< uint64_t, WASM_NUM_LIMBS > &right_limbs, uint64_t &result_0, uint64_t &result_1, uint64_t &result_2, uint64_t &result_3, uint64_t &result_4, uint64_t &result_5, uint64_t &result_6, uint64_t &result_7, uint64_t &result_8)
Multiply left limb by a sequence of 9 limbs and accumulate into result variables.
static BB_INLINE constexpr uint64_t square_accumulate(uint64_t a, uint64_t b, uint64_t c, uint64_t carry_in_lo, uint64_t carry_in_hi, uint64_t &carry_lo, uint64_t &carry_hi) noexcept
Computes a + 2 * b * c + carry_in_lo + 2^64 * carry_in_hi, in the form of returning a uint64_t and mo...
BB_INLINE constexpr field to_montgomery_form_reduced() const noexcept
constexpr uint256_t uint256_t_no_montgomery_conversion() const noexcept
static BB_INLINE constexpr void wasm_reduce_yuval(uint64_t &result_0, uint64_t &result_1, uint64_t &result_2, uint64_t &result_3, uint64_t &result_4, uint64_t &result_5, uint64_t &result_6, uint64_t &result_7, uint64_t &result_8, uint64_t &result_9)
Perform 29-bit Montgomery reduction on 1 limb using Yuval's method.
static field serialize_from_buffer(const uint8_t *buffer)
static constexpr uint256_t modulus_minus_two
static void serialize_to_buffer(const field &value, uint8_t *buffer)
void msgpack_pack(auto &packer) const
constexpr std::pair< bool, field > sqrt() const noexcept
Compute square root of the field element.
static BB_INLINE void __copy(const field &a, field &r) noexcept
const uint8_t * vec_in_buf
constexpr field(const field &other) noexcept=default
BB_INLINE constexpr void self_from_montgomery_form() &noexcept
BB_INLINE constexpr bool is_zero() const noexcept
static void batch_invert(C &coeffs) noexcept
Batch invert a collection of field elements using Montgomery's trick.
static constexpr uint256_t not_modulus
BB_INLINE constexpr void self_to_montgomery_form() &noexcept
static constexpr std::array< uint64_t, 9 > wasm_r_inv
BB_INLINE constexpr field from_montgomery_form() const noexcept
BB_INLINE constexpr field operator-() const noexcept
constexpr field(const numeric::uint256_t &input) noexcept
BB_INLINE constexpr void self_set_msb() &noexcept
void msgpack_unpack(auto o)
BB_INLINE constexpr field add(const field &other) const noexcept
BB_INLINE std::vector< uint8_t > to_buffer() const
constexpr field(const unsigned int input) noexcept
static constexpr size_t primitive_root_log_size() noexcept
static field compute_endomorphism_k2(const field &k)
Shared core of the endomorphism scalar decomposition.
static field reconstruct_from_public(const std::span< const field< V >, PUBLIC_INPUTS_SIZE > &limbs)
BB_INLINE constexpr field montgomery_square() const noexcept
Squaring via a variant of the Montgomery algorithm, where we roughly take advantage of the repeated t...
BB_INLINE constexpr field reduce_once() const noexcept
BB_INLINE constexpr field montgomery_mul(const field &other) const noexcept
static std::pair< std::array< uint64_t, 2 >, std::array< uint64_t, 2 > > split_into_endomorphism_scalars(const field &k)
128-bit endomorphism decomposition: k ≡ k1 - k2·λ (mod r).
BB_INLINE constexpr field reduce() const noexcept
reduce once, i.e., if the value is bigger than the modulus, subtract off the modulus once.
constexpr field(const unsigned long input) noexcept
static constexpr field zero()
static BB_INLINE constexpr uint64_t mac_mini(uint64_t a, uint64_t b, uint64_t c, uint64_t &out) noexcept
BB_INLINE constexpr uint64_t is_msb_set_word() const noexcept
static constexpr uint256_t twice_modulus
constexpr field(std::string input) noexcept
std::size_t operator()(const bb::field< Params > &ff) const noexcept