use base2k::{Infos, Module, VecZnx, VecZnxApi, VecZnxBorrow, VecZnxOps, VmpPMat, VmpPMatOps}; use crate::parameters::Parameters; impl Parameters { pub fn elem_from_bytes(&self, log_q: usize, rows: usize, bytes: &mut [u8]) -> Elem where T: VecZnxCommon, Elem: Infos + ElemVecZnx, { Elem::::from_bytes(self.module(), self.log_base2k(), log_q, rows, bytes) } } pub struct Elem { pub value: Vec, pub log_base2k: usize, pub log_q: usize, pub log_scale: usize, } pub trait VecZnxCommon: VecZnxApi + Infos {} impl VecZnxCommon for VecZnx {} impl VecZnxCommon for VecZnxBorrow {} pub trait ElemVecZnx { fn from_bytes( module: &Module, log_base2k: usize, log_q: usize, rows: usize, bytes: &mut [u8], ) -> Elem; fn bytes_of(module: &Module, log_base2k: usize, log_q: usize, rows: usize) -> usize; fn at(&self, i: usize) -> &T; fn at_mut(&mut self, i: usize) -> &mut T; fn zero(&mut self); } impl ElemVecZnx for Elem where T: VecZnxCommon, Elem: Infos, { fn bytes_of(module: &Module, log_base2k: usize, log_q: usize, rows: usize) -> usize { let cols = (log_q + log_base2k - 1) / log_base2k; module.n() * cols * (rows + 1) * 8 } fn from_bytes( module: &Module, log_base2k: usize, log_q: usize, rows: usize, bytes: &mut [u8], ) -> Elem { assert!(rows > 0); let n: usize = module.n(); assert!(bytes.len() >= Self::bytes_of(module, log_base2k, log_q, rows)); let mut value: Vec = Vec::new(); let limbs: usize = (log_q + log_base2k - 1) / log_base2k; let size = T::bytes_of(n, limbs); let mut ptr: usize = 0; (0..rows).for_each(|_| { value.push(T::from_bytes(n, limbs, &mut bytes[ptr..])); ptr += size }); Self { value, log_q, log_base2k, log_scale: 0, } } fn at(&self, i: usize) -> &T { assert!(i < self.rows()); &self.value[i] } fn at_mut(&mut self, i: usize) -> &mut T { assert!(i < self.rows()); &mut self.value[i] } fn zero(&mut self) { self.value.iter_mut().for_each(|i| i.zero()); } } impl Elem { pub fn log_base2k(&self) -> usize { self.log_base2k } pub fn log_q(&self) -> usize { self.log_q } pub fn log_scale(&self) -> usize { self.log_scale } } impl Infos for Elem { fn n(&self) -> usize { self.value[0].n() } fn log_n(&self) -> usize { self.value[0].log_n() } fn rows(&self) -> usize { self.value.len() } fn cols(&self) -> usize { self.value[0].cols() } } impl Infos for Elem { fn n(&self) -> usize { self.value[0].n() } fn log_n(&self) -> usize { self.value[0].log_n() } fn rows(&self) -> usize { self.value.len() } fn cols(&self) -> usize { self.value[0].cols() } } impl Elem { pub fn new(module: &Module, log_base2k: usize, log_q: usize, rows: usize) -> Self { assert!(rows > 0); let limbs: usize = (log_q + log_base2k - 1) / log_base2k; let mut value: Vec = Vec::new(); (0..rows).for_each(|_| value.push(module.new_vec_znx(limbs))); Self { value, log_q, log_base2k, log_scale: 0, } } } impl Infos for Elem { fn n(&self) -> usize { self.value[0].n() } fn log_n(&self) -> usize { self.value[0].log_n() } fn rows(&self) -> usize { self.value[0].rows() } fn cols(&self) -> usize { self.value[0].cols() } } impl Elem { pub fn new(module: &Module, log_base2k: usize, rows: usize, cols: usize) -> Self { assert!(rows > 0); assert!(cols > 0); Self { value: Vec::from([module.new_vmp_pmat(rows, cols); 1]), log_q: 0, log_base2k: log_base2k, log_scale: 0, } } }