Skip to content

Commit b450c34

Browse files
committed
Merge pull request bitcoin#163
bbd5ba7 Use rfc6979 as default nonce generation function (Pieter Wuille) b37fbc2 Implement SHA256 / HMAC-SHA256 / RFC6979. (Pieter Wuille) c6e7f4e [API BREAK] Use a nonce-generation function instead of a nonce (Pieter Wuille)
2 parents d57cae9 + bbd5ba7 commit b450c34

File tree

8 files changed

+566
-48
lines changed

8 files changed

+566
-48
lines changed

Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ noinst_HEADERS += src/java/org_bitcoin_NativeSecp256k1.h
3333
noinst_HEADERS += src/util.h
3434
noinst_HEADERS += src/testrand.h
3535
noinst_HEADERS += src/testrand_impl.h
36+
noinst_HEADERS += src/hash.h
37+
noinst_HEADERS += src/hash_impl.h
3638
noinst_HEADERS += src/field.h
3739
noinst_HEADERS += src/field_impl.h
3840
noinst_HEADERS += src/bench.h

include/secp256k1.h

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,42 +77,73 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify(
7777
int pubkeylen
7878
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4);
7979

80+
/** A pointer to a function to deterministically generate a nonce.
81+
* Returns: 1 if a nonce was succesfully generated. 0 will cause signing to fail.
82+
* In: msg32: the 32-byte message hash being verified (will not be NULL)
83+
* key32: pointer to a 32-byte secret key (will not be NULL)
84+
* attempt: how many iterations we have tried to find a nonce.
85+
* This will almost always be 0, but different attempt values
86+
* are required to result in a different nonce.
87+
* data: Arbitrary data pointer that is passed through.
88+
* Out: nonce32: pointer to a 32-byte array to be filled by the function.
89+
* Except for test cases, this function should compute some cryptographic hash of
90+
* the message, the key and the attempt.
91+
*/
92+
typedef int (*secp256k1_nonce_function_t)(
93+
unsigned char *nonce32,
94+
const unsigned char *msg32,
95+
const unsigned char *key32,
96+
unsigned int attempt,
97+
const void *data
98+
);
99+
100+
/** An implementation of RFC6979 (using HMAC-SHA256) as nonce generation function. */
101+
extern const secp256k1_nonce_function_t secp256k1_nonce_function_rfc6979;
102+
103+
/** A default safe nonce generation function (currently equal to secp256k1_nonce_function_rfc6979). */
104+
extern const secp256k1_nonce_function_t secp256k1_nonce_function_default;
105+
106+
80107
/** Create an ECDSA signature.
81108
* Returns: 1: signature created
82-
* 0: nonce invalid, try another one
109+
* 0: the nonce generation function failed
83110
* In: msg32: the 32-byte message hash being signed (cannot be NULL)
84111
* seckey: pointer to a 32-byte secret key (cannot be NULL, assumed to be valid)
85-
* nonce: pointer to a 32-byte nonce (cannot be NULL, generated with a cryptographic PRNG)
112+
* noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used
113+
* ndata: pointer to arbitrary data used by the nonce generation function (can be NULL)
86114
* Out: sig: pointer to an array where the signature will be placed (cannot be NULL)
87115
* In/Out: siglen: pointer to an int with the length of sig, which will be updated
88116
* to contain the actual signature length (<=72).
89117
* Requires starting using SECP256K1_START_SIGN.
90118
*/
91-
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_sign(
119+
int secp256k1_ecdsa_sign(
92120
const unsigned char *msg32,
93121
unsigned char *sig,
94122
int *siglen,
95123
const unsigned char *seckey,
96-
const unsigned char *nonce
97-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
124+
secp256k1_nonce_function_t noncefp,
125+
const void *ndata
126+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
98127

99128
/** Create a compact ECDSA signature (64 byte + recovery id).
100129
* Returns: 1: signature created
101-
* 0: nonce invalid, try another one
130+
* 0: the nonce generation function failed
102131
* In: msg32: the 32-byte message hash being signed (cannot be NULL)
103132
* seckey: pointer to a 32-byte secret key (cannot be NULL, assumed to be valid)
104-
* nonce: pointer to a 32-byte nonce (cannot be NULL, generated with a cryptographic PRNG)
133+
* noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used
134+
* ndata: pointer to arbitrary data used by the nonce generation function (can be NULL)
105135
* Out: sig: pointer to a 64-byte array where the signature will be placed (cannot be NULL)
106136
* recid: pointer to an int, which will be updated to contain the recovery id (can be NULL)
107137
* Requires starting using SECP256K1_START_SIGN.
108138
*/
109-
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_sign_compact(
139+
int secp256k1_ecdsa_sign_compact(
110140
const unsigned char *msg32,
111141
unsigned char *sig64,
112142
const unsigned char *seckey,
113-
const unsigned char *nonce,
143+
secp256k1_nonce_function_t noncefp,
144+
const void *ndata,
114145
int *recid
115-
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
146+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
116147

117148
/** Recover an ECDSA public key from a compact signature.
118149
* Returns: 1: public key successfully recovered (which guarantees a correct signature).

src/bench_sign.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,13 @@
1010

1111
typedef struct {
1212
unsigned char msg[32];
13-
unsigned char nonce[32];
1413
unsigned char key[32];
1514
} bench_sign_t;
1615

1716
static void bench_sign_setup(void* arg) {
1817
bench_sign_t *data = (bench_sign_t*)arg;
1918

2019
for (int i = 0; i < 32; i++) data->msg[i] = i + 1;
21-
for (int i = 0; i < 32; i++) data->nonce[i] = i + 33;
2220
for (int i = 0; i < 32; i++) data->key[i] = i + 65;
2321
}
2422

@@ -28,9 +26,8 @@ static void bench_sign(void* arg) {
2826
unsigned char sig[64];
2927
for (int i=0; i<20000; i++) {
3028
int recid = 0;
31-
CHECK(secp256k1_ecdsa_sign_compact(data->msg, sig, data->key, data->nonce, &recid));
29+
secp256k1_ecdsa_sign_compact(data->msg, sig, data->key, NULL, NULL, &recid);
3230
for (int j = 0; j < 32; j++) {
33-
data->nonce[j] = data->key[j]; /* Move former key to nonce */
3431
data->msg[j] = sig[j]; /* Move former R to message. */
3532
data->key[j] = sig[j + 32]; /* Move former S to key. */
3633
}

src/bench_verify.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
typedef struct {
1515
unsigned char msg[32];
1616
unsigned char key[32];
17-
unsigned char nonce[32];
1817
unsigned char sig[72];
1918
int siglen;
2019
unsigned char pubkey[33];
@@ -42,9 +41,8 @@ int main(void) {
4241

4342
for (int i = 0; i < 32; i++) data.msg[i] = 1 + i;
4443
for (int i = 0; i < 32; i++) data.key[i] = 33 + i;
45-
for (int i = 0; i < 32; i++) data.nonce[i] = 65 + i;
4644
data.siglen = 72;
47-
CHECK(secp256k1_ecdsa_sign(data.msg, data.sig, &data.siglen, data.key, data.nonce));
45+
secp256k1_ecdsa_sign(data.msg, data.sig, &data.siglen, data.key, NULL, NULL);
4846
data.pubkeylen = 33;
4947
CHECK(secp256k1_ec_pubkey_create(data.pubkey, &data.pubkeylen, data.key, 1));
5048

src/hash.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**********************************************************************
2+
* Copyright (c) 2014 Pieter Wuille *
3+
* Distributed under the MIT software license, see the accompanying *
4+
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
5+
**********************************************************************/
6+
7+
#ifndef _SECP256K1_HASH_
8+
#define _SECP256K1_HASH_
9+
10+
#include <stdlib.h>
11+
#include <stdint.h>
12+
13+
typedef struct {
14+
uint32_t s[32];
15+
unsigned char buf[64];
16+
size_t bytes;
17+
} secp256k1_sha256_t;
18+
19+
static void secp256k1_sha256_initialize(secp256k1_sha256_t *hash);
20+
static void secp256k1_sha256_write(secp256k1_sha256_t *hash, const unsigned char *data, size_t size);
21+
static void secp256k1_sha256_finalize(secp256k1_sha256_t *hash, unsigned char *out32);
22+
23+
typedef struct {
24+
secp256k1_sha256_t inner, outer;
25+
} secp256k1_hmac_sha256_t;
26+
27+
static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256_t *hash, const unsigned char *key, size_t size);
28+
static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256_t *hash, const unsigned char *data, size_t size);
29+
static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256_t *hash, unsigned char *out32);
30+
31+
typedef struct {
32+
unsigned char v[32];
33+
unsigned char k[32];
34+
int retry;
35+
} secp256k1_rfc6979_hmac_sha256_t;
36+
37+
static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256_t *rng, const unsigned char *key, size_t keylen, const unsigned char *msg, size_t msglen);
38+
static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256_t *rng, unsigned char *out, size_t outlen);
39+
static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256_t *rng);
40+
41+
#endif

0 commit comments

Comments
 (0)