Skip to content

Commit c41bfd1

Browse files
committed
Squashed 'src/secp256k1/' changes from 8746600ee..44c2452fd
44c2452fd Merge bitcoin-core/secp256k1#1105: Don't export symbols in static libraries 6f6cab998 abi: Don't export symbols in static Windows libraries 485f608fa Merge bitcoin-core/secp256k1#1104: Fix the false positive of `SECP_64BIT_ASM_CHECK` 8b013fce5 Merge bitcoin-core/secp256k1#1056: Save negations in var-time group addition 7efc9835a Fix the false positive of `SECP_64BIT_ASM_CHECK` 2f984ffc4 Save negations in var-time group addition git-subtree-dir: src/secp256k1 git-subtree-split: 44c2452fd387f7ca604ab42d73746e7d3a44d8a2
1 parent afb7a6f commit c41bfd1

File tree

5 files changed

+111
-83
lines changed

5 files changed

+111
-83
lines changed

build-aux/m4/bitcoin_secp.m4

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
dnl escape "$0x" below using the m4 quadrigaph @S|@, and escape it again with a \ for the shell.
22
AC_DEFUN([SECP_64BIT_ASM_CHECK],[
33
AC_MSG_CHECKING(for x86_64 assembly availability)
4-
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
4+
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
55
#include <stdint.h>]],[[
66
uint64_t a = 11, tmp;
77
__asm__ __volatile__("movq \@S|@0x100000000,%1; mulq %%rsi" : "+a"(a) : "S"(tmp) : "cc", "%rdx");

include/secp256k1.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,13 @@ typedef int (*secp256k1_nonce_function)(
141141
# define SECP256K1_NO_BUILD
142142
#endif
143143

144+
/** At secp256k1 build-time DLL_EXPORT is defined when building objects destined
145+
* for a shared library, but not for those intended for static libraries.
146+
*/
147+
144148
#ifndef SECP256K1_API
145149
# if defined(_WIN32)
146-
# ifdef SECP256K1_BUILD
150+
# if defined(SECP256K1_BUILD) && defined(DLL_EXPORT)
147151
# define SECP256K1_API __declspec(dllexport)
148152
# else
149153
# define SECP256K1_API

sage/prove_group_implementations.sage

+34-43
Original file line numberDiff line numberDiff line change
@@ -40,29 +40,26 @@ def formula_secp256k1_gej_add_var(branch, a, b):
4040
s2 = s2 * a.Z
4141
h = -u1
4242
h = h + u2
43-
i = -s1
44-
i = i + s2
43+
i = -s2
44+
i = i + s1
4545
if branch == 2:
4646
r = formula_secp256k1_gej_double_var(a)
4747
return (constraints(), constraints(zero={h : 'h=0', i : 'i=0', a.Infinity : 'a_finite', b.Infinity : 'b_finite'}), r)
4848
if branch == 3:
4949
return (constraints(), constraints(zero={h : 'h=0', a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={i : 'i!=0'}), point_at_infinity())
50-
i2 = i^2
50+
t = h * b.Z
51+
rz = a.Z * t
5152
h2 = h^2
53+
h2 = -h2
5254
h3 = h2 * h
53-
h = h * b.Z
54-
rz = a.Z * h
5555
t = u1 * h2
56-
rx = t
57-
rx = rx * 2
56+
rx = i^2
5857
rx = rx + h3
59-
rx = -rx
60-
rx = rx + i2
61-
ry = -rx
62-
ry = ry + t
63-
ry = ry * i
58+
rx = rx + t
59+
rx = rx + t
60+
t = t + rx
61+
ry = t * i
6462
h3 = h3 * s1
65-
h3 = -h3
6663
ry = ry + h3
6764
return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={h : 'h!=0'}), jacobianpoint(rx, ry, rz))
6865

@@ -80,43 +77,41 @@ def formula_secp256k1_gej_add_ge_var(branch, a, b):
8077
s2 = s2 * a.Z
8178
h = -u1
8279
h = h + u2
83-
i = -s1
84-
i = i + s2
80+
i = -s2
81+
i = i + s1
8582
if (branch == 2):
8683
r = formula_secp256k1_gej_double_var(a)
8784
return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0', i : 'i=0'}), r)
8885
if (branch == 3):
8986
return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0'}, nonzero={i : 'i!=0'}), point_at_infinity())
90-
i2 = i^2
91-
h2 = h^2
92-
h3 = h * h2
9387
rz = a.Z * h
88+
h2 = h^2
89+
h2 = -h2
90+
h3 = h2 * h
9491
t = u1 * h2
95-
rx = t
96-
rx = rx * 2
92+
rx = i^2
9793
rx = rx + h3
98-
rx = -rx
99-
rx = rx + i2
100-
ry = -rx
101-
ry = ry + t
102-
ry = ry * i
94+
rx = rx + t
95+
rx = rx + t
96+
t = t + rx
97+
ry = t * i
10398
h3 = h3 * s1
104-
h3 = -h3
10599
ry = ry + h3
106100
return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={h : 'h!=0'}), jacobianpoint(rx, ry, rz))
107101

