Skip to main content

ark_ff/fields/models/small_fp/
ops.rs

1use crate::fields::models::small_fp::small_fp_backend::{SmallFp, SmallFpConfig};
2use crate::{Field, One, Zero};
3use ark_std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
4
5impl<P: SmallFpConfig> Neg for SmallFp<P> {
6    type Output = Self;
7    #[inline]
8    fn neg(mut self) -> Self {
9        P::neg_in_place(&mut self);
10        self
11    }
12}
13
14impl<P: SmallFpConfig> Add<&SmallFp<P>> for SmallFp<P> {
15    type Output = Self;
16
17    #[inline]
18    fn add(mut self, other: &Self) -> Self {
19        self += other;
20        self
21    }
22}
23
24impl<P: SmallFpConfig> Sub<&SmallFp<P>> for SmallFp<P> {
25    type Output = Self;
26
27    #[inline]
28    fn sub(mut self, other: &Self) -> Self {
29        self -= other;
30        self
31    }
32}
33
34impl<P: SmallFpConfig> Mul<&SmallFp<P>> for SmallFp<P> {
35    type Output = Self;
36
37    #[inline]
38    fn mul(mut self, other: &Self) -> Self {
39        self *= other;
40        self
41    }
42}
43
44impl<P: SmallFpConfig> Div<&SmallFp<P>> for SmallFp<P> {
45    type Output = Self;
46
47    /// Returns `self * other.inverse()` if `other.inverse()` is `Some`, and
48    /// panics otherwise.
49    #[inline]
50    #[allow(clippy::suspicious_arithmetic_impl)]
51    fn div(mut self, other: &Self) -> Self {
52        match other.inverse() {
53            Some(inv) => {
54                self *= &inv;
55                self
56            },
57            None => panic!("Division by zero in finite field"),
58        }
59    }
60}
61
62impl<'b, P: SmallFpConfig> Add<&'b SmallFp<P>> for &SmallFp<P> {
63    type Output = SmallFp<P>;
64
65    #[inline]
66    fn add(self, other: &'b SmallFp<P>) -> SmallFp<P> {
67        let mut result = *self;
68        result += other;
69        result
70    }
71}
72
73impl<P: SmallFpConfig> Sub<&SmallFp<P>> for &SmallFp<P> {
74    type Output = SmallFp<P>;
75
76    #[inline]
77    fn sub(self, other: &SmallFp<P>) -> SmallFp<P> {
78        let mut result = *self;
79        result -= other;
80        result
81    }
82}
83
84impl<P: SmallFpConfig> Mul<&SmallFp<P>> for &SmallFp<P> {
85    type Output = SmallFp<P>;
86
87    #[inline]
88    fn mul(self, other: &SmallFp<P>) -> SmallFp<P> {
89        let mut result = *self;
90        result *= other;
91        result
92    }
93}
94
95impl<P: SmallFpConfig> Div<&SmallFp<P>> for &SmallFp<P> {
96    type Output = SmallFp<P>;
97
98    #[inline]
99    fn div(self, other: &SmallFp<P>) -> SmallFp<P> {
100        let mut result = *self;
101        result.div_assign(other);
102        result
103    }
104}
105
106impl<P: SmallFpConfig> AddAssign<&Self> for SmallFp<P> {
107    #[inline]
108    fn add_assign(&mut self, other: &Self) {
109        P::add_assign(self, other)
110    }
111}
112
113impl<P: SmallFpConfig> SubAssign<&Self> for SmallFp<P> {
114    #[inline]
115    fn sub_assign(&mut self, other: &Self) {
116        P::sub_assign(self, other);
117    }
118}
119
120impl<P: SmallFpConfig> core::ops::Add<Self> for SmallFp<P> {
121    type Output = Self;
122
123    #[inline]
124    fn add(mut self, other: Self) -> Self {
125        self += &other;
126        self
127    }
128}
129
130impl<'a, P: SmallFpConfig> core::ops::Add<&'a mut Self> for SmallFp<P> {
131    type Output = Self;
132
133    #[inline]
134    fn add(mut self, other: &'a mut Self) -> Self {
135        self += &*other;
136        self
137    }
138}
139
140impl<P: SmallFpConfig> core::ops::Sub<Self> for SmallFp<P> {
141    type Output = Self;
142
143    #[inline]
144    fn sub(mut self, other: Self) -> Self {
145        self -= &other;
146        self
147    }
148}
149
150impl<'a, P: SmallFpConfig> core::ops::Sub<&'a mut Self> for SmallFp<P> {
151    type Output = Self;
152
153    #[inline]
154    fn sub(mut self, other: &'a mut Self) -> Self {
155        self -= &*other;
156        self
157    }
158}
159
160impl<P: SmallFpConfig> core::iter::Sum<Self> for SmallFp<P> {
161    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
162        iter.fold(Self::zero(), core::ops::Add::add)
163    }
164}
165
166impl<'a, P: SmallFpConfig> core::iter::Sum<&'a Self> for SmallFp<P> {
167    fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
168        iter.fold(Self::zero(), core::ops::Add::add)
169    }
170}
171
172impl<P: SmallFpConfig> core::ops::AddAssign<Self> for SmallFp<P> {
173    #[inline(always)]
174    fn add_assign(&mut self, other: Self) {
175        *self += &other
176    }
177}
178
179impl<P: SmallFpConfig> core::ops::SubAssign<Self> for SmallFp<P> {
180    #[inline(always)]
181    fn sub_assign(&mut self, other: Self) {
182        *self -= &other
183    }
184}
185
186impl<'a, P: SmallFpConfig> core::ops::AddAssign<&'a mut Self> for SmallFp<P> {
187    #[inline(always)]
188    fn add_assign(&mut self, other: &'a mut Self) {
189        *self += &*other
190    }
191}
192
193impl<'a, P: SmallFpConfig> core::ops::SubAssign<&'a mut Self> for SmallFp<P> {
194    #[inline(always)]
195    fn sub_assign(&mut self, other: &'a mut Self) {
196        *self -= &*other
197    }
198}
199
200impl<P: SmallFpConfig> MulAssign<&Self> for SmallFp<P> {
201    #[inline(always)]
202    fn mul_assign(&mut self, other: &Self) {
203        P::mul_assign(self, other)
204    }
205}
206
207/// Computes `self *= other.inverse()` if `other.inverse()` is `Some`, and
208/// panics otherwise.
209impl<P: SmallFpConfig> DivAssign<&Self> for SmallFp<P> {
210    #[inline(always)]
211    fn div_assign(&mut self, other: &Self) {
212        match other.inverse() {
213            Some(inv) => {
214                *self *= &inv;
215            },
216            None => panic!("Division by zero in finite field"),
217        }
218    }
219}
220
221impl<P: SmallFpConfig> core::ops::Mul<Self> for SmallFp<P> {
222    type Output = Self;
223
224    #[inline(always)]
225    fn mul(mut self, other: Self) -> Self {
226        self *= &other;
227        self
228    }
229}
230
231impl<P: SmallFpConfig> core::ops::Div<Self> for SmallFp<P> {
232    type Output = Self;
233
234    #[inline(always)]
235    fn div(mut self, other: Self) -> Self {
236        self.div_assign(&other);
237        self
238    }
239}
240
241impl<'a, P: SmallFpConfig> core::ops::Mul<&'a mut Self> for SmallFp<P> {
242    type Output = Self;
243
244    #[inline(always)]
245    fn mul(mut self, other: &'a mut Self) -> Self {
246        self *= &*other;
247        self
248    }
249}
250
251impl<'a, P: SmallFpConfig> core::ops::Div<&'a mut Self> for SmallFp<P> {
252    type Output = Self;
253
254    #[inline(always)]
255    fn div(mut self, other: &'a mut Self) -> Self {
256        self.div_assign(&*other);
257        self
258    }
259}
260
261impl<P: SmallFpConfig> core::iter::Product<Self> for SmallFp<P> {
262    fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
263        iter.fold(Self::one(), core::ops::Mul::mul)
264    }
265}
266
267impl<'a, P: SmallFpConfig> core::iter::Product<&'a Self> for SmallFp<P> {
268    fn product<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
269        iter.fold(Self::one(), Mul::mul)
270    }
271}
272
273impl<P: SmallFpConfig> core::ops::MulAssign<Self> for SmallFp<P> {
274    #[inline(always)]
275    fn mul_assign(&mut self, other: Self) {
276        *self *= &other
277    }
278}
279
280impl<'a, P: SmallFpConfig> core::ops::DivAssign<&'a mut Self> for SmallFp<P> {
281    #[inline(always)]
282    fn div_assign(&mut self, other: &'a mut Self) {
283        self.div_assign(&*other)
284    }
285}
286
287impl<'a, P: SmallFpConfig> core::ops::MulAssign<&'a mut Self> for SmallFp<P> {
288    #[inline(always)]
289    fn mul_assign(&mut self, other: &'a mut Self) {
290        *self *= &*other
291    }
292}
293
294impl<P: SmallFpConfig> core::ops::DivAssign<Self> for SmallFp<P> {
295    #[inline(always)]
296    fn div_assign(&mut self, other: Self) {
297        self.div_assign(&other)
298    }
299}
300
301impl<P: SmallFpConfig> zeroize::Zeroize for SmallFp<P> {
302    // The phantom data does not contain element-specific data
303    // and thus does not need to be zeroized.
304    fn zeroize(&mut self) {
305        self.value = P::ZERO.value;
306    }
307}