arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/src/modulus.rs
src/modulus.rsRaw
 1pub mod prime;
 2pub mod barrett;
 3pub mod montgomery;
 4pub mod shoup;
 5pub mod impl_u64;
 6
 7pub trait WordOps<O>{
 8    fn log2(self) -> O;
 9    fn reverse_bits_msb(self, n:u32) -> O;
10}
11
12impl WordOps<u64> for u64{
13    #[inline(always)]
14    fn log2(self) -> u64{
15        (u64::BITS - (self-1).leading_zeros()) as _
16    }
17    #[inline(always)]
18    fn reverse_bits_msb(self, n: u32) -> u64{
19        self.reverse_bits() >> (usize::BITS - n)
20    }
21}
22
23impl WordOps<usize> for usize{
24    #[inline(always)]
25    fn log2(self) -> usize{
26        (usize::BITS - (self-1).leading_zeros()) as _
27    }
28    #[inline(always)]
29    fn reverse_bits_msb(self, n: u32) -> usize{
30        self.reverse_bits() >> (usize::BITS - n)
31    }
32}
33
34pub trait ReduceOnce<O>{
35    /// Assigns self-q to self if self >= q in constant time.
36    /// User must ensure that 2q fits in O.
37    fn reduce_once_constant_time_assign(&mut self, q: O);
38    /// Returns self-q if self >= q else self in constant time.
39    /// /// User must ensure that 2q fits in O.
40    fn reduce_once_constant_time(&self, q:O) -> O;
41    /// Assigns self-q to self if self >= q.
42    /// /// User must ensure that 2q fits in O.
43    fn reduce_once_assign(&mut self, q: O);
44    /// Returns self-q if self >= q else self.
45    /// /// User must ensure that 2q fits in O.
46    fn reduce_once(&self, q:O) -> O;
47}
48
49impl ReduceOnce<u64> for u64{
50    #[inline(always)]
51    fn reduce_once_constant_time_assign(&mut self, q: u64){
52        debug_assert!(q < 0x8000000000000000, "2q >= 2^64");
53        *self -= (q.wrapping_sub(*self)>>63)*q;
54    }
55    
56    #[inline(always)]
57    fn reduce_once_constant_time(&self, q:u64) -> u64{
58        debug_assert!(q < 0x8000000000000000, "2q >= 2^64");
59        self - (q.wrapping_sub(*self)>>63)*q
60    }
61
62    #[inline(always)]
63    fn reduce_once_assign(&mut self, q: u64){
64        debug_assert!(q < 0x8000000000000000, "2q >= 2^64");
65        *self = (*self).min(self.wrapping_sub(q))
66    }
67
68    #[inline(always)]
69    fn reduce_once(&self, q:u64) -> u64{
70        debug_assert!(q < 0x8000000000000000, "2q >= 2^64");
71        (*self).min(self.wrapping_sub(q))
72    }
73}