108102
def formula_secp256k1_gej_add_zinv_var(branch, a, b):
109103
"""libsecp256k1's secp256k1_gej_add_zinv_var"""
110104
bzinv = b.Z^(-1)
111105
if branch == 0:
112-
return (constraints(), constraints(nonzero={b.Infinity : 'b_infinite'}), a)
113-
if branch == 1:
106+
rinf = b.Infinity
114107
bzinv2 = bzinv^2
115108
bzinv3 = bzinv2 * bzinv
116109
rx = b.X * bzinv2
117110
ry = b.Y * bzinv3
118111
rz = 1
119-
return (constraints(), constraints(zero={b.Infinity : 'b_finite'}, nonzero={a.Infinity : 'a_infinite'}), jacobianpoint(rx, ry, rz))
112+
return (constraints(), constraints(nonzero={a.Infinity : 'a_infinite'}), jacobianpoint(rx, ry, rz, rinf))
113+
if branch == 1:
114+
return (constraints(), constraints(zero={a.Infinity : 'a_finite'}, nonzero={b.Infinity : 'b_infinite'}), a)
120115
azz = a.Z * bzinv
121116
z12 = azz^2
122117
u1 = a.X
@@ -126,29 +121,25 @@ def formula_secp256k1_gej_add_zinv_var(branch, a, b):
126121
s2 = s2 * azz
127122
h = -u1
128123
h = h + u2
129-
i = -s1
130-
i = i + s2
124+
i = -s2
125+
i = i + s1
131126
if branch == 2:
132127
r = formula_secp256k1_gej_double_var(a)
133128
return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0', i : 'i=0'}), r)
134129
if branch == 3:
135130
return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0'}, nonzero={i : 'i!=0'}), point_at_infinity())
136-
i2 = i^2
131+
rz = a.Z * h
137132
h2 = h^2
138-
h3 = h * h2
139-
rz = a.Z
140-
rz = rz * h
133+
h2 = -h2
134+
h3 = h2 * h
141135
t = u1 * h2
142-
rx = t
143-
rx = rx * 2
136+
rx = i^2
144137
rx = rx + h3
145-
rx = -rx
146-
rx = rx + i2
147-
ry = -rx
148-
ry = ry + t
149-
ry = ry * i
138+
rx = rx + t
139+
rx = rx + t
140+
t = t + rx
141+
ry = t * i
150142
h3 = h3 * s1
151-
h3 = -h3
152143
ry = ry + h3
153144
return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={h : 'h!=0'}), jacobianpoint(rx, ry, rz))
154145

src/bench_internal.c

+10
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,15 @@ void bench_group_add_affine_var(void* arg, int iters) {
254254
}
255255
}
256256

