Let us walk on the 3-isogeny graph
Loading...
Searching...
No Matches
fp2.c File Reference
#include <string.h>
#include "fp2.h"
#include "utilities.h"
Include dependency graph for fp2.c:

Go to the source code of this file.

Functions

void fp2_add (fp2_t *output, fp2_t input_a, fp2_t input_b)
void fp2_sub (fp2_t *output, fp2_t input_a, fp2_t input_b)
void fp2_mul (fp2_t *output, fp2_t input_a, fp2_t input_b)
void fp2_sqr (fp2_t *output, fp2_t input)
void fp2_neg (fp2_t *output, fp2_t input)
void fp2_set_to_one (fp2_t *output)
void fp2_set_to_zero (fp2_t *output)
void fp2_copy (fp2_t *output, fp2_t input)
void fp2_cswap (fp2_t *input_a, fp2_t *input_b, uint64_t input)
void fp2_cset (fp2_t *output, fp2_t input, uint64_t input_mask)
void fp2_inv (fp2_t *output, fp2_t input)
void fp2_half (fp2_t *output, fp2_t input)
void fp2_to_mont (fp2_t *output, fp2_t input)
void fp2_from_mont (fp2_t *output, fp2_t input)
void fp2_conj (fp2_t *output, fp2_t input)
void fp2_to_bytes (uint8_t *output, fp2_t input)
void fp2_element_from_bytes (fp2_t *output, const uint8_t *input)
int64_t fp2_is_zero (fp2_t input)
uint8_t fp2_is_equal (fp2_t input_a, fp2_t input_b)
void fp2_linear_pass_in (fp2_t *output, const fp2_t *input, uint8_t input_length, uint8_t input_index)
void fp2_linear_pass_out (fp2_t *output, fp2_t input, uint8_t input_length, uint8_t input_index)
uint8_t fp2_locate_zero (const fp2_t *input, uint8_t input_length)
uint8_t fp2_is_square (fp2_t input)
void fp2_batchinv (fp2_t *output_list, const fp2_t *input_list, uint8_t input_length)
void fp2_sqrt_slow (fp2_t *output, fp2_t input)
void fp2_sqrt_fast (fp2_t *output, fp2_t input)
void fp2_curt (fp2_t *output, fp2_t input)

Function Documentation

◆ fp2_add()

void fp2_add ( fp2_t * output,
fp2_t input_a,
fp2_t input_b )

Definition at line 10 of file fp2.c.

10 {
11 fp_add(output->re, input_a.re, input_b.re);
12 fp_add(output->im, input_a.im, input_b.im);
13}
#define fp_add
Definition fp-gmp.h:64
fp_t re
Definition fp2.h:11
fp_t im
Definition fp2.h:12

References fp_add, fp2_t::im, and fp2_t::re.

◆ fp2_batchinv()

void fp2_batchinv ( fp2_t * output_list,
const fp2_t * input_list,
uint8_t input_length )

Definition at line 202 of file fp2.c.

202 {
203 int i;
204 fp2_t tmp_list[input_length], inv, tmp;
205
206 fp2_copy(&tmp_list[0], input_list[0]);
207 for(i = 1; i < input_length; i++) { fp2_mul(&tmp_list[i], tmp_list[i - 1], input_list[i]); }
208 fp2_inv(&inv, tmp_list[input_length - 1]);
209 for(i = (input_length - 1); i > 0; i--) {
210 fp2_mul(&tmp, inv, tmp_list[i - 1]);
211 fp2_mul(&inv, inv, input_list[i]);
212 fp2_copy(&output_list[i], tmp);
213 }
214 fp2_copy(&output_list[0], inv);
215}
for i
Definition fp2.h:10

References fp2_copy, fp2_inv, fp2_mul, and i.

◆ fp2_conj()

void fp2_conj ( fp2_t * output,
fp2_t input )

Definition at line 125 of file fp2.c.

125 {
126 fp_copy(output->re, input.re);
127 fp_neg(output->im, input.im);
128}
#define fp_copy
Definition fp-gmp.h:79
void fp_neg(fp_t output, const fp_t input)
Definition fp.c:9

