Let us walk on the 3-isogeny graph
Loading...
Searching...
No Matches
fp-gmp.h
Go to the documentation of this file.
1#ifndef _FP_GMP_H_
2#define _FP_GMP_H_
3
4#include <stdbool.h>
5#include <stdio.h>
6#include <stdlib.h>
7#include <string.h>
8#include <immintrin.h>
9
10#include <assert.h>
11#include <inttypes.h>
12#include <stddef.h>
13
14#include "../../rng.h" // Random Number Generator
15// #include "framework.h"
16#include "../../namespace.h"
17#include "../fp-counters.h"
18#include "../../primes.h"
19
20// (64 x NUMBER_OF_WORDS)-bits integer number in Montgomery domain
21// #define NUMBER_OF_WORDS 64
22typedef uint64_t fp[NUMBER_OF_WORDS];
23
24// -------------------------------------
25// big unsigned add and sub implementation
26#define uintbig_1 COMMON(uintbig_1)
27extern const fp uintbig_1;
28
29#define r_squared_mod_p COMMON(r_squared_mod_p)
30extern const fp r_squared_mod_p;
31#define p_minus_2 COMMON(p_minus_2)
32extern const fp p_minus_2;
33#define inv_min_p_mod_r COMMON(inv_min_p_mod_r)
34extern const fp inv_min_p_mod_r;
35
36#define uintbig_bit COMMON(uintbig_bit)
37// bool uintbig_bit(fp const x, uint64_t k);
38#define uintbig_add COMMON(uintbig_add)
39bool uintbig_add(fp x, fp const y, fp const z); /* returns carry */
40#define uintbig_sub COMMON(uintbig_sub)
41bool uintbig_sub(fp x, fp const y, fp const z); /* returns borrow */
42
43// -------------------------------------
44#define p COMMON(p)
45extern const fp p; // field characteristic
46// extern const fp inv_min_p_mod_r;
47// extern const fp r_squared_mod_p;
48#define fp_1 COMMON(fp_1)
49extern const fp fp_1;
50#define fp_0 COMMON(fp_0)
51extern const fp fp_0;
52
53
54
55#define fp_enc COMMON(fp_enc)
56void fp_enc(fp a, fp const b); // from fp into Montgomery domain
57
58#define fp_dec COMMON(fp_dec)
59void fp_dec(fp a, fp const b); // from Montgomery domain into fp
60
61#define fp_pow COMMON(fp_pow)
62void fp_pow(fp b, const fp e, const fp a);
63
64#define fp_add COMMON(fp_add)
65void fp_add(fp c, const fp a, const fp b); // a + a
66
67#define fp_sub COMMON(fp_sub)
68void fp_sub(fp c, const fp a, const fp b);
69
70#define fp_mul COMMON(fp_mul)
71void fp_mul(fp c, const fp a, const fp b);
72
73#define fp_sqr COMMON(fp_sqr)
74void fp_sqr(fp b, const fp a);
75
76#define fp_issquare COMMON(fp_issquare)
77bool fp_issquare(fp const a);
78
79#define fp_copy COMMON(fp_copy)
80void fp_copy(fp b, const fp a);
81
82#define fp_cswap COMMON(fp_cswap)
83void fp_cswap(fp x, fp y, uint8_t c);
84
85#define fp_random COMMON(fp_random)
86void fp_random(fp a);
87
88#define fp_inv COMMON(fp_inv)
89void fp_inv(fp a);
90#ifdef MONTGOMERY
91#define fp_mont_redc COMMON(fp_mont_redc)
92void fp_mont_redc(fp a, const uint64_t b[2 * NUMBER_OF_WORDS]);
93#endif
94
95#ifdef KARATSUBA
96 // #if defined(P9215k384)
97 // #define fp_mult_144x144 COMMON(fp_mult_144x144)
98 // void fp_mult_144x144(uint64_t *c, const uint64_t *a, const uint64_t *b);
99 // #endif
100
101 // #if defined(P8191k332)
102 // #define fp_mult_128x128 COMMON(fp_mult_128x128)
103 // void fp_mult_128x128(uint64_t *c, const uint64_t *a, const uint64_t *b);
104 // #endif
105
106 // #if defined(P6143k256)
107 // #define fp_mult_96x96 COMMON(fp_mult_96x96)
108 // void fp_mult_96x96(uint64_t *c, const uint64_t *a, const uint64_t *b);
109 // #endif
110
111 // #if defined(P5119k234)
112 // #define fp_mult_80x80 COMMON(fp_mult_80x80)
113 // void fp_mult_80x80(uint64_t *c, const uint64_t *a, const uint64_t *b);
114 // #endif
115
116 // # if defined(P4095k256)
117 // #define fp_mult_64x64 COMMON(fp_mult_64x64)
118 // void fp_mult_64x64(uint64_t *c, const uint64_t *a, const uint64_t *b);
119 // #endif
120
121 // #if defined(P2047k221)
122 #define fp_mult_32x32 COMMON(fp_mult_32x32)
123 void fp_mult_32x32(uint64_t *c, const uint64_t *a, const uint64_t *b);
124 // #endif
125
126
127#endif
128// repeated squaring
129static inline void fp_sq1_rep(fp x,long long n)
130{
131 while (n > 0) {
132 --n;
133 fp_sqr(x, x);
134 }
135}
136
137static inline void fp_2oct(uint8_t *buf, const fp *a)
138{
139 for (int i = 0; i < NUMBER_OF_WORDS; i++)
140 {
141 for (int j = 0; j < 8; j++)
142 {
143 buf[i * 8 + j] = a[0][i] >> j * 8;
144 }
145 }
146}
147
148static inline void oct2_fp(fp *a, const uint8_t *buf)
149{
150 // fp test = {0};
151 // memcpy(test, buf, sizeof(fp));
152
153 uint64_t tmp = {0};
154 for (int i = 0; i < NUMBER_OF_WORDS; i++)
155 {
156 for (int j = 0; j < 8; j++)
157 {
158 tmp = buf[i * 8 + j];
159 a[0][i] += tmp << j * 8;
160 }
161 }
162
163 // assert(memcmp(test, a, sizeof(test))==0);
164}
165
166// set to zero
167static inline void fp_set0(fp a)
168{
169 fp_copy(a, fp_0);
170}
171
172// set to one
173static inline void uintbig_set1(fp a)
174{
176}
177
178// set to one in mongotmery domnain
179static inline void fp_set1(fp a)
180{
181 fp_copy(a, fp_1);
182}
183
184// set to value
185static inline void fp_set(fp a, uint64_t value)
186{
187 fp_set0(a);
188 a[0] = value;
189}
190
191// constant-time check of a < b
192static inline uint64_t fp_issmaller(fp const a, fp const b)
193{
194 int i;
195 int64_t r = 0, ab, c;
196
197 for (i = 0; i < NUMBER_OF_WORDS; i++)
198 {
199
200 ab = a[i] ^ b[i];
201 c = a[i] - b[i];
202 c ^= ab & (c ^ a[i]);
203 c = (c >> 63);
204 r |= c;
205 };
206
207 return 1 - (uint64_t)(r + 1);
208}
209
210// constant-time check of a == b
211static inline uint64_t fp_isequal(fp const a, fp const b)
212{
213 int i;
214 uint64_t r = 0, t;
215
216 for (i = 0; i < NUMBER_OF_WORDS; i++)
217 {
218 t = 0;
219 unsigned char *ta = (unsigned char *)&a[i];
220 unsigned char *tb = (unsigned char *)&b[i];
221 t = (ta[0] ^ tb[0]) | (ta[1] ^ tb[1]) | (ta[2] ^ tb[2]) | (ta[3] ^ tb[3]) | (ta[4] ^ tb[4]) | (ta[5] ^ tb[5]) | (ta[6] ^ tb[6]) | (ta[7] ^ tb[7]);
222
223 t = (-t);
224 t = t >> 63;
225 r |= t;
226 };
227
228 return (uint64_t)(1 - r);
229}
230
231// constant-time check of a == 0
232static inline int fp_iszero(fp const a)
233{
234 int i;
235 uint64_t c = 0;
236 for (i=NUMBER_OF_WORDS-1; i >= 0; i--)
237 c |= a[i];
238 return (c == 0);
239}
240
241// constant-time check of a == R mod p (one in Montogmery domain)
242static inline uint64_t fp_isone(fp const a)
243{
244 return fp_isequal(a, fp_1);
245}
246
247#define UBITS 2048
248
249// #if defined P2047m1l226
250// #define UBITS 2048
251// #elif defined P4095m27l262
252// #define UBITS 4096
253// #elif defined P5119m46l244
254// #define UBITS 5120
255// #elif defined P6143m59l262
256// #define UBITS 6144
257// #elif defined P8191m78l338
258// #define UBITS 8192
259// #elif defined P9215m85l389
260// #define UBITS 9216
261// #endif
262
263#define UINTBIG_LIMBS ((UBITS+63)/64)
264
265
266 typedef struct uintbig {
267 uint64_t c[UINTBIG_LIMBS];
269
270 long long uintbig_bit(uintbig const *x, uint64_t k);
271
272 #define uintbig_p COMMON(uintbig_p)
273 extern const uintbig uintbig_p;
274
275 // #define uintbig_1 COMMON(uintbig_1)
276 // extern const uintbig uintbig_1;
277
278 #define uintbig_four_sqrt_p COMMON(uintbig_four_sqrt_p)
279 extern const fp uintbig_four_sqrt_p;
280
281 #define uintbig_set COMMON(uintbig_set)
282 void uintbig_set(uintbig *x, uint64_t y);
283
284
285 #define uintbig_mul3_64 COMMON(uintbig_mul3_64)
286 void uintbig_mul3_64(fp *x, fp const *y, uint64_t z);
287
288 static inline long long uintbig_uint64_iszero(uint64_t t)
289 {
290 // is t nonzero?
291 t |= t>>32;
292 // are bottom 32 bits of t nonzero?
293 t &= 0xffffffff;
294 // is t nonzero? between 0 and 0xffffffff
295 t = -t;
296 // is t nonzero? 0, or between 2^64-0xffffffff and 2^64-1
297 t >>= 63;
298 return 1-(long long) t;
299 }
300
301 static inline long long uintbig_iszero(const uintbig *x)
302 {
303 uint64_t t = 0;
304 for (long long i = 0;i < UINTBIG_LIMBS;++i)
305 t |= x->c[i];
306 return uintbig_uint64_iszero(t);
307 }
308
309 static inline long long uintbig_isequal(const uintbig *x,const uintbig *y)
310 {
311 uint64_t t = 0;
312 for (long long i = 0;i < UINTBIG_LIMBS;++i)
313 t |= (x->c[i])^(y->c[i]);
314 return uintbig_uint64_iszero(t);
315 }
316
317 #define fp_2 COMMON(fp_2)
318 extern const fp fp_2; // 2 in the Montgomery domain
319
320 #define uintbig_1_ctidh COMMON(uintbig_1_ctidh)
321 extern const uintbig uintbig_1_ctidh;
322
323 #define fp_cmov COMMON(fp_cmov)
324 void fp_cmov(fp *a,const fp *b, uint8_t c);
325
326 // static inline long long fp_iszero_ctidh(fp *x) {
327 // return fp_iszero(*x);
328 // }
329
330 static inline void fp_mul3(fp *c, fp const *a, fp const *b) {
331 fp_mul(*c, *a, *b);
332 }
333
334 static inline void fp_mul2(fp *c, fp const *a) {
335 fp_mul(*c, *c, *a);
336 }
337
338 static inline void fp_add3(fp *c, fp const *a, fp const *b) {
339 fp_add(*c, *a, *b);
340 }
341
342 static inline void fp_add2(fp *c, fp const *a) {
343 fp_add(*c, *c, *a);
344 }
345
346 static inline void fp_sub2(fp *c, fp const *a) {
347 fp_sub(*c, *c, *a);
348 }
349
350 // static inline void fp_sub3_test(fp *c, fp *a, fp const *b) {
351 // fp_sub(*c, *a, *b);
352 // }
353
354 static inline void fp_cmov_ctidh(fp *a, const fp *b, uint8_t c) {
355 fp_cmov(a, b, c);
356 }
357
358 static inline void fp_sub3(fp *c, fp const *a, fp const *b) {
359 fp_sub(*c, *a, *b);
360 }
361
362 static inline void fp_neg1(fp *x)
363 {
364 fp_sub(*x,fp_0,*x);
365 }
366
367 static inline void fp_neg2(fp *x,fp const *y)
368 {
369 fp_sub(*x,fp_0,*y);
370 }
371
372 static inline void fp_sq1(fp *x)
373 {
374 fp_sqr(*x,*x);
375 }
376
377 static inline void fp_sq2(fp *x,fp const *y)
378 {
379 fp_sqr(*x,*y);
380 }
381
382 static inline void fp_double1(fp *x)
383 {
384 fp_add2(x, (const fp*) x);
385 }
386
387 static inline void fp_double2(fp *x,fp const *y)
388 {
389 fp_add(*x,*y,*y);
390 }
391
392 static inline void fp_quadruple1(fp *x)
393 {
394 fp_double1(x);
395 fp_double1(x);
396 }
397
398 static inline void fp_quadruple2(fp *x,fp const *y)
399 {
400 fp_double2(x,y);
401 fp_double1(x);
402 }
403
404 static inline long long fp_sqrt(fp *x) {
405 return fp_issquare(*x);
406 }
407
408
409// #endif
410
411
412#endif
#define uintbig_set
Definition fp-gmp.h:281
#define p
Definition fp-gmp.h:44
#define fp_sqr
Definition fp-gmp.h:73
uint64_t fp[NUMBER_OF_WORDS]
Definition fp-gmp.h:22
#define r_squared_mod_p
Definition fp-gmp.h:29
#define fp_pow
Definition fp-gmp.h:61
#define uintbig_bit
Definition fp-gmp.h:36
#define fp_sub
Definition fp-gmp.h:67
#define fp_mul
Definition fp-gmp.h:70
#define fp_1
Definition fp-gmp.h:48
#define fp_inv
Definition fp-gmp.h:88
#define fp_cmov
Definition fp-gmp.h:323
#define uintbig_p
Definition fp-gmp.h:272
#define fp_2
Definition fp-gmp.h:317
#define inv_min_p_mod_r
Definition fp-gmp.h:33
#define fp_issquare
Definition fp-gmp.h:76
#define uintbig_sub
Definition fp-gmp.h:40
#define uintbig_four_sqrt_p
Definition fp-gmp.h:278
#define fp_0
Definition fp-gmp.h:50
#define fp_add
Definition fp-gmp.h:64
#define UINTBIG_LIMBS
Definition fp-gmp.h:263
#define uintbig_add
Definition fp-gmp.h:38
#define fp_enc
Definition fp-gmp.h:55
#define fp_copy
Definition fp-gmp.h:79
#define uintbig_mul3_64
Definition fp-gmp.h:285
#define fp_cswap
Definition fp-gmp.h:82
#define p_minus_2
Definition fp-gmp.h:31
#define uintbig_1_ctidh
Definition fp-gmp.h:320
#define fp_random
Definition fp-gmp.h:85
#define fp_dec
Definition fp-gmp.h:58
#define uintbig_1
Definition fp-gmp.h:26
void fp_mont_redc(fp a, const uint64_t b[2 *NUMBER_OF_WORDS])
#define UINTBIG_LIMBS
void fp_sqrt(fp_t output, const fp_t input)
Definition fp.c:168
for i
for j
uint64_t c[UINTBIG_LIMBS]
Definition fp-gmp.h:267
f a
Definition to_model.m:12