]>
Commit | Line | Data |
---|---|---|
71712b27 GM |
1 | /********************************************************************** |
2 | * Copyright (c) 2013, 2014 Pieter Wuille * | |
3 | * Distributed under the MIT software license, see the accompanying * | |
4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* | |
5 | **********************************************************************/ | |
0a433ea2 | 6 | |
abe2d3e8 DR |
7 | #ifndef SECP256K1_GROUP_H |
8 | #define SECP256K1_GROUP_H | |
b394396b | 9 | |
607884fc | 10 | #include "num.h" |
b394396b PW |
11 | #include "field.h" |
12 | ||
7fef6619 | 13 | /** A group element of the secp256k1 curve, in affine coordinates. */ |
254327e4 | 14 | typedef struct { |
dd891e0e PW |
15 | secp256k1_fe x; |
16 | secp256k1_fe y; | |
71712b27 | 17 | int infinity; /* whether this represents the point at infinity */ |
dd891e0e | 18 | } secp256k1_ge; |
254327e4 | 19 | |
443cd4b8 PW |
20 | #define SECP256K1_GE_CONST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {SECP256K1_FE_CONST((a),(b),(c),(d),(e),(f),(g),(h)), SECP256K1_FE_CONST((i),(j),(k),(l),(m),(n),(o),(p)), 0} |
21 | #define SECP256K1_GE_CONST_INFINITY {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), 1} | |
22 | ||
7fef6619 | 23 | /** A group element of the secp256k1 curve, in jacobian coordinates. */ |
254327e4 | 24 | typedef struct { |
dd891e0e PW |
25 | secp256k1_fe x; /* actual X: x/z^2 */ |
26 | secp256k1_fe y; /* actual Y: y/z^3 */ | |
27 | secp256k1_fe z; | |
71712b27 | 28 | int infinity; /* whether this represents the point at infinity */ |
dd891e0e | 29 | } secp256k1_gej; |
254327e4 | 30 | |
443cd4b8 PW |
31 | #define SECP256K1_GEJ_CONST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {SECP256K1_FE_CONST((a),(b),(c),(d),(e),(f),(g),(h)), SECP256K1_FE_CONST((i),(j),(k),(l),(m),(n),(o),(p)), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1), 0} |
32 | #define SECP256K1_GEJ_CONST_INFINITY {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), 1} | |
33 | ||
e68d7208 | 34 | typedef struct { |
dd891e0e PW |
35 | secp256k1_fe_storage x; |
36 | secp256k1_fe_storage y; | |
37 | } secp256k1_ge_storage; | |
e68d7208 | 38 | |
443cd4b8 PW |
39 | #define SECP256K1_GE_STORAGE_CONST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {SECP256K1_FE_STORAGE_CONST((a),(b),(c),(d),(e),(f),(g),(h)), SECP256K1_FE_STORAGE_CONST((i),(j),(k),(l),(m),(n),(o),(p))} |
40 | ||
fbecc38a TD |
41 | #define SECP256K1_GE_STORAGE_CONST_GET(t) SECP256K1_FE_STORAGE_CONST_GET(t.x), SECP256K1_FE_STORAGE_CONST_GET(t.y) |
42 | ||
7fef6619 | 43 | /** Set a group element equal to the point with given X and Y coordinates */ |
dd891e0e | 44 | static void secp256k1_ge_set_xy(secp256k1_ge *r, const secp256k1_fe *x, const secp256k1_fe *y); |
7fef6619 | 45 | |
64666251 PW |
46 | /** Set a group element (affine) equal to the point with the given X coordinate |
47 | * and a Y coordinate that is a quadratic residue modulo p. The return value | |
48 | * is true iff a coordinate with the given X coordinate exists. | |
49 | */ | |
926836ad | 50 | static int secp256k1_ge_set_xquad(secp256k1_ge *r, const secp256k1_fe *x); |
64666251 | 51 | |
09ca4f32 PD |
52 | /** Set a group element (affine) equal to the point with the given X coordinate, and given oddness |
53 | * for Y. Return value indicates whether the result is valid. */ | |
dd891e0e | 54 | static int secp256k1_ge_set_xo_var(secp256k1_ge *r, const secp256k1_fe *x, int odd); |
764332d0 | 55 | |
7fef6619 | 56 | /** Check whether a group element is the point at infinity. */ |
dd891e0e | 57 | static int secp256k1_ge_is_infinity(const secp256k1_ge *a); |
7fef6619 | 58 | |
764332d0 | 59 | /** Check whether a group element is valid (i.e., on the curve). */ |
dd891e0e | 60 | static int secp256k1_ge_is_valid_var(const secp256k1_ge *a); |
764332d0 | 61 | |
dd891e0e | 62 | static void secp256k1_ge_neg(secp256k1_ge *r, const secp256k1_ge *a); |
7fef6619 | 63 | |
7fef6619 | 64 | /** Set a group element equal to another which is given in jacobian coordinates */ |
dd891e0e | 65 | static void secp256k1_ge_set_gej(secp256k1_ge *r, secp256k1_gej *a); |
254327e4 | 66 | |
f16be77f | 67 | /** Set a batch of group elements equal to the inputs given in jacobian coordinates */ |
7f7a2ed3 | 68 | static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len); |
f16be77f | 69 | |
4f9791ab PD |
70 | /** Bring a batch inputs given in jacobian coordinates (with known z-ratios) to |
71 | * the same global z "denominator". zr must contain the known z-ratios such | |
72 | * that mul(a[i].z, zr[i+1]) == a[i+1].z. zr[0] is ignored. The x and y | |
73 | * coordinates of the result are stored in r, the common z coordinate is | |
74 | * stored in globalz. */ | |
dd891e0e | 75 | static void secp256k1_ge_globalz_set_table_gej(size_t len, secp256k1_ge *r, secp256k1_fe *globalz, const secp256k1_gej *a, const secp256k1_fe *zr); |
7fef6619 | 76 | |
8c1c831b PW |
77 | /** Set a group element (affine) equal to the point at infinity. */ |
78 | static void secp256k1_ge_set_infinity(secp256k1_ge *r); | |
79 | ||
7fef6619 | 80 | /** Set a group element (jacobian) equal to the point at infinity. */ |
dd891e0e | 81 | static void secp256k1_gej_set_infinity(secp256k1_gej *r); |
7fef6619 | 82 | |
7fef6619 | 83 | /** Set a group element (jacobian) equal to another which is given in affine coordinates. */ |
dd891e0e | 84 | static void secp256k1_gej_set_ge(secp256k1_gej *r, const secp256k1_ge *a); |
7fef6619 | 85 | |
ce7eb6fb | 86 | /** Compare the X coordinate of a group element (jacobian). */ |
dd891e0e | 87 | static int secp256k1_gej_eq_x_var(const secp256k1_fe *x, const secp256k1_gej *a); |
7fef6619 PW |
88 | |
89 | /** Set r equal to the inverse of a (i.e., mirrored around the X axis) */ | |
dd891e0e | 90 | static void secp256k1_gej_neg(secp256k1_gej *r, const secp256k1_gej *a); |
7fef6619 PW |
91 | |
92 | /** Check whether a group element is the point at infinity. */ | |
dd891e0e | 93 | static int secp256k1_gej_is_infinity(const secp256k1_gej *a); |
7fef6619 | 94 | |
e6e9805f PW |
95 | /** Check whether a group element's y coordinate is a quadratic residue. */ |
96 | static int secp256k1_gej_has_quad_y_var(const secp256k1_gej *a); | |
97 | ||
18d36327 PW |
98 | /** Set r equal to the double of a. Constant time. */ |
99 | static void secp256k1_gej_double(secp256k1_gej *r, const secp256k1_gej *a); | |
44015000 | 100 | |
d567b779 | 101 | /** Set r equal to the double of a. If rzr is not-NULL this sets *rzr such that r->z == a->z * *rzr (where infinity means an implicit z = 0). */ |
dd891e0e | 102 | static void secp256k1_gej_double_var(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr); |
7fef6619 | 103 | |
d567b779 | 104 | /** Set r equal to the sum of a and b. If rzr is non-NULL this sets *rzr such that r->z == a->z * *rzr (a cannot be infinity in that case). */ |
dd891e0e | 105 | static void secp256k1_gej_add_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_gej *b, secp256k1_fe *rzr); |
7fef6619 | 106 | |
9338dbf7 | 107 | /** Set r equal to the sum of a and b (with b given in affine coordinates, and not infinity). */ |
dd891e0e | 108 | static void secp256k1_gej_add_ge(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b); |
9338dbf7 | 109 | |
09ca4f32 | 110 | /** Set r equal to the sum of a and b (with b given in affine coordinates). This is more efficient |
9338dbf7 | 111 | than secp256k1_gej_add_var. It is identical to secp256k1_gej_add_ge but without constant-time |
d567b779 | 112 | guarantee, and b is allowed to be infinity. If rzr is non-NULL this sets *rzr such that r->z == a->z * *rzr (a cannot be infinity in that case). */ |
dd891e0e | 113 | static void secp256k1_gej_add_ge_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, secp256k1_fe *rzr); |
7fef6619 | 114 | |
4f9791ab | 115 | /** Set r equal to the sum of a and b (with the inverse of b's Z coordinate passed as bzinv). */ |
dd891e0e | 116 | static void secp256k1_gej_add_zinv_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, const secp256k1_fe *bzinv); |
4f9791ab | 117 | |
399c03f2 | 118 | #ifdef USE_ENDOMORPHISM |
7fef6619 | 119 | /** Set r to be equal to lambda times a, where lambda is chosen in a way such that this is very fast. */ |
dd891e0e | 120 | static void secp256k1_ge_mul_lambda(secp256k1_ge *r, const secp256k1_ge *a); |
399c03f2 | 121 | #endif |
254327e4 | 122 | |
dd891e0e PW |
123 | /** Clear a secp256k1_gej to prevent leaking sensitive information. */ |
124 | static void secp256k1_gej_clear(secp256k1_gej *r); | |
2f6c8019 | 125 | |
dd891e0e PW |
126 | /** Clear a secp256k1_ge to prevent leaking sensitive information. */ |
127 | static void secp256k1_ge_clear(secp256k1_ge *r); | |
2f6c8019 | 128 | |
e68d7208 | 129 | /** Convert a group element to the storage type. */ |
cfe0ed91 | 130 | static void secp256k1_ge_to_storage(secp256k1_ge_storage *r, const secp256k1_ge *a); |
e68d7208 PW |
131 | |
132 | /** Convert a group element back from the storage type. */ | |
cfe0ed91 | 133 | static void secp256k1_ge_from_storage(secp256k1_ge *r, const secp256k1_ge_storage *a); |
e68d7208 | 134 | |
a39c2b09 | 135 | /** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized.*/ |
dd891e0e | 136 | static void secp256k1_ge_storage_cmov(secp256k1_ge_storage *r, const secp256k1_ge_storage *a, int flag); |
55422b6a | 137 | |
d2275795 | 138 | /** Rescale a jacobian point by b which must be non-zero. Constant-time. */ |
dd891e0e | 139 | static void secp256k1_gej_rescale(secp256k1_gej *r, const secp256k1_fe *b); |
d2275795 | 140 | |
abe2d3e8 | 141 | #endif /* SECP256K1_GROUP_H */ |