arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/rlwe/src/elem.rs
rlwe/src/elem.rsRaw
  1use crate::parameters::Parameters;
  2use base2k::{Infos, Module, VecZnx, VecZnxOps};
  3
  4pub struct Elem {
  5    pub value: Vec<VecZnx>,
  6    pub log_base2k: usize,
  7    pub log_q: usize,
  8    pub log_scale: usize,
  9}
 10
 11impl Elem {
 12    pub fn new(
 13        module: &Module,
 14        log_base2k: usize,
 15        log_q: usize,
 16        degree: usize,
 17        log_scale: usize,
 18    ) -> Self {
 19        let limbs: usize = (log_q + log_base2k - 1) / log_base2k;
 20        let mut value: Vec<VecZnx> = Vec::new();
 21        (0..degree + 1).for_each(|_| value.push(module.new_vec_znx(limbs)));
 22        Self {
 23            value,
 24            log_q,
 25            log_base2k,
 26            log_scale: log_scale,
 27        }
 28    }
 29
 30    pub fn bytes_of(module: &Module, log_base2k: usize, log_q: usize, degree: usize) -> usize {
 31        let cols = (log_q + log_base2k - 1) / log_base2k;
 32        module.n() * cols * (degree + 1) * 8
 33    }
 34
 35    pub fn from_bytes(
 36        module: &Module,
 37        log_base2k: usize,
 38        log_q: usize,
 39        degree: usize,
 40        bytes: &mut [u8],
 41    ) -> Self {
 42        let n: usize = module.n();
 43        assert!(bytes.len() >= Self::bytes_of(module, log_base2k, log_q, degree));
 44        let mut value: Vec<VecZnx> = Vec::new();
 45        let limbs: usize = (log_q + log_base2k - 1) / log_base2k;
 46        let size = VecZnx::bytes(n, limbs);
 47        let mut ptr: usize = 0;
 48        (0..degree + 1).for_each(|_| {
 49            value.push(VecZnx::from_bytes(n, limbs, &mut bytes[ptr..]));
 50            ptr += size
 51        });
 52        Self {
 53            value,
 54            log_q,
 55            log_base2k,
 56            log_scale: 0,
 57        }
 58    }
 59
 60    pub fn n(&self) -> usize {
 61        self.value[0].n()
 62    }
 63
 64    pub fn degree(&self) -> usize {
 65        self.value.len()
 66    }
 67
 68    pub fn limbs(&self) -> usize {
 69        self.value[0].limbs()
 70    }
 71
 72    pub fn log_base2k(&self) -> usize {
 73        self.log_base2k
 74    }
 75
 76    pub fn log_scale(&self) -> usize {
 77        self.log_scale
 78    }
 79
 80    pub fn log_q(&self) -> usize {
 81        self.log_q
 82    }
 83
 84    pub fn at(&self, i: usize) -> &VecZnx {
 85        assert!(i <= self.degree());
 86        &self.value[i]
 87    }
 88
 89    pub fn at_mut(&mut self, i: usize) -> &mut VecZnx {
 90        assert!(i <= self.degree());
 91        &mut self.value[i]
 92    }
 93
 94    pub fn zero(&mut self) {
 95        self.value.iter_mut().for_each(|i| i.zero());
 96    }
 97}
 98
 99impl Parameters {
100    pub fn bytes_of_elem(&self, log_q: usize, degree: usize) -> usize {
101        Elem::bytes_of(self.module(), self.log_base2k(), log_q, degree)
102    }
103
104    pub fn elem_from_bytes(&self, log_q: usize, degree: usize, bytes: &mut [u8]) -> Elem {
105        Elem::from_bytes(self.module(), self.log_base2k(), log_q, degree, bytes)
106    }
107}