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}