]> Git Repo - secp256k1.git/blame - src/group.h
Merge #699: Initialize field elements when resulting in infinity
[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
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 14typedef 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 24typedef 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 34typedef 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 44static 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 50static 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 54static 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 57static 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 60static int secp256k1_ge_is_valid_var(const secp256k1_ge *a);
764332d0 61
dd891e0e 62static 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 65static 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 68static 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 75static 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. */
78static void secp256k1_ge_set_infinity(secp256k1_ge *r);
79
7fef6619 80/** Set a group element (jacobian) equal to the point at infinity. */
dd891e0e 81static 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 84static 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 87static 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 90static 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 93static 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. */
96static 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. */
99static 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 102static 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 105static 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 108static 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 113static 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 116static 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 120static 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. */
124static void secp256k1_gej_clear(secp256k1_gej *r);
2f6c8019 125
dd891e0e
PW
126/** Clear a secp256k1_ge to prevent leaking sensitive information. */
127static void secp256k1_ge_clear(secp256k1_ge *r);
2f6c8019 128
e68d7208 129/** Convert a group element to the storage type. */
cfe0ed91 130static 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 133static 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 136static 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 139static void secp256k1_gej_rescale(secp256k1_gej *r, const secp256k1_fe *b);
d2275795 140
abe2d3e8 141#endif /* SECP256K1_GROUP_H */
This page took 0.079255 seconds and 4 git commands to generate.