diff --git a/math/src/circle/cosets.rs b/math/src/circle/cosets.rs index 709ea76fc..957097efb 100644 --- a/math/src/circle/cosets.rs +++ b/math/src/circle/cosets.rs @@ -3,8 +3,8 @@ use crate::circle::point::CirclePoint; use crate::field::fields::mersenne31::field::Mersenne31Field; use alloc::vec::Vec; -/// Given g_n, a generator of the subgroup of the circle of size n, -/// and given a shift, that is a another point of the cirvle, +/// Given g_n, a generator of the subgroup of size n of the circle, i.e. , +/// and given a shift, that is a another point of the circle, /// we define the coset shift + which is the set of all the points in /// plus the shift. /// For example, if = {p1, p2, p3, p4}, then g_8 + = {g_8 + p1, g_8 + p2, g_8 + p3, g_8 + p4}. diff --git a/math/src/circle/point.rs b/math/src/circle/point.rs index 24759a043..e0e7aa210 100644 --- a/math/src/circle/point.rs +++ b/math/src/circle/point.rs @@ -4,7 +4,7 @@ use crate::field::{ element::FieldElement, fields::mersenne31::{extensions::Degree4ExtensionField, field::Mersenne31Field}, }; -use core::ops::{Add, Mul}; +use core::ops::{Add, AddAssign, Mul, MulAssign}; /// Given a Field F, we implement here the Group which consists of all the points (x, y) such as /// x in F, y in F and x^2 + y^2 = 1, i.e. the Circle. The operation of the group will have @@ -31,10 +31,10 @@ impl> CirclePoint { } /// Computes 2(x, y) = (2x^2 - 1, 2xy). - pub fn double(self) -> Self { + pub fn double(&self) -> Self { Self::new( self.x.square().double() - FieldElement::one(), - self.x.double() * self.y, + self.x.double() * self.y.clone(), ) .unwrap() } @@ -129,14 +129,13 @@ impl> PartialEq for CirclePoint { /// (a, b) + (c, d) = (a * c - b * d, a * d + b * c) impl> Add for &CirclePoint { type Output = CirclePoint; - fn add(self, other: Self) -> Self::Output { let x = &self.x * &other.x - &self.y * &other.y; let y = &self.x * &other.y + &self.y * &other.x; CirclePoint { x, y } } } -impl> Add> for CirclePoint { +impl> Add for CirclePoint { type Output = CirclePoint; fn add(self, rhs: CirclePoint) -> Self::Output { &self + &rhs @@ -154,28 +153,58 @@ impl> Add<&CirclePoint> for CirclePoint { &self + rhs } } - +impl> AddAssign<&CirclePoint> for CirclePoint { + fn add_assign(&mut self, rhs: &CirclePoint) { + *self = &*self + rhs; + } +} +impl> AddAssign> for CirclePoint { + fn add_assign(&mut self, rhs: CirclePoint) { + *self += &rhs; + } +} /// Multiplication between a point and a scalar (i.e. group operation repeatedly): /// (x, y) * n = (x ,y) + ... + (x, y) n-times. -impl> Mul for CirclePoint { +impl> Mul for &CirclePoint { type Output = CirclePoint; - - fn mul(self, scalar: u128) -> Self { + fn mul(self, scalar: u128) -> Self::Output { let mut scalar = scalar; - let mut res = Self::zero(); - let mut cur = self; + let mut res = CirclePoint::::zero(); + let mut cur = self.clone(); loop { if scalar == 0 { return res; } if scalar & 1 == 1 { - res = &res + &cur; + res += &cur; } cur = cur.double(); scalar >>= 1; } } } +impl> Mul for CirclePoint { + type Output = CirclePoint; + fn mul(self, scalar: u128) -> Self::Output { + &self * scalar + } +} +impl> MulAssign for CirclePoint { + fn mul_assign(&mut self, scalar: u128) { + let mut scalar = scalar; + let mut res = CirclePoint::::zero(); + loop { + if scalar == 0 { + *self = res.clone(); + } + if scalar & 1 == 1 { + res += &*self; + } + *self = self.double(); + scalar >>= 1; + } + } +} #[cfg(test)] mod tests {