This commit is contained in:
Hennadii Stepanov 2025-04-29 11:54:32 +02:00 committed by GitHub
commit c73e7d0d79
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
39 changed files with 471 additions and 400 deletions

View file

@ -29,6 +29,8 @@ env:
BENCH: yes BENCH: yes
SECP256K1_BENCH_ITERS: 2 SECP256K1_BENCH_ITERS: 2
CTIMETESTS: yes CTIMETESTS: yes
SYMBOL_CHECK: yes
VIRTUAL_ENV: /root/venv
# Compile and run the tests # Compile and run the tests
EXAMPLES: yes EXAMPLES: yes
@ -53,6 +55,7 @@ cat_logs_snippet: &CAT_LOGS
linux_arm64_container_snippet: &LINUX_ARM64_CONTAINER linux_arm64_container_snippet: &LINUX_ARM64_CONTAINER
env_script: env_script:
- export PATH="$VIRTUAL_ENV/bin:$PATH"
- env | tee /tmp/env - env | tee /tmp/env
build_script: build_script:
- DOCKER_BUILDKIT=1 docker build --file "ci/linux-debian.Dockerfile" --tag="ci_secp256k1_arm" - DOCKER_BUILDKIT=1 docker build --file "ci/linux-debian.Dockerfile" --tag="ci_secp256k1_arm"

View file

@ -0,0 +1,34 @@
name: "Print logs"
description: "Print the log files produced by ci/ci.sh"
runs:
using: "composite"
steps:
- shell: bash
run: |
# Print the log files produced by ci/ci.sh
# Helper functions
group() {
title=$1
echo "::group::$title"
}
endgroup() {
echo "::endgroup::"
}
cat_file() {
file=$1
group "$file"
cat "$file"
endgroup
}
# Print all *.log files
shopt -s nullglob
for file in *.log; do
cat_file "$file"
done
# Print environment
group "CI env"
env
endgroup

View file

@ -40,6 +40,7 @@ env:
BENCH: 'yes' BENCH: 'yes'
SECP256K1_BENCH_ITERS: 2 SECP256K1_BENCH_ITERS: 2
CTIMETESTS: 'yes' CTIMETESTS: 'yes'
SYMBOL_CHECK: 'yes'
# Compile and run the examples. # Compile and run the examples.
EXAMPLES: 'yes' EXAMPLES: 'yes'
@ -107,23 +108,9 @@ jobs:
dockerfile: ./ci/linux-debian.Dockerfile dockerfile: ./ci/linux-debian.Dockerfile
tag: linux-debian-image tag: linux-debian-image
- run: cat tests.log || true - name: Print logs
if: ${{ always() }} uses: ./.github/actions/print-logs
- run: cat noverify_tests.log || true if: ${{ !cancelled() }}
if: ${{ always() }}
- run: cat exhaustive_tests.log || true
if: ${{ always() }}
- run: cat ctime_tests.log || true
if: ${{ always() }}
- run: cat bench.log || true
if: ${{ always() }}
- run: cat config.log || true
if: ${{ always() }}
- run: cat test_env.log || true
if: ${{ always() }}
- name: CI env
run: env
if: ${{ always() }}
i686_debian: i686_debian:
name: "i686: Linux (Debian stable)" name: "i686: Linux (Debian stable)"
@ -157,23 +144,9 @@ jobs:
dockerfile: ./ci/linux-debian.Dockerfile dockerfile: ./ci/linux-debian.Dockerfile
tag: linux-debian-image tag: linux-debian-image
- run: cat tests.log || true - name: Print logs
if: ${{ always() }} uses: ./.github/actions/print-logs
- run: cat noverify_tests.log || true if: ${{ !cancelled() }}
if: ${{ always() }}
- run: cat exhaustive_tests.log || true
if: ${{ always() }}
- run: cat ctime_tests.log || true
if: ${{ always() }}
- run: cat bench.log || true
if: ${{ always() }}
- run: cat config.log || true
if: ${{ always() }}
- run: cat test_env.log || true
if: ${{ always() }}
- name: CI env
run: env
if: ${{ always() }}
s390x_debian: s390x_debian:
name: "s390x (big-endian): Linux (Debian stable, QEMU)" name: "s390x (big-endian): Linux (Debian stable, QEMU)"
@ -203,23 +176,10 @@ jobs:
dockerfile: ./ci/linux-debian.Dockerfile dockerfile: ./ci/linux-debian.Dockerfile
tag: linux-debian-image tag: linux-debian-image
- run: cat tests.log || true - name: Print logs
if: ${{ always() }} uses: ./.github/actions/print-logs
- run: cat noverify_tests.log || true if: ${{ !cancelled() }}
if: ${{ always() }}
- run: cat exhaustive_tests.log || true
if: ${{ always() }}
- run: cat ctime_tests.log || true
if: ${{ always() }}
- run: cat bench.log || true
if: ${{ always() }}
- run: cat config.log || true
if: ${{ always() }}
- run: cat test_env.log || true
if: ${{ always() }}
- name: CI env
run: env
if: ${{ always() }}
arm32_debian: arm32_debian:
name: "ARM32: Linux (Debian stable, QEMU)" name: "ARM32: Linux (Debian stable, QEMU)"
@ -257,23 +217,9 @@ jobs:
dockerfile: ./ci/linux-debian.Dockerfile dockerfile: ./ci/linux-debian.Dockerfile
tag: linux-debian-image tag: linux-debian-image
- run: cat tests.log || true - name: Print logs
if: ${{ always() }} uses: ./.github/actions/print-logs
- run: cat noverify_tests.log || true if: ${{ !cancelled() }}
if: ${{ always() }}
- run: cat exhaustive_tests.log || true
if: ${{ always() }}
- run: cat ctime_tests.log || true
if: ${{ always() }}
- run: cat bench.log || true
if: ${{ always() }}
- run: cat config.log || true
if: ${{ always() }}
- run: cat test_env.log || true
if: ${{ always() }}
- name: CI env
run: env
if: ${{ always() }}
arm64_debian: arm64_debian:
name: "ARM64: Linux (Debian stable, QEMU)" name: "ARM64: Linux (Debian stable, QEMU)"
@ -314,23 +260,9 @@ jobs:
dockerfile: ./ci/linux-debian.Dockerfile dockerfile: ./ci/linux-debian.Dockerfile
tag: linux-debian-image tag: linux-debian-image
- run: cat tests.log || true - name: Print logs
if: ${{ always() }} uses: ./.github/actions/print-logs
- run: cat noverify_tests.log || true if: ${{ !cancelled() }}
if: ${{ always() }}
- run: cat exhaustive_tests.log || true
if: ${{ always() }}
- run: cat ctime_tests.log || true
if: ${{ always() }}
- run: cat bench.log || true
if: ${{ always() }}
- run: cat config.log || true
if: ${{ always() }}
- run: cat test_env.log || true
if: ${{ always() }}
- name: CI env
run: env
if: ${{ always() }}
ppc64le_debian: ppc64le_debian:
name: "ppc64le: Linux (Debian stable, QEMU)" name: "ppc64le: Linux (Debian stable, QEMU)"
@ -360,23 +292,10 @@ jobs:
dockerfile: ./ci/linux-debian.Dockerfile dockerfile: ./ci/linux-debian.Dockerfile
tag: linux-debian-image tag: linux-debian-image
- run: cat tests.log || true - name: Print logs
if: ${{ always() }} uses: ./.github/actions/print-logs
- run: cat noverify_tests.log || true if: ${{ !cancelled() }}
if: ${{ always() }}
- run: cat exhaustive_tests.log || true
if: ${{ always() }}
- run: cat ctime_tests.log || true
if: ${{ always() }}
- run: cat bench.log || true
if: ${{ always() }}
- run: cat config.log || true
if: ${{ always() }}
- run: cat test_env.log || true
if: ${{ always() }}
- name: CI env
run: env
if: ${{ always() }}
valgrind_debian: valgrind_debian:
name: "Valgrind (memcheck)" name: "Valgrind (memcheck)"
@ -416,23 +335,9 @@ jobs:
dockerfile: ./ci/linux-debian.Dockerfile dockerfile: ./ci/linux-debian.Dockerfile
tag: linux-debian-image tag: linux-debian-image
- run: cat tests.log || true - name: Print logs
if: ${{ always() }} uses: ./.github/actions/print-logs
- run: cat noverify_tests.log || true if: ${{ !cancelled() }}
if: ${{ always() }}
- run: cat exhaustive_tests.log || true
if: ${{ always() }}
- run: cat ctime_tests.log || true
if: ${{ always() }}
- run: cat bench.log || true
if: ${{ always() }}
- run: cat config.log || true
if: ${{ always() }}
- run: cat test_env.log || true
if: ${{ always() }}
- name: CI env
run: env
if: ${{ always() }}
sanitizers_debian: sanitizers_debian:
name: "UBSan, ASan, LSan" name: "UBSan, ASan, LSan"
@ -461,6 +366,7 @@ jobs:
ASAN_OPTIONS: 'strict_string_checks=1:detect_stack_use_after_return=1:detect_leaks=1' ASAN_OPTIONS: 'strict_string_checks=1:detect_stack_use_after_return=1:detect_leaks=1'
LSAN_OPTIONS: 'use_unaligned=1' LSAN_OPTIONS: 'use_unaligned=1'
SECP256K1_TEST_ITERS: 32 SECP256K1_TEST_ITERS: 32
SYMBOL_CHECK: 'no'
steps: steps:
- name: Checkout - name: Checkout
@ -473,23 +379,9 @@ jobs:
dockerfile: ./ci/linux-debian.Dockerfile dockerfile: ./ci/linux-debian.Dockerfile
tag: linux-debian-image tag: linux-debian-image
- run: cat tests.log || true - name: Print logs
if: ${{ always() }} uses: ./.github/actions/print-logs
- run: cat noverify_tests.log || true if: ${{ !cancelled() }}
if: ${{ always() }}
- run: cat exhaustive_tests.log || true
if: ${{ always() }}
- run: cat ctime_tests.log || true
if: ${{ always() }}
- run: cat bench.log || true
if: ${{ always() }}
- run: cat config.log || true
if: ${{ always() }}
- run: cat test_env.log || true
if: ${{ always() }}
- name: CI env
run: env
if: ${{ always() }}
msan_debian: msan_debian:
name: "MSan" name: "MSan"
@ -525,6 +417,7 @@ jobs:
SECP256K1_TEST_ITERS: 32 SECP256K1_TEST_ITERS: 32
ASM: 'no' ASM: 'no'
WITH_VALGRIND: 'no' WITH_VALGRIND: 'no'
SYMBOL_CHECK: 'no'
steps: steps:
- name: Checkout - name: Checkout
@ -537,23 +430,10 @@ jobs:
dockerfile: ./ci/linux-debian.Dockerfile dockerfile: ./ci/linux-debian.Dockerfile
tag: linux-debian-image tag: linux-debian-image
- run: cat tests.log || true - name: Print logs
if: ${{ always() }} uses: ./.github/actions/print-logs
- run: cat noverify_tests.log || true if: ${{ !cancelled() }}
if: ${{ always() }}
- run: cat exhaustive_tests.log || true
if: ${{ always() }}
- run: cat ctime_tests.log || true
if: ${{ always() }}
- run: cat bench.log || true
if: ${{ always() }}
- run: cat config.log || true
if: ${{ always() }}
- run: cat test_env.log || true
if: ${{ always() }}
- name: CI env
run: env
if: ${{ always() }}
mingw_debian: mingw_debian:
name: ${{ matrix.configuration.job_name }} name: ${{ matrix.configuration.job_name }}
@ -593,23 +473,9 @@ jobs:
dockerfile: ./ci/linux-debian.Dockerfile dockerfile: ./ci/linux-debian.Dockerfile
tag: linux-debian-image tag: linux-debian-image
- run: cat tests.log || true - name: Print logs
if: ${{ always() }} uses: ./.github/actions/print-logs
- run: cat noverify_tests.log || true if: ${{ !cancelled() }}
if: ${{ always() }}
- run: cat exhaustive_tests.log || true
if: ${{ always() }}
- run: cat ctime_tests.log || true
if: ${{ always() }}
- run: cat bench.log || true
if: ${{ always() }}
- run: cat config.log || true
if: ${{ always() }}
- run: cat test_env.log || true
if: ${{ always() }}
- name: CI env
run: env
if: ${{ always() }}
x86_64-macos-native: x86_64-macos-native:
name: "x86_64: macOS Ventura, Valgrind" name: "x86_64: macOS Ventura, Valgrind"
@ -620,6 +486,7 @@ jobs:
CC: 'clang' CC: 'clang'
HOMEBREW_NO_AUTO_UPDATE: 1 HOMEBREW_NO_AUTO_UPDATE: 1
HOMEBREW_NO_INSTALL_CLEANUP: 1 HOMEBREW_NO_INSTALL_CLEANUP: 1
SYMBOL_CHECK: 'no'
strategy: strategy:
fail-fast: false fail-fast: false
@ -652,23 +519,15 @@ jobs:
env: ${{ matrix.env_vars }} env: ${{ matrix.env_vars }}
run: ./ci/ci.sh run: ./ci/ci.sh
- run: cat tests.log || true - name: Symbol check
if: ${{ always() }} run: |
- run: cat noverify_tests.log || true python3 --version
if: ${{ always() }} python3 -m pip install lief
- run: cat exhaustive_tests.log || true python3 ./tools/symbol-check.py .libs/libsecp256k1.dylib
if: ${{ always() }}
- run: cat ctime_tests.log || true - name: Print logs
if: ${{ always() }} uses: ./.github/actions/print-logs
- run: cat bench.log || true if: ${{ !cancelled() }}
if: ${{ always() }}
- run: cat config.log || true
if: ${{ always() }}
- run: cat test_env.log || true
if: ${{ always() }}
- name: CI env
run: env
if: ${{ always() }}
arm64-macos-native: arm64-macos-native:
name: "ARM64: macOS Sonoma" name: "ARM64: macOS Sonoma"
@ -681,6 +540,7 @@ jobs:
HOMEBREW_NO_INSTALL_CLEANUP: 1 HOMEBREW_NO_INSTALL_CLEANUP: 1
WITH_VALGRIND: 'no' WITH_VALGRIND: 'no'
CTIMETESTS: 'no' CTIMETESTS: 'no'
SYMBOL_CHECK: 'no'
strategy: strategy:
fail-fast: false fail-fast: false
@ -708,23 +568,20 @@ jobs:
env: ${{ matrix.env_vars }} env: ${{ matrix.env_vars }}
run: ./ci/ci.sh run: ./ci/ci.sh
- run: cat tests.log || true - name: Symbol check
if: ${{ always() }} env:
- run: cat noverify_tests.log || true VIRTUAL_ENV: '${{ github.workspace }}/venv'
if: ${{ always() }} run: |
- run: cat exhaustive_tests.log || true python3 --version
if: ${{ always() }} python3 -m venv $VIRTUAL_ENV
- run: cat ctime_tests.log || true export PATH="$VIRTUAL_ENV/bin:$PATH"
if: ${{ always() }} python3 -m pip install lief
- run: cat bench.log || true python3 ./tools/symbol-check.py .libs/libsecp256k1.dylib
if: ${{ always() }}
- run: cat config.log || true - name: Print logs
if: ${{ always() }} uses: ./.github/actions/print-logs
- run: cat test_env.log || true if: ${{ !cancelled() }}
if: ${{ always() }}
- name: CI env
run: env
if: ${{ always() }}
win64-native: win64-native:
name: ${{ matrix.configuration.job_name }} name: ${{ matrix.configuration.job_name }}
@ -737,6 +594,7 @@ jobs:
configuration: configuration:
- job_name: 'x64 (MSVC): Windows (VS 2022, shared)' - job_name: 'x64 (MSVC): Windows (VS 2022, shared)'
cmake_options: '-A x64 -DBUILD_SHARED_LIBS=ON' cmake_options: '-A x64 -DBUILD_SHARED_LIBS=ON'
symbol_check: 'true'
- job_name: 'x64 (MSVC): Windows (VS 2022, static)' - job_name: 'x64 (MSVC): Windows (VS 2022, static)'
cmake_options: '-A x64 -DBUILD_SHARED_LIBS=OFF' cmake_options: '-A x64 -DBUILD_SHARED_LIBS=OFF'
- job_name: 'x64 (MSVC): Windows (VS 2022, int128_struct)' - job_name: 'x64 (MSVC): Windows (VS 2022, int128_struct)'
@ -746,6 +604,8 @@ jobs:
cpp_flags: '/DSECP256K1_MSVC_MULH_TEST_OVERRIDE' cpp_flags: '/DSECP256K1_MSVC_MULH_TEST_OVERRIDE'
- job_name: 'x86 (MSVC): Windows (VS 2022)' - job_name: 'x86 (MSVC): Windows (VS 2022)'
cmake_options: '-A Win32' cmake_options: '-A Win32'
- job_name: 'x64 (MSVC): Windows (clang-cl)'
cmake_options: '-T ClangCL'
steps: steps:
- name: Checkout - name: Checkout
@ -763,6 +623,13 @@ jobs:
run: | run: |
cd build/bin/RelWithDebInfo && file *tests.exe bench*.exe libsecp256k1-*.dll || true cd build/bin/RelWithDebInfo && file *tests.exe bench*.exe libsecp256k1-*.dll || true
- name: Symbol check
if: ${{ matrix.configuration.symbol_check }}
run: |
py -3 --version
py -3 -m pip install lief
py -3 .\tools\symbol-check.py build\bin\RelWithDebInfo\libsecp256k1-5.dll
- name: Check - name: Check
run: | run: |
ctest -C RelWithDebInfo --test-dir build -j ([int]$env:NUMBER_OF_PROCESSORS + 1) ctest -C RelWithDebInfo --test-dir build -j ([int]$env:NUMBER_OF_PROCESSORS + 1)
@ -813,23 +680,9 @@ jobs:
dockerfile: ./ci/linux-debian.Dockerfile dockerfile: ./ci/linux-debian.Dockerfile
tag: linux-debian-image tag: linux-debian-image
- run: cat tests.log || true - name: Print logs
if: ${{ always() }} uses: ./.github/actions/print-logs
- run: cat noverify_tests.log || true if: ${{ !cancelled() }}
if: ${{ always() }}
- run: cat exhaustive_tests.log || true
if: ${{ always() }}
- run: cat ctime_tests.log || true
if: ${{ always() }}
- run: cat bench.log || true
if: ${{ always() }}
- run: cat config.log || true
if: ${{ always() }}
- run: cat test_env.log || true
if: ${{ always() }}
- name: CI env
run: env
if: ${{ always() }}
cxx_headers_debian: cxx_headers_debian:
name: "C++ (public headers)" name: "C++ (public headers)"

