Skip to content

Commit d253a63

Browse files
committed
Introduce secp256k1_pubkey_t type
1 parent 1b68366 commit d253a63

File tree

6 files changed

+179
-246
lines changed

6 files changed

+179
-246
lines changed

include/secp256k1.h

Lines changed: 36 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -74,25 +74,44 @@ void secp256k1_context_destroy(
7474
secp256k1_context_t* ctx
7575
) SECP256K1_ARG_NONNULL(1);
7676

77+
/** Data type to hold a parsed public key.
78+
This data type should be considered opaque to the user, and only created
79+
through API functions.
80+
*/
81+
typedef struct {
82+
unsigned char data[64];
83+
} secp256k1_pubkey_t;
84+
85+
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse(
86+
const secp256k1_context_t* ctx,
87+
secp256k1_pubkey_t* pubkey,
88+
const unsigned char *input,
89+
int inputlen
90+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
91+
92+
int secp256k1_ec_pubkey_serialize(
93+
const secp256k1_context_t* ctx,
94+
unsigned char *output,
95+
int *outputlen,
96+
const secp256k1_pubkey_t* pubkey,
97+
int compressed
98+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
99+
77100
/** Verify an ECDSA signature.
78101
* Returns: 1: correct signature
79-
* 0: incorrect signature
80-
* -1: invalid public key
81-
* -2: invalid signature
102+
* 0: incorrect or unparseable signature
82103
* In: ctx: a secp256k1 context object, initialized for verification.
83104
* msg32: the 32-byte message hash being verified (cannot be NULL)
84105
* sig: the signature being verified (cannot be NULL)
85106
* siglen: the length of the signature
86107
* pubkey: the public key to verify with (cannot be NULL)
87-
* pubkeylen: the length of pubkey
88108
*/
89109
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify(
90110
const secp256k1_context_t* ctx,
91111
const unsigned char *msg32,
92112
const unsigned char *sig,
93113
int siglen,
94-
const unsigned char *pubkey,
95-
int pubkeylen
114+
const secp256k1_pubkey_t *pubkey
96115
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5);
97116

98117
/** A pointer to a function to deterministically generate a nonce.
@@ -124,7 +143,6 @@ extern const secp256k1_nonce_function_t secp256k1_nonce_function_rfc6979;
124143
/** A default safe nonce generation function (currently equal to secp256k1_nonce_function_rfc6979). */
125144
extern const secp256k1_nonce_function_t secp256k1_nonce_function_default;
126145

127-
128146
/** Create an ECDSA signature.
129147
* Returns: 1: signature created
130148
* 0: the nonce generation function failed, the private key was invalid, or there is not
@@ -202,20 +220,16 @@ int secp256k1_ecdsa_sign_compact(
202220
* In: ctx: pointer to a context object, initialized for verification (cannot be NULL)
203221
* msg32: the 32-byte message hash assumed to be signed (cannot be NULL)
204222
* sig64: signature as 64 byte array (cannot be NULL)
205-
* compressed: whether to recover a compressed or uncompressed pubkey
206223
* recid: the recovery id (0-3, as returned by ecdsa_sign_compact)
207-
* Out: pubkey: pointer to a 33 or 65 byte array to put the pubkey (cannot be NULL)
208-
* pubkeylen: pointer to an int that will contain the pubkey length (cannot be NULL)
224+
* Out: pubkey: pointer to the recoved public key (cannot be NULL)
209225
*/
210226
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover_compact(
211227
const secp256k1_context_t* ctx,
212228
const unsigned char *msg32,
213229
const unsigned char *sig64,
214-
unsigned char *pubkey,
215-
int *pubkeylen,
216-
int compressed,
230+
secp256k1_pubkey_t *pubkey,
217231
int recid
218-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
232+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
219233

220234
/** Verify an ECDSA secret key.
221235
* Returns: 1: secret key is valid
@@ -228,24 +242,11 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify(
228242
const unsigned char *seckey
229243
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
230244

231-
/** Just validate a public key.
232-
* Returns: 1: public key is valid
233-
* 0: public key is invalid
234-
* In: ctx: pointer to a context object (cannot be NULL)
235-
* pubkey: pointer to a 33-byte or 65-byte public key (cannot be NULL).
236-
* pubkeylen: length of pubkey
237-
*/
238-
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_verify(
239-
const secp256k1_context_t* ctx,
240-
const unsigned char *pubkey,
241-
int pubkeylen
242-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
243-
244245
/** Compute the public key for a secret key.
245246
* In: ctx: pointer to a context object, initialized for signing (cannot be NULL)
246247
* compressed: whether the computed public key should be compressed
247248
* seckey: pointer to a 32-byte private key (cannot be NULL)
248-
* Out: pubkey: pointer to a 33-byte (if compressed) or 65-byte (if uncompressed)
249+
* Out: pubkey: pointer to the created public key (cannot be NULL)
249250
* area to store the public key (cannot be NULL)
250251
* pubkeylen: pointer to int that will be updated to contains the pubkey's
251252
* length (cannot be NULL)
@@ -254,45 +255,9 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_verify(
254255
*/
255256
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(
256257
const secp256k1_context_t* ctx,
257-
unsigned char *pubkey,
258-
int *pubkeylen,
259-
const unsigned char *seckey,
260-
int compressed
261-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
262-
263-
/** Compress a public key.
264-
* In: ctx: pointer to a context object (cannot be NULL)
265-
* pubkeyin: pointer to a 33-byte or 65-byte public key (cannot be NULL)
266-
* Out: pubkeyout: pointer to a 33-byte array to put the compressed public key (cannot be NULL)
267-
* May alias pubkeyin.
268-
* pubkeylen: pointer to the size of the public key pointed to by pubkeyin (cannot be NULL)
269-
* It will be updated to reflect the size of the public key in pubkeyout.
270-
* Returns: 0: pubkeyin was invalid
271-
* 1: pubkeyin was valid, and pubkeyout is its compressed version
272-
*/
273-
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_compress(
274-
const secp256k1_context_t* ctx,
275-
const unsigned char *pubkeyin,
276-
unsigned char *pubkeyout,
277-
int *pubkeylen
278-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
279-
280-
/** Decompress a public key.
281-
* In: ctx: pointer to a context object (cannot be NULL)
282-
* pubkeyin: pointer to a 33-byte or 65-byte public key (cannot be NULL)
283-
* Out: pubkeyout: pointer to a 65-byte array to put the decompressed public key (cannot be NULL)
284-
* May alias pubkeyin.
285-
* pubkeylen: pointer to the size of the public key pointed to by pubkeyin (cannot be NULL)
286-
* It will be updated to reflect the size of the public key in pubkeyout.
287-
* Returns: 0: pubkeyin was invalid
288-
* 1: pubkeyin was valid, and pubkeyout is its decompressed version
289-
*/
290-
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_decompress(
291-
const secp256k1_context_t* ctx,
292-
const unsigned char *pubkeyin,
293-
unsigned char *pubkeyout,
294-
int *pubkeylen
295-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
258+
secp256k1_pubkey_t *pubkey,
259+
const unsigned char *seckey
260+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
296261

297262
/** Export a private key in DER format.
298263
* In: ctx: pointer to a context object, initialized for signing (cannot be NULL)
@@ -325,10 +290,9 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add(
325290
*/
326291
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add(
327292
const secp256k1_context_t* ctx,
328-
unsigned char *pubkey,
329-
int pubkeylen,
293+
secp256k1_pubkey_t *pubkey,
330294
const unsigned char *tweak
331-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4);
295+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
332296

333297
/** Tweak a private key by multiplying it with tweak. */
334298
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul(
@@ -342,10 +306,9 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul(
342306
*/
343307
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul(
344308
const secp256k1_context_t* ctx,
345-
unsigned char *pubkey,
346-
int pubkeylen,
309+
secp256k1_pubkey_t *pubkey,
347310
const unsigned char *tweak
348-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4);
311+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
349312

350313
/** Updates the context randomization.
351314
* Returns: 1: randomization successfully updated

src/bench_recover.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,18 @@ 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+
CHECK(secp256k1_ecdsa_recover_compact(data->ctx, data->msg, data->sig, &pubkey, 1));
27+
CHECK(secp256k1_ec_pubkey_serialize(data->ctx, pubkeyc, &pubkeylen, &pubkey, i % 2));
2628
for (j = 0; j < 32; j++) {
2729
data->sig[j + 32] = data->msg[j]; /* Move former message to S. */
2830
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). */
31+
data->sig[j] = pubkeyc[j + 1]; /* Move recovered pubkey X coordinate to R (which must be a valid X coordinate). */
3032
}
3133
}
3234
}

src/bench_verify.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,12 @@ 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;
2930
data->sig[data->siglen - 1] ^= (i & 0xFF);
3031
data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF);
3132
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));
33+
CHECK(secp256k1_ec_pubkey_parse(data->ctx, &pubkey, data->pubkey, data->pubkeylen) == 1);
34+
CHECK(secp256k1_ecdsa_verify(data->ctx, data->msg, data->sig, data->siglen, &pubkey) == (i == 0));
3335
data->sig[data->siglen - 1] ^= (i & 0xFF);
3436
data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF);
3537
data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF);
@@ -38,6 +40,7 @@ static void benchmark_verify(void* arg) {
3840

3941
int main(void) {
4042
int i;
43+
secp256k1_pubkey_t pubkey;
4144
benchmark_verify_t data;
4245

4346
data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
@@ -46,8 +49,8 @@ int main(void) {
4649
for (i = 0; i < 32; i++) data.key[i] = 33 + i;
4750
data.siglen = 72;
4851
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));
52+
CHECK(secp256k1_ec_pubkey_create(data.ctx, &pubkey, data.key));
53+
CHECK(secp256k1_ec_pubkey_serialize(data.ctx, data.pubkey, &data.pubkeylen, &pubkey, 1) == 1);
5154

5255
run_benchmark("ecdsa_verify", benchmark_verify, NULL, NULL, &data, 10, 20000);
5356

src/eckey.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
#include "ecmult_gen.h"
1414

1515
static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned char *pub, int size);
16-
static int secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char *pub, int *size, int compressed);
1716

1817
static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned char *privkey, int privkeylen);
1918
static int secp256k1_eckey_privkey_serialize(const secp256k1_ecmult_gen_context_t *ctx, unsigned char *privkey, int *privkeylen, const secp256k1_scalar_t *key, int compressed);

0 commit comments

Comments
 (0)