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); }