Changeset View
Changeset View
Standalone View
Standalone View
src/secp256k1/src/tests.c
Show First 20 Lines • Show All 245 Lines • ▼ Show 20 Lines | void run_context_tests(void) { | ||||
secp256k1_context_destroy(none); | secp256k1_context_destroy(none); | ||||
secp256k1_context_destroy(sign); | secp256k1_context_destroy(sign); | ||||
secp256k1_context_destroy(vrfy); | secp256k1_context_destroy(vrfy); | ||||
secp256k1_context_destroy(both); | secp256k1_context_destroy(both); | ||||
/* Defined as no-op. */ | /* Defined as no-op. */ | ||||
secp256k1_context_destroy(NULL); | secp256k1_context_destroy(NULL); | ||||
} | } | ||||
void run_scratch_tests(void) { | |||||
int32_t ecount = 0; | |||||
secp256k1_context *none = secp256k1_context_create(SECP256K1_CONTEXT_NONE); | |||||
secp256k1_scratch_space *scratch; | |||||
/* Test public API */ | |||||
secp256k1_context_set_illegal_callback(none, counting_illegal_callback_fn, &ecount); | |||||
scratch = secp256k1_scratch_space_create(none, 100, 10); | |||||
CHECK(scratch == NULL); | |||||
CHECK(ecount == 1); | |||||
scratch = secp256k1_scratch_space_create(none, 100, 100); | |||||
CHECK(scratch != NULL); | |||||
CHECK(ecount == 1); | |||||
secp256k1_scratch_space_destroy(scratch); | |||||
scratch = secp256k1_scratch_space_create(none, 100, 1000); | |||||
CHECK(scratch != NULL); | |||||
CHECK(ecount == 1); | |||||
/* Test internal API */ | |||||
CHECK(secp256k1_scratch_max_allocation(scratch, 0) == 1000); | |||||
CHECK(secp256k1_scratch_max_allocation(scratch, 1) < 1000); | |||||
CHECK(secp256k1_scratch_resize(scratch, 50, 1) == 1); /* no-op */ | |||||
CHECK(secp256k1_scratch_resize(scratch, 200, 1) == 1); | |||||
CHECK(secp256k1_scratch_resize(scratch, 950, 1) == 1); | |||||
CHECK(secp256k1_scratch_resize(scratch, 1000, 1) == 0); | |||||
CHECK(secp256k1_scratch_resize(scratch, 2000, 1) == 0); | |||||
CHECK(secp256k1_scratch_max_allocation(scratch, 0) == 1000); | |||||
/* cleanup */ | |||||
secp256k1_scratch_space_destroy(scratch); | |||||
secp256k1_context_destroy(none); | |||||
} | |||||
/***** HASH TESTS *****/ | /***** HASH TESTS *****/ | ||||
void run_sha256_tests(void) { | void run_sha256_tests(void) { | ||||
static const char *inputs[8] = { | static const char *inputs[8] = { | ||||
"", "abc", "message digest", "secure hash algorithm", "SHA256 is considered to be safe", | "", "abc", "message digest", "secure hash algorithm", "SHA256 is considered to be safe", | ||||
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", | "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", | ||||
"For this sample, this 63-byte string will be used as input data", | "For this sample, this 63-byte string will be used as input data", | ||||
"This is exactly 64 bytes long, not counting the terminating byte" | "This is exactly 64 bytes long, not counting the terminating byte" | ||||
▲ Show 20 Lines • Show All 2,223 Lines • ▼ Show 20 Lines | |||||
void run_ecmult_const_tests(void) { | void run_ecmult_const_tests(void) { | ||||
ecmult_const_mult_zero_one(); | ecmult_const_mult_zero_one(); | ||||
ecmult_const_random_mult(); | ecmult_const_random_mult(); | ||||
ecmult_const_commutativity(); | ecmult_const_commutativity(); | ||||
ecmult_const_chain_multiply(); | ecmult_const_chain_multiply(); | ||||
} | } | ||||
typedef struct { | |||||
secp256k1_scalar *sc; | |||||
secp256k1_ge *pt; | |||||
} ecmult_multi_data; | |||||
static int ecmult_multi_callback(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx, void *cbdata) { | |||||
ecmult_multi_data *data = (ecmult_multi_data*) cbdata; | |||||
*sc = data->sc[idx]; | |||||
*pt = data->pt[idx]; | |||||
return 1; | |||||
} | |||||
static int ecmult_multi_false_callback(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx, void *cbdata) { | |||||
(void)sc; | |||||
(void)pt; | |||||
(void)idx; | |||||
(void)cbdata; | |||||
return 0; | |||||
} | |||||
void test_ecmult_multi(secp256k1_scratch *scratch, secp256k1_ecmult_multi_func ecmult_multi) { | |||||
int ncount; | |||||
secp256k1_scalar szero; | |||||
secp256k1_scalar sc[32]; | |||||
secp256k1_ge pt[32]; | |||||
secp256k1_gej r; | |||||
secp256k1_gej r2; | |||||
ecmult_multi_data data; | |||||
secp256k1_scratch *scratch_empty; | |||||
data.sc = sc; | |||||
data.pt = pt; | |||||
secp256k1_scalar_set_int(&szero, 0); | |||||
secp256k1_scratch_reset(scratch); | |||||
/* No points to multiply */ | |||||
CHECK(ecmult_multi(&ctx->ecmult_ctx, scratch, &r, NULL, ecmult_multi_callback, &data, 0)); | |||||
/* Check 1- and 2-point multiplies against ecmult */ | |||||
for (ncount = 0; ncount < count; ncount++) { | |||||
secp256k1_ge ptg; | |||||
secp256k1_gej ptgj; | |||||
random_scalar_order(&sc[0]); | |||||
random_scalar_order(&sc[1]); | |||||
random_group_element_test(&ptg); | |||||
secp256k1_gej_set_ge(&ptgj, &ptg); | |||||
pt[0] = ptg; | |||||
pt[1] = secp256k1_ge_const_g; | |||||
/* only G scalar */ | |||||
secp256k1_ecmult(&ctx->ecmult_ctx, &r2, &ptgj, &szero, &sc[0]); | |||||
CHECK(ecmult_multi(&ctx->ecmult_ctx, scratch, &r, &sc[0], ecmult_multi_callback, &data, 0)); | |||||
secp256k1_gej_neg(&r2, &r2); | |||||
secp256k1_gej_add_var(&r, &r, &r2, NULL); | |||||
CHECK(secp256k1_gej_is_infinity(&r)); | |||||
/* 1-point */ | |||||
secp256k1_ecmult(&ctx->ecmult_ctx, &r2, &ptgj, &sc[0], &szero); | |||||
CHECK(ecmult_multi(&ctx->ecmult_ctx, scratch, &r, &szero, ecmult_multi_callback, &data, 1)); | |||||
secp256k1_gej_neg(&r2, &r2); | |||||
secp256k1_gej_add_var(&r, &r, &r2, NULL); | |||||
CHECK(secp256k1_gej_is_infinity(&r)); | |||||
/* Try to multiply 1 point, but scratch space is empty */ | |||||
scratch_empty = secp256k1_scratch_create(&ctx->error_callback, 0, 0); | |||||
CHECK(!ecmult_multi(&ctx->ecmult_ctx, scratch_empty, &r, &szero, ecmult_multi_callback, &data, 1)); | |||||
secp256k1_scratch_destroy(scratch_empty); | |||||
/* Try to multiply 1 point, but callback returns false */ | |||||
CHECK(!ecmult_multi(&ctx->ecmult_ctx, scratch, &r, &szero, ecmult_multi_false_callback, &data, 1)); | |||||
/* 2-point */ | |||||
secp256k1_ecmult(&ctx->ecmult_ctx, &r2, &ptgj, &sc[0], &sc[1]); | |||||
CHECK(ecmult_multi(&ctx->ecmult_ctx, scratch, &r, &szero, ecmult_multi_callback, &data, 2)); | |||||
secp256k1_gej_neg(&r2, &r2); | |||||
secp256k1_gej_add_var(&r, &r, &r2, NULL); | |||||
CHECK(secp256k1_gej_is_infinity(&r)); | |||||
/* 2-point with G scalar */ | |||||
secp256k1_ecmult(&ctx->ecmult_ctx, &r2, &ptgj, &sc[0], &sc[1]); | |||||
CHECK(ecmult_multi(&ctx->ecmult_ctx, scratch, &r, &sc[1], ecmult_multi_callback, &data, 1)); | |||||
secp256k1_gej_neg(&r2, &r2); | |||||
secp256k1_gej_add_var(&r, &r, &r2, NULL); | |||||
CHECK(secp256k1_gej_is_infinity(&r)); | |||||
} | |||||
/* Check infinite outputs of various forms */ | |||||
for (ncount = 0; ncount < count; ncount++) { | |||||
secp256k1_ge ptg; | |||||
size_t i, j; | |||||
size_t sizes[] = { 2, 10, 32 }; | |||||
for (j = 0; j < 3; j++) { | |||||
for (i = 0; i < 32; i++) { | |||||
random_scalar_order(&sc[i]); | |||||
secp256k1_ge_set_infinity(&pt[i]); | |||||
} | |||||
CHECK(ecmult_multi(&ctx->ecmult_ctx, scratch, &r, &szero, ecmult_multi_callback, &data, sizes[j])); | |||||
CHECK(secp256k1_gej_is_infinity(&r)); | |||||
} | |||||
for (j = 0; j < 3; j++) { | |||||
for (i = 0; i < 32; i++) { | |||||
random_group_element_test(&ptg); | |||||
pt[i] = ptg; | |||||
secp256k1_scalar_set_int(&sc[i], 0); | |||||
} | |||||
CHECK(ecmult_multi(&ctx->ecmult_ctx, scratch, &r, &szero, ecmult_multi_callback, &data, sizes[j])); | |||||
CHECK(secp256k1_gej_is_infinity(&r)); | |||||
} | |||||
for (j = 0; j < 3; j++) { | |||||
random_group_element_test(&ptg); | |||||
for (i = 0; i < 16; i++) { | |||||
random_scalar_order(&sc[2*i]); | |||||
secp256k1_scalar_negate(&sc[2*i + 1], &sc[2*i]); | |||||
pt[2 * i] = ptg; | |||||
pt[2 * i + 1] = ptg; | |||||
} | |||||
CHECK(ecmult_multi(&ctx->ecmult_ctx, scratch, &r, &szero, ecmult_multi_callback, &data, sizes[j])); | |||||
CHECK(secp256k1_gej_is_infinity(&r)); | |||||
random_scalar_order(&sc[0]); | |||||
for (i = 0; i < 16; i++) { | |||||
random_group_element_test(&ptg); | |||||
sc[2*i] = sc[0]; | |||||
sc[2*i+1] = sc[0]; | |||||
pt[2 * i] = ptg; | |||||
secp256k1_ge_neg(&pt[2*i+1], &pt[2*i]); | |||||
} | |||||
CHECK(ecmult_multi(&ctx->ecmult_ctx, scratch, &r, &szero, ecmult_multi_callback, &data, sizes[j])); | |||||
CHECK(secp256k1_gej_is_infinity(&r)); | |||||
} | |||||
random_group_element_test(&ptg); | |||||
secp256k1_scalar_set_int(&sc[0], 0); | |||||
pt[0] = ptg; | |||||
for (i = 1; i < 32; i++) { | |||||
pt[i] = ptg; | |||||
random_scalar_order(&sc[i]); | |||||
secp256k1_scalar_add(&sc[0], &sc[0], &sc[i]); | |||||
secp256k1_scalar_negate(&sc[i], &sc[i]); | |||||
} | |||||
CHECK(ecmult_multi(&ctx->ecmult_ctx, scratch, &r, &szero, ecmult_multi_callback, &data, 32)); | |||||
CHECK(secp256k1_gej_is_infinity(&r)); | |||||
} | |||||
/* Check random points, constant scalar */ | |||||
for (ncount = 0; ncount < count; ncount++) { | |||||
size_t i; | |||||
secp256k1_gej_set_infinity(&r); | |||||
random_scalar_order(&sc[0]); | |||||
for (i = 0; i < 20; i++) { | |||||
secp256k1_ge ptg; | |||||
sc[i] = sc[0]; | |||||
random_group_element_test(&ptg); | |||||
pt[i] = ptg; | |||||
secp256k1_gej_add_ge_var(&r, &r, &pt[i], NULL); | |||||
} | |||||
secp256k1_ecmult(&ctx->ecmult_ctx, &r2, &r, &sc[0], &szero); | |||||
CHECK(ecmult_multi(&ctx->ecmult_ctx, scratch, &r, &szero, ecmult_multi_callback, &data, 20)); | |||||
secp256k1_gej_neg(&r2, &r2); | |||||
secp256k1_gej_add_var(&r, &r, &r2, NULL); | |||||
CHECK(secp256k1_gej_is_infinity(&r)); | |||||
} | |||||
/* Check random scalars, constant point */ | |||||
for (ncount = 0; ncount < count; ncount++) { | |||||
size_t i; | |||||
secp256k1_ge ptg; | |||||
secp256k1_gej p0j; | |||||
secp256k1_scalar rs; | |||||
secp256k1_scalar_set_int(&rs, 0); | |||||
random_group_element_test(&ptg); | |||||
for (i = 0; i < 20; i++) { | |||||
random_scalar_order(&sc[i]); | |||||
pt[i] = ptg; | |||||
secp256k1_scalar_add(&rs, &rs, &sc[i]); | |||||
} | |||||
secp256k1_gej_set_ge(&p0j, &pt[0]); | |||||
secp256k1_ecmult(&ctx->ecmult_ctx, &r2, &p0j, &rs, &szero); | |||||
CHECK(ecmult_multi(&ctx->ecmult_ctx, scratch, &r, &szero, ecmult_multi_callback, &data, 20)); | |||||
secp256k1_gej_neg(&r2, &r2); | |||||
secp256k1_gej_add_var(&r, &r, &r2, NULL); | |||||
CHECK(secp256k1_gej_is_infinity(&r)); | |||||
} | |||||
/* Sanity check that zero scalars don't cause problems */ | |||||
secp256k1_scalar_clear(&sc[0]); | |||||
CHECK(ecmult_multi(&ctx->ecmult_ctx, scratch, &r, &szero, ecmult_multi_callback, &data, 20)); | |||||
secp256k1_scalar_clear(&sc[1]); | |||||
secp256k1_scalar_clear(&sc[2]); | |||||
secp256k1_scalar_clear(&sc[3]); | |||||
secp256k1_scalar_clear(&sc[4]); | |||||
CHECK(ecmult_multi(&ctx->ecmult_ctx, scratch, &r, &szero, ecmult_multi_callback, &data, 6)); | |||||
CHECK(ecmult_multi(&ctx->ecmult_ctx, scratch, &r, &szero, ecmult_multi_callback, &data, 5)); | |||||
CHECK(secp256k1_gej_is_infinity(&r)); | |||||
/* Run through s0*(t0*P) + s1*(t1*P) exhaustively for many small values of s0, s1, t0, t1 */ | |||||
{ | |||||
const size_t TOP = 8; | |||||
size_t s0i, s1i; | |||||
size_t t0i, t1i; | |||||
secp256k1_ge ptg; | |||||
secp256k1_gej ptgj; | |||||
random_group_element_test(&ptg); | |||||
secp256k1_gej_set_ge(&ptgj, &ptg); | |||||
for(t0i = 0; t0i < TOP; t0i++) { | |||||
for(t1i = 0; t1i < TOP; t1i++) { | |||||
secp256k1_gej t0p, t1p; | |||||
secp256k1_scalar t0, t1; | |||||
secp256k1_scalar_set_int(&t0, (t0i + 1) / 2); | |||||
secp256k1_scalar_cond_negate(&t0, t0i & 1); | |||||
secp256k1_scalar_set_int(&t1, (t1i + 1) / 2); | |||||
secp256k1_scalar_cond_negate(&t1, t1i & 1); | |||||
secp256k1_ecmult(&ctx->ecmult_ctx, &t0p, &ptgj, &t0, &szero); | |||||
secp256k1_ecmult(&ctx->ecmult_ctx, &t1p, &ptgj, &t1, &szero); | |||||
for(s0i = 0; s0i < TOP; s0i++) { | |||||
for(s1i = 0; s1i < TOP; s1i++) { | |||||
secp256k1_scalar tmp1, tmp2; | |||||
secp256k1_gej expected, actual; | |||||
secp256k1_ge_set_gej(&pt[0], &t0p); | |||||
secp256k1_ge_set_gej(&pt[1], &t1p); | |||||
secp256k1_scalar_set_int(&sc[0], (s0i + 1) / 2); | |||||
secp256k1_scalar_cond_negate(&sc[0], s0i & 1); | |||||
secp256k1_scalar_set_int(&sc[1], (s1i + 1) / 2); | |||||
secp256k1_scalar_cond_negate(&sc[1], s1i & 1); | |||||
secp256k1_scalar_mul(&tmp1, &t0, &sc[0]); | |||||
secp256k1_scalar_mul(&tmp2, &t1, &sc[1]); | |||||
secp256k1_scalar_add(&tmp1, &tmp1, &tmp2); | |||||
secp256k1_ecmult(&ctx->ecmult_ctx, &expected, &ptgj, &tmp1, &szero); | |||||
CHECK(ecmult_multi(&ctx->ecmult_ctx, scratch, &actual, &szero, ecmult_multi_callback, &data, 2)); | |||||
secp256k1_gej_neg(&expected, &expected); | |||||
secp256k1_gej_add_var(&actual, &actual, &expected, NULL); | |||||
CHECK(secp256k1_gej_is_infinity(&actual)); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
void test_secp256k1_pippenger_bucket_window_inv(void) { | |||||
int i; | |||||
CHECK(secp256k1_pippenger_bucket_window_inv(0) == 0); | |||||
for(i = 1; i <= PIPPENGER_MAX_BUCKET_WINDOW; i++) { | |||||
#ifdef USE_ENDOMORPHISM | |||||
/* Bucket_window of 8 is not used with endo */ | |||||
if (i == 8) { | |||||
continue; | |||||
} | |||||
#endif | |||||
CHECK(secp256k1_pippenger_bucket_window(secp256k1_pippenger_bucket_window_inv(i)) == i); | |||||
if (i != PIPPENGER_MAX_BUCKET_WINDOW) { | |||||
CHECK(secp256k1_pippenger_bucket_window(secp256k1_pippenger_bucket_window_inv(i)+1) > i); | |||||
} | |||||
} | |||||
} | |||||
/** | |||||
* Probabilistically test the function returning the maximum number of possible points | |||||
* for a given scratch space. | |||||
*/ | |||||
void test_ecmult_multi_pippenger_max_points(void) { | |||||
size_t scratch_size = secp256k1_rand_int(256); | |||||
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; | |||||
int bucket_window = 0; | |||||
for(; scratch_size < max_size; scratch_size+=256) { | |||||
scratch = secp256k1_scratch_create(&ctx->error_callback, 0, scratch_size); | |||||
CHECK(scratch != NULL); | |||||
n_points_supported = secp256k1_pippenger_max_points(scratch); | |||||
if (n_points_supported == 0) { | |||||
secp256k1_scratch_destroy(scratch); | |||||
continue; | |||||
} | |||||
bucket_window = secp256k1_pippenger_bucket_window(n_points_supported); | |||||
CHECK(secp256k1_scratch_resize(scratch, secp256k1_pippenger_scratch_size(n_points_supported, bucket_window), PIPPENGER_SCRATCH_OBJECTS)); | |||||
secp256k1_scratch_destroy(scratch); | |||||
} | |||||
CHECK(bucket_window == PIPPENGER_MAX_BUCKET_WINDOW); | |||||
} | |||||
/** | |||||
* Run secp256k1_ecmult_multi_var with num points and a scratch space restricted to | |||||
* 1 <= i <= num points. | |||||
*/ | |||||
void test_ecmult_multi_batching(void) { | |||||
static const int n_points = 2*ECMULT_PIPPENGER_THRESHOLD; | |||||
secp256k1_scalar scG; | |||||
secp256k1_scalar szero; | |||||
secp256k1_scalar *sc = (secp256k1_scalar *)checked_malloc(&ctx->error_callback, sizeof(secp256k1_scalar) * n_points); | |||||
secp256k1_ge *pt = (secp256k1_ge *)checked_malloc(&ctx->error_callback, sizeof(secp256k1_ge) * n_points); | |||||
secp256k1_gej r; | |||||
secp256k1_gej r2; | |||||
ecmult_multi_data data; | |||||
int i; | |||||
secp256k1_scratch *scratch; | |||||
secp256k1_gej_set_infinity(&r2); | |||||
secp256k1_scalar_set_int(&szero, 0); | |||||
/* Get random scalars and group elements and compute result */ | |||||
random_scalar_order(&scG); | |||||
secp256k1_ecmult(&ctx->ecmult_ctx, &r2, &r2, &szero, &scG); | |||||
for(i = 0; i < n_points; i++) { | |||||
secp256k1_ge ptg; | |||||
secp256k1_gej ptgj; | |||||
random_group_element_test(&ptg); | |||||
secp256k1_gej_set_ge(&ptgj, &ptg); | |||||
pt[i] = ptg; | |||||
random_scalar_order(&sc[i]); | |||||
secp256k1_ecmult(&ctx->ecmult_ctx, &ptgj, &ptgj, &sc[i], NULL); | |||||
secp256k1_gej_add_var(&r2, &r2, &ptgj, NULL); | |||||
} | |||||
data.sc = sc; | |||||
data.pt = pt; | |||||
/* Test with empty scratch space */ | |||||
scratch = secp256k1_scratch_create(&ctx->error_callback, 0, 0); | |||||
CHECK(!secp256k1_ecmult_multi_var(&ctx->ecmult_ctx, scratch, &r, &scG, ecmult_multi_callback, &data, 1)); | |||||
secp256k1_scratch_destroy(scratch); | |||||
/* Test with space for 1 point in pippenger. That's not enough because | |||||
* ecmult_multi selects strauss which requires more memory. */ | |||||
scratch = secp256k1_scratch_create(&ctx->error_callback, 0, secp256k1_pippenger_scratch_size(1, 1) + PIPPENGER_SCRATCH_OBJECTS*ALIGNMENT); | |||||
CHECK(!secp256k1_ecmult_multi_var(&ctx->ecmult_ctx, scratch, &r, &scG, ecmult_multi_callback, &data, 1)); | |||||
secp256k1_scratch_destroy(scratch); | |||||
secp256k1_gej_neg(&r2, &r2); | |||||
for(i = 1; i <= n_points; i++) { | |||||
if (i > ECMULT_PIPPENGER_THRESHOLD) { | |||||
int bucket_window = secp256k1_pippenger_bucket_window(i); | |||||
size_t scratch_size = secp256k1_pippenger_scratch_size(i, bucket_window); | |||||
scratch = secp256k1_scratch_create(&ctx->error_callback, 0, scratch_size + PIPPENGER_SCRATCH_OBJECTS*ALIGNMENT); | |||||
} else { | |||||
size_t scratch_size = secp256k1_strauss_scratch_size(i); | |||||
scratch = secp256k1_scratch_create(&ctx->error_callback, 0, scratch_size + STRAUSS_SCRATCH_OBJECTS*ALIGNMENT); | |||||
} | |||||
CHECK(secp256k1_ecmult_multi_var(&ctx->ecmult_ctx, scratch, &r, &scG, ecmult_multi_callback, &data, n_points)); | |||||
secp256k1_gej_add_var(&r, &r, &r2, NULL); | |||||
CHECK(secp256k1_gej_is_infinity(&r)); | |||||
secp256k1_scratch_destroy(scratch); | |||||
} | |||||
free(sc); | |||||
free(pt); | |||||
} | |||||
void run_ecmult_multi_tests(void) { | |||||
secp256k1_scratch *scratch; | |||||
test_secp256k1_pippenger_bucket_window_inv(); | |||||
test_ecmult_multi_pippenger_max_points(); | |||||
scratch = secp256k1_scratch_create(&ctx->error_callback, 0, 819200); | |||||
test_ecmult_multi(scratch, secp256k1_ecmult_multi_var); | |||||
test_ecmult_multi(scratch, secp256k1_ecmult_pippenger_batch_single); | |||||
test_ecmult_multi(scratch, secp256k1_ecmult_strauss_batch_single); | |||||
secp256k1_scratch_destroy(scratch); | |||||
/* Run test_ecmult_multi with space for exactly one point */ | |||||
scratch = secp256k1_scratch_create(&ctx->error_callback, 0, secp256k1_strauss_scratch_size(1) + STRAUSS_SCRATCH_OBJECTS*ALIGNMENT); | |||||
test_ecmult_multi(scratch, secp256k1_ecmult_multi_var); | |||||
secp256k1_scratch_destroy(scratch); | |||||
test_ecmult_multi_batching(); | |||||
} | |||||
void test_wnaf(const secp256k1_scalar *number, int w) { | void test_wnaf(const secp256k1_scalar *number, int w) { | ||||
secp256k1_scalar x, two, t; | secp256k1_scalar x, two, t; | ||||
int wnaf[256]; | int wnaf[256]; | ||||
int zeroes = -1; | int zeroes = -1; | ||||
int i; | int i; | ||||
int bits; | int bits; | ||||
secp256k1_scalar_set_int(&x, 0); | secp256k1_scalar_set_int(&x, 0); | ||||
secp256k1_scalar_set_int(&two, 2); | secp256k1_scalar_set_int(&two, 2); | ||||
▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | for (i = WNAF_SIZE(w); i >= 0; --i) { | ||||
} | } | ||||
secp256k1_scalar_add(&x, &x, &t); | secp256k1_scalar_add(&x, &x, &t); | ||||
} | } | ||||
/* Skew num because when encoding numbers as odd we use an offset */ | /* Skew num because when encoding numbers as odd we use an offset */ | ||||
secp256k1_scalar_cadd_bit(&num, skew == 2, 1); | secp256k1_scalar_cadd_bit(&num, skew == 2, 1); | ||||
CHECK(secp256k1_scalar_eq(&x, &num)); | CHECK(secp256k1_scalar_eq(&x, &num)); | ||||
} | } | ||||
void test_fixed_wnaf(const secp256k1_scalar *number, int w) { | |||||
secp256k1_scalar x, shift; | |||||
int wnaf[256] = {0}; | |||||
int i; | |||||
int skew; | |||||
secp256k1_scalar num = *number; | |||||
secp256k1_scalar_set_int(&x, 0); | |||||
secp256k1_scalar_set_int(&shift, 1 << w); | |||||
/* With USE_ENDOMORPHISM on we only consider 128-bit numbers */ | |||||
#ifdef USE_ENDOMORPHISM | |||||
for (i = 0; i < 16; ++i) { | |||||
secp256k1_scalar_shr_int(&num, 8); | |||||
} | |||||
#endif | |||||
skew = secp256k1_wnaf_fixed(wnaf, &num, w); | |||||
for (i = WNAF_SIZE(w)-1; i >= 0; --i) { | |||||
secp256k1_scalar t; | |||||
int v = wnaf[i]; | |||||
CHECK(v != 0); /* check nonzero */ | |||||
CHECK(v & 1); /* check parity */ | |||||
CHECK(v > -(1 << w)); /* check range above */ | |||||
CHECK(v < (1 << w)); /* check range below */ | |||||
secp256k1_scalar_mul(&x, &x, &shift); | |||||
if (v >= 0) { | |||||
secp256k1_scalar_set_int(&t, v); | |||||
} else { | |||||
secp256k1_scalar_set_int(&t, -v); | |||||
secp256k1_scalar_negate(&t, &t); | |||||
} | |||||
secp256k1_scalar_add(&x, &x, &t); | |||||
} | |||||
/* If skew is 1 then add 1 to num */ | |||||
secp256k1_scalar_cadd_bit(&num, 0, skew == 1); | |||||
CHECK(secp256k1_scalar_eq(&x, &num)); | |||||
} | |||||
void test_fixed_wnaf_zero(int w) { | |||||
int wnaf[256] = {0}; | |||||
int i; | |||||
int skew; | |||||
secp256k1_scalar num; | |||||
secp256k1_scalar_set_int(&num, 0); | |||||
skew = secp256k1_wnaf_fixed(wnaf, &num, w); | |||||
for (i = WNAF_SIZE(w)-1; i >= 0; --i) { | |||||
int v = wnaf[i]; | |||||
CHECK(v == 0); | |||||
} | |||||
CHECK(skew == 0); | |||||
} | |||||
void run_wnaf(void) { | void run_wnaf(void) { | ||||
int i; | int i; | ||||
secp256k1_scalar n = {{0}}; | secp256k1_scalar n = {{0}}; | ||||
/* Sanity check: 1 and 2 are the smallest odd and even numbers and should | /* Sanity check: 1 and 2 are the smallest odd and even numbers and should | ||||
* have easier-to-diagnose failure modes */ | * have easier-to-diagnose failure modes */ | ||||
n.d[0] = 1; | n.d[0] = 1; | ||||
test_constant_wnaf(&n, 4); | test_constant_wnaf(&n, 4); | ||||
n.d[0] = 2; | n.d[0] = 2; | ||||
test_constant_wnaf(&n, 4); | test_constant_wnaf(&n, 4); | ||||
/* Test 0 */ | |||||
test_fixed_wnaf_zero(4); | |||||
/* Random tests */ | /* Random tests */ | ||||
for (i = 0; i < count; i++) { | for (i = 0; i < count; i++) { | ||||
random_scalar_order(&n); | random_scalar_order(&n); | ||||
test_wnaf(&n, 4+(i%10)); | test_wnaf(&n, 4+(i%10)); | ||||
test_constant_wnaf_negate(&n); | test_constant_wnaf_negate(&n); | ||||
test_constant_wnaf(&n, 4 + (i % 10)); | test_constant_wnaf(&n, 4 + (i % 10)); | ||||
test_fixed_wnaf(&n, 4 + (i % 10)); | |||||
} | } | ||||
secp256k1_scalar_set_int(&n, 0); | secp256k1_scalar_set_int(&n, 0); | ||||
CHECK(secp256k1_scalar_cond_negate(&n, 1) == -1); | CHECK(secp256k1_scalar_cond_negate(&n, 1) == -1); | ||||
CHECK(secp256k1_scalar_is_zero(&n)); | CHECK(secp256k1_scalar_is_zero(&n)); | ||||
CHECK(secp256k1_scalar_cond_negate(&n, 0) == 1); | CHECK(secp256k1_scalar_cond_negate(&n, 0) == 1); | ||||
CHECK(secp256k1_scalar_is_zero(&n)); | CHECK(secp256k1_scalar_is_zero(&n)); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,856 Lines • ▼ Show 20 Lines | int main(int argc, char **argv) { | ||||
} | } | ||||
secp256k1_rand_seed(seed16); | secp256k1_rand_seed(seed16); | ||||
printf("test count = %i\n", count); | printf("test count = %i\n", count); | ||||
printf("random seed = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", seed16[0], seed16[1], seed16[2], seed16[3], seed16[4], seed16[5], seed16[6], seed16[7], seed16[8], seed16[9], seed16[10], seed16[11], seed16[12], seed16[13], seed16[14], seed16[15]); | printf("random seed = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", seed16[0], seed16[1], seed16[2], seed16[3], seed16[4], seed16[5], seed16[6], seed16[7], seed16[8], seed16[9], seed16[10], seed16[11], seed16[12], seed16[13], seed16[14], seed16[15]); | ||||
/* initialize */ | /* initialize */ | ||||
run_context_tests(); | run_context_tests(); | ||||
run_scratch_tests(); | |||||
ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); | ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); | ||||
if (secp256k1_rand_bits(1)) { | if (secp256k1_rand_bits(1)) { | ||||
secp256k1_rand256(run32); | secp256k1_rand256(run32); | ||||
CHECK(secp256k1_context_randomize(ctx, secp256k1_rand_bits(1) ? run32 : NULL)); | CHECK(secp256k1_context_randomize(ctx, secp256k1_rand_bits(1) ? run32 : NULL)); | ||||
} | } | ||||
run_rand_bits(); | run_rand_bits(); | ||||
run_rand_int(); | run_rand_int(); | ||||
Show All 25 Lines | #endif | ||||
/* ecmult tests */ | /* ecmult tests */ | ||||
run_wnaf(); | run_wnaf(); | ||||
run_point_times_order(); | run_point_times_order(); | ||||
run_ecmult_chain(); | run_ecmult_chain(); | ||||
run_ecmult_constants(); | run_ecmult_constants(); | ||||
run_ecmult_gen_blind(); | run_ecmult_gen_blind(); | ||||
run_ecmult_const_tests(); | run_ecmult_const_tests(); | ||||
run_ecmult_multi_tests(); | |||||
run_ec_combine(); | run_ec_combine(); | ||||
/* endomorphism tests */ | /* endomorphism tests */ | ||||
#ifdef USE_ENDOMORPHISM | #ifdef USE_ENDOMORPHISM | ||||
run_endomorphism_tests(); | run_endomorphism_tests(); | ||||
#endif | #endif | ||||
/* EC point parser test */ | /* EC point parser test */ | ||||
▲ Show 20 Lines • Show All 43 Lines • Show Last 20 Lines |