View file

@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
#### Removed
- Removed previously deprecated function aliases `secp256k1_ec_privkey_negate`, `secp256k1_ec_privkey_tweak_add` and
`secp256k1_ec_privkey_tweak_mul`. Use `secp256k1_ec_seckey_negate`, `secp256k1_ec_seckey_tweak_add` and
`secp256k1_ec_seckey_tweak_mul` instead.
## [0.6.0] - 2024-11-04 ## [0.6.0] - 2024-11-04
#### Added #### Added
@ -162,6 +169,7 @@ This version was in fact never released.
The number was given by the build system since the introduction of autotools in Jan 2014 (ea0fe5a5bf0c04f9cc955b2966b614f5f378c6f6). The number was given by the build system since the introduction of autotools in Jan 2014 (ea0fe5a5bf0c04f9cc955b2966b614f5f378c6f6).
Therefore, this version number does not uniquely identify a set of source files. Therefore, this version number does not uniquely identify a set of source files.
[unreleased]: https://github.com/bitcoin-core/secp256k1/compare/v0.6.0...HEAD
[0.6.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.5.1...v0.6.0 [0.6.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.5.1...v0.6.0
[0.5.1]: https://github.com/bitcoin-core/secp256k1/compare/v0.5.0...v0.5.1 [0.5.1]: https://github.com/bitcoin-core/secp256k1/compare/v0.5.0...v0.5.1
[0.5.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.4.1...v0.5.0 [0.5.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.4.1...v0.5.0

View file

@ -7,7 +7,7 @@ project(libsecp256k1
# The package (a.k.a. release) version is based on semantic versioning 2.0.0 of # The package (a.k.a. release) version is based on semantic versioning 2.0.0 of
# the API. All changes in experimental modules are treated as # the API. All changes in experimental modules are treated as
# backwards-compatible and therefore at most increase the minor version. # backwards-compatible and therefore at most increase the minor version.
VERSION 0.6.0 VERSION 0.6.1
DESCRIPTION "Optimized C library for ECDSA signatures and secret/public key operations on curve secp256k1." DESCRIPTION "Optimized C library for ECDSA signatures and secret/public key operations on curve secp256k1."
HOMEPAGE_URL "https://github.com/bitcoin-core/secp256k1" HOMEPAGE_URL "https://github.com/bitcoin-core/secp256k1"
LANGUAGES C LANGUAGES C
@ -32,7 +32,7 @@ endif()
# All changes in experimental modules are treated as if they don't affect the # All changes in experimental modules are treated as if they don't affect the
# interface and therefore only increase the revision. # interface and therefore only increase the revision.
set(${PROJECT_NAME}_LIB_VERSION_CURRENT 5) set(${PROJECT_NAME}_LIB_VERSION_CURRENT 5)
set(${PROJECT_NAME}_LIB_VERSION_REVISION 0) set(${PROJECT_NAME}_LIB_VERSION_REVISION 1)
set(${PROJECT_NAME}_LIB_VERSION_AGE 0) set(${PROJECT_NAME}_LIB_VERSION_AGE 0)
#============================= #=============================
@ -55,7 +55,7 @@ option(SECP256K1_INSTALL "Enable installation." ${PROJECT_IS_TOP_LEVEL})
## Modules ## Modules
# We declare all options before processing them, to make sure we can express # We declare all options before processing them, to make sure we can express
# dependendencies while processing. # dependencies while processing.
option(SECP256K1_ENABLE_MODULE_ECDH "Enable ECDH module." ON) option(SECP256K1_ENABLE_MODULE_ECDH "Enable ECDH module." ON)
option(SECP256K1_ENABLE_MODULE_RECOVERY "Enable ECDSA pubkey recovery module." OFF) option(SECP256K1_ENABLE_MODULE_RECOVERY "Enable ECDSA pubkey recovery module." OFF)
option(SECP256K1_ENABLE_MODULE_EXTRAKEYS "Enable extrakeys module." ON) option(SECP256K1_ENABLE_MODULE_EXTRAKEYS "Enable extrakeys module." ON)
@ -242,17 +242,21 @@ endif()
include(TryAppendCFlags) include(TryAppendCFlags)
if(MSVC) if(MSVC)
# Keep the following commands ordered lexicographically. # For both cl and clang-cl compilers.
try_append_c_flags(/W3) # Production quality warning level. try_append_c_flags(/W3) # Production quality warning level.
try_append_c_flags(/wd4146) # Disable warning C4146 "unary minus operator applied to unsigned type, result still unsigned".
try_append_c_flags(/wd4244) # Disable warning C4244 "'conversion' conversion from 'type1' to 'type2', possible loss of data".
try_append_c_flags(/wd4267) # Disable warning C4267 "'var' : conversion from 'size_t' to 'type', possible loss of data".
# Eliminate deprecation warnings for the older, less secure functions. # Eliminate deprecation warnings for the older, less secure functions.
add_compile_definitions(_CRT_SECURE_NO_WARNINGS) add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
else()
try_append_c_flags(-Wall) # GCC >= 2.95 and probably many other compilers.
endif()
if(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
# Keep the following commands ordered lexicographically.
try_append_c_flags(/wd4146) # Disable warning C4146 "unary minus operator applied to unsigned type, result still unsigned".
try_append_c_flags(/wd4244) # Disable warning C4244 "'conversion' conversion from 'type1' to 'type2', possible loss of data".
try_append_c_flags(/wd4267) # Disable warning C4267 "'var' : conversion from 'size_t' to 'type', possible loss of data".
else() else()
# Keep the following commands ordered lexicographically. # Keep the following commands ordered lexicographically.
try_append_c_flags(-pedantic) try_append_c_flags(-pedantic)
try_append_c_flags(-Wall) # GCC >= 2.95 and probably many other compilers.
try_append_c_flags(-Wcast-align) # GCC >= 2.95. try_append_c_flags(-Wcast-align) # GCC >= 2.95.
try_append_c_flags(-Wcast-align=strict) # GCC >= 8.0. try_append_c_flags(-Wcast-align=strict) # GCC >= 8.0.
try_append_c_flags(-Wconditional-uninitialized) # Clang >= 3.0 only. try_append_c_flags(-Wconditional-uninitialized) # Clang >= 3.0 only.
@ -267,8 +271,6 @@ else()
try_append_c_flags(-Wundef) try_append_c_flags(-Wundef)
endif() endif()
set(CMAKE_C_VISIBILITY_PRESET hidden)
set(print_msan_notice) set(print_msan_notice)
if(SECP256K1_BUILD_CTIME_TESTS) if(SECP256K1_BUILD_CTIME_TESTS)
include(CheckMemorySanitizer) include(CheckMemorySanitizer)

View file

@ -74,6 +74,7 @@ In addition, libsecp256k1 tries to maintain the following coding conventions:
* User-facing comment lines in headers should be limited to 80 chars if possible. * User-facing comment lines in headers should be limited to 80 chars if possible.
* All identifiers in file scope should start with `secp256k1_`. * All identifiers in file scope should start with `secp256k1_`.
* Avoid trailing whitespace. * Avoid trailing whitespace.
* Use the constants `EXIT_SUCCESS`/`EXIT_FAILURE` (defined in `stdlib.h`) to indicate program execution status for examples and other binaries.
### Tests ### Tests

View file

@ -47,6 +47,7 @@ noinst_HEADERS += src/assumptions.h
noinst_HEADERS += src/checkmem.h noinst_HEADERS += src/checkmem.h
noinst_HEADERS += src/testutil.h noinst_HEADERS += src/testutil.h
noinst_HEADERS += src/util.h noinst_HEADERS += src/util.h
noinst_HEADERS += src/util_local_visibility.h
noinst_HEADERS += src/int128.h noinst_HEADERS += src/int128.h
noinst_HEADERS += src/int128_impl.h noinst_HEADERS += src/int128_impl.h
noinst_HEADERS += src/int128_native.h noinst_HEADERS += src/int128_native.h

View file

@ -61,14 +61,50 @@ Implementation details
* Optional runtime blinding which attempts to frustrate differential power analysis. * Optional runtime blinding which attempts to frustrate differential power analysis.
* The precomputed tables add and eventually subtract points for which no known scalar (secret key) is known, preventing even an attacker with control over the secret key used to control the data internally. * The precomputed tables add and eventually subtract points for which no known scalar (secret key) is known, preventing even an attacker with control over the secret key used to control the data internally.
Obtaining and verifying
-----------------------
The git tag for each release (e.g. `v0.6.0`) is GPG-signed by one of the maintainers.
For a fully verified build of this project, it is recommended to obtain this repository
via git, obtain the GPG keys of the signing maintainer(s), and then verify the release
tag's signature using git.
This can be done with the following steps:
1. Obtain the GPG keys listed in [SECURITY.md](./SECURITY.md).
2. If possible, cross-reference these key IDs with another source controlled by its owner (e.g.
social media, personal website). This is to mitigate the unlikely case that incorrect
content is being presented by this repository.
3. Clone the repository:
```
git clone https://github.com/bitcoin-core/secp256k1
```
4. Check out the latest release tag, e.g.
```
git checkout v0.6.0
```
5. Use git to verify the GPG signature:
```
% git tag -v v0.6.0 | grep -C 3 'Good signature'
gpg: Signature made Mon 04 Nov 2024 12:14:44 PM EST
gpg: using RSA key 4BBB845A6F5A65A69DFAEC234861DBF262123605
gpg: Good signature from "Jonas Nick <jonas@n-ck.net>" [unknown]
gpg: aka "Jonas Nick <jonasd.nick@gmail.com>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
Primary key fingerprint: 36C7 1A37 C9D9 88BD E825 08D9 B1A7 0E4F 8DCD 0366
Subkey fingerprint: 4BBB 845A 6F5A 65A6 9DFA EC23 4861 DBF2 6212 3605
```
Building with Autotools Building with Autotools
----------------------- -----------------------
$ ./autogen.sh $ ./autogen.sh # Generate a ./configure script
$ ./configure $ ./configure # Generate a build system
$ make $ make # Run the actual build process
$ make check # run the test suite $ make check # Run the test suite
$ sudo make install # optional $ sudo make install # Install the library into the system (optional)
To compile optional modules (such as Schnorr signatures), you need to run `./configure` with additional flags (such as `--enable-module-schnorrsig`). Run `./configure --help` to see the full list of available flags. To compile optional modules (such as Schnorr signatures), you need to run `./configure` with additional flags (such as `--enable-module-schnorrsig`). Run `./configure --help` to see the full list of available flags.
@ -79,24 +115,23 @@ To maintain a pristine source tree, CMake encourages to perform an out-of-source
### Building on POSIX systems ### Building on POSIX systems
$ mkdir build && cd build $ cmake -B build # Generate a build system in subdirectory "build"
$ cmake .. $ cmake --build build # Run the actual build process
$ cmake --build . $ ctest --test-dir build # Run the test suite
$ ctest # run the test suite $ sudo cmake --install build # Install the library into the system (optional)
$ sudo cmake --install . # optional
To compile optional modules (such as Schnorr signatures), you need to run `cmake` with additional flags (such as `-DSECP256K1_ENABLE_MODULE_SCHNORRSIG=ON`). Run `cmake .. -LH` to see the full list of available flags. To compile optional modules (such as Schnorr signatures), you need to run `cmake` with additional flags (such as `-DSECP256K1_ENABLE_MODULE_SCHNORRSIG=ON`). Run `cmake -B build -LH` or `ccmake -B build` to see the full list of available flags.
### Cross compiling ### Cross compiling
To alleviate issues with cross compiling, preconfigured toolchain files are available in the `cmake` directory. To alleviate issues with cross compiling, preconfigured toolchain files are available in the `cmake` directory.
For example, to cross compile for Windows: For example, to cross compile for Windows:
$ cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/x86_64-w64-mingw32.toolchain.cmake $ cmake -B build -DCMAKE_TOOLCHAIN_FILE=cmake/x86_64-w64-mingw32.toolchain.cmake
To cross compile for Android with [NDK](https://developer.android.com/ndk/guides/cmake) (using NDK's toolchain file, and assuming the `ANDROID_NDK_ROOT` environment variable has been set): To cross compile for Android with [NDK](https://developer.android.com/ndk/guides/cmake) (using NDK's toolchain file, and assuming the `ANDROID_NDK_ROOT` environment variable has been set):
$ cmake .. -DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK_ROOT}/build/cmake/android.toolchain.cmake" -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=28 $ cmake -B build -DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK_ROOT}/build/cmake/android.toolchain.cmake" -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=28
### Building on Windows ### Building on Windows
@ -106,7 +141,7 @@ The following example assumes using of Visual Studio 2022 and CMake v3.21+.
In "Developer Command Prompt for VS 2022": In "Developer Command Prompt for VS 2022":
>cmake -G "Visual Studio 17 2022" -A x64 -S . -B build >cmake -G "Visual Studio 17 2022" -A x64 -B build
>cmake --build build --config RelWithDebInfo >cmake --build build --config RelWithDebInfo
Usage examples Usage examples

View file

@ -14,7 +14,7 @@ print_environment() {
for var in WERROR_CFLAGS MAKEFLAGS BUILD \ for var in WERROR_CFLAGS MAKEFLAGS BUILD \
ECMULTWINDOW ECMULTGENKB ASM WIDEMUL WITH_VALGRIND EXTRAFLAGS \ ECMULTWINDOW ECMULTGENKB ASM WIDEMUL WITH_VALGRIND EXTRAFLAGS \
EXPERIMENTAL ECDH RECOVERY EXTRAKEYS MUSIG SCHNORRSIG ELLSWIFT \ EXPERIMENTAL ECDH RECOVERY EXTRAKEYS MUSIG SCHNORRSIG ELLSWIFT \
SECP256K1_TEST_ITERS BENCH SECP256K1_BENCH_ITERS CTIMETESTS\ SECP256K1_TEST_ITERS BENCH SECP256K1_BENCH_ITERS CTIMETESTS SYMBOL_CHECK \
EXAMPLES \ EXAMPLES \
HOST WRAPPER_CMD \ HOST WRAPPER_CMD \
CC CFLAGS CPPFLAGS AR NM \ CC CFLAGS CPPFLAGS AR NM \
@ -94,10 +94,10 @@ if [ $build_exit_code -ne 0 ]; then
*snapshot*) *snapshot*)
# Ignore internal compiler errors in gcc-snapshot and clang-snapshot # Ignore internal compiler errors in gcc-snapshot and clang-snapshot
grep -e "internal compiler error:" -e "PLEASE submit a bug report" make.log grep -e "internal compiler error:" -e "PLEASE submit a bug report" make.log
return $?; exit $?
;; ;;
*) *)
return 1; exit 1
;; ;;
esac esac
fi fi
@ -107,6 +107,20 @@ file *tests* || true
file bench* || true file bench* || true
file .libs/* || true file .libs/* || true
if [ "$SYMBOL_CHECK" = "yes" ]
then
python3 --version
case "$HOST" in
*mingw*)
ls -l .libs
python3 ./tools/symbol-check.py .libs/libsecp256k1-5.dll
;;
*)
python3 ./tools/symbol-check.py .libs/libsecp256k1.so
;;
esac
fi
# This tells `make check` to wrap test invocations. # This tells `make check` to wrap test invocations.
export LOG_COMPILER="$WRAPPER_CMD" export LOG_COMPILER="$WRAPPER_CMD"

View file

@ -32,7 +32,7 @@ RUN apt-get update && apt-get install --no-install-recommends -y \
gcc-powerpc64le-linux-gnu libc6-dev-ppc64el-cross libc6-dbg:ppc64el \ gcc-powerpc64le-linux-gnu libc6-dev-ppc64el-cross libc6-dbg:ppc64el \
gcc-mingw-w64-x86-64-win32 wine64 wine \ gcc-mingw-w64-x86-64-win32 wine64 wine \
gcc-mingw-w64-i686-win32 wine32 \ gcc-mingw-w64-i686-win32 wine32 \
python3 && \ python3-full && \
if ! ( dpkg --print-architecture | grep --quiet "arm64" ) ; then \ if ! ( dpkg --print-architecture | grep --quiet "arm64" ) ; then \
apt-get install --no-install-recommends -y \ apt-get install --no-install-recommends -y \
gcc-aarch64-linux-gnu libc6-dev-arm64-cross libc6-dbg:arm64 ;\ gcc-aarch64-linux-gnu libc6-dev-arm64-cross libc6-dbg:arm64 ;\
@ -77,3 +77,7 @@ RUN \
apt-get autoremove -y wget && \ apt-get autoremove -y wget && \
apt-get clean && rm -rf /var/lib/apt/lists/* apt-get clean && rm -rf /var/lib/apt/lists/*
ENV VIRTUAL_ENV=/root/venv
RUN python3 -m venv $VIRTUAL_ENV
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
RUN pip install lief

View file

@ -5,8 +5,8 @@ AC_PREREQ([2.60])
# backwards-compatible and therefore at most increase the minor version. # backwards-compatible and therefore at most increase the minor version.
define(_PKG_VERSION_MAJOR, 0) define(_PKG_VERSION_MAJOR, 0)
define(_PKG_VERSION_MINOR, 6) define(_PKG_VERSION_MINOR, 6)
define(_PKG_VERSION_PATCH, 0) define(_PKG_VERSION_PATCH, 1)
define(_PKG_VERSION_IS_RELEASE, true) define(_PKG_VERSION_IS_RELEASE, false)
# The library version is based on libtool versioning of the ABI. The set of # The library version is based on libtool versioning of the ABI. The set of
# rules for updating the version can be found here: # rules for updating the version can be found here:
@ -14,7 +14,7 @@ define(_PKG_VERSION_IS_RELEASE, true)
# All changes in experimental modules are treated as if they don't affect the # All changes in experimental modules are treated as if they don't affect the
# interface and therefore only increase the revision. # interface and therefore only increase the revision.
define(_LIB_VERSION_CURRENT, 5) define(_LIB_VERSION_CURRENT, 5)
define(_LIB_VERSION_REVISION, 0) define(_LIB_VERSION_REVISION, 1)
define(_LIB_VERSION_AGE, 0) define(_LIB_VERSION_AGE, 0)
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]) 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])
@ -111,7 +111,6 @@ AC_DEFUN([SECP_TRY_APPEND_DEFAULT_CFLAGS], [
SECP_TRY_APPEND_CFLAGS([-Wcast-align=strict], $1) # GCC >= 8.0 SECP_TRY_APPEND_CFLAGS([-Wcast-align=strict], $1) # GCC >= 8.0
SECP_TRY_APPEND_CFLAGS([-Wconditional-uninitialized], $1) # Clang >= 3.0 only SECP_TRY_APPEND_CFLAGS([-Wconditional-uninitialized], $1) # Clang >= 3.0 only
SECP_TRY_APPEND_CFLAGS([-Wreserved-identifier], $1) # Clang >= 13.0 only SECP_TRY_APPEND_CFLAGS([-Wreserved-identifier], $1) # Clang >= 13.0 only
SECP_TRY_APPEND_CFLAGS([-fvisibility=hidden], $1) # GCC >= 4.0
CFLAGS="$SECP_TRY_APPEND_DEFAULT_CFLAGS_saved_CFLAGS" CFLAGS="$SECP_TRY_APPEND_DEFAULT_CFLAGS_saved_CFLAGS"
fi fi
@ -254,8 +253,8 @@ fi
print_msan_notice=no print_msan_notice=no
if test x"$enable_ctime_tests" = x"yes"; then if test x"$enable_ctime_tests" = x"yes"; then
SECP_MSAN_CHECK SECP_MSAN_CHECK
# MSan on Clang >=16 reports unitialized memory in function parameters and return values, even if # MSan on Clang >=16 reports uninitialized memory in function parameters and return values, even if
# the uninitalized variable is never actually "used". This is called "eager" checking, and it's # the uninitialized variable is never actually "used". This is called "eager" checking, and it's
# sounds like good idea for normal use of MSan. However, it yields many false positives in the # sounds like good idea for normal use of MSan. However, it yields many false positives in the
# ctime_tests because many return values depend on secret (i.e., "uninitialized") values, and # ctime_tests because many return values depend on secret (i.e., "uninitialized") values, and
# we're only interested in detecting branches (which count as "uses") on secret data. # we're only interested in detecting branches (which count as "uses") on secret data.
@ -477,6 +476,7 @@ echo "Build Options:"
echo " with external callbacks = $enable_external_default_callbacks" echo " with external callbacks = $enable_external_default_callbacks"
echo " with benchmarks = $enable_benchmark" echo " with benchmarks = $enable_benchmark"
echo " with tests = $enable_tests" echo " with tests = $enable_tests"
echo " with exhaustive tests = $enable_exhaustive_tests"
echo " with ctime tests = $enable_ctime_tests" echo " with ctime tests = $enable_ctime_tests"
echo " with coverage = $enable_coverage" echo " with coverage = $enable_coverage"
echo " with examples = $enable_examples" echo " with examples = $enable_examples"

View file

@ -8,6 +8,7 @@
*************************************************************************/ *************************************************************************/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
@ -33,7 +34,7 @@ int main(void) {
secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
if (!fill_random(randomize, sizeof(randomize))) { if (!fill_random(randomize, sizeof(randomize))) {
printf("Failed to generate randomness\n"); printf("Failed to generate randomness\n");
return 1; return EXIT_FAILURE;
} }
/* Randomizing the context is recommended to protect against side-channel /* Randomizing the context is recommended to protect against side-channel
* leakage See `secp256k1_context_randomize` in secp256k1.h for more * leakage See `secp256k1_context_randomize` in secp256k1.h for more
@ -44,14 +45,14 @@ int main(void) {
/*** Key Generation ***/ /*** Key Generation ***/
if (!fill_random(seckey1, sizeof(seckey1)) || !fill_random(seckey2, sizeof(seckey2))) { if (!fill_random(seckey1, sizeof(seckey1)) || !fill_random(seckey2, sizeof(seckey2))) {
printf("Failed to generate randomness\n"); printf("Failed to generate randomness\n");
return 1; return EXIT_FAILURE;
} }
/* If the secret key is zero or out of range (greater than secp256k1's /* If the secret key is zero or out of range (greater than secp256k1's
* order), we fail. Note that the probability of this occurring is negligible * order), we fail. Note that the probability of this occurring is negligible
* with a properly functioning random number generator. */ * with a properly functioning random number generator. */
if (!secp256k1_ec_seckey_verify(ctx, seckey1) || !secp256k1_ec_seckey_verify(ctx, seckey2)) { if (!secp256k1_ec_seckey_verify(ctx, seckey1) || !secp256k1_ec_seckey_verify(ctx, seckey2)) {
printf("Generated secret key is invalid. This indicates an issue with the random number generator.\n"); printf("Generated secret key is invalid. This indicates an issue with the random number generator.\n");
return 1; return EXIT_FAILURE;
} }
/* Public key creation using a valid context with a verified secret key should never fail */ /* Public key creation using a valid context with a verified secret key should never fail */
@ -116,5 +117,5 @@ int main(void) {
secure_erase(shared_secret1, sizeof(shared_secret1)); secure_erase(shared_secret1, sizeof(shared_secret1));
secure_erase(shared_secret2, sizeof(shared_secret2)); secure_erase(shared_secret2, sizeof(shared_secret2));
return 0; return EXIT_SUCCESS;
} }

View file

@ -8,6 +8,7 @@
*************************************************************************/ *************************************************************************/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
@ -40,7 +41,7 @@ int main(void) {
secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
if (!fill_random(randomize, sizeof(randomize))) { if (!fill_random(randomize, sizeof(randomize))) {
printf("Failed to generate randomness\n"); printf("Failed to generate randomness\n");
return 1; return EXIT_FAILURE;
} }
/* Randomizing the context is recommended to protect against side-channel /* Randomizing the context is recommended to protect against side-channel
* leakage See `secp256k1_context_randomize` in secp256k1.h for more * leakage See `secp256k1_context_randomize` in secp256k1.h for more
@ -51,14 +52,14 @@ int main(void) {
/*** Key Generation ***/ /*** Key Generation ***/
if (!fill_random(seckey, sizeof(seckey))) { if (!fill_random(seckey, sizeof(seckey))) {
printf("Failed to generate randomness\n"); printf("Failed to generate randomness\n");
return 1; return EXIT_FAILURE;
} }
/* If the secret key is zero or out of range (greater than secp256k1's /* If the secret key is zero or out of range (greater than secp256k1's
* order), we fail. Note that the probability of this occurring is negligible * order), we fail. Note that the probability of this occurring is negligible
* with a properly functioning random number generator. */ * with a properly functioning random number generator. */
if (!secp256k1_ec_seckey_verify(ctx, seckey)) { if (!secp256k1_ec_seckey_verify(ctx, seckey)) {
printf("Generated secret key is invalid. This indicates an issue with the random number generator.\n"); printf("Generated secret key is invalid. This indicates an issue with the random number generator.\n");
return 1; return EXIT_FAILURE;
} }
/* Public key creation using a valid context with a verified secret key should never fail */ /* Public key creation using a valid context with a verified secret key should never fail */
@ -92,13 +93,13 @@ int main(void) {
/* Deserialize the signature. This will return 0 if the signature can't be parsed correctly. */ /* Deserialize the signature. This will return 0 if the signature can't be parsed correctly. */
if (!secp256k1_ecdsa_signature_parse_compact(ctx, &sig, serialized_signature)) { if (!secp256k1_ecdsa_signature_parse_compact(ctx, &sig, serialized_signature)) {
printf("Failed parsing the signature\n"); printf("Failed parsing the signature\n");
return 1; return EXIT_FAILURE;
} }
/* Deserialize the public key. This will return 0 if the public key can't be parsed correctly. */ /* Deserialize the public key. This will return 0 if the public key can't be parsed correctly. */
if (!secp256k1_ec_pubkey_parse(ctx, &pubkey, compressed_pubkey, sizeof(compressed_pubkey))) { if (!secp256k1_ec_pubkey_parse(ctx, &pubkey, compressed_pubkey, sizeof(compressed_pubkey))) {
printf("Failed parsing the public key\n"); printf("Failed parsing the public key\n");
return 1; return EXIT_FAILURE;
} }
/* Verify a signature. This will return 1 if it's valid and 0 if it's not. */ /* Verify a signature. This will return 1 if it's valid and 0 if it's not. */
@ -133,5 +134,5 @@ int main(void) {
* will remove any writes that aren't used. */ * will remove any writes that aren't used. */
secure_erase(seckey, sizeof(seckey)); secure_erase(seckey, sizeof(seckey));
return 0; return EXIT_SUCCESS;
} }

View file

@ -13,6 +13,7 @@
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
@ -38,7 +39,7 @@ int main(void) {
ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
if (!fill_random(randomize, sizeof(randomize))) { if (!fill_random(randomize, sizeof(randomize))) {
printf("Failed to generate randomness\n"); printf("Failed to generate randomness\n");
return 1; return EXIT_FAILURE;
} }
/* Randomizing the context is recommended to protect against side-channel /* Randomizing the context is recommended to protect against side-channel
* leakage. See `secp256k1_context_randomize` in secp256k1.h for more * leakage. See `secp256k1_context_randomize` in secp256k1.h for more
@ -49,14 +50,14 @@ int main(void) {
/*** Generate secret keys ***/ /*** Generate secret keys ***/
if (!fill_random(seckey1, sizeof(seckey1)) || !fill_random(seckey2, sizeof(seckey2))) { if (!fill_random(seckey1, sizeof(seckey1)) || !fill_random(seckey2, sizeof(seckey2))) {
printf("Failed to generate randomness\n"); printf("Failed to generate randomness\n");
return 1; return EXIT_FAILURE;
} }
/* If the secret key is zero or out of range (greater than secp256k1's /* If the secret key is zero or out of range (greater than secp256k1's
* order), we fail. Note that the probability of this occurring is negligible * order), we fail. Note that the probability of this occurring is negligible
* with a properly functioning random number generator. */ * with a properly functioning random number generator. */
if (!secp256k1_ec_seckey_verify(ctx, seckey1) || !secp256k1_ec_seckey_verify(ctx, seckey2)) { if (!secp256k1_ec_seckey_verify(ctx, seckey1) || !secp256k1_ec_seckey_verify(ctx, seckey2)) {
printf("Generated secret key is invalid. This indicates an issue with the random number generator.\n"); printf("Generated secret key is invalid. This indicates an issue with the random number generator.\n");
return 1; return EXIT_FAILURE;
} }
/* Generate ElligatorSwift public keys. This should never fail with valid context and /* Generate ElligatorSwift public keys. This should never fail with valid context and
@ -64,7 +65,7 @@ int main(void) {
optional, but recommended. */ optional, but recommended. */
if (!fill_random(auxrand1, sizeof(auxrand1)) || !fill_random(auxrand2, sizeof(auxrand2))) { if (!fill_random(auxrand1, sizeof(auxrand1)) || !fill_random(auxrand2, sizeof(auxrand2))) {
printf("Failed to generate randomness\n"); printf("Failed to generate randomness\n");
return 1; return EXIT_FAILURE;
} }
return_val = secp256k1_ellswift_create(ctx, ellswift_pubkey1, seckey1, auxrand1); return_val = secp256k1_ellswift_create(ctx, ellswift_pubkey1, seckey1, auxrand1);
assert(return_val); assert(return_val);
@ -117,5 +118,5 @@ int main(void) {
secure_erase(shared_secret1, sizeof(shared_secret1)); secure_erase(shared_secret1, sizeof(shared_secret1));
secure_erase(shared_secret2, sizeof(shared_secret2)); secure_erase(shared_secret2, sizeof(shared_secret2));
return 0; return EXIT_SUCCESS;
} }

View file

@ -12,6 +12,7 @@
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
@ -193,7 +194,7 @@ int main(void) {
for (i = 0; i < N_SIGNERS; i++) { for (i = 0; i < N_SIGNERS; i++) {
if (!create_keypair(ctx, &signer_secrets[i], &signers[i])) { if (!create_keypair(ctx, &signer_secrets[i], &signers[i])) {
printf("FAILED\n"); printf("FAILED\n");
return 1; return EXIT_FAILURE;
} }
pubkeys_ptr[i] = &signers[i].pubkey; pubkeys_ptr[i] = &signers[i].pubkey;
} }
@ -208,7 +209,7 @@ int main(void) {
fflush(stdout); fflush(stdout);
if (!secp256k1_ec_pubkey_sort(ctx, pubkeys_ptr, N_SIGNERS)) { if (!secp256k1_ec_pubkey_sort(ctx, pubkeys_ptr, N_SIGNERS)) {
printf("FAILED\n"); printf("FAILED\n");
return 1; return EXIT_FAILURE;
} }
printf("ok\n"); printf("ok\n");
@ -219,7 +220,7 @@ int main(void) {
* while providing a non-NULL agg_pk argument. */ * while providing a non-NULL agg_pk argument. */
if (!secp256k1_musig_pubkey_agg(ctx, NULL, &cache, pubkeys_ptr, N_SIGNERS)) { if (!secp256k1_musig_pubkey_agg(ctx, NULL, &cache, pubkeys_ptr, N_SIGNERS)) {
printf("FAILED\n"); printf("FAILED\n");
return 1; return EXIT_FAILURE;
} }
printf("ok\n"); printf("ok\n");
printf("Tweaking................"); printf("Tweaking................");
@ -227,21 +228,21 @@ int main(void) {
/* Optionally tweak the aggregate key */ /* Optionally tweak the aggregate key */
if (!tweak(ctx, &agg_pk, &cache)) { if (!tweak(ctx, &agg_pk, &cache)) {
printf("FAILED\n"); printf("FAILED\n");
return 1; return EXIT_FAILURE;
} }
printf("ok\n"); printf("ok\n");
printf("Signing message........."); printf("Signing message.........");
fflush(stdout); fflush(stdout);
if (!sign(ctx, signer_secrets, signers, &cache, msg, sig)) { if (!sign(ctx, signer_secrets, signers, &cache, msg, sig)) {
printf("FAILED\n"); printf("FAILED\n");
return 1; return EXIT_FAILURE;
} }
printf("ok\n"); printf("ok\n");
printf("Verifying signature....."); printf("Verifying signature.....");
fflush(stdout); fflush(stdout);
if (!secp256k1_schnorrsig_verify(ctx, sig, msg, 32, &agg_pk)) { if (!secp256k1_schnorrsig_verify(ctx, sig, msg, 32, &agg_pk)) {
printf("FAILED\n"); printf("FAILED\n");
return 1; return EXIT_FAILURE;
} }
printf("ok\n"); printf("ok\n");
@ -256,5 +257,5 @@ int main(void) {
secure_erase(&signer_secrets[i], sizeof(signer_secrets[i])); secure_erase(&signer_secrets[i], sizeof(signer_secrets[i]));
} }
secp256k1_context_destroy(ctx); secp256k1_context_destroy(ctx);
return 0; return EXIT_SUCCESS;
} }

View file

@ -8,6 +8,7 @@
*************************************************************************/ *************************************************************************/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
@ -34,7 +35,7 @@ int main(void) {
secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
if (!fill_random(randomize, sizeof(randomize))) { if (!fill_random(randomize, sizeof(randomize))) {
printf("Failed to generate randomness\n"); printf("Failed to generate randomness\n");
return 1; return EXIT_FAILURE;
} }
/* Randomizing the context is recommended to protect against side-channel /* Randomizing the context is recommended to protect against side-channel
* leakage See `secp256k1_context_randomize` in secp256k1.h for more * leakage See `secp256k1_context_randomize` in secp256k1.h for more
@ -45,7 +46,7 @@ int main(void) {
/*** Key Generation ***/ /*** Key Generation ***/
if (!fill_random(seckey, sizeof(seckey))) { if (!fill_random(seckey, sizeof(seckey))) {
printf("Failed to generate randomness\n"); printf("Failed to generate randomness\n");
return 1; return EXIT_FAILURE;
} }
/* Try to create a keypair with a valid context. This only fails if the /* Try to create a keypair with a valid context. This only fails if the
* secret key is zero or out of range (greater than secp256k1's order). Note * secret key is zero or out of range (greater than secp256k1's order). Note
@ -53,7 +54,7 @@ int main(void) {
* functioning random number generator. */ * functioning random number generator. */
if (!secp256k1_keypair_create(ctx, &keypair, seckey)) { if (!secp256k1_keypair_create(ctx, &keypair, seckey)) {
printf("Generated secret key is invalid. This indicates an issue with the random number generator.\n"); printf("Generated secret key is invalid. This indicates an issue with the random number generator.\n");
return 1; return EXIT_FAILURE;
} }
/* Extract the X-only public key from the keypair. We pass NULL for /* Extract the X-only public key from the keypair. We pass NULL for
@ -90,7 +91,7 @@ int main(void) {
/* Generate 32 bytes of randomness to use with BIP-340 schnorr signing. */ /* Generate 32 bytes of randomness to use with BIP-340 schnorr signing. */
if (!fill_random(auxiliary_rand, sizeof(auxiliary_rand))) { if (!fill_random(auxiliary_rand, sizeof(auxiliary_rand))) {
printf("Failed to generate randomness\n"); printf("Failed to generate randomness\n");
return 1; return EXIT_FAILURE;
} }
/* Generate a Schnorr signature. /* Generate a Schnorr signature.
@ -110,7 +111,7 @@ int main(void) {
* be parsed correctly */ * be parsed correctly */
if (!secp256k1_xonly_pubkey_parse(ctx, &pubkey, serialized_pubkey)) { if (!secp256k1_xonly_pubkey_parse(ctx, &pubkey, serialized_pubkey)) {
printf("Failed parsing the public key\n"); printf("Failed parsing the public key\n");
return 1; return EXIT_FAILURE;
} }
/* Compute the tagged hash on the received messages using the same tag as the signer. */ /* Compute the tagged hash on the received messages using the same tag as the signer. */
@ -149,5 +150,5 @@ int main(void) {
* Here we are preventing these writes from being optimized out, as any good compiler * Here we are preventing these writes from being optimized out, as any good compiler
* will remove any writes that aren't used. */ * will remove any writes that aren't used. */
secure_erase(seckey, sizeof(seckey)); secure_erase(seckey, sizeof(seckey));
return 0; return EXIT_SUCCESS;
} }

View file

@ -230,10 +230,10 @@ typedef int (*secp256k1_nonce_function)(
* *
* It is highly recommended to call secp256k1_selftest before using this context. * It is highly recommended to call secp256k1_selftest before using this context.
*/ */
SECP256K1_API const secp256k1_context *secp256k1_context_static; SECP256K1_API const secp256k1_context * const secp256k1_context_static;
/** Deprecated alias for secp256k1_context_static. */ /** Deprecated alias for secp256k1_context_static. */
SECP256K1_API const secp256k1_context *secp256k1_context_no_precomp SECP256K1_API const secp256k1_context * const secp256k1_context_no_precomp
SECP256K1_DEPRECATED("Use secp256k1_context_static instead"); SECP256K1_DEPRECATED("Use secp256k1_context_static instead");
/** Perform basic self tests (to be used in conjunction with secp256k1_context_static) /** Perform basic self tests (to be used in conjunction with secp256k1_context_static)
@ -701,21 +701,13 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_negate(
unsigned char *seckey unsigned char *seckey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
/** Same as secp256k1_ec_seckey_negate, but DEPRECATED. Will be removed in
* future versions. */
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_negate(
const secp256k1_context *ctx,
unsigned char *seckey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2)
SECP256K1_DEPRECATED("Use secp256k1_ec_seckey_negate instead");
/** Negates a public key in place. /** Negates a public key in place.
* *
* Returns: 1 always * Returns: 1 always
* Args: ctx: pointer to a context object * Args: ctx: pointer to a context object
* In/Out: pubkey: pointer to the public key to be negated. * In/Out: pubkey: pointer to the public key to be negated.
*/ */
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_negate( SECP256K1_API int secp256k1_ec_pubkey_negate(
const secp256k1_context *ctx, const secp256k1_context *ctx,
secp256k1_pubkey *pubkey secp256k1_pubkey *pubkey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
@ -741,15 +733,6 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_add(
const unsigned char *tweak32 const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Same as secp256k1_ec_seckey_tweak_add, but DEPRECATED. Will be removed in
* future versions. */
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add(
const secp256k1_context *ctx,
unsigned char *seckey,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
SECP256K1_DEPRECATED("Use secp256k1_ec_seckey_tweak_add instead");
/** Tweak a public key by adding tweak times the generator to it. /** Tweak a public key by adding tweak times the generator to it.
* *
* Returns: 0 if the arguments are invalid or the resulting public key would be * Returns: 0 if the arguments are invalid or the resulting public key would be
@ -788,15 +771,6 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_mul(
const unsigned char *tweak32 const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Same as secp256k1_ec_seckey_tweak_mul, but DEPRECATED. Will be removed in
* future versions. */
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul(
const secp256k1_context *ctx,
unsigned char *seckey,
const unsigned char *tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
SECP256K1_DEPRECATED("Use secp256k1_ec_seckey_tweak_mul instead");
/** Tweak a public key by multiplying it by a tweak value. /** Tweak a public key by multiplying it by a tweak value.
* *
* Returns: 0 if the arguments are invalid. 1 otherwise. * Returns: 0 if the arguments are invalid. 1 otherwise.
@ -883,7 +857,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_combine(
* msg: pointer to an array containing the message * msg: pointer to an array containing the message
* msglen: length of the message array * msglen: length of the message array
*/ */
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_tagged_sha256( SECP256K1_API int secp256k1_tagged_sha256(
const secp256k1_context *ctx, const secp256k1_context *ctx,
unsigned char *hash32, unsigned char *hash32,
const unsigned char *tag, const unsigned char *tag,

View file

@ -90,7 +90,7 @@ SECP256K1_API int secp256k1_xonly_pubkey_cmp(
* the negation of the pubkey and set to 0 otherwise. * the negation of the pubkey and set to 0 otherwise.
* In: pubkey: pointer to a public key that is converted. * In: pubkey: pointer to a public key that is converted.
*/ */
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_from_pubkey( SECP256K1_API int secp256k1_xonly_pubkey_from_pubkey(
const secp256k1_context *ctx, const secp256k1_context *ctx,
secp256k1_xonly_pubkey *xonly_pubkey, secp256k1_xonly_pubkey *xonly_pubkey,
int *pk_parity, int *pk_parity,
@ -179,7 +179,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_create(
* Out: seckey: pointer to a 32-byte buffer for the secret key. * Out: seckey: pointer to a 32-byte buffer for the secret key.
* In: keypair: pointer to a keypair. * In: keypair: pointer to a keypair.
*/ */
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_sec( SECP256K1_API int secp256k1_keypair_sec(
const secp256k1_context *ctx, const secp256k1_context *ctx,
unsigned char *seckey, unsigned char *seckey,
const secp256k1_keypair *keypair const secp256k1_keypair *keypair
@ -192,7 +192,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_sec(
* Out: pubkey: pointer to a pubkey object, set to the keypair public key. * Out: pubkey: pointer to a pubkey object, set to the keypair public key.
* In: keypair: pointer to a keypair. * In: keypair: pointer to a keypair.
*/ */
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_pub( SECP256K1_API int secp256k1_keypair_pub(
const secp256k1_context *ctx, const secp256k1_context *ctx,
secp256k1_pubkey *pubkey, secp256k1_pubkey *pubkey,
const secp256k1_keypair *keypair const secp256k1_keypair *keypair
@ -211,7 +211,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_pub(
* pk_parity argument of secp256k1_xonly_pubkey_from_pubkey. * pk_parity argument of secp256k1_xonly_pubkey_from_pubkey.
* In: keypair: pointer to a keypair. * In: keypair: pointer to a keypair.
*/ */
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_pub( SECP256K1_API int secp256k1_keypair_xonly_pub(
const secp256k1_context *ctx, const secp256k1_context *ctx,
secp256k1_xonly_pubkey *pubkey, secp256k1_xonly_pubkey *pubkey,
int *pk_parity, int *pk_parity,

View file

@ -5,6 +5,7 @@
***********************************************************************/ ***********************************************************************/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include "../include/secp256k1.h" #include "../include/secp256k1.h"
@ -15,18 +16,22 @@ static void help(int default_iters) {
printf("Benchmarks the following algorithms:\n"); printf("Benchmarks the following algorithms:\n");
printf(" - ECDSA signing/verification\n"); printf(" - ECDSA signing/verification\n");
#ifdef ENABLE_MODULE_ECDH
printf(" - ECDH key exchange (optional module)\n");
#endif
#ifdef ENABLE_MODULE_RECOVERY #ifdef ENABLE_MODULE_RECOVERY
printf(" - Public key recovery (optional module)\n"); printf(" - Public key recovery (optional module)\n");
#endif #endif
#ifdef ENABLE_MODULE_ECDH
printf(" - ECDH key exchange (optional module)\n");
#endif
#ifdef ENABLE_MODULE_SCHNORRSIG #ifdef ENABLE_MODULE_SCHNORRSIG
printf(" - Schnorr signatures (optional module)\n"); printf(" - Schnorr signatures (optional module)\n");
#endif #endif
#ifdef ENABLE_MODULE_ELLSWIFT
printf(" - ElligatorSwift (optional module)\n");
#endif
printf("\n"); printf("\n");
printf("The default number of iterations for each benchmark is %d. This can be\n", default_iters); printf("The default number of iterations for each benchmark is %d. This can be\n", default_iters);
printf("customized using the SECP256K1_BENCH_ITERS environment variable.\n"); printf("customized using the SECP256K1_BENCH_ITERS environment variable.\n");
@ -188,11 +193,11 @@ int main(int argc, char** argv) {
|| have_flag(argc, argv, "--help") || have_flag(argc, argv, "--help")
|| have_flag(argc, argv, "help")) { || have_flag(argc, argv, "help")) {
help(default_iters); help(default_iters);
return 0; return EXIT_SUCCESS;
} else if (invalid_args) { } else if (invalid_args) {
fprintf(stderr, "./bench: unrecognized argument.\n\n"); fprintf(stderr, "./bench: unrecognized argument.\n\n");
help(default_iters); help(default_iters);
return 1; return EXIT_FAILURE;
} }
} }
@ -201,7 +206,7 @@ int main(int argc, char** argv) {
if (have_flag(argc, argv, "ecdh")) { if (have_flag(argc, argv, "ecdh")) {
fprintf(stderr, "./bench: ECDH module not enabled.\n"); fprintf(stderr, "./bench: ECDH module not enabled.\n");
fprintf(stderr, "Use ./configure --enable-module-ecdh.\n\n"); fprintf(stderr, "Use ./configure --enable-module-ecdh.\n\n");
return 1; return EXIT_FAILURE;
} }
#endif #endif
@ -209,7 +214,7 @@ int main(int argc, char** argv) {
if (have_flag(argc, argv, "recover") || have_flag(argc, argv, "ecdsa_recover")) { if (have_flag(argc, argv, "recover") || have_flag(argc, argv, "ecdsa_recover")) {
fprintf(stderr, "./bench: Public key recovery module not enabled.\n"); fprintf(stderr, "./bench: Public key recovery module not enabled.\n");
fprintf(stderr, "Use ./configure --enable-module-recovery.\n\n"); fprintf(stderr, "Use ./configure --enable-module-recovery.\n\n");
return 1; return EXIT_FAILURE;
} }
#endif #endif
@ -217,7 +222,7 @@ int main(int argc, char** argv) {
if (have_flag(argc, argv, "schnorrsig") || have_flag(argc, argv, "schnorrsig_sign") || have_flag(argc, argv, "schnorrsig_verify")) { if (have_flag(argc, argv, "schnorrsig") || have_flag(argc, argv, "schnorrsig_sign") || have_flag(argc, argv, "schnorrsig_verify")) {
fprintf(stderr, "./bench: Schnorr signatures module not enabled.\n"); fprintf(stderr, "./bench: Schnorr signatures module not enabled.\n");
fprintf(stderr, "Use ./configure --enable-module-schnorrsig.\n\n"); fprintf(stderr, "Use ./configure --enable-module-schnorrsig.\n\n");
return 1; return EXIT_FAILURE;
} }
#endif #endif
@ -227,7 +232,7 @@ int main(int argc, char** argv) {
have_flag(argc, argv, "ellswift_ecdh")) { have_flag(argc, argv, "ellswift_ecdh")) {
fprintf(stderr, "./bench: ElligatorSwift module not enabled.\n"); fprintf(stderr, "./bench: ElligatorSwift module not enabled.\n");
fprintf(stderr, "Use ./configure --enable-module-ellswift.\n\n"); fprintf(stderr, "Use ./configure --enable-module-ellswift.\n\n");
return 1; return EXIT_FAILURE;
} }
#endif #endif
@ -275,5 +280,5 @@ int main(int argc, char** argv) {
run_ellswift_bench(iters, argc, argv); run_ellswift_bench(iters, argc, argv);
#endif #endif
return 0; return EXIT_SUCCESS;
} }

View file

@ -24,7 +24,7 @@ static int64_t gettime_i64(void) {
struct timespec tv; struct timespec tv;
if (!timespec_get(&tv, TIME_UTC)) { if (!timespec_get(&tv, TIME_UTC)) {
fputs("timespec_get failed!", stderr); fputs("timespec_get failed!", stderr);
exit(1); exit(EXIT_FAILURE);
} }
return (int64_t)tv.tv_nsec / 1000 + (int64_t)tv.tv_sec * 1000000LL; return (int64_t)tv.tv_nsec / 1000 + (int64_t)tv.tv_sec * 1000000LL;
#else #else

View file

@ -4,6 +4,7 @@
* file COPYING or https://www.opensource.org/licenses/mit-license.php.* * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/ ***********************************************************************/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include "secp256k1.c" #include "secp256k1.c"
#include "../include/secp256k1.h" #include "../include/secp256k1.h"
@ -287,7 +288,7 @@ int main(int argc, char **argv) {
|| have_flag(argc, argv, "--help") || have_flag(argc, argv, "--help")
|| have_flag(argc, argv, "help")) { || have_flag(argc, argv, "help")) {
help(argv); help(argv);
return 0; return EXIT_SUCCESS;
} else if(have_flag(argc, argv, "pippenger_wnaf")) { } else if(have_flag(argc, argv, "pippenger_wnaf")) {
printf("Using pippenger_wnaf:\n"); printf("Using pippenger_wnaf:\n");
data.ecmult_multi = secp256k1_ecmult_pippenger_batch_single; data.ecmult_multi = secp256k1_ecmult_pippenger_batch_single;
@ -299,7 +300,7 @@ int main(int argc, char **argv) {
} else { } else {
fprintf(stderr, "%s: unrecognized argument '%s'.\n\n", argv[0], argv[1]); fprintf(stderr, "%s: unrecognized argument '%s'.\n\n", argv[0], argv[1]);
help(argv); help(argv);
return 1; return EXIT_FAILURE;
} }
} }
@ -363,5 +364,5 @@ int main(int argc, char **argv) {
free(data.output); free(data.output);
free(data.expected_output); free(data.expected_output);
return(0); return EXIT_SUCCESS;
} }

View file

@ -4,6 +4,7 @@
* file COPYING or https://www.opensource.org/licenses/mit-license.php.* * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/ ***********************************************************************/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include "secp256k1.c" #include "secp256k1.c"
#include "../include/secp256k1.h" #include "../include/secp256k1.h"
@ -393,7 +394,7 @@ int main(int argc, char **argv) {
|| have_flag(argc, argv, "--help") || have_flag(argc, argv, "--help")
|| have_flag(argc, argv, "help")) { || have_flag(argc, argv, "help")) {
help(default_iters); help(default_iters);
return 0; return EXIT_SUCCESS;
} }
} }
@ -432,5 +433,5 @@ int main(int argc, char **argv) {
if (d || have_flag(argc, argv, "context")) run_benchmark("context_create", bench_context, bench_setup, NULL, &data, 10, iters); if (d || have_flag(argc, argv, "context")) run_benchmark("context_create", bench_context, bench_setup, NULL, &data, 10, iters);
return 0; return EXIT_SUCCESS;
} }

View file

@ -5,6 +5,7 @@
***********************************************************************/ ***********************************************************************/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include "../include/secp256k1.h" #include "../include/secp256k1.h"
@ -49,7 +50,7 @@ int main(void) {
if (!SECP256K1_CHECKMEM_RUNNING()) { if (!SECP256K1_CHECKMEM_RUNNING()) {
fprintf(stderr, "This test can only usefully be run inside valgrind because it was not compiled under msan.\n"); fprintf(stderr, "This test can only usefully be run inside valgrind because it was not compiled under msan.\n");
fprintf(stderr, "Usage: libtool --mode=execute valgrind ./ctime_tests\n"); fprintf(stderr, "Usage: libtool --mode=execute valgrind ./ctime_tests\n");
return 1; return EXIT_FAILURE;
} }
ctx = secp256k1_context_create(SECP256K1_CONTEXT_DECLASSIFY); ctx = secp256k1_context_create(SECP256K1_CONTEXT_DECLASSIFY);
/** In theory, testing with a single secret input should be sufficient: /** In theory, testing with a single secret input should be sufficient:
@ -69,7 +70,7 @@ int main(void) {
CHECK(ret); CHECK(ret);
secp256k1_context_destroy(ctx); secp256k1_context_destroy(ctx);
return 0; return EXIT_SUCCESS;
} }
static void run_tests(secp256k1_context *ctx, unsigned char *key) { static void run_tests(secp256k1_context *ctx, unsigned char *key) {

View file

@ -9,6 +9,7 @@
#include "eckey.h" #include "eckey.h"
#include "util.h"
#include "scalar.h" #include "scalar.h"
#include "field.h" #include "field.h"
#include "group.h" #include "group.h"
@ -35,6 +36,8 @@ static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char
} }
static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed) { static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed) {
VERIFY_CHECK(compressed == 0 || compressed == 1);
if (secp256k1_ge_is_infinity(elem)) { if (secp256k1_ge_is_infinity(elem)) {
return 0; return 0;
} }

View file

@ -80,7 +80,11 @@ static void secp256k1_ge_set_gej(secp256k1_ge *r, secp256k1_gej *a);
/** Set a group element equal to another which is given in jacobian coordinates. */ /** Set a group element equal to another which is given in jacobian coordinates. */
static void secp256k1_ge_set_gej_var(secp256k1_ge *r, secp256k1_gej *a); static void secp256k1_ge_set_gej_var(secp256k1_ge *r, secp256k1_gej *a);
/** Set a batch of group elements equal to the inputs given in jacobian coordinates */ /** Set group elements r[0:len] (affine) equal to group elements a[0:len] (jacobian).
* None of the group elements in a[0:len] may be infinity. Constant time. */
static void secp256k1_ge_set_all_gej(secp256k1_ge *r, const secp256k1_gej *a, size_t len);
/** Set group elements r[0:len] (affine) equal to group elements a[0:len] (jacobian). */
static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len); static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len);
/** Bring a batch of inputs to the same global z "denominator", based on ratios between /** Bring a batch of inputs to the same global z "denominator", based on ratios between

View file

@ -195,6 +195,44 @@ static void secp256k1_ge_set_gej_var(secp256k1_ge *r, secp256k1_gej *a) {
SECP256K1_GE_VERIFY(r); SECP256K1_GE_VERIFY(r);
} }
static void secp256k1_ge_set_all_gej(secp256k1_ge *r, const secp256k1_gej *a, size_t len) {
secp256k1_fe u;
size_t i;
#ifdef VERIFY
for (i = 0; i < len; i++) {
SECP256K1_GEJ_VERIFY(&a[i]);
VERIFY_CHECK(!secp256k1_gej_is_infinity(&a[i]));
}
#endif
if (len == 0) {
return;
}
/* Use destination's x coordinates as scratch space */
r[0].x = a[0].z;
for (i = 1; i < len; i++) {
secp256k1_fe_mul(&r[i].x, &r[i - 1].x, &a[i].z);
}
secp256k1_fe_inv(&u, &r[len - 1].x);
for (i = len - 1; i > 0; i--) {
secp256k1_fe_mul(&r[i].x, &r[i - 1].x, &u);
secp256k1_fe_mul(&u, &u, &a[i].z);
}
r[0].x = u;
for (i = 0; i < len; i++) {
secp256k1_ge_set_gej_zinv(&r[i], &a[i], &r[i].x);
}
#ifdef VERIFY
for (i = 0; i < len; i++) {
SECP256K1_GE_VERIFY(&r[i]);
}
#endif
}
static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len) { static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len) {
secp256k1_fe u; secp256k1_fe u;
size_t i; size_t i;

View file

@ -395,6 +395,7 @@ static void secp256k1_nonce_function_musig(secp256k1_scalar *k, const unsigned c
static int secp256k1_musig_nonce_gen_internal(const secp256k1_context* ctx, secp256k1_musig_secnonce *secnonce, secp256k1_musig_pubnonce *pubnonce, const unsigned char *input_nonce, const unsigned char *seckey, const secp256k1_pubkey *pubkey, const unsigned char *msg32, const secp256k1_musig_keyagg_cache *keyagg_cache, const unsigned char *extra_input32) { static int secp256k1_musig_nonce_gen_internal(const secp256k1_context* ctx, secp256k1_musig_secnonce *secnonce, secp256k1_musig_pubnonce *pubnonce, const unsigned char *input_nonce, const unsigned char *seckey, const secp256k1_pubkey *pubkey, const unsigned char *msg32, const secp256k1_musig_keyagg_cache *keyagg_cache, const unsigned char *extra_input32) {
secp256k1_scalar k[2]; secp256k1_scalar k[2];
secp256k1_ge nonce_pts[2]; secp256k1_ge nonce_pts[2];
secp256k1_gej nonce_ptj[2];
int i; int i;
unsigned char pk_ser[33]; unsigned char pk_ser[33];
size_t pk_ser_len = sizeof(pk_ser); size_t pk_ser_len = sizeof(pk_ser);
@ -444,13 +445,20 @@ static int secp256k1_musig_nonce_gen_internal(const secp256k1_context* ctx, secp
secp256k1_musig_secnonce_save(secnonce, k, &pk); secp256k1_musig_secnonce_save(secnonce, k, &pk);
secp256k1_musig_secnonce_invalidate(ctx, secnonce, !ret); secp256k1_musig_secnonce_invalidate(ctx, secnonce, !ret);
/* Compute pubnonce as two gejs */
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
secp256k1_gej nonce_ptj; secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &nonce_ptj[i], &k[i]);
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &nonce_ptj, &k[i]);
secp256k1_ge_set_gej(&nonce_pts[i], &nonce_ptj);
secp256k1_declassify(ctx, &nonce_pts[i], sizeof(nonce_pts[i]));
secp256k1_scalar_clear(&k[i]); secp256k1_scalar_clear(&k[i]);
secp256k1_gej_clear(&nonce_ptj); }
/* Batch convert to two public ges */
secp256k1_ge_set_all_gej(nonce_pts, nonce_ptj, 2);
for (i = 0; i < 2; i++) {
secp256k1_gej_clear(&nonce_ptj[i]);
}
for (i = 0; i < 2; i++) {
secp256k1_declassify(ctx, &nonce_pts[i], sizeof(nonce_pts[i]));
} }
/* None of the nonce_pts will be infinity because k != 0 with overwhelming /* None of the nonce_pts will be infinity because k != 0 with overwhelming
* probability */ * probability */

View file

@ -94,6 +94,8 @@ static int nonce_function_bip340(unsigned char *nonce32, const unsigned char *ms
secp256k1_sha256_write(&sha, msg, msglen); secp256k1_sha256_write(&sha, msg, msglen);
secp256k1_sha256_finalize(&sha, nonce32); secp256k1_sha256_finalize(&sha, nonce32);
secp256k1_sha256_clear(&sha); secp256k1_sha256_clear(&sha);
secp256k1_memclear(masked_key, sizeof(masked_key));
return 1; return 1;
} }

View file

@ -6,6 +6,7 @@
#include <inttypes.h> #include <inttypes.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include "../include/secp256k1.h" #include "../include/secp256k1.h"
@ -62,7 +63,7 @@ int main(void) {
fp = fopen(outfile, "w"); fp = fopen(outfile, "w");
if (fp == NULL) { if (fp == NULL) {
fprintf(stderr, "Could not open %s for writing!\n", outfile); fprintf(stderr, "Could not open %s for writing!\n", outfile);
return -1; return EXIT_FAILURE;
} }
fprintf(fp, "/* This file was automatically generated by precompute_ecmult. */\n"); fprintf(fp, "/* This file was automatically generated by precompute_ecmult. */\n");
@ -86,5 +87,5 @@ int main(void) {
fprintf(fp, "#undef S\n"); fprintf(fp, "#undef S\n");
fclose(fp); fclose(fp);
return 0; return EXIT_SUCCESS;
} }

View file

@ -6,6 +6,7 @@
#include <inttypes.h> #include <inttypes.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include "../include/secp256k1.h" #include "../include/secp256k1.h"
@ -64,7 +65,7 @@ int main(int argc, char **argv) {
fp = fopen(outfile, "w"); fp = fopen(outfile, "w");
if (fp == NULL) { if (fp == NULL) {
fprintf(stderr, "Could not open %s for writing!\n", outfile); fprintf(stderr, "Could not open %s for writing!\n", outfile);
return -1; return EXIT_FAILURE;
} }
fprintf(fp, "/* This file was automatically generated by precompute_ecmult_gen. */\n"); fprintf(fp, "/* This file was automatically generated by precompute_ecmult_gen. */\n");
@ -96,5 +97,5 @@ int main(int argc, char **argv) {
fprintf(fp, "#undef S\n"); fprintf(fp, "#undef S\n");
fclose(fp); fclose(fp);
return 0; return EXIT_SUCCESS;
} }

View file

@ -13,6 +13,8 @@ extern "C" {
#include "ecmult.h" #include "ecmult.h"
#include "group.h" #include "group.h"
#include "util_local_visibility.h"
#if defined(EXHAUSTIVE_TEST_ORDER) #if defined(EXHAUSTIVE_TEST_ORDER)
# if EXHAUSTIVE_TEST_ORDER == 7 # if EXHAUSTIVE_TEST_ORDER == 7
# define WINDOW_G 3 # define WINDOW_G 3
@ -27,8 +29,8 @@ static secp256k1_ge_storage secp256k1_pre_g[ECMULT_TABLE_SIZE(WINDOW_G)];
static secp256k1_ge_storage secp256k1_pre_g_128[ECMULT_TABLE_SIZE(WINDOW_G)]; static secp256k1_ge_storage secp256k1_pre_g_128[ECMULT_TABLE_SIZE(WINDOW_G)];
#else /* !defined(EXHAUSTIVE_TEST_ORDER) */ #else /* !defined(EXHAUSTIVE_TEST_ORDER) */
# define WINDOW_G ECMULT_WINDOW_SIZE # define WINDOW_G ECMULT_WINDOW_SIZE
extern const secp256k1_ge_storage secp256k1_pre_g[ECMULT_TABLE_SIZE(WINDOW_G)]; SECP256K1_LOCAL_VAR const secp256k1_ge_storage secp256k1_pre_g[ECMULT_TABLE_SIZE(WINDOW_G)];
extern const secp256k1_ge_storage secp256k1_pre_g_128[ECMULT_TABLE_SIZE(WINDOW_G)]; SECP256K1_LOCAL_VAR const secp256k1_ge_storage secp256k1_pre_g_128[ECMULT_TABLE_SIZE(WINDOW_G)];
#endif /* defined(EXHAUSTIVE_TEST_ORDER) */ #endif /* defined(EXHAUSTIVE_TEST_ORDER) */
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -13,10 +13,12 @@ extern "C" {
#include "group.h" #include "group.h"
#include "ecmult_gen.h" #include "ecmult_gen.h"
#include "util_local_visibility.h"
#ifdef EXHAUSTIVE_TEST_ORDER #ifdef EXHAUSTIVE_TEST_ORDER
static secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[COMB_BLOCKS][COMB_POINTS]; static secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[COMB_BLOCKS][COMB_POINTS];
#else #else
extern const secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[COMB_BLOCKS][COMB_POINTS]; SECP256K1_LOCAL_VAR const secp256k1_ge_storage secp256k1_ecmult_gen_prec_table[COMB_BLOCKS][COMB_POINTS];
#endif /* defined(EXHAUSTIVE_TEST_ORDER) */ #endif /* defined(EXHAUSTIVE_TEST_ORDER) */
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -90,11 +90,11 @@ static void secp256k1_scalar_split_lambda_verify(const secp256k1_scalar *r1, con
#endif #endif
/* /*
* Both lambda and beta are primitive cube roots of unity. That is lamba^3 == 1 mod n and * Both lambda and beta are primitive cube roots of unity. That is lambda^3 == 1 mod n and
* beta^3 == 1 mod p, where n is the curve order and p is the field order. * beta^3 == 1 mod p, where n is the curve order and p is the field order.
* *
* Furthermore, because (X^3 - 1) = (X - 1)(X^2 + X + 1), the primitive cube roots of unity are * Furthermore, because (X^3 - 1) = (X - 1)(X^2 + X + 1), the primitive cube roots of unity are
* roots of X^2 + X + 1. Therefore lambda^2 + lamba == -1 mod n and beta^2 + beta == -1 mod p. * roots of X^2 + X + 1. Therefore lambda^2 + lambda == -1 mod n and beta^2 + beta == -1 mod p.
* (The other primitive cube roots of unity are lambda^2 and beta^2 respectively.) * (The other primitive cube roots of unity are lambda^2 and beta^2 respectively.)
* *
* Let l = -1/2 + i*sqrt(3)/2, the complex root of X^2 + X + 1. We can define a ring * Let l = -1/2 + i*sqrt(3)/2, the complex root of X^2 + X + 1. We can define a ring

View file

@ -71,8 +71,8 @@ static const secp256k1_context secp256k1_context_static_ = {
{ secp256k1_default_error_callback_fn, 0 }, { secp256k1_default_error_callback_fn, 0 },
0 0
}; };
const secp256k1_context *secp256k1_context_static = &secp256k1_context_static_; const secp256k1_context * const secp256k1_context_static = &secp256k1_context_static_;
const secp256k1_context *secp256k1_context_no_precomp = &secp256k1_context_static_; const secp256k1_context * const secp256k1_context_no_precomp = &secp256k1_context_static_;
/* Helper function that determines if a context is proper, i.e., is not the static context or a copy thereof. /* Helper function that determines if a context is proper, i.e., is not the static context or a copy thereof.
* *
@ -280,7 +280,7 @@ int secp256k1_ec_pubkey_serialize(const secp256k1_context* ctx, unsigned char *o
ARG_CHECK(pubkey != NULL); ARG_CHECK(pubkey != NULL);
ARG_CHECK((flags & SECP256K1_FLAGS_TYPE_MASK) == SECP256K1_FLAGS_TYPE_COMPRESSION); ARG_CHECK((flags & SECP256K1_FLAGS_TYPE_MASK) == SECP256K1_FLAGS_TYPE_COMPRESSION);
if (secp256k1_pubkey_load(ctx, &Q, pubkey)) { if (secp256k1_pubkey_load(ctx, &Q, pubkey)) {
ret = secp256k1_eckey_pubkey_serialize(&Q, output, &len, flags & SECP256K1_FLAGS_BIT_COMPRESSION); ret = secp256k1_eckey_pubkey_serialize(&Q, output, &len, !!(flags & SECP256K1_FLAGS_BIT_COMPRESSION));
if (ret) { if (ret) {
*outputlen = len; *outputlen = len;
} }
@ -634,10 +634,6 @@ int secp256k1_ec_seckey_negate(const secp256k1_context* ctx, unsigned char *seck
return ret; return ret;
} }
int secp256k1_ec_privkey_negate(const secp256k1_context* ctx, unsigned char *seckey) {
return secp256k1_ec_seckey_negate(ctx, seckey);
}
int secp256k1_ec_pubkey_negate(const secp256k1_context* ctx, secp256k1_pubkey *pubkey) { int secp256k1_ec_pubkey_negate(const secp256k1_context* ctx, secp256k1_pubkey *pubkey) {
int ret = 0; int ret = 0;
secp256k1_ge p; secp256k1_ge p;
@ -681,10 +677,6 @@ int secp256k1_ec_seckey_tweak_add(const secp256k1_context* ctx, unsigned char *s
return ret; return ret;
} }
int secp256k1_ec_privkey_tweak_add(const secp256k1_context* ctx, unsigned char *seckey, const unsigned char *tweak32) {
return secp256k1_ec_seckey_tweak_add(ctx, seckey, tweak32);
}
static int secp256k1_ec_pubkey_tweak_add_helper(secp256k1_ge *p, const unsigned char *tweak32) { static int secp256k1_ec_pubkey_tweak_add_helper(secp256k1_ge *p, const unsigned char *tweak32) {
secp256k1_scalar term; secp256k1_scalar term;
int overflow = 0; int overflow = 0;
@ -729,10 +721,6 @@ int secp256k1_ec_seckey_tweak_mul(const secp256k1_context* ctx, unsigned char *s
return ret; return ret;
} }
int secp256k1_ec_privkey_tweak_mul(const secp256k1_context* ctx, unsigned char *seckey, const unsigned char *tweak32) {
return secp256k1_ec_seckey_tweak_mul(ctx, seckey, tweak32);
}
int secp256k1_ec_pubkey_tweak_mul(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *tweak32) { int secp256k1_ec_pubkey_tweak_mul(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *tweak32) {
secp256k1_ge p; secp256k1_ge p;
secp256k1_scalar factor; secp256k1_scalar factor;

View file

@ -87,15 +87,6 @@ static void counting_callback_fn(const char* str, void* data) {
(*p)++; (*p)++;
} }
static void uncounting_illegal_callback_fn(const char* str, void* data) {
/* Dummy callback function that just counts (backwards). */
int32_t *p;
(void)str;
p = data;
CHECK(*p != INT32_MIN);
(*p)--;
}
static void run_xoshiro256pp_tests(void) { static void run_xoshiro256pp_tests(void) {
{ {
size_t i; size_t i;
@ -3821,14 +3812,38 @@ static void test_ge(void) {
/* Test batch gej -> ge conversion without known z ratios. */ /* Test batch gej -> ge conversion without known z ratios. */
{ {
secp256k1_ge *ge_set_all_var = (secp256k1_ge *)checked_malloc(&CTX->error_callback, (4 * runs + 1) * sizeof(secp256k1_ge));
secp256k1_ge *ge_set_all = (secp256k1_ge *)checked_malloc(&CTX->error_callback, (4 * runs + 1) * sizeof(secp256k1_ge)); secp256k1_ge *ge_set_all = (secp256k1_ge *)checked_malloc(&CTX->error_callback, (4 * runs + 1) * sizeof(secp256k1_ge));
secp256k1_ge_set_all_gej_var(ge_set_all, gej, 4 * runs + 1); secp256k1_ge_set_all_gej_var(&ge_set_all_var[0], &gej[0], 4 * runs + 1);
for (i = 0; i < 4 * runs + 1; i++) { for (i = 0; i < 4 * runs + 1; i++) {
secp256k1_fe s; secp256k1_fe s;
testutil_random_fe_non_zero(&s); testutil_random_fe_non_zero(&s);
secp256k1_gej_rescale(&gej[i], &s); secp256k1_gej_rescale(&gej[i], &s);
CHECK(secp256k1_gej_eq_ge_var(&gej[i], &ge_set_all[i])); CHECK(secp256k1_gej_eq_ge_var(&gej[i], &ge_set_all_var[i]));
} }
/* Skip infinity at &gej[0]. */
secp256k1_ge_set_all_gej(&ge_set_all[1], &gej[1], 4 * runs);
for (i = 1; i < 4 * runs + 1; i++) {
secp256k1_fe s;
testutil_random_fe_non_zero(&s);
secp256k1_gej_rescale(&gej[i], &s);
CHECK(secp256k1_gej_eq_ge_var(&gej[i], &ge_set_all[i]));
CHECK(secp256k1_ge_eq_var(&ge_set_all_var[i], &ge_set_all[i]));
}
/* Test with an array of length 1. */
secp256k1_ge_set_all_gej_var(ge_set_all_var, &gej[1], 1);
secp256k1_ge_set_all_gej(ge_set_all, &gej[1], 1);
CHECK(secp256k1_gej_eq_ge_var(&gej[1], &ge_set_all_var[1]));
CHECK(secp256k1_gej_eq_ge_var(&gej[1], &ge_set_all[1]));
CHECK(secp256k1_ge_eq_var(&ge_set_all_var[1], &ge_set_all[1]));
/* Test with an array of length 0. */
secp256k1_ge_set_all_gej_var(NULL, NULL, 0);
secp256k1_ge_set_all_gej(NULL, NULL, 0);
free(ge_set_all_var);
free(ge_set_all); free(ge_set_all);
} }
@ -6248,11 +6263,6 @@ static void run_eckey_negate_test(void) {
CHECK(secp256k1_ec_seckey_negate(CTX, seckey) == 1); CHECK(secp256k1_ec_seckey_negate(CTX, seckey) == 1);
CHECK(secp256k1_memcmp_var(seckey, seckey_tmp, 32) == 0); CHECK(secp256k1_memcmp_var(seckey, seckey_tmp, 32) == 0);
/* Check that privkey alias gives same result */
CHECK(secp256k1_ec_seckey_negate(CTX, seckey) == 1);
CHECK(secp256k1_ec_privkey_negate(CTX, seckey_tmp) == 1);
CHECK(secp256k1_memcmp_var(seckey, seckey_tmp, 32) == 0);
/* Negating all 0s fails */ /* Negating all 0s fails */
memset(seckey, 0, 32); memset(seckey, 0, 32);
memset(seckey_tmp, 0, 32); memset(seckey_tmp, 0, 32);
@ -6413,22 +6423,15 @@ static void test_ecdsa_end_to_end(void) {
if (testrand_int(3) == 0) { if (testrand_int(3) == 0) {
int ret1; int ret1;
int ret2; int ret2;
int ret3;
unsigned char rnd[32]; unsigned char rnd[32];
unsigned char privkey_tmp[32];
secp256k1_pubkey pubkey2; secp256k1_pubkey pubkey2;
testrand256_test(rnd); testrand256_test(rnd);
memcpy(privkey_tmp, privkey, 32);
ret1 = secp256k1_ec_seckey_tweak_add(CTX, privkey, rnd); ret1 = secp256k1_ec_seckey_tweak_add(CTX, privkey, rnd);
ret2 = secp256k1_ec_pubkey_tweak_add(CTX, &pubkey, rnd); ret2 = secp256k1_ec_pubkey_tweak_add(CTX, &pubkey, rnd);
/* Check that privkey alias gives same result */
ret3 = secp256k1_ec_privkey_tweak_add(CTX, privkey_tmp, rnd);
CHECK(ret1 == ret2); CHECK(ret1 == ret2);
CHECK(ret2 == ret3);
if (ret1 == 0) { if (ret1 == 0) {
return; return;
} }
CHECK(secp256k1_memcmp_var(privkey, privkey_tmp, 32) == 0);
CHECK(secp256k1_ec_pubkey_create(CTX, &pubkey2, privkey) == 1); CHECK(secp256k1_ec_pubkey_create(CTX, &pubkey2, privkey) == 1);
CHECK(secp256k1_memcmp_var(&pubkey, &pubkey2, sizeof(pubkey)) == 0); CHECK(secp256k1_memcmp_var(&pubkey, &pubkey2, sizeof(pubkey)) == 0);
} }
@ -6437,22 +6440,15 @@ static void test_ecdsa_end_to_end(void) {
if (testrand_int(3) == 0) { if (testrand_int(3) == 0) {
int ret1; int ret1;
int ret2; int ret2;
int ret3;
unsigned char rnd[32]; unsigned char rnd[32];
unsigned char privkey_tmp[32];
secp256k1_pubkey pubkey2; secp256k1_pubkey pubkey2;
testrand256_test(rnd); testrand256_test(rnd);
memcpy(privkey_tmp, privkey, 32);
ret1 = secp256k1_ec_seckey_tweak_mul(CTX, privkey, rnd); ret1 = secp256k1_ec_seckey_tweak_mul(CTX, privkey, rnd);
ret2 = secp256k1_ec_pubkey_tweak_mul(CTX, &pubkey, rnd); ret2 = secp256k1_ec_pubkey_tweak_mul(CTX, &pubkey, rnd);
/* Check that privkey alias gives same result */
ret3 = secp256k1_ec_privkey_tweak_mul(CTX, privkey_tmp, rnd);
CHECK(ret1 == ret2); CHECK(ret1 == ret2);
CHECK(ret2 == ret3);
if (ret1 == 0) { if (ret1 == 0) {
return; return;
} }
CHECK(secp256k1_memcmp_var(privkey, privkey_tmp, 32) == 0);
CHECK(secp256k1_ec_pubkey_create(CTX, &pubkey2, privkey) == 1); CHECK(secp256k1_ec_pubkey_create(CTX, &pubkey2, privkey) == 1);
CHECK(secp256k1_memcmp_var(&pubkey, &pubkey2, sizeof(pubkey)) == 0); CHECK(secp256k1_memcmp_var(&pubkey, &pubkey2, sizeof(pubkey)) == 0);
} }
@ -7837,5 +7833,5 @@ int main(int argc, char **argv) {
testrand_finish(); testrand_finish();
printf("no problems found\n"); printf("no problems found\n");
return 0; return EXIT_SUCCESS;
} }

View file

@ -383,7 +383,7 @@ int main(int argc, char** argv) {
this_core = strtol(argv[4], NULL, 0); this_core = strtol(argv[4], NULL, 0);
if (num_cores < 1 || this_core >= num_cores) { if (num_cores < 1 || this_core >= num_cores) {
fprintf(stderr, "Usage: %s [count] [seed] [numcores] [thiscore]\n", argv[0]); fprintf(stderr, "Usage: %s [count] [seed] [numcores] [thiscore]\n", argv[0]);
return 1; return EXIT_FAILURE;
} }
printf("running tests for core %lu (out of [0..%lu])\n", (unsigned long)this_core, (unsigned long)num_cores - 1); printf("running tests for core %lu (out of [0..%lu])\n", (unsigned long)this_core, (unsigned long)num_cores - 1);
} }
@ -462,5 +462,5 @@ int main(int argc, char** argv) {
testrand_finish(); testrand_finish();
printf("no problems found\n"); printf("no problems found\n");
return 0; return EXIT_SUCCESS;
} }

View file

@ -232,7 +232,7 @@ static SECP256K1_INLINE void secp256k1_memclear(void *ptr, size_t len) {
* As best as we can tell, this is sufficient to break any optimisations that * As best as we can tell, this is sufficient to break any optimisations that
* might try to eliminate "superfluous" memsets. * might try to eliminate "superfluous" memsets.
* This method is used in memzero_explicit() the Linux kernel, too. Its advantage is that it * This method is used in memzero_explicit() the Linux kernel, too. Its advantage is that it
* is pretty efficient, because the compiler can still implement the memset() efficently, * is pretty efficient, because the compiler can still implement the memset() efficiently,
* just not remove it entirely. See "Dead Store Elimination (Still) Considered Harmful" by * just not remove it entirely. See "Dead Store Elimination (Still) Considered Harmful" by
* Yang et al. (USENIX Security 2017) for more background. * Yang et al. (USENIX Security 2017) for more background.
*/ */

View file

@ -0,0 +1,12 @@
#ifndef SECP256K1_LOCAL_VISIBILITY_H
#define SECP256K1_LOCAL_VISIBILITY_H
/* Global variable visibility */
/* See: https://github.com/bitcoin-core/secp256k1/issues/1181 */
#if !defined(_WIN32) && defined(__GNUC__) && (__GNUC__ >= 4)
# define SECP256K1_LOCAL_VAR extern __attribute__ ((visibility ("hidden")))
#else
# define SECP256K1_LOCAL_VAR extern
#endif
#endif /* SECP256K1_LOCAL_VISIBILITY_H */

View file

@ -0,0 +1,72 @@
#!/usr/bin/env python3
"""Check that a libsecp256k1 shared library exports only expected symbols.
Usage examples:
- When building with Autotools:
./tools/symbol-check.py .libs/libsecp256k1.so
./tools/symbol-check.py .libs/libsecp256k1-<V>.dll
./tools/symbol-check.py .libs/libsecp256k1.dylib
- When building with CMake:
./tools/symbol-check.py build/lib/libsecp256k1.so
./tools/symbol-check.py build/bin/libsecp256k1-<V>.dll
./tools/symbol-check.py build/lib/libsecp256k1.dylib"""
import re
import sys
import subprocess
import lief
class UnexpectedExport(RuntimeError):
pass
def get_exported_exports(library) -> list[str]:
"""Adapter function to get exported symbols based on the library format."""
if library.format == lief.Binary.FORMATS.ELF:
return [symbol.name for symbol in library.exported_symbols]
elif library.format == lief.Binary.FORMATS.PE:
return [entry.name for entry in library.get_export().entries]
elif library.format == lief.Binary.FORMATS.MACHO:
return [symbol.name[1:] for symbol in library.exported_symbols]
raise NotImplementedError(f"Unsupported format: {library.format}")
def grep_expected_symbols() -> list[str]:
"""Guess the list of expected exported symbols from the source code."""
grep_output = subprocess.check_output(
["git", "grep", r"^\s*SECP256K1_API", "--", "include"],
universal_newlines=True,
encoding="utf-8"
)
lines = grep_output.split("\n")
pattern = re.compile(r'\bsecp256k1_\w+')
exported: list[str] = [pattern.findall(line)[-1] for line in lines if line.strip()]
return exported
def check_symbols(library, expected_exports) -> None:
"""Check that the library exports only the expected symbols."""
actual_exports = get_exported_exports(library)
unexpected_exports = set(actual_exports) - set(expected_exports)
if unexpected_exports != set():
raise UnexpectedExport(f"Unexpected exported symbols: {unexpected_exports}")
def main():
if len(sys.argv) != 2:
print(__doc__)
return 1
library = lief.parse(sys.argv[1])
expected_exports = grep_expected_symbols()
try:
check_symbols(library, expected_exports)
except UnexpectedExport as e:
print(f"{sys.argv[0]}: In {sys.argv[1]}: {e}")
return 1
return 0
if __name__ == "__main__":
sys.exit(main())