poulpy/base2k/src/module.rs
base2k/src/module.rsRaw
1use crate::ffi::module::{delete_module_info, module_info_t, new_module_info, MODULE};
2use crate::{Free, GALOISGENERATOR};
3
4pub type MODULETYPE = u8;
5pub const FFT64: u8 = 0;
6pub const NTT120: u8 = 1;
7
8pub struct Module(pub *mut MODULE, pub usize);
9
10impl Module {
11 // Instantiates a new module.
12 pub fn new<const MODULETYPE: MODULETYPE>(n: usize) -> Self {
13 unsafe {
14 let m: *mut module_info_t = new_module_info(n as u64, MODULETYPE as u32);
15 if m.is_null() {
16 panic!("Failed to create module.");
17 }
18 Self(m, n)
19 }
20 }
21
22 pub fn n(&self) -> usize {
23 self.1
24 }
25
26 pub fn log_n(&self) -> usize {
27 (usize::BITS - (self.n() - 1).leading_zeros()) as _
28 }
29
30 pub fn cyclotomic_order(&self) -> u64 {
31 (self.n() << 1) as _
32 }
33
34 // GALOISGENERATOR^|gen| * sign(gen)
35 pub fn galois_element(&self, gen: i64) -> i64 {
36 if gen == 0 {
37 return 1;
38 }
39
40 let mut gal_el: u64 = 1;
41 let mut gen_1_pow: u64 = GALOISGENERATOR;
42 let mut e: usize = gen.abs() as usize;
43 while e > 0 {
44 if e & 1 == 1 {
45 gal_el = gal_el.wrapping_mul(gen_1_pow);
46 }
47
48 gen_1_pow = gen_1_pow.wrapping_mul(gen_1_pow);
49 e >>= 1;
50 }
51
52 gal_el &= self.cyclotomic_order() - 1;
53
54 (gal_el as i64) * gen.signum()
55 }
56}
57
58impl Free for Module {
59 fn free(self) {
60 unsafe { delete_module_info(self.0) }
61 drop(self);
62 }
63}
64
65pub trait Bytes {
66 /// Returns the minimum number of bytes necessary to allocate
67 /// a new [VecZnxBig] through [VecZnxBig::from_bytes].
68 fn bytes_of_vec_znx_big(&self, limbs: usize) -> usize;
69
70 /// Returns the minimum number of bytes necessary to allocate
71 /// a new [VecZnxDft] through [VecZnxDft::from_bytes].
72 fn vec_znx_idft_tmp_bytes(&self) -> usize;
73
74 /// Returns a new [VecZnxDft] with the provided bytes array as backing array.
75 ///
76 /// # Arguments
77 ///
78 /// * `limbs`: the number of limbs of the [VecZnxDft].
79 /// * `bytes`: a byte array of size at least [Module::bytes_of_vec_znx_dft].
80 ///
81 /// # Panics
82 /// If `bytes.len()` < [Module::bytes_of_vec_znx_dft].
83 fn bytes_of_vec_znx_dft(&self, limbs: usize) -> usize;
84
85 fn vec_znx_big_normalize_tmp_bytes(&self) -> usize;
86}