use crate::ffi::vec_znx_big; use crate::ffi::vec_znx_dft; use crate::znx_base::ZnxAlloc; use crate::znx_base::ZnxInfos; use crate::znx_base::ZnxLayout; use crate::znx_base::ZnxSliceSize; use crate::{Backend, FFT64, Module, VecZnx, VecZnxBig, VecZnxDft, assert_alignement}; pub trait VecZnxDftOps { /// Allocates a vector Z[X]/(X^N+1) that stores normalized in the DFT space. fn new_vec_znx_dft(&self, cols: usize, size: usize) -> VecZnxDft; /// Returns a new [VecZnxDft] with the provided bytes array as backing array. /// /// Behavior: takes ownership of the backing array. /// /// # Arguments /// /// * `cols`: the number of cols of the [VecZnxDft]. /// * `bytes`: a byte array of size at least [Module::bytes_of_vec_znx_dft]. /// /// # Panics /// If `bytes.len()` < [Module::bytes_of_vec_znx_dft]. fn new_vec_znx_dft_from_bytes(&self, cols: usize, size: usize, bytes: Vec) -> VecZnxDft; /// Returns a new [VecZnxDft] with the provided bytes array as backing array. /// /// Behavior: the backing array is only borrowed. /// /// # Arguments /// /// * `cols`: the number of cols of the [VecZnxDft]. /// * `bytes`: a byte array of size at least [Module::bytes_of_vec_znx_dft]. /// /// # Panics /// If `bytes.len()` < [Module::bytes_of_vec_znx_dft]. fn new_vec_znx_dft_from_bytes_borrow(&self, cols: usize, size: usize, bytes: &mut [u8]) -> VecZnxDft; /// Returns a new [VecZnxDft] with the provided bytes array as backing array. /// /// # Arguments /// /// * `cols`: the number of cols of the [VecZnxDft]. /// * `bytes`: a byte array of size at least [Module::bytes_of_vec_znx_dft]. /// /// # Panics /// If `bytes.len()` < [Module::bytes_of_vec_znx_dft]. fn bytes_of_vec_znx_dft(&self, cols: usize, size: usize) -> usize; /// Returns the minimum number of bytes necessary to allocate /// a new [VecZnxDft] through [VecZnxDft::from_bytes]. fn vec_znx_idft_tmp_bytes(&self) -> usize; /// b <- IDFT(a), uses a as scratch space. fn vec_znx_idft_tmp_a(&self, res: &mut VecZnxBig, res_col: usize, a: &mut VecZnxDft, a_cols: usize); fn vec_znx_idft(&self, res: &mut VecZnxBig, res_col: usize, a: &VecZnxDft, a_col: usize, tmp_bytes: &mut [u8]); fn vec_znx_dft(&self, res: &mut VecZnxDft, res_col: usize, a: &VecZnx, a_col: usize); } impl VecZnxDftOps for Module { fn new_vec_znx_dft(&self, cols: usize, size: usize) -> VecZnxDft { VecZnxDft::::new(&self, 1, cols, size) } fn new_vec_znx_dft_from_bytes(&self, cols: usize, size: usize, bytes: Vec) -> VecZnxDft { VecZnxDft::from_bytes(self, 1, cols, size, bytes) } fn new_vec_znx_dft_from_bytes_borrow(&self, cols: usize, size: usize, bytes: &mut [u8]) -> VecZnxDft { VecZnxDft::from_bytes_borrow(self, 1, cols, size, bytes) } fn bytes_of_vec_znx_dft(&self, cols: usize, size: usize) -> usize { VecZnxDft::bytes_of(&self, 1, cols, size) } fn vec_znx_idft_tmp_a(&self, res: &mut VecZnxBig, res_col: usize, a: &mut VecZnxDft, a_col: usize) { #[cfg(debug_assertions)] { assert_eq!(res.poly_count(), a.poly_count()); } unsafe { vec_znx_dft::vec_znx_idft_tmp_a( self.ptr, res.at_mut_ptr(res_col * res.size(), 0) as *mut vec_znx_big::vec_znx_big_t, res.size() as u64, a.at_ptr(a_col * a.size(), 0) as *mut vec_znx_dft::vec_znx_dft_t, a.size() as u64, ) } } fn vec_znx_idft_tmp_bytes(&self) -> usize { unsafe { vec_znx_dft::vec_znx_idft_tmp_bytes(self.ptr) as usize } } /// b <- DFT(a) /// /// # Panics /// If b.cols < a_cols fn vec_znx_dft(&self, res: &mut VecZnxDft, res_col: usize, a: &VecZnx, a_col: usize) { unsafe { vec_znx_dft::vec_znx_dft( self.ptr, res.at_mut_ptr(res_col * res.size(), 0) as *mut vec_znx_dft::vec_znx_dft_t, res.size() as u64, a.at_ptr(a_col, 0), a.size() as u64, a.sl() as u64, ) } } // b <- IDFT(a), scratch space size obtained with [vec_znx_idft_tmp_bytes]. fn vec_znx_idft(&self, res: &mut VecZnxBig, res_col: usize, a: &VecZnxDft, a_col: usize, tmp_bytes: &mut [u8]) { #[cfg(debug_assertions)] { assert!( tmp_bytes.len() >= Self::vec_znx_idft_tmp_bytes(self), "invalid tmp_bytes: tmp_bytes.len()={} < self.vec_znx_idft_tmp_bytes()={}", tmp_bytes.len(), Self::vec_znx_idft_tmp_bytes(self) ); assert_alignement(tmp_bytes.as_ptr()) } unsafe { vec_znx_dft::vec_znx_idft( self.ptr, res.at_mut_ptr(res_col * res.size(), 0) as *mut vec_znx_big::vec_znx_big_t, res.size() as u64, a.at_ptr(a_col * res.size(), 0) as *const vec_znx_dft::vec_znx_dft_t, a.size() as u64, tmp_bytes.as_mut_ptr(), ) } } }