Let us walk on the 3-isogeny graph
Loading...
Searching...
No Matches
fp-karatsuba.h
Go to the documentation of this file.
1#ifndef _FP_KARATSUBA_H_
2#define _FP_KARATSUBA_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 fp_1 COMMON(fp_1)
30extern const fp fp_1;
31
32#define inv_min_p_mod_r COMMON(inv_min_p_mod_r)
33extern const fp inv_min_p_mod_r;
34#define p_minus_2 COMMON(p_minus_2)
35extern const fp p_minus_2;
36#define p COMMON(p)
37extern const fp p;
38#define r_squared_mod_p COMMON(r_squared_mod_p)
39extern const fp r_squared_mod_p;
40#define p_minus_2 COMMON(p_minus_2)
41extern const fp p_minus_2;
42#define inv_min_p_mod_r COMMON(inv_min_p_mod_r)
43extern const fp inv_min_p_mod_r;
44
45#define uintbig_bit COMMON(uintbig_bit)
46// bool uintbig_bit(fp const x, uint64_t k);
47#define uintbig_add COMMON(uintbig_add)
48bool uintbig_add(fp x, fp const y, fp const z); /* returns carry */
49#define uintbig_sub COMMON(uintbig_sub)
50bool uintbig_sub(fp x, fp const y, fp const z); /* returns borrow */
51
52// -------------------------------------
53#define p COMMON(p)
54extern const fp p; // field characteristic
55// extern const fp inv_min_p_mod_r;
56// extern const fp r_squared_mod_p;
57#define fp_1 COMMON(fp_1)
58extern const fp fp_1;
59#define fp_0 COMMON(fp_0)
60extern const fp fp_0;
61
62#define redc_alpha COMMON(redc_alpha)
63extern const fp redc_alpha;
64
65#define fp_enc COMMON(fp_enc)
66void fp_enc(fp a, fp const b); // from fp into Montgomery domain
67
68#define fp_dec COMMON(fp_dec)
69void fp_dec(fp a, fp const b); // from Montgomery domain into fp
70
71#define fp_pow COMMON(fp_pow)
72void fp_pow(fp b, const fp e, const fp a);
73
74#define fp_add_s COMMON(fp_add_s)
75void fp_add_s(fp c, const fp a, const fp b); // a + a
76
77#define fp_add COMMON(fp_add)
78void fp_add(fp c, const fp a, const fp b); // a + a
79
80#define fp_sub_s COMMON(fp_sub_s)
81void fp_sub_s(fp c, const fp a, const fp b);
82
83#define fp_sub COMMON(fp_sub)
84void fp_sub(fp c, const fp a, const fp b);
85
86#define fp_mul COMMON(fp_mul)
87void fp_mul(fp c, const fp a, const fp b);
88
89#define fp_sqr COMMON(fp_sqr)
90void fp_sqr(fp b, const fp a);
91
92#define fp_squaring COMMON(fp_squaring)
93void fp_squaring(uint64_t *c, const uint64_t *a, const uint64_t *b);
94
95#define fp_issquare COMMON(fp_issquare)
96bool fp_issquare(fp a);
97
98#define fp_copy COMMON(fp_copy)
99void fp_copy(fp b, const fp a);
100
101#define fp_cswap COMMON(fp_cswap)
102void fp_cswap(fp x, fp y, uint8_t c);
103
104#define fp_mont_redc_a COMMON(fp_mont_redc_a)
105void fp_mont_redc_a(fp a, const uint64_t b[2 * NUMBER_OF_WORDS]);
106
107#define fp_random COMMON(fp_random)
108void fp_random(fp a);
109
110#define fp_inv COMMON(fp_inv)
111void fp_inv(fp a);
112#ifdef MONTGOMERY
113#define fp_mont_redc COMMON(fp_mont_redc)
114void fp_mont_redc(fp a, const uint64_t b[2 * NUMBER_OF_WORDS]);
115#endif
116
117#ifdef KARATSUBA
118 // #if defined(P9215m85l389)
119 // #define fp_mult_144x144 COMMON(fp_mult_144x144)
120 // void fp_mult_144x144(uint64_t *c, const uint64_t *a, const uint64_t *b);
121
122 // #define mult_redc COMMON(mult_redc)
123 // void mult_redc(uint64_t *c, const uint64_t *a, const uint64_t *b);
124
125 // #define add_redc COMMON(add_redc)
126 // void add_redc(uint64_t *c, const uint64_t *a, const uint64_t *b);
127
128 // #define fp_mont_it_redc COMMON(fp_mont_it_redc)
129 // void fp_mont_it_redc(fp a, const uint64_t b[2 * NUMBER_OF_WORDS]);
130
131 // #define add_redc_final COMMON(add_redc_final)
132 // void add_redc_final(uint64_t *c, const uint64_t *a, const uint64_t *b);
133
134 // #endif
135
136 // #if defined(P8191m78l338)
137 // #define fp_mult_128x128 COMMON(fp_mult_128x128)
138 // void fp_mult_128x128(uint64_t *c, const uint64_t *a, const uint64_t *b);
139
140 // #define mult_redc COMMON(mult_redc)
141 // void mult_redc(uint64_t *c, const uint64_t *a, const uint64_t *b);
142
143 // #define add_redc COMMON(add_redc)
144 // void add_redc(uint64_t *c, const uint64_t *a, const uint64_t *b);
145
146 // #define fp_mont_it_redc COMMON(fp_mont_it_redc)
147 // void fp_mont_it_redc(fp a, const uint64_t b[2 * NUMBER_OF_WORDS]);
148
149 // #define add_redc_final COMMON(add_redc_final)
150 // void add_redc_final(uint64_t *c, const uint64_t *a, const uint64_t *b);
151
152 // #endif
153
154 // #if defined(P6143m59l262)
155 // #define fp_mult_96x96 COMMON(fp_mult_96x96)
156 // void fp_mult_96x96(uint64_t *c, const uint64_t *a, const uint64_t *b);
157
158 // #define mult_redc COMMON(mult_redc)
159 // void mult_redc(uint64_t *c, const uint64_t *a, const uint64_t *b);
160
161 // #define add_redc COMMON(add_redc)
162 // void add_redc(uint64_t *c, const uint64_t *a, const uint64_t *b);
163
164 // #define fp_mont_it_redc COMMON(fp_mont_it_redc)
165 // void fp_mont_it_redc(fp a, const uint64_t b[2 * NUMBER_OF_WORDS]);
166
167 // #define add_redc_final COMMON(add_redc_final)
168 // void add_redc_final(uint64_t *c, const uint64_t *a, const uint64_t *b);
169
170 // #endif
171
172 // #if defined(P5119m46l244)
173 // #define fp_mult_80x80 COMMON(fp_mult_80x80)
174 // void fp_mult_80x80(uint64_t *c, const uint64_t *a, const uint64_t *b);
175
176
177 // #define mult_redc COMMON(mult_redc)
178 // void mult_redc(uint64_t *c, const uint64_t *a, const uint64_t *b);
179
180 // #define add_redc COMMON(add_redc)
181 // void add_redc(uint64_t *c, const uint64_t *a, const uint64_t *b);
182
183 // #define fp_mont_it_redc COMMON(fp_mont_it_redc)
184 // void fp_mont_it_redc(fp a, const uint64_t b[2 * NUMBER_OF_WORDS]);
185
186 // #define add_redc_final COMMON(add_redc_final)
187 // void add_redc_final(uint64_t *c, const uint64_t *a, const uint64_t *b);
188
189 // #endif
190
191 // # if defined(P4095m27l262)
192 // #define fp_mult_64x64 COMMON(fp_mult_64x64)
193 // void fp_mult_64x64(uint64_t *c, const uint64_t *a, const uint64_t *b);
194 // #endif
195
196 // #define fp_mont_4k COMMON(fp_mont_4k)
197 // void fp_mont_4k(uint64_t *c, const uint64_t *a);
198
199 // #define fp_word_redc COMMON(fp_word_redc)
200 // void fp_word_redc(uint64_t *c, const uint64_t *a);
201
202
203 // #if defined(P2047m1l226)
204 #define fp_mult_32x32 COMMON(fp_mult_32x32)
205 void fp_mult_32x32(uint64_t *c, const uint64_t *a, const uint64_t *b);
206
207 // #define fp_mont_2k COMMON(fp_mont_2k)
208 // void fp_mont_2k(uint64_t *c, const uint64_t *a);
209
210 #define fp_word_redc COMMON(fp_word_redc)
211 void fp_word_redc(uint64_t *c, const uint64_t *a);
212
213 // #endif
214
215
216#endif
217// repeated squaring
218static inline void fp_sq1_rep(fp x,long long n)
219{
220 while (n > 0) {
221 --n;
222 fp_sqr(x, x);
223 }
224}
225
226static inline void fp_2oct(uint8_t *buf, const fp *a)
227{
228 for (int i = 0; i < NUMBER_OF_WORDS; i++)
229 {
230 for (int j = 0; j < 8; j++)
231 {
232 buf[i * 8 + j] = a[0][i] >> j * 8;
233 }
234 }
235}
236
237static inline void oct2_fp(fp *a, const uint8_t *buf)
238{
239 // fp test = {0};
240 // memcpy(test, buf, sizeof(fp));
241
242 uint64_t tmp = {0};
243 for (int i = 0; i < NUMBER_OF_WORDS; i++)
244 {
245 for (int j = 0; j < 8; j++)
246 {
247 tmp = buf[i * 8 + j];
248 a[0][i] += tmp << j * 8;
249 }
250 }
251
252 // assert(memcmp(test, a, sizeof(test))==0);
253}
254
255// set to zero
256static inline void fp_set0(fp a)
257{
258 fp_copy(a, fp_0);
259}
260
261// set to one
262static inline void uintbig_set1(fp a)
263{
265}
266
267// set to one in mongotmery domnain
268static inline void fp_set1(fp a)
269{
270 fp_copy(a, fp_1);
271}
272
273// set to value
274static inline void fp_set(fp a, uint64_t value)
275{
276 fp_set0(a);
277 a[0] = value;
278}
279
280// constant-time check of a < b
281static inline uint64_t fp_issmaller(fp const a, fp const b)
282{
283 int i;
284 int64_t r = 0, ab, c;
285
286 for (i = 0; i < NUMBER_OF_WORDS; i++)
287 {
288
289 ab = a[i] ^ b[i];
290 c = a[i] - b[i];
291 c ^= ab & (c ^ a[i]);
292 c = (c >> 63);
293 r |= c;
294 };
295
296 return 1 - (uint64_t)(r + 1);
297}
298
299// constant-time check of a == b
300static inline uint64_t fp_isequal(fp const a, fp const b)
301{
302 int i;
303 uint64_t r = 0, t;
304
305 for (i = 0; i < NUMBER_OF_WORDS; i++)
306 {
307 t = 0;
308 unsigned char *ta = (unsigned char *)&a[i];
309 unsigned char *tb = (unsigned char *)&b[i];
310 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]);
311
312 t = (-t);
313 t = t >> 63;
314 r |= t;
315 };
316
317 return (uint64_t)(1 - r);
318}
319
320// constant-time check of a == 0
321static inline int fp_iszero(fp const a)
322{
323 int i;
324 uint64_t c = 0;
325 for (i=NUMBER_OF_WORDS-1; i >= 0; i--)
326 c |= a[i];
327 return (c == 0);
328}
329
330// constant-time check of a == R mod p (one in Montogmery domain)
331static inline uint64_t fp_isone(fp const a)
332{
333 return fp_isequal(a, fp_1);
334}
335
336// #if defined CTIDH
337 #define UBITS 2048
338
339 // #if defined P2047m1l226
340 // #define UBITS 2048
341 // #elif defined P4095m27l262
342 // #define UBITS 4096
343 // #elif defined P5119m46l244
344 // #define UBITS 5120
345 // #elif defined P6143m59l262
346 // #define UBITS 6144
347 // #elif defined P8191m78l338
348 // #define UBITS 8192
349 // #elif defined P9215m85l389
350 // #define UBITS 9216
351 // #endif
352
353 #define UINTBIG_LIMBS ((UBITS+63)/64)
354
355
356 typedef struct uintbig {
357 uint64_t c[UINTBIG_LIMBS];
359
360 long long uintbig_bit(uintbig const *x, uint64_t k);
361
362 #define uintbig_p COMMON(uintbig_p)
363 extern const uintbig uintbig_p;
364
365 // #define uintbig_1 COMMON(uintbig_1)
366 // extern const uintbig uintbig_1;
367
368 #define uintbig_four_sqrt_p COMMON(uintbig_four_sqrt_p)
369 extern const fp uintbig_four_sqrt_p;
370
371 #define uintbig_set COMMON(uintbig_set)
372 void uintbig_set(uintbig *x, uint64_t y);
373
374
375 #define uintbig_mul3_64 COMMON(uintbig_mul3_64)
376 void uintbig_mul3_64(fp *x, fp const *y, uint64_t z);
377
378 static inline long long uintbig_uint64_iszero(uint64_t t)
379 {
380 // is t nonzero?
381 t |= t>>32;
382 // are bottom 32 bits of t nonzero?
383 t &= 0xffffffff;
384 // is t nonzero? between 0 and 0xffffffff
385 t = -t;
386 // is t nonzero? 0, or between 2^64-0xffffffff and 2^64-1
387 t >>= 63;
388 return 1-(long long) t;
389 }
390
391 static inline long long uintbig_iszero(const uintbig *x)
392 {
393 uint64_t t = 0;
394 for (long long i = 0;i < UINTBIG_LIMBS;++i)
395 t |= x->c[i];
396 return uintbig_uint64_iszero(t);
397 }
398
399 static inline long long uintbig_isequal(const uintbig *x,const uintbig *y)
400 {
401 uint64_t t = 0;
402 for (long long i = 0;i < UINTBIG_LIMBS;++i)
403 t |= (x->c[i])^(y->c[i]);
404 return uintbig_uint64_iszero(t);
405 }
406
407 #define fp_2 COMMON(fp_2)
408 extern const fp fp_2; // 2 in the Montgomery domain
409
410 #define uintbig_1_ctidh COMMON(uintbig_1_ctidh)
411 extern const uintbig uintbig_1_ctidh;
412
413 #define fp_cmov COMMON(fp_cmov)
414 void fp_cmov(fp *a,const fp *b, uint8_t c);
415
416 // static inline long long fp_iszero_ctidh(fp *x) {
417 // return fp_iszero(*x);
418 // }
419
420 static inline void fp_mul3(fp *c, fp const *a, fp const *b) {
421 fp_mul(*c, *a, *b);
422 }
423
424 static inline void fp_mul2(fp *c, fp const *a) {
425 fp_mul(*c, *c, *a);
426 }
427
428 static inline void fp_add3(fp *c, fp const *a, fp const *b) {
429 fp_add(*c, *a, *b);
430 }
431
432 static inline void fp_add2(fp *c, fp const *a) {
433 fp_add(*c, *c, *a);
434 }
435
436 static inline void fp_sub2(fp *c, fp const *a) {
437 fp_sub(*c, *c, *a);
438 }
439
440 // static inline void fp_sub3_test(fp *c, fp *a, fp const *b) {
441 // fp_sub(*c, *a, *b);
442 // }
443
444 static inline void fp_cmov_ctidh(fp *a, const fp *b, uint8_t c) {
445 fp_cmov(a, b, c);
446 }
447
448 static inline void fp_sub3(fp *c, fp const *a, fp const *b) {
449 fp_sub(*c, *a, *b);
450 }
451
452 static inline void fp_neg1(fp *x)
453 {
454 fp_sub(*x,fp_0,*x);
455 }
456
457 static inline void fp_neg2(fp *x,fp const *y)
458 {
459 fp_sub(*x,fp_0,*y);
460 }
461
462 static inline void fp_sq1(fp *x)
463 {
464 fp_sqr(*x,*x);
465 }
466
467 static inline void fp_sq2(fp *x,fp const *y)
468 {
469 fp_sqr(*x,*y);
470 }
471
472 static inline void fp_double1(fp *x)
473 {
474 fp_add2(x, (const fp*) x);
475 }
476
477 static inline void fp_double2(fp *x,fp const *y)
478 {
479 fp_add(*x,*y,*y);
480 }
481
482 static inline void fp_quadruple1(fp *x)
483 {
484 fp_double1(x);
485 fp_double1(x);
486 }
487
488 static inline void fp_quadruple2(fp *x,fp const *y)
489 {
490 fp_double2(x,y);
491 fp_double1(x);
492 }
493
494 static inline long long fp_sqrt(fp *x) {
495 return fp_issquare(*x);
496 }
497
498
499// #endif
500
501
502#endif
#define p
Definition fp-gmp.h:44
uint64_t fp[NUMBER_OF_WORDS]
Definition fp-gmp.h:22
#define r_squared_mod_p
Definition fp-gmp.h:29
#define fp_1
Definition fp-gmp.h:48
#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 uintbig_four_sqrt_p
Definition fp-gmp.h:278
#define fp_0
Definition fp-gmp.h:50
#define UINTBIG_LIMBS
Definition fp-gmp.h:263
#define p_minus_2
Definition fp-gmp.h:31
#define uintbig_1_ctidh
Definition fp-gmp.h:320
#define uintbig_1
Definition fp-gmp.h:26
void fp_mont_redc(fp a, const uint64_t b[2 *NUMBER_OF_WORDS])
#define uintbig_set
#define fp_sqr
#define fp_pow
#define fp_squaring
#define uintbig_bit
#define fp_sub
#define fp_mul
#define fp_inv
#define fp_cmov
#define fp_issquare
#define uintbig_sub
#define fp_add_s
#define redc_alpha
#define fp_add
#define uintbig_add
#define fp_enc
#define fp_copy
#define fp_sub_s
#define fp_mont_redc_a
#define uintbig_mul3_64
#define fp_cswap
#define fp_random
#define fp_dec
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