Skip to content

Commit c0da4f6

Browse files
committedSep 4, 2023
Squashed 'src/secp256k1/' changes from c545fdc..199d27c
199d27c Merge bitcoin-core/secp256k1#1415: release: Prepare for 0.4.0 1633980 release: Prepare for 0.4.0 d9a8506 changelog: Catch up in preparation of release 0b4640a Merge bitcoin-core/secp256k1#1413: ci: Add `release` job 8659a01 ci: Add `release` job f9b3889 ci: Update `actions/checkout` version 727bec5 Merge bitcoin-core/secp256k1#1414: ci/gha: Add ARM64 QEMU jobs for clang and clang-snapshot 2635068 ci/gha: Let MSan continue checking after errors in all jobs e78c7b6 ci/Dockerfile: Reduce size of Docker image further 2f0d3bb ci/Dockerfile: Warn if `ulimit -n` is too high when running Docker 4b8a647 ci/gha: Add ARM64 QEMU jobs for clang and clang-snapshot 6ebe7d2 ci/Dockerfile: Always use versioned clang packages 65c79fe Merge bitcoin-core/secp256k1#1412: ci: Switch macOS from Ventura to Monterey and add Valgrind c223d7e ci: Switch macOS from Ventura to Monterey and add Valgrind ea26b71 Merge bitcoin-core/secp256k1#1411: ci: Make repetitive command the default one cce0456 ci: Make repetitive command the default one 317a4c4 ci: Move `git config ...` to `run-in-docker-action` 4d7fe60 Merge bitcoin-core/secp256k1#1409: ci: Move remained task from Cirrus to GitHub Actions 676ed8f ci: Move "C++ (public headers)" from Cirrus to GitHub Actions 61fc3a2 ci: Move "C++ -fpermissive..." from Cirrus to GitHub Actions d51fb0a ci: Move "MSan" from Cirrus to GitHub Actions c22ac27 ci: Move sanitizers task from Cirrus to GitHub Actions 26a9899 Merge bitcoin-core/secp256k1#1410: ci: Use concurrency for pull requests only ee1be62 ci: Use concurrency for pull requests only 6ee1455 Merge bitcoin-core/secp256k1#1406: ci, gha: Move more non-x86_64 tasks from Cirrus CI to GitHub Actions fc3dea2 ci: Move "ppc64le: Linux..." from Cirrus to GitHub Actions 7782dc8 ci: Move "ARM64: Linux..." from Cirrus to GitHub Actions 0a16de6 ci: Move "ARM32: Linux..." from Cirrus to GitHub Actions ea33914 ci: Move "s390x (big-endian): Linux..." from Cirrus to GitHub Actions 880be8a ci: Move "i686: Linux (Debian stable)" from Cirrus to GiHub Actions 2e6cf9b Merge bitcoin-core/secp256k1#1396: ci, gha: Add "x86_64: Linux (Debian stable)" GitHub Actions job 5373693 Merge bitcoin-core/secp256k1#1405: ci: Drop no longer needed workaround ef9fe95 ci: Drop no longer needed workaround e10878f ci, gha: Drop `driver-opts.network` input for `setup-buildx-action` 4ad4914 ci, gha: Add `retry_builder` Docker image builder 6617a62 ci: Remove "x86_64: Linux (Debian stable)" task from Cirrus CI 03c9e65 ci, gha: Add "x86_64: Linux (Debian stable)" GitHub Actions job ad3e65d ci: Remove GCC build files and sage to reduce size of Docker image 6b9507a Merge bitcoin-core/secp256k1#1398: ci, gha: Add Windows jobs based on Linux image 87d35f3 ci: Rename `cirrus.sh` to more general `ci.sh` d6281dd ci: Remove Windows tasks from Cirrus CI 2b6f9cd ci, gha: Add Windows jobs based on Linux image 48b1d93 Merge bitcoin-core/secp256k1#1403: ci, gha: Ensure only a single workflow processes `github.ref` at a time 0ba2b94 Merge bitcoin-core/secp256k1#1373: Add invariant checking for scalars 060e32c Merge bitcoin-core/secp256k1#1401: ci, gha: Run all MSVC tests on Windows natively de657c2 Merge bitcoin-core/secp256k1#1062: Removes `_fe_equal_var`, and unwanted `_fe_normalize_weak` calls (in tests) bcffeb1 Merge bitcoin-core/secp256k1#1404: ci: Remove "arm64: macOS Ventura" task from Cirrus CI c2f6435 ci: Add comment about switching macOS to M1 on GHA later 4a24fae ci: Remove "arm64: macOS Ventura" task from Cirrus CI b0886fd ci, gha: Ensure only a single workflow processes `github.ref` at a time 3d05c86 Merge bitcoin-core/secp256k1#1394: ci, gha: Run "x86_64: macOS Ventura" job on GitHub Actions d78bec7 ci: Remove Windows MSVC tasks from Cirrus CI 3545dc2 ci, gha: Run all MSVC tests on Windows natively 5d8fa82 Merge bitcoin-core/secp256k1#1274: test: Silent noisy clang warnings about Valgrind code on macOS x86_64 8e54a34 ci, gha: Run "x86_64: macOS Ventura" job on GitHub Actions b327abf Merge bitcoin-core/secp256k1#1402: ci: Use Homebrew's gcc in native macOS task d62db57 ci: Use Homebrew's gcc in native macOS task 54058d1 field: remove `secp256k1_fe_equal_var` bb4efd6 tests: remove unwanted `secp256k1_fe_normalize_weak` call eedd781 Merge bitcoin-core/secp256k1#1348: tighten group magnitude limits, save normalize_weak calls in group add methods (revival of bitcoin#1032) b2f6712 Merge bitcoin-core/secp256k1#1400: ctimetests: Use new SECP256K1_CHECKMEM macros also for ellswift 9c91ea4 ci: Enable ellswift module where it's missing db32a24 ctimetests: Use new SECP256K1_CHECKMEM macros also for ellswift ce765a5 Merge bitcoin-core/secp256k1#1399: ci, gha: Run "SageMath prover" job on GitHub Actions 8408dfd Revert "ci: Run sage prover on CI" c8d9914 ci, gha: Run "SageMath prover" job on GitHub Actions 8d2960c Merge bitcoin-core/secp256k1#1397: ci: Remove "Windows (VS 2022)" task from Cirrus CI f1774e5 ci, gha: Make MSVC job presentation more explicit 5ee039b ci: Remove "Windows (VS 2022)" task from Cirrus CI 96294c0 Merge bitcoin-core/secp256k1#1389: ci: Run "Windows (VS 2022)" job on GitHub Actions a2f7ccd ci: Run "Windows (VS 2022)" job on GitHub Actions 374e2b5 Merge bitcoin-core/secp256k1#1290: cmake: Set `ENVIRONMENT` property for examples on Windows 1b13415 Merge bitcoin-core/secp256k1#1391: refactor: take use of `secp256k1_scalar_{zero,one}` constants (part 2) a1bd497 refactor: take use of `secp256k1_scalar_{zero,one}` constants (part 2) b7c685e Save _normalize_weak calls in group add methods c83afa6 Tighten group magnitude limits 26392da Merge bitcoin-core/secp256k1#1386: ci: print $ELLSWIFT in cirrus.sh d23da6d use secp256k1_scalar_verify checks 4692478 ci: print $ELLSWIFT in cirrus.sh c7d0454 add verification for scalars c734c64 Merge bitcoin-core/secp256k1#1384: build: enable ellswift module via SECP_CONFIG_DEFINES ad15215 update max scalar in scalar_cmov_test and fix schnorrsig_verify exhaustive test 78ca880 build: enable ellswift module via SECP_CONFIG_DEFINES 0e00fc7 Merge bitcoin-core/secp256k1#1383: util: remove unused checked_realloc b097a46 util: remove unused checked_realloc 2bd5f3e Merge bitcoin-core/secp256k1#1382: refactor: Drop unused cast 4f8c5bd refactor: Drop unused cast 173e8d0 Implement current magnitude assumptions 49afd2f Take use of _fe_verify_magnitude in field_impl.h 4e9661f Add _fe_verify_magnitude (no-op unless VERIFY is enabled) 690b0fc add missing group element invariant checks 175db31 ci: Drop no longer needed `PATH` variable update on Windows 116d2ab cmake: Set `ENVIRONMENT` property for examples on Windows cef3739 cmake, refactor: Use helper function instead of interface library 747ada3 test: Silent noisy clang warnings about Valgrind code on macOS x86_64 git-subtree-dir: src/secp256k1 git-subtree-split: 199d27c
1 parent ff061fd commit c0da4f6

29 files changed

+1476
-694
lines changed
 

‎.cirrus.yml

-413
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: "Install Valgrind"
2+
description: "Install Homebrew's Valgrind package and cache it."
3+
runs:
4+
using: "composite"
5+
steps:
6+
- run: |
7+
brew tap LouisBrunner/valgrind
8+
brew fetch --HEAD LouisBrunner/valgrind/valgrind
9+
echo "CI_HOMEBREW_CELLAR_VALGRIND=$(brew --cellar valgrind)" >> "$GITHUB_ENV"
10+
shell: bash
11+
12+
- run: |
13+
sw_vers > valgrind_fingerprint
14+
brew --version >> valgrind_fingerprint
15+
git -C "$(brew --cache)/valgrind--git" rev-parse HEAD >> valgrind_fingerprint
16+
cat valgrind_fingerprint
17+
shell: bash
18+
19+
- uses: actions/cache@v3
20+
id: cache
21+
with:
22+
path: ${{ env.CI_HOMEBREW_CELLAR_VALGRIND }}
23+
key: ${{ github.job }}-valgrind-${{ hashFiles('valgrind_fingerprint') }}
24+
25+
- if: steps.cache.outputs.cache-hit != 'true'
26+
run: |
27+
brew install --HEAD LouisBrunner/valgrind/valgrind
28+
shell: bash
29+
30+
- if: steps.cache.outputs.cache-hit == 'true'
31+
run: |
32+
brew link valgrind
33+
shell: bash
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: 'Run in Docker with environment'
2+
description: 'Run a command in a Docker container, while passing explicitly set environment variables into the container.'
3+
inputs:
4+
dockerfile:
5+
description: 'A Dockerfile that defines an image'
6+
required: true
7+
tag:
8+
description: 'A tag of an image'
9+
required: true
10+
command:
11+
description: 'A command to run in a container'
12+
required: false
13+
default: ./ci/ci.sh
14+
runs:
15+
using: "composite"
16+
steps:
17+
- uses: docker/setup-buildx-action@v2
18+
19+
- uses: docker/build-push-action@v4
20+
id: main_builder
21+
continue-on-error: true
22+
with:
23+
context: .
24+
file: ${{ inputs.dockerfile }}
25+
tags: ${{ inputs.tag }}
26+
load: true
27+
cache-from: type=gha
28+
29+
- uses: docker/build-push-action@v4
30+
id: retry_builder
31+
if: steps.main_builder.outcome == 'failure'
32+
with:
33+
context: .
34+
file: ${{ inputs.dockerfile }}
35+
tags: ${{ inputs.tag }}
36+
load: true
37+
cache-from: type=gha
38+
39+
- # Tell Docker to pass environment variables in `env` into the container.
40+
run: >
41+
docker run \
42+
$(echo '${{ toJSON(env) }}' | jq -r 'keys[] | "--env \(.) "') \
43+
--volume ${{ github.workspace }}:${{ github.workspace }} \
44+
--workdir ${{ github.workspace }} \
45+
${{ inputs.tag }} bash -c "
46+
git config --global --add safe.directory ${{ github.workspace }}
47+
${{ inputs.command }}
48+
"
49+
shell: bash

