poulpy/spqlios/lib/spqlios/arithmetic/scalar_vector_product.c
spqlios/lib/spqlios/arithmetic/scalar_vector_product.cRaw
1#include <string.h>
2
3#include "vec_znx_arithmetic_private.h"
4
5EXPORT uint64_t bytes_of_svp_ppol(const MODULE* module) { return module->func.bytes_of_svp_ppol(module); }
6
7EXPORT uint64_t fft64_bytes_of_svp_ppol(const MODULE* module) { return module->nn * sizeof(double); }
8
9EXPORT SVP_PPOL* new_svp_ppol(const MODULE* module) { return spqlios_alloc(bytes_of_svp_ppol(module)); }
10
11EXPORT void delete_svp_ppol(SVP_PPOL* ppol) { spqlios_free(ppol); }
12
13// public wrappers
14EXPORT void svp_prepare(const MODULE* module, // N
15 SVP_PPOL* ppol, // output
16 const int64_t* pol // a
17) {
18 module->func.svp_prepare(module, ppol, pol);
19}
20
21/** @brief prepares a svp polynomial */
22EXPORT void fft64_svp_prepare_ref(const MODULE* module, // N
23 SVP_PPOL* ppol, // output
24 const int64_t* pol // a
25) {
26 reim_from_znx64(module->mod.fft64.p_conv, ppol, pol);
27 reim_fft(module->mod.fft64.p_fft, (double*)ppol);
28}
29
30EXPORT void svp_apply_dft(const MODULE* module, // N
31 const VEC_ZNX_DFT* res, uint64_t res_size, // output
32 const SVP_PPOL* ppol, // prepared pol
33 const int64_t* a, uint64_t a_size, uint64_t a_sl) {
34 module->func.svp_apply_dft(module, // N
35 res,
36 res_size, // output
37 ppol, // prepared pol
38 a, a_size, a_sl);
39}
40
41// result = ppol * a
42EXPORT void fft64_svp_apply_dft_ref(const MODULE* module, // N
43 const VEC_ZNX_DFT* res, uint64_t res_size, // output
44 const SVP_PPOL* ppol, // prepared pol
45 const int64_t* a, uint64_t a_size, uint64_t a_sl // a
46) {
47 const uint64_t nn = module->nn;
48 double* const dres = (double*)res;
49 double* const dppol = (double*)ppol;
50
51 const uint64_t auto_end_idx = res_size < a_size ? res_size : a_size;
52 for (uint64_t i = 0; i < auto_end_idx; ++i) {
53 const int64_t* a_ptr = a + i * a_sl;
54 double* const res_ptr = dres + i * nn;
55 // copy the polynomial to res, apply fft in place, call fftvec_mul in place.
56 reim_from_znx64(module->mod.fft64.p_conv, res_ptr, a_ptr);
57 reim_fft(module->mod.fft64.p_fft, res_ptr);
58 reim_fftvec_mul(module->mod.fft64.mul_fft, res_ptr, res_ptr, dppol);
59 }
60
61 // then extend with zeros
62 memset(dres + auto_end_idx * nn, 0, (res_size - auto_end_idx) * nn * sizeof(double));
63}