poulpy/poulpy-core/src/layouts/glwe_to_lwe_ksk.rs
poulpy-core/src/layouts/glwe_to_lwe_ksk.rsRaw
1use poulpy_hal::{
2 layouts::{Data, DataMut, DataRef, FillUniform, ReaderFrom, WriterTo},
3 source::Source,
4};
5
6use crate::layouts::{
7 Base2K, Degree, Digits, GGLWELayoutInfos, GGLWESwitchingKey, GLWEInfos, LWEInfos, Rank, Rows, TorusPrecision,
8};
9
10use std::fmt;
11
12#[derive(PartialEq, Eq, Copy, Clone, Debug)]
13pub struct GLWEToLWESwitchingKeyLayout {
14 pub n: Degree,
15 pub base2k: Base2K,
16 pub k: TorusPrecision,
17 pub rows: Rows,
18 pub rank_in: Rank,
19}
20
21impl LWEInfos for GLWEToLWESwitchingKeyLayout {
22 fn n(&self) -> Degree {
23 self.n
24 }
25
26 fn base2k(&self) -> Base2K {
27 self.base2k
28 }
29
30 fn k(&self) -> TorusPrecision {
31 self.k
32 }
33}
34
35impl GLWEInfos for GLWEToLWESwitchingKeyLayout {
36 fn rank(&self) -> Rank {
37 self.rank_out()
38 }
39}
40
41impl GGLWELayoutInfos for GLWEToLWESwitchingKeyLayout {
42 fn rank_in(&self) -> Rank {
43 self.rank_in
44 }
45
46 fn digits(&self) -> Digits {
47 Digits(1)
48 }
49
50 fn rank_out(&self) -> Rank {
51 Rank(1)
52 }
53
54 fn rows(&self) -> Rows {
55 self.rows
56 }
57}
58
59/// A special [GLWESwitchingKey] required to for the conversion from [GLWECiphertext] to [LWECiphertext].
60#[derive(PartialEq, Eq, Clone)]
61pub struct GLWEToLWESwitchingKey<D: Data>(pub(crate) GGLWESwitchingKey<D>);
62
63impl<D: Data> LWEInfos for GLWEToLWESwitchingKey<D> {
64 fn base2k(&self) -> Base2K {
65 self.0.base2k()
66 }
67
68 fn k(&self) -> TorusPrecision {
69 self.0.k()
70 }
71
72 fn n(&self) -> Degree {
73 self.0.n()
74 }
75
76 fn size(&self) -> usize {
77 self.0.size()
78 }
79}
80
81impl<D: Data> GLWEInfos for GLWEToLWESwitchingKey<D> {
82 fn rank(&self) -> Rank {
83 self.rank_out()
84 }
85}
86impl<D: Data> GGLWELayoutInfos for GLWEToLWESwitchingKey<D> {
87 fn rank_in(&self) -> Rank {
88 self.0.rank_in()
89 }
90
91 fn digits(&self) -> Digits {
92 self.0.digits()
93 }
94
95 fn rank_out(&self) -> Rank {
96 self.0.rank_out()
97 }
98
99 fn rows(&self) -> Rows {
100 self.0.rows()
101 }
102}
103
104impl<D: DataRef> fmt::Debug for GLWEToLWESwitchingKey<D> {
105 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
106 write!(f, "{self}")
107 }
108}
109
110impl<D: DataMut> FillUniform for GLWEToLWESwitchingKey<D> {
111 fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
112 self.0.fill_uniform(log_bound, source);
113 }
114}
115
116impl<D: DataRef> fmt::Display for GLWEToLWESwitchingKey<D> {
117 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118 write!(f, "(GLWEToLWESwitchingKey) {}", self.0)
119 }
120}
121
122impl<D: DataMut> ReaderFrom for GLWEToLWESwitchingKey<D> {
123 fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
124 self.0.read_from(reader)
125 }
126}
127
128impl<D: DataRef> WriterTo for GLWEToLWESwitchingKey<D> {
129 fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
130 self.0.write_to(writer)
131 }
132}
133
134impl GLWEToLWESwitchingKey<Vec<u8>> {
135 pub fn alloc<A>(infos: &A) -> Self
136 where
137 A: GGLWELayoutInfos,
138 {
139 debug_assert_eq!(
140 infos.rank_out().0,
141 1,
142 "rank_out > 1 is not supported for GLWEToLWESwitchingKey"
143 );
144 debug_assert_eq!(
145 infos.digits().0,
146 1,
147 "digits > 1 is not supported for GLWEToLWESwitchingKey"
148 );
149 Self(GGLWESwitchingKey::alloc(infos))
150 }
151
152 pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rows: Rows, rank_in: Rank) -> Self {
153 Self(GGLWESwitchingKey::alloc_with(
154 n,
155 base2k,
156 k,
157 rows,
158 Digits(1),
159 rank_in,
160 Rank(1),
161 ))
162 }
163
164 pub fn alloc_bytes<A>(infos: &A) -> usize
165 where
166 A: GGLWELayoutInfos,
167 {
168 debug_assert_eq!(
169 infos.rank_out().0,
170 1,
171 "rank_out > 1 is not supported for GLWEToLWESwitchingKey"
172 );
173 debug_assert_eq!(
174 infos.digits().0,
175 1,
176 "digits > 1 is not supported for GLWEToLWESwitchingKey"
177 );
178 GGLWESwitchingKey::alloc_bytes(infos)
179 }
180
181 pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, rows: Rows, rank_in: Rank) -> usize {
182 GGLWESwitchingKey::alloc_bytes_with(n, base2k, k, rows, Digits(1), rank_in, Rank(1))
183 }
184}