arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-core/src/layouts/glwe_tensor.rs
poulpy-core/src/layouts/glwe_tensor.rsRaw
  1use poulpy_hal::{
  2    layouts::{Data, DataMut, DataRef, FillUniform, VecZnx, VecZnxToMut, VecZnxToRef, ZnxInfos},
  3    source::Source,
  4};
  5
  6use crate::layouts::{Base2K, Degree, GLWE, GLWEInfos, GLWEToMut, GLWEToRef, LWEInfos, Rank, SetGLWEInfos, TorusPrecision};
  7use std::fmt;
  8
  9#[derive(PartialEq, Eq, Clone)]
 10pub struct GLWETensor<D: Data> {
 11    pub(crate) data: VecZnx<D>,
 12    pub(crate) base2k: Base2K,
 13    pub(crate) rank: Rank,
 14    pub(crate) k: TorusPrecision,
 15}
 16
 17impl<D: DataMut> SetGLWEInfos for GLWETensor<D> {
 18    fn set_base2k(&mut self, base2k: Base2K) {
 19        self.base2k = base2k
 20    }
 21
 22    fn set_k(&mut self, k: TorusPrecision) {
 23        self.k = k
 24    }
 25}
 26
 27impl<D: DataRef> GLWETensor<D> {
 28    pub fn data(&self) -> &VecZnx<D> {
 29        &self.data
 30    }
 31}
 32
 33impl<D: DataMut> GLWETensor<D> {
 34    pub fn data_mut(&mut self) -> &mut VecZnx<D> {
 35        &mut self.data
 36    }
 37}
 38
 39impl<D: Data> LWEInfos for GLWETensor<D> {
 40    fn base2k(&self) -> Base2K {
 41        self.base2k
 42    }
 43
 44    fn k(&self) -> TorusPrecision {
 45        self.k
 46    }
 47
 48    fn n(&self) -> Degree {
 49        Degree(self.data.n() as u32)
 50    }
 51
 52    fn size(&self) -> usize {
 53        self.data.size()
 54    }
 55}
 56
 57impl<D: Data> GLWEInfos for GLWETensor<D> {
 58    ///NOTE: self.rank() != self.to_ref().rank() if self is of type [GLWETensor]
 59    fn rank(&self) -> Rank {
 60        self.rank
 61    }
 62}
 63
 64impl<D: DataRef> fmt::Debug for GLWETensor<D> {
 65    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 66        write!(f, "{self}")
 67    }
 68}
 69
 70impl<D: DataRef> fmt::Display for GLWETensor<D> {
 71    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 72        write!(f, "GLWETensor: base2k={} k={}: {}", self.base2k().0, self.k().0, self.data)
 73    }
 74}
 75
 76impl<D: DataMut> FillUniform for GLWETensor<D> {
 77    fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
 78        self.data.fill_uniform(log_bound, source);
 79    }
 80}
 81
 82impl GLWETensor<Vec<u8>> {
 83    pub fn alloc_from_infos<A>(infos: &A) -> Self
 84    where
 85        A: GLWEInfos,
 86    {
 87        Self::alloc(infos.n(), infos.base2k(), infos.k(), infos.rank())
 88    }
 89
 90    pub fn alloc(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank) -> Self {
 91        let cols: usize = rank.as_usize() + 1;
 92        let pairs: usize = (((cols + 1) * cols) >> 1).max(1);
 93        GLWETensor {
 94            data: VecZnx::alloc(n.into(), pairs, k.0.div_ceil(base2k.0) as usize),
 95            base2k,
 96            k,
 97            rank,
 98        }
 99    }
100
101    pub fn bytes_of_from_infos<A>(infos: &A) -> usize
102    where
103        A: GLWEInfos,
104    {
105        Self::bytes_of(infos.n(), infos.base2k(), infos.k(), infos.rank())
106    }
107
108    pub fn bytes_of(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank) -> usize {
109        let cols: usize = rank.as_usize() + 1;
110        let pairs: usize = (((cols + 1) * cols) >> 1).max(1);
111        VecZnx::bytes_of(n.into(), pairs, k.0.div_ceil(base2k.0) as usize)
112    }
113}
114
115impl<D: DataRef> GLWEToRef for GLWETensor<D> {
116    fn to_ref(&self) -> GLWE<&[u8]> {
117        GLWE {
118            k: self.k,
119            base2k: self.base2k,
120            data: self.data.to_ref(),
121        }
122    }
123}
124
125impl<D: DataMut> GLWEToMut for GLWETensor<D> {
126    fn to_mut(&mut self) -> GLWE<&mut [u8]> {
127        GLWE {
128            k: self.k,
129            base2k: self.base2k,
130            data: self.data.to_mut(),
131        }
132    }
133}