257+
void bench_group_add_zinv_var(void* arg, int iters) {
258+
int i;
259+
bench_inv *data = (bench_inv*)arg;
260+
261+
for (i = 0; i < iters; i++) {
262+
secp256k1_gej_add_zinv_var(&data->gej[0], &data->gej[0], &data->ge[1], &data->gej[0].y);
263+
}
264+
}
265+
257266
void bench_group_to_affine_var(void* arg, int iters) {
258267
int i;
259268
bench_inv *data = (bench_inv*)arg;
@@ -376,6 +385,7 @@ int main(int argc, char **argv) {
376385
if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_var", bench_group_add_var, bench_setup, NULL, &data, 10, iters*10);
377386
if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine", bench_group_add_affine, bench_setup, NULL, &data, 10, iters*10);
378387
if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine_var", bench_group_add_affine_var, bench_setup, NULL, &data, 10, iters*10);
388+
if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_zinv_var", bench_group_add_zinv_var, bench_setup, NULL, &data, 10, iters*10);
379389
if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "to_affine")) run_benchmark("group_to_affine_var", bench_group_to_affine_var, bench_setup, NULL, &data, 10, iters);
380390

381391
if (d || have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("wnaf_const", bench_wnaf_const, bench_setup, NULL, &data, 10, iters);

src/group_impl.h

+61-38
Original file line numberDiff line numberDiff line change
@@ -330,15 +330,14 @@ static void secp256k1_gej_double_var(secp256k1_gej *r, const secp256k1_gej *a, s
330330
}
331331

332332
static void secp256k1_gej_add_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_gej *b, secp256k1_fe *rzr) {
333-
/* Operations: 12 mul, 4 sqr, 2 normalize, 12 mul_int/add/negate */
334-
secp256k1_fe z22, z12, u1, u2, s1, s2, h, i, i2, h2, h3, t;
333+
/* 12 mul, 4 sqr, 11 add/negate/normalizes_to_zero (ignoring special cases) */
334+
secp256k1_fe z22, z12, u1, u2, s1, s2, h, i, h2, h3, t;
335335

336336
if (a->infinity) {
337337
VERIFY_CHECK(rzr == NULL);
338338
*r = *b;
339339
return;
340340
}
341-
342341
if (b->infinity) {
343342
if (rzr != NULL) {
344343
secp256k1_fe_set_int(rzr, 1);
@@ -347,15 +346,14 @@ static void secp256k1_gej_add_var(secp256k1_gej *r, const secp256k1_gej *a, cons
347346
return;
348347
}
349348

350-
r->infinity = 0;
351349
secp256k1_fe_sqr(&z22, &b->z);
352350
secp256k1_fe_sqr(&z12, &a->z);
353351
secp256k1_fe_mul(&u1, &a->x, &z22);
354352
secp256k1_fe_mul(&u2, &b->x, &z12);
355353
secp256k1_fe_mul(&s1, &a->y, &z22); secp256k1_fe_mul(&s1, &s1, &b->z);
356354
secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z);
357355
secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2);
358-
secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2);
356+
secp256k1_fe_negate(&i, &s2, 1); secp256k1_fe_add(&i, &s1);
359357
if (secp256k1_fe_normalizes_to_zero_var(&h)) {
360358
if (secp256k1_fe_normalizes_to_zero_var(&i)) {
361359
secp256k1_gej_double_var(r, a, rzr);
@@ -367,24 +365,33 @@ static void secp256k1_gej_add_var(secp256k1_gej *r, const secp256k1_gej *a, cons
367365
}
368366
return;
369367
}
370-
secp256k1_fe_sqr(&i2, &i);
371-
secp256k1_fe_sqr(&h2, &h);
372-
secp256k1_fe_mul(&h3, &h, &h2);
373-
secp256k1_fe_mul(&h, &h, &b->z);
368+
369+
r->infinity = 0;
370+
secp256k1_fe_mul(&t, &h, &b->z);
374371
if (rzr != NULL) {
375-
*rzr = h;
372+
*rzr = t;
376373
}
377-
secp256k1_fe_mul(&r->z, &a->z, &h);
374+
secp256k1_fe_mul(&r->z, &a->z, &t);
375+
376+
secp256k1_fe_sqr(&h2, &h);
377+
secp256k1_fe_negate(&h2, &h2, 1);
378+
secp256k1_fe_mul(&h3, &h2, &h);
378379
secp256k1_fe_mul(&t, &u1, &h2);
379-
r->x = t; secp256k1_fe_mul_int(&r->x, 2); secp256k1_fe_add(&r->x, &h3); secp256k1_fe_negate(&r->x, &r->x, 3); secp256k1_fe_add(&r->x, &i2);
380-
secp256k1_fe_negate(&r->y, &r->x, 5); secp256k1_fe_add(&r->y, &t); secp256k1_fe_mul(&r->y, &r->y, &i);
381-
secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_negate(&h3, &h3, 1);
380+
381+
secp256k1_fe_sqr(&r->x, &i);
382+
secp256k1_fe_add(&r->x, &h3);
383+
secp256k1_fe_add(&r->x, &t);
384+
secp256k1_fe_add(&r->x, &t);
385+
386+
secp256k1_fe_add(&t, &r->x);
387+
secp256k1_fe_mul(&r->y, &t, &i);
388+
secp256k1_fe_mul(&h3, &h3, &s1);
382389
secp256k1_fe_add(&r->y, &h3);
383390
}
384391

