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