Let us walk on the 3-isogeny graph
Loading...
Searching...
No Matches
test_isogeny_walks.c
Go to the documentation of this file.
1#include "test_declarations.h"
2#include "test_utils.h"
3#include "isogeny_walks.h"
4
5/*
6 * Test cases
7 */
8
9
10static MunitResult mul_by_small_constants(MUNIT_UNUSED const MunitParameter params[], MUNIT_UNUSED void *user_data_or_fixture) {
11
12 fp2_t a, b, c, t;
13
14 RANDOM_FP2_ELEMENT(&a);
15
17 t.re[0] = 1488;
18 fp2_to_mont(&t, t);
19 fp2_mul(&c, a, t);
20 fp2_mul_by_1488(&b, a);
21 assert_memory_equal(sizeof(fp2_t), &b, &c); // Testing 1488 × a
22
24 t.re[0] = 2976;
25 fp2_to_mont(&t, t);
26 fp2_mul(&c, a, t);
27 fp2_mul_by_2976(&b, a);
28 assert_memory_equal(sizeof(fp2_t), &b, &c); // Testing 2976 × a
29
31 t.re[0] = 162000;
32 fp2_to_mont(&t, t);
33 fp2_mul(&c, a, t);
35 assert_memory_equal(sizeof(fp2_t), &b, &c); // Testing 162000 × a
36
38 t.re[0] = 324000;
39 fp2_to_mont(&t, t);
40 fp2_mul(&c, a, t);
42 assert_memory_equal(sizeof(fp2_t), &b, &c); // Testing 324000 × a
43
45 t.re[0] = 2532192;
46 fp2_to_mont(&t, t);
47 fp2_mul(&c, a, t);
49 assert_memory_equal(sizeof(fp2_t), &b, &c); // Testing 2532192 × a
50
52 t.re[0] = 645205500;
53 fp2_to_mont(&t, t);
54 fp2_mul(&c, a, t);
56 assert_memory_equal(sizeof(fp2_t), &b, &c); // Testing 645205500 × a
57
59 t.re[0] = 8748000000;
60 fp2_to_mont(&t, t);
61 fp2_mul(&c, a, t);
63 assert_memory_equal(sizeof(fp2_t), &b, &c); // Testing 8748000000 × a
64
65 return MUNIT_OK;
66}
67
68static MunitResult degree_2(MUNIT_UNUSED const MunitParameter params[], MUNIT_UNUSED void *user_data_or_fixture) {
69 uint8_t path[BIT_LENGTH_PATH / 8] = {0};
71 fp2_t j1, j0, j_invariant;
72
73 fp2_set_to_zero(&j1);
74 j1.re[0] = 287496;
75 fp2_to_mont(&j1, j1);
76
77 fp2_set_to_zero(&j0);
78 j0.re[0] = 1728;
79 fp2_to_mont(&j0, j0);
80
81 // We take as origin a j-invariant defined over GF(p^2) excluding GF(p).
82 isogeny_walks_2_slow(&j0, &j1, j0, j1, path, BIT_LENGTH_PATH / 8);
83 isogeny_walks_2(&j_invariant, j0, j1, path, BIT_LENGTH_PATH / 8);
84
85 // ++++++++++++++++++++++++++++++++++++
86 // Test through magma script generated:
87 // If you have installed magma on your machine, run: magma TEST-[FIELD_NAME]-deg2.log
88 // Else, copy/paste the content of TEST-[FIELD_NAME]-deg2.log in online magma calculator (http://magma.maths.usyd.edu.au/calc/)
89 // Remark. Take into account that the online calculator has a limit buffer.
90
91 char file_name[256];
92 strcpy(file_name, "TEST-");
93 strcat(file_name, FIELD_NAME);
94 strcat(file_name, "-deg2.log");
95
96 FILE *fptr = fopen(file_name, "a");
97 if (fptr == NULL) {
98 printf("Could not open file");
99 return 0;
100 }
101
102 file_print_bytes(fptr, "// PATH (Hexadecimal): ", path, BIT_LENGTH_PATH / 8);
103 fprintf(fptr, "// j-invariant (from 287496 to j0):\n");
104 fprintf(fptr, "// Re := 0x");
105 for(int pos = FIELD_64BITS_WORDS - 1; pos >= 0; pos--) {
106 fprintf(fptr, "%016lX", j0.re[pos]);
107 }
108 fprintf(fptr, ";\n// Im := 0x");
109 for(int pos = FIELD_64BITS_WORDS - 1; pos >= 0; pos--) {
110 fprintf(fptr, "%016lX", j0.im[pos]);
111 }
112 fprintf(fptr, ";\n");
113 fprintf(fptr, "// j-invariant (from 287496 to j1):\n");
114 fprintf(fptr, "// Re := 0x");
115 for(int pos = FIELD_64BITS_WORDS - 1; pos >= 0; pos--) {
116 fprintf(fptr, "%016lX", j1.re[pos]);
117 }
118 fprintf(fptr, ";\n// Im := 0x");
119 for(int pos = FIELD_64BITS_WORDS - 1; pos >= 0; pos--) {
120 fprintf(fptr, "%016lX", j1.im[pos]);
121 }
122 fprintf(fptr, ";\n");
123 fprintf(fptr, "clear;\np := 0x");
124 for(int pos = FIELD_64BITS_WORDS - 1; pos >= 0; pos--) {
125 fprintf(fptr, "%016lX", FIELD_CHARACTERISTIC[pos]);
126 }
127
128 fprintf(fptr, ";\n");
129 fprintf(fptr, "fp := GF(p);\n");
130 fprintf(fptr, "_<x> := PolynomialRing(fp);\n");
131 fprintf(fptr, "fp2<i>:= ext<fp | x^2 + 1>;\n");
132
133 fp2_t temp;
134 fp2_from_mont(&temp, j_invariant);
135 fprintf(fptr, "Re := 0x");
136 for(int pos = FIELD_64BITS_WORDS - 1; pos >= 0; pos--) {
137 fprintf(fptr, "%016lX", temp.re[pos]);
138 }
139 fprintf(fptr, ";\nIm := 0x");
140 for(int pos = FIELD_64BITS_WORDS - 1; pos >= 0; pos--) {
141 fprintf(fptr, "%016lX", temp.im[pos]);
142 }
143 fprintf(fptr, ";\n");
144 fprintf(fptr, "assert(IsZero(Random(EllipticCurveFromjInvariant(fp2![Re, Im])) * (p + 1)) or IsZero(Random(EllipticCurveFromjInvariant(fp2![Re, Im])) * (p - 1)));\n\n");
145 fclose(fptr);
146 // ++++++++++++++++++++++++++++++++++++
147
148 return MUNIT_OK;
149}
150
151static MunitResult trit_string(MUNIT_UNUSED const MunitParameter params[], MUNIT_UNUSED void *user_data_or_fixture) {
152 int32_t value_equality, expected_value = 0x00000000;
153 uint8_t path[TRITLENGTH_PATH / 5] = {0};
154
156
157 uint8_t bound = 0xF3;
158 for(int i = 0; i < (TRITLENGTH_PATH / 5); i++) {
159 value_equality = issmaller((int32_t)bound, (int32_t)(path[i]));
160 assert_memory_equal(sizeof(uint8_t), &value_equality, &expected_value);
161 }
162
163 return MUNIT_OK;
164}
165
166static MunitResult degree_3(MUNIT_UNUSED const MunitParameter params[], MUNIT_UNUSED void *user_data_or_fixture) {
167 fp2_t A, t, xP[4], zero;
168 fp2_set_to_zero(&zero);
169 fp2_set_to_one(&t);
170 fp2_add(&A, t, t);
171 fp2_add(&A, A, t);
172 fp2_add(&A, A, A);
173
175
176 fp2_t xP_squared, A_times_xP, temporal, auxiliar, six;
177 fp2_add(&six, t, t);
178 fp2_add(&six, six, t);
179 fp2_add(&six, six, six);
180
181 // Testing A = 6
182 for(int i = 0; i < 4; i++) {
183 fp2_sqr(&xP_squared, xP[i]);
184 fp2_add(&temporal, xP_squared, xP_squared);
185 fp2_add(&temporal, temporal, xP_squared);
186
187 fp2_mul(&A_times_xP, A, xP[i]);
188 fp2_add(&auxiliar, A_times_xP, A_times_xP);
189 fp2_add(&auxiliar, auxiliar, auxiliar);
190
191 fp2_add(&temporal, temporal, auxiliar);
192 fp2_add(&temporal, temporal, six);
193 fp2_mul(&temporal, xP_squared, temporal);
194 fp2_sub(&temporal, temporal, t);
195
196 assert_memory_equal(sizeof(fp2_t), &temporal, &zero); // temporal must be zero
197 }
198
199 fp2_t a1, a3;
200
201 // Each byte determines a coefficient in [0, 3^5 - 1]. Thus, it determines five trits
202 uint8_t path[TRITLENGTH_PATH / 5] = {0};
203 RANDOM_TRIT_STRING(path);
204 uint32_t trit_string[TRITLENGTH_PATH / 5] = {0};
205 to_trit_string(trit_string, path, TRITLENGTH_PATH / 5);
206
207 isogeny_walks_from_montgomery_model_3(&a1, &a3, A, xP[0]); // For simplicity we take the first x-coordinate point
208 isogeny_walks_3(&a1, &a3, a1, a3, path, TRITLENGTH_PATH / 5);
209
210 fp2_t j_invariant;
212
213 // ++++++++++++++++++++++++++++++++++++
214 // Test through magma script generated:
215 // If you have installed magma on your machine, run: magma TEST-[FIELD_NAME]-deg3.log
216 // Else, copy/paste the content of TEST-[FIELD_NAME]-deg3.log in online magma calculator (http://magma.maths.usyd.edu.au/calc/)
217 // Remark. Take into account that the online calculator has a limit buffer.
218
219 char file_name[256];
220 strcpy(file_name, "TEST-");
221 strcat(file_name, FIELD_NAME);
222 strcat(file_name, "-deg3.log");
223
224 FILE *fptr = fopen(file_name, "a");
225 if (fptr == NULL) {
226 printf("Could not open file");
227 return 0;
228 }
229
230 file_print_bytes(fptr, "// PATH (Hexadecimal): ", path, TRITLENGTH_PATH / 5);
231 fprintf(fptr, "// PATH (TRIT string): ");
232 for(int i = 0; i < (TRITLENGTH_PATH / 5); i++) {
233 fprintf(fptr, "%05X", trit_string[i]);
234 }
235 fprintf(fptr, "\n// Montgomery Curve Coefficient (A): 6\n");
236 fprintf(fptr, "// x-coordinate point (xP): First root deterministically chosen\n");
237 fprintf(fptr, "clear;\np := 0x");
238 for(int pos = FIELD_64BITS_WORDS - 1; pos >= 0; pos--) {
239 fprintf(fptr, "%016lX", FIELD_CHARACTERISTIC[pos]);
240 }
241 fprintf(fptr, ";\n");
242 fprintf(fptr, "fp := GF(p);\n");
243 fprintf(fptr, "_<x> := PolynomialRing(fp);\n");
244 fprintf(fptr, "fp2<i>:= ext<fp | x^2 + 1>;\n");
245
246 fp2_t temp;
247 fp2_from_mont(&temp, j_invariant);
248 fprintf(fptr, "Re := 0x");
249 for(int pos = FIELD_64BITS_WORDS - 1; pos >= 0; pos--) {
250 fprintf(fptr, "%016lX", temp.re[pos]);
251 }
252 fprintf(fptr, ";\nIm := 0x");
253 for(int pos = FIELD_64BITS_WORDS - 1; pos >= 0; pos--) {
254 fprintf(fptr, "%016lX", temp.im[pos]);
255 }
256 fprintf(fptr, ";\n");
257 fprintf(fptr, "assert(IsZero(Random(EllipticCurveFromjInvariant(fp2![Re, Im])) * (p + 1)) or IsZero(Random(EllipticCurveFromjInvariant(fp2![Re, Im])) * (p - 1)));\n\n");
258 fclose(fptr);
259 // ++++++++++++++++++++++++++++++++++++
260
261 return MUNIT_OK;
262}
263
264static void print_fp(const fp_t input, char* s){
265 fp_t aux;
266 fp_from_mont(aux, input);
267 printf("%s = 0x", s);
268 for(int i = FIELD_64BITS_WORDS -1; i >= 0; i--){
269 printf("%016lX", aux[i]);
270 }
271 printf(";\n");
272}
273
274static MunitResult degree_3_fp(MUNIT_UNUSED const MunitParameter params[], MUNIT_UNUSED void *user_data_or_fixture) {
275 if((FIELD_BITS == 381) || (FIELD_BITS == 575) || (FIELD_BITS == 765)){
276 return MUNIT_SKIP;
277 }
278 fp_t input = {6, 0, 0, 0};
279 fp_to_mont(input, input);
280
281 fp_t A;
282 fp_copy(A, input);
283 for(int value = 0; value < 128; value++) {
284 isogeny_walks_3_fp(A, A, value);
285 }
286
287 for(int value = 0; value < 128; value++) {
288 isogeny_walks_3_fp(A, A, -value);
289 }
290
291 assert_memory_equal(sizeof(fp_t), &input, &A);
292
293 return MUNIT_OK;
294}
295
296
297/*
298 * Register test cases
299 */
300
302 TEST_CASE(mul_by_small_constants),
303 TEST_CASE(degree_2),
304 TEST_CASE(trit_string),
305 TEST_CASE(degree_3),
306 TEST_CASE(degree_3_fp),
308};
void fp2_set_to_zero(fp2_t *output)
Definition fp2.c:54
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_set_to_one(fp2_t *output)
Definition fp2.c:49
void isogeny_walks_from_montgomery_model_3(fp2_t *output_a1, fp2_t *output_a3, fp2_t input_A, fp2_t input_xP)
void isogeny_walks_3(fp2_t *output_a1, fp2_t *output_a3, fp2_t input_a1, fp2_t input_a3, const uint8_t *input_path, size_t input_length)
void isogeny_walks_get_points_3(fp2_t *output, fp2_t input_A)
void fp2_mul_by_2532192(fp2_t *output, fp2_t input)
void isogeny_walks_2_slow(fp2_t *j0, fp2_t *j1, fp2_t input_prev, fp2_t input, const uint8_t *input_path, size_t input_length)
void fp2_mul_by_1488(fp2_t *output, fp2_t input)
void isogeny_walks_switch_from_model_3(fp2_t *output_j, fp2_t input_a1, fp2_t input_a3)
void isogeny_walks_2(fp2_t *output, fp2_t input_prev, fp2_t input, const uint8_t *input_path, size_t input_length)
void isogeny_walks_sample_trit_string(uint8_t *output)
void fp2_mul_by_645205500(fp2_t *output, fp2_t input)
void isogeny_walks_3_fp(fp_t output_A, const fp_t input_A, int input_length)
void fp2_mul_by_8748000000(fp2_t *output, fp2_t input)
void fp2_mul_by_324000(fp2_t *output, fp2_t input)
void fp2_mul_by_2976(fp2_t *output, fp2_t input)
void fp2_mul_by_162000(fp2_t *output, fp2_t input)
#define fp_copy
Definition fp-gmp.h:79
void fp_to_mont(fp_t output, const fp_t input)
Definition fp.c:99
void fp_from_mont(fp_t output, const fp_t input)
Definition fp.c:104
uint64_t fp_t[FIELD_64BITS_WORDS]
Definition fp.h:12
den a3
#define MUNIT_UNUSED
Definition munit.h:136
MunitResult
Definition munit.h:415
@ MUNIT_SKIP
Definition munit.h:421
@ MUNIT_OK
Definition munit.h:417
A
Definition tests.py:29
#define TRITLENGTH_PATH
Definition p254.h:15
#define FIELD_NAME
Definition p254.h:6
#define FIELD_64BITS_WORDS
Definition p254.h:9
#define FIELD_BITS
Definition p254.h:7
#define BIT_LENGTH_PATH
Definition p254.h:14
for i
Definition fp2.h:10
fp_t re
Definition fp2.h:11
fp_t im
Definition fp2.h:12
MunitTest test_isogeny_walks[]
#define RANDOM_BIT_STRING(out)
Definition test_utils.h:58
#define TEST_END
Definition test_utils.h:11
#define RANDOM_TRIT_STRING(out)
Definition test_utils.h:64
#define TEST_CASE(test_func)
Definition test_utils.h:19
g a1
Definition to_model.m:15
f a
Definition to_model.m:12