385392
static void secp256k1_gej_add_ge_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, secp256k1_fe *rzr) {
386-
/* 8 mul, 3 sqr, 4 normalize, 12 mul_int/add/negate */
387-
secp256k1_fe z12, u1, u2, s1, s2, h, i, i2, h2, h3, t;
393+
/* 8 mul, 3 sqr, 13 add/negate/normalize_weak/normalizes_to_zero (ignoring special cases) */
394+
secp256k1_fe z12, u1, u2, s1, s2, h, i, h2, h3, t;
388395
if (a->infinity) {
389396
VERIFY_CHECK(rzr == NULL);
390397
secp256k1_gej_set_ge(r, b);
@@ -397,15 +404,14 @@ static void secp256k1_gej_add_ge_var(secp256k1_gej *r, const secp256k1_gej *a, c
397404
*r = *a;
398405
return;
399406
}
400-
r->infinity = 0;
401407

402408
secp256k1_fe_sqr(&z12, &a->z);
403409
u1 = a->x; secp256k1_fe_normalize_weak(&u1);
404410
secp256k1_fe_mul(&u2, &b->x, &z12);
405411
s1 = a->y; secp256k1_fe_normalize_weak(&s1);
406412
secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z);
407413
secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2);
408-
secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2);
414+
secp256k1_fe_negate(&i, &s2, 1); secp256k1_fe_add(&i, &s1);
409415
if (secp256k1_fe_normalizes_to_zero_var(&h)) {
410416
if (secp256k1_fe_normalizes_to_zero_var(&i)) {
411417
secp256k1_gej_double_var(r, a, rzr);
@@ -417,28 +423,33 @@ static void secp256k1_gej_add_ge_var(secp256k1_gej *r, const secp256k1_gej *a, c
417423
}
418424
return;
419425
}
420-
secp256k1_fe_sqr(&i2, &i);
421-
secp256k1_fe_sqr(&h2, &h);
422-
secp256k1_fe_mul(&h3, &h, &h2);
426+
427+
r->infinity = 0;
423428
if (rzr != NULL) {
424429
*rzr = h;
425430
}
426431
secp256k1_fe_mul(&r->z, &a->z, &h);
432+
433+
secp256k1_fe_sqr(&h2, &h);
434+
secp256k1_fe_negate(&h2, &h2, 1);
435+
secp256k1_fe_mul(&h3, &h2, &h);
427436
secp256k1_fe_mul(&t, &u1, &h2);
428-
r->x = t; secp256k1_fe_mul_int(&r->x, 2); secp256k1_fe_add(&r->x, &h3); secp256k1_fe_negate(&r->x, &r->x, 3); secp256k1_fe_add(&r->x, &i2);
429-
secp256k1_fe_negate(&r->y, &r->x, 5); secp256k1_fe_add(&r->y, &t); secp256k1_fe_mul(&r->y, &r->y, &i);
430-
secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_negate(&h3, &h3, 1);
437+
438+
secp256k1_fe_sqr(&r->x, &i);
439+
secp256k1_fe_add(&r->x, &h3);
440+
secp256k1_fe_add(&r->x, &t);
441+
secp256k1_fe_add(&r->x, &t);
442+
443+
secp256k1_fe_add(&t, &r->x);
444+
secp256k1_fe_mul(&r->y, &t, &i);
445+
secp256k1_fe_mul(&h3, &h3, &s1);
431446
secp256k1_fe_add(&r->y, &h3);
432447
}
433448

