1use crate::algo;
2use core::{iter, ops};
3
4#[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}