snarkvm_console_types_scalar/
arithmetic.rs1use super::*;
17
18impl<E: Environment> Neg for Scalar<E> {
19 type Output = Scalar<E>;
20
21 #[inline]
23 fn neg(self) -> Self::Output {
24 Scalar::new(-self.scalar)
25 }
26}
27
28impl<E: Environment> Add<Scalar<E>> for Scalar<E> {
29 type Output = Scalar<E>;
30
31 #[inline]
33 fn add(self, other: Scalar<E>) -> Self::Output {
34 Scalar::new(self.scalar + other.scalar)
35 }
36}
37
38impl<E: Environment> Add<&Scalar<E>> for Scalar<E> {
39 type Output = Scalar<E>;
40
41 #[inline]
43 fn add(self, other: &Scalar<E>) -> Self::Output {
44 Scalar::new(self.scalar + other.scalar)
45 }
46}
47
48impl<E: Environment> AddAssign<Scalar<E>> for Scalar<E> {
49 #[inline]
51 fn add_assign(&mut self, other: Scalar<E>) {
52 self.scalar += other.scalar;
53 }
54}
55
56impl<E: Environment> AddAssign<&Scalar<E>> for Scalar<E> {
57 #[inline]
59 fn add_assign(&mut self, other: &Scalar<E>) {
60 self.scalar += other.scalar;
61 }
62}
63
64impl<E: Environment> Sub<Scalar<E>> for Scalar<E> {
65 type Output = Scalar<E>;
66
67 #[inline]
69 fn sub(self, other: Scalar<E>) -> Self::Output {
70 Scalar::new(self.scalar - other.scalar)
71 }
72}
73
74impl<E: Environment> Sub<&Scalar<E>> for Scalar<E> {
75 type Output = Scalar<E>;
76
77 #[inline]
79 fn sub(self, other: &Scalar<E>) -> Self::Output {
80 Scalar::new(self.scalar - other.scalar)
81 }
82}
83
84impl<E: Environment> SubAssign<Scalar<E>> for Scalar<E> {
85 #[inline]
87 fn sub_assign(&mut self, other: Scalar<E>) {
88 self.scalar -= other.scalar;
89 }
90}
91
92impl<E: Environment> SubAssign<&Scalar<E>> for Scalar<E> {
93 #[inline]
95 fn sub_assign(&mut self, other: &Scalar<E>) {
96 self.scalar -= other.scalar;
97 }
98}
99
100impl<E: Environment> Mul<Scalar<E>> for Scalar<E> {
101 type Output = Scalar<E>;
102
103 #[inline]
105 fn mul(self, other: Scalar<E>) -> Self::Output {
106 Scalar::new(self.scalar * other.scalar)
107 }
108}
109
110impl<E: Environment> Mul<&Scalar<E>> for Scalar<E> {
111 type Output = Scalar<E>;
112
113 #[inline]
115 fn mul(self, other: &Scalar<E>) -> Self::Output {
116 Scalar::new(self.scalar * other.scalar)
117 }
118}
119
120impl<E: Environment> MulAssign<Scalar<E>> for Scalar<E> {
121 #[inline]
123 fn mul_assign(&mut self, other: Scalar<E>) {
124 self.scalar *= other.scalar;
125 }
126}
127
128impl<E: Environment> MulAssign<&Scalar<E>> for Scalar<E> {
129 #[inline]
131 fn mul_assign(&mut self, other: &Scalar<E>) {
132 self.scalar *= other.scalar;
133 }
134}
135
136impl<E: Environment> Div<Scalar<E>> for Scalar<E> {
137 type Output = Scalar<E>;
138
139 #[inline]
141 fn div(self, other: Scalar<E>) -> Self::Output {
142 match other.is_zero() {
143 true => E::halt(format!("Scalar division by zero: {self} / {other}")),
144 false => Scalar::new(self.scalar / other.scalar),
145 }
146 }
147}
148
149impl<E: Environment> Div<&Scalar<E>> for Scalar<E> {
150 type Output = Scalar<E>;
151
152 #[inline]
154 fn div(self, other: &Scalar<E>) -> Self::Output {
155 match other.is_zero() {
156 true => E::halt(format!("Scalar division by zero: {self} / {other}")),
157 false => Scalar::new(self.scalar / other.scalar),
158 }
159 }
160}
161
162impl<E: Environment> DivAssign<Scalar<E>> for Scalar<E> {
163 #[inline]
165 fn div_assign(&mut self, other: Scalar<E>) {
166 match other.is_zero() {
167 true => E::halt(format!("Scalar division by zero: {self} / {other}")),
168 false => self.scalar /= other.scalar,
169 }
170 }
171}
172
173impl<E: Environment> DivAssign<&Scalar<E>> for Scalar<E> {
174 #[inline]
176 fn div_assign(&mut self, other: &Scalar<E>) {
177 match other.is_zero() {
178 true => E::halt(format!("Scalar division by zero: {self} / {other}")),
179 false => self.scalar /= other.scalar,
180 }
181 }
182}
183
184impl<E: Environment> Pow<Scalar<E>> for Scalar<E> {
185 type Output = Scalar<E>;
186
187 #[inline]
189 fn pow(self, other: Scalar<E>) -> Self::Output {
190 Scalar::new(self.scalar.pow(other.scalar.to_bigint()))
191 }
192}
193
194impl<E: Environment> Pow<&Scalar<E>> for Scalar<E> {
195 type Output = Scalar<E>;
196
197 #[inline]
199 fn pow(self, other: &Scalar<E>) -> Self::Output {
200 Scalar::new(self.scalar.pow(other.scalar.to_bigint()))
201 }
202}
203
204impl<E: Environment> Double for Scalar<E> {
205 type Output = Scalar<E>;
206
207 #[inline]
209 fn double(&self) -> Self::Output {
210 Scalar::new(self.scalar.double())
211 }
212}
213
214impl<E: Environment> Inverse for Scalar<E> {
215 type Output = Scalar<E>;
216
217 #[inline]
219 fn inverse(&self) -> Result<Self::Output> {
220 match self.scalar.inverse() {
221 Some(inverse) => Ok(Scalar::new(inverse)),
222 None => bail!("Failed to invert a scalar element: {self}"),
223 }
224 }
225}
226
227impl<E: Environment> Square for Scalar<E> {
228 type Output = Scalar<E>;
229
230 #[inline]
232 fn square(&self) -> Self::Output {
233 Scalar::new(self.scalar.square())
234 }
235}
236
237impl<E: Environment> Sum<Scalar<E>> for Scalar<E> {
238 #[inline]
240 fn sum<I: Iterator<Item = Scalar<E>>>(iter: I) -> Self {
241 iter.fold(Scalar::zero(), |a, b| a + b)
242 }
243}
244
245impl<'a, E: Environment> Sum<&'a Scalar<E>> for Scalar<E> {
246 #[inline]
248 fn sum<I: Iterator<Item = &'a Scalar<E>>>(iter: I) -> Self {
249 iter.fold(Scalar::zero(), |a, b| a + b)
250 }
251}
252
253impl<E: Environment> Product<Scalar<E>> for Scalar<E> {
254 #[inline]
256 fn product<I: Iterator<Item = Scalar<E>>>(iter: I) -> Self {
257 iter.fold(Scalar::one(), |a, b| a * b)
258 }
259}
260
261impl<'a, E: Environment> Product<&'a Scalar<E>> for Scalar<E> {
262 #[inline]
264 fn product<I: Iterator<Item = &'a Scalar<E>>>(iter: I) -> Self {
265 iter.fold(Scalar::one(), |a, b| a * b)
266 }
267}
268
269#[cfg(test)]
270mod tests {
271 use super::*;
272 use snarkvm_console_network_environment::Console;
273
274 type CurrentEnvironment = Console;
275
276 #[test]
277 fn test_div_by_zero_fails() {
278 let one = Scalar::<CurrentEnvironment>::one();
279 let zero = Scalar::<CurrentEnvironment>::zero();
280
281 let result = std::panic::catch_unwind(|| one / zero);
282 assert!(result.is_err()); }
284}