Let us walk on the 3-isogeny graph
Loading...
Searching...
No Matches
test_fq.c
Go to the documentation of this file.
1#include "test_declarations.h"
2#include "test_utils.h"
3#include <fp2.h>
4
5/*
6 * Test cases
7 */
8
9static MunitResult is_zero(MUNIT_UNUSED const MunitParameter params[], MUNIT_UNUSED void *user_data_or_fixture) {
10
11 fp2_t a;
13 assert_true(fp2_is_zero(a));
14 RANDOM_FP2_ELEMENT(&a);
15 assert_false(fp2_is_zero(a));
16
17 return MUNIT_OK;
18}
19
20
21static MunitResult locate_zero(MUNIT_UNUSED const MunitParameter params[], MUNIT_UNUSED void *user_data_or_fixture) {
22
23 uint8_t length = 255;
24 fp2_t a[length], b;
25 uint8_t i;
26
27 for(i = 0; i < length; i++) {
28 RANDOM_FP2_ELEMENT(&a[i]);
29 }
30
31 for(i = 0; i < length; i++) {
32 fp2_copy(&b, a[i]);
34 assert_true(fp2_locate_zero(a, length) == i);
35 fp2_copy(&a[i], b);
36 }
37
38 return MUNIT_OK;
39}
40
41static MunitResult linear_pass(MUNIT_UNUSED const MunitParameter params[], MUNIT_UNUSED void *user_data_or_fixture) {
42
43 uint8_t length = 255;
44 fp2_t a[length], b, c[length];
45 uint8_t i, j;
46
47 for(i = 0; i < length; i++) {
48 RANDOM_FP2_ELEMENT(&a[i]);
49 fp2_set_to_zero(&c[i]);
50 }
51
52 // Linear pass to store at the ith position
53 for(i = 0; i < length; i++) {
54 fp2_linear_pass_in(&b, a, length, i);
55 assert_memory_equal(sizeof(fp2_t), &b, &a[i]);
56 }
57
58 // Linear pass to store at the (i ^ index)-th position
59 for(i = 0; i < length; i++) {
60 RANDOM_FP2_ELEMENT(&b);
61 fp2_linear_pass_out(c, b, length, i);
62 assert_memory_equal(sizeof(fp2_t), &c[i], &b);
63 for(j = 0; j < length; j++) {
64 if(j != i) { assert_true(fp2_is_zero(c[j])); }
65 }
66 fp2_set_to_zero(&c[i]);
67 }
68
69 return MUNIT_OK;
70}
71
72
73static MunitResult add_and_sub(MUNIT_UNUSED const MunitParameter params[], MUNIT_UNUSED void *user_data_or_fixture) {
74
75 fp2_t a, b, c, d, e, f;
76
77 RANDOM_FP2_ELEMENT(&a);
81
82 assert_memory_not_equal(sizeof(fp2_t), &a, &d); // Random value different from zero
83
84 fp2_add(&c, a, b);
85 assert_memory_equal(sizeof(fp2_t), &a, &c); // a + 0 = a
87 fp2_add(&c, b, a);
88 assert_memory_equal(sizeof(fp2_t), &a, &c); // 0 + a = a
89
90 fp2_neg(&b, a);
91 assert_memory_not_equal(sizeof(fp2_t), &a, &b); // -a != a
92 fp2_add(&c, a, b);
93 assert_memory_equal(sizeof(fp2_t), &c, &d); // a - a = 0
94 fp2_add(&c, b, a);
95 assert_memory_equal(sizeof(fp2_t), &c, &d); // (-a) + a = 0
96
97 fp2_add(&b, a, a);
98 fp2_half(&c, b);
99 assert_memory_equal(sizeof(fp2_t), &c, &a); // (2a)/2 = a
100
101 RANDOM_FP2_ELEMENT(&b);
102 assert_memory_not_equal(sizeof(fp2_t), &b, &d); // Random value different from zero
103
104 fp2_add(&c, a, b);
105 fp2_sub(&d, a, b);
106 assert_memory_not_equal(sizeof(fp2_t), &b, &d); // a + b != a - b
107
108 fp2_sub(&e, c, b);
109 assert_memory_equal(sizeof(fp2_t), &e, &a); // (a + b) - b = a
110
111 fp2_add(&f, d, b);
112 assert_memory_equal(sizeof(fp2_t), &f, &a); // (a - b) + b = a
113
114 fp2_add(&e, c, d);
115 fp2_half(&e, e);
116 assert_memory_equal(sizeof(fp2_t), &e, &a); // ([a + b] + [a - b])/2 = a
117
118 fp2_sub(&f, c, d);
119 fp2_half(&f, f);
120 assert_memory_equal(sizeof(fp2_t), &f, &b); // ([a + b] - [a - b])/2 = b
121
122 fp2_sub(&c, b, a);
123 fp2_neg(&c, c);
124 assert_memory_equal(sizeof(fp2_t), &c, &d); // (a - b) = -(b - a)
125
126 return MUNIT_OK;
127}
128
129
130static MunitResult mul_and_sqr(MUNIT_UNUSED const MunitParameter params[], MUNIT_UNUSED void *user_data_or_fixture) {
131
132 fp2_t a, b, c, d, e;
133
135 fp2_set_to_zero(&b);
136 fp2_set_to_zero(&c);
137 fp2_set_to_zero(&d);
138 fp2_set_to_one(&e);
139
140 a.re[0] = 1;
141 fp2_copy(&b, a);
142
143 fp2_to_mont(&b, b);
144 assert_memory_equal(sizeof(fp2_t), &b, &e); // 1 -> R
145
146 fp2_from_mont(&b, b);
147 assert_memory_equal(sizeof(fp2_t), &b, &a); // R -> 1
148
149 RANDOM_FP2_ELEMENT(&a);
150 fp2_mul(&b, a, e);
151 assert_memory_equal(sizeof(fp2_t), &b, &a); // a * 1 = a
152
153 fp2_mul(&b, e, a);
154 assert_memory_equal(sizeof(fp2_t), &b, &a); // 1 * a = a
155
156 fp2_set_to_zero(&c);
157 fp2_mul(&b, a, c);
158 assert_memory_equal(sizeof(fp2_t), &b, &c); // a * 0 = 0
159
160 fp2_mul(&b, c, a);
161 assert_memory_equal(sizeof(fp2_t), &b, &c); // 0 * a = 0
162
163 c.re[0] = 2;
164 fp2_to_mont(&c, c);
165 fp2_add(&b, a, a);
166 fp2_mul(&d, a, c);
167 assert_memory_equal(sizeof(fp2_t), &b, &d); // 2 * a = a + a
168
169 fp2_set_to_zero(&b);
170 fp2_set_to_zero(&c);
171 fp2_sqr(&b, b);
172 assert_memory_equal(sizeof(fp2_t), &b, &c); // 0² = 0
173
174 fp2_set_to_one(&b);
175 fp2_sqr(&b, b);
176 assert_memory_equal(sizeof(fp2_t), &b, &e); // 1² = 1
177
178 fp2_sqr(&b, a);
179 fp2_mul(&c, a, a);
180 assert_memory_equal(sizeof(fp2_t), &b, &c); // a * a = a²
181
182 return MUNIT_OK;
183}
184
185
186static MunitResult inv(MUNIT_UNUSED const MunitParameter params[], MUNIT_UNUSED void *user_data_or_fixture) {
187
188 fp2_t a, b, c, one;
189
190 RANDOM_FP2_ELEMENT(&a);
191 fp2_set_to_zero(&b);
192 fp2_set_to_zero(&c);
193 fp2_set_to_one(&one);
194
195 assert_memory_not_equal(sizeof(fp2_t), &a, &c); // Random value different from zero
196
197 fp2_inv(&b, a);
198 fp2_mul(&c, a, b);
199 assert_memory_equal(sizeof(fp2_t), &c, &one); // a * a⁻¹ = 1
200
201 fp2_inv(&b, b);
202 assert_memory_equal(sizeof(fp2_t), &a, &b); // (a⁻¹)⁻¹ = a
203
205 fp2_inv(&b, a);
206 assert_memory_equal(sizeof(fp2_t), &a, &b); // (1⁻¹) = 1
207
208 fp2_mul(&c, a, b);
209 assert_memory_equal(sizeof(fp2_t), &c, &a); // 1 * 1 = 1
210
211 return MUNIT_OK;
212}
213
214static MunitResult batchinv(MUNIT_UNUSED const MunitParameter params[], MUNIT_UNUSED void *user_data_or_fixture) {
215
216 int length;
217
218 for(length = 1; length < 16; length++) {
219 fp2_t a[length], b[length], c, one;
220
221 for(int i = 0; i < length; i++) {
222 RANDOM_FP2_ELEMENT(&a[i]);
223 fp2_set_to_zero(&b[i]);
224 assert_memory_not_equal(sizeof(fp2_t), &a[i], &b[i]); // Random value different from zero
225 }
226 fp2_set_to_one(&one);
227
228 fp2_batchinv(b, a, length);
229
230 for(int i = 0; i < length; i++) {
231 fp2_mul(&c, a[i], b[i]);
232 assert_memory_equal(sizeof(fp2_t), &c, &one); // a * a⁻¹ = 1
233 }
234 }
235
236 return MUNIT_OK;
237}
238
239static MunitResult square_root_slow(MUNIT_UNUSED const MunitParameter params[], MUNIT_UNUSED void *user_data_or_fixture) {
240
241 fp2_t a, b, c;
242
243 RANDOM_FP2_ELEMENT(&a);
244 fp2_sqr(&a, a);
245 fp2_set_to_zero(&b);
246 fp2_set_to_zero(&c);
247
248 assert_memory_not_equal(sizeof(fp2_t), &a, &c); // Random value different from zero
249
250 // GF(p)-elements always have sqrt
251 fp2_set_to_zero(&b);
252 fp_copy(b.re, a.re);
253 fp2_sqrt_slow(&c, b);
254 fp2_sqr(&c, c);
255 assert_memory_equal(sizeof(fp2_t), &c, &b); // c ^ 2 = b
256
257 fp2_sqrt_slow(&b, a);
258 fp2_sqr(&c, b);
259 assert_memory_equal(sizeof(fp2_t), &c, &a); // c ^ 2 = a
260
262 fp2_sqrt_slow(&b, a);
263 fp2_sqr(&c, b);
264 assert_memory_equal(sizeof(fp2_t), &c, &a); // c ^ 2 = 1
265
267 fp2_sqrt_slow(&b, a);
268 assert_memory_equal(sizeof(fp2_t), &b, &a); // b = 0
269
270 return MUNIT_OK;
271}
272
273static MunitResult square_root_fast(MUNIT_UNUSED const MunitParameter params[], MUNIT_UNUSED void *user_data_or_fixture) {
274
275 fp2_t a, b, c;
276
277 RANDOM_FP2_ELEMENT(&a);
278 fp2_sqr(&a, a);
279 fp2_set_to_zero(&b);
280 fp2_set_to_zero(&c);
281
282 assert_memory_not_equal(sizeof(fp2_t), &a, &c); // Random value different from zero
283
284 // GF(p)-elements always have sqrt but sqrt_fast does not work always (1/2 of probability of returning zero)
285 // So we skip tests over GF(p)
286
287 fp2_sqrt_fast(&b, a);
288 fp2_sqr(&c, b);
289 assert_memory_equal(sizeof(fp2_t), &c, &a); // c ^ 2 = a
290
292 fp2_sqrt_fast(&b, a);
293 fp2_sqr(&c, b);
294 assert_memory_equal(sizeof(fp2_t), &c, &a); // c ^ 2 = 1
295
297 fp2_sqrt_fast(&b, a);
298 assert_memory_equal(sizeof(fp2_t), &b, &a); // b = 0
299
300 return MUNIT_OK;
301}
302
303static MunitResult cube_root(MUNIT_UNUSED const MunitParameter params[], MUNIT_UNUSED void *user_data_or_fixture) {
304
305 fp2_t a, b, c, t;
306
307 RANDOM_FP2_ELEMENT(&a);
308 fp2_sqr(&t, a);
309 fp2_mul(&a, t, a);
310 fp2_set_to_zero(&b);
311 fp2_set_to_zero(&c);
312
313 assert_memory_not_equal(sizeof(fp2_t), &a, &c); // Random value different from zero
314
315 fp2_curt(&b, a);
316 fp2_sqr(&t, b);
317 fp2_mul(&c, t, b);
318 assert_memory_equal(sizeof(fp2_t), &c, &a); // c ^ 3 = a
319
321 fp2_copy(&b, *((fp2_t *)&CUBE_ROOT_OF_UNITY));
322 assert_memory_not_equal(sizeof(fp2_t), &a, &b); // Cube root of unity different from 1
323 fp2_curt(&c, b);
324 fp2_sqr(&t, c);
325 fp2_mul(&t, t, c);
326 assert_memory_equal(sizeof(fp2_t), &t, &a); // c ^ 3 = 1
327
329 fp2_curt(&b, a);
330 assert_memory_equal(sizeof(fp2_t), &b, &a); // b = 0
331
332 return MUNIT_OK;
333}
334
335/*
336 * Register test cases
337 */
338
340 TEST_CASE(is_zero),
341 TEST_CASE(locate_zero),
342 TEST_CASE(linear_pass),
343 TEST_CASE(add_and_sub),
344 TEST_CASE(mul_and_sqr),
345 TEST_CASE(inv),
346 TEST_CASE(batchinv),
347 TEST_CASE(square_root_slow),
348 TEST_CASE(square_root_fast),
349 TEST_CASE(cube_root),
351};
void fp2_sqrt_slow(fp2_t *output, fp2_t input)
Definition fp2.c:283
void fp2_linear_pass_out(fp2_t *output, fp2_t input, uint8_t input_length, uint8_t input_index)
Definition fp2.c:170
void fp2_batchinv(fp2_t *output_list, const fp2_t *input_list, uint8_t input_length)
Definition fp2.c:202
void fp2_linear_pass_in(fp2_t *output, const fp2_t *input, uint8_t input_length, uint8_t input_index)
Definition fp2.c:159
void fp2_set_to_zero(fp2_t *output)
Definition fp2.c:54
int64_t fp2_is_zero(fp2_t input)
Definition fp2.c:149
void fp2_sqrt_fast(fp2_t *output, fp2_t input)
Definition fp2.c:333
void fp2_half(fp2_t *output, fp2_t input)
Definition fp2.c:107
void fp2_from_mont(fp2_t *output, fp2_t input)
Definition fp2.c:119
void fp2_to_mont(fp2_t *output, fp2_t input)
Definition fp2.c:113
void fp2_curt(fp2_t *output, fp2_t input)
Definition fp2.c:399
uint8_t fp2_locate_zero(const fp2_t *input, uint8_t input_length)
Definition fp2.c:181
void fp2_set_to_one(fp2_t *output)
Definition fp2.c:49
#define fp_copy
Definition fp-gmp.h:79
#define MUNIT_UNUSED
Definition munit.h:136
MunitResult
Definition munit.h:415
@ MUNIT_OK
Definition munit.h:417
for i
for j
Definition fp2.h:10
fp_t re
Definition fp2.h:11
MunitTest test_fq[]
Definition test_fq.c:339
#define TEST_END
Definition test_utils.h:11
#define TEST_CASE(test_func)
Definition test_utils.h:19
f a
Definition to_model.m:12