poulpy_core/layouts/prepared/
glwe_switching_key.rs1use poulpy_hal::layouts::{Backend, Data, DataMut, DataRef, Module, Scratch};
2
3use crate::layouts::{
4 Base2K, Degree, Dnum, Dsize, GGLWEInfos, GGLWEToRef, GLWEInfos, GLWESwitchingKeyDegrees, GLWESwitchingKeyDegreesMut,
5 LWEInfos, Rank, TorusPrecision,
6 prepared::{GGLWEPrepared, GGLWEPreparedFactory, GGLWEPreparedToMut, GGLWEPreparedToRef},
7};
8
9#[derive(PartialEq, Eq)]
10pub struct GLWESwitchingKeyPrepared<D: Data, B: Backend> {
11 pub(crate) key: GGLWEPrepared<D, B>,
12 pub(crate) input_degree: Degree, pub(crate) output_degree: Degree, }
15
16impl<D: DataRef, BE: Backend> GLWESwitchingKeyDegrees for GLWESwitchingKeyPrepared<D, BE> {
17 fn output_degree(&self) -> &Degree {
18 &self.output_degree
19 }
20
21 fn input_degree(&self) -> &Degree {
22 &self.input_degree
23 }
24}
25
26impl<D: DataMut, BE: Backend> GLWESwitchingKeyDegreesMut for GLWESwitchingKeyPrepared<D, BE> {
27 fn output_degree(&mut self) -> &mut Degree {
28 &mut self.output_degree
29 }
30
31 fn input_degree(&mut self) -> &mut Degree {
32 &mut self.input_degree
33 }
34}
35
36impl<D: Data, B: Backend> LWEInfos for GLWESwitchingKeyPrepared<D, B> {
37 fn n(&self) -> Degree {
38 self.key.n()
39 }
40
41 fn base2k(&self) -> Base2K {
42 self.key.base2k()
43 }
44
45 fn k(&self) -> TorusPrecision {
46 self.key.k()
47 }
48
49 fn size(&self) -> usize {
50 self.key.size()
51 }
52}
53
54impl<D: Data, B: Backend> GLWEInfos for GLWESwitchingKeyPrepared<D, B> {
55 fn rank(&self) -> Rank {
56 self.rank_out()
57 }
58}
59
60impl<D: Data, B: Backend> GGLWEInfos for GLWESwitchingKeyPrepared<D, B> {
61 fn rank_in(&self) -> Rank {
62 self.key.rank_in()
63 }
64
65 fn rank_out(&self) -> Rank {
66 self.key.rank_out()
67 }
68
69 fn dsize(&self) -> Dsize {
70 self.key.dsize()
71 }
72
73 fn dnum(&self) -> Dnum {
74 self.key.dnum()
75 }
76}
77
78pub trait GLWESwitchingKeyPreparedFactory<B: Backend>
79where
80 Self: GGLWEPreparedFactory<B>,
81{
82 fn alloc_glwe_switching_key_prepared(
83 &self,
84 base2k: Base2K,
85 k: TorusPrecision,
86 rank_in: Rank,
87 rank_out: Rank,
88 dnum: Dnum,
89 dsize: Dsize,
90 ) -> GLWESwitchingKeyPrepared<Vec<u8>, B> {
91 GLWESwitchingKeyPrepared::<Vec<u8>, B> {
92 key: self.alloc_gglwe_prepared(base2k, k, rank_in, rank_out, dnum, dsize),
93 input_degree: Degree(0),
94 output_degree: Degree(0),
95 }
96 }
97
98 fn alloc_glwe_switching_key_prepared_from_infos<A>(&self, infos: &A) -> GLWESwitchingKeyPrepared<Vec<u8>, B>
99 where
100 A: GGLWEInfos,
101 {
102 self.alloc_glwe_switching_key_prepared(
103 infos.base2k(),
104 infos.k(),
105 infos.rank_in(),
106 infos.rank_out(),
107 infos.dnum(),
108 infos.dsize(),
109 )
110 }
111
112 fn bytes_of_glwe_switching_key_prepared(
113 &self,
114 base2k: Base2K,
115 k: TorusPrecision,
116 rank_in: Rank,
117 rank_out: Rank,
118 dnum: Dnum,
119 dsize: Dsize,
120 ) -> usize {
121 self.bytes_of_gglwe_prepared(base2k, k, rank_in, rank_out, dnum, dsize)
122 }
123
124 fn bytes_of_glwe_switching_key_prepared_from_infos<A>(&self, infos: &A) -> usize
125 where
126 A: GGLWEInfos,
127 {
128 self.bytes_of_glwe_switching_key_prepared(
129 infos.base2k(),
130 infos.k(),
131 infos.rank_in(),
132 infos.rank_out(),
133 infos.dnum(),
134 infos.dsize(),
135 )
136 }
137
138 fn prepare_glwe_switching_key_tmp_bytes<A>(&self, infos: &A) -> usize
139 where
140 A: GGLWEInfos,
141 {
142 self.prepare_gglwe_tmp_bytes(infos)
143 }
144
145 fn prepare_glwe_switching<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
146 where
147 R: GGLWEPreparedToMut<B> + GLWESwitchingKeyDegreesMut,
148 O: GGLWEToRef + GLWESwitchingKeyDegrees,
149 {
150 self.prepare_gglwe(res, other, scratch);
151 *res.input_degree() = *other.input_degree();
152 *res.output_degree() = *other.output_degree();
153 }
154}
155
156impl<B: Backend> GLWESwitchingKeyPreparedFactory<B> for Module<B> where Self: GGLWEPreparedFactory<B> {}
157
158impl<B: Backend> GLWESwitchingKeyPrepared<Vec<u8>, B> {
159 pub fn alloc_from_infos<A, M>(module: &M, infos: &A) -> Self
160 where
161 A: GGLWEInfos,
162 M: GLWESwitchingKeyPreparedFactory<B>,
163 {
164 module.alloc_glwe_switching_key_prepared_from_infos(infos)
165 }
166
167 pub fn alloc<M>(
168 module: &M,
169 base2k: Base2K,
170 k: TorusPrecision,
171 rank_in: Rank,
172 rank_out: Rank,
173 dnum: Dnum,
174 dsize: Dsize,
175 ) -> Self
176 where
177 M: GLWESwitchingKeyPreparedFactory<B>,
178 {
179 module.alloc_glwe_switching_key_prepared(base2k, k, rank_in, rank_out, dnum, dsize)
180 }
181
182 pub fn bytes_of_from_infos<A, M>(module: &M, infos: &A) -> usize
183 where
184 A: GGLWEInfos,
185 M: GLWESwitchingKeyPreparedFactory<B>,
186 {
187 module.bytes_of_glwe_switching_key_prepared_from_infos(infos)
188 }
189
190 pub fn bytes_of<M>(
191 module: &M,
192 base2k: Base2K,
193 k: TorusPrecision,
194 rank_in: Rank,
195 rank_out: Rank,
196 dnum: Dnum,
197 dsize: Dsize,
198 ) -> usize
199 where
200 M: GLWESwitchingKeyPreparedFactory<B>,
201 {
202 module.bytes_of_glwe_switching_key_prepared(base2k, k, rank_in, rank_out, dnum, dsize)
203 }
204}
205
206impl<D: DataMut, B: Backend> GLWESwitchingKeyPrepared<D, B> {
207 pub fn prepare<O, M>(&mut self, module: &M, other: &O, scratch: &mut Scratch<B>)
208 where
209 O: GGLWEToRef + GLWESwitchingKeyDegrees,
210 M: GLWESwitchingKeyPreparedFactory<B>,
211 {
212 module.prepare_glwe_switching(self, other, scratch);
213 }
214}
215
216impl<B: Backend> GLWESwitchingKeyPrepared<Vec<u8>, B> {
217 pub fn prepare_tmp_bytes<M>(&self, module: &M) -> usize
218 where
219 M: GLWESwitchingKeyPreparedFactory<B>,
220 {
221 module.prepare_glwe_switching_key_tmp_bytes(self)
222 }
223}
224
225impl<D: DataRef, BE: Backend> GGLWEPreparedToRef<BE> for GLWESwitchingKeyPrepared<D, BE>
226where
227 GGLWEPrepared<D, BE>: GGLWEPreparedToRef<BE>,
228{
229 fn to_ref(&self) -> GGLWEPrepared<&[u8], BE> {
230 self.key.to_ref()
231 }
232}
233
234impl<D: DataRef, BE: Backend> GGLWEPreparedToMut<BE> for GLWESwitchingKeyPrepared<D, BE>
235where
236 GGLWEPrepared<D, BE>: GGLWEPreparedToMut<BE>,
237{
238 fn to_mut(&mut self) -> GGLWEPrepared<&mut [u8], BE> {
239 self.key.to_mut()
240 }
241}