poulpy/poulpy-hal/src/reference/fft64/svp.rs
poulpy-hal/src/reference/fft64/svp.rsRaw
1use crate::{
2 layouts::{
3 Backend, ScalarZnx, ScalarZnxToRef, SvpPPol, SvpPPolToMut, SvpPPolToRef, VecZnx, VecZnxDft, VecZnxDftToMut,
4 VecZnxDftToRef, VecZnxToRef, ZnxInfos, ZnxView, ZnxViewMut,
5 },
6 reference::fft64::reim::{ReimAddMul, ReimDFTExecute, ReimFFTTable, ReimFromZnx, ReimMul, ReimMulInplace, ReimZero},
7};
8
9pub fn svp_prepare<R, A, BE>(table: &ReimFFTTable<f64>, res: &mut R, res_col: usize, a: &A, a_col: usize)
10where
11 BE: Backend<ScalarPrep = f64> + ReimDFTExecute<ReimFFTTable<f64>, f64> + ReimFromZnx,
12 R: SvpPPolToMut<BE>,
13 A: ScalarZnxToRef,
14{
15 let mut res: SvpPPol<&mut [u8], BE> = res.to_mut();
16 let a: ScalarZnx<&[u8]> = a.to_ref();
17 BE::reim_from_znx(res.at_mut(res_col, 0), a.at(a_col, 0));
18 BE::reim_dft_execute(table, res.at_mut(res_col, 0));
19}
20
21pub fn svp_apply_dft<R, A, B, BE>(
22 table: &ReimFFTTable<f64>,
23 res: &mut R,
24 res_col: usize,
25 a: &A,
26 a_col: usize,
27 b: &B,
28 b_col: usize,
29) where
30 BE: Backend<ScalarPrep = f64> + ReimDFTExecute<ReimFFTTable<f64>, f64> + ReimZero + ReimFromZnx + ReimMulInplace,
31 R: VecZnxDftToMut<BE>,
32 A: SvpPPolToRef<BE>,
33 B: VecZnxToRef,
34{
35 let mut res: VecZnxDft<&mut [u8], BE> = res.to_mut();
36 let a: SvpPPol<&[u8], BE> = a.to_ref();
37 let b: VecZnx<&[u8]> = b.to_ref();
38
39 let res_size: usize = res.size();
40 let b_size: usize = b.size();
41 let min_size: usize = res_size.min(b_size);
42
43 let ppol: &[f64] = a.at(a_col, 0);
44 for j in 0..min_size {
45 let out: &mut [f64] = res.at_mut(res_col, j);
46 BE::reim_from_znx(out, b.at(b_col, j));
47 BE::reim_dft_execute(table, out);
48 BE::reim_mul_inplace(out, ppol);
49 }
50
51 for j in min_size..res_size {
52 BE::reim_zero(res.at_mut(res_col, j));
53 }
54}
55
56pub fn svp_apply_dft_to_dft<R, A, B, BE>(res: &mut R, res_col: usize, a: &A, a_col: usize, b: &B, b_col: usize)
57where
58 BE: Backend<ScalarPrep = f64> + ReimMul + ReimZero,
59 R: VecZnxDftToMut<BE>,
60 A: SvpPPolToRef<BE>,
61 B: VecZnxDftToRef<BE>,
62{
63 let mut res: VecZnxDft<&mut [u8], BE> = res.to_mut();
64 let a: SvpPPol<&[u8], BE> = a.to_ref();
65 let b: VecZnxDft<&[u8], BE> = b.to_ref();
66
67 let res_size: usize = res.size();
68 let b_size: usize = b.size();
69 let min_size: usize = res_size.min(b_size);
70
71 let ppol: &[f64] = a.at(a_col, 0);
72 for j in 0..min_size {
73 BE::reim_mul(res.at_mut(res_col, j), ppol, b.at(b_col, j));
74 }
75
76 for j in min_size..res_size {
77 BE::reim_zero(res.at_mut(res_col, j));
78 }
79}
80
81pub fn svp_apply_dft_to_dft_add<R, A, B, BE>(res: &mut R, res_col: usize, a: &A, a_col: usize, b: &B, b_col: usize)
82where
83 BE: Backend<ScalarPrep = f64> + ReimAddMul + ReimZero,
84 R: VecZnxDftToMut<BE>,
85 A: SvpPPolToRef<BE>,
86 B: VecZnxDftToRef<BE>,
87{
88 let mut res: VecZnxDft<&mut [u8], BE> = res.to_mut();
89 let a: SvpPPol<&[u8], BE> = a.to_ref();
90 let b: VecZnxDft<&[u8], BE> = b.to_ref();
91
92 let res_size: usize = res.size();
93 let b_size: usize = b.size();
94 let min_size: usize = res_size.min(b_size);
95
96 let ppol: &[f64] = a.at(a_col, 0);
97 for j in 0..min_size {
98 BE::reim_addmul(res.at_mut(res_col, j), ppol, b.at(b_col, j));
99 }
100
101 for j in min_size..res_size {
102 BE::reim_zero(res.at_mut(res_col, j));
103 }
104}
105
106pub fn svp_apply_dft_to_dft_inplace<R, A, BE>(res: &mut R, res_col: usize, a: &A, a_col: usize)
107where
108 BE: Backend<ScalarPrep = f64> + ReimMulInplace,
109 R: VecZnxDftToMut<BE>,
110 A: SvpPPolToRef<BE>,
111{
112 let mut res: VecZnxDft<&mut [u8], BE> = res.to_mut();
113 let a: SvpPPol<&[u8], BE> = a.to_ref();
114
115 let ppol: &[f64] = a.at(a_col, 0);
116 for j in 0..res.size() {
117 BE::reim_mul_inplace(res.at_mut(res_col, j), ppol);
118 }
119}