References fp_copy, fp_neg(), fp2_t::im, and fp2_t::re.

Here is the call graph for this function:

◆ fp2_copy()

void fp2_copy ( fp2_t * output,
fp2_t input )

Definition at line 59 of file fp2.c.

59 {
60 fp_copy(output->re, input.re);
61 fp_copy(output->im, input.im);
62}

References fp_copy, fp2_t::im, and fp2_t::re.

◆ fp2_cset()

void fp2_cset ( fp2_t * output,
fp2_t input,
uint64_t input_mask )

Definition at line 81 of file fp2.c.

81 {
82 // If mask = 0 then output is not modified, else if input = 0xFF...FF then output <- input
83 uint64_t temp;
84 unsigned int i;
85
86 for (i = 0; i < FIELD_64BITS_WORDS; i++) {
87 temp = input_mask & (output->re[i] ^ input.re[i]);
88 output->re[i] = temp ^ output->re[i];
89 temp = input_mask & (output->im[i] ^ input.im[i]);
90 output->im[i] = temp ^ output->im[i];
91 }
92}
#define FIELD_64BITS_WORDS
Definition p254.h:9

References FIELD_64BITS_WORDS, i, fp2_t::im, and fp2_t::re.

Referenced by fp2_linear_pass_in(), and fp2_linear_pass_out().

Here is the caller graph for this function:

◆ fp2_cswap()

void fp2_cswap ( fp2_t * input_a,
fp2_t * input_b,
uint64_t input )

Definition at line 65 of file fp2.c.

65 {
66 // If input = 0 then a <- a and b <- b, else if input = 0xFF...FF then a <- b and b <- a
67 uint64_t temp;
68 unsigned int i;
69
70 for (i = 0; i < FIELD_64BITS_WORDS; i++) {
71 temp = input & (input_a->re[i] ^ input_b->re[i]);
72 input_a->re[i] = temp ^ input_a->re[i];
73 input_b->re[i] = temp ^ input_b->re[i];
74 temp = input & (input_a->im[i] ^ input_b->im[i]);
75 input_a->im[i] = temp ^ input_a->im[i];
76 input_b->im[i] = temp ^ input_b->im[i];
77 }
78}

References FIELD_64BITS_WORDS, i, fp2_t::im, and fp2_t::re.

◆ fp2_curt()

void fp2_curt ( fp2_t * output,
fp2_t input )

Definition at line 399 of file fp2.c.

399 {
400 // This function assumes the input has cube-root
401 int i, j, k;
402 uint64_t flag;
403 fp2_t temp, aux;
404 fp2_set_to_one(&aux);
405 fp2_copy(&temp, input);
406
407 for (i = 0, k = 0; i < 2 * FIELD_64BITS_WORDS && k < CUBE_ROOT_EXPONENT_BITS; i++, k++) {
408 flag = 1;
409 for (j = 0; j < 64; j++, k++) {
410 if ((flag & CUBE_ROOT_EXPONENT[i]) != 0) {fp2_mul(&aux, temp, aux);}
411 fp2_sqr(&temp, temp);
412 flag <<= 1;
413 }
414 }
415
416 fp2_copy(output, aux);
417}
void fp2_set_to_one(fp2_t *output)
Definition fp2.c:49
#define CUBE_ROOT_EXPONENT_BITS
Definition p254.h:59
for j

References CUBE_ROOT_EXPONENT_BITS, FIELD_64BITS_WORDS, fp2_copy, fp2_mul, fp2_set_to_one(), fp2_sqr, i, and j.

Referenced by isogeny_walks_3(), and isogeny_walks_get_points_3().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ fp2_element_from_bytes()

void fp2_element_from_bytes ( fp2_t * output,
const uint8_t * input )

Definition at line 140 of file fp2.c.

