poulpy_core/layouts/
lwe_ct.rs1use 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}