UltrafastSecp256k1/cpu/tests/run_selftest.cpp
shrec 34b7c167e5
BIP-141/143/144/342: fill all SegWit + tapscript coverage gaps
Implement BIP-143 (SegWit v0 sighash), BIP-144 (witness tx serialization/
wtxid/commitment), BIP-141 (witness program creation/parsing/validation),
and BIP-342 tapscript sighash + BIP-341 keypath sighash.

New files:
  - bip143.hpp/cpp: full BIP-143 sighash with ANYONECANPAY/NONE/SINGLE
  - bip144.hpp/cpp: witness/legacy serialization, txid/wtxid, weight/vsize
  - segwit.hpp/cpp: witness program detection, P2WPKH/P2WSH/P2TR builders

Extended:
  - taproot.hpp/cpp: TapSighashTxData + tapscript_sighash + keypath_sighash
  - ufsecp.h: 14 new C ABI functions (BIP-143/144/141/342)
  - ufsecp_impl.cpp: all implementations + raw tx txid/wtxid parsing

Tests: 79 BIP-141/143/144 + 12 BIP-342 tests, registered in selftest (30/30)
Benchmarks: Section 8.12 in bench_unified (10 new rows)
2026-03-22 13:03:47 +00:00

166 lines
6.6 KiB
C++

// ============================================================================
// Unified Test Runner -- UltrafastSecp256k1
// ============================================================================
// Single binary that runs the library selftest + all test modules.
// Build once, run everywhere. Registers as a single ctest target.
//
// Usage:
// run_selftest # ci mode (default)
// run_selftest smoke # fast startup check
// run_selftest stress # extended nightly suite
// run_selftest ci <seed> # explicit seed (hex)
// ============================================================================
#include "secp256k1/selftest.hpp"
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace secp256k1::fast;
// -- Forward declarations -- each test module exports a run function -----------
// Returns 0 on success, non-zero on failure.
int test_large_scalar_multiplication_run();
int test_mul_run();
int test_arithmetic_correctness_run();
int test_ct_run();
int test_ct_equivalence_run();
int test_ecdsa_schnorr_run();
int test_multiscalar_batch_run();
int test_bip32_run();
int test_bip32_vectors_run();
int test_bip39_run();
int test_musig2_run();
int test_ecdh_recovery_taproot_run();
int test_edge_cases_run();
int test_v4_features_run();
int test_coins_run();
int test_batch_add_affine_run();
int test_hash_accel_run();
int run_exhaustive_tests();
int test_comprehensive_run();
int test_bip340_vectors_run();
int test_rfc6979_vectors_run();
int test_ecc_properties_run();
int test_ecies_run();
int test_sha_run();
int test_bip141_143_144_run();
int test_bip342_run();
#ifdef SECP256K1_BUILD_ETHEREUM
int test_ethereum_run();
#endif
int test_wallet_run();
int test_zk_run();
#ifdef SECP256K1_BIP324
int test_bip324_run();
#endif
// -- Module descriptor --------------------------------------------------------
struct TestModule {
const char* name;
int (*run)();
};
static const TestModule MODULES[] = {
{ "field & scalar arithmetic", test_mul_run },
{ "arithmetic correctness", test_arithmetic_correctness_run },
{ "scalar multiplication", test_large_scalar_multiplication_run },
{ "constant-time layer", test_ct_run },
{ "FAST\u2261CT equivalence", test_ct_equivalence_run },
{ "ECDSA + Schnorr", test_ecdsa_schnorr_run },
{ "multi-scalar & batch verify", test_multiscalar_batch_run },
{ "BIP-32 HD derivation", test_bip32_run },
{ "BIP-32 official test vectors TV1-5", test_bip32_vectors_run },
{ "BIP-39 mnemonic seed phrases", test_bip39_run },
{ "MuSig2", test_musig2_run },
{ "ECDH + recovery + taproot", test_ecdh_recovery_taproot_run },
{ "edge cases & coverage gaps", test_edge_cases_run },
{ "v4 features (Pedersen/FROST/etc)", test_v4_features_run },
{ "coins layer", test_coins_run },
{ "affine batch addition", test_batch_add_affine_run },
{ "accelerated hashing", test_hash_accel_run },
{ "exhaustive algebraic verification", run_exhaustive_tests },
{ "comprehensive 500+ test suite", test_comprehensive_run },
{ "BIP-340 official test vectors", test_bip340_vectors_run },
{ "RFC 6979 ECDSA test vectors", test_rfc6979_vectors_run },
{ "ECC property-based invariants", test_ecc_properties_run },
{ "ECIES encrypt/decrypt", test_ecies_run },
{ "SHA-256/512 NIST vectors", test_sha_run },
{ "BIP-141/143/144 SegWit", test_bip141_143_144_run },
{ "BIP-342 tapscript sighash", test_bip342_run },
#ifdef SECP256K1_BUILD_ETHEREUM
{ "Ethereum signing layer", test_ethereum_run },
#endif
{ "Unified wallet API", test_wallet_run },
{ "ZK proofs (knowledge/DLEQ/Bulletproof)", test_zk_run },
#ifdef SECP256K1_BIP324
{ "BIP-324 encrypted transport", test_bip324_run },
#endif
};
static constexpr int NUM_MODULES = sizeof(MODULES) / sizeof(MODULES[0]);
// -- Main ---------------------------------------------------------------------
int main(int argc, char* argv[]) {
// Parse mode
SelftestMode mode = SelftestMode::ci;
uint64_t seed = 0;
if (argc >= 2) {
if (std::strcmp(argv[1], "smoke") == 0) { mode = SelftestMode::smoke;
} else if (std::strcmp(argv[1], "stress") == 0) { mode = SelftestMode::stress;
} else if (std::strcmp(argv[1], "ci") == 0) { mode = SelftestMode::ci;
}
}
if (argc >= 3) {
seed = std::strtoull(argv[2], nullptr, 16);
}
const char* mode_name = (mode == SelftestMode::smoke) ? "smoke"
: (mode == SelftestMode::stress) ? "stress"
: "ci";
std::printf("===============================================================\n");
std::printf(" UltrafastSecp256k1 -- Unified Test Runner (%s)\n", mode_name);
std::printf("===============================================================\n\n");
// -- Phase 1: Library selftest (core arithmetic KAT) ----------------------
std::printf("[Phase 1] Library selftest (%s)...\n", mode_name);
if (!Selftest(true, mode, seed)) {
std::printf("\n*** SELFTEST FAILED -- aborting ***\n");
return 1;
}
std::printf("[Phase 1] Selftest PASSED\n\n");
// -- Phase 2: Test modules ------------------------------------------------
std::printf("[Phase 2] Running %d test modules...\n\n", NUM_MODULES);
int modules_passed = 0;
int modules_failed = 0;
for (int i = 0; i < NUM_MODULES; ++i) {
std::printf("-- Module %d/%d: %s --\n", i + 1, NUM_MODULES, MODULES[i].name);
int const rc = MODULES[i].run();
if (rc == 0) {
++modules_passed;
std::printf("-- PASSED --\n\n");
} else {
++modules_failed;
std::printf("-- FAILED --\n\n");
}
}
// -- Summary --------------------------------------------------------------
std::printf("===============================================================\n");
std::printf(" Results: %d/%d modules passed (selftest + %d modules)\n",
modules_passed, NUM_MODULES, NUM_MODULES);
if (modules_failed == 0) {
std::printf(" ALL TESTS PASSED\n");
} else {
std::printf(" *** %d MODULE(S) FAILED ***\n", modules_failed);
}
std::printf("===============================================================\n");
return modules_failed > 0 ? 1 : 0;
}