poulpy_core/layouts/prepared/
glwe_switching_key.rs

1use 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,  // Degree of sk_in
13    pub(crate) output_degree: Degree, // Degree of sk_out
14}
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}