‎.github/workflows/ci.yml

+806
Large diffs are not rendered by default.

‎CHANGELOG.md

+10-2
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,25 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8-
## [Unreleased]
8+
## [0.4.0] - 2023-09-04
99

1010
#### Added
1111
- New module `ellswift` implements ElligatorSwift encoding for public keys and x-only Diffie-Hellman key exchange for them.
1212
ElligatorSwift permits representing secp256k1 public keys as 64-byte arrays which cannot be distinguished from uniformly random. See:
1313
- Header file `include/secp256k1_ellswift.h` which defines the new API.
1414
- Document `doc/ellswift.md` which explains the mathematical background of the scheme.
1515
- The [paper](https://eprint.iacr.org/2022/759) on which the scheme is based.
16+
- We now test the library with unreleased development snapshots of GCC and Clang. This gives us an early chance to catch miscompilations and constant-time issues introduced by the compiler (such as those that led to the previous two releases).
17+
18+
#### Fixed
19+
- Fixed symbol visibility in Windows DLL builds, where three internal library symbols were wrongly exported.
1620

1721
#### Changed
1822
- When consuming libsecp256k1 as a static library on Windows, the user must now define the `SECP256K1_STATIC` macro before including `secp256k1.h`.
1923

24+
#### ABI Compatibility
25+
This release is backward compatible with the ABI of 0.3.0, 0.3.1, and 0.3.2. Symbol visibility is now believed to be handled properly on supported platforms and is now considered to be part of the ABI. Please report any improperly exported symbols as a bug.
26+
2027
## [0.3.2] - 2023-05-13
2128
We strongly recommend updating to 0.3.2 if you use or plan to use GCC >=13 to compile libsecp256k1. When in doubt, check the GCC version using `gcc -v`.
2229

@@ -97,7 +104,8 @@ This version was in fact never released.
97104
The number was given by the build system since the introduction of autotools in Jan 2014 (ea0fe5a5bf0c04f9cc955b2966b614f5f378c6f6).
98105
Therefore, this version number does not uniquely identify a set of source files.
99106

100-
[unreleased]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.2...HEAD
107+
[unreleased]: https://github.com/bitcoin-core/secp256k1/compare/v0.4.0...HEAD
108+
[0.4.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.2...v0.4.0
101109
[0.3.2]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.1...v0.3.2
102110
[0.3.1]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.0...v0.3.1
103111
[0.3.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.2.0...v0.3.0

‎CMakeLists.txt

+4-4
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ project(libsecp256k1
1111
# The package (a.k.a. release) version is based on semantic versioning 2.0.0 of
1212
# the API. All changes in experimental modules are treated as
1313
# backwards-compatible and therefore at most increase the minor version.
14-
VERSION 0.3.3
14+
VERSION 0.4.0
1515
DESCRIPTION "Optimized C library for ECDSA signatures and secret/public key operations on curve secp256k1."
1616
HOMEPAGE_URL "https://github.com/bitcoin-core/secp256k1"
1717
LANGUAGES C
@@ -34,9 +34,9 @@ endif()
3434
# https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
3535
# All changes in experimental modules are treated as if they don't affect the
3636
# interface and therefore only increase the revision.
37-
set(${PROJECT_NAME}_LIB_VERSION_CURRENT 2)
38-
set(${PROJECT_NAME}_LIB_VERSION_REVISION 3)
39-
set(${PROJECT_NAME}_LIB_VERSION_AGE 0)
37+
set(${PROJECT_NAME}_LIB_VERSION_CURRENT 3)
38+
set(${PROJECT_NAME}_LIB_VERSION_REVISION 0)
39+
set(${PROJECT_NAME}_LIB_VERSION_AGE 1)
4040

4141
set(CMAKE_C_STANDARD 90)
4242
set(CMAKE_C_EXTENSIONS OFF)

‎ci/cirrus.sh ‎ci/ci.sh

+7-10
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ print_environment() {
1313
# does not rely on bash.
1414
for var in WERROR_CFLAGS MAKEFLAGS BUILD \
1515
ECMULTWINDOW ECMULTGENPRECISION ASM WIDEMUL WITH_VALGRIND EXTRAFLAGS \
16-
EXPERIMENTAL ECDH RECOVERY SCHNORRSIG \
16+
EXPERIMENTAL ECDH RECOVERY SCHNORRSIG ELLSWIFT \
1717
SECP256K1_TEST_ITERS BENCH SECP256K1_BENCH_ITERS CTIMETESTS\
1818
EXAMPLES \
1919
HOST WRAPPER_CMD \
@@ -31,18 +31,15 @@ print_environment() {
3131
}
3232
print_environment
3333

34-
# Start persistent wineserver if necessary.
35-
# This speeds up jobs with many invocations of wine (e.g., ./configure with MSVC) tremendously.
36-
case "$WRAPPER_CMD" in
37-
*wine*)
38-
# Make sure to shutdown wineserver whenever we exit.
39-
trap "wineserver -k || true" EXIT INT HUP
40-
wineserver -p
34+
env >> test_env.log
35+
36+
# If gcc is requested, assert that it's in fact gcc (and not some symlinked Apple clang).
37+
case "${CC:-undefined}" in
38+
*gcc*)
39+
$CC -v 2>&1 | grep -q "gcc version" || exit 1;
4140
;;
4241
esac
4342

44-
env >> test_env.log
45-
4643
if [ -n "${CC+x}" ]; then
4744
# The MSVC compiler "cl" doesn't understand "-v"
4845
$CC -v || true

‎ci/linux-debian.Dockerfile

+36-36
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
1-
FROM debian:stable
1+
FROM debian:stable-slim
22

33
SHELL ["/bin/bash", "-c"]
44

5+
WORKDIR /root
6+
7+
# A too high maximum number of file descriptors (with the default value
8+
# inherited from the docker host) can cause issues with some of our tools:
9+
# - sanitizers hanging: https://github.com/google/sanitizers/issues/1662
10+
# - valgrind crashing: https://stackoverflow.com/a/75293014
11+
# This is not be a problem on our CI hosts, but developers who run the image
12+
# on their machines may run into this (e.g., on Arch Linux), so warn them.
13+
# (Note that .bashrc is only executed in interactive bash shells.)
14+
RUN echo 'if [[ $(ulimit -n) -gt 200000 ]]; then echo "WARNING: Very high value reported by \"ulimit -n\". Consider passing \"--ulimit nofile=32768\" to \"docker run\"."; fi' >> /root/.bashrc
15+
516
RUN dpkg --add-architecture i386 && \
617
dpkg --add-architecture s390x && \
718
dpkg --add-architecture armhf && \
@@ -11,7 +22,7 @@ RUN dpkg --add-architecture i386 && \
1122
# dkpg-dev: to make pkg-config work in cross-builds
1223
# llvm: for llvm-symbolizer, which is used by clang's UBSan for symbolized stack traces
1324
RUN apt-get update && apt-get install --no-install-recommends -y \
14-
git ca-certificates wget \
25+
git ca-certificates \
1526
make automake libtool pkg-config dpkg-dev valgrind qemu-user \
1627
gcc clang llvm libclang-rt-dev libc6-dbg \
1728
g++ \
@@ -22,54 +33,43 @@ RUN apt-get update && apt-get install --no-install-recommends -y \
2233
gcc-powerpc64le-linux-gnu libc6-dev-ppc64el-cross libc6-dbg:ppc64el \
2334
gcc-mingw-w64-x86-64-win32 wine64 wine \
2435
gcc-mingw-w64-i686-win32 wine32 \
25-
sagemath
26-
27-
WORKDIR /root
36+
python3
2837

2938
# Build and install gcc snapshot
3039
ARG GCC_SNAPSHOT_MAJOR=14
31-
RUN wget --progress=dot:giga --https-only --recursive --accept '*.tar.xz' --level 1 --no-directories "https://gcc.gnu.org/pub/gcc/snapshots/LATEST-${GCC_SNAPSHOT_MAJOR}" && \
40+
RUN apt-get update && apt-get install --no-install-recommends -y wget libgmp-dev libmpfr-dev libmpc-dev flex && \
41+
mkdir gcc && cd gcc && \
42+
wget --progress=dot:giga --https-only --recursive --accept '*.tar.xz' --level 1 --no-directories "https://gcc.gnu.org/pub/gcc/snapshots/LATEST-${GCC_SNAPSHOT_MAJOR}" && \
3243
wget "https://gcc.gnu.org/pub/gcc/snapshots/LATEST-${GCC_SNAPSHOT_MAJOR}/sha512.sum" && \
3344
sha512sum --check --ignore-missing sha512.sum && \
3445
# We should have downloaded exactly one tar.xz file
3546
ls && \
3647
[[ $(ls *.tar.xz | wc -l) -eq "1" ]] && \
3748
tar xf *.tar.xz && \
3849
mkdir gcc-build && cd gcc-build && \
39-
apt-get update && apt-get install --no-install-recommends -y libgmp-dev libmpfr-dev libmpc-dev flex && \
4050
../*/configure --prefix=/opt/gcc-snapshot --enable-languages=c --disable-bootstrap --disable-multilib --without-isl && \
4151
make -j $(nproc) && \
4252
make install && \
43-
ln -s /opt/gcc-snapshot/bin/gcc /usr/bin/gcc-snapshot
53+
cd ../.. && rm -rf gcc && \
54+
ln -s /opt/gcc-snapshot/bin/gcc /usr/bin/gcc-snapshot && \
55+
apt-get autoremove -y wget libgmp-dev libmpfr-dev libmpc-dev flex && \
56+
apt-get clean && rm -rf /var/lib/apt/lists/*
4457

45-
# Install clang snapshot
46-
RUN wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc && \
58+
# Install clang snapshot, see https://apt.llvm.org/
59+
RUN \
60+
# Setup GPG keys of LLVM repository
61+
apt-get update && apt-get install --no-install-recommends -y wget && \
62+
wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc && \
4763
# Add repository for this Debian release
4864
. /etc/os-release && echo "deb http://apt.llvm.org/${VERSION_CODENAME} llvm-toolchain-${VERSION_CODENAME} main" >> /etc/apt/sources.list && \
49-
# Install clang snapshot
50-
apt-get update && apt-get install --no-install-recommends -y clang && \
51-
# Remove just the "clang" symlink again
52-
apt-get remove -y clang && \
53-
# We should have exactly two clang versions now
54-
ls /usr/bin/clang* && \
55-
[[ $(ls /usr/bin/clang-?? | sort | wc -l) -eq "2" ]] && \
56-
# Create symlinks for them
57-
ln -s $(ls /usr/bin/clang-?? | sort | tail -1) /usr/bin/clang-snapshot && \
58-
ln -s $(ls /usr/bin/clang-?? | sort | head -1) /usr/bin/clang
65+
apt-get update && \
66+
# Determine the version number of the LLVM development branch
67+
LLVM_VERSION=$(apt-cache search --names-only '^clang-[0-9]+$' | sort -V | tail -1 | cut -f1 -d" " | cut -f2 -d"-" ) && \
68+
# Install
69+
apt-get install --no-install-recommends -y "clang-${LLVM_VERSION}" && \
70+
# Create symlink
71+
ln -s "/usr/bin/clang-${LLVM_VERSION}" /usr/bin/clang-snapshot && \
72+
# Clean up
73+
apt-get autoremove -y wget && \
74+
apt-get clean && rm -rf /var/lib/apt/lists/*
5975

60-
# The "wine" package provides a convenience wrapper that we need
61-
RUN apt-get update && apt-get install --no-install-recommends -y \
62-
git ca-certificates wine64 wine python3-simplejson python3-six msitools winbind procps && \
63-
# Workaround for `wine` package failure to employ the Debian alternatives system properly.
64-
ln -s /usr/lib/wine/wine64 /usr/bin/wine64 && \
65-
# Set of tools for using MSVC on Linux.
66-
git clone https://github.com/mstorsjo/msvc-wine && \
67-
mkdir /opt/msvc && \
68-
python3 msvc-wine/vsdownload.py --accept-license --dest /opt/msvc Microsoft.VisualStudio.Workload.VCTools && \
69-
# Since commit 2146cbfaf037e21de56c7157ec40bb6372860f51, the
70-
# msvc-wine effectively initializes the wine prefix when running
71-
# the install.sh script.
72-
msvc-wine/install.sh /opt/msvc && \
73-
# Wait until the wineserver process has exited before closing the session,
74-
# to avoid corrupting the wine prefix.
75-
while (ps -A | grep wineserver) > /dev/null; do sleep 1; done

‎configure.ac

+7-7
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@ AC_PREREQ([2.60])
44
# the API. All changes in experimental modules are treated as
55
# backwards-compatible and therefore at most increase the minor version.
66
define(_PKG_VERSION_MAJOR, 0)
7-
define(_PKG_VERSION_MINOR, 3)
8-
define(_PKG_VERSION_PATCH, 3)
9-
define(_PKG_VERSION_IS_RELEASE, false)
7+
define(_PKG_VERSION_MINOR, 4)
8+
define(_PKG_VERSION_PATCH, 0)
9+
define(_PKG_VERSION_IS_RELEASE, true)
1010

1111
# The library version is based on libtool versioning of the ABI. The set of
1212
# rules for updating the version can be found here:
1313
# https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
1414
# All changes in experimental modules are treated as if they don't affect the
1515
# interface and therefore only increase the revision.
16-
define(_LIB_VERSION_CURRENT, 2)
17-
define(_LIB_VERSION_REVISION, 3)
18-
define(_LIB_VERSION_AGE, 0)
16+
define(_LIB_VERSION_CURRENT, 3)
17+
define(_LIB_VERSION_REVISION, 0)
18+
define(_LIB_VERSION_AGE, 1)
1919

2020
AC_INIT([libsecp256k1],m4_join([.], _PKG_VERSION_MAJOR, _PKG_VERSION_MINOR, _PKG_VERSION_PATCH)m4_if(_PKG_VERSION_IS_RELEASE, [true], [], [-dev]),[https://github.com/bitcoin-core/secp256k1/issues],[libsecp256k1],[https://github.com/bitcoin-core/secp256k1])
2121

@@ -401,7 +401,7 @@ if test x"$enable_module_schnorrsig" = x"yes"; then
401401
fi
402402

403403
if test x"$enable_module_ellswift" = x"yes"; then
404-
AC_DEFINE(ENABLE_MODULE_ELLSWIFT, 1, [Define this symbol to enable the ElligatorSwift module])
404+
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_ELLSWIFT=1"
405405
fi
406406

407407
# Test if extrakeys is set after the schnorrsig module to allow the schnorrsig

‎examples/CMakeLists.txt

+23-17
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,30 @@
1-
add_library(example INTERFACE)
2-
target_include_directories(example INTERFACE
3-
${PROJECT_SOURCE_DIR}/include
4-
)
5-
target_link_libraries(example INTERFACE
6-
secp256k1
7-
$<$<PLATFORM_ID:Windows>:bcrypt>
8-
)
1+
function(add_example name)
2+
set(target_name ${name}_example)
3+
add_executable(${target_name} ${name}.c)
4+
target_include_directories(${target_name} PRIVATE
5+
${PROJECT_SOURCE_DIR}/include
6+
)
7+
target_link_libraries(${target_name}
8+
secp256k1
9+
$<$<PLATFORM_ID:Windows>:bcrypt>
10+
)
11+
set(test_name ${name}_example)
12+
add_test(NAME ${test_name} COMMAND ${target_name})
13+
if(BUILD_SHARED_LIBS AND MSVC)
14+
# The DLL must reside either in the same folder where the executable is
15+
# or somewhere in PATH. Using the latter option.
16+
set_tests_properties(${test_name} PROPERTIES
17+
ENVIRONMENT "PATH=$<TARGET_FILE_DIR:secp256k1>;$ENV{PATH}"
18+
)
19+
endif()
20+
endfunction()
921

10-
add_executable(ecdsa_example ecdsa.c)
11-
target_link_libraries(ecdsa_example example)
12-
add_test(NAME ecdsa_example COMMAND ecdsa_example)
22+
add_example(ecdsa)
1323

1424
if(SECP256K1_ENABLE_MODULE_ECDH)
15-
add_executable(ecdh_example ecdh.c)
16-
target_link_libraries(ecdh_example example)
17-
add_test(NAME ecdh_example COMMAND ecdh_example)
25+
add_example(ecdh)
1826
endif()
1927

2028
if(SECP256K1_ENABLE_MODULE_SCHNORRSIG)
21-
add_executable(schnorr_example schnorr.c)
22-
target_link_libraries(schnorr_example example)
23-
add_test(NAME schnorr_example COMMAND schnorr_example)
29+
add_example(schnorr)
2430
endif()

‎src/bench_ecmult.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,6 @@ static void generate_scalar(uint32_t num, secp256k1_scalar* scalar) {
244244

245245
static void run_ecmult_multi_bench(bench_data* data, size_t count, int includes_g, int num_iters) {
246246
char str[32];
247-
static const secp256k1_scalar zero = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0);
248247
size_t iters = 1 + num_iters / count;
249248
size_t iter;
250249

@@ -262,7 +261,7 @@ static void run_ecmult_multi_bench(bench_data* data, size_t count, int includes_
262261
secp256k1_scalar_add(&total, &total, &tmp);
263262
}
264263
secp256k1_scalar_negate(&total, &total);
265-
secp256k1_ecmult(&data->expected_output[iter], NULL, &zero, &total);
264+
secp256k1_ecmult(&data->expected_output[iter], NULL, &secp256k1_scalar_zero, &total);
266265
}
267266

268267
/* Run the benchmark. */

‎src/checkmem.h

+7
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,14 @@
5858
#if !defined SECP256K1_CHECKMEM_ENABLED
5959
# if defined VALGRIND
6060
# include <stddef.h>
61+
# if defined(__clang__) && defined(__APPLE__)
62+
# pragma clang diagnostic push
63+
# pragma clang diagnostic ignored "-Wreserved-identifier"
64+
# endif
6165
# include <valgrind/memcheck.h>
66+
# if defined(__clang__) && defined(__APPLE__)
67+
# pragma clang diagnostic pop
68+
# endif
6269
# define SECP256K1_CHECKMEM_ENABLED 1
6370
# define SECP256K1_CHECKMEM_UNDEFINE(p, len) VALGRIND_MAKE_MEM_UNDEFINED((p), (len))
6471
# define SECP256K1_CHECKMEM_DEFINE(p, len) VALGRIND_MAKE_MEM_DEFINED((p), (len))

‎src/ctime_tests.c

+10-10
Original file line numberDiff line numberDiff line change
@@ -181,27 +181,27 @@ static void run_tests(secp256k1_context *ctx, unsigned char *key) {
181181
#endif
182182

183183
#ifdef ENABLE_MODULE_ELLSWIFT
184-
VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
184+
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
185185
ret = secp256k1_ellswift_create(ctx, ellswift, key, NULL);
186-
VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
186+
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
187187
CHECK(ret == 1);
188188

189-
VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
189+
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
190190
ret = secp256k1_ellswift_create(ctx, ellswift, key, ellswift);
191-
VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
191+
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
192192
CHECK(ret == 1);
193193

194194
for (i = 0; i < 2; i++) {
195-
VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
196-
VALGRIND_MAKE_MEM_DEFINED(&ellswift, sizeof(ellswift));
195+
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
196+
SECP256K1_CHECKMEM_DEFINE(&ellswift, sizeof(ellswift));
197197
ret = secp256k1_ellswift_xdh(ctx, msg, ellswift, ellswift, key, i, secp256k1_ellswift_xdh_hash_function_bip324, NULL);
198-
VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
198+
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
199199
CHECK(ret == 1);
200200

201-
VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
202-
VALGRIND_MAKE_MEM_DEFINED(&ellswift, sizeof(ellswift));
201+
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
202+
SECP256K1_CHECKMEM_DEFINE(&ellswift, sizeof(ellswift));
203203
ret = secp256k1_ellswift_xdh(ctx, msg, ellswift, ellswift, key, i, secp256k1_ellswift_xdh_hash_function_prefix, (void *)prefix);
204-
VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
204+
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
205205
CHECK(ret == 1);
206206
}
207207

‎src/field.h

+3-6
Original file line numberDiff line numberDiff line change
@@ -176,12 +176,6 @@ static int secp256k1_fe_is_odd(const secp256k1_fe *a);
176176
*/
177177
static int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b);
178178

179-
/** Determine whether two field elements are equal, without constant-time guarantee.
180-
*
181-
* Identical in behavior to secp256k1_fe_equal, but not constant time in either a or b.
182-
*/
183-
static int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *b);
184-
185179
/** Compare the values represented by 2 field elements, without constant-time guarantee.
186180
*
187181
* On input, a and b must be valid normalized field elements.
@@ -352,4 +346,7 @@ static int secp256k1_fe_is_square_var(const secp256k1_fe *a);
352346
/** Check invariants on a field element (no-op unless VERIFY is enabled). */
353347
static void secp256k1_fe_verify(const secp256k1_fe *a);
354348

349+
/** Check that magnitude of a is at most m (no-op unless VERIFY is enabled). */
350+
static void secp256k1_fe_verify_magnitude(const secp256k1_fe *a, int m);
351+
355352
#endif /* SECP256K1_FIELD_H */

‎src/field_impl.h

+18-24
Original file line numberDiff line numberDiff line change
@@ -23,27 +23,14 @@ SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe *a, const secp
2323
#ifdef VERIFY
2424
secp256k1_fe_verify(a);
2525
secp256k1_fe_verify(b);
26-
VERIFY_CHECK(a->magnitude <= 1);
27-
VERIFY_CHECK(b->magnitude <= 31);
26+
secp256k1_fe_verify_magnitude(a, 1);
27+
secp256k1_fe_verify_magnitude(b, 31);
2828
#endif
2929
secp256k1_fe_negate(&na, a, 1);
3030
secp256k1_fe_add(&na, b);
3131
return secp256k1_fe_normalizes_to_zero(&na);
3232
}
3333

34-
SECP256K1_INLINE static int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *b) {
35-
secp256k1_fe na;
36-
#ifdef VERIFY
37-
secp256k1_fe_verify(a);
38-
secp256k1_fe_verify(b);
39-
VERIFY_CHECK(a->magnitude <= 1);
40-
VERIFY_CHECK(b->magnitude <= 31);
41-
#endif
42-
secp256k1_fe_negate(&na, a, 1);
43-
secp256k1_fe_add(&na, b);
44-
return secp256k1_fe_normalizes_to_zero_var(&na);
45-
}
46-
4734
static int secp256k1_fe_sqrt(secp256k1_fe * SECP256K1_RESTRICT r, const secp256k1_fe * SECP256K1_RESTRICT a) {
4835
/** Given that p is congruent to 3 mod 4, we can compute the square root of
4936
* a mod p as the (p+1)/4'th power of a.
@@ -60,7 +47,7 @@ static int secp256k1_fe_sqrt(secp256k1_fe * SECP256K1_RESTRICT r, const secp256k
6047
#ifdef VERIFY
6148
VERIFY_CHECK(r != a);
6249
secp256k1_fe_verify(a);
63-
VERIFY_CHECK(a->magnitude <= 8);
50+
secp256k1_fe_verify_magnitude(a, 8);
6451
#endif
6552

6653
/** The binary representation of (p + 1)/4 has 3 blocks of 1s, with lengths in
@@ -151,27 +138,34 @@ static int secp256k1_fe_sqrt(secp256k1_fe * SECP256K1_RESTRICT r, const secp256k
151138
if (!ret) {
152139
secp256k1_fe_negate(&t1, &t1, 1);
153140
secp256k1_fe_normalize_var(&t1);
154-
VERIFY_CHECK(secp256k1_fe_equal_var(&t1, a));
141+
VERIFY_CHECK(secp256k1_fe_equal(&t1, a));
155142
}
156143
#endif
157144
return ret;
158145
}
159146

160147
#ifndef VERIFY
161148
static void secp256k1_fe_verify(const secp256k1_fe *a) { (void)a; }
149+
static void secp256k1_fe_verify_magnitude(const secp256k1_fe *a, int m) { (void)a; (void)m; }
162150
#else
163151
static void secp256k1_fe_impl_verify(const secp256k1_fe *a);
164152
static void secp256k1_fe_verify(const secp256k1_fe *a) {
165153
/* Magnitude between 0 and 32. */
166-
VERIFY_CHECK((a->magnitude >= 0) && (a->magnitude <= 32));
154+
secp256k1_fe_verify_magnitude(a, 32);
167155
/* Normalized is 0 or 1. */
168156
VERIFY_CHECK((a->normalized == 0) || (a->normalized == 1));
169157
/* If normalized, magnitude must be 0 or 1. */
170-
if (a->normalized) VERIFY_CHECK(a->magnitude <= 1);
158+
if (a->normalized) secp256k1_fe_verify_magnitude(a, 1);
171159
/* Invoke implementation-specific checks. */
172160
secp256k1_fe_impl_verify(a);
173161
}
174162

