Skip to content

Commit c333074

Browse files
committed
Merge pull request bitcoin#282
18c329c Remove the internal secp256k1_ecdsa_sig_t type (Pieter Wuille) 74a2acd Add a secp256k1_ecdsa_signature_t type (Pieter Wuille) 23cfa91 Introduce secp256k1_pubkey_t type (Pieter Wuille)
2 parents 4c63780 + 18c329c commit c333074

File tree

8 files changed

+576
-520
lines changed

8 files changed

+576
-520
lines changed

include/secp256k1.h

Lines changed: 152 additions & 116 deletions
Large diffs are not rendered by default.

src/bench_recover.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,20 @@ typedef struct {
1717
void bench_recover(void* arg) {
1818
int i;
1919
bench_recover_t *data = (bench_recover_t*)arg;
20-
unsigned char pubkey[33];
20+
secp256k1_pubkey_t pubkey;
21+
unsigned char pubkeyc[33];
2122

2223
for (i = 0; i < 20000; i++) {
2324
int j;
2425
int pubkeylen = 33;
25-
CHECK(secp256k1_ecdsa_recover_compact(data->ctx, data->msg, data->sig, pubkey, &pubkeylen, 1, i % 2));
26+
secp256k1_ecdsa_signature_t sig;
27+
CHECK(secp256k1_ecdsa_signature_parse_compact(data->ctx, &sig, data->sig, i % 2));
28+
CHECK(secp256k1_ecdsa_recover(data->ctx, data->msg, &sig, &pubkey));
29+
CHECK(secp256k1_ec_pubkey_serialize(data->ctx, pubkeyc, &pubkeylen, &pubkey, 1));
2630
for (j = 0; j < 32; j++) {
2731
data->sig[j + 32] = data->msg[j]; /* Move former message to S. */
2832
data->msg[j] = data->sig[j]; /* Move former R to message. */
29-
data->sig[j] = pubkey[j + 1]; /* Move recovered pubkey X coordinate to R (which must be a valid X coordinate). */
33+
data->sig[j] = pubkeyc[j + 1]; /* Move recovered pubkey X coordinate to R (which must be a valid X coordinate). */
3034
}
3135
}
3236
}

src/bench_sign.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ static void bench_sign(void* arg) {
3030
for (i = 0; i < 20000; i++) {
3131
int j;
3232
int recid = 0;
33-
CHECK(secp256k1_ecdsa_sign_compact(data->ctx, data->msg, sig, data->key, NULL, NULL, &recid));
33+
secp256k1_ecdsa_signature_t signature;
34+
CHECK(secp256k1_ecdsa_sign(data->ctx, data->msg, &signature, data->key, NULL, NULL));
35+
CHECK(secp256k1_ecdsa_signature_serialize_compact(data->ctx, sig, &recid, &signature));
3436
for (j = 0; j < 32; j++) {
3537
data->msg[j] = sig[j]; /* Move former R to message. */
3638
data->key[j] = sig[j + 32]; /* Move former S to key. */

src/bench_verify.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,14 @@ static void benchmark_verify(void* arg) {
2626
benchmark_verify_t* data = (benchmark_verify_t*)arg;
2727

2828
for (i = 0; i < 20000; i++) {
29+
secp256k1_pubkey_t pubkey;
30+
secp256k1_ecdsa_signature_t sig;
2931
data->sig[data->siglen - 1] ^= (i & 0xFF);
3032
data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF);
3133
data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF);
32-
CHECK(secp256k1_ecdsa_verify(data->ctx, data->msg, data->sig, data->siglen, data->pubkey, data->pubkeylen) == (i == 0));
34+
CHECK(secp256k1_ec_pubkey_parse(data->ctx, &pubkey, data->pubkey, data->pubkeylen) == 1);
35+
CHECK(secp256k1_ecdsa_signature_parse_der(data->ctx, &sig, data->sig, data->siglen) == 1);
36+
CHECK(secp256k1_ecdsa_verify(data->ctx, data->msg, &sig, &pubkey) == (i == 0));
3337
data->sig[data->siglen - 1] ^= (i & 0xFF);
3438
data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF);
3539
data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF);
@@ -38,16 +42,19 @@ static void benchmark_verify(void* arg) {
3842

3943
int main(void) {
4044
int i;
45+
secp256k1_pubkey_t pubkey;
46+
secp256k1_ecdsa_signature_t sig;
4147
benchmark_verify_t data;
4248

4349
data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
4450

4551
for (i = 0; i < 32; i++) data.msg[i] = 1 + i;
4652
for (i = 0; i < 32; i++) data.key[i] = 33 + i;
4753
data.siglen = 72;
48-
secp256k1_ecdsa_sign(data.ctx, data.msg, data.sig, &data.siglen, data.key, NULL, NULL);
49-
data.pubkeylen = 33;
50-
CHECK(secp256k1_ec_pubkey_create(data.ctx, data.pubkey, &data.pubkeylen, data.key, 1));
54+
CHECK(secp256k1_ecdsa_sign(data.ctx, data.msg, &sig, data.key, NULL, NULL));
55+
CHECK(secp256k1_ecdsa_signature_serialize_der(data.ctx, data.sig, &data.siglen, &sig));
56+
CHECK(secp256k1_ec_pubkey_create(data.ctx, &pubkey, data.key));
57+
CHECK(secp256k1_ec_pubkey_serialize(data.ctx, data.pubkey, &data.pubkeylen, &pubkey, 1) == 1);
5158

5259
run_benchmark("ecdsa_verify", benchmark_verify, NULL, NULL, &data, 10, 20000);
5360

src/ecdsa.h

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,10 @@
1111
#include "group.h"
1212
#include "ecmult.h"
1313

14-
typedef struct {
15-
secp256k1_scalar_t r, s;
16-
} secp256k1_ecdsa_sig_t;
17-
18-
static int secp256k1_ecdsa_sig_parse(secp256k1_ecdsa_sig_t *r, const unsigned char *sig, int size);
19-
static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const secp256k1_ecdsa_sig_t *a);
20-
static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context_t *ctx, const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message);
21-
static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context_t *ctx, secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *seckey, const secp256k1_scalar_t *message, const secp256k1_scalar_t *nonce, int *recid);
22-
static int secp256k1_ecdsa_sig_recover(const secp256k1_ecmult_context_t *ctx, const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid);
14+
static int secp256k1_ecdsa_sig_parse(secp256k1_scalar_t *r, secp256k1_scalar_t *s, const unsigned char *sig, int size);
15+
static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const secp256k1_scalar_t *r, const secp256k1_scalar_t *s);
16+
static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context_t *ctx, const secp256k1_scalar_t* r, const secp256k1_scalar_t* s, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message);
17+
static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context_t *ctx, secp256k1_scalar_t* r, secp256k1_scalar_t* s, const secp256k1_scalar_t *seckey, const secp256k1_scalar_t *message, const secp256k1_scalar_t *nonce, int *recid);
18+
static int secp256k1_ecdsa_sig_recover(const secp256k1_ecmult_context_t *ctx, const secp256k1_scalar_t* r, const secp256k1_scalar_t* s, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid);
2319

