/ console / types / group / 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> Neg for Group<E> {
 22      type Output = Group<E>;
 23  
 24      /// Returns the `negation` of `self`.
 25      #[inline]
 26      fn neg(self) -> Self::Output {
 27          Group::from_projective(-self.group)
 28      }
 29  }
 30  
 31  impl<E: Environment> Add<Group<E>> for Group<E> {
 32      type Output = Group<E>;
 33  
 34      /// Returns the `sum` of `self` and `other`.
 35      #[inline]
 36      fn add(self, other: Group<E>) -> Self::Output {
 37          Group::from_projective(self.group + other.group)
 38      }
 39  }
 40  
 41  impl<E: Environment> Add<&Group<E>> for Group<E> {
 42      type Output = Group<E>;
 43  
 44      /// Returns the `sum` of `self` and `other`.
 45      #[inline]
 46      fn add(self, other: &Group<E>) -> Self::Output {
 47          Group::from_projective(self.group + other.group)
 48      }
 49  }
 50  
 51  impl<E: Environment> AddAssign<Group<E>> for Group<E> {
 52      /// Adds `other` to `self`.
 53      #[inline]
 54      fn add_assign(&mut self, other: Group<E>) {
 55          self.group += other.group;
 56      }
 57  }
 58  
 59  impl<E: Environment> AddAssign<&Group<E>> for Group<E> {
 60      /// Adds `other` to `self`.
 61      #[inline]
 62      fn add_assign(&mut self, other: &Group<E>) {
 63          self.group += other.group;
 64      }
 65  }
 66  
 67  impl<E: Environment> Sub<Group<E>> for Group<E> {
 68      type Output = Group<E>;
 69  
 70      /// Returns the `difference` of `self` and `other`.
 71      #[inline]
 72      fn sub(self, other: Group<E>) -> Self::Output {
 73          Group::from_projective(self.group - other.group)
 74      }
 75  }
 76  
 77  impl<E: Environment> Sub<&Group<E>> for Group<E> {
 78      type Output = Group<E>;
 79  
 80      /// Returns the `difference` of `self` and `other`.
 81      #[inline]
 82      fn sub(self, other: &Group<E>) -> Self::Output {
 83          Group::from_projective(self.group - other.group)
 84      }
 85  }
 86  
 87  impl<E: Environment> SubAssign<Group<E>> for Group<E> {
 88      /// Subtracts `other` from `self`.
 89      #[inline]
 90      fn sub_assign(&mut self, other: Group<E>) {
 91          self.group -= other.group;
 92      }
 93  }
 94  
 95  impl<E: Environment> SubAssign<&Group<E>> for Group<E> {
 96      /// Subtracts `other` from `self`.
 97      #[inline]
 98      fn sub_assign(&mut self, other: &Group<E>) {
 99          self.group -= other.group;
100      }
101  }
102  
103  impl<E: Environment> Mul<Scalar<E>> for Group<E> {
104      type Output = Group<E>;
105  
106      /// Returns the `product` of `self` and `other`.
107      #[inline]
108      fn mul(self, other: Scalar<E>) -> Self::Output {
109          Group::from_projective(self.group * *other)
110      }
111  }
112  
113  impl<E: Environment> Mul<&Scalar<E>> for Group<E> {
114      type Output = Group<E>;
115  
116      /// Returns the `product` of `self` and `other`.
117      #[inline]
118      fn mul(self, other: &Scalar<E>) -> Self::Output {
119          Group::from_projective(self.group * **other)
120      }
121  }
122  
123  impl<E: Environment> Mul<Group<E>> for Scalar<E> {
124      type Output = Group<E>;
125  
126      /// Returns the `product` of `self` and `other`.
127      #[inline]
128      fn mul(self, other: Group<E>) -> Self::Output {
129          Group::from_projective(other.group * *self)
130      }
131  }
132  
133  impl<E: Environment> Mul<&Group<E>> for Scalar<E> {
134      type Output = Group<E>;
135  
136      /// Returns the `product` of `self` and `other`.
137      #[inline]
138      fn mul(self, other: &Group<E>) -> Self::Output {
139          Group::from_projective(other.group * *self)
140      }
141  }
142  
143  impl<E: Environment> MulAssign<Scalar<E>> for Group<E> {
144      /// Multiplies `self` by `other`.
145      #[inline]
146      fn mul_assign(&mut self, other: Scalar<E>) {
147          self.group *= *other;
148      }
149  }
150  
151  impl<E: Environment> MulAssign<&Scalar<E>> for Group<E> {
152      /// Multiplies `self` by `other`.
153      #[inline]
154      fn mul_assign(&mut self, other: &Scalar<E>) {
155          self.group *= **other;
156      }
157  }
158  
159  impl<E: Environment> Double for Group<E> {
160      type Output = Group<E>;
161  
162      /// Returns the `double` of `self`.
163      #[inline]
164      fn double(&self) -> Self::Output {
165          Group::from_projective(self.group.double())
166      }
167  }
168  
169  impl<E: Environment> Sum<Group<E>> for Group<E> {
170      /// Returns the `sum` of `self` and `other`.
171      #[inline]
172      fn sum<I: Iterator<Item = Group<E>>>(iter: I) -> Self {
173          iter.fold(Group::zero(), |a, b| a + b)
174      }
175  }
176  
177  impl<'a, E: Environment> Sum<&'a Group<E>> for Group<E> {
178      /// Returns the `sum` of `self` and `other`.
179      #[inline]
180      fn sum<I: Iterator<Item = &'a Group<E>>>(iter: I) -> Self {
181          iter.fold(Group::zero(), |a, b| a + b)
182      }
183  }