163+
static void secp256k1_fe_verify_magnitude(const secp256k1_fe *a, int m) {
164+
VERIFY_CHECK(m >= 0);
165+
VERIFY_CHECK(m <= 32);
166+
VERIFY_CHECK(a->magnitude <= m);
167+
}
168+
175169
static void secp256k1_fe_impl_normalize(secp256k1_fe *r);
176170
SECP256K1_INLINE static void secp256k1_fe_normalize(secp256k1_fe *r) {
177171
secp256k1_fe_verify(r);
@@ -293,7 +287,7 @@ static void secp256k1_fe_impl_negate_unchecked(secp256k1_fe *r, const secp256k1_
293287
SECP256K1_INLINE static void secp256k1_fe_negate_unchecked(secp256k1_fe *r, const secp256k1_fe *a, int m) {
294288
secp256k1_fe_verify(a);
295289
VERIFY_CHECK(m >= 0 && m <= 31);
296-
VERIFY_CHECK(a->magnitude <= m);
290+
secp256k1_fe_verify_magnitude(a, m);
297291
secp256k1_fe_impl_negate_unchecked(r, a, m);
298292
r->magnitude = m + 1;
299293
r->normalized = 0;
@@ -326,8 +320,8 @@ static void secp256k1_fe_impl_mul(secp256k1_fe *r, const secp256k1_fe *a, const
326320
SECP256K1_INLINE static void secp256k1_fe_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * SECP256K1_RESTRICT b) {
327321
secp256k1_fe_verify(a);
328322
secp256k1_fe_verify(b);
329-
VERIFY_CHECK(a->magnitude <= 8);
330-
VERIFY_CHECK(b->magnitude <= 8);
323+
secp256k1_fe_verify_magnitude(a, 8);
324+
secp256k1_fe_verify_magnitude(b, 8);
331325
VERIFY_CHECK(r != b);
332326
VERIFY_CHECK(a != b);
333327
secp256k1_fe_impl_mul(r, a, b);
@@ -339,7 +333,7 @@ SECP256K1_INLINE static void secp256k1_fe_mul(secp256k1_fe *r, const secp256k1_f
339333
static void secp256k1_fe_impl_sqr(secp256k1_fe *r, const secp256k1_fe *a);
340334
SECP256K1_INLINE static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a) {
341335
secp256k1_fe_verify(a);
342-
VERIFY_CHECK(a->magnitude <= 8);
336+
secp256k1_fe_verify_magnitude(a, 8);
343337
secp256k1_fe_impl_sqr(r, a);
344338
r->magnitude = 1;
345339
r->normalized = 0;
@@ -418,7 +412,7 @@ SECP256K1_INLINE static void secp256k1_fe_get_bounds(secp256k1_fe* r, int m) {
418412
static void secp256k1_fe_impl_half(secp256k1_fe *r);
419413
SECP256K1_INLINE static void secp256k1_fe_half(secp256k1_fe *r) {
420414
secp256k1_fe_verify(r);
421-
VERIFY_CHECK(r->magnitude < 32);
415+
secp256k1_fe_verify_magnitude(r, 31);
422416
secp256k1_fe_impl_half(r);
423417
r->magnitude = (r->magnitude >> 1) + 1;
424418
r->normalized = 0;

‎src/group.h

+8
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ typedef struct {
4444

4545
#define SECP256K1_GE_STORAGE_CONST_GET(t) SECP256K1_FE_STORAGE_CONST_GET(t.x), SECP256K1_FE_STORAGE_CONST_GET(t.y)
4646

47+
/** Maximum allowed magnitudes for group element coordinates
48+
* in affine (x, y) and jacobian (x, y, z) representation. */
49+
#define SECP256K1_GE_X_MAGNITUDE_MAX 4
50+
#define SECP256K1_GE_Y_MAGNITUDE_MAX 3
51+
#define SECP256K1_GEJ_X_MAGNITUDE_MAX 4
52+
#define SECP256K1_GEJ_Y_MAGNITUDE_MAX 4
53+
#define SECP256K1_GEJ_Z_MAGNITUDE_MAX 1
54+
4755
/** Set a group element equal to the point with given X and Y coordinates */
4856
static void secp256k1_ge_set_xy(secp256k1_ge *r, const secp256k1_fe *x, const secp256k1_fe *y);
4957

‎src/group_impl.h

+116-49
Large diffs are not rendered by default.

‎src/hash_impl.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char *
138138
}
139139
if (len) {
140140
/* Fill the buffer with what remains. */
141-
memcpy(((unsigned char*)hash->buf) + bufsize, data, len);
141+
memcpy(hash->buf + bufsize, data, len);
142142
}
143143
}
144144

‎src/modules/extrakeys/tests_exhaustive_impl.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ static void test_exhaustive_extrakeys(const secp256k1_context *ctx, const secp25
4848

4949
/* Compare the xonly_pubkey bytes against the precomputed group. */
5050
secp256k1_fe_set_b32_mod(&fe, xonly_pubkey_bytes[i - 1]);
51-
CHECK(secp256k1_fe_equal_var(&fe, &group[i].x));
51+
CHECK(secp256k1_fe_equal(&fe, &group[i].x));
5252

5353
/* Check the parity against the precomputed group. */
5454
fe = group[i].y;

‎src/modules/schnorrsig/main_impl.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ int secp256k1_schnorrsig_verify(const secp256k1_context* ctx, const unsigned cha
261261

262262
secp256k1_fe_normalize_var(&r.y);
263263
return !secp256k1_fe_is_odd(&r.y) &&
264-
secp256k1_fe_equal_var(&rx, &r.x);
264+
secp256k1_fe_equal(&rx, &r.x);
265265
}
266266

267267
#endif

‎src/modules/schnorrsig/tests_exhaustive_impl.h

+5-5
Original file line numberDiff line numberDiff line change
@@ -110,15 +110,15 @@ static void test_exhaustive_schnorrsig_verify(const secp256k1_context *ctx, cons
110110
if (!e_done[e]) {
111111
/* Iterate over the possible valid last 32 bytes in the signature.
112112
0..order=that s value; order+1=random bytes */
113-
int count_valid = 0, s;
113+
int count_valid = 0;
114+
unsigned int s;
114115
for (s = 0; s <= EXHAUSTIVE_TEST_ORDER + 1; ++s) {
115116
int expect_valid, valid;
116117
if (s <= EXHAUSTIVE_TEST_ORDER) {
117-
secp256k1_scalar s_s;
118-
secp256k1_scalar_set_int(&s_s, s);
119-
secp256k1_scalar_get_b32(sig64 + 32, &s_s);
118+
memset(sig64 + 32, 0, 32);
119+
secp256k1_write_be32(sig64 + 60, s);
120120
expect_valid = actual_k != -1 && s != EXHAUSTIVE_TEST_ORDER &&
121-
(s_s == (actual_k + actual_d * e) % EXHAUSTIVE_TEST_ORDER);
121+
(s == (actual_k + actual_d * e) % EXHAUSTIVE_TEST_ORDER);
122122
} else {
123123
secp256k1_testrand256(sig64 + 32);
124124
expect_valid = 0;

‎src/scalar.h

+3
Original file line numberDiff line numberDiff line change
@@ -99,4 +99,7 @@ static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, const secp256k1_
9999
/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized.*/
100100
static void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag);
101101

102+
/** Check invariants on a scalar (no-op unless VERIFY is enabled). */
103+
static void secp256k1_scalar_verify(const secp256k1_scalar *r);
104+
102105
#endif /* SECP256K1_SCALAR_H */

‎src/scalar_4x64_impl.h

+72-7
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,22 @@ SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsig
4141
r->d[1] = 0;
4242
r->d[2] = 0;
4343
r->d[3] = 0;
44+
45+
secp256k1_scalar_verify(r);
4446
}
4547

4648
SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count) {
49+
secp256k1_scalar_verify(a);
4750
VERIFY_CHECK((offset + count - 1) >> 6 == offset >> 6);
51+
4852
return (a->d[offset >> 6] >> (offset & 0x3F)) & ((((uint64_t)1) << count) - 1);
4953
}
5054

5155
SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) {
56+
secp256k1_scalar_verify(a);
5257
VERIFY_CHECK(count < 32);
5358
VERIFY_CHECK(offset + count <= 256);
59+
5460
if ((offset + count - 1) >> 6 == offset >> 6) {
5561
return secp256k1_scalar_get_bits(a, offset, count);
5662
} else {
@@ -74,6 +80,7 @@ SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scal
7480
SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar *r, unsigned int overflow) {
7581
secp256k1_uint128 t;
7682
VERIFY_CHECK(overflow <= 1);
83+
7784
secp256k1_u128_from_u64(&t, r->d[0]);
7885
secp256k1_u128_accum_u64(&t, overflow * SECP256K1_N_C_0);
7986
r->d[0] = secp256k1_u128_to_u64(&t); secp256k1_u128_rshift(&t, 64);
@@ -85,12 +92,17 @@ SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar *r, unsigne
8592
r->d[2] = secp256k1_u128_to_u64(&t); secp256k1_u128_rshift(&t, 64);
8693
secp256k1_u128_accum_u64(&t, r->d[3]);
8794
r->d[3] = secp256k1_u128_to_u64(&t);
95+
96+
secp256k1_scalar_verify(r);
8897
return overflow;
8998
}
9099

91100
static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) {
92101
int overflow;
93102
secp256k1_uint128 t;
103+
secp256k1_scalar_verify(a);
104+
secp256k1_scalar_verify(b);
105+
94106
secp256k1_u128_from_u64(&t, a->d[0]);
95107
secp256k1_u128_accum_u64(&t, b->d[0]);
96108
r->d[0] = secp256k1_u128_to_u64(&t); secp256k1_u128_rshift(&t, 64);
@@ -106,13 +118,17 @@ static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a,
106118
overflow = secp256k1_u128_to_u64(&t) + secp256k1_scalar_check_overflow(r);
107119
VERIFY_CHECK(overflow == 0 || overflow == 1);
108120
secp256k1_scalar_reduce(r, overflow);
121+
122+
secp256k1_scalar_verify(r);
109123
return overflow;
110124
}
111125

112126
static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag) {
113127
secp256k1_uint128 t;
114128
volatile int vflag = flag;
129+
secp256k1_scalar_verify(r);
115130
VERIFY_CHECK(bit < 256);
131+
116132
bit += ((uint32_t) vflag - 1) & 0x100; /* forcing (bit >> 6) > 3 makes this a noop */
117133
secp256k1_u128_from_u64(&t, r->d[0]);
118134
secp256k1_u128_accum_u64(&t, ((uint64_t)((bit >> 6) == 0)) << (bit & 0x3F));
@@ -126,6 +142,8 @@ static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int
126142
secp256k1_u128_accum_u64(&t, r->d[3]);
127143
secp256k1_u128_accum_u64(&t, ((uint64_t)((bit >> 6) == 3)) << (bit & 0x3F));
128144
r->d[3] = secp256k1_u128_to_u64(&t);
145+
146+
secp256k1_scalar_verify(r);
129147
#ifdef VERIFY
130148
VERIFY_CHECK(secp256k1_u128_hi_u64(&t) == 0);
131149
#endif
@@ -141,22 +159,30 @@ static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b
141159
if (overflow) {
142160
*overflow = over;
143161
}
162+
163+
secp256k1_scalar_verify(r);
144164
}
145165

146166
static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a) {
167+
secp256k1_scalar_verify(a);
168+
147169
secp256k1_write_be64(&bin[0], a->d[3]);
148170
secp256k1_write_be64(&bin[8], a->d[2]);
149171
secp256k1_write_be64(&bin[16], a->d[1]);
150172
secp256k1_write_be64(&bin[24], a->d[0]);
151173
}
152174

153175
SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar *a) {
176+
secp256k1_scalar_verify(a);
177+
154178
return (a->d[0] | a->d[1] | a->d[2] | a->d[3]) == 0;
155179
}
156180

157181
static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a) {
158182
uint64_t nonzero = 0xFFFFFFFFFFFFFFFFULL * (secp256k1_scalar_is_zero(a) == 0);
159183
secp256k1_uint128 t;
184+
secp256k1_scalar_verify(a);
185+
160186
secp256k1_u128_from_u64(&t, ~a->d[0]);
161187
secp256k1_u128_accum_u64(&t, SECP256K1_N_0 + 1);
162188
r->d[0] = secp256k1_u128_to_u64(&t) & nonzero; secp256k1_u128_rshift(&t, 64);
@@ -169,15 +195,21 @@ static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar
169195
secp256k1_u128_accum_u64(&t, ~a->d[3]);
170196
secp256k1_u128_accum_u64(&t, SECP256K1_N_3);
171197
r->d[3] = secp256k1_u128_to_u64(&t) & nonzero;
198+
199+
secp256k1_scalar_verify(r);
172200
}
173201

174202
SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar *a) {
203+
secp256k1_scalar_verify(a);
204+
175205
return ((a->d[0] ^ 1) | a->d[1] | a->d[2] | a->d[3]) == 0;
176206
}
177207

178208
static int secp256k1_scalar_is_high(const secp256k1_scalar *a) {
179209
int yes = 0;
180210
int no = 0;
211+
secp256k1_scalar_verify(a);
212+
181213
no |= (a->d[3] < SECP256K1_N_H_3);
182214
yes |= (a->d[3] > SECP256K1_N_H_3) & ~no;
183215
no |= (a->d[2] < SECP256K1_N_H_2) & ~yes; /* No need for a > check. */
@@ -194,6 +226,8 @@ static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) {
194226
uint64_t mask = -vflag;
195227
uint64_t nonzero = (secp256k1_scalar_is_zero(r) != 0) - 1;
196228
secp256k1_uint128 t;
229+
secp256k1_scalar_verify(r);
230+
197231
secp256k1_u128_from_u64(&t, r->d[0] ^ mask);
198232
secp256k1_u128_accum_u64(&t, (SECP256K1_N_0 + 1) & mask);
199233
r->d[0] = secp256k1_u128_to_u64(&t) & nonzero; secp256k1_u128_rshift(&t, 64);
@@ -206,6 +240,8 @@ static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) {
206240
secp256k1_u128_accum_u64(&t, r->d[3] ^ mask);
207241
secp256k1_u128_accum_u64(&t, SECP256K1_N_3 & mask);
208242
r->d[3] = secp256k1_u128_to_u64(&t) & nonzero;
243+
244+
secp256k1_scalar_verify(r);
209245
return 2 * (mask == 0) - 1;
210246
}
211247

@@ -764,23 +800,34 @@ static void secp256k1_scalar_mul_512(uint64_t l[8], const secp256k1_scalar *a, c
764800

765801
static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) {
766802
uint64_t l[8];
803+
secp256k1_scalar_verify(a);
804+
secp256k1_scalar_verify(b);
805+
767806
secp256k1_scalar_mul_512(l, a, b);
768807
secp256k1_scalar_reduce_512(r, l);
808+
809+
secp256k1_scalar_verify(r);
769810
}
770811

771812
static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n) {
772813
int ret;
814+
secp256k1_scalar_verify(r);
773815
VERIFY_CHECK(n > 0);
774816
VERIFY_CHECK(n < 16);
817+
775818
ret = r->d[0] & ((1 << n) - 1);
776819
r->d[0] = (r->d[0] >> n) + (r->d[1] << (64 - n));
777820
r->d[1] = (r->d[1] >> n) + (r->d[2] << (64 - n));
778821
r->d[2] = (r->d[2] >> n) + (r->d[3] << (64 - n));
779822
r->d[3] = (r->d[3] >> n);
823+
824+
secp256k1_scalar_verify(r);
780825
return ret;
781826
}
782827

783828
static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *k) {
829+
secp256k1_scalar_verify(k);
830+
784831
r1->d[0] = k->d[0];
785832
r1->d[1] = k->d[1];
786833
r1->d[2] = 0;
@@ -789,9 +836,15 @@ static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r
789836
r2->d[1] = k->d[3];
790837
r2->d[2] = 0;
791838
r2->d[3] = 0;
839+
840+
secp256k1_scalar_verify(r1);
841+
secp256k1_scalar_verify(r2);
792842
}
793843

