poulpy_core/layouts/
lwe_ct.rs

1use std::fmt;
2
3use poulpy_hal::{
4    layouts::{Data, DataMut, DataRef, FillUniform, ReaderFrom, Reset, WriterTo, Zn, ZnToMut, ZnToRef, ZnxInfos},
5    source::Source,
6};
7
8#[derive(PartialEq, Eq, Clone)]
9pub struct LWECiphertext<D: Data> {
10    pub(crate) data: Zn<D>,
11    pub(crate) k: usize,
12    pub(crate) basek: usize,
13}
14
15impl<D: DataRef> LWECiphertext<D> {
16    pub fn data(&self) -> &Zn<D> {
17        &self.data
18    }
19}
20
21impl<D: DataMut> LWECiphertext<D> {
22    pub fn data_mut(&mut self) -> &Zn<D> {
23        &mut self.data
24    }
25}
26
27impl<D: DataRef> fmt::Debug for LWECiphertext<D> {
28    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
29        write!(f, "{}", self)
30    }
31}
32
33impl<D: DataRef> fmt::Display for LWECiphertext<D> {
34    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35        write!(
36            f,
37            "LWECiphertext: basek={} k={}: {}",
38            self.basek(),
39            self.k(),
40            self.data
41        )
42    }
43}
44
45impl<D: DataMut> Reset for LWECiphertext<D> {
46    fn reset(&mut self) {
47        self.data.reset();
48        self.basek = 0;
49        self.k = 0;
50    }
51}
52
53impl<D: DataMut> FillUniform for LWECiphertext<D>
54where
55    Zn<D>: FillUniform,
56{
57    fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
58        self.data.fill_uniform(log_bound, source);
59    }
60}
61
62impl LWECiphertext<Vec<u8>> {
63    pub fn alloc(n: usize, basek: usize, k: usize) -> Self {
64        Self {
65            data: Zn::alloc(n + 1, 1, k.div_ceil(basek)),
66            k,
67            basek,
68        }
69    }
70}
71
72impl<D: Data> Infos for LWECiphertext<D>
73where
74    Zn<D>: ZnxInfos,
75{
76    type Inner = Zn<D>;
77
78    fn n(&self) -> usize {
79        &self.inner().n() - 1
80    }
81
82    fn inner(&self) -> &Self::Inner {
83        &self.data
84    }
85
86    fn basek(&self) -> usize {
87        self.basek
88    }
89
90    fn k(&self) -> usize {
91        self.k
92    }
93}
94
95impl<DataSelf: DataMut> SetMetaData for LWECiphertext<DataSelf> {
96    fn set_k(&mut self, k: usize) {
97        self.k = k
98    }
99
100    fn set_basek(&mut self, basek: usize) {
101        self.basek = basek
102    }
103}
104
105pub trait LWECiphertextToRef {
106    fn to_ref(&self) -> LWECiphertext<&[u8]>;
107}
108
109impl<D: DataRef> LWECiphertextToRef for LWECiphertext<D> {
110    fn to_ref(&self) -> LWECiphertext<&[u8]> {
111        LWECiphertext {
112            data: self.data.to_ref(),
113            basek: self.basek,
114            k: self.k,
115        }
116    }
117}
118
119pub trait LWECiphertextToMut {
120    #[allow(dead_code)]
121    fn to_mut(&mut self) -> LWECiphertext<&mut [u8]>;
122}
123
124impl<D: DataMut> LWECiphertextToMut for LWECiphertext<D> {
125    fn to_mut(&mut self) -> LWECiphertext<&mut [u8]> {
126        LWECiphertext {
127            data: self.data.to_mut(),
128            basek: self.basek,
129            k: self.k,
130        }
131    }
132}
133
134use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
135
136use crate::layouts::{Infos, SetMetaData};
137
138impl<D: DataMut> ReaderFrom for LWECiphertext<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 LWECiphertext<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}