11#ifndef EXHAUSTIVE_TEST_ORDER
13#define EXHAUSTIVE_TEST_ORDER 13
17#define EXHAUSTIVE_TEST_CURVE_HAS_EVEN_ORDER (SECP256K1_B == 1 || SECP256K1_B == 6 || SECP256K1_B == 8)
19#ifdef USE_EXTERNAL_DEFAULT_CALLBACKS
20 #pragma message("Ignoring USE_EXTERNAL_CALLBACKS in exhaustive_tests.")
21 #undef USE_EXTERNAL_DEFAULT_CALLBACKS
41 *iter += 0xe7037ed1a0b428dbULL;
46 const unsigned char *key32,
const unsigned char *algo16,
47 void *data,
unsigned int attempt) {
60 secp256k1_scalar_set_int(&s, *idata);
61 secp256k1_scalar_get_b32(nonce32, &s);
69 secp256k1_ge_mul_lambda(&res, &group[i]);
79 CHECK(secp256k1_ge_is_infinity(&group[0]));
80 CHECK(secp256k1_gej_is_infinity(&groupj[0]));
82 CHECK(!secp256k1_ge_is_infinity(&group[i]));
83 CHECK(!secp256k1_gej_is_infinity(&groupj[i]));
95 secp256k1_gej_add_var(&tmp, &groupj[i], &groupj[j], NULL);
99 secp256k1_gej_add_ge(&tmp, &groupj[i], &group[j]);
103 secp256k1_gej_add_ge_var(&tmp, &groupj[i], &group[j], NULL);
106 if (secp256k1_gej_is_infinity(&groupj[j])) {
109 secp256k1_ge_set_xy(&zless_gej, &groupj[j].x, &groupj[j].y);
111 secp256k1_gej_add_zinv_var(&tmp, &groupj[i], &zless_gej, &fe_inv);
119 secp256k1_gej_double(&tmp, &groupj[i]);
121 secp256k1_gej_double_var(&tmp, &groupj[i], NULL);
129 secp256k1_ge_neg(&tmp, &group[i]);
131 secp256k1_gej_neg(&tmpj, &groupj[i]);
145 secp256k1_scalar_set_int(&na, i);
146 secp256k1_scalar_set_int(&ng, j);
148 secp256k1_ecmult(&tmp, &groupj[r_log], &na, &ng);
163 secp256k1_scalar_set_int(&ng, j);
166 secp256k1_ecmult_const(&tmp, &group[i], &ng);
169 if (i != 0 && j != 0) {
171 ret = secp256k1_ecmult_const_xonly(&tmpf, &group[i].x, NULL, &ng, 0);
176 testutil_random_fe_non_zero(&xd);
178 ret = secp256k1_ecmult_const_xonly(&tmpf, &xn, &xd, &ng, 0);
212 secp256k1_scalar_set_int(&data.sc[0], i);
213 secp256k1_scalar_set_int(&data.sc[1], j);
214 secp256k1_scalar_set_int(&g_sc,
k);
215 data.pt[0] = group[x];
216 data.pt[1] = group[y];
230 unsigned char x_bin[32];
235 secp256k1_scalar_set_b32(r, x_bin, overflow);
250 int k, should_verify;
251 unsigned char msg32[32];
255 secp256k1_scalar_set_int(&s_s, s);
256 secp256k1_scalar_set_int(&r_s, r);
257 secp256k1_scalar_set_int(&msg_s, msg);
258 secp256k1_scalar_set_int(&sk_s, key);
267 if (r_s == check_x_s) {
268 secp256k1_scalar_set_int(&s_times_k_s,
k);
269 secp256k1_scalar_mul(&s_times_k_s, &s_times_k_s, &s_s);
270 secp256k1_scalar_mul(&msg_plus_r_times_sk_s, &r_s, &sk_s);
271 secp256k1_scalar_add(&msg_plus_r_times_sk_s, &msg_plus_r_times_sk_s, &msg_s);
272 should_verify |= secp256k1_scalar_eq(&s_times_k_s, &msg_plus_r_times_sk_s);
276 should_verify &= !secp256k1_scalar_is_high(&s_s);
279 secp256k1_ecdsa_signature_save(&sig, &r_s, &s_s);
280 memcpy(&nonconst_ge, &group[sk_s],
sizeof(nonconst_ge));
281 secp256k1_pubkey_save(&pk, &nonconst_ge);
282 secp256k1_scalar_get_b32(msg32, &msg_s);
283 CHECK(should_verify ==
300 const int starting_k =
k;
304 unsigned char sk32[32], msg32[32];
305 secp256k1_scalar_set_int(&msg, i);
306 secp256k1_scalar_set_int(&sk, j);
307 secp256k1_scalar_get_b32(sk32, &sk);
308 secp256k1_scalar_get_b32(msg32, &msg);
313 secp256k1_ecdsa_signature_load(ctx, &r, &s, &sig);
318 CHECK(r == expected_r);
323 if (
k < starting_k) {
340#ifdef ENABLE_MODULE_RECOVERY
344#ifdef ENABLE_MODULE_EXTRAKEYS
348#ifdef ENABLE_MODULE_SCHNORRSIG
352#ifdef ENABLE_MODULE_ELLSWIFT
356int main(
int argc,
char** argv) {
360 unsigned char rand32[32];
366 setbuf(stdout, NULL);
369 setbuf(stderr, NULL);
375 count = strtol(argv[1], NULL, 0);
377 printf(
"test count = %i\n",
count);
387 fprintf(stderr,
"Usage: %s [count] [seed] [numcores] [thiscore]\n", argv[0]);
390 printf(
"running tests for core %lu (out of [0..%lu])\n", (
unsigned long)
this_core, (
unsigned long)
num_cores - 1);
404 secp256k1_gej_set_infinity(&groupj[0]);
405 secp256k1_ge_set_gej(&group[0], &groupj[0]);
407 secp256k1_gej_add_ge(&groupj[i], &groupj[i - 1], &secp256k1_ge_const_g);
408 secp256k1_ge_set_gej(&group[i], &groupj[i]);
413 testutil_random_fe(&z);
414 secp256k1_gej_rescale(&groupj[i], &z);
423 secp256k1_scalar_set_int(&scalar_i, i);
424 secp256k1_ecmult_gen(&ctx->
ecmult_gen_ctx, &generatedj, &scalar_i);
425 secp256k1_ge_set_gej(&generated, &generatedj);
427 CHECK(!secp256k1_ge_is_infinity(&group[i]));
440#ifdef ENABLE_MODULE_RECOVERY
443#ifdef ENABLE_MODULE_EXTRAKEYS
446#ifdef ENABLE_MODULE_SCHNORRSIG
449#ifdef ENABLE_MODULE_ELLSWIFT
454 #if !EXHAUSTIVE_TEST_CURVE_HAS_EVEN_ORDER
464 printf(
"no problems found\n");
int main(int argc, char **argv)
static void secp256k1_ecmult_compute_two_tables(secp256k1_ge_storage *table, secp256k1_ge_storage *table_128, int window_g, const secp256k1_ge *gen)
static void secp256k1_ecmult_gen_compute_table(secp256k1_ge_storage *table, const secp256k1_ge *gen, int blocks, int teeth, int spacing)
static void test_exhaustive_ellswift(const secp256k1_context *ctx, const secp256k1_ge *group)
#define secp256k1_fe_get_b32
#define secp256k1_fe_normalize
static int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b)
Determine whether two field elements are equal.
static int secp256k1_ge_eq_var(const secp256k1_ge *a, const secp256k1_ge *b)
Check two group elements (affine) for equality in variable time.
static void secp256k1_ge_set_infinity(secp256k1_ge *r)
Set a group element (affine) equal to the point at infinity.
#define CHECK(cond)
Unconditional failure on condition failure.
const secp256k1_ge_storage secp256k1_pre_g_128[ECMULT_TABLE_SIZE(WINDOW_G)]
const secp256k1_ge_storage secp256k1_pre_g[ECMULT_TABLE_SIZE(WINDOW_G)]
const secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[COMB_BLOCKS][COMB_POINTS]
static void test_exhaustive_recovery(const secp256k1_context *ctx, const secp256k1_ge *group)
static void test_exhaustive_schnorrsig(const secp256k1_context *ctx)
static void secp256k1_scratch_destroy(const secp256k1_callback *error_callback, secp256k1_scratch *scratch)
static secp256k1_scratch * secp256k1_scratch_create(const secp256k1_callback *error_callback, size_t max_size)
struct secp256k1_scratch_space_struct secp256k1_scratch
SECP256K1_API void secp256k1_context_destroy(secp256k1_context *ctx) SECP256K1_ARG_NONNULL(1)
Destroy a secp256k1 context object (created in dynamically allocated memory).
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize(secp256k1_context *ctx, const unsigned char *seed32) SECP256K1_ARG_NONNULL(1)
Randomizes the context to provide enhanced protection against side-channel leakage.
struct secp256k1_context_struct secp256k1_context
Unless explicitly stated all pointer arguments must not be NULL.
SECP256K1_API secp256k1_context * secp256k1_context_create(unsigned int flags) SECP256K1_WARN_UNUSED_RESULT
Create a secp256k1 context object (in dynamically allocated memory).
SECP256K1_API int secp256k1_ecdsa_sign(const secp256k1_context *ctx, secp256k1_ecdsa_signature *sig, const unsigned char *msghash32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void *ndata) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Create an ECDSA signature.
#define SECP256K1_CONTEXT_NONE
Context flags to pass to secp256k1_context_create, secp256k1_context_preallocated_size,...
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify(const secp256k1_context *ctx, const secp256k1_ecdsa_signature *sig, const unsigned char *msghash32, const secp256k1_pubkey *pubkey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Verify an ECDSA signature.
secp256k1_callback error_callback
secp256k1_ecmult_gen_context ecmult_gen_ctx
Opaque data structure that holds a parsed ECDSA signature.
This field implementation represents the value as 10 uint32_t limbs in base 2^26.
A group element in affine coordinates on the secp256k1 curve, or occasionally on an isomorphic curve ...
A group element of the secp256k1 curve, in jacobian coordinates.
Opaque data structure that holds a parsed and valid public key.
A scalar modulo the group order of the secp256k1 curve.
static void testrand_init(const char *hexseed)
Initialize the test RNG using (hex encoded) array up to 16 bytes, or randomly if hexseed is NULL.
static void testrand_finish(void)
Print final test information.
static int ecmult_multi_callback(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx, void *cbdata)
static void test_exhaustive_verify(const secp256k1_context *ctx, const secp256k1_ge *group)
static void test_exhaustive_endomorphism(const secp256k1_ge *group)
static void test_exhaustive_ecmult(const secp256k1_ge *group, const secp256k1_gej *groupj)
static uint32_t this_core
static SECP256K1_INLINE int skip_section(uint64_t *iter)
static void r_from_k(secp256k1_scalar *r, const secp256k1_ge *group, int k, int *overflow)
static void test_exhaustive_ecmult_multi(const secp256k1_context *ctx, const secp256k1_ge *group)
static void test_exhaustive_sign(const secp256k1_context *ctx, const secp256k1_ge *group)
static uint32_t num_cores
static void test_exhaustive_addition(const secp256k1_ge *group, const secp256k1_gej *groupj)
#define EXHAUSTIVE_TEST_ORDER
static int secp256k1_nonce_function_smallint(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int attempt)