arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-backend/src/cpu_spqlios/spqlios-arithmetic/spqlios/arithmetic/vec_znx_arithmetic.h
poulpy-backend/src/cpu_spqlios/spqlios-arithmetic/spqlios/arithmetic/vec_znx_arithmetic.hRaw
  1#ifndef SPQLIOS_VEC_ZNX_ARITHMETIC_H
  2#define SPQLIOS_VEC_ZNX_ARITHMETIC_H
  3
  4#include <stdint.h>
  5
  6#include "../commons.h"
  7#include "../reim/reim_fft.h"
  8
  9/**
 10 * We support the following module families:
 11 * - FFT64:
 12 *    all the polynomials should fit at all times over 52 bits.
 13 *    for FHE implementations, the recommended limb-sizes are
 14 *    between K=10 and 20, which is good for low multiplicative depths.
 15 * - NTT120:
 16 *    all the polynomials should fit at all times over 119 bits.
 17 *    for FHE implementations, the recommended limb-sizes are
 18 *    between K=20 and 40, which is good for large multiplicative depths.
 19 */
 20typedef enum module_type_t { FFT64, NTT120 } MODULE_TYPE;
 21
 22/** @brief opaque structure that describr the modules (ZnX,TnX) and the hardware */
 23typedef struct module_info_t MODULE;
 24/** @brief opaque type that represents a prepared matrix */
 25typedef struct vmp_pmat_t VMP_PMAT;
 26/** @brief opaque type that represents a vector of znx in DFT space */
 27typedef struct vec_znx_dft_t VEC_ZNX_DFT;
 28/** @brief opaque type that represents a vector of znx in large coeffs space */
 29typedef struct vec_znx_bigcoeff_t VEC_ZNX_BIG;
 30/** @brief opaque type that represents a prepared scalar vector product */
 31typedef struct svp_ppol_t SVP_PPOL;
 32/** @brief opaque type that represents a prepared left convolution vector product */
 33typedef struct cnv_pvec_l_t CNV_PVEC_L;
 34/** @brief opaque type that represents a prepared right convolution vector product */
 35typedef struct cnv_pvec_r_t CNV_PVEC_R;
 36
 37/** @brief bytes needed for a vec_znx in DFT space */
 38EXPORT uint64_t bytes_of_vec_znx_dft(const MODULE* module,  // N
 39                                     uint64_t size);
 40
 41/** @brief allocates a vec_znx in DFT space */
 42EXPORT VEC_ZNX_DFT* new_vec_znx_dft(const MODULE* module,  // N
 43                                    uint64_t size);
 44
 45/** @brief frees memory from a vec_znx in DFT space */
 46EXPORT void delete_vec_znx_dft(VEC_ZNX_DFT* res);
 47
 48/** @brief bytes needed for a vec_znx_big */
 49EXPORT uint64_t bytes_of_vec_znx_big(const MODULE* module,  // N
 50                                     uint64_t size);
 51
 52/** @brief allocates a vec_znx_big */
 53EXPORT VEC_ZNX_BIG* new_vec_znx_big(const MODULE* module,  // N
 54                                    uint64_t size);
 55/** @brief frees memory from a vec_znx_big */
 56EXPORT void delete_vec_znx_big(VEC_ZNX_BIG* res);
 57
 58/** @brief bytes needed for a prepared vector */
 59EXPORT uint64_t bytes_of_svp_ppol(const MODULE* module);  // N
 60
 61/** @brief allocates a prepared vector */
 62EXPORT SVP_PPOL* new_svp_ppol(const MODULE* module);  // N
 63
 64/** @brief frees memory for a prepared vector */
 65EXPORT void delete_svp_ppol(SVP_PPOL* res);
 66
 67/** @brief bytes needed for a prepared matrix */
 68EXPORT uint64_t bytes_of_vmp_pmat(const MODULE* module,  // N
 69                                  uint64_t nrows, uint64_t ncols);
 70
 71/** @brief allocates a prepared matrix */
 72EXPORT VMP_PMAT* new_vmp_pmat(const MODULE* module,  // N
 73                              uint64_t nrows, uint64_t ncols);
 74
 75/** @brief frees memory for a prepared matrix */
 76EXPORT void delete_vmp_pmat(VMP_PMAT* res);
 77
 78/**
 79 * @brief obtain a module info for ring dimension N
 80 * the module-info knows about:
 81 *  - the dimension N (or the complex dimension m=N/2)
 82 *  - any moduleuted fft or ntt items
 83 *  - the hardware (avx, arm64, x86, ...)
 84 */
 85EXPORT MODULE* new_module_info(uint64_t N, MODULE_TYPE mode);
 86EXPORT void delete_module_info(MODULE* module_info);
 87EXPORT uint64_t module_get_n(const MODULE* module);
 88
 89/** @brief sets res = 0 */
 90EXPORT void vec_znx_zero(const MODULE* module,                             // N
 91                         int64_t* res, uint64_t res_size, uint64_t res_sl  // res
 92);
 93
 94/** @brief sets res = a */
 95EXPORT void vec_znx_copy(const MODULE* module,                              // N
 96                         int64_t* res, uint64_t res_size, uint64_t res_sl,  // res
 97                         const int64_t* a, uint64_t a_size, uint64_t a_sl   // a
 98);
 99
