Commit Graph

23 Commits

Author SHA1 Message Date
w0xlt
f48b1bfa5d hash: add midstate initializer and use it for tagged hashes
Introduce secp256k1_sha256_initialize_midstate() in the hash layer and use it at all tagged-hash midstate call sites across schnorrsig, musig, and ellswift.

Document the byte-counter contract at the declaration site in hash.h and add run_sha256_initialize_midstate_tests() to directly verify helper behavior against initialize_tagged.

Also switch the helper to take const uint32_t state[8] to reduce argument-order risk at call sites.
2026-02-25 15:37:43 -08:00
merge-script
8d445730ec Merge bitcoin-core/secp256k1#1783: Add VERIFY_CHECKs and documentation that flags must be 0 or 1
ae00c552df Add VERIFY_CHECKs that flags are 0 or 1 (John Moffett)

Pull request description:

  Flags for constant-time masking rely on the values being exactly `0` or `1` rather than `0` or true (any nonzero). One function, `secp256k1_fe_cmov` [documents](e7f7083b53/src/field.h (L315)) and [`VERIFY_CHECK`s](e7f7083b53/src/field_impl.h (L365)) this, but most don't.

  This updates the documentation and adds `VERIFY_CHECK`s enforcing `flag == 0 || flag == 1` for:

  `secp256k1_fe_storage_cmov`
  `secp256k1_gej_cmov`
  `secp256k1_ge_storage_cmov`
  `secp256k1_scalar_cadd_bit`
  `secp256k1_scalar_cond_negate`
  `secp256k1_scalar_cmov`
  `secp256k1_int_cmov`

ACKs for top commit:
  furszy:
    ACK ae00c55
  hebasto:
    re-ACK ae00c552df.

Tree-SHA512: c9d358929d39d93b0aea602d318429f7e82af96bf601f048a1cdeb0621b8adc6d1204648d352aa2060cb0f63db6dcf0da863854375ed313cea44dfad61c19a18
2025-12-15 20:43:58 +01:00
John Moffett
ae00c552df Add VERIFY_CHECKs that flags are 0 or 1
Flags for constant-time masking rely
on the values being exactly 0 or 1 rather
than 0 or true. Add VERIFY_CHECKs to enforce
in VERIFY builds as a preventative
measure and add documentation where relevant.
2025-12-15 09:07:42 -05:00
Sebastian Falbesoner
8bcda186d2 test: Add non-NULL checks for "pointer of array" API functions 2025-12-09 01:38:48 +01:00
Sebastian Falbesoner
5a08c1bcdc Add ARG_CHECKs to ensure "array of pointers" elements are non-NULL 2025-12-06 01:13:58 +01:00
Sebastian Falbesoner
0d3659c547 use new _eckey_pubkey_serialize{33,65} functions in modules (ellswift,musig) 2025-11-17 18:13:56 +01:00
merge-script
d543c0d917 Merge bitcoin-core/secp256k1#1734: Introduce (mini) unit test framework
2f4546ce56 test: add --log option to display tests execution (furszy)
95b9953ea4 test: Add option to display all available tests (furszy)
953f7b0088 test: support running specific tests/modules targets (furszy)
0302c1a3d7 test: add --help for command-line options (furszy)
9ec3bfe22d test: adapt modules to the new test infrastructure (furszy)
48789dafc2 test: introduce (mini) unit test framework (furszy)
9cce703863 refactor: move 'gettime_i64()' to tests_common.h (furszy)

Pull request description:

  Early Note:
  Don’t be scared by the PR’s line changes count — most of it’s just doc or part of the test framework API.

  Context:
  Currently, all tests run single-threaded sequentially and the library lacks the ability to specify which test (or group of tests) you would like to run. This is not only inconvenient as more tests are added but also time consuming during development and affects downstream projects that may want to parallelize the workload (such as Bitcoin-Core CI).

  PR Goal:
  Introduce a lightweight, extensible C89 unit test framework with no dynamic memory allocations, providing a structured way to register, execute, and report tests. The framework supports named command-line arguments in `-key=value` form, parallel test execution across multiple worker processes, granular test selection (selecting tests either by name or by module name), and time accumulation reports.

  The introduced framework supports:
  * `-help` or `-h`: display list of available commands along with their descriptions.
  * `-jobs=<num>`: distribute tests across multiple worker processes (default: sequential if 0).
  * `-target=<name>` or `-t=<name>`: run only specific tests by name; can be repeated to select multiple tests.
  *  `-target=<module name>`, `-t=<module>`  Run all tests within a specific module (can be provided multiple times)
  * `-seed=<hex>`: set a specific RNG seed (defaults to random if unspecified).
  * `-iterations=<n>`: specify the number of iterations.
  * `-list_tests`:   display list of available tests and modules you can run.
  * `-log=<0|1>`: enable or disable test execution logging (default: 0 = disabled).

  Beyond these features, the idea is to also make future developments smoother, as adding new tests require only a single entry in the central test registry, and new command-line options can be introduced easily by extending the framework’s `parse_arg()` function.

  Compatibility Note:
  The framework continues accepting the two positional arguments previously supported (iterations and seed), ensuring existing workflows remain intact.

  Testing Notes:
  Have fun. You can quickly try it through `./tests -j=<workers_num>` for parallel execution  or `./tests -t=<test_name>` to run a specific test (call `./tests -print_tests` to display all available tests and modules).

  Extra Note:
  I haven't checked the exhaustive tests file so far, but I will soon. For now, this only runs all tests declared in the `tests` binary.

  Testing Results: (Current master branch vs PR in seconds)

  * Raspberry Pi 5: master \~100 s → PR \~38 s (5 jobs)
  * MacBook Pro M1: master \~30 s → PR \~10 s (6 jobs)

