Commit Graph

1766 Commits

Author SHA1 Message Date
DarkWindman
598e22dcde whitelist: document the degenerate W = -P_i destination 2026-08-17 13:43:52 +03:00
DarkWindman
e8c3396597 whitelist: honour the documented parse initialization guarantee 2026-08-14 12:01:58 +03:00
DarkWindman
1de3864ff9 bppp: check for overflow in generator allocation 2026-08-14 12:01:43 +03:00
mllwchrry
65093e1444 surjection: prevent s-value reuse for different proof inputs
The s-values produced by secp256k1_surjection_genrand previously
depended only on their indices and the difference between
input_blinding_key and output_blinding_key. Calls with the same
difference therefore reused s-values even when their proof inputs
differed.

For proofs with the same used-input selection and honest input index,
the same generated s-value was used as the signing nonce. Reusing this
nonce across different proof messages allowed recovery of the
blinding-key difference. The remaining repeated s-values also revealed
the honest input index.

This commit affects proof generation only; verification is unchanged.
2026-08-13 17:35:31 +03:00
mllwchrry
217fe59bbf tests: register run_util_tests and run_ec_commit, remove dead print_vector 2026-07-03 15:17:36 +03:00
mllwchrry
b1f9e6e360 Merge branch 'master' into sync-ebf59432 2026-07-02 18:43:56 +03:00
merge-script
b90075a074 Merge bitcoin-core/secp256k1#1882: scalar: correct _scalar_get_bits_{limb32,var} input condition docs
6a599a4428 scalar: correct `_scalar_get_bits_{limb32,var}` input condition docs (Sebastian Falbesoner)

Pull request description:

  This PR is a small correction of documented (off-by-one) input conditions for the `scalar_get_bits_{limb32,var}`, that came up during reviewing #1845.

ACKs for top commit:
  real-or-random:
    ACK 6a599a4428

Tree-SHA512: 2f0982b6d69d2abeebe0c9d82161e85feaae317d1e3ac2f415338044c8725a0442e14d998053e62f1b5f59f785a31796b5b3c4b36d9eb516ff53e9bb11429e78
2026-06-26 08:40:47 +02:00
Sebastian Falbesoner
6a599a4428 scalar: correct _scalar_get_bits_{limb32,var} input condition docs 2026-06-26 03:04:13 +02:00
Lőrinc
994b35010d field: correct fe_equal's b magnitude bound
`secp256k1_fe_equal` negates `a` before adding `b`.
That gives the temporary value magnitude 2, and the following field addition requires the input magnitudes to sum to at most 32.
So the largest `b` magnitude the implementation can accept is 30, not 31.

Lower the documented and checked bound for `b` to 30.
Adjust the focused test to use random field elements with randomized magnitudes within the accepted `a <= 1` and `b <= 30` bounds.

Co-authored-by: Sebastian Falbesoner <sebastian.falbesoner@gmail.com>
Co-authored-by: Tim Ruffing <me@real-or-random.org>
2026-06-25 09:23:38 -07:00
merge-script
2ce4f71dc5 Merge bitcoin-core/secp256k1#1845: Improve checks for scalar _get_bits methods
0cad3df503 Improve checks for scalar _get_bits methods (Peter.Dettman)

Pull request description:

  Improves the `VERIFY_CHECK`s in all `_scalar_get_bits_limb32` and `_scalar_get_bits_var` methods.

  The initial prompt was noticing that scalar_4x64_impl/`secp256k1_scalar_get_bits_limb32` was not restricting to 32-bit limbs correctly. Then missing range checks for `offset` were added and all such checks rewritten to avoid overflow.

  With these changes, the _low and _4x64 impls of `_get_bits_var` can no longer forward to `_get_bits_limb32`, so those calls were inlined instead.

ACKs for top commit:
  sipa:
    ACK 0cad3df503
  theStack:
    ACK 0cad3df503
  real-or-random:
    utACK 0cad3df503

Tree-SHA512: 753991d586fe5695dd33af6c261c5458ab659be94204626166503af7d403748abb76d791846857a16383cbd38a1f84af9fde74b4327d68d706f88b6531ee7546
2026-06-25 17:02:04 +02:00
Tim Ruffing
9d75769dec tests: Fix GCC 17 snapshot warning
Passing a non-malloc pointer to free() would be UB. In this case, the
free() line is never actually reached (and GCC 17 fails to prove this)
in a correct implementation of secp256k1_scratch_space_destroy(), but
the test shouldn't rely on the correctness of the tested function.
2026-06-25 14:57:56 +02:00
merge-script
bd0287d650 Merge bitcoin-core/secp256k1#1859: field: force-inline 5x52 mul and sqr
71fcd8410e field: force-inline 5x52 mul and sqr (Lőrinc)

