poulpy/poulpy-schemes/src/tfhe/blind_rotation/key_compressed.rs
poulpy-schemes/src/tfhe/blind_rotation/key_compressed.rsRaw
1use poulpy_backend::hal::{
2 api::{FillUniform, Reset},
3 layouts::{Data, DataMut, DataRef, ReaderFrom, WriterTo},
4 source::Source,
5};
6
7use std::{fmt, marker::PhantomData};
8
9use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
10use poulpy_core::{
11 Distribution,
12 layouts::{Infos, compressed::GGSWCiphertextCompressed},
13};
14
15use crate::tfhe::blind_rotation::BlindRotationAlgo;
16
17#[derive(Clone)]
18pub struct BlindRotationKeyCompressed<D: Data, BRT: BlindRotationAlgo> {
19 pub(crate) keys: Vec<GGSWCiphertextCompressed<D>>,
20 pub(crate) dist: Distribution,
21 pub(crate) _phantom: PhantomData<BRT>,
22}
23
24impl<D: DataRef, BRT: BlindRotationAlgo> fmt::Debug for BlindRotationKeyCompressed<D, BRT> {
25 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
26 write!(f, "{}", self)
27 }
28}
29
30impl<D: Data, BRT: BlindRotationAlgo> PartialEq for BlindRotationKeyCompressed<D, BRT> {
31 fn eq(&self, other: &Self) -> bool {
32 if self.keys.len() != other.keys.len() {
33 return false;
34 }
35 for (a, b) in self.keys.iter().zip(other.keys.iter()) {
36 if a != b {
37 return false;
38 }
39 }
40 self.dist == other.dist && self._phantom == other._phantom
41 }
42}
43
44impl<D: Data, BRT: BlindRotationAlgo> Eq for BlindRotationKeyCompressed<D, BRT> {}
45
46impl<D: DataRef, BRT: BlindRotationAlgo> fmt::Display for BlindRotationKeyCompressed<D, BRT> {
47 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48 for (i, key) in self.keys.iter().enumerate() {
49 write!(f, "key[{}]: {}", i, key)?;
50 }
51 writeln!(f, "{:?}", self.dist)
52 }
53}
54
55impl<D: DataMut, BRT: BlindRotationAlgo> Reset for BlindRotationKeyCompressed<D, BRT> {
56 fn reset(&mut self) {
57 self.keys.iter_mut().for_each(|key| key.reset());
58 self.dist = Distribution::NONE;
59 }
60}
61
62impl<D: DataMut, BRT: BlindRotationAlgo> FillUniform for BlindRotationKeyCompressed<D, BRT> {
63 fn fill_uniform(&mut self, source: &mut Source) {
64 self.keys
65 .iter_mut()
66 .for_each(|key| key.fill_uniform(source));
67 }
68}
69
70impl<D: DataMut, BRT: BlindRotationAlgo> ReaderFrom for BlindRotationKeyCompressed<D, BRT> {
71 fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
72 match Distribution::read_from(reader) {
73 Ok(dist) => self.dist = dist,
74 Err(e) => return Err(e),
75 }
76 let len: usize = reader.read_u64::<LittleEndian>()? as usize;
77 if self.keys.len() != len {
78 return Err(std::io::Error::new(
79 std::io::ErrorKind::InvalidData,
80 format!("self.keys.len()={} != read len={}", self.keys.len(), len),
81 ));
82 }
83 for key in &mut self.keys {
84 key.read_from(reader)?;
85 }
86 Ok(())
87 }
88}
89
90impl<D: DataRef, BRT: BlindRotationAlgo> WriterTo for BlindRotationKeyCompressed<D, BRT> {
91 fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
92 match self.dist.write_to(writer) {
93 Ok(()) => {}
94 Err(e) => return Err(e),
95 }
96 writer.write_u64::<LittleEndian>(self.keys.len() as u64)?;
97 for key in &self.keys {
98 key.write_to(writer)?;
99 }
100 Ok(())
101 }
102}
103
104impl<D: DataRef, BRA: BlindRotationAlgo> BlindRotationKeyCompressed<D, BRA> {
105 #[allow(dead_code)]
106 pub(crate) fn n(&self) -> usize {
107 self.keys[0].n()
108 }
109
110 #[allow(dead_code)]
111 pub(crate) fn rows(&self) -> usize {
112 self.keys[0].rows()
113 }
114
115 #[allow(dead_code)]
116 pub(crate) fn k(&self) -> usize {
117 self.keys[0].k()
118 }
119
120 #[allow(dead_code)]
121 pub(crate) fn size(&self) -> usize {
122 self.keys[0].size()
123 }
124
125 #[allow(dead_code)]
126 pub(crate) fn rank(&self) -> usize {
127 self.keys[0].rank()
128 }
129
130 #[allow(dead_code)]
131 pub(crate) fn basek(&self) -> usize {
132 self.keys[0].basek()
133 }
134
135 #[allow(dead_code)]
136 pub(crate) fn block_size(&self) -> usize {
137 match self.dist {
138 Distribution::BinaryBlock(value) => value,
139 _ => 1,
140 }
141 }
142}