use base2k::{ Backend, Module, VecZnx, VecZnxAlloc, VecZnxDft, VecZnxDftAlloc, VecZnxDftToMut, VecZnxDftToRef, VecZnxToMut, VecZnxToRef, ZnxInfos, }; pub trait Infos { type Inner: ZnxInfos; fn inner(&self) -> &Self::Inner; /// Returns the ring degree of the polynomials. fn n(&self) -> usize { self.inner().n() } /// Returns the base two logarithm of the ring dimension of the polynomials. fn log_n(&self) -> usize { self.inner().log_n() } /// Returns the number of rows. fn rows(&self) -> usize { self.inner().rows() } /// Returns the number of polynomials in each row. fn cols(&self) -> usize { self.inner().cols() } /// Returns the number of size per polynomial. fn size(&self) -> usize { let size: usize = self.inner().size(); debug_assert_eq!(size, derive_size(self.log_base2k(), self.log_k())); size } /// Returns the total number of small polynomials. fn poly_count(&self) -> usize { self.rows() * self.cols() * self.size() } /// Returns the base 2 logarithm of the ciphertext base. fn log_base2k(&self) -> usize; /// Returns the bit precision of the ciphertext. fn log_k(&self) -> usize; } pub struct RLWECt { pub data: VecZnx, pub log_base2k: usize, pub log_k: usize, } impl Infos for RLWECt { type Inner = VecZnx; fn inner(&self) -> &Self::Inner { &self.data } fn log_base2k(&self) -> usize { self.log_base2k } fn log_k(&self) -> usize { self.log_k } } impl VecZnxToMut for RLWECt where VecZnx: VecZnxToMut, { fn to_mut(&mut self) -> VecZnx<&mut [u8]> { self.data.to_mut() } } impl VecZnxToRef for RLWECt where VecZnx: VecZnxToRef, { fn to_ref(&self) -> VecZnx<&[u8]> { self.data.to_ref() } } pub struct RLWEPt { pub data: VecZnx, pub log_base2k: usize, pub log_k: usize, } impl Infos for RLWEPt { type Inner = VecZnx; fn inner(&self) -> &Self::Inner { &self.data } fn log_base2k(&self) -> usize { self.log_base2k } fn log_k(&self) -> usize { self.log_k } } impl VecZnxToMut for RLWEPt where VecZnx: VecZnxToMut, { fn to_mut(&mut self) -> VecZnx<&mut [u8]> { self.data.to_mut() } } impl VecZnxToRef for RLWEPt where VecZnx: VecZnxToRef, { fn to_ref(&self) -> VecZnx<&[u8]> { self.data.to_ref() } } impl RLWECt> { pub fn new(module: &Module, log_base2k: usize, log_k: usize, cols: usize) -> Self { Self { data: module.new_vec_znx(cols, derive_size(log_base2k, log_k)), log_base2k: log_base2k, log_k: log_k, } } } impl RLWEPt> { pub fn new(module: &Module, log_base2k: usize, log_k: usize) -> Self { Self { data: module.new_vec_znx(1, derive_size(log_base2k, log_k)), log_base2k: log_base2k, log_k: log_k, } } } pub struct RLWECtDft { pub data: VecZnxDft, pub log_base2k: usize, pub log_k: usize, } impl RLWECtDft, B> { pub fn new(module: &Module, log_base2k: usize, log_k: usize, cols: usize) -> Self { Self { data: module.new_vec_znx_dft(cols, derive_size(log_base2k, log_k)), log_base2k: log_base2k, log_k: log_k, } } } impl Infos for RLWECtDft { type Inner = VecZnxDft; fn inner(&self) -> &Self::Inner { &self.data } fn log_base2k(&self) -> usize { self.log_base2k } fn log_k(&self) -> usize { self.log_k } } impl VecZnxDftToMut for RLWECtDft where VecZnxDft: VecZnxDftToMut, { fn to_mut(&mut self) -> VecZnxDft<&mut [u8], B> { self.data.to_mut() } } impl VecZnxDftToRef for RLWECtDft where VecZnxDft: VecZnxDftToRef, { fn to_ref(&self) -> VecZnxDft<&[u8], B> { self.data.to_ref() } } pub(crate) fn derive_size(log_base2k: usize, log_k: usize) -> usize { (log_k + log_base2k - 1) / log_base2k }