ACKs for top commit:
  theStack:
    re-ACK 2f4546ce56
  real-or-random:
    ACK 2f4546ce56
  hebasto:
    ACK 2f4546ce56.

Tree-SHA512: 85ca2cbb620b84b35b353d5d4cf093c388fc3851ca405eeb0e458f8fa72b60534bccd357c7edabf8fc9aa93d9ad0a6fbac3dd5c4d5f9dfdf4d8701a9834755b9
2025-10-15 08:37:23 +02:00
furszy
9ec3bfe22d test: adapt modules to the new test infrastructure
This not only provides a structural improvement but also
allows us to (1) specify individual tests to run and (2)
execute each of them concurrently.
2025-10-01 10:17:57 -04:00
John Moffett
399b582a5f Split memclear into two versions
secp256k1_memclear has the side effect of undefining bytes for
valgrind checks. In some cases, we may want to zero bytes
but allow subsequent reads. So we split memclear into
memclear_explicit, which makes no guarantees about the content
of the buffer on return, and memzero_explicit, which guarantees
zero value on return.

Change the memset in partial_sign to use memzero_explicit.
2025-09-08 12:26:04 -04:00
josibake
5153cf1c91 tests: refactor tagged hash tests
Move the sha256_tag_test_internal function out of the musig module
into tests.c. This makes it available to other modules wishing to verify tagged
hashes without needing to duplicate the function.

Change the function signature to expect a const unsigned char and update
the tagged hash tests to use static const unsigned char character
arrays (where necessary).

Add a comment for each tag. This is done as a convenience for checking
the strings against the protocol specifications, where the tags are
normally specified as strings.

Update tests in the ellswift and schnorrsig modules to use the
sha256_tag_test_internal helper function.
2025-08-20 10:37:06 +01:00
Jonas Nick
cde4130898 musig/tests: initialize keypair
The keypair is unused in musig_partial_sign, but clang-snapshot gives a compiler
warning anyway.
2025-07-21 14:08:23 +00:00
Tim Ruffing
8d967a602b musig/test: Remove dead code
This avoids a compiler warning on clang-snapshot about &keypair being uninitialized.
2025-07-21 14:47:57 +02:00
Tim Ruffing
983711cd6d musig/tests: Refactor vectors_signverify
for improved readability
2025-07-21 14:44:57 +02:00
Tim Ruffing
961ec25a83 musig: Fix clearing of pubnonces
Fixes a silent merge conflict between #1614 and #1579.
2025-03-10 15:10:29 +01:00
merge-script
3186082387 Merge bitcoin-core/secp256k1#1614: Add _ge_set_all_gej and use it in musig for own public nonces
64228a648f musig: Use _ge_set_all_gej for own public nonces (Tim Ruffing)
300aab1c05 tests: Improve _ge_set_all_gej(_var) tests (Tim Ruffing)
365f274ce3 group: Simplify secp256k1_ge_set_all_gej (Tim Ruffing)
d3082ddead group: Add constant-time secp256k1_ge_set_all_gej (Tim Ruffing)

Pull request description:

  As suggested in https://github.com/bitcoin-core/secp256k1/pull/1479#discussion_r1781469191

ACKs for top commit:
  theStack:
    re-ACK 64228a648f
  sipa:
    ACK 64228a648f

