Merge pull request #278

995c548 Introduce callback functions for dealing with errors. (Pieter Wuille)
This commit is contained in:
Pieter Wuille 2015-07-29 17:51:53 +02:00
commit ae4f0c6eec
No known key found for this signature in database
GPG Key ID: 57896D2FF8F0B657
11 changed files with 205 additions and 116 deletions

View File

@ -74,6 +74,37 @@ 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. The philosophy is that these shouldn't be dealt with through a
* specific return value, as calling code should not have branches to deal with
* the case that this code itself is broken.
* On the other hand, during debug stage, one would want to be informed about
* such mistakes, and the default (crashing) may be inadvisable.
* When this callback is triggered, the API function called is guaranteed not
* to cause a crash, though its return value and output arguments are
* undefined.
*/
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);
/** Set a callback function to be called when an internal consistency check
* fails. The default is crashing.
* This can only trigger in case of a hardware failure, miscompilation,
* memory corruption, serious bug in the library, or other error would can
* otherwise result in undefined behaviour. It will not trigger due to mere
* incorrect usage of the API (see secp256k1_context_set_illegal_callback
* for that). After this callback returns, anything may happen, including
* crashing.
*/
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);
/** Data type to hold a parsed and valid public key.
This data type should be considered opaque to the user, and only created
through API functions. It is not guaranteed to be compatible between

View File

@ -19,9 +19,9 @@ typedef struct {
} secp256k1_ecmult_context_t;
static void secp256k1_ecmult_context_init(secp256k1_ecmult_context_t *ctx);
static void secp256k1_ecmult_context_build(secp256k1_ecmult_context_t *ctx);
static void secp256k1_ecmult_context_build(secp256k1_ecmult_context_t *ctx, const callback_t *cb);
static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context_t *dst,
const secp256k1_ecmult_context_t *src);
const secp256k1_ecmult_context_t *src, const callback_t *cb);
static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context_t *ctx);
static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context_t *ctx);

View File

@ -29,9 +29,9 @@ typedef struct {
} secp256k1_ecmult_gen_context_t;
static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context_t* ctx);
static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context_t* ctx);
static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context_t* ctx, const callback_t* cb);
static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context_t *dst,
const secp256k1_ecmult_gen_context_t* src);
const secp256k1_ecmult_gen_context_t* src, const callback_t* cb);
static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context_t* ctx);
static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context_t* ctx);

View File

@ -18,7 +18,7 @@ static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context_t *ct
ctx->prec = NULL;
}
static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context_t *ctx) {
static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context_t *ctx, const callback_t* cb) {
#ifndef USE_ECMULT_STATIC_PRECOMPUTATION
secp256k1_ge_t prec[1024];
secp256k1_gej_t gj;
@ -30,7 +30,7 @@ static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context_t *c
return;
}
#ifndef USE_ECMULT_STATIC_PRECOMPUTATION
ctx->prec = (secp256k1_ge_storage_t (*)[64][16])checked_malloc(sizeof(*ctx->prec));
ctx->prec = (secp256k1_ge_storage_t (*)[64][16])checked_malloc(cb, sizeof(*ctx->prec));
/* get the generator */
secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g);
@ -72,7 +72,7 @@ static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context_t *c
secp256k1_gej_add_var(&numsbase, &numsbase, &nums_gej, NULL);
}
}
secp256k1_ge_set_all_gej_var(1024, prec, precj);
secp256k1_ge_set_all_gej_var(1024, prec, precj, cb);
}
for (j = 0; j < 64; j++) {
for (i = 0; i < 16; i++) {
@ -80,6 +80,7 @@ static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context_t *c
}
}
#else
(void)cb;
ctx->prec = (secp256k1_ge_storage_t (*)[64][16])secp256k1_ecmult_static_context;
#endif
secp256k1_ecmult_gen_blind(ctx, NULL);
@ -90,14 +91,15 @@ static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_cont
}
static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context_t *dst,
const secp256k1_ecmult_gen_context_t *src) {
const secp256k1_ecmult_gen_context_t *src, const callback_t* cb) {
if (src->prec == NULL) {
dst->prec = NULL;
} else {
#ifndef USE_ECMULT_STATIC_PRECOMPUTATION
dst->prec = (secp256k1_ge_storage_t (*)[64][16])checked_malloc(sizeof(*dst->prec));
dst->prec = (secp256k1_ge_storage_t (*)[64][16])checked_malloc(cb, sizeof(*dst->prec));
memcpy(dst->prec, src->prec, sizeof(*dst->prec));
#else
(void)cb;
dst->prec = src->prec;
#endif
dst->initial = src->initial;

View File

@ -92,10 +92,10 @@ static void secp256k1_ecmult_odd_multiples_table_globalz_windowa(secp256k1_ge_t
secp256k1_ge_globalz_set_table_gej(ECMULT_TABLE_SIZE(WINDOW_A), pre, globalz, prej, zr);
}
static void secp256k1_ecmult_odd_multiples_table_storage_var(int n, secp256k1_ge_storage_t *pre, const secp256k1_gej_t *a) {
secp256k1_gej_t *prej = (secp256k1_gej_t*)checked_malloc(sizeof(secp256k1_gej_t) * n);
secp256k1_ge_t *prea = (secp256k1_ge_t*)checked_malloc(sizeof(secp256k1_ge_t) * n);
secp256k1_fe_t *zr = (secp256k1_fe_t*)checked_malloc(sizeof(secp256k1_fe_t) * n);
static void secp256k1_ecmult_odd_multiples_table_storage_var(int n, secp256k1_ge_storage_t *pre, const secp256k1_gej_t *a, const callback_t *cb) {
secp256k1_gej_t *prej = (secp256k1_gej_t*)checked_malloc(cb, sizeof(secp256k1_gej_t) * n);
secp256k1_ge_t *prea = (secp256k1_ge_t*)checked_malloc(cb, sizeof(secp256k1_ge_t) * n);
secp256k1_fe_t *zr = (secp256k1_fe_t*)checked_malloc(cb, sizeof(secp256k1_fe_t) * n);
int i;
/* Compute the odd multiples in Jacobian form. */
@ -144,7 +144,7 @@ static void secp256k1_ecmult_context_init(secp256k1_ecmult_context_t *ctx) {
#endif
}
static void secp256k1_ecmult_context_build(secp256k1_ecmult_context_t *ctx) {
static void secp256k1_ecmult_context_build(secp256k1_ecmult_context_t *ctx, const callback_t *cb) {
secp256k1_gej_t gj;
if (ctx->pre_g != NULL) {
@ -154,35 +154,35 @@ static void secp256k1_ecmult_context_build(secp256k1_ecmult_context_t *ctx) {
/* get the generator */
secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g);
ctx->pre_g = (secp256k1_ge_storage_t (*)[])checked_malloc(sizeof((*ctx->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G));
ctx->pre_g = (secp256k1_ge_storage_t (*)[])checked_malloc(cb, sizeof((*ctx->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G));
/* precompute the tables with odd multiples */
secp256k1_ecmult_odd_multiples_table_storage_var(ECMULT_TABLE_SIZE(WINDOW_G), *ctx->pre_g, &gj);
secp256k1_ecmult_odd_multiples_table_storage_var(ECMULT_TABLE_SIZE(WINDOW_G), *ctx->pre_g, &gj, cb);
#ifdef USE_ENDOMORPHISM
{
secp256k1_gej_t g_128j;
int i;
ctx->pre_g_128 = (secp256k1_ge_storage_t (*)[])checked_malloc(sizeof((*ctx->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G));
ctx->pre_g_128 = (secp256k1_ge_storage_t (*)[])checked_malloc(cb, sizeof((*ctx->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G));
/* calculate 2^128*generator */
g_128j = gj;
for (i = 0; i < 128; i++) {
secp256k1_gej_double_var(&g_128j, &g_128j, NULL);
}
secp256k1_ecmult_odd_multiples_table_storage_var(ECMULT_TABLE_SIZE(WINDOW_G), *ctx->pre_g_128, &g_128j);
secp256k1_ecmult_odd_multiples_table_storage_var(ECMULT_TABLE_SIZE(WINDOW_G), *ctx->pre_g_128, &g_128j, cb);
}
#endif
}
static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context_t *dst,
const secp256k1_ecmult_context_t *src) {
const secp256k1_ecmult_context_t *src, const callback_t *cb) {
if (src->pre_g == NULL) {
dst->pre_g = NULL;
} else {
size_t size = sizeof((*dst->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G);
dst->pre_g = (secp256k1_ge_storage_t (*)[])checked_malloc(size);
dst->pre_g = (secp256k1_ge_storage_t (*)[])checked_malloc(cb, size);
memcpy(dst->pre_g, src->pre_g, size);
}
#ifdef USE_ENDOMORPHISM
@ -190,7 +190,7 @@ static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context_t *dst,
dst->pre_g_128 = NULL;
} else {
size_t size = sizeof((*dst->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G);
dst->pre_g_128 = (secp256k1_ge_storage_t (*)[])checked_malloc(size);
dst->pre_g_128 = (secp256k1_ge_storage_t (*)[])checked_malloc(cb, size);
memcpy(dst->pre_g_128, src->pre_g_128, size);
}
#endif

View File

@ -13,6 +13,17 @@
#include "group_impl.h"
#include "ecmult_gen_impl.h"
static void default_error_callback_fn(const char* str, void* data) {
(void)data;
fprintf(stderr, "[libsecp256k1] internal consistency check failed: %s\n", str);
abort();
}
static const callback_t default_error_callback = {
default_error_callback_fn,
NULL
};
int main(int argc, char **argv) {
secp256k1_ecmult_gen_context_t ctx;
int inner;
@ -35,7 +46,7 @@ int main(int argc, char **argv) {
fprintf(fp, "static const secp256k1_ge_storage_t secp256k1_ecmult_static_context[64][16] = {\n");
secp256k1_ecmult_gen_context_init(&ctx);
secp256k1_ecmult_gen_context_build(&ctx);
secp256k1_ecmult_gen_context_build(&ctx, &default_error_callback);
for(outer = 0; outer != 64; outer++) {
fprintf(fp,"{\n");
for(inner = 0; inner != 16; inner++) {

View File

@ -62,7 +62,7 @@ static void secp256k1_ge_neg(secp256k1_ge_t *r, const secp256k1_ge_t *a);
static void secp256k1_ge_set_gej(secp256k1_ge_t *r, secp256k1_gej_t *a);
/** Set a batch of group elements equal to the inputs given in jacobian coordinates */
static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge_t *r, const secp256k1_gej_t *a);
static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge_t *r, const secp256k1_gej_t *a, const callback_t *cb);
/** Set a batch of group elements equal to the inputs given in jacobian
* coordinates (with known z-ratios). zr must contain the known z-ratios such

View File

@ -82,19 +82,19 @@ static void secp256k1_ge_set_gej_var(secp256k1_ge_t *r, secp256k1_gej_t *a) {
r->y = a->y;
}
static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge_t *r, const secp256k1_gej_t *a) {
static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge_t *r, const secp256k1_gej_t *a, const callback_t *cb) {
secp256k1_fe_t *az;
secp256k1_fe_t *azi;
size_t i;
size_t count = 0;
az = (secp256k1_fe_t *)checked_malloc(sizeof(secp256k1_fe_t) * len);
az = (secp256k1_fe_t *)checked_malloc(cb, sizeof(secp256k1_fe_t) * len);
for (i = 0; i < len; i++) {
if (!a[i].infinity) {
az[count++] = a[i].z;
}
}
azi = (secp256k1_fe_t *)checked_malloc(sizeof(secp256k1_fe_t) * count);
azi = (secp256k1_fe_t *)checked_malloc(cb, sizeof(secp256k1_fe_t) * count);
secp256k1_fe_inv_all_var(count, azi, az);
free(az);

View File

@ -19,31 +19,67 @@
#include "eckey_impl.h"
#include "hash_impl.h"
#define ARG_CHECK(cond) do { \
if (EXPECT(!(cond), 0)) { \
ctx->illegal_callback.fn(#cond, ctx->illegal_callback.data); \
return 0; \
} \
} while(0)
static void default_illegal_callback_fn(const char* str, void* data) {
(void)data;
fprintf(stderr, "[libsecp256k1] illegal argument: %s\n", str);
abort();
}
static const callback_t default_illegal_callback = {
default_illegal_callback_fn,
NULL
};
static void default_error_callback_fn(const char* str, void* data) {
(void)data;
fprintf(stderr, "[libsecp256k1] internal consistency check failed: %s\n", str);
abort();
}
static const callback_t default_error_callback = {
default_error_callback_fn,
NULL
};
struct secp256k1_context_struct {
secp256k1_ecmult_context_t ecmult_ctx;
secp256k1_ecmult_gen_context_t ecmult_gen_ctx;
callback_t illegal_callback;
callback_t error_callback;
};
secp256k1_context_t* secp256k1_context_create(int flags) {
secp256k1_context_t* ret = (secp256k1_context_t*)checked_malloc(sizeof(secp256k1_context_t));
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;
secp256k1_ecmult_context_init(&ret->ecmult_ctx);
secp256k1_ecmult_gen_context_init(&ret->ecmult_gen_ctx);
if (flags & SECP256K1_CONTEXT_SIGN) {
secp256k1_ecmult_gen_context_build(&ret->ecmult_gen_ctx);
secp256k1_ecmult_gen_context_build(&ret->ecmult_gen_ctx, &ret->error_callback);
}
if (flags & SECP256K1_CONTEXT_VERIFY) {
secp256k1_ecmult_context_build(&ret->ecmult_ctx);
secp256k1_ecmult_context_build(&ret->ecmult_ctx, &ret->error_callback);
}
return ret;
}
secp256k1_context_t* secp256k1_context_clone(const secp256k1_context_t* ctx) {
secp256k1_context_t* ret = (secp256k1_context_t*)checked_malloc(sizeof(secp256k1_context_t));
secp256k1_ecmult_context_clone(&ret->ecmult_ctx, &ctx->ecmult_ctx);
secp256k1_ecmult_gen_context_clone(&ret->ecmult_gen_ctx, &ctx->ecmult_gen_ctx);
secp256k1_context_t* ret = (secp256k1_context_t*)checked_malloc(&ctx->error_callback, sizeof(secp256k1_context_t));
ret->illegal_callback = ctx->illegal_callback;
ret->error_callback = ctx->error_callback;
secp256k1_ecmult_context_clone(&ret->ecmult_ctx, &ctx->ecmult_ctx, &ctx->error_callback);
secp256k1_ecmult_gen_context_clone(&ret->ecmult_gen_ctx, &ctx->ecmult_gen_ctx, &ctx->error_callback);
return ret;
}
@ -54,7 +90,17 @@ void secp256k1_context_destroy(secp256k1_context_t* ctx) {
free(ctx);
}
static void secp256k1_pubkey_load(secp256k1_ge_t* ge, const secp256k1_pubkey_t* pubkey) {
void secp256k1_context_set_illegal_callback(secp256k1_context_t* ctx, void (*fun)(const char* message, void* data), void* data) {
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) {
ctx->error_callback.fn = fun;
ctx->error_callback.data = data;
}
static int secp256k1_pubkey_load(const secp256k1_context_t* ctx, secp256k1_ge_t* ge, const secp256k1_pubkey_t* pubkey) {
if (sizeof(secp256k1_ge_storage_t) == 64) {
/* When the secp256k1_ge_storage_t type is exactly 64 byte, use its
* representation inside secp256k1_pubkey_t, as conversion is very fast.
@ -62,15 +108,15 @@ static void secp256k1_pubkey_load(secp256k1_ge_t* ge, const secp256k1_pubkey_t*
secp256k1_ge_storage_t s;
memcpy(&s, &pubkey->data[0], 64);
secp256k1_ge_from_storage(ge, &s);
DEBUG_CHECK(!secp256k1_fe_is_zero(&ge->x));
} else {
/* Otherwise, fall back to 32-byte big endian for X and Y. */
secp256k1_fe_t x, y;
secp256k1_fe_set_b32(&x, pubkey->data);
DEBUG_CHECK(!secp256k1_fe_is_zero(&x));
secp256k1_fe_set_b32(&y, pubkey->data + 32);
secp256k1_ge_set_xy(ge, &x, &y);
}
ARG_CHECK(!secp256k1_fe_is_zero(&ge->x));
return 1;
}
static void secp256k1_pubkey_save(secp256k1_pubkey_t* pubkey, secp256k1_ge_t* ge) {
@ -104,11 +150,12 @@ int secp256k1_ec_pubkey_serialize(const secp256k1_context_t* ctx, unsigned char
secp256k1_ge_t Q;
(void)ctx;
secp256k1_pubkey_load(&Q, pubkey);
return secp256k1_eckey_pubkey_serialize(&Q, output, outputlen, compressed);
return (secp256k1_pubkey_load(ctx, &Q, pubkey) &&
secp256k1_eckey_pubkey_serialize(&Q, output, outputlen, compressed));
}
static void secp256k1_ecdsa_signature_load(secp256k1_scalar_t* r, secp256k1_scalar_t* s, int* recid, const secp256k1_ecdsa_signature_t* sig) {
static void secp256k1_ecdsa_signature_load(const secp256k1_context_t* ctx, secp256k1_scalar_t* r, secp256k1_scalar_t* s, int* recid, const secp256k1_ecdsa_signature_t* sig) {
(void)ctx;
if (sizeof(secp256k1_scalar_t) == 32) {
/* When the secp256k1_scalar_t type is exactly 32 byte, use its
* representation inside secp256k1_ecdsa_signature_t, as conversion is very fast.
@ -139,8 +186,8 @@ int secp256k1_ecdsa_signature_parse_der(const secp256k1_context_t* ctx, secp256k
secp256k1_scalar_t r, s;
(void)ctx;
DEBUG_CHECK(sig != NULL);
DEBUG_CHECK(input != NULL);
ARG_CHECK(sig != NULL);
ARG_CHECK(input != NULL);
if (secp256k1_ecdsa_sig_parse(&r, &s, input, inputlen)) {
secp256k1_ecdsa_signature_save(sig, &r, &s, -1);
@ -157,8 +204,8 @@ int secp256k1_ecdsa_signature_parse_compact(const secp256k1_context_t* ctx, secp
int overflow = 0;
(void)ctx;
DEBUG_CHECK(sig != NULL);
DEBUG_CHECK(input64 != NULL);
ARG_CHECK(sig != NULL);
ARG_CHECK(input64 != NULL);
secp256k1_scalar_set_b32(&r, &input64[0], &overflow);
ret &= !overflow;
@ -177,11 +224,11 @@ int secp256k1_ecdsa_signature_serialize_der(const secp256k1_context_t* ctx, unsi
secp256k1_scalar_t r, s;
(void)ctx;
DEBUG_CHECK(output != NULL);
DEBUG_CHECK(outputlen != NULL);
DEBUG_CHECK(sig != NULL);
ARG_CHECK(output != NULL);
ARG_CHECK(outputlen != NULL);
ARG_CHECK(sig != NULL);
secp256k1_ecdsa_signature_load(&r, &s, NULL, sig);
secp256k1_ecdsa_signature_load(ctx, &r, &s, NULL, sig);
return secp256k1_ecdsa_sig_serialize(output, outputlen, &r, &s);
}
@ -190,14 +237,14 @@ int secp256k1_ecdsa_signature_serialize_compact(const secp256k1_context_t* ctx,
int rec;
(void)ctx;
DEBUG_CHECK(output64 != NULL);
DEBUG_CHECK(sig != NULL);
ARG_CHECK(output64 != NULL);
ARG_CHECK(sig != NULL);
secp256k1_ecdsa_signature_load(&r, &s, &rec, sig);
secp256k1_ecdsa_signature_load(ctx, &r, &s, &rec, sig);
secp256k1_scalar_get_b32(&output64[0], &r);
secp256k1_scalar_get_b32(&output64[32], &s);
if (recid) {
DEBUG_CHECK(rec >= 0 && rec < 4);
ARG_CHECK(rec >= 0 && rec < 4);
*recid = rec;
}
return 1;
@ -207,16 +254,16 @@ int secp256k1_ecdsa_verify(const secp256k1_context_t* ctx, const unsigned char *
secp256k1_ge_t q;
secp256k1_scalar_t r, s;
secp256k1_scalar_t m;
DEBUG_CHECK(ctx != NULL);
DEBUG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx));
DEBUG_CHECK(msg32 != NULL);
DEBUG_CHECK(sig != NULL);
DEBUG_CHECK(pubkey != NULL);
ARG_CHECK(ctx != NULL);
ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx));
ARG_CHECK(msg32 != NULL);
ARG_CHECK(sig != NULL);
ARG_CHECK(pubkey != NULL);
secp256k1_scalar_set_b32(&m, msg32, NULL);
secp256k1_pubkey_load(&q, pubkey);
secp256k1_ecdsa_signature_load(&r, &s, NULL, sig);
return secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &r, &s, &q, &m);
secp256k1_ecdsa_signature_load(ctx, &r, &s, NULL, sig);
return (secp256k1_pubkey_load(ctx, &q, pubkey) &&
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, unsigned int counter, const void *data) {
@ -251,11 +298,11 @@ int secp256k1_ecdsa_sign(const secp256k1_context_t* ctx, const unsigned char *ms
int ret = 0;
int overflow = 0;
unsigned int count = 0;
DEBUG_CHECK(ctx != NULL);
DEBUG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
DEBUG_CHECK(msg32 != NULL);
DEBUG_CHECK(signature != NULL);
DEBUG_CHECK(seckey != NULL);
ARG_CHECK(ctx != NULL);
ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
ARG_CHECK(msg32 != NULL);
ARG_CHECK(signature != NULL);
ARG_CHECK(seckey != NULL);
if (noncefp == NULL) {
noncefp = secp256k1_nonce_function_default;
}
@ -296,14 +343,14 @@ int secp256k1_ecdsa_recover(const secp256k1_context_t* ctx, const unsigned char
secp256k1_scalar_t r, s;
secp256k1_scalar_t m;
int recid;
DEBUG_CHECK(ctx != NULL);
DEBUG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx));
DEBUG_CHECK(msg32 != NULL);
DEBUG_CHECK(signature != NULL);
DEBUG_CHECK(pubkey != NULL);
ARG_CHECK(ctx != NULL);
ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx));
ARG_CHECK(msg32 != NULL);
ARG_CHECK(signature != NULL);
ARG_CHECK(pubkey != NULL);
secp256k1_ecdsa_signature_load(&r, &s, &recid, signature);
DEBUG_CHECK(recid >= 0 && recid < 4);
secp256k1_ecdsa_signature_load(ctx, &r, &s, &recid, signature);
ARG_CHECK(recid >= 0 && recid < 4);
secp256k1_scalar_set_b32(&m, msg32, NULL);
if (secp256k1_ecdsa_sig_recover(&ctx->ecmult_ctx, &r, &s, &q, &m, recid)) {
secp256k1_pubkey_save(pubkey, &q);
@ -318,8 +365,8 @@ int secp256k1_ec_seckey_verify(const secp256k1_context_t* ctx, const unsigned ch
secp256k1_scalar_t sec;
int ret;
int overflow;
DEBUG_CHECK(ctx != NULL);
DEBUG_CHECK(seckey != NULL);
ARG_CHECK(ctx != NULL);
ARG_CHECK(seckey != NULL);
(void)ctx;
secp256k1_scalar_set_b32(&sec, seckey, &overflow);
@ -334,10 +381,10 @@ int secp256k1_ec_pubkey_create(const secp256k1_context_t* ctx, secp256k1_pubkey_
secp256k1_scalar_t sec;
int overflow;
int ret = 0;
DEBUG_CHECK(ctx != NULL);
DEBUG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
DEBUG_CHECK(pubkey != NULL);
DEBUG_CHECK(seckey != NULL);
ARG_CHECK(ctx != NULL);
ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
ARG_CHECK(pubkey != NULL);
ARG_CHECK(seckey != NULL);
secp256k1_scalar_set_b32(&sec, seckey, &overflow);
ret = !overflow & !secp256k1_scalar_is_zero(&sec);
@ -356,9 +403,9 @@ int secp256k1_ec_privkey_tweak_add(const secp256k1_context_t* ctx, unsigned char
secp256k1_scalar_t sec;
int ret = 0;
int overflow = 0;
DEBUG_CHECK(ctx != NULL);
DEBUG_CHECK(seckey != NULL);
DEBUG_CHECK(tweak != NULL);
ARG_CHECK(ctx != NULL);
ARG_CHECK(seckey != NULL);
ARG_CHECK(tweak != NULL);
(void)ctx;
secp256k1_scalar_set_b32(&term, tweak, &overflow);
@ -379,14 +426,13 @@ int secp256k1_ec_pubkey_tweak_add(const secp256k1_context_t* ctx, secp256k1_pubk
secp256k1_scalar_t term;
int ret = 0;
int overflow = 0;
DEBUG_CHECK(ctx != NULL);
DEBUG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx));
DEBUG_CHECK(pubkey != NULL);
DEBUG_CHECK(tweak != NULL);
ARG_CHECK(ctx != NULL);
ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx));
ARG_CHECK(pubkey != NULL);
ARG_CHECK(tweak != NULL);
secp256k1_scalar_set_b32(&term, tweak, &overflow);
secp256k1_pubkey_load(&p, pubkey);
if (!overflow) {
if (!overflow && secp256k1_pubkey_load(ctx, &p, pubkey)) {
ret = secp256k1_eckey_pubkey_tweak_add(&ctx->ecmult_ctx, &p, &term);
if (ret) {
secp256k1_pubkey_save(pubkey, &p);
@ -403,9 +449,9 @@ int secp256k1_ec_privkey_tweak_mul(const secp256k1_context_t* ctx, unsigned char
secp256k1_scalar_t sec;
int ret = 0;
int overflow = 0;
DEBUG_CHECK(ctx != NULL);
DEBUG_CHECK(seckey != NULL);
DEBUG_CHECK(tweak != NULL);
ARG_CHECK(ctx != NULL);
ARG_CHECK(seckey != NULL);
ARG_CHECK(tweak != NULL);
(void)ctx;
secp256k1_scalar_set_b32(&factor, tweak, &overflow);
@ -425,14 +471,13 @@ int secp256k1_ec_pubkey_tweak_mul(const secp256k1_context_t* ctx, secp256k1_pubk
secp256k1_scalar_t factor;
int ret = 0;
int overflow = 0;
DEBUG_CHECK(ctx != NULL);
DEBUG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx));
DEBUG_CHECK(pubkey != NULL);
DEBUG_CHECK(tweak != NULL);
ARG_CHECK(ctx != NULL);
ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx));
ARG_CHECK(pubkey != NULL);
ARG_CHECK(tweak != NULL);
secp256k1_scalar_set_b32(&factor, tweak, &overflow);
secp256k1_pubkey_load(&p, pubkey);
if (!overflow) {
if (!overflow && secp256k1_pubkey_load(ctx, &p, pubkey)) {
ret = secp256k1_eckey_pubkey_tweak_mul(&ctx->ecmult_ctx, &p, &factor);
if (ret) {
secp256k1_pubkey_save(pubkey, &p);
@ -447,11 +492,11 @@ int secp256k1_ec_pubkey_tweak_mul(const secp256k1_context_t* ctx, secp256k1_pubk
int secp256k1_ec_privkey_export(const secp256k1_context_t* ctx, const unsigned char *seckey, unsigned char *privkey, int *privkeylen, int compressed) {
secp256k1_scalar_t key;
int ret = 0;
DEBUG_CHECK(seckey != NULL);
DEBUG_CHECK(privkey != NULL);
DEBUG_CHECK(privkeylen != NULL);
DEBUG_CHECK(ctx != NULL);
DEBUG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
ARG_CHECK(seckey != NULL);
ARG_CHECK(privkey != NULL);
ARG_CHECK(privkeylen != NULL);
ARG_CHECK(ctx != NULL);
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);
@ -462,8 +507,8 @@ int secp256k1_ec_privkey_export(const secp256k1_context_t* ctx, const unsigned c
int secp256k1_ec_privkey_import(const secp256k1_context_t* ctx, unsigned char *seckey, const unsigned char *privkey, int privkeylen) {
secp256k1_scalar_t key;
int ret = 0;
DEBUG_CHECK(seckey != NULL);
DEBUG_CHECK(privkey != NULL);
ARG_CHECK(seckey != NULL);
ARG_CHECK(privkey != NULL);
(void)ctx;
ret = secp256k1_eckey_privkey_parse(&key, privkey, privkeylen);
@ -475,8 +520,8 @@ int secp256k1_ec_privkey_import(const secp256k1_context_t* ctx, unsigned char *s
}
int secp256k1_context_randomize(secp256k1_context_t* ctx, const unsigned char *seed32) {
DEBUG_CHECK(ctx != NULL);
DEBUG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
ARG_CHECK(ctx != NULL);
ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, seed32);
return 1;
}

View File

@ -1160,7 +1160,7 @@ void test_ge(void) {
}
}
secp256k1_ge_set_table_gej_var(4 * runs + 1, ge_set_table, gej, zr);
secp256k1_ge_set_all_gej_var(4 * runs + 1, ge_set_all, gej);
secp256k1_ge_set_all_gej_var(4 * runs + 1, ge_set_all, gej, &ctx->error_callback);
for (i = 0; i < 4 * runs + 1; i++) {
secp256k1_fe_t s;
random_fe_non_zero(&s);
@ -2051,7 +2051,7 @@ void test_ecdsa_edge_cases(void) {
msg[0] = i;
CHECK(secp256k1_ecdsa_sign(ctx, msg, &sig2, key, NULL, extra) == 1);
CHECK(!is_empty_signature(&sig2));
secp256k1_ecdsa_signature_load(&sr[i], &ss, NULL, &sig2);
secp256k1_ecdsa_signature_load(ctx, &sr[i], &ss, NULL, &sig2);
for (j = 0; j < i; j++) {
CHECK(!secp256k1_scalar_eq(&sr[i], &sr[j]));
}
@ -2064,7 +2064,7 @@ void test_ecdsa_edge_cases(void) {
key[0] = i - 256;
CHECK(secp256k1_ecdsa_sign(ctx, msg, &sig2, key, NULL, extra) == 1);
CHECK(!is_empty_signature(&sig2));
secp256k1_ecdsa_signature_load(&sr[i], &ss, NULL, &sig2);
secp256k1_ecdsa_signature_load(ctx, &sr[i], &ss, NULL, &sig2);
for (j = 0; j < i; j++) {
CHECK(!secp256k1_scalar_eq(&sr[i], &sr[j]));
}

View File

@ -15,6 +15,11 @@
#include <stdint.h>
#include <stdio.h>
typedef struct {
void (*fn)(const char *text, void* data);
void* data;
} callback_t;
#ifdef DETERMINISTIC
#define TEST_FAILURE(msg) do { \
fprintf(stderr, "%s\n", msg); \
@ -47,23 +52,18 @@
} while(0)
#endif
/* Like assert(), but safe to use on expressions with side effects. */
#ifndef NDEBUG
#define DEBUG_CHECK CHECK
#else
#define DEBUG_CHECK(cond) do { (void)(cond); } while(0)
#endif
/* Like DEBUG_CHECK(), but when VERIFY is defined instead of NDEBUG not defined. */
/* Like assert(), but when VERIFY is defined, and side-effect safe. */
#ifdef VERIFY
#define VERIFY_CHECK CHECK
#else
#define VERIFY_CHECK(cond) do { (void)(cond); } while(0)
#endif
static SECP256K1_INLINE void *checked_malloc(size_t size) {
static SECP256K1_INLINE void *checked_malloc(const callback_t* cb, size_t size) {
void *ret = malloc(size);
CHECK(ret != NULL);
if (ret == NULL) {
cb->fn("Out of memory", cb->data);
}
return ret;
}