blob: e69768857c00f42b5fc3edc5b23ada79c97abff0 [file] [log] [blame]
Pete Bentley0c61efe2019-08-13 09:32:23 +01001#ifndef FPX_H_
2#define FPX_H_
3
4#include "utils.h"
5
6#if defined(__cplusplus)
7extern "C" {
8#endif
9
10// Modular addition, c = a+b mod p.
11void sike_fpadd(const felm_t a, const felm_t b, felm_t c);
12// Modular subtraction, c = a-b mod p.
13void sike_fpsub(const felm_t a, const felm_t b, felm_t c);
14// Modular division by two, c = a/2 mod p.
15void 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].
17void sike_fpcorrection(felm_t a);
18// Multiprecision multiply, c = a*b, where lng(a) = lng(b) = nwords.
19void 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.
22void sike_fprdc(dfelm_t a, felm_t c);
23// Double 2x443-bit multiprecision subtraction, c = c-a-b
24void sike_mpdblsubx2_asm(const felm_t a, const felm_t b, felm_t c);
25// Multiprecision subtraction, c = a-b
26crypto_word_t sike_mpsubx2_asm(const dfelm_t a, const dfelm_t b, dfelm_t c);
27// 443-bit multiprecision addition, c = a+b
28void sike_mpadd_asm(const felm_t a, const felm_t b, felm_t c);
29// Modular negation, a = -a mod p.
30void sike_fpneg(felm_t a);
31// Copy of a field element, c = a
32void sike_fpcopy(const felm_t a, felm_t c);
33// Copy a field element, c = a.
34void sike_fpzero(felm_t a);
35// If option = 0xFF...FF x=y; y=x, otherwise swap doesn't happen. Constant time.
36void 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].
39void 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
41void 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)
43void 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)
45void sike_fp2inv_mont(f2elm_t a);
46// GF(p^2) squaring using Montgomery arithmetic, c = a^2 in GF(p^2).
47void sike_fp2sqr_mont(const f2elm_t a, f2elm_t c);
48// Modular correction, a = a in GF(p^2).
49void 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) \
57do { \
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) \
64do { \
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) \
71do { \
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) \
78do { \
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) \
85do { \
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) \
92do { \
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) \
108do { \
109 sike_from_mont(ma->c0, c->c0); \
110 sike_from_mont(ma->c1, c->c1); \
111} while(0)
112
113#endif // FPX_H_