use std::fmt::{Display, Formatter, Result}; use std::ops::{Add, Mul, Sub}; /// Did I really implement an awfully hacky prime order field to play with this /// Yes...yes I did... #[derive(Clone, Copy, Debug)] pub struct PrimeOrderDomain { val: u64, } impl Display for PrimeOrderDomain<{ ORDER }> { fn fmt(&self, f: &mut Formatter<'_>) -> Result { write!(f, "{:20}", self.val) } } impl PrimeOrderDomain<{ ORDER }> { pub fn new(val: u64) -> PrimeOrderDomain<{ ORDER }> { PrimeOrderDomain { val } } pub fn is_zero(&self) -> bool { self.val == 0 } pub fn gt(&self, rhs: &Self) -> bool { self.val > rhs.val } pub fn inverse(&self) -> Self { self.pow(ORDER - 2) // at least it is faster an iterating... } // exponentiation by squaring pub fn pow(&self, exp: u64) -> Self { if exp == 0 { return PrimeOrderDomain::new(1); } if exp == 1 { return self.clone(); } if exp % 2 == 0 { (*self * *self).pow(exp / 2) } else { *self * self.pow(2).pow((exp - 1) / 2) } } } impl Add for PrimeOrderDomain<{ ORDER }> { type Output = Self; fn add(self, rhs: Self) -> Self::Output { PrimeOrderDomain { val: ((self.val as u128 + rhs.val as u128) % ORDER as u128) as u64, } } } impl Sub for PrimeOrderDomain<{ ORDER }> { type Output = Self; fn sub(self, rhs: Self) -> Self::Output { if rhs.val > self.val { return PrimeOrderDomain { val: ((ORDER - rhs.val) + self.val) % ORDER, }; } PrimeOrderDomain { val: (self.val - rhs.val) % ORDER, } } } impl Mul for PrimeOrderDomain<{ ORDER }> { type Output = Self; fn mul(self, rhs: Self) -> Self::Output { PrimeOrderDomain { val: ((self.val as u128 * rhs.val as u128) % ORDER as u128) as u64, } } }