1use poulpy_hal::layouts::{Backend, DataMut, Module, Scratch};
2
3use crate::{
4 ScratchTakeCore,
5 keyswitching::GLWEKeyswitch,
6 layouts::{GGLWE, GGLWEInfos, GGLWEPreparedToRef, GGLWEToMut, GGLWEToRef, GLWEAutomorphismKey, GLWESwitchingKey},
7};
8
9impl GLWEAutomorphismKey<Vec<u8>> {
10 pub fn keyswitch_tmp_bytes<R, A, K, M, BE: Backend>(module: &M, res_infos: &R, a_infos: &A, key_infos: &K) -> usize
11 where
12 R: GGLWEInfos,
13 A: GGLWEInfos,
14 K: GGLWEInfos,
15 M: GGLWEKeyswitch<BE>,
16 {
17 module.glwe_keyswitch_tmp_bytes(res_infos, a_infos, key_infos)
18 }
19}
20
21impl<DataSelf: DataMut> GLWEAutomorphismKey<DataSelf> {
22 pub fn keyswitch<A, B, M, BE: Backend>(&mut self, module: &M, a: &A, b: &B, scratch: &mut Scratch<BE>)
23 where
24 A: GGLWEToRef + GGLWEInfos,
25 B: GGLWEPreparedToRef<BE> + GGLWEInfos,
26 Scratch<BE>: ScratchTakeCore<BE>,
27 M: GGLWEKeyswitch<BE>,
28 {
29 module.gglwe_keyswitch(self, a, b, scratch);
30 }
31
32 pub fn keyswitch_inplace<A, M, BE: Backend>(&mut self, module: &M, a: &A, scratch: &mut Scratch<BE>)
33 where
34 A: GGLWEPreparedToRef<BE> + GGLWEInfos,
35 Scratch<BE>: ScratchTakeCore<BE>,
36 M: GGLWEKeyswitch<BE>,
37 {
38 module.gglwe_keyswitch_inplace(self, a, scratch);
39 }
40}
41
42impl GLWESwitchingKey<Vec<u8>> {
43 pub fn keyswitch_tmp_bytes<R, A, K, M, BE: Backend>(module: &M, res_infos: &R, a_infos: &A, key_infos: &K) -> usize
44 where
45 R: GGLWEInfos,
46 A: GGLWEInfos,
47 K: GGLWEInfos,
48 M: GGLWEKeyswitch<BE>,
49 {
50 module.glwe_keyswitch_tmp_bytes(res_infos, a_infos, key_infos)
51 }
52}
53
54impl<DataSelf: DataMut> GLWESwitchingKey<DataSelf> {
55 pub fn keyswitch<A, B, M, BE: Backend>(&mut self, module: &M, a: &A, b: &B, scratch: &mut Scratch<BE>)
56 where
57 A: GGLWEToRef + GGLWEInfos,
58 B: GGLWEPreparedToRef<BE> + GGLWEInfos,
59 Scratch<BE>: ScratchTakeCore<BE>,
60 M: GGLWEKeyswitch<BE>,
61 {
62 module.gglwe_keyswitch(self, a, b, scratch);
63 }
64
65 pub fn keyswitch_inplace<A, M, BE: Backend>(&mut self, module: &M, a: &A, scratch: &mut Scratch<BE>)
66 where
67 A: GGLWEPreparedToRef<BE> + GGLWEInfos,
68 Scratch<BE>: ScratchTakeCore<BE>,
69 M: GGLWEKeyswitch<BE>,
70 {
71 module.gglwe_keyswitch_inplace(self, a, scratch);
72 }
73}
74
75impl GGLWE<Vec<u8>> {
76 pub fn keyswitch_tmp_bytes<R, A, K, M, BE: Backend>(module: &M, res_infos: &R, a_infos: &A, key_infos: &K) -> usize
77 where
78 R: GGLWEInfos,
79 A: GGLWEInfos,
80 K: GGLWEInfos,
81 M: GGLWEKeyswitch<BE>,
82 {
83 module.glwe_keyswitch_tmp_bytes(res_infos, a_infos, key_infos)
84 }
85}
86
87impl<DataSelf: DataMut> GGLWE<DataSelf> {
88 pub fn keyswitch<A, B, M, BE: Backend>(&mut self, module: &M, a: &A, b: &B, scratch: &mut Scratch<BE>)
89 where
90 A: GGLWEToRef + GGLWEInfos,
91 B: GGLWEPreparedToRef<BE> + GGLWEInfos,
92 Scratch<BE>: ScratchTakeCore<BE>,
93 M: GGLWEKeyswitch<BE>,
94 {
95 module.gglwe_keyswitch(self, a, b, scratch);
96 }
97
98 pub fn keyswitch_inplace<A, M, BE: Backend>(&mut self, module: &M, a: &A, scratch: &mut Scratch<BE>)
99 where
100 A: GGLWEPreparedToRef<BE> + GGLWEInfos,
101 Scratch<BE>: ScratchTakeCore<BE>,
102 M: GGLWEKeyswitch<BE>,
103 {
104 module.gglwe_keyswitch_inplace(self, a, scratch);
105 }
106}
107
108impl<BE: Backend> GGLWEKeyswitch<BE> for Module<BE> where Self: GLWEKeyswitch<BE> {}
109
110pub trait GGLWEKeyswitch<BE: Backend>
111where
112 Self: GLWEKeyswitch<BE>,
113{
114 fn gglwe_keyswitch_tmp_bytes<R, A, K>(&self, res_infos: &R, a_infos: &A, key_infos: &K) -> usize
115 where
116 R: GGLWEInfos,
117 A: GGLWEInfos,
118 K: GGLWEInfos,
119 {
120 self.glwe_keyswitch_tmp_bytes(res_infos, a_infos, key_infos)
121 }
122
123 fn gglwe_keyswitch<R, A, B>(&self, res: &mut R, a: &A, b: &B, scratch: &mut Scratch<BE>)
124 where
125 R: GGLWEToMut + GGLWEInfos,
126 A: GGLWEToRef + GGLWEInfos,
127 B: GGLWEPreparedToRef<BE> + GGLWEInfos,
128 Scratch<BE>: ScratchTakeCore<BE>,
129 {
130 assert_eq!(
131 res.rank_in(),
132 a.rank_in(),
133 "res input rank: {} != a input rank: {}",
134 res.rank_in(),
135 a.rank_in()
136 );
137 assert_eq!(
138 a.rank_out(),
139 b.rank_in(),
140 "res output rank: {} != b input rank: {}",
141 a.rank_out(),
142 b.rank_in()
143 );
144 assert_eq!(
145 res.rank_out(),
146 b.rank_out(),
147 "res output rank: {} != b output rank: {}",
148 res.rank_out(),
149 b.rank_out()
150 );
151 assert!(
152 res.dnum() <= a.dnum(),
153 "res.dnum()={} > a.dnum()={}",
154 res.dnum(),
155 a.dnum()
156 );
157 assert_eq!(
158 res.dsize(),
159 a.dsize(),
160 "res dsize: {} != a dsize: {}",
161 res.dsize(),
162 a.dsize()
163 );
164 assert_eq!(res.base2k(), a.base2k());
165
166 let res: &mut GGLWE<&mut [u8]> = &mut res.to_mut();
167 let a: &GGLWE<&[u8]> = &a.to_ref();
168
169 for row in 0..res.dnum().into() {
170 for col in 0..res.rank_in().into() {
171 self.glwe_keyswitch(&mut res.at_mut(row, col), &a.at(row, col), b, scratch);
172 }
173 }
174 }
175
176 fn gglwe_keyswitch_inplace<R, A>(&self, res: &mut R, a: &A, scratch: &mut Scratch<BE>)
177 where
178 R: GGLWEToMut,
179 A: GGLWEPreparedToRef<BE> + GGLWEInfos,
180 Scratch<BE>: ScratchTakeCore<BE>,
181 {
182 let res: &mut GGLWE<&mut [u8]> = &mut res.to_mut();
183
184 assert_eq!(
185 res.rank_out(),
186 a.rank_out(),
187 "res output rank: {} != a output rank: {}",
188 res.rank_out(),
189 a.rank_out()
190 );
191
192 for row in 0..res.dnum().into() {
193 for col in 0..res.rank_in().into() {
194 self.glwe_keyswitch_inplace(&mut res.at_mut(row, col), a, scratch);
195 }
196 }
197 }
198}
199
200impl<DataSelf: DataMut> GLWESwitchingKey<DataSelf> {}