#36188 crypto: plug hardware optimized SHA256 into libsecp256k1's context

ReviewabilityReviewsAgreementSize
#36188 furszy crypto: plug hardware optimized SHA256 into libsecp256k1's contextReady2Strong224 + 237 tests
  • Speed up elliptic curve signing by enabling hardware-accelerated SHA256 in libsecp256k1
  • Brings signing performance gains to users running on CPUs with dedicated SHA extensions
  • Ready for review; no known blockers or pending changes to invalidate review
  • Broad concept support across several contributors and maintainers
  • Verified by differential testing across 20,000 cryptographic operation rounds (fametrano)
  • Reviewed and approved after addressing context separation and startup questions (theStack, w0xlt)
  • Unanswered suggestion to clone the signing context to avoid a second self-test (fametrano)
  • 224 lines added or modified outside tests
  • 237 lines added or modified in tests
  • 150 lines removed in total
  • 44 files, 11 commits
Utilities (logging, arguments, libraries)#8 of 59
P2 · speedup
  • P2 because it speeds up cryptographic signing operations on CPUs with hardware SHA extensions
  • ECDSA signing drops by roughly 13% to 15% and Schnorr signing drops by 3% to 7%
  • Verification gains are negligible, keeping the performance benefits focused on signing workloads
Reviewability: ReadyStalePaused
Agreement: StrongPositivePositive w/ caveatsNeutralMildDisputedBlockedCrickets
Reviews: current code-review ACKs, then (+stale ACKs) and -NACKs; greener = more ACKs.
Size: lines added or modified outside tests, then in tests; greener = smaller.

Goal

Plugs Bitcoin Core's hardware-accelerated SHA256 compression function into libsecp256k1 contexts. It restructures `ECC_Context` into a lifecycle manager that provides both signing and verification contexts, moves ECC initialization into `common/ecc_init`, and updates call sites to use the new verification context instead of `secp256k1_context_static`.

Problem: libsecp256k1 uses its internal pure-software SHA256 compression implementation by default, bypassing available CPU hardware acceleration (such as x86 SHA-NI and ARMv8 cryptography extensions) during elliptic curve signing and verification. Additionally, `secp256k1_context_static` cannot be configured with custom compression hooks, and ECC initialization was tightly coupled to `key.h` primitives.

Evidence of importance:

  • PR description benchmarks on ARM64 with SHA-NI show ECDSA signing time drops from 79.2 µs to 69.3 µs (-13%) and Schnorr signing drops from 39.9 µs to 37.1 µs (-7%).
  • Commit 3104f72514 notes: 'With ours, ECDSA signing gets ~15% faster on CPUs with SHA extensions, Schnorr signing ~3%.' Verification benchmarks show negligible improvement (0% to -1%).

Scope: A significant portion of the 44 changed files is mechanical: updating fuzz targets, benchmarks, and binaries to initialize ECC state via `MakeContextECC()`, plus a scripted-diff substituting `secp256k1_context_static` with `GetSecp256k1VerifyContext()` in `src/pubkey.cpp`.

Risk of a mistake: medium (consensus, validation, wallet). A flaw in the SHA256 compression callback or context initialization could cause silent signature creation errors or misvalidate cryptographic checks across the node.

Changed since the previous assessment: The underlying approach and commit progression remain consistent with the prior description; changes reflect rebasing and test/benchmark adjustments.

Reviewability

Ready

Nothing known that would invalidate a review now.

Waiting on (from the thread read):

  • author: response to fametrano's suggestion on cloning context 2026-10-25
  • reviewer: re-review by theStack requested by sedited 2026-10-31

Agreement

Strong

substantive support, no open objection (fametrano)

Thread notes: sedited asked theStack to take another look; no new claims were raised.

Objections, suggestions, and questions:

ReviewerTypeHarm, request, or questionStatusMust beAuthor repliedQuote
theStack (member)suggestion, approachKeep only one non-static context for both signing and verifying instead of splitting themaccepted · theStack accepted furszy's explanation that separate contexts avoid adding a mutex on verification for thread safety if re-seeding is ever neededansweredyes2026-09-30: 'An alternative to this split-up would be to keep having only one "full" (i.e. non-static) context and use it for both signing and verifying'
Status from: 2026-09-30: theStack: 'Fair point, I didn't consider that there could be potential use-cases where the context needs any further modification a'
fametrano (none)suggestion, approachClone the signing context before randomizing it to create the verification context, skipping the second SHA256 self-testopenansweredno2026-10-25: 'Cloning the signing context before randomizing it would skip the second SHA256 self-test.'
w0xlt (contributor)suggestion, maintenanceRemove redundant SHA256AutoDetect() call since kernel::Context already runs it before ECC initializationaccepted · furszy explained it is needed for tests; w0xlt noted the overhead is negligible and dropped the suggestion with an ACKansweredyes2026-10-27: 'This call appears redundant. Both `bitcoind.cpp` and `NodeImpl::baseInitialize()` construct a `kernel::Context`, which already runs `SHA256AutoDetect()` before ECC initialization.'
Status from: 2026-10-28: w0xlt: 'although the extra overhead is negligible during normal startup'

