Coverage Report

Created: 2025-06-06 15:08

/root/bitcoin/src/secp256k1/src/group_impl.h
Line
Count
Source (jump to first uncovered line)
1
/***********************************************************************
2
 * Copyright (c) 2013, 2014 Pieter Wuille                              *
3
 * Distributed under the MIT software license, see the accompanying    *
4
 * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
5
 ***********************************************************************/
6
7
#ifndef SECP256K1_GROUP_IMPL_H
8
#define SECP256K1_GROUP_IMPL_H
9
10
#include <string.h>
11
12
#include "field.h"
13
#include "group.h"
14
#include "util.h"
15
16
/* Begin of section generated by sage/gen_exhaustive_groups.sage. */
17
#define SECP256K1_G_ORDER_7 SECP256K1_GE_CONST(\
18
    0x66625d13, 0x317ffe44, 0x63d32cff, 0x1ca02b9b,\
19
    0xe5c6d070, 0x50b4b05e, 0x81cc30db, 0xf5166f0a,\
20
    0x1e60e897, 0xa7c00c7c, 0x2df53eb6, 0x98274ff4,\
21
    0x64252f42, 0x8ca44e17, 0x3b25418c, 0xff4ab0cf\
22
)
23
#define SECP256K1_G_ORDER_13 SECP256K1_GE_CONST(\
24
    0xa2482ff8, 0x4bf34edf, 0xa51262fd, 0xe57921db,\
25
    0xe0dd2cb7, 0xa5914790, 0xbc71631f, 0xc09704fb,\
26
    0x942536cb, 0xa3e49492, 0x3a701cc3, 0xee3e443f,\
27
    0xdf182aa9, 0x15b8aa6a, 0x166d3b19, 0xba84b045\
28
)
29
#define SECP256K1_G_ORDER_199 SECP256K1_GE_CONST(\
30
    0x7fb07b5c, 0xd07c3bda, 0x553902e2, 0x7a87ea2c,\
31
    0x35108a7f, 0x051f41e5, 0xb76abad5, 0x1f2703ad,\
32
    0x0a251539, 0x5b4c4438, 0x952a634f, 0xac10dd4d,\
33
    0x6d6f4745, 0x98990c27, 0x3a4f3116, 0xd32ff969\
34
)
35
/** Generator for secp256k1, value 'g' defined in
36
 *  "Standards for Efficient Cryptography" (SEC2) 2.7.1.
37
 */
38
#define SECP256K1_G SECP256K1_GE_CONST(\
39
    0x79be667e, 0xf9dcbbac, 0x55a06295, 0xce870b07,\
40
    0x029bfcdb, 0x2dce28d9, 0x59f2815b, 0x16f81798,\
41
    0x483ada77, 0x26a3c465, 0x5da4fbfc, 0x0e1108a8,\
42
    0xfd17b448, 0xa6855419, 0x9c47d08f, 0xfb10d4b8\
43
)
44
/* These exhaustive group test orders and generators are chosen such that:
45
 * - The field size is equal to that of secp256k1, so field code is the same.
46
 * - The curve equation is of the form y^2=x^3+B for some small constant B.
47
 * - The subgroup has a generator 2*P, where P.x is as small as possible.
48
 * - The subgroup has size less than 1000 to permit exhaustive testing.
49
 * - The subgroup admits an endomorphism of the form lambda*(x,y) == (beta*x,y).
50
 */
