arnaucube
arnaucube/poulpyPublic Self-hosted repository
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}