Support:

  • w0xlt (contributor) (Concept ACK, 2026-09-08): Concept ACK [not substantive]
  • fjahr (member) (Concept ACK, 2026-09-08): Concept ACK [not substantive]
  • sedited (member) (Concept ACK, 2026-09-08): Finally! Concept ACK [not substantive]
  • ismaelsadeeq (member) (Concept ACK, 2026-09-08): Awesome Concept ACK [not substantive]
  • theStack (member) (Concept ACK, 2026-09-08): Splendid Concept ACK [not substantive]
  • hebasto (member) (Concept ACK, 2026-09-10): Concept ACK. [not substantive]
  • theStack (member) (2026-09-30) [read]: LGTM, just left two organizational comments. The MuSig and BIP352 modules could also take use of the plugged in compression function, either here or in a follow-up PR. [not substantive]
  • fametrano (none) (Tested ACK, 2026-10-25) [both]: Ran a differential test harness comparing 20,000 rounds across tagged hashes, BIP340 signing, ECDSA, EllSwift, MuSig2, and silent payments labels; benchmarked speedups on Apple M5
  • w0xlt (contributor) (ACK, 2026-10-28): ACK ecf779fa06cef78ca668715cba21b30a1fda8a06 [not substantive]

Participants:

  • fjahr (member, support, 1 statements 2026-09-08 to 2026-09-08): Concept ACK
  • ismaelsadeeq (member, support, 1 statements 2026-09-08 to 2026-09-08): Concept ACK
  • sedited (member, support, 2 statements 2026-09-08 to 2026-10-31): Concept ACK; pinged theStack for re-review
  • theStack (member, support, 5 statements 2026-09-08 to 2026-09-30): Concept ACK and review; suggested keeping a single context and accepted author's explanation
  • w0xlt (contributor, support, 4 statements 2026-09-08 to 2026-10-28): Concept ACK and ACK; suggested removing redundant SHA256AutoDetect call and dropped it
  • fanquake (member, neutral, 1 statements 2026-09-09 to 2026-09-09): pinged real-or-random for awareness
  • hebasto (member, support, 1 statements 2026-09-10 to 2026-09-10): Concept ACK
  • real-or-random (member, neutral, 1 statements 2026-10-01 to 2026-10-01): discussed context re-randomization and agreed it belongs in a follow-up
  • fametrano (none, support, 2 statements 2026-10-25 to 2026-10-25): Tested ACK; suggested cloning signing context before randomizing

Files

262 lines under test/bench/ci.

  • src/bench/ecc_sign_verify.cpp +119/-0
  • src/key.cpp +14/-63
  • src/test/ecc_context_tests.cpp +62/-0
  • src/ecc_context.cpp +58/-0
  • src/pubkey.cpp +28/-27
  • src/ecc_context.h +41/-0
  • src/common/ecc_init.cpp +35/-0
  • src/key.h +0/-22
  • src/common/ecc_init.h +21/-0
  • src/bitcoin-tx.cpp +4/-4
  • src/test/fuzz/script_flags.cpp +7/-1
  • src/bench/sign_transaction.cpp +4/-2
  • src/test/fuzz/script_assets_test_minimizer.cpp +5/-1
  • src/bench/ccoins_caching.cpp +3/-2
  • src/bench/checkqueue.cpp +3/-2
  • src/crypto/sha256.cpp +5/-0
  • src/node/context.h +3/-2
  • src/bench/bip324_ecdh.cpp +3/-1
  • src/bench/descriptors.cpp +2/-2
  • src/bench/ellswift.cpp +3/-1
  • src/bench/verify_script.cpp +3/-1
  • src/bitcoin-wallet.cpp +2/-2
  • src/node/interfaces.cpp +2/-2
  • src/test/fuzz/secp256k1_ecdsa_signature_parse_der_lax.cpp +2/-2
  • src/bitcoind.cpp +2/-1
  • src/crypto/sha256.h +3/-0
  • src/test/fuzz/bip324.cpp +2/-1
  • src/test/fuzz/descriptor_parse.cpp +2/-1
  • src/test/fuzz/key.cpp +2/-1
  • src/test/fuzz/key_io.cpp +2/-1
  • src/test/fuzz/message.cpp +2/-1
  • src/test/fuzz/miniscript.cpp +2/-1
  • src/test/fuzz/p2p_transport_serialization.cpp +2/-1
  • src/test/fuzz/script_sign.cpp +2/-1
  • src/test/util/setup_common.cpp +2/-1
  • src/CMakeLists.txt +2/-0
  • src/init.cpp +1/-1
  • src/test/sanity_tests.cpp +1/-1
  • src/bench/CMakeLists.txt +1/-0
  • src/common/bip352.cpp +1/-0
  • src/kernel/CMakeLists.txt +1/-0
  • src/musig.cpp +1/-0
  • src/node/context.cpp +0/-1
  • src/test/CMakeLists.txt +1/-0

Card

The short text the ranking pass compares across PRs.

This PR integrates Bitcoin Core's hardware-accelerated SHA256 compression function into libsecp256k1 context instances, replacing libsecp256k1's software-only hashing fallback. It also separates ECC context initialization into dedicated signing and verification contexts managed via a unified RAII lifecycle. Benchmarks show a 7% to 13% reduction in signing latency on architectures with SHA hardware extensions, while verification performance remains essentially unchanged. No prerequisite or dependent pull requests are indicated.

Data

dossier JSON · extract JSON · model ledger, generated 2026-11-01T01:16, confidence high, input hash c4057a1b291574a1
thread read through 2026-10-31 (23 statements), head ecf779fa06
labels: Utils/log/libs

Categories

Utilities (logging, arguments, libraries)

P2 · speedup

Plugging Bitcoin Core's hardware SHA256 implementation into libsecp256k1 provides measurable performance improvements for cryptographic signing. Benchmarks show ECDSA signing improves by ~13–15% and Schnorr signing by ~3–7% on CPUs with SHA extensions, while cleanly structuring the ECC context lifecycle across the codebase.

Membership: Has the Utils/log/libs label, updates src/crypto/sha256 and ECC initialization in src/common/, and integrates hardware SHA256 into libsecp256k1 contexts.

Factors: security/stability 1, bug 0, performance 2, user value 1, leverage 1