lambdaworks_math/field/fields/
u64_goldilocks_field.rs

1use core::fmt::{self, Display};
2
3use crate::traits::ByteConversion;
4use crate::{
5    errors::CreationError,
6    field::{
7        element::FieldElement,
8        errors::FieldError,
9        extensions::quadratic::{HasQuadraticNonResidue, QuadraticExtensionField},
10        traits::{IsField, IsPrimeField},
11    },
12};
13
14/// Goldilocks Prime Field F_p where p = 2^64 - 2^32 + 1;
15#[derive(Debug, Clone, Copy, Hash, PartialOrd, Ord, PartialEq, Eq)]
16pub struct Goldilocks64Field;
17
18impl Goldilocks64Field {
19    pub const ORDER: u64 = 0xFFFF_FFFF_0000_0001;
20    // Two's complement of `ORDER` i.e. `2^64 - ORDER = 2^32 - 1`
21    pub const NEG_ORDER: u64 = Self::ORDER.wrapping_neg();
22}
23
24impl ByteConversion for u64 {
25    #[cfg(feature = "alloc")]
26    fn to_bytes_be(&self) -> alloc::vec::Vec<u8> {
27        unimplemented!()
28    }
29
30    #[cfg(feature = "alloc")]
31    fn to_bytes_le(&self) -> alloc::vec::Vec<u8> {
32        unimplemented!()
33    }
34
35    fn from_bytes_be(_bytes: &[u8]) -> Result<Self, crate::errors::ByteConversionError>
36    where
37        Self: Sized,
38    {
39        unimplemented!()
40    }
41
42    fn from_bytes_le(_bytes: &[u8]) -> Result<Self, crate::errors::ByteConversionError>
43    where
44        Self: Sized,
45    {
46        unimplemented!()
47    }
48}
49
50//NOTE: This implementation was inspired by and borrows from the work done by the Plonky3 team
51//https://github.com/Plonky3/Plonky3/blob/main/goldilocks/src/lib.rs
52// Thank you for pushing this technology forward.
53impl IsField for Goldilocks64Field {
54    type BaseType = u64;
55
56    fn add(a: &u64, b: &u64) -> u64 {
57        let (sum, over) = a.overflowing_add(*b);
58        let (mut sum, over) = sum.overflowing_add(u64::from(over) * Self::NEG_ORDER);
59        if over {
60            sum += Self::NEG_ORDER
61        }
62        Self::representative(&sum)
63    }
64
65    fn mul(a: &u64, b: &u64) -> u64 {
66        Self::representative(&reduce_128(u128::from(*a) * u128::from(*b)))
67    }
68
69    fn sub(a: &u64, b: &u64) -> u64 {
70        let (diff, under) = a.overflowing_sub(*b);
71        let (mut diff, under) = diff.overflowing_sub(u64::from(under) * Self::NEG_ORDER);
72        if under {
73            diff -= Self::NEG_ORDER;
74        }
75        Self::representative(&diff)
76    }
77
78    fn neg(a: &u64) -> u64 {
79        Self::sub(&Self::ORDER, &Self::representative(a))
80    }
81
82    /// Returns the multiplicative inverse of `a`.
83    fn inv(a: &u64) -> Result<u64, FieldError> {
84        if *a == Self::zero() || *a == Self::ORDER {
85            return Err(FieldError::InvZeroError);
86        }
87
88        // a^11
89        let t2 = Self::mul(&Self::square(a), a);
90
91        // a^111
92        let t3 = Self::mul(&Self::square(&t2), a);
93
94        // compute base^111111 (6 ones) by repeatedly squaring t3 3 times and multiplying by t3
95        let t6 = exp_acc::<3>(&t3, &t3);
96        let t60 = Self::square(&t6);
97        let t7 = Self::mul(&t60, a);
98
99        // compute base^111111111111 (12 ones)
100        // repeatedly square t6 6 times and multiply by t6
101        let t12 = exp_acc::<5>(&t60, &t6);
102
103        // compute base^111111111111111111111111 (24 ones)
104        // repeatedly square t12 12 times and multiply by t12
105        let t24 = exp_acc::<12>(&t12, &t12);
106
107        // compute base^1111111111111111111111111111111 (31 ones)
108        // repeatedly square t24 6 times and multiply by t6 first. then square t30 and multiply by base
109        let t31 = exp_acc::<7>(&t24, &t7);
110
111        // compute base^111111111111111111111111111111101111111111111111111111111111111
112        // repeatedly square t31 32 times and multiply by t31
113        let t63 = exp_acc::<32>(&t31, &t31);
114
115        Ok(Self::mul(&Self::square(&t63), a))
116    }
117
118    /// Returns the division of `a` and `b`.
119    fn div(a: &u64, b: &u64) -> Result<u64, FieldError> {
120        let b_inv = &Self::inv(b)?;
121        Ok(Self::mul(a, b_inv))
122    }
123
124    /// Returns a boolean indicating whether `a` and `b` are equal or not.
125    fn eq(a: &u64, b: &u64) -> bool {
126        Self::representative(a) == Self::representative(b)
127    }
128
129    /// Returns the additive neutral element.
130    fn zero() -> u64 {
131        0u64
132    }
133
134    /// Returns the multiplicative neutral element.
135    fn one() -> u64 {
136        1u64
137    }
138
139    /// Returns the element `x * 1` where 1 is the multiplicative neutral element.
140    fn from_u64(x: u64) -> u64 {
141        Self::representative(&x)
142    }
143
144    /// Takes as input an element of BaseType and returns the internal representation
145    /// of that element in the field.
146    fn from_base_type(x: u64) -> u64 {
147        Self::representative(&x)
148    }
149}
150
151impl IsPrimeField for Goldilocks64Field {
152    type RepresentativeType = u64;
153
154    fn representative(x: &u64) -> u64 {
155        let mut u = *x;
156        if u >= Self::ORDER {
157            u -= Self::ORDER;
158        }
159        u
160    }
161
162    fn field_bit_size() -> usize {
163        ((self::Goldilocks64Field::ORDER - 1).ilog2() + 1) as usize
164    }
165
166    fn from_hex(hex_string: &str) -> Result<Self::BaseType, CreationError> {
167        let mut hex_string = hex_string;
168        // Remove 0x if it's on the string
169        let mut char_iterator = hex_string.chars();
170        if hex_string.len() > 2
171            && char_iterator.next().unwrap() == '0'
172            && char_iterator.next().unwrap() == 'x'
173        {
174            hex_string = &hex_string[2..];
175        }
176        u64::from_str_radix(hex_string, 16).map_err(|_| CreationError::InvalidHexString)
177    }
178
179    #[cfg(feature = "std")]
180    fn to_hex(x: &u64) -> String {
181        format!("{x:X}")
182    }
183}
184
185#[inline(always)]
186fn reduce_128(x: u128) -> u64 {
187    //possibly split apart into separate function to ensure inline
188    let (x_lo, x_hi) = (x as u64, (x >> 64) as u64);
189    let x_hi_hi = x_hi >> 32;
190    let x_hi_lo = x_hi & Goldilocks64Field::NEG_ORDER;
191
192    let (mut t0, borrow) = x_lo.overflowing_sub(x_hi_hi);
193    if borrow {
194        t0 -= Goldilocks64Field::NEG_ORDER // Cannot underflow
195    }
196
197    let t1 = x_hi_lo * Goldilocks64Field::NEG_ORDER;
198    let (res_wrapped, carry) = t0.overflowing_add(t1);
199    // Below cannot overflow unless the assumption if x + y < 2**64 + ORDER is incorrect.
200    res_wrapped + Goldilocks64Field::NEG_ORDER * u64::from(carry)
201}
202
203#[inline(always)]
204fn exp_acc<const N: usize>(base: &u64, tail: &u64) -> u64 {
205    Goldilocks64Field::mul(&exp_power_of_2::<N>(base), tail)
206}
207
208#[must_use]
209fn exp_power_of_2<const POWER_LOG: usize>(base: &u64) -> u64 {
210    let mut res = *base;
211    for _ in 0..POWER_LOG {
212        res = Goldilocks64Field::square(&res);
213    }
214    res
215}
216
217pub type Goldilocks64ExtensionField = QuadraticExtensionField<Goldilocks64Field, Goldilocks64Field>;
218
219impl HasQuadraticNonResidue<Goldilocks64Field> for Goldilocks64Field {
220    // Verifiable in Sage with
221    // `R.<x> = GF(p)[]; assert (x^2 - 7).is_irreducible()`
222    fn residue() -> FieldElement<Goldilocks64Field> {
223        FieldElement::from(Goldilocks64Field::from_u64(7u64))
224    }
225}
226
227impl Display for FieldElement<Goldilocks64Field> {
228    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
229        write!(f, "{:x}", self.representative())?;
230        Ok(())
231    }
232}
233
234#[cfg(test)]
235mod tests {
236    use super::*;
237    type F = Goldilocks64Field;
238
239    // Over the Goldilocks field, the following set of equations hold
240    // p               = 0
241    // 2^64 - 2^32 + 1 = 0
242    // 2^64            = 2^32 - 1
243    #[test]
244    fn from_hex_for_b_is_11() {
245        assert_eq!(F::from_hex("B").unwrap(), 11);
246    }
247
248    #[test]
249    fn from_hex_for_0x1_a_is_26() {
250        assert_eq!(F::from_hex("0x1a").unwrap(), 26);
251    }
252
253    #[test]
254    fn bit_size_of_field_is_64() {
255        assert_eq!(
256            <F as crate::field::traits::IsPrimeField>::field_bit_size(),
257            64
258        );
259    }
260
261    #[test]
262    fn one_plus_one_is_two() {
263        let a = F::one();
264        let b = F::one();
265        let c = F::add(&a, &b);
266        assert_eq!(c, 2u64);
267    }
268
269    #[test]
270    fn neg_one_plus_one_is_zero() {
271        let a = F::neg(&F::one());
272        let b = F::one();
273        let c = F::add(&a, &b);
274        assert_eq!(c, F::zero());
275    }
276
277    #[test]
278    fn neg_one_plus_two_is_one() {
279        let a = F::neg(&F::one());
280        let b = F::from_base_type(2u64);
281        let c = F::add(&a, &b);
282        assert_eq!(c, F::one());
283    }
284
285    #[test]
286    fn max_order_plus_one_is_zero() {
287        let a = F::from_base_type(F::ORDER - 1);
288        let b = F::one();
289        let c = F::add(&a, &b);
290        assert_eq!(c, F::zero());
291    }
292
293    #[test]
294    fn comparing_13_and_13_are_equal() {
295        let a = F::from_base_type(13);
296        let b = F::from_base_type(13);
297        assert_eq!(a, b);
298    }
299
300    #[test]
301    fn comparing_13_and_8_they_are_not_equal() {
302        let a = F::from_base_type(13);
303        let b = F::from_base_type(8);
304        assert_ne!(a, b);
305    }
306
307    #[test]
308    fn one_sub_one_is_zero() {
309        let a = F::one();
310        let b = F::one();
311        let c = F::sub(&a, &b);
312        assert_eq!(c, F::zero());
313    }
314
315    #[test]
316    fn zero_sub_one_is_order_minus_1() {
317        let a = F::zero();
318        let b = F::one();
319        let c = F::sub(&a, &b);
320        assert_eq!(c, F::ORDER - 1);
321    }
322
323    #[test]
324    fn neg_one_sub_neg_one_is_zero() {
325        let a = F::neg(&F::one());
326        let b = F::neg(&F::one());
327        let c = F::sub(&a, &b);
328        assert_eq!(c, F::zero());
329    }
330
331    #[test]
332    fn neg_one_sub_one_is_neg_one() {
333        let a = F::neg(&F::one());
334        let b = F::zero();
335        let c = F::sub(&a, &b);
336        assert_eq!(c, F::neg(&F::one()));
337    }
338
339    #[test]
340    fn mul_neutral_element() {
341        let a = F::from_base_type(1);
342        let b = F::from_base_type(2);
343        let c = F::mul(&a, &b);
344        assert_eq!(c, F::from_base_type(2));
345    }
346
347    #[test]
348    fn mul_two_three_is_six() {
349        let a = F::from_base_type(2);
350        let b = F::from_base_type(3);
351        assert_eq!(a * b, F::from_base_type(6));
352    }
353
354    #[test]
355    fn mul_order_neg_one() {
356        let a = F::from_base_type(F::ORDER - 1);
357        let b = F::from_base_type(F::ORDER - 1);
358        let c = F::mul(&a, &b);
359        assert_eq!(c, F::from_base_type(1));
360    }
361
362    #[test]
363    fn pow_p_neg_one() {
364        assert_eq!(F::pow(&F::from_base_type(2), F::ORDER - 1), F::one())
365    }
366
367    #[test]
368    fn inv_zero_error() {
369        let result = F::inv(&F::zero());
370        assert!(matches!(result, Err(FieldError::InvZeroError)));
371    }
372
373    #[test]
374    fn inv_two() {
375        let result = F::inv(&F::from_base_type(2u64)).unwrap();
376        // sage: 1 / F(2) = 9223372034707292161
377        assert_eq!(result, 9223372034707292161);
378    }
379
380    #[test]
381    fn pow_two_three() {
382        assert_eq!(F::pow(&F::from_base_type(2), 3_u64), 8)
383    }
384
385    #[test]
386    fn div_one() {
387        assert_eq!(
388            F::div(&F::from_base_type(2), &F::from_base_type(1)).unwrap(),
389            2
390        )
391    }
392
393    #[test]
394    fn div_4_2() {
395        assert_eq!(
396            F::div(&F::from_base_type(4), &F::from_base_type(2)).unwrap(),
397            2
398        )
399    }
400
401    // 1431655766
402    #[test]
403    fn div_4_3() {
404        // sage: F(4) / F(3) = 12297829379609722882
405        assert_eq!(
406            F::div(&F::from_base_type(4), &F::from_base_type(3)).unwrap(),
407            12297829379609722882
408        )
409    }
410
411    #[test]
412    fn two_plus_its_additive_inv_is_0() {
413        let two = F::from_base_type(2);
414
415        assert_eq!(F::add(&two, &F::neg(&two)), F::zero())
416    }
417
418    #[test]
419    fn from_u64_test() {
420        let num = F::from_u64(1u64);
421        assert_eq!(num, F::one());
422    }
423
424    #[test]
425    fn from_u64_zero_test() {
426        let num = F::from_u64(0);
427        assert_eq!(num, F::zero());
428    }
429
430    #[test]
431    fn from_u64_max_test() {
432        let num = F::from_u64(u64::MAX);
433        assert_eq!(num, u32::MAX as u64 - 1);
434    }
435
436    #[test]
437    fn from_u64_order_test() {
438        let num = F::from_u64(F::ORDER);
439        assert_eq!(num, F::zero());
440    }
441
442    #[test]
443    fn creating_a_field_element_from_its_representative_returns_the_same_element_1() {
444        let change = 1;
445        let f1 = F::from_base_type(F::ORDER + change);
446        let f2 = F::from_base_type(F::representative(&f1));
447        assert_eq!(f1, f2);
448    }
449
450    #[test]
451    fn reduct_128() {
452        let x = u128::MAX;
453        let y = reduce_128(x);
454        // The following equalitiy sequence holds, modulo p = 2^64 - 2^32 + 1
455        // 2^128 - 1 = (2^64 - 1) * (2^64 + 1)
456        //           = (2^32 - 1 - 1) * (2^32 - 1 + 1)
457        //           = (2^32 - 2) * (2^32)
458        //           = 2^64 - 2 * 2^32
459        //           = 2^64 - 2^33
460        //           = 2^32 - 1 - 2^33
461        //           = - 2^32 - 1
462        let expected_result = F::neg(&F::add(&F::from_base_type(2_u64.pow(32)), &F::one()));
463        assert_eq!(y, expected_result);
464    }
465
466    #[test]
467    fn u64_max_as_representative_less_than_u32_max_sub_1() {
468        let f = F::from_base_type(u64::MAX);
469        assert_eq!(F::representative(&f), u32::MAX as u64 - 1)
470    }
471
472    #[test]
473    fn creating_a_field_element_from_its_representative_returns_the_same_element_2() {
474        let change = 8;
475        let f1 = F::from_base_type(F::ORDER + change);
476        let f2 = F::from_base_type(F::representative(&f1));
477        assert_eq!(f1, f2);
478    }
479
480    #[test]
481    fn from_base_type_test() {
482        let b = F::from_base_type(1u64);
483        assert_eq!(b, F::one());
484    }
485
486    #[cfg(feature = "std")]
487    #[test]
488    fn to_hex_test() {
489        let num = F::from_hex("B").unwrap();
490        assert_eq!(F::to_hex(&num), "B");
491    }
492}