poulpy/core/src/layouts/glwe_ct.rs
core/src/layouts/glwe_ct.rsRaw
1use backend::hal::{
2 api::{FillUniform, Reset},
3 layouts::{Data, DataMut, DataRef, ReaderFrom, VecZnx, VecZnxToMut, VecZnxToRef, WriterTo},
4};
5use sampling::source::Source;
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> fmt::Debug for GLWECiphertext<D> {
19 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
20 write!(f, "{}", self)
21 }
22}
23
24impl<D: DataRef> fmt::Display for GLWECiphertext<D> {
25 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26 write!(
27 f,
28 "GLWECiphertext: basek={} k={}: {}",
29 self.basek(),
30 self.k(),
31 self.data
32 )
33 }
34}
35
36impl<D: DataMut> Reset for GLWECiphertext<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 GLWECiphertext<D> {
48 fn fill_uniform(&mut self, source: &mut Source) {
49 self.data.fill_uniform(source);
50 }
51}
52
53impl GLWECiphertext<Vec<u8>> {
54 pub fn alloc(n: usize, basek: usize, k: usize, rank: usize) -> Self {
55 Self {
56 data: VecZnx::alloc(n, rank + 1, k.div_ceil(basek)),
57 basek,
58 k,
59 }
60 }
61
62 pub fn bytes_of(n: usize, basek: usize, k: usize, rank: usize) -> usize {
63 VecZnx::alloc_bytes(n, rank + 1, k.div_ceil(basek))
64 }
65}
66
67impl<D: Data> Infos for GLWECiphertext<D> {
68 type Inner = VecZnx<D>;
69
70 fn inner(&self) -> &Self::Inner {
71 &self.data
72 }
73
74 fn basek(&self) -> usize {
75 self.basek
76 }
77
78 fn k(&self) -> usize {
79 self.k
80 }
81}
82
83impl<D: Data> GLWECiphertext<D> {
84 pub fn rank(&self) -> usize {
85 self.cols() - 1
86 }
87}
88
89impl<D: DataRef> GLWECiphertext<D> {
90 pub fn clone(&self) -> GLWECiphertext<Vec<u8>> {
91 GLWECiphertext {
92 data: self.data.clone(),
93 basek: self.basek(),
94 k: self.k(),
95 }
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}