pub mod prime; pub mod barrett; pub mod montgomery; pub mod impl_u64; pub type REDUCEMOD = u8; pub const NONE: REDUCEMOD = 0; pub const ONCE: REDUCEMOD = 1; pub const TWICE: REDUCEMOD = 2; pub const FOURTIMES: REDUCEMOD = 3; pub const BARRETT: REDUCEMOD = 4; pub const BARRETTLAZY: REDUCEMOD = 5; pub trait WordOps{ fn log2(self) -> O; fn reverse_bits_msb(self, n:u32) -> O; } impl WordOps for u64{ #[inline(always)] fn log2(self) -> u64{ (u64::BITS - (self-1).leading_zeros()) as _ } #[inline(always)] fn reverse_bits_msb(self, n: u32) -> u64{ self.reverse_bits() >> (usize::BITS - n) } } impl WordOps for usize{ #[inline(always)] fn log2(self) -> usize{ (usize::BITS - (self-1).leading_zeros()) as _ } #[inline(always)] fn reverse_bits_msb(self, n: u32) -> usize{ self.reverse_bits() >> (usize::BITS - n) } } pub trait ReduceOnce{ /// Assigns self-q to self if self >= q in constant time. /// User must ensure that 2q fits in O. fn reduce_once_constant_time_assign(&mut self, q: O); /// Returns self-q if self >= q else self in constant time. /// /// User must ensure that 2q fits in O. fn reduce_once_constant_time(&self, q:O) -> O; /// Assigns self-q to self if self >= q. /// /// User must ensure that 2q fits in O. fn reduce_once_assign(&mut self, q: O); /// Returns self-q if self >= q else self. /// /// User must ensure that 2q fits in O. fn reduce_once(&self, q:O) -> O; } pub trait WordOperations{ // Applies a parameterized modular reduction. fn word_reduce_assign(&self, x: &mut O); // Assigns a + b to c. fn word_add_binary_assign(&self, a: &O, b:&O, c: &mut O); // Assigns a + b to b. fn word_add_unary_assign(&self, a: &O, b: &mut O); // Assigns a - b to c. fn word_sub_binary_assign(&self, a: &O, b:&O, c: &mut O); // Assigns b - a to b. fn word_sub_unary_assign(&self, a: &O, b: &mut O); // Assigns -a to a. fn word_neg_unary_assign(&self, a:&mut O); // Assigns -a to b. fn word_neg_binary_assign(&self, a: &O, b:&mut O); // Assigns a * 2^64 to b. fn word_prepare_montgomery_assign(&self, a: &O, b: &mut montgomery::Montgomery); // Assigns a * b to c. fn word_mul_montgomery_external_binary_assign(&self, a:&montgomery::Montgomery, b:&O, c: &mut O); // Assigns a * b to b. fn word_mul_montgomery_external_unary_assign(&self, a:&montgomery::Montgomery, b:&mut O); // Assigns a * b to c. fn word_mul_barrett_binary_assign(&self, a: &barrett::Barrett, b:&O, c: &mut O); // Assigns a * b to b. fn word_mul_barrett_unary_assign(&self, a:&barrett::Barrett, b:&mut O); // Assigns (a + 2q - b) * c to d. fn word_sum_aqqmb_prod_c_barrett_assign_d(&self, a: &O, b: &O, c: &barrett::Barrett, d: &mut O); } pub trait VecOperations{ // Applies a parameterized modular reduction. fn vec_reduce_assign(&self, x: &mut [O]); // Assigns a[i] + b[i] to c[i] fn vec_add_binary_assign(&self, a: &[O], b:&[O], c: &mut [O]); // Assigns a[i] + b[i] to b[i] fn vec_add_unary_assign(&self, a: &[O], b: &mut [O]); // Assigns a[i] - b[i] to c[i] fn vec_sub_binary_assign(&self, a: &[O], b:&[O], c: &mut [O]); // Assigns a[i] - b[i] to b[i] fn vec_sub_unary_assign(&self, a: &[O], b: &mut [O]); // Assigns -a[i] to a[i]. fn vec_neg_unary_assign(&self, a: &mut [O]); // Assigns -a[i] to a[i]. fn vec_neg_binary_assign(&self, a: &[O], b: &mut [O]); // Assigns a * 2^64 to b. fn vec_prepare_montgomery_assign(&self, a: &[O], b: &mut [montgomery::Montgomery]); // Assigns a[i] * b[i] to c[i]. fn vec_mul_montgomery_external_binary_assign(&self, a:&[montgomery::Montgomery], b:&[O], c: &mut [O]); // Assigns a[i] * b[i] to b[i]. fn vec_mul_montgomery_external_unary_assign(&self, a:&[montgomery::Montgomery], b:&mut [O]); // Assigns a * b[i] to b[i]. fn vec_mul_scalar_barrett_external_unary_assign(&self, a:& barrett::Barrett, b:&mut [u64]); // Assigns a * b[i] to c[i]. fn vec_mul_scalar_barrett_external_binary_assign(&self, a:& barrett::Barrett, b:&[u64], c: &mut [u64]); // Assigns (a[i] + 2q - b[i]) * c to d[i]. fn vec_sum_aqqmb_prod_c_scalar_barrett_assign_d(&self, a: &[u64], b: &[u64], c: &barrett::Barrett, d: &mut [u64]); }