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