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 }