arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/src/modulus/impl_u64/shoup.rs
src/modulus/impl_u64/shoup.rsRaw
 1use crate::modulus::ReduceOnce;
 2use crate::modulus::shoup::{ShoupPrecomp, Shoup};
 3
 4impl ShoupPrecomp<u64>{
 5
 6    pub fn new(q: u64) -> Self {
 7        let mut precomp: ShoupPrecomp<u64> = Self{q:q, one:Shoup(0,0)};
 8        precomp.one = precomp.prepare(1);
 9        precomp
10    }
11
12    #[inline(always)]
13    pub fn one(&self) -> Shoup<u64> {
14        self.one
15    }
16
17    #[inline(always)]
18    pub fn prepare(&self, v: u64) -> Shoup<u64> {
19        debug_assert!(v < self.q);
20        let quotient: u64 = (((v as u128) << 64) / self.q as u128) as _;
21        Shoup(v, quotient)
22    }
23
24    #[inline(always)]
25    pub fn mul_external(&self, lhs: Shoup<u64>, rhs: u64) -> u64 {
26        let mut r: u64 = self.mul_external_lazy(lhs, rhs);
27        r.reduce_once_assign(self.q);
28        r
29    }
30
31    #[inline(always)]
32    pub fn mul_external_assign(&self, lhs: Shoup<u64>, rhs: &mut u64){
33        self.mul_external_lazy_assign(lhs, rhs);
34        rhs.reduce_once_assign(self.q);
35    }
36
37    #[inline(always)]
38    pub fn mul_external_lazy(&self, lhs: Shoup<u64>, rhs: u64) -> u64 {
39        let mut r: u64 = rhs;
40        self.mul_external_lazy_assign(lhs, &mut r);
41        r
42    }
43
44    #[inline(always)]
45    pub fn mul_external_lazy_assign(&self, lhs: Shoup<u64>, rhs: &mut u64){
46        let t: u64 = ((*lhs.quotient() as u128 * *rhs as u128) >> 64) as _;
47        *rhs = (rhs.wrapping_mul(*lhs.value())).wrapping_sub(self.q.wrapping_mul(t));
48    }
49
50    #[inline(always)]
51    pub fn reduce_assign(&self, rhs: &mut u64){
52        self.reduce_assign_lazy(rhs);
53        rhs.reduce_once_assign(self.q);
54    }
55
56    #[inline(always)]
57    pub fn reduce_assign_lazy(&self, rhs: &mut u64){
58        *rhs = rhs.wrapping_sub(self.q.wrapping_mul(((self.one.1 as u128 * *rhs as u128) >> 64) as _))
59    }
60}