434449
static void secp256k1_gej_add_zinv_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, const secp256k1_fe *bzinv) {
435-
/* 9 mul, 3 sqr, 4 normalize, 12 mul_int/add/negate */
436-
secp256k1_fe az, z12, u1, u2, s1, s2, h, i, i2, h2, h3, t;
450+
/* 9 mul, 3 sqr, 13 add/negate/normalize_weak/normalizes_to_zero (ignoring special cases) */
451+
secp256k1_fe az, z12, u1, u2, s1, s2, h, i, h2, h3, t;
437452

438-
if (b->infinity) {
439-
*r = *a;
440-
return;
441-
}
442453
if (a->infinity) {
443454
secp256k1_fe bzinv2, bzinv3;
444455
r->infinity = b->infinity;
@@ -449,7 +460,10 @@ static void secp256k1_gej_add_zinv_var(secp256k1_gej *r, const secp256k1_gej *a,
449460
secp256k1_fe_set_int(&r->z, 1);
450461
return;
451462
}
452-
r->infinity = 0;
463+
if (b->infinity) {
464+
*r = *a;
465+
return;
466+
}
453467

454468
/** We need to calculate (rx,ry,rz) = (ax,ay,az) + (bx,by,1/bzinv). Due to
455469
* secp256k1's isomorphism we can multiply the Z coordinates on both sides
@@ -467,7 +481,7 @@ static void secp256k1_gej_add_zinv_var(secp256k1_gej *r, const secp256k1_gej *a,
467481
s1 = a->y; secp256k1_fe_normalize_weak(&s1);
468482
secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &az);
469483
secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2);
470-
secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2);
484+
secp256k1_fe_negate(&i, &s2, 1); secp256k1_fe_add(&i, &s1);
471485
if (secp256k1_fe_normalizes_to_zero_var(&h)) {
472486
if (secp256k1_fe_normalizes_to_zero_var(&i)) {
473487
secp256k1_gej_double_var(r, a, NULL);
@@ -476,14 +490,23 @@ static void secp256k1_gej_add_zinv_var(secp256k1_gej *r, const secp256k1_gej *a,
476490
}
477491
return;
478492
}
479-
secp256k1_fe_sqr(&i2, &i);
493+
494+
r->infinity = 0;
495+
secp256k1_fe_mul(&r->z, &a->z, &h);
496+
480497
secp256k1_fe_sqr(&h2, &h);
481-
secp256k1_fe_mul(&h3, &h, &h2);
482-
r->z = a->z; secp256k1_fe_mul(&r->z, &r->z, &h);
498+
secp256k1_fe_negate(&h2, &h2, 1);
499+
secp256k1_fe_mul(&h3, &h2, &h);
483500
secp256k1_fe_mul(&t, &u1, &h2);
484-
r->x = t; secp256k1_fe_mul_int(&r->x, 2); secp256k1_fe_add(&r->x, &h3); secp256k1_fe_negate(&r->x, &r->x, 3); secp256k1_fe_add(&r->x, &i2);
485-
secp256k1_fe_negate(&r->y, &r->x, 5); secp256k1_fe_add(&r->y, &t); secp256k1_fe_mul(&r->y, &r->y, &i);
486-
secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_negate(&h3, &h3, 1);
501+
502+
secp256k1_fe_sqr(&r->x, &i);
503+
secp256k1_fe_add(&r->x, &h3);
504+
secp256k1_fe_add(&r->x, &t);
505+
secp256k1_fe_add(&r->x, &t);
506+
507+
secp256k1_fe_add(&t, &r->x);
508+
secp256k1_fe_mul(&r->y, &t, &i);
509+
secp256k1_fe_mul(&h3, &h3, &s1);
487510
secp256k1_fe_add(&r->y, &h3);
488511
}
489512

0 commit comments

Comments
 (0)