decaf377/fields/fp/
ops.rs

1use core::{
2    cmp::Ordering,
3    hash::Hash,
4    iter::{Product, Sum},
5    ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},
6};
7
8use crate::Fp;
9
10impl From<u128> for Fp {
11    fn from(other: u128) -> Self {
12        Self::from_le_limbs([other as u64, (other >> 64) as u64, 0, 0, 0, 0])
13    }
14}
15
16impl From<u64> for Fp {
17    fn from(other: u64) -> Self {
18        u128::from(other).into()
19    }
20}
21
22impl From<u32> for Fp {
23    fn from(other: u32) -> Self {
24        u128::from(other).into()
25    }
26}
27
28impl From<u16> for Fp {
29    fn from(other: u16) -> Self {
30        u128::from(other).into()
31    }
32}
33
34impl From<u8> for Fp {
35    fn from(other: u8) -> Self {
36        u128::from(other).into()
37    }
38}
39
40impl From<bool> for Fp {
41    fn from(other: bool) -> Self {
42        u128::from(other).into()
43    }
44}
45
46impl Neg for Fp {
47    type Output = Self;
48
49    #[inline]
50    #[must_use]
51    fn neg(self) -> Self {
52        let neg = self.neg();
53        neg
54    }
55}
56
57impl<'a> AddAssign<&'a Self> for Fp {
58    #[inline]
59    fn add_assign(&mut self, other: &Self) {
60        *self = self.add(other);
61    }
62}
63
64impl AddAssign<Self> for Fp {
65    #[inline(always)]
66    fn add_assign(&mut self, other: Self) {
67        *self = self.add(&other);
68    }
69}
70
71impl<'a> AddAssign<&'a mut Self> for Fp {
72    #[inline(always)]
73    fn add_assign(&mut self, other: &'a mut Self) {
74        *self = self.add(other);
75    }
76}
77
78impl Add<Self> for Fp {
79    type Output = Self;
80
81    #[inline]
82    fn add(self, other: Self) -> Self {
83        self.add(&other)
84    }
85}
86
87impl<'a> Add<&'a Fp> for Fp {
88    type Output = Self;
89
90    #[inline]
91    fn add(self, other: &Self) -> Self {
92        self.add(other)
93    }
94}
95
96impl<'a> Add<&'a mut Self> for Fp {
97    type Output = Self;
98
99    #[inline]
100    fn add(self, other: &'a mut Self) -> Self {
101        self.add(other)
102    }
103}
104
105impl<'a> SubAssign<&'a Self> for Fp {
106    #[inline]
107    fn sub_assign(&mut self, other: &Self) {
108        *self = self.sub(other);
109    }
110}
111
112impl SubAssign<Self> for Fp {
113    #[inline(always)]
114    fn sub_assign(&mut self, other: Self) {
115        *self = self.sub(&other);
116    }
117}
118
119impl<'a> SubAssign<&'a mut Self> for Fp {
120    #[inline(always)]
121    fn sub_assign(&mut self, other: &'a mut Self) {
122        *self = self.sub(other);
123    }
124}
125
126impl Sub<Self> for Fp {
127    type Output = Self;
128
129    #[inline]
130    fn sub(self, other: Self) -> Self {
131        self.sub(&other)
132    }
133}
134
135impl<'a> Sub<&'a Fp> for Fp {
136    type Output = Self;
137
138    #[inline]
139    fn sub(self, other: &Self) -> Self {
140        self.sub(other)
141    }
142}
143
144impl<'a> Sub<&'a mut Self> for Fp {
145    type Output = Self;
146
147    #[inline]
148    fn sub(self, other: &'a mut Self) -> Self {
149        self.sub(other)
150    }
151}
152
153impl<'a> MulAssign<&'a Self> for Fp {
154    fn mul_assign(&mut self, other: &Self) {
155        *self = self.mul(other);
156    }
157}
158
159impl core::ops::MulAssign<Self> for Fp {
160    #[inline(always)]
161    fn mul_assign(&mut self, other: Self) {
162        *self = self.mul(&other);
163    }
164}
165
166impl<'a> core::ops::MulAssign<&'a mut Self> for Fp {
167    #[inline(always)]
168    fn mul_assign(&mut self, other: &'a mut Self) {
169        *self = self.mul(other);
170    }
171}
172
173impl Mul<Self> for Fp {
174    type Output = Self;
175
176    #[inline(always)]
177    fn mul(self, other: Self) -> Self {
178        self.mul(&other)
179    }
180}
181
182impl<'a> Mul<&'a Fp> for Fp {
183    type Output = Self;
184
185    #[inline]
186    fn mul(self, other: &Self) -> Self {
187        self.mul(other)
188    }
189}
190
191impl<'a> Mul<&'a mut Self> for Fp {
192    type Output = Self;
193
194    #[inline(always)]
195    fn mul(self, other: &'a mut Self) -> Self {
196        self.mul(other)
197    }
198}
199
200impl<'a> DivAssign<&'a Self> for Fp {
201    #[inline(always)]
202    fn div_assign(&mut self, other: &Self) {
203        self.mul_assign(&other.inverse().unwrap());
204    }
205}
206
207impl DivAssign<Self> for Fp {
208    #[inline(always)]
209    fn div_assign(&mut self, other: Self) {
210        self.div_assign(&other)
211    }
212}
213
214impl<'a> DivAssign<&'a mut Self> for Fp {
215    #[inline(always)]
216    fn div_assign(&mut self, other: &'a mut Self) {
217        self.div_assign(&*other)
218    }
219}
220
221impl Div<Self> for Fp {
222    type Output = Self;
223
224    #[inline(always)]
225    fn div(mut self, other: Self) -> Self {
226        self.div_assign(&other);
227        self
228    }
229}
230
231impl<'a> Div<&'a Fp> for Fp {
232    type Output = Self;
233
234    #[inline]
235    fn div(mut self, other: &Self) -> Self {
236        self.mul_assign(&other.inverse().unwrap());
237        self
238    }
239}
240
241impl<'a> Div<&'a mut Self> for Fp {
242    type Output = Self;
243
244    #[inline(always)]
245    fn div(mut self, other: &'a mut Self) -> Self {
246        self.div_assign(&*other);
247        self
248    }
249}
250
251impl Sum<Self> for Fp {
252    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
253        iter.fold(Self::ZERO, Add::add)
254    }
255}
256
257impl<'a> Sum<&'a Self> for Fp {
258    fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
259        iter.fold(Self::ZERO, Add::add)
260    }
261}
262
263impl Product<Self> for Fp {
264    fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
265        iter.fold(Self::ONE, Mul::mul)
266    }
267}
268
269impl<'a> Product<&'a Self> for Fp {
270    fn product<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
271        iter.fold(Self::ONE, Mul::mul)
272    }
273}
274
275impl Ord for Fp {
276    #[inline(always)]
277    fn cmp(&self, other: &Self) -> Ordering {
278        let mut left = self.to_le_limbs();
279        let mut right = other.to_le_limbs();
280        left.reverse();
281        right.reverse();
282        left.cmp(&right)
283    }
284}
285
286impl PartialOrd for Fp {
287    #[inline(always)]
288    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
289        Some(self.cmp(other))
290    }
291}
292
293impl Hash for Fp {
294    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
295        state.write(&self.to_bytes_le())
296    }
297}
298
299impl Default for Fp {
300    fn default() -> Self {
301        Self::ZERO
302    }
303}
304
305impl core::fmt::Debug for Fp {
306    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
307        let bytes = {
308            let mut out = self.to_bytes_le();
309            out.reverse();
310            out
311        };
312        let mut hex_chars = [0u8; 96];
313        hex::encode_to_slice(&bytes, &mut hex_chars)
314            .expect("not enough space to write hex characters");
315        // Safety: hex characters will be valid UTF8.
316        write!(f, "Fp(0x{})", unsafe {
317            core::str::from_utf8_unchecked(&hex_chars)
318        })
319    }
320}