Skip to content

Commit dbc9d46

Browse files
committed
refreshed secp256k1 C sources with PR rust-bitcoin#377 variable sized precomputed table for signing from bitcoin-core/secp256k1#337
1 parent 3768151 commit dbc9d46

File tree

7 files changed

+85
-71
lines changed

7 files changed

+85
-71
lines changed

depend/secp256k1/contrib/lax_der_parsing.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_
3232
lenbyte = input[pos++];
3333
if (lenbyte & 0x80) {
3434
lenbyte -= 0x80;
35-
if (pos + lenbyte > inputlen) {
35+
if (lenbyte > inputlen - pos) {
3636
return 0;
3737
}
3838
pos += lenbyte;
@@ -51,7 +51,7 @@ int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_
5151
lenbyte = input[pos++];
5252
if (lenbyte & 0x80) {
5353
lenbyte -= 0x80;
54-
if (pos + lenbyte > inputlen) {
54+
if (lenbyte > inputlen - pos) {
5555
return 0;
5656
}
5757
while (lenbyte > 0 && input[pos] == 0) {
@@ -89,7 +89,7 @@ int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_
8989
lenbyte = input[pos++];
9090
if (lenbyte & 0x80) {
9191
lenbyte -= 0x80;
92-
if (pos + lenbyte > inputlen) {
92+
if (lenbyte > inputlen - pos) {
9393
return 0;
9494
}
9595
while (lenbyte > 0 && input[pos] == 0) {

depend/secp256k1/src/basic-config.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
#define USE_SCALAR_INV_BUILTIN 1
3131
#define USE_FIELD_10X26 1
3232
#define USE_SCALAR_8X32 1
33-
#define ECMULT_WINDOW_SIZE 15
33+
#define ECMULT_WINDOW_SIZE 4
3434

3535
#endif /* USE_BASIC_CONFIG */
3636

depend/secp256k1/src/ecdsa_impl.h

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -46,68 +46,73 @@ static const secp256k1_fe secp256k1_ecdsa_const_p_minus_order = SECP256K1_FE_CON
4646
0, 0, 0, 1, 0x45512319UL, 0x50B75FC4UL, 0x402DA172UL, 0x2FC9BAEEUL
4747
);
4848

49-
static int secp256k1_der_read_len(const unsigned char **sigp, const unsigned char *sigend) {
50-
int lenleft, b1;
51-
size_t ret = 0;
49+
static int secp256k1_der_read_len(size_t *len, const unsigned char **sigp, const unsigned char *sigend) {
50+
size_t lenleft;
51+
unsigned char b1;
52+
VERIFY_CHECK(len != NULL);
53+
*len = 0;
5254
if (*sigp >= sigend) {
53-
return -1;
55+
return 0;
5456
}
5557
b1 = *((*sigp)++);
5658
if (b1 == 0xFF) {
5759
/* X.690-0207 8.1.3.5.c the value 0xFF shall not be used. */
58-
return -1;
60+
return 0;
5961
}
6062
if ((b1 & 0x80) == 0) {
6163
/* X.690-0207 8.1.3.4 short form length octets */
62-
return b1;
64+
*len = b1;
65+
return 1;
6366
}
6467
if (b1 == 0x80) {
6568
/* Indefinite length is not allowed in DER. */
66-
return -1;
69+
return 0;
6770
}
6871
/* X.690-207 8.1.3.5 long form length octets */
69-
lenleft = b1 & 0x7F;
70-
if (lenleft > sigend - *sigp) {
71-
return -1;
72+
lenleft = b1 & 0x7F; /* lenleft is at least 1 */
73+
if (lenleft > (size_t)(sigend - *sigp)) {
74+
return 0;
7275
}
7376
if (**sigp == 0) {
7477
/* Not the shortest possible length encoding. */
75-
return -1;
78+
return 0;
7679
}
77-
if ((size_t)lenleft > sizeof(size_t)) {
80+
if (lenleft > sizeof(size_t)) {
7881
/* The resulting length would exceed the range of a size_t, so
7982
* certainly longer than the passed array size.
8083
*/
81-
return -1;
84+
return 0;
8285
}
8386
while (lenleft > 0) {
84-
ret = (ret << 8) | **sigp;
85-
if (ret + lenleft > (size_t)(sigend - *sigp)) {
86-
/* Result exceeds the length of the passed array. */
87-
return -1;
88-
}
87+
*len = (*len << 8) | **sigp;
8988
(*sigp)++;
9089
lenleft--;
9190
}
92-
if (ret < 128) {
91+
if (*len > (size_t)(sigend - *sigp)) {
92+
/* Result exceeds the length of the passed array. */
93+
return 0;
94+
}
95+
if (*len < 128) {
9396
/* Not the shortest possible length encoding. */
94-
return -1;
97+
return 0;
9598
}
96-
return ret;
99+
return 1;
97100
}
98101

99102
static int secp256k1_der_parse_integer(secp256k1_scalar *r, const unsigned char **sig, const unsigned char *sigend) {
100103
int overflow = 0;
101104
unsigned char ra[32] = {0};
102-
int rlen;
105+
size_t rlen;
103106

104107
if (*sig == sigend || **sig != 0x02) {
105108
/* Not a primitive integer (X.690-0207 8.3.1). */
106109
return 0;
107110
}
108111
(*sig)++;
109-
rlen = secp256k1_der_read_len(sig, sigend);
110-
if (rlen <= 0 || (*sig) + rlen > sigend) {
112+
if (secp256k1_der_read_len(&rlen, sig, sigend) == 0) {
113+
return 0;
114+
}
115+
if (rlen == 0 || *sig + rlen > sigend) {
111116
/* Exceeds bounds or not at least length 1 (X.690-0207 8.3.1). */
112117
return 0;
113118
}
@@ -123,8 +128,11 @@ static int secp256k1_der_parse_integer(secp256k1_scalar *r, const unsigned char
123128
/* Negative. */
124129
overflow = 1;
125130
}
126-
while (rlen > 0 && **sig == 0) {
127-
/* Skip leading zero bytes */
131+
/* There is at most one leading zero byte:
132+
* if there were two leading zero bytes, we would have failed and returned 0
133+
* because of excessive 0x00 padding already. */
134+
if (rlen > 0 && **sig == 0) {
135+
/* Skip leading zero byte */
128136
rlen--;
129137
(*sig)++;
130138
}
@@ -144,18 +152,16 @@ static int secp256k1_der_parse_integer(secp256k1_scalar *r, const unsigned char
144152

145153
static int secp256k1_ecdsa_sig_parse(secp256k1_scalar *rr, secp256k1_scalar *rs, const unsigned char *sig, size_t size) {
146154
const unsigned char *sigend = sig + size;
147-
int rlen;
155+
size_t rlen;
148156
if (sig == sigend || *(sig++) != 0x30) {
149157
/* The encoding doesn't start with a constructed sequence (X.690-0207 8.9.1). */
150158
return 0;
151159
}
152-
rlen = secp256k1_der_read_len(&sig, sigend);
153-
if (rlen < 0 || sig + rlen > sigend) {
154-
/* Tuple exceeds bounds */
160+
if (secp256k1_der_read_len(&rlen, &sig, sigend) == 0) {
155161
return 0;
156162
}
157-
if (sig + rlen != sigend) {
158-
/* Garbage after tuple. */
163+
if (rlen != (size_t)(sigend - sig)) {
164+
/* Tuple exceeds bounds or garage after tuple. */
159165
return 0;
160166
}
161167

depend/secp256k1/src/ecmult_gen.h

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,27 @@
1010
#include "scalar.h"
1111
#include "group.h"
1212

13+
#ifndef ECMULT_GEN_PREC_BITS
14+
#define ECMULT_GEN_PREC_BITS 4/* 4 bits: 64kB table, fastest; 2 bits: 32kB table, ~75% speed */
15+
#endif
16+
#define ECMULT_GEN_PREC_B ECMULT_GEN_PREC_BITS
17+
#define ECMULT_GEN_PREC_G (1 << ECMULT_GEN_PREC_B)
18+
#define ECMULT_GEN_PREC_N (256 / ECMULT_GEN_PREC_B)
19+
1320
typedef struct {
1421
/* For accelerating the computation of a*G:
1522
* To harden against timing attacks, use the following mechanism:
16-
* * Break up the multiplicand into groups of 4 bits, called n_0, n_1, n_2, ..., n_63.
17-
* * Compute sum(n_i * 16^i * G + U_i, i=0..63), where:
18-
* * U_i = U * 2^i (for i=0..62)
19-
* * U_i = U * (1-2^63) (for i=63)
20-
* where U is a point with no known corresponding scalar. Note that sum(U_i, i=0..63) = 0.
21-
* For each i, and each of the 16 possible values of n_i, (n_i * 16^i * G + U_i) is
22-
* precomputed (call it prec(i, n_i)). The formula now becomes sum(prec(i, n_i), i=0..63).
23+
* * Break up the multiplicand into groups of PREC_B bits, called n_0, n_1, n_2, ..., n_(PREC_N-1).
24+
* * Compute sum(n_i * (PREC_G)^i * G + U_i, i=0 ... PREC_N-1), where:
25+
* * U_i = U * 2^i, for i=0 ... PREC_N-2
26+
* * U_i = U * (1-2^(PREC_N-1)), for i=PREC_N-1
27+
* where U is a point with no known corresponding scalar. Note that sum(U_i, i=0 ... PREC_N-1) = 0.
28+
* For each i, and each of the PREC_G possible values of n_i, (n_i * (PREC_G)^i * G + U_i) is
29+
* precomputed (call it prec(i, n_i)). The formula now becomes sum(prec(i, n_i), i=0 ... PREC_N-1).
2330
* None of the resulting prec group elements have a known scalar, and neither do any of
2431
* the intermediate sums while computing a*G.
2532
*/
26-
secp256k1_ge_storage (*prec)[64][16]; /* prec[j][i] = 16^j * i * G + U_i */
33+
secp256k1_ge_storage (*prec)[ECMULT_GEN_PREC_N][ECMULT_GEN_PREC_G]; /* prec[j][i] = (PREC_G)^j * i * G + U_i */
2734
secp256k1_scalar blind;
2835
secp256k1_gej initial;
2936
} secp256k1_ecmult_gen_context;

depend/secp256k1/src/ecmult_gen_impl.h

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context *ctx)
2828

2929
static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context *ctx, void **prealloc) {
3030
#ifndef USE_ECMULT_STATIC_PRECOMPUTATION
31-
secp256k1_ge prec[1024];
31+
secp256k1_ge prec[ECMULT_GEN_PREC_N * ECMULT_GEN_PREC_G];
3232
secp256k1_gej gj;
3333
secp256k1_gej nums_gej;
3434
int i, j;
@@ -40,7 +40,7 @@ static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context *ctx
4040
return;
4141
}
4242
#ifndef USE_ECMULT_STATIC_PRECOMPUTATION
43-
ctx->prec = (secp256k1_ge_storage (*)[64][16])manual_alloc(prealloc, prealloc_size, base, prealloc_size);
43+
ctx->prec = (secp256k1_ge_storage (*)[ECMULT_GEN_PREC_N][ECMULT_GEN_PREC_G])manual_alloc(prealloc, prealloc_size, base, prealloc_size);
4444

4545
/* get the generator */
4646
secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g);
@@ -64,39 +64,39 @@ static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context *ctx
6464

6565
/* compute prec. */
6666
{
67-
secp256k1_gej precj[1024]; /* Jacobian versions of prec. */
67+
secp256k1_gej precj[ECMULT_GEN_PREC_N * ECMULT_GEN_PREC_G]; /* Jacobian versions of prec. */
6868
secp256k1_gej gbase;
6969
secp256k1_gej numsbase;
70-
gbase = gj; /* 16^j * G */
70+
gbase = gj; /* PREC_G^j * G */
7171
numsbase = nums_gej; /* 2^j * nums. */
72-
for (j = 0; j < 64; j++) {
73-
/* Set precj[j*16 .. j*16+15] to (numsbase, numsbase + gbase, ..., numsbase + 15*gbase). */
74-
precj[j*16] = numsbase;
75-
for (i = 1; i < 16; i++) {
76-
secp256k1_gej_add_var(&precj[j*16 + i], &precj[j*16 + i - 1], &gbase, NULL);
72+
for (j = 0; j < ECMULT_GEN_PREC_N; j++) {
73+
/* Set precj[j*PREC_G .. j*PREC_G+(PREC_G-1)] to (numsbase, numsbase + gbase, ..., numsbase + (PREC_G-1)*gbase). */
74+
precj[j*ECMULT_GEN_PREC_G] = numsbase;
75+
for (i = 1; i < ECMULT_GEN_PREC_G; i++) {
76+
secp256k1_gej_add_var(&precj[j*ECMULT_GEN_PREC_G + i], &precj[j*ECMULT_GEN_PREC_G + i - 1], &gbase, NULL);
7777
}
78-
/* Multiply gbase by 16. */
79-
for (i = 0; i < 4; i++) {
78+
/* Multiply gbase by PREC_G. */
79+
for (i = 0; i < ECMULT_GEN_PREC_B; i++) {
8080
secp256k1_gej_double_var(&gbase, &gbase, NULL);
8181
}
8282
/* Multiply numbase by 2. */
8383
secp256k1_gej_double_var(&numsbase, &numsbase, NULL);
84-
if (j == 62) {
84+
if (j == ECMULT_GEN_PREC_N - 2) {
8585
/* In the last iteration, numsbase is (1 - 2^j) * nums instead. */
8686
secp256k1_gej_neg(&numsbase, &numsbase);
8787
secp256k1_gej_add_var(&numsbase, &numsbase, &nums_gej, NULL);
8888
}
8989
}
90-
secp256k1_ge_set_all_gej_var(prec, precj, 1024);
90+
secp256k1_ge_set_all_gej_var(prec, precj, ECMULT_GEN_PREC_N * ECMULT_GEN_PREC_G);
9191
}
92-
for (j = 0; j < 64; j++) {
93-
for (i = 0; i < 16; i++) {
94-
secp256k1_ge_to_storage(&(*ctx->prec)[j][i], &prec[j*16 + i]);
92+
for (j = 0; j < ECMULT_GEN_PREC_N; j++) {
93+
for (i = 0; i < ECMULT_GEN_PREC_G; i++) {
94+
secp256k1_ge_to_storage(&(*ctx->prec)[j][i], &prec[j*ECMULT_GEN_PREC_G + i]);
9595
}
9696
}
9797
#else
9898
(void)prealloc;
99-
ctx->prec = (secp256k1_ge_storage (*)[64][16])secp256k1_ecmult_static_context;
99+
ctx->prec = (secp256k1_ge_storage (*)[ECMULT_GEN_PREC_N][ECMULT_GEN_PREC_G])secp256k1_ecmult_static_context;
100100
#endif
101101
secp256k1_ecmult_gen_blind(ctx, NULL);
102102
}
@@ -109,7 +109,7 @@ static void secp256k1_ecmult_gen_context_finalize_memcpy(secp256k1_ecmult_gen_co
109109
#ifndef USE_ECMULT_STATIC_PRECOMPUTATION
110110
if (src->prec != NULL) {
111111
/* We cast to void* first to suppress a -Wcast-align warning. */
112-
dst->prec = (secp256k1_ge_storage (*)[64][16])(void*)((unsigned char*)dst + ((unsigned char*)src->prec - (unsigned char*)src));
112+
dst->prec = (secp256k1_ge_storage (*)[ECMULT_GEN_PREC_N][ECMULT_GEN_PREC_G])(void*)((unsigned char*)dst + ((unsigned char*)src->prec - (unsigned char*)src));
113113
}
114114
#else
115115
(void)dst, (void)src;
@@ -133,9 +133,9 @@ static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context *ctx, secp25
133133
/* Blind scalar/point multiplication by computing (n-b)G + bG instead of nG. */
134134
secp256k1_scalar_add(&gnb, gn, &ctx->blind);
135135
add.infinity = 0;
136-
for (j = 0; j < 64; j++) {
137-
bits = secp256k1_scalar_get_bits(&gnb, j * 4, 4);
138-
for (i = 0; i < 16; i++) {
136+
for (j = 0; j < ECMULT_GEN_PREC_N; j++) {
137+
bits = secp256k1_scalar_get_bits(&gnb, j * ECMULT_GEN_PREC_B, ECMULT_GEN_PREC_B);
138+
for (i = 0; i < ECMULT_GEN_PREC_G; i++) {
139139
/** This uses a conditional move to avoid any secret data in array indexes.
140140
* _Any_ use of secret indexes has been demonstrated to result in timing
141141
* sidechannels, even when the cache-line access patterns are uniform.

depend/secp256k1/src/gen_context.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,23 +45,23 @@ int main(int argc, char **argv) {
4545
fprintf(fp, "#define _SECP256K1_ECMULT_STATIC_CONTEXT_\n");
4646
fprintf(fp, "#include \"src/group.h\"\n");
4747
fprintf(fp, "#define SC SECP256K1_GE_STORAGE_CONST\n");
48-
fprintf(fp, "static const secp256k1_ge_storage secp256k1_ecmult_static_context[64][16] = {\n");
48+
fprintf(fp, "static const secp256k1_ge_storage secp256k1_ecmult_static_context[ECMULT_GEN_PREC_N][ECMULT_GEN_PREC_G] = {\n");
4949

5050
base = checked_malloc(&default_error_callback, SECP256K1_ECMULT_GEN_CONTEXT_PREALLOCATED_SIZE);
5151
prealloc = base;
5252
secp256k1_ecmult_gen_context_init(&ctx);
5353
secp256k1_ecmult_gen_context_build(&ctx, &prealloc);
54-
for(outer = 0; outer != 64; outer++) {
54+
for(outer = 0; outer != ECMULT_GEN_PREC_N; outer++) {
5555
fprintf(fp,"{\n");
56-
for(inner = 0; inner != 16; inner++) {
56+
for(inner = 0; inner != ECMULT_GEN_PREC_G; inner++) {
5757
fprintf(fp," SC(%uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu)", SECP256K1_GE_STORAGE_CONST_GET((*ctx.prec)[outer][inner]));
58-
if (inner != 15) {
58+
if (inner != ECMULT_GEN_PREC_G - 1) {
5959
fprintf(fp,",\n");
6060
} else {
6161
fprintf(fp,"\n");
6262
}
6363
}
64-
if (outer != 63) {
64+
if (outer != ECMULT_GEN_PREC_N - 1) {
6565
fprintf(fp,"},\n");
6666
} else {
6767
fprintf(fp,"}\n");

depend/secp256k1/src/hash_impl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,8 @@ static void secp256k1_sha256_transform(uint32_t* s, const uint32_t* chunk) {
131131
static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char *data, size_t len) {
132132
size_t bufsize = hash->bytes & 0x3F;
133133
hash->bytes += len;
134-
while (bufsize + len >= 64) {
134+
VERIFY_CHECK(hash->bytes >= len);
135+
while (len >= 64 - bufsize) {
135136
/* Fill the buffer, and process it. */
136137
size_t chunk_len = 64 - bufsize;
137138
memcpy(((unsigned char*)hash->buf) + bufsize, data, chunk_len);

0 commit comments

Comments
 (0)