From 965393fceadf8024c6b60dff59b2c30b61af28d2 Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Fri, 14 Feb 2025 13:43:10 +0100 Subject: [PATCH 1/3] examples: use `EXIT_...` constants for `main` return values Fixes issue #1609. --- examples/ecdh.c | 9 +++++---- examples/ecdsa.c | 13 +++++++------ examples/ellswift.c | 11 ++++++----- examples/musig.c | 15 ++++++++------- examples/schnorr.c | 13 +++++++------ 5 files changed, 33 insertions(+), 28 deletions(-) diff --git a/examples/ecdh.c b/examples/ecdh.c index 13aa760b2d..67b8c2047a 100644 --- a/examples/ecdh.c +++ b/examples/ecdh.c @@ -8,6 +8,7 @@ *************************************************************************/ #include +#include #include #include @@ -33,7 +34,7 @@ int main(void) { secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); if (!fill_random(randomize, sizeof(randomize))) { printf("Failed to generate randomness\n"); - return 1; + return EXIT_FAILURE; } /* Randomizing the context is recommended to protect against side-channel * leakage See `secp256k1_context_randomize` in secp256k1.h for more @@ -44,14 +45,14 @@ int main(void) { /*** Key Generation ***/ if (!fill_random(seckey1, sizeof(seckey1)) || !fill_random(seckey2, sizeof(seckey2))) { printf("Failed to generate randomness\n"); - return 1; + return EXIT_FAILURE; } /* If the secret key is zero or out of range (greater than secp256k1's * order), we fail. Note that the probability of this occurring is negligible * with a properly functioning random number generator. */ if (!secp256k1_ec_seckey_verify(ctx, seckey1) || !secp256k1_ec_seckey_verify(ctx, seckey2)) { printf("Generated secret key is invalid. This indicates an issue with the random number generator.\n"); - return 1; + return EXIT_FAILURE; } /* Public key creation using a valid context with a verified secret key should never fail */ @@ -116,5 +117,5 @@ int main(void) { secure_erase(shared_secret1, sizeof(shared_secret1)); secure_erase(shared_secret2, sizeof(shared_secret2)); - return 0; + return EXIT_SUCCESS; } diff --git a/examples/ecdsa.c b/examples/ecdsa.c index 80ae9d46c5..ae16c180dc 100644 --- a/examples/ecdsa.c +++ b/examples/ecdsa.c @@ -8,6 +8,7 @@ *************************************************************************/ #include +#include #include #include @@ -40,7 +41,7 @@ int main(void) { secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); if (!fill_random(randomize, sizeof(randomize))) { printf("Failed to generate randomness\n"); - return 1; + return EXIT_FAILURE; } /* Randomizing the context is recommended to protect against side-channel * leakage See `secp256k1_context_randomize` in secp256k1.h for more @@ -51,14 +52,14 @@ int main(void) { /*** Key Generation ***/ if (!fill_random(seckey, sizeof(seckey))) { printf("Failed to generate randomness\n"); - return 1; + return EXIT_FAILURE; } /* If the secret key is zero or out of range (greater than secp256k1's * order), we fail. Note that the probability of this occurring is negligible * with a properly functioning random number generator. */ if (!secp256k1_ec_seckey_verify(ctx, seckey)) { printf("Generated secret key is invalid. This indicates an issue with the random number generator.\n"); - return 1; + return EXIT_FAILURE; } /* Public key creation using a valid context with a verified secret key should never fail */ @@ -92,13 +93,13 @@ int main(void) { /* Deserialize the signature. This will return 0 if the signature can't be parsed correctly. */ if (!secp256k1_ecdsa_signature_parse_compact(ctx, &sig, serialized_signature)) { printf("Failed parsing the signature\n"); - return 1; + return EXIT_FAILURE; } /* Deserialize the public key. This will return 0 if the public key can't be parsed correctly. */ if (!secp256k1_ec_pubkey_parse(ctx, &pubkey, compressed_pubkey, sizeof(compressed_pubkey))) { printf("Failed parsing the public key\n"); - return 1; + return EXIT_FAILURE; } /* Verify a signature. This will return 1 if it's valid and 0 if it's not. */ @@ -133,5 +134,5 @@ int main(void) { * will remove any writes that aren't used. */ secure_erase(seckey, sizeof(seckey)); - return 0; + return EXIT_SUCCESS; } diff --git a/examples/ellswift.c b/examples/ellswift.c index afb2fee40b..d58e96b053 100644 --- a/examples/ellswift.c +++ b/examples/ellswift.c @@ -13,6 +13,7 @@ */ #include +#include #include #include @@ -38,7 +39,7 @@ int main(void) { ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); if (!fill_random(randomize, sizeof(randomize))) { printf("Failed to generate randomness\n"); - return 1; + return EXIT_FAILURE; } /* Randomizing the context is recommended to protect against side-channel * leakage. See `secp256k1_context_randomize` in secp256k1.h for more @@ -49,14 +50,14 @@ int main(void) { /*** Generate secret keys ***/ if (!fill_random(seckey1, sizeof(seckey1)) || !fill_random(seckey2, sizeof(seckey2))) { printf("Failed to generate randomness\n"); - return 1; + return EXIT_FAILURE; } /* If the secret key is zero or out of range (greater than secp256k1's * order), we fail. Note that the probability of this occurring is negligible * with a properly functioning random number generator. */ if (!secp256k1_ec_seckey_verify(ctx, seckey1) || !secp256k1_ec_seckey_verify(ctx, seckey2)) { printf("Generated secret key is invalid. This indicates an issue with the random number generator.\n"); - return 1; + return EXIT_FAILURE; } /* Generate ElligatorSwift public keys. This should never fail with valid context and @@ -64,7 +65,7 @@ int main(void) { optional, but recommended. */ if (!fill_random(auxrand1, sizeof(auxrand1)) || !fill_random(auxrand2, sizeof(auxrand2))) { printf("Failed to generate randomness\n"); - return 1; + return EXIT_FAILURE; } return_val = secp256k1_ellswift_create(ctx, ellswift_pubkey1, seckey1, auxrand1); assert(return_val); @@ -117,5 +118,5 @@ int main(void) { secure_erase(shared_secret1, sizeof(shared_secret1)); secure_erase(shared_secret2, sizeof(shared_secret2)); - return 0; + return EXIT_SUCCESS; } diff --git a/examples/musig.c b/examples/musig.c index 0352dc40f3..bdb8fced0c 100644 --- a/examples/musig.c +++ b/examples/musig.c @@ -12,6 +12,7 @@ */ #include +#include #include #include @@ -193,7 +194,7 @@ int main(void) { for (i = 0; i < N_SIGNERS; i++) { if (!create_keypair(ctx, &signer_secrets[i], &signers[i])) { printf("FAILED\n"); - return 1; + return EXIT_FAILURE; } pubkeys_ptr[i] = &signers[i].pubkey; } @@ -208,7 +209,7 @@ int main(void) { fflush(stdout); if (!secp256k1_ec_pubkey_sort(ctx, pubkeys_ptr, N_SIGNERS)) { printf("FAILED\n"); - return 1; + return EXIT_FAILURE; } printf("ok\n"); @@ -219,7 +220,7 @@ int main(void) { * while providing a non-NULL agg_pk argument. */ if (!secp256k1_musig_pubkey_agg(ctx, NULL, &cache, pubkeys_ptr, N_SIGNERS)) { printf("FAILED\n"); - return 1; + return EXIT_FAILURE; } printf("ok\n"); printf("Tweaking................"); @@ -227,21 +228,21 @@ int main(void) { /* Optionally tweak the aggregate key */ if (!tweak(ctx, &agg_pk, &cache)) { printf("FAILED\n"); - return 1; + return EXIT_FAILURE; } printf("ok\n"); printf("Signing message........."); fflush(stdout); if (!sign(ctx, signer_secrets, signers, &cache, msg, sig)) { printf("FAILED\n"); - return 1; + return EXIT_FAILURE; } printf("ok\n"); printf("Verifying signature....."); fflush(stdout); if (!secp256k1_schnorrsig_verify(ctx, sig, msg, 32, &agg_pk)) { printf("FAILED\n"); - return 1; + return EXIT_FAILURE; } printf("ok\n"); @@ -256,5 +257,5 @@ int main(void) { secure_erase(&signer_secrets[i], sizeof(signer_secrets[i])); } secp256k1_context_destroy(ctx); - return 0; + return EXIT_SUCCESS; } diff --git a/examples/schnorr.c b/examples/schnorr.c index 909fcaa1f3..49baed24be 100644 --- a/examples/schnorr.c +++ b/examples/schnorr.c @@ -8,6 +8,7 @@ *************************************************************************/ #include +#include #include #include @@ -34,7 +35,7 @@ int main(void) { secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); if (!fill_random(randomize, sizeof(randomize))) { printf("Failed to generate randomness\n"); - return 1; + return EXIT_FAILURE; } /* Randomizing the context is recommended to protect against side-channel * leakage See `secp256k1_context_randomize` in secp256k1.h for more @@ -45,7 +46,7 @@ int main(void) { /*** Key Generation ***/ if (!fill_random(seckey, sizeof(seckey))) { printf("Failed to generate randomness\n"); - return 1; + return EXIT_FAILURE; } /* Try to create a keypair with a valid context. This only fails if the * secret key is zero or out of range (greater than secp256k1's order). Note @@ -53,7 +54,7 @@ int main(void) { * functioning random number generator. */ if (!secp256k1_keypair_create(ctx, &keypair, seckey)) { printf("Generated secret key is invalid. This indicates an issue with the random number generator.\n"); - return 1; + return EXIT_FAILURE; } /* Extract the X-only public key from the keypair. We pass NULL for @@ -90,7 +91,7 @@ int main(void) { /* Generate 32 bytes of randomness to use with BIP-340 schnorr signing. */ if (!fill_random(auxiliary_rand, sizeof(auxiliary_rand))) { printf("Failed to generate randomness\n"); - return 1; + return EXIT_FAILURE; } /* Generate a Schnorr signature. @@ -110,7 +111,7 @@ int main(void) { * be parsed correctly */ if (!secp256k1_xonly_pubkey_parse(ctx, &pubkey, serialized_pubkey)) { printf("Failed parsing the public key\n"); - return 1; + return EXIT_FAILURE; } /* Compute the tagged hash on the received messages using the same tag as the signer. */ @@ -149,5 +150,5 @@ int main(void) { * Here we are preventing these writes from being optimized out, as any good compiler * will remove any writes that aren't used. */ secure_erase(seckey, sizeof(seckey)); - return 0; + return EXIT_SUCCESS; } From c8555817280d106a9f860462a4499f0eb1acd001 Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Fri, 14 Feb 2025 13:43:29 +0100 Subject: [PATCH 2/3] test, bench, precompute_ecmult: use `EXIT_...` constants for `main` return values --- src/bench.c | 15 ++++++++------- src/bench.h | 2 +- src/bench_ecmult.c | 7 ++++--- src/bench_internal.c | 5 +++-- src/ctime_tests.c | 5 +++-- src/precompute_ecmult.c | 5 +++-- src/precompute_ecmult_gen.c | 5 +++-- src/tests.c | 2 +- src/tests_exhaustive.c | 4 ++-- 9 files changed, 28 insertions(+), 22 deletions(-) diff --git a/src/bench.c b/src/bench.c index 1127df67ae..149f25fce4 100644 --- a/src/bench.c +++ b/src/bench.c @@ -5,6 +5,7 @@ ***********************************************************************/ #include +#include #include #include "../include/secp256k1.h" @@ -188,11 +189,11 @@ int main(int argc, char** argv) { || have_flag(argc, argv, "--help") || have_flag(argc, argv, "help")) { help(default_iters); - return 0; + return EXIT_SUCCESS; } else if (invalid_args) { fprintf(stderr, "./bench: unrecognized argument.\n\n"); help(default_iters); - return 1; + return EXIT_FAILURE; } } @@ -201,7 +202,7 @@ int main(int argc, char** argv) { if (have_flag(argc, argv, "ecdh")) { fprintf(stderr, "./bench: ECDH module not enabled.\n"); fprintf(stderr, "Use ./configure --enable-module-ecdh.\n\n"); - return 1; + return EXIT_FAILURE; } #endif @@ -209,7 +210,7 @@ int main(int argc, char** argv) { if (have_flag(argc, argv, "recover") || have_flag(argc, argv, "ecdsa_recover")) { fprintf(stderr, "./bench: Public key recovery module not enabled.\n"); fprintf(stderr, "Use ./configure --enable-module-recovery.\n\n"); - return 1; + return EXIT_FAILURE; } #endif @@ -217,7 +218,7 @@ int main(int argc, char** argv) { if (have_flag(argc, argv, "schnorrsig") || have_flag(argc, argv, "schnorrsig_sign") || have_flag(argc, argv, "schnorrsig_verify")) { fprintf(stderr, "./bench: Schnorr signatures module not enabled.\n"); fprintf(stderr, "Use ./configure --enable-module-schnorrsig.\n\n"); - return 1; + return EXIT_FAILURE; } #endif @@ -227,7 +228,7 @@ int main(int argc, char** argv) { have_flag(argc, argv, "ellswift_ecdh")) { fprintf(stderr, "./bench: ElligatorSwift module not enabled.\n"); fprintf(stderr, "Use ./configure --enable-module-ellswift.\n\n"); - return 1; + return EXIT_FAILURE; } #endif @@ -275,5 +276,5 @@ int main(int argc, char** argv) { run_ellswift_bench(iters, argc, argv); #endif - return 0; + return EXIT_SUCCESS; } diff --git a/src/bench.h b/src/bench.h index 1564b1a176..232fb35fc0 100644 --- a/src/bench.h +++ b/src/bench.h @@ -24,7 +24,7 @@ static int64_t gettime_i64(void) { struct timespec tv; if (!timespec_get(&tv, TIME_UTC)) { fputs("timespec_get failed!", stderr); - exit(1); + exit(EXIT_FAILURE); } return (int64_t)tv.tv_nsec / 1000 + (int64_t)tv.tv_sec * 1000000LL; #else diff --git a/src/bench_ecmult.c b/src/bench_ecmult.c index 3974af75f4..172292d570 100644 --- a/src/bench_ecmult.c +++ b/src/bench_ecmult.c @@ -4,6 +4,7 @@ * file COPYING or https://www.opensource.org/licenses/mit-license.php.* ***********************************************************************/ #include +#include #include "secp256k1.c" #include "../include/secp256k1.h" @@ -287,7 +288,7 @@ int main(int argc, char **argv) { || have_flag(argc, argv, "--help") || have_flag(argc, argv, "help")) { help(argv); - return 0; + return EXIT_SUCCESS; } else if(have_flag(argc, argv, "pippenger_wnaf")) { printf("Using pippenger_wnaf:\n"); data.ecmult_multi = secp256k1_ecmult_pippenger_batch_single; @@ -299,7 +300,7 @@ int main(int argc, char **argv) { } else { fprintf(stderr, "%s: unrecognized argument '%s'.\n\n", argv[0], argv[1]); help(argv); - return 1; + return EXIT_FAILURE; } } @@ -363,5 +364,5 @@ int main(int argc, char **argv) { free(data.output); free(data.expected_output); - return(0); + return EXIT_SUCCESS; } diff --git a/src/bench_internal.c b/src/bench_internal.c index a700684922..8688a4dc77 100644 --- a/src/bench_internal.c +++ b/src/bench_internal.c @@ -4,6 +4,7 @@ * file COPYING or https://www.opensource.org/licenses/mit-license.php.* ***********************************************************************/ #include +#include #include "secp256k1.c" #include "../include/secp256k1.h" @@ -393,7 +394,7 @@ int main(int argc, char **argv) { || have_flag(argc, argv, "--help") || have_flag(argc, argv, "help")) { help(default_iters); - return 0; + return EXIT_SUCCESS; } } @@ -432,5 +433,5 @@ int main(int argc, char **argv) { if (d || have_flag(argc, argv, "context")) run_benchmark("context_create", bench_context, bench_setup, NULL, &data, 10, iters); - return 0; + return EXIT_SUCCESS; } diff --git a/src/ctime_tests.c b/src/ctime_tests.c index bbde863d96..f81bdb9228 100644 --- a/src/ctime_tests.c +++ b/src/ctime_tests.c @@ -5,6 +5,7 @@ ***********************************************************************/ #include +#include #include #include "../include/secp256k1.h" @@ -49,7 +50,7 @@ int main(void) { if (!SECP256K1_CHECKMEM_RUNNING()) { fprintf(stderr, "This test can only usefully be run inside valgrind because it was not compiled under msan.\n"); fprintf(stderr, "Usage: libtool --mode=execute valgrind ./ctime_tests\n"); - return 1; + return EXIT_FAILURE; } ctx = secp256k1_context_create(SECP256K1_CONTEXT_DECLASSIFY); /** In theory, testing with a single secret input should be sufficient: @@ -69,7 +70,7 @@ int main(void) { CHECK(ret); secp256k1_context_destroy(ctx); - return 0; + return EXIT_SUCCESS; } static void run_tests(secp256k1_context *ctx, unsigned char *key) { diff --git a/src/precompute_ecmult.c b/src/precompute_ecmult.c index 5ef198a770..021fe3940c 100644 --- a/src/precompute_ecmult.c +++ b/src/precompute_ecmult.c @@ -6,6 +6,7 @@ #include #include +#include #include "../include/secp256k1.h" @@ -62,7 +63,7 @@ int main(void) { fp = fopen(outfile, "w"); if (fp == NULL) { fprintf(stderr, "Could not open %s for writing!\n", outfile); - return -1; + return EXIT_FAILURE; } fprintf(fp, "/* This file was automatically generated by precompute_ecmult. */\n"); @@ -86,5 +87,5 @@ int main(void) { fprintf(fp, "#undef S\n"); fclose(fp); - return 0; + return EXIT_SUCCESS; } diff --git a/src/precompute_ecmult_gen.c b/src/precompute_ecmult_gen.c index 4d153a6574..cd0fe70fc2 100644 --- a/src/precompute_ecmult_gen.c +++ b/src/precompute_ecmult_gen.c @@ -6,6 +6,7 @@ #include #include +#include #include "../include/secp256k1.h" @@ -64,7 +65,7 @@ int main(int argc, char **argv) { fp = fopen(outfile, "w"); if (fp == NULL) { fprintf(stderr, "Could not open %s for writing!\n", outfile); - return -1; + return EXIT_FAILURE; } fprintf(fp, "/* This file was automatically generated by precompute_ecmult_gen. */\n"); @@ -96,5 +97,5 @@ int main(int argc, char **argv) { fprintf(fp, "#undef S\n"); fclose(fp); - return 0; + return EXIT_SUCCESS; } diff --git a/src/tests.c b/src/tests.c index 78533b11c2..88628a14ea 100644 --- a/src/tests.c +++ b/src/tests.c @@ -7837,5 +7837,5 @@ int main(int argc, char **argv) { testrand_finish(); printf("no problems found\n"); - return 0; + return EXIT_SUCCESS; } diff --git a/src/tests_exhaustive.c b/src/tests_exhaustive.c index 6efa88982e..f8bbcaaf5c 100644 --- a/src/tests_exhaustive.c +++ b/src/tests_exhaustive.c @@ -383,7 +383,7 @@ int main(int argc, char** argv) { this_core = strtol(argv[4], NULL, 0); if (num_cores < 1 || this_core >= num_cores) { fprintf(stderr, "Usage: %s [count] [seed] [numcores] [thiscore]\n", argv[0]); - return 1; + return EXIT_FAILURE; } printf("running tests for core %lu (out of [0..%lu])\n", (unsigned long)this_core, (unsigned long)num_cores - 1); } @@ -462,5 +462,5 @@ int main(int argc, char** argv) { testrand_finish(); printf("no problems found\n"); - return 0; + return EXIT_SUCCESS; } From 13d389629aba2c686798a856332c00c6934cacd5 Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Fri, 14 Feb 2025 13:42:28 +0100 Subject: [PATCH 3/3] CONTRIBUTING: mention that `EXIT_` codes should be used --- CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a366d38b0e..80890fb706 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -74,6 +74,7 @@ In addition, libsecp256k1 tries to maintain the following coding conventions: * User-facing comment lines in headers should be limited to 80 chars if possible. * All identifiers in file scope should start with `secp256k1_`. * Avoid trailing whitespace. +* Use the constants `EXIT_SUCCESS`/`EXIT_FAILURE` (defined in `stdlib.h`) to indicate program execution status for examples and other binaries. ### Tests