arnaucube
arnaucube/phantom-zonePublic Self-hosted repository
phantom-zone/src/backend/word_size.rs
src/backend/word_size.rsRaw
  1use itertools::izip;
  2use num_traits::{PrimInt, Signed, ToPrimitive, WrappingAdd, WrappingMul, WrappingSub, Zero};
  3
  4use super::{
  5    ArithmeticLazyOps, ArithmeticOps, GetModulus, ModInit, Modulus, ShoupMatrixFMA, VectorOps,
  6};
  7use crate::{utils::ShoupMul, Matrix, RowMut};
  8
  9pub struct WordSizeModulus<T> {
 10    modulus: T,
 11}
 12
 13impl<T> ModInit for WordSizeModulus<T>
 14where
 15    T: Modulus,
 16{
 17    type M = T;
 18    fn new(modulus: T) -> Self {
 19        assert!(modulus.is_native());
 20        // For now assume ModulusOpsU64 is only used for u64
 21        Self { modulus: modulus }
 22    }
 23}
 24
 25impl<T> ArithmeticOps for WordSizeModulus<T>
 26where
 27    T: Modulus,
 28    T::Element: WrappingAdd + WrappingSub + WrappingMul + Zero,
 29{
 30    type Element = T::Element;
 31    fn add(&self, a: &Self::Element, b: &Self::Element) -> Self::Element {
 32        T::Element::wrapping_add(a, b)
 33    }
 34
 35    fn mul(&self, a: &Self::Element, b: &Self::Element) -> Self::Element {
 36        T::Element::wrapping_mul(a, b)
 37    }
 38
 39    fn neg(&self, a: &Self::Element) -> Self::Element {
 40        T::Element::wrapping_sub(&T::Element::zero(), a)
 41    }
 42
 43    fn sub(&self, a: &Self::Element, b: &Self::Element) -> Self::Element {
 44        T::Element::wrapping_sub(a, b)
 45    }
 46}
 47
 48impl<T> VectorOps for WordSizeModulus<T>
 49where
 50    T: Modulus,
 51    T::Element: WrappingAdd + WrappingSub + WrappingMul + Zero,
 52{
 53    type Element = T::Element;
 54
 55    fn elwise_add_mut(&self, a: &mut [Self::Element], b: &[Self::Element]) {
 56        izip!(a.iter_mut(), b.iter()).for_each(|(ai, bi)| {
 57            *ai = T::Element::wrapping_add(ai, bi);
 58        });
 59    }
 60
 61    fn elwise_sub_mut(&self, a: &mut [Self::Element], b: &[Self::Element]) {
 62        izip!(a.iter_mut(), b.iter()).for_each(|(ai, bi)| {
 63            *ai = T::Element::wrapping_sub(ai, bi);
 64        });
 65    }
 66
 67    fn elwise_mul_mut(&self, a: &mut [Self::Element], b: &[Self::Element]) {
 68        izip!(a.iter_mut(), b.iter()).for_each(|(ai, bi)| {
 69            *ai = T::Element::wrapping_mul(ai, bi);
 70        });
 71    }
 72
 73    fn elwise_neg_mut(&self, a: &mut [Self::Element]) {
 74        a.iter_mut()
 75            .for_each(|ai| *ai = T::Element::wrapping_sub(&T::Element::zero(), ai));
 76    }
 77
 78    fn elwise_scalar_mul(&self, out: &mut [Self::Element], a: &[Self::Element], b: &Self::Element) {
 79        izip!(out.iter_mut(), a.iter()).for_each(|(oi, ai)| {
 80            *oi = T::Element::wrapping_mul(ai, b);
 81        });
 82    }
 83
 84    fn elwise_mul(&self, out: &mut [Self::Element], a: &[Self::Element], b: &[Self::Element]) {
 85        izip!(out.iter_mut(), a.iter(), b.iter()).for_each(|(oi, ai, bi)| {
 86            *oi = T::Element::wrapping_mul(ai, bi);
 87        });
 88    }
 89
 90    fn elwise_scalar_mul_mut(&self, a: &mut [Self::Element], b: &Self::Element) {
 91        a.iter_mut().for_each(|ai| {
 92            *ai = T::Element::wrapping_mul(ai, b);
 93        });
 94    }
 95
 96    fn elwise_fma_mut(&self, a: &mut [Self::Element], b: &[Self::Element], c: &[Self::Element]) {
 97        izip!(a.iter_mut(), b.iter(), c.iter()).for_each(|(ai, bi, ci)| {
 98            *ai = T::Element::wrapping_add(ai, &T::Element::wrapping_mul(bi, ci));
 99        });
100    }
101
102    fn elwise_fma_scalar_mut(
103        &self,
104        a: &mut [Self::Element],
105        b: &[Self::Element],
106        c: &Self::Element,
107    ) {
108        izip!(a.iter_mut(), b.iter()).for_each(|(ai, bi)| {
109            *ai = T::Element::wrapping_add(ai, &T::Element::wrapping_mul(bi, c));
110        });
111    }
112
113    // fn modulus(&self) -> &T {
114    //     &self.modulus
115    // }
116}
117
118impl<T> GetModulus for WordSizeModulus<T>
119where
120    T: Modulus,
121{
122    type Element = T::Element;
123    type M = T;
124    fn modulus(&self) -> &Self::M {
125        &self.modulus
126    }
127}