100/** @brief sets res = a */
101EXPORT void vec_znx_negate(const MODULE* module,                              // N
102                           int64_t* res, uint64_t res_size, uint64_t res_sl,  // res
103                           const int64_t* a, uint64_t a_size, uint64_t a_sl   // a
104);
105
106/** @brief sets res = a + b */
107EXPORT void vec_znx_add(const MODULE* module,                              // N
108                        int64_t* res, uint64_t res_size, uint64_t res_sl,  // res
109                        const int64_t* a, uint64_t a_size, uint64_t a_sl,  // a
110                        const int64_t* b, uint64_t b_size, uint64_t b_sl   // b
111);
112
113/** @brief sets res = a - b */
114EXPORT void vec_znx_sub(const MODULE* module,                              // N
115                        int64_t* res, uint64_t res_size, uint64_t res_sl,  // res
116                        const int64_t* a, uint64_t a_size, uint64_t a_sl,  // a
117                        const int64_t* b, uint64_t b_size, uint64_t b_sl   // b
118);
119
120/** @brief sets res = k-normalize-reduce(a) */
121EXPORT void vec_znx_normalize_base2k(const MODULE* module,                              // MODULE
122                                     uint64_t nn,                                       // N
123                                     uint64_t log2_base2k,                              // output base 2^K
124                                     int64_t* res, uint64_t res_size, uint64_t res_sl,  // res
125                                     const int64_t* a, uint64_t a_size, uint64_t a_sl,  // a
126                                     uint8_t* tmp_space                                 // scratch space (size >= N)
127);
128
129/** @brief returns the minimal byte length of scratch space for vec_znx_normalize_base2k */
130EXPORT uint64_t vec_znx_normalize_base2k_tmp_bytes(const MODULE* module, uint64_t nn  // N
131);
132
133/** @brief sets res = a . X^p */
134EXPORT void vec_znx_rotate(const MODULE* module,                              // N
135                           const int64_t p,                                   // rotation value
136                           int64_t* res, uint64_t res_size, uint64_t res_sl,  // res
137                           const int64_t* a, uint64_t a_size, uint64_t a_sl   // a
138);
139
140/** @brief sets res = a * (X^{p} - 1) */
141EXPORT void vec_znx_mul_xp_minus_one(const MODULE* module,                              // N
142                           const int64_t p,                                   // rotation value
143                           int64_t* res, uint64_t res_size, uint64_t res_sl,  // res
144                           const int64_t* a, uint64_t a_size, uint64_t a_sl   // a
145);
146
147/** @brief sets res = a(X^p) */
148EXPORT void vec_znx_automorphism(const MODULE* module,                              // N
149                                 const int64_t p,                                   // X-X^p
150                                 int64_t* res, uint64_t res_size, uint64_t res_sl,  // res
151                                 const int64_t* a, uint64_t a_size, uint64_t a_sl   // a
152);
153
154/** @brief sets res = 0 */
155EXPORT void vec_dft_zero(const MODULE* module,                // N
156                         VEC_ZNX_DFT* res, uint64_t res_size  // res
157);
158
159/** @brief sets res = a+b */
160EXPORT void vec_dft_add(const MODULE* module,                   // N
161                        VEC_ZNX_DFT* res, uint64_t res_size,    // res
162                        const VEC_ZNX_DFT* a, uint64_t a_size,  // a
163                        const VEC_ZNX_DFT* b, uint64_t b_size   // b
164);
165
166/** @brief sets res = a-b */
167EXPORT void vec_dft_sub(const MODULE* module,                   // N
168                        VEC_ZNX_DFT* res, uint64_t res_size,    // res
169                        const VEC_ZNX_DFT* a, uint64_t a_size,  // a
170                        const VEC_ZNX_DFT* b, uint64_t b_size   // b
171);
172
173/** @brief sets res = DFT(a) */
174EXPORT void vec_znx_dft(const MODULE* module,                             // N
175                        VEC_ZNX_DFT* res, uint64_t res_size,              // res
176                        const int64_t* a, uint64_t a_size, uint64_t a_sl  // a
177);
178
179/** @brief sets res = iDFT(a_dft) -- output in big coeffs space */
180EXPORT void vec_znx_idft(const MODULE* module,                       // N
181                         VEC_ZNX_BIG* res, uint64_t res_size,        // res
182                         const VEC_ZNX_DFT* a_dft, uint64_t a_size,  // a
183                         uint8_t* tmp                                // scratch space
184);
185
186/** @brief tmp bytes required for vec_znx_idft  */
187EXPORT uint64_t vec_znx_idft_tmp_bytes(const MODULE* module, uint64_t nn);
188
189/**
190 * @brief      sets res = iDFT(a_dft) -- output in big coeffs space
191 *
192 * @note       a_dft is overwritten
193 */
194EXPORT void vec_znx_idft_tmp_a(const MODULE* module,                 // N
195                               VEC_ZNX_BIG* res, uint64_t res_size,  // res
196                               VEC_ZNX_DFT* a_dft, uint64_t a_size   // a is overwritten
197);
198
199/** @brief sets res = a+b */
200EXPORT void vec_znx_big_add(const MODULE* module,                   // N
201                            VEC_ZNX_BIG* res, uint64_t res_size,    // res
202                            const VEC_ZNX_BIG* a, uint64_t a_size,  // a
203                            const VEC_ZNX_BIG* b, uint64_t b_size   // b
204);
205/** @brief sets res = a+b */
206EXPORT void vec_znx_big_add_small(const MODULE* module,                             // N
207                                  VEC_ZNX_BIG* res, uint64_t res_size,              // res
208                                  const VEC_ZNX_BIG* a, uint64_t a_size,            // a
209                                  const int64_t* b, uint64_t b_size, uint64_t b_sl  // b
210);
211EXPORT void vec_znx_big_add_small2(const MODULE* module,                              // N
212                                   VEC_ZNX_BIG* res, uint64_t res_size,               // res
213                                   const int64_t* a, uint64_t a_size, uint64_t a_sl,  // a
214                                   const int64_t* b, uint64_t b_size, uint64_t b_sl   // b
215);
216
217/** @brief sets res = a-b */
218EXPORT void vec_znx_big_sub(const MODULE* module,                   // N
219                            VEC_ZNX_BIG* res, uint64_t res_size,    // res
220                            const VEC_ZNX_BIG* a, uint64_t a_size,  // a
221                            const VEC_ZNX_BIG* b, uint64_t b_size   // b
222);
223EXPORT void vec_znx_big_sub_small_b(const MODULE* module,                             // N
224                                    VEC_ZNX_BIG* res, uint64_t res_size,              // res
225                                    const VEC_ZNX_BIG* a, uint64_t a_size,            // a
226                                    const int64_t* b, uint64_t b_size, uint64_t b_sl  // b
227);
228EXPORT void vec_znx_big_sub_small_a(const MODULE* module,                              // N
229                                    VEC_ZNX_BIG* res, uint64_t res_size,               // res
230                                    const int64_t* a, uint64_t a_size, uint64_t a_sl,  // a
231                                    const VEC_ZNX_BIG* b, uint64_t b_size              // b
232);
233EXPORT void vec_znx_big_sub_small2(const MODULE* module,                              // N
234                                   VEC_ZNX_BIG* res, uint64_t res_size,               // res
235                                   const int64_t* a, uint64_t a_size, uint64_t a_sl,  // a
236                                   const int64_t* b, uint64_t b_size, uint64_t b_sl   // b
237);
238
239/** @brief sets res = k-normalize(a) -- output in int64 coeffs space */
240EXPORT void vec_znx_big_normalize_base2k(const MODULE* module,                              // MODULE
241                                         uint64_t nn,                                       // N
242                                         uint64_t log2_base2k,                              // base-2^k
243                                         int64_t* res, uint64_t res_size, uint64_t res_sl,  // res
244                                         const VEC_ZNX_BIG* a, uint64_t a_size,             // a
245                                         uint8_t* tmp_space                                 // temp space
246);
247
248/** @brief returns the minimal byte length of scratch space for vec_znx_big_normalize_base2k */
249EXPORT uint64_t vec_znx_big_normalize_base2k_tmp_bytes(const MODULE* module, uint64_t nn  // N
250);
251
252/** @brief sets res = k-normalize(a.subrange) -- output in int64 coeffs space */
253EXPORT void vec_znx_big_range_normalize_base2k(                                                  //
254    const MODULE* module,                                                                        // MODULE
255    uint64_t nn,
256    uint64_t log2_base2k,                                                                        // base-2^k
257    int64_t* res, uint64_t res_size, uint64_t res_sl,                                            // res
258    const VEC_ZNX_BIG* a, uint64_t a_range_begin, uint64_t a_range_xend, uint64_t a_range_step,  // range
259    uint8_t* tmp_space                                                                           // temp space
260);
261
262/** @brief returns the minimal byte length of scratch space for vec_znx_big_range_normalize_base2k */
263EXPORT uint64_t vec_znx_big_range_normalize_base2k_tmp_bytes(  //
264    const MODULE* module, uint64_t nn                                       // N
265);
266
267/** @brief sets res = a . X^p */
268EXPORT void vec_znx_big_rotate(const MODULE* module,                  // N
269                               int64_t p,                             // rotation value
270                               VEC_ZNX_BIG* res, uint64_t res_size,   // res
271                               const VEC_ZNX_BIG* a, uint64_t a_size  // a
272);
273
274/** @brief sets res = a(X^p) */
275EXPORT void vec_znx_big_automorphism(const MODULE* module,                  // N
276                                     int64_t p,                             // X-X^p
277                                     VEC_ZNX_BIG* res, uint64_t res_size,   // res
278                                     const VEC_ZNX_BIG* a, uint64_t a_size  // a
279);
280
281/** @brief apply a svp product, result = ppol * a, presented in DFT space */
282EXPORT void svp_apply_dft(const MODULE* module,                             // N
283                          const VEC_ZNX_DFT* res, uint64_t res_size,        // output
284                          const SVP_PPOL* ppol,                             // prepared pol
285                          const int64_t* a, uint64_t a_size, uint64_t a_sl  // a
286);
287
288/** @brief apply a svp product, result = ppol * a, presented in DFT space */
289EXPORT void svp_apply_dft_to_dft(const MODULE* module,  // N
290                                 const VEC_ZNX_DFT* res, uint64_t res_size,
291                                 uint64_t res_cols,                                      // output
292                                 const SVP_PPOL* ppol,                                   // prepared pol
293                                 const VEC_ZNX_DFT* a, uint64_t a_size, uint64_t a_cols  // a
294);
295
296/** @brief prepares a svp polynomial  */
297EXPORT void svp_prepare(const MODULE* module,  // N
298                        SVP_PPOL* ppol,        // output
299                        const int64_t* pol     // a
300);
301
302/** @brief res = a * b : small integer polynomial product  */
303EXPORT void znx_small_single_product(const MODULE* module,  // N
304                                     int64_t* res,          // output
305                                     const int64_t* a,      // a
306                                     const int64_t* b,      // b
307                                     uint8_t* tmp);
308
309/** @brief tmp bytes required for znx_small_single_product  */
310EXPORT uint64_t znx_small_single_product_tmp_bytes(const MODULE* module, uint64_t nn);
311
312/** @brief minimal scratch space byte-size required for the vmp_prepare function */
313EXPORT uint64_t vmp_prepare_tmp_bytes(const MODULE* module, uint64_t nn,  // N
314                                      uint64_t nrows, uint64_t ncols);
315
316/** @brief prepares a vmp matrix (contiguous row-major version) */
317EXPORT void vmp_prepare_contiguous(const MODULE* module,                                // N
318                                   VMP_PMAT* pmat,                                      // output
319                                   const int64_t* mat, uint64_t nrows, uint64_t ncols,  // a
320                                   uint8_t* tmp_space                                   // scratch space
321);
322
323/** @brief applies a vmp product (result in DFT space) adds to res inplace */
324EXPORT void vmp_apply_dft_add(const MODULE* module,                                                       // N
325                              VEC_ZNX_DFT* res, uint64_t res_size,                                        // res
326                              const int64_t* a, uint64_t a_size, uint64_t a_sl,                           // a
327                              const VMP_PMAT* pmat, uint64_t nrows, uint64_t ncols, uint64_t pmat_scale,  // prep matrix
328                              uint8_t* tmp_space  // scratch space
329);
330
331/** @brief applies a vmp product (result in DFT space) */
332EXPORT void vmp_apply_dft(const MODULE* module,                                  // N
333                          VEC_ZNX_DFT* res, uint64_t res_size,                   // res
334                          const int64_t* a, uint64_t a_size, uint64_t a_sl,      // a
335                          const VMP_PMAT* pmat, uint64_t nrows, uint64_t ncols,  // prep matrix
336                          uint8_t* tmp_space                                     // scratch space
337);
338
339/** @brief minimal size of the tmp_space */
340EXPORT uint64_t vmp_apply_dft_tmp_bytes(const MODULE* module, uint64_t nn,           // N
341                                        uint64_t res_size,              // res
342                                        uint64_t a_size,                // a
343                                        uint64_t nrows, uint64_t ncols  // prep matrix
344);
345
346/** @brief applies vmp product */
347EXPORT void vmp_apply_dft_to_dft(const MODULE* module,                       // N
348                                 VEC_ZNX_DFT* res, const uint64_t res_size,  // res
349                                 const VEC_ZNX_DFT* a_dft, uint64_t a_size,  // a
350                                 const VMP_PMAT* pmat, const uint64_t nrows,
351                                 const uint64_t ncols,  // prep matrix
352                                 uint8_t* tmp_space     // scratch space (a_size*sizeof(reim4) bytes)
353);
354
355/** @brief applies vmp product and adds to res inplace */
356EXPORT void vmp_apply_dft_to_dft_add(const MODULE* module,                       // N
357                                     VEC_ZNX_DFT* res, const uint64_t res_size,  // res
358                                     const VEC_ZNX_DFT* a_dft, uint64_t a_size,  // a
359                                     const VMP_PMAT* pmat, const uint64_t nrows, const uint64_t ncols,
360                                     const uint64_t pmat_scale,  // prep matrix
361                                     uint8_t* tmp_space          // scratch space (a_size*sizeof(reim4) bytes)
362);
363
364/** @brief minimal size of the tmp_space */
365EXPORT uint64_t vmp_apply_dft_to_dft_tmp_bytes(const MODULE* module, uint64_t nn,           // N
366                                               uint64_t res_size,              // res
367                                               uint64_t a_size,                // a
368                                               uint64_t nrows, uint64_t ncols  // prep matrix
369);
370#endif  // SPQLIOS_VEC_ZNX_ARITHMETIC_H