diff --git a/.gitignore b/.gitignore index ce33a84adf..55c2ca6a2e 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,7 @@ libtool *.lo *.o *~ +*.[gp]ch coverage/ coverage.html diff --git a/Makefile.am b/Makefile.am index d511853b05..4fc9ed9cf2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -8,6 +8,7 @@ lib_LTLIBRARIES = libsecp256k1.la include_HEADERS = include/secp256k1.h include_HEADERS += include/secp256k1_preallocated.h noinst_HEADERS = +noinst_HEADERS += src/secp256k1_internal.h noinst_HEADERS += src/scalar.h noinst_HEADERS += src/scalar_4x64.h noinst_HEADERS += src/scalar_8x32.h @@ -57,6 +58,7 @@ noinst_HEADERS += src/int128_struct_impl.h noinst_HEADERS += src/scratch.h noinst_HEADERS += src/scratch_impl.h noinst_HEADERS += src/selftest.h +noinst_HEADERS += src/selftest_impl.h noinst_HEADERS += src/testrand.h noinst_HEADERS += src/testrand_impl.h noinst_HEADERS += src/hash.h diff --git a/sage/gen_exhaustive_groups.sage b/sage/gen_exhaustive_groups.sage index 070bc1285f..87be4fe4c2 100644 --- a/sage/gen_exhaustive_groups.sage +++ b/sage/gen_exhaustive_groups.sage @@ -99,7 +99,7 @@ def output_b(b): print(f"#define SECP256K1_B {int(b)}") print() -print("To be put in src/group_impl.h:") +print("To be put in src/group.h:") print() print("/* Begin of section generated by sage/gen_exhaustive_groups.sage. */") for f in sorted(solutions.keys()): @@ -141,7 +141,7 @@ print("/* End of section generated by sage/gen_exhaustive_groups.sage. */") print() print() -print("To be put in src/scalar_impl.h:") +print("To be put in src/scalar.h:") print() print("/* Begin of section generated by sage/gen_exhaustive_groups.sage. */") first = True diff --git a/src/bench_ecmult.c b/src/bench_ecmult.c index b2bab65d26..ef2c3ca900 100644 --- a/src/bench_ecmult.c +++ b/src/bench_ecmult.c @@ -336,7 +336,7 @@ int main(int argc, char **argv) { data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); scratch_size = secp256k1_strauss_scratch_size(POINTS) + STRAUSS_SCRATCH_OBJECTS*16; if (!have_flag(argc, argv, "simple")) { - data.scratch = secp256k1_scratch_space_create(data.ctx, scratch_size); + data.scratch = secp256k1_scratch_create(&data.ctx->error_callback, scratch_size); } else { data.scratch = NULL; } @@ -384,7 +384,7 @@ int main(int argc, char **argv) { } if (data.scratch != NULL) { - secp256k1_scratch_space_destroy(data.ctx, data.scratch); + secp256k1_scratch_destroy(&data.ctx->error_callback, data.scratch); } secp256k1_context_destroy(data.ctx); free(data.scalars); diff --git a/src/bench_internal.c b/src/bench_internal.c index 8688a4dc77..378c21f544 100644 --- a/src/bench_internal.c +++ b/src/bench_internal.c @@ -10,13 +10,8 @@ #include "../include/secp256k1.h" #include "assumptions.h" -#include "util.h" -#include "hash_impl.h" -#include "field_impl.h" -#include "group_impl.h" -#include "scalar_impl.h" -#include "ecmult_impl.h" #include "bench.h" +#include "util.h" static void help(int default_iters) { printf("Benchmarks various internal routines.\n"); diff --git a/src/ecdsa.h b/src/ecdsa.h index 4441b08398..157ff631b5 100644 --- a/src/ecdsa.h +++ b/src/ecdsa.h @@ -12,6 +12,7 @@ #include "scalar.h" #include "group.h" #include "ecmult.h" +#include "ecmult_gen.h" static int secp256k1_ecdsa_sig_parse(secp256k1_scalar *r, secp256k1_scalar *s, const unsigned char *sig, size_t size); static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const secp256k1_scalar *r, const secp256k1_scalar *s); diff --git a/src/ecmult_compute_table.h b/src/ecmult_compute_table.h index 665f87ff3d..9b0c385477 100644 --- a/src/ecmult_compute_table.h +++ b/src/ecmult_compute_table.h @@ -7,6 +7,8 @@ #ifndef SECP256K1_ECMULT_COMPUTE_TABLE_H #define SECP256K1_ECMULT_COMPUTE_TABLE_H +#include "group.h" + /* Construct table of all odd multiples of gen in range 1..(2**(window_g-1)-1). */ static void secp256k1_ecmult_compute_table(secp256k1_ge_storage* table, int window_g, const secp256k1_gej* gen); diff --git a/src/ecmult_gen.h b/src/ecmult_gen.h index 43dd10c38d..5fe959b9ff 100644 --- a/src/ecmult_gen.h +++ b/src/ecmult_gen.h @@ -134,6 +134,7 @@ typedef struct { static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context* ctx); static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context* ctx); +static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context* ctx); /** Multiply with the generator: R = a*G */ static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context* ctx, secp256k1_gej *r, const secp256k1_scalar *a); diff --git a/src/field.h b/src/field.h index 1f6ba7460f..f4b13f4b20 100644 --- a/src/field.h +++ b/src/field.h @@ -29,13 +29,6 @@ * implementation also provides a secp256k1_fe_verify routine to verify that * these fields match the run-time value and perform internal consistency * checks. */ -#ifdef VERIFY -# define SECP256K1_FE_VERIFY_FIELDS \ - int magnitude; \ - int normalized; -#else -# define SECP256K1_FE_VERIFY_FIELDS -#endif #if defined(SECP256K1_WIDEMUL_INT128) #include "field_5x52.h" diff --git a/src/field_10x26.h b/src/field_10x26.h index 203c10167c..c01d92c10b 100644 --- a/src/field_10x26.h +++ b/src/field_10x26.h @@ -30,7 +30,10 @@ typedef struct { * sum(i=0..9, n[i] << (i*26)) < p * (together these imply n[9] <= 2^22 - 1) */ - SECP256K1_FE_VERIFY_FIELDS +#ifdef VERIFY + int magnitude; + int normalized; +#endif } secp256k1_fe; /* Unpacks a constant into a overlapping multi-limbed FE element. */ diff --git a/src/field_10x26_impl.h b/src/field_10x26_impl.h index ea14c27318..009fb288d3 100644 --- a/src/field_10x26_impl.h +++ b/src/field_10x26_impl.h @@ -10,7 +10,7 @@ #include "checkmem.h" #include "util.h" #include "field.h" -#include "modinv32_impl.h" +#include "modinv32.h" #ifdef VERIFY static void secp256k1_fe_impl_verify(const secp256k1_fe *a) { diff --git a/src/field_5x52.h b/src/field_5x52.h index f20c246fdd..30cdf3bb10 100644 --- a/src/field_5x52.h +++ b/src/field_5x52.h @@ -30,7 +30,10 @@ typedef struct { * sum(i=0..4, n[i] << (i*52)) < p * (together these imply n[4] <= 2^48 - 1) */ - SECP256K1_FE_VERIFY_FIELDS +#ifdef VERIFY + int magnitude; + int normalized; +#endif } secp256k1_fe; /* Unpacks a constant into a overlapping multi-limbed FE element. */ diff --git a/src/field_5x52_impl.h b/src/field_5x52_impl.h index 46dca6b981..4f36743f66 100644 --- a/src/field_5x52_impl.h +++ b/src/field_5x52_impl.h @@ -10,7 +10,7 @@ #include "checkmem.h" #include "util.h" #include "field.h" -#include "modinv64_impl.h" +#include "modinv64.h" #include "field_5x52_int128_impl.h" diff --git a/src/group.h b/src/group.h index 05ae0d203c..5ad098980c 100644 --- a/src/group.h +++ b/src/group.h @@ -52,6 +52,68 @@ typedef struct { #define SECP256K1_GEJ_Y_MAGNITUDE_MAX 4 #define SECP256K1_GEJ_Z_MAGNITUDE_MAX 1 +/* Begin of section generated by sage/gen_exhaustive_groups.sage. */ +#define SECP256K1_G_ORDER_7 SECP256K1_GE_CONST(\ + 0x66625d13, 0x317ffe44, 0x63d32cff, 0x1ca02b9b,\ + 0xe5c6d070, 0x50b4b05e, 0x81cc30db, 0xf5166f0a,\ + 0x1e60e897, 0xa7c00c7c, 0x2df53eb6, 0x98274ff4,\ + 0x64252f42, 0x8ca44e17, 0x3b25418c, 0xff4ab0cf\ +) +#define SECP256K1_G_ORDER_13 SECP256K1_GE_CONST(\ + 0xa2482ff8, 0x4bf34edf, 0xa51262fd, 0xe57921db,\ + 0xe0dd2cb7, 0xa5914790, 0xbc71631f, 0xc09704fb,\ + 0x942536cb, 0xa3e49492, 0x3a701cc3, 0xee3e443f,\ + 0xdf182aa9, 0x15b8aa6a, 0x166d3b19, 0xba84b045\ +) +#define SECP256K1_G_ORDER_199 SECP256K1_GE_CONST(\ + 0x7fb07b5c, 0xd07c3bda, 0x553902e2, 0x7a87ea2c,\ + 0x35108a7f, 0x051f41e5, 0xb76abad5, 0x1f2703ad,\ + 0x0a251539, 0x5b4c4438, 0x952a634f, 0xac10dd4d,\ + 0x6d6f4745, 0x98990c27, 0x3a4f3116, 0xd32ff969\ +) +/** Generator for secp256k1, value 'g' defined in + * "Standards for Efficient Cryptography" (SEC2) 2.7.1. + */ +#define SECP256K1_G SECP256K1_GE_CONST(\ + 0x79be667e, 0xf9dcbbac, 0x55a06295, 0xce870b07,\ + 0x029bfcdb, 0x2dce28d9, 0x59f2815b, 0x16f81798,\ + 0x483ada77, 0x26a3c465, 0x5da4fbfc, 0x0e1108a8,\ + 0xfd17b448, 0xa6855419, 0x9c47d08f, 0xfb10d4b8\ +) +/* These exhaustive group test orders and generators are chosen such that: + * - The field size is equal to that of secp256k1, so field code is the same. + * - The curve equation is of the form y^2=x^3+B for some small constant B. + * - The subgroup has a generator 2*P, where P.x is as small as possible. + * - The subgroup has size less than 1000 to permit exhaustive testing. + * - The subgroup admits an endomorphism of the form lambda*(x,y) == (beta*x,y). + */ +#if defined(EXHAUSTIVE_TEST_ORDER) +# if EXHAUSTIVE_TEST_ORDER == 7 + +static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_G_ORDER_7; +#define SECP256K1_B 6 + +# elif EXHAUSTIVE_TEST_ORDER == 13 + +static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_G_ORDER_13; +#define SECP256K1_B 2 + +# elif EXHAUSTIVE_TEST_ORDER == 199 + +static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_G_ORDER_199; +#define SECP256K1_B 4 + +# else +# error No known generator for the specified exhaustive test group order. +# endif +#else + +static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_G; +#define SECP256K1_B 7 + +#endif +/* End of section generated by sage/gen_exhaustive_groups.sage. */ + /** Set a group element equal to the point with given X and Y coordinates */ static void secp256k1_ge_set_xy(secp256k1_ge *r, const secp256k1_fe *x, const secp256k1_fe *y); @@ -87,6 +149,12 @@ static void secp256k1_ge_set_all_gej(secp256k1_ge *r, const secp256k1_gej *a, si /** Set group elements r[0:len] (affine) equal to group elements a[0:len] (jacobian). */ static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len); +/** Set a group element (affine) equal to the group element with jacobian coordinates (a.x, a.y, 1/zi). */ +static void secp256k1_ge_set_gej_zinv(secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zi); + +/** Set a group element (affine) equal to the group element with jacobian coordinates (a.x, a.y, 1/zi). */ +static void secp256k1_ge_set_ge_zinv(secp256k1_ge *r, const secp256k1_ge *a, const secp256k1_fe *zi); + /** Bring a batch of inputs to the same global z "denominator", based on ratios between * (omitted) z coordinates of adjacent elements. * diff --git a/src/group_impl.h b/src/group_impl.h index b8f2395d93..a137d2a5c6 100644 --- a/src/group_impl.h +++ b/src/group_impl.h @@ -13,68 +13,6 @@ #include "group.h" #include "util.h" -/* Begin of section generated by sage/gen_exhaustive_groups.sage. */ -#define SECP256K1_G_ORDER_7 SECP256K1_GE_CONST(\ - 0x66625d13, 0x317ffe44, 0x63d32cff, 0x1ca02b9b,\ - 0xe5c6d070, 0x50b4b05e, 0x81cc30db, 0xf5166f0a,\ - 0x1e60e897, 0xa7c00c7c, 0x2df53eb6, 0x98274ff4,\ - 0x64252f42, 0x8ca44e17, 0x3b25418c, 0xff4ab0cf\ -) -#define SECP256K1_G_ORDER_13 SECP256K1_GE_CONST(\ - 0xa2482ff8, 0x4bf34edf, 0xa51262fd, 0xe57921db,\ - 0xe0dd2cb7, 0xa5914790, 0xbc71631f, 0xc09704fb,\ - 0x942536cb, 0xa3e49492, 0x3a701cc3, 0xee3e443f,\ - 0xdf182aa9, 0x15b8aa6a, 0x166d3b19, 0xba84b045\ -) -#define SECP256K1_G_ORDER_199 SECP256K1_GE_CONST(\ - 0x7fb07b5c, 0xd07c3bda, 0x553902e2, 0x7a87ea2c,\ - 0x35108a7f, 0x051f41e5, 0xb76abad5, 0x1f2703ad,\ - 0x0a251539, 0x5b4c4438, 0x952a634f, 0xac10dd4d,\ - 0x6d6f4745, 0x98990c27, 0x3a4f3116, 0xd32ff969\ -) -/** Generator for secp256k1, value 'g' defined in - * "Standards for Efficient Cryptography" (SEC2) 2.7.1. - */ -#define SECP256K1_G SECP256K1_GE_CONST(\ - 0x79be667e, 0xf9dcbbac, 0x55a06295, 0xce870b07,\ - 0x029bfcdb, 0x2dce28d9, 0x59f2815b, 0x16f81798,\ - 0x483ada77, 0x26a3c465, 0x5da4fbfc, 0x0e1108a8,\ - 0xfd17b448, 0xa6855419, 0x9c47d08f, 0xfb10d4b8\ -) -/* These exhaustive group test orders and generators are chosen such that: - * - The field size is equal to that of secp256k1, so field code is the same. - * - The curve equation is of the form y^2=x^3+B for some small constant B. - * - The subgroup has a generator 2*P, where P.x is as small as possible. - * - The subgroup has size less than 1000 to permit exhaustive testing. - * - The subgroup admits an endomorphism of the form lambda*(x,y) == (beta*x,y). - */ -#if defined(EXHAUSTIVE_TEST_ORDER) -# if EXHAUSTIVE_TEST_ORDER == 7 - -static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_G_ORDER_7; -#define SECP256K1_B 6 - -# elif EXHAUSTIVE_TEST_ORDER == 13 - -static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_G_ORDER_13; -#define SECP256K1_B 2 - -# elif EXHAUSTIVE_TEST_ORDER == 199 - -static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_G_ORDER_199; -#define SECP256K1_B 4 - -# else -# error No known generator for the specified exhaustive test group order. -# endif -#else - -static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_G; -#define SECP256K1_B 7 - -#endif -/* End of section generated by sage/gen_exhaustive_groups.sage. */ - static void secp256k1_ge_verify(const secp256k1_ge *a) { SECP256K1_FE_VERIFY(&a->x); SECP256K1_FE_VERIFY(&a->y); @@ -95,7 +33,6 @@ static void secp256k1_gej_verify(const secp256k1_gej *a) { (void)a; } -/* Set r to the affine coordinates of Jacobian point (a.x, a.y, 1/zi). */ static void secp256k1_ge_set_gej_zinv(secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zi) { secp256k1_fe zi2; secp256k1_fe zi3; @@ -112,7 +49,6 @@ static void secp256k1_ge_set_gej_zinv(secp256k1_ge *r, const secp256k1_gej *a, c SECP256K1_GE_VERIFY(r); } -/* Set r to the affine coordinates of Jacobian point (a.x, a.y, 1/zi). */ static void secp256k1_ge_set_ge_zinv(secp256k1_ge *r, const secp256k1_ge *a, const secp256k1_fe *zi) { secp256k1_fe zi2; secp256k1_fe zi3; diff --git a/src/hsort_impl.h b/src/hsort_impl.h index 1c674ff1c4..651ccc3e7a 100644 --- a/src/hsort_impl.h +++ b/src/hsort_impl.h @@ -8,6 +8,7 @@ #define SECP256K1_HSORT_IMPL_H #include "hsort.h" +#include "util.h" /* An array is a heap when, for all non-zero indexes i, the element at index i * compares as less than or equal to the element at index parent(i) = (i-1)/2. diff --git a/src/modinv64.h b/src/modinv64.h index f4208e6c23..86a414dc61 100644 --- a/src/modinv64.h +++ b/src/modinv64.h @@ -9,6 +9,8 @@ #include "util.h" +#include + #ifndef SECP256K1_WIDEMUL_INT128 #error "modinv64 requires 128-bit wide multiplication support" #endif diff --git a/src/precompute_ecmult.c b/src/precompute_ecmult.c index 021fe3940c..cdf57b9f60 100644 --- a/src/precompute_ecmult.c +++ b/src/precompute_ecmult.c @@ -16,6 +16,12 @@ #include "field_impl.h" #include "group_impl.h" #include "int128_impl.h" +#include "modinv32_impl.h" +#ifdef SECP256K1_WIDEMUL_INT128 +/* modinv64 is only available if we have an int128 implementation. */ +#include "modinv64_impl.h" +#endif + #include "ecmult.h" #include "ecmult_compute_table_impl.h" diff --git a/src/precompute_ecmult_gen.c b/src/precompute_ecmult_gen.c index cd0fe70fc2..cd3570b223 100644 --- a/src/precompute_ecmult_gen.c +++ b/src/precompute_ecmult_gen.c @@ -15,6 +15,12 @@ #include "group.h" #include "int128_impl.h" +#include "modinv32_impl.h" +#ifdef SECP256K1_WIDEMUL_INT128 +/* modinv64 is only available if we have an int128 implementation. */ +#include "modinv64_impl.h" +#endif + #include "ecmult_gen.h" #include "ecmult_gen_compute_table_impl.h" diff --git a/src/scalar.h b/src/scalar.h index 70f49b1cf2..773034ed27 100644 --- a/src/scalar.h +++ b/src/scalar.h @@ -10,6 +10,17 @@ #include "util.h" #if defined(EXHAUSTIVE_TEST_ORDER) +/* Begin of section generated by sage/gen_exhaustive_groups.sage. */ +# if EXHAUSTIVE_TEST_ORDER == 7 +# define EXHAUSTIVE_TEST_LAMBDA 2 +# elif EXHAUSTIVE_TEST_ORDER == 13 +# define EXHAUSTIVE_TEST_LAMBDA 9 +# elif EXHAUSTIVE_TEST_ORDER == 199 +# define EXHAUSTIVE_TEST_LAMBDA 92 +# else +# error No known lambda for the specified exhaustive test group order. +# endif +/* End of section generated by sage/gen_exhaustive_groups.sage. */ #include "scalar_low.h" #elif defined(SECP256K1_WIDEMUL_INT128) #include "scalar_4x64.h" @@ -19,6 +30,9 @@ #error "Please select wide multiplication implementation" #endif +static const secp256k1_scalar secp256k1_scalar_one = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 1); +static const secp256k1_scalar secp256k1_scalar_zero = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0); + /** Clear a scalar to prevent the leak of sensitive data. */ static void secp256k1_scalar_clear(secp256k1_scalar *r); diff --git a/src/scalar_4x64_impl.h b/src/scalar_4x64_impl.h index 807b9b70ab..1e11fc8abf 100644 --- a/src/scalar_4x64_impl.h +++ b/src/scalar_4x64_impl.h @@ -9,7 +9,9 @@ #include "checkmem.h" #include "int128.h" -#include "modinv64_impl.h" +#include "modinv64.h" +#include "scalar.h" +#include "scalar_4x64.h" #include "util.h" /* Limbs of the secp256k1 order. */ diff --git a/src/scalar_8x32_impl.h b/src/scalar_8x32_impl.h index 2610496052..0dbf612fa0 100644 --- a/src/scalar_8x32_impl.h +++ b/src/scalar_8x32_impl.h @@ -8,7 +8,9 @@ #define SECP256K1_SCALAR_REPR_IMPL_H #include "checkmem.h" -#include "modinv32_impl.h" +#include "modinv32.h" +#include "scalar.h" +#include "scalar_8x32.h" #include "util.h" /* Limbs of the secp256k1 order. */ diff --git a/src/scalar_impl.h b/src/scalar_impl.h index 0232a8c223..e65850f2f8 100644 --- a/src/scalar_impl.h +++ b/src/scalar_impl.h @@ -24,9 +24,6 @@ #error "Please select wide multiplication implementation" #endif -static const secp256k1_scalar secp256k1_scalar_one = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 1); -static const secp256k1_scalar secp256k1_scalar_zero = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0); - SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar *r) { secp256k1_memclear(r, sizeof(secp256k1_scalar)); } @@ -46,18 +43,6 @@ static void secp256k1_scalar_verify(const secp256k1_scalar *r) { } #if defined(EXHAUSTIVE_TEST_ORDER) -/* Begin of section generated by sage/gen_exhaustive_groups.sage. */ -# if EXHAUSTIVE_TEST_ORDER == 7 -# define EXHAUSTIVE_TEST_LAMBDA 2 -# elif EXHAUSTIVE_TEST_ORDER == 13 -# define EXHAUSTIVE_TEST_LAMBDA 9 -# elif EXHAUSTIVE_TEST_ORDER == 199 -# define EXHAUSTIVE_TEST_LAMBDA 92 -# else -# error No known lambda for the specified exhaustive test group order. -# endif -/* End of section generated by sage/gen_exhaustive_groups.sage. */ - /** * Find r1 and r2 given k, such that r1 + r2 * lambda == k mod n; unlike in the * full case we don't bother making r1 and r2 be small, we just want them to be diff --git a/src/scratch.h b/src/scratch.h index 6164330b39..8d325a6f51 100644 --- a/src/scratch.h +++ b/src/scratch.h @@ -7,6 +7,10 @@ #ifndef SECP256K1_SCRATCH_H #define SECP256K1_SCRATCH_H +#include "secp256k1_internal.h" + +#include + /* The typedef is used internally; the struct name is used in the public API * (where it is exposed as a different typedef) */ typedef struct secp256k1_scratch_space_struct { diff --git a/src/secp256k1.c b/src/secp256k1.c index 0915af7797..5ae16a4a15 100644 --- a/src/secp256k1.c +++ b/src/secp256k1.c @@ -20,23 +20,30 @@ #include "../include/secp256k1.h" #include "../include/secp256k1_preallocated.h" +#include "secp256k1_internal.h" + #include "assumptions.h" #include "checkmem.h" #include "util.h" -#include "field_impl.h" -#include "scalar_impl.h" -#include "group_impl.h" -#include "ecmult_impl.h" -#include "ecmult_const_impl.h" -#include "ecmult_gen_impl.h" #include "ecdsa_impl.h" #include "eckey_impl.h" +#include "ecmult_const_impl.h" +#include "ecmult_gen_impl.h" +#include "ecmult_impl.h" +#include "field_impl.h" +#include "group_impl.h" #include "hash_impl.h" +#include "hsort_impl.h" #include "int128_impl.h" +#include "modinv32_impl.h" +#ifdef SECP256K1_WIDEMUL_INT128 +/* modinv64 is only available if we have an int128 implementation. */ +#include "modinv64_impl.h" +#endif +#include "scalar_impl.h" #include "scratch_impl.h" -#include "selftest.h" -#include "hsort_impl.h" +#include "selftest_impl.h" #ifdef SECP256K1_NO_BUILD # error "secp256k1.h processed without SECP256K1_BUILD defined while building secp256k1.c" @@ -74,11 +81,6 @@ static const secp256k1_context secp256k1_context_static_ = { const secp256k1_context * const secp256k1_context_static = &secp256k1_context_static_; const secp256k1_context * const secp256k1_context_no_precomp = &secp256k1_context_static_; -/* Helper function that determines if a context is proper, i.e., is not the static context or a copy thereof. - * - * This is intended for "context" functions such as secp256k1_context_clone. Functions that need specific - * features of a context should still check for these features directly. For example, a function that needs - * ecmult_gen should directly check for the existence of the ecmult_gen context. */ static int secp256k1_context_is_proper(const secp256k1_context* ctx) { return secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx); } @@ -220,19 +222,6 @@ void secp256k1_context_set_error_callback(secp256k1_context* ctx, void (*fun)(co ctx->error_callback.data = data; } -static secp256k1_scratch_space* secp256k1_scratch_space_create(const secp256k1_context* ctx, size_t max_size) { - VERIFY_CHECK(ctx != NULL); - return secp256k1_scratch_create(&ctx->error_callback, max_size); -} - -static void secp256k1_scratch_space_destroy(const secp256k1_context *ctx, secp256k1_scratch_space* scratch) { - VERIFY_CHECK(ctx != NULL); - secp256k1_scratch_destroy(&ctx->error_callback, scratch); -} - -/* Mark memory as no-longer-secret for the purpose of analysing constant-time behaviour - * of the software. - */ static SECP256K1_INLINE void secp256k1_declassify(const secp256k1_context* ctx, const void *p, size_t len) { if (EXPECT(ctx->declassify, 0)) SECP256K1_CHECKMEM_DEFINE(p, len); } diff --git a/src/secp256k1_internal.h b/src/secp256k1_internal.h new file mode 100644 index 0000000000..8fbc266aa6 --- /dev/null +++ b/src/secp256k1_internal.h @@ -0,0 +1,43 @@ +/*********************************************************************** + * Copyright (c) 2013-2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_SECP256K1_INTERNAL_H +#define SECP256K1_SECP256K1_INTERNAL_H + +#include "../include/secp256k1.h" + +#include "ecmult_gen.h" +#include "group.h" +#include "scalar.h" +#include "util.h" + +/* Helper function that determines if a context is proper, i.e., is not the static context or a copy thereof. + * + * This is intended for "context" functions such as secp256k1_context_clone. Functions that need specific + * features of a context should still check for these features directly. For example, a function that needs + * ecmult_gen should directly check for the existence of the ecmult_gen context. */ +static int secp256k1_context_is_proper(const secp256k1_context* ctx); + +/* Mark memory as no-longer-secret for the purpose of analysing constant-time behaviour + * of the software. + */ +static SECP256K1_INLINE void secp256k1_declassify(const secp256k1_context* ctx, const void *p, size_t len); + +static int secp256k1_pubkey_load(const secp256k1_context* ctx, secp256k1_ge* ge, const secp256k1_pubkey* pubkey); +static void secp256k1_pubkey_save(secp256k1_pubkey* pubkey, secp256k1_ge* ge); + +static int secp256k1_ec_pubkey_sort_cmp(const void* pk1, const void* pk2, void *ctx); + +static void secp256k1_ecdsa_signature_load(const secp256k1_context* ctx, secp256k1_scalar* r, secp256k1_scalar* s, const secp256k1_ecdsa_signature* sig); +static void secp256k1_ecdsa_signature_save(secp256k1_ecdsa_signature* sig, const secp256k1_scalar* r, const secp256k1_scalar* s); + +static int secp256k1_ecdsa_sign_inner(const secp256k1_context* ctx, secp256k1_scalar* r, secp256k1_scalar* s, int* recid, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata); + +static int secp256k1_ec_pubkey_create_helper(const secp256k1_ecmult_gen_context *ecmult_gen_ctx, secp256k1_scalar *seckey_scalar, secp256k1_ge *p, const unsigned char *seckey); +static int secp256k1_ec_seckey_tweak_add_helper(secp256k1_scalar *sec, const unsigned char *tweak32); +static int secp256k1_ec_pubkey_tweak_add_helper(secp256k1_ge *p, const unsigned char *tweak32); + +#endif /* SECP256K1_SECP256K1_INTERNAL_H */ diff --git a/src/selftest.h b/src/selftest.h index d083ac9524..96dc6cd86f 100644 --- a/src/selftest.h +++ b/src/selftest.h @@ -7,26 +7,7 @@ #ifndef SECP256K1_SELFTEST_H #define SECP256K1_SELFTEST_H -#include "hash.h" - -#include - -static int secp256k1_selftest_sha256(void) { - static const char *input63 = "For this sample, this 63-byte string will be used as input data"; - static const unsigned char output32[32] = { - 0xf0, 0x8a, 0x78, 0xcb, 0xba, 0xee, 0x08, 0x2b, 0x05, 0x2a, 0xe0, 0x70, 0x8f, 0x32, 0xfa, 0x1e, - 0x50, 0xc5, 0xc4, 0x21, 0xaa, 0x77, 0x2b, 0xa5, 0xdb, 0xb4, 0x06, 0xa2, 0xea, 0x6b, 0xe3, 0x42, - }; - unsigned char out[32]; - secp256k1_sha256 hasher; - secp256k1_sha256_initialize(&hasher); - secp256k1_sha256_write(&hasher, (const unsigned char*)input63, 63); - secp256k1_sha256_finalize(&hasher, out); - return secp256k1_memcmp_var(out, output32, 32) == 0; -} - -static int secp256k1_selftest_passes(void) { - return secp256k1_selftest_sha256(); -} +static int secp256k1_selftest_sha256(void); +static int secp256k1_selftest_passes(void); #endif /* SECP256K1_SELFTEST_H */ diff --git a/src/selftest_impl.h b/src/selftest_impl.h new file mode 100644 index 0000000000..db89803ecb --- /dev/null +++ b/src/selftest_impl.h @@ -0,0 +1,34 @@ +/*********************************************************************** + * Copyright (c) 2020 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_SELFTEST_IMPL_H +#define SECP256K1_SELFTEST_IMPL_H + +#include "hash.h" +#include "selftest.h" +#include "util.h" + +#include + +static int secp256k1_selftest_sha256(void) { + static const char *input63 = "For this sample, this 63-byte string will be used as input data"; + static const unsigned char output32[32] = { + 0xf0, 0x8a, 0x78, 0xcb, 0xba, 0xee, 0x08, 0x2b, 0x05, 0x2a, 0xe0, 0x70, 0x8f, 0x32, 0xfa, 0x1e, + 0x50, 0xc5, 0xc4, 0x21, 0xaa, 0x77, 0x2b, 0xa5, 0xdb, 0xb4, 0x06, 0xa2, 0xea, 0x6b, 0xe3, 0x42, + }; + unsigned char out[32]; + secp256k1_sha256 hasher; + secp256k1_sha256_initialize(&hasher); + secp256k1_sha256_write(&hasher, (const unsigned char*)input63, 63); + secp256k1_sha256_finalize(&hasher, out); + return secp256k1_memcmp_var(out, output32, 32) == 0; +} + +static int secp256k1_selftest_passes(void) { + return secp256k1_selftest_sha256(); +} + +#endif /* SECP256K1_SELFTEST_IMPL_H */ diff --git a/src/testrand_impl.h b/src/testrand_impl.h index b84f5730a9..2ccbcd892d 100644 --- a/src/testrand_impl.h +++ b/src/testrand_impl.h @@ -10,6 +10,7 @@ #include #include #include +#include #include "testrand.h" #include "hash.h" diff --git a/src/tests.c b/src/tests.c index 0f7b0d4c4c..596bd3861a 100644 --- a/src/tests.c +++ b/src/tests.c @@ -8,8 +8,6 @@ #include #include -#include - #ifdef USE_EXTERNAL_DEFAULT_CALLBACKS #pragma message("Ignoring USE_EXTERNAL_CALLBACKS in tests.") #undef USE_EXTERNAL_DEFAULT_CALLBACKS @@ -29,12 +27,6 @@ #include "../contrib/lax_der_parsing.c" #include "../contrib/lax_der_privatekey_parsing.c" -#include "modinv32_impl.h" -#ifdef SECP256K1_WIDEMUL_INT128 -#include "modinv64_impl.h" -#include "int128_impl.h" -#endif - #define CONDITIONAL_TEST(cnt, nam) if (COUNT < (cnt)) { printf("Skipping %s (iteration count too low)\n", nam); } else static int COUNT = 16; @@ -357,11 +349,9 @@ static void run_scratch_tests(void) { secp256k1_scratch_space *scratch; secp256k1_scratch_space local_scratch; - /* Test public API */ - scratch = secp256k1_scratch_space_create(CTX, 1000); - CHECK(scratch != NULL); - /* Test internal API */ + scratch = secp256k1_scratch_create(&CTX->error_callback, 1000); + CHECK(scratch != NULL); CHECK(secp256k1_scratch_max_allocation(&CTX->error_callback, scratch, 0) == 1000); CHECK(secp256k1_scratch_max_allocation(&CTX->error_callback, scratch, 1) == 1000 - (ALIGNMENT - 1)); CHECK(scratch->alloc_size == 0); @@ -396,15 +386,15 @@ static void run_scratch_tests(void) { CHECK_ERROR_VOID(CTX, secp256k1_scratch_apply_checkpoint(&CTX->error_callback, scratch, (size_t) -1)); /* this is just wildly invalid */ /* try to use badly initialized scratch space */ - secp256k1_scratch_space_destroy(CTX, scratch); + secp256k1_scratch_destroy(&CTX->error_callback, scratch); memset(&local_scratch, 0, sizeof(local_scratch)); scratch = &local_scratch; CHECK_ERROR(CTX, secp256k1_scratch_max_allocation(&CTX->error_callback, scratch, 0)); CHECK_ERROR(CTX, secp256k1_scratch_alloc(&CTX->error_callback, scratch, 500)); - CHECK_ERROR_VOID(CTX, secp256k1_scratch_space_destroy(CTX, scratch)); + CHECK_ERROR_VOID(CTX, secp256k1_scratch_destroy(&CTX->error_callback, scratch)); /* Test that large integers do not wrap around in a bad way */ - scratch = secp256k1_scratch_space_create(CTX, 1000); + scratch = secp256k1_scratch_create(&CTX->error_callback, 1000); /* Try max allocation with a large number of objects. Only makes sense if * ALIGNMENT is greater than 1 because otherwise the objects take no extra * space. */ @@ -413,10 +403,10 @@ static void run_scratch_tests(void) { * ALIGNMENT > 1, otherwise it returns NULL anyway because the scratch * space is too small. */ CHECK(secp256k1_scratch_alloc(&CTX->error_callback, scratch, SIZE_MAX) == NULL); - secp256k1_scratch_space_destroy(CTX, scratch); + secp256k1_scratch_destroy(&CTX->error_callback, scratch); /* cleanup */ - secp256k1_scratch_space_destroy(CTX, NULL); /* no-op */ + secp256k1_scratch_destroy(&CTX->error_callback, NULL); /* no-op */ } static void run_ctz_tests(void) { @@ -5455,7 +5445,7 @@ static void test_ecmult_constants_2bit(void) { secp256k1_sha256 acc; unsigned char b32[32]; int i, j; - secp256k1_scratch_space *scratch = secp256k1_scratch_space_create(CTX, 65536); + secp256k1_scratch_space *scratch = secp256k1_scratch_create(&CTX->error_callback, 65536); /* Expected hash of all the computed points; created with an independent * implementation. */ @@ -5483,7 +5473,7 @@ static void test_ecmult_constants_2bit(void) { secp256k1_sha256_finalize(&acc, b32); CHECK(secp256k1_memcmp_var(b32, expected32, 32) == 0); - secp256k1_scratch_space_destroy(CTX, scratch); + secp256k1_scratch_destroy(&CTX->error_callback, scratch); } static void test_ecmult_constants_sha(uint32_t prefix, size_t iter, const unsigned char* expected32) { @@ -5499,7 +5489,7 @@ static void test_ecmult_constants_sha(uint32_t prefix, size_t iter, const unsign unsigned char b32[32]; unsigned char inp[6]; size_t i; - secp256k1_scratch_space *scratch = secp256k1_scratch_space_create(CTX, 65536); + secp256k1_scratch_space *scratch = secp256k1_scratch_create(&CTX->error_callback, 65536); inp[0] = prefix & 0xFF; inp[1] = (prefix >> 8) & 0xFF; @@ -5526,7 +5516,7 @@ static void test_ecmult_constants_sha(uint32_t prefix, size_t iter, const unsign secp256k1_sha256_finalize(&acc, b32); CHECK(secp256k1_memcmp_var(b32, expected32, 32) == 0); - secp256k1_scratch_space_destroy(CTX, scratch); + secp256k1_scratch_destroy(&CTX->error_callback, scratch); } static void run_ecmult_constants(void) { diff --git a/src/testutil.h b/src/testutil.h index 64b3bb41c0..0ecbbafc00 100644 --- a/src/testutil.h +++ b/src/testutil.h @@ -8,6 +8,8 @@ #include "field.h" #include "group.h" +#include "scalar.h" +#include "secp256k1_internal.h" #include "testrand.h" #include "util.h"