794844
SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b) {
845+
secp256k1_scalar_verify(a);
846+
secp256k1_scalar_verify(b);
847+
795848
return ((a->d[0] ^ b->d[0]) | (a->d[1] ^ b->d[1]) | (a->d[2] ^ b->d[2]) | (a->d[3] ^ b->d[3])) == 0;
796849
}
797850

@@ -800,7 +853,10 @@ SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r,
800853
unsigned int shiftlimbs;
801854
unsigned int shiftlow;
802855
unsigned int shifthigh;
856+
secp256k1_scalar_verify(a);
857+
secp256k1_scalar_verify(b);
803858
VERIFY_CHECK(shift >= 256);
859+
804860
secp256k1_scalar_mul_512(l, a, b);
805861
shiftlimbs = shift >> 6;
806862
shiftlow = shift & 0x3F;
@@ -810,18 +866,24 @@ SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r,
810866
r->d[2] = shift < 384 ? (l[2 + shiftlimbs] >> shiftlow | (shift < 320 && shiftlow ? (l[3 + shiftlimbs] << shifthigh) : 0)) : 0;
811867
r->d[3] = shift < 320 ? (l[3 + shiftlimbs] >> shiftlow) : 0;
812868
secp256k1_scalar_cadd_bit(r, 0, (l[(shift - 1) >> 6] >> ((shift - 1) & 0x3f)) & 1);
869+
870+
secp256k1_scalar_verify(r);
813871
}
814872

