Merge bitcoin-core/secp256k1#1824: util: introduce and use ARRAY_SIZE macro

921b9711ea util: introduce and use `ARRAY_SIZE` macro (Sebastian Falbesoner)

Pull request description:

  This PR is another tiny improvement found while working on #1765, with the goal to avoid code repetition.

  The `ARRAY_SIZE` macro definition is pretty wide-spread in C projects and e.g. matches the one [used in the Linux Kernel](9702969978/include/linux/array_size.h (L11))  (without the additional check to reject pointers, as we would need GNU C for that, see e.g. https://stackoverflow.com/a/19455169; not sure if a useful counterpart exists that only relies on C89). Replacement instances were identified via `$ git grep sizeof.*/.*sizeof`.

ACKs for top commit:
  w0xlt:
    ACK 921b9711ea
  real-or-random:
    utACK 921b9711ea

Tree-SHA512: 44b6bf0132cf00fade526a3fc04e03dc896d04874123614c032206b61f97c81f94d139b6cc0c108eceaa699251580c19420d230b3150607303ca2cb7ab9a0bcb
This commit is contained in:
merge-script
2026-03-03 15:31:46 +01:00
8 changed files with 42 additions and 38 deletions

View File

@@ -183,8 +183,7 @@ int main(int argc, char** argv) {
"ecdsa_recover", "schnorrsig", "schnorrsig_verify", "schnorrsig_sign", "ec",
"keygen", "ec_keygen", "ellswift", "encode", "ellswift_encode", "decode",
"ellswift_decode", "ellswift_keygen", "ellswift_ecdh"};
size_t valid_args_size = sizeof(valid_args)/sizeof(valid_args[0]);
int invalid_args = have_invalid_args(argc, argv, valid_args, valid_args_size);
int invalid_args = have_invalid_args(argc, argv, valid_args, ARRAY_SIZE(valid_args));
int default_iters = 20000;
int iters = get_iters(default_iters);

View File

@@ -8,6 +8,7 @@
#include "../../../include/secp256k1_ellswift.h"
#include "../../unit_test.h"
#include "../../util.h"
struct ellswift_xswiftec_inv_test {
int enc_bitmap;
@@ -180,7 +181,7 @@ static int ellswift_xdh_hash_x32(unsigned char *output, const unsigned char *x32
/* Run the test vectors for ellswift encoding */
void ellswift_encoding_test_vectors_tests(void) {
int i;
for (i = 0; (unsigned)i < sizeof(ellswift_xswiftec_inv_tests) / sizeof(ellswift_xswiftec_inv_tests[0]); ++i) {
for (i = 0; (unsigned)i < ARRAY_SIZE(ellswift_xswiftec_inv_tests); ++i) {
const struct ellswift_xswiftec_inv_test *testcase = &ellswift_xswiftec_inv_tests[i];
int c;
for (c = 0; c < 8; ++c) {
@@ -200,7 +201,7 @@ void ellswift_encoding_test_vectors_tests(void) {
/* Run the test vectors for ellswift decoding */
void ellswift_decoding_test_vectors_tests(void) {
int i;
for (i = 0; (unsigned)i < sizeof(ellswift_decode_tests) / sizeof(ellswift_decode_tests[0]); ++i) {
for (i = 0; (unsigned)i < ARRAY_SIZE(ellswift_decode_tests); ++i) {
const struct ellswift_decode_test *testcase = &ellswift_decode_tests[i];
secp256k1_pubkey pubkey;
secp256k1_ge ge;
@@ -217,7 +218,7 @@ void ellswift_decoding_test_vectors_tests(void) {
/* Run the test vectors for ellswift expected xdh BIP324 shared secrets */
void ellswift_xdh_test_vectors_tests(void) {
int i;
for (i = 0; (unsigned)i < sizeof(ellswift_xdh_tests_bip324) / sizeof(ellswift_xdh_tests_bip324[0]); ++i) {
for (i = 0; (unsigned)i < ARRAY_SIZE(ellswift_xdh_tests_bip324); ++i) {
const struct ellswift_xdh_test *test = &ellswift_xdh_tests_bip324[i];
unsigned char shared_secret[32];
int ret;

View File

@@ -769,7 +769,7 @@ static void musig_test_vectors_keyagg(void) {
size_t i;
const struct musig_key_agg_vector *vector = &musig_key_agg_vector;
for (i = 0; i < sizeof(vector->valid_case)/sizeof(vector->valid_case[0]); i++) {
for (i = 0; i < ARRAY_SIZE(vector->valid_case); i++) {
const struct musig_key_agg_valid_test_case *c = &vector->valid_case[i];
enum MUSIG_ERROR error;
secp256k1_musig_keyagg_cache keyagg_cache;
@@ -779,7 +779,7 @@ static void musig_test_vectors_keyagg(void) {
CHECK(secp256k1_memcmp_var(agg_pk, c->expected, sizeof(agg_pk)) == 0);
}
for (i = 0; i < sizeof(vector->error_case)/sizeof(vector->error_case[0]); i++) {
for (i = 0; i < ARRAY_SIZE(vector->error_case); i++) {
const struct musig_key_agg_error_test_case *c = &vector->error_case[i];
enum MUSIG_ERROR error;
secp256k1_musig_keyagg_cache keyagg_cache;
@@ -793,7 +793,7 @@ static void musig_test_vectors_noncegen(void) {
size_t i;
const struct musig_nonce_gen_vector *vector = &musig_nonce_gen_vector;
for (i = 0; i < sizeof(vector->test_case)/sizeof(vector->test_case[0]); i++) {
for (i = 0; i < ARRAY_SIZE(vector->test_case); i++) {
const struct musig_nonce_gen_test_case *c = &vector->test_case[i];
secp256k1_musig_keyagg_cache keyagg_cache;
secp256k1_musig_keyagg_cache *keyagg_cache_ptr = NULL;
@@ -847,7 +847,7 @@ static void musig_test_vectors_nonceagg(void) {
int j;
const struct musig_nonce_agg_vector *vector = &musig_nonce_agg_vector;
for (i = 0; i < sizeof(vector->valid_case)/sizeof(vector->valid_case[0]); i++) {
for (i = 0; i < ARRAY_SIZE(vector->valid_case); i++) {
const struct musig_nonce_agg_test_case *c = &vector->valid_case[i];
secp256k1_musig_pubnonce pubnonce[2];
const secp256k1_musig_pubnonce *pubnonce_ptr[2];
@@ -862,7 +862,7 @@ static void musig_test_vectors_nonceagg(void) {
CHECK(secp256k1_musig_aggnonce_serialize(CTX, aggnonce66, &aggnonce));
CHECK(secp256k1_memcmp_var(aggnonce66, c->expected, 33) == 0);
}
for (i = 0; i < sizeof(vector->error_case)/sizeof(vector->error_case[0]); i++) {
for (i = 0; i < ARRAY_SIZE(vector->error_case); i++) {
const struct musig_nonce_agg_test_case *c = &vector->error_case[i];
secp256k1_musig_pubnonce pubnonce[2];
for (j = 0; j < 2; j++) {
@@ -886,7 +886,7 @@ static void musig_test_vectors_signverify(void) {
size_t i;
const struct musig_sign_verify_vector *vector = &musig_sign_verify_vector;
for (i = 0; i < sizeof(vector->valid_case)/sizeof(vector->valid_case[0]); i++) {
for (i = 0; i < ARRAY_SIZE(vector->valid_case); i++) {
const struct musig_valid_case *c = &vector->valid_case[i];
enum MUSIG_ERROR error;
secp256k1_musig_keyagg_cache keyagg_cache;
@@ -914,7 +914,7 @@ static void musig_test_vectors_signverify(void) {
CHECK(secp256k1_musig_pubnonce_parse(CTX, &pubnonce, vector->pubnonces[0]));
CHECK(secp256k1_musig_partial_sig_verify(CTX, &partial_sig, &pubnonce, &pubkey, &keyagg_cache, &session));
}
for (i = 0; i < sizeof(vector->sign_error_case)/sizeof(vector->sign_error_case[0]); i++) {
for (i = 0; i < ARRAY_SIZE(vector->sign_error_case); i++) {
const struct musig_sign_error_case *c = &vector->sign_error_case[i];
enum MUSIG_ERROR error;
secp256k1_musig_keyagg_cache keyagg_cache;
@@ -953,7 +953,7 @@ static void musig_test_vectors_signverify(void) {
musig_test_set_secnonce(&secnonce, vector->secnonces[c->secnonce_index], &pubkey);
CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sign(CTX, &partial_sig, &secnonce, &keypair, &keyagg_cache, &session));
}
for (i = 0; i < sizeof(vector->verify_fail_case)/sizeof(vector->verify_fail_case[0]); i++) {
for (i = 0; i < ARRAY_SIZE(vector->verify_fail_case); i++) {
const struct musig_verify_fail_error_case *c = &vector->verify_fail_case[i];
enum MUSIG_ERROR error;
secp256k1_musig_keyagg_cache keyagg_cache;
@@ -987,7 +987,7 @@ static void musig_test_vectors_signverify(void) {
expected = c->error != MUSIG_SIG_VERIFY;
CHECK(expected == secp256k1_musig_partial_sig_verify(CTX, &partial_sig, pubnonce, &pubkey, &keyagg_cache, &session));
}
for (i = 0; i < sizeof(vector->verify_error_case)/sizeof(vector->verify_error_case[0]); i++) {
for (i = 0; i < ARRAY_SIZE(vector->verify_error_case); i++) {
const struct musig_verify_fail_error_case *c = &vector->verify_error_case[i];
enum MUSIG_ERROR error;
secp256k1_musig_keyagg_cache keyagg_cache;
@@ -1015,7 +1015,7 @@ static void musig_test_vectors_tweak(void) {
CHECK(secp256k1_musig_aggnonce_parse(CTX, &aggnonce, vector->aggnonce));
CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, vector->pubkeys[0], sizeof(vector->pubkeys[0])));
for (i = 0; i < sizeof(vector->valid_case)/sizeof(vector->valid_case[0]); i++) {
for (i = 0; i < ARRAY_SIZE(vector->valid_case); i++) {
const struct musig_tweak_case *c = &vector->valid_case[i];
enum MUSIG_ERROR error;
secp256k1_musig_keyagg_cache keyagg_cache;
@@ -1039,7 +1039,7 @@ static void musig_test_vectors_tweak(void) {
CHECK(secp256k1_musig_pubnonce_parse(CTX, &pubnonce, vector->pubnonces[c->nonce_indices[c->signer_index]]));
CHECK(secp256k1_musig_partial_sig_verify(CTX, &partial_sig, &pubnonce, &pubkey, &keyagg_cache, &session));
}
for (i = 0; i < sizeof(vector->error_case)/sizeof(vector->error_case[0]); i++) {
for (i = 0; i < ARRAY_SIZE(vector->error_case); i++) {
const struct musig_tweak_case *c = &vector->error_case[i];
enum MUSIG_ERROR error;
secp256k1_musig_keyagg_cache keyagg_cache;
@@ -1052,7 +1052,7 @@ static void musig_test_vectors_sigagg(void) {
size_t i, j;
const struct musig_sig_agg_vector *vector = &musig_sig_agg_vector;
for (i = 0; i < sizeof(vector->valid_case)/sizeof(vector->valid_case[0]); i++) {
for (i = 0; i < ARRAY_SIZE(vector->valid_case); i++) {
const struct musig_sig_agg_case *c = &vector->valid_case[i];
enum MUSIG_ERROR error;
unsigned char final_sig[64];
@@ -1061,8 +1061,8 @@ static void musig_test_vectors_sigagg(void) {
secp256k1_xonly_pubkey agg_pk;
secp256k1_musig_aggnonce aggnonce;
secp256k1_musig_session session;
secp256k1_musig_partial_sig partial_sig[(sizeof(vector->psigs)/sizeof(vector->psigs[0]))];
const secp256k1_musig_partial_sig *partial_sig_ptr[(sizeof(vector->psigs)/sizeof(vector->psigs[0]))];
secp256k1_musig_partial_sig partial_sig[ARRAY_SIZE(vector->psigs)];
const secp256k1_musig_partial_sig *partial_sig_ptr[ARRAY_SIZE(vector->psigs)];
CHECK(musig_vectors_keyagg_and_tweak(&error, &keyagg_cache, agg_pk32, vector->pubkeys, vector->tweaks, c->key_indices_len, c->key_indices, c->tweak_indices_len, c->tweak_indices, c->is_xonly));
CHECK(secp256k1_musig_aggnonce_parse(CTX, &aggnonce, c->aggnonce));
@@ -1078,9 +1078,9 @@ static void musig_test_vectors_sigagg(void) {
CHECK(secp256k1_xonly_pubkey_parse(CTX, &agg_pk, agg_pk32));
CHECK(secp256k1_schnorrsig_verify(CTX, final_sig, vector->msg, sizeof(vector->msg), &agg_pk) == 1);
}
for (i = 0; i < sizeof(vector->error_case)/sizeof(vector->error_case[0]); i++) {
for (i = 0; i < ARRAY_SIZE(vector->error_case); i++) {
const struct musig_sig_agg_case *c = &vector->error_case[i];
secp256k1_musig_partial_sig partial_sig[(sizeof(vector->psigs)/sizeof(vector->psigs[0]))];
secp256k1_musig_partial_sig partial_sig[ARRAY_SIZE(vector->psigs)];
for (j = 0; j < c->psig_indices_len; j++) {
int expected = c->invalid_sig_idx != (int)j;
CHECK(expected == secp256k1_musig_partial_sig_parse(CTX, &partial_sig[j], vector->psigs[c->psig_indices[j]]));

View File

@@ -56,7 +56,7 @@ static const unsigned char invalid_pubkey_bytes[][32] = {
}
};
#define NUM_INVALID_KEYS (sizeof(invalid_pubkey_bytes) / sizeof(invalid_pubkey_bytes[0]))
#define NUM_INVALID_KEYS (ARRAY_SIZE(invalid_pubkey_bytes))
static int secp256k1_hardened_nonce_function_smallint(unsigned char *nonce32, const unsigned char *msg,
size_t msglen,

View File

@@ -80,7 +80,7 @@ int main(int argc, char **argv) {
fprintf(fp, "const secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[COMB_BLOCKS][COMB_POINTS] = {\n");
fprintf(fp, "#if 0\n");
for (config = 0; config < sizeof(CONFIGS) / sizeof(*CONFIGS); ++config) {
for (config = 0; config < ARRAY_SIZE(CONFIGS); ++config) {
print_table(fp, CONFIGS[config][0], CONFIGS[config][1]);
if (CONFIGS[config][0] == COMB_BLOCKS && CONFIGS[config][1] == COMB_TEETH) {
did_current_config = 1;

View File

@@ -92,7 +92,7 @@ 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++) {
for (i = 0; i < ARRAY_SIZE(secp256k1_test_state); i++) {
CHECK(secp256k1_test_state[i] == 0);
}
}
@@ -146,7 +146,7 @@ static void run_deprecated_context_flags_test(void) {
SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY };
secp256k1_context *none_ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
int i;
for (i = 0; i < (int)(sizeof(flags)/sizeof(flags[0])); i++) {
for (i = 0; i < (int)(ARRAY_SIZE(flags)); i++) {
secp256k1_context *tmp_ctx;
CHECK(secp256k1_context_preallocated_size(SECP256K1_CONTEXT_NONE) == secp256k1_context_preallocated_size(flags[i]));
tmp_ctx = secp256k1_context_create(flags[i]);
@@ -437,13 +437,13 @@ static void run_ctz_tests(void) {
static const uint64_t b64[] = {1, 0xffffffffffffffff, 0xbcd02462139b3fc3, 0x98b5f80c769693ef};
int shift;
unsigned i;
for (i = 0; i < sizeof(b32) / sizeof(b32[0]); ++i) {
for (i = 0; i < ARRAY_SIZE(b32); ++i) {
for (shift = 0; shift < 32; ++shift) {
CHECK(secp256k1_ctz32_var_debruijn(b32[i] << shift) == shift);
CHECK(secp256k1_ctz32_var(b32[i] << shift) == shift);
}
}
for (i = 0; i < sizeof(b64) / sizeof(b64[0]); ++i) {
for (i = 0; i < ARRAY_SIZE(b64); ++i) {
for (shift = 0; shift < 64; ++shift) {
CHECK(secp256k1_ctz64_var_debruijn(b64[i] << shift) == shift);
CHECK(secp256k1_ctz64_var(b64[i] << shift) == shift);
@@ -478,7 +478,7 @@ static void run_sha256_known_output_tests(void) {
unsigned int i, ninputs;
/* Skip last input vector for low iteration counts */
ninputs = sizeof(inputs)/sizeof(inputs[0]) - 1;
ninputs = ARRAY_SIZE(inputs) - 1;
CONDITIONAL_TEST(16, "run_sha256_known_output_tests 1000000") ninputs++;
for (i = 0; i < ninputs; i++) {
@@ -603,7 +603,7 @@ static void run_sha256_counter_tests(void) {
{0xec, 0x12, 0x24, 0x9f, 0x35, 0xa4, 0x29, 0x8b, 0x9e, 0x4a, 0x95, 0xf8, 0x61, 0xaf, 0x61, 0xc5, 0x66, 0x55, 0x3e, 0x3f, 0x2a, 0x98, 0xea, 0x71, 0x16, 0x6b, 0x1c, 0xd9, 0xe4, 0x09, 0xd2, 0x8e},
};
unsigned int i;
for (i = 0; i < sizeof(midstates)/sizeof(midstates[0]); i++) {
for (i = 0; i < ARRAY_SIZE(midstates); i++) {
unsigned char out[32];
secp256k1_sha256 hasher = midstates[i];
secp256k1_sha256_write(&hasher, (const unsigned char*)input, strlen(input));
@@ -1662,7 +1662,7 @@ static void run_modinv_tests(void) {
int i, j, ok;
/* Test known inputs/outputs */
for (i = 0; (size_t)i < sizeof(CASES) / sizeof(CASES[0]); ++i) {
for (i = 0; (size_t)i < ARRAY_SIZE(CASES); ++i) {
uint16_t out[16];
test_modinv32_uint16(out, CASES[i][0], CASES[i][1]);
for (j = 0; j < 16; ++j) CHECK(out[j] == CASES[i][2][j]);
@@ -2310,7 +2310,7 @@ static void run_scalar_tests(void) {
SECP256K1_SCALAR_CONST(0x7ffffffful, 0xfffffffful, 0xfffffffful, 0xfffffffful, 0xfffffffful, 0xfffffffful, 0xfffffffful, 0xfffffffful),
};
unsigned n;
for (n = 0; n < sizeof(HALF_TESTS) / sizeof(HALF_TESTS[0]); ++n) {
for (n = 0; n < ARRAY_SIZE(HALF_TESTS); ++n) {
secp256k1_scalar s;
secp256k1_scalar_half(&s, &HALF_TESTS[n]);
secp256k1_scalar_add(&s, &s, &s);
@@ -3578,7 +3578,7 @@ static void run_inverse_tests(void)
secp256k1_scalar x_scalar;
memset(b32, 0, sizeof(b32));
/* Test fixed test cases through test_inverse_{scalar,field}, both ways. */
for (i = 0; (size_t)i < sizeof(fe_cases)/sizeof(fe_cases[0]); ++i) {
for (i = 0; (size_t)i < ARRAY_SIZE(fe_cases); ++i) {
for (var = 0; var <= 1; ++var) {
test_inverse_field(&x_fe, &fe_cases[i][0], var);
CHECK(fe_equal(&x_fe, &fe_cases[i][1]));
@@ -3586,7 +3586,7 @@ static void run_inverse_tests(void)
CHECK(fe_equal(&x_fe, &fe_cases[i][0]));
}
}
for (i = 0; (size_t)i < sizeof(scalar_cases)/sizeof(scalar_cases[0]); ++i) {
for (i = 0; (size_t)i < ARRAY_SIZE(scalar_cases); ++i) {
for (var = 0; var <= 1; ++var) {
test_inverse_scalar(&x_scalar, &scalar_cases[i][0], var);
CHECK(secp256k1_scalar_eq(&x_scalar, &scalar_cases[i][1]));
@@ -4462,7 +4462,7 @@ static void run_ecmult_near_split_bound(void) {
int i;
unsigned j;
for (i = 0; i < 4*COUNT; ++i) {
for (j = 0; j < sizeof(scalars_near_split_bounds) / sizeof(scalars_near_split_bounds[0]); ++j) {
for (j = 0; j < ARRAY_SIZE(scalars_near_split_bounds); ++j) {
test_ecmult_target(&scalars_near_split_bounds[j], 0);
test_ecmult_target(&scalars_near_split_bounds[j], 1);
test_ecmult_target(&scalars_near_split_bounds[j], 2);
@@ -4586,7 +4586,7 @@ static void ecmult_const_edges(void) {
secp256k1_ge point;
secp256k1_gej res;
size_t i;
size_t cases = 1 + sizeof(scalars_near_split_bounds) / sizeof(scalars_near_split_bounds[0]);
size_t cases = 1 + ARRAY_SIZE(scalars_near_split_bounds);
/* We are trying to reach the following edge cases (variables are defined as
* in ecmult_const_impl.h):
@@ -5738,7 +5738,7 @@ static void run_endomorphism_tests(void) {
testutil_random_scalar_order_test(&full);
test_scalar_split(&full);
}
for (i = 0; i < sizeof(scalars_near_split_bounds) / sizeof(scalars_near_split_bounds[0]); ++i) {
for (i = 0; i < ARRAY_SIZE(scalars_near_split_bounds); ++i) {
test_scalar_split(&scalars_near_split_bounds[i]);
}
}
@@ -7892,7 +7892,7 @@ static int teardown(void) {
int main(int argc, char **argv) {
struct tf_framework tf = {0};
tf.registry_modules = registry_modules;
tf.num_modules = sizeof(registry_modules) / sizeof(registry_modules[0]);
tf.num_modules = ARRAY_SIZE(registry_modules);
tf.registry_no_rng = &registry_modules_no_rng;
/* Add context creation/destruction functions */

View File

@@ -6,6 +6,8 @@
#ifndef SECP256K1_UNIT_TEST_H
#define SECP256K1_UNIT_TEST_H
#include "util.h"
/* --------------------------------------------------------- */
/* Configurable constants */
/* --------------------------------------------------------- */
@@ -27,7 +29,7 @@
#define MAKE_TEST_MODULE(name) { \
#name, \
tests_##name, \
sizeof(tests_##name) / sizeof(tests_##name[0]) \
ARRAY_SIZE(tests_##name) \
}
/* Macro to wrap a test internal function with a COUNT loop (iterations number) */

View File

@@ -181,6 +181,8 @@ static SECP256K1_INLINE void *checked_malloc(const secp256k1_callback* cb, size_
#define ROUND_TO_ALIGN(size) (CEIL_DIV(size, ALIGNMENT) * ALIGNMENT)
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
/* Macro for restrict, when available and not in a VERIFY build. */
#if defined(SECP256K1_BUILD) && defined(VERIFY)
# define SECP256K1_RESTRICT