140 {
141 output->re[FIELD_64BITS_WORDS - 1] = 0;
142 memcpy(output->re, input, FIELD_BYTES);
143 output->im[FIELD_64BITS_WORDS - 1] = 0;
144 memcpy(output->im, &input[FIELD_BYTES], FIELD_BYTES);
145 fp2_to_mont(output, *output);
146}
void fp2_to_mont(fp2_t *output, fp2_t input)
Definition fp2.c:113
#define FIELD_BYTES
Definition p254.h:8

References FIELD_64BITS_WORDS, FIELD_BYTES, and fp2_to_mont().

Here is the call graph for this function:

◆ fp2_from_mont()

void fp2_from_mont ( fp2_t * output,
fp2_t input )

Definition at line 119 of file fp2.c.

119 {
120 fp_from_mont(output->re, input.re);
121 fp_from_mont(output->im, input.im);
122}
void fp_from_mont(fp_t output, const fp_t input)
Definition fp.c:104

References fp_from_mont(), fp2_t::im, and fp2_t::re.

Referenced by fp2_to_bytes().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ fp2_half()

void fp2_half ( fp2_t * output,
fp2_t input )

Definition at line 107 of file fp2.c.

107 {
108 fp_half(output->re, input.re);
109 fp_half(output->im, input.im);
110}
void fp_half(fp_t output, const fp_t input)
Definition fp.c:84

References fp_half(), fp2_t::im, and fp2_t::re.

Referenced by isogeny_walks_2(), isogeny_walks_2_slow(), and isogeny_walks_get_points_3().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ fp2_inv()

void fp2_inv ( fp2_t * output,
fp2_t input )

Definition at line 95 of file fp2.c.

95 {
96 fp_t N0, N1, S1, S2, zero = {0};
97 fp_sqr(N0, input.re);
98 fp_sqr(N1, input.im);
99 fp_add(S1, N0, N1);
100 fp_inv(S1, S1);
101 fp_sub(S2, zero, input.im);
102 fp_mul(output->re, S1, input.re);
103 fp_mul(output->im, S1, S2);
104}
#define fp_sqr
Definition fp-gmp.h:73
#define fp_sub
Definition fp-gmp.h:67
#define fp_mul
Definition fp-gmp.h:70
#define fp_inv
Definition fp-gmp.h:88
uint64_t fp_t[FIELD_64BITS_WORDS]
Definition fp.h:12

References fp_add, fp_inv, fp_mul, fp_sqr, fp_sub, fp2_t::im, and fp2_t::re.

◆ fp2_is_equal()

uint8_t fp2_is_equal ( fp2_t input_a,
fp2_t input_b )

Definition at line 154 of file fp2.c.

154 {
155 return fp_is_equal(input_a.re, input_b.re) & fp_is_equal(input_a.im, input_b.im);
156}
uint8_t fp_is_equal(const fp_t input_a, const fp_t input_b)
Definition fp.c:122

References fp_is_equal(), fp2_t::im, and fp2_t::re.

Here is the call graph for this function:

◆ fp2_is_square()

uint8_t fp2_is_square ( fp2_t input)

Definition at line 192 of file fp2.c.

192 {
193 fp_t t0, t1;
194
195 fp_sqr(t0, input.re);
196 fp_sqr(t1, input.im);
197 fp_add(t0, t0, t1);
198 return fp_is_square(t0);
199}
uint8_t fp_is_square(const fp_t input)
Definition fp.c:148

References fp_add, fp_is_square(), fp_sqr, fp2_t::im, and fp2_t::re.

Here is the call graph for this function:

◆ fp2_is_zero()

int64_t fp2_is_zero ( fp2_t input)

Definition at line 149 of file fp2.c.

149 {
150 return fp_is_zero(input.re) & fp_is_zero(input.im);
151}
int64_t fp_is_zero(const fp_t input)
Definition fp.c:112

References fp_is_zero(), fp2_t::im, and fp2_t::re.

Referenced by fp2_locate_zero().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ fp2_linear_pass_in()

void fp2_linear_pass_in ( fp2_t * output,
const fp2_t * input,
uint8_t input_length,
uint8_t input_index )