2420
#endif

src/ecdsa_impl.h

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ static const secp256k1_fe_t secp256k1_ecdsa_const_p_minus_order = SECP256K1_FE_C
4646
0, 0, 0, 1, 0x45512319UL, 0x50B75FC4UL, 0x402DA172UL, 0x2FC9BAEEUL
4747
);
4848

49-
static int secp256k1_ecdsa_sig_parse(secp256k1_ecdsa_sig_t *r, const unsigned char *sig, int size) {
49+
static int secp256k1_ecdsa_sig_parse(secp256k1_scalar_t *rr, secp256k1_scalar_t *rs, const unsigned char *sig, int size) {
5050
unsigned char ra[32] = {0}, sa[32] = {0};
5151
const unsigned char *rp;
5252
const unsigned char *sp;
@@ -98,26 +98,27 @@ static int secp256k1_ecdsa_sig_parse(secp256k1_ecdsa_sig_t *r, const unsigned ch
9898
memcpy(ra + 32 - lenr, rp, lenr);
9999
memcpy(sa + 32 - lens, sp, lens);
100100
overflow = 0;
101-
secp256k1_scalar_set_b32(&r->r, ra, &overflow);
101+
secp256k1_scalar_set_b32(rr, ra, &overflow);
102102
if (overflow) {
103103
return 0;
104104
}
105-
secp256k1_scalar_set_b32(&r->s, sa, &overflow);
105+
secp256k1_scalar_set_b32(rs, sa, &overflow);
106106
if (overflow) {
107107
return 0;
108108
}
109109
return 1;
110110
}
111111

112-
static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const secp256k1_ecdsa_sig_t *a) {
112+
static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const secp256k1_scalar_t* ar, const secp256k1_scalar_t* as) {
113113
unsigned char r[33] = {0}, s[33] = {0};
114114
unsigned char *rp = r, *sp = s;
115115
int lenR = 33, lenS = 33;
116-
secp256k1_scalar_get_b32(&r[1], &a->r);
117-
secp256k1_scalar_get_b32(&s[1], &a->s);
116+
secp256k1_scalar_get_b32(&r[1], ar);
117+
secp256k1_scalar_get_b32(&s[1], as);
118118
while (lenR > 1 && rp[0] == 0 && rp[1] < 0x80) { lenR--; rp++; }
119119
while (lenS > 1 && sp[0] == 0 && sp[1] < 0x80) { lenS--; sp++; }
120120
if (*size < 6+lenS+lenR) {
121+
*size = 6 + lenS + lenR;
121122
return 0;
122123
}
123124
*size = 6 + lenS + lenR;
@@ -132,26 +133,26 @@ static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const se
132133
return 1;
133134
}
134135

135-
static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context_t *ctx, const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message) {
136+
static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context_t *ctx, const secp256k1_scalar_t *sigr, const secp256k1_scalar_t *sigs, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message) {
136137
unsigned char c[32];
137138
secp256k1_scalar_t sn, u1, u2;
138139
secp256k1_fe_t xr;
139140
secp256k1_gej_t pubkeyj;
140141
secp256k1_gej_t pr;
141142

142-
if (secp256k1_scalar_is_zero(&sig->r) || secp256k1_scalar_is_zero(&sig->s)) {
143+
if (secp256k1_scalar_is_zero(sigr) || secp256k1_scalar_is_zero(sigs)) {
143144
return 0;
144145
}
145146

146-
secp256k1_scalar_inverse_var(&sn, &sig->s);
147+
secp256k1_scalar_inverse_var(&sn, sigs);
147148
secp256k1_scalar_mul(&u1, &sn, message);
148-
secp256k1_scalar_mul(&u2, &sn, &sig->r);
149+
secp256k1_scalar_mul(&u2, &sn, sigr);
149150
secp256k1_gej_set_ge(&pubkeyj, pubkey);
150151
secp256k1_ecmult(ctx, &pr, &pubkeyj, &u2, &u1);
151152
if (secp256k1_gej_is_infinity(&pr)) {
152153
return 0;
153154
}
154-
secp256k1_scalar_get_b32(c, &sig->r);
155+
secp256k1_scalar_get_b32(c, sigr);
155156
secp256k1_fe_set_b32(&xr, c);
156157

157158
/** We now have the recomputed R point in pr, and its claimed x coordinate (modulo n)
@@ -186,19 +187,19 @@ static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context_t *ctx, con
186187
return 0;
187188
}
188189

189-
static int secp256k1_ecdsa_sig_recover(const secp256k1_ecmult_context_t *ctx, const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid) {
190+
static int secp256k1_ecdsa_sig_recover(const secp256k1_ecmult_context_t *ctx, const secp256k1_scalar_t *sigr, const secp256k1_scalar_t* sigs, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid) {
190191
unsigned char brx[32];
191192
secp256k1_fe_t fx;
192193
secp256k1_ge_t x;
193194
secp256k1_gej_t xj;
194195
secp256k1_scalar_t rn, u1, u2;
195196
secp256k1_gej_t qj;
196197

197-
if (secp256k1_scalar_is_zero(&sig->r) || secp256k1_scalar_is_zero(&sig->s)) {
198+
if (secp256k1_scalar_is_zero(sigr) || secp256k1_scalar_is_zero(sigs)) {
198199
return 0;
199200
}
200201

201-
secp256k1_scalar_get_b32(brx, &sig->r);
202+
secp256k1_scalar_get_b32(brx, sigr);
202203
VERIFY_CHECK(secp256k1_fe_set_b32(&fx, brx)); /* brx comes from a scalar, so is less than the order; certainly less than p */
203204
if (recid & 2) {
204205
if (secp256k1_fe_cmp_var(&fx, &secp256k1_ecdsa_const_p_minus_order) >= 0) {
@@ -210,16 +211,16 @@ static int secp256k1_ecdsa_sig_recover(const secp256k1_ecmult_context_t *ctx, co
210211
return 0;
211212
}
212213
secp256k1_gej_set_ge(&xj, &x);
213-
secp256k1_scalar_inverse_var(&rn, &sig->r);
214+
secp256k1_scalar_inverse_var(&rn, sigr);
214215
secp256k1_scalar_mul(&u1, &rn, message);
215216
secp256k1_scalar_negate(&u1, &u1);
216-
secp256k1_scalar_mul(&u2, &rn, &sig->s);
217+
secp256k1_scalar_mul(&u2, &rn, sigs);
217218
secp256k1_ecmult(ctx, &qj, &xj, &u2, &u1);
218219
secp256k1_ge_set_gej_var(pubkey, &qj);
219220
return !secp256k1_gej_is_infinity(&qj);
220221
}
221222

222-
static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context_t *ctx, secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *seckey, const secp256k1_scalar_t *message, const secp256k1_scalar_t *nonce, int *recid) {
223+
static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context_t *ctx, secp256k1_scalar_t *sigr, secp256k1_scalar_t *sigs, const secp256k1_scalar_t *seckey, const secp256k1_scalar_t *message, const secp256k1_scalar_t *nonce, int *recid) {
223224
unsigned char b[32];
224225
secp256k1_gej_t rp;
225226
secp256k1_ge_t r;
@@ -231,8 +232,8 @@ static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context_t *ctx, s
231232
secp256k1_fe_normalize(&r.x);
232233
secp256k1_fe_normalize(&r.y);
233234
secp256k1_fe_get_b32(b, &r.x);
234-
secp256k1_scalar_set_b32(&sig->r, b, &overflow);
235-
if (secp256k1_scalar_is_zero(&sig->r)) {
235+
secp256k1_scalar_set_b32(sigr, b, &overflow);
236+
if (secp256k1_scalar_is_zero(sigr)) {
236237
/* P.x = order is on the curve, so technically sig->r could end up zero, which would be an invalid signature. */
237238
secp256k1_gej_clear(&rp);
238239
secp256k1_ge_clear(&r);
@@ -241,18 +242,18 @@ static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context_t *ctx, s
241242
if (recid) {
242243
*recid = (overflow ? 2 : 0) | (secp256k1_fe_is_odd(&r.y) ? 1 : 0);
243244
}
244-
secp256k1_scalar_mul(&n, &sig->r, seckey);
245+
secp256k1_scalar_mul(&n, sigr, seckey);
245246
secp256k1_scalar_add(&n, &n, message);
246-
secp256k1_scalar_inverse(&sig->s, nonce);
247-
secp256k1_scalar_mul(&sig->s, &sig->s, &n);
247+
secp256k1_scalar_inverse(sigs, nonce);
248+
secp256k1_scalar_mul(sigs, sigs, &n);
248249
secp256k1_scalar_clear(&n);
249250
secp256k1_gej_clear(&rp);
250251
secp256k1_ge_clear(&r);
251-
if (secp256k1_scalar_is_zero(&sig->s)) {
252+
if (secp256k1_scalar_is_zero(sigs)) {
252253
return 0;
253254
}
254-
if (secp256k1_scalar_is_high(&sig->s)) {
255-
secp256k1_scalar_negate(&sig->s, &sig->s);
255+
if (secp256k1_scalar_is_high(sigs)) {
256+
secp256k1_scalar_negate(sigs, sigs);
256257
if (recid) {
257258
*recid ^= 1;
258259
}

0 commit comments

Comments
 (0)