51
#if defined(EXHAUSTIVE_TEST_ORDER)
52
#  if EXHAUSTIVE_TEST_ORDER == 7
53
54
static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_G_ORDER_7;
55
#define SECP256K1_B 6
56
57
#  elif EXHAUSTIVE_TEST_ORDER == 13
58
59
static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_G_ORDER_13;
60
#define SECP256K1_B 2
61
62
#  elif EXHAUSTIVE_TEST_ORDER == 199
63
64
static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_G_ORDER_199;
65
#define SECP256K1_B 4
66
67
#  else
68
#    error No known generator for the specified exhaustive test group order.
69
#  endif
70
#else
71
72
static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_G;
73
0
#define SECP256K1_B 7
74
75
#endif
76
/* End of section generated by sage/gen_exhaustive_groups.sage. */
77
78
0
static void secp256k1_ge_verify(const secp256k1_ge *a) {
79
0
    SECP256K1_FE_VERIFY(&a->x);
80
0
    SECP256K1_FE_VERIFY(&a->y);
81
0
    SECP256K1_FE_VERIFY_MAGNITUDE(&a->x, SECP256K1_GE_X_MAGNITUDE_MAX);
82
0
    SECP256K1_FE_VERIFY_MAGNITUDE(&a->y, SECP256K1_GE_Y_MAGNITUDE_MAX);
83
0
    VERIFY_CHECK(a->infinity == 0 || a->infinity == 1);
84
0
    (void)a;
85
0
}
86
87
0
static void secp256k1_gej_verify(const secp256k1_gej *a) {
88
0
    SECP256K1_FE_VERIFY(&a->x);
89
0
    SECP256K1_FE_VERIFY(&a->y);
90
0
    SECP256K1_FE_VERIFY(&a->z);
91
0
    SECP256K1_FE_VERIFY_MAGNITUDE(&a->x, SECP256K1_GEJ_X_MAGNITUDE_MAX);
92
0
    SECP256K1_FE_VERIFY_MAGNITUDE(&a->y, SECP256K1_GEJ_Y_MAGNITUDE_MAX);
93
0
    SECP256K1_FE_VERIFY_MAGNITUDE(&a->z, SECP256K1_GEJ_Z_MAGNITUDE_MAX);
94
0
    VERIFY_CHECK(a->infinity == 0 || a->infinity == 1);
95
0
    (void)a;
96
0
}
97
98
/* Set r to the affine coordinates of Jacobian point (a.x, a.y, 1/zi). */
99
0
static void secp256k1_ge_set_gej_zinv(secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zi) {
100
0
    secp256k1_fe zi2;
101
0
    secp256k1_fe zi3;
102
0
    SECP256K1_GEJ_VERIFY(a);
103
0
    SECP256K1_FE_VERIFY(zi);
104
0
    VERIFY_CHECK(!a->infinity);
105
106
0
    secp256k1_fe_sqr(&zi2, zi);
107
0
    secp256k1_fe_mul(&zi3, &zi2, zi);
108
0
    secp256k1_fe_mul(&r->x, &a->x, &zi2);
109
0
    secp256k1_fe_mul(&r->y, &a->y, &zi3);
110
0
    r->infinity = a->infinity;
111
112
0
    SECP256K1_GE_VERIFY(r);
113
0
}
114
115
/* Set r to the affine coordinates of Jacobian point (a.x, a.y, 1/zi). */
116
0
static void secp256k1_ge_set_ge_zinv(secp256k1_ge *r, const secp256k1_ge *a, const secp256k1_fe *zi) {
117
0
    secp256k1_fe zi2;
118
0
    secp256k1_fe zi3;
119
0
    SECP256K1_GE_VERIFY(a);
120
0
    SECP256K1_FE_VERIFY(zi);
121
0
    VERIFY_CHECK(!a->infinity);
122
123
0
    secp256k1_fe_sqr(&zi2, zi);
124
0
    secp256k1_fe_mul(&zi3, &zi2, zi);
125
0
    secp256k1_fe_mul(&r->x, &a->x, &zi2);
126
0
    secp256k1_fe_mul(&r->y, &a->y, &zi3);
127
0
    r->infinity = a->infinity;
128
129
0
    SECP256K1_GE_VERIFY(r);
130
0
}
131
132
0
static void secp256k1_ge_set_xy(secp256k1_ge *r, const secp256k1_fe *x, const secp256k1_fe *y) {
133
0
    SECP256K1_FE_VERIFY(x);
134
0
    SECP256K1_FE_VERIFY(y);
135
136
0
    r->infinity = 0;
137
0
    r->x = *x;
138
0
    r->y = *y;
139
140
0
    SECP256K1_GE_VERIFY(r);
141
0
}
142
143
0
static int secp256k1_ge_is_infinity(const secp256k1_ge *a) {
144
0
    SECP256K1_GE_VERIFY(a);
145
146
0
    return a->infinity;
147
0
}
148
149
0
static void secp256k1_ge_neg(secp256k1_ge *r, const secp256k1_ge *a) {
150
0
    SECP256K1_GE_VERIFY(a);
151
152
0
    *r = *a;
153
0
    secp256k1_fe_normalize_weak(&r->y);
154
0
    secp256k1_fe_negate(&r->y, &r->y, 1);
155
156
0
    SECP256K1_GE_VERIFY(r);
157
0
}
158
159
0
static void secp256k1_ge_set_gej(secp256k1_ge *r, secp256k1_gej *a) {
160
0
    secp256k1_fe z2, z3;
161
0
    SECP256K1_GEJ_VERIFY(a);
162
163
0
    r->infinity = a->infinity;
164
0
    secp256k1_fe_inv(&a->z, &a->z);
165
0
    secp256k1_fe_sqr(&z2, &a->z);
166
0
    secp256k1_fe_mul(&z3, &a->z, &z2);
167
0
    secp256k1_fe_mul(&a->x, &a->x, &z2);
168
0
    secp256k1_fe_mul(&a->y, &a->y, &z3);
169
0
    secp256k1_fe_set_int(&a->z, 1);
170
0
    r->x = a->x;
171
0
    r->y = a->y;
172
173
0
    SECP256K1_GEJ_VERIFY(a);
174
0
    SECP256K1_GE_VERIFY(r);
175
0
}
176
177
0
static void secp256k1_ge_set_gej_var(secp256k1_ge *r, secp256k1_gej *a) {
178
0
    secp256k1_fe z2, z3;
179
0
    SECP256K1_GEJ_VERIFY(a);
180
181
0
    if (secp256k1_gej_is_infinity(a)) {
182
0
        secp256k1_ge_set_infinity(r);
183
0
        return;
184
0
    }
185
0
    r->infinity = 0;
186
0
    secp256k1_fe_inv_var(&a->z, &a->z);
187
0
    secp256k1_fe_sqr(&z2, &a->z);
188
0
    secp256k1_fe_mul(&z3, &a->z, &z2);
189
0
    secp256k1_fe_mul(&a->x, &a->x, &z2);
190
0
    secp256k1_fe_mul(&a->y, &a->y, &z3);
191
0
    secp256k1_fe_set_int(&a->z, 1);
192
0
    secp256k1_ge_set_xy(r, &a->x, &a->y);
193
194
0
    SECP256K1_GEJ_VERIFY(a);
195
0
    SECP256K1_GE_VERIFY(r);
196
0
}
197
198
0
static void secp256k1_ge_set_all_gej(secp256k1_ge *r, const secp256k1_gej *a, size_t len) {
199
0
    secp256k1_fe u;
200
0
    size_t i;
201
0
#ifdef VERIFY
202
0
    for (i = 0; i < len; i++) {
203
0
        SECP256K1_GEJ_VERIFY(&a[i]);
204
0
        VERIFY_CHECK(!secp256k1_gej_is_infinity(&a[i]));
205
0
    }
206
0
#endif
207
0
208
0
    if (len == 0) {
209
0
        return;
210
0
    }
211
0
212
0
    /* Use destination's x coordinates as scratch space */
213
0
    r[0].x = a[0].z;
214
0
    for (i = 1; i < len; i++) {
215
0
        secp256k1_fe_mul(&r[i].x, &r[i - 1].x, &a[i].z);
216
0
    }
217
0
    secp256k1_fe_inv(&u, &r[len - 1].x);
218
0
219
0
    for (i = len - 1; i > 0; i--) {
220
0
        secp256k1_fe_mul(&r[i].x, &r[i - 1].x, &u);
221
0
        secp256k1_fe_mul(&u, &u, &a[i].z);
222
0
    }
223
0
    r[0].x = u;
224
0
225
0
    for (i = 0; i < len; i++) {
226
0
        secp256k1_ge_set_gej_zinv(&r[i], &a[i], &r[i].x);
227
0
    }
228
0
229
0
#ifdef VERIFY
230
0
    for (i = 0; i < len; i++) {
231
0
        SECP256K1_GE_VERIFY(&r[i]);
232
0
    }
233
0
#endif
234
0
}
235
236
0
static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len) {
237
0
    secp256k1_fe u;
238
0
    size_t i;
239
0
    size_t last_i = SIZE_MAX;
240
0
#ifdef VERIFY
241
0
    for (i = 0; i < len; i++) {
242
0
        SECP256K1_GEJ_VERIFY(&a[i]);
243
0
    }
244
0
#endif
245
0
246
0
    for (i = 0; i < len; i++) {
247
0
        if (a[i].infinity) {
248
0
            secp256k1_ge_set_infinity(&r[i]);
249
0
        } else {
250
0
            /* Use destination's x coordinates as scratch space */
251
0
            if (last_i == SIZE_MAX) {
252
0
                r[i].x = a[i].z;
253
0
            } else {
254
0
                secp256k1_fe_mul(&r[i].x, &r[last_i].x, &a[i].z);
255
0
            }
256
0
            last_i = i;
257
0
        }
258
0
    }
259
0
    if (last_i == SIZE_MAX) {
260
0
        return;
261
0
    }
262
0
    secp256k1_fe_inv_var(&u, &r[last_i].x);
263
0
264
0
    i = last_i;
265
0
    while (i > 0) {
266
0
        i--;
267
0
        if (!a[i].infinity) {
268
0
            secp256k1_fe_mul(&r[last_i].x, &r[i].x, &u);
269
0
            secp256k1_fe_mul(&u, &u, &a[last_i].z);
270
0
            last_i = i;
271
0
        }
272
0
    }
273
0
    VERIFY_CHECK(!a[last_i].infinity);
274
0
    r[last_i].x = u;
275
0
276
0
    for (i = 0; i < len; i++) {
277
0
        if (!a[i].infinity) {
278
0
            secp256k1_ge_set_gej_zinv(&r[i], &a[i], &r[i].x);
279
0
        }
280
0
    }
281
0
282
0
#ifdef VERIFY
283
0
    for (i = 0; i < len; i++) {
284
0
        SECP256K1_GE_VERIFY(&r[i]);
285
0
    }
286
0
#endif
287
0
}
288
289
0
static void secp256k1_ge_table_set_globalz(size_t len, secp256k1_ge *a, const secp256k1_fe *zr) {
290
0
    size_t i;
291
0
    secp256k1_fe zs;
292
#ifdef VERIFY
293
    for (i = 0; i < len; i++) {
294
        SECP256K1_GE_VERIFY(&a[i]);
295
        SECP256K1_FE_VERIFY(&zr[i]);
296
    }
297
#endif
298
299
0
    if (len > 0) {
300
0
        i = len - 1;
301
        /* Ensure all y values are in weak normal form for fast negation of points */
302
0
        secp256k1_fe_normalize_weak(&a[i].y);
303
0
        zs = zr[i];
304
305
        /* Work our way backwards, using the z-ratios to scale the x/y values. */
306
0
        while (i > 0) {
307
0
            if (i != len - 1) {
308
0
                secp256k1_fe_mul(&zs, &zs, &zr[i]);
309
0
            }
310
0
            i--;
311
0
            secp256k1_ge_set_ge_zinv(&a[i], &a[i], &zs);
312
0
        }
313
0
    }
314
315
#ifdef VERIFY
316
    for (i = 0; i < len; i++) {
317
        SECP256K1_GE_VERIFY(&a[i]);
318
    }
319
#endif
320
0
}
321
322
0
static void secp256k1_gej_set_infinity(secp256k1_gej *r) {
323
0
    r->infinity = 1;
324
0
    secp256k1_fe_set_int(&r->x, 0);
325
0
    secp256k1_fe_set_int(&r->y, 0);
326
0
    secp256k1_fe_set_int(&r->z, 0);
327
328
0
    SECP256K1_GEJ_VERIFY(r);
329
0
}
330
331
0
static void secp256k1_ge_set_infinity(secp256k1_ge *r) {
332
0
    r->infinity = 1;
333
0
    secp256k1_fe_set_int(&r->x, 0);
334
0
    secp256k1_fe_set_int(&r->y, 0);
335
336
0
    SECP256K1_GE_VERIFY(r);
337
0
}
338
339
0
static void secp256k1_gej_clear(secp256k1_gej *r) {
340
0
    secp256k1_memclear(r, sizeof(secp256k1_gej));
341
0
}
342
343
0
static void secp256k1_ge_clear(secp256k1_ge *r) {
344
0
    secp256k1_memclear(r, sizeof(secp256k1_ge));
345
0
}
346
347
0
static int secp256k1_ge_set_xo_var(secp256k1_ge *r, const secp256k1_fe *x, int odd) {
348
0
    secp256k1_fe x2, x3;
349
0
    int ret;
350
0
    SECP256K1_FE_VERIFY(x);
351
352
0
    r->x = *x;
353
0
    secp256k1_fe_sqr(&x2, x);
354
0
    secp256k1_fe_mul(&x3, x, &x2);
355
0
    r->infinity = 0;
356
0
    secp256k1_fe_add_int(&x3, SECP256K1_B);
357
0
    ret = secp256k1_fe_sqrt(&r->y, &x3);
358
0
    secp256k1_fe_normalize_var(&r->y);
359
0
    if (secp256k1_fe_is_odd(&r->y) != odd) {
360
0
        secp256k1_fe_negate(&r->y, &r->y, 1);
361
0
    }
362
363
0
    SECP256K1_GE_VERIFY(r);
364
0
    return ret;
365
0
}
366
367
0
static void secp256k1_gej_set_ge(secp256k1_gej *r, const secp256k1_ge *a) {
368
0
   SECP256K1_GE_VERIFY(a);
369
370
0
   r->infinity = a->infinity;
371
0
   r->x = a->x;
372
0
   r->y = a->y;
373
0
   secp256k1_fe_set_int(&r->z, 1);
374
375
0
   SECP256K1_GEJ_VERIFY(r);
376
0
}
377
378
0
static int secp256k1_gej_eq_var(const secp256k1_gej *a, const secp256k1_gej *b) {
379
0
    secp256k1_gej tmp;
380
0
    SECP256K1_GEJ_VERIFY(b);
381
0
    SECP256K1_GEJ_VERIFY(a);
382
0
383
0
    secp256k1_gej_neg(&tmp, a);
384
0
    secp256k1_gej_add_var(&tmp, &tmp, b, NULL);
385
0
    return secp256k1_gej_is_infinity(&tmp);
386
0
}
387
388
0
static int secp256k1_gej_eq_ge_var(const secp256k1_gej *a, const secp256k1_ge *b) {
389
0
    secp256k1_gej tmp;
390
0
    SECP256K1_GEJ_VERIFY(a);
391
0
    SECP256K1_GE_VERIFY(b);
392
0
393
0
    secp256k1_gej_neg(&tmp, a);
394
0
    secp256k1_gej_add_ge_var(&tmp, &tmp, b, NULL);
395
0
    return secp256k1_gej_is_infinity(&tmp);
396
0
}
397
398
0
static int secp256k1_ge_eq_var(const secp256k1_ge *a, const secp256k1_ge *b) {
399
0
    secp256k1_fe tmp;
400
0
    SECP256K1_GE_VERIFY(a);
401
0
    SECP256K1_GE_VERIFY(b);
402
0
403
0
    if (a->infinity != b->infinity) return 0;
404
0
    if (a->infinity) return 1;
405
0
406
0
    tmp = a->x;
407
0
    secp256k1_fe_normalize_weak(&tmp);
408
0
    if (!secp256k1_fe_equal(&tmp, &b->x)) return 0;
409
0
410
0
    tmp = a->y;
411
0
    secp256k1_fe_normalize_weak(&tmp);
412
0
    if (!secp256k1_fe_equal(&tmp, &b->y)) return 0;
413
0
414
0
    return 1;
415
0
}
416
417
0
static int secp256k1_gej_eq_x_var(const secp256k1_fe *x, const secp256k1_gej *a) {
418
0
    secp256k1_fe r;
419
0
    SECP256K1_FE_VERIFY(x);
420
0
    SECP256K1_GEJ_VERIFY(a);
421
0
    VERIFY_CHECK(!a->infinity);
422
423
0
    secp256k1_fe_sqr(&r, &a->z); secp256k1_fe_mul(&r, &r, x);
424
0
    return secp256k1_fe_equal(&r, &a->x);
425
0
}
426
427
0
static void secp256k1_gej_neg(secp256k1_gej *r, const secp256k1_gej *a) {
428
0
    SECP256K1_GEJ_VERIFY(a);
429
0
430
0
    r->infinity = a->infinity;
431
0
    r->x = a->x;
432
0
    r->y = a->y;
433
0
    r->z = a->z;
434
0
    secp256k1_fe_normalize_weak(&r->y);
435
0
    secp256k1_fe_negate(&r->y, &r->y, 1);
436
0
437
0
    SECP256K1_GEJ_VERIFY(r);
438
0
}
439
440
0
static int secp256k1_gej_is_infinity(const secp256k1_gej *a) {
441
0
    SECP256K1_GEJ_VERIFY(a);
442
443
0
    return a->infinity;
444
0
}
445
446
0
static int secp256k1_ge_is_valid_var(const secp256k1_ge *a) {
447
0
    secp256k1_fe y2, x3;
448
0
    SECP256K1_GE_VERIFY(a);
449
450
0
    if (a->infinity) {
451
0
        return 0;
452
0
    }
453
    /* y^2 = x^3 + 7 */
454
0
    secp256k1_fe_sqr(&y2, &a->y);
455
0
    secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x);
