diff --git a/Makefile.am b/Makefile.am index 15e7baa..0e413cb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -46,7 +46,6 @@ noinst_PROGRAMS = if USE_BENCHMARK noinst_PROGRAMS += bench bench_SOURCES = src/bench.c -bench_CPPFLAGS = -DNDEBUG bench_LDADD = libsecp256k1_common.la $(SECP_LIBS) bench_LDFLAGS = -static endif diff --git a/configure.ac b/configure.ac index c6ed81f..d7d88d2 100644 --- a/configure.ac +++ b/configure.ac @@ -144,6 +144,8 @@ if test x"$set_bignum" = x"openssl"; then fi ]) +AC_CHECK_DECL(__builtin_expect,AC_DEFINE(HAVE_BUILTIN_EXPECT,1,[Define this symbol if __builtin_expect is available]),,) + AC_DEFUN([SECP_GMP_CHECK],[ if test x"$has_gmp" != x"yes"; then AC_CHECK_HEADER(gmp.h,[AC_CHECK_LIB(gmp, __gmpz_init,[has_gmp=yes; GMP_LIBS=-lgmp; AC_DEFINE(HAVE_LIBGMP,1,[Define this symbol if libgmp is installed])])]) diff --git a/src/ecmult_impl.h b/src/ecmult_impl.h index 10e8e45..e893add 100644 --- a/src/ecmult_impl.h +++ b/src/ecmult_impl.h @@ -53,9 +53,9 @@ void static secp256k1_ecmult_table_precomp_ge(secp256k1_ge_t *pre, const secp256 /** The following two macro retrieves a particular odd multiple from a table * of precomputed multiples. */ #define ECMULT_TABLE_GET(r,pre,n,w,neg) do { \ - assert(((n) & 1) == 1); \ - assert((n) >= -((1 << ((w)-1)) - 1)); \ - assert((n) <= ((1 << ((w)-1)) - 1)); \ + VERIFY_CHECK(((n) & 1) == 1); \ + VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \ + VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1)); \ if ((n) > 0) \ *(r) = (pre)[((n)-1)/2]; \ else \ @@ -117,7 +117,7 @@ static void secp256k1_ecmult_start(void) { tj[pos++] = gj; } } - assert(pos == 960); + VERIFY_CHECK(pos == 960); tj[pos] = fn; secp256k1_ge_t t[961]; secp256k1_ge_set_all_gej(961, t, tj); pos = 0; @@ -131,7 +131,7 @@ static void secp256k1_ecmult_start(void) { ret->prec[j][k][i] = raw[k]; } } - assert(pos == 960); + VERIFY_CHECK(pos == 960); secp256k1_ge_neg(&ret->fin, &t[pos]); } diff --git a/src/field_10x26_impl.h b/src/field_10x26_impl.h index 4818131..571823f 100644 --- a/src/field_10x26_impl.h +++ b/src/field_10x26_impl.h @@ -8,6 +8,7 @@ #include #include #include +#include "util.h" #include "num.h" #include "field.h" @@ -35,7 +36,7 @@ void static secp256k1_fe_normalize(secp256k1_fe_t *r) { t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; m &= t8; // ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) - assert(t9 >> 23 == 0); + VERIFY_CHECK(t9 >> 23 == 0); // At most a single final reduction is needed; check if the value is >= the field characteristic x = (t9 >> 22) | ((t9 == 0x03FFFFFULL) & (m == 0x3FFFFFFULL) @@ -54,7 +55,7 @@ void static secp256k1_fe_normalize(secp256k1_fe_t *r) { t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; // If t9 didn't carry to bit 22 already, then it should have after any final reduction - assert(t9 >> 22 == x); + VERIFY_CHECK(t9 >> 22 == x); // Mask off the possible multiple of 2^256 from the final reduction t9 &= 0x03FFFFFUL; @@ -80,14 +81,14 @@ void static inline secp256k1_fe_set_int(secp256k1_fe_t *r, int a) { // TODO: not constant time! int static inline secp256k1_fe_is_zero(const secp256k1_fe_t *a) { #ifdef VERIFY - assert(a->normalized); + VERIFY_CHECK(a->normalized); #endif return (a->n[0] == 0 && a->n[1] == 0 && a->n[2] == 0 && a->n[3] == 0 && a->n[4] == 0 && a->n[5] == 0 && a->n[6] == 0 && a->n[7] == 0 && a->n[8] == 0 && a->n[9] == 0); } int static inline secp256k1_fe_is_odd(const secp256k1_fe_t *a) { #ifdef VERIFY - assert(a->normalized); + VERIFY_CHECK(a->normalized); #endif return a->n[0] & 1; } @@ -105,8 +106,8 @@ void static inline secp256k1_fe_clear(secp256k1_fe_t *a) { // TODO: not constant time! int static inline secp256k1_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { #ifdef VERIFY - assert(a->normalized); - assert(b->normalized); + VERIFY_CHECK(a->normalized); + VERIFY_CHECK(b->normalized); #endif return (a->n[0] == b->n[0] && a->n[1] == b->n[1] && a->n[2] == b->n[2] && a->n[3] == b->n[3] && a->n[4] == b->n[4] && a->n[5] == b->n[5] && a->n[6] == b->n[6] && a->n[7] == b->n[7] && a->n[8] == b->n[8] && a->n[9] == b->n[9]); @@ -131,7 +132,7 @@ void static secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) { /** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */ void static secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe_t *a) { #ifdef VERIFY - assert(a->normalized); + VERIFY_CHECK(a->normalized); #endif for (int i=0; i<32; i++) { int c = 0; @@ -146,7 +147,7 @@ void static secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe_t *a) { void static inline secp256k1_fe_negate(secp256k1_fe_t *r, const secp256k1_fe_t *a, int m) { #ifdef VERIFY - assert(a->magnitude <= m); + VERIFY_CHECK(a->magnitude <= m); r->magnitude = m + 1; r->normalized = 0; #endif @@ -452,8 +453,8 @@ void static inline secp256k1_fe_sqr_inner(const uint32_t *a, uint32_t *r) { void static secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const secp256k1_fe_t *b) { #ifdef VERIFY - assert(a->magnitude <= 8); - assert(b->magnitude <= 8); + VERIFY_CHECK(a->magnitude <= 8); + VERIFY_CHECK(b->magnitude <= 8); r->magnitude = 1; r->normalized = 0; #endif @@ -462,7 +463,7 @@ void static secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const s void static secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) { #ifdef VERIFY - assert(a->magnitude <= 8); + VERIFY_CHECK(a->magnitude <= 8); r->magnitude = 1; r->normalized = 0; #endif diff --git a/src/field_5x52_impl.h b/src/field_5x52_impl.h index b2c924a..8f6753f 100644 --- a/src/field_5x52_impl.h +++ b/src/field_5x52_impl.h @@ -11,6 +11,7 @@ #include #include +#include "util.h" #include "num.h" #include "field.h" @@ -48,7 +49,7 @@ void static secp256k1_fe_verify(const secp256k1_fe_t *a) { r &= (d[0] < 0xFFFFEFFFFFC2FULL); } } - assert(r == 1); + VERIFY_CHECK(r == 1); } #else void static secp256k1_fe_verify(const secp256k1_fe_t *a) {} @@ -69,7 +70,7 @@ void static secp256k1_fe_normalize(secp256k1_fe_t *r) { t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; m &= t3; // ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) - assert(t4 >> 49 == 0); + VERIFY_CHECK(t4 >> 49 == 0); // At most a single final reduction is needed; check if the value is >= the field characteristic x = (t4 >> 48) | ((t4 == 0x0FFFFFFFFFFFFULL) & (m == 0xFFFFFFFFFFFFFULL) @@ -83,7 +84,7 @@ void static secp256k1_fe_normalize(secp256k1_fe_t *r) { t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; // If t4 didn't carry to bit 48 already, then it should have after any final reduction - assert(t4 >> 48 == x); + VERIFY_CHECK(t4 >> 48 == x); // Mask off the possible multiple of 2^256 from the final reduction t4 &= 0x0FFFFFFFFFFFFULL; @@ -110,7 +111,7 @@ void static inline secp256k1_fe_set_int(secp256k1_fe_t *r, int a) { // TODO: not constant time! int static inline secp256k1_fe_is_zero(const secp256k1_fe_t *a) { #ifdef VERIFY - assert(a->normalized); + VERIFY_CHECK(a->normalized); secp256k1_fe_verify(a); #endif return (a->n[0] == 0 && a->n[1] == 0 && a->n[2] == 0 && a->n[3] == 0 && a->n[4] == 0); @@ -118,7 +119,7 @@ int static inline secp256k1_fe_is_zero(const secp256k1_fe_t *a) { int static inline secp256k1_fe_is_odd(const secp256k1_fe_t *a) { #ifdef VERIFY - assert(a->normalized); + VERIFY_CHECK(a->normalized); secp256k1_fe_verify(a); #endif return a->n[0] & 1; @@ -137,8 +138,8 @@ void static inline secp256k1_fe_clear(secp256k1_fe_t *a) { // TODO: not constant time! int static inline secp256k1_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { #ifdef VERIFY - assert(a->normalized); - assert(b->normalized); + VERIFY_CHECK(a->normalized); + VERIFY_CHECK(b->normalized); secp256k1_fe_verify(a); secp256k1_fe_verify(b); #endif @@ -164,7 +165,7 @@ void static secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) { /** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */ void static secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe_t *a) { #ifdef VERIFY - assert(a->normalized); + VERIFY_CHECK(a->normalized); secp256k1_fe_verify(a); #endif for (int i=0; i<32; i++) { @@ -180,7 +181,7 @@ void static secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe_t *a) { void static inline secp256k1_fe_negate(secp256k1_fe_t *r, const secp256k1_fe_t *a, int m) { #ifdef VERIFY - assert(a->magnitude <= m); + VERIFY_CHECK(a->magnitude <= m); secp256k1_fe_verify(a); #endif r->n[0] = 0xFFFFEFFFFFC2FULL * (m + 1) - a->n[0]; @@ -224,8 +225,8 @@ void static inline secp256k1_fe_add(secp256k1_fe_t *r, const secp256k1_fe_t *a) void static secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const secp256k1_fe_t *b) { #ifdef VERIFY - assert(a->magnitude <= 8); - assert(b->magnitude <= 8); + VERIFY_CHECK(a->magnitude <= 8); + VERIFY_CHECK(b->magnitude <= 8); secp256k1_fe_verify(a); secp256k1_fe_verify(b); #endif @@ -239,7 +240,7 @@ void static secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const s void static secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) { #ifdef VERIFY - assert(a->magnitude <= 8); + VERIFY_CHECK(a->magnitude <= 8); #endif secp256k1_fe_sqr_inner(a->n, r->n); #ifdef VERIFY diff --git a/src/field_impl.h b/src/field_impl.h index 43287d5..8360b6f 100644 --- a/src/field_impl.h +++ b/src/field_impl.h @@ -9,6 +9,8 @@ #include "libsecp256k1-config.h" #endif +#include "util.h" + #if defined(USE_FIELD_GMP) #include "field_gmp_impl.h" #elif defined(USE_FIELD_10X26) @@ -218,7 +220,7 @@ void static secp256k1_fe_inv_all(size_t len, secp256k1_fe_t r[len], const secp25 if (len < 1) return; - assert((r + len <= a) || (a + len <= r)); + VERIFY_CHECK((r + len <= a) || (a + len <= r)); r[0] = a[0]; @@ -242,7 +244,7 @@ void static secp256k1_fe_inv_all_var(size_t len, secp256k1_fe_t r[len], const se if (len < 1) return; - assert((r + len <= a) || (a + len <= r)); + VERIFY_CHECK((r + len <= a) || (a + len <= r)); r[0] = a[0]; diff --git a/src/num_gmp_impl.h b/src/num_gmp_impl.h index 6da535a..4bf3af1 100644 --- a/src/num_gmp_impl.h +++ b/src/num_gmp_impl.h @@ -10,11 +10,12 @@ #include #include +#include "util.h" #include "num.h" #ifdef VERIFY void static secp256k1_num_sanity(const secp256k1_num_t *a) { - assert(a->limbs == 1 || (a->limbs > 1 && a->data[a->limbs-1] != 0)); + VERIFY_CHECK(a->limbs == 1 || (a->limbs > 1 && a->data[a->limbs-1] != 0)); } #else #define secp256k1_num_sanity(a) do { } while(0) @@ -56,7 +57,7 @@ void static secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const sec } int shift = 0; while (shift < len && tmp[shift] == 0) shift++; - assert(len-shift <= rlen); + VERIFY_CHECK(len-shift <= rlen); memset(r, 0, rlen - len + shift); if (len > shift) { memcpy(r + rlen - len + shift, tmp + shift, len - shift); @@ -65,10 +66,10 @@ void static secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const sec } void static secp256k1_num_set_bin(secp256k1_num_t *r, const unsigned char *a, unsigned int alen) { - assert(alen > 0); - assert(alen <= 64); + VERIFY_CHECK(alen > 0); + VERIFY_CHECK(alen <= 64); int len = mpn_set_str(r->data, a, alen, 256); - assert(len <= NUM_LIMBS*2); + VERIFY_CHECK(len <= NUM_LIMBS*2); r->limbs = len; r->neg = 0; while (r->limbs > 1 && r->data[r->limbs-1]==0) r->limbs--; @@ -84,14 +85,14 @@ void static secp256k1_num_add_abs(secp256k1_num_t *r, const secp256k1_num_t *a, mp_limb_t c = mpn_add(r->data, a->data, a->limbs, b->data, b->limbs); r->limbs = a->limbs; if (c != 0) { - assert(r->limbs < 2*NUM_LIMBS); + VERIFY_CHECK(r->limbs < 2*NUM_LIMBS); r->data[r->limbs++] = c; } } void static secp256k1_num_sub_abs(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) { mp_limb_t c = mpn_sub(r->data, a->data, a->limbs, b->data, b->limbs); - assert(c == 0); + VERIFY_CHECK(c == 0); r->limbs = a->limbs; while (r->limbs > 1 && r->data[r->limbs-1]==0) r->limbs--; } @@ -127,8 +128,8 @@ void static secp256k1_num_mod_inverse(secp256k1_num_t *r, const secp256k1_num_t // G = a*S mod m // Assuming G=1: // S = 1/a mod m - assert(m->limbs <= NUM_LIMBS); - assert(m->data[m->limbs-1] != 0); + VERIFY_CHECK(m->limbs <= NUM_LIMBS); + VERIFY_CHECK(m->data[m->limbs-1] != 0); mp_limb_t g[NUM_LIMBS+1]; mp_limb_t u[NUM_LIMBS+1]; mp_limb_t v[NUM_LIMBS+1]; @@ -138,8 +139,8 @@ void static secp256k1_num_mod_inverse(secp256k1_num_t *r, const secp256k1_num_t } mp_size_t sn = NUM_LIMBS+1; mp_size_t gn = mpn_gcdext(g, r->data, &sn, u, m->limbs, v, m->limbs); - assert(gn == 1); - assert(g[0] == 1); + VERIFY_CHECK(gn == 1); + VERIFY_CHECK(g[0] == 1); r->neg = a->neg ^ m->neg; if (sn < 0) { mpn_sub(r->data, m->data, m->limbs, r->data, -sn); @@ -214,7 +215,7 @@ void static secp256k1_num_mul(secp256k1_num_t *r, const secp256k1_num_t *a, cons secp256k1_num_sanity(b); mp_limb_t tmp[2*NUM_LIMBS+1]; - assert(a->limbs + b->limbs <= 2*NUM_LIMBS+1); + VERIFY_CHECK(a->limbs + b->limbs <= 2*NUM_LIMBS+1); if ((a->limbs==1 && a->data[0]==0) || (b->limbs==1 && b->data[0]==0)) { r->limbs = 1; r->neg = 0; @@ -227,7 +228,7 @@ void static secp256k1_num_mul(secp256k1_num_t *r, const secp256k1_num_t *a, cons mpn_mul(tmp, b->data, b->limbs, a->data, a->limbs); r->limbs = a->limbs + b->limbs; if (r->limbs > 1 && tmp[r->limbs - 1]==0) r->limbs--; - assert(r->limbs <= 2*NUM_LIMBS); + VERIFY_CHECK(r->limbs <= 2*NUM_LIMBS); mpn_copyi(r->data, tmp, r->limbs); r->neg = a->neg ^ b->neg; memset(tmp, 0, sizeof(tmp)); @@ -259,7 +260,7 @@ void static secp256k1_num_mod_mul(secp256k1_num_t *r, const secp256k1_num_t *a, int static secp256k1_num_shift(secp256k1_num_t *r, int bits) { - assert(bits <= GMP_NUMB_BITS); + VERIFY_CHECK(bits <= GMP_NUMB_BITS); mp_limb_t ret = mpn_rshift(r->data, r->data, r->limbs, bits); if (r->limbs>1 && r->data[r->limbs-1]==0) r->limbs--; ret >>= (GMP_NUMB_BITS - bits); @@ -273,7 +274,7 @@ int static secp256k1_num_get_bit(const secp256k1_num_t *a, int pos) { void static secp256k1_num_inc(secp256k1_num_t *r) { mp_limb_t ret = mpn_add_1(r->data, r->data, r->limbs, (mp_limb_t)1); if (ret) { - assert(r->limbs < 2*NUM_LIMBS); + VERIFY_CHECK(r->limbs < 2*NUM_LIMBS); r->data[r->limbs++] = ret; } } @@ -309,24 +310,24 @@ void static secp256k1_num_get_hex(char *r, int rlen, const secp256k1_num_t *a) { static const unsigned char cvt[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; unsigned char *tmp = malloc(257); mp_size_t len = mpn_get_str(tmp, 16, (mp_limb_t*)a->data, a->limbs); - assert(len <= rlen); + VERIFY_CHECK(len <= rlen); for (int i=0; i= 0); - assert(rlen-len+i < rlen); - assert(tmp[i] >= 0); - assert(tmp[i] < 16); + VERIFY_CHECK(rlen-len+i >= 0); + VERIFY_CHECK(rlen-len+i < rlen); + VERIFY_CHECK(tmp[i] >= 0); + VERIFY_CHECK(tmp[i] < 16); r[rlen-len+i] = cvt[tmp[i]]; } for (int i=0; i= 0); - assert(i < rlen); + VERIFY_CHECK(i >= 0); + VERIFY_CHECK(i < rlen); r[i] = cvt[0]; } free(tmp); } void static secp256k1_num_split(secp256k1_num_t *rl, secp256k1_num_t *rh, const secp256k1_num_t *a, int bits) { - assert(bits > 0); + VERIFY_CHECK(bits > 0); rh->neg = a->neg; if (bits >= a->limbs * GMP_NUMB_BITS) { *rl = *a; diff --git a/src/num_openssl_impl.h b/src/num_openssl_impl.h index 1a69730..ba98c0e 100644 --- a/src/num_openssl_impl.h +++ b/src/num_openssl_impl.h @@ -11,6 +11,7 @@ #include #include +#include "util.h" #include "num.h" void static secp256k1_num_init(secp256k1_num_t *r) { @@ -31,7 +32,7 @@ void static secp256k1_num_copy(secp256k1_num_t *r, const secp256k1_num_t *a) { void static secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num_t *a) { unsigned int size = BN_num_bytes(&a->bn); - assert(size <= rlen); + VERIFY_CHECK(size <= rlen); memset(r,0,rlen); BN_bn2bin(&a->bn, r + rlen - size); } @@ -133,7 +134,7 @@ void static secp256k1_num_set_hex(secp256k1_num_t *r, const char *a, int alen) { void static secp256k1_num_get_hex(char *r, int rlen, const secp256k1_num_t *a) { char *str = BN_bn2hex(&a->bn); int len = strlen(str); - assert(rlen >= len); + VERIFY_CHECK(rlen >= len); for (int i=0; i +#include "util.h" #include "num_impl.h" #include "field_impl.h" #include "group_impl.h" @@ -22,6 +23,11 @@ void secp256k1_stop(void) { } int secp256k1_ecdsa_verify(const unsigned char *msg, int msglen, const unsigned char *sig, int siglen, const unsigned char *pubkey, int pubkeylen) { + DEBUG_CHECK(msg != NULL); + DEBUG_CHECK(msglen <= 32); + DEBUG_CHECK(sig != NULL); + DEBUG_CHECK(pubkey != NULL); + int ret = -3; secp256k1_num_t m; secp256k1_num_init(&m); @@ -50,6 +56,13 @@ end: } int secp256k1_ecdsa_sign(const unsigned char *message, int messagelen, unsigned char *signature, int *signaturelen, const unsigned char *seckey, const unsigned char *nonce) { + DEBUG_CHECK(message != NULL); + DEBUG_CHECK(messagelen <= 32); + DEBUG_CHECK(signature != NULL); + DEBUG_CHECK(signaturelen != NULL); + DEBUG_CHECK(seckey != NULL); + DEBUG_CHECK(nonce != NULL); + secp256k1_num_t sec, non, msg; secp256k1_num_init(&sec); secp256k1_num_init(&non); @@ -78,6 +91,12 @@ int secp256k1_ecdsa_sign(const unsigned char *message, int messagelen, unsigned } int secp256k1_ecdsa_sign_compact(const unsigned char *message, int messagelen, unsigned char *sig64, const unsigned char *seckey, const unsigned char *nonce, int *recid) { + DEBUG_CHECK(message != NULL); + DEBUG_CHECK(messagelen <= 32); + DEBUG_CHECK(sig64 != NULL); + DEBUG_CHECK(seckey != NULL); + DEBUG_CHECK(nonce != NULL); + secp256k1_num_t sec, non, msg; secp256k1_num_init(&sec); secp256k1_num_init(&non); @@ -107,6 +126,13 @@ int secp256k1_ecdsa_sign_compact(const unsigned char *message, int messagelen, u } int secp256k1_ecdsa_recover_compact(const unsigned char *msg, int msglen, const unsigned char *sig64, unsigned char *pubkey, int *pubkeylen, int compressed, int recid) { + DEBUG_CHECK(msg != NULL); + DEBUG_CHECK(msglen <= 32); + DEBUG_CHECK(sig64 != NULL); + DEBUG_CHECK(pubkey != NULL); + DEBUG_CHECK(pubkeylen != NULL); + DEBUG_CHECK(recid >= 0 && recid <= 3); + int ret = 0; secp256k1_num_t m; secp256k1_num_init(&m); @@ -127,6 +153,8 @@ int secp256k1_ecdsa_recover_compact(const unsigned char *msg, int msglen, const } int secp256k1_ecdsa_seckey_verify(const unsigned char *seckey) { + DEBUG_CHECK(seckey != NULL); + secp256k1_num_t sec; secp256k1_num_init(&sec); secp256k1_num_set_bin(&sec, seckey, 32); @@ -138,11 +166,17 @@ int secp256k1_ecdsa_seckey_verify(const unsigned char *seckey) { } int secp256k1_ecdsa_pubkey_verify(const unsigned char *pubkey, int pubkeylen) { + DEBUG_CHECK(pubkey != NULL); + secp256k1_ge_t q; return secp256k1_ecdsa_pubkey_parse(&q, pubkey, pubkeylen); } int secp256k1_ecdsa_pubkey_create(unsigned char *pubkey, int *pubkeylen, const unsigned char *seckey, int compressed) { + DEBUG_CHECK(pubkey != NULL); + DEBUG_CHECK(pubkeylen != NULL); + DEBUG_CHECK(seckey != NULL); + secp256k1_num_t sec; secp256k1_num_init(&sec); secp256k1_num_set_bin(&sec, seckey, 32); @@ -157,6 +191,9 @@ int secp256k1_ecdsa_pubkey_create(unsigned char *pubkey, int *pubkeylen, const u } int secp256k1_ecdsa_pubkey_decompress(unsigned char *pubkey, int *pubkeylen) { + DEBUG_CHECK(pubkey != NULL); + DEBUG_CHECK(pubkeylen != NULL); + secp256k1_ge_t p; if (!secp256k1_ecdsa_pubkey_parse(&p, pubkey, *pubkeylen)) return 0; @@ -165,6 +202,9 @@ int secp256k1_ecdsa_pubkey_decompress(unsigned char *pubkey, int *pubkeylen) { } int secp256k1_ecdsa_privkey_tweak_add(unsigned char *seckey, const unsigned char *tweak) { + DEBUG_CHECK(seckey != NULL); + DEBUG_CHECK(tweak != NULL); + int ret = 1; secp256k1_num_t term; secp256k1_num_init(&term); @@ -190,6 +230,9 @@ int secp256k1_ecdsa_privkey_tweak_add(unsigned char *seckey, const unsigned char } int secp256k1_ecdsa_pubkey_tweak_add(unsigned char *pubkey, int pubkeylen, const unsigned char *tweak) { + DEBUG_CHECK(pubkey != NULL); + DEBUG_CHECK(tweak != NULL); + int ret = 1; secp256k1_num_t term; secp256k1_num_init(&term); @@ -210,13 +253,16 @@ int secp256k1_ecdsa_pubkey_tweak_add(unsigned char *pubkey, int pubkeylen, const secp256k1_ge_set_gej(&p, &pt); int oldlen = pubkeylen; secp256k1_ecdsa_pubkey_serialize(&p, pubkey, &pubkeylen, oldlen <= 33); - assert(pubkeylen == oldlen); + VERIFY_CHECK(pubkeylen == oldlen); } secp256k1_num_free(&term); return ret; } int secp256k1_ecdsa_privkey_tweak_mul(unsigned char *seckey, const unsigned char *tweak) { + DEBUG_CHECK(seckey != NULL); + DEBUG_CHECK(tweak != NULL); + int ret = 1; secp256k1_num_t factor; secp256k1_num_init(&factor); @@ -239,6 +285,9 @@ int secp256k1_ecdsa_privkey_tweak_mul(unsigned char *seckey, const unsigned char } int secp256k1_ecdsa_pubkey_tweak_mul(unsigned char *pubkey, int pubkeylen, const unsigned char *tweak) { + DEBUG_CHECK(pubkey != NULL); + DEBUG_CHECK(tweak != NULL); + int ret = 1; secp256k1_num_t factor; secp256k1_num_init(&factor); @@ -263,13 +312,17 @@ int secp256k1_ecdsa_pubkey_tweak_mul(unsigned char *pubkey, int pubkeylen, const secp256k1_ge_set_gej(&p, &pt); int oldlen = pubkeylen; secp256k1_ecdsa_pubkey_serialize(&p, pubkey, &pubkeylen, oldlen <= 33); - assert(pubkeylen == oldlen); + VERIFY_CHECK(pubkeylen == oldlen); } secp256k1_num_free(&factor); return ret; } int secp256k1_ecdsa_privkey_export(const unsigned char *seckey, unsigned char *privkey, int *privkeylen, int compressed) { + DEBUG_CHECK(seckey != NULL); + DEBUG_CHECK(privkey != NULL); + DEBUG_CHECK(privkeylen != NULL); + secp256k1_num_t key; secp256k1_num_init(&key); secp256k1_num_set_bin(&key, seckey, 32); @@ -279,6 +332,9 @@ int secp256k1_ecdsa_privkey_export(const unsigned char *seckey, unsigned char *p } int secp256k1_ecdsa_privkey_import(unsigned char *seckey, const unsigned char *privkey, int privkeylen) { + DEBUG_CHECK(seckey != NULL); + DEBUG_CHECK(privkey != NULL); + secp256k1_num_t key; secp256k1_num_init(&key); int ret = secp256k1_ecdsa_privkey_parse(&key, privkey, privkeylen); diff --git a/src/tests.c b/src/tests.c index 5827eae..b8f3c08 100644 --- a/src/tests.c +++ b/src/tests.c @@ -19,13 +19,6 @@ #include "openssl/obj_mac.h" #endif -#define TEST_FAILURE(msg) do { \ - fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, msg); \ - abort(); \ -} while(0) - -#define CHECK(cond) do { if (!(cond)) { TEST_FAILURE("test condition failed: " #cond); } } while(0) - static int count = 100; /***** NUM TESTS *****/ diff --git a/src/util.h b/src/util.h index d047b0f..1228895 100644 --- a/src/util.h +++ b/src/util.h @@ -5,6 +5,44 @@ #ifndef _SECP256K1_UTIL_H_ #define _SECP256K1_UTIL_H_ +#if defined HAVE_CONFIG_H +#include "libsecp256k1-config.h" +#endif + +#include +#include + +#define TEST_FAILURE(msg) do { \ + fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, msg); \ + abort(); \ +} while(0) + +#ifndef HAVE_BUILTIN_EXPECT +#define EXPECT(x,c) __builtin_expect((x),(c)) +#else +#define EXPECT(x,c) (x) +#endif + +#define CHECK(cond) do { \ + if (EXPECT(!(cond), 0)) { \ + TEST_FAILURE("test condition failed: " #cond); \ + } \ +} while(0) + +// Like assert(), but safe to use on expressions with side effects. +#ifndef NDEBUG +#define DEBUG_CHECK CHECK +#else +#define DEBUG_CHECK(cond) do { (cond); } while(0) +#endif + +// Like DEBUG_CHECK(), but when VERIFY is defined instead of NDEBUG not defined. +#ifdef VERIFY +#define VERIFY_CHECK CHECK +#else +#define VERIFY_CHECK(cond) do { (cond); } while(0) +#endif + /** Generate a pseudorandom 32-bit number. */ static uint32_t secp256k1_rand32(void);