Tree-SHA512: f62a95e44dc09bb55a64da0640ad323e7ef5acc262d3c2aea6787eae0918769ea97da466b7d602e59693e4fb85c5ec9a67fdfba8b890624467855b6d1e1596c0
2025-03-10 14:44:37 +01:00
Hennadii Stepanov
145868a84d Do not export secp256k1_musig_nonce_gen_internal 2024-11-04 15:59:41 +00:00
merge-script
b161bffb8b Merge bitcoin-core/secp256k1#1579: Clear sensitive memory without getting optimized out (revival of #636)
765ef53335 Clear _gej instances after point multiplication to avoid potential leaks (Sebastian Falbesoner)
349e6ab916 Introduce separate _clear functions for hash module (Tim Ruffing)
99cc9fd6d0 Don't rely on memset to set signed integers to 0 (Tim Ruffing)
97c57f42ba Implement various _clear() functions with secp256k1_memclear() (Tim Ruffing)
9bb368d146 Use secp256k1_memclear() to clear stack memory instead of memset() (Tim Ruffing)
e3497bbf00 Separate between clearing memory and setting to zero in tests (Tim Ruffing)
d79a6ccd43 Separate secp256k1_fe_set_int( . , 0 ) from secp256k1_fe_clear() (Tim Ruffing)
1c08126222 Add secp256k1_memclear() for clearing secret data (Tim Ruffing)
e7d384488e Don't clear secrets in pippenger implementation (Tim Ruffing)

Pull request description:

  This PR picks up #636 (which in turn picked up #448, so this is take number three) and is essentially a rebase on master.

  Some changes to the original PR:
  * the clearing function now has the `secp256k1_` prefix again, since the related helper `_memczero` got it as well (see PR #835 / commit e89278f211)
  * the original commit b17a7df8145a6a86d49c354c7e7b59a432ea5346 ("Make _set_fe_int( . , 0 ) set magnitude to 0") is not needed anymore, since it was already applied in PR #943 (commit d49011f54c)
  * clearing of stack memory with `secp256k1_memclear` is now also done on modules that have been newly introduced since then, i.e. schnorr and ellswift (of course, there is still no guarantee that all places where clearing is necessary are covered)

  So far I haven't looked at any disassembly and possible performance implications yet (there were some concerns expressed in https://github.com/bitcoin-core/secp256k1/pull/636#issuecomment-620118629), happy to go deeper there if this gets Concept ACKed.

  The proposed method of using a memory barrier to prevent optimizating away the memset is still used in BoringSSL (where it was originally picked up from) and in the Linux Kernel, see e.g. 5af122c3df/crypto/mem.c (L335) and d456068672/include/linux/string.h (L348) / d456068672/include/linux/compiler.h (L102)

  Fixes #185.

ACKs for top commit:
  sipa:
    reACK 765ef53335
  real-or-random:
    ACK 765ef53335

Tree-SHA512: 5a034d5ad14178c06928022459f3d4f0877d06f576b24ab07b86b3608b0b3e9273217b8309a1db606f024f3032731f13013114b1e0828964b578814d1efb2959
2024-11-04 16:34:52 +01:00
Tim Ruffing
64228a648f musig: Use _ge_set_all_gej for own public nonces 2024-11-01 23:33:53 +01:00
Sebastian Falbesoner
765ef53335 Clear _gej instances after point multiplication to avoid potential leaks
Quoting sipa (see https://github.com/bitcoin-core/secp256k1/pull/1479#discussion_r1790079414):
"When performing an EC multiplication A = aG for secret a, the resulting
 _affine_ coordinates of A are presumed to not leak information about a (ECDLP),
  but the same is not necessarily true for the Jacobian coordinates that come
  out of our multiplication algorithm."

For the ECDH point multiplication result, the result in Jacobi coordinates should be
cleared not only to avoid leaking the scalar, but even more so as it's a representation
of the resulting shared secret.
2024-10-25 18:44:48 +02:00
Tim Ruffing
349e6ab916 Introduce separate _clear functions for hash module
This gives the caller more control about whether the state should
be cleaned (= should be considered secret). Moreover, it gives the
caller the possibility to clean a hash struct without finalizing it.
2024-10-25 18:44:48 +02:00
Tim Ruffing
9bb368d146 Use secp256k1_memclear() to clear stack memory instead of memset()
All of the invocations of secp256k1_memclear() operate on stack
memory and happen after the function is done with the memory object.
This commit replaces existing memset() invocations and also adds
secp256k1_memclear() to code locations where clearing was missing;
there is no guarantee that this commit covers all code locations
where clearing is necessary.

Co-Authored-By: isle2983 <isle2983@yahoo.com>
2024-10-25 18:44:48 +02:00
Sebastian Falbesoner
57eda3ba30 musig: ctimetests: fix _declassify range for generated nonce points
The area marked as non-secret exceeds the nonce_pts array in the
second iteration of the for loop. Fix that by passing the correct
size to the _declassify call.
2024-10-20 02:29:35 +02:00
Jonas Nick
f411841a46 Add module "musig" that implements MuSig2 multi-signatures (BIP 327) 2024-10-07 14:03:42 +00:00