arnaucube
arnaucube/poulpyPublic Self-hosted repository
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}