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