Skip to main content

p3_goldilocks/
goldilocks.rs

1use alloc::vec;
2use alloc::vec::Vec;
3use core::fmt::{Debug, Display, Formatter};
4use core::hash::{Hash, Hasher};
5use core::hint::assert_unchecked;
6use core::iter::{Product, Sum};
7use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
8use core::{array, fmt};
9
10use num_bigint::BigUint;
11use p3_field::exponentiation::exp_10540996611094048183;
12use p3_field::integers::QuotientMap;
13use p3_field::op_assign_macros::{
14    impl_add_assign, impl_div_methods, impl_mul_methods, impl_sub_assign,
15};
16use p3_field::{
17    Field, InjectiveMonomial, Packable, PermutationMonomial, PrimeCharacteristicRing, PrimeField,
18    PrimeField64, RawDataSerializable, TwoAdicField, UniformSamplingField,
19    impl_raw_serializable_primefield64, quotient_map_large_iint, quotient_map_large_uint,
20    quotient_map_small_int, tonelli_shanks_two_adic,
21};
22use p3_util::{branch_hint, flatten_to_base, gcd_inner};
23use rand::Rng;
24use rand::distr::{Distribution, StandardUniform};
25use serde::de::Error;
26use serde::{Deserialize, Deserializer, Serialize};
27
28/// The Goldilocks prime
29pub(crate) const P: u64 = 0xFFFF_FFFF_0000_0001;
30
31/// The prime field known as Goldilocks, defined as `F_p` where `p = 2^64 - 2^32 + 1`.
32///
33/// The serde encoding is canonical: every field element has exactly one valid byte representation.
34#[derive(Copy, Clone, Default)]
35#[repr(transparent)] // Important for reasoning about memory layout
36#[must_use]
37pub struct Goldilocks {
38    /// Not necessarily canonical.
39    pub(crate) value: u64,
40}
41
42impl Serialize for Goldilocks {
43    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
44        // Emit the canonical representative so every field element has one encoding.
45        let val = self.as_canonical_u64();
46        // Binary (non human-readable) formats get a fixed 8-byte encoding instead of
47        // the serializer's default varint, since every value here is a near-uniform
48        // 64-bit integer and varint saves nothing on average.
49        if serializer.is_human_readable() {
50            serializer.serialize_u64(val)
51        } else {
52            val.to_le_bytes().serialize(serializer)
53        }
54    }
55}
56
57impl<'de> Deserialize<'de> for Goldilocks {
58    fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
59        let human_readable = d.is_human_readable();
60        let val = if human_readable {
61            u64::deserialize(d)?
62        } else {
63            u64::from_le_bytes(<[u8; 8]>::deserialize(d)?)
64        };
65        // Reject non-canonical encodings so a proof cannot be re-encoded without the witness.
66        if val < P {
67            Ok(Self::new(val))
68        } else {
69            Err(D::Error::custom("Goldilocks value is out of range"))
70        }
71    }
72}
73
74impl Goldilocks {
75    /// Create a new field element from any `u64`.
76    ///
77    /// Any `u64` value is accepted. No reduction is performed since
78    /// Goldilocks uses a non-canonical internal representation.
79    #[inline]
80    pub const fn new(value: u64) -> Self {
81        Self { value }
82    }
83
84    /// Convert a `[u64; N]` array to an array of field elements.
85    ///
86    /// Const version of `input.map(Goldilocks::new)`.
87    #[inline]
88    pub const fn new_array<const N: usize>(input: [u64; N]) -> [Self; N] {
89        let mut output = [Self::ZERO; N];
90        let mut i = 0;
91        while i < N {
92            output[i].value = input[i];
93            i += 1;
94        }
95        output
96    }
97
98    /// Convert a `[[u64; N]; M]` array to a 2D array of field elements.
99    ///
100    /// Const version of `input.map(Goldilocks::new_array)`.
101    #[inline]
102    pub const fn new_2d_array<const N: usize, const M: usize>(
103        input: [[u64; N]; M],
104    ) -> [[Self; N]; M] {
105        let mut output = [[Self::ZERO; N]; M];
106        let mut i = 0;
107        while i < M {
108            output[i] = Self::new_array(input[i]);
109            i += 1;
110        }
111        output
112    }
113
114    /// Two's complement of `ORDER`, i.e. `2^64 - ORDER = 2^32 - 1`.
115    const NEG_ORDER: u64 = Self::ORDER_U64.wrapping_neg();
116
117    /// A list of generators for the two-adic subgroups of the goldilocks field.
118    ///
119    /// These satisfy the properties that `TWO_ADIC_GENERATORS[0] = 1` and `TWO_ADIC_GENERATORS[i+1]^2 = TWO_ADIC_GENERATORS[i]`.
120    pub const TWO_ADIC_GENERATORS: [Self; 33] = Self::new_array([
121        0x0000000000000001,
122        0xffffffff00000000,
123        0x0001000000000000,
124        0xfffffffeff000001,
125        0xefffffff00000001,
126        0x00003fffffffc000,
127        0x0000008000000000,
128        0xf80007ff08000001,
129        0xbf79143ce60ca966,
130        0x1905d02a5c411f4e,
131        0x9d8f2ad78bfed972,
132        0x0653b4801da1c8cf,
133        0xf2c35199959dfcb6,
134        0x1544ef2335d17997,
135        0xe0ee099310bba1e2,
136        0xf6b2cffe2306baac,
137        0x54df9630bf79450e,
138        0xabd0a6e8aa3d8a0e,
139        0x81281a7b05f9beac,
140        0xfbd41c6b8caa3302,
141        0x30ba2ecd5e93e76d,
142        0xf502aef532322654,
143        0x4b2a18ade67246b5,
144        0xea9d5a1336fbc98b,
145        0x86cdcc31c307e171,
146        0x4bbaf5976ecfefd8,
147        0xed41d05b78d6e286,
148        0x10d78dd8915a171d,
149        0x59049500004a4485,
150        0xdfa8c93ba46d2666,
151        0x7e9bd009b86a0845,
152        0x400a7f755588e659,
153        0x185629dcda58878c,
154    ]);
155
156    /// A list of powers of two from 0 to 95.
157    ///
158    /// Note that 2^{96} = -1 mod P so all powers of two can be simply
159    /// derived from this list.
160    const POWERS_OF_TWO: [Self; 96] = {
161        let mut powers_of_two = [Self::ONE; 96];
162
163        let mut i = 1;
164        while i < 64 {
165            powers_of_two[i] = Self::new(1 << i);
166            i += 1;
167        }
168        let mut var = Self::new(1 << 63);
169        while i < 96 {
170            var = const_add(var, var);
171            powers_of_two[i] = var;
172            i += 1;
173        }
174        powers_of_two
175    };
176}
177
178impl PartialEq for Goldilocks {
179    fn eq(&self, other: &Self) -> bool {
180        self.as_canonical_u64() == other.as_canonical_u64()
181    }
182}
183
184impl Eq for Goldilocks {}
185
186impl Packable for Goldilocks {}
187
188impl Hash for Goldilocks {
189    fn hash<H: Hasher>(&self, state: &mut H) {
190        state.write_u64(self.as_canonical_u64());
191    }
192}
193
194impl Ord for Goldilocks {
195    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
196        self.as_canonical_u64().cmp(&other.as_canonical_u64())
197    }
198}
199
200impl PartialOrd for Goldilocks {
201    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
202        Some(self.cmp(other))
203    }
204}
205
206impl Display for Goldilocks {
207    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
208        Display::fmt(&self.as_canonical_u64(), f)
209    }
210}
211
212impl Debug for Goldilocks {
213    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
214        Debug::fmt(&self.as_canonical_u64(), f)
215    }
216}
217
218impl Distribution<Goldilocks> for StandardUniform {
219    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Goldilocks {
220        loop {
221            let next_u64 = rng.next_u64();
222            let is_canonical = next_u64 < Goldilocks::ORDER_U64;
223            if is_canonical {
224                return Goldilocks::new(next_u64);
225            }
226        }
227    }
228}
229
230impl UniformSamplingField for Goldilocks {
231    const MAX_SINGLE_SAMPLE_BITS: usize = 32;
232    const SAMPLING_BITS_M: [u64; 64] = {
233        let prime: u64 = P;
234        let mut a = [0u64; 64];
235        let mut k = 0;
236        while k < 64 {
237            if k == 0 {
238                a[k] = prime; // This value is irrelevant in practice. `bits = 0` returns 0 always.
239            } else {
240                // Create a mask to zero out the last k bits
241                let mask = !((1u64 << k) - 1);
242                a[k] = prime & mask;
243            }
244            k += 1;
245        }
246        a
247    };
248}
249
250impl PrimeCharacteristicRing for Goldilocks {
251    type PrimeSubfield = Self;
252
253    const ZERO: Self = Self::new(0);
254    const ONE: Self = Self::new(1);
255    const TWO: Self = Self::new(2);
256    const NEG_ONE: Self = Self::new(Self::ORDER_U64 - 1);
257
258    #[inline]
259    fn from_prime_subfield(f: Self::PrimeSubfield) -> Self {
260        f
261    }
262
263    #[inline]
264    fn from_bool(b: bool) -> Self {
265        Self::new(b.into())
266    }
267
268    #[inline]
269    fn halve(&self) -> Self {
270        // Branchless halving: x/2 = (x >> 1) + ((x & 1) * (p+1)/2).
271        // When x is odd, add (p+1)/2 to compensate for the lost bit.
272        // Uses mask arithmetic to avoid the 50/50 unpredictable branch.
273        const HALF_P_PLUS_1: u64 = (P + 1) >> 1; // 0x7FFFFFFF80000001
274        let lo_bit = self.value & 1;
275        let half = self.value >> 1;
276        let mask = 0u64.wrapping_sub(lo_bit); // all-ones when odd, zero when even
277        Self::new(half.wrapping_add(mask & HALF_P_PLUS_1))
278    }
279
280    #[inline]
281    fn mul_2exp_u64(&self, exp: u64) -> Self {
282        // In the Goldilocks field, 2^96 = -1 mod P and 2^192 = 1 mod P.
283        match exp {
284            0 => *self,
285            1 => *self + *self,
286            _ => {
287                if exp < 96 {
288                    *self * Self::POWERS_OF_TWO[exp as usize]
289                } else if exp < 192 {
290                    -*self * Self::POWERS_OF_TWO[(exp - 96) as usize]
291                } else {
292                    self.mul_2exp_u64(exp % 192)
293                }
294            }
295        }
296    }
297
298    #[inline]
299    fn div_2exp_u64(&self, mut exp: u64) -> Self {
300        // In the goldilocks field, 2^192 = 1 mod P.
301        // Thus 2^{-n} = 2^{192 - n} mod P.
302        exp %= 192;
303        match exp {
304            0 => *self,
305            1 => self.halve(),
306            _ => self.mul_2exp_u64(192 - exp),
307        }
308    }
309
310    #[inline]
311    fn sum_array<const N: usize>(input: &[Self]) -> Self {
312        assert_eq!(N, input.len());
313        // Benchmarking shows that for N <= 3 it's faster to sum the elements directly
314        // but for N > 3 it's faster to use the .sum() methods which passes through u128's
315        // allowing for delayed reductions.
316        match N {
317            0 => Self::ZERO,
318            1 => input[0],
319            2 => input[0] + input[1],
320            3 => input[0] + input[1] + input[2],
321            _ => input.iter().copied().sum(),
322        }
323    }
324
325    #[inline]
326    fn dot_product<const N: usize>(lhs: &[Self; N], rhs: &[Self; N]) -> Self {
327        // The constant OFFSET has 2 important properties:
328        // 1. It is a multiple of P.
329        // 2. It is greater than the maximum possible value of the sum of the products of two u64s.
330        const OFFSET: u128 = ((P as u128) << 64) - (P as u128) + ((P as u128) << 32);
331        const {
332            assert!((N as u32) <= (1 << 31));
333        }
334        match N {
335            0 => Self::ZERO,
336            1 => lhs[0] * rhs[0],
337            2 => {
338                // We unroll the N = 2 case as it is slightly faster and this is an important case
339                // as a major use is in extension field arithmetic and Goldilocks has a degree 2 extension.
340                let long_prod_0 = (lhs[0].value as u128) * (rhs[0].value as u128);
341                let long_prod_1 = (lhs[1].value as u128) * (rhs[1].value as u128);
342
343                // We know that long_prod_0, long_prod_1 < OFFSET.
344                // Thus if long_prod_0 + long_prod_1 overflows, we can just subtract OFFSET.
345                let (sum, over) = long_prod_0.overflowing_add(long_prod_1);
346                // Compiler really likes defining sum_corr here instead of in the if/else.
347                let sum_corr = sum.wrapping_sub(OFFSET);
348                if over {
349                    reduce128(sum_corr)
350                } else {
351                    reduce128(sum)
352                }
353            }
354            _ => {
355                let (lo_plus_hi, hi) = lhs
356                    .iter()
357                    .zip(rhs)
358                    .map(|(x, y)| (x.value as u128) * (y.value as u128))
359                    .fold((0_u128, 0_u64), |(acc_lo, acc_hi), val| {
360                        // Split val into (hi, lo) where hi is the upper 32 bits and lo is the lower 96 bits.
361                        let val_hi = (val >> 96) as u64;
362                        // acc_hi accumulates hi, acc_lo accumulates lo + 2^{96}hi.
363                        // As N <= 2^32, acc_hi cannot overflow.
364                        unsafe { (acc_lo.wrapping_add(val), acc_hi.unchecked_add(val_hi)) }
365                    });
366                // First, remove the hi part from lo_plus_hi.
367                let lo = lo_plus_hi.wrapping_sub((hi as u128) << 96);
368                // As 2^{96} = -1 mod P, we simply need to reduce lo - hi.
369                // As N <= 2^31, lo < 2^127 and hi < 2^63 < P. Hence the equation below will not over or underflow.
370                let sum = unsafe { lo.unchecked_add(P.unchecked_sub(hi) as u128) };
371                reduce128(sum)
372            }
373        }
374    }
375
376    #[inline]
377    fn zero_vec(len: usize) -> Vec<Self> {
378        // SAFETY:
379        // Due to `#[repr(transparent)]`, Goldilocks and u64 have the same size, alignment
380        // and memory layout making `flatten_to_base` safe. This will create
381        // a vector of Goldilocks elements with value set to 0.
382        unsafe { flatten_to_base(vec![0u64; len]) }
383    }
384}
385
386/// Degree of the smallest permutation polynomial for Goldilocks.
387///
388/// As p - 1 = 2^32 * 3 * 5 * 17 * ... the smallest choice for a degree D satisfying gcd(p - 1, D) = 1 is 7.
389impl InjectiveMonomial<7> for Goldilocks {}
390
391impl PermutationMonomial<7> for Goldilocks {
392    /// In the field `Goldilocks`, `a^{1/7}` is equal to a^{10540996611094048183}.
393    ///
394    /// This follows from the calculation `7*10540996611094048183 = 4*(2^64 - 2**32) + 1 = 1 mod (p - 1)`.
395    fn injective_exp_root_n(&self) -> Self {
396        exp_10540996611094048183(*self)
397    }
398}
399
400impl RawDataSerializable for Goldilocks {
401    impl_raw_serializable_primefield64!();
402}
403
404impl Field for Goldilocks {
405    #[cfg(all(
406        target_arch = "x86_64",
407        target_feature = "avx2",
408        not(target_feature = "avx512f")
409    ))]
410    type Packing = crate::PackedGoldilocksAVX2;
411
412    #[cfg(all(target_arch = "x86_64", target_feature = "avx512f"))]
413    type Packing = crate::PackedGoldilocksAVX512;
414
415    #[cfg(all(target_arch = "aarch64", target_feature = "neon"))]
416    type Packing = crate::PackedGoldilocksNeon;
417
418    #[cfg(all(target_arch = "wasm32", target_feature = "simd128"))]
419    type Packing = crate::PackedGoldilocksWasmSimd128;
420
421    #[cfg(not(any(
422        all(
423            target_arch = "x86_64",
424            target_feature = "avx2",
425            not(target_feature = "avx512f")
426        ),
427        all(target_arch = "x86_64", target_feature = "avx512f"),
428        all(target_arch = "aarch64", target_feature = "neon"),
429        all(target_arch = "wasm32", target_feature = "simd128"),
430    )))]
431    type Packing = Self;
432
433    // Sage: GF(2^64 - 2^32 + 1).multiplicative_generator()
434    const GENERATOR: Self = Self::new(7);
435
436    // Measured -11% on quotient evaluation (twoadic PCS, Keccak AIR, aarch64+neon).
437    const BENEFITS_FROM_LOCKSTEP_EVALUATION: bool = true;
438
439    fn is_zero(&self) -> bool {
440        self.value == 0 || self.value == Self::ORDER_U64
441    }
442
443    fn try_inverse(&self) -> Option<Self> {
444        if self.is_zero() {
445            return None;
446        }
447
448        Some(gcd_inversion(*self))
449    }
450
451    #[inline]
452    fn order() -> BigUint {
453        P.into()
454    }
455
456    #[inline]
457    fn try_sqrt(&self) -> Option<Self> {
458        tonelli_shanks_two_adic(*self)
459    }
460}
461
462// We use macros to implement QuotientMap<Int> for all integer types except for u64 and i64.
463quotient_map_small_int!(Goldilocks, u64, [u8, u16, u32]);
464quotient_map_small_int!(Goldilocks, i64, [i8, i16, i32]);
465quotient_map_large_uint!(
466    Goldilocks,
467    u64,
468    Goldilocks::ORDER_U64,
469    "`[0, 2^64 - 2^32]`",
470    "`[0, 2^64 - 1]`",
471    [u128]
472);
473quotient_map_large_iint!(
474    Goldilocks,
475    i64,
476    "`[-(2^63 - 2^31), 2^63 - 2^31]`",
477    "`[1 + 2^32 - 2^64, 2^64 - 1]`",
478    [(i128, u128)]
479);
480
481impl QuotientMap<u64> for Goldilocks {
482    /// Convert a given `u64` integer into an element of the `Goldilocks` field.
483    ///
484    /// No reduction is needed as the internal value is allowed
485    /// to be any u64.
486    #[inline]
487    fn from_int(int: u64) -> Self {
488        Self::new(int)
489    }
490
491    /// Convert a given `u64` integer into an element of the `Goldilocks` field.
492    ///
493    /// Return `None` if the given integer is greater than `p = 2^64 - 2^32 + 1`.
494    #[inline]
495    fn from_canonical_checked(int: u64) -> Option<Self> {
496        (int < Self::ORDER_U64).then(|| Self::new(int))
497    }
498
499    /// Convert a given `u64` integer into an element of the `Goldilocks` field.
500    ///
501    /// # Safety
502    /// In this case this function is actually always safe as the internal
503    /// value is allowed to be any u64.
504    #[inline(always)]
505    unsafe fn from_canonical_unchecked(int: u64) -> Self {
506        Self::new(int)
507    }
508}
509
510impl QuotientMap<i64> for Goldilocks {
511    /// Convert a given `i64` integer into an element of the `Goldilocks` field.
512    ///
513    /// We simply need to deal with the sign.
514    #[inline]
515    fn from_int(int: i64) -> Self {
516        if int >= 0 {
517            Self::new(int as u64)
518        } else {
519            Self::new(Self::ORDER_U64.wrapping_add_signed(int))
520        }
521    }
522
523    /// Convert a given `i64` integer into an element of the `Goldilocks` field.
524    ///
525    /// Returns none if the input does not lie in the range `(-(2^63 - 2^31), 2^63 - 2^31)`.
526    #[inline]
527    fn from_canonical_checked(int: i64) -> Option<Self> {
528        const POS_BOUND: i64 = (P >> 1) as i64;
529        const NEG_BOUND: i64 = -POS_BOUND;
530        match int {
531            0..=POS_BOUND => Some(Self::new(int as u64)),
532            NEG_BOUND..0 => Some(Self::new(Self::ORDER_U64.wrapping_add_signed(int))),
533            _ => None,
534        }
535    }
536
537    /// Convert a given `i64` integer into an element of the `Goldilocks` field.
538    ///
539    /// # Safety
540    /// In this case this function is actually always safe as the internal
541    /// value is allowed to be any u64.
542    #[inline(always)]
543    unsafe fn from_canonical_unchecked(int: i64) -> Self {
544        Self::from_int(int)
545    }
546}
547
548impl PrimeField for Goldilocks {
549    fn as_canonical_biguint(&self) -> BigUint {
550        self.as_canonical_u64().into()
551    }
552}
553
554impl PrimeField64 for Goldilocks {
555    const ORDER_U64: u64 = P;
556
557    #[inline]
558    fn as_canonical_u64(&self) -> u64 {
559        let mut c = self.value;
560        // We only need one condition subtraction, since 2 * ORDER would not fit in a u64.
561        if c >= Self::ORDER_U64 {
562            c -= Self::ORDER_U64;
563        }
564        c
565    }
566}
567
568impl TwoAdicField for Goldilocks {
569    const TWO_ADICITY: usize = 32;
570
571    fn two_adic_generator(bits: usize) -> Self {
572        assert!(bits <= Self::TWO_ADICITY);
573        Self::TWO_ADIC_GENERATORS[bits]
574    }
575}
576
577/// A const version of the addition function.
578///
579/// Useful for constructing constants values in const contexts. Outside of
580/// const contexts, Add should be used instead.
581#[inline]
582const fn const_add(lhs: Goldilocks, rhs: Goldilocks) -> Goldilocks {
583    let (sum, over) = lhs.value.overflowing_add(rhs.value);
584    let (mut sum, over) = sum.overflowing_add((over as u64) * Goldilocks::NEG_ORDER);
585    if over {
586        sum += Goldilocks::NEG_ORDER;
587    }
588    Goldilocks::new(sum)
589}
590
591impl Add for Goldilocks {
592    type Output = Self;
593
594    #[inline]
595    fn add(self, rhs: Self) -> Self {
596        let (sum, over) = self.value.overflowing_add(rhs.value);
597        let (mut sum, over) = sum.overflowing_add(u64::from(over) * Self::NEG_ORDER);
598        if over {
599            // NB: self.value > Self::ORDER && rhs.value > Self::ORDER is necessary but not
600            // sufficient for double-overflow.
601            // This hint does two things:
602            //  1. If compiler knows that either self.value or rhs.value <= ORDER, then it can skip
603            //     this check.
604            //  2. Hints to the compiler how rare this double-overflow is (thus handled better with
605            //     a branch).
606            unsafe {
607                assert_unchecked(self.value > Self::ORDER_U64 && rhs.value > Self::ORDER_U64);
608            }
609            branch_hint();
610            sum += Self::NEG_ORDER; // Cannot overflow.
611        }
612        Self::new(sum)
613    }
614}
615
616impl Sub for Goldilocks {
617    type Output = Self;
618
619    #[inline]
620    fn sub(self, rhs: Self) -> Self {
621        let (diff, under) = self.value.overflowing_sub(rhs.value);
622        let (mut diff, under) = diff.overflowing_sub(u64::from(under) * Self::NEG_ORDER);
623        if under {
624            // NB: self.value < NEG_ORDER - 1 && rhs.value > ORDER is necessary but not
625            // sufficient for double-underflow.
626            // This hint does two things:
627            //  1. If compiler knows that either self.value >= NEG_ORDER - 1 or rhs.value <= ORDER,
628            //     then it can skip this check.
629            //  2. Hints to the compiler how rare this double-underflow is (thus handled better
630            //     with a branch).
631            unsafe {
632                assert_unchecked(self.value < Self::NEG_ORDER - 1 && rhs.value > Self::ORDER_U64);
633            }
634            branch_hint();
635            diff -= Self::NEG_ORDER; // Cannot underflow.
636        }
637        Self::new(diff)
638    }
639}
640
641impl Neg for Goldilocks {
642    type Output = Self;
643
644    #[inline]
645    fn neg(self) -> Self::Output {
646        Self::new(Self::ORDER_U64 - self.as_canonical_u64())
647    }
648}
649
650impl Mul for Goldilocks {
651    type Output = Self;
652
653    #[inline]
654    fn mul(self, rhs: Self) -> Self {
655        reduce128(u128::from(self.value) * u128::from(rhs.value))
656    }
657}
658
659impl_add_assign!(Goldilocks);
660impl_sub_assign!(Goldilocks);
661impl_mul_methods!(Goldilocks);
662impl_div_methods!(Goldilocks, Goldilocks);
663
664impl Sum for Goldilocks {
665    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
666        // This is faster than iter.reduce(|x, y| x + y).unwrap_or(Self::ZERO) for iterators of length > 2.
667
668        // This sum will not overflow so long as iter.len() < 2^64.
669        let sum = iter.map(|x| x.value as u128).sum::<u128>();
670        reduce128(sum)
671    }
672}
673
674/// Reduces to a 64-bit value. The result might not be in canonical form; it could be in between the
675/// field order and `2^64`.
676#[inline]
677pub(crate) fn reduce128(x: u128) -> Goldilocks {
678    let (x_lo, x_hi) = split(x); // This is a no-op
679    let x_hi_hi = x_hi >> 32;
680    let x_hi_lo = x_hi & Goldilocks::NEG_ORDER;
681
682    let (mut t0, borrow) = x_lo.overflowing_sub(x_hi_hi);
683    if borrow {
684        branch_hint(); // A borrow is exceedingly rare. It is faster to branch.
685        t0 -= Goldilocks::NEG_ORDER; // Cannot underflow.
686    }
687    let t1 = x_hi_lo * Goldilocks::NEG_ORDER;
688    let t2 = unsafe { add_no_canonicalize_trashing_input(t0, t1) };
689    Goldilocks::new(t2)
690}
691
692#[inline]
693#[allow(clippy::cast_possible_truncation)]
694const fn split(x: u128) -> (u64, u64) {
695    (x as u64, (x >> 64) as u64)
696}
697
698/// Fast addition modulo ORDER for x86-64.
699/// This function is marked unsafe for the following reasons:
700///   - It is only correct if x + y < 2**64 + ORDER = 0x1ffffffff00000001.
701///   - It is only faster in some circumstances. In particular, on x86 it overwrites both inputs in
702///     the registers, so its use is not recommended when either input will be used again.
703#[inline(always)]
704#[cfg(target_arch = "x86_64")]
705unsafe fn add_no_canonicalize_trashing_input(x: u64, y: u64) -> u64 {
706    unsafe {
707        let res_wrapped: u64;
708        let adjustment: u64;
709        core::arch::asm!(
710            "add {0}, {1}",
711            // Trick. The carry flag is set iff the addition overflowed.
712            // sbb x, y does x := x - y - CF. In our case, x and y are both {1:e}, so it simply does
713            // {1:e} := 0xffffffff on overflow and {1:e} := 0 otherwise. {1:e} is the low 32 bits of
714            // {1}; the high 32-bits are zeroed on write. In the end, we end up with 0xffffffff in {1}
715            // on overflow; this happens be NEG_ORDER.
716            // Note that the CPU does not realize that the result of sbb x, x does not actually depend
717            // on x. We must write the result to a register that we know to be ready. We have a
718            // dependency on {1} anyway, so let's use it.
719            "sbb {1:e}, {1:e}",
720            inlateout(reg) x => res_wrapped,
721            inlateout(reg) y => adjustment,
722            options(pure, nomem, nostack),
723        );
724        assert_unchecked(x != 0 || (res_wrapped == y && adjustment == 0));
725        assert_unchecked(y != 0 || (res_wrapped == x && adjustment == 0));
726        // Add NEG_ORDER == subtract ORDER.
727        // Cannot overflow unless the assumption if x + y < 2**64 + ORDER is incorrect.
728        res_wrapped + adjustment
729    }
730}
731
732#[inline(always)]
733#[cfg(not(target_arch = "x86_64"))]
734unsafe fn add_no_canonicalize_trashing_input(x: u64, y: u64) -> u64 {
735    let (res_wrapped, carry) = x.overflowing_add(y);
736    // Below cannot overflow unless the assumption if x + y < 2**64 + ORDER is incorrect.
737    res_wrapped + Goldilocks::NEG_ORDER * u64::from(carry)
738}
739
740/// Compute the inverse of a Goldilocks element `a` using the binary GCD algorithm.
741///
742/// Instead of applying the standard algorithm this uses a variant inspired by <https://eprint.iacr.org/2020/972.pdf>.
743/// The key idea is to compute update factors which are incorrect by a known power of 2 which
744/// can be corrected at the end. These update factors can then be used to construct the inverse
745/// via a simple linear combination.
746///
747/// This is much faster than the standard algorithm as we avoid most of the (more expensive) field arithmetic.
748fn gcd_inversion(input: Goldilocks) -> Goldilocks {
749    // Initialise our values to the value we want to invert and the prime.
750    let (mut a, mut b) = (input.value, P);
751
752    // As the goldilocks prime is 64 bit, initially `len(a) + len(b) ≤ 2 * 64 = 128`.
753    // This means we will need `126` iterations of the inner loop ensure `len(a) + len(b) ≤ 2`.
754    // We split the iterations into 2 rounds of length 63.
755    const ROUND_SIZE: usize = 63;
756
757    // In theory we could make this slightly faster by replacing the first `gcd_inner` by a copy-pasted
758    // version which doesn't do any computations involving g. But either the compiler works this out
759    // for itself or the speed up is negligible as I couldn't notice any difference in benchmarks.
760    let (f00, _, f10, _) = gcd_inner::<ROUND_SIZE>(&mut a, &mut b);
761    let (_, _, f11, g11) = gcd_inner::<ROUND_SIZE>(&mut a, &mut b);
762
763    // The update factors are i64's except we need to interpret -2^63 as 2^63.
764    // This is because the outputs of `gcd_inner` are always in the range `(-2^ROUND_SIZE, 2^ROUND_SIZE]`.
765    let u = from_unusual_int(f00);
766    let v = from_unusual_int(f10);
767    let u_fac11 = from_unusual_int(f11);
768    let v_fac11 = from_unusual_int(g11);
769
770    // Each iteration introduced a factor of 2 and so we need to divide by 2^{126}.
771    // But 2^{192} = 1 mod P, so we can instead multiply by 2^{66} as 192 - 126 = 66.
772    (u * u_fac11 + v * v_fac11).mul_2exp_u64(66)
773}
774
775/// Convert from an i64 to a Goldilocks element but interpret -2^63 as 2^63.
776const fn from_unusual_int(int: i64) -> Goldilocks {
777    if (int >= 0) || (int == i64::MIN) {
778        Goldilocks::new(int as u64)
779    } else {
780        Goldilocks::new(Goldilocks::ORDER_U64.wrapping_add_signed(int))
781    }
782}
783
784#[cfg(test)]
785mod tests {
786    use p3_field::extension::BinomialExtensionField;
787    use p3_field_testing::{
788        test_field, test_field_dft, test_prime_field, test_prime_field_64, test_two_adic_field,
789    };
790
791    use super::*;
792
793    type F = Goldilocks;
794    type EF = BinomialExtensionField<F, 5>;
795
796    #[test]
797    fn deserialize_rejects_non_canonical_encodings() {
798        // p, p + i, and u64::MAX are all field-equal to canonical values.
799        // Only the canonical encoding may deserialize.
800        // This blocks re-encoding a proof as p + i without the witness.
801        for non_canonical in [P, P + 5, u64::MAX] {
802            let json = serde_json::to_string(&non_canonical).unwrap();
803            assert!(serde_json::from_str::<F>(&json).is_err());
804        }
805
806        // The largest canonical value, p - 1, still deserializes.
807        let max_canonical_json = serde_json::to_string(&(P - 1)).unwrap();
808        let max_canonical: F = serde_json::from_str(&max_canonical_json).unwrap();
809        assert_eq!(max_canonical.as_canonical_u64(), P - 1);
810    }
811
812    #[test]
813    fn serialize_is_canonical() {
814        // A non-canonical in-memory value serializes to its canonical representative.
815        //     in memory : p + 5
816        //     canonical : 5
817        let non_canonical = F::new(P + 5);
818        let json = serde_json::to_string(&non_canonical).unwrap();
819        assert_eq!(json, "5");
820
821        // The canonical encoding round-trips back to the same field element.
822        let roundtrip: F = serde_json::from_str(&json).unwrap();
823        assert_eq!(roundtrip, non_canonical);
824    }
825
826    #[test]
827    fn test_goldilocks() {
828        let f = F::new(100);
829        assert_eq!(f.as_canonical_u64(), 100);
830
831        // Over the Goldilocks field, the following set of equations hold
832        // p               = 0
833        // 2^64 - 2^32 + 1 = 0
834        // 2^64            = 2^32 - 1
835        let f = F::new(u64::MAX);
836        assert_eq!(f.as_canonical_u64(), u32::MAX as u64 - 1);
837
838        let f = F::from_u64(u64::MAX);
839        assert_eq!(f.as_canonical_u64(), u32::MAX as u64 - 1);
840
841        // Generator check
842        let expected_multiplicative_group_generator = F::new(7);
843        assert_eq!(F::GENERATOR, expected_multiplicative_group_generator);
844        assert_eq!(F::GENERATOR.as_canonical_u64(), 7_u64);
845
846        // Check on `reduce_u128`
847        let x = u128::MAX;
848        let y = reduce128(x);
849        // The following equality sequence holds, modulo p = 2^64 - 2^32 + 1
850        // 2^128 - 1 = (2^64 - 1) * (2^64 + 1)
851        //           = (2^32 - 1 - 1) * (2^32 - 1 + 1)
852        //           = (2^32 - 2) * (2^32)
853        //           = 2^64 - 2 * 2^32
854        //           = 2^64 - 2^33
855        //           = 2^32 - 1 - 2^33
856        //           = - 2^32 - 1
857        let expected_result = -F::TWO.exp_power_of_2(5) - F::ONE;
858        assert_eq!(y, expected_result);
859
860        let f = F::new(100);
861        assert_eq!(f.injective_exp_n().injective_exp_root_n(), f);
862        assert_eq!(y.injective_exp_n().injective_exp_root_n(), y);
863        assert_eq!(F::TWO.injective_exp_n().injective_exp_root_n(), F::TWO);
864    }
865
866    // Goldilocks has a redundant representation for both 0 and 1.
867    const ZEROS: [Goldilocks; 2] = [Goldilocks::ZERO, Goldilocks::new(P)];
868    const ONES: [Goldilocks; 2] = [Goldilocks::ONE, Goldilocks::new(P + 1)];
869
870    // Get the prime factorization of the order of the multiplicative group.
871    // i.e. the prime factorization of P - 1.
872    fn multiplicative_group_prime_factorization() -> [(BigUint, u32); 6] {
873        [
874            (BigUint::from(2u8), 32),
875            (BigUint::from(3u8), 1),
876            (BigUint::from(5u8), 1),
877            (BigUint::from(17u8), 1),
878            (BigUint::from(257u16), 1),
879            (BigUint::from(65537u32), 1),
880        ]
881    }
882
883    test_field!(
884        crate::Goldilocks,
885        &super::ZEROS,
886        &super::ONES,
887        &super::multiplicative_group_prime_factorization()
888    );
889    test_prime_field!(crate::Goldilocks);
890    test_prime_field_64!(crate::Goldilocks, &super::ZEROS, &super::ONES);
891    test_two_adic_field!(crate::Goldilocks);
892
893    test_field_dft!(
894        radix2dit,
895        crate::Goldilocks,
896        super::EF,
897        p3_dft::Radix2Dit<_>
898    );
899    test_field_dft!(bowers, crate::Goldilocks, super::EF, p3_dft::Radix2Bowers);
900    test_field_dft!(
901        parallel,
902        crate::Goldilocks,
903        super::EF,
904        p3_dft::Radix2DitParallel<crate::Goldilocks>
905    );
906}