815873
static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag) {
816874
uint64_t mask0, mask1;
817875
volatile int vflag = flag;
876+
secp256k1_scalar_verify(a);
818877
SECP256K1_CHECKMEM_CHECK_VERIFY(r->d, sizeof(r->d));
878+
819879
mask0 = vflag + ~((uint64_t)0);
820880
mask1 = ~mask0;
821881
r->d[0] = (r->d[0] & mask0) | (a->d[0] & mask1);
822882
r->d[1] = (r->d[1] & mask0) | (a->d[1] & mask1);
823883
r->d[2] = (r->d[2] & mask0) | (a->d[2] & mask1);
824884
r->d[3] = (r->d[3] & mask0) | (a->d[3] & mask1);
885+
886+
secp256k1_scalar_verify(r);
825887
}
826888

827889
static void secp256k1_scalar_from_signed62(secp256k1_scalar *r, const secp256k1_modinv64_signed62 *a) {
@@ -841,18 +903,13 @@ static void secp256k1_scalar_from_signed62(secp256k1_scalar *r, const secp256k1_
841903
r->d[2] = a2 >> 4 | a3 << 58;
842904
r->d[3] = a3 >> 6 | a4 << 56;
843905

844-
#ifdef VERIFY
845-
VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0);
846-
#endif
906+
secp256k1_scalar_verify(r);
847907
}
848908

