goldilocks_ntt/
field.rs

1use crate::algo;
2use core::{iter, ops};
3
4/// An element in the Goldilocks field.
5#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
6#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7pub struct Field(u64);
8
9impl Field {
10    const MODULUS: u64 = 0xffff_ffff_0000_0001;
11    const MAX: Field = Self(Self::MODULUS - 1);
12}
13
14impl From<u64> for Field {
15    #[inline(always)]
16    fn from(value: u64) -> Self {
17        Self(algo::reduce_1(value))
18    }
19}
20
21impl From<Field> for u64 {
22    #[inline(always)]
23    fn from(value: Field) -> Self {
24        value.0
25    }
26}
27
28impl ops::Add<Field> for Field {
29    type Output = Field;
30
31    #[inline(always)]
32    fn add(self, rhs: Field) -> Self {
33        Self(algo::add(self.0, rhs.0))
34    }
35}
36
37impl ops::AddAssign for Field {
38    #[inline(always)]
39    fn add_assign(&mut self, rhs: Self) {
40        self.0 = algo::add(self.0, rhs.0);
41    }
42}
43
44impl iter::Sum for Field {
45    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
46        Self(iter.fold(0, |a, n| algo::add(a, n.0)))
47    }
48}
49
50impl ops::Neg for Field {
51    type Output = Field;
52
53    #[inline(always)]
54    fn neg(self) -> Self {
55        Self(Self::MODULUS - self.0)
56    }
57}
58
59impl ops::Sub for Field {
60    type Output = Field;
61
62    #[inline(always)]
63    fn sub(self, rhs: Field) -> Self {
64        Self(algo::add(self.0, Self::MODULUS - rhs.0))
65    }
66}
67
68impl ops::SubAssign for Field {
69    #[inline(always)]
70    fn sub_assign(&mut self, rhs: Self) {
71        self.0 = algo::add(self.0, Self::MODULUS - rhs.0);
72    }
73}
74
75impl ops::Mul<Field> for Field {
76    type Output = Field;
77
78    #[inline(always)]
79    fn mul(self, rhs: Field) -> Self {
80        Self(algo::mul(self.0, rhs.0))
81    }
82}
83
84impl ops::MulAssign<Field> for Field {
85    #[inline(always)]
86    fn mul_assign(&mut self, rhs: Field) {
87        self.0 = algo::mul(self.0, rhs.0);
88    }
89}
90
91impl iter::Product for Field {
92    fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
93        Self(iter.fold(1, |a, n| algo::mul(a, n.0)))
94    }
95}