Definition at line 159 of file fp2.c.

159 {
160 // This function copies the ith entry of the input into the output
161 // At most 255-length lists
162 uint8_t i;
163 for(i = 0; i < input_length; i++) {
164 int64_t mask = (int64_t)input_index - (int64_t)i;
165 fp2_cset(output, input[i], ~((mask >> 63) | (-mask >> 63)));
166 }
167}
void fp2_cset(fp2_t *output, fp2_t input, uint64_t input_mask)
Definition fp2.c:81

References fp2_cset(), and i.

Referenced by fp2_sqrt_slow(), isogeny_walks_2(), isogeny_walks_2_slow(), and isogeny_walks_3().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ fp2_linear_pass_out()

void fp2_linear_pass_out ( fp2_t * output,
fp2_t input,
uint8_t input_length,
uint8_t input_index )

Definition at line 170 of file fp2.c.

170 {
171 // This function copies the input into the ith entry of the output
172 // At most 255-length lists
173 uint8_t i;
174 for(i = 0; i < input_length; i++) {
175 int64_t mask = (int64_t)input_index - (int64_t)i;
176 fp2_cset(&output[i], input, ~((mask >> 63) | (-mask >> 63)));
177 }
178}

References fp2_cset(), and i.

Here is the call graph for this function:

◆ fp2_locate_zero()

uint8_t fp2_locate_zero ( const fp2_t * input,
uint8_t input_length )

Definition at line 181 of file fp2.c.

181 {
182 // At most 255-length lists
183 uint8_t i;
184 int64_t index = 0;
185 for(i = 0; i < input_length; i++) {
186 index |= i & fp2_is_zero(input[i]);
187 }
188 return (uint8_t)index;
189}
int64_t fp2_is_zero(fp2_t input)
Definition fp2.c:149

References fp2_is_zero(), and i.

Here is the call graph for this function:

◆ fp2_mul()

void fp2_mul ( fp2_t * output,
fp2_t input_a,
fp2_t input_b )

Definition at line 21 of file fp2.c.

21 {
22 fp_t z0, z1, z2, z3, tmp;
23 fp_add(z0, input_a.re, input_a.im);
24 fp_add(z1, input_b.re, input_b.im);
25 fp_mul(tmp, z0, z1);
26 fp_mul(z2, input_a.re, input_b.re);
27 fp_mul(z3, input_a.im, input_b.im);
28 fp_sub(output->re, z2, z3);
29 fp_sub(output->im, tmp, z2);
30 fp_sub(output->im, output->im, z3);
31}

References fp_add, fp_mul, fp_sub, fp2_t::im, and fp2_t::re.

◆ fp2_neg()

void fp2_neg ( fp2_t * output,
fp2_t input )

Definition at line 43 of file fp2.c.

43 {
44 fp_neg(output->re, input.re);
45 fp_neg(output->im, input.im);
46}

References fp_neg(), fp2_t::im, and fp2_t::re.

Here is the call graph for this function:

◆ fp2_set_to_one()

void fp2_set_to_one ( fp2_t * output)

Definition at line 49 of file fp2.c.

49 {
52}
void fp_set_to_zero(fp_t input_output)
Definition fp.c:19
void fp_set_to_one(fp_t input_output)
Definition fp.c:14

References fp_set_to_one(), and fp_set_to_zero().

Referenced by fp2_curt(), fp2_sqrt_slow(), isogeny_walks_2(), isogeny_walks_2_slow(), isogeny_walks_3(), isogeny_walks_from_montgomery_model_2(), isogeny_walks_from_montgomery_model_3(), isogeny_walks_get_previous_step_2(), and main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ fp2_set_to_zero()

void fp2_set_to_zero ( fp2_t * output)

Definition at line 54 of file fp2.c.

54 {
57}

References fp_set_to_zero().

Referenced by cgl_hash_digest_2(), cgl_hash_digest_3(), fp2_sqrt_slow(), and main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ fp2_sqr()

void fp2_sqr ( fp2_t * output,
fp2_t input )

