mirror of
https://github.com/bitcoin/bitcoin.git
synced 2024-11-20 10:38:42 +01:00
Merge pull request #299
486b9bb
Use a flags bitfield for compressed option to secp256k1_ec_pubkey_serialize and secp256k1_ec_privkey_export (Luke Dashjr)05732c5
Callback data: Accept pointers to either const or non-const data (Luke Dashjr)1973c73
Bugfix: Reinitialise buffer lengths that have been used as outputs (Luke Dashjr)788038d
Use size_t for lengths (at least in external API) (Luke Dashjr)c9d7c2a
secp256k1_context_set_{error,illegal}_callback: Restore default handler by passing NULL as function argument (Luke Dashjr)9aac008
secp256k1_context_destroy: Allow NULL argument as a no-op (Luke Dashjr)64b730b
secp256k1_context_create: Use unsigned type for flags bitfield (Luke Dashjr)
This commit is contained in:
commit
eeab823b70
@ -5,6 +5,8 @@
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* These rules specify the order of arguments in API calls:
|
||||
*
|
||||
* 1. Context pointers go first, followed by output arguments, combined
|
||||
@ -92,7 +94,7 @@ typedef int (*secp256k1_nonce_function_t)(
|
||||
const unsigned char *msg32,
|
||||
const unsigned char *key32,
|
||||
const unsigned char *algo16,
|
||||
const void *data,
|
||||
void *data,
|
||||
unsigned int attempt
|
||||
);
|
||||
|
||||
@ -135,13 +137,16 @@ typedef int (*secp256k1_nonce_function_t)(
|
||||
# define SECP256K1_CONTEXT_VERIFY (1 << 0)
|
||||
# define SECP256K1_CONTEXT_SIGN (1 << 1)
|
||||
|
||||
/** Flag to pass to secp256k1_ec_pubkey_serialize and secp256k1_ec_privkey_export. */
|
||||
# define SECP256K1_EC_COMPRESSED (1 << 0)
|
||||
|
||||
/** Create a secp256k1 context object.
|
||||
*
|
||||
* Returns: a newly created context object.
|
||||
* In: flags: which parts of the context to initialize.
|
||||
*/
|
||||
secp256k1_context_t* secp256k1_context_create(
|
||||
int flags
|
||||
unsigned int flags
|
||||
) SECP256K1_WARN_UNUSED_RESULT;
|
||||
|
||||
/** Copies a secp256k1 context object.
|
||||
@ -160,7 +165,7 @@ secp256k1_context_t* secp256k1_context_clone(
|
||||
*/
|
||||
void secp256k1_context_destroy(
|
||||
secp256k1_context_t* ctx
|
||||
) SECP256K1_ARG_NONNULL(1);
|
||||
);
|
||||
|
||||
/** Set a callback function to be called when an illegal argument is passed to
|
||||
* an API call. It will only trigger for violations that are mentioned
|
||||
@ -179,14 +184,14 @@ void secp256k1_context_destroy(
|
||||
* Args: ctx: an existing context object (cannot be NULL)
|
||||
* In: fun: a pointer to a function to call when an illegal argument is
|
||||
* passed to the API, taking a message and an opaque pointer
|
||||
* (cannot be NULL).
|
||||
* (NULL restores a default handler that calls abort).
|
||||
* data: the opaque pointer to pass to fun above.
|
||||
*/
|
||||
void secp256k1_context_set_illegal_callback(
|
||||
secp256k1_context_t* ctx,
|
||||
void (*fun)(const char* message, void* data),
|
||||
void* data
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
|
||||
const void* data
|
||||
) SECP256K1_ARG_NONNULL(1);
|
||||
|
||||
/** Set a callback function to be called when an internal consistency check
|
||||
* fails. The default is crashing.
|
||||
@ -200,14 +205,15 @@ void secp256k1_context_set_illegal_callback(
|
||||
*
|
||||
* Args: ctx: an existing context object (cannot be NULL)
|
||||
* In: fun: a pointer to a function to call when an interal error occurs,
|
||||
* taking a message and an opaque pointer (cannot be NULL).
|
||||
* taking a message and an opaque pointer (NULL restores a default
|
||||
* handler that calls abort).
|
||||
* data: the opaque pointer to pass to fun above.
|
||||
*/
|
||||
void secp256k1_context_set_error_callback(
|
||||
secp256k1_context_t* ctx,
|
||||
void (*fun)(const char* message, void* data),
|
||||
void* data
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
|
||||
const void* data
|
||||
) SECP256K1_ARG_NONNULL(1);
|
||||
|
||||
/** Parse a variable-length public key into the pubkey object.
|
||||
*
|
||||
@ -227,7 +233,7 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse(
|
||||
const secp256k1_context_t* ctx,
|
||||
secp256k1_pubkey_t* pubkey,
|
||||
const unsigned char *input,
|
||||
int inputlen
|
||||
size_t inputlen
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Serialize a pubkey object into a serialized byte sequence.
|
||||
@ -240,14 +246,15 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse(
|
||||
* size.
|
||||
* In: pubkey: a pointer to a secp256k1_pubkey_t containing an initialized
|
||||
* public key.
|
||||
* compressed: whether to serialize in compressed format.
|
||||
* flags: SECP256K1_EC_COMPRESSED if serialization should be in
|
||||
* compressed format.
|
||||
*/
|
||||
int secp256k1_ec_pubkey_serialize(
|
||||
const secp256k1_context_t* ctx,
|
||||
unsigned char *output,
|
||||
int *outputlen,
|
||||
size_t *outputlen,
|
||||
const secp256k1_pubkey_t* pubkey,
|
||||
int compressed
|
||||
unsigned int flags
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Parse a DER ECDSA signature.
|
||||
@ -264,7 +271,7 @@ int secp256k1_ecdsa_signature_parse_der(
|
||||
const secp256k1_context_t* ctx,
|
||||
secp256k1_ecdsa_signature_t* sig,
|
||||
const unsigned char *input,
|
||||
int inputlen
|
||||
size_t inputlen
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Serialize an ECDSA signature in DER format.
|
||||
@ -281,7 +288,7 @@ int secp256k1_ecdsa_signature_parse_der(
|
||||
int secp256k1_ecdsa_signature_serialize_der(
|
||||
const secp256k1_context_t* ctx,
|
||||
unsigned char *output,
|
||||
int *outputlen,
|
||||
size_t *outputlen,
|
||||
const secp256k1_ecdsa_signature_t* sig
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
@ -393,7 +400,8 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(
|
||||
* privkeylen: Pointer to an int where the length of the private key in
|
||||
* privkey will be stored.
|
||||
* In: seckey: pointer to a 32-byte secret key to export.
|
||||
* compressed: whether the key should be exported in compressed format.
|
||||
* flags: SECP256K1_EC_COMPRESSED if the key should be exported in
|
||||
* compressed format.
|
||||
*
|
||||
* This function is purely meant for compatibility with applications that
|
||||
* require BER encoded keys. When working with secp256k1-specific code, the
|
||||
@ -405,9 +413,9 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(
|
||||
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_export(
|
||||
const secp256k1_context_t* ctx,
|
||||
unsigned char *privkey,
|
||||
int *privkeylen,
|
||||
size_t *privkeylen,
|
||||
const unsigned char *seckey,
|
||||
int compressed
|
||||
unsigned int flags
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Import a private key in DER format.
|
||||
@ -428,7 +436,7 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_import(
|
||||
const secp256k1_context_t* ctx,
|
||||
unsigned char *seckey,
|
||||
const unsigned char *privkey,
|
||||
int privkeylen
|
||||
size_t privkeylen
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Tweak a private key by adding tweak to it.
|
||||
|
@ -23,11 +23,11 @@ void bench_recover(void* arg) {
|
||||
|
||||
for (i = 0; i < 20000; i++) {
|
||||
int j;
|
||||
int pubkeylen = 33;
|
||||
size_t pubkeylen = 33;
|
||||
secp256k1_ecdsa_recoverable_signature_t sig;
|
||||
CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(data->ctx, &sig, data->sig, i % 2));
|
||||
CHECK(secp256k1_ecdsa_recover(data->ctx, &pubkey, &sig, data->msg));
|
||||
CHECK(secp256k1_ec_pubkey_serialize(data->ctx, pubkeyc, &pubkeylen, &pubkey, 1));
|
||||
CHECK(secp256k1_ec_pubkey_serialize(data->ctx, pubkeyc, &pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED));
|
||||
for (j = 0; j < 32; j++) {
|
||||
data->sig[j + 32] = data->msg[j]; /* Move former message to S. */
|
||||
data->msg[j] = data->sig[j]; /* Move former R to message. */
|
||||
|
@ -16,7 +16,7 @@ typedef struct {
|
||||
unsigned char key[32];
|
||||
unsigned char sig[64];
|
||||
unsigned char pubkey[33];
|
||||
int pubkeylen;
|
||||
size_t pubkeylen;
|
||||
} benchmark_schnorr_sig_t;
|
||||
|
||||
typedef struct {
|
||||
@ -37,7 +37,7 @@ static void benchmark_schnorr_init(void* arg) {
|
||||
secp256k1_schnorr_sign(data->ctx, data->sigs[k].sig, data->msg, data->sigs[k].key, NULL, NULL);
|
||||
data->sigs[k].pubkeylen = 33;
|
||||
CHECK(secp256k1_ec_pubkey_create(data->ctx, &pubkey, data->sigs[k].key));
|
||||
CHECK(secp256k1_ec_pubkey_serialize(data->ctx, data->sigs[k].pubkey, &data->sigs[k].pubkeylen, &pubkey, 1));
|
||||
CHECK(secp256k1_ec_pubkey_serialize(data->ctx, data->sigs[k].pubkey, &data->sigs[k].pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ static void bench_sign(void* arg) {
|
||||
|
||||
unsigned char sig[74];
|
||||
for (i = 0; i < 20000; i++) {
|
||||
int siglen = 74;
|
||||
size_t siglen = 74;
|
||||
int j;
|
||||
secp256k1_ecdsa_signature_t signature;
|
||||
CHECK(secp256k1_ecdsa_sign(data->ctx, &signature, data->msg, data->key, NULL, NULL));
|
||||
|
@ -16,9 +16,9 @@ typedef struct {
|
||||
unsigned char msg[32];
|
||||
unsigned char key[32];
|
||||
unsigned char sig[72];
|
||||
int siglen;
|
||||
size_t siglen;
|
||||
unsigned char pubkey[33];
|
||||
int pubkeylen;
|
||||
size_t pubkeylen;
|
||||
} benchmark_verify_t;
|
||||
|
||||
static void benchmark_verify(void* arg) {
|
||||
@ -54,7 +54,7 @@ int main(void) {
|
||||
CHECK(secp256k1_ecdsa_sign(data.ctx, &sig, data.msg, data.key, NULL, NULL));
|
||||
CHECK(secp256k1_ecdsa_signature_serialize_der(data.ctx, data.sig, &data.siglen, &sig));
|
||||
CHECK(secp256k1_ec_pubkey_create(data.ctx, &pubkey, data.key));
|
||||
CHECK(secp256k1_ec_pubkey_serialize(data.ctx, data.pubkey, &data.pubkeylen, &pubkey, 1) == 1);
|
||||
CHECK(secp256k1_ec_pubkey_serialize(data.ctx, data.pubkey, &data.pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED) == 1);
|
||||
|
||||
run_benchmark("ecdsa_verify", benchmark_verify, NULL, NULL, &data, 10, 20000);
|
||||
|
||||
|
@ -7,12 +7,14 @@
|
||||
#ifndef _SECP256K1_ECDSA_
|
||||
#define _SECP256K1_ECDSA_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "scalar.h"
|
||||
#include "group.h"
|
||||
#include "ecmult.h"
|
||||
|
||||
static int secp256k1_ecdsa_sig_parse(secp256k1_scalar_t *r, secp256k1_scalar_t *s, const unsigned char *sig, int size);
|
||||
static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const secp256k1_scalar_t *r, const secp256k1_scalar_t *s);
|
||||
static int secp256k1_ecdsa_sig_parse(secp256k1_scalar_t *r, secp256k1_scalar_t *s, const unsigned char *sig, size_t size);
|
||||
static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const secp256k1_scalar_t *r, const secp256k1_scalar_t *s);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
|
@ -46,12 +46,12 @@ static const secp256k1_fe_t secp256k1_ecdsa_const_p_minus_order = SECP256K1_FE_C
|
||||
0, 0, 0, 1, 0x45512319UL, 0x50B75FC4UL, 0x402DA172UL, 0x2FC9BAEEUL
|
||||
);
|
||||
|
||||
static int secp256k1_ecdsa_sig_parse(secp256k1_scalar_t *rr, secp256k1_scalar_t *rs, const unsigned char *sig, int size) {
|
||||
static int secp256k1_ecdsa_sig_parse(secp256k1_scalar_t *rr, secp256k1_scalar_t *rs, const unsigned char *sig, size_t size) {
|
||||
unsigned char ra[32] = {0}, sa[32] = {0};
|
||||
const unsigned char *rp;
|
||||
const unsigned char *sp;
|
||||
int lenr;
|
||||
int lens;
|
||||
size_t lenr;
|
||||
size_t lens;
|
||||
int overflow;
|
||||
if (sig[0] != 0x30) {
|
||||
return 0;
|
||||
@ -109,10 +109,10 @@ static int secp256k1_ecdsa_sig_parse(secp256k1_scalar_t *rr, secp256k1_scalar_t
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const secp256k1_scalar_t* ar, const secp256k1_scalar_t* as) {
|
||||
static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const secp256k1_scalar_t* ar, const secp256k1_scalar_t* as) {
|
||||
unsigned char r[33] = {0}, s[33] = {0};
|
||||
unsigned char *rp = r, *sp = s;
|
||||
int lenR = 33, lenS = 33;
|
||||
size_t lenR = 33, lenS = 33;
|
||||
secp256k1_scalar_get_b32(&r[1], ar);
|
||||
secp256k1_scalar_get_b32(&s[1], as);
|
||||
while (lenR > 1 && rp[0] == 0 && rp[1] < 0x80) { lenR--; rp++; }
|
||||
|
10
src/eckey.h
10
src/eckey.h
@ -7,16 +7,18 @@
|
||||
#ifndef _SECP256K1_ECKEY_
|
||||
#define _SECP256K1_ECKEY_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "group.h"
|
||||
#include "scalar.h"
|
||||
#include "ecmult.h"
|
||||
#include "ecmult_gen.h"
|
||||
|
||||
static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned char *pub, int size);
|
||||
static int secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char *pub, int *size, int compressed);
|
||||
static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned char *pub, size_t size);
|
||||
static int secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char *pub, size_t *size, unsigned int flags);
|
||||
|
||||
static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned char *privkey, int privkeylen);
|
||||
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);
|
||||
static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned char *privkey, size_t privkeylen);
|
||||
static int secp256k1_eckey_privkey_serialize(const secp256k1_ecmult_gen_context_t *ctx, unsigned char *privkey, size_t *privkeylen, const secp256k1_scalar_t *key, unsigned int flags);
|
||||
|
||||
static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak);
|
||||
static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context_t *ctx, secp256k1_ge_t *key, const secp256k1_scalar_t *tweak);
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include "group.h"
|
||||
#include "ecmult_gen.h"
|
||||
|
||||
static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned char *pub, int size) {
|
||||
static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned char *pub, size_t size) {
|
||||
if (size == 33 && (pub[0] == 0x02 || pub[0] == 0x03)) {
|
||||
secp256k1_fe_t x;
|
||||
return secp256k1_fe_set_b32(&x, pub+1) && secp256k1_ge_set_xo_var(elem, &x, pub[0] == 0x03);
|
||||
@ -33,14 +33,14 @@ static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned cha
|
||||
}
|
||||
}
|
||||
|
||||
static int secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char *pub, int *size, int compressed) {
|
||||
static int secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char *pub, size_t *size, unsigned int flags) {
|
||||
if (secp256k1_ge_is_infinity(elem)) {
|
||||
return 0;
|
||||
}
|
||||
secp256k1_fe_normalize_var(&elem->x);
|
||||
secp256k1_fe_normalize_var(&elem->y);
|
||||
secp256k1_fe_get_b32(&pub[1], &elem->x);
|
||||
if (compressed) {
|
||||
if (flags & SECP256K1_EC_COMPRESSED) {
|
||||
*size = 33;
|
||||
pub[0] = 0x02 | (secp256k1_fe_is_odd(&elem->y) ? 0x01 : 0x00);
|
||||
} else {
|
||||
@ -51,7 +51,7 @@ static int secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned char *privkey, int privkeylen) {
|
||||
static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned char *privkey, size_t privkeylen) {
|
||||
unsigned char c[32] = {0};
|
||||
const unsigned char *end = privkey + privkeylen;
|
||||
int lenb = 0;
|
||||
@ -94,13 +94,13 @@ static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned
|
||||
return !overflow;
|
||||
}
|
||||
|
||||
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) {
|
||||
static int secp256k1_eckey_privkey_serialize(const secp256k1_ecmult_gen_context_t *ctx, unsigned char *privkey, size_t *privkeylen, const secp256k1_scalar_t *key, unsigned int flags) {
|
||||
secp256k1_gej_t rp;
|
||||
secp256k1_ge_t r;
|
||||
int pubkeylen = 0;
|
||||
size_t pubkeylen = 0;
|
||||
secp256k1_ecmult_gen(ctx, &rp, key);
|
||||
secp256k1_ge_set_gej(&r, &rp);
|
||||
if (compressed) {
|
||||
if (flags & SECP256K1_EC_COMPRESSED) {
|
||||
static const unsigned char begin[] = {
|
||||
0x30,0x81,0xD3,0x02,0x01,0x01,0x04,0x20
|
||||
};
|
||||
|
@ -20,7 +20,7 @@ void test_ecdh_generator_basepoint(void) {
|
||||
unsigned char output_ecdh[32];
|
||||
unsigned char output_ser[32];
|
||||
unsigned char point_ser[33];
|
||||
int point_ser_len = sizeof(point_ser);
|
||||
size_t point_ser_len = sizeof(point_ser);
|
||||
secp256k1_scalar_t s;
|
||||
|
||||
random_scalar_order(&s);
|
||||
@ -31,7 +31,7 @@ void test_ecdh_generator_basepoint(void) {
|
||||
CHECK(secp256k1_ecdh(ctx, output_ecdh, &point[0], s_b32) == 1);
|
||||
/* compute "explicitly" */
|
||||
CHECK(secp256k1_ec_pubkey_create(ctx, &point[1], s_b32) == 1);
|
||||
CHECK(secp256k1_ec_pubkey_serialize(ctx, point_ser, &point_ser_len, &point[1], 1) == 1);
|
||||
CHECK(secp256k1_ec_pubkey_serialize(ctx, point_ser, &point_ser_len, &point[1], SECP256K1_EC_COMPRESSED) == 1);
|
||||
CHECK(point_ser_len == sizeof(point_ser));
|
||||
secp256k1_sha256_initialize(&sha);
|
||||
secp256k1_sha256_write(&sha, point_ser, point_ser_len);
|
||||
|
@ -105,7 +105,7 @@ int secp256k1_ecdsa_sign_recoverable(const secp256k1_context_t* ctx, secp256k1_e
|
||||
secp256k1_scalar_set_b32(&msg, msg32, NULL);
|
||||
while (1) {
|
||||
unsigned char nonce32[32];
|
||||
ret = noncefp(nonce32, seckey, msg32, NULL, noncedata, count);
|
||||
ret = noncefp(nonce32, seckey, msg32, NULL, (void*)noncedata, count);
|
||||
if (!ret) {
|
||||
break;
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ int secp256k1_schnorr_sign(const secp256k1_context_t* ctx, unsigned char *sig64,
|
||||
secp256k1_scalar_set_b32(&sec, seckey, NULL);
|
||||
while (1) {
|
||||
unsigned char nonce32[32];
|
||||
ret = noncefp(nonce32, msg32, seckey, secp256k1_schnorr_algo16, noncedata, count);
|
||||
ret = noncefp(nonce32, msg32, seckey, secp256k1_schnorr_algo16, (void*)noncedata, count);
|
||||
if (!ret) {
|
||||
break;
|
||||
}
|
||||
@ -107,7 +107,7 @@ int secp256k1_schnorr_generate_nonce_pair(const secp256k1_context_t* ctx, secp25
|
||||
|
||||
do {
|
||||
int overflow;
|
||||
ret = noncefp(privnonce32, sec32, msg32, secp256k1_schnorr_algo16, noncedata, count++);
|
||||
ret = noncefp(privnonce32, sec32, msg32, secp256k1_schnorr_algo16, (void*)noncedata, count++);
|
||||
if (!ret) {
|
||||
break;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
#define ARG_CHECK(cond) do { \
|
||||
if (EXPECT(!(cond), 0)) { \
|
||||
ctx->illegal_callback.fn(#cond, ctx->illegal_callback.data); \
|
||||
secp256k1_callback(&ctx->illegal_callback, #cond); \
|
||||
return 0; \
|
||||
} \
|
||||
} while(0)
|
||||
@ -57,7 +57,7 @@ struct secp256k1_context_struct {
|
||||
callback_t error_callback;
|
||||
};
|
||||
|
||||
secp256k1_context_t* secp256k1_context_create(int flags) {
|
||||
secp256k1_context_t* secp256k1_context_create(unsigned int flags) {
|
||||
secp256k1_context_t* ret = (secp256k1_context_t*)checked_malloc(&default_error_callback, sizeof(secp256k1_context_t));
|
||||
ret->illegal_callback = default_illegal_callback;
|
||||
ret->error_callback = default_error_callback;
|
||||
@ -85,18 +85,25 @@ secp256k1_context_t* secp256k1_context_clone(const secp256k1_context_t* ctx) {
|
||||
}
|
||||
|
||||
void secp256k1_context_destroy(secp256k1_context_t* ctx) {
|
||||
if (!ctx)
|
||||
return;
|
||||
|
||||
secp256k1_ecmult_context_clear(&ctx->ecmult_ctx);
|
||||
secp256k1_ecmult_gen_context_clear(&ctx->ecmult_gen_ctx);
|
||||
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
void secp256k1_context_set_illegal_callback(secp256k1_context_t* ctx, void (*fun)(const char* message, void* data), void* data) {
|
||||
void secp256k1_context_set_illegal_callback(secp256k1_context_t* ctx, void (*fun)(const char* message, void* data), const void* data) {
|
||||
if (!fun)
|
||||
fun = default_illegal_callback_fn;
|
||||
ctx->illegal_callback.fn = fun;
|
||||
ctx->illegal_callback.data = data;
|
||||
}
|
||||
|
||||
void secp256k1_context_set_error_callback(secp256k1_context_t* ctx, void (*fun)(const char* message, void* data), void* data) {
|
||||
void secp256k1_context_set_error_callback(secp256k1_context_t* ctx, void (*fun)(const char* message, void* data), const void* data) {
|
||||
if (!fun)
|
||||
fun = default_error_callback_fn;
|
||||
ctx->error_callback.fn = fun;
|
||||
ctx->error_callback.data = data;
|
||||
}
|
||||
@ -134,7 +141,7 @@ static void secp256k1_pubkey_save(secp256k1_pubkey_t* pubkey, secp256k1_ge_t* ge
|
||||
}
|
||||
}
|
||||
|
||||
int secp256k1_ec_pubkey_parse(const secp256k1_context_t* ctx, secp256k1_pubkey_t* pubkey, const unsigned char *input, int inputlen) {
|
||||
int secp256k1_ec_pubkey_parse(const secp256k1_context_t* ctx, secp256k1_pubkey_t* pubkey, const unsigned char *input, size_t inputlen) {
|
||||
secp256k1_ge_t Q;
|
||||
|
||||
(void)ctx;
|
||||
@ -147,12 +154,12 @@ int secp256k1_ec_pubkey_parse(const secp256k1_context_t* ctx, secp256k1_pubkey_t
|
||||
return 1;
|
||||
}
|
||||
|
||||
int secp256k1_ec_pubkey_serialize(const secp256k1_context_t* ctx, unsigned char *output, int *outputlen, const secp256k1_pubkey_t* pubkey, int compressed) {
|
||||
int secp256k1_ec_pubkey_serialize(const secp256k1_context_t* ctx, unsigned char *output, size_t *outputlen, const secp256k1_pubkey_t* pubkey, unsigned int flags) {
|
||||
secp256k1_ge_t Q;
|
||||
|
||||
(void)ctx;
|
||||
return (secp256k1_pubkey_load(ctx, &Q, pubkey) &&
|
||||
secp256k1_eckey_pubkey_serialize(&Q, output, outputlen, compressed));
|
||||
secp256k1_eckey_pubkey_serialize(&Q, output, outputlen, flags));
|
||||
}
|
||||
|
||||
static void secp256k1_ecdsa_signature_load(const secp256k1_context_t* ctx, secp256k1_scalar_t* r, secp256k1_scalar_t* s, const secp256k1_ecdsa_signature_t* sig) {
|
||||
@ -179,7 +186,7 @@ static void secp256k1_ecdsa_signature_save(secp256k1_ecdsa_signature_t* sig, con
|
||||
}
|
||||
}
|
||||
|
||||
int secp256k1_ecdsa_signature_parse_der(const secp256k1_context_t* ctx, secp256k1_ecdsa_signature_t* sig, const unsigned char *input, int inputlen) {
|
||||
int secp256k1_ecdsa_signature_parse_der(const secp256k1_context_t* ctx, secp256k1_ecdsa_signature_t* sig, const unsigned char *input, size_t inputlen) {
|
||||
secp256k1_scalar_t r, s;
|
||||
|
||||
(void)ctx;
|
||||
@ -195,7 +202,7 @@ int secp256k1_ecdsa_signature_parse_der(const secp256k1_context_t* ctx, secp256k
|
||||
}
|
||||
}
|
||||
|
||||
int secp256k1_ecdsa_signature_serialize_der(const secp256k1_context_t* ctx, unsigned char *output, int *outputlen, const secp256k1_ecdsa_signature_t* sig) {
|
||||
int secp256k1_ecdsa_signature_serialize_der(const secp256k1_context_t* ctx, unsigned char *output, size_t *outputlen, const secp256k1_ecdsa_signature_t* sig) {
|
||||
secp256k1_scalar_t r, s;
|
||||
|
||||
(void)ctx;
|
||||
@ -223,7 +230,7 @@ int secp256k1_ecdsa_verify(const secp256k1_context_t* ctx, const secp256k1_ecdsa
|
||||
secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &r, &s, &q, &m));
|
||||
}
|
||||
|
||||
static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, const void *data, unsigned int counter) {
|
||||
static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) {
|
||||
unsigned char keydata[112];
|
||||
int keylen = 64;
|
||||
secp256k1_rfc6979_hmac_sha256_t rng;
|
||||
@ -278,7 +285,7 @@ int secp256k1_ecdsa_sign(const secp256k1_context_t* ctx, secp256k1_ecdsa_signatu
|
||||
secp256k1_scalar_set_b32(&msg, msg32, NULL);
|
||||
while (1) {
|
||||
unsigned char nonce32[32];
|
||||
ret = noncefp(nonce32, msg32, seckey, NULL, noncedata, count);
|
||||
ret = noncefp(nonce32, msg32, seckey, NULL, (void*)noncedata, count);
|
||||
if (!ret) {
|
||||
break;
|
||||
}
|
||||
@ -431,7 +438,7 @@ int secp256k1_ec_pubkey_tweak_mul(const secp256k1_context_t* ctx, secp256k1_pubk
|
||||
return ret;
|
||||
}
|
||||
|
||||
int secp256k1_ec_privkey_export(const secp256k1_context_t* ctx, unsigned char *privkey, int *privkeylen, const unsigned char *seckey, int compressed) {
|
||||
int secp256k1_ec_privkey_export(const secp256k1_context_t* ctx, unsigned char *privkey, size_t *privkeylen, const unsigned char *seckey, unsigned int flags) {
|
||||
secp256k1_scalar_t key;
|
||||
int ret = 0;
|
||||
VERIFY_CHECK(ctx != NULL);
|
||||
@ -441,12 +448,12 @@ int secp256k1_ec_privkey_export(const secp256k1_context_t* ctx, unsigned char *p
|
||||
ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
|
||||
|
||||
secp256k1_scalar_set_b32(&key, seckey, NULL);
|
||||
ret = secp256k1_eckey_privkey_serialize(&ctx->ecmult_gen_ctx, privkey, privkeylen, &key, compressed);
|
||||
ret = secp256k1_eckey_privkey_serialize(&ctx->ecmult_gen_ctx, privkey, privkeylen, &key, flags);
|
||||
secp256k1_scalar_clear(&key);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int secp256k1_ec_privkey_import(const secp256k1_context_t* ctx, unsigned char *seckey, const unsigned char *privkey, int privkeylen) {
|
||||
int secp256k1_ec_privkey_import(const secp256k1_context_t* ctx, unsigned char *seckey, const unsigned char *privkey, size_t privkeylen) {
|
||||
secp256k1_scalar_t key;
|
||||
int ret = 0;
|
||||
ARG_CHECK(seckey != NULL);
|
||||
|
36
src/tests.c
36
src/tests.c
@ -1378,7 +1378,7 @@ void test_point_times_order(const secp256k1_gej_t *point) {
|
||||
secp256k1_gej_t res1, res2;
|
||||
secp256k1_ge_t res3;
|
||||
unsigned char pub[65];
|
||||
int psize = 65;
|
||||
size_t psize = 65;
|
||||
random_scalar_order_test(&x);
|
||||
secp256k1_scalar_negate(&nx, &x);
|
||||
secp256k1_ecmult(&ctx->ecmult_ctx, &res1, point, &x, &x); /* calc res1 = x * point + x * G; */
|
||||
@ -1787,7 +1787,7 @@ void run_ecdsa_sign_verify(void) {
|
||||
}
|
||||
|
||||
/** Dummy nonce generation function that just uses a precomputed nonce, and fails if it is not accepted. Use only for testing. */
|
||||
static int precomputed_nonce_function(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, const void *data, unsigned int counter) {
|
||||
static int precomputed_nonce_function(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) {
|
||||
(void)msg32;
|
||||
(void)key32;
|
||||
(void)algo16;
|
||||
@ -1795,7 +1795,7 @@ static int precomputed_nonce_function(unsigned char *nonce32, const unsigned cha
|
||||
return (counter == 0);
|
||||
}
|
||||
|
||||
static int nonce_function_test_fail(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, const void *data, unsigned int counter) {
|
||||
static int nonce_function_test_fail(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) {
|
||||
/* Dummy nonce generator that has a fatal error on the first counter value. */
|
||||
if (counter == 0) {
|
||||
return 0;
|
||||
@ -1803,7 +1803,7 @@ static int nonce_function_test_fail(unsigned char *nonce32, const unsigned char
|
||||
return nonce_function_rfc6979(nonce32, msg32, key32, algo16, data, counter - 1);
|
||||
}
|
||||
|
||||
static int nonce_function_test_retry(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, const void *data, unsigned int counter) {
|
||||
static int nonce_function_test_retry(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) {
|
||||
/* Dummy nonce generator that produces unacceptable nonces for the first several counter values. */
|
||||
if (counter < 3) {
|
||||
memset(nonce32, counter==0 ? 0 : 255, 32);
|
||||
@ -1845,12 +1845,12 @@ void test_ecdsa_end_to_end(void) {
|
||||
unsigned char privkey2[32];
|
||||
secp256k1_ecdsa_signature_t signature[5];
|
||||
unsigned char sig[74];
|
||||
int siglen = 74;
|
||||
size_t siglen = 74;
|
||||
unsigned char pubkeyc[65];
|
||||
int pubkeyclen = 65;
|
||||
size_t pubkeyclen = 65;
|
||||
secp256k1_pubkey_t pubkey;
|
||||
unsigned char seckey[300];
|
||||
int seckeylen = 300;
|
||||
size_t seckeylen = 300;
|
||||
|
||||
/* Generate a random key and message. */
|
||||
{
|
||||
@ -1871,7 +1871,7 @@ void test_ecdsa_end_to_end(void) {
|
||||
CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, pubkeyclen) == 1);
|
||||
|
||||
/* Verify private key import and export. */
|
||||
CHECK(secp256k1_ec_privkey_export(ctx, seckey, &seckeylen, privkey, secp256k1_rand32() % 2) == 1);
|
||||
CHECK(secp256k1_ec_privkey_export(ctx, seckey, &seckeylen, privkey, (secp256k1_rand32() % 2) == 1) ? SECP256K1_EC_COMPRESSED : 0);
|
||||
CHECK(secp256k1_ec_privkey_import(ctx, privkey2, seckey, seckeylen) == 1);
|
||||
CHECK(memcmp(privkey, privkey2, 32) == 0);
|
||||
|
||||
@ -1937,6 +1937,7 @@ void test_ecdsa_end_to_end(void) {
|
||||
CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &signature[0], sig, siglen) == 1);
|
||||
CHECK(secp256k1_ecdsa_verify(ctx, &signature[0], message, &pubkey) == 1);
|
||||
/* Serialize/destroy/parse DER and verify again. */
|
||||
siglen = 74;
|
||||
CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, sig, &siglen, &signature[0]) == 1);
|
||||
sig[secp256k1_rand32() % siglen] += 1 + (secp256k1_rand32() % 255);
|
||||
CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &signature[0], sig, siglen) == 0 ||
|
||||
@ -1949,7 +1950,7 @@ void test_random_pubkeys(void) {
|
||||
unsigned char in[65];
|
||||
/* Generate some randomly sized pubkeys. */
|
||||
uint32_t r = secp256k1_rand32();
|
||||
int len = (r & 3) == 0 ? 65 : 33;
|
||||
size_t len = (r & 3) == 0 ? 65 : 33;
|
||||
r>>=2;
|
||||
if ((r & 3) == 0) {
|
||||
len = (r & 252) >> 3;
|
||||
@ -1975,10 +1976,10 @@ void test_random_pubkeys(void) {
|
||||
unsigned char out[65];
|
||||
unsigned char firstb;
|
||||
int res;
|
||||
int size = len;
|
||||
size_t size = len;
|
||||
firstb = in[0];
|
||||
/* If the pubkey can be parsed, it should round-trip... */
|
||||
CHECK(secp256k1_eckey_pubkey_serialize(&elem, out, &size, len == 33));
|
||||
CHECK(secp256k1_eckey_pubkey_serialize(&elem, out, &size, (len == 33) ? SECP256K1_EC_COMPRESSED : 0));
|
||||
CHECK(size == len);
|
||||
CHECK(memcmp(&in[1], &out[1], len-1) == 0);
|
||||
/* ... except for the type of hybrid inputs. */
|
||||
@ -2046,7 +2047,7 @@ void test_ecdsa_edge_cases(void) {
|
||||
/*Signature where s would be zero.*/
|
||||
{
|
||||
unsigned char signature[72];
|
||||
int siglen;
|
||||
size_t siglen;
|
||||
const unsigned char nonce[32] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
@ -2152,9 +2153,10 @@ void test_ecdsa_edge_cases(void) {
|
||||
0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b,
|
||||
0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41,
|
||||
};
|
||||
int outlen = 300;
|
||||
size_t outlen = 300;
|
||||
CHECK(!secp256k1_ec_privkey_export(ctx, privkey, &outlen, seckey, 0));
|
||||
CHECK(!secp256k1_ec_privkey_export(ctx, privkey, &outlen, seckey, 1));
|
||||
outlen = 300;
|
||||
CHECK(!secp256k1_ec_privkey_export(ctx, privkey, &outlen, seckey, SECP256K1_EC_COMPRESSED));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2165,11 +2167,11 @@ void run_ecdsa_edge_cases(void) {
|
||||
#ifdef ENABLE_OPENSSL_TESTS
|
||||
EC_KEY *get_openssl_key(const secp256k1_scalar_t *key) {
|
||||
unsigned char privkey[300];
|
||||
int privkeylen;
|
||||
size_t privkeylen;
|
||||
const unsigned char* pbegin = privkey;
|
||||
int compr = secp256k1_rand32() & 1;
|
||||
EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||
CHECK(secp256k1_eckey_privkey_serialize(&ctx->ecmult_gen_ctx, privkey, &privkeylen, key, compr));
|
||||
CHECK(secp256k1_eckey_privkey_serialize(&ctx->ecmult_gen_ctx, privkey, &privkeylen, key, compr ? SECP256K1_EC_COMPRESSED : 0));
|
||||
CHECK(d2i_ECPrivateKey(&ec_key, &pbegin, privkeylen));
|
||||
CHECK(EC_KEY_check_key(ec_key));
|
||||
return ec_key;
|
||||
@ -2184,7 +2186,7 @@ void test_ecdsa_openssl(void) {
|
||||
secp256k1_scalar_t key, msg;
|
||||
EC_KEY *ec_key;
|
||||
unsigned int sigsize = 80;
|
||||
int secp_sigsize = 80;
|
||||
size_t secp_sigsize = 80;
|
||||
unsigned char message[32];
|
||||
unsigned char signature[80];
|
||||
secp256k1_rand256_test(message);
|
||||
|
@ -17,9 +17,13 @@
|
||||
|
||||
typedef struct {
|
||||
void (*fn)(const char *text, void* data);
|
||||
void* data;
|
||||
const void* data;
|
||||
} callback_t;
|
||||
|
||||
static SECP256K1_INLINE void secp256k1_callback(const callback_t * const cb, const char * const text) {
|
||||
cb->fn(text, (void*)cb->data);
|
||||
}
|
||||
|
||||
#ifdef DETERMINISTIC
|
||||
#define TEST_FAILURE(msg) do { \
|
||||
fprintf(stderr, "%s\n", msg); \
|
||||
@ -64,7 +68,7 @@ typedef struct {
|
||||
static SECP256K1_INLINE void *checked_malloc(const callback_t* cb, size_t size) {
|
||||
void *ret = malloc(size);
|
||||
if (ret == NULL) {
|
||||
cb->fn("Out of memory", cb->data);
|
||||
secp256k1_callback(cb, "Out of memory");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user