arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-core/src/layouts/glwe_pt.rs
poulpy-core/src/layouts/glwe_pt.rsRaw
  1use std::fmt;
  2
  3use poulpy_hal::layouts::{Backend, Data, DataMut, DataRef, Module, VecZnx, VecZnxToMut, VecZnxToRef, ZnxInfos};
  4
  5use crate::layouts::{
  6    Base2K, GLWE, GLWEInfos, GLWEToMut, GLWEToRef, GetRingDegree, LWEInfos, Rank, RingDegree, SetGLWEInfos, TorusPrecision,
  7};
  8
  9#[derive(PartialEq, Eq, Copy, Clone, Debug)]
 10pub struct GLWEPlaintextLayout {
 11    pub n: RingDegree,
 12    pub base2k: Base2K,
 13    pub k: TorusPrecision,
 14}
 15
 16impl LWEInfos for GLWEPlaintextLayout {
 17    fn base2k(&self) -> Base2K {
 18        self.base2k
 19    }
 20
 21    fn k(&self) -> TorusPrecision {
 22        self.k
 23    }
 24
 25    fn n(&self) -> RingDegree {
 26        self.n
 27    }
 28}
 29
 30impl GLWEInfos for GLWEPlaintextLayout {
 31    fn rank(&self) -> Rank {
 32        Rank(0)
 33    }
 34}
 35
 36pub struct GLWEPlaintext<D: Data> {
 37    pub data: VecZnx<D>,
 38    pub base2k: Base2K,
 39    pub k: TorusPrecision,
 40}
 41
 42impl<D: DataMut> SetGLWEInfos for GLWEPlaintext<D> {
 43    fn set_base2k(&mut self, base2k: Base2K) {
 44        self.base2k = base2k
 45    }
 46
 47    fn set_k(&mut self, k: TorusPrecision) {
 48        self.k = k
 49    }
 50}
 51
 52impl<D: Data> LWEInfos for GLWEPlaintext<D> {
 53    fn base2k(&self) -> Base2K {
 54        self.base2k
 55    }
 56
 57    fn k(&self) -> TorusPrecision {
 58        self.k
 59    }
 60
 61    fn size(&self) -> usize {
 62        self.data.size()
 63    }
 64
 65    fn n(&self) -> RingDegree {
 66        RingDegree(self.data.n() as u32)
 67    }
 68}
 69
 70impl<D: Data> GLWEInfos for GLWEPlaintext<D> {
 71    fn rank(&self) -> Rank {
 72        Rank(self.data.cols() as u32 - 1)
 73    }
 74}
 75
 76impl<D: DataRef> fmt::Display for GLWEPlaintext<D> {
 77    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 78        write!(
 79            f,
 80            "GLWEPlaintext: base2k={} k={}: {}",
 81            self.base2k().0,
 82            self.k().0,
 83            self.data
 84        )
 85    }
 86}
 87
 88pub trait GLWEPlaintextAlloc
 89where
 90    Self: GetRingDegree,
 91{
 92    fn alloc_glwe_plaintext(&self, base2k: Base2K, k: TorusPrecision) -> GLWEPlaintext<Vec<u8>> {
 93        GLWEPlaintext {
 94            data: VecZnx::alloc(
 95                self.ring_degree().into(),
 96                1,
 97                k.0.div_ceil(base2k.0) as usize,
 98            ),
 99            base2k,
100            k,
101        }
102    }
103
104    fn alloc_glwe_plaintext_from_infos<A>(&self, infos: &A) -> GLWEPlaintext<Vec<u8>>
105    where
106        A: GLWEInfos,
107    {
108        self.alloc_glwe_plaintext(infos.base2k(), infos.k())
109    }
110
111    fn bytes_of_glwe_plaintext(&self, base2k: Base2K, k: TorusPrecision) -> usize {
112        VecZnx::bytes_of(
113            self.ring_degree().into(),
114            1,
115            k.0.div_ceil(base2k.0) as usize,
116        )
117    }
118
119    fn bytes_of_glwe_plaintext_from_infos<A>(&self, infos: &A) -> usize
120    where
121        A: GLWEInfos,
122    {
123        self.bytes_of_glwe_plaintext(infos.base2k(), infos.k())
124    }
125}
126
127impl<B: Backend> GLWEPlaintextAlloc for Module<B> where Self: GetRingDegree {}
128
129impl GLWEPlaintext<Vec<u8>> {
130    pub fn alloc_from_infos<A, M>(module: &M, infos: &A) -> Self
131    where
132        A: GLWEInfos,
133        M: GLWEPlaintextAlloc,
134    {
135        module.alloc_glwe_plaintext_from_infos(infos)
136    }
137
138    pub fn alloc<M>(module: &M, base2k: Base2K, k: TorusPrecision) -> Self
139    where
140        M: GLWEPlaintextAlloc,
141    {
142        module.alloc_glwe_plaintext(base2k, k)
143    }
144
145    pub fn bytes_of_from_infos<A, M>(module: &M, infos: &A) -> usize
146    where
147        A: GLWEInfos,
148        M: GLWEPlaintextAlloc,
149    {
150        module.bytes_of_glwe_plaintext_from_infos(infos)
151    }
152
153    pub fn bytes_of<M>(module: &M, base2k: Base2K, k: TorusPrecision) -> usize
154    where
155        M: GLWEPlaintextAlloc,
156    {
157        module.bytes_of_glwe_plaintext(base2k, k)
158    }
159}
160
161impl<D: DataRef> GLWEToRef for GLWEPlaintext<D> {
162    fn to_ref(&self) -> GLWE<&[u8]> {
163        GLWE {
164            k: self.k,
165            base2k: self.base2k,
166            data: self.data.to_ref(),
167        }
168    }
169}
170
171impl<D: DataMut> GLWEToMut for GLWEPlaintext<D> {
172    fn to_mut(&mut self) -> GLWE<&mut [u8]> {
173        GLWE {
174            k: self.k,
175            base2k: self.base2k,
176            data: self.data.to_mut(),
177        }
178    }
179}
180
181pub trait GLWEPlaintextToRef {
182    fn to_ref(&self) -> GLWEPlaintext<&[u8]>;
183}
184
185impl<D: DataRef> GLWEPlaintextToRef for GLWEPlaintext<D> {
186    fn to_ref(&self) -> GLWEPlaintext<&[u8]> {
187        GLWEPlaintext {
188            data: self.data.to_ref(),
189            base2k: self.base2k,
190            k: self.k,
191        }
192    }
193}
194
195pub trait GLWEPlaintextToMut {
196    fn to_ref(&mut self) -> GLWEPlaintext<&mut [u8]>;
197}
198
199impl<D: DataMut> GLWEPlaintextToMut for GLWEPlaintext<D> {
200    fn to_ref(&mut self) -> GLWEPlaintext<&mut [u8]> {
201        GLWEPlaintext {
202            base2k: self.base2k,
203            k: self.k,
204            data: self.data.to_mut(),
205        }
206    }
207}