poulpy/base2k/src/vec_znx_big_ops.rs
base2k/src/vec_znx_big_ops.rsRaw
1use crate::ffi::vec_znx;
2use crate::{Backend, FFT64, Module, VecZnx, VecZnxBig, VecZnxOps, ZnxBase, ZnxInfos, ZnxLayout, assert_alignement};
3
4pub trait VecZnxBigOps<B: Backend> {
5 /// Allocates a vector Z[X]/(X^N+1) that stores not normalized values.
6 fn new_vec_znx_big(&self, cols: usize, size: usize) -> VecZnxBig<B>;
7
8 /// Returns a new [VecZnxBig] with the provided bytes array as backing array.
9 ///
10 /// Behavior: takes ownership of the backing array.
11 ///
12 /// # Arguments
13 ///
14 /// * `cols`: the number of polynomials..
15 /// * `size`: the number of polynomials per column.
16 /// * `bytes`: a byte array of size at least [Module::bytes_of_vec_znx_big].
17 ///
18 /// # Panics
19 /// If `bytes.len()` < [Module::bytes_of_vec_znx_big].
20 fn new_vec_znx_big_from_bytes(&self, cols: usize, size: usize, bytes: &mut [u8]) -> VecZnxBig<B>;
21
22 /// Returns a new [VecZnxBig] with the provided bytes array as backing array.
23 ///
24 /// Behavior: the backing array is only borrowed.
25 ///
26 /// # Arguments
27 ///
28 /// * `cols`: the number of polynomials..
29 /// * `size`: the number of polynomials per column.
30 /// * `bytes`: a byte array of size at least [Module::bytes_of_vec_znx_big].
31 ///
32 /// # Panics
33 /// If `bytes.len()` < [Module::bytes_of_vec_znx_big].
34 fn new_vec_znx_big_from_bytes_borrow(&self, cols: usize, size: usize, tmp_bytes: &mut [u8]) -> VecZnxBig<B>;
35
36 /// Returns the minimum number of bytes necessary to allocate
37 /// a new [VecZnxBig] through [VecZnxBig::from_bytes].
38 fn bytes_of_vec_znx_big(&self, cols: usize, size: usize) -> usize;
39
40 /// Adds `a` to `b` and stores the result on `c`.
41 fn vec_znx_big_add(
42 &self,
43 res: &mut VecZnxBig<B>,
44 col_res: usize,
45 a: &VecZnxBig<B>,
46 col_a: usize,
47 b: &VecZnxBig<B>,
48 col_b: usize,
49 );
50
51 /// Adds `a` to `b` and stores the result on `b`.
52 fn vec_znx_big_add_inplace(&self, res: &mut VecZnxBig<B>, col_res: usize, a: &VecZnxBig<B>, col_a: usize);
53
54 /// Adds `a` to `b` and stores the result on `c`.
55 fn vec_znx_big_add_small(
56 &self,
57 res: &mut VecZnxBig<B>,
58 col_res: usize,
59 a: &VecZnx,
60 col_a: usize,
61 b: &VecZnxBig<B>,
62 col_b: usize,
63 );
64
65 /// Adds `a` to `b` and stores the result on `b`.
66 fn vec_znx_big_add_small_inplace(&self, res: &mut VecZnxBig<B>, col_res: usize, a: &VecZnx, col_a: usize);
67
68 /// Subtracts `a` to `b` and stores the result on `c`.
69 fn vec_znx_big_sub(
70 &self,
71 res: &mut VecZnxBig<B>,
72 col_res: usize,
73 a: &VecZnxBig<B>,
74 col_a: usize,
75 b: &VecZnxBig<B>,
76 col_b: usize,
77 );
78
79 /// Subtracts `a` to `b` and stores the result on `b`.
80 fn vec_znx_big_sub_ab_inplace(&self, res: &mut VecZnxBig<B>, col_res: usize, a: &VecZnxBig<B>, col_a: usize);
81
82 /// Subtracts `b` to `a` and stores the result on `b`.
83 fn vec_znx_big_sub_ba_inplace(&self, res: &mut VecZnxBig<B>, col_res: usize, a: &VecZnxBig<B>, col_a: usize);
84
85 /// Subtracts `b` to `a` and stores the result on `c`.
86 fn vec_znx_big_sub_small_a(
87 &self,
88 res: &mut VecZnxBig<B>,
89 col_res: usize,
90 a: &VecZnx,
91 col_a: usize,
92 b: &VecZnxBig<B>,
93 col_b: usize,
94 );
95
96 /// Subtracts `a` to `b` and stores the result on `b`.
97 fn vec_znx_big_sub_small_a_inplace(&self, res: &mut VecZnxBig<B>, col_res: usize, a: &VecZnx, col_a: usize);
98
99 /// Subtracts `b` to `a` and stores the result on `c`.
100 fn vec_znx_big_sub_small_b(
101 &self,
102 res: &mut VecZnxBig<B>,
103 col_res: usize,
104 a: &VecZnxBig<B>,
105 col_a: usize,
106 b: &VecZnx,
107 col_b: usize,
108 );
109
110 /// Subtracts `b` to `a` and stores the result on `b`.
111 fn vec_znx_big_sub_small_b_inplace(&self, res: &mut VecZnxBig<B>, col_res: usize, a: &VecZnx, col_a: usize);
112
113 /// Returns the minimum number of bytes to apply [VecZnxBigOps::vec_znx_big_normalize].
114 fn vec_znx_big_normalize_tmp_bytes(&self) -> usize;
115
116 /// Normalizes `a` and stores the result on `b`.
117 ///
118 /// # Arguments
119 ///
120 /// * `log_base2k`: normalization basis.
121 /// * `tmp_bytes`: scratch space of size at least [VecZnxBigOps::vec_znx_big_normalize].
122 fn vec_znx_big_normalize(
123 &self,
124 log_base2k: usize,
125 res: &mut VecZnx,
126 col_res: usize,
127 a: &VecZnxBig<B>,
128 col_a: usize,
129 tmp_bytes: &mut [u8],
130 );
131
132 /// Applies the automorphism X^i -> X^ik on `a` and stores the result on `b`.
133 fn vec_znx_big_automorphism(&self, k: i64, res: &mut VecZnxBig<B>, col_res: usize, a: &VecZnxBig<B>, col_a: usize);
134
135 /// Applies the automorphism X^i -> X^ik on `a` and stores the result on `a`.
136 fn vec_znx_big_automorphism_inplace(&self, k: i64, a: &mut VecZnxBig<B>, col_a: usize);
137}
138
139impl VecZnxBigOps<FFT64> for Module<FFT64> {
140 fn new_vec_znx_big(&self, cols: usize, size: usize) -> VecZnxBig<FFT64> {
141 VecZnxBig::new(self, cols, size)
142 }
143
144 fn new_vec_znx_big_from_bytes(&self, cols: usize, size: usize, bytes: &mut [u8]) -> VecZnxBig<FFT64> {
145 VecZnxBig::from_bytes(self, cols, size, bytes)
146 }
147
148 fn new_vec_znx_big_from_bytes_borrow(&self, cols: usize, size: usize, tmp_bytes: &mut [u8]) -> VecZnxBig<FFT64> {
149 VecZnxBig::from_bytes_borrow(self, cols, size, tmp_bytes)
150 }
151
152 fn bytes_of_vec_znx_big(&self, cols: usize, size: usize) -> usize {
153 VecZnxBig::bytes_of(self, cols, size)
154 }
155
156 fn vec_znx_big_add(
157 &self,
158 res: &mut VecZnxBig<FFT64>,
159 col_res: usize,
160 a: &VecZnxBig<FFT64>,
161 col_a: usize,
162 b: &VecZnxBig<FFT64>,
163 col_b: usize,
164 ) {
165 #[cfg(debug_assertions)]
166 {
167 assert_eq!(a.n(), self.n());
168 assert_eq!(b.n(), self.n());
169 assert_eq!(res.n(), self.n());
170 assert_ne!(a.as_ptr(), b.as_ptr());
171 }
172 unsafe {
173 vec_znx::vec_znx_add(
174 self.ptr,
175 res.at_mut_ptr(col_res, 0),
176 res.size() as u64,
177 res.sl() as u64,
178 a.at_ptr(col_a, 0),
179 a.size() as u64,
180 a.sl() as u64,
181 b.at_ptr(col_b, 0),
182 b.size() as u64,
183 b.sl() as u64,
184 )
185 }
186 }
187
188 fn vec_znx_big_add_inplace(&self, res: &mut VecZnxBig<FFT64>, col_res: usize, a: &VecZnxBig<FFT64>, col_a: usize) {
189 unsafe {
190 let res_ptr: *mut VecZnxBig<FFT64> = res as *mut VecZnxBig<FFT64>;
191 Self::vec_znx_big_add(self, &mut *res_ptr, col_res, a, col_a, &*res_ptr, col_res);
192 }
193 }
194
195 fn vec_znx_big_sub(
196 &self,
197 res: &mut VecZnxBig<FFT64>,
198 col_res: usize,
199 a: &VecZnxBig<FFT64>,
200 col_a: usize,
201 b: &VecZnxBig<FFT64>,
202 col_b: usize,
203 ) {
204 #[cfg(debug_assertions)]
205 {
206 assert_eq!(a.n(), self.n());
207 assert_eq!(b.n(), self.n());
208 assert_eq!(res.n(), self.n());
209 assert_ne!(a.as_ptr(), b.as_ptr());
210 }
211 unsafe {
212 vec_znx::vec_znx_sub(
213 self.ptr,
214 res.at_mut_ptr(col_res, 0),
215 res.size() as u64,
216 res.sl() as u64,
217 a.at_ptr(col_a, 0),
218 a.size() as u64,
219 a.sl() as u64,
220 b.at_ptr(col_b, 0),
221 b.size() as u64,
222 b.sl() as u64,
223 )
224 }
225 }
226
227 fn vec_znx_big_sub_ab_inplace(&self, res: &mut VecZnxBig<FFT64>, col_res: usize, a: &VecZnxBig<FFT64>, col_a: usize) {
228 unsafe {
229 let res_ptr: *mut VecZnxBig<FFT64> = res as *mut VecZnxBig<FFT64>;
230 Self::vec_znx_big_sub(self, &mut *res_ptr, col_res, a, col_a, &*res_ptr, col_res);
231 }
232 }
233
234 fn vec_znx_big_sub_ba_inplace(&self, res: &mut VecZnxBig<FFT64>, col_res: usize, a: &VecZnxBig<FFT64>, col_a: usize) {
235 unsafe {
236 let res_ptr: *mut VecZnxBig<FFT64> = res as *mut VecZnxBig<FFT64>;
237 Self::vec_znx_big_sub(self, &mut *res_ptr, col_res, &*res_ptr, col_res, a, col_a);
238 }
239 }
240
241 fn vec_znx_big_sub_small_b(
242 &self,
243 res: &mut VecZnxBig<FFT64>,
244 col_res: usize,
245 a: &VecZnxBig<FFT64>,
246 col_a: usize,
247 b: &VecZnx,
248 col_b: usize,
249 ) {
250 #[cfg(debug_assertions)]
251 {
252 assert_eq!(a.n(), self.n());
253 assert_eq!(b.n(), self.n());
254 assert_eq!(res.n(), self.n());
255 assert_ne!(a.as_ptr(), b.as_ptr());
256 }
257 unsafe {
258 vec_znx::vec_znx_sub(
259 self.ptr,
260 res.at_mut_ptr(col_res, 0),
261 res.size() as u64,
262 res.sl() as u64,
263 a.at_ptr(col_a, 0),
264 a.size() as u64,
265 a.sl() as u64,
266 b.at_ptr(col_b, 0),
267 b.size() as u64,
268 b.sl() as u64,
269 )
270 }
271 }
272
273 fn vec_znx_big_sub_small_b_inplace(&self, res: &mut VecZnxBig<FFT64>, col_res: usize, a: &VecZnx, col_a: usize) {
274 unsafe {
275 let res_ptr: *mut VecZnxBig<FFT64> = res as *mut VecZnxBig<FFT64>;
276 Self::vec_znx_big_sub_small_b(self, &mut *res_ptr, col_res, &*res_ptr, col_res, a, col_a);
277 }
278 }
279
280 fn vec_znx_big_sub_small_a(
281 &self,
282 res: &mut VecZnxBig<FFT64>,
283 col_res: usize,
284 a: &VecZnx,
285 col_a: usize,
286 b: &VecZnxBig<FFT64>,
287 col_b: usize,
288 ) {
289 #[cfg(debug_assertions)]
290 {
291 assert_eq!(a.n(), self.n());
292 assert_eq!(b.n(), self.n());
293 assert_eq!(res.n(), self.n());
294 assert_ne!(a.as_ptr(), b.as_ptr());
295 }
296 unsafe {
297 vec_znx::vec_znx_sub(
298 self.ptr,
299 res.at_mut_ptr(col_res, 0),
300 res.size() as u64,
301 res.sl() as u64,
302 a.at_ptr(col_a, 0),
303 a.size() as u64,
304 a.sl() as u64,
305 b.at_ptr(col_b, 0),
306 b.size() as u64,
307 b.sl() as u64,
308 )
309 }
310 }
311
312 fn vec_znx_big_sub_small_a_inplace(&self, res: &mut VecZnxBig<FFT64>, col_res: usize, a: &VecZnx, col_a: usize) {
313 unsafe {
314 let res_ptr: *mut VecZnxBig<FFT64> = res as *mut VecZnxBig<FFT64>;
315 Self::vec_znx_big_sub_small_a(self, &mut *res_ptr, col_res, a, col_a, &*res_ptr, col_res);
316 }
317 }
318
319 fn vec_znx_big_add_small(
320 &self,
321 res: &mut VecZnxBig<FFT64>,
322 col_res: usize,
323 a: &VecZnx,
324 col_a: usize,
325 b: &VecZnxBig<FFT64>,
326 col_b: usize,
327 ) {
328 #[cfg(debug_assertions)]
329 {
330 assert_eq!(a.n(), self.n());
331 assert_eq!(b.n(), self.n());
332 assert_eq!(res.n(), self.n());
333 assert_ne!(a.as_ptr(), b.as_ptr());
334 }
335 unsafe {
336 vec_znx::vec_znx_add(
337 self.ptr,
338 res.at_mut_ptr(col_res, 0),
339 res.size() as u64,
340 res.sl() as u64,
341 a.at_ptr(col_a, 0),
342 a.size() as u64,
343 a.sl() as u64,
344 b.at_ptr(col_b, 0),
345 b.size() as u64,
346 b.sl() as u64,
347 )
348 }
349 }
350
351 fn vec_znx_big_add_small_inplace(&self, res: &mut VecZnxBig<FFT64>, col_res: usize, a: &VecZnx, a_col: usize) {
352 unsafe {
353 let res_ptr: *mut VecZnxBig<FFT64> = res as *mut VecZnxBig<FFT64>;
354 Self::vec_znx_big_add_small(self, &mut *res_ptr, col_res, a, a_col, &*res_ptr, col_res);
355 }
356 }
357
358 fn vec_znx_big_normalize_tmp_bytes(&self) -> usize {
359 Self::vec_znx_normalize_tmp_bytes(self)
360 }
361
362 fn vec_znx_big_normalize(
363 &self,
364 log_base2k: usize,
365 res: &mut VecZnx,
366 col_res: usize,
367 a: &VecZnxBig<FFT64>,
368 col_a: usize,
369 tmp_bytes: &mut [u8],
370 ) {
371 #[cfg(debug_assertions)]
372 {
373 assert_eq!(a.n(), self.n());
374 assert_eq!(res.n(), self.n());
375 assert!(tmp_bytes.len() >= Self::vec_znx_normalize_tmp_bytes(&self));
376 assert_alignement(tmp_bytes.as_ptr());
377 }
378 unsafe {
379 vec_znx::vec_znx_normalize_base2k(
380 self.ptr,
381 log_base2k as u64,
382 res.at_mut_ptr(col_res, 0),
383 res.size() as u64,
384 res.sl() as u64,
385 a.at_ptr(col_a, 0),
386 a.size() as u64,
387 a.sl() as u64,
388 tmp_bytes.as_mut_ptr(),
389 );
390 }
391 }
392
393 fn vec_znx_big_automorphism(&self, k: i64, res: &mut VecZnxBig<FFT64>, col_res: usize, a: &VecZnxBig<FFT64>, col_a: usize) {
394 #[cfg(debug_assertions)]
395 {
396 assert_eq!(a.n(), self.n());
397 assert_eq!(res.n(), self.n());
398 }
399 unsafe {
400 vec_znx::vec_znx_automorphism(
401 self.ptr,
402 k,
403 res.at_mut_ptr(col_res, 0),
404 res.size() as u64,
405 res.sl() as u64,
406 a.at_ptr(col_a, 0),
407 a.size() as u64,
408 a.sl() as u64,
409 )
410 }
411 }
412
413 fn vec_znx_big_automorphism_inplace(&self, k: i64, a: &mut VecZnxBig<FFT64>, col_a: usize) {
414 unsafe {
415 let a_ptr: *mut VecZnxBig<FFT64> = a as *mut VecZnxBig<FFT64>;
416 Self::vec_znx_big_automorphism(self, k, &mut *a_ptr, col_a, &*a_ptr, col_a);
417 }
418 }
419}