Pull request description:

  **Problem:** The 5x52 field multiplication and squaring routines are hot in group arithmetic and scalar multiplication. Some compilers leave the thin wrappers and int128 inner helpers out of line, which keeps a call boundary in this hot path and limits scheduling of the 64x64->128 arithmetic.

  **Fix:** Define `SECP256K1_FORCE_INLINE` next to the existing inline helper and use it for the 5x52 multiplication and squaring wrappers and `int128` inner helpers.

  For default optimized builds, this expands to `__forceinline` on MSVC-compatible compilers and to `__attribute__((always_inline))` on GCC-compatible compilers. It falls back to the existing inline spelling when inlining is disabled, when optimization is disabled, when optimizing for size on GCC/Clang, or when `_DEBUG` is defined.

  **Benchmarks:** Values are relative changes in `Min(us)`, lower is better.

  | Source | Host / CPU | Compiler | ecdsa_verify | ecdh | schnorrsig_verify | field_sqr | field_mul |
  |---|---|---|---:|---:|---:|---:|---:|
  | local | M4-Max.local | gcc-14 14.3.0 | -9.1% | -9.0% | -9.6% | -7.0% | -4.0% |
  | local | i9-ssd | GCC 16.1.0 | -5.3% | -4.1% | -5.5% | -15.7% | -11.6% |
  | local | WIN-A2EHOAU4JET / Xeon E5-2637 v2 | MSVC 19.50.35728 | -2.6% | -9.3% | -2.4% | -7.4% | -7.4% |
  | local | i7-hdd | GCC 14.2.0 | -10.9% | -11.1% | -10.5% | -9.4% | -21.6% |
  | local | umbrel / Intel N150 | GCC 12.2.0 | -4.9% | -4.3% | -4.6% | +0.6% | -1.1% |
  | local | rpi5-16-3 | GCC 14.2.0 | -0.6% | -0.7% | -0.6% | -5.5% | -1.0% |
  | local | rpi4-2-1 | GCC 14.2.0 | -2.7% | -2.3% | -2.7% | -5.6% | -4.0% |
  | local | nodl / Cortex-A53 | GCC 11.4.0 | -3.3% | -7.6% | -5.7% | -9.9% | -1.8% |
  | andrewtoth | i9-14900HX | GCC 12.3 | -5.3% | -4.2% | -5.6% | -1.5% | -6.1% |
  | theStack | Snapdragon X Elite X1E-78-100 | GCC 14.2.0 | -11.2% | n/a | -11.1% | n/a | n/a |
  | sipa | Ryzen 5950X | GCC 15.2.0 | -11.4% | -10.4% | -8.4% | n/a | n/a |

  <img width="2534" height="1104" alt="image" src="https://github.com/user-attachments/assets/218a4075-5937-4850-ab8b-c6fc5d2fee57" />

  **Tradeoffs:** The speedups reproduce most consistently with GCC and MSVC. Clang was less consistently positive.

  Inlining also increases code size:
  | Platform | Artifact | Before | After | Delta |
  |---|---|---:|---:|---:|
  | macOS GCC | `libsecp256k1.a` | 1,254,320 | 1,311,368 | +57,048 (+4.55%) |
  | Linux GCC | `libsecp256k1.a` | 1,271,040 | 1,330,808 | +59,768 (+4.70%) |
  | Windows MSVC Release | `libsecp256k1-*.dll` | 1,239,040 | 1,414,144 | +175,104 (+14.13%) |

  ---

  <details><summary>Linux benchmarking script</summary>

  ```bash
  BEFORE=8363a2d8d1b47857c437f7cf22bd11ab06c7c50f; AFTER=33b1b9c455eb2bb07eded939b36abc49859d2ccf; CC=gcc; \
  API_ITERS=10000; INT_ITERS=200000; JOBS=1; \
  BH=$(git rev-parse --short=12 "$BEFORE") && AH=$(git rev-parse --short=12 "$AFTER") && \
  RUN=$(date +%Y%m%d%H%M%S) && \
  ROOT="$PWD/.bench-builds/gcc-$BH-$AH-$RUN" && \
  RAW="$PWD/.bench-results/secp-bench-gcc-$BH-$AH-$RUN.txt" && \
  (set -e; \
    mkdir -p "$ROOT" "$(dirname "$RAW")"; \
    printf "host: %s, compiler: %s\n" "$(hostname)" "$("$CC" --version | sed -n '1p')" | tee "$RAW" >&2; \
    old=$(git symbolic-ref --short -q HEAD || git rev-parse HEAD); \
    trap 'git switch -q "$old" 2>/dev/null || git switch -q --detach "$old"' EXIT; \
    for side in before after; do \
      ref=$([ "$side" = before ] && printf %s "$BEFORE" || printf %s "$AFTER"); \
      git cat-file -e "$ref^{commit}" 2>/dev/null || git fetch -q origin "$ref"; \
      h=$(git rev-parse --short=12 "$ref"); \
      b="$ROOT/$side-$h"; \
      echo "== $side $h ==" >&2; \
      git switch -q --detach "$ref"; \
      cmake -S . -B "$b" -DCMAKE_C_COMPILER="$CC" -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DSECP256K1_BUILD_BENCHMARK=ON -DSECP256K1_BUILD_TESTS=OFF -DSECP256K1_BUILD_EXHAUSTIVE_TESTS=OFF -DSECP256K1_BUILD_CTIME_TESTS=OFF -DSECP256K1_BUILD_EXAMPLES=OFF -DSECP256K1_ENABLE_MODULE_MUSIG=OFF -DSECP256K1_VALGRIND=OFF >> "$RAW" 2>&1; \
      cmake --build "$b" -j "$JOBS" --target bench bench_internal >> "$RAW" 2>&1; \
      echo "=== $side $ref $h ===" >> "$RAW"; \
      SECP256K1_BENCH_ITERS=$API_ITERS "$b/bin/bench" ecdsa ec ecdh schnorrsig ellswift >> "$RAW"; \
      SECP256K1_BENCH_ITERS=$INT_ITERS "$b/bin/bench_internal" field group ecmult hash context >> "$RAW"; \
    done; \
    awk -F, '/^=== /{split($0,p," "); side=p[2]; next} /^[[:alnum:]_][[:alnum:]_]*[[:space:]]*,/{name=$1; val=$2+0; gsub(/^[[:space:]]+|[[:space:]]+$/,"",name); if(name!="Benchmark"){if(!(name in seen)){seen[name]=1; order[++n]=name} x[side,name]=val}} END{print "Benchmark\tBefore min(us)\tAfter min(us)\tDelta"; for(i=1;i<=n;i++){name=order[i]; b=x["before",name]; a=x["after",name]; if(b&&a) printf "%s\t%.6g\t%.6g\t%+.1f%%\n",name,b,a,100*(a-b)/b}}' "$RAW" | column -t -s $'\t'; \
    echo "raw: $RAW" >&2)
  ```
  </details>

  <details><summary>Linux size comparison script</summary>

  ```bash
  BEFORE=8363a2d8d1b47857c437f7cf22bd11ab06c7c50f; AFTER=33b1b9c455eb2bb07eded939b36abc49859d2ccf; CC=gcc; JOBS=1; \
  BH=$(git rev-parse --short=12 "$BEFORE"); AH=$(git rev-parse --short=12 "$AFTER"); RUN=$(date +%Y%m%d%H%M%S); ROOT="$PWD/.size-builds/gcc-$BH-$AH-$RUN"; \
  (set -e; old=$(git symbolic-ref --short -q HEAD || git rev-parse HEAD); trap 'git switch -q "$old" 2>/dev/null || git switch -q --detach "$old"' EXIT; \
  printf "host: %s, compiler: %s\n" "$(hostname)" "$("$CC" --version | sed -n '1p')"; \
  for side in before after; do \
    ref=$([ "$side" = before ] && printf %s "$BEFORE" || printf %s "$AFTER"); git cat-file -e "$ref^{commit}" 2>/dev/null || git fetch -q origin "$ref"; h=$(git rev-parse --short=12 "$ref"); b="$ROOT/$side-$h"; \
    git switch -q --detach "$ref"; \
    cmake -S . -B "$b" -DCMAKE_C_COMPILER="$CC" -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DSECP256K1_BUILD_BENCHMARK=OFF -DSECP256K1_BUILD_TESTS=OFF -DSECP256K1_BUILD_EXHAUSTIVE_TESTS=OFF -DSECP256K1_BUILD_CTIME_TESTS=OFF -DSECP256K1_BUILD_EXAMPLES=OFF -DSECP256K1_ENABLE_MODULE_MUSIG=OFF -DSECP256K1_VALGRIND=OFF >/dev/null; \
    cmake --build "$b" -j "$JOBS" --target secp256k1 >/dev/null; \
    lib=$(find "$b" -name 'libsecp256k1.a' -print -quit); \
    bytes=$(wc -c < "$lib" | tr -d ' '); \
    printf "%s\t%s\t%s\n" "$side" "$h" "$bytes"; \
    done | awk 'BEGIN{print "Side\tCommit\tlibsecp256k1.a bytes"} {print; size[$1]=$3} END{if(size["before"]&&size["after"]) printf "Delta\t\t%+d bytes (%+.2f%%)\n",size["after"]-size["before"],100*(size["after"]-size["before"])/size["before"]}' | column -t -s $'\t')
  ```
  </details>

  <details><summary>host: M4-Max.local, compiler: gcc-14 (Homebrew GCC 14.3.0) 14.3.0</summary>

  ```bash
  Benchmark                 Before min(us)  After min(us)  Delta
  ecdsa_verify              17.5            15.9           -9.1%
  ecdsa_sign                12.3            12.1           -1.6%
  ec_keygen                 8.07            7.77           -3.7%
  ecdh                      16.6            15.1           -9.0%
  schnorrsig_sign           8.6             8.29           -3.6%
  schnorrsig_verify         17.8            16.1           -9.6%
  ellswift_encode           11.1            11.1           +0.0%
  ellswift_decode           4.68            4.69           +0.2%
  ellswift_keygen           19.4            19.1           -1.5%
  ellswift_ecdh             18.5            17.1           -7.6%
  field_half                0.00154         0.00155        +0.6%
  field_normalize           0.00665         0.00672        +1.1%
  field_normalize_weak      0.00291         0.00291        +0.0%
  field_sqr                 0.00871         0.0081         -7.0%
  field_mul                 0.00969         0.0093         -4.0%
  field_inverse             1.57            1.58           +0.6%
  field_inverse_var         0.735           0.742          +1.0%
  field_is_square_var       0.994           1              +0.6%
  field_sqrt                2.21            2.22           +0.5%
  group_double_var          0.0502          0.0447         -11.0%
  group_add_var             0.126           0.11           -12.7%
  group_add_affine          0.1             0.0922         -7.8%
  group_add_affine_var      0.0887          0.077          -13.2%
  group_add_zinv_var        0.106           0.0902         -14.9%
  group_to_affine_var       0.774           0.774          +0.0%
  ecmult_wnaf               0.334           0.334          +0.0%
  hash_sha256               0.12            0.12           +0.0%
  hash_hmac_sha256          0.464           0.463          -0.2%
  hash_rfc6979_hmac_sha256  2.55            2.55           +0.0%
  context_create            1.96            1.96           +0.0%

  Side    Commit                 libsecp256k1.a bytes
  before  8363a2d8d1           1254320
  after   33b1b9c455eb           1311368
  Delta   +57048 bytes (+4.55%)
  ```

  </details>

  <details><summary>host: WIN-A2EHOAU4JET (Intel(R) Xeon(R) CPU E5-2637 v2 @ 3.50GHz), system: Microsoft Windows NT 10.0.20348.0, compiler: Microsoft (R) C/C++ Optimizing Compiler Version 19.50.35728 for x64</summary>

  ```bash
  Benchmark                    Before min(us) After min(us)    Delta
  ecdsa_verify                           74.1          72.2    -2.6%
  ecdsa_sign                             43.3          41.4    -4.4%
  ec_keygen                              32.3            30    -7.1%
  ecdh                                     75            68    -9.3%
  schnorrsig_sign                        34.1            32    -6.2%
  schnorrsig_verify                      74.9          73.1    -2.4%
  ellswift_encode                        32.3          32.5    +0.6%
  ellswift_decode                        14.4          14.6    +1.4%
  ellswift_keygen                        64.6          62.9    -2.6%
  ellswift_ecdh                          80.2          73.7    -8.1%
  field_half                          0.00378       0.00378    +0.0%
  field_normalize                      0.0114        0.0114    +0.0%
  field_normalize_weak                0.00389       0.00389    +0.0%
  field_sqr                            0.0272        0.0252    -7.4%
  field_mul                            0.0394        0.0365    -7.4%
  field_inverse                          3.27          3.29    +0.6%
  field_inverse_var                      2.07          2.11    +1.9%
  field_is_square_var                     2.7          2.67    -1.1%
  field_sqrt                             7.47          6.98    -6.6%
  group_double_var                      0.245         0.207   -15.5%
  group_add_var                           0.6         0.525   -12.5%
  group_add_affine                      0.465         0.405   -12.9%
  group_add_affine_var                  0.418         0.358   -14.4%
  group_add_zinv_var                    0.458         0.403   -12.0%
  group_to_affine_var                    2.25          2.26    +0.4%
  ecmult_wnaf                            0.58          0.59    +1.7%
  hash_sha256                           0.332         0.333    +0.3%
  hash_hmac_sha256                       1.31          1.31    +0.0%
  hash_rfc6979_hmac_sha256               7.23           7.2    -0.4%
  context_create                         3.32          3.34    +0.6%

  Side     Commit          DLL bytes
  before   8363a2d8d1      1239040
  after    a37e34e187da      1414144
  Delta                      175104 (+14.13%)
  ```
  </details>

  <details><summary>host: i9-ssd, compiler: gcc (GCC) 16.1.0</summary>

  ```bash
  Benchmark                 Before min(us)  After min(us)  Delta
  ecdsa_verify              39.6            37.5           -5.3%
  ecdsa_sign                27.1            26.4           -2.6%
  ec_keygen                 18.2            17.5           -3.8%
  ecdh                      39              37.4           -4.1%
  schnorrsig_sign           19.5            18.7           -4.1%
  schnorrsig_verify         40.3            38.1           -5.5%
  ellswift_encode           20.1            19.9           -1.0%
  ellswift_decode           8.59            8.46           -1.5%
  ellswift_keygen           38.2            37.3           -2.4%
  ellswift_ecdh             43.4            40.9           -5.8%
  field_half                0.00275         0.00275        +0.0%
  field_normalize           0.00995         0.00994        -0.1%
  field_normalize_weak      0.00378         0.00378        +0.0%
  field_sqr                 0.0178          0.015          -15.7%
  field_mul                 0.019           0.0168         -11.6%
  field_inverse             2.41            2.39           -0.8%
  field_inverse_var         1.32            1.28           -3.0%
  field_is_square_var       1.69            1.68           -0.6%
  field_sqrt                4.21            4.16           -1.2%
  group_double_var          0.121           0.115          -5.0%
  group_add_var             0.309           0.272          -12.0%
  group_add_affine          0.248           0.231          -6.9%
  group_add_affine_var      0.216           0.194          -10.2%
  group_add_zinv_var        0.245           0.213          -13.1%
  group_to_affine_var       1.41            1.36           -3.5%
  ecmult_wnaf               0.536           0.581          +8.4%
  hash_sha256               0.29            0.286          -1.4%
  hash_hmac_sha256          1.14            1.13           -0.9%
  hash_rfc6979_hmac_sha256  6.3             6.21           -1.4%
  context_create            2.68            2.68           +0.0%

  Side    Commit        libsecp256k1.a bytes
  before  8363a2d8d1  1271040
  after   33b1b9c455eb  1330808
  Delta                 +59768 bytes (+4.70%)
  ```
  </details>

  <details><summary>host: i7-hdd, compiler: gcc (Ubuntu 14.2.0-19ubuntu2) 14.2.0</summary>

  ```bash
  Benchmark                 Before min(us)  After min(us)  Delta
  ecdsa_verify              43.1            38.4           -10.9%
  ecdsa_sign                28.4            27.3           -3.9%
  ec_keygen                 19.3            18             -6.7%
  ecdh                      43.2            38.4           -11.1%
  schnorrsig_sign           20.6            19.4           -5.8%
  schnorrsig_verify         43.7            39.1           -10.5%
  ellswift_encode           19.9            19.7           -1.0%
  ellswift_decode           8.48            8.41           -0.8%
  ellswift_keygen           39.2            37.8           -3.6%
  ellswift_ecdh             46.4            41.8           -9.9%
  field_half                0.00275         0.00275        +0.0%
  field_normalize           0.00998         0.00998        +0.0%
  field_normalize_weak      0.00402         0.00402        +0.0%
  field_sqr                 0.017           0.0154         -9.4%
  field_mul                 0.0218          0.0171         -21.6%
  field_inverse             2.49            2.46           -1.2%
  field_inverse_var         1.36            1.35           -0.7%
  field_is_square_var       1.66            1.67           +0.6%
  field_sqrt                4.07            4.07           +0.0%
  group_double_var          0.132           0.119          -9.8%
  group_add_var             0.346           0.28           -19.1%
  group_add_affine          0.266           0.236          -11.3%
  group_add_affine_var      0.243           0.201          -17.3%
  group_add_zinv_var        0.265           0.216          -18.5%
  group_to_affine_var       1.46            1.44           -1.4%
  ecmult_wnaf               0.554           0.604          +9.0%
  hash_sha256               0.305           0.298          -2.3%
  hash_hmac_sha256          1.18            1.17           -0.8%
  hash_rfc6979_hmac_sha256  6.47            6.43           -0.6%
  context_create            2.73            2.71           -0.7%
  ```

  </details>

  <details><summary>host: rpi5-16-3, compiler: gcc (Ubuntu 14.2.0-19ubuntu2) 14.2.0</summary>

  ```bash
  Benchmark                 Before min(us)  After min(us)  Delta
  ecdsa_verify              157             156            -0.6%
  ecdsa_sign                69.5            69.3           -0.3%
  ec_keygen                 57.6            57.5           -0.2%
  ecdh                      149             148            -0.7%
  schnorrsig_sign           59.3            59             -0.5%
  schnorrsig_verify         158             157            -0.6%
  ellswift_encode           44.9            44.8           -0.2%
  ellswift_decode           24.2            24.2           +0.0%
  ellswift_keygen           103             102            -1.0%
  ellswift_ecdh             154             154            +0.0%
  field_half                0.00334         0.00334        +0.0%
  field_normalize           0.0143          0.0144         +0.7%
  field_normalize_weak      0.00543         0.00543        +0.0%
  field_sqr                 0.0654          0.0618         -5.5%
  field_mul                 0.0919          0.091          -1.0%
  field_inverse             4.8             4.78           -0.4%
  field_inverse_var         2.24            2.24           +0.0%
  field_is_square_var       2.31            2.31           +0.0%
  field_sqrt                17              17             +0.0%
  group_double_var          0.526           0.525          -0.2%
  group_add_var             1.35            1.34           -0.7%
  group_add_affine          0.988           0.984          -0.4%
  group_add_affine_var      0.926           0.915          -1.2%
  group_add_zinv_var        1.02            1.01           -1.0%
  group_to_affine_var       2.6             2.6            +0.0%
  ecmult_wnaf               0.606           0.614          +1.3%
  hash_sha256               0.316           0.315          -0.3%
  hash_hmac_sha256          1.2             1.2            +0.0%
  hash_rfc6979_hmac_sha256  6.62            6.62           +0.0%
  context_create            4.18            4.18           +0.0%
  ```
  </details>

  <details><summary>host: rpi4-2-1, compiler: gcc (Ubuntu 14.2.0-19ubuntu2) 14.2.0</summary>

  ```bash
  Benchmark                 Before min(us)  After min(us)  Delta
  ecdsa_verify              222             216            -2.7%
  ecdsa_sign                111             109            -1.8%
  ec_keygen                 90.4            88.6           -2.0%
  ecdh                      216             211            -2.3%
  schnorrsig_sign           93.4            91.4           -2.1%
  schnorrsig_verify         224             218            -2.7%
  ellswift_encode           64.2            64.1           -0.2%
  ellswift_decode           33.5            33.5           +0.0%
  ellswift_keygen           156             153            -1.9%
  ellswift_ecdh             226             220            -2.7%
  field_half                0.00447         0.00447        +0.0%
  field_normalize           0.0215          0.0215         +0.0%
  field_normalize_weak      0.00783         0.00783        +0.0%
  field_sqr                 0.0871          0.0822         -5.6%
  field_mul                 0.126           0.121          -4.0%
  field_inverse             8.54            8.54           +0.0%
  field_inverse_var         3.25            3.25           +0.0%
  field_is_square_var       3.57            3.57           +0.0%
  field_sqrt                22.7            22.6           -0.4%
  group_double_var          0.72            0.71           -1.4%
  group_add_var             1.87            1.8            -3.7%
  group_add_affine          1.4             1.36           -2.9%
  group_add_affine_var      1.3             1.24           -4.6%
  group_add_zinv_var        1.42            1.37           -3.5%
  group_to_affine_var       3.76            3.75           -0.3%
  ecmult_wnaf               1.06            1.05           -0.9%
  hash_sha256               0.532           0.531          -0.2%
  hash_hmac_sha256          2.02            2.02           +0.0%
  hash_rfc6979_hmac_sha256  11.2            11.2           +0.0%
  context_create            6.8             6.8            +0.0%
  ```
  </details>

  <details><summary>host: umbrel (Intel(R) N150), compiler: gcc (Debian 12.2.0-14+deb12u1) 12.2.0</summary>

  ```bash
  Benchmark                 Before min(us)  After min(us)  Delta
  ecdsa_verify              371             353            -4.9%
  ecdsa_sign                163             160            -1.8%
  ec_keygen                 129             123            -4.7%
  ecdh                      347             332            -4.3%
  schnorrsig_sign           131             126            -3.8%
  schnorrsig_verify         373             356            -4.6%
  ellswift_encode           143             142            -0.7%
  ellswift_decode           71.3            70.8           -0.7%
  ellswift_keygen           272             268            -1.5%
  ellswift_ecdh             367             352            -4.1%
  field_half                0.0124          0.0124         +0.0%
  field_normalize           0.0439          0.0439         +0.0%
  field_normalize_weak      0.0192          0.0192         +0.0%
  field_sqr                 0.168           0.169          +0.6%
  field_mul                 0.182           0.18           -1.1%
  field_inverse             11.2            11.2           +0.0%
  field_inverse_var         8.44            8.4            -0.5%
  field_is_square_var       9.56            9.55           -0.1%
  field_sqrt                45              44             -2.2%
  group_double_var          1.25            1.18           -5.6%
  group_add_var             2.92            2.68           -8.2%
  group_add_affine          2.22            2.12           -4.5%
  group_add_affine_var      2.02            1.86           -7.9%
  group_add_zinv_var        2.21            2.01           -9.0%
  group_to_affine_var       9.25            9.13           -1.3%
  ecmult_wnaf               2.51            2.45           -2.4%
  hash_sha256               1.13            1.12           -0.9%
  hash_hmac_sha256          4.44            4.44           +0.0%
  hash_rfc6979_hmac_sha256  24.4            24.4           +0.0%
  context_create            14.2            14.1           -0.7%
  ```
  </details>

  <details><summary>host: nodl (Cortex-A53), compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0</summary>

  ```bash
  Benchmark                 Before min(us)  After min(us)  Delta
  ecdsa_verify              632             611            -3.3%
  ecdsa_sign                308             291            -5.5%
  ec_keygen                 228             212            -7.0%
  ecdh                      633             585            -7.6%
  schnorrsig_sign           231             221            -4.3%
  schnorrsig_verify         630             594            -5.7%
  ellswift_encode           156             156            +0.0%
  ellswift_decode           80              76.1           -4.9%
  ellswift_keygen           438             455            +3.9%
  ellswift_ecdh             613             599            -2.3%
  field_half                0.0106          0.00985        -7.1%
  field_normalize           0.0483          0.0499         +3.3%
  field_normalize_weak      0.0173          0.0173         +0.0%
  field_sqr                 0.202           0.182          -9.9%
  field_mul                 0.278           0.273          -1.8%
  field_inverse             21.3            21.1           -0.9%
  field_inverse_var         7.67            7.48           -2.5%
  field_is_square_var       8.73            8.91           +2.1%
  field_sqrt                65.8            61.9           -5.9%
  group_double_var          2.04            1.9            -6.9%
  group_add_var             5.35            5.09           -4.9%
  group_add_affine          3.93            3.51           -10.7%
  group_add_affine_var      3.56            3.32           -6.7%
  group_add_zinv_var        3.94            3.65           -7.4%
  group_to_affine_var       9.56            10.4           +8.8%
  ecmult_wnaf               2.37            2.48           +4.6%
  hash_sha256               1.13            1.19           +5.3%
  hash_hmac_sha256          5.08            4.76           -6.3%
  hash_rfc6979_hmac_sha256  33.3            31.2           -6.3%
  context_create            19.3            18.8           -2.6%
  ```
  </details>

  <details><summary>Reviewer measurements</summary>

  ### andrewtoth, i9-14900HX, GCC 12.3

  ```text
  Benchmark                 Before min(us)  After min(us)  Delta
  ecdsa_verify              22.7            21.5           -5.3%
  ecdsa_sign                14.3            14.0           -2.1%
  ec_keygen                 9.90            9.54           -3.6%
  ecdh                      21.6            20.7           -4.2%
  schnorrsig_sign           10.6            10.2           -3.8%
  schnorrsig_verify         23.1            21.8           -5.6%
  ellswift_ecdh             23.8            22.7           -4.6%
  field_sqr                 0.00912         0.00898        -1.5%
  field_mul                 0.0114          0.0107         -6.1%
  field_inverse             1.23            1.24           +0.8%
  field_inverse_var         0.770           0.773          +0.4%
  field_is_square_var       1.06            1.05           -0.9%
  field_sqrt                2.82            2.46           -12.8%
  group_double_var          0.0701          0.0612         -12.7%
  group_add_var             0.168           0.153          -8.9%
  group_add_affine          0.132           0.123          -6.8%
  group_add_affine_var      0.120           0.103          -14.2%
  group_add_zinv_var        0.138           0.117          -15.2%
  group_to_affine_var       0.820           0.819          -0.1%
  ```

  ### theStack, Snapdragon X Elite X1E-78-100, GCC 14.2.0

  ```text
  Benchmark                 Before min(us)  After min(us)  Delta
  ecdsa_verify              24.1            21.4           -11.2%
  ecdsa_sign                19.0            18.5           -2.6%
  schnorrsig_sign           13.0            12.7           -2.3%
  schnorrsig_verify         24.4            21.7           -11.1%
  ```

  Bitcoin Core subtree `bench_bitcoin -filter=VerifyScript.*`:

  ```text
  Benchmark                   Before ns/script  After ns/script  Delta
  VerifyScriptP2TR_KeyPath    23679.52          20899.66         -11.7%
  VerifyScriptP2TR_ScriptPath 43430.71          39280.19         -9.6%
  VerifyScriptP2WPKH          23526.82          20870.22         -11.3%
  ```

  ### sipa, Ryzen 5950X, GCC 15.2.0

  ```text
  Benchmark                 Before min(us)  After min(us)  Delta
  ecdsa_verify              30.8            27.3           -11.4%
  ecdsa_sign                18.7            17.2           -8.0%
  ec_keygen                 13.6            12.2           -10.3%
  ecdh                      29.8            26.7           -10.4%
  ecdsa_recover             31.0            28.2           -9.0%
  schnorrsig_sign           14.4            13.0           -9.7%
  schnorrsig_verify         31.1            28.5           -8.4%
  ellswift_encode           13.2            13.4           +1.5%
  ellswift_decode           5.79            5.84           +0.9%
  ellswift_keygen           26.8            25.7           -4.1%
  ellswift_ecdh             32.1            29.6           -7.8%
  ```
  </details>

  ---

  **clang:**
  <details><summary>host: i9-ssd, compiler: Ubuntu clang version 22.1.6 (++20260508084839+c0262e742787-1~exp1~20260508204859.77)</summary>

  ```bash
  Benchmark                 Before min(us)  After min(us)  Delta
  ecdsa_verify              40.1            39.8           -0.7%
  ecdsa_sign                29.2            29.1           -0.3%
  ec_keygen                 19.5            19.6           +0.5%
  ecdh                      40.3            39.8           -1.2%
  schnorrsig_sign           21              20.9           -0.5%
  schnorrsig_verify         40.6            40.3           -0.7%
  ellswift_encode           20.1            20.1           +0.0%
  ellswift_decode           8.43            8.41           -0.2%
  ellswift_keygen           39.8            39.7           -0.3%
  ellswift_ecdh             44.1            43.5           -1.4%
  field_half                0.0028          0.0028         +0.0%
  field_normalize           0.00889         0.00891        +0.2%
  field_normalize_weak      0.0037          0.0037         +0.0%
  field_sqr                 0.0144          0.0144         +0.0%
  field_mul                 0.021           0.019          -9.5%
  field_inverse             2.6             2.64           +1.5%
  field_inverse_var         1.34            1.35           +0.7%
  field_is_square_var       1.73            1.73           +0.0%
  field_sqrt                3.95            3.96           +0.3%
  group_double_var          0.128           0.125          -2.3%
  group_add_var             0.311           0.31           -0.3%
  group_add_affine          0.243           0.242          -0.4%
  group_add_affine_var      0.207           0.207          +0.0%
  group_add_zinv_var        0.229           0.228          -0.4%
  group_to_affine_var       1.43            1.44           +0.7%
  ecmult_wnaf               0.536           0.598          +11.6%
  hash_sha256               0.3             0.299          -0.3%
  hash_hmac_sha256          1.18            1.18           +0.0%
  hash_rfc6979_hmac_sha256  6.51            6.53           +0.3%
  context_create            2.16            2.15           -0.5%
  ```
  </details>

  **reindex-chainstate:**
  <details><summary>2026-05-28 | reindex-chainstate | 950059 blocks | dbcache 5000 | i9-ssd | x86_64 | Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz | 16 cores | 62Gi RAM | SSD</summary>

  ```bash
  for DBCACHE in 5000; do \
      COMMITS="67250b1d97e6159d908ef44639b6a12471e7c717 c264526415f38afb9890003003b7de39b370b745"; \
      STOP=950059; CC=gcc; CXX=g++; \
      BASE_DIR="/mnt/my_storage"; DATA_DIR="$BASE_DIR/BitcoinData"; LOG_DIR="$BASE_DIR/logs"; \
      (echo ""; for c in $COMMITS; do git fetch -q origin "$c" 2>/dev/null || true; git log -1 --pretty='%h %s' $c || exit 1; done) && \
      (echo "" && echo "$(date -I) | reindex-chainstate | ${STOP} blocks | dbcache ${DBCACHE} | $(hostname) | $(uname -m) | $(lscpu | grep 'Model name' | head -1 | cut -d: -f2 | xargs) | $(nproc) cores | $(free -h | awk '/^Mem:/{print $2}') RAM | $(l
  sblk -no ROTA $(df --output=source $BASE_DIR | tail -1) | grep -q 1 && echo HDD || echo SSD)"; echo "") && \
      hyperfine \
      --sort command \
      --runs 1 \
      --export-json "$BASE_DIR/rdx-$(sed -E 's/[^ ]+/\L&/g;s/[.]/_/g;s/ /-/g'<<<"$COMMITS")-$STOP-$DBCACHE-$CC.json" \
      --parameter-list COMMIT ${COMMITS// /,} \
      --prepare "killall -9 bitcoind 2>/dev/null; rm -f ./build/bin/bitcoind; git clean -fxd; git reset --hard {COMMIT} && \
        cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release && ninja -C build bitcoind -j1 && \
        ./build/bin/bitcoind -datadir=$DATA_DIR -stopatheight=$STOP -dbcache=1000 -printtoconsole=0; sleep 20; rm -f $DATA_DIR/debug.log; rm -rfd $DATA_DIR/indexes;" \
      --conclude "killall bitcoind || true; sleep 5; grep -q 'height=0' $DATA_DIR/debug.log && grep -q 'Disabling script verification at block #1' $DATA_DIR/debug.log && grep -q 'height=$STOP' $DATA_DIR/debug.log && grep 'Bitcoin Core version' $DATA_
  DIR/debug.log | grep -q \"\$(git rev-parse --short=12 {COMMIT})\"; \
                  cp $DATA_DIR/debug.log $LOG_DIR/debug-{COMMIT}-$(date +%s).log" \
      "COMPILER=$CC ./build/bin/bitcoind -datadir=$DATA_DIR -stopatheight=$STOP -dbcache=$DBCACHE -reindex-chainstate -blocksonly -connect=0 -printtoconsole=0 -assumevalid=0"; \
  done

  67250b1d97 parallel input fetcher
  c264526415 Refactor: optimize scalar reduction and arithmetic functions.

  2026-05-28 | reindex-chainstate | 950059 blocks | dbcache 5000 | i9-ssd | x86_64 | Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz | 16 cores | 62Gi RAM | SSD

  Benchmark 1: COMPILER=gcc ./build/bin/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=950059 -dbcache=5000 -reindex-chainstate -blocksonly -connect=0 -printtoconsole=0 -assumevalid=0 (COMMIT = 67250b1d97e6159d908ef44639b6a12471e7c717)
    Time (abs ≡):        37155.108 s               [User: 375835.978 s, System: 978.929 s]

  Benchmark 2: COMPILER=gcc ./build/bin/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=950059 -dbcache=5000 -reindex-chainstate -blocksonly -connect=0 -printtoconsole=0 -assumevalid=0 (COMMIT = c264526415f38afb9890003003b7de39b370b745)
    Time (abs ≡):        36261.785 s               [User: 362247.387 s, System: 1002.867 s]

  Relative speed comparison
          1.02          COMPILER=gcc ./build/bin/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=950059 -dbcache=5000 -reindex-chainstate -blocksonly -connect=0 -printtoconsole=0 -assumevalid=0 (COMMIT = 67250b1d97e6159d908ef44639b6a12471e7c717)
          1.00          COMPILER=gcc ./build/bin/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=950059 -dbcache=5000 -reindex-chainstate -blocksonly -connect=0 -printtoconsole=0 -assumevalid=0 (COMMIT = c264526415f38afb9890003003b7de39b370b745)
  ```
  </details>