849909
static void secp256k1_scalar_to_signed62(secp256k1_modinv64_signed62 *r, const secp256k1_scalar *a) {
850910
const uint64_t M62 = UINT64_MAX >> 2;
851911
const uint64_t a0 = a->d[0], a1 = a->d[1], a2 = a->d[2], a3 = a->d[3];
852-
853-
#ifdef VERIFY
854-
VERIFY_CHECK(secp256k1_scalar_check_overflow(a) == 0);
855-
#endif
912+
secp256k1_scalar_verify(a);
856913

857914
r->v[0] = a0 & M62;
858915
r->v[1] = (a0 >> 62 | a1 << 2) & M62;
@@ -871,10 +928,13 @@ static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar
871928
#ifdef VERIFY
872929
int zero_in = secp256k1_scalar_is_zero(x);
873930
#endif
931+
secp256k1_scalar_verify(x);
932+
874933
secp256k1_scalar_to_signed62(&s, x);
875934
secp256k1_modinv64(&s, &secp256k1_const_modinfo_scalar);
876935
secp256k1_scalar_from_signed62(r, &s);
877936

937+
secp256k1_scalar_verify(r);
878938
#ifdef VERIFY
879939
VERIFY_CHECK(secp256k1_scalar_is_zero(r) == zero_in);
880940
#endif
@@ -885,16 +945,21 @@ static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_sc
885945
#ifdef VERIFY
886946
int zero_in = secp256k1_scalar_is_zero(x);
887947
#endif
948+
secp256k1_scalar_verify(x);
949+
888950
secp256k1_scalar_to_signed62(&s, x);
889951
secp256k1_modinv64_var(&s, &secp256k1_const_modinfo_scalar);
890952
secp256k1_scalar_from_signed62(r, &s);
891953

954+
secp256k1_scalar_verify(r);
892955
#ifdef VERIFY
893956
VERIFY_CHECK(secp256k1_scalar_is_zero(r) == zero_in);
894957
#endif
895958
}
896959

897960
SECP256K1_INLINE static int secp256k1_scalar_is_even(const secp256k1_scalar *a) {
961+
secp256k1_scalar_verify(a);
962+
898963
return !(a->d[0] & 1);
899964
}
900965

‎src/scalar_8x32_impl.h

+72-8
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,22 @@ SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsig
5858
r->d[5] = 0;
5959
r->d[6] = 0;
6060
r->d[7] = 0;
61+
62+
secp256k1_scalar_verify(r);
6163
}
6264

6365
SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count) {
66+
secp256k1_scalar_verify(a);
6467
VERIFY_CHECK((offset + count - 1) >> 5 == offset >> 5);
68+
6569
return (a->d[offset >> 5] >> (offset & 0x1F)) & ((1 << count) - 1);
6670
}
6771

6872
SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) {
73+
secp256k1_scalar_verify(a);
6974
VERIFY_CHECK(count < 32);
7075
VERIFY_CHECK(offset + count <= 256);
76+
7177
if ((offset + count - 1) >> 5 == offset >> 5) {
7278
return secp256k1_scalar_get_bits(a, offset, count);
7379
} else {
@@ -97,6 +103,7 @@ SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scal
97103
SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar *r, uint32_t overflow) {
98104
uint64_t t;
99105
VERIFY_CHECK(overflow <= 1);
106+
100107
t = (uint64_t)r->d[0] + overflow * SECP256K1_N_C_0;
101108
r->d[0] = t & 0xFFFFFFFFUL; t >>= 32;
102109
t += (uint64_t)r->d[1] + overflow * SECP256K1_N_C_1;
@@ -113,12 +120,17 @@ SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar *r, uint32_
113120
r->d[6] = t & 0xFFFFFFFFUL; t >>= 32;
114121
t += (uint64_t)r->d[7];
115122
r->d[7] = t & 0xFFFFFFFFUL;
123+
124+
secp256k1_scalar_verify(r);
116125
return overflow;
117126
}
118127

119128
static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) {
120129
int overflow;
121130
uint64_t t = (uint64_t)a->d[0] + b->d[0];
131+
secp256k1_scalar_verify(a);
132+
secp256k1_scalar_verify(b);
133+
122134
r->d[0] = t & 0xFFFFFFFFULL; t >>= 32;
123135
t += (uint64_t)a->d[1] + b->d[1];
124136
r->d[1] = t & 0xFFFFFFFFULL; t >>= 32;
@@ -137,13 +149,17 @@ static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a,
137149
overflow = t + secp256k1_scalar_check_overflow(r);
138150
VERIFY_CHECK(overflow == 0 || overflow == 1);
139151
secp256k1_scalar_reduce(r, overflow);
152+
153+
secp256k1_scalar_verify(r);
140154
return overflow;
141155
}
142156

143157
static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag) {
144158
uint64_t t;
145159
volatile int vflag = flag;
160+
secp256k1_scalar_verify(r);
146161
VERIFY_CHECK(bit < 256);
162+
147163
bit += ((uint32_t) vflag - 1) & 0x100; /* forcing (bit >> 5) > 7 makes this a noop */
148164
t = (uint64_t)r->d[0] + (((uint32_t)((bit >> 5) == 0)) << (bit & 0x1F));
149165
r->d[0] = t & 0xFFFFFFFFULL; t >>= 32;
@@ -161,9 +177,10 @@ static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int
161177
r->d[6] = t & 0xFFFFFFFFULL; t >>= 32;
162178
t += (uint64_t)r->d[7] + (((uint32_t)((bit >> 5) == 7)) << (bit & 0x1F));
163179
r->d[7] = t & 0xFFFFFFFFULL;
180+
181+
secp256k1_scalar_verify(r);
164182
#ifdef VERIFY
165183
VERIFY_CHECK((t >> 32) == 0);
166-
VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0);
167184
#endif
168185
}
169186

@@ -181,9 +198,13 @@ static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b
181198
if (overflow) {
182199
*overflow = over;
183200
}
201+
202+
secp256k1_scalar_verify(r);
184203
}
185204

186205
static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a) {
206+
secp256k1_scalar_verify(a);
207+
187208
secp256k1_write_be32(&bin[0], a->d[7]);
188209
secp256k1_write_be32(&bin[4], a->d[6]);
189210
secp256k1_write_be32(&bin[8], a->d[5]);
@@ -195,12 +216,16 @@ static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar*
195216
}
196217

197218
SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar *a) {
219+
secp256k1_scalar_verify(a);
220+
198221
return (a->d[0] | a->d[1] | a->d[2] | a->d[3] | a->d[4] | a->d[5] | a->d[6] | a->d[7]) == 0;
199222
}
200223

201224
static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a) {
202225
uint32_t nonzero = 0xFFFFFFFFUL * (secp256k1_scalar_is_zero(a) == 0);
203226
uint64_t t = (uint64_t)(~a->d[0]) + SECP256K1_N_0 + 1;
227+
secp256k1_scalar_verify(a);
228+
204229
r->d[0] = t & nonzero; t >>= 32;
205230
t += (uint64_t)(~a->d[1]) + SECP256K1_N_1;
206231
r->d[1] = t & nonzero; t >>= 32;
@@ -216,15 +241,21 @@ static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar
216241
r->d[6] = t & nonzero; t >>= 32;
217242
t += (uint64_t)(~a->d[7]) + SECP256K1_N_7;
218243
r->d[7] = t & nonzero;
244+
245+
secp256k1_scalar_verify(r);
219246
}
220247

221248
SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar *a) {
249+
secp256k1_scalar_verify(a);
250+
222251
return ((a->d[0] ^ 1) | a->d[1] | a->d[2] | a->d[3] | a->d[4] | a->d[5] | a->d[6] | a->d[7]) == 0;
223252
}
224253

225254
static int secp256k1_scalar_is_high(const secp256k1_scalar *a) {
226255
int yes = 0;
227256
int no = 0;
257+
secp256k1_scalar_verify(a);
258+
228259
no |= (a->d[7] < SECP256K1_N_H_7);
229260
yes |= (a->d[7] > SECP256K1_N_H_7) & ~no;
230261
no |= (a->d[6] < SECP256K1_N_H_6) & ~yes; /* No need for a > check. */
@@ -247,6 +278,8 @@ static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) {
247278
uint32_t mask = -vflag;
248279
uint32_t nonzero = 0xFFFFFFFFUL * (secp256k1_scalar_is_zero(r) == 0);
249280
uint64_t t = (uint64_t)(r->d[0] ^ mask) + ((SECP256K1_N_0 + 1) & mask);
281+
secp256k1_scalar_verify(r);
282+
250283
r->d[0] = t & nonzero; t >>= 32;
251284
t += (uint64_t)(r->d[1] ^ mask) + (SECP256K1_N_1 & mask);
252285
r->d[1] = t & nonzero; t >>= 32;
@@ -262,6 +295,8 @@ static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) {
262295
r->d[6] = t & nonzero; t >>= 32;
263296
t += (uint64_t)(r->d[7] ^ mask) + (SECP256K1_N_7 & mask);
264297
r->d[7] = t & nonzero;
298+
299+
secp256k1_scalar_verify(r);
265300
return 2 * (mask == 0) - 1;
266301
}
267302

