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