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