@@ -569,14 +604,21 @@ static void secp256k1_scalar_mul_512(uint32_t *l, const secp256k1_scalar *a, con
569604

570605
static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) {
571606
uint32_t l[16];
607+
secp256k1_scalar_verify(a);
608+
secp256k1_scalar_verify(b);
609+
572610
secp256k1_scalar_mul_512(l, a, b);
573611
secp256k1_scalar_reduce_512(r, l);
612+
613+
secp256k1_scalar_verify(r);
574614
}
575615

576616
static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n) {
577617
int ret;
618+
secp256k1_scalar_verify(r);
578619
VERIFY_CHECK(n > 0);
579620
VERIFY_CHECK(n < 16);
621+
580622
ret = r->d[0] & ((1 << n) - 1);
581623
r->d[0] = (r->d[0] >> n) + (r->d[1] << (32 - n));
582624
r->d[1] = (r->d[1] >> n) + (r->d[2] << (32 - n));
@@ -586,10 +628,14 @@ static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n) {
586628
r->d[5] = (r->d[5] >> n) + (r->d[6] << (32 - n));
587629
r->d[6] = (r->d[6] >> n) + (r->d[7] << (32 - n));
588630
r->d[7] = (r->d[7] >> n);
631+
632+
secp256k1_scalar_verify(r);
589633
return ret;
590634
}
591635

592636
static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *k) {
637+
secp256k1_scalar_verify(k);
638+
593639
r1->d[0] = k->d[0];
594640
r1->d[1] = k->d[1];
595641
r1->d[2] = k->d[2];
@@ -606,9 +652,15 @@ static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r
606652
r2->d[5] = 0;
607653
r2->d[6] = 0;
608654
r2->d[7] = 0;
655+
656+
secp256k1_scalar_verify(r1);
657+
secp256k1_scalar_verify(r2);
609658
}
610659

611660
SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b) {
661+
secp256k1_scalar_verify(a);
662+
secp256k1_scalar_verify(b);
663+
612664
return ((a->d[0] ^ b->d[0]) | (a->d[1] ^ b->d[1]) | (a->d[2] ^ b->d[2]) | (a->d[3] ^ b->d[3]) | (a->d[4] ^ b->d[4]) | (a->d[5] ^ b->d[5]) | (a->d[6] ^ b->d[6]) | (a->d[7] ^ b->d[7])) == 0;
613665
}
614666

@@ -617,7 +669,10 @@ SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r,
617669
unsigned int shiftlimbs;
618670
unsigned int shiftlow;
619671
unsigned int shifthigh;
672+
secp256k1_scalar_verify(a);
673+
secp256k1_scalar_verify(b);
620674
VERIFY_CHECK(shift >= 256);
675+
621676
secp256k1_scalar_mul_512(l, a, b);
622677
shiftlimbs = shift >> 5;
623678
shiftlow = shift & 0x1F;
@@ -631,12 +686,16 @@ SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r,
631686
r->d[6] = shift < 320 ? (l[6 + shiftlimbs] >> shiftlow | (shift < 288 && shiftlow ? (l[7 + shiftlimbs] << shifthigh) : 0)) : 0;
632687
r->d[7] = shift < 288 ? (l[7 + shiftlimbs] >> shiftlow) : 0;
633688
secp256k1_scalar_cadd_bit(r, 0, (l[(shift - 1) >> 5] >> ((shift - 1) & 0x1f)) & 1);
689+
690+
secp256k1_scalar_verify(r);
634691
}
635692

636693
static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag) {
637694
uint32_t mask0, mask1;
638695
volatile int vflag = flag;
696+
secp256k1_scalar_verify(a);
639697
SECP256K1_CHECKMEM_CHECK_VERIFY(r->d, sizeof(r->d));
698+
640699
mask0 = vflag + ~((uint32_t)0);
641700
mask1 = ~mask0;
642701
r->d[0] = (r->d[0] & mask0) | (a->d[0] & mask1);
@@ -647,6 +706,8 @@ static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const se
647706
r->d[5] = (r->d[5] & mask0) | (a->d[5] & mask1);
648707
r->d[6] = (r->d[6] & mask0) | (a->d[6] & mask1);
649708
r->d[7] = (r->d[7] & mask0) | (a->d[7] & mask1);
709+
710+
secp256k1_scalar_verify(r);
650711
}
651712

652713
static void secp256k1_scalar_from_signed30(secp256k1_scalar *r, const secp256k1_modinv32_signed30 *a) {
@@ -675,19 +736,14 @@ static void secp256k1_scalar_from_signed30(secp256k1_scalar *r, const secp256k1_
675736
r->d[6] = a6 >> 12 | a7 << 18;
676737
r->d[7] = a7 >> 14 | a8 << 16;
677738

678-
#ifdef VERIFY
679-
VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0);
680-
#endif
739+
secp256k1_scalar_verify(r);
681740
}
682741

683742
static void secp256k1_scalar_to_signed30(secp256k1_modinv32_signed30 *r, const secp256k1_scalar *a) {
684743
const uint32_t M30 = UINT32_MAX >> 2;
685744
const uint32_t a0 = a->d[0], a1 = a->d[1], a2 = a->d[2], a3 = a->d[3],
686745
a4 = a->d[4], a5 = a->d[5], a6 = a->d[6], a7 = a->d[7];
687-
688-
#ifdef VERIFY
689-
VERIFY_CHECK(secp256k1_scalar_check_overflow(a) == 0);
690-
#endif
746+
secp256k1_scalar_verify(a);
691747

692748
r->v[0] = a0 & M30;
693749
r->v[1] = (a0 >> 30 | a1 << 2) & M30;
@@ -710,10 +766,13 @@ static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar
710766
#ifdef VERIFY
711767
int zero_in = secp256k1_scalar_is_zero(x);
712768
#endif
769+
secp256k1_scalar_verify(x);
770+
713771
secp256k1_scalar_to_signed30(&s, x);
714772
secp256k1_modinv32(&s, &secp256k1_const_modinfo_scalar);
715773
secp256k1_scalar_from_signed30(r, &s);
716774

775+
secp256k1_scalar_verify(r);
717776
#ifdef VERIFY
718777
VERIFY_CHECK(secp256k1_scalar_is_zero(r) == zero_in);
719778
#endif
@@ -724,16 +783,21 @@ static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_sc
724783
#ifdef VERIFY
725784
int zero_in = secp256k1_scalar_is_zero(x);
726785
#endif
786+
secp256k1_scalar_verify(x);
787+
727788
secp256k1_scalar_to_signed30(&s, x);
728789
secp256k1_modinv32_var(&s, &secp256k1_const_modinfo_scalar);
729790
secp256k1_scalar_from_signed30(r, &s);
730791

792+
secp256k1_scalar_verify(r);
731793
#ifdef VERIFY
732794
VERIFY_CHECK(secp256k1_scalar_is_zero(r) == zero_in);
733795
#endif
734796
}
735797

736798
SECP256K1_INLINE static int secp256k1_scalar_is_even(const secp256k1_scalar *a) {
799+
secp256k1_scalar_verify(a);
800+
737801
return !(a->d[0] & 1);
738802
}
739803

‎src/scalar_impl.h

+19
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,19 @@ static const secp256k1_scalar secp256k1_scalar_zero = SECP256K1_SCALAR_CONST(0,
3030
static int secp256k1_scalar_set_b32_seckey(secp256k1_scalar *r, const unsigned char *bin) {
3131
int overflow;
3232
secp256k1_scalar_set_b32(r, bin, &overflow);
33+
34+
secp256k1_scalar_verify(r);
3335
return (!overflow) & (!secp256k1_scalar_is_zero(r));
3436
}
3537

38+
static void secp256k1_scalar_verify(const secp256k1_scalar *r) {
39+
#ifdef VERIFY
40+
VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0);
41+
#endif
42+
43+
(void)r;
44+
}
45+
3646
#if defined(EXHAUSTIVE_TEST_ORDER)
3747
/* Begin of section generated by sage/gen_exhaustive_groups.sage. */
3848
# if EXHAUSTIVE_TEST_ORDER == 7
@@ -53,11 +63,16 @@ static int secp256k1_scalar_set_b32_seckey(secp256k1_scalar *r, const unsigned c
5363
* (arbitrarily) set r2 = k + 5 (mod n) and r1 = k - r2 * lambda (mod n).
5464
*/
5565
static void secp256k1_scalar_split_lambda(secp256k1_scalar * SECP256K1_RESTRICT r1, secp256k1_scalar * SECP256K1_RESTRICT r2, const secp256k1_scalar * SECP256K1_RESTRICT k) {
66+
secp256k1_scalar_verify(k);
5667
VERIFY_CHECK(r1 != k);
5768
VERIFY_CHECK(r2 != k);
5869
VERIFY_CHECK(r1 != r2);
70+
5971
*r2 = (*k + 5) % EXHAUSTIVE_TEST_ORDER;
6072
*r1 = (*k + (EXHAUSTIVE_TEST_ORDER - *r2) * EXHAUSTIVE_TEST_LAMBDA) % EXHAUSTIVE_TEST_ORDER;
73+
74+
secp256k1_scalar_verify(r1);
75+
secp256k1_scalar_verify(r2);
6176
}
6277
#else
6378
/**
@@ -140,9 +155,11 @@ static void secp256k1_scalar_split_lambda(secp256k1_scalar * SECP256K1_RESTRICT
140155
0xE4437ED6UL, 0x010E8828UL, 0x6F547FA9UL, 0x0ABFE4C4UL,
141156
0x221208ACUL, 0x9DF506C6UL, 0x1571B4AEUL, 0x8AC47F71UL
142157
);
158+
secp256k1_scalar_verify(k);
143159
VERIFY_CHECK(r1 != k);
144160
VERIFY_CHECK(r2 != k);
145161
VERIFY_CHECK(r1 != r2);
162+
146163
/* these _var calls are constant time since the shift amount is constant */
147164
secp256k1_scalar_mul_shift_var(&c1, k, &g1, 384);
148165
secp256k1_scalar_mul_shift_var(&c2, k, &g2, 384);
@@ -153,6 +170,8 @@ static void secp256k1_scalar_split_lambda(secp256k1_scalar * SECP256K1_RESTRICT
153170
secp256k1_scalar_negate(r1, r1);
154171
secp256k1_scalar_add(r1, r1, k);
155172

173+
secp256k1_scalar_verify(r1);
174+
secp256k1_scalar_verify(r2);
156175
#ifdef VERIFY
157176
secp256k1_scalar_split_lambda_verify(r1, r2, k);
158177
#endif

‎src/scalar_low_impl.h

+68-2
Original file line numberDiff line numberDiff line change
@@ -14,38 +14,57 @@
1414
#include <string.h>
1515

1616
SECP256K1_INLINE static int secp256k1_scalar_is_even(const secp256k1_scalar *a) {
17+
secp256k1_scalar_verify(a);
18+
1719
return !(*a & 1);
1820
}
1921

2022
SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar *r) { *r = 0; }
21-
SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v) { *r = v; }
23+
24+
SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v) {
25+
*r = v % EXHAUSTIVE_TEST_ORDER;
26+
27+
secp256k1_scalar_verify(r);
28+
}
2229

