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

pull furszy wants to merge 11 commits into bitcoin:master from furszy:2026_secp_pluggable_sha changing 43 files +452 −151
  1. furszy commented at 8:28 PM on September 7, 2026: member

    Since https://github.com/bitcoin-core/secp256k1/pull//1777 , libsecp256k1 allows an externally provided SHA256 compression function. This PR plug ours in, so it runs on our SHA-NI/ARMv8/SSE4 hardware optimized implementation instead of the libsecp bare internal one.

    The biggest gains are at the signing side, not at the verification side.

    The first commits restructure how the libsecp context is encapsulated and initialized. ECC_Context now properly handles the libsecp context lifecycle and fully behaves as a singleton, getting decoupled from the key.h/cpp primitive (which is no longer accessed by upper layers just to init ECC), allowing us to introduce a verification context within the same object, and moving the singleton initialization to ecc_init.h which simplifies usage to a single entry point for all users.

    Benchmarks at the bench introduction commit (43c9bdbf8ada1b581b5ab1f0a102517c243a60da) and at the tip:

    On ARM64, arm_shani implementation

    benchmark before after change
    ECDSASign 79.2 µs 69.3 µs -13%
    SchnorrSign 39.9 µs 37.1 µs -7%
    ECDSAVerify 27.4 µs 27.3 µs -0%
    SchnorrVerify 28.1 µs 27.8 µs -1%
    EllSwiftCreate 29.8 µs 28.8 µs -3%
    BIP324_ECDH 30.4 µs 30.1 µs -1%
  2. libsecp: generalize context setup and teardown
    No behavior change.
    
    First step toward an ECC_Context that owns the lifecycle of both
    libsecp contexts, signing and verification.
    
    ECC_Start receives the rng seed, so a verification context can be
    created without one. Blinding is not needed for public data.
    
    Also disallow copying ECC_Context, two copies would destroy the
    same context.
    0a0ab68160
  3. libsecp: encapsulate signing context inside ECC_Context
    No behavior change.
    
    The signing context belongs to the ECC_Context that creates and
    destroys it. Only one instance may exist at a time, and the
    getter reads from it.
    1253e64d63
  4. init: decouple ECC init from primitives
    No behavior change.
    
    One entry point for ECC initialization, which will soon be moved to
    the consensus library, and set up a verification context.
    
    The goal is to decouple context handling from the primitive key.h/cpp
    and pubkey.h/cpp, which shouldn't be accessed by the upper layers.
    1fda5a0740
  5. libsecp: ECC_Context takes the blinding seed
    No behavior change.
    
    Last ECC_Context dependency on the RNG before the move to
    the consensus library.
    fa2e2dc69f
  6. refactor: move ECC_Context to ecc_context.{h,cpp}
    No behavior change.
    
    ECC_Context now lives in the consensus library, so it can
    hold the libsecp verification context next.
    b44f0da9b2
  7. test: add ECC_Context lifecycle coverage ee77338bbd
  8. DrahtBot added the label Utils/log/libs on Sep 7, 2026
  9. DrahtBot commented at 8:28 PM on September 7, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    <!--006a51241073e994b41acfe9ec718e94-->

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/36188.

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline and AI policy for information on the review process.

    Type Reviewers
    Concept ACK w0xlt, fjahr, sedited, ismaelsadeeq, theStack

    If your review is incorrectly listed, please copy-paste <code>&lt;!--meta-tag:bot-skip--&gt;</code> into the comment that the bot should ignore.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #36122 (BIP460: CISA for Taproot key path spends by fjahr)
    • #35675 (mining: add block template manager by ismaelsadeeq)
    • #35646 (RFC: Separate out runtime errors from BlockValidationState using util::Expected by yuvicc)
    • #35511 (RFC: consensus: Make CAmount a class by hodlinator)
    • #28690 (build: Introduce internal kernel library by sedited)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

  10. DrahtBot added the label CI failed on Sep 7, 2026
  11. DrahtBot commented at 9:39 PM on September 7, 2026: contributor

    <!--85328a0da195eb286784d51f73fa0af9-->

    🚧 At least one of the CI tasks failed. <sub>Task iwyu: https://github.com/bitcoin/bitcoin/actions/runs/34159538723/job/101858273499</sub> <sub>LLM reason (✨ experimental): CI failed because the IWYU lint check detected missing/incorrect headers (generated “Failure generated from IWYU” for src/bench/ecc_sign_verify.cpp).</sub>

    <details><summary>Hints</summary>

    Try to run the tests locally, according to the documentation. However, a CI failure may still happen due to a number of reasons, for example:

    • Possibly due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

    • A sanitizer issue, which can only be found by compiling with the sanitizer and running the affected test.

    • An intermittent issue.

    Leave a comment here, if you need help tracking down a confusing failure.

    </details>

  12. bench: ECDSA and Schnorr signing and verification
    Low-level signature creation and validation benchmarks.
    f61a8a9594
  13. libsecp: plug our hardware optimized SHA256 into libsecp256k1 ctx
    libsecp256k1 lets a context use an external SHA256 compression
    function. With ours, ECDSA signing gets ~15% faster on CPUs with
    SHA extensions, Schnorr signing ~3%.
    5fb21ed986
  14. libsecp: introduce verification context to ECC_Context
    Verification uses secp256k1_context_static, which can't take our
    optimized SHA256 compression function. Rather than reusing the signing
    context, which blinds certain calculations, for no benefit to public
    data, verification gets its own context, owned by ECC_Context along
    with the signing one.
    
    Around 1% faster Schnorr signature verification. ECDSA remains equal
    as hashing is done outside libsecp.
    99a29f69fd
  15. scripted-diff: use verification context in pubkey.cpp
    Every use of secp256k1_context_static in pubkey.cpp uses public
    data, so all of them can use the verification  context, which
    contains our optimized SHA256 compression plugged in.
    
    -BEGIN VERIFY SCRIPT-
    sed -i -e '/\/\*/! s/secp256k1_context_static/GetSecp256k1VerifyContext()/g' -e 's|^#include <hash.h>$|#include <ecc_context.h>\n#include <hash.h>|' src/pubkey.cpp
    -END VERIFY SCRIPT-
    e0d46a42e0
  16. fuzz: use libsecp verification context
    Make fuzz tests use the verification context instead of the
    static one provided by libsecp.
    
    Also, introduces a simple unit test validating VerifySchnorr
    provides the correct context to libsecp.
    1c216a069b
  17. furszy force-pushed on Sep 7, 2026
  18. DrahtBot removed the label CI failed on Sep 8, 2026
  19. w0xlt commented at 7:00 AM on September 8, 2026: contributor

    Concept ACK

  20. fjahr commented at 7:23 AM on September 8, 2026: contributor

    Concept ACK

  21. sedited commented at 7:30 AM on September 8, 2026: contributor

    Finally! Concept ACK

  22. ismaelsadeeq commented at 9:32 AM on September 8, 2026: member

    Awesome Concept ACK

  23. theStack commented at 4:55 PM on September 8, 2026: contributor

    Splendid Concept ACK


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-09-09 07:56 UTC