Let us walk on the 3-isogeny graph
Loading...
Searching...
No Matches
fp.c
Go to the documentation of this file.
1//
2// Prime field arithmetic GF(p)
3//
4
5#include <string.h>
6#include "fp.h"
7#include "utilities.h"
8
9void fp_neg(fp_t output, const fp_t input) {
10 fp_t zero = {0};
11 fp_sub(output, zero, input);
12}
13
14void fp_set_to_one(fp_t input_output) {
15 fp_copy(input_output, MONTGOMERY_CONSTANT_ONE);
16}
17
18
19void fp_set_to_zero(fp_t input_output) {
20 memset(input_output, 0, sizeof(fp_t));
21}
22
23
24void fp_copy(fp_t output, const fp_t input) {
25 memcpy(output, input, sizeof(fp_t));
26}
27
28void fp_cset(fp_t output, const fp_t input, uint64_t input_mask) {
29 // If mask = 0 then output is not modified, else if input = 0xFF...FF then output <- input
30 uint64_t temp;
31 unsigned int i;
32
33 for (i = 0; i < FIELD_64BITS_WORDS; i++) {
34 temp = input_mask & (output[i] ^ input[i]);
35 output[i] = temp ^ output[i];
36 }
37}
38
39void fp_cswap(fp_t input_a, fp_t input_b, uint64_t input) {
40 // If input = 0 then a <- a and b <- b, else if input = 0xFF...FF then a <- b and b <- a
41 uint64_t temp;
42 unsigned int i;
43
44 for (i = 0; i < FIELD_64BITS_WORDS; i++) {
45 temp = input & (input_a[i] ^ input_b[i]);
46 input_a[i] = temp ^ input_a[i];
47 input_b[i] = temp ^ input_b[i];
48 }
49}
50
51void fp_sample(fp_t output) {
52 randombytes((uint8_t *) output, FIELD_BYTES);
54 while (!multiprecision_is_smaller(output, FIELD_CHARACTERISTIC, FIELD_64BITS_WORDS)) {
55 randombytes((uint8_t *) output, FIELD_BYTES);
57 }
58}
59
60
61// We should use Bernstein & Yang algorithm
62void fp_inv(fp_t output, const fp_t input) {
63
64 fp_t temp, out;
65 fp_set_to_one(out);
66 fp_copy(temp, input);
67
68 int i, j, k;
69 uint64_t flag;
70
71 for (i = 0, k = 0; i < FIELD_64BITS_WORDS && k < FIELD_BITS; i++, k++) {
72 flag = 1;
73 for (j = 0; j < 64; j++, k++) {
74 if ((flag & FIELD_INVERSION_EXPONENT[i]) != 0)
75 fp_mul(out, temp, out);
76 fp_sqr(temp, temp);
77 flag <<= 1;
78 }
79 }
80 fp_copy(output, out);
81}
82
83
84void fp_half(fp_t output, const fp_t input) {
85 uint8_t carry = 0;
86 int i;
87 uint64_t mask;
88
89 mask = 0 - (uint64_t) (input[0] & 1);
90 // If a is odd compute a + p
91 for (i = 0; i < FIELD_64BITS_WORDS; i++) {
92 addition_with_carry_u64(output[i], carry, carry, input[i], FIELD_CHARACTERISTIC[i] & mask);
93 }
94
96}
97
98
99void fp_to_mont(fp_t output, const fp_t input) {
100 fp_mul(output, input, (uint64_t *) &MONTGOMERY_CONSTANT_R_SQUARED);
101}
102
103
104void fp_from_mont(fp_t output, const fp_t input) {
105 fp_t one = {0};
106 one[0] = 1;
107 fp_mul(output, input, one);
108}
109
110
111// constant-time check of a == 0
112int64_t fp_is_zero(const fp_t input) {
113 int i;
114 uint64_t output = 0;
115 for (i = FIELD_64BITS_WORDS - 1; i >= 0; i--)
116 output |= input[i];
117
118 return ~(((int64_t)output >> 63) | (-(int64_t)output >> 63));
119}
120
121
122uint8_t fp_is_equal(const fp_t input_a, const fp_t input_b) {
123 int i;
124 uint8_t r = 0;
125 uint64_t t;
126
127 for (i = 0; i < FIELD_64BITS_WORDS; i++) {
128 t = 0;
129 uint8_t *ta = (uint8_t *) &input_a[i];
130 uint8_t *tb = (uint8_t *) &input_b[i];
131 t = (ta[0] ^ tb[0]) | (ta[1] ^ tb[1]) | (ta[2] ^ tb[2]) | (ta[3] ^ tb[3]) |
132 (ta[4] ^ tb[4]) | (ta[5] ^ tb[5]) | (ta[6] ^ tb[6]) | (ta[7] ^ tb[7]);
133
134 t = (-t);
135 t = t >> 63;
136 r |= t;
137 }
138
139 return (uint8_t) (1 - r);
140}
141
142
143uint8_t fp_is_smaller(const fp_t input1, const fp_t input2) {
144 return multiprecision_is_smaller(input1, input2, FIELD_64BITS_WORDS);
145}
146
147
148uint8_t fp_is_square(const fp_t input) {
149 fp_t temp, input_1;
150 uint64_t flag;
151 int i, j;
152 // input_1 <- input ^ ([p - 1] / 2)
153 fp_set_to_one(input_1);
154 fp_copy(temp, input);
155 for (i = 0; i < FIELD_64BITS_WORDS; i++) {
156 flag = 1;
157 for (j = 0; j < 64; j++) {
158 if ((flag & SQUARE_ROOT_EXPONENT_12[i]) != 0)
159 fp_mul(input_1, temp, input_1);
160 fp_sqr(temp, temp);
161 flag <<= 1;
162 }
163 }
164
165 return fp_is_equal(input_1, MONTGOMERY_CONSTANT_ONE);
166}
167
168void fp_sqrt(fp_t output, const fp_t input) {
169 fp_t temp, input_1;
170 uint64_t flag;
171 int i, j;
172 // input_1 <- input ^ ([p - 3] / 4)
173 fp_set_to_one(input_1);
174 fp_copy(temp, input);
175 for (i = 0; i < FIELD_64BITS_WORDS; i++) {
176 flag = 1;
177 for (j = 0; j < 64; j++) {
178 if ((flag & SQUARE_ROOT_EXPONENT_34[i]) != 0)
179 fp_mul(input_1, temp, input_1);
180 fp_sqr(temp, temp);
181 flag <<= 1;
182 }
183 }
184 fp_mul(output, input_1, input);
185}
186
187#ifdef SSEC_CUBE_ROOT_OVER_FP
188// Cube root when p = 2 mod 3
189void fp_curt(fp_t output, const fp_t input) {
190 fp_t temp, input_1;
191 uint64_t flag;
192 int i, j;
193 // input_1 <- input ^ -([p - 2] / 3)
194 fp_set_to_one(input_1);
195 fp_copy(temp, input);
196 for (i = 0; i < FIELD_64BITS_WORDS; i++) {
197 flag = 1;
198 for (j = 0; j < 64; j++) {
199 if ((flag & CUBE_ROOT_EXPONENT_213[i]) != 0)
200 fp_mul(input_1, temp, input_1);
201 fp_sqr(temp, temp);
202 flag <<= 1;
203 }
204 }
205 fp_copy(output, input_1);
206}
207#else
208// Cube root not implemented! (Not required)
209void fp_curt(fp_t output, const fp_t input) {
210 fp_copy(output, input);
211}
212#endif
void randombytes(void *x, size_t l)
Definition rng.c:8
#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
#define fp_copy
Definition fp-gmp.h:79
#define fp_cswap
Definition fp-gmp.h:82
int64_t fp_is_zero(const fp_t input)
Definition fp.c:112
void fp_sample(fp_t output)
Definition fp.c:51
void fp_curt(fp_t output, const fp_t input)
Definition fp.c:189
void fp_to_mont(fp_t output, const fp_t input)
Definition fp.c:99
void fp_neg(fp_t output, const fp_t input)
Definition fp.c:9
uint8_t fp_is_equal(const fp_t input_a, const fp_t input_b)
Definition fp.c:122
void fp_set_to_zero(fp_t input_output)
Definition fp.c:19
void fp_cset(fp_t output, const fp_t input, uint64_t input_mask)
Definition fp.c:28
void fp_half(fp_t output, const fp_t input)
Definition fp.c:84
void fp_from_mont(fp_t output, const fp_t input)
Definition fp.c:104
void fp_set_to_one(fp_t input_output)
Definition fp.c:14
void fp_sqrt(fp_t output, const fp_t input)
Definition fp.c:168
uint8_t fp_is_smaller(const fp_t input1, const fp_t input2)
Definition fp.c:143
uint8_t fp_is_square(const fp_t input)
Definition fp.c:148
uint64_t fp_t[FIELD_64BITS_WORDS]
Definition fp.h:12
#define FIELD_BYTES
Definition p254.h:8
#define FIELD_64BITS_WORDS
Definition p254.h:9
#define FIELD_BITS
Definition p254.h:7
#define MASK_FIELD_ELEMENT
Definition p254.h:11
for i
for j
void multiprecision_shift_to_right(uint64_t *input_a_output_shifted_a, uint64_t input_words_length)
Definition utilities.c:80
uint8_t multiprecision_is_smaller(const uint64_t *input_a, const uint64_t *input_b, uint64_t input_length)
Definition utilities.c:111
#define addition_with_carry_u64(output, output_carry, input_carry, input_a, input_b)
Definition utilities.h:34