Pete Bentley | 0c61efe | 2019-08-13 09:32:23 +0100 | [diff] [blame^] | 1 | #ifndef FPX_H_ |
| 2 | #define FPX_H_ |
| 3 | |
| 4 | #include "utils.h" |
| 5 | |
| 6 | #if defined(__cplusplus) |
| 7 | extern "C" { |
| 8 | #endif |
| 9 | |
| 10 | // Modular addition, c = a+b mod p. |
| 11 | void sike_fpadd(const felm_t a, const felm_t b, felm_t c); |
| 12 | // Modular subtraction, c = a-b mod p. |
| 13 | void sike_fpsub(const felm_t a, const felm_t b, felm_t c); |
| 14 | // Modular division by two, c = a/2 mod p. |
| 15 | void sike_fpdiv2(const felm_t a, felm_t c); |
| 16 | // Modular correction to reduce field element a in [0, 2*p-1] to [0, p-1]. |
| 17 | void sike_fpcorrection(felm_t a); |
| 18 | // Multiprecision multiply, c = a*b, where lng(a) = lng(b) = nwords. |
| 19 | void sike_mpmul(const felm_t a, const felm_t b, dfelm_t c); |
| 20 | // 443-bit Montgomery reduction, c = a mod p. Buffer 'a' is modified after |
| 21 | // call returns. |
| 22 | void sike_fprdc(dfelm_t a, felm_t c); |
| 23 | // Double 2x443-bit multiprecision subtraction, c = c-a-b |
| 24 | void sike_mpdblsubx2_asm(const felm_t a, const felm_t b, felm_t c); |
| 25 | // Multiprecision subtraction, c = a-b |
| 26 | crypto_word_t sike_mpsubx2_asm(const dfelm_t a, const dfelm_t b, dfelm_t c); |
| 27 | // 443-bit multiprecision addition, c = a+b |
| 28 | void sike_mpadd_asm(const felm_t a, const felm_t b, felm_t c); |
| 29 | // Modular negation, a = -a mod p. |
| 30 | void sike_fpneg(felm_t a); |
| 31 | // Copy of a field element, c = a |
| 32 | void sike_fpcopy(const felm_t a, felm_t c); |
| 33 | // Copy a field element, c = a. |
| 34 | void sike_fpzero(felm_t a); |
| 35 | // If option = 0xFF...FF x=y; y=x, otherwise swap doesn't happen. Constant time. |
| 36 | void sike_cswap_asm(point_proj_t x, point_proj_t y, const crypto_word_t option); |
| 37 | // Conversion from Montgomery representation to standard representation, |
| 38 | // c = ma*R^(-1) mod p = a mod p, where ma in [0, p-1]. |
| 39 | void sike_from_mont(const felm_t ma, felm_t c); |
| 40 | // Field multiplication using Montgomery arithmetic, c = a*b*R^-1 mod p443, where R=2^768 |
| 41 | void sike_fpmul_mont(const felm_t ma, const felm_t mb, felm_t mc); |
| 42 | // GF(p443^2) multiplication using Montgomery arithmetic, c = a*b in GF(p443^2) |
| 43 | void sike_fp2mul_mont(const f2elm_t a, const f2elm_t b, f2elm_t c); |
| 44 | // GF(p443^2) inversion using Montgomery arithmetic, a = (a0-i*a1)/(a0^2+a1^2) |
| 45 | void sike_fp2inv_mont(f2elm_t a); |
| 46 | // GF(p^2) squaring using Montgomery arithmetic, c = a^2 in GF(p^2). |
| 47 | void sike_fp2sqr_mont(const f2elm_t a, f2elm_t c); |
| 48 | // Modular correction, a = a in GF(p^2). |
| 49 | void sike_fp2correction(f2elm_t a); |
| 50 | |
| 51 | #if defined(__cplusplus) |
| 52 | } // extern C |
| 53 | #endif |
| 54 | |
| 55 | // GF(p^2) addition, c = a+b in GF(p^2). |
| 56 | #define sike_fp2add(a, b, c) \ |
| 57 | do { \ |
| 58 | sike_fpadd(a->c0, b->c0, c->c0); \ |
| 59 | sike_fpadd(a->c1, b->c1, c->c1); \ |
| 60 | } while(0) |
| 61 | |
| 62 | // GF(p^2) subtraction, c = a-b in GF(p^2). |
| 63 | #define sike_fp2sub(a,b,c) \ |
| 64 | do { \ |
| 65 | sike_fpsub(a->c0, b->c0, c->c0); \ |
| 66 | sike_fpsub(a->c1, b->c1, c->c1); \ |
| 67 | } while(0) |
| 68 | |
| 69 | // Copy a GF(p^2) element, c = a. |
| 70 | #define sike_fp2copy(a, c) \ |
| 71 | do { \ |
| 72 | sike_fpcopy(a->c0, c->c0); \ |
| 73 | sike_fpcopy(a->c1, c->c1); \ |
| 74 | } while(0) |
| 75 | |
| 76 | // GF(p^2) negation, a = -a in GF(p^2). |
| 77 | #define sike_fp2neg(a) \ |
| 78 | do { \ |
| 79 | sike_fpneg(a->c0); \ |
| 80 | sike_fpneg(a->c1); \ |
| 81 | } while(0) |
| 82 | |
| 83 | // GF(p^2) division by two, c = a/2 in GF(p^2). |
| 84 | #define sike_fp2div2(a, c) \ |
| 85 | do { \ |
| 86 | sike_fpdiv2(a->c0, c->c0); \ |
| 87 | sike_fpdiv2(a->c1, c->c1); \ |
| 88 | } while(0) |
| 89 | |
| 90 | // Modular correction, a = a in GF(p^2). |
| 91 | #define sike_fp2correction(a) \ |
| 92 | do { \ |
| 93 | sike_fpcorrection(a->c0); \ |
| 94 | sike_fpcorrection(a->c1); \ |
| 95 | } while(0) |
| 96 | |
| 97 | // Conversion of a GF(p^2) element to Montgomery representation, |
| 98 | // mc_i = a_i*R^2*R^(-1) = a_i*R in GF(p^2). |
| 99 | #define sike_to_fp2mont(a, mc) \ |
| 100 | do { \ |
| 101 | sike_fpmul_mont(a->c0, sike_params.mont_R2, mc->c0); \ |
| 102 | sike_fpmul_mont(a->c1, sike_params.mont_R2, mc->c1); \ |
| 103 | } while (0) |
| 104 | |
| 105 | // Conversion of a GF(p^2) element from Montgomery representation to standard representation, |
| 106 | // c_i = ma_i*R^(-1) = a_i in GF(p^2). |
| 107 | #define sike_from_fp2mont(ma, c) \ |
| 108 | do { \ |
| 109 | sike_from_mont(ma->c0, c->c0); \ |
| 110 | sike_from_mont(ma->c1, c->c1); \ |
| 111 | } while(0) |
| 112 | |
| 113 | #endif // FPX_H_ |