ecmult_gen: add variable-time generator point multiplication (no API behaviour changes yet) #1883

pull theStack wants to merge 2 commits into bitcoin-core:master from theStack:add-ecmult_gen_var changing 10 files +165 −31
  1. theStack commented at 11:39 PM on June 28, 2026: contributor

    The PR is a rebased subset of #1843: it adds a variable-time variant for generator point multiplication, with the idea of enabling potential performance gains for use cases where the scalar isn't treated as secret. The implementation is essentially a copy of the existing secp256k1_ecmult_gen_gej function, but with all side-channel mitigations (i.e., constant-time code, random scalar blinding, and memory clearing) removed. The EC point operation calls (addition, doubling) are replaced with their faster variable-time equivalents.

    The first commit moves the calculation of the ecmult_gen_scalar_diff constant (scalar (2^COMB_BITS - 1) / 2) from run-time to compile-time, in order to avoid needing a context object and thus enable computing the result statelessly.

    On my arm64 machine, the variable-time variant is ~86% faster than the constant-time variant (with the default build table size, i.e. ECMULT_GEN_KB=86):

    $ ./build/bin/bench_ecmult
    Benchmark                     ,    Min(us)    ,    Avg(us)    ,    Max(us)
    
    ecmult_gen                    ,     9.32      ,     9.35      ,     9.60
    ecmult_gen_var                ,     5.02      ,     5.02      ,     5.02
    .....
    

    Note that in contrast to #1843, this PR doesn't take use of the new functions in any user-facing code (API functions) yet, to keep discussions about potential behavior changes w.r.t. constant-timing guarantees separated. The only visible change for users after merging this PR would be that the library is a tiny bit larger, as the generated tables now also contain the ecmult_gen_scalar_diff constant. On my arm64 machine, this leads to an increase of 56 bytes for the .so file (1392672 bytes master vs. 1392728 bytes PR on a default release build), which I think we can treat as negligible.

    One relatively obvious scenario where using the variable-time variant would make sense is for verifying P2TR script-paths spends in Bitcoin Core via secp256k1_xonly_pubkey_tweak_add_check (see #1843 (comment)). However, whether to change the behavior of the existing API function or adding a new one (e.g. with _var suffix) still has to be decided and might be a topic for a different PR (see #1843 (comment)). Another scenario could be scanning of Silent Payments, though in this case it has to be carefully evaluated whether it's safe to treat the tweak t_k as non-secret.

  2. ecmult_gen: compute `ecmult_gen_scalar_diff` at compile-time
    Having this available as a global constant allows to introduce an
    alternative `ecmult_gen_gej` function that doesn't need access to
    a context, see next commit.
    
    Note that the precomputed constant takes the name of the function that
    previously generated it at run-time (`secp256k1_ecmult_gen_scalar_diff`),
    while the function is now renamed to include the "compute" verb
    (`secp256k1_ecmult_gen_compute_scalar_diff`), to match the naming
    of the table generation function.
    
    Can be reviewed with `--color-moved=dimmed-zebra` for easier
    checking of the move-only parts.
    e44cb53fd2
  3. ecmult_gen: introduce `secp256k1_ecmult_gen_var_{gej,ge}`
    Add faster variable-time variants for generator point multiplication.
    This is essentially `ecmult_gen` without side-channel mitigations and
    without requiring a context object. Intended for use cases where the
    scalar is not representing sensitive data.
    
    On my arm64 machine, this is ~86% faster than the constant-time variant
    (with the default build table size, i.e. ECMULT_GEN_KB=86):
    
    ```
    $ ./build/bin/bench_ecmult
    Benchmark                     ,    Min(us)    ,    Avg(us)    ,    Max(us)
    
    ecmult_gen                    ,     9.32      ,     9.35      ,     9.60
    ecmult_gen_var                ,     5.02      ,     5.02      ,     5.02
    .....
    ```
    4dedd6effc

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin-core/secp256k1. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-07-12 14:15 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me