poulpy_core/layouts/
gglwe_ksk.rs1use poulpy_hal::{
2 layouts::{Data, DataMut, DataRef, FillUniform, MatZnx, ReaderFrom, Reset, WriterTo},
3 source::Source,
4};
5
6use crate::layouts::{GGLWECiphertext, GLWECiphertext, Infos};
7use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
8
9use std::fmt;
10
11#[derive(PartialEq, Eq, Clone)]
12pub struct GGLWESwitchingKey<D: Data> {
13 pub(crate) key: GGLWECiphertext<D>,
14 pub(crate) sk_in_n: usize, pub(crate) sk_out_n: usize, }
17
18impl<D: DataRef> fmt::Debug for GGLWESwitchingKey<D> {
19 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
20 write!(f, "{}", self)
21 }
22}
23
24impl<D: DataRef> fmt::Display for GGLWESwitchingKey<D> {
25 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26 write!(
27 f,
28 "(GLWESwitchingKey: sk_in_n={} sk_out_n={}) {}",
29 self.sk_in_n, self.sk_out_n, self.key.data
30 )
31 }
32}
33
34impl<D: DataMut> FillUniform for GGLWESwitchingKey<D> {
35 fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
36 self.key.fill_uniform(log_bound, source);
37 }
38}
39
40impl<D: DataMut> Reset for GGLWESwitchingKey<D>
41where
42 MatZnx<D>: Reset,
43{
44 fn reset(&mut self) {
45 self.key.reset();
46 self.sk_in_n = 0;
47 self.sk_out_n = 0;
48 }
49}
50
51impl GGLWESwitchingKey<Vec<u8>> {
52 pub fn alloc(n: usize, basek: usize, k: usize, rows: usize, digits: usize, rank_in: usize, rank_out: usize) -> Self {
53 GGLWESwitchingKey {
54 key: GGLWECiphertext::alloc(n, basek, k, rows, digits, rank_in, rank_out),
55 sk_in_n: 0,
56 sk_out_n: 0,
57 }
58 }
59
60 pub fn bytes_of(n: usize, basek: usize, k: usize, rows: usize, digits: usize, rank_in: usize, rank_out: usize) -> usize {
61 GGLWECiphertext::<Vec<u8>>::bytes_of(n, basek, k, rows, digits, rank_in, rank_out)
62 }
63}
64
65impl<D: Data> Infos for GGLWESwitchingKey<D> {
66 type Inner = MatZnx<D>;
67
68 fn inner(&self) -> &Self::Inner {
69 self.key.inner()
70 }
71
72 fn basek(&self) -> usize {
73 self.key.basek()
74 }
75
76 fn k(&self) -> usize {
77 self.key.k()
78 }
79}
80
81impl<D: Data> GGLWESwitchingKey<D> {
82 pub fn rank(&self) -> usize {
83 self.key.data.cols_out() - 1
84 }
85
86 pub fn rank_in(&self) -> usize {
87 self.key.data.cols_in()
88 }
89
90 pub fn rank_out(&self) -> usize {
91 self.key.data.cols_out() - 1
92 }
93
94 pub fn digits(&self) -> usize {
95 self.key.digits()
96 }
97
98 pub fn sk_degree_in(&self) -> usize {
99 self.sk_in_n
100 }
101
102 pub fn sk_degree_out(&self) -> usize {
103 self.sk_out_n
104 }
105}
106
107impl<D: DataRef> GGLWESwitchingKey<D> {
108 pub fn at(&self, row: usize, col: usize) -> GLWECiphertext<&[u8]> {
109 self.key.at(row, col)
110 }
111}
112
113impl<D: DataMut> GGLWESwitchingKey<D> {
114 pub fn at_mut(&mut self, row: usize, col: usize) -> GLWECiphertext<&mut [u8]> {
115 self.key.at_mut(row, col)
116 }
117}
118
119impl<D: DataMut> ReaderFrom for GGLWESwitchingKey<D> {
120 fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
121 self.sk_in_n = reader.read_u64::<LittleEndian>()? as usize;
122 self.sk_out_n = reader.read_u64::<LittleEndian>()? as usize;
123 self.key.read_from(reader)
124 }
125}
126
127impl<D: DataRef> WriterTo for GGLWESwitchingKey<D> {
128 fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
129 writer.write_u64::<LittleEndian>(self.sk_in_n as u64)?;
130 writer.write_u64::<LittleEndian>(self.sk_out_n as u64)?;
131 self.key.write_to(writer)
132 }
133}