test: adapt modules to the new test infrastructure
What changed, and why it matters
This commit is purely a test-code refactoring. It reorganizes how the project's test cases are registered and run, allowing individual tests to be selected and run in parallel. No production cryptographic code is changed, and there is no indication this fixes or introduces a security vulnerability.
No security action required. Treat as a normal test-framework maintenance commit.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit adapts module test headers (ecdh, ellswift, extrakeys, musig, recovery, schnorrsig) to a new test infrastructure. It replaces monolithic run_*_tests(void) functions with arrays of tf_test_entry test registries, adds unit_test.h includes, introduces CASE1 and REPEAT_TEST/REPEAT_TEST_MULT macros, and removes duplicate registry definitions from src/tests.c. Some test functions are renamed with an _internal suffix and wrapped by generated repeat loops. The changes are structural and confined to the test harness.
Changed components
src/modules/ecdh/tests_impl.hsrc/modules/ellswift/tests_impl.hsrc/modules/extrakeys/tests_impl.hsrc/modules/musig/tests_impl.hsrc/modules/recovery/tests_impl.hsrc/modules/schnorrsig/tests_impl.hsrc/tests.csrc/unit_test.hInspect captured patch +93 / −106
diff --git a/src/modules/ecdh/tests_impl.h b/src/modules/ecdh/tests_impl.h
index 6888f18..c1a5e73 100644
--- a/src/modules/ecdh/tests_impl.h
+++ b/src/modules/ecdh/tests_impl.h
@@ -7,6 +7,8 @@
#ifndef SECP256K1_MODULE_ECDH_TESTS_H
#define SECP256K1_MODULE_ECDH_TESTS_H
+#include "../../unit_test.h"
+
static int ecdh_hash_function_test_xpassthru(unsigned char *output, const unsigned char *x, const unsigned char *y, void *data) {
(void)y;
(void)data;
@@ -182,12 +184,13 @@ static void test_ecdh_wycheproof(void) {
}
}
-static void run_ecdh_tests(void) {
- test_ecdh_api();
- test_ecdh_generator_basepoint();
- test_bad_scalar();
- test_result_basepoint();
- test_ecdh_wycheproof();
-}
+/* --- Test registry --- */
+static const struct tf_test_entry tests_ecdh[] = {
+ CASE1(test_ecdh_api),
+ CASE1(test_ecdh_generator_basepoint),
+ CASE1(test_bad_scalar),
+ CASE1(test_result_basepoint),
+ CASE1(test_ecdh_wycheproof),
+};
#endif /* SECP256K1_MODULE_ECDH_TESTS_H */
diff --git a/src/modules/ellswift/tests_impl.h b/src/modules/ellswift/tests_impl.h
index b90fd0a..63c36e7 100644
--- a/src/modules/ellswift/tests_impl.h
+++ b/src/modules/ellswift/tests_impl.h
@@ -7,6 +7,7 @@
#define SECP256K1_MODULE_ELLSWIFT_TESTS_H
#include "../../../include/secp256k1_ellswift.h"
+#include "../../unit_test.h"
struct ellswift_xswiftec_inv_test {
int enc_bitmap;
@@ -433,4 +434,10 @@ void run_ellswift_tests(void) {
}
}
+/* --- Test registry --- */
+/* TODO: subdivide test in cases */
+static const struct tf_test_entry tests_ellswift[] = {
+ CASE(ellswift_tests),
+};
+
#endif
diff --git a/src/modules/extrakeys/tests_impl.h b/src/modules/extrakeys/tests_impl.h
index ab4ef4a..abebd11 100644
--- a/src/modules/extrakeys/tests_impl.h
+++ b/src/modules/extrakeys/tests_impl.h
@@ -8,6 +8,7 @@
#define SECP256K1_MODULE_EXTRAKEYS_TESTS_H
#include "../../../include/secp256k1_extrakeys.h"
+#include "../../unit_test.h"
static void test_xonly_pubkey(void) {
secp256k1_pubkey pk;
@@ -467,17 +468,17 @@ static void test_keypair_add(void) {
}
}
-static void run_extrakeys_tests(void) {
+/* --- Test registry --- */
+static const struct tf_test_entry tests_extrakeys[] = {
/* xonly key test cases */
- test_xonly_pubkey();
- test_xonly_pubkey_tweak();
- test_xonly_pubkey_tweak_check();
- test_xonly_pubkey_tweak_recursive();
- test_xonly_pubkey_comparison();
-
+ CASE1(test_xonly_pubkey),
+ CASE1(test_xonly_pubkey_tweak),
+ CASE1(test_xonly_pubkey_tweak_check),
+ CASE1(test_xonly_pubkey_tweak_recursive),
+ CASE1(test_xonly_pubkey_comparison),
/* keypair tests */
- test_keypair();
- test_keypair_add();
-}
+ CASE1(test_keypair),
+ CASE1(test_keypair_add),
+};
#endif
diff --git a/src/modules/musig/tests_impl.h b/src/modules/musig/tests_impl.h
index b57b262..b4ba185 100644
--- a/src/modules/musig/tests_impl.h
+++ b/src/modules/musig/tests_impl.h
@@ -20,6 +20,7 @@
#include "../../group.h"
#include "../../hash.h"
#include "../../util.h"
+#include "../../unit_test.h"
#include "vectors.h"
@@ -36,7 +37,7 @@ static int create_keypair_and_pk(secp256k1_keypair *keypair, secp256k1_pubkey *p
/* Just a simple (non-tweaked) 2-of-2 MuSig aggregate, sign, verify
* test. */
-static void musig_simple_test(void) {
+static void musig_simple_test_internal(void) {
unsigned char sk[2][32];
secp256k1_keypair keypair[2];
secp256k1_musig_pubnonce pubnonce[2];
@@ -629,7 +630,7 @@ static void musig_tweak_test_helper(const secp256k1_xonly_pubkey* agg_pk, const
/* Create aggregate public key P[0], tweak multiple times (using xonly and
* plain tweaking) and test signing. */
-static void musig_tweak_test(void) {
+static void musig_tweak_test_internal(void) {
unsigned char sk[2][32];
secp256k1_pubkey pk[2];
const secp256k1_pubkey *pk_ptr[2];
@@ -1114,28 +1115,24 @@ static void musig_test_static_nonce_gen_counter(void) {
CHECK(secp256k1_memcmp_var(pubnonce66, expected_pubnonce, sizeof(pubnonce66)) == 0);
}
-static void run_musig_tests(void) {
- int i;
-
- for (i = 0; i < COUNT; i++) {
- musig_simple_test();
- }
- musig_api_tests();
- musig_nonce_test();
- for (i = 0; i < COUNT; i++) {
- /* Run multiple times to ensure that pk and nonce have different y
- * parities */
- musig_tweak_test();
- }
- sha256_tag_test();
- musig_test_vectors_keyagg();
- musig_test_vectors_noncegen();
- musig_test_vectors_nonceagg();
- musig_test_vectors_signverify();
- musig_test_vectors_tweak();
- musig_test_vectors_sigagg();
-
- musig_test_static_nonce_gen_counter();
-}
+/* --- Test registry --- */
+REPEAT_TEST(musig_simple_test)
+/* Run multiple times to ensure that pk and nonce have different y parities */
+REPEAT_TEST(musig_tweak_test)
+
+static const struct tf_test_entry tests_musig[] = {
+ CASE1(musig_simple_test),
+ CASE1(musig_api_tests),
+ CASE1(musig_nonce_test),
+ CASE1(musig_tweak_test),
+ CASE1(sha256_tag_test),
+ CASE1(musig_test_vectors_keyagg),
+ CASE1(musig_test_vectors_noncegen),
+ CASE1(musig_test_vectors_nonceagg),
+ CASE1(musig_test_vectors_signverify),
+ CASE1(musig_test_vectors_tweak),
+ CASE1(musig_test_vectors_sigagg),
+ CASE1(musig_test_static_nonce_gen_counter),
+};
#endif
diff --git a/src/modules/recovery/tests_impl.h b/src/modules/recovery/tests_impl.h
index 7a28a3c..09554a2 100644
--- a/src/modules/recovery/tests_impl.h
+++ b/src/modules/recovery/tests_impl.h
@@ -7,6 +7,8 @@
#ifndef SECP256K1_MODULE_RECOVERY_TESTS_H
#define SECP256K1_MODULE_RECOVERY_TESTS_H
+#include "../../unit_test.h"
+
static int recovery_test_nonce_function(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) {
(void) msg32;
(void) key32;
@@ -28,7 +30,7 @@ static int recovery_test_nonce_function(unsigned char *nonce32, const unsigned c
return testrand_bits(1);
}
-static void test_ecdsa_recovery_api(void) {
+static void test_ecdsa_recovery_api_internal(void) {
/* Setup contexts that just count errors */
secp256k1_pubkey pubkey;
secp256k1_pubkey recpubkey;
@@ -92,7 +94,7 @@ static void test_ecdsa_recovery_api(void) {
CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &recsig, sig, recid) == 0);
}
-static void test_ecdsa_recovery_end_to_end(void) {
+static void test_ecdsa_recovery_end_to_end_internal(void) {
unsigned char extra[32] = {0x00};
unsigned char privkey[32];
unsigned char message[32];
@@ -324,15 +326,14 @@ static void test_ecdsa_recovery_edge_cases(void) {
}
}
-static void run_recovery_tests(void) {
- int i;
- for (i = 0; i < COUNT; i++) {
- test_ecdsa_recovery_api();
- }
- for (i = 0; i < 64*COUNT; i++) {
- test_ecdsa_recovery_end_to_end();
- }
- test_ecdsa_recovery_edge_cases();
-}
+/* --- Test registry --- */
+REPEAT_TEST(test_ecdsa_recovery_api)
+REPEAT_TEST_MULT(test_ecdsa_recovery_end_to_end, 64)
+
+static const struct tf_test_entry tests_recovery[] = {
+ CASE1(test_ecdsa_recovery_api),
+ CASE1(test_ecdsa_recovery_end_to_end),
+ CASE1(test_ecdsa_recovery_edge_cases)
+};
#endif /* SECP256K1_MODULE_RECOVERY_TESTS_H */
diff --git a/src/modules/schnorrsig/tests_impl.h b/src/modules/schnorrsig/tests_impl.h
index 5abbeef..9a1b15f 100644
--- a/src/modules/schnorrsig/tests_impl.h
+++ b/src/modules/schnorrsig/tests_impl.h
@@ -8,6 +8,7 @@
#define SECP256K1_MODULE_SCHNORRSIG_TESTS_H
#include "../../../include/secp256k1_schnorrsig.h"
+#include "../../unit_test.h"
/* Checks that a bit flip in the n_flip-th argument (that has n_bytes many
* bytes) changes the hash function
@@ -802,7 +803,7 @@ static int nonce_function_overflowing(unsigned char *nonce32, const unsigned cha
return 1;
}
-static void test_schnorrsig_sign(void) {
+static void test_schnorrsig_sign_internal(void) {
unsigned char sk[32];
secp256k1_xonly_pubkey pk;
secp256k1_keypair keypair;
@@ -852,7 +853,7 @@ static void test_schnorrsig_sign(void) {
/* Creates N_SIGS valid signatures and verifies them with verify and
* verify_batch (TODO). Then flips some bits and checks that verification now
* fails. */
-static void test_schnorrsig_sign_verify(void) {
+static void test_schnorrsig_sign_verify_internal(void) {
unsigned char sk[32];
unsigned char msg[N_SIGS][32];
unsigned char sig[N_SIGS][64];
@@ -965,18 +966,18 @@ static void test_schnorrsig_taproot(void) {
CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, output_pk_bytes, pk_parity, &internal_pk, tweak) == 1);
}
-static void run_schnorrsig_tests(void) {
- int i;
- run_nonce_function_bip340_tests();
-
- test_schnorrsig_api();
- test_schnorrsig_sha256_tagged();
- test_schnorrsig_bip_vectors();
- for (i = 0; i < COUNT; i++) {
- test_schnorrsig_sign();
- test_schnorrsig_sign_verify();
- }
- test_schnorrsig_taproot();
-}
+/* --- Test registry --- */
+REPEAT_TEST(test_schnorrsig_sign)
+REPEAT_TEST(test_schnorrsig_sign_verify)
+
+static const struct tf_test_entry tests_schnorrsig[] = {
+ CASE(nonce_function_bip340_tests),
+ CASE1(test_schnorrsig_api),
+ CASE1(test_schnorrsig_sha256_tagged),
+ CASE1(test_schnorrsig_bip_vectors),
+ CASE1(test_schnorrsig_sign),
+ CASE1(test_schnorrsig_sign_verify),
+ CASE1(test_schnorrsig_taproot),
+};
#endif
diff --git a/src/tests.c b/src/tests.c
index efcdbdc..5f4f6b0 100644
--- a/src/tests.c
+++ b/src/tests.c
@@ -7755,12 +7755,6 @@ static const struct tf_test_entry tests_ec[] = {
CASE(eckey_negate_test),
};
-#ifdef ENABLE_MODULE_ECDH
-static const struct tf_test_entry tests_ecdh[] = {
- CASE(ecdh_tests),
-};
-#endif
-
static const struct tf_test_entry tests_ecdsa[] = {
CASE(ec_illegal_argument_tests),
CASE(pubkey_comparison),
@@ -7773,37 +7767,6 @@ static const struct tf_test_entry tests_ecdsa[] = {
CASE(ecdsa_wycheproof),
};
-#ifdef ENABLE_MODULE_RECOVERY
-static const struct tf_test_entry tests_recovery[] = {
- /* ECDSA pubkey recovery tests */
- CASE(recovery_tests),
-};
-#endif
-
-#ifdef ENABLE_MODULE_EXTRAKEYS
-static const struct tf_test_entry tests_extrakeys[] = {
- CASE(extrakeys_tests),
-};
-#endif
-
-#ifdef ENABLE_MODULE_SCHNORRSIG
-static const struct tf_test_entry tests_schnorrsig[] = {
- CASE(schnorrsig_tests),
-};
-#endif
-
-#ifdef ENABLE_MODULE_MUSIG
-static const struct tf_test_entry tests_musig[] = {
- CASE(musig_tests),
-};
-#endif
-
-#ifdef ENABLE_MODULE_ELLSWIFT
-static const struct tf_test_entry tests_ellswift[] = {
- CASE(ellswift_tests),
-};
-#endif
-
static const struct tf_test_entry tests_utils[] = {
CASE(hsort_tests),
CASE(secp256k1_memczero_test),
@@ -7827,6 +7790,7 @@ static const struct tf_test_module registry_modules[] = {
#endif
MAKE_TEST_MODULE(ecdsa),
#ifdef ENABLE_MODULE_RECOVERY
+ /* ECDSA pubkey recovery tests */
MAKE_TEST_MODULE(recovery),
#endif
#ifdef ENABLE_MODULE_EXTRAKEYS
diff --git a/src/unit_test.h b/src/unit_test.h
index f1374a0..7052fdc 100644
--- a/src/unit_test.h
+++ b/src/unit_test.h
@@ -22,6 +22,7 @@
/* --------------------------------------------------------- */
#define CASE(name) { #name, run_##name }
+#define CASE1(name) { #name, name }
#define MAKE_TEST_MODULE(name) { \
#name, \
@@ -29,6 +30,18 @@
sizeof(tests_##name) / sizeof(tests_##name[0]) \
}
+/* Macro to wrap a test internal function with a COUNT loop (iterations number) */
+#define REPEAT_TEST(fn) REPEAT_TEST_MULT(fn, 1)
+#define REPEAT_TEST_MULT(fn, multiplier) \
+ static void fn(void) { \
+ int i; \
+ int repeat = COUNT * (multiplier); \
+ for (i = 0; i < repeat; i++) \
+ fn##_internal(); \
+ }
+
+
+
/* --------------------------------------------------------- */
/* Test Framework API */
/* --------------------------------------------------------- */
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.