From 723e8ca8f7ee75126bac4240feeac825c23a0d44 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 8 May 2023 12:07:26 -0400 Subject: [PATCH 01/33] Remove randomness tests Our RNG has been replaced with Xoshiro256++, a well-analyzed RNG. Our unit tests should not be resposible for verifying its statistical qualities. --- src/tests.c | 76 ----------------------------------------------------- 1 file changed, 76 deletions(-) diff --git a/src/tests.c b/src/tests.c index 6d46b39d..462407be 100644 --- a/src/tests.c +++ b/src/tests.c @@ -804,78 +804,6 @@ static void run_tagged_sha256_tests(void) { CHECK(secp256k1_memcmp_var(hash32, hash_expected, sizeof(hash32)) == 0); } -/***** RANDOM TESTS *****/ - -static void test_rand_bits(int rand32, int bits) { - /* (1-1/2^B)^rounds[B] < 1/10^9, so rounds is the number of iterations to - * get a false negative chance below once in a billion */ - static const unsigned int rounds[7] = {1, 30, 73, 156, 322, 653, 1316}; - /* We try multiplying the results with various odd numbers, which shouldn't - * influence the uniform distribution modulo a power of 2. */ - static const uint32_t mults[6] = {1, 3, 21, 289, 0x9999, 0x80402011}; - /* We only select up to 6 bits from the output to analyse */ - unsigned int usebits = bits > 6 ? 6 : bits; - unsigned int maxshift = bits - usebits; - /* For each of the maxshift+1 usebits-bit sequences inside a bits-bit - number, track all observed outcomes, one per bit in a uint64_t. */ - uint64_t x[6][27] = {{0}}; - unsigned int i, shift, m; - /* Multiply the output of all rand calls with the odd number m, which - should not change the uniformity of its distribution. */ - for (i = 0; i < rounds[usebits]; i++) { - uint32_t r = (rand32 ? secp256k1_testrand32() : secp256k1_testrand_bits(bits)); - CHECK((((uint64_t)r) >> bits) == 0); - for (m = 0; m < sizeof(mults) / sizeof(mults[0]); m++) { - uint32_t rm = r * mults[m]; - for (shift = 0; shift <= maxshift; shift++) { - x[m][shift] |= (((uint64_t)1) << ((rm >> shift) & ((1 << usebits) - 1))); - } - } - } - for (m = 0; m < sizeof(mults) / sizeof(mults[0]); m++) { - for (shift = 0; shift <= maxshift; shift++) { - /* Test that the lower usebits bits of x[shift] are 1 */ - CHECK(((~x[m][shift]) << (64 - (1 << usebits))) == 0); - } - } -} - -/* Subrange must be a whole divisor of range, and at most 64 */ -static void test_rand_int(uint32_t range, uint32_t subrange) { - /* (1-1/subrange)^rounds < 1/10^9 */ - int rounds = (subrange * 2073) / 100; - int i; - uint64_t x = 0; - CHECK((range % subrange) == 0); - for (i = 0; i < rounds; i++) { - uint32_t r = secp256k1_testrand_int(range); - CHECK(r < range); - r = r % subrange; - x |= (((uint64_t)1) << r); - } - /* Test that the lower subrange bits of x are 1. */ - CHECK(((~x) << (64 - subrange)) == 0); -} - -static void run_rand_bits(void) { - size_t b; - test_rand_bits(1, 32); - for (b = 1; b <= 32; b++) { - test_rand_bits(0, b); - } -} - -static void run_rand_int(void) { - static const uint32_t ms[] = {1, 3, 17, 1000, 13771, 999999, 33554432}; - static const uint32_t ss[] = {1, 3, 6, 9, 13, 31, 64}; - unsigned int m, s; - for (m = 0; m < sizeof(ms) / sizeof(ms[0]); m++) { - for (s = 0; s < sizeof(ss) / sizeof(ss[0]); s++) { - test_rand_int(ms[m] * ss[s], ss[s]); - } - } -} - /***** MODINV TESTS *****/ /* Compute the modular inverse of (odd) x mod 2^64. */ @@ -7730,10 +7658,6 @@ int main(int argc, char **argv) { /* scratch tests */ run_scratch_tests(); - /* randomness tests */ - run_rand_bits(); - run_rand_int(); - /* integer arithmetic tests */ #ifdef SECP256K1_WIDEMUL_INT128 run_int128_tests(); From fb5bfa4eed834dcd58109525408a2d88dabc48c5 Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Tue, 9 May 2023 18:07:11 +0200 Subject: [PATCH 02/33] Add static test vector for Xoshiro256++ --- src/tests.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/tests.c b/src/tests.c index 462407be..664c541d 100644 --- a/src/tests.c +++ b/src/tests.c @@ -172,6 +172,35 @@ static void random_scalar_order_b32(unsigned char *b32) { secp256k1_scalar_get_b32(b32, &num); } +static void run_xoshiro256pp_tests(void) { + { + size_t i; + /* Sanity check that we run before the actual seeding. */ + for (i = 0; i < sizeof(secp256k1_test_state)/sizeof(secp256k1_test_state[0]); i++) { + CHECK(secp256k1_test_state[i] == 0); + } + } + { + int i; + unsigned char buf32[32]; + unsigned char seed16[16] = { + 'C', 'H', 'I', 'C', 'K', 'E', 'N', '!', + 'C', 'H', 'I', 'C', 'K', 'E', 'N', '!', + }; + unsigned char buf32_expected[32] = { + 0xAF, 0xCC, 0xA9, 0x16, 0xB5, 0x6C, 0xE3, 0xF0, + 0x44, 0x3F, 0x45, 0xE0, 0x47, 0xA5, 0x08, 0x36, + 0x4C, 0xCC, 0xC1, 0x18, 0xB2, 0xD8, 0x8F, 0xEF, + 0x43, 0x26, 0x15, 0x57, 0x37, 0x00, 0xEF, 0x30, + }; + secp256k1_testrand_seed(seed16); + for (i = 0; i < 17; i++) { + secp256k1_testrand256(buf32); + } + CHECK(secp256k1_memcmp_var(buf32, buf32_expected, sizeof(buf32)) == 0); + } +} + static void run_selftest_tests(void) { /* Test public API */ secp256k1_selftest(); @@ -7621,6 +7650,9 @@ int main(int argc, char **argv) { } printf("test count = %i\n", COUNT); + /* run test RNG tests (must run before we really initialize the test RNG) */ + run_xoshiro256pp_tests(); + /* find random seed */ secp256k1_testrand_init(argc > 2 ? argv[2] : NULL); From 6ec3731e8c53658fcf68634c81bb1e47cad791ad Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 10 May 2023 10:40:08 -0400 Subject: [PATCH 03/33] Simplify test PRNG implementation --- src/testrand_impl.h | 65 ++++++++++++--------------------------------- 1 file changed, 17 insertions(+), 48 deletions(-) diff --git a/src/testrand_impl.h b/src/testrand_impl.h index 1b7481a5..fe976204 100644 --- a/src/testrand_impl.h +++ b/src/testrand_impl.h @@ -16,8 +16,6 @@ #include "util.h" static uint64_t secp256k1_test_state[4]; -static uint64_t secp256k1_test_rng_integer; -static int secp256k1_test_rng_integer_bits_left = 0; SECP256K1_INLINE static void secp256k1_testrand_seed(const unsigned char *seed16) { static const unsigned char PREFIX[19] = "secp256k1 test init"; @@ -36,7 +34,6 @@ SECP256K1_INLINE static void secp256k1_testrand_seed(const unsigned char *seed16 for (j = 0; j < 8; ++j) s = (s << 8) | out32[8*i + j]; secp256k1_test_state[i] = s; } - secp256k1_test_rng_integer_bits_left = 0; } SECP256K1_INLINE static uint64_t rotl(const uint64_t x, int k) { @@ -57,58 +54,30 @@ SECP256K1_INLINE static uint64_t secp256k1_testrand64(void) { } SECP256K1_INLINE static uint64_t secp256k1_testrand_bits(int bits) { - uint64_t ret; - if (secp256k1_test_rng_integer_bits_left < bits) { - secp256k1_test_rng_integer = secp256k1_testrand64(); - secp256k1_test_rng_integer_bits_left = 64; - } - ret = secp256k1_test_rng_integer; - secp256k1_test_rng_integer >>= bits; - secp256k1_test_rng_integer_bits_left -= bits; - ret &= ((~((uint64_t)0)) >> (64 - bits)); - return ret; + if (bits == 0) return 0; + return secp256k1_testrand64() >> (64 - bits); } SECP256K1_INLINE static uint32_t secp256k1_testrand32(void) { - return secp256k1_testrand_bits(32); + return secp256k1_testrand64() >> 32; } static uint32_t secp256k1_testrand_int(uint32_t range) { - /* We want a uniform integer between 0 and range-1, inclusive. - * B is the smallest number such that range <= 2**B. - * two mechanisms implemented here: - * - generate B bits numbers until one below range is found, and return it - * - find the largest multiple M of range that is <= 2**(B+A), generate B+A - * bits numbers until one below M is found, and return it modulo range - * The second mechanism consumes A more bits of entropy in every iteration, - * but may need fewer iterations due to M being closer to 2**(B+A) then - * range is to 2**B. The array below (indexed by B) contains a 0 when the - * first mechanism is to be used, and the number A otherwise. - */ - static const int addbits[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0}; - uint32_t trange, mult; - int bits = 0; - if (range <= 1) { - return 0; + uint32_t mask = 0; + uint32_t range_copy; + /* Reduce range by 1, changing its meaning to "maximum value". */ + VERIFY_CHECK(range != 0); + range -= 1; + /* Count the number of bits in range. */ + range_copy = range; + while (range_copy) { + mask = (mask << 1) | 1U; + range_copy >>= 1; } - trange = range - 1; - while (trange > 0) { - trange >>= 1; - bits++; - } - if (addbits[bits]) { - bits = bits + addbits[bits]; - mult = ((~((uint32_t)0)) >> (32 - bits)) / range; - trange = range * mult; - } else { - trange = range; - mult = 1; - } - while(1) { - uint32_t x = secp256k1_testrand_bits(bits); - if (x < trange) { - return (mult == 1) ? x : (x % range); - } + /* Generation loop. */ + while (1) { + uint32_t val = secp256k1_testrand64() & mask; + if (val <= range) return val; } } From 05873bb6b1041227f413626717b7af69fb6176ef Mon Sep 17 00:00:00 2001 From: Jonas Nick Date: Tue, 23 May 2023 18:32:15 +0000 Subject: [PATCH 04/33] tweak_add: fix API doc for tweak=0 --- include/secp256k1.h | 16 ++++++++-------- include/secp256k1_extrakeys.h | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/include/secp256k1.h b/include/secp256k1.h index a7a2be7a..398eb32d 100644 --- a/include/secp256k1.h +++ b/include/secp256k1.h @@ -733,10 +733,10 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_negate( * invalid according to secp256k1_ec_seckey_verify, this * function returns 0. seckey will be set to some unspecified * value if this function returns 0. - * In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid according to - * secp256k1_ec_seckey_verify, this function returns 0. For - * uniformly random 32-byte arrays the chance of being invalid - * is negligible (around 1 in 2^128). + * In: tweak32: pointer to a 32-byte tweak, which must be valid according to + * secp256k1_ec_seckey_verify or 32 zero bytes. For uniformly + * random 32-byte tweaks, the chance of being invalid is + * negligible (around 1 in 2^128). */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_add( const secp256k1_context *ctx, @@ -761,10 +761,10 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add( * Args: ctx: pointer to a context object. * In/Out: pubkey: pointer to a public key object. pubkey will be set to an * invalid value if this function returns 0. - * In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid according to - * secp256k1_ec_seckey_verify, this function returns 0. For - * uniformly random 32-byte arrays the chance of being invalid - * is negligible (around 1 in 2^128). + * In: tweak32: pointer to a 32-byte tweak, which must be valid according to + * secp256k1_ec_seckey_verify or 32 zero bytes. For uniformly + * random 32-byte tweaks, the chance of being invalid is + * negligible (around 1 in 2^128). */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add( const secp256k1_context *ctx, diff --git a/include/secp256k1_extrakeys.h b/include/secp256k1_extrakeys.h index 52bba240..615a3fc3 100644 --- a/include/secp256k1_extrakeys.h +++ b/include/secp256k1_extrakeys.h @@ -112,10 +112,10 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_from_pubke * Out: output_pubkey: pointer to a public key to store the result. Will be set * to an invalid value if this function returns 0. * In: internal_pubkey: pointer to an x-only pubkey to apply the tweak to. - * tweak32: pointer to a 32-byte tweak. If the tweak is invalid - * according to secp256k1_ec_seckey_verify, this function - * returns 0. For uniformly random 32-byte arrays the - * chance of being invalid is negligible (around 1 in 2^128). + * tweak32: pointer to a 32-byte tweak, which must be valid + * according to secp256k1_ec_seckey_verify or 32 zero + * bytes. For uniformly random 32-byte tweaks, the chance of + * being invalid is negligible (around 1 in 2^128). */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add( const secp256k1_context *ctx, @@ -231,10 +231,10 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_pub( * Args: ctx: pointer to a context object. * In/Out: keypair: pointer to a keypair to apply the tweak to. Will be set to * an invalid value if this function returns 0. - * In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid according - * to secp256k1_ec_seckey_verify, this function returns 0. For - * uniformly random 32-byte arrays the chance of being invalid - * is negligible (around 1 in 2^128). + * In: tweak32: pointer to a 32-byte tweak, which must be valid according to + * secp256k1_ec_seckey_verify or 32 zero bytes. For uniformly + * random 32-byte tweaks, the chance of being invalid is + * negligible (around 1 in 2^128). */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_tweak_add( const secp256k1_context *ctx, From efa76c4bf7cab1c22aa476cd2730e891450ad4a0 Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Mon, 12 Jun 2023 23:36:57 +0200 Subject: [PATCH 05/33] group: remove unneeded normalize_weak in `secp256k1_ge_is_valid_var` After calculating the right-hand side of the elliptic curve equation (x^3 + 7), the field element `x3` has a magnitude of 2 (1 as result of `secp256k1_fe_mul`, then increased by 1 due to `secp256k1_fe_add_int`). This is fine for `secp256k1_fe_equal_var`, as the second parameter only requires the magnitude to not exceed 31, and the normalize_weak call can hence be dropped. --- src/group_impl.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/group_impl.h b/src/group_impl.h index 44d98434..83a45c2d 100644 --- a/src/group_impl.h +++ b/src/group_impl.h @@ -349,7 +349,6 @@ static int secp256k1_ge_is_valid_var(const secp256k1_ge *a) { secp256k1_fe_sqr(&y2, &a->y); secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x); secp256k1_fe_add_int(&x3, SECP256K1_B); - secp256k1_fe_normalize_weak(&x3); return secp256k1_fe_equal_var(&y2, &x3); } From be8ff3a02aeff87c60d49883a1b2afa8b2999bbe Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Tue, 13 Jun 2023 13:34:49 +0200 Subject: [PATCH 06/33] field: Static-assert that int args affecting magnitude are constant See #1001. --- src/field.h | 24 ++++++++++++++++++------ src/field_10x26_impl.h | 4 ++-- src/field_5x52_impl.h | 4 ++-- src/field_impl.h | 12 ++++++------ src/tests.c | 4 ++-- src/util.h | 13 +++++++++++++ 6 files changed, 43 insertions(+), 18 deletions(-) diff --git a/src/field.h b/src/field.h index e632f9e3..eceee9c8 100644 --- a/src/field.h +++ b/src/field.h @@ -88,8 +88,8 @@ static const secp256k1_fe secp256k1_const_beta = SECP256K1_FE_CONST( # define secp256k1_fe_set_b32_mod secp256k1_fe_impl_set_b32_mod # define secp256k1_fe_set_b32_limit secp256k1_fe_impl_set_b32_limit # define secp256k1_fe_get_b32 secp256k1_fe_impl_get_b32 -# define secp256k1_fe_negate secp256k1_fe_impl_negate -# define secp256k1_fe_mul_int secp256k1_fe_impl_mul_int +# define secp256k1_fe_negate_unchecked secp256k1_fe_impl_negate_unchecked +# define secp256k1_fe_mul_int_unchecked secp256k1_fe_impl_mul_int_unchecked # define secp256k1_fe_add secp256k1_fe_impl_add # define secp256k1_fe_mul secp256k1_fe_impl_mul # define secp256k1_fe_sqr secp256k1_fe_impl_sqr @@ -214,11 +214,17 @@ static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a); /** Negate a field element. * * On input, r does not need to be initialized. a must be a valid field element with - * magnitude not exceeding m. m must be an integer in [0,31]. + * magnitude not exceeding m. m must be an integer constant expression in [0,31]. * Performs {r = -a}. * On output, r will not be normalized, and will have magnitude m+1. */ -static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m); +#define secp256k1_fe_negate(r, a, m) ASSERT_INT_CONST_AND_DO(m, secp256k1_fe_negate_unchecked(r, a, m)) + +/** Like secp256k1_fe_negate_unchecked but m is not checked to be an integer constant expression. + * + * Should not be called directly outside of tests. + */ +static void secp256k1_fe_negate_unchecked(secp256k1_fe *r, const secp256k1_fe *a, int m); /** Add a small integer to a field element. * @@ -229,12 +235,18 @@ static void secp256k1_fe_add_int(secp256k1_fe *r, int a); /** Multiply a field element with a small integer. * - * On input, r must be a valid field element. a must be an integer in [0,32]. + * On input, r must be a valid field element. a must be an integer constant expression in [0,32]. * The magnitude of r times a must not exceed 32. * Performs {r *= a}. * On output, r's magnitude is multiplied by a, and r will not be normalized. */ -static void secp256k1_fe_mul_int(secp256k1_fe *r, int a); +#define secp256k1_fe_mul_int(r, a) ASSERT_INT_CONST_AND_DO(a, secp256k1_fe_mul_int_unchecked(r, a)) + +/** Like secp256k1_fe_mul_int but a is not checked to be an integer constant expression. + * + * Should not be called directly outside of tests. + */ +static void secp256k1_fe_mul_int_unchecked(secp256k1_fe *r, int a); /** Increment a field element by another. * diff --git a/src/field_10x26_impl.h b/src/field_10x26_impl.h index c1b32b80..8445db16 100644 --- a/src/field_10x26_impl.h +++ b/src/field_10x26_impl.h @@ -344,7 +344,7 @@ static void secp256k1_fe_impl_get_b32(unsigned char *r, const secp256k1_fe *a) { r[31] = a->n[0] & 0xff; } -SECP256K1_INLINE static void secp256k1_fe_impl_negate(secp256k1_fe *r, const secp256k1_fe *a, int m) { +SECP256K1_INLINE static void secp256k1_fe_impl_negate_unchecked(secp256k1_fe *r, const secp256k1_fe *a, int m) { /* For all legal values of m (0..31), the following properties hold: */ VERIFY_CHECK(0x3FFFC2FUL * 2 * (m + 1) >= 0x3FFFFFFUL * 2 * m); VERIFY_CHECK(0x3FFFFBFUL * 2 * (m + 1) >= 0x3FFFFFFUL * 2 * m); @@ -365,7 +365,7 @@ SECP256K1_INLINE static void secp256k1_fe_impl_negate(secp256k1_fe *r, const sec r->n[9] = 0x03FFFFFUL * 2 * (m + 1) - a->n[9]; } -SECP256K1_INLINE static void secp256k1_fe_impl_mul_int(secp256k1_fe *r, int a) { +SECP256K1_INLINE static void secp256k1_fe_impl_mul_int_unchecked(secp256k1_fe *r, int a) { r->n[0] *= a; r->n[1] *= a; r->n[2] *= a; diff --git a/src/field_5x52_impl.h b/src/field_5x52_impl.h index 0a4cc1a6..ecb70502 100644 --- a/src/field_5x52_impl.h +++ b/src/field_5x52_impl.h @@ -314,7 +314,7 @@ static void secp256k1_fe_impl_get_b32(unsigned char *r, const secp256k1_fe *a) { r[31] = a->n[0] & 0xFF; } -SECP256K1_INLINE static void secp256k1_fe_impl_negate(secp256k1_fe *r, const secp256k1_fe *a, int m) { +SECP256K1_INLINE static void secp256k1_fe_impl_negate_unchecked(secp256k1_fe *r, const secp256k1_fe *a, int m) { /* For all legal values of m (0..31), the following properties hold: */ VERIFY_CHECK(0xFFFFEFFFFFC2FULL * 2 * (m + 1) >= 0xFFFFFFFFFFFFFULL * 2 * m); VERIFY_CHECK(0xFFFFFFFFFFFFFULL * 2 * (m + 1) >= 0xFFFFFFFFFFFFFULL * 2 * m); @@ -329,7 +329,7 @@ SECP256K1_INLINE static void secp256k1_fe_impl_negate(secp256k1_fe *r, const sec r->n[4] = 0x0FFFFFFFFFFFFULL * 2 * (m + 1) - a->n[4]; } -SECP256K1_INLINE static void secp256k1_fe_impl_mul_int(secp256k1_fe *r, int a) { +SECP256K1_INLINE static void secp256k1_fe_impl_mul_int_unchecked(secp256k1_fe *r, int a) { r->n[0] *= a; r->n[1] *= a; r->n[2] *= a; diff --git a/src/field_impl.h b/src/field_impl.h index f9769a4a..2a0fba20 100644 --- a/src/field_impl.h +++ b/src/field_impl.h @@ -289,23 +289,23 @@ SECP256K1_INLINE static void secp256k1_fe_get_b32(unsigned char *r, const secp25 secp256k1_fe_impl_get_b32(r, a); } -static void secp256k1_fe_impl_negate(secp256k1_fe *r, const secp256k1_fe *a, int m); -SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m) { +static void secp256k1_fe_impl_negate_unchecked(secp256k1_fe *r, const secp256k1_fe *a, int m); +SECP256K1_INLINE static void secp256k1_fe_negate_unchecked(secp256k1_fe *r, const secp256k1_fe *a, int m) { secp256k1_fe_verify(a); VERIFY_CHECK(m >= 0 && m <= 31); VERIFY_CHECK(a->magnitude <= m); - secp256k1_fe_impl_negate(r, a, m); + secp256k1_fe_impl_negate_unchecked(r, a, m); r->magnitude = m + 1; r->normalized = 0; secp256k1_fe_verify(r); } -static void secp256k1_fe_impl_mul_int(secp256k1_fe *r, int a); -SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe *r, int a) { +static void secp256k1_fe_impl_mul_int_unchecked(secp256k1_fe *r, int a); +SECP256K1_INLINE static void secp256k1_fe_mul_int_unchecked(secp256k1_fe *r, int a) { secp256k1_fe_verify(r); VERIFY_CHECK(a >= 0 && a <= 32); VERIFY_CHECK(a*r->magnitude <= 32); - secp256k1_fe_impl_mul_int(r, a); + secp256k1_fe_impl_mul_int_unchecked(r, a); r->magnitude *= a; r->normalized = 0; secp256k1_fe_verify(r); diff --git a/src/tests.c b/src/tests.c index e67891a8..838729e7 100644 --- a/src/tests.c +++ b/src/tests.c @@ -108,7 +108,7 @@ static void random_field_element_magnitude(secp256k1_fe *fe) { } secp256k1_fe_clear(&zero); secp256k1_fe_negate(&zero, &zero, 0); - secp256k1_fe_mul_int(&zero, n - 1); + secp256k1_fe_mul_int_unchecked(&zero, n - 1); secp256k1_fe_add(fe, &zero); #ifdef VERIFY CHECK(fe->magnitude == n); @@ -3223,7 +3223,7 @@ static void run_field_misc(void) { CHECK(q.normalized && q.magnitude == 1); #endif for (j = 0; j < 6; j++) { - secp256k1_fe_negate(&z, &z, j+1); + secp256k1_fe_negate_unchecked(&z, &z, j+1); secp256k1_fe_normalize_var(&q); secp256k1_fe_cmov(&q, &z, (j&1)); #ifdef VERIFY diff --git a/src/util.h b/src/util.h index 0e3faf02..5e6c65d3 100644 --- a/src/util.h +++ b/src/util.h @@ -51,6 +51,19 @@ static void print_buf_plain(const unsigned char *buf, size_t len) { # define SECP256K1_INLINE inline # endif +/** Assert statically that expr is an integer constant expression, and run stmt. + * + * Useful for example to enforce that magnitude arguments are constant. + */ +#define ASSERT_INT_CONST_AND_DO(expr, stmt) do { \ + switch(42) { \ + case /* ERROR: integer argument is not constant */ expr: \ + break; \ + default: ; \ + } \ + stmt; \ +} while(0) + typedef struct { void (*fn)(const char *text, void* data); const void* data; From 7d8d5c86df8b27b45e80ed50341dd0ce64546c0f Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Sun, 25 Jun 2023 22:14:13 +0200 Subject: [PATCH 07/33] tests: refactor: take use of `secp256k1_ge_x_on_curve_var` The recently merged ellswift PR (#1129) introduced a helper `secp256k1_ge_x_on_curve_var` to check if a given X coordinate is valid (i.e. the expression x^3 + 7 is square, see commit 79e5b2a8b80f507e2c9936ff1c4e2fb39bc66a4e). This can be used for code deduplication in the `ecmult_const_mult_xonly` test. --- src/tests.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/tests.c b/src/tests.c index 8ada3f86..fd106b8f 100644 --- a/src/tests.c +++ b/src/tests.c @@ -4611,17 +4611,14 @@ static void ecmult_const_mult_xonly(void) { /* Test that secp256k1_ecmult_const_xonly correctly rejects X coordinates not on curve. */ for (i = 0; i < 2*COUNT; ++i) { - secp256k1_fe x, n, d, c, r; + secp256k1_fe x, n, d, r; int res; secp256k1_scalar q; random_scalar_order_test(&q); /* Generate random X coordinate not on the curve. */ do { random_field_element_test(&x); - secp256k1_fe_sqr(&c, &x); - secp256k1_fe_mul(&c, &c, &x); - secp256k1_fe_add_int(&c, SECP256K1_B); - } while (secp256k1_fe_is_square_var(&c)); + } while (secp256k1_ge_x_on_curve_var(&x)); /* If i is odd, n=d*x for random non-zero d. */ if (i & 1) { do { From 304421d57b66670428de656ae6b3272c1ab6fde5 Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Mon, 26 Jun 2023 02:14:10 +0200 Subject: [PATCH 08/33] tests: refactor: remove duplicate function `random_field_element_test` There is a function `random_fe_test` which does exactly the same, so use that instead. Note that it's also moved up before the `random_group_element_test` function, in order to avoid needing a forward declaration. --- src/tests.c | 46 ++++++++++++++++++---------------------------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/src/tests.c b/src/tests.c index 21392d76..958c3472 100644 --- a/src/tests.c +++ b/src/tests.c @@ -89,16 +89,6 @@ static void uncounting_illegal_callback_fn(const char* str, void* data) { (*p)--; } -static void random_field_element_test(secp256k1_fe *fe) { - do { - unsigned char b32[32]; - secp256k1_testrand256_test(b32); - if (secp256k1_fe_set_b32_limit(fe, b32)) { - break; - } - } while(1); -} - static void random_field_element_magnitude(secp256k1_fe *fe) { secp256k1_fe zero; int n = secp256k1_testrand_int(9); @@ -115,10 +105,20 @@ static void random_field_element_magnitude(secp256k1_fe *fe) { #endif } +static void random_fe_test(secp256k1_fe *x) { + unsigned char bin[32]; + do { + secp256k1_testrand256_test(bin); + if (secp256k1_fe_set_b32_limit(x, bin)) { + return; + } + } while(1); +} + static void random_group_element_test(secp256k1_ge *ge) { secp256k1_fe fe; do { - random_field_element_test(&fe); + random_fe_test(&fe); if (secp256k1_ge_set_xo_var(ge, &fe, secp256k1_testrand_bits(1))) { secp256k1_fe_normalize(&ge->y); break; @@ -130,7 +130,7 @@ static void random_group_element_test(secp256k1_ge *ge) { static void random_group_element_jacobian_test(secp256k1_gej *gej, const secp256k1_ge *ge) { secp256k1_fe z2, z3; do { - random_field_element_test(&gej->z); + random_fe_test(&gej->z); if (!secp256k1_fe_is_zero(&gej->z)) { break; } @@ -2984,16 +2984,6 @@ static void random_fe(secp256k1_fe *x) { } while(1); } -static void random_fe_test(secp256k1_fe *x) { - unsigned char bin[32]; - do { - secp256k1_testrand256_test(bin); - if (secp256k1_fe_set_b32_limit(x, bin)) { - return; - } - } while(1); -} - static void random_fe_non_zero(secp256k1_fe *nz) { int tries = 10; while (--tries >= 0) { @@ -3821,7 +3811,7 @@ static void test_ge(void) { /* Generate random zf, and zfi2 = 1/zf^2, zfi3 = 1/zf^3 */ do { - random_field_element_test(&zf); + random_fe_test(&zf); } while(secp256k1_fe_is_zero(&zf)); random_field_element_magnitude(&zf); secp256k1_fe_inv_var(&zfi3, &zf); @@ -3830,7 +3820,7 @@ static void test_ge(void) { /* Generate random r */ do { - random_field_element_test(&r); + random_fe_test(&r); } while(secp256k1_fe_is_zero(&r)); for (i1 = 0; i1 < 1 + 4 * runs; i1++) { @@ -4148,7 +4138,7 @@ static void run_gej(void) { CHECK(!secp256k1_gej_eq_var(&a, &b)); b = a; - random_field_element_test(&fe); + random_fe_test(&fe); if (secp256k1_fe_is_zero(&fe)) { continue; } @@ -4591,7 +4581,7 @@ static void ecmult_const_mult_xonly(void) { /* If i is odd, n=d*base.x for random non-zero d */ if (i & 1) { do { - random_field_element_test(&d); + random_fe_test(&d); } while (secp256k1_fe_normalizes_to_zero_var(&d)); secp256k1_fe_mul(&n, &base.x, &d); } else { @@ -4617,12 +4607,12 @@ static void ecmult_const_mult_xonly(void) { random_scalar_order_test(&q); /* Generate random X coordinate not on the curve. */ do { - random_field_element_test(&x); + random_fe_test(&x); } while (secp256k1_ge_x_on_curve_var(&x)); /* If i is odd, n=d*x for random non-zero d. */ if (i & 1) { do { - random_field_element_test(&d); + random_fe_test(&d); } while (secp256k1_fe_normalizes_to_zero_var(&d)); secp256k1_fe_mul(&n, &x, &d); } else { From 5a95a268b944ffe64b7857e58f5b3b44aba514da Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Mon, 26 Jun 2023 02:42:06 +0200 Subject: [PATCH 09/33] tests: introduce helper for non-zero `random_fe_test` results There are several instances in the tests where random non-zero field elements are generated by calling `random_fe_test` in a do/while-loop. This commit deduplicates all these by introducing a `random_fe_non_zero_test` helper. Note that some instances checked the is-zero condition via `secp256k1_fe_normalizes_to_zero_var`, which is unnecessary, as the result of `random_fe_test` is already normalized (so strictly speaking, this is not a pure refactor). --- src/tests.c | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/src/tests.c b/src/tests.c index 958c3472..7b38d790 100644 --- a/src/tests.c +++ b/src/tests.c @@ -115,6 +115,12 @@ static void random_fe_test(secp256k1_fe *x) { } while(1); } +static void random_fe_non_zero_test(secp256k1_fe *fe) { + do { + random_fe_test(fe); + } while(secp256k1_fe_is_zero(fe)); +} + static void random_group_element_test(secp256k1_ge *ge) { secp256k1_fe fe; do { @@ -129,12 +135,7 @@ static void random_group_element_test(secp256k1_ge *ge) { static void random_group_element_jacobian_test(secp256k1_gej *gej, const secp256k1_ge *ge) { secp256k1_fe z2, z3; - do { - random_fe_test(&gej->z); - if (!secp256k1_fe_is_zero(&gej->z)) { - break; - } - } while(1); + random_fe_non_zero_test(&gej->z); secp256k1_fe_sqr(&z2, &gej->z); secp256k1_fe_mul(&z3, &z2, &gej->z); secp256k1_fe_mul(&gej->x, &ge->x, &z2); @@ -3810,18 +3811,14 @@ static void test_ge(void) { } /* Generate random zf, and zfi2 = 1/zf^2, zfi3 = 1/zf^3 */ - do { - random_fe_test(&zf); - } while(secp256k1_fe_is_zero(&zf)); + random_fe_non_zero_test(&zf); random_field_element_magnitude(&zf); secp256k1_fe_inv_var(&zfi3, &zf); secp256k1_fe_sqr(&zfi2, &zfi3); secp256k1_fe_mul(&zfi3, &zfi3, &zfi2); /* Generate random r */ - do { - random_fe_test(&r); - } while(secp256k1_fe_is_zero(&r)); + random_fe_non_zero_test(&r); for (i1 = 0; i1 < 1 + 4 * runs; i1++) { int i2; @@ -4138,10 +4135,7 @@ static void run_gej(void) { CHECK(!secp256k1_gej_eq_var(&a, &b)); b = a; - random_fe_test(&fe); - if (secp256k1_fe_is_zero(&fe)) { - continue; - } + random_fe_non_zero_test(&fe); secp256k1_gej_rescale(&a, &fe); CHECK(secp256k1_gej_eq_var(&a, &b)); } @@ -4580,9 +4574,7 @@ static void ecmult_const_mult_xonly(void) { random_scalar_order_test(&q); /* If i is odd, n=d*base.x for random non-zero d */ if (i & 1) { - do { - random_fe_test(&d); - } while (secp256k1_fe_normalizes_to_zero_var(&d)); + random_fe_non_zero_test(&d); secp256k1_fe_mul(&n, &base.x, &d); } else { n = base.x; @@ -4611,9 +4603,7 @@ static void ecmult_const_mult_xonly(void) { } while (secp256k1_ge_x_on_curve_var(&x)); /* If i is odd, n=d*x for random non-zero d. */ if (i & 1) { - do { - random_fe_test(&d); - } while (secp256k1_fe_normalizes_to_zero_var(&d)); + random_fe_non_zero_test(&d); secp256k1_fe_mul(&n, &x, &d); } else { n = x; From a6ca76cdf2a3d0aef091e3d26d7c6c8ee9c88e72 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Wed, 28 Jun 2023 07:45:57 +0100 Subject: [PATCH 10/33] Avoid `-Wmaybe-uninitialized` when compiling with `gcc -O1` --- src/ecmult_impl.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ecmult_impl.h b/src/ecmult_impl.h index f4624677..6d14c7ac 100644 --- a/src/ecmult_impl.h +++ b/src/ecmult_impl.h @@ -288,7 +288,9 @@ static void secp256k1_ecmult_strauss_wnaf(const struct secp256k1_strauss_state * } /* Bring them to the same Z denominator. */ - secp256k1_ge_table_set_globalz(ECMULT_TABLE_SIZE(WINDOW_A) * no, state->pre_a, state->aux); + if (no) { + secp256k1_ge_table_set_globalz(ECMULT_TABLE_SIZE(WINDOW_A) * no, state->pre_a, state->aux); + } for (np = 0; np < no; ++np) { for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) { From 5b9f37f136620b9c61cd66439904b2db266fba70 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Wed, 28 Jun 2023 07:46:40 +0100 Subject: [PATCH 11/33] ci: Add `CFLAGS: -O1` to task matrix --- .cirrus.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.cirrus.yml b/.cirrus.yml index 5a00b65a..a28b747e 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -86,6 +86,7 @@ task: - env: {BUILD: distcheck, WITH_VALGRIND: no, CTIMETESTS: no, BENCH: no} - env: {CPPFLAGS: -DDETERMINISTIC} - env: {CFLAGS: -O0, CTIMETESTS: no} + - env: {CFLAGS: -O1, RECOVERY: yes, ECDH: yes, SCHNORRSIG: yes, ELLSWIFT: yes} - env: { ECMULTGENPRECISION: 2, ECMULTWINDOW: 2 } - env: { ECMULTGENPRECISION: 8, ECMULTWINDOW: 4 } matrix: From 98579e297b19bbb23c924f21942eccdbd618de67 Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Sat, 1 Jul 2023 10:47:40 +0200 Subject: [PATCH 12/33] ci: Drop manual checkout of merge commit This is no longer necessary as of https://github.com/cirruslabs/cirrus-ci-docs/issues/791#issuecomment-1615691585 . --- .cirrus.yml | 20 -------------------- ci/cirrus.sh | 3 ++- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index 5a00b65a..b449bff1 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -54,12 +54,6 @@ cat_logs_snippet: &CAT_LOGS cat_ci_env_script: - env -merge_base_script_snippet: &MERGE_BASE - merge_base_script: - - if [ "$CIRRUS_PR" = "" ]; then exit 0; fi - - git fetch --depth=1 $CIRRUS_REPO_CLONE_URL "pull/${CIRRUS_PR}/merge" - - git checkout FETCH_HEAD # Use merged changes to detect silent merge conflicts - linux_container_snippet: &LINUX_CONTAINER container: dockerfile: ci/linux-debian.Dockerfile @@ -93,7 +87,6 @@ task: CC: gcc - env: CC: clang - << : *MERGE_BASE test_script: - ./ci/cirrus.sh << : *CAT_LOGS @@ -111,7 +104,6 @@ task: CC: i686-linux-gnu-gcc - env: CC: clang --target=i686-pc-linux-gnu -isystem /usr/i686-linux-gnu/include - << : *MERGE_BASE test_script: - ./ci/cirrus.sh << : *CAT_LOGS @@ -138,7 +130,6 @@ task: CC: clang brew_script: - brew install automake libtool gcc - << : *MERGE_BASE test_script: - ./ci/cirrus.sh << : *CAT_LOGS @@ -157,7 +148,6 @@ task: SCHNORRSIG: yes ELLSWIFT: yes CTIMETESTS: no - << : *MERGE_BASE test_script: # https://sourceware.org/bugzilla/show_bug.cgi?id=27008 - rm /etc/ld.so.cache @@ -180,7 +170,6 @@ task: matrix: - env: {} - env: {EXPERIMENTAL: yes, ASM: arm32} - << : *MERGE_BASE test_script: - ./ci/cirrus.sh << : *CAT_LOGS @@ -198,7 +187,6 @@ task: SCHNORRSIG: yes ELLSWIFT: yes CTIMETESTS: no - << : *MERGE_BASE test_script: - ./ci/cirrus.sh << : *CAT_LOGS @@ -216,7 +204,6 @@ task: SCHNORRSIG: yes ELLSWIFT: yes CTIMETESTS: no - << : *MERGE_BASE test_script: - ./ci/cirrus.sh << : *CAT_LOGS @@ -237,7 +224,6 @@ task: - name: "i686 (mingw32-w64): Windows (Debian stable, Wine)" env: HOST: i686-w64-mingw32 - << : *MERGE_BASE test_script: - ./ci/cirrus.sh << : *CAT_LOGS @@ -280,7 +266,6 @@ task: CC: /opt/msvc/bin/x86/cl AR: /opt/msvc/bin/x86/lib NM: /opt/msvc/bin/x86/dumpbin -symbols -headers - << : *MERGE_BASE test_script: - ./ci/cirrus.sh << : *CAT_LOGS @@ -325,7 +310,6 @@ task: - env: HOST: i686-linux-gnu CC: i686-linux-gnu-gcc - << : *MERGE_BASE test_script: - ./ci/cirrus.sh << : *CAT_LOGS @@ -352,7 +336,6 @@ task: ECMULTGENPRECISION: 2 ECMULTWINDOW: 2 CFLAGS: "-fsanitize=memory -g -O3" - << : *MERGE_BASE test_script: - ./ci/cirrus.sh << : *CAT_LOGS @@ -369,7 +352,6 @@ task: RECOVERY: yes SCHNORRSIG: yes ELLSWIFT: yes - << : *MERGE_BASE test_script: - ./ci/cirrus.sh << : *CAT_LOGS @@ -401,8 +383,6 @@ task: # Ignore MSBuild warning MSB8029. # See: https://learn.microsoft.com/en-us/visualstudio/msbuild/errors/msb8029?view=vs-2022 IgnoreWarnIntDirInTempDetected: 'true' - merge_script: - - PowerShell -NoLogo -Command if ($env:CIRRUS_PR -ne $null) { git fetch $env:CIRRUS_REPO_CLONE_URL pull/$env:CIRRUS_PR/merge; git reset --hard FETCH_HEAD; } configure_script: - '%x64_NATIVE_TOOLS%' - cmake -E env CFLAGS="/WX" cmake -G "Visual Studio 17 2022" -A x64 -S . -B build -DSECP256K1_ENABLE_MODULE_RECOVERY=ON -DSECP256K1_BUILD_EXAMPLES=ON diff --git a/ci/cirrus.sh b/ci/cirrus.sh index cb3c4219..48a9783c 100755 --- a/ci/cirrus.sh +++ b/ci/cirrus.sh @@ -4,7 +4,8 @@ set -eux export LC_ALL=C -# Print relevant CI environment to allow reproducing the job outside of CI. +# Print commit and relevant CI environment to allow reproducing the job outside of CI. +git show --no-patch print_environment() { # Turn off -x because it messes up the output set +x From a7bec34231b991ad0e1f686f6505a81749a2a8c7 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Mon, 3 Jul 2023 09:31:49 +0100 Subject: [PATCH 13/33] ci: Print commit in Windows container This change adds the same functionality to Windows containers that is already available in Linux containers. --- .cirrus.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.cirrus.yml b/.cirrus.yml index b449bff1..cec5ad8f 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -383,6 +383,9 @@ task: # Ignore MSBuild warning MSB8029. # See: https://learn.microsoft.com/en-us/visualstudio/msbuild/errors/msb8029?view=vs-2022 IgnoreWarnIntDirInTempDetected: 'true' + git_show_script: + # Print commit to allow reproducing the job outside of CI. + - git show --no-patch configure_script: - '%x64_NATIVE_TOOLS%' - cmake -E env CFLAGS="/WX" cmake -G "Visual Studio 17 2022" -A x64 -S . -B build -DSECP256K1_ENABLE_MODULE_RECOVERY=ON -DSECP256K1_BUILD_EXAMPLES=ON From ae9db95ceaa2605138fac9c237c640acea3f3bd6 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Fri, 30 Jun 2023 09:26:48 +0100 Subject: [PATCH 14/33] build: Introduce `SECP256K1_STATIC` macro for Windows users It is a non-Libtool-specific way to explicitly specify the user's intention to consume a static `libseck256k1`. This change allows to get rid of MSVC linker warnings LNK4217 and LNK4286. Also, it makes possible to merge the `SECP256K1_API` and `SECP256K1_API_VAR` into one. --- CHANGELOG.md | 3 +++ Makefile.am | 6 +++--- configure.ac | 6 ------ examples/CMakeLists.txt | 3 --- include/secp256k1.h | 8 ++++---- src/CMakeLists.txt | 1 + 6 files changed, 11 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7f2053e..dacb0a3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Document `doc/ellswift.md` which explains the mathematical background of the scheme. - The [paper](https://eprint.iacr.org/2022/759) on which the scheme is based. +#### Changed + - When consuming libsecp256k1 as a static library on Windows, the user must now define the `SECP256K1_STATIC` macro before including `secp256k1.h`. + ## [0.3.2] - 2023-05-13 We strongly recommend updating to 0.3.2 if you use or plan to use GCC >=13 to compile libsecp256k1. When in doubt, check the GCC version using `gcc -v`. diff --git a/Makefile.am b/Makefile.am index ee14ac45..32bc729a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -153,7 +153,7 @@ endif if USE_EXAMPLES noinst_PROGRAMS += ecdsa_example ecdsa_example_SOURCES = examples/ecdsa.c -ecdsa_example_CPPFLAGS = -I$(top_srcdir)/include +ecdsa_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC ecdsa_example_LDADD = libsecp256k1.la ecdsa_example_LDFLAGS = -static if BUILD_WINDOWS @@ -163,7 +163,7 @@ TESTS += ecdsa_example if ENABLE_MODULE_ECDH noinst_PROGRAMS += ecdh_example ecdh_example_SOURCES = examples/ecdh.c -ecdh_example_CPPFLAGS = -I$(top_srcdir)/include +ecdh_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC ecdh_example_LDADD = libsecp256k1.la ecdh_example_LDFLAGS = -static if BUILD_WINDOWS @@ -174,7 +174,7 @@ endif if ENABLE_MODULE_SCHNORRSIG noinst_PROGRAMS += schnorr_example schnorr_example_SOURCES = examples/schnorr.c -schnorr_example_CPPFLAGS = -I$(top_srcdir)/include +schnorr_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC schnorr_example_LDADD = libsecp256k1.la schnorr_example_LDFLAGS = -static if BUILD_WINDOWS diff --git a/configure.ac b/configure.ac index 82cf9513..a502d130 100644 --- a/configure.ac +++ b/configure.ac @@ -127,12 +127,6 @@ AC_DEFUN([SECP_TRY_APPEND_DEFAULT_CFLAGS], [ SECP_TRY_APPEND_CFLAGS([-wd4267], $1) # Disable warning C4267 "'var' : conversion from 'size_t' to 'type', possible loss of data". # Eliminate deprecation warnings for the older, less secure functions. CPPFLAGS="-D_CRT_SECURE_NO_WARNINGS $CPPFLAGS" - # We pass -ignore:4217 to the MSVC linker to suppress warning 4217 when - # importing variables from a statically linked secp256k1. - # (See the libtool manual, section "Windows DLLs" for background.) - # Unfortunately, libtool tries to be too clever and strips "-Xlinker arg" - # into "arg", so this will be " -Xlinker -ignore:4217" after stripping. - LDFLAGS="-Xlinker -Xlinker -Xlinker -ignore:4217 $LDFLAGS" fi ]) SECP_TRY_APPEND_DEFAULT_CFLAGS(SECP_CFLAGS) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index e095b7f8..e2ea4730 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -6,9 +6,6 @@ target_link_libraries(example INTERFACE secp256k1 $<$:bcrypt> ) -if(NOT BUILD_SHARED_LIBS AND MSVC) - target_link_options(example INTERFACE /IGNORE:4217) -endif() add_executable(ecdsa_example ecdsa.c) target_link_libraries(ecdsa_example example) diff --git a/include/secp256k1.h b/include/secp256k1.h index 01d18cff..4429bd34 100644 --- a/include/secp256k1.h +++ b/include/secp256k1.h @@ -141,10 +141,10 @@ typedef int (*secp256k1_nonce_function)( # define SECP256K1_API __declspec (dllexport) # define SECP256K1_API_VAR extern __declspec (dllexport) # endif -# elif defined _MSC_VER -# define SECP256K1_API -# define SECP256K1_API_VAR extern __declspec (dllimport) -# elif defined DLL_EXPORT + /* The user must define SECP256K1_STATIC when consuming libsecp256k1 as a static + * library on Windows. */ +# elif !defined(SECP256K1_STATIC) + /* Consuming libsecp256k1 as a DLL. */ # define SECP256K1_API __declspec (dllimport) # define SECP256K1_API_VAR extern __declspec (dllimport) # endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0bba1998..fd7c48fc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -24,6 +24,7 @@ endif() # This matches libtool's usage of DLL_EXPORT if(WIN32) set_target_properties(secp256k1 PROPERTIES DEFINE_SYMBOL "DLL_EXPORT") + target_compile_definitions(secp256k1 INTERFACE $<$>:SECP256K1_STATIC>) endif() # Object libs don't know if they're being built for a shared or static lib. From 9f1b1904a358e4ce7248c6542e8c7ac143ba0e3f Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Thu, 29 Jun 2023 17:07:50 +0100 Subject: [PATCH 15/33] refactor: Replace `SECP256K1_API_VAR` with `SECP256K1_API` --- include/secp256k1.h | 20 ++++++++------------ include/secp256k1_ecdh.h | 4 ++-- include/secp256k1_ellswift.h | 4 ++-- include/secp256k1_schnorrsig.h | 2 +- 4 files changed, 13 insertions(+), 17 deletions(-) diff --git a/include/secp256k1.h b/include/secp256k1.h index 4429bd34..9370906c 100644 --- a/include/secp256k1.h +++ b/include/secp256k1.h @@ -138,24 +138,20 @@ typedef int (*secp256k1_nonce_function)( #if defined(_WIN32) # ifdef SECP256K1_BUILD # ifdef DLL_EXPORT -# define SECP256K1_API __declspec (dllexport) -# define SECP256K1_API_VAR extern __declspec (dllexport) +# define SECP256K1_API extern __declspec (dllexport) # endif /* The user must define SECP256K1_STATIC when consuming libsecp256k1 as a static * library on Windows. */ # elif !defined(SECP256K1_STATIC) /* Consuming libsecp256k1 as a DLL. */ -# define SECP256K1_API __declspec (dllimport) -# define SECP256K1_API_VAR extern __declspec (dllimport) +# define SECP256K1_API extern __declspec (dllimport) # endif #endif #ifndef SECP256K1_API # if defined(__GNUC__) && (__GNUC__ >= 4) && defined(SECP256K1_BUILD) -# define SECP256K1_API __attribute__ ((visibility ("default"))) -# define SECP256K1_API_VAR extern __attribute__ ((visibility ("default"))) +# define SECP256K1_API extern __attribute__ ((visibility ("default"))) # else -# define SECP256K1_API -# define SECP256K1_API_VAR extern +# define SECP256K1_API extern # endif #endif @@ -227,10 +223,10 @@ typedef int (*secp256k1_nonce_function)( * * It is highly recommended to call secp256k1_selftest before using this context. */ -SECP256K1_API_VAR const secp256k1_context *secp256k1_context_static; +SECP256K1_API const secp256k1_context *secp256k1_context_static; /** Deprecated alias for secp256k1_context_static. */ -SECP256K1_API_VAR const secp256k1_context *secp256k1_context_no_precomp +SECP256K1_API const secp256k1_context *secp256k1_context_no_precomp SECP256K1_DEPRECATED("Use secp256k1_context_static instead"); /** Perform basic self tests (to be used in conjunction with secp256k1_context_static) @@ -627,10 +623,10 @@ SECP256K1_API int secp256k1_ecdsa_signature_normalize( * If a data pointer is passed, it is assumed to be a pointer to 32 bytes of * extra entropy. */ -SECP256K1_API_VAR const secp256k1_nonce_function secp256k1_nonce_function_rfc6979; +SECP256K1_API const secp256k1_nonce_function secp256k1_nonce_function_rfc6979; /** A default safe nonce generation function (currently equal to secp256k1_nonce_function_rfc6979). */ -SECP256K1_API_VAR const secp256k1_nonce_function secp256k1_nonce_function_default; +SECP256K1_API const secp256k1_nonce_function secp256k1_nonce_function_default; /** Create an ECDSA signature. * diff --git a/include/secp256k1_ecdh.h b/include/secp256k1_ecdh.h index 837ae2ab..515e1742 100644 --- a/include/secp256k1_ecdh.h +++ b/include/secp256k1_ecdh.h @@ -27,11 +27,11 @@ typedef int (*secp256k1_ecdh_hash_function)( /** An implementation of SHA256 hash function that applies to compressed public key. * Populates the output parameter with 32 bytes. */ -SECP256K1_API_VAR const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_sha256; +SECP256K1_API const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_sha256; /** A default ECDH hash function (currently equal to secp256k1_ecdh_hash_function_sha256). * Populates the output parameter with 32 bytes. */ -SECP256K1_API_VAR const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_default; +SECP256K1_API const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_default; /** Compute an EC Diffie-Hellman secret in constant time * diff --git a/include/secp256k1_ellswift.h b/include/secp256k1_ellswift.h index c0b89871..2b7e403c 100644 --- a/include/secp256k1_ellswift.h +++ b/include/secp256k1_ellswift.h @@ -72,7 +72,7 @@ typedef int (*secp256k1_ellswift_xdh_hash_function)( /** An implementation of an secp256k1_ellswift_xdh_hash_function which uses * SHA256(prefix64 || ell_a64 || ell_b64 || x32), where prefix64 is the 64-byte * array pointed to by data. */ -SECP256K1_API_VAR const secp256k1_ellswift_xdh_hash_function secp256k1_ellswift_xdh_hash_function_prefix; +SECP256K1_API const secp256k1_ellswift_xdh_hash_function secp256k1_ellswift_xdh_hash_function_prefix; /** An implementation of an secp256k1_ellswift_xdh_hash_function compatible with * BIP324. It returns H_tag(ell_a64 || ell_b64 || x32), where H_tag is the @@ -80,7 +80,7 @@ SECP256K1_API_VAR const secp256k1_ellswift_xdh_hash_function secp256k1_ellswift_ * to secp256k1_ellswift_xdh_hash_function_prefix with prefix64 set to * SHA256("bip324_ellswift_xonly_ecdh")||SHA256("bip324_ellswift_xonly_ecdh"). * The data argument is ignored. */ -SECP256K1_API_VAR const secp256k1_ellswift_xdh_hash_function secp256k1_ellswift_xdh_hash_function_bip324; +SECP256K1_API const secp256k1_ellswift_xdh_hash_function secp256k1_ellswift_xdh_hash_function_bip324; /** Construct a 64-byte ElligatorSwift encoding of a given pubkey. * diff --git a/include/secp256k1_schnorrsig.h b/include/secp256k1_schnorrsig.h index 1ee665fd..26358533 100644 --- a/include/secp256k1_schnorrsig.h +++ b/include/secp256k1_schnorrsig.h @@ -61,7 +61,7 @@ typedef int (*secp256k1_nonce_function_hardened)( * Therefore, to create BIP-340 compliant signatures, algo must be set to * "BIP0340/nonce" and algolen to 13. */ -SECP256K1_API_VAR const secp256k1_nonce_function_hardened secp256k1_nonce_function_bip340; +SECP256K1_API const secp256k1_nonce_function_hardened secp256k1_nonce_function_bip340; /** Data structure that contains additional arguments for schnorrsig_sign_custom. * From 0196e8ade16e2b2d8efadac01d8520205553ee39 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Thu, 29 Jun 2023 17:14:03 +0100 Subject: [PATCH 16/33] build: Introduce `SECP256k1_DLL_EXPORT` macro This change provides a way to build a shared library that is not tired to the Libtool-specific `DLL_EXPORT` macro. --- include/secp256k1.h | 8 +++++--- src/CMakeLists.txt | 5 ++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/include/secp256k1.h b/include/secp256k1.h index 9370906c..88b68df7 100644 --- a/include/secp256k1.h +++ b/include/secp256k1.h @@ -134,10 +134,12 @@ typedef int (*secp256k1_nonce_function)( #endif /* Symbol visibility. See https://gcc.gnu.org/wiki/Visibility */ -/* DLL_EXPORT is defined internally for shared builds */ #if defined(_WIN32) -# ifdef SECP256K1_BUILD -# ifdef DLL_EXPORT +# if defined(SECP256K1_BUILD) +# if defined(DLL_EXPORT) || defined(SECP256K1_DLL_EXPORT) + /* Building libsecp256k1 as a DLL. + * 1. If using Libtool, it defines DLL_EXPORT automatically. + * 2. In other cases, SECP256K1_DLL_EXPORT must be defined. */ # define SECP256K1_API extern __declspec (dllexport) # endif /* The user must define SECP256K1_STATIC when consuming libsecp256k1 as a static diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fd7c48fc..b305751b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -20,10 +20,9 @@ if(SECP256K1_ASM STREQUAL "arm32") target_link_libraries(secp256k1_asm INTERFACE secp256k1_asm_arm) endif() -# Define our export symbol only for Win32 and only for shared libs. -# This matches libtool's usage of DLL_EXPORT if(WIN32) - set_target_properties(secp256k1 PROPERTIES DEFINE_SYMBOL "DLL_EXPORT") + # Define our export symbol only for shared libs. + set_target_properties(secp256k1 PROPERTIES DEFINE_SYMBOL SECP256K1_DLL_EXPORT) target_compile_definitions(secp256k1 INTERFACE $<$>:SECP256K1_STATIC>) endif() From 020bf69a44ba700624d09de0c18ceb867369d24e Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Tue, 27 Jun 2023 15:22:44 +0200 Subject: [PATCH 17/33] build: Add extensive docs on visibility issues --- include/secp256k1.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/include/secp256k1.h b/include/secp256k1.h index 88b68df7..ce2145ae 100644 --- a/include/secp256k1.h +++ b/include/secp256k1.h @@ -133,8 +133,14 @@ typedef int (*secp256k1_nonce_function)( # define SECP256K1_NO_BUILD #endif -/* Symbol visibility. See https://gcc.gnu.org/wiki/Visibility */ +/* Symbol visibility. */ #if defined(_WIN32) + /* GCC for Windows (e.g., MinGW) accepts the __declspec syntax + * for MSVC compatibility. A __declspec declaration implies (but is not + * exactly equivalent to) __attribute__ ((visibility("default"))), and so we + * actually want __declspec even on GCC, see "Microsoft Windows Function + * Attributes" in the GCC manual and the recommendations in + * https://gcc.gnu.org/wiki/Visibility. */ # if defined(SECP256K1_BUILD) # if defined(DLL_EXPORT) || defined(SECP256K1_DLL_EXPORT) /* Building libsecp256k1 as a DLL. @@ -151,8 +157,10 @@ typedef int (*secp256k1_nonce_function)( #endif #ifndef SECP256K1_API # if defined(__GNUC__) && (__GNUC__ >= 4) && defined(SECP256K1_BUILD) + /* Building libsecp256k1 on non-Windows using GCC or compatible. */ # define SECP256K1_API extern __attribute__ ((visibility ("default"))) # else + /* All cases not captured above. */ # define SECP256K1_API extern # endif #endif From c6cd2b15a007ad0a2d5c4656ae641ba442d8b2fe Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Fri, 30 Jun 2023 09:32:57 +0100 Subject: [PATCH 18/33] ci: Add task for static library on Windows + CMake --- .cirrus.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.cirrus.yml b/.cirrus.yml index cec5ad8f..835b6b22 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -383,12 +383,17 @@ task: # Ignore MSBuild warning MSB8029. # See: https://learn.microsoft.com/en-us/visualstudio/msbuild/errors/msb8029?view=vs-2022 IgnoreWarnIntDirInTempDetected: 'true' + matrix: + - env: + BUILD_SHARED_LIBS: ON + - env: + BUILD_SHARED_LIBS: OFF git_show_script: # Print commit to allow reproducing the job outside of CI. - git show --no-patch configure_script: - '%x64_NATIVE_TOOLS%' - - cmake -E env CFLAGS="/WX" cmake -G "Visual Studio 17 2022" -A x64 -S . -B build -DSECP256K1_ENABLE_MODULE_RECOVERY=ON -DSECP256K1_BUILD_EXAMPLES=ON + - cmake -E env CFLAGS="/WX" cmake -A x64 -B build -DSECP256K1_ENABLE_MODULE_RECOVERY=ON -DSECP256K1_BUILD_EXAMPLES=ON -DBUILD_SHARED_LIBS=%BUILD_SHARED_LIBS% build_script: - '%x64_NATIVE_TOOLS%' - cmake --build build --config RelWithDebInfo -- -property:UseMultiToolTask=true;CL_MPcount=5 From 07c0e8b82e2cea87f85263512945fed7adffea18 Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Wed, 14 Jun 2023 17:15:46 +0200 Subject: [PATCH 19/33] group: remove unneeded normalize_weak in `secp256k1_gej_eq_x_var` By requiring that the input group element's X coordinate (`a->x`) has a magnitude of <= 31, the normalize_weak call and also the field element variable `r2` are not needed anymore and hence can be dropped. --- src/group.h | 3 ++- src/group_impl.h | 10 +++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/group.h b/src/group.h index 77ad7435..85c40b8b 100644 --- a/src/group.h +++ b/src/group.h @@ -100,7 +100,8 @@ static void secp256k1_gej_set_ge(secp256k1_gej *r, const secp256k1_ge *a); /** Check two group elements (jacobian) for equality in variable time. */ static int secp256k1_gej_eq_var(const secp256k1_gej *a, const secp256k1_gej *b); -/** Compare the X coordinate of a group element (jacobian). */ +/** Compare the X coordinate of a group element (jacobian). + * The magnitude of the group element's X coordinate must not exceed 31. */ static int secp256k1_gej_eq_x_var(const secp256k1_fe *x, const secp256k1_gej *a); /** Set r equal to the inverse of a (i.e., mirrored around the X axis) */ diff --git a/src/group_impl.h b/src/group_impl.h index 83a45c2d..1176c7f2 100644 --- a/src/group_impl.h +++ b/src/group_impl.h @@ -314,13 +314,17 @@ static int secp256k1_gej_eq_var(const secp256k1_gej *a, const secp256k1_gej *b) } static int secp256k1_gej_eq_x_var(const secp256k1_fe *x, const secp256k1_gej *a) { - secp256k1_fe r, r2; + secp256k1_fe r; + +#ifdef VERIFY secp256k1_fe_verify(x); + VERIFY_CHECK(a->x.magnitude <= 31); secp256k1_gej_verify(a); VERIFY_CHECK(!a->infinity); +#endif + secp256k1_fe_sqr(&r, &a->z); secp256k1_fe_mul(&r, &r, x); - r2 = a->x; secp256k1_fe_normalize_weak(&r2); - return secp256k1_fe_equal_var(&r, &r2); + return secp256k1_fe_equal_var(&r, &a->x); } static void secp256k1_gej_neg(secp256k1_gej *r, const secp256k1_gej *a) { From b6b9834e8da7f3fd91b95f750a4ee7a10bf67435 Mon Sep 17 00:00:00 2001 From: Alejandro Date: Mon, 3 Jul 2023 15:21:21 +0200 Subject: [PATCH 20/33] small fixes restoring wycheproof files restoring wycheproof files2 --- examples/examples_util.h | 2 +- include/secp256k1_ellswift.h | 2 +- sage/group_prover.sage | 2 +- src/ecmult.h | 2 +- src/ecmult_const_impl.h | 2 +- src/field.h | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/examples_util.h b/examples/examples_util.h index 8e3a8f00..3293b640 100644 --- a/examples/examples_util.h +++ b/examples/examples_util.h @@ -95,7 +95,7 @@ static void secure_erase(void *ptr, size_t len) { * As best as we can tell, this is sufficient to break any optimisations that * might try to eliminate "superfluous" memsets. * This method used in memzero_explicit() the Linux kernel, too. Its advantage is that it is - * pretty efficient, because the compiler can still implement the memset() efficently, + * pretty efficient, because the compiler can still implement the memset() efficiently, * just not remove it entirely. See "Dead Store Elimination (Still) Considered Harmful" by * Yang et al. (USENIX Security 2017) for more background. */ diff --git a/include/secp256k1_ellswift.h b/include/secp256k1_ellswift.h index c0b89871..fafd01af 100644 --- a/include/secp256k1_ellswift.h +++ b/include/secp256k1_ellswift.h @@ -161,7 +161,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ellswift_create( /** Given a private key, and ElligatorSwift public keys sent in both directions, * compute a shared secret using x-only Elliptic Curve Diffie-Hellman (ECDH). * - * Returns: 1: shared secret was succesfully computed + * Returns: 1: shared secret was successfully computed * 0: secret was invalid or hashfp returned 0 * Args: ctx: pointer to a context object. * Out: output: pointer to an array to be filled by hashfp. diff --git a/sage/group_prover.sage b/sage/group_prover.sage index 9305c215..bb092953 100644 --- a/sage/group_prover.sage +++ b/sage/group_prover.sage @@ -198,7 +198,7 @@ def normalize_factor(p): (8) * (-bx + ax)^3 ``` """ - # Assert p is not 0 and that its non-zero coeffients are coprime. + # Assert p is not 0 and that its non-zero coefficients are coprime. # (We could just work with the primitive part p/p.content() but we want to be # aware if factor() does not return a primitive part in future sage versions.) assert p.content() == 1 diff --git a/src/ecmult.h b/src/ecmult.h index e28c6025..326a5eeb 100644 --- a/src/ecmult.h +++ b/src/ecmult.h @@ -22,7 +22,7 @@ # pragma message DEBUG_CONFIG_DEF(ECMULT_WINDOW_SIZE) #endif -/* Noone will ever need more than a window size of 24. The code might +/* No one will ever need more than a window size of 24. The code might * be correct for larger values of ECMULT_WINDOW_SIZE but this is not * tested. * diff --git a/src/ecmult_const_impl.h b/src/ecmult_const_impl.h index 26b3e238..06f9e53f 100644 --- a/src/ecmult_const_impl.h +++ b/src/ecmult_const_impl.h @@ -276,7 +276,7 @@ static int secp256k1_ecmult_const_xonly(secp256k1_fe* r, const secp256k1_fe *n, * * It is easy to verify that both (n*g, g^2, v) and its negation (n*g, -g^2, v) have affine X * coordinate n/d, and this holds even when the square root function doesn't have a - * determinstic sign. We choose the (n*g, g^2, v) version. + * deterministic sign. We choose the (n*g, g^2, v) version. * * Now switch to the effective affine curve using phi_v, where the input point has coordinates * (n*g, g^2). Compute (X, Y, Z) = q * (n*g, g^2) there. diff --git a/src/field.h b/src/field.h index 38e7389a..bb99f948 100644 --- a/src/field.h +++ b/src/field.h @@ -192,14 +192,14 @@ static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b); /** Set a field element equal to a provided 32-byte big endian value, reducing it. * - * On input, r does not need to be initalized. a must be a pointer to an initialized 32-byte array. + * On input, r does not need to be initialized. a must be a pointer to an initialized 32-byte array. * On output, r = a (mod p). It will have magnitude 1, and not be normalized. */ static void secp256k1_fe_set_b32_mod(secp256k1_fe *r, const unsigned char *a); /** Set a field element equal to a provided 32-byte big endian value, checking for overflow. * - * On input, r does not need to be initalized. a must be a pointer to an initialized 32-byte array. + * On input, r does not need to be initialized. a must be a pointer to an initialized 32-byte array. * On output, r = a if (a < p), it will be normalized with magnitude 1, and 1 is returned. * If a >= p, 0 is returned, and r will be made invalid (and must not be used without overwriting). */ From c7d900ffd18e88076920d4cd13fcdca210acd903 Mon Sep 17 00:00:00 2001 From: stratospher <44024636+stratospher@users.noreply.github.com> Date: Wed, 28 Jun 2023 01:30:27 +0530 Subject: [PATCH 21/33] doc: minor ellswift.md updates --- doc/ellswift.md | 4 ++-- include/secp256k1_ellswift.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/ellswift.md b/doc/ellswift.md index 7fbb7c17..9d60e6be 100644 --- a/doc/ellswift.md +++ b/doc/ellswift.md @@ -88,7 +88,7 @@ $$ \begin{array}{lcl} X(u, t) & = & \left\\{\begin{array}{ll} \dfrac{g(u) - t^2}{2t} & a = 0 \\ - \dfrac{g(u) + h(u)(Y_0(u) + X_0(u)t)^2}{X_0(u)(1 + h(u)t^2)} & a \neq 0 + \dfrac{g(u) + h(u)(Y_0(u) - X_0(u)t)^2}{X_0(u)(1 + h(u)t^2)} & a \neq 0 \end{array}\right. \\ Y(u, t) & = & \left\\{\begin{array}{ll} \dfrac{X(u, t) + t}{u \sqrt{-3}} = \dfrac{g(u) + t^2}{2tu\sqrt{-3}} & a = 0 \\ @@ -329,7 +329,7 @@ $t$ value for multiple $c$ inputs (thereby biasing that encoding): it requires $g(u)=0$ which is already outlawed on even-ordered curves and impossible on others; in the second it would trigger division by zero. * Curve-specific special cases also exist that need to be rejected, because they result in $(u,t)$ which is invalid to the decoder, or because of division by zero in the encoder: * For $a=0$ curves, when $u=0$ or when $t=0$. The latter can only be reached by the encoder when $g(u)=0$, which requires an even-ordered curve. - * For $a \neq 0$ curves, when $X_0(u)=0$, when $h(u)t^2 = -1$, or when $2w(u + 2v) = 2X_0(u)$ while also either $w \neq 2Y_0(u)$ or $h(u)=0$. + * For $a \neq 0$ curves, when $X_0(u)=0$, when $h(u)t^2 = -1$, or when $w(u + 2v) = 2X_0(u)$ while also either $w \neq 2Y_0(u)$ or $h(u)=0$. **Define** a version of $G_{c,u}(x)$ which deals with all these cases: * If $a=0$ and $u=0$, return $\bot.$ diff --git a/include/secp256k1_ellswift.h b/include/secp256k1_ellswift.h index c0b89871..fafd01af 100644 --- a/include/secp256k1_ellswift.h +++ b/include/secp256k1_ellswift.h @@ -161,7 +161,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ellswift_create( /** Given a private key, and ElligatorSwift public keys sent in both directions, * compute a shared secret using x-only Elliptic Curve Diffie-Hellman (ECDH). * - * Returns: 1: shared secret was succesfully computed + * Returns: 1: shared secret was successfully computed * 0: secret was invalid or hashfp returned 0 * Args: ctx: pointer to a context object. * Out: output: pointer to an array to be filled by hashfp. From 2792119278bcb2a0befce3fbc64c83578df54953 Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Tue, 4 Jul 2023 02:50:05 +0200 Subject: [PATCH 22/33] Add exhaustive test for ellswift (create+decode roundtrip) Co-authored-by: Pieter Wuille Co-authored-by: Tim Ruffing --- src/modules/ellswift/Makefile.am.include | 1 + src/modules/ellswift/tests_exhaustive_impl.h | 39 ++++++++++++++++++++ src/tests_exhaustive.c | 16 ++++++++ 3 files changed, 56 insertions(+) create mode 100644 src/modules/ellswift/tests_exhaustive_impl.h diff --git a/src/modules/ellswift/Makefile.am.include b/src/modules/ellswift/Makefile.am.include index e7efea29..8251231e 100644 --- a/src/modules/ellswift/Makefile.am.include +++ b/src/modules/ellswift/Makefile.am.include @@ -2,3 +2,4 @@ include_HEADERS += include/secp256k1_ellswift.h noinst_HEADERS += src/modules/ellswift/bench_impl.h noinst_HEADERS += src/modules/ellswift/main_impl.h noinst_HEADERS += src/modules/ellswift/tests_impl.h +noinst_HEADERS += src/modules/ellswift/tests_exhaustive_impl.h diff --git a/src/modules/ellswift/tests_exhaustive_impl.h b/src/modules/ellswift/tests_exhaustive_impl.h new file mode 100644 index 00000000..e002a8c0 --- /dev/null +++ b/src/modules/ellswift/tests_exhaustive_impl.h @@ -0,0 +1,39 @@ +/*********************************************************************** + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_ELLSWIFT_TESTS_EXHAUSTIVE_H +#define SECP256K1_MODULE_ELLSWIFT_TESTS_EXHAUSTIVE_H + +#include "../../../include/secp256k1_ellswift.h" +#include "main_impl.h" + +static void test_exhaustive_ellswift(const secp256k1_context *ctx, const secp256k1_ge *group) { + int i; + + /* Note that SwiftEC/ElligatorSwift are inherently curve operations, not + * group operations, and this test only checks the curve points which are in + * a tiny subgroup. In that sense it can't be really seen as exhaustive as + * it doesn't (and for computational reasons obviously cannot) test the + * entire domain ellswift operates under. */ + for (i = 1; i < EXHAUSTIVE_TEST_ORDER; i++) { + secp256k1_scalar scalar_i; + unsigned char sec32[32]; + unsigned char ell64[64]; + secp256k1_pubkey pub_decoded; + secp256k1_ge ge_decoded; + + /* Construct ellswift pubkey from exhaustive loop scalar i. */ + secp256k1_scalar_set_int(&scalar_i, i); + secp256k1_scalar_get_b32(sec32, &scalar_i); + CHECK(secp256k1_ellswift_create(ctx, ell64, sec32, NULL)); + + /* Decode ellswift pubkey and check that it matches the precomputed group element. */ + secp256k1_ellswift_decode(ctx, &pub_decoded, ell64); + secp256k1_pubkey_load(ctx, &ge_decoded, &pub_decoded); + ge_equals_ge(&ge_decoded, &group[i]); + } +} + +#endif diff --git a/src/tests_exhaustive.c b/src/tests_exhaustive.c index d35acdd5..dbb6b7eb 100644 --- a/src/tests_exhaustive.c +++ b/src/tests_exhaustive.c @@ -13,6 +13,9 @@ #define EXHAUSTIVE_TEST_ORDER 13 #endif +/* These values of B are all values in [1, 8] that result in a curve with even order. */ +#define EXHAUSTIVE_TEST_CURVE_HAS_EVEN_ORDER (SECP256K1_B == 1 || SECP256K1_B == 6 || SECP256K1_B == 8) + #ifdef USE_EXTERNAL_DEFAULT_CALLBACKS #pragma message("Ignoring USE_EXTERNAL_CALLBACKS in exhaustive_tests.") #undef USE_EXTERNAL_DEFAULT_CALLBACKS @@ -395,6 +398,10 @@ static void test_exhaustive_sign(const secp256k1_context *ctx, const secp256k1_g #include "modules/schnorrsig/tests_exhaustive_impl.h" #endif +#ifdef ENABLE_MODULE_ELLSWIFT +#include "modules/ellswift/tests_exhaustive_impl.h" +#endif + int main(int argc, char** argv) { int i; secp256k1_gej groupj[EXHAUSTIVE_TEST_ORDER]; @@ -490,6 +497,15 @@ int main(int argc, char** argv) { #ifdef ENABLE_MODULE_SCHNORRSIG test_exhaustive_schnorrsig(ctx); #endif +#ifdef ENABLE_MODULE_ELLSWIFT + /* The ellswift algorithm does have additional edge cases when operating on + * curves of even order, which are not included in the code as secp256k1 is + * of odd order. Skip the ellswift tests if the used exhaustive tests curve + * is even-ordered accordingly. */ + #if !EXHAUSTIVE_TEST_CURVE_HAS_EVEN_ORDER + test_exhaustive_ellswift(ctx, group); + #endif +#endif secp256k1_context_destroy(ctx); } From b79ba8aa4c074b2cd09188f6f85ba68d6b80fe50 Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Thu, 29 Jun 2023 16:44:22 +0200 Subject: [PATCH 23/33] field: Use `restrict` consistently in fe_sqrt That is, use it also in the definition and not only the declaration. I believe this was the intention of commit be82bd8e0347e090037ff1d30a22a9d614db8c9f, but it was omitted there. --- src/field_impl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/field_impl.h b/src/field_impl.h index 2a0fba20..7f18ebdc 100644 --- a/src/field_impl.h +++ b/src/field_impl.h @@ -44,7 +44,7 @@ SECP256K1_INLINE static int secp256k1_fe_equal_var(const secp256k1_fe *a, const return secp256k1_fe_normalizes_to_zero_var(&na); } -static int secp256k1_fe_sqrt(secp256k1_fe *r, const secp256k1_fe *a) { +static int secp256k1_fe_sqrt(secp256k1_fe * SECP256K1_RESTRICT r, const secp256k1_fe * SECP256K1_RESTRICT a) { /** Given that p is congruent to 3 mod 4, we can compute the square root of * a mod p as the (p+1)/4'th power of a. * From 1deecaaf3b94dbf08896e015e7f1e5ec328a40f2 Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Thu, 11 May 2023 16:10:09 +0200 Subject: [PATCH 24/33] ci: Install development snapshots of gcc and clang TODO: Make sure the Docker image is actually rebuild --- ci/linux-debian.Dockerfile | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/ci/linux-debian.Dockerfile b/ci/linux-debian.Dockerfile index 0a5bd54e..bba7b302 100644 --- a/ci/linux-debian.Dockerfile +++ b/ci/linux-debian.Dockerfile @@ -1,5 +1,7 @@ FROM debian:stable +SHELL ["/bin/bash", "-c"] + RUN dpkg --add-architecture i386 && \ dpkg --add-architecture s390x && \ dpkg --add-architecture armhf && \ @@ -9,7 +11,7 @@ RUN dpkg --add-architecture i386 && \ # dkpg-dev: to make pkg-config work in cross-builds # llvm: for llvm-symbolizer, which is used by clang's UBSan for symbolized stack traces RUN apt-get update && apt-get install --no-install-recommends -y \ - git ca-certificates \ + git ca-certificates wget \ make automake libtool pkg-config dpkg-dev valgrind qemu-user \ gcc clang llvm libclang-rt-dev libc6-dbg \ g++ \ @@ -23,6 +25,38 @@ RUN apt-get update && apt-get install --no-install-recommends -y \ sagemath WORKDIR /root + +# Build and install gcc snapshot +ARG GCC_SNAPSHOT_MAJOR=14 +RUN wget --progress=dot:giga --https-only --recursive --accept '*.tar.xz' --level 1 --no-directories "https://gcc.gnu.org/pub/gcc/snapshots/LATEST-${GCC_SNAPSHOT_MAJOR}" && \ + wget "https://gcc.gnu.org/pub/gcc/snapshots/LATEST-${GCC_SNAPSHOT_MAJOR}/sha512.sum" && \ + sha512sum --check --ignore-missing sha512.sum && \ + # We should have downloaded exactly one tar.xz file + ls && \ + [[ $(ls *.tar.xz | wc -l) -eq "1" ]] && \ + tar xf *.tar.xz && \ + mkdir gcc-build && cd gcc-build && \ + apt-get update && apt-get install --no-install-recommends -y libgmp-dev libmpfr-dev libmpc-dev flex && \ + ../*/configure --prefix=/opt/gcc-snapshot --enable-languages=c --disable-bootstrap --disable-multilib --without-isl && \ + make -j $(nproc) && \ + make install && \ + ln -s /opt/gcc-snapshot/bin/gcc /usr/bin/gcc-snapshot + +# Install clang snapshot +RUN wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc && \ + # Add repository for this Debian release + . /etc/os-release && echo "deb http://apt.llvm.org/${VERSION_CODENAME} llvm-toolchain-${VERSION_CODENAME} main" >> /etc/apt/sources.list && \ + # Install clang snapshot + apt-get update && apt-get install --no-install-recommends -y clang && \ + # Remove just the "clang" symlink again + apt-get remove -y clang && \ + # We should have exactly two clang versions now + ls /usr/bin/clang* && \ + [[ $(ls /usr/bin/clang-?? | sort | wc -l) -eq "2" ]] && \ + # Create symlinks for them + ln -s $(ls /usr/bin/clang-?? | sort | tail -1) /usr/bin/clang-snapshot && \ + ln -s $(ls /usr/bin/clang-?? | sort | head -1) /usr/bin/clang + # The "wine" package provides a convience wrapper that we need RUN apt-get update && apt-get install --no-install-recommends -y \ git ca-certificates wine64 wine python3-simplejson python3-six msitools winbind procps && \ From 609093b3877b2fb21bd4bb2301a3eafb444a2fdb Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Sat, 13 May 2023 19:12:32 +0200 Subject: [PATCH 25/33] ci: Add x86_64 Linux tasks for gcc and clang snapshots --- .cirrus.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.cirrus.yml b/.cirrus.yml index 89eec3da..5c7b0244 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -62,7 +62,7 @@ linux_container_snippet: &LINUX_CONTAINER # Gives us more CPUs for free if they're available. greedy: true # More than enough for our scripts. - memory: 1G + memory: 2G task: name: "x86_64: Linux (Debian stable)" @@ -88,6 +88,10 @@ task: CC: gcc - env: CC: clang + - env: + CC: gcc-snapshot + - env: + CC: clang-snapshot test_script: - ./ci/cirrus.sh << : *CAT_LOGS From e9e96482196da641733a8a6763341a84f8b9806a Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Wed, 28 Jun 2023 17:51:21 +0200 Subject: [PATCH 26/33] ci: Reduce number of macOS tasks from 28 to 8 --- .cirrus.yml | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index 5c7b0244..ae205c62 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -67,7 +67,7 @@ linux_container_snippet: &LINUX_CONTAINER task: name: "x86_64: Linux (Debian stable)" << : *LINUX_CONTAINER - matrix: &ENV_MATRIX + matrix: - env: {WIDEMUL: int64, RECOVERY: yes} - env: {WIDEMUL: int64, ECDH: yes, SCHNORRSIG: yes, ELLSWIFT: yes} - env: {WIDEMUL: int128} @@ -122,17 +122,20 @@ task: HOMEBREW_NO_INSTALL_CLEANUP: 1 # Cirrus gives us a fixed number of 4 virtual CPUs. Not that we even have that many jobs at the moment... MAKEFLAGS: -j5 - matrix: - << : *ENV_MATRIX env: ASM: no WITH_VALGRIND: no CTIMETESTS: no + CC: clang matrix: - - env: - CC: gcc - - env: - CC: clang + - env: {WIDEMUL: int64, RECOVERY: yes, ECDH: yes, SCHNORRSIG: yes, ELLSWIFT: yes} + - env: {WIDEMUL: int64, RECOVERY: yes, ECDH: yes, SCHNORRSIG: yes, ELLSWIFT: yes, CC: gcc} + - env: {WIDEMUL: int128_struct, ECMULTGENPRECISION: 2, ECMULTWINDOW: 4} + - env: {WIDEMUL: int128, ECDH: yes, SCHNORRSIG: yes, ELLSWIFT: yes} + - env: {WIDEMUL: int128, RECOVERY: yes, SCHNORRSIG: yes} + - env: {WIDEMUL: int128, RECOVERY: yes, ECDH: yes, SCHNORRSIG: yes, ELLSWIFT: yes, CC: gcc} + - env: {WIDEMUL: int128, RECOVERY: yes, ECDH: yes, SCHNORRSIG: yes, ELLSWIFT: yes, CPPFLAGS: -DVERIFY} + - env: {BUILD: distcheck} brew_script: - brew install automake libtool gcc test_script: From 981e5be38c492f0c0230fbe61be555d157380331 Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Thu, 6 Jul 2023 20:19:07 +0200 Subject: [PATCH 27/33] ci: Fix typo in comment --- ci/linux-debian.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/linux-debian.Dockerfile b/ci/linux-debian.Dockerfile index bba7b302..dbb1dd29 100644 --- a/ci/linux-debian.Dockerfile +++ b/ci/linux-debian.Dockerfile @@ -57,7 +57,7 @@ RUN wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | tee /etc/apt/trusted. ln -s $(ls /usr/bin/clang-?? | sort | tail -1) /usr/bin/clang-snapshot && \ ln -s $(ls /usr/bin/clang-?? | sort | head -1) /usr/bin/clang -# The "wine" package provides a convience wrapper that we need +# The "wine" package provides a convenience wrapper that we need RUN apt-get update && apt-get install --no-install-recommends -y \ git ca-certificates wine64 wine python3-simplejson python3-six msitools winbind procps && \ # Workaround for `wine` package failure to employ the Debian alternatives system properly. From 600c5adcd59240305e22918943f45dceeabb7e93 Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Sun, 11 Jun 2023 16:38:12 +0200 Subject: [PATCH 28/33] clean up in-comment Sage code (refer to secp256k1_params.sage, update to Python3) Some of the C source files contain contain in-comment Sage code calculating secp256k1 parameters that are already defined in the file secp256k1_params.sage. Replace that by a corresponding load instruction and access the necessary variables. In ecdsa_impl.h, update the comment to use a one-line shell command calling sage to get the values. The remaining code (test `test_add_neg_y_diff_x` in tests.c) is updated to work with a current version based on Python3 (Sage 9.0+, see https://wiki.sagemath.org/Python3-Switch). The latter can be seen as a small follow-up to PR #849 (commit 13c88efed0005eb6745a222963ee74564054eafb). --- src/ecdsa_impl.h | 21 ++++----------------- src/tests.c | 17 +++++------------ 2 files changed, 9 insertions(+), 29 deletions(-) diff --git a/src/ecdsa_impl.h b/src/ecdsa_impl.h index 48e30851..e71254d9 100644 --- a/src/ecdsa_impl.h +++ b/src/ecdsa_impl.h @@ -16,17 +16,8 @@ #include "ecdsa.h" /** Group order for secp256k1 defined as 'n' in "Standards for Efficient Cryptography" (SEC2) 2.7.1 - * sage: for t in xrange(1023, -1, -1): - * .. p = 2**256 - 2**32 - t - * .. if p.is_prime(): - * .. print '%x'%p - * .. break - * 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f' - * sage: a = 0 - * sage: b = 7 - * sage: F = FiniteField (p) - * sage: '%x' % (EllipticCurve ([F (a), F (b)]).order()) - * 'fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141' + * $ sage -c 'load("secp256k1_params.sage"); print(hex(N))' + * 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141 */ static const secp256k1_fe secp256k1_ecdsa_const_order_as_fe = SECP256K1_FE_CONST( 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL, @@ -35,12 +26,8 @@ static const secp256k1_fe secp256k1_ecdsa_const_order_as_fe = SECP256K1_FE_CONST /** Difference between field and order, values 'p' and 'n' values defined in * "Standards for Efficient Cryptography" (SEC2) 2.7.1. - * sage: p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F - * sage: a = 0 - * sage: b = 7 - * sage: F = FiniteField (p) - * sage: '%x' % (p - EllipticCurve ([F (a), F (b)]).order()) - * '14551231950b75fc4402da1722fc9baee' + * $ sage -c 'load("secp256k1_params.sage"); print(hex(P-N))' + * 0x14551231950b75fc4402da1722fc9baee */ static const secp256k1_fe secp256k1_ecdsa_const_p_minus_order = SECP256K1_FE_CONST( 0, 0, 0, 1, 0x45512319UL, 0x50B75FC4UL, 0x402DA172UL, 0x2FC9BAEEUL diff --git a/src/tests.c b/src/tests.c index e67891a8..ca5a3145 100644 --- a/src/tests.c +++ b/src/tests.c @@ -4009,22 +4009,15 @@ static void test_add_neg_y_diff_x(void) { * which this test is a regression test for. * * These points were generated in sage as - * # secp256k1 params - * F = FiniteField (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F) - * C = EllipticCurve ([F (0), F (7)]) - * G = C.lift_x(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798) - * N = FiniteField(G.order()) * - * # endomorphism values (lambda is 1^{1/3} in N, beta is 1^{1/3} in F) - * x = polygen(N) - * lam = (1 - x^3).roots()[1][0] + * load("secp256k1_params.sage") * * # random "bad pair" * P = C.random_element() - * Q = -int(lam) * P - * print " P: %x %x" % P.xy() - * print " Q: %x %x" % Q.xy() - * print "P + Q: %x %x" % (P + Q).xy() + * Q = -int(LAMBDA) * P + * print(" P: %x %x" % P.xy()) + * print(" Q: %x %x" % Q.xy()) + * print("P + Q: %x %x" % (P + Q).xy()) */ secp256k1_gej aj = SECP256K1_GEJ_CONST( 0x8d24cd95, 0x0a355af1, 0x3c543505, 0x44238d30, From c424e2fb43c8ed959b2af7b2216028ce2a023488 Mon Sep 17 00:00:00 2001 From: Jonas Nick Date: Mon, 17 Jul 2023 09:28:09 +0000 Subject: [PATCH 29/33] ellswift: fix probabilistic test failure when swapping sides When configured with `--disable-module-ecdh --enable-module-recovery`, then `./tests 64 81af32fd7ab8c9cbc2e62a689f642106` fails with ``` src/modules/ellswift/tests_impl.h:396: test condition failed: secp256k1_memcmp_var(share32_bad, share32a, 32) != 0 ``` This tests verifies that changing the `party` bit of the `secp256k1_ellswift_xdh` function results in a different share. However, that's not the case when the secret keys of both parties are the same and this is actually what happens in the observed test failure. The keys can be equal in this test case because they are created by the `random_scalar_order_test` function whose output is not uniformly random (it's biased towards 0). This commit restores the assummption that the secret keys differ. --- src/modules/ellswift/tests_impl.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/modules/ellswift/tests_impl.h b/src/modules/ellswift/tests_impl.h index 86ca0986..47f443d9 100644 --- a/src/modules/ellswift/tests_impl.h +++ b/src/modules/ellswift/tests_impl.h @@ -322,7 +322,9 @@ void run_ellswift_tests(void) { secp256k1_testrand256_test(auxrnd32a); secp256k1_testrand256_test(auxrnd32b); random_scalar_order_test(&seca); - random_scalar_order_test(&secb); + /* Draw secb uniformly at random to make sure that the secret keys + * differ */ + random_scalar_order(&secb); secp256k1_scalar_get_b32(sec32a, &seca); secp256k1_scalar_get_b32(sec32b, &secb); From 4f8c5bd76132a0d0242c7a29b666153f927800bb Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Mon, 24 Jul 2023 13:14:23 +0100 Subject: [PATCH 30/33] refactor: Drop unused cast --- src/hash_impl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hash_impl.h b/src/hash_impl.h index 0991fe78..89f75ace 100644 --- a/src/hash_impl.h +++ b/src/hash_impl.h @@ -138,7 +138,7 @@ static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char * } if (len) { /* Fill the buffer with what remains. */ - memcpy(((unsigned char*)hash->buf) + bufsize, data, len); + memcpy(hash->buf + bufsize, data, len); } } From b097a466c168dcdb3fde435ec4a1e0b63609f55d Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 25 Jul 2023 20:35:57 +0000 Subject: [PATCH 31/33] util: remove unused checked_realloc Usage was removed in 6fe50439 . --- src/util.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/util.h b/src/util.h index 801ea0c8..cf7e5d1a 100644 --- a/src/util.h +++ b/src/util.h @@ -152,14 +152,6 @@ static SECP256K1_INLINE void *checked_malloc(const secp256k1_callback* cb, size_ return ret; } -static SECP256K1_INLINE void *checked_realloc(const secp256k1_callback* cb, void *ptr, size_t size) { - void *ret = realloc(ptr, size); - if (ret == NULL) { - secp256k1_callback_call(cb, "Out of memory"); - } - return ret; -} - #if defined(__BIGGEST_ALIGNMENT__) #define ALIGNMENT __BIGGEST_ALIGNMENT__ #else From 78ca8807880def68a575b2487f374fdf4b49962d Mon Sep 17 00:00:00 2001 From: Jonas Nick Date: Wed, 26 Jul 2023 14:44:20 +0000 Subject: [PATCH 32/33] build: enable ellswift module via SECP_CONFIG_DEFINES ...like the other modules. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index a502d130..18784967 100644 --- a/configure.ac +++ b/configure.ac @@ -401,7 +401,7 @@ if test x"$enable_module_schnorrsig" = x"yes"; then fi if test x"$enable_module_ellswift" = x"yes"; then - AC_DEFINE(ENABLE_MODULE_ELLSWIFT, 1, [Define this symbol to enable the ElligatorSwift module]) + SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_ELLSWIFT=1" fi # Test if extrakeys is set after the schnorrsig module to allow the schnorrsig From 4692478853df2149375d1447908a792fcf240fbf Mon Sep 17 00:00:00 2001 From: Jonas Nick Date: Thu, 27 Jul 2023 10:20:50 +0000 Subject: [PATCH 33/33] ci: print $ELLSWIFT in cirrus.sh --- ci/cirrus.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/cirrus.sh b/ci/cirrus.sh index 48a9783c..fe54b5ea 100755 --- a/ci/cirrus.sh +++ b/ci/cirrus.sh @@ -13,7 +13,7 @@ print_environment() { # does not rely on bash. for var in WERROR_CFLAGS MAKEFLAGS BUILD \ ECMULTWINDOW ECMULTGENPRECISION ASM WIDEMUL WITH_VALGRIND EXTRAFLAGS \ - EXPERIMENTAL ECDH RECOVERY SCHNORRSIG \ + EXPERIMENTAL ECDH RECOVERY SCHNORRSIG ELLSWIFT \ SECP256K1_TEST_ITERS BENCH SECP256K1_BENCH_ITERS CTIMETESTS\ EXAMPLES \ HOST WRAPPER_CMD \