arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/base2k/src/vec_znx_dft.rs
base2k/src/vec_znx_dft.rsRaw
  1use crate::ffi::vec_znx_big;
  2use crate::ffi::vec_znx_dft;
  3use crate::ffi::vec_znx_dft::bytes_of_vec_znx_dft;
  4use crate::{Module, VecZnx, VecZnxBig};
  5
  6pub struct VecZnxDft(pub *mut vec_znx_dft::vec_znx_dft_t, pub usize);
  7
  8impl VecZnxDft {
  9    /// Returns a new [VecZnxDft] with the provided data as backing array.
 10    /// User must ensure that data is properly alligned and that
 11    /// the size of data is at least equal to [Module::bytes_of_vec_znx_dft].
 12    pub fn from_bytes(limbs: usize, data: &mut [u8]) -> VecZnxDft {
 13        VecZnxDft(data.as_mut_ptr() as *mut vec_znx_dft::vec_znx_dft_t, limbs)
 14    }
 15
 16    /// Cast a [VecZnxDft] into a [VecZnxBig].
 17    /// The returned [VecZnxBig] shares the backing array
 18    /// with the original [VecZnxDft].
 19    pub fn as_vec_znx_big(&mut self) -> VecZnxBig {
 20        VecZnxBig(self.0 as *mut vec_znx_big::vec_znx_bigcoeff_t, self.1)
 21    }
 22    pub fn limbs(&self) -> usize {
 23        self.1
 24    }
 25}
 26
 27impl Module {
 28    // Allocates a vector Z[X]/(X^N+1) that stores normalized in the DFT space.
 29    pub fn new_vec_znx_dft(&self, limbs: usize) -> VecZnxDft {
 30        unsafe { VecZnxDft(vec_znx_dft::new_vec_znx_dft(self.0, limbs as u64), limbs) }
 31    }
 32
 33    /// Returns a new [VecZnxDft] with the provided bytes array as backing array.
 34    ///
 35    /// # Arguments
 36    ///
 37    /// * `limbs`: the number of limbs of the [VecZnxDft].
 38    /// * `bytes`: a byte array of size at least [Module::bytes_of_vec_znx_dft].
 39    ///
 40    /// # Panics
 41    /// If `bytes.len()` < [Module::bytes_of_vec_znx_dft].
 42    pub fn new_vec_znx_from_bytes(&self, limbs: usize, bytes: &mut [u8]) -> VecZnxDft {
 43        assert!(
 44            bytes.len() >= self.bytes_of_vec_znx_dft(limbs),
 45            "invalid bytes: bytes.len()={} < bytes_of_vec_znx_dft={}",
 46            bytes.len(),
 47            self.bytes_of_vec_znx_dft(limbs)
 48        );
 49        VecZnxDft::from_bytes(limbs, bytes)
 50    }
 51
 52    /// Returns the minimum number of bytes necessary to allocate
 53    /// a new [VecZnxDft] through [VecZnxDft::from_bytes].
 54    pub fn bytes_of_vec_znx_dft(&self, limbs: usize) -> usize {
 55        unsafe { bytes_of_vec_znx_dft(self.0, limbs as u64) as usize }
 56    }
 57
 58    // b <- IDFT(a), uses a as scratch space.
 59    pub fn vec_znx_idft_tmp_a(&self, b: &mut VecZnxBig, a: &mut VecZnxDft, a_limbs: usize) {
 60        assert!(
 61            b.limbs() >= a_limbs,
 62            "invalid c_vector: b_vector.limbs()={} < a_limbs={}",
 63            b.limbs(),
 64            a_limbs
 65        );
 66        unsafe { vec_znx_dft::vec_znx_idft_tmp_a(self.0, b.0, b.limbs() as u64, a.0, a_limbs as u64) }
 67    }
 68
 69    // Returns the size of the scratch space for [vec_znx_idft].
 70    pub fn vec_znx_idft_tmp_bytes(&self) -> usize {
 71        unsafe { vec_znx_dft::vec_znx_idft_tmp_bytes(self.0) as usize }
 72    }
 73
 74    /// b <- DFT(a)
 75    ///
 76    /// # Panics
 77    /// If b.limbs < a_limbs
 78    pub fn vec_znx_dft(&self, b: &mut VecZnxDft, a: &VecZnx, a_limbs: usize) {
 79        assert!(
 80            b.limbs() >= a_limbs,
 81            "invalid a_limbs: b.limbs()={} < a_limbs={}",
 82            b.limbs(),
 83            a_limbs
 84        );
 85        unsafe {
 86            vec_znx_dft::vec_znx_dft(
 87                self.0,
 88                b.0,
 89                b.limbs() as u64,
 90                a.as_ptr(),
 91                a_limbs as u64,
 92                a.n as u64,
 93            )
 94        }
 95    }
 96
 97    // b <- IDFT(a), scratch space size obtained with [vec_znx_idft_tmp_bytes].
 98    pub fn vec_znx_idft(
 99        &self,
100        b: &mut VecZnxBig,
101        a: &mut VecZnxDft,
102        a_limbs: usize,
103        tmp_bytes: &mut [u8],
104    ) {
105        assert!(
106            b.limbs() >= a_limbs,
107            "invalid c_vector: b.limbs()={} < a_limbs={}",
108            b.limbs(),
109            a_limbs
110        );
111        assert!(
112            a.limbs() >= a_limbs,
113            "invalid c_vector: a.limbs()={} < a_limbs={}",
114            a.limbs(),
115            a_limbs
116        );
117        assert!(
118            tmp_bytes.len() <= self.vec_znx_idft_tmp_bytes(),
119            "invalid tmp_bytes: tmp_bytes.len()={} < self.vec_znx_idft_tmp_bytes()={}",
120            tmp_bytes.len(),
121            self.vec_znx_idft_tmp_bytes()
122        );
123        unsafe {
124            vec_znx_dft::vec_znx_idft(
125                self.0,
126                b.0,
127                a.limbs() as u64,
128                a.0,
129                a_limbs as u64,
130                tmp_bytes.as_mut_ptr(),
131            )
132        }
133    }
134}