ACKs for top commit:
  real-or-random:
    utACK 71fcd8410e
  theStack:
    ACK 71fcd8410e
  hebasto:
    ACK 71fcd8410e, tested different scenarios on Linux and Windows.

Tree-SHA512: 4686badb33da4613fb43df69355354cbcbbf7cb726130670e8f97f7992332db39ca8c45c0e0944de9e2ead61c3d4b8fdd0a62b023f1cfcd2e8d9b2abb74084cd
2026-06-17 13:35:57 +02:00
merge-script
fdcf2d41e2 Merge bitcoin-core/secp256k1#1865: test: enable -Wunused-function in test suite (Fix #1831)
a77dacad9a test: enable -Wunused-function in test suite (Fix #1831) (kallal79)

Pull request description:

  This PR addresses issue #1831 by enabling the `-Wunused-function` compiler warning within the test suite.

  Currently, `-Wno-unused-function` is passed globally to disable warnings about unused functions, making it too easy to write a test case but forget to actually call it. To catch untested helper functions safely, this PR uses GCC/Clang pragmas scoped strictly to the body of the test files.

  ### Changes Made:
  - Added `#pragma GCC diagnostic warning "-Wunused-function"` directly after the `#include` statements in `src/tests.c`, `src/tests_exhaustive.c`, `src/ctime_tests.c`, and `src/unit_test.c`.
  Fixes #1831

ACKs for top commit:
  real-or-random:
    ACK a77dacad9a
  hebasto:
    ACK a77dacad9a.

Tree-SHA512: 775d633d9d2e95154b6718270ce1687a1b20c2c8cc67c909953b3395d76e6853e6be1d6a95d8aef3f15a78dec3497bea8e3864e36830977e11beb42ea9abcc31
2026-06-16 13:58:19 +02:00
merge-script
b2d2bd362d Merge bitcoin-core/secp256k1#1860: cmake: Emulate Libtool's behavior on NetBSD and OpenBSD
1eab757207 cmake: Fix shared library versioning on OpenBSD (Hennadii Stepanov)
a401c5145a cmake: Fix shared library versioning on NetBSD (Hennadii Stepanov)
8a0f4002c7 cmake, refactor: Improve documenting in `SetLibtoolAbiVersion` module (Hennadii Stepanov)
acf2084aa7 cmake, refactor: Introduce `SetLibtoolAbiVersion` module (Hennadii Stepanov)

Pull request description:

  This is a continuation of https://github.com/bitcoin-core/secp256k1/pull/1685.

  Additionally, the logic has been factored out into its own module and the documentation has been also improved.

ACKs for top commit:
  real-or-random:
    utACK 1eab757207

Tree-SHA512: 24738053d3049f0ce551b0d05d62642d7f1e6645967288fbe30ce4799f4e64594e88a8fa2dd9109efd6cfc5666d7c5fe7a3bb99f0f06766d70b2a9362721e3c9
2026-06-16 11:07:32 +02:00
merge-script
87bec430bf Merge bitcoin-core/secp256k1#1867: test: musig: fix dead "aggnonce encodes two points at infinity" check
d7125e517d test: musig: fix dead "aggnonce encodes two points at infinity" check (Sebastian Falbesoner)

Pull request description:

  Due to the missing `CHECK` around, the return values were discarded and nothing was actually checked here.

  (Fwiw I prompted two AI models (MiniMax M3 and Opus 4.8) to find more similar instances in tests with bare statements that miss a surrounding `CHECK` in tests, and both didn't find any.)

ACKs for top commit:
  real-or-random:
    utACK d7125e517d
  hebasto:
    ACK d7125e517d, I have reviewed the code and it looks OK.

Tree-SHA512: 6eab61ce51a414e0555413bde29cf582b70fbf4a24ad1aae135bf88f28e3ee25ece8c79b7ccc254288395fedf6b2547931d5e00b0090146f1b83e43acc6570d7
2026-06-16 08:27:58 +02:00
Lőrinc
71fcd8410e field: force-inline 5x52 mul and sqr
The 5x52 field multiplication and squaring routines are hot in group arithmetic and scalar multiplication.

Use the new `SECP256K1_FORCE_INLINE` for the thin wrappers and `int128` inner helpers so compilers can schedule the 64x64->128 arithmetic without a call boundary.

Across the measured GCC and MSVC Release builds, this improves ECDSA verification by 0.6% to 9.1%, ECDH by 0.7% to 9.3%, and Schnorr verification by 0.6% to 9.6%.

The direct field benchmarks generally show the intended effect on field squaring and multiplication, while Clang results are mostly flat and less consistently positive.

This is a code-size tradeoff: the tested static library builds grew by about 4.6% to 4.7%, and the tested Windows Release DLL grew by 14.1%.

Co-authored-by: Sebastian Falbesoner <sebastian.falbesoner@gmail.com>
Co-authored-by: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>
Co-authored-by: Tim Ruffing <crypto@timruffing.de>
2026-06-15 23:56:19 +02:00
kallal79
a77dacad9a test: enable -Wunused-function in test suite (Fix #1831) 2026-06-12 19:10:33 +05:30
merge-script
aea86bc350 Merge bitcoin-core/secp256k1#1864: test: refactor: simplify tests by using _ecmult_gen_ge helper, add test
2ee79e77e6 test: add unit test for `_ecmult_gen_ge` (Sebastian Falbesoner)
ca68daf8e1 test: refactor: simplify tests by using `_ecmult_gen_ge` helper (Sebastian Falbesoner)

Pull request description:

  This PR is a small follow-up to #1861. If the generator point multiplication result in Jacobian coordinates is immediately converted to affine coordinates after and is not needed for anything else, we can deduplicate by using the new `secp256k1_ecmult_gen_ge` helper. The second commit adds a simple unit tests, verifying for random scalars that the result of `secp256k1_ecmult_gen_ge` matches the two expected steps (`secp256k1_ecmult_gen_gej` plus Jacobian->affine conersion via `secp256k1_ge_set_gej`).

  Note that in a very strict sense the first commit is not a refactor, as the Jacobian object is now cleared out which was not done on master, but for the logic in the tests this shouldn't matter at all.

ACKs for top commit:
  real-or-random:
    utACK 2ee79e77e6

Tree-SHA512: 452895b6f6e70c686063afb051d25dab1d086aac28081c4a3071a3dbe7dae964e806f9fe8052b88a7da4305a0cf636badc2dba817cae96aae0a35b2bc9675c03
2026-06-12 08:47:31 +02:00
Sebastian Falbesoner
2ee79e77e6 test: add unit test for _ecmult_gen_ge 2026-06-11 17:56:32 +02:00
Sebastian Falbesoner
d7125e517d test: musig: fix dead "aggnonce encodes two points at infinity" check 2026-06-10 00:21:24 +02:00
Hennadii Stepanov
acf2084aa7 cmake, refactor: Introduce SetLibtoolAbiVersion module 2026-06-09 13:22:57 +01:00
merge-script
0f4a7e6bf9 Merge bitcoin-core/secp256k1#1855: bench: add internal benchmark for secp256k1_fe_normalize_var
240578eef5 bench: add internal benchmark for `secp256k1_fe_normalize_var` (Sebastian Falbesoner)

Pull request description:

  While addressing the review suggestion https://github.com/bitcoin-core/secp256k1/pull/1765#discussion_r3238616034 ([b10c mirror link](https://mirror.b10c.me/bitcoin-core-secp256k1/1765/#discussion_r3238616034)), I noticed that we don't have an internal benchmark for the variable-time variant of `_fe_normalize` yet, so this PR adds one. IIUC it's fine to repeatedly apply the operation on the same (already normalized at latest after the first loop iteration) field element for benchmarking purposes and don't put in an effort to reach the [final reduction code path](b11340b3ce/src/field_5x52_impl.h (L120-L132)), considering how extremely unlikely it is to reach it in practice.

  Results on my machine:
  ```
  $ ./build/bin/bench_internal normalize
  Benchmark                     ,    Min(us)    ,    Avg(us)    ,    Max(us)

  field_normalize               ,     0.0103    ,     0.0106    ,     0.0128
  field_normalize_var           ,     0.00545   ,     0.00546   ,     0.00547
  field_normalize_weak          ,     0.00352   ,     0.00354   ,     0.00363
  ```

ACKs for top commit:
  real-or-random:
    utACK 240578eef5

Tree-SHA512: 4480e65b24c9e3c498389c5faf807cc44ae2a421d4500dd95066f9bb4f4885c67d2a6e1875e93912b96422963fd1430f724d442f30eb152faf86302ba266bd94
2026-06-09 10:05:56 +02:00
Sebastian Falbesoner
ca68daf8e1 test: refactor: simplify tests by using _ecmult_gen_ge helper
If the generator point multiplication result in Jacobian coordinates is
immediately converted to affine coordinates after and is not needed for
anything else, we can deduplicate by using the helper introduced in #1861.

Note that in a very strict sense this is not a refactor, as the Jacobian
object is now cleared out which was not done on master, but for the logic
in the tests this shouldn't matter at all.
2026-06-08 18:44:58 +02:00
Sebastian Falbesoner
9e017e5062 refactor: rename _ecmult_gen -> _ecmult_gen_gej for consistency
Now that we have a function `_ecmult_gen_ge`, it makes sense to rename
the existing function `_ecmult_gen` to `_ecmult_gen_gej` for
consistency, to signal that the result is a Jacobian group element.

This diff was created by applying
```
$ sed -i s/secp256k1_ecmult_gen\(/secp256k1_ecmult_gen_gej\(/g $(git ls-files)
```
2026-06-07 20:21:18 +02:00
Sebastian Falbesoner
a3296d5e23 refactor: introduce _ecmult_gen_ge helper (preventing accidental gej leaks)
Scalar multiplication with the generator point frequently involves a
conversion to affine coordinates and clearing out the temporary Jacobian
group element object after to avoid leaking secret key material, i.e.
executing the following three steps:
    - secp256k1_ecmult_gen(ctx, &rj, ...)
    - secp256k1_ge_set_gej(&r, &rj)
    - secp256k1_gej_clear(&rj)

This commit introduces a corresponding helper to deduplicate code
and mitigate the risk that last step is forgotten (which can easily
happen and is not detected by tests).

The idea came up during a conversation with furszy, see
https://github.com/bitcoin-core/secp256k1/pull/1765#issuecomment-4482838033
2026-06-07 20:21:18 +02:00
merge-script
c63062380f Merge bitcoin-core/secp256k1#1852: Add exhaustive test for ECDH module
5698e66c64 Add exhaustive test for ECDH module (Sebastian Falbesoner)

Pull request description:

  This PR adds an exhaustive test for the ECDH module, looping over all key combinations and verifying the commutativity property (ECDH(i\*G, j) == ECDH(j\*G, i)) and checking against a recalculated ECDH result (by manually invoking the default ECDH hash function on the precalculated group element `group[i * j]`'s coordinates). The existing test coverage is already solid (including Wycheproof test vectors), but I figured it likely wouldn't hurt to add this as well.

ACKs for top commit:
  sipa:
    ACK 5698e66c64
  real-or-random:
    utACK 5698e66c64

Tree-SHA512: e80b8508ee61e3bf5230951393a08c8937f19d2d16220ff2b02fe69b039195a1545809d3ea420dfed1f192c3711f403c63e86c3af2bb2fc4ab1254388ba50287
2026-06-07 13:38:34 +02:00
Sebastian Falbesoner
240578eef5 bench: add internal benchmark for secp256k1_fe_normalize_var 2026-06-04 19:17:03 +02:00
merge-script
95b983597a Merge BlockstreamResearch/secp256k1-zkp#361: ecdsa_adaptor: make DLEQ nonce generation pluggable
b36c4ab717 ecdsa_adaptor: use context hash functions in nonce generation (DarkWindman)

Pull request description:

  Addresses #359.

ACKs for top commit:
  real-or-random:
    utACK b36c4ab717

Tree-SHA512: 0262dfcc2ec2e3d91e37c85bcf1243099aa11d9f4bff115400ce81d36a223818e09c02c41c0602fcbeeaa1f129c4f936ef643afb7149d1230cec2ea57f5b3894
2026-06-03 13:40:27 +02:00
DarkWindman
b36c4ab717 ecdsa_adaptor: use context hash functions in nonce generation 2026-06-03 13:07:37 +03:00
Sebastian Falbesoner
5698e66c64 Add exhaustive test for ECDH module 2026-06-02 14:25:34 +02:00
merge-script
cfb3312645 Merge BlockstreamResearch/secp256k1-zkp#364: Upstream PRs 1854
af1fdd1215 tests: compare full MuSig aggregate nonce (w0xlt)

Pull request description:

  This PR has been created by a GitHub Actions workflow without human involvement.

  [bitcoin-core/secp256k1#1854]: tests: compare full MuSig aggregate nonce

  Tips:
   * Use `git show --remerge-diff <pr-branch>` to show the conflict resolution in the merge commit.
   * Use `git read-tree --reset -u <pr-branch>` to replay these resolutions during the conflict resolution stage when recreating the PR branch locally.
     Be aware that this may discard your index as well as the uncommitted changes and untracked files in your worktree.

ACKs for top commit:
  mllwchrry:
    ACK 8363a2d

Tree-SHA512: 55406814de269c612159922ae521dd874887107ee9bd26cff81e2e2cca28ade74a0609e5c48e25a7d9913698899da146aef8b3eebf96e5ad70933a884d75a655
2026-06-01 13:11:35 +03:00
w0xlt
af1fdd1215 tests: compare full MuSig aggregate nonce 2026-05-12 15:26:12 -07:00
merge-script
45f6f0f158 Merge BlockstreamResearch/secp256k1-zkp#363: Upstream PRs 1846, 1848, 1849
8479eafa57 musig: always clear out secret key in `secp256k1_musig_nonce_gen_counter` (Sebastian Falbesoner)
3cca6451a2 ci: Bump GCC snapshot major version to 17 (Hennadii Stepanov)
285cb788e9 ci: Replace `ilammy/msvc-dev-cmd` with manual MSVC setup (Hennadii Stepanov)

Pull request description:

  This PR has been created by a GitHub Actions workflow without human involvement.

  [bitcoin-core/secp256k1#1846]: ci: Replace `ilammy/msvc-dev-cmd` with manual MSVC setup
  [bitcoin-core/secp256k1#1848]: ci: Bump GCC snapshot major version to 17
  [bitcoin-core/secp256k1#1849]: musig: always clear out secret key in `secp256k1_musig_nonce_gen_counter`

  Tips:
   * Use `git show --remerge-diff <pr-branch>` to show the conflict resolution in the merge commit.
   * Use `git read-tree --reset -u <pr-branch>` to replay these resolutions during the conflict resolution stage when recreating the PR branch locally.
     Be aware that this may discard your index as well as the uncommitted changes and untracked files in your worktree.

ACKs for top commit:
  mllwchrry:
    ACK b11340b. This sync PR can be merged as-is.
  DarkWindman:
    ACK b11340b3ce

Tree-SHA512: 4b311e9bfa21f00b4780202c08af9d00380f5b3df40704641764d706cfc3408615b6206c7c82ca915b56c27a354bdf24680674269a28eefe7d4e93adc06cbaa5
2026-05-05 16:23:21 +03:00
Sebastian Falbesoner
8479eafa57 musig: always clear out secret key in secp256k1_musig_nonce_gen_counter
Even though `secp256k1_musig_nonce_gen_internal` can currently only fail
if the API is misused (invalid `keypair` or `keyagg_cache` parameters),
clear out the buffer holding secret key data as well in this case to
follow best practices.

The issue was found and reported by l0rinc using GPT 5.5 (Thanks!).
2026-04-28 23:22:29 +02:00
DarkWindman
baac08d207 modules, tests: Port bitcoin-core/secp256k1#1777 and bitcoin-core/secp256k1#1824 to zkp-specific code 2026-04-20 15:39:54 +03:00
Peter.Dettman
0cad3df503 Improve checks for scalar _get_bits methods 2026-04-12 17:37:42 +07:00
DarkWindman
f7e7e6bb15 Merge branch 'master' into sync-7262adb4 2026-04-01 17:29:57 +03:00
merge-script
95b702de34 Merge bitcoin-core/secp256k1#1839: ecdsa: VERIFY_CHECK result of _fe_set_b32_limit
43fca0ff55 ecdsa: VERIFY_CHECK result of _fe_set_b32_limit (Tim Ruffing)

Pull request description:

  This also avoids a spurious `-Wmaybe-uninitialized` warning emitted by gcc 16 (snapshot) when compiling with `-DDETERMINISTIC`.

  Alternative to #1838 by @mllwchrry who tried very a similar thing as this PR but couldn't convince the compiler. (The GCC snapshot is very annoying: a simple `VERIFY_CHECK(secp256k1_fe_set_b32_limit(&xr, c))` doesn't do the trick. I found this variant here with a local store rather by accident.)

ACKs for top commit:
  mllwchrry:
    ACK 43fca0f
  theStack:
    utACK 43fca0ff55

Tree-SHA512: 2550043e953675db7614f98bbdffb706721834967ef36f7c905f7cbfeee5d88189a9acfcd64865ef822bb0e3272d228440bdfb1124228afe083e025056e53212
2026-03-25 17:01:19 +01:00
Tim Ruffing
43fca0ff55 ecdsa: VERIFY_CHECK result of _fe_set_b32_limit
This also avoids a spurious "-Wmaybe-uninitialized" warning emitted by
gcc 16 (snapshot) when compiling with -DDETERMINISTIC.
2026-03-23 16:54:51 +01:00
mllwchrry
b84635ed3b tests: Fix C89 function pointer initialization in ellswift tests 2026-03-20 16:45:28 +02:00
mllwchrry
be075fe86c bench: Fix bench_whitelist hang 2026-03-18 14:29:02 +02:00
merge-script
ffc25a2731 Merge bitcoin-core/secp256k1#1834: ecmult: Document and test ng=NULL in ecmult
3a403639dc eckey: Call ecmult with NULL instead of zero scalar (Tim Ruffing)
7e68c0c88b ecmult: Document and test ng=NULL in ecmult (Tim Ruffing)

Pull request description:

ACKs for top commit:
  theStack:
    re-ACK 3a403639dc

Tree-SHA512: 954928d4dfa120845c6e899c1a69ad0408072809551d42735eac491b8bc41249eb25d7c57cfa4f44763167620b5cb78639b5c396c0a342c47b0afc48a088c755
2026-03-11 14:45:56 +01:00
Tim Ruffing
3a403639dc eckey: Call ecmult with NULL instead of zero scalar 2026-03-11 11:10:32 +01:00
Tim Ruffing
7e68c0c88b ecmult: Document and test ng=NULL in ecmult 2026-03-11 11:10:32 +01:00
merge-script
daf96bb07c Merge BlockstreamResearch/secp256k1-zkp#343: build: Add missing schnorrsig_halfagg module configuration
92e61ba95f build: Add missing schnorrsig_halfagg module configuration (mllwchrry)

Pull request description:

  The `schnorrsig_halfagg` module was added in 3a9b1d46 but was never configured in the CMake build system. Additionally, the autotools configuration was missing the dependency error check when `schnorrsig` is explicitly disabled.

ACKs for top commit:
  real-or-random:
    ACK 92e61ba95f

Tree-SHA512: f3770f6ae6c91a6ef51b633d147d8156a6ae843b6cb430deef07e7b9e6ea5f0b02cb228dbb41954620ce5560252d5dde7d85ce4114789bd5fcdff195915382dd
2026-03-06 15:18:18 +01:00
mllwchrry
92e61ba95f build: Add missing schnorrsig_halfagg module configuration 2026-03-06 15:07:40 +02:00
merge-script
b0ddc0357e Merge BlockstreamResearch/secp256k1-zkp#338: ci: enable surjectionproof in CI module-enabled configurations
4359f050cc surjection: Remove test that reads out of bounds (Tim Ruffing)
78999f3a9a surjection: Fix leading whitespace (Tim Ruffing)
229e1f127a surjection: Fix read of uninitialized value in tests (Tim Ruffing)
c0a26a9c1b ci: enable surjectionproof module in CI configs (copilot-swe-agent[bot])

Pull request description:

  The CI workflow enabled the ZKP experimental module set but omitted surjectionproof, so that module was never exercised in those jobs. This change wires surjectionproof into the same CI paths as the other enabled ZKP modules.

  - **CI module plumbing (`ci/ci.sh`)**
    - Added `SURJECTIONPROOF` to the exported/printed CI env set.
    - Passed `SURJECTIONPROOF` into configure via `--enable-module-surjectionproof`.

  - **Workflow env defaults and matrices (`.github/workflows/ci.yml`)**
    - Added a global default: `SURJECTIONPROOF: 'no'`.
    - Added `SURJECTIONPROOF: 'yes'` in every job/matrix env block that already enables the ZKP module group (`RANGEPROOF`, `WHITELIST`, `GENERATOR`, etc.).

  - **Representative wiring change**
    ```sh
    --enable-module-rangeproof="$RANGEPROOF" \
    --enable-module-surjectionproof="$SURJECTIONPROOF" \
    --enable-module-whitelist="$WHITELIST"
    ```

  <!-- START COPILOT ORIGINAL PROMPT -->

  <details>

  <summary>Original prompt</summary>

  >
  > ----
  >
  > *This section details on the original issue you should resolve*
  >
  > <issue_title>ci: surjectionproof module is never enabled</issue_title>
  > <issue_description>There's not even a SURJECTIONPROOF env variable in the GitHub Actions workflow... This should be enabled everywhere where the other ZKP modules are enabled.
  >
  > It may be better to enable all modules by default, but that's a change that could potentially benefit even upstream, so maybe let's first just fix this by enabling surjectionproof.</issue_description>
  >
  > <agent_instructions>Only add enabling of the surjectionproof module (no enabling of all modules by default)</agent_instructions>
  >
  > ## Comments on the Issue (you are @copilot in this section)
  >
  > <comments>
  > </comments>
  >

  </details>

  <!-- START COPILOT CODING AGENT SUFFIX -->

  - Fixes BlockstreamResearch/secp256k1-zkp#334

ACKs for top commit:
  mllwchrry:
    ACK 4359f05

Tree-SHA512: 13d776a76f73db6e74ca253099583da3d2600f424ea1f6bcbc9cd12544721477225a4190ffd34f4f1a77ab3b1d1e21d1f6d83409aa969bafe66a7978bef1b2d2
2026-03-06 12:12:06 +01:00
Tim Ruffing
4359f050cc surjection: Remove test that reads out of bounds 2026-03-05 21:27:19 +01:00
Tim Ruffing
78999f3a9a surjection: Fix leading whitespace 2026-03-05 21:12:46 +01:00
Tim Ruffing
229e1f127a surjection: Fix read of uninitialized value in tests 2026-03-05 21:12:40 +01:00