arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/src/modulus/impl_u64/barrett.rs
src/modulus/impl_u64/barrett.rsRaw
 1use crate::modulus::barrett::BarrettPrecomp;
 2use crate::modulus::ReduceOnce;
 3
 4use num_bigint::BigUint;
 5use num_traits::cast::ToPrimitive;
 6
 7impl BarrettPrecomp<u64>{
 8    pub fn new(q: u64) -> BarrettPrecomp<u64> {
 9        let big_r: BigUint = (BigUint::from(1 as usize)<<((u64::BITS<<1) as usize)) / BigUint::from(q);
10        let lo: u64 = (&big_r & BigUint::from(u64::MAX)).to_u64().unwrap();
11        let hi: u64 = (big_r >> u64::BITS).to_u64().unwrap();
12        Self{q, lo, hi}
13    }
14
15    /// Returns lhs mod q.
16    #[inline(always)]
17    pub fn reduce(&self, lhs: u64) -> u64{
18        let mut r: u64 = self.reduce_lazy(lhs);
19        r.reduce_once_assign(self.q);
20        r
21    }
22
23    /// Returns lhs mod q in range [0, 2q-1].
24    #[inline(always)]
25    pub fn reduce_lazy(&self, lhs: u64) -> u64{
26        let (_, mhi) = lhs.widening_mul(self.hi);
27        lhs - mhi.wrapping_mul(self.q)
28    }
29
30    /// Assigns lhs mod q to lhs.
31    #[inline(always)]
32    pub fn reduce_assign(&self, lhs: &mut u64){
33        self.reduce_lazy_assign(lhs);
34        lhs.reduce_once_assign(self.q);
35    }
36
37    /// Assigns lhs mod q in range [0, 2q-1] to lhs.
38    #[inline(always)]
39    pub fn reduce_lazy_assign(&self, lhs: &mut u64){
40        let (_, mhi) = lhs.widening_mul(self.hi);
41        *lhs = *lhs - mhi.wrapping_mul(self.q)
42    }
43}