poulpy/src/modulus/barrett.rs
src/modulus/barrett.rsRaw
1use crate::modulus::ReduceOnce;
2
3use num_bigint::BigUint;
4use num_traits::cast::ToPrimitive;
5
6#[derive(Clone, Copy, Debug, PartialEq, Eq)]
7pub struct BarrettPrecomp<O>{
8 q: O,
9 lo:O,
10 hi:O,
11}
12
13impl<O> BarrettPrecomp<O>{
14
15 #[inline(always)]
16 pub fn value_hi(&self) -> &O{
17 &self.hi
18 }
19
20 #[inline(always)]
21 pub fn value_lo(&self) -> &O{
22 &self.lo
23 }
24}
25
26impl BarrettPrecomp<u64>{
27 pub fn new(q: u64) -> BarrettPrecomp<u64> {
28 let mut big_r = BigUint::parse_bytes(b"100000000000000000000000000000000", 16).unwrap();
29 big_r = big_r / BigUint::from(q);
30 let lo = (&big_r & BigUint::from(u64::MAX)).to_u64().unwrap();
31 let hi = (big_r >> 64u64).to_u64().unwrap();
32 Self{q, lo, hi}
33 }
34
35 /// Returns lhs mod q.
36 #[inline(always)]
37 pub fn reduce(&self, lhs: u64) -> u64{
38 let mut r: u64 = self.reduce_lazy(lhs);
39 r.reduce_once_assign(self.q);
40 r
41 }
42
43 /// Returns lhs mod q in range [0, 2q-1].
44 #[inline(always)]
45 pub fn reduce_lazy(&self, lhs: u64) -> u64{
46 let (_, mhi) = lhs.widening_mul(self.hi);
47 lhs - mhi.wrapping_mul(self.q)
48 }
49}