Commit Graph

37 Commits

Author SHA1 Message Date
DarkWindman
f7e7e6bb15 Merge branch 'master' into sync-7262adb4 2026-04-01 17:29:57 +03:00
merge-script
1aafe15139 Merge bitcoin-core/secp256k1#1777: Make SHA256 compression runtime pluggable
4d92a083bc sha256: speed up writes using multi-block compression (furszy)
0753f8b909 Add API to override SHA256 compression at runtime (furszy)
fdb6a91a5e Introduce hash context to support pluggable SHA256 compression (furszy)

Pull request description:

  Tackling the long-standing request #702.

  Right now we ship our own SHA256 implementation, a standard baseline version that does not take advantage of any hardware-optimized instruction, and it cannot be accessed by the embedding application - it is for internal usage only.

  This means embedding applications often have to implement or include a different version for their use cases, wasting space on constrained environments, and in performance-sensitive setups it forces them to use a slower path than what the platform provides. Many projects already rely on tuned SHA-NI / ARMv8 / or other hardware-optimized code, so always using the baseline implementation we ship within the library is not ideal.

  These changes allow users to supply their own SHA256 compression function at runtime, while preserving the existing default behavior for everyone else. This is primarily intended for environments where the available SHA256 implementation is detected dynamically and recompiling the library with a different implementation is not feasible (equivalent build-time functionality will come in a follow-up PR).

  It introduces a new API:

  ```C89
  secp256k1_context_set_sha256_transform_callback(ctx, fn_transform)
  ```

  This function installs the optimized SHA256 compression into the `secp256k1_context`, which is then used by all internal computations. Important: The provided function is verified to be output-equivalent to the original one.

  As a quick example, using this functionality in Bitcoin-Core will be very straightforward: f68bef06d9

ACKs for top commit:
  real-or-random:
    ACK 4d92a083bc
  w0xlt:
    ACK 4d92a083bc
  theStack:
    ACK 4d92a083bc

Tree-SHA512: 058e2e82071f1ca77254b684458292c621e60d65bbcc5500574429717e7db75bc9f3221129fafd11eb5d33e666a5efec5e9844460d3b194ef3b6b16f2df28fb9
2026-03-04 08:43:07 +01:00
merge-script
b9cb1cbfd7 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
2026-03-03 15:31:46 +01:00
furszy
fdb6a91a5e Introduce hash context to support pluggable SHA256 compression
This is purely a mechanical change with no behavior change.

It introduces a secp256k1_hash_ctx struct inside secp256k1_context
and propagates it to all SHA256-related operations.

This sets up the ability to provide a hardware-optimized SHA256
compression function at runtime in a follow-up commit.
2026-03-03 10:25:50 -03:00
mllwchrry
3b2ceb3e7a Merge commits '14e56970 1605b02f cd49c57e 453949ab 57315a69 97de5120 c5da3bde 99ab4a10 d071aa56 1d146ac3 322d0a43 c7a7f732 ac561601 dfe042fe 3019186a 95e68158 10f546a2 c0a2aba0 ' into temp-merge-1811 2026-03-03 14:45:28 +02:00
mllwchrry
07d4de6433 Merge commits '115b135f c8206b1c b6c2a3cd e7f7083b be5e4f02 5c751833 540fec8a aa2a39c1 8d445730 f9a944ff 2d9137ce 4721e077 471e3a13 ebb35882 1a53f496 c7a52400 ' into temp-merge-1809 2026-03-02 15:56:43 +02:00
DarkWindman
f1e52fac20 Merge commits '88be4e8d b4756543 10dab907 58178851 de6af6ae baa26542 2b7337f6 a44a3393 f44c1ebd d543c0d9 43e7b115 7a2fff85 ' into temp-merge-1758 2026-02-27 14:47:34 +02:00
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
DarkWindman
38284aa008 Merge commits '2c076d90 20e3b447 74b8068c e523e4f9 d5997141 d2dcf520 f36afb8b 8113671f d93380fb 03fb60ad 4985ac0f 36e76952 ' into temp-merge-1738 2026-02-25 10:44:34 +02:00
mllwchrry
9dcd857d54 Merge commits '29e73f4b 89096c23 c4987790 ad60ef7e 943479a7 cbbbf3bd 73a69595 7c338042 5e74086d 6037833c 020ee604 a660a497 b9313c6e ' into temp-merge-1708 2026-02-24 13:31:44 +02:00
mllwchrry
79953d074b Merge commits '1b1fc093 6c2a39da 31860823 abd25054 4ba1ba2a 03bbe8c6 13ed6f65 a7a51171 2abb35b0 e56716a3 3f54ed8c d84bb83e ' into temp-merge-1661 2026-02-20 18:29:53 +02:00
DarkWindman
913be29ea2 Merge commits 'b161bffb 0cdc758a ec329c25 8deef00b f79f46c7 00774d07 2e3bf136 c0d9480f ' into temp-merge-1654 2026-02-18 15:57:18 +02:00
Sebastian Falbesoner
921b9711ea util: introduce and use ARRAY_SIZE macro
The macro definition matches the one used in Linux, see e.g.
9702969978/include/linux/array_size.h (L11)
(without the additional check rejecting pointers, as we would need
 GNU C for that, see e.g. https://stackoverflow.com/a/19455169)
2026-02-17 00:21:58 +01:00
mllwchrry
347d6adfd2 Merge commits 'a88aa935 01b58933 18f9b967 e59158b6 1fae76f5 f0868a9b 68b55209 9b7c59cb 1464f15c 9a8db52f 7d48f5ed a38d879a ' into temp-merge-1628 2026-02-16 16:04:51 +02:00
mllwchrry
8d443b8030 musig: Re-add adaptor signatures support 2026-02-13 15:07:52 +02: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