arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/spqlios/lib/test/spqlios_vec_znx_big_test.cpp
spqlios/lib/test/spqlios_vec_znx_big_test.cppRaw
  1#include <gtest/gtest.h>
  2
  3#include "spqlios/arithmetic/vec_znx_arithmetic_private.h"
  4#include "test/testlib/polynomial_vector.h"
  5#include "testlib/fft64_layouts.h"
  6#include "testlib/test_commons.h"
  7
  8#define def_rand_big(varname, ringdim, varsize)       \
  9  fft64_vec_znx_big_layout varname(ringdim, varsize); \
 10  varname.fill_random()
 11
 12#define def_rand_small(varname, ringdim, varsize)            \
 13  znx_vec_i64_layout varname(ringdim, varsize, 2 * ringdim); \
 14  varname.fill_random()
 15
 16#define test_prelude(ringdim, moduletype, dim1, dim2, dim3) \
 17  uint64_t n = ringdim;                                     \
 18  MODULE* module = new_module_info(ringdim, moduletype);    \
 19  for (uint64_t sa : {dim1, dim2, dim3}) {                  \
 20    for (uint64_t sb : {dim1, dim2, dim3}) {                \
 21      for (uint64_t sr : {dim1, dim2, dim3})
 22
 23#define test_end() \
 24  }                \
 25  }                \
 26  free(module)
 27
 28void test_fft64_vec_znx_big_add(VEC_ZNX_BIG_ADD_F vec_znx_big_add_fcn) {
 29  test_prelude(8, FFT64, 3, 5, 7) {
 30    fft64_vec_znx_big_layout r(n, sr);
 31    def_rand_big(a, n, sa);
 32    def_rand_big(b, n, sb);
 33    vec_znx_big_add_fcn(module, r.data, sr, a.data, sa, b.data, sb);
 34    for (uint64_t i = 0; i < sr; ++i) {
 35      ASSERT_EQ(r.get_copy(i), a.get_copy_zext(i) + b.get_copy_zext(i));
 36    }
 37  }
 38  test_end();
 39}
 40void test_fft64_vec_znx_big_add_small(VEC_ZNX_BIG_ADD_SMALL_F vec_znx_big_add_fcn) {
 41  test_prelude(16, FFT64, 2, 4, 5) {
 42    fft64_vec_znx_big_layout r(n, sr);
 43    def_rand_big(a, n, sa);
 44    def_rand_small(b, n, sb);
 45    vec_znx_big_add_fcn(module, r.data, sr, a.data, sa, b.data(), sb, 2 * n);
 46    for (uint64_t i = 0; i < sr; ++i) {
 47      ASSERT_EQ(r.get_copy(i), a.get_copy_zext(i) + b.get_copy_zext(i));
 48    }
 49  }
 50  test_end();
 51}
 52void test_fft64_vec_znx_big_add_small2(VEC_ZNX_BIG_ADD_SMALL2_F vec_znx_big_add_fcn) {
 53  test_prelude(64, FFT64, 3, 6, 7) {
 54    fft64_vec_znx_big_layout r(n, sr);
 55    def_rand_small(a, n, sa);
 56    def_rand_small(b, n, sb);
 57    vec_znx_big_add_fcn(module, r.data, sr, a.data(), sa, 2 * n, b.data(), sb, 2 * n);
 58    for (uint64_t i = 0; i < sr; ++i) {
 59      ASSERT_EQ(r.get_copy(i), a.get_copy_zext(i) + b.get_copy_zext(i));
 60    }
 61  }
 62  test_end();
 63}
 64
 65TEST(fft64_vec_znx_big, fft64_vec_znx_big_add) { test_fft64_vec_znx_big_add(fft64_vec_znx_big_add); }
 66TEST(vec_znx_big, vec_znx_big_add) { test_fft64_vec_znx_big_add(vec_znx_big_add); }
 67
 68TEST(fft64_vec_znx_big, fft64_vec_znx_big_add_small) { test_fft64_vec_znx_big_add_small(fft64_vec_znx_big_add_small); }
 69TEST(vec_znx_big, vec_znx_big_add_small) { test_fft64_vec_znx_big_add_small(vec_znx_big_add_small); }
 70
 71TEST(fft64_vec_znx_big, fft64_vec_znx_big_add_small2) {
 72  test_fft64_vec_znx_big_add_small2(fft64_vec_znx_big_add_small2);
 73}
 74TEST(vec_znx_big, vec_znx_big_add_small2) { test_fft64_vec_znx_big_add_small2(vec_znx_big_add_small2); }
 75
 76void test_fft64_vec_znx_big_sub(VEC_ZNX_BIG_SUB_F vec_znx_big_sub_fcn) {
 77  test_prelude(16, FFT64, 3, 5, 7) {
 78    fft64_vec_znx_big_layout r(n, sr);
 79    def_rand_big(a, n, sa);
 80    def_rand_big(b, n, sb);
 81    vec_znx_big_sub_fcn(module, r.data, sr, a.data, sa, b.data, sb);
 82    for (uint64_t i = 0; i < sr; ++i) {
 83      ASSERT_EQ(r.get_copy(i), a.get_copy_zext(i) - b.get_copy_zext(i));
 84    }
 85  }
 86  test_end();
 87}
 88void test_fft64_vec_znx_big_sub_small_a(VEC_ZNX_BIG_SUB_SMALL_A_F vec_znx_big_sub_fcn) {
 89  test_prelude(32, FFT64, 2, 4, 5) {
 90    fft64_vec_znx_big_layout r(n, sr);
 91    def_rand_small(a, n, sa);
 92    def_rand_big(b, n, sb);
 93    vec_znx_big_sub_fcn(module, r.data, sr, a.data(), sa, 2 * n, b.data, sb);
 94    for (uint64_t i = 0; i < sr; ++i) {
 95      ASSERT_EQ(r.get_copy(i), a.get_copy_zext(i) - b.get_copy_zext(i));
 96    }
 97  }
 98  test_end();
 99}