456
0
    secp256k1_fe_add_int(&x3, SECP256K1_B);
457
0
    return secp256k1_fe_equal(&y2, &x3);
458
0
}
459
460
0
static SECP256K1_INLINE void secp256k1_gej_double(secp256k1_gej *r, const secp256k1_gej *a) {
461
    /* Operations: 3 mul, 4 sqr, 8 add/half/mul_int/negate */
462
0
    secp256k1_fe l, s, t;
463
0
    SECP256K1_GEJ_VERIFY(a);
464
465
0
    r->infinity = a->infinity;
466
467
    /* Formula used:
468
     * L = (3/2) * X1^2
469
     * S = Y1^2
470
     * T = -X1*S
471
     * X3 = L^2 + 2*T
472
     * Y3 = -(L*(X3 + T) + S^2)
473
     * Z3 = Y1*Z1
474
     */
475
476
0
    secp256k1_fe_mul(&r->z, &a->z, &a->y); /* Z3 = Y1*Z1 (1) */
477
0
    secp256k1_fe_sqr(&s, &a->y);           /* S = Y1^2 (1) */
478
0
    secp256k1_fe_sqr(&l, &a->x);           /* L = X1^2 (1) */
479
0
    secp256k1_fe_mul_int(&l, 3);           /* L = 3*X1^2 (3) */
480
0
    secp256k1_fe_half(&l);                 /* L = 3/2*X1^2 (2) */
481
0
    secp256k1_fe_negate(&t, &s, 1);        /* T = -S (2) */
482
0
    secp256k1_fe_mul(&t, &t, &a->x);       /* T = -X1*S (1) */
483
0
    secp256k1_fe_sqr(&r->x, &l);           /* X3 = L^2 (1) */
484
0
    secp256k1_fe_add(&r->x, &t);           /* X3 = L^2 + T (2) */
485
0
    secp256k1_fe_add(&r->x, &t);           /* X3 = L^2 + 2*T (3) */
486
0
    secp256k1_fe_sqr(&s, &s);              /* S' = S^2 (1) */
487
0
    secp256k1_fe_add(&t, &r->x);           /* T' = X3 + T (4) */
488
0
    secp256k1_fe_mul(&r->y, &t, &l);       /* Y3 = L*(X3 + T) (1) */
489
0
    secp256k1_fe_add(&r->y, &s);           /* Y3 = L*(X3 + T) + S^2 (2) */
490
0
    secp256k1_fe_negate(&r->y, &r->y, 2);  /* Y3 = -(L*(X3 + T) + S^2) (3) */
491
492
0
    SECP256K1_GEJ_VERIFY(r);
493
0
}
494
495
0
static void secp256k1_gej_double_var(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr) {
496
0
    SECP256K1_GEJ_VERIFY(a);
497
498
    /** For secp256k1, 2Q is infinity if and only if Q is infinity. This is because if 2Q = infinity,
499
     *  Q must equal -Q, or that Q.y == -(Q.y), or Q.y is 0. For a point on y^2 = x^3 + 7 to have
500
     *  y=0, x^3 must be -7 mod p. However, -7 has no cube root mod p.
501
     *
502
     *  Having said this, if this function receives a point on a sextic twist, e.g. by
503
     *  a fault attack, it is possible for y to be 0. This happens for y^2 = x^3 + 6,
504
     *  since -6 does have a cube root mod p. For this point, this function will not set
505
     *  the infinity flag even though the point doubles to infinity, and the result
506
     *  point will be gibberish (z = 0 but infinity = 0).
507
     */
508
0
    if (a->infinity) {
509
0
        secp256k1_gej_set_infinity(r);
510
0
        if (rzr != NULL) {
511
0
            secp256k1_fe_set_int(rzr, 1);
512
0
        }
513
0
        return;
514
0
    }
515
516
0
    if (rzr != NULL) {
517
0
        *rzr = a->y;
518
0
        secp256k1_fe_normalize_weak(rzr);
519
0
    }
520
521
0
    secp256k1_gej_double(r, a);
522
523
0
    SECP256K1_GEJ_VERIFY(r);
524
0
}
525
526
0
static void secp256k1_gej_add_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_gej *b, secp256k1_fe *rzr) {
527
0
    /* 12 mul, 4 sqr, 11 add/negate/normalizes_to_zero (ignoring special cases) */
528
0
    secp256k1_fe z22, z12, u1, u2, s1, s2, h, i, h2, h3, t;
529
0
    SECP256K1_GEJ_VERIFY(a);
530
0
    SECP256K1_GEJ_VERIFY(b);
531
0
532
0
    if (a->infinity) {
533
0
        VERIFY_CHECK(rzr == NULL);
534
0
        *r = *b;
535
0
        return;
536
0
    }
537
0
    if (b->infinity) {
538
0
        if (rzr != NULL) {
539
0
            secp256k1_fe_set_int(rzr, 1);
540
0
        }
541
0
        *r = *a;
542
0
        return;
543
0
    }
544
0
545
0
    secp256k1_fe_sqr(&z22, &b->z);
546
0
    secp256k1_fe_sqr(&z12, &a->z);
547
0
    secp256k1_fe_mul(&u1, &a->x, &z22);
548
0
    secp256k1_fe_mul(&u2, &b->x, &z12);
549
0
    secp256k1_fe_mul(&s1, &a->y, &z22); secp256k1_fe_mul(&s1, &s1, &b->z);
550
0
    secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z);
