]> Git Repo - secp256k1.git/blame - src/group.h
Implement endomorphism optimization for secp256k1_ecmult_const
[secp256k1.git] / src / group.h
CommitLineData
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
b394396b
PW
7#ifndef _SECP256K1_GROUP_
8#define _SECP256K1_GROUP_
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
PW
14typedef struct {
15 secp256k1_fe_t x;
16 secp256k1_fe_t y;
71712b27 17 int infinity; /* whether this represents the point at infinity */
254327e4
PW
18} secp256k1_ge_t;
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 24typedef struct {
71712b27
GM
25 secp256k1_fe_t x; /* actual X: x/z^2 */
26 secp256k1_fe_t y; /* actual Y: y/z^3 */
254327e4 27 secp256k1_fe_t z;
71712b27 28 int infinity; /* whether this represents the point at infinity */
254327e4
PW
29} secp256k1_gej_t;
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
PW
34typedef struct {
35 secp256k1_fe_storage_t x;
36 secp256k1_fe_storage_t y;
37} secp256k1_ge_storage_t;
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 at infinity */
a4a43d75 44static void secp256k1_ge_set_infinity(secp256k1_ge_t *r);
7fef6619
PW
45
46/** Set a group element equal to the point with given X and Y coordinates */
a4a43d75 47static void secp256k1_ge_set_xy(secp256k1_ge_t *r, const secp256k1_fe_t *x, const secp256k1_fe_t *y);
7fef6619 48
09ca4f32
PD
49/** Set a group element (affine) equal to the point with the given X coordinate, and given oddness
50 * for Y. Return value indicates whether the result is valid. */
39bd94d8 51static int secp256k1_ge_set_xo_var(secp256k1_ge_t *r, const secp256k1_fe_t *x, int odd);
764332d0 52
7fef6619 53/** Check whether a group element is the point at infinity. */
a4a43d75 54static int secp256k1_ge_is_infinity(const secp256k1_ge_t *a);
7fef6619 55
764332d0 56/** Check whether a group element is valid (i.e., on the curve). */
39bd94d8 57static int secp256k1_ge_is_valid_var(const secp256k1_ge_t *a);
764332d0 58
a4a43d75 59static void secp256k1_ge_neg(secp256k1_ge_t *r, const secp256k1_ge_t *a);
7fef6619 60
7fef6619 61/** Set a group element equal to another which is given in jacobian coordinates */
a4a43d75 62static void secp256k1_ge_set_gej(secp256k1_ge_t *r, secp256k1_gej_t *a);
254327e4 63
f16be77f 64/** Set a batch of group elements equal to the inputs given in jacobian coordinates */
995c5487 65static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge_t *r, const secp256k1_gej_t *a, const callback_t *cb);
f16be77f 66
4f9791ab
PD
67/** Set a batch of group elements equal to the inputs given in jacobian
68 * coordinates (with known z-ratios). zr must contain the known z-ratios such
69 * that mul(a[i].z, zr[i+1]) == a[i+1].z. zr[0] is ignored. */
70static void secp256k1_ge_set_table_gej_var(size_t len, secp256k1_ge_t *r, const secp256k1_gej_t *a, const secp256k1_fe_t *zr);
71
72/** Bring a batch inputs given in jacobian coordinates (with known z-ratios) to
73 * the same global z "denominator". zr must contain the known z-ratios such
74 * that mul(a[i].z, zr[i+1]) == a[i+1].z. zr[0] is ignored. The x and y
75 * coordinates of the result are stored in r, the common z coordinate is
76 * stored in globalz. */
77static void secp256k1_ge_globalz_set_table_gej(size_t len, secp256k1_ge_t *r, secp256k1_fe_t *globalz, const secp256k1_gej_t *a, const secp256k1_fe_t *zr);
7fef6619
PW
78
79/** Set a group element (jacobian) equal to the point at infinity. */
a4a43d75 80static void secp256k1_gej_set_infinity(secp256k1_gej_t *r);
7fef6619
PW
81
82/** Set a group element (jacobian) equal to the point with given X and Y coordinates. */
a4a43d75 83static void secp256k1_gej_set_xy(secp256k1_gej_t *r, const secp256k1_fe_t *x, const secp256k1_fe_t *y);
7fef6619 84
7fef6619 85/** Set a group element (jacobian) equal to another which is given in affine coordinates. */
a4a43d75 86static void secp256k1_gej_set_ge(secp256k1_gej_t *r, const secp256k1_ge_t *a);
7fef6619 87
ce7eb6fb
PW
88/** Compare the X coordinate of a group element (jacobian). */
89static int secp256k1_gej_eq_x_var(const secp256k1_fe_t *x, const secp256k1_gej_t *a);
7fef6619
PW
90
91/** Set r equal to the inverse of a (i.e., mirrored around the X axis) */
0295f0a3 92static void secp256k1_gej_neg(secp256k1_gej_t *r, const secp256k1_gej_t *a);
7fef6619
PW
93
94/** Check whether a group element is the point at infinity. */
a4a43d75 95static int secp256k1_gej_is_infinity(const secp256k1_gej_t *a);
7fef6619 96
44015000
AP
97/** Set r equal to the double of a. If rzr is not-NULL, r->z = a->z * *rzr (where infinity means an implicit z = 0).
98 * a may not be zero. Constant time. */
99static void secp256k1_gej_double_nonzero(secp256k1_gej_t *r, const secp256k1_gej_t *a, secp256k1_fe_t *rzr);
100
4f9791ab
PD
101/** Set r equal to the double of a. If rzr is not-NULL, r->z = a->z * *rzr (where infinity means an implicit z = 0). */
102static void secp256k1_gej_double_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, secp256k1_fe_t *rzr);
7fef6619 103
4f9791ab
PD
104/** Set r equal to the sum of a and b. If rzr is non-NULL, r->z = a->z * *rzr (a cannot be infinity in that case). */
105static void secp256k1_gej_add_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_gej_t *b, secp256k1_fe_t *rzr);
7fef6619 106
9338dbf7 107/** Set r equal to the sum of a and b (with b given in affine coordinates, and not infinity). */
a4a43d75 108static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_ge_t *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
2d5a186c
PD
112 guarantee, and b is allowed to be infinity. If rzr is non-NULL, r->z = a->z * *rzr (a cannot be infinity in that case). */
113static void secp256k1_gej_add_ge_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_ge_t *b, secp256k1_fe_t *rzr);
7fef6619 114
4f9791ab
PD
115/** Set r equal to the sum of a and b (with the inverse of b's Z coordinate passed as bzinv). */
116static void secp256k1_gej_add_zinv_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_ge_t *b, const secp256k1_fe_t *bzinv);
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. */
4f9791ab 120static void secp256k1_ge_mul_lambda(secp256k1_ge_t *r, const secp256k1_ge_t *a);
399c03f2 121#endif
254327e4 122
2f6c8019 123/** Clear a secp256k1_gej_t to prevent leaking sensitive information. */
a4a43d75 124static void secp256k1_gej_clear(secp256k1_gej_t *r);
2f6c8019
GM
125
126/** Clear a secp256k1_ge_t to prevent leaking sensitive information. */
a4a43d75 127static void secp256k1_ge_clear(secp256k1_ge_t *r);
2f6c8019 128
e68d7208
PW
129/** Convert a group element to the storage type. */
130static void secp256k1_ge_to_storage(secp256k1_ge_storage_t *r, const secp256k1_ge_t*);
131
132/** Convert a group element back from the storage type. */
133static void secp256k1_ge_from_storage(secp256k1_ge_t *r, const secp256k1_ge_storage_t*);
134
55422b6a
PW
135/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */
136static void secp256k1_ge_storage_cmov(secp256k1_ge_storage_t *r, const secp256k1_ge_storage_t *a, int flag);
137
d2275795
GM
138/** Rescale a jacobian point by b which must be non-zero. Constant-time. */
139static void secp256k1_gej_rescale(secp256k1_gej_t *r, const secp256k1_fe_t *b);
140
b394396b 141#endif
This page took 0.058882 seconds and 4 git commands to generate.