100void test_fft64_vec_znx_big_sub_small_b(VEC_ZNX_BIG_SUB_SMALL_B_F vec_znx_big_sub_fcn) {
101  test_prelude(16, FFT64, 2, 4, 5) {
102    fft64_vec_znx_big_layout r(n, sr);
103    def_rand_big(a, n, sa);
104    def_rand_small(b, n, sb);
105    vec_znx_big_sub_fcn(module, r.data, sr, a.data, sa, b.data(), sb, 2 * n);
106    for (uint64_t i = 0; i < sr; ++i) {
107      ASSERT_EQ(r.get_copy(i), a.get_copy_zext(i) - b.get_copy_zext(i));
108    }
109  }
110  test_end();
111}
112void test_fft64_vec_znx_big_sub_small2(VEC_ZNX_BIG_SUB_SMALL2_F vec_znx_big_sub_fcn) {
113  test_prelude(8, FFT64, 3, 6, 7) {
114    fft64_vec_znx_big_layout r(n, sr);
115    def_rand_small(a, n, sa);
116    def_rand_small(b, n, sb);
117    vec_znx_big_sub_fcn(module, r.data, sr, a.data(), sa, 2 * n, b.data(), sb, 2 * n);
118    for (uint64_t i = 0; i < sr; ++i) {
119      ASSERT_EQ(r.get_copy(i), a.get_copy_zext(i) - b.get_copy_zext(i));
120    }
121  }
122  test_end();
123}
124
125TEST(fft64_vec_znx_big, fft64_vec_znx_big_sub) { test_fft64_vec_znx_big_sub(fft64_vec_znx_big_sub); }
126TEST(vec_znx_big, vec_znx_big_sub) { test_fft64_vec_znx_big_sub(vec_znx_big_sub); }
127
128TEST(fft64_vec_znx_big, fft64_vec_znx_big_sub_small_a) {
129  test_fft64_vec_znx_big_sub_small_a(fft64_vec_znx_big_sub_small_a);
130}
131TEST(vec_znx_big, vec_znx_big_sub_small_a) { test_fft64_vec_znx_big_sub_small_a(vec_znx_big_sub_small_a); }
132
133TEST(fft64_vec_znx_big, fft64_vec_znx_big_sub_small_b) {
134  test_fft64_vec_znx_big_sub_small_b(fft64_vec_znx_big_sub_small_b);
135}
136TEST(vec_znx_big, vec_znx_big_sub_small_b) { test_fft64_vec_znx_big_sub_small_b(vec_znx_big_sub_small_b); }
137
138TEST(fft64_vec_znx_big, fft64_vec_znx_big_sub_small2) {
139  test_fft64_vec_znx_big_sub_small2(fft64_vec_znx_big_sub_small2);
140}
141TEST(vec_znx_big, vec_znx_big_sub_small2) { test_fft64_vec_znx_big_sub_small2(vec_znx_big_sub_small2); }
142
143static void test_vec_znx_big_normalize(VEC_ZNX_BIG_NORMALIZE_BASE2K_F normalize,
144                                       VEC_ZNX_BIG_NORMALIZE_BASE2K_TMP_BYTES_F normalize_tmp_bytes) {
145  // in the FFT64 case, big_normalize is just a forward.
146  // we will just test that the functions are callable
147  uint64_t n = 16;
148  uint64_t k = 12;
149  MODULE* module = new_module_info(n, FFT64);
150  for (uint64_t sa : {3, 5, 7}) {
151    for (uint64_t sr : {3, 5, 7}) {
152      uint64_t r_sl = n + 3;
153      def_rand_big(a, n, sa);
154      znx_vec_i64_layout r(n, sr, r_sl);
155      std::vector<uint8_t> tmp_space(normalize_tmp_bytes(module));
156      normalize(module, k, r.data(), sr, r_sl, a.data, sa, tmp_space.data());
157    }
158  }
159  delete_module_info(module);
160}
161
162TEST(vec_znx_big, fft64_vec_znx_big_normalize_base2k) {
163  test_vec_znx_big_normalize(fft64_vec_znx_big_normalize_base2k, fft64_vec_znx_big_normalize_base2k_tmp_bytes);
164}
165TEST(vec_znx_big, vec_znx_big_normalize_base2k) {
166  test_vec_znx_big_normalize(vec_znx_big_normalize_base2k, vec_znx_big_normalize_base2k_tmp_bytes);
167}
168
169static void test_vec_znx_big_range_normalize(  //
170    VEC_ZNX_BIG_RANGE_NORMALIZE_BASE2K_F normalize,
171    VEC_ZNX_BIG_RANGE_NORMALIZE_BASE2K_TMP_BYTES_F normalize_tmp_bytes) {
172  // in the FFT64 case, big_normalize is just a forward.
173  // we will just test that the functions are callable
174  uint64_t n = 16;
175  uint64_t k = 11;
176  MODULE* module = new_module_info(n, FFT64);
177  for (uint64_t sa : {6, 15, 21}) {
178    for (uint64_t sr : {3, 5, 7}) {
179      uint64_t r_sl = n + 3;
180      def_rand_big(a, n, sa);
181      uint64_t a_start = uniform_u64_bits(30) % (sa / 2);
182      uint64_t a_end = sa - (uniform_u64_bits(30) % (sa / 2));
183      uint64_t a_step = (uniform_u64_bits(30) % 3) + 1;
184      uint64_t range_size = (a_end + a_step - 1 - a_start) / a_step;
185      fft64_vec_znx_big_layout aextr(n, range_size);
186      for (uint64_t i = 0, idx = a_start; idx < a_end; ++i, idx += a_step) {
187        aextr.set(i, a.get_copy(idx));
188      }
189      znx_vec_i64_layout r(n, sr, r_sl);
190      znx_vec_i64_layout r2(n, sr, r_sl);
191      // tmp_space is large-enough for both
192      std::vector<uint8_t> tmp_space(normalize_tmp_bytes(module));
193      normalize(module, k, r.data(), sr, r_sl, a.data, a_start, a_end, a_step, tmp_space.data());
194      fft64_vec_znx_big_normalize_base2k(module, k, r2.data(), sr, r_sl, aextr.data, range_size, tmp_space.data());
195      for (uint64_t i = 0; i < sr; ++i) {
196        ASSERT_EQ(r.get_copy(i), r2.get_copy(i));
197      }
198    }
199  }
200  delete_module_info(module);
201}
202
203TEST(vec_znx_big, fft64_vec_znx_big_range_normalize_base2k) {
204  test_vec_znx_big_range_normalize(fft64_vec_znx_big_range_normalize_base2k,
205                                   fft64_vec_znx_big_range_normalize_base2k_tmp_bytes);
206}
207TEST(vec_znx_big, vec_znx_big_range_normalize_base2k) {
208  test_vec_znx_big_range_normalize(vec_znx_big_range_normalize_base2k, vec_znx_big_range_normalize_base2k_tmp_bytes);
209}
210
211static void test_vec_znx_big_rotate(VEC_ZNX_BIG_ROTATE_F rotate) {
212  // in the FFT64 case, big_normalize is just a forward.
213  // we will just test that the functions are callable
214  uint64_t n = 16;
215  int64_t p = 12;
216  MODULE* module = new_module_info(n, FFT64);
217  for (uint64_t sa : {3, 5, 7}) {
218    for (uint64_t sr : {3, 5, 7}) {
219      def_rand_big(a, n, sa);
220      fft64_vec_znx_big_layout r(n, sr);
221      rotate(module, p, r.data, sr, a.data, sa);
222      for (uint64_t i = 0; i < sr; ++i) {
223        znx_i64 aa = a.get_copy_zext(i);
224        znx_i64 expect(n);
225        for (uint64_t j = 0; j < n; ++j) {
226          expect.set_coeff(j, aa.get_coeff(int64_t(j) - p));
227        }
228        znx_i64 actual = r.get_copy(i);
229        ASSERT_EQ(expect, actual);
230      }
231    }
232  }
233  delete_module_info(module);
234}
235
236TEST(vec_znx_big, fft64_vec_znx_big_rotate) { test_vec_znx_big_rotate(fft64_vec_znx_big_rotate); }
237TEST(vec_znx_big, vec_znx_big_rotate) { test_vec_znx_big_rotate(vec_znx_big_rotate); }
238
239static void test_vec_znx_big_automorphism(VEC_ZNX_BIG_AUTOMORPHISM_F automorphism) {
240  // in the FFT64 case, big_normalize is just a forward.
241  // we will just test that the functions are callable
242  uint64_t n = 16;
243  int64_t p = 11;
244  MODULE* module = new_module_info(n, FFT64);
245  for (uint64_t sa : {3, 5, 7}) {
246    for (uint64_t sr : {3, 5, 7}) {
247      def_rand_big(a, n, sa);
248      fft64_vec_znx_big_layout r(n, sr);
249      automorphism(module, p, r.data, sr, a.data, sa);
250      for (uint64_t i = 0; i < sr; ++i) {
251        znx_i64 aa = a.get_copy_zext(i);
252        znx_i64 expect(n);
253        for (uint64_t j = 0; j < n; ++j) {
254          expect.set_coeff(p * j, aa.get_coeff(j));
255        }
256        znx_i64 actual = r.get_copy(i);
257        ASSERT_EQ(expect, actual);
258      }
259    }
260  }
261  delete_module_info(module);
262}
263
264TEST(vec_znx_big, fft64_vec_znx_big_automorphism) { test_vec_znx_big_automorphism(fft64_vec_znx_big_automorphism); }
265TEST(vec_znx_big, vec_znx_big_automorphism) { test_vec_znx_big_automorphism(vec_znx_big_automorphism); }