551
0
    secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2);
552
0
    secp256k1_fe_negate(&i, &s2, 1); secp256k1_fe_add(&i, &s1);
553
0
    if (secp256k1_fe_normalizes_to_zero_var(&h)) {
554
0
        if (secp256k1_fe_normalizes_to_zero_var(&i)) {
555
0
            secp256k1_gej_double_var(r, a, rzr);
556
0
        } else {
557
0
            if (rzr != NULL) {
558
0
                secp256k1_fe_set_int(rzr, 0);
559
0
            }
560
0
            secp256k1_gej_set_infinity(r);
561
0
        }
562
0
        return;
563
0
    }
564
0
565
0
    r->infinity = 0;
566
0
    secp256k1_fe_mul(&t, &h, &b->z);
567
0
    if (rzr != NULL) {
568
0
        *rzr = t;
569
0
    }
570
0
    secp256k1_fe_mul(&r->z, &a->z, &t);
571
0
572
0
    secp256k1_fe_sqr(&h2, &h);
573
0
    secp256k1_fe_negate(&h2, &h2, 1);
574
0
    secp256k1_fe_mul(&h3, &h2, &h);
575
0
    secp256k1_fe_mul(&t, &u1, &h2);
576
0
577
0
    secp256k1_fe_sqr(&r->x, &i);
