decaf377/fields/fr/
ops.rs1use 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::Fr;
9
10impl From<u128> for Fr {
11 fn from(other: u128) -> Self {
12 Self::from_le_limbs([other as u64, (other >> 64) as u64, 0, 0])
13 }
14}
15
16impl From<u64> for Fr {
17 fn from(other: u64) -> Self {
18 u128::from(other).into()
19 }
20}
21
22impl From<u32> for Fr {
23 fn from(other: u32) -> Self {
24 u128::from(other).into()
25 }
26}
27
28impl From<u16> for Fr {
29 fn from(other: u16) -> Self {
30 u128::from(other).into()
31 }
32}
33
34impl From<u8> for Fr {
35 fn from(other: u8) -> Self {
36 u128::from(other).into()
37 }
38}
39
40impl From<bool> for Fr {
41 fn from(other: bool) -> Self {
42 u128::from(other).into()
43 }
44}
45
46impl Neg for Fr {
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 Fr {
58 #[inline]
59 fn add_assign(&mut self, other: &Self) {
60 *self = self.add(other);
61 }
62}
63
64impl AddAssign<Self> for Fr {
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 Fr {
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 Fr {
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 Fr> for Fr {
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 Fr {
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 Fr {
106 #[inline]
107 fn sub_assign(&mut self, other: &Self) {
108 *self = self.sub(other);
109 }
110}
111
112impl SubAssign<Self> for Fr {
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 Fr {
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 Fr {
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 Fr> for Fr {
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 Fr {
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 Fr {
154 fn mul_assign(&mut self, other: &Self) {
155 *self = self.mul(other);
156 }
157}
158
159impl core::ops::MulAssign<Self> for Fr {
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 Fr {
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 Fr {
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 Fr> for Fr {
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 Fr {
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 Fr {
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 Fr {
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 Fr {
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 Fr {
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 Fr> for Fr {
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 Fr {
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 Fr {
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 Fr {
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 Fr {
264 fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
265 iter.fold(Self::ZERO, Mul::mul)
266 }
267}
268
269impl<'a> Product<&'a Self> for Fr {
270 fn product<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
271 iter.fold(Self::ZERO, Mul::mul)
272 }
273}
274
275impl Ord for Fr {
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 Fr {
287 #[inline(always)]
288 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
289 Some(self.cmp(other))
290 }
291}
292
293impl Hash for Fr {
294 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
295 state.write(&self.to_bytes_le())
296 }
297}
298
299impl Default for Fr {
300 fn default() -> Self {
301 Self::ZERO
302 }
303}
304
305impl core::fmt::Debug for Fr {
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; 64];
313 hex::encode_to_slice(&bytes, &mut hex_chars)
314 .expect("not enough space to write hex characters");
315 write!(f, "Fr(0x{})", unsafe {
317 core::str::from_utf8_unchecked(&hex_chars)
318 })
319 }
320}