Merge commits with sync-upstream.sh

da0092bc 10f9bd84 297ce820 f34b5cae 920a0e5f 9526874d aa1b889b 20d791ed 3e7b2ea1 21c188b3 8fa41201 515a5dbd c74a7b7e 74c34e72 7006f1b9 ea5e8a9c 793ad901 2e5e4b67 fecf436d 49f608de 49002274 6ad908aa 4f01840b 61ae37c6 486205aa 5d0dbef0 0559fc6e be6944ad a69df3ad b39d431a 0b83b203 09971a3f 9281c9f4 423b6d19 a310e79e 39a36db9 a1102b12

Deal with
  - secp256k1_test_rng removal in commit
    77a19750b4
  - ecmult_gen context simplification after making table static in commit
    3b0c2185ea
This commit is contained in:
Jonas Nick
2022-01-01 21:59:25 +00:00
69 changed files with 11594 additions and 1919 deletions

View File

@@ -20,16 +20,6 @@
#include "testrand_impl.h"
#include "util.h"
#ifdef ENABLE_OPENSSL_TESTS
#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/ecdsa.h>
#include <openssl/obj_mac.h>
# if OPENSSL_VERSION_NUMBER < 0x10100000L
void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) {*pr = sig->r; *ps = sig->s;}
# endif
#endif
#include "../contrib/lax_der_parsing.c"
#include "../contrib/lax_der_privatekey_parsing.c"
@@ -110,6 +100,12 @@ void random_group_element_jacobian_test(secp256k1_gej *gej, const secp256k1_ge *
gej->infinity = ge->infinity;
}
void random_gej_test(secp256k1_gej *gej) {
secp256k1_ge ge;
random_group_element_test(&ge);
random_group_element_jacobian_test(gej, &ge);
}
void random_scalar_order_test(secp256k1_scalar *num) {
do {
unsigned char b32[32];
@@ -199,10 +195,12 @@ void run_context_tests(int use_prealloc) {
secp256k1_context *sign;
secp256k1_context *vrfy;
secp256k1_context *both;
secp256k1_context *sttc;
void *none_prealloc = NULL;
void *sign_prealloc = NULL;
void *vrfy_prealloc = NULL;
void *both_prealloc = NULL;
void *sttc_prealloc = NULL;
secp256k1_gej pubj;
secp256k1_ge pub;
@@ -214,26 +212,30 @@ void run_context_tests(int use_prealloc) {
sign_prealloc = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_SIGN));
vrfy_prealloc = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_VERIFY));
both_prealloc = malloc(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY));
sttc_prealloc = malloc(secp256k1_context_preallocated_clone_size(secp256k1_context_no_precomp));
CHECK(none_prealloc != NULL);
CHECK(sign_prealloc != NULL);
CHECK(vrfy_prealloc != NULL);
CHECK(both_prealloc != NULL);
CHECK(sttc_prealloc != NULL);
none = secp256k1_context_preallocated_create(none_prealloc, SECP256K1_CONTEXT_NONE);
sign = secp256k1_context_preallocated_create(sign_prealloc, SECP256K1_CONTEXT_SIGN);
vrfy = secp256k1_context_preallocated_create(vrfy_prealloc, SECP256K1_CONTEXT_VERIFY);
both = secp256k1_context_preallocated_create(both_prealloc, SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
sttc = secp256k1_context_preallocated_clone(secp256k1_context_no_precomp, sttc_prealloc);
} else {
none = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
vrfy = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
both = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
sttc = secp256k1_context_clone(secp256k1_context_no_precomp);
}
memset(&zero_pubkey, 0, sizeof(zero_pubkey));
ecount = 0;
ecount2 = 10;
secp256k1_context_set_illegal_callback(vrfy, counting_illegal_callback_fn, &ecount);
secp256k1_context_set_illegal_callback(sttc, counting_illegal_callback_fn, &ecount);
secp256k1_context_set_illegal_callback(sign, counting_illegal_callback_fn, &ecount2);
/* set error callback (to a function that still aborts in case malloc() fails in secp256k1_context_clone() below) */
secp256k1_context_set_error_callback(sign, secp256k1_default_illegal_callback_fn, NULL);
@@ -245,6 +247,7 @@ void run_context_tests(int use_prealloc) {
CHECK(secp256k1_context_preallocated_clone_size(sign) == secp256k1_context_preallocated_size(SECP256K1_CONTEXT_SIGN));
CHECK(secp256k1_context_preallocated_clone_size(vrfy) == secp256k1_context_preallocated_size(SECP256K1_CONTEXT_VERIFY));
CHECK(secp256k1_context_preallocated_clone_size(both) == secp256k1_context_preallocated_size(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY));
CHECK(secp256k1_context_preallocated_clone_size(sttc) >= sizeof(secp256k1_context));
/*** clone and destroy all of them to make sure cloning was complete ***/
{
@@ -308,12 +311,12 @@ void run_context_tests(int use_prealloc) {
/* Verify context-type checking illegal-argument errors. */
memset(ctmp, 1, 32);
CHECK(secp256k1_ec_pubkey_create(vrfy, &pubkey, ctmp) == 0);
CHECK(secp256k1_ec_pubkey_create(sttc, &pubkey, ctmp) == 0);
CHECK(ecount == 1);
VG_UNDEF(&pubkey, sizeof(pubkey));
CHECK(secp256k1_ec_pubkey_create(sign, &pubkey, ctmp) == 1);
VG_CHECK(&pubkey, sizeof(pubkey));
CHECK(secp256k1_ecdsa_sign(vrfy, &sig, ctmp, ctmp, NULL, NULL) == 0);
CHECK(secp256k1_ecdsa_sign(sttc, &sig, ctmp, ctmp, NULL, NULL) == 0);
CHECK(ecount == 2);
VG_UNDEF(&sig, sizeof(sig));
CHECK(secp256k1_ecdsa_sign(sign, &sig, ctmp, ctmp, NULL, NULL) == 1);
@@ -321,33 +324,33 @@ void run_context_tests(int use_prealloc) {
CHECK(ecount2 == 10);
CHECK(secp256k1_ecdsa_verify(sign, &sig, ctmp, &pubkey) == 1);
CHECK(ecount2 == 10);
CHECK(secp256k1_ecdsa_verify(vrfy, &sig, ctmp, &pubkey) == 1);
CHECK(secp256k1_ecdsa_verify(sttc, &sig, ctmp, &pubkey) == 1);
CHECK(ecount == 2);
CHECK(secp256k1_ec_pubkey_tweak_add(sign, &pubkey, ctmp) == 1);
CHECK(ecount2 == 10);
CHECK(secp256k1_ec_pubkey_tweak_add(vrfy, &pubkey, ctmp) == 1);
CHECK(secp256k1_ec_pubkey_tweak_add(sttc, &pubkey, ctmp) == 1);
CHECK(ecount == 2);
CHECK(secp256k1_ec_pubkey_tweak_mul(sign, &pubkey, ctmp) == 1);
CHECK(ecount2 == 10);
CHECK(secp256k1_ec_pubkey_negate(vrfy, &pubkey) == 1);
CHECK(secp256k1_ec_pubkey_negate(sttc, &pubkey) == 1);
CHECK(ecount == 2);
CHECK(secp256k1_ec_pubkey_negate(sign, &pubkey) == 1);
CHECK(ecount == 2);
CHECK(secp256k1_ec_pubkey_negate(sign, NULL) == 0);
CHECK(ecount2 == 11);
CHECK(secp256k1_ec_pubkey_negate(vrfy, &zero_pubkey) == 0);
CHECK(secp256k1_ec_pubkey_negate(sttc, &zero_pubkey) == 0);
CHECK(ecount == 3);
CHECK(secp256k1_ec_pubkey_tweak_mul(vrfy, &pubkey, ctmp) == 1);
CHECK(secp256k1_ec_pubkey_tweak_mul(sttc, &pubkey, ctmp) == 1);
CHECK(ecount == 3);
CHECK(secp256k1_context_randomize(vrfy, ctmp) == 1);
CHECK(secp256k1_context_randomize(sttc, ctmp) == 1);
CHECK(ecount == 3);
CHECK(secp256k1_context_randomize(vrfy, NULL) == 1);
CHECK(secp256k1_context_randomize(sttc, NULL) == 1);
CHECK(ecount == 3);
CHECK(secp256k1_context_randomize(sign, ctmp) == 1);
CHECK(ecount2 == 11);
CHECK(secp256k1_context_randomize(sign, NULL) == 1);
CHECK(ecount2 == 11);
secp256k1_context_set_illegal_callback(vrfy, NULL, NULL);
secp256k1_context_set_illegal_callback(sttc, NULL, NULL);
secp256k1_context_set_illegal_callback(sign, NULL, NULL);
/* obtain a working nonce */
@@ -369,15 +372,18 @@ void run_context_tests(int use_prealloc) {
secp256k1_context_preallocated_destroy(sign);
secp256k1_context_preallocated_destroy(vrfy);
secp256k1_context_preallocated_destroy(both);
secp256k1_context_preallocated_destroy(sttc);
free(none_prealloc);
free(sign_prealloc);
free(vrfy_prealloc);
free(both_prealloc);
free(sttc_prealloc);
} else {
secp256k1_context_destroy(none);
secp256k1_context_destroy(sign);
secp256k1_context_destroy(vrfy);
secp256k1_context_destroy(both);
secp256k1_context_destroy(sttc);
}
/* Defined as no-op. */
secp256k1_context_destroy(NULL);
@@ -836,7 +842,7 @@ void signed30_to_uint16(uint16_t* out, const secp256k1_modinv32_signed30* in) {
void mutate_sign_signed30(secp256k1_modinv32_signed30* x) {
int i;
for (i = 0; i < 16; ++i) {
int pos = secp256k1_testrand_int(8);
int pos = secp256k1_testrand_bits(3);
if (x->v[pos] > 0 && x->v[pos + 1] <= 0x3fffffff) {
x->v[pos] -= 0x40000000;
x->v[pos + 1] += 1;
@@ -908,7 +914,7 @@ void mutate_sign_signed62(secp256k1_modinv64_signed62* x) {
static const int64_t M62 = (int64_t)(UINT64_MAX >> 2);
int i;
for (i = 0; i < 8; ++i) {
int pos = secp256k1_testrand_int(4);
int pos = secp256k1_testrand_bits(2);
if (x->v[pos] > 0 && x->v[pos + 1] <= M62) {
x->v[pos] -= (M62 + 1);
x->v[pos + 1] += 1;
@@ -2607,13 +2613,16 @@ void run_field_convert(void) {
CHECK(secp256k1_memcmp_var(&fes2, &fes, sizeof(fes)) == 0);
}
int fe_secp256k1_memcmp_var(const secp256k1_fe *a, const secp256k1_fe *b) {
secp256k1_fe t = *b;
/* Returns true if two field elements have the same representation. */
int fe_identical(const secp256k1_fe *a, const secp256k1_fe *b) {
int ret = 1;
#ifdef VERIFY
t.magnitude = a->magnitude;
t.normalized = a->normalized;
ret &= (a->magnitude == b->magnitude);
ret &= (a->normalized == b->normalized);
#endif
return secp256k1_memcmp_var(a, &t, sizeof(secp256k1_fe));
/* Compare the struct member that holds the limbs. */
ret &= (secp256k1_memcmp_var(a->n, b->n, sizeof(a->n)) == 0);
return ret;
}
void run_field_misc(void) {
@@ -2639,13 +2648,13 @@ void run_field_misc(void) {
CHECK(x.normalized && x.magnitude == 1);
#endif
secp256k1_fe_cmov(&x, &x, 1);
CHECK(fe_secp256k1_memcmp_var(&x, &z) != 0);
CHECK(fe_secp256k1_memcmp_var(&x, &q) == 0);
CHECK(!fe_identical(&x, &z));
CHECK(fe_identical(&x, &q));
secp256k1_fe_cmov(&q, &z, 1);
#ifdef VERIFY
CHECK(!q.normalized && q.magnitude == z.magnitude);
#endif
CHECK(fe_secp256k1_memcmp_var(&q, &z) == 0);
CHECK(fe_identical(&q, &z));
secp256k1_fe_normalize_var(&x);
secp256k1_fe_normalize_var(&z);
CHECK(!secp256k1_fe_equal_var(&x, &z));
@@ -3391,7 +3400,7 @@ void test_intialized_inf(void) {
secp256k1_gej pj, npj, infj1, infj2, infj3;
secp256k1_fe zinv;
/* Test that adding P+(-P) results in a fully initalized infinity*/
/* Test that adding P+(-P) results in a fully initialized infinity*/
random_group_element_test(&p);
secp256k1_gej_set_ge(&pj, &p);
secp256k1_gej_neg(&npj, &pj);
@@ -3494,6 +3503,37 @@ void run_ge(void) {
test_intialized_inf();
}
void test_gej_cmov(const secp256k1_gej *a, const secp256k1_gej *b) {
secp256k1_gej t = *a;
secp256k1_gej_cmov(&t, b, 0);
CHECK(gej_xyz_equals_gej(&t, a));
secp256k1_gej_cmov(&t, b, 1);
CHECK(gej_xyz_equals_gej(&t, b));
}
void run_gej(void) {
int i;
secp256k1_gej a, b;
/* Tests for secp256k1_gej_cmov */
for (i = 0; i < count; i++) {
secp256k1_gej_set_infinity(&a);
secp256k1_gej_set_infinity(&b);
test_gej_cmov(&a, &b);
random_gej_test(&a);
test_gej_cmov(&a, &b);
test_gej_cmov(&b, &a);
b = a;
test_gej_cmov(&a, &b);
random_gej_test(&b);
test_gej_cmov(&a, &b);
test_gej_cmov(&b, &a);
}
}
void test_ec_combine(void) {
secp256k1_scalar sum = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0);
secp256k1_pubkey data[6];
@@ -3697,8 +3737,6 @@ void test_pre_g_table(const secp256k1_ge_storage * pre_g, size_t n) {
CHECK(0 < n);
secp256k1_ge_from_storage(&p, &pre_g[0]);
secp256k1_fe_verify(&p.x);
secp256k1_fe_verify(&p.y);
CHECK(secp256k1_ge_is_valid_var(&p));
secp256k1_gej_set_ge(&g2, &p);
@@ -3711,8 +3749,6 @@ void test_pre_g_table(const secp256k1_ge_storage * pre_g, size_t n) {
CHECK(!secp256k1_fe_normalizes_to_zero_var(&dpx) || !secp256k1_fe_normalizes_to_zero_var(&dpy));
secp256k1_ge_from_storage(&q, &pre_g[i]);
secp256k1_fe_verify(&q.x);
secp256k1_fe_verify(&q.y);
CHECK(secp256k1_ge_is_valid_var(&q));
secp256k1_fe_negate(&dqx, &q.x, 1); secp256k1_fe_add(&dqx, &gg.x); secp256k1_fe_normalize_weak(&dqx);
@@ -4318,6 +4354,174 @@ void test_ecmult_multi(secp256k1_scratch *scratch, secp256k1_ecmult_multi_func e
}
}
int test_ecmult_multi_random(secp256k1_scratch *scratch) {
/* Large random test for ecmult_multi_* functions which exercises:
* - Few or many inputs (0 up to 128, roughly exponentially distributed).
* - Few or many 0*P or a*INF inputs (roughly uniformly distributed).
* - Including or excluding an nonzero a*G term (or such a term at all).
* - Final expected result equal to infinity or not (roughly 50%).
* - ecmult_multi_var, ecmult_strauss_single_batch, ecmult_pippenger_single_batch
*/
/* These 4 variables define the eventual input to the ecmult_multi function.
* g_scalar is the G scalar fed to it (or NULL, possibly, if g_scalar=0), and
* scalars[0..filled-1] and gejs[0..filled-1] are the scalars and points
* which form its normal inputs. */
int filled = 0;
secp256k1_scalar g_scalar = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0);
secp256k1_scalar scalars[128];
secp256k1_gej gejs[128];
/* The expected result, and the computed result. */
secp256k1_gej expected, computed;
/* Temporaries. */
secp256k1_scalar sc_tmp;
secp256k1_ge ge_tmp;
/* Variables needed for the actual input to ecmult_multi. */
secp256k1_ge ges[128];
ecmult_multi_data data;
int i;
/* Which multiplication function to use */
int fn = secp256k1_testrand_int(3);
secp256k1_ecmult_multi_func ecmult_multi = fn == 0 ? secp256k1_ecmult_multi_var :
fn == 1 ? secp256k1_ecmult_strauss_batch_single :
secp256k1_ecmult_pippenger_batch_single;
/* Simulate exponentially distributed num. */
int num_bits = 2 + secp256k1_testrand_int(6);
/* Number of (scalar, point) inputs (excluding g). */
int num = secp256k1_testrand_int((1 << num_bits) + 1);
/* Number of those which are nonzero. */
int num_nonzero = secp256k1_testrand_int(num + 1);
/* Whether we're aiming to create an input with nonzero expected result. */
int nonzero_result = secp256k1_testrand_bits(1);
/* Whether we will provide nonzero g multiplicand. In some cases our hand
* is forced here based on num_nonzero and nonzero_result. */
int g_nonzero = num_nonzero == 0 ? nonzero_result :
num_nonzero == 1 && !nonzero_result ? 1 :
(int)secp256k1_testrand_bits(1);
/* Which g_scalar pointer to pass into ecmult_multi(). */
const secp256k1_scalar* g_scalar_ptr = (g_nonzero || secp256k1_testrand_bits(1)) ? &g_scalar : NULL;
/* How many EC multiplications were performed in this function. */
int mults = 0;
/* How many randomization steps to apply to the input list. */
int rands = (int)secp256k1_testrand_bits(3);
if (rands > num_nonzero) rands = num_nonzero;
secp256k1_gej_set_infinity(&expected);
secp256k1_gej_set_infinity(&gejs[0]);
secp256k1_scalar_set_int(&scalars[0], 0);
if (g_nonzero) {
/* If g_nonzero, set g_scalar to nonzero value r. */
random_scalar_order_test(&g_scalar);
if (!nonzero_result) {
/* If expected=0 is desired, add a (a*r, -(1/a)*g) term to compensate. */
CHECK(num_nonzero > filled);
random_scalar_order_test(&sc_tmp);
secp256k1_scalar_mul(&scalars[filled], &sc_tmp, &g_scalar);
secp256k1_scalar_inverse_var(&sc_tmp, &sc_tmp);
secp256k1_scalar_negate(&sc_tmp, &sc_tmp);
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &gejs[filled], &sc_tmp);
++filled;
++mults;
}
}
if (nonzero_result && filled < num_nonzero) {
/* If a nonzero result is desired, and there is space, add a random nonzero term. */
random_scalar_order_test(&scalars[filled]);
random_group_element_test(&ge_tmp);
secp256k1_gej_set_ge(&gejs[filled], &ge_tmp);
++filled;
}
if (nonzero_result) {
/* Compute the expected result using normal ecmult. */
CHECK(filled <= 1);
secp256k1_ecmult(&expected, &gejs[0], &scalars[0], &g_scalar);
mults += filled + g_nonzero;
}
/* At this point we have expected = scalar_g*G + sum(scalars[i]*gejs[i] for i=0..filled-1). */
CHECK(filled <= 1 + !nonzero_result);
CHECK(filled <= num_nonzero);
/* Add entries to scalars,gejs so that there are num of them. All the added entries
* either have scalar=0 or point=infinity, so these do not change the expected result. */
while (filled < num) {
if (secp256k1_testrand_bits(1)) {
secp256k1_gej_set_infinity(&gejs[filled]);
random_scalar_order_test(&scalars[filled]);
} else {
secp256k1_scalar_set_int(&scalars[filled], 0);
random_group_element_test(&ge_tmp);
secp256k1_gej_set_ge(&gejs[filled], &ge_tmp);
}
++filled;
}
/* Now perform cheapish transformations on gejs and scalars, for indices
* 0..num_nonzero-1, which do not change the expected result, but may
* convert some of them to be both non-0-scalar and non-infinity-point. */
for (i = 0; i < rands; ++i) {
int j;
secp256k1_scalar v, iv;
/* Shuffle the entries. */
for (j = 0; j < num_nonzero; ++j) {
int k = secp256k1_testrand_int(num_nonzero - j);
if (k != 0) {
secp256k1_gej gej = gejs[j];
secp256k1_scalar sc = scalars[j];
gejs[j] = gejs[j + k];
scalars[j] = scalars[j + k];
gejs[j + k] = gej;
scalars[j + k] = sc;
}
}
/* Perturb all consecutive pairs of inputs:
* a*P + b*Q -> (a+b)*P + b*(Q-P). */
for (j = 0; j + 1 < num_nonzero; j += 2) {
secp256k1_gej gej;
secp256k1_scalar_add(&scalars[j], &scalars[j], &scalars[j+1]);
secp256k1_gej_neg(&gej, &gejs[j]);
secp256k1_gej_add_var(&gejs[j+1], &gejs[j+1], &gej, NULL);
}
/* Transform the last input: a*P -> (v*a) * ((1/v)*P). */
CHECK(num_nonzero >= 1);
random_scalar_order_test(&v);
secp256k1_scalar_inverse(&iv, &v);
secp256k1_scalar_mul(&scalars[num_nonzero - 1], &scalars[num_nonzero - 1], &v);
secp256k1_ecmult(&gejs[num_nonzero - 1], &gejs[num_nonzero - 1], &iv, NULL);
++mults;
}
/* Shuffle all entries (0..num-1). */
for (i = 0; i < num; ++i) {
int j = secp256k1_testrand_int(num - i);
if (j != 0) {
secp256k1_gej gej = gejs[i];
secp256k1_scalar sc = scalars[i];
gejs[i] = gejs[i + j];
scalars[i] = scalars[i + j];
gejs[i + j] = gej;
scalars[i + j] = sc;
}
}
/* Compute affine versions of all inputs. */
secp256k1_ge_set_all_gej_var(ges, gejs, filled);
/* Invoke ecmult_multi code. */
data.sc = scalars;
data.pt = ges;
CHECK(ecmult_multi(&ctx->error_callback, scratch, &computed, g_scalar_ptr, ecmult_multi_callback, &data, filled));
mults += num_nonzero + g_nonzero;
/* Compare with expected result. */
secp256k1_gej_neg(&computed, &computed);
secp256k1_gej_add_var(&computed, &computed, &expected, NULL);
CHECK(secp256k1_gej_is_infinity(&computed));
return mults;
}
void test_ecmult_multi_batch_single(secp256k1_ecmult_multi_func ecmult_multi) {
secp256k1_scalar szero;
secp256k1_scalar sc;
@@ -4359,7 +4563,7 @@ void test_secp256k1_pippenger_bucket_window_inv(void) {
* for a given scratch space.
*/
void test_ecmult_multi_pippenger_max_points(void) {
size_t scratch_size = secp256k1_testrand_int(256);
size_t scratch_size = secp256k1_testrand_bits(8);
size_t max_size = secp256k1_pippenger_scratch_size(secp256k1_pippenger_bucket_window_inv(PIPPENGER_MAX_BUCKET_WINDOW-1)+512, 12);
secp256k1_scratch *scratch;
size_t n_points_supported;
@@ -4508,6 +4712,7 @@ void test_ecmult_multi_batching(void) {
void run_ecmult_multi_tests(void) {
secp256k1_scratch *scratch;
int64_t todo = (int64_t)320 * count;
test_secp256k1_pippenger_bucket_window_inv();
test_ecmult_multi_pippenger_max_points();
@@ -4518,6 +4723,9 @@ void run_ecmult_multi_tests(void) {
test_ecmult_multi_batch_single(secp256k1_ecmult_pippenger_batch_single);
test_ecmult_multi(scratch, secp256k1_ecmult_strauss_batch_single);
test_ecmult_multi_batch_single(secp256k1_ecmult_strauss_batch_single);
while (todo > 0) {
todo -= test_ecmult_multi_random(scratch);
}
secp256k1_scratch_destroy(&ctx->error_callback, scratch);
/* Run test_ecmult_multi with space for exactly one point */
@@ -4613,7 +4821,7 @@ void test_constant_wnaf(const secp256k1_scalar *number, int w) {
secp256k1_scalar_add(&x, &x, &t);
}
/* Skew num because when encoding numbers as odd we use an offset */
secp256k1_scalar_set_int(&scalar_skew, 1 << (skew == 2));
secp256k1_scalar_set_int(&scalar_skew, skew);
secp256k1_scalar_add(&num, &num, &scalar_skew);
CHECK(secp256k1_scalar_eq(&x, &num));
}
@@ -4765,37 +4973,89 @@ void run_wnaf(void) {
CHECK(secp256k1_scalar_is_zero(&n));
}
static int test_ecmult_accumulate_cb(secp256k1_scalar* sc, secp256k1_ge* pt, size_t idx, void* data) {
const secp256k1_scalar* indata = (const secp256k1_scalar*)data;
*sc = *indata;
*pt = secp256k1_ge_const_g;
CHECK(idx == 0);
return 1;
}
void test_ecmult_accumulate(secp256k1_sha256* acc, const secp256k1_scalar* x, secp256k1_scratch* scratch) {
/* Compute x*G in 6 different ways, serialize it uncompressed, and feed it into acc. */
secp256k1_gej rj1, rj2, rj3, rj4, rj5, rj6, gj, infj;
secp256k1_ge r;
const secp256k1_scalar zero = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0);
unsigned char bytes[65];
size_t size = 65;
secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g);
secp256k1_gej_set_infinity(&infj);
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &rj1, x);
secp256k1_ecmult(&rj2, &gj, x, &zero);
secp256k1_ecmult(&rj3, &infj, &zero, x);
secp256k1_ecmult_multi_var(NULL, scratch, &rj4, x, NULL, NULL, 0);
secp256k1_ecmult_multi_var(NULL, scratch, &rj5, &zero, test_ecmult_accumulate_cb, (void*)x, 1);
secp256k1_ecmult_const(&rj6, &secp256k1_ge_const_g, x, 256);
secp256k1_ge_set_gej_var(&r, &rj1);
ge_equals_gej(&r, &rj2);
ge_equals_gej(&r, &rj3);
ge_equals_gej(&r, &rj4);
ge_equals_gej(&r, &rj5);
ge_equals_gej(&r, &rj6);
if (secp256k1_ge_is_infinity(&r)) {
/* Store infinity as 0x00 */
const unsigned char zerobyte[1] = {0};
secp256k1_sha256_write(acc, zerobyte, 1);
} else {
/* Store other points using their uncompressed serialization. */
secp256k1_eckey_pubkey_serialize(&r, bytes, &size, 0);
CHECK(size == 65);
secp256k1_sha256_write(acc, bytes, size);
}
}
void test_ecmult_constants(void) {
/* Test ecmult_gen() for [0..36) and [order-36..0). */
/* Test ecmult_gen for:
* - For i in 0..36:
* - Key i
* - Key -i
* - For i in 0..255:
* - For j in 1..255 (only odd values):
* - Key (j*2^i) mod order
*/
secp256k1_scalar x;
secp256k1_gej r;
secp256k1_ge ng;
int i;
int j;
secp256k1_ge_neg(&ng, &secp256k1_ge_const_g);
for (i = 0; i < 36; i++ ) {
secp256k1_scalar_set_int(&x, i);
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &r, &x);
for (j = 0; j < i; j++) {
if (j == i - 1) {
ge_equals_gej(&secp256k1_ge_const_g, &r);
}
secp256k1_gej_add_ge(&r, &r, &ng);
}
CHECK(secp256k1_gej_is_infinity(&r));
}
for (i = 1; i <= 36; i++ ) {
secp256k1_sha256 acc;
unsigned char b32[32];
int i, j;
secp256k1_scratch_space *scratch = secp256k1_scratch_space_create(ctx, 65536);
/* Expected hash of all the computed points; created with an independent
* implementation. */
static const unsigned char expected32[32] = {
0xe4, 0x71, 0x1b, 0x4d, 0x14, 0x1e, 0x68, 0x48,
0xb7, 0xaf, 0x47, 0x2b, 0x4c, 0xd2, 0x04, 0x14,
0x3a, 0x75, 0x87, 0x60, 0x1a, 0xf9, 0x63, 0x60,
0xd0, 0xcb, 0x1f, 0xaa, 0x85, 0x9a, 0xb7, 0xb4
};
secp256k1_sha256_initialize(&acc);
for (i = 0; i <= 36; ++i) {
secp256k1_scalar_set_int(&x, i);
test_ecmult_accumulate(&acc, &x, scratch);
secp256k1_scalar_negate(&x, &x);
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &r, &x);
for (j = 0; j < i; j++) {
if (j == i - 1) {
ge_equals_gej(&ng, &r);
}
secp256k1_gej_add_ge(&r, &r, &secp256k1_ge_const_g);
test_ecmult_accumulate(&acc, &x, scratch);
};
for (i = 0; i < 256; ++i) {
for (j = 1; j < 256; j += 2) {
int k;
secp256k1_scalar_set_int(&x, j);
for (k = 0; k < i; ++k) secp256k1_scalar_add(&x, &x, &x);
test_ecmult_accumulate(&acc, &x, scratch);
}
CHECK(secp256k1_gej_is_infinity(&r));
}
secp256k1_sha256_finalize(&acc, b32);
CHECK(secp256k1_memcmp_var(b32, expected32, 32) == 0);
secp256k1_scratch_space_destroy(ctx, scratch);
}
void run_ecmult_constants(void) {
@@ -5951,14 +6211,6 @@ void run_ecdsa_end_to_end(void) {
int test_ecdsa_der_parse(const unsigned char *sig, size_t siglen, int certainly_der, int certainly_not_der) {
static const unsigned char zeroes[32] = {0};
#ifdef ENABLE_OPENSSL_TESTS
static const unsigned char max_scalar[32] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b,
0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x40
};
#endif
int ret = 0;
@@ -5974,15 +6226,6 @@ int test_ecdsa_der_parse(const unsigned char *sig, size_t siglen, int certainly_
size_t len_der_lax = 2048;
int parsed_der_lax = 0, valid_der_lax = 0, roundtrips_der_lax = 0;
#ifdef ENABLE_OPENSSL_TESTS
ECDSA_SIG *sig_openssl;
const BIGNUM *r = NULL, *s = NULL;
const unsigned char *sigptr;
unsigned char roundtrip_openssl[2048];
int len_openssl = 2048;
int parsed_openssl, valid_openssl = 0, roundtrips_openssl = 0;
#endif
parsed_der = secp256k1_ecdsa_signature_parse_der(ctx, &sig_der, sig, siglen);
if (parsed_der) {
ret |= (!secp256k1_ecdsa_signature_serialize_compact(ctx, compact_der, &sig_der)) << 0;
@@ -6023,43 +6266,6 @@ int test_ecdsa_der_parse(const unsigned char *sig, size_t siglen, int certainly_
ret |= (!parsed_der_lax) << 16;
}
#ifdef ENABLE_OPENSSL_TESTS
sig_openssl = ECDSA_SIG_new();
sigptr = sig;
parsed_openssl = (d2i_ECDSA_SIG(&sig_openssl, &sigptr, siglen) != NULL);
if (parsed_openssl) {
ECDSA_SIG_get0(sig_openssl, &r, &s);
valid_openssl = !BN_is_negative(r) && !BN_is_negative(s) && BN_num_bits(r) > 0 && BN_num_bits(r) <= 256 && BN_num_bits(s) > 0 && BN_num_bits(s) <= 256;
if (valid_openssl) {
unsigned char tmp[32] = {0};
BN_bn2bin(r, tmp + 32 - BN_num_bytes(r));
valid_openssl = secp256k1_memcmp_var(tmp, max_scalar, 32) < 0;
}
if (valid_openssl) {
unsigned char tmp[32] = {0};
BN_bn2bin(s, tmp + 32 - BN_num_bytes(s));
valid_openssl = secp256k1_memcmp_var(tmp, max_scalar, 32) < 0;
}
}
len_openssl = i2d_ECDSA_SIG(sig_openssl, NULL);
if (len_openssl <= 2048) {
unsigned char *ptr = roundtrip_openssl;
CHECK(i2d_ECDSA_SIG(sig_openssl, &ptr) == len_openssl);
roundtrips_openssl = valid_openssl && ((size_t)len_openssl == siglen) && (secp256k1_memcmp_var(roundtrip_openssl, sig, siglen) == 0);
} else {
len_openssl = 0;
}
ECDSA_SIG_free(sig_openssl);
ret |= (parsed_der && !parsed_openssl) << 4;
ret |= (valid_der && !valid_openssl) << 5;
ret |= (roundtrips_openssl && !parsed_der) << 6;
ret |= (roundtrips_der != roundtrips_openssl) << 7;
if (roundtrips_openssl) {
ret |= (len_der != (size_t)len_openssl) << 8;
ret |= ((len_der != (size_t)len_openssl) || (secp256k1_memcmp_var(roundtrip_der, roundtrip_openssl, len_der) != 0)) << 9;
}
#endif
return ret;
}
@@ -6119,14 +6325,14 @@ static void random_ber_signature(unsigned char *sig, size_t *len, int* certainly
/* We generate two classes of numbers: nlow==1 "low" ones (up to 32 bytes), nlow==0 "high" ones (32 bytes with 129 top bits set, or larger than 32 bytes) */
nlow[n] = der ? 1 : (secp256k1_testrand_bits(3) != 0);
/* The length of the number in bytes (the first byte of which will always be nonzero) */
nlen[n] = nlow[n] ? secp256k1_testrand_int(33) : 32 + secp256k1_testrand_int(200) * secp256k1_testrand_int(8) / 8;
nlen[n] = nlow[n] ? secp256k1_testrand_int(33) : 32 + secp256k1_testrand_int(200) * secp256k1_testrand_bits(3) / 8;
CHECK(nlen[n] <= 232);
/* The top bit of the number. */
nhbit[n] = (nlow[n] == 0 && nlen[n] == 32) ? 1 : (nlen[n] == 0 ? 0 : secp256k1_testrand_bits(1));
/* The top byte of the number (after the potential hardcoded 16 0xFF characters for "high" 32 bytes numbers) */
nhbyte[n] = nlen[n] == 0 ? 0 : (nhbit[n] ? 128 + secp256k1_testrand_bits(7) : 1 + secp256k1_testrand_int(127));
/* The number of zero bytes in front of the number (which is 0 or 1 in case of DER, otherwise we extend up to 300 bytes) */
nzlen[n] = der ? ((nlen[n] == 0 || nhbit[n]) ? 1 : 0) : (nlow[n] ? secp256k1_testrand_int(3) : secp256k1_testrand_int(300 - nlen[n]) * secp256k1_testrand_int(8) / 8);
nzlen[n] = der ? ((nlen[n] == 0 || nhbit[n]) ? 1 : 0) : (nlow[n] ? secp256k1_testrand_int(3) : secp256k1_testrand_int(300 - nlen[n]) * secp256k1_testrand_bits(3) / 8);
if (nzlen[n] > ((nlen[n] == 0 || nhbit[n]) ? 1 : 0)) {
*certainly_not_der = 1;
}
@@ -6135,7 +6341,7 @@ static void random_ber_signature(unsigned char *sig, size_t *len, int* certainly
nlenlen[n] = nlen[n] + nzlen[n] < 128 ? 0 : (nlen[n] + nzlen[n] < 256 ? 1 : 2);
if (!der) {
/* nlenlen[n] max 127 bytes */
int add = secp256k1_testrand_int(127 - nlenlen[n]) * secp256k1_testrand_int(16) * secp256k1_testrand_int(16) / 256;
int add = secp256k1_testrand_int(127 - nlenlen[n]) * secp256k1_testrand_bits(4) * secp256k1_testrand_bits(4) / 256;
nlenlen[n] += add;
if (add != 0) {
*certainly_not_der = 1;
@@ -6149,7 +6355,7 @@ static void random_ber_signature(unsigned char *sig, size_t *len, int* certainly
CHECK(tlen <= 856);
/* The length of the garbage inside the tuple. */
elen = (der || indet) ? 0 : secp256k1_testrand_int(980 - tlen) * secp256k1_testrand_int(8) / 8;
elen = (der || indet) ? 0 : secp256k1_testrand_int(980 - tlen) * secp256k1_testrand_bits(3) / 8;
if (elen != 0) {
*certainly_not_der = 1;
}
@@ -6157,7 +6363,7 @@ static void random_ber_signature(unsigned char *sig, size_t *len, int* certainly
CHECK(tlen <= 980);
/* The length of the garbage after the end of the tuple. */
glen = der ? 0 : secp256k1_testrand_int(990 - tlen) * secp256k1_testrand_int(8) / 8;
glen = der ? 0 : secp256k1_testrand_int(990 - tlen) * secp256k1_testrand_bits(3) / 8;
if (glen != 0) {
*certainly_not_der = 1;
}
@@ -6172,7 +6378,7 @@ static void random_ber_signature(unsigned char *sig, size_t *len, int* certainly
} else {
int tlenlen = tlen < 128 ? 0 : (tlen < 256 ? 1 : 2);
if (!der) {
int add = secp256k1_testrand_int(127 - tlenlen) * secp256k1_testrand_int(16) * secp256k1_testrand_int(16) / 256;
int add = secp256k1_testrand_int(127 - tlenlen) * secp256k1_testrand_bits(4) * secp256k1_testrand_bits(4) / 256;
tlenlen += add;
if (add != 0) {
*certainly_not_der = 1;
@@ -6653,62 +6859,6 @@ void run_ecdsa_edge_cases(void) {
test_ecdsa_edge_cases();
}
#ifdef ENABLE_OPENSSL_TESTS
EC_KEY *get_openssl_key(const unsigned char *key32) {
unsigned char privkey[300];
size_t privkeylen;
const unsigned char* pbegin = privkey;
int compr = secp256k1_testrand_bits(1);
EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_secp256k1);
CHECK(ec_privkey_export_der(ctx, privkey, &privkeylen, key32, compr));
CHECK(d2i_ECPrivateKey(&ec_key, &pbegin, privkeylen));
CHECK(EC_KEY_check_key(ec_key));
return ec_key;
}
void test_ecdsa_openssl(void) {
secp256k1_gej qj;
secp256k1_ge q;
secp256k1_scalar sigr, sigs;
secp256k1_scalar one;
secp256k1_scalar msg2;
secp256k1_scalar key, msg;
EC_KEY *ec_key;
unsigned int sigsize = 80;
size_t secp_sigsize = 80;
unsigned char message[32];
unsigned char signature[80];
unsigned char key32[32];
secp256k1_testrand256_test(message);
secp256k1_scalar_set_b32(&msg, message, NULL);
random_scalar_order_test(&key);
secp256k1_scalar_get_b32(key32, &key);
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &qj, &key);
secp256k1_ge_set_gej(&q, &qj);
ec_key = get_openssl_key(key32);
CHECK(ec_key != NULL);
CHECK(ECDSA_sign(0, message, sizeof(message), signature, &sigsize, ec_key));
CHECK(secp256k1_ecdsa_sig_parse(&sigr, &sigs, signature, sigsize));
CHECK(secp256k1_ecdsa_sig_verify(&sigr, &sigs, &q, &msg));
secp256k1_scalar_set_int(&one, 1);
secp256k1_scalar_add(&msg2, &msg, &one);
CHECK(!secp256k1_ecdsa_sig_verify(&sigr, &sigs, &q, &msg2));
random_sign(&sigr, &sigs, &key, &msg, NULL);
CHECK(secp256k1_ecdsa_sig_serialize(signature, &secp_sigsize, &sigr, &sigs));
CHECK(ECDSA_verify(0, message, sizeof(message), signature, secp_sigsize, ec_key) == 1);
EC_KEY_free(ec_key);
}
void run_ecdsa_openssl(void) {
int i;
for (i = 0; i < 10*count; i++) {
test_ecdsa_openssl();
}
}
#endif
#ifdef ENABLE_MODULE_ECDH
# include "modules/ecdh/tests_impl.h"
#endif
@@ -6986,6 +7136,7 @@ int main(int argc, char **argv) {
/* group tests */
run_ge();
run_gej();
run_group_decompress();
/* ecmult tests */
@@ -7029,9 +7180,6 @@ int main(int argc, char **argv) {
run_ecdsa_sign_verify();
run_ecdsa_end_to_end();
run_ecdsa_edge_cases();
#ifdef ENABLE_OPENSSL_TESTS
run_ecdsa_openssl();
#endif
#ifdef ENABLE_MODULE_RECOVERY
/* ECDSA pubkey recovery tests */