578
0
    secp256k1_fe_add(&r->x, &h3);
579
0
    secp256k1_fe_add(&r->x, &t);
580
0
    secp256k1_fe_add(&r->x, &t);
581
0
582
0
    secp256k1_fe_add(&t, &r->x);
583
0
    secp256k1_fe_mul(&r->y, &t, &i);
584
0
    secp256k1_fe_mul(&h3, &h3, &s1);
585
0
    secp256k1_fe_add(&r->y, &h3);
586
0
587
0
    SECP256K1_GEJ_VERIFY(r);
588
0
}
589
590
0
static void secp256k1_gej_add_ge_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, secp256k1_fe *rzr) {
591
    /* Operations: 8 mul, 3 sqr, 11 add/negate/normalizes_to_zero (ignoring special cases) */
592
0
    secp256k1_fe z12, u1, u2, s1, s2, h, i, h2, h3, t;
593
0
    SECP256K1_GEJ_VERIFY(a);
594
0
    SECP256K1_GE_VERIFY(b);
595
596
0
    if (a->infinity) {
597
0
        VERIFY_CHECK(rzr == NULL);
598
0
        secp256k1_gej_set_ge(r, b);
599
0
        return;
600
0
    }
601
0
    if (b->infinity) {
602
0
        if (rzr != NULL) {
603
0
            secp256k1_fe_set_int(rzr, 1);
604
0
        }
605
0
        *r = *a;
606
0
        return;
607
0
    }
608
609
0
    secp256k1_fe_sqr(&z12, &a->z);
610
0
    u1 = a->x;
611
0
    secp256k1_fe_mul(&u2, &b->x, &z12);
612
0
    s1 = a->y;
613
0
    secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z);
614
0
    secp256k1_fe_negate(&h, &u1, SECP256K1_GEJ_X_MAGNITUDE_MAX); secp256k1_fe_add(&h, &u2);
615
0
    secp256k1_fe_negate(&i, &s2, 1); secp256k1_fe_add(&i, &s1);
616
0
    if (secp256k1_fe_normalizes_to_zero_var(&h)) {
617
0
        if (secp256k1_fe_normalizes_to_zero_var(&i)) {
618
0
            secp256k1_gej_double_var(r, a, rzr);
619
0
        } else {
620
0
            if (rzr != NULL) {
621
0
                secp256k1_fe_set_int(rzr, 0);
622
0
            }
623
0
            secp256k1_gej_set_infinity(r);
624
0
        }
625
0
        return;
626
0
    }
627
628
0
    r->infinity = 0;
629
0
    if (rzr != NULL) {
630
0
        *rzr = h;
631
0
    }
632
0
    secp256k1_fe_mul(&r->z, &a->z, &h);
633
634
0
    secp256k1_fe_sqr(&h2, &h);
635
0
    secp256k1_fe_negate(&h2, &h2, 1);
636
0
    secp256k1_fe_mul(&h3, &h2, &h);
637
0
    secp256k1_fe_mul(&t, &u1, &h2);
638
639
0
    secp256k1_fe_sqr(&r->x, &i);
640
0
    secp256k1_fe_add(&r->x, &h3);
641
0
    secp256k1_fe_add(&r->x, &t);
642
0
    secp256k1_fe_add(&r->x, &t);
643
644
0
    secp256k1_fe_add(&t, &r->x);
645
0
    secp256k1_fe_mul(&r->y, &t, &i);
646
0
    secp256k1_fe_mul(&h3, &h3, &s1);
647
0
    secp256k1_fe_add(&r->y, &h3);
648
649
0
    SECP256K1_GEJ_VERIFY(r);
650
0
    if (rzr != NULL) SECP256K1_FE_VERIFY(rzr);
651
0
}
652
653
0
static void secp256k1_gej_add_zinv_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, const secp256k1_fe *bzinv) {
654
    /* Operations: 9 mul, 3 sqr, 11 add/negate/normalizes_to_zero (ignoring special cases) */
655
0
    secp256k1_fe az, z12, u1, u2, s1, s2, h, i, h2, h3, t;
656
0
    SECP256K1_GEJ_VERIFY(a);
657
0
    SECP256K1_GE_VERIFY(b);
658
0
    SECP256K1_FE_VERIFY(bzinv);
659
660
0
    if (a->infinity) {
661
0
        secp256k1_fe bzinv2, bzinv3;
662
0
        r->infinity = b->infinity;
663
0
        secp256k1_fe_sqr(&bzinv2, bzinv);
664
0
        secp256k1_fe_mul(&bzinv3, &bzinv2, bzinv);
665
0
        secp256k1_fe_mul(&r->x, &b->x, &bzinv2);
666
0
        secp256k1_fe_mul(&r->y, &b->y, &bzinv3);
667
0
        secp256k1_fe_set_int(&r->z, 1);
668
0
        SECP256K1_GEJ_VERIFY(r);
669
0
        return;
670
0
    }
671
0
    if (b->infinity) {
672
0
        *r = *a;
673
0
        return;
674
0
    }
675
676
    /** We need to calculate (rx,ry,rz) = (ax,ay,az) + (bx,by,1/bzinv). Due to
677
     *  secp256k1's isomorphism we can multiply the Z coordinates on both sides
678
     *  by bzinv, and get: (rx,ry,rz*bzinv) = (ax,ay,az*bzinv) + (bx,by,1).
679
     *  This means that (rx,ry,rz) can be calculated as
680
     *  (ax,ay,az*bzinv) + (bx,by,1), when not applying the bzinv factor to rz.
681
     *  The variable az below holds the modified Z coordinate for a, which is used
682
     *  for the computation of rx and ry, but not for rz.
683
     */
684
0
    secp256k1_fe_mul(&az, &a->z, bzinv);
685
686
0
    secp256k1_fe_sqr(&z12, &az);
687
0
    u1 = a->x;
688
0
    secp256k1_fe_mul(&u2, &b->x, &z12);
689
0
    s1 = a->y;
690
0
    secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &az);