Definition at line 33 of file fp2.c.

33 {
34 fp_t z0, z1, z2;
35 fp_add(z0, input.re, input.re);
36 fp_add(z1, input.re, input.im);
37 fp_sub(z2, input.re, input.im);
38 fp_mul(output->re, z1, z2);
39 fp_mul(output->im, z0, input.im);
40}

References fp_add, fp_mul, fp_sub, fp2_t::im, and fp2_t::re.

◆ fp2_sqrt_fast()

void fp2_sqrt_fast ( fp2_t * output,
fp2_t input )

Definition at line 333 of file fp2.c.

333 {
334 fp_t delta, x0, t0, x1, t1, temp;
335 uint64_t flag;
336
337 // x1 <- (a0^2 + a1^2)
338 fp_sqr(x0, input.re);
339 fp_sqr(x1, input.im);
340 fp_add(x1, x0, x1);
341
342 // alpha <- x1 ^ ([p + 1] / 4)
343 fp_set_to_one(delta);
344 fp_copy(temp, x1);
345 for (int i = 0; i < FIELD_64BITS_WORDS; i++) {
346 flag = 1;
347 for (int j = 0; j < 64; j++) {
348 if ((flag & SQUARE_ROOT_EXPONENT_14[i]) != 0)
349 fp_mul(delta, temp, delta);
350 fp_sqr(temp, temp);
351 flag <<= 1;
352 }
353 }
354
355 // x0 <- a0 + delta
356 fp_add(x0, input.re, delta);
357 // t0 <- 2 * x0
358 fp_add(t0, x0, x0);
359
360 // x1 <- t0 ^ ([p - 3] / 4)
361 fp_set_to_one(x1);
362 fp_copy(temp, t0);
363 for (int i = 0; i < FIELD_64BITS_WORDS; i++) {
364 flag = 1;
365 for (int j = 0; j < 64; j++) {
366 if ((flag & SQUARE_ROOT_EXPONENT_34[i]) != 0)
367 fp_mul(x1, temp, x1);
368 fp_sqr(temp, temp);
369 flag <<= 1;
370 }
371 }
372
373 // x0 <- x0 * x1
374 fp_mul(x0, x0, x1);
375 // x1 <- a1 * x1
376 fp_mul(x1, input.im, x1);
377
378 // t1 <- (2 * x0)^2
379 fp_add(t1, x0, x0);
380 fp_sqr(t1, t1);
381
382 fp_t uno, zero;
383 fp_set_to_one(uno);
384 fp_set_to_zero(zero);
385
386 uint8_t selector = -fp_is_equal(t1, t0);
387
388 fp_neg(temp, x0);
389 fp_copy(t0, x1);
390 fp_copy(t1, temp);
391
392 constant_time_conditional_mov((uint8_t *)&t0, (uint8_t *)&x0, FIELD_64BITS_WORDS * 8, selector);
393 constant_time_conditional_mov((uint8_t *)&t1, (uint8_t *)&x1, FIELD_64BITS_WORDS * 8, selector);
394
395 fp_copy(output->re, t0);
396 fp_copy(output->im, t1);
397}
void constant_time_conditional_mov(uint8_t *output, const uint8_t *input, uint64_t input_length, uint8_t input_selector)
Definition utilities.c:74

References constant_time_conditional_mov(), FIELD_64BITS_WORDS, fp_add, fp_copy, fp_is_equal(), fp_mul, fp_neg(), fp_set_to_one(), fp_set_to_zero(), fp_sqr, i, fp2_t::im, j, and fp2_t::re.

Referenced by isogeny_walks_2().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ fp2_sqrt_slow()

void fp2_sqrt_slow ( fp2_t * output,
fp2_t input )

Definition at line 283 of file fp2.c.

