/ console / types / integers / src / arithmetic.rs
arithmetic.rs
  1  // Copyright (c) 2025-2026 ACDC Network
  2  // This file is part of the alphavm library.
  3  //
  4  // Alpha Chain | Delta Chain Protocol
  5  // International Monetary Graphite.
  6  //
  7  // Derived from Aleo (https://aleo.org) and ProvableHQ (https://provable.com).
  8  // They built world-class ZK infrastructure. We installed the EASY button.
  9  // Their cryptography: elegant. Our modifications: bureaucracy-compatible.
 10  // Original brilliance: theirs. Robert's Rules: ours. Bugs: definitely ours.
 11  //
 12  // Original Aleo/ProvableHQ code subject to Apache 2.0 https://www.apache.org/licenses/LICENSE-2.0
 13  // All modifications and new work: CC0 1.0 Universal Public Domain Dedication.
 14  // No rights reserved. No permission required. No warranty. No refunds.
 15  //
 16  // https://creativecommons.org/publicdomain/zero/1.0/
 17  // SPDX-License-Identifier: CC0-1.0
 18  
 19  use super::*;
 20  
 21  impl<E: Environment, I: IntegerType> Neg for Integer<E, I> {
 22      type Output = Integer<E, I>;
 23  
 24      /// Returns the `negation` of `self`.
 25      #[inline]
 26      fn neg(self) -> Self::Output {
 27          match I::is_signed() {
 28              true => match self.integer.checked_neg() {
 29                  Some(integer) => Integer::new(integer),
 30                  None => E::halt(format!("Integer negation failed on: {}", self.integer)),
 31              },
 32              false => E::halt("Negation of unsigned integers is not supported."),
 33          }
 34      }
 35  }
 36  
 37  impl<E: Environment, I: IntegerType> AbsChecked for Integer<E, I> {
 38      type Output = Integer<E, I>;
 39  
 40      /// Returns the `absolute value` of `self`.
 41      #[inline]
 42      fn abs_checked(self) -> Self::Output {
 43          match I::is_signed() {
 44              true => match self.integer.checked_abs() {
 45                  Some(integer) => Integer::new(integer),
 46                  None => E::halt(format!("Integer absolute value failed on: {}", self.integer)),
 47              },
 48              false => self,
 49          }
 50      }
 51  }
 52  
 53  impl<E: Environment, I: IntegerType> AbsWrapped for Integer<E, I> {
 54      type Output = Integer<E, I>;
 55  
 56      /// Returns the `absolute value` of `self`.
 57      #[inline]
 58      fn abs_wrapped(self) -> Self::Output {
 59          match I::is_signed() {
 60              true => Integer::new(self.integer.wrapping_abs()),
 61              false => self,
 62          }
 63      }
 64  }
 65  
 66  impl<E: Environment, I: IntegerType> Add<Integer<E, I>> for Integer<E, I> {
 67      type Output = Integer<E, I>;
 68  
 69      /// Returns the `sum` of `self` and `other`.
 70      #[inline]
 71      fn add(self, other: Integer<E, I>) -> Self::Output {
 72          match self.integer.checked_add(&other.integer) {
 73              Some(integer) => Integer::new(integer),
 74              None => E::halt(format!("Integer addition failed on: {self} and {other}")),
 75          }
 76      }
 77  }
 78  
 79  impl<E: Environment, I: IntegerType> Add<&Integer<E, I>> for Integer<E, I> {
 80      type Output = Integer<E, I>;
 81  
 82      /// Returns the `sum` of `self` and `other`.
 83      #[inline]
 84      fn add(self, other: &Integer<E, I>) -> Self::Output {
 85          match self.integer.checked_add(&other.integer) {
 86              Some(integer) => Integer::new(integer),
 87              None => E::halt(format!("Integer addition failed on: {self} and {other}")),
 88          }
 89      }
 90  }
 91  
 92  impl<E: Environment, I: IntegerType> AddWrapped<Integer<E, I>> for Integer<E, I> {
 93      type Output = Integer<E, I>;
 94  
 95      /// Returns the `sum` of `self` and `other`.
 96      #[inline]
 97      fn add_wrapped(&self, other: &Integer<E, I>) -> Self::Output {
 98          Integer::new(self.integer.wrapping_add(&other.integer))
 99      }
100  }
101  
102  impl<E: Environment, I: IntegerType> AddAssign<Integer<E, I>> for Integer<E, I> {
103      /// Adds `other` to `self`.
104      #[inline]
105      fn add_assign(&mut self, other: Integer<E, I>) {
106          match self.integer.checked_add(&other.integer) {
107              Some(integer) => self.integer = integer,
108              None => E::halt(format!("Integer addition failed on: {self} and {other}")),
109          }
110      }
111  }
112  
113  impl<E: Environment, I: IntegerType> AddAssign<&Integer<E, I>> for Integer<E, I> {
114      /// Adds `other` to `self`.
115      #[inline]
116      fn add_assign(&mut self, other: &Integer<E, I>) {
117          match self.integer.checked_add(&other.integer) {
118              Some(integer) => self.integer = integer,
119              None => E::halt(format!("Integer addition failed on: {self} and {other}")),
120          }
121      }
122  }
123  
124  impl<E: Environment, I: IntegerType> Sub<Integer<E, I>> for Integer<E, I> {
125      type Output = Integer<E, I>;
126  
127      /// Returns the `difference` of `self` and `other`.
128      #[inline]
129      fn sub(self, other: Integer<E, I>) -> Self::Output {
130          match self.integer.checked_sub(&other.integer) {
131              Some(integer) => Integer::new(integer),
132              None => E::halt(format!("Integer subtraction failed on: {self} and {other}")),
133          }
134      }
135  }
136  
137  impl<E: Environment, I: IntegerType> Sub<&Integer<E, I>> for Integer<E, I> {
138      type Output = Integer<E, I>;
139  
140      /// Returns the `difference` of `self` and `other`.
141      #[inline]
142      fn sub(self, other: &Integer<E, I>) -> Self::Output {
143          match self.integer.checked_sub(&other.integer) {
144              Some(integer) => Integer::new(integer),
145              None => E::halt(format!("Integer subtraction failed on: {self} and {other}")),
146          }
147      }
148  }
149  
150  impl<E: Environment, I: IntegerType> SubWrapped<Integer<E, I>> for Integer<E, I> {
151      type Output = Integer<E, I>;
152  
153      /// Returns the `difference` of `self` and `other`.
154      #[inline]
155      fn sub_wrapped(&self, other: &Integer<E, I>) -> Self::Output {
156          Integer::new(self.integer.wrapping_sub(&other.integer))
157      }
158  }
159  
160  impl<E: Environment, I: IntegerType> SubAssign<Integer<E, I>> for Integer<E, I> {
161      /// Subtracts `other` from `self`.
162      #[inline]
163      fn sub_assign(&mut self, other: Integer<E, I>) {
164          match self.integer.checked_sub(&other.integer) {
165              Some(integer) => self.integer = integer,
166              None => E::halt(format!("Integer subtraction failed on: {self} and {other}")),
167          }
168      }
169  }
170  
171  impl<E: Environment, I: IntegerType> SubAssign<&Integer<E, I>> for Integer<E, I> {
172      /// Subtracts `other` from `self`.
173      #[inline]
174      fn sub_assign(&mut self, other: &Integer<E, I>) {
175          match self.integer.checked_sub(&other.integer) {
176              Some(integer) => self.integer = integer,
177              None => E::halt(format!("Integer subtraction failed on: {self} and {other}")),
178          }
179      }
180  }
181  
182  impl<E: Environment, I: IntegerType> Mul<Integer<E, I>> for Integer<E, I> {
183      type Output = Integer<E, I>;
184  
185      /// Returns the `product` of `self` and `other`.
186      #[inline]
187      fn mul(self, other: Integer<E, I>) -> Self::Output {
188          match self.integer.checked_mul(&other.integer) {
189              Some(integer) => Integer::new(integer),
190              None => E::halt(format!("Integer multiplication failed on: {self} and {other}")),
191          }
192      }
193  }
194  
195  impl<E: Environment, I: IntegerType> Mul<&Integer<E, I>> for Integer<E, I> {
196      type Output = Integer<E, I>;
197  
198      /// Returns the `product` of `self` and `other`.
199      #[inline]
200      fn mul(self, other: &Integer<E, I>) -> Self::Output {
201          match self.integer.checked_mul(&other.integer) {
202              Some(integer) => Integer::new(integer),
203              None => E::halt(format!("Integer multiplication failed on: {self} and {other}")),
204          }
205      }
206  }
207  
208  impl<E: Environment, I: IntegerType> MulWrapped<Integer<E, I>> for Integer<E, I> {
209      type Output = Integer<E, I>;
210  
211      /// Returns the `product` of `self` and `other`.
212      #[inline]
213      fn mul_wrapped(&self, other: &Integer<E, I>) -> Self::Output {
214          Integer::new(self.integer.wrapping_mul(&other.integer))
215      }
216  }
217  
218  impl<E: Environment, I: IntegerType> MulAssign<Integer<E, I>> for Integer<E, I> {
219      /// Multiplies `self` by `other`.
220      #[inline]
221      fn mul_assign(&mut self, other: Integer<E, I>) {
222          match self.integer.checked_mul(&other.integer) {
223              Some(integer) => self.integer = integer,
224              None => E::halt(format!("Integer multiplication failed on: {self} and {other}")),
225          }
226      }
227  }
228  
229  impl<E: Environment, I: IntegerType> MulAssign<&Integer<E, I>> for Integer<E, I> {
230      /// Multiplies `self` by `other`.
231      #[inline]
232      fn mul_assign(&mut self, other: &Integer<E, I>) {
233          match self.integer.checked_mul(&other.integer) {
234              Some(integer) => self.integer = integer,
235              None => E::halt(format!("Integer multiplication failed on: {self} and {other}")),
236          }
237      }
238  }
239  
240  impl<E: Environment, I: IntegerType> Div<Integer<E, I>> for Integer<E, I> {
241      type Output = Integer<E, I>;
242  
243      /// Returns the `quotient` of `self` and `other`.
244      #[inline]
245      fn div(self, other: Integer<E, I>) -> Self::Output {
246          match self.integer.checked_div(&other.integer) {
247              Some(integer) => Integer::new(integer),
248              None => E::halt(format!("Integer division failed on: {self} and {other}")),
249          }
250      }
251  }
252  
253  impl<E: Environment, I: IntegerType> Div<&Integer<E, I>> for Integer<E, I> {
254      type Output = Integer<E, I>;
255  
256      /// Returns the `quotient` of `self` and `other`.
257      #[inline]
258      fn div(self, other: &Integer<E, I>) -> Self::Output {
259          match self.integer.checked_div(&other.integer) {
260              Some(integer) => Integer::new(integer),
261              None => E::halt(format!("Integer division failed on: {self} and {other}")),
262          }
263      }
264  }
265  
266  impl<E: Environment, I: IntegerType> DivWrapped<Integer<E, I>> for Integer<E, I> {
267      type Output = Integer<E, I>;
268  
269      /// Returns the `quotient` of `self` and `other`.
270      #[inline]
271      fn div_wrapped(&self, other: &Integer<E, I>) -> Self::Output {
272          match other.is_zero() {
273              true => E::halt(format!("Integer division by zero: {self} / {other}")),
274              false => Integer::new(self.integer.wrapping_div(&other.integer)),
275          }
276      }
277  }
278  
279  impl<E: Environment, I: IntegerType> DivAssign<Integer<E, I>> for Integer<E, I> {
280      /// Divides `self` by `other`.
281      #[inline]
282      fn div_assign(&mut self, other: Integer<E, I>) {
283          match self.integer.checked_div(&other.integer) {
284              Some(integer) => self.integer = integer,
285              None => E::halt(format!("Integer division failed on: {self} and {other}")),
286          }
287      }
288  }
289  
290  impl<E: Environment, I: IntegerType> DivAssign<&Integer<E, I>> for Integer<E, I> {
291      /// Divides `self` by `other`.
292      #[inline]
293      fn div_assign(&mut self, other: &Integer<E, I>) {
294          match self.integer.checked_div(&other.integer) {
295              Some(integer) => self.integer = integer,
296              None => E::halt(format!("Integer division failed on: {self} and {other}")),
297          }
298      }
299  }
300  
301  impl<E: Environment, I: IntegerType> Modulo<Integer<E, I>> for Integer<E, I> {
302      type Output = Integer<E, I>;
303  
304      /// Returns the result of taking the modulus of `self` with respect to `other`.
305      #[inline]
306      fn modulo(&self, other: &Integer<E, I>) -> Self {
307          match I::is_signed() {
308              true => E::halt("Taking the modulus of signed integers is not supported"),
309              false => match other.is_zero() {
310                  true => E::halt(format!("Integer modulus by zero: {self} % {other}")),
311                  false => Integer::new(self.integer.modulo(&other.integer)),
312              },
313          }
314      }
315  }
316  
317  impl<E: Environment, I: IntegerType> Rem<Integer<E, I>> for Integer<E, I> {
318      type Output = Integer<E, I>;
319  
320      /// Returns the `remainder` of `self` divided by `other`.
321      #[inline]
322      fn rem(self, other: Integer<E, I>) -> Self {
323          match self.integer.checked_rem(&other.integer) {
324              Some(integer) => Integer::new(integer),
325              None => E::halt(format!("Integer remainder failed on: {self} and {other}")),
326          }
327      }
328  }
329  
330  impl<E: Environment, I: IntegerType> Rem<&Integer<E, I>> for Integer<E, I> {
331      type Output = Integer<E, I>;
332  
333      /// Returns the `remainder` of `self` divided by `other`.
334      #[inline]
335      fn rem(self, other: &Integer<E, I>) -> Self {
336          match self.integer.checked_rem(&other.integer) {
337              Some(integer) => Integer::new(integer),
338              None => E::halt(format!("Integer remainder failed on: {self} and {other}")),
339          }
340      }
341  }
342  
343  impl<E: Environment, I: IntegerType> RemWrapped<Integer<E, I>> for Integer<E, I> {
344      type Output = Integer<E, I>;
345  
346      /// Returns the `remainder` of `self` divided by `other`.
347      #[inline]
348      fn rem_wrapped(&self, other: &Integer<E, I>) -> Self::Output {
349          match other.is_zero() {
350              true => E::halt(format!("Integer remainder by zero: {self} % {other}")),
351              false => Integer::new(self.integer.wrapping_rem(&other.integer)),
352          }
353      }
354  }
355  
356  impl<E: Environment, I: IntegerType> RemAssign<Integer<E, I>> for Integer<E, I> {
357      /// Returns the `remainder` of `self` divided by `other`.
358      #[inline]
359      fn rem_assign(&mut self, other: Integer<E, I>) {
360          match self.integer.checked_rem(&other.integer) {
361              Some(integer) => self.integer = integer,
362              None => E::halt(format!("Integer remainder failed on: {self} and {other}")),
363          }
364      }
365  }
366  
367  impl<E: Environment, I: IntegerType> RemAssign<&Integer<E, I>> for Integer<E, I> {
368      /// Returns the `remainder` of `self` divided by `other`.
369      #[inline]
370      fn rem_assign(&mut self, other: &Integer<E, I>) {
371          match self.integer.checked_rem(&other.integer) {
372              Some(integer) => self.integer = integer,
373              None => E::halt(format!("Integer remainder failed on: {self} and {other}")),
374          }
375      }
376  }
377  
378  impl<E: Environment, I: IntegerType, M: Magnitude> Pow<Integer<E, M>> for Integer<E, I> {
379      type Output = Integer<E, I>;
380  
381      /// Returns the `power` of `self` to the power of `other`.
382      #[inline]
383      fn pow(self, other: Integer<E, M>) -> Self::Output {
384          match self.integer.checked_pow(&other.integer.to_u32().unwrap()) {
385              // Unwrap is safe as we only cast up.
386              Some(integer) => Integer::new(integer),
387              None => E::halt(format!("Integer power failed on: {self} and {other}")),
388          }
389      }
390  }
391  
392  impl<E: Environment, I: IntegerType, M: Magnitude> Pow<&Integer<E, M>> for Integer<E, I> {
393      type Output = Integer<E, I>;
394  
395      /// Returns the `power` of `self` to the power of `other`.
396      #[inline]
397      fn pow(self, other: &Integer<E, M>) -> Self::Output {
398          match self.integer.checked_pow(&other.integer.to_u32().unwrap()) {
399              // Unwrap is safe as we only cast up.
400              Some(integer) => Integer::new(integer),
401              None => E::halt(format!("Integer power failed on: {self} and {other}")),
402          }
403      }
404  }
405  
406  impl<E: Environment, I: IntegerType, M: Magnitude> PowWrapped<Integer<E, M>> for Integer<E, I> {
407      type Output = Integer<E, I>;
408  
409      /// Returns the `power` of `self` to the power of `other`.
410      #[inline]
411      fn pow_wrapped(&self, other: &Integer<E, M>) -> Self::Output {
412          Integer::new(self.integer.wrapping_pow(&other.integer.to_u32().unwrap()))
413      }
414  }
415  
416  impl<E: Environment, I: IntegerType> Square for Integer<E, I> {
417      type Output = Integer<E, I>;
418  
419      /// Returns the `square` of `self`.
420      #[inline]
421      fn square(&self) -> Self::Output {
422          match self.integer.checked_mul(&self.integer) {
423              Some(integer) => Integer::new(integer),
424              None => E::halt(format!("Integer square failed on: {}", self.integer)),
425          }
426      }
427  }