poulpy/base2k/src/module.rs
base2k/src/module.rsRaw
1use crate::bindings::{
2 module_info_t, new_module_info, svp_ppol_t, vec_znx_bigcoeff_t, vec_znx_dft_t, MODULE,
3};
4
5use crate::GALOISGENERATOR;
6
7pub type MODULETYPE = u8;
8pub const FFT64: u8 = 0;
9pub const NTT120: u8 = 1;
10
11pub struct Module(pub *mut MODULE, pub usize);
12
13impl Module {
14 // Instantiates a new module.
15 pub fn new<const MODULETYPE: MODULETYPE>(n: usize) -> Self {
16 unsafe {
17 let m: *mut module_info_t = new_module_info(n as u64, MODULETYPE as u32);
18 if m.is_null() {
19 panic!("Failed to create module.");
20 }
21 Self(m, n)
22 }
23 }
24
25 pub fn n(&self) -> usize {
26 self.1
27 }
28
29 pub fn log_n(&self) -> usize {
30 (usize::BITS - (self.n() - 1).leading_zeros()) as _
31 }
32
33 pub fn cyclotomic_order(&self) -> u64 {
34 (self.n() << 1) as _
35 }
36
37 // GALOISGENERATOR^|gen| * sign(gen)
38 pub fn galois_element(&self, gen: i64) -> i64 {
39 if gen == 0 {
40 return 1;
41 }
42
43 let mut gal_el: u64 = 1;
44 let mut gen_1_pow: u64 = GALOISGENERATOR;
45 let mut e: usize = gen.abs() as usize;
46 while e > 0 {
47 if e & 1 == 1 {
48 gal_el = gal_el.wrapping_mul(gen_1_pow);
49 }
50
51 gen_1_pow = gen_1_pow.wrapping_mul(gen_1_pow);
52 e >>= 1;
53 }
54
55 gal_el &= self.cyclotomic_order() - 1;
56
57 (gal_el as i64) * gen.signum()
58 }
59}
60
61pub struct SvpPPol(pub *mut svp_ppol_t);
62
63pub struct VecZnxBig(pub *mut vec_znx_bigcoeff_t, pub usize);
64
65impl VecZnxBig {
66 pub fn as_vec_znx_dft(&mut self) -> VecZnxDft {
67 VecZnxDft(self.0 as *mut vec_znx_dft_t, self.1)
68 }
69 pub fn limbs(&self) -> usize {
70 self.1
71 }
72}
73
74pub struct VecZnxDft(pub *mut vec_znx_dft_t, pub usize);
75
76impl VecZnxDft {
77 pub fn as_vec_znx_big(&mut self) -> VecZnxBig {
78 VecZnxBig(self.0 as *mut vec_znx_bigcoeff_t, self.1)
79 }
80 pub fn limbs(&self) -> usize {
81 self.1
82 }
83}