283 {
284 // Square root over Fq with q = p²: Kong et al.'s algorithm. We assume p² = 9 mod 16 and p = 3 mod 4
285 // This function assumes the input has square-root
286
287 int i, j, k;
288 uint64_t flag;
289 fp_t one;
290 fp2_t a_double, b, b_square, c, r, temp, s[2], u;
291
292 fp_set_to_one(one);
293
294 fp2_set_to_one(&b);
295 fp2_add(&a_double, input, input);
296 fp2_copy(&temp, a_double);
297
298 for (i = 0, k = 0; i < 2 * FIELD_64BITS_WORDS && k < SQUARE_ROOT_EXPONENT_BITS; i++, k++) {
299 flag = 1;
300 for (j = 0; j < 64; j++, k++) {
301 if ((flag & SQUARE_ROOT_EXPONENT_916[i]) != 0) {fp2_mul(&b, temp, b);}
302 fp2_sqr(&temp, temp);
303 flag <<= 1;
304 }
305 }
306 fp2_sqr(&b_square, b);
307 fp2_mul(&c, a_double, b_square);
308 fp2_sqr(&r, c);
309 fp_sub(c.re, c.re, one); // c - 1
310
311 fp2_mul(&s[0], input, b);
312 fp2_mul(&s[0], s[0], c);
313 fp2_mul(&u, b, *((fp2_t *)&SQUARE_ROOT_CONSTANT_T));
314 fp2_mul(&s[1], u, *((fp2_t *)&SQUARE_ROOT_CONSTANT_D));
315
316 fp2_sqr(&c, s[1]);
317 fp2_mul(&c, c, input);
318 fp2_add(&c, c, c);
319 fp_sub(c.re, c.re, one); // c - 1
320 fp2_mul(&s[1], s[1], input);
321 fp2_mul(&s[1], s[1], c);
322
323 // select the correct square-root output by linear pass (constant-time)
324 fp2_linear_pass_in(output, s, 2, fp_is_equal(one, r.re) & fp_is_zero(r.im));
325
326 // clear data
327 fp2_set_to_zero(&s[0]);
328 fp2_set_to_zero(&s[1]);
329 fp2_set_to_zero(&temp);
330}
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
#define SQUARE_ROOT_EXPONENT_BITS
Definition p255.h:72

References FIELD_64BITS_WORDS, fp2_add, fp2_copy, fp2_linear_pass_in(), fp2_mul, fp2_set_to_one(), fp2_set_to_zero(), fp2_sqr, fp_is_equal(), fp_is_zero(), fp_set_to_one(), fp_sub, i, fp2_t::im, j, fp2_t::re, and SQUARE_ROOT_EXPONENT_BITS.

Referenced by isogeny_walks_2_slow(), and isogeny_walks_get_points_3().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ fp2_sub()

void fp2_sub ( fp2_t * output,
fp2_t input_a,
fp2_t input_b )

Definition at line 16 of file fp2.c.

16 {
17 fp_sub(output->re, input_a.re, input_b.re);
18 fp_sub(output->im, input_a.im, input_b.im);
19}

References fp_sub, fp2_t::im, and fp2_t::re.

◆ fp2_to_bytes()

void fp2_to_bytes ( uint8_t * output,
fp2_t input )

Definition at line 131 of file fp2.c.

131 {
132 fp2_t t;
133
134 fp2_from_mont(&t, input);
135 memcpy(output, t.re, FIELD_BYTES);
136 memcpy(&output[FIELD_BYTES], t.im, FIELD_BYTES);
137}
void fp2_from_mont(fp2_t *output, fp2_t input)
Definition fp2.c:119

References FIELD_BYTES, fp2_from_mont(), fp2_t::im, and fp2_t::re.

Here is the call graph for this function:

◆ fp2_to_mont()

void fp2_to_mont ( fp2_t * output,
fp2_t input )

Definition at line 113 of file fp2.c.

113 {
114 fp_to_mont(output->re, input.re);
115 fp_to_mont(output->im, input.im);
116}
void fp_to_mont(fp_t output, const fp_t input)
Definition fp.c:99

References fp_to_mont(), fp2_t::im, and fp2_t::re.

Referenced by fp2_element_from_bytes().

Here is the call graph for this function:
Here is the caller graph for this function: