Skip to content

Commit 9f443be

Browse files
committed
Move pubkey recovery code to separate module
1 parent d49abbd commit 9f443be

File tree

11 files changed

+559
-484
lines changed

11 files changed

+559
-484
lines changed

.travis.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,20 @@ compiler:
88
- gcc
99
env:
1010
global:
11-
- FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no STATICPRECOMPUTATION=yes ASM=no BUILD=check EXTRAFLAGS= HOST= ECDH=no schnorr=NO
11+
- FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no STATICPRECOMPUTATION=yes ASM=no BUILD=check EXTRAFLAGS= HOST= ECDH=no schnorr=NO RECOVERY=NO
1212
matrix:
13-
- SCALAR=32bit
13+
- SCALAR=32bit RECOVERY=yes
1414
- SCALAR=32bit FIELD=32bit ECDH=yes
1515
- SCALAR=64bit
16-
- FIELD=64bit
16+
- FIELD=64bit RECOVERY=yes
1717
- FIELD=64bit ENDOMORPHISM=yes
1818
- FIELD=64bit ENDOMORPHISM=yes ECDH=yes
1919
- FIELD=64bit ASM=x86_64
2020
- FIELD=64bit ENDOMORPHISM=yes ASM=x86_64
2121
- FIELD=32bit SCHNORR=yes
2222
- FIELD=32bit ENDOMORPHISM=yes
2323
- BIGNUM=no
24-
- BIGNUM=no ENDOMORPHISM=yes SCHNORR=yes
24+
- BIGNUM=no ENDOMORPHISM=yes SCHNORR=yes RECOVERY=yes
2525
- BIGNUM=no STATICPRECOMPUTATION=no
2626
- BUILD=distcheck
2727
- EXTRAFLAGS=CFLAGS=-DDETERMINISTIC

Makefile.am

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,10 @@ libsecp256k1_la_LIBADD = $(SECP_LIBS)
5151

5252
noinst_PROGRAMS =
5353
if USE_BENCHMARK
54-
noinst_PROGRAMS += bench_verify bench_recover bench_sign bench_internal
54+
noinst_PROGRAMS += bench_verify bench_sign bench_internal
5555
bench_verify_SOURCES = src/bench_verify.c
5656
bench_verify_LDADD = libsecp256k1.la $(SECP_LIBS)
5757
bench_verify_LDFLAGS = -static
58-
bench_recover_SOURCES = src/bench_recover.c
59-
bench_recover_LDADD = libsecp256k1.la $(SECP_LIBS)
60-
bench_recover_LDFLAGS = -static
6158
bench_sign_SOURCES = src/bench_sign.c
6259
bench_sign_LDADD = libsecp256k1.la $(SECP_LIBS)
6360
bench_sign_LDFLAGS = -static
@@ -106,3 +103,7 @@ endif
106103
if ENABLE_MODULE_SCHNORR
107104
include src/modules/schnorr/Makefile.am.include
108105
endif
106+
107+
if ENABLE_MODULE_RECOVERY
108+
include src/modules/recovery/Makefile.am.include
109+
endif

configure.ac

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ AC_ARG_ENABLE(module_schnorr,
114114
[enable_module_schnorr=$enableval],
115115
[enable_module_schnorr=no])
116116

117+
AC_ARG_ENABLE(module_recovery,
118+
AS_HELP_STRING([--enable-module-recovery],[enable ECDSA pubkey recovery module (default is no)]),
119+
[enable_module_recovery=$enableval],
120+
[enable_module_recovery=no])
121+
117122
AC_ARG_WITH([field], [AS_HELP_STRING([--with-field=64bit|32bit|auto],
118123
[Specify Field Implementation. Default is auto])],[req_field=$withval], [req_field=auto])
119124

@@ -335,6 +340,10 @@ if test x"$enable_module_schnorr" = x"yes"; then
335340
AC_DEFINE(ENABLE_MODULE_SCHNORR, 1, [Define this symbol to enable the Schnorr signature module])
336341
fi
337342

343+
if test x"$enable_module_recovery" = x"yes"; then
344+
AC_DEFINE(ENABLE_MODULE_RECOVERY, 1, [Define this symbol to enable the ECDSA pubkey recovery module])
345+
fi
346+
338347
AC_C_BIGENDIAN()
339348

340349
AC_MSG_NOTICE([Using assembly optimizations: $set_asm])
@@ -345,6 +354,7 @@ AC_MSG_NOTICE([Using endomorphism optimizations: $use_endomorphism])
345354
AC_MSG_NOTICE([Building ECDH module: $enable_module_ecdh])
346355

347356
AC_MSG_NOTICE([Building Schnorr signatures module: $enable_module_schnorr])
357+
AC_MSG_NOTICE([Building ECDSA pubkey recovery module: $enable_module_recovery])
348358

349359
AC_CONFIG_HEADERS([src/libsecp256k1-config.h])
350360
AC_CONFIG_FILES([Makefile libsecp256k1.pc])
@@ -357,6 +367,7 @@ AM_CONDITIONAL([USE_BENCHMARK], [test x"$use_benchmark" = x"yes"])
357367
AM_CONDITIONAL([USE_ECMULT_STATIC_PRECOMPUTATION], [test x"$use_ecmult_static_precomputation" = x"yes"])
358368
AM_CONDITIONAL([ENABLE_MODULE_ECDH], [test x"$enable_module_ecdh" = x"yes"])
359369
AM_CONDITIONAL([ENABLE_MODULE_SCHNORR], [test x"$enable_module_schnorr" = x"yes"])
370+
AM_CONDITIONAL([ENABLE_MODULE_RECOVERY], [test x"$enable_module_recovery" = x"yes"])
360371

361372
dnl make sure nothing new is exported so that we don't break the cache
362373
PKGCONFIG_PATH_TEMP="$PKG_CONFIG_PATH"

include/secp256k1.h

Lines changed: 0 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -56,24 +56,6 @@ typedef struct {
5656
unsigned char data[64];
5757
} secp256k1_ecdsa_signature_t;
5858

59-
/** Opaque data structured that holds a parsed ECDSA signature,
60-
* supporting pubkey recovery.
61-
*
62-
* The exact representation of data inside is implementation defined and not
63-
* guaranteed to be portable between different platforms or versions. It is
64-
* however guaranteed to be 65 bytes in size, and can be safely copied/moved.
65-
* If you need to convert to a format suitable for storage or transmission, use
66-
* the secp256k1_ecdsa_signature_serialize_* and
67-
* secp256k1_ecdsa_signature_serialize_* functions.
68-
*
69-
* Furthermore, it is guaranteed to identical signatures (including their
70-
* recoverability) will have identical representation, so they can be
71-
* memcmp'ed.
72-
*/
73-
typedef struct {
74-
unsigned char data[65];
75-
} secp256k1_ecdsa_recoverable_signature_t;
76-
7759
/** A pointer to a function to deterministically generate a nonce.
7860
*
7961
* Returns: 1 if a nonce was successfully generated. 0 will cause signing to fail.
@@ -270,33 +252,6 @@ int secp256k1_ecdsa_signature_parse_der(
270252
int inputlen
271253
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
272254

273-
/** Parse a compact ECDSA signature (64 bytes + recovery id).
274-
*
275-
* Returns: 1 when the signature could be parsed, 0 otherwise
276-
* In: ctx: a secp256k1 context object
277-
* input64: a pointer to a 64-byte compact signature
278-
* recid: the recovery id (0, 1, 2 or 3)
279-
* Out: sig: a pointer to a signature object
280-
*/
281-
int secp256k1_ecdsa_recoverable_signature_parse_compact(
282-
const secp256k1_context_t* ctx,
283-
secp256k1_ecdsa_recoverable_signature_t* sig,
284-
const unsigned char *input64,
285-
int recid
286-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
287-
288-
/** Convert a recoverable signature into a normal signature.
289-
*
290-
* Returns: 1
291-
* In: sigin: a pointer to a recoverable signature (cannot be NULL).
292-
* Out: sig: a pointer to a normal signature (cannot be NULL).
293-
*/
294-
int secp256k1_ecdsa_recoverable_signature_convert(
295-
const secp256k1_context_t* ctx,
296-
secp256k1_ecdsa_signature_t* sig,
297-
const secp256k1_ecdsa_recoverable_signature_t* sigin
298-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
299-
300255
/** Serialize an ECDSA signature in DER format.
301256
*
302257
* Returns: 1 if enough space was available to serialize, 0 otherwise
@@ -315,21 +270,6 @@ int secp256k1_ecdsa_signature_serialize_der(
315270
const secp256k1_ecdsa_signature_t* sig
316271
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
317272

318-
/** Serialize an ECDSA signature in compact format (64 bytes + recovery id).
319-
*
320-
* Returns: 1
321-
* In: ctx: a secp256k1 context object
322-
* sig: a pointer to an initialized signature object (cannot be NULL)
323-
* Out: output64: a pointer to a 64-byte array of the compact signature (cannot be NULL)
324-
* recid: a pointer to an integer to hold the recovery id (can be NULL).
325-
*/
326-
int secp256k1_ecdsa_recoverable_signature_serialize_compact(
327-
const secp256k1_context_t* ctx,
328-
unsigned char *output64,
329-
int *recid,
330-
const secp256k1_ecdsa_recoverable_signature_t* sig
331-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4);
332-
333273
/** Verify an ECDSA signature.
334274
*
335275
* Returns: 1: correct signature
@@ -366,8 +306,6 @@ extern const secp256k1_nonce_function_t secp256k1_nonce_function_default;
366306
* ndata: pointer to arbitrary data used by the nonce generation function (can be NULL)
367307
* Out: sig: pointer to an array where the signature will be placed (cannot be NULL)
368308
*
369-
* The resulting signature will support pubkey recovery.
370-
*
371309
* The sig always has an s value in the lower half of the range (From 0x1
372310
* to 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0,
373311
* inclusive), unlike many other implementations.
@@ -404,42 +342,6 @@ int secp256k1_ecdsa_sign(
404342
const void *ndata
405343
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
406344

407-
/** Create a recoverable ECDSA signature.
408-
*
409-
* Returns: 1: signature created
410-
* 0: the nonce generation function failed, or the private key was invalid.
411-
* In: ctx: pointer to a context object, initialized for signing (cannot be NULL)
412-
* msg32: the 32-byte message hash being signed (cannot be NULL)
413-
* seckey: pointer to a 32-byte secret key (cannot be NULL)
414-
* noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used
415-
* ndata: pointer to arbitrary data used by the nonce generation function (can be NULL)
416-
* Out: sig: pointer to an array where the signature will be placed (cannot be NULL)
417-
*/
418-
int secp256k1_ecdsa_sign_recoverable(
419-
const secp256k1_context_t* ctx,
420-
const unsigned char *msg32,
421-
secp256k1_ecdsa_recoverable_signature_t *sig,
422-
const unsigned char *seckey,
423-
secp256k1_nonce_function_t noncefp,
424-
const void *ndata
425-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
426-
427-
/** Recover an ECDSA public key from a signature.
428-
*
429-
* Returns: 1: public key successfully recovered (which guarantees a correct signature).
430-
* 0: otherwise.
431-
* In: ctx: pointer to a context object, initialized for verification (cannot be NULL)
432-
* msg32: the 32-byte message hash assumed to be signed (cannot be NULL)
433-
* sig: pointer to initialized signature that supports pubkey recovery (cannot be NULL)
434-
* Out: pubkey: pointer to the recoved public key (cannot be NULL)
435-
*/
436-
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover(
437-
const secp256k1_context_t* ctx,
438-
const unsigned char *msg32,
439-
const secp256k1_ecdsa_recoverable_signature_t *sig,
440-
secp256k1_pubkey_t *pubkey
441-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
442-
443345
/** Verify an ECDSA secret key.
444346
*
445347
* Returns: 1: secret key is valid

include/secp256k1_recovery.h

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
#ifndef _SECP256K1_RECOVERY_
2+
# define _SECP256K1_RECOVERY_
3+
4+
# include "secp256k1.h"
5+
6+
# ifdef __cplusplus
7+
extern "C" {
8+
# endif
9+
10+
/** Opaque data structured that holds a parsed ECDSA signature,
11+
* supporting pubkey recovery.
12+
*
13+
* The exact representation of data inside is implementation defined and not
14+
* guaranteed to be portable between different platforms or versions. It is
15+
* however guaranteed to be 65 bytes in size, and can be safely copied/moved.
16+
* If you need to convert to a format suitable for storage or transmission, use
17+
* the secp256k1_ecdsa_signature_serialize_* and
18+
* secp256k1_ecdsa_signature_serialize_* functions.
19+
*
20+
* Furthermore, it is guaranteed to identical signatures (including their
21+
* recoverability) will have identical representation, so they can be
22+
* memcmp'ed.
23+
*/
24+
typedef struct {
25+
unsigned char data[65];
26+
} secp256k1_ecdsa_recoverable_signature_t;
27+
28+
/** Parse a compact ECDSA signature (64 bytes + recovery id).
29+
*
30+
* Returns: 1 when the signature could be parsed, 0 otherwise
31+
* In: ctx: a secp256k1 context object
32+
* input64: a pointer to a 64-byte compact signature
33+
* recid: the recovery id (0, 1, 2 or 3)
34+
* Out: sig: a pointer to a signature object
35+
*/
36+
int secp256k1_ecdsa_recoverable_signature_parse_compact(
37+
const secp256k1_context_t* ctx,
38+
secp256k1_ecdsa_recoverable_signature_t* sig,
39+
const unsigned char *input64,
40+
int recid
41+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
42+
43+
/** Convert a recoverable signature into a normal signature.
44+
*
45+
* Returns: 1
46+
* In: sigin: a pointer to a recoverable signature (cannot be NULL).
47+
* Out: sig: a pointer to a normal signature (cannot be NULL).
48+
*/
49+
int secp256k1_ecdsa_recoverable_signature_convert(
50+
const secp256k1_context_t* ctx,
51+
secp256k1_ecdsa_signature_t* sig,
52+
const secp256k1_ecdsa_recoverable_signature_t* sigin
53+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
54+
55+
/** Serialize an ECDSA signature in compact format (64 bytes + recovery id).
56+
*
57+
* Returns: 1
58+
* In: ctx: a secp256k1 context object
59+
* sig: a pointer to an initialized signature object (cannot be NULL)
60+
* Out: output64: a pointer to a 64-byte array of the compact signature (cannot be NULL)
61+
* recid: a pointer to an integer to hold the recovery id (can be NULL).
62+
*/
63+
int secp256k1_ecdsa_recoverable_signature_serialize_compact(
64+
const secp256k1_context_t* ctx,
65+
unsigned char *output64,
66+
int *recid,
67+
const secp256k1_ecdsa_recoverable_signature_t* sig
68+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4);
69+
70+
/** Create a recoverable ECDSA signature.
71+
*
72+
* Returns: 1: signature created
73+
* 0: the nonce generation function failed, or the private key was invalid.
74+
* In: ctx: pointer to a context object, initialized for signing (cannot be NULL)
75+
* msg32: the 32-byte message hash being signed (cannot be NULL)
76+
* seckey: pointer to a 32-byte secret key (cannot be NULL)
77+
* noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used
78+
* ndata: pointer to arbitrary data used by the nonce generation function (can be NULL)
79+
* Out: sig: pointer to an array where the signature will be placed (cannot be NULL)
80+
*/
81+
int secp256k1_ecdsa_sign_recoverable(
82+
const secp256k1_context_t* ctx,
83+
const unsigned char *msg32,
84+
secp256k1_ecdsa_recoverable_signature_t *sig,
85+
const unsigned char *seckey,
86+
secp256k1_nonce_function_t noncefp,
87+
const void *ndata
88+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
89+
90+
/** Recover an ECDSA public key from a signature.
91+
*
92+
* Returns: 1: public key successfully recovered (which guarantees a correct signature).
93+
* 0: otherwise.
94+
* In: ctx: pointer to a context object, initialized for verification (cannot be NULL)
95+
* msg32: the 32-byte message hash assumed to be signed (cannot be NULL)
96+
* sig: pointer to initialized signature that supports pubkey recovery (cannot be NULL)
97+
* Out: pubkey: pointer to the recoved public key (cannot be NULL)
98+
*/
99+
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover(
100+
const secp256k1_context_t* ctx,
101+
const unsigned char *msg32,
102+
const secp256k1_ecdsa_recoverable_signature_t *sig,
103+
secp256k1_pubkey_t *pubkey
104+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
105+
106+
# ifdef __cplusplus
107+
}
108+
# endif
109+
110+
#endif

src/bench_recover.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
/**********************************************************************
2-
* Copyright (c) 2014 Pieter Wuille *
2+
* Copyright (c) 2014-2015 Pieter Wuille *
33
* Distributed under the MIT software license, see the accompanying *
44
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
55
**********************************************************************/
66

77
#include "include/secp256k1.h"
8+
#include "include/secp256k1_recovery.h"
89
#include "util.h"
910
#include "bench.h"
1011

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
include_HEADERS += include/secp256k1_recovery.h
2+
noinst_HEADERS += src/modules/recovery/main_impl.h
3+
noinst_HEADERS += src/modules/recovery/tests_impl.h
4+
if USE_BENCHMARK
5+
noinst_PROGRAMS += bench_recover
6+
bench_recover_SOURCES = src/bench_recover.c
7+
bench_recover_LDADD = libsecp256k1.la $(SECP_LIBS)
8+
bench_recover_LDFLAGS = -static
9+
endif

0 commit comments

Comments
 (0)