diff --git a/.cirrus.yml b/.cirrus.yml deleted file mode 100644 index 023cd1916..000000000 --- a/.cirrus.yml +++ /dev/null @@ -1,104 +0,0 @@ -env: - ### cirrus config - CIRRUS_CLONE_DEPTH: 1 - ### compiler options - HOST: - WRAPPER_CMD: - # Specific warnings can be disabled with -Wno-error=foo. - # -pedantic-errors is not equivalent to -Werror=pedantic and thus not implied by -Werror according to the GCC manual. - WERROR_CFLAGS: -Werror -pedantic-errors - MAKEFLAGS: -j4 - BUILD: check - ### secp256k1 config - ECMULTWINDOW: 15 - ECMULTGENKB: 22 - ASM: no - WIDEMUL: auto - WITH_VALGRIND: yes - EXTRAFLAGS: - ### secp256k1 modules - EXPERIMENTAL: no - ECDH: no - RECOVERY: no - EXTRAKEYS: no - SCHNORRSIG: no - MUSIG: no - ELLSWIFT: no - ### test options - SECP256K1_TEST_ITERS: 64 - BENCH: yes - SECP256K1_BENCH_ITERS: 2 - CTIMETESTS: yes - SYMBOL_CHECK: yes - VIRTUAL_ENV: /root/venv - # Compile and run the tests - EXAMPLES: yes - -cat_logs_snippet: &CAT_LOGS - always: - cat_tests_log_script: - - cat tests.log || true - cat_noverify_tests_log_script: - - cat noverify_tests.log || true - cat_exhaustive_tests_log_script: - - cat exhaustive_tests.log || true - cat_ctime_tests_log_script: - - cat ctime_tests.log || true - cat_bench_log_script: - - cat bench.log || true - cat_config_log_script: - - cat config.log || true - cat_test_env_script: - - cat test_env.log || true - cat_ci_env_script: - - env - -linux_arm64_container_snippet: &LINUX_ARM64_CONTAINER - env_script: - - export PATH="$VIRTUAL_ENV/bin:$PATH" - - env | tee /tmp/env - build_script: - - DOCKER_BUILDKIT=1 docker build --file "ci/linux-debian.Dockerfile" --tag="ci_secp256k1_arm" - - docker image prune --force # Cleanup stale layers - test_script: - - docker run --rm --mount "type=bind,src=./,dst=/ci_secp256k1" --env-file /tmp/env --replace --name "ci_secp256k1_arm" "ci_secp256k1_arm" bash -c "cd /ci_secp256k1/ && ./ci/ci.sh" - -task: - name: "ARM64: Linux (Debian stable)" - persistent_worker: - labels: - type: arm64 - env: - ECDH: yes - RECOVERY: yes - EXTRAKEYS: yes - SCHNORRSIG: yes - MUSIG: yes - ELLSWIFT: yes - matrix: - # Currently only gcc-snapshot, the other compilers are tested on GHA with QEMU - - env: { CC: 'gcc-snapshot' } - << : *LINUX_ARM64_CONTAINER - << : *CAT_LOGS - -task: - name: "ARM64: Linux (Debian stable), Valgrind" - persistent_worker: - labels: - type: arm64 - env: - ECDH: yes - RECOVERY: yes - EXTRAKEYS: yes - SCHNORRSIG: yes - MUSIG: yes - ELLSWIFT: yes - WRAPPER_CMD: 'valgrind --error-exitcode=42' - SECP256K1_TEST_ITERS: 2 - matrix: - - env: { CC: 'gcc' } - - env: { CC: 'clang' } - - env: { CC: 'gcc-snapshot' } - - env: { CC: 'clang-snapshot' } - << : *LINUX_ARM64_CONTAINER - << : *CAT_LOGS diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b39223558..28ef1685e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,8 +53,18 @@ env: jobs: docker_cache: - name: "Build Docker image" - runs-on: ubuntu-latest + name: "Build ${{ matrix.arch }} Docker image" + runs-on: ${{ matrix.runner }} + + strategy: + fail-fast: false + matrix: + include: + - arch: x64 + runner: ubuntu-latest + - arch: arm64 + runner: ubuntu-24.04-arm + steps: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -67,11 +77,11 @@ jobs: uses: docker/build-push-action@v5 with: file: ./ci/linux-debian.Dockerfile - tags: linux-debian-image + tags: ${{ matrix.arch }}-debian-image cache-from: type=gha cache-to: type=gha,mode=min - linux_debian: + x86_64-debian: name: "x86_64: Linux (Debian stable)" runs-on: ubuntu-latest needs: docker_cache @@ -113,7 +123,7 @@ jobs: uses: ./.github/actions/run-in-docker-action with: dockerfile: ./ci/linux-debian.Dockerfile - tag: linux-debian-image + tag: x64-debian-image - name: Print logs uses: ./.github/actions/print-logs @@ -157,7 +167,7 @@ jobs: uses: ./.github/actions/run-in-docker-action with: dockerfile: ./ci/linux-debian.Dockerfile - tag: linux-debian-image + tag: x64-debian-image - name: Print logs uses: ./.github/actions/print-logs @@ -197,7 +207,7 @@ jobs: uses: ./.github/actions/run-in-docker-action with: dockerfile: ./ci/linux-debian.Dockerfile - tag: linux-debian-image + tag: x64-debian-image - name: Print logs uses: ./.github/actions/print-logs @@ -246,21 +256,19 @@ jobs: uses: ./.github/actions/run-in-docker-action with: dockerfile: ./ci/linux-debian.Dockerfile - tag: linux-debian-image + tag: x64-debian-image - name: Print logs uses: ./.github/actions/print-logs if: ${{ !cancelled() }} - arm64_debian: - name: "ARM64: Linux (Debian stable, QEMU)" - runs-on: ubuntu-latest + arm64-debian: + name: "arm64: Linux (Debian stable)" + runs-on: ubuntu-24.04-arm needs: docker_cache env: - WRAPPER_CMD: 'qemu-aarch64' SECP256K1_TEST_ITERS: 16 - HOST: 'aarch64-linux-gnu' WITH_VALGRIND: 'no' ECDH: 'yes' RECOVERY: 'yes' @@ -277,27 +285,26 @@ jobs: BPPP: 'yes' SCHNORRSIG_HALFAGG: 'yes' CTIMETESTS: 'no' + CC: ${{ matrix.cc }} strategy: fail-fast: false matrix: - configuration: - - env_vars: { } # gcc - - env_vars: # clang - CC: 'clang --target=aarch64-linux-gnu' - - env_vars: # clang-snapshot - CC: 'clang-snapshot --target=aarch64-linux-gnu' + cc: + - 'gcc' + - 'clang' + - 'gcc-snapshot' + - 'clang-snapshot' steps: - name: Checkout uses: actions/checkout@v4 - name: CI script - env: ${{ matrix.configuration.env_vars }} uses: ./.github/actions/run-in-docker-action with: dockerfile: ./ci/linux-debian.Dockerfile - tag: linux-debian-image + tag: arm64-debian-image - name: Print logs uses: ./.github/actions/print-logs @@ -337,7 +344,7 @@ jobs: uses: ./.github/actions/run-in-docker-action with: dockerfile: ./ci/linux-debian.Dockerfile - tag: linux-debian-image + tag: x64-debian-image - name: Print logs uses: ./.github/actions/print-logs @@ -345,18 +352,38 @@ jobs: valgrind_debian: - name: "Valgrind (memcheck)" - runs-on: ubuntu-latest + name: "Valgrind ${{ matrix.binary_arch }} (memcheck)" + runs-on: ${{ matrix.runner }} needs: docker_cache strategy: fail-fast: false matrix: - configuration: - - env_vars: { CC: 'clang', ASM: 'auto' } - - env_vars: { CC: 'i686-linux-gnu-gcc', HOST: 'i686-linux-gnu', ASM: 'auto' } - - env_vars: { CC: 'clang', ASM: 'no', ECMULTGENKB: 2, ECMULTWINDOW: 2 } - - env_vars: { CC: 'i686-linux-gnu-gcc', HOST: 'i686-linux-gnu', ASM: 'no', ECMULTGENKB: 2, ECMULTWINDOW: 2 } + include: + - docker_arch: x64 + runner: ubuntu-latest + binary_arch: x64 + env_vars: { CC: 'clang', ASM: 'auto' } + - docker_arch: x64 + runner: ubuntu-latest + binary_arch: i686 + env_vars: { CC: 'i686-linux-gnu-gcc', HOST: 'i686-linux-gnu', ASM: 'auto' } + - docker_arch: arm64 + runner: ubuntu-24.04-arm + binary_arch: arm64 + env_vars: { CC: 'clang', ASM: 'auto' } + - docker_arch: x64 + runner: ubuntu-latest + binary_arch: x64 + env_vars: { CC: 'clang', ASM: 'no', ECMULTGENKB: 2, ECMULTWINDOW: 2 } + - docker_arch: x64 + runner: ubuntu-latest + binary_arch: i686 + env_vars: { CC: 'i686-linux-gnu-gcc', HOST: 'i686-linux-gnu', ASM: 'no', ECMULTGENKB: 2, ECMULTWINDOW: 2 } + - docker_arch: arm64 + runner: ubuntu-24.04-arm + binary_arch: arm64 + env_vars: { CC: 'clang', ASM: 'no', ECMULTGENKB: 2, ECMULTWINDOW: 2 } env: # The `--error-exitcode` is required to make the test fail if valgrind found errors, @@ -384,11 +411,11 @@ jobs: uses: actions/checkout@v4 - name: CI script - env: ${{ matrix.configuration.env_vars }} + env: ${{ matrix.env_vars }} uses: ./.github/actions/run-in-docker-action with: dockerfile: ./ci/linux-debian.Dockerfile - tag: linux-debian-image + tag: ${{ matrix.docker_arch }}-debian-image - name: Print logs uses: ./.github/actions/print-logs @@ -440,7 +467,7 @@ jobs: uses: ./.github/actions/run-in-docker-action with: dockerfile: ./ci/linux-debian.Dockerfile - tag: linux-debian-image + tag: x64-debian-image - name: Print logs uses: ./.github/actions/print-logs @@ -499,7 +526,7 @@ jobs: uses: ./.github/actions/run-in-docker-action with: dockerfile: ./ci/linux-debian.Dockerfile - tag: linux-debian-image + tag: x64-debian-image - name: Print logs uses: ./.github/actions/print-logs @@ -550,7 +577,7 @@ jobs: uses: ./.github/actions/run-in-docker-action with: dockerfile: ./ci/linux-debian.Dockerfile - tag: linux-debian-image + tag: x64-debian-image - name: Print logs uses: ./.github/actions/print-logs @@ -628,13 +655,13 @@ jobs: fail-fast: false matrix: env_vars: - - { WIDEMUL: 'int64', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes' } + - { WIDEMUL: 'int64', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes' } - { WIDEMUL: 'int128_struct', ECMULTGENKB: 2, ECMULTWINDOW: 4 } - - { WIDEMUL: 'int128', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes' } + - { WIDEMUL: 'int128', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes' } - { WIDEMUL: 'int128', RECOVERY: 'yes' } - - { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes' } - - { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', CC: 'gcc' } - - { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', CPPFLAGS: '-DVERIFY' } + - { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes' } + - { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', CC: 'gcc' } + - { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', CPPFLAGS: '-DVERIFY' } - BUILD: 'distcheck' steps: @@ -769,7 +796,7 @@ jobs: uses: ./.github/actions/run-in-docker-action with: dockerfile: ./ci/linux-debian.Dockerfile - tag: linux-debian-image + tag: x64-debian-image - name: Print logs uses: ./.github/actions/print-logs @@ -788,7 +815,7 @@ jobs: uses: ./.github/actions/run-in-docker-action with: dockerfile: ./ci/linux-debian.Dockerfile - tag: linux-debian-image + tag: x64-debian-image command: | g++ -Werror include/*.h clang -Werror -x c++-header include/*.h diff --git a/CHANGELOG.md b/CHANGELOG.md index e14073d2c..e3ab6e04e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,11 +10,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.7.0] - 2025-07-21 + +#### Added + - CMake: Added `secp256k1_objs` interface library to allow parent projects to embed libsecp256k1 object files into their own static libraries. + - build: Added `SECP256K1_NO_API_VISIBILITY_ATTRIBUTES` preprocessor flag (CMake option: `SECP256K1_ENABLE_API_VISIBILITY_ATTRIBUTES`) that disables explicit "visibility" attributes for API symbols. Defining this macro enables the user to control the visibility of the API symbols via `-fvisibility=` when building libsecp256k1. (All non-API declarations will always have hidden visibility, even with `SECP256K1_ENABLE_API_VISIBILITY_ATTRIBUTES` defined.) For instance, `-fvisibility=hidden` can be useful even for the API symbols, e.g., when building a static libsecp256k1 which is linked into a shared library, and the latter should not re-export the libsecp256k1 API. + +#### Changed + - The pointers `secp256k1_context_static` and `secp256k1_context_no_precomp` to the constant context objects are now `const`. + - Removed `SECP256K1_WARN_UNUSED_RESULT` attribute (defined as `__attribute__ ((__warn_unused_result__))`) from several API functions that always return 1. Compilers will no longer warn if the return value is unused. + - CMake: Building with CMake is no longer considered experimental. + - CMake: The minimum required CMake version was increased to 3.22. + - CMake: Shared libraries built with CMake on FreeBSD now create the full versioned filename and symlink chain, matching the behavior of autotools builds. + #### 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. +#### ABI Compatibility +The symbols `secp256k1_ec_privkey_negate`, `secp256k1_ec_privkey_tweak_add`, and `secp256k1_ec_privkey_tweak_mul` were removed. +The pointers `secp256k1_context_static` and `secp256k1_context_no_precomp` have been made `const`. +Otherwise, the library maintains backward compatibility with version 0.6.0. + ## [0.6.0] - 2024-11-04 #### Added @@ -172,7 +190,8 @@ This version was in fact never released. 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. -[unreleased]: https://github.com/bitcoin-core/secp256k1/compare/v0.6.0...HEAD +[unreleased]: https://github.com/bitcoin-core/secp256k1/compare/v0.7.0...HEAD +[0.7.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.6.0...v0.7.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.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.4.1...v0.5.0 diff --git a/CMakeLists.txt b/CMakeLists.txt index 43751c4d3..b3913c332 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,12 +7,13 @@ project(libsecp256k1 # 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 # backwards-compatible and therefore at most increase the minor version. - VERSION 0.6.1 + VERSION 0.7.1 DESCRIPTION "Optimized C library for ECDSA signatures and secret/public key operations on curve secp256k1." HOMEPAGE_URL "https://github.com/bitcoin-core/secp256k1" LANGUAGES C ) enable_testing() +include(CTestUseLaunchers) # Allow users to set CTEST_USE_LAUNCHERS in custom `ctest -S` scripts. list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) # The library version is based on libtool versioning of the ABI. The set of @@ -20,7 +21,7 @@ list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) # https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html # All changes in experimental modules are treated as if they don't affect the # interface and therefore only increase the revision. -set(${PROJECT_NAME}_LIB_VERSION_CURRENT 5) +set(${PROJECT_NAME}_LIB_VERSION_CURRENT 6) set(${PROJECT_NAME}_LIB_VERSION_REVISION 1) set(${PROJECT_NAME}_LIB_VERSION_AGE 0) @@ -41,6 +42,8 @@ endif() option(SECP256K1_INSTALL "Enable installation." ${PROJECT_IS_TOP_LEVEL}) +option(SECP256K1_ENABLE_API_VISIBILITY_ATTRIBUTES "Enable visibility attributes in the API." ON) + ## Modules # We declare all options before processing them, to make sure we can express @@ -326,6 +329,7 @@ else() set(cross_status "FALSE") endif() message("Cross compiling ....................... ${cross_status}") +message("API visibility attributes ............. ${SECP256K1_ENABLE_API_VISIBILITY_ATTRIBUTES}") message("Valgrind .............................. ${SECP256K1_VALGRIND}") get_directory_property(definitions COMPILE_DEFINITIONS) string(REPLACE ";" " " definitions "${definitions}") diff --git a/include/secp256k1.h b/include/secp256k1.h index 1d25a02ab..f55a6ab97 100644 --- a/include/secp256k1.h +++ b/include/secp256k1.h @@ -121,45 +121,57 @@ typedef int (*secp256k1_nonce_function)( #endif /* Symbol visibility. */ -#if defined(_WIN32) - /* GCC for Windows (e.g., MinGW) accepts the __declspec syntax - * for MSVC compatibility. A __declspec declaration implies (but is not - * exactly equivalent to) __attribute__ ((visibility("default"))), and so we - * actually want __declspec even on GCC, see "Microsoft Windows Function - * Attributes" in the GCC manual and the recommendations in - * https://gcc.gnu.org/wiki/Visibility. */ -# if defined(SECP256K1_BUILD) -# if defined(DLL_EXPORT) || defined(SECP256K1_DLL_EXPORT) - /* Building libsecp256k1 as a DLL. - * 1. If using Libtool, it defines DLL_EXPORT automatically. - * 2. In other cases, SECP256K1_DLL_EXPORT must be defined. */ -# define SECP256K1_API extern __declspec (dllexport) -# else - /* Building libsecp256k1 as a static library on Windows. - * No declspec is needed, and so we would want the non-Windows-specific - * logic below take care of this case. However, this may result in setting - * __attribute__ ((visibility("default"))), which is supposed to be a noop - * on Windows but may trigger warnings when compiling with -flto due to a - * bug in GCC, see - * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116478 . */ -# define SECP256K1_API extern -# endif - /* The user must define SECP256K1_STATIC when consuming libsecp256k1 as a static - * library on Windows. */ -# elif !defined(SECP256K1_STATIC) - /* Consuming libsecp256k1 as a DLL. */ -# define SECP256K1_API extern __declspec (dllimport) -# endif +#if !defined(SECP256K1_API) && defined(SECP256K1_NO_API_VISIBILITY_ATTRIBUTES) + /* The user has requested that we don't specify visibility attributes in + * the public API. + * + * Since all our non-API declarations use the static qualifier, this means + * that the user can use -fvisibility= to set the visibility of the + * API symbols. For instance, -fvisibility=hidden can be useful *even for + * the API symbols*, e.g., when building a static library which is linked + * into a shared library, and the latter should not re-export the + * libsecp256k1 API. + * + * While visibility is a concept that applies only to shared libraries, + * setting visibility will still make a difference when building a static + * library: the visibility settings will be stored in the static library, + * solely for the potential case that the static library will be linked into + * a shared library. In that case, the stored visibility settings will + * resurface and be honored for the shared library. */ +# define SECP256K1_API extern #endif -#ifndef SECP256K1_API -/* All cases not captured by the Windows-specific logic. */ -# if defined(__GNUC__) && (__GNUC__ >= 4) && defined(SECP256K1_BUILD) - /* Building libsecp256k1 using GCC or compatible. */ -# define SECP256K1_API extern __attribute__ ((visibility ("default"))) -# else - /* Fall back to standard C's extern. */ -# define SECP256K1_API extern -# endif +#if !defined(SECP256K1_API) +# if defined(SECP256K1_BUILD) + /* On Windows, assume a shared library only if explicitly requested. + * 1. If using Libtool, it defines DLL_EXPORT automatically. + * 2. In other cases, SECP256K1_DLL_EXPORT must be defined. */ +# if defined(_WIN32) && (defined(SECP256K1_DLL_EXPORT) || defined(DLL_EXPORT)) + /* GCC for Windows (e.g., MinGW) accepts the __declspec syntax for + * MSVC compatibility. A __declspec declaration implies (but is not + * exactly equivalent to) __attribute__ ((visibility("default"))), + * and so we actually want __declspec even on GCC, see "Microsoft + * Windows Function Attributes" in the GCC manual and the + * recommendations in https://gcc.gnu.org/wiki/Visibility . */ +# define SECP256K1_API extern __declspec(dllexport) + /* Avoid __attribute__ ((visibility("default"))) on Windows to get rid + * of warnings when compiling with -flto due to a bug in GCC, see + * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116478 . */ +# elif !defined(_WIN32) && defined (__GNUC__) && (__GNUC__ >= 4) +# define SECP256K1_API extern __attribute__ ((visibility("default"))) +# else +# define SECP256K1_API extern +# endif +# else + /* On Windows, SECP256K1_STATIC must be defined when consuming + * libsecp256k1 as a static library. Note that SECP256K1_STATIC is a + * "consumer-only" macro, and it has no meaning when building + * libsecp256k1. */ +# if defined(_WIN32) && !defined(SECP256K1_STATIC) +# define SECP256K1_API extern __declspec(dllimport) +# else +# define SECP256K1_API extern +# endif +# endif #endif /* Warning attributes diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8c7f17918..52587ada7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -106,6 +106,10 @@ add_library(secp256k1_precomputed OBJECT EXCLUDE_FROM_ALL # from being exported. target_sources(secp256k1 PRIVATE secp256k1.c $) +if(NOT SECP256K1_ENABLE_API_VISIBILITY_ATTRIBUTES) + target_compile_definitions(secp256k1 PRIVATE SECP256K1_NO_API_VISIBILITY_ATTRIBUTES) +endif() + # Create a helper lib that parent projects can use to link secp256k1 into a # static lib. add_library(secp256k1_objs INTERFACE) @@ -138,7 +142,8 @@ target_include_directories(secp256k1 INTERFACE $>:${PROJECT_SOURCE_DIR}/include>> ) set_target_properties(secp256k1_objs PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "$" + INTERFACE_COMPILE_DEFINITIONS "$" + INTERFACE_INCLUDE_DIRECTORIES "$" ) # This emulates Libtool to make sure Libtool and CMake agree on the ABI version, @@ -147,7 +152,7 @@ math(EXPR ${PROJECT_NAME}_soversion "${${PROJECT_NAME}_LIB_VERSION_CURRENT} - ${ set_target_properties(secp256k1 PROPERTIES SOVERSION ${${PROJECT_NAME}_soversion} ) -if(CMAKE_SYSTEM_NAME STREQUAL "Linux") +if(CMAKE_SYSTEM_NAME MATCHES "^(Linux|FreeBSD)$") set_target_properties(secp256k1 PROPERTIES VERSION ${${PROJECT_NAME}_soversion}.${${PROJECT_NAME}_LIB_VERSION_AGE}.${${PROJECT_NAME}_LIB_VERSION_REVISION} ) diff --git a/src/modules/musig/tests_impl.h b/src/modules/musig/tests_impl.h index f4ae1585a..38f4a80d5 100644 --- a/src/modules/musig/tests_impl.h +++ b/src/modules/musig/tests_impl.h @@ -1058,12 +1058,15 @@ static void musig_test_vectors_signverify(void) { * the signing key does not belong to any pubkey. */ continue; } + expected = c->error != MUSIG_PUBKEY; CHECK(expected == musig_vectors_keyagg_and_tweak(&error, &keyagg_cache, NULL, vector->pubkeys, NULL, c->key_indices_len, c->key_indices, 0, NULL, NULL)); CHECK(expected || c->error == error); if (!expected) { continue; } + CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, vector->pubkeys[0], sizeof(vector->pubkeys[0]))); + CHECK(secp256k1_keypair_create(CTX, &keypair, vector->sk)); expected = c->error != MUSIG_AGGNONCE; CHECK(expected == secp256k1_musig_aggnonce_parse(CTX, &aggnonce, vector->aggnonces[c->aggnonce_index])); @@ -1072,15 +1075,10 @@ static void musig_test_vectors_signverify(void) { } CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, vector->msgs[c->msg_index], &keyagg_cache, NULL)); - CHECK(secp256k1_keypair_create(CTX, &keypair, vector->sk)); - CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, vector->pubkeys[0], sizeof(vector->pubkeys[0]))); - musig_test_set_secnonce(&secnonce, vector->secnonces[c->secnonce_index], &pubkey); expected = c->error != MUSIG_SECNONCE; - if (expected) { - CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig, &secnonce, &keypair, &keyagg_cache, &session)); - } else { - CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sign(CTX, &partial_sig, &secnonce, &keypair, &keyagg_cache, &session)); - } + CHECK(!expected); + musig_test_set_secnonce(&secnonce, vector->secnonces[c->secnonce_index], &pubkey); + CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sign(CTX, &partial_sig, &secnonce, &keypair, &keyagg_cache, &session)); } for (i = 0; i < sizeof(vector->verify_fail_case)/sizeof(vector->verify_fail_case[0]); i++) { const struct musig_verify_fail_error_case *c = &vector->verify_fail_case[i];