poulpy_core/layouts/
glwe_ct.rs

1use poulpy_hal::{
2    api::{FillUniform, Reset},
3    layouts::{Data, DataMut, DataRef, ReaderFrom, ToOwnedDeep, VecZnx, VecZnxToMut, VecZnxToRef, WriterTo},
4    source::Source,
5};
6
7use crate::layouts::{Infos, SetMetaData};
8use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
9use std::fmt;
10
11#[derive(PartialEq, Eq, Clone)]
12pub struct GLWECiphertext<D: Data> {
13    pub data: VecZnx<D>,
14    pub basek: usize,
15    pub k: usize,
16}
17
18impl<D: DataRef> ToOwnedDeep for GLWECiphertext<D> {
19    type Owned = GLWECiphertext<Vec<u8>>;
20    fn to_owned_deep(&self) -> Self::Owned {
21        GLWECiphertext {
22            data: self.data.to_owned_deep(),
23            basek: self.basek,
24            k: self.k,
25        }
26    }
27}
28
29impl<D: DataRef> fmt::Debug for GLWECiphertext<D> {
30    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
31        write!(f, "{}", self)
32    }
33}
34
35impl<D: DataRef> fmt::Display for GLWECiphertext<D> {
36    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37        write!(
38            f,
39            "GLWECiphertext: basek={} k={}: {}",
40            self.basek(),
41            self.k(),
42            self.data
43        )
44    }
45}
46
47impl<D: DataMut> Reset for GLWECiphertext<D>
48where
49    VecZnx<D>: Reset,
50{
51    fn reset(&mut self) {
52        self.data.reset();
53        self.basek = 0;
54        self.k = 0;
55    }
56}
57
58impl<D: DataMut> FillUniform for GLWECiphertext<D> {
59    fn fill_uniform(&mut self, source: &mut Source) {
60        self.data.fill_uniform(source);
61    }
62}
63
64impl GLWECiphertext<Vec<u8>> {
65    pub fn alloc(n: usize, basek: usize, k: usize, rank: usize) -> Self {
66        Self {
67            data: VecZnx::alloc(n, rank + 1, k.div_ceil(basek)),
68            basek,
69            k,
70        }
71    }
72
73    pub fn bytes_of(n: usize, basek: usize, k: usize, rank: usize) -> usize {
74        VecZnx::alloc_bytes(n, rank + 1, k.div_ceil(basek))
75    }
76}
77
78impl<D: Data> Infos for GLWECiphertext<D> {
79    type Inner = VecZnx<D>;
80
81    fn inner(&self) -> &Self::Inner {
82        &self.data
83    }
84
85    fn basek(&self) -> usize {
86        self.basek
87    }
88
89    fn k(&self) -> usize {
90        self.k
91    }
92}
93
94impl<D: Data> GLWECiphertext<D> {
95    pub fn rank(&self) -> usize {
96        self.cols() - 1
97    }
98}
99
100impl<D: DataMut> SetMetaData for GLWECiphertext<D> {
101    fn set_k(&mut self, k: usize) {
102        self.k = k
103    }
104
105    fn set_basek(&mut self, basek: usize) {
106        self.basek = basek
107    }
108}
109
110pub trait GLWECiphertextToRef: Infos {
111    fn to_ref(&self) -> GLWECiphertext<&[u8]>;
112}
113
114impl<D: DataRef> GLWECiphertextToRef for GLWECiphertext<D> {
115    fn to_ref(&self) -> GLWECiphertext<&[u8]> {
116        GLWECiphertext {
117            data: self.data.to_ref(),
118            basek: self.basek,
119            k: self.k,
120        }
121    }
122}
123
124pub trait GLWECiphertextToMut: Infos {
125    fn to_mut(&mut self) -> GLWECiphertext<&mut [u8]>;
126}
127
128impl<D: DataMut> GLWECiphertextToMut for GLWECiphertext<D> {
129    fn to_mut(&mut self) -> GLWECiphertext<&mut [u8]> {
130        GLWECiphertext {
131            data: self.data.to_mut(),
132            basek: self.basek,
133            k: self.k,
134        }
135    }
136}
137
138impl<D: DataMut> ReaderFrom for GLWECiphertext<D> {
139    fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
140        self.k = reader.read_u64::<LittleEndian>()? as usize;
141        self.basek = reader.read_u64::<LittleEndian>()? as usize;
142        self.data.read_from(reader)
143    }
144}
145
146impl<D: DataRef> WriterTo for GLWECiphertext<D> {
147    fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
148        writer.write_u64::<LittleEndian>(self.k as u64)?;
149        writer.write_u64::<LittleEndian>(self.basek as u64)?;
150        self.data.write_to(writer)
151    }
152}