2330
SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count) {
31+
secp256k1_scalar_verify(a);
32+
2433
if (offset < 32)
2534
return ((*a >> offset) & ((((uint32_t)1) << count) - 1));
2635
else
2736
return 0;
2837
}
2938

3039
SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) {
40+
secp256k1_scalar_verify(a);
41+
3142
return secp256k1_scalar_get_bits(a, offset, count);
3243
}
3344

3445
SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar *a) { return *a >= EXHAUSTIVE_TEST_ORDER; }
3546

3647
static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) {
48+
secp256k1_scalar_verify(a);
49+
secp256k1_scalar_verify(b);
50+
3751
*r = (*a + *b) % EXHAUSTIVE_TEST_ORDER;
52+
53+
secp256k1_scalar_verify(r);
3854
return *r < *b;
3955
}
4056

4157
static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag) {
58+
secp256k1_scalar_verify(r);
59+
4260
if (flag && bit < 32)
4361
*r += ((uint32_t)1 << bit);
62+
63+
secp256k1_scalar_verify(r);
4464
#ifdef VERIFY
4565
VERIFY_CHECK(bit < 32);
4666
/* Verify that adding (1 << bit) will not overflow any in-range scalar *r by overflowing the underlying uint32_t. */
4767
VERIFY_CHECK(((uint32_t)1 << bit) - 1 <= UINT32_MAX - EXHAUSTIVE_TEST_ORDER);
48-
VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0);
4968
#endif
5069
}
5170

@@ -61,82 +80,129 @@ static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b
6180
}
6281
}
6382
if (overflow) *overflow = over;
83+
84+
secp256k1_scalar_verify(r);
6485
}
6586

6687
static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a) {
88+
secp256k1_scalar_verify(a);
89+
6790
memset(bin, 0, 32);
6891
bin[28] = *a >> 24; bin[29] = *a >> 16; bin[30] = *a >> 8; bin[31] = *a;
6992
}
7093

7194
SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar *a) {
95+
secp256k1_scalar_verify(a);
96+
7297
return *a == 0;
7398
}
7499

75100
static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a) {
101+
secp256k1_scalar_verify(a);
102+
76103
if (*a == 0) {
77104
*r = 0;
78105
} else {
79106
*r = EXHAUSTIVE_TEST_ORDER - *a;
80107
}
108+
109+
secp256k1_scalar_verify(r);
81110
}
82111

83112
SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar *a) {
113+
secp256k1_scalar_verify(a);
114+
84115
return *a == 1;
85116
}
86117

87118
static int secp256k1_scalar_is_high(const secp256k1_scalar *a) {
119+
secp256k1_scalar_verify(a);
120+
88121
return *a > EXHAUSTIVE_TEST_ORDER / 2;
89122
}
90123

91124
static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) {
125+
secp256k1_scalar_verify(r);
126+
92127
if (flag) secp256k1_scalar_negate(r, r);
128+
129+
secp256k1_scalar_verify(r);
93130
return flag ? -1 : 1;
94131
}
95132

96133
static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) {
134+
secp256k1_scalar_verify(a);
135+
secp256k1_scalar_verify(b);
136+
97137
*r = (*a * *b) % EXHAUSTIVE_TEST_ORDER;
138+
139+
secp256k1_scalar_verify(r);
98140
}
99141

100142
static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n) {
101143
int ret;
144+
secp256k1_scalar_verify(r);
102145
VERIFY_CHECK(n > 0);
103146
VERIFY_CHECK(n < 16);
147+
104148
ret = *r & ((1 << n) - 1);
105149
*r >>= n;
150+
151+
secp256k1_scalar_verify(r);
106152
return ret;
107153
}
108154

109155
static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) {
156+
secp256k1_scalar_verify(a);
157+
110158
*r1 = *a;
111159
*r2 = 0;
160+
161+
secp256k1_scalar_verify(r1);
162+
secp256k1_scalar_verify(r2);
112163
}
113164

114165
SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b) {
166+
secp256k1_scalar_verify(a);
167+
secp256k1_scalar_verify(b);
168+
115169
return *a == *b;
116170
}
117171

118172
static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag) {
119173
uint32_t mask0, mask1;
120174
volatile int vflag = flag;
175+
secp256k1_scalar_verify(a);
121176
SECP256K1_CHECKMEM_CHECK_VERIFY(r, sizeof(*r));
177+
122178
mask0 = vflag + ~((uint32_t)0);
123179
mask1 = ~mask0;
124180
*r = (*r & mask0) | (*a & mask1);
181+
182+
secp256k1_scalar_verify(r);
125183
}
126184

127185
static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *x) {
128186
int i;
129187
*r = 0;
188+
secp256k1_scalar_verify(x);
189+
130190
for (i = 0; i < EXHAUSTIVE_TEST_ORDER; i++)
131191
if ((i * *x) % EXHAUSTIVE_TEST_ORDER == 1)
132192
*r = i;
193+
194+
secp256k1_scalar_verify(r);
133195
/* If this VERIFY_CHECK triggers we were given a noninvertible scalar (and thus
134196
* have a composite group order; fix it in exhaustive_tests.c). */
135197
VERIFY_CHECK(*r != 0);
136198
}
137199

138200
static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_scalar *x) {
201+
secp256k1_scalar_verify(x);
202+
139203
secp256k1_scalar_inverse(r, x);
204+
205+
secp256k1_scalar_verify(r);
140206
}
141207

142208
#endif /* SECP256K1_SCALAR_REPR_IMPL_H */

‎src/tests.c

+86-71
Large diffs are not rendered by default.

‎src/tests_exhaustive.c

+10-10
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ static void ge_equals_ge(const secp256k1_ge *a, const secp256k1_ge *b) {
3838
if (a->infinity) {
3939
return;
4040
}
41-
CHECK(secp256k1_fe_equal_var(&a->x, &b->x));
42-
CHECK(secp256k1_fe_equal_var(&a->y, &b->y));
41+
CHECK(secp256k1_fe_equal(&a->x, &b->x));
42+
CHECK(secp256k1_fe_equal(&a->y, &b->y));
4343
}
4444

4545
static void ge_equals_gej(const secp256k1_ge *a, const secp256k1_gej *b) {
@@ -52,11 +52,11 @@ static void ge_equals_gej(const secp256k1_ge *a, const secp256k1_gej *b) {
5252
/* Check a.x * b.z^2 == b.x && a.y * b.z^3 == b.y, to avoid inverses. */
5353
secp256k1_fe_sqr(&z2s, &b->z);
5454
secp256k1_fe_mul(&u1, &a->x, &z2s);
55-
u2 = b->x; secp256k1_fe_normalize_weak(&u2);
55+
u2 = b->x;
5656
secp256k1_fe_mul(&s1, &a->y, &z2s); secp256k1_fe_mul(&s1, &s1, &b->z);
57-
s2 = b->y; secp256k1_fe_normalize_weak(&s2);
58-
CHECK(secp256k1_fe_equal_var(&u1, &u2));
59-
CHECK(secp256k1_fe_equal_var(&s1, &s2));
57+
s2 = b->y;
58+
CHECK(secp256k1_fe_equal(&u1, &u2));
59+
CHECK(secp256k1_fe_equal(&s1, &s2));
6060
}
6161

6262
static void random_fe(secp256k1_fe *x) {
@@ -219,14 +219,14 @@ static void test_exhaustive_ecmult(const secp256k1_ge *group, const secp256k1_ge
219219
/* Test secp256k1_ecmult_const_xonly with all curve X coordinates, and xd=NULL. */
220220
ret = secp256k1_ecmult_const_xonly(&tmpf, &group[i].x, NULL, &ng, 0);
221221
CHECK(ret);
222-
CHECK(secp256k1_fe_equal_var(&tmpf, &group[(i * j) % EXHAUSTIVE_TEST_ORDER].x));
222+
CHECK(secp256k1_fe_equal(&tmpf, &group[(i * j) % EXHAUSTIVE_TEST_ORDER].x));
223223

224224
/* Test secp256k1_ecmult_const_xonly with all curve X coordinates, with random xd. */
225225
random_fe_non_zero(&xd);
226226
secp256k1_fe_mul(&xn, &xd, &group[i].x);
227227
ret = secp256k1_ecmult_const_xonly(&tmpf, &xn, &xd, &ng, 0);
228228
CHECK(ret);
229-
CHECK(secp256k1_fe_equal_var(&tmpf, &group[(i * j) % EXHAUSTIVE_TEST_ORDER].x));
229+
CHECK(secp256k1_fe_equal(&tmpf, &group[(i * j) % EXHAUSTIVE_TEST_ORDER].x));
230230
}
231231
}
232232
}
@@ -475,8 +475,8 @@ int main(int argc, char** argv) {
475475

476476
CHECK(group[i].infinity == 0);
477477
CHECK(generated.infinity == 0);
478-
CHECK(secp256k1_fe_equal_var(&generated.x, &group[i].x));
479-
CHECK(secp256k1_fe_equal_var(&generated.y, &group[i].y));
478+
CHECK(secp256k1_fe_equal(&generated.x, &group[i].x));
479+
CHECK(secp256k1_fe_equal(&generated.y, &group[i].y));
480480
}
481481
}
482482

‎src/util.h

-8
Original file line numberDiff line numberDiff line change
@@ -152,14 +152,6 @@ static SECP256K1_INLINE void *checked_malloc(const secp256k1_callback* cb, size_
152152
return ret;
153153
}
154154

155-
static SECP256K1_INLINE void *checked_realloc(const secp256k1_callback* cb, void *ptr, size_t size) {
156-
void *ret = realloc(ptr, size);
157-
if (ret == NULL) {
158-
secp256k1_callback_call(cb, "Out of memory");
159-
}
160-
return ret;
161-
}
162-
163155
#if defined(__BIGGEST_ALIGNMENT__)
164156
#define ALIGNMENT __BIGGEST_ALIGNMENT__
165157
#else

0 commit comments

Comments
 (0)
Please sign in to comment.