691
0
    secp256k1_fe_negate(&h, &u1, SECP256K1_GEJ_X_MAGNITUDE_MAX); secp256k1_fe_add(&h, &u2);
692
0
    secp256k1_fe_negate(&i, &s2, 1); secp256k1_fe_add(&i, &s1);
693
0
    if (secp256k1_fe_normalizes_to_zero_var(&h)) {
694
0
        if (secp256k1_fe_normalizes_to_zero_var(&i)) {
695
0
            secp256k1_gej_double_var(r, a, NULL);
696
0
        } else {
697
0
            secp256k1_gej_set_infinity(r);
698
0
        }
699
0
        return;
700
0
    }
701
702
0
    r->infinity = 0;
703
0
    secp256k1_fe_mul(&r->z, &a->z, &h);
704
705
0
    secp256k1_fe_sqr(&h2, &h);
706
0
    secp256k1_fe_negate(&h2, &h2, 1);
707
0
    secp256k1_fe_mul(&h3, &h2, &h);
708
0
    secp256k1_fe_mul(&t, &u1, &h2);
709
710
0
    secp256k1_fe_sqr(&r->x, &i);
711
0
    secp256k1_fe_add(&r->x, &h3);
712
0
    secp256k1_fe_add(&r->x, &t);
713
0
    secp256k1_fe_add(&r->x, &t);
714
715
0
    secp256k1_fe_add(&t, &r->x);
716
0
    secp256k1_fe_mul(&r->y, &t, &i);
717
0
    secp256k1_fe_mul(&h3, &h3, &s1);
718
0
    secp256k1_fe_add(&r->y, &h3);
719
720
0
    SECP256K1_GEJ_VERIFY(r);
721
0
}
722
723
724
0
static void secp256k1_gej_add_ge(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b) {
725
    /* Operations: 7 mul, 5 sqr, 21 add/cmov/half/mul_int/negate/normalizes_to_zero */
726
0
    secp256k1_fe zz, u1, u2, s1, s2, t, tt, m, n, q, rr;
727
0
    secp256k1_fe m_alt, rr_alt;
728
0
    int degenerate;
729
0
    SECP256K1_GEJ_VERIFY(a);
730
0
    SECP256K1_GE_VERIFY(b);
731
0
    VERIFY_CHECK(!b->infinity);
732
733
    /*  In:
734
     *    Eric Brier and Marc Joye, Weierstrass Elliptic Curves and Side-Channel Attacks.
735
     *    In D. Naccache and P. Paillier, Eds., Public Key Cryptography, vol. 2274 of Lecture Notes in Computer Science, pages 335-345. Springer-Verlag, 2002.
736
     *  we find as solution for a unified addition/doubling formula:
737
     *    lambda = ((x1 + x2)^2 - x1 * x2 + a) / (y1 + y2), with a = 0 for secp256k1's curve equation.
738
     *    x3 = lambda^2 - (x1 + x2)
739
     *    2*y3 = lambda * (x1 + x2 - 2 * x3) - (y1 + y2).
740
     *
741
     *  Substituting x_i = Xi / Zi^2 and yi = Yi / Zi^3, for i=1,2,3, gives:
742
     *    U1 = X1*Z2^2, U2 = X2*Z1^2
743
     *    S1 = Y1*Z2^3, S2 = Y2*Z1^3
744
     *    Z = Z1*Z2
745
     *    T = U1+U2
746
     *    M = S1+S2
747
     *    Q = -T*M^2
748
     *    R = T^2-U1*U2
749
     *    X3 = R^2+Q
750
     *    Y3 = -(R*(2*X3+Q)+M^4)/2
751
     *    Z3 = M*Z
752
     *  (Note that the paper uses xi = Xi / Zi and yi = Yi / Zi instead.)
753
     *
754
     *  This formula has the benefit of being the same for both addition
755
     *  of distinct points and doubling. However, it breaks down in the
756
     *  case that either point is infinity, or that y1 = -y2. We handle
757
     *  these cases in the following ways:
758
     *
759
     *    - If b is infinity we simply bail by means of a VERIFY_CHECK.
760
     *
761
     *    - If a is infinity, we detect this, and at the end of the
762
     *      computation replace the result (which will be meaningless,
763
     *      but we compute to be constant-time) with b.x : b.y : 1.
764
     *
765
     *    - If a = -b, we have y1 = -y2, which is a degenerate case.
766
     *      But here the answer is infinity, so we simply set the
767
     *      infinity flag of the result, overriding the computed values
768
     *      without even needing to cmov.
769
     *
770
     *    - If y1 = -y2 but x1 != x2, which does occur thanks to certain
771
     *      properties of our curve (specifically, 1 has nontrivial cube
772
     *      roots in our field, and the curve equation has no x coefficient)
773
     *      then the answer is not infinity but also not given by the above
774
     *      equation. In this case, we cmov in place an alternate expression
775
     *      for lambda. Specifically (y1 - y2)/(x1 - x2). Where both these
776
     *      expressions for lambda are defined, they are equal, and can be
777
     *      obtained from each other by multiplication by (y1 + y2)/(y1 + y2)
778
     *      then substitution of x^3 + 7 for y^2 (using the curve equation).
779
     *      For all pairs of nonzero points (a, b) at least one is defined,
780
     *      so this covers everything.
781
     */
782
783
0
    secp256k1_fe_sqr(&zz, &a->z);                       /* z = Z1^2 */
784
0
    u1 = a->x;                                          /* u1 = U1 = X1*Z2^2 (GEJ_X_M) */
785
0
    secp256k1_fe_mul(&u2, &b->x, &zz);                  /* u2 = U2 = X2*Z1^2 (1) */
786
0
    s1 = a->y;                                          /* s1 = S1 = Y1*Z2^3 (GEJ_Y_M) */
787
0
    secp256k1_fe_mul(&s2, &b->y, &zz);                  /* s2 = Y2*Z1^2 (1) */
788
0
    secp256k1_fe_mul(&s2, &s2, &a->z);                  /* s2 = S2 = Y2*Z1^3 (1) */
789
0
    t = u1; secp256k1_fe_add(&t, &u2);                  /* t = T = U1+U2 (GEJ_X_M+1) */
790
0
    m = s1; secp256k1_fe_add(&m, &s2);                  /* m = M = S1+S2 (GEJ_Y_M+1) */
791
0
    secp256k1_fe_sqr(&rr, &t);                          /* rr = T^2 (1) */
792
0
    secp256k1_fe_negate(&m_alt, &u2, 1);                /* Malt = -X2*Z1^2 (2) */
793
0
    secp256k1_fe_mul(&tt, &u1, &m_alt);                 /* tt = -U1*U2 (1) */
794
0
    secp256k1_fe_add(&rr, &tt);                         /* rr = R = T^2-U1*U2 (2) */
795
    /* If lambda = R/M = R/0 we have a problem (except in the "trivial"
796
     * case that Z = z1z2 = 0, and this is special-cased later on). */
797
0
    degenerate = secp256k1_fe_normalizes_to_zero(&m);
798
    /* This only occurs when y1 == -y2 and x1^3 == x2^3, but x1 != x2.
799
     * This means either x1 == beta*x2 or beta*x1 == x2, where beta is
800
     * a nontrivial cube root of one. In either case, an alternate
801
     * non-indeterminate expression for lambda is (y1 - y2)/(x1 - x2),
802
     * so we set R/M equal to this. */
803
0
    rr_alt = s1;
804
0
    secp256k1_fe_mul_int(&rr_alt, 2);       /* rr_alt = Y1*Z2^3 - Y2*Z1^3 (GEJ_Y_M*2) */
805
0
    secp256k1_fe_add(&m_alt, &u1);          /* Malt = X1*Z2^2 - X2*Z1^2 (GEJ_X_M+2) */
806
807
0
    secp256k1_fe_cmov(&rr_alt, &rr, !degenerate);       /* rr_alt (GEJ_Y_M*2) */
808
0
    secp256k1_fe_cmov(&m_alt, &m, !degenerate);         /* m_alt (GEJ_X_M+2) */
809
    /* Now Ralt / Malt = lambda and is guaranteed not to be Ralt / 0.
810
     * From here on out Ralt and Malt represent the numerator
811
     * and denominator of lambda; R and M represent the explicit
812
     * expressions x1^2 + x2^2 + x1x2 and y1 + y2. */
813
0
    secp256k1_fe_sqr(&n, &m_alt);                       /* n = Malt^2 (1) */
814
0
    secp256k1_fe_negate(&q, &t,
815
0
        SECP256K1_GEJ_X_MAGNITUDE_MAX + 1);             /* q = -T (GEJ_X_M+2) */
816
0
    secp256k1_fe_mul(&q, &q, &n);                       /* q = Q = -T*Malt^2 (1) */
817
    /* These two lines use the observation that either M == Malt or M == 0,
818
     * so M^3 * Malt is either Malt^4 (which is computed by squaring), or
819
     * zero (which is "computed" by cmov). So the cost is one squaring
820
     * versus two multiplications. */
821
0
    secp256k1_fe_sqr(&n, &n);                           /* n = Malt^4 (1) */
822
0
    secp256k1_fe_cmov(&n, &m, degenerate);              /* n = M^3 * Malt (GEJ_Y_M+1) */
823
0
    secp256k1_fe_sqr(&t, &rr_alt);                      /* t = Ralt^2 (1) */
824
0
    secp256k1_fe_mul(&r->z, &a->z, &m_alt);             /* r->z = Z3 = Malt*Z (1) */
825
0
    secp256k1_fe_add(&t, &q);                           /* t = Ralt^2 + Q (2) */
826
0
    r->x = t;                                           /* r->x = X3 = Ralt^2 + Q (2) */
827
0
    secp256k1_fe_mul_int(&t, 2);                        /* t = 2*X3 (4) */
828
0
    secp256k1_fe_add(&t, &q);                           /* t = 2*X3 + Q (5) */
829
0
    secp256k1_fe_mul(&t, &t, &rr_alt);                  /* t = Ralt*(2*X3 + Q) (1) */
830
0
    secp256k1_fe_add(&t, &n);                           /* t = Ralt*(2*X3 + Q) + M^3*Malt (GEJ_Y_M+2) */
831
0
    secp256k1_fe_negate(&r->y, &t,
832
0
        SECP256K1_GEJ_Y_MAGNITUDE_MAX + 2);             /* r->y = -(Ralt*(2*X3 + Q) + M^3*Malt) (GEJ_Y_M+3) */
833
0
    secp256k1_fe_half(&r->y);                           /* r->y = Y3 = -(Ralt*(2*X3 + Q) + M^3*Malt)/2 ((GEJ_Y_M+3)/2 + 1) */
834
835
    /* In case a->infinity == 1, replace r with (b->x, b->y, 1). */
836
0
    secp256k1_fe_cmov(&r->x, &b->x, a->infinity);
837
0
    secp256k1_fe_cmov(&r->y, &b->y, a->infinity);
838
0
    secp256k1_fe_cmov(&r->z, &secp256k1_fe_one, a->infinity);
839
840
    /* Set r->infinity if r->z is 0.
841
     *
842
     * If a->infinity is set, then r->infinity = (r->z == 0) = (1 == 0) = false,
843
     * which is correct because the function assumes that b is not infinity.
844
     *
845
     * Now assume !a->infinity. This implies Z = Z1 != 0.
846
     *
847
     * Case y1 = -y2:
848
     * In this case we could have a = -b, namely if x1 = x2.
849
     * We have degenerate = true, r->z = (x1 - x2) * Z.
850
     * Then r->infinity = ((x1 - x2)Z == 0) = (x1 == x2) = (a == -b).
851
     *
852
     * Case y1 != -y2:
853
     * In this case, we can't have a = -b.
854
     * We have degenerate = false, r->z = (y1 + y2) * Z.
855
     * Then r->infinity = ((y1 + y2)Z == 0) = (y1 == -y2) = false. */
856
0
    r->infinity = secp256k1_fe_normalizes_to_zero(&r->z);
857
858
0
    SECP256K1_GEJ_VERIFY(r);
859
0
}
860
861
0
static void secp256k1_gej_rescale(secp256k1_gej *r, const secp256k1_fe *s) {
862
    /* Operations: 4 mul, 1 sqr */
863
0
    secp256k1_fe zz;
864
0
    SECP256K1_GEJ_VERIFY(r);
865
0
    SECP256K1_FE_VERIFY(s);
866
0
    VERIFY_CHECK(!secp256k1_fe_normalizes_to_zero_var(s));
867
868
0
    secp256k1_fe_sqr(&zz, s);
869
0
    secp256k1_fe_mul(&r->x, &r->x, &zz);                /* r->x *= s^2 */
870
0
    secp256k1_fe_mul(&r->y, &r->y, &zz);
871
0
    secp256k1_fe_mul(&r->y, &r->y, s);                  /* r->y *= s^3 */
872
0
    secp256k1_fe_mul(&r->z, &r->z, s);                  /* r->z *= s   */
873
874
0
    SECP256K1_GEJ_VERIFY(r);
875
0
}
876
877
0
static void secp256k1_ge_to_storage(secp256k1_ge_storage *r, const secp256k1_ge *a) {
878
0
    secp256k1_fe x, y;
879
0
    SECP256K1_GE_VERIFY(a);
880
0
    VERIFY_CHECK(!a->infinity);
881
882
0
    x = a->x;
883
0
    secp256k1_fe_normalize(&x);
884
0
    y = a->y;
885
0
    secp256k1_fe_normalize(&y);
886
0
    secp256k1_fe_to_storage(&r->x, &x);
887
0
    secp256k1_fe_to_storage(&r->y, &y);
888
0
}
889
890
0
static void secp256k1_ge_from_storage(secp256k1_ge *r, const secp256k1_ge_storage *a) {
891
0
    secp256k1_fe_from_storage(&r->x, &a->x);
892
0
    secp256k1_fe_from_storage(&r->y, &a->y);
893
0
    r->infinity = 0;
894
895
0
    SECP256K1_GE_VERIFY(r);
896
0
}
897
898
0
static SECP256K1_INLINE void secp256k1_gej_cmov(secp256k1_gej *r, const secp256k1_gej *a, int flag) {
899
0
    SECP256K1_GEJ_VERIFY(r);
900
0
    SECP256K1_GEJ_VERIFY(a);
901
0
902
0
    secp256k1_fe_cmov(&r->x, &a->x, flag);
903
0
    secp256k1_fe_cmov(&r->y, &a->y, flag);
904
0
    secp256k1_fe_cmov(&r->z, &a->z, flag);
905
0
    r->infinity ^= (r->infinity ^ a->infinity) & flag;
906
0
907
0
    SECP256K1_GEJ_VERIFY(r);
908
0
}
909
910
0
static SECP256K1_INLINE void secp256k1_ge_storage_cmov(secp256k1_ge_storage *r, const secp256k1_ge_storage *a, int flag) {
911
0
    secp256k1_fe_storage_cmov(&r->x, &a->x, flag);
912
0
    secp256k1_fe_storage_cmov(&r->y, &a->y, flag);
913
0
}
914
915
0
static void secp256k1_ge_mul_lambda(secp256k1_ge *r, const secp256k1_ge *a) {
916
0
    SECP256K1_GE_VERIFY(a);
917
918
0
    *r = *a;
919
0
    secp256k1_fe_mul(&r->x, &r->x, &secp256k1_const_beta);
920
921
0
    SECP256K1_GE_VERIFY(r);
922
0
}
923
924
0
static int secp256k1_ge_is_in_correct_subgroup(const secp256k1_ge* ge) {
925
#ifdef EXHAUSTIVE_TEST_ORDER
926
    secp256k1_gej out;
927
    int i;
928
    SECP256K1_GE_VERIFY(ge);
929
930
    /* A very simple EC multiplication ladder that avoids a dependency on ecmult. */
931
    secp256k1_gej_set_infinity(&out);
932
    for (i = 0; i < 32; ++i) {
933
        secp256k1_gej_double_var(&out, &out, NULL);
934
        if ((((uint32_t)EXHAUSTIVE_TEST_ORDER) >> (31 - i)) & 1) {
935
            secp256k1_gej_add_ge_var(&out, &out, ge, NULL);
936
        }
937
    }
938
    return secp256k1_gej_is_infinity(&out);
939
#else
940
0
    SECP256K1_GE_VERIFY(ge);
941
942
0
    (void)ge;
943
    /* The real secp256k1 group has cofactor 1, so the subgroup is the entire curve. */
944
0
    return 1;
945
0
#endif
946
0
}
947
948
0
static int secp256k1_ge_x_on_curve_var(const secp256k1_fe *x) {
949
0
    secp256k1_fe c;
950
0
    secp256k1_fe_sqr(&c, x);
951
0
    secp256k1_fe_mul(&c, &c, x);
952
0
    secp256k1_fe_add_int(&c, SECP256K1_B);
953
0
    return secp256k1_fe_is_square_var(&c);
954
0
}
955
956
0
static int secp256k1_ge_x_frac_on_curve_var(const secp256k1_fe *xn, const secp256k1_fe *xd) {
957
    /* We want to determine whether (xn/xd) is on the curve.
958
     *
959
     * (xn/xd)^3 + 7 is square <=> xd*xn^3 + 7*xd^4 is square (multiplying by xd^4, a square).
960
     */
961
0
     secp256k1_fe r, t;
962
0
     VERIFY_CHECK(!secp256k1_fe_normalizes_to_zero_var(xd));
963
964
0
     secp256k1_fe_mul(&r, xd, xn); /* r = xd*xn */
965
0
     secp256k1_fe_sqr(&t, xn); /* t = xn^2 */
966
0
     secp256k1_fe_mul(&r, &r, &t); /* r = xd*xn^3 */
967
0
     secp256k1_fe_sqr(&t, xd); /* t = xd^2 */
968
0
     secp256k1_fe_sqr(&t, &t); /* t = xd^4 */
969
0
     VERIFY_CHECK(SECP256K1_B <= 31);
970
0
     secp256k1_fe_mul_int(&t, SECP256K1_B); /* t = 7*xd^4 */
971
0
     secp256k1_fe_add(&r, &t); /* r = xd*xn^3 + 7*xd^4 */
972
0
     return secp256k1_fe_is_square_var(&r);
973
0
}
974
975
0
static void secp256k1_ge_to_bytes(unsigned char *buf, const secp256k1_ge *a) {
976
0
    secp256k1_ge_storage s;
977
978
    /* We require that the secp256k1_ge_storage type is exactly 64 bytes.
979
     * This is formally not guaranteed by the C standard, but should hold on any
980
     * sane compiler in the real world. */
981
0
    STATIC_ASSERT(sizeof(secp256k1_ge_storage) == 64);
982
0
    VERIFY_CHECK(!secp256k1_ge_is_infinity(a));
983
0
    secp256k1_ge_to_storage(&s, a);
984
0
    memcpy(buf, &s, 64);
985
0
}
986
987
0
static void secp256k1_ge_from_bytes(secp256k1_ge *r, const unsigned char *buf) {
988
0
    secp256k1_ge_storage s;
989
990
0
    STATIC_ASSERT(sizeof(secp256k1_ge_storage) == 64);
991
0
    memcpy(&s, buf, 64);
992
0
    secp256k1_ge_from_storage(r, &s);
993
0
}
994
995
0
static void secp256k1_ge_to_bytes_ext(unsigned char *data, const secp256k1_ge *ge) {
996
0
    if (secp256k1_ge_is_infinity(ge)) {
997
0
        memset(data, 0, 64);
998
0
    } else {
999
0
        secp256k1_ge_to_bytes(data, ge);
1000
0
    }
1001
0
}
1002
1003
0
static void secp256k1_ge_from_bytes_ext(secp256k1_ge *ge, const unsigned char *data) {
1004
0
    static const unsigned char zeros[64] = { 0 };
1005
0
    if (secp256k1_memcmp_var(data, zeros, sizeof(zeros)) == 0) {
1006
0
        secp256k1_ge_set_infinity(ge);
1007
0
    } else {
1008
0
        secp256k1_ge_from_bytes(ge, data);
1009
0
    }
1010
0
}
1011
1012
#endif /* SECP256K1_GROUP_IMPL_H */