Squashed 'src/secp256k1/' changes from 95b983597a..a2b001cc20
What changed, and why it matters
This commit is a large subtree update that pulls in many upstream secp256k1-zkp changes. The most security-relevant parts are fixes for two cryptographic proof modules used in Elements' confidential transactions: surjection proofs and range proofs. The commit message says the fixes prevent reusing random-looking proof values ('s-values' and nonces) across different proof statements, which is a known way cryptographic proofs can be forged or leak secrets. However, the actual code changes for those fixes are not shown in the supplied diff; only repository-wide metadata and build/CI file changes are visible. So while the topic is security-sensitive, we cannot directly verify the cryptographic details from the materials provided.
Review the actual secp256k1-zkp commits a2b001cc20, f8841c14d5, cde28971a2, and 65093e1444 to confirm the cryptographic fixes are correct and complete. Ensure downstream Elements code that calls surjection/rangeproof APIs does not reuse nonces or s-values across differing statements. Run the updated secp256k1 tests and Elements confidential-transaction functional tests before deploying.
Security signals we found
Subtree update of secp256k1-zkp with explicit security-relevant merges
surjection proof: nonce binding to full statement (prevents s-value reuse)
rangeproof: nonce reuse warning/prevention
Large file churn (+94609/-1066438) consistent with subtree replacement
No direct diff evidence for the cryptographic changes in the provided materials
Evidence from the diff
The commit is a squashed git-subtree update of src/secp256k1 from 95b983597a to a2b001cc20. The commit log explicitly highlights three security-relevant upstream merges: elementsproject/secp256k1-zkp#369 (surjection: bind genrand nonce to the full statement), #370 (rangeproof: warn that nonce must not be reused across differing arguments), and a related surjection commit (prevent s-value reuse for different proof inputs). These address nonce/s-value reuse vulnerabilities in zero-knowledge proofs used by Elements. The supplied diff, however, only covers top-level repository files (CI configs, .gitattributes, CMakeLists.txt, etc.) and does not include the actual secp256k1 source changes. The diff shows the subtree replacement is massive (+94k/-1M lines, 3205 files). Because the cryptographic fixes are not directly inspectable here, classification relies on the commit message and subtree log, not on direct diff evidence.
Changed components
src/secp256k1 (subtree)secp256k1 modules: surjectionproofsecp256k1 modules: rangeproofElements confidential transaction proof generation/verificationInspect captured patch +94609 / −1066438
diff --git a/.cirrus.yml b/.cirrus.yml
deleted file mode 100644
index 5e06b56..0000000
--- a/.cirrus.yml
+++ /dev/null
@@ -1,224 +0,0 @@
-env: # Global defaults
- SECP256K1_TEST_ITERS: 16 # ELEMENTS: avoid test timeouts on arm
- CIRRUS_CLONE_DEPTH: 1
- CIRRUS_LOG_TIMESTAMP: true
- MAKEJOBS: "-j3" # ELEMENTS: reduced from j4
- TEST_RUNNER_PORT_MIN: "14000" # Must be larger than 12321, which is used for the http cache. See https://cirrus-ci.org/guide/writing-tasks/#http-cache
- CI_FAILFAST_TEST_LEAVE_DANGLING: "1" # Cirrus CI does not care about dangling processes and setting this variable avoids killing the CI script itself on error
-
-cirrus_ephemeral_worker_template_env: &CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
- DANGER_RUN_CI_ON_HOST: "1" # Containers will be discarded after the run, so there is no risk that the ci scripts modify the system
-
-# A self-hosted machine(s) can be used via Cirrus CI. It can be configured with
-# multiple users to run tasks in parallel. No sudo permission is required.
-#
-# https://cirrus-ci.org/guide/persistent-workers/
-#
-# Generally, a persistent worker must run Ubuntu 23.04+ or Debian 12+.
-#
-# The following specific types should exist, with the following requirements:
-# - small: For an x86_64 machine, with at least 2 vCPUs and 8 GB of memory.
-# - medium: For an x86_64 machine, with at least 4 vCPUs and 16 GB of memory.
-# - arm64: For an aarch64 machine, with at least 2 vCPUs and 8 GB of memory.
-#
-# CI jobs for the latter configuration can be run on x86_64 hardware
-# by installing qemu-user-static, which works out of the box with
-# podman or docker. Background: https://stackoverflow.com/a/72890225/313633
-#
-# The above machine types are matched to each task by their label. Refer to the
-# Cirrus CI docs for more details.
-#
-# When a contributor maintains a fork of the repo, any pull request they make
-# to their own fork, or to the main repository, will trigger two CI runs:
-# one for the branch push and one for the pull request.
-# This can be avoided by setting SKIP_BRANCH_PUSH=true as a custom env variable
-# in Cirrus repository settings, accessible from
-# https://cirrus-ci.com/github/my-organization/my-repository
-#
-# On machines that are persisted between CI jobs, RESTART_CI_DOCKER_BEFORE_RUN=1
-# ensures that previous containers and artifacts are cleared before each run.
-# This requires installing Podman instead of Docker.
-#
-# Futhermore:
-# - podman-docker-4.1+ is required due to the bugfix in 4.1
-# (https://github.com/bitcoin/bitcoin/pull/21652#issuecomment-1657098200)
-# - The ./ci/ dependencies (with cirrus-cli) should be installed. One-liner example
-# for a single user setup with sudo permission:
-#
-# ```
-# apt update && apt install git screen python3 bash podman-docker uidmap slirp4netns curl -y && curl -L -o cirrus "https://github.com/cirruslabs/cirrus-cli/releases/latest/download/cirrus-linux-$(dpkg --print-architecture)" && mv cirrus /usr/local/bin/cirrus && chmod +x /usr/local/bin/cirrus
-# ```
-#
-# - There are no strict requirements on the hardware. Having fewer CPU threads
-# than recommended merely causes the CI script to run slower.
-# To avoid rare and intermittent OOM due to short memory usage spikes,
-# it is recommended to add (and persist) swap:
-#
-# ```
-# fallocate -l 16G /swapfile_ci && chmod 600 /swapfile_ci && mkswap /swapfile_ci && swapon /swapfile_ci && ( echo '/swapfile_ci none swap sw 0 0' | tee -a /etc/fstab )
-# ```
-#
-# - To register the persistent worker, open a `screen` session and run:
-#
-# ```
-# RESTART_CI_DOCKER_BEFORE_RUN=1 screen cirrus worker run --labels type=todo_fill_in_type --token todo_fill_in_token
-# ```
-
-# https://cirrus-ci.org/guide/tips-and-tricks/#sharing-configuration-between-tasks
-filter_template: &FILTER_TEMPLATE
- # Allow forks to specify SKIP_BRANCH_PUSH=true and skip CI runs when a branch is pushed,
- # but still run CI when a PR is created.
- # https://cirrus-ci.org/guide/writing-tasks/#conditional-task-execution
- skip: $SKIP_BRANCH_PUSH == "true" && $CIRRUS_PR == ""
- stateful: false # https://cirrus-ci.org/guide/writing-tasks/#stateful-tasks
-
-base_template: &BASE_TEMPLATE
- << : *FILTER_TEMPLATE
- merge_base_script:
- # Require git (used in fingerprint_script).
- - git --version || ( apt-get update && apt-get install -y git )
- - rsync --version || bash -c "$PACKAGE_MANAGER_INSTALL rsync" # ELEMENTS
- - if [ "$CIRRUS_PR" = "" ]; then exit 0; fi
- - git fetch --depth=1 $CIRRUS_REPO_CLONE_URL "pull/${CIRRUS_PR}/merge"
- - git checkout FETCH_HEAD # Use merged changes to detect silent merge conflicts
- # Also, the merge commit is used to lint COMMIT_RANGE="HEAD~..HEAD"
-
-main_template: &MAIN_TEMPLATE
- timeout_in: 120m # https://cirrus-ci.org/faq/#instance-timed-out
- ci_script:
- - ./ci/test_run_all.sh
-
-global_task_template: &GLOBAL_TASK_TEMPLATE
- << : *BASE_TEMPLATE
- << : *MAIN_TEMPLATE
-
-compute_credits_template: &CREDITS_TEMPLATE
- # https://cirrus-ci.org/pricing/#compute-credits
- # Only use credits for pull requests to the main repo
- use_compute_credits: $CIRRUS_REPO_FULL_NAME == 'ElementsProject/elements' && $CIRRUS_PR != ""
-
-task:
- name: 'lint'
- << : *BASE_TEMPLATE
- container:
- image: debian:bookworm
- cpu: 1
- memory: 1G
- # For faster CI feedback, immediately schedule the linters
- << : *CREDITS_TEMPLATE
- test_runner_cache:
- folder: "/lint_test_runner"
- fingerprint_script: echo $CIRRUS_TASK_NAME $(git rev-parse HEAD:test/lint/test_runner)
- python_cache:
- folder: "/python_build"
- fingerprint_script: cat .python-version /etc/os-release
- unshallow_script:
- - git fetch --unshallow --no-tags
- lint_script:
- - ./ci/lint_run_all.sh
-
-task:
- name: 'tidy'
- << : *GLOBAL_TASK_TEMPLATE
- timeout_in: 180m # ELEMENTS
- container:
- image: docker.io/ubuntu:24.04
- env:
- << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
- FILE_ENV: "./ci/test/00_setup_env_native_tidy.sh"
-
-task:
- name: 'ARM, unit tests, no functional tests'
- << : *GLOBAL_TASK_TEMPLATE
- arm_container:
- image: docker.io/arm64v8/debian:bookworm
- env:
- << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
- FILE_ENV: "./ci/test/00_setup_env_arm.sh"
-
-task:
- name: 'Win64-cross'
- << : *GLOBAL_TASK_TEMPLATE
- container:
- image: docker.io/amd64/ubuntu:22.04
- env:
- << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
- FILE_ENV: "./ci/test/00_setup_env_win64.sh"
-
-task:
- name: 'CentOS, depends, gui'
- << : *GLOBAL_TASK_TEMPLATE
- container:
- image: quay.io/rockylinux/rockylinux:9
- env:
- FILE_ENV: "./ci/test/00_setup_env_native_centos.sh"
-
-task:
- name: 'previous releases, depends DEBUG'
- << : *GLOBAL_TASK_TEMPLATE
- container:
- image: docker.io/debian:bullseye
- env:
- << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
- FILE_ENV: "./ci/test/00_setup_env_native_previous_releases.sh"
-
-task:
- name: 'TSan, depends, gui'
- << : *GLOBAL_TASK_TEMPLATE
- container:
- image: docker.io/ubuntu:24.04
- cpu: 6
- memory: 24G
- env:
- << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
- FILE_ENV: "./ci/test/00_setup_env_native_tsan.sh"
-
-task:
- name: 'MSan, depends'
- << : *GLOBAL_TASK_TEMPLATE
- container:
- image: ubuntu:24.04
- cpu: 4
- memory: 16G
- env:
- << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
- FILE_ENV: "./ci/test/00_setup_env_native_msan.sh"
-
-task:
- name: 'fuzzer,address,undefined,integer, no depends'
- << : *GLOBAL_TASK_TEMPLATE
- container:
- image: docker.io/ubuntu:24.04
- cpu: 8
- memory: 16G
- timeout_in: 240m # larger timeout, due to the high CPU demand
- env:
- << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
- FILE_ENV: "./ci/test/00_setup_env_native_fuzz.sh"
-
-task:
- name: 'multiprocess, i686, DEBUG'
- << : *GLOBAL_TASK_TEMPLATE
- container:
- image: docker.io/amd64/ubuntu:22.04
- env:
- << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
- FILE_ENV: "./ci/test/00_setup_env_i686_multiprocess.sh"
-
-task:
- name: 'no wallet, libbitcoinkernel'
- << : *GLOBAL_TASK_TEMPLATE
- container:
- image: docker.io/ubuntu:22.04
- env:
- << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
- FILE_ENV: "./ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh"
-
-task:
- name: 'macOS-cross, gui, no tests'
- << : *GLOBAL_TASK_TEMPLATE
- container:
- image: docker.io/ubuntu:22.04
- env:
- << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
- FILE_ENV: "./ci/test/00_setup_env_mac_cross.sh"
diff --git a/.editorconfig b/.editorconfig
deleted file mode 100644
index c5f3028..0000000
--- a/.editorconfig
+++ /dev/null
@@ -1,26 +0,0 @@
-# This is the top-most EditorConfig file.
-root = true
-
-# For all files.
-[*]
-charset = utf-8
-end_of_line = lf
-indent_style = space
-insert_final_newline = true
-trim_trailing_whitespace = true
-
-# Source code files
-[*.{h,cpp,rs,py,sh}]
-indent_size = 4
-
-# .cirrus.yml, etc.
-[*.yml]
-indent_size = 2
-
-# Makefiles (only relevant for depends build)
-[Makefile]
-indent_style = tab
-
-# CMake files
-[{CMakeLists.txt,*.cmake,*.cmake.in}]
-indent_size = 2
diff --git a/.gitattributes b/.gitattributes
index c9cf4a7..30efb22 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1 +1,2 @@
-src/clientversion.cpp export-subst
+src/precomputed_ecmult.c linguist-generated
+src/precomputed_ecmult_gen.c linguist-generated
diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml
deleted file mode 100644
index 83922b5..0000000
--- a/.github/ISSUE_TEMPLATE/bug.yml
+++ /dev/null
@@ -1,93 +0,0 @@
-name: Bug report
-description: Submit a new bug report.
-labels: [bug]
-body:
- - type: markdown
- attributes:
- value: |
- ## This issue tracker is only for technical issues related to Bitcoin Core.
-
- * General bitcoin questions and/or support requests should use Bitcoin StackExchange at https://bitcoin.stackexchange.com.
- * For reporting security issues, please read instructions at https://bitcoincore.org/en/contact/.
- * If the node is "stuck" during sync or giving "block checksum mismatch" errors, please ensure your hardware is stable by running `memtest` and observe CPU temperature with a load-test tool such as `linpack` before creating an issue.
-
- ----
- - type: checkboxes
- attributes:
- label: Is there an existing issue for this?
- description: Please search to see if an issue already exists for the bug you encountered.
- options:
- - label: I have searched the existing issues
- required: true
- - type: textarea
- id: current-behaviour
- attributes:
- label: Current behaviour
- description: Tell us what went wrong
- validations:
- required: true
- - type: textarea
- id: expected-behaviour
- attributes:
- label: Expected behaviour
- description: Tell us what you expected to happen
- validations:
- required: true
- - type: textarea
- id: reproduction-steps
- attributes:
- label: Steps to reproduce
- description: |
- Tell us how to reproduce your bug. Please attach related screenshots if necessary.
- * Run-time or compile-time configuration options
- * Actions taken
- validations:
- required: true
- - type: textarea
- id: logs
- attributes:
- label: Relevant log output
- description: |
- Please copy and paste any relevant log output or attach a debug log file.
-
- You can find the debug.log in your [data dir.](https://github.com/bitcoin/bitcoin/blob/master/doc/files.md#data-directory-location)
-
- Please be aware that the debug log might contain personally identifying information.
- validations:
- required: false
- - type: dropdown
- attributes:
- label: How did you obtain Bitcoin Core
- multiple: false
- options:
- - Compiled from source
- - Pre-built binaries
- - Package manager
- - Other
- validations:
- required: true
- - type: input
- id: core-version
- attributes:
- label: What version of Bitcoin Core are you using?
- description: Run `bitcoind --version` or in Bitcoin-QT use `Help > About Bitcoin Core`
- placeholder: e.g. v24.0.1 or master@e1bf547
- validations:
- required: true
- - type: input
- id: os
- attributes:
- label: Operating system and version
- placeholder: e.g. "MacOS Ventura 13.2" or "Ubuntu 22.04 LTS"
- validations:
- required: true
- - type: textarea
- id: machine-specs
- attributes:
- label: Machine specifications
- description: |
- What are the specifications of the host machine?
- e.g. OS/CPU and disk type, network connectivity
- validations:
- required: false
-
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
deleted file mode 100644
index 4037028..0000000
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-blank_issues_enabled: true
-contact_links:
- - name: Bitcoin Core Security Policy
- url: https://github.com/bitcoin/bitcoin/blob/master/SECURITY.md
- about: View security policy
- - name: Bitcoin Core Developers
- url: https://bitcoincore.org
- about: Bitcoin Core homepage
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
deleted file mode 100644
index 4622fd9..0000000
--- a/.github/ISSUE_TEMPLATE/feature_request.yml
+++ /dev/null
@@ -1,36 +0,0 @@
-name: Feature Request
-description: Suggest an idea for this project.
-labels: [Feature]
-body:
- - type: textarea
- id: feature
- attributes:
- label: Please describe the feature you'd like to see added.
- description: Attach screenshots or logs if applicable.
- validations:
- required: true
- - type: textarea
- id: related-problem
- attributes:
- label: Is your feature related to a problem, if so please describe it.
- description: Attach screenshots or logs if applicable.
- validations:
- required: false
- - type: textarea
- id: solution
- attributes:
- label: Describe the solution you'd like
- validations:
- required: false
- - type: textarea
- id: alternatives
- attributes:
- label: Describe any alternatives you've considered
- validations:
- required: false
- - type: textarea
- id: additional-context
- attributes:
- label: Please leave any additional context
- validations:
- required: false
diff --git a/.github/ISSUE_TEMPLATE/good_first_issue.yml b/.github/ISSUE_TEMPLATE/good_first_issue.yml
deleted file mode 100644
index 133937c..0000000
--- a/.github/ISSUE_TEMPLATE/good_first_issue.yml
+++ /dev/null
@@ -1,44 +0,0 @@
-name: Good First Issue
-description: (Regular devs only) Suggest a new good first issue
-labels: [good first issue]
-body:
- - type: markdown
- attributes:
- value: |
- Please add the label "good first issue" manually before or after opening
-
- A good first issue is an uncontroversial issue, that has a relatively unique and obvious solution
-
- Motivate the issue and explain the solution briefly
- - type: textarea
- id: motivation
- attributes:
- label: Motivation
- description: Motivate the issue
- validations:
- required: true
- - type: textarea
- id: solution
- attributes:
- label: Possible solution
- description: Describe a possible solution
- validations:
- required: false
- - type: textarea
- id: useful-skills
- attributes:
- label: Useful Skills
- description: For example, “`std::thread`”, “Qt5 GUI and async GUI design” or “basic understanding of Bitcoin mining and the Bitcoin Core RPC interface”.
- value: |
- * Compiling Bitcoin Core from source
- * Running the C++ unit tests and the Python functional tests
- * ...
- - type: textarea
- attributes:
- label: Guidance for new contributors
- description: Please leave this to automatically add the footer for new contributors
- value: |
- Want to work on this issue?
-
- For guidance on contributing, please read [CONTRIBUTING.md](https://github.com/bitcoin/bitcoin/blob/master/CONTRIBUTING.md) before opening your pull request.
-
diff --git a/.github/ISSUE_TEMPLATE/gui_issue.yml b/.github/ISSUE_TEMPLATE/gui_issue.yml
deleted file mode 100644
index 4fe578e..0000000
--- a/.github/ISSUE_TEMPLATE/gui_issue.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-name: Issue or feature request related to the GUI
-description: Any report, issue or feature request related to the GUI
-labels: [GUI]
-body:
-- type: checkboxes
- id: acknowledgement
- attributes:
- label: Issues, reports or feature requests related to the GUI should be opened directly on the GUI repo
- description: https://github.com/bitcoin-core/gui/issues/
- options:
- - label: I still think this issue should be opened here
- required: true
-- type: textarea
- id: gui-request
- attributes:
- label: Report
- validations:
- required: true
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
deleted file mode 100644
index ae92fc7..0000000
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ /dev/null
@@ -1,43 +0,0 @@
-<!--
-*** Please remove the following help text before submitting: ***
-
-Pull requests without a rationale and clear improvement may be closed
-immediately.
-
-GUI-related pull requests should be opened against
-https://github.com/bitcoin-core/gui
-first. See CONTRIBUTING.md
--->
-
-<!--
-Please provide clear motivation for your patch and explain how it improves
-Bitcoin Core user experience or Bitcoin Core developer experience
-significantly:
-
-* Any test improvements or new tests that improve coverage are always welcome.
-* All other changes should have accompanying unit tests (see `src/test/`) or
- functional tests (see `test/`). Contributors should note which tests cover
- modified code. If no tests exist for a region of modified code, new tests
- should accompany the change.
-* Bug fixes are most welcome when they come with steps to reproduce or an
- explanation of the potential issue as well as reasoning for the way the bug
- was fixed.
-* Features are welcome, but might be rejected due to design or scope issues.
- If a feature is based on a lot of dependencies, contributors should first
- consider building the system outside of Bitcoin Core, if possible.
-* Refactoring changes are only accepted if they are required for a feature or
- bug fix or otherwise improve developer experience significantly. For example,
- most "code style" refactoring changes require a thorough explanation why they
- are useful, what downsides they have and why they *significantly* improve
- developer experience or avoid serious programming bugs. Note that code style
- is often a subjective matter. Unless they are explicitly mentioned to be
- preferred in the [developer notes](/doc/developer-notes.md), stylistic code
- changes are usually rejected.
--->
-
-<!--
-Bitcoin Core has a thorough review process and even the most trivial change
-needs to pass a lot of eyes and requires non-zero or even substantial time
-effort to review. There is a huge lack of active reviewers on the project, so
-patches often sit for a long time.
--->
diff --git a/.github/actions/install-homebrew-valgrind/action.yml b/.github/actions/install-homebrew-valgrind/action.yml
new file mode 100644
index 0000000..c4e0b5d
--- /dev/null
+++ b/.github/actions/install-homebrew-valgrind/action.yml
@@ -0,0 +1,34 @@
+name: "Install Valgrind"
+description: "Install Homebrew's Valgrind package and cache it."
+runs:
+ using: "composite"
+ steps:
+ - run: |
+ brew tap LouisBrunner/valgrind
+ brew trust --formula LouisBrunner/valgrind/valgrind
+ brew fetch --HEAD LouisBrunner/valgrind/valgrind
+ echo "CI_HOMEBREW_CELLAR_VALGRIND=$(brew --cellar valgrind)" >> "$GITHUB_ENV"
+ shell: bash
+
+ - run: |
+ sw_vers > valgrind_fingerprint
+ brew --version >> valgrind_fingerprint
+ git -C "$(brew --cache)/valgrind--git" rev-parse HEAD >> valgrind_fingerprint
+ cat valgrind_fingerprint
+ shell: bash
+
+ - uses: actions/cache@v5
+ id: cache
+ with:
+ path: ${{ env.CI_HOMEBREW_CELLAR_VALGRIND }}
+ key: ${{ github.job }}-valgrind-${{ hashFiles('valgrind_fingerprint') }}
+
+ - if: steps.cache.outputs.cache-hit != 'true'
+ run: |
+ brew install --HEAD LouisBrunner/valgrind/valgrind
+ shell: bash
+
+ - if: steps.cache.outputs.cache-hit == 'true'
+ run: |
+ brew link valgrind
+ shell: bash
diff --git a/.github/actions/print-logs/action.yml b/.github/actions/print-logs/action.yml
new file mode 100644
index 0000000..33de35c
--- /dev/null
+++ b/.github/actions/print-logs/action.yml
@@ -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
diff --git a/.github/actions/run-in-docker-action/action.yml b/.github/actions/run-in-docker-action/action.yml
new file mode 100644
index 0000000..f0eb981
--- /dev/null
+++ b/.github/actions/run-in-docker-action/action.yml
@@ -0,0 +1,52 @@
+name: 'Run in Docker with environment'
+description: 'Run a command in a Docker container, while passing explicitly set environment variables into the container.'
+inputs:
+ dockerfile:
+ description: 'A Dockerfile that defines an image'
+ required: true
+ scope:
+ description: 'A cached image scope'
+ required: true
+ command:
+ description: 'A command to run in a container'
+ required: true
+runs:
+ using: "composite"
+ steps:
+ - uses: docker/setup-buildx-action@v4
+
+ - uses: docker/build-push-action@v7
+ id: main_builder
+ continue-on-error: true
+ with:
+ context: .
+ file: ${{ inputs.dockerfile }}
+ load: true
+ cache-from: type=gha,scope=${{ inputs.scope }}
+
+ - uses: docker/build-push-action@v7
+ id: retry_builder
+ if: steps.main_builder.outcome == 'failure'
+ with:
+ context: .
+ file: ${{ inputs.dockerfile }}
+ load: true
+ cache-from: type=gha,scope=${{ inputs.scope }}
+
+ - # Workaround for https://github.com/google/sanitizers/issues/1614 .
+ # The underlying issue has been fixed in clang 18.1.3.
+ run: sudo sysctl -w vm.mmap_rnd_bits=28
+ shell: bash
+
+ - # Tell Docker to pass environment variables in `env` into the container.
+ run: >
+ docker run \
+ $(echo '${{ toJSON(env) }}' | jq -r 'keys[] | "--env \(.) "') \
+ --volume ${{ github.workspace }}:${{ github.workspace }} \
+ --workdir ${{ github.workspace }} \
+ ${{ case(steps.main_builder.outcome == 'success', steps.main_builder.outputs.imageid, steps.retry_builder.outputs.imageid) }} \
+ bash -c "
+ git config --global --add safe.directory ${{ github.workspace }}
+ ${{ inputs.command }}
+ "
+ shell: bash
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 8883596..c667077 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,314 +1,791 @@
-# Copyright (c) 2023-present The Bitcoin Core developers
-# Distributed under the MIT software license, see the accompanying
-# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
name: CI
on:
- # See: https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request.
pull_request:
- # See: https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#push.
push:
branches:
- '**'
tags-ignore:
- '**'
+ schedule:
+ # Run on the default branch every Monday morning.
+ # This also warms the Docker caches after key rotation.
+ - cron: '22 2 * * 1'
concurrency:
group: ${{ github.event_name != 'pull_request' && github.run_id || github.ref }}
cancel-in-progress: true
env:
- CI_FAILFAST_TEST_LEAVE_DANGLING: 1 # GHA does not care about dangling processes and setting this variable avoids killing the CI script itself on error
- MAKEJOBS: '-j10'
+ ### 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: 86
+ ASM: 'no'
+ WIDEMUL: 'auto'
+ WITH_VALGRIND: 'yes'
+ EXTRAFLAGS:
+ ### secp256k1 modules
+ EXPERIMENTAL: 'no'
+ ECDH: 'no'
+ RECOVERY: 'no'
+ EXTRAKEYS: 'no'
+ SCHNORRSIG: 'no'
+ MUSIG: 'no'
+ ELLSWIFT: 'no'
+ ECDSA_S2C: 'no'
+ GENERATOR: 'no'
+ RANGEPROOF: 'no'
+ SURJECTIONPROOF: 'no'
+ WHITELIST: 'no'
+ ECDSAADAPTOR: 'no'
+ BPPP: 'no'
+ SCHNORRSIG_HALFAGG: 'no'
+ ### test options
+ SECP256K1_TEST_ITERS: 64
+ BENCH: 'yes'
+ SECP256K1_BENCH_ITERS: 2
+ CTIMETESTS: 'yes'
+ SYMBOL_CHECK: 'yes'
+ # Compile and run the examples.
+ EXAMPLES: 'yes'
+ # Disable Docker build summary generation.
+ # See https://github.com/docker/build-push-action/blob/master/README.md#environment-variables.
+ DOCKER_BUILD_SUMMARY: false
jobs:
- test-each-commit:
- name: 'test each commit'
- runs-on: ubuntu-24.04
- if: github.event_name == 'pull_request' && github.event.pull_request.commits != 1
- timeout-minutes: 360 # Use maximum time, see https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idtimeout-minutes. Assuming a worst case time of 1 hour per commit, this leads to a --max-count=6 below.
+ docker_cache:
+ name: "Build ${{ matrix.arch }} Docker image"
+ runs-on: ${{ matrix.runner }}
+ outputs:
+ cache_scope: ${{ steps.cache_timestamp.outputs.period }}
+
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - arch: x64
+ runner: ubuntu-latest
+ - arch: arm64
+ runner: ubuntu-24.04-arm
+
+ steps:
+ - name: Get cache validity period
+ id: cache_timestamp
+ run: echo "period=$((10#$(date +%V) / 4))" >> "$GITHUB_OUTPUT"
+
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v4
+ with:
+ # See: https://github.com/moby/buildkit/issues/3969.
+ driver-opts: |
+ network=host
+
+ - name: Build container
+ uses: docker/build-push-action@v7
+ with:
+ file: ./ci/linux-debian.Dockerfile
+ cache-from: type=gha,scope=${{ runner.arch }}-${{ steps.cache_timestamp.outputs.period }}
+ cache-to: type=gha,scope=${{ runner.arch }}-${{ steps.cache_timestamp.outputs.period }},mode=min
+
+ x86_64-debian:
+ name: "x86_64: Linux (Debian stable)"
+ runs-on: ubuntu-latest
+ needs: docker_cache
+
+ strategy:
+ fail-fast: false
+ matrix:
+ configuration:
+ - env_vars: { WIDEMUL: 'int64', RECOVERY: 'yes' }
+ - env_vars: { WIDEMUL: 'int64', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes'}
+ - env_vars: { WIDEMUL: 'int128' }
+ - env_vars: { WIDEMUL: 'int128_struct', ELLSWIFT: 'yes' }
+ - env_vars: { WIDEMUL: 'int128', RECOVERY: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes' }
+ - env_vars: { WIDEMUL: 'int128', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes'}
+ - env_vars: { WIDEMUL: 'int128', ASM: 'x86_64', ELLSWIFT: 'yes' }
+ - env_vars: { RECOVERY: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes'}
+ - env_vars: { CTIMETESTS: 'no', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', CPPFLAGS: '-DVERIFY' }
+ - env_vars: { BUILD: 'distcheck', WITH_VALGRIND: 'no', CTIMETESTS: 'no', BENCH: 'no' }
+ - env_vars: { CPPFLAGS: '-DDETERMINISTIC' }
+ - env_vars: { CFLAGS: '-O0', CTIMETESTS: 'no' }
+ - env_vars: { CFLAGS: '-O1', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes' }
+ - env_vars: { ECMULTGENKB: 2, ECMULTWINDOW: 2 }
+ - env_vars: { ECMULTGENKB: 86, ECMULTWINDOW: 4 }
+ cc:
+ - 'gcc'
+ - 'clang'
+ - 'gcc-snapshot'
+ - 'clang-snapshot'
+
env:
- MAX_COUNT: 6
+ CC: ${{ matrix.cc }}
+
steps:
- - name: Determine fetch depth
- run: echo "FETCH_DEPTH=$((${{ github.event.pull_request.commits }} + 2))" >> "$GITHUB_ENV"
- - uses: actions/checkout@v4
+ - &CHECKOUT
+ name: Checkout
+ uses: actions/checkout@v5
+
+ - &CI_SCRIPT_IN_DOCKER
+ name: CI script
+ env: ${{ matrix.configuration.env_vars }}
+ uses: ./.github/actions/run-in-docker-action
with:
- ref: ${{ github.event.pull_request.head.sha }}
- fetch-depth: ${{ env.FETCH_DEPTH }}
- - name: Determine commit range
- run: |
- # Checkout HEAD~ and find the test base commit
- # Checkout HEAD~ because it would be wasteful to rerun tests on the PR
- # head commit that are already run by other jobs.
- git checkout HEAD~
- # Figure out test base commit by listing ancestors of HEAD, excluding
- # ancestors of the most recent merge commit, limiting the list to the
- # newest MAX_COUNT ancestors, ordering it from oldest to newest, and
- # taking the first one.
- #
- # If the branch contains up to MAX_COUNT ancestor commits after the
- # most recent merge commit, all of those commits will be tested. If it
- # contains more, only the most recent MAX_COUNT commits will be
- # tested.
- #
- # In the command below, the ^@ suffix is used to refer to all parents
- # of the merge commit as described in:
- # https://git-scm.com/docs/git-rev-parse#_other_rev_parent_shorthand_notations
- # and the ^ prefix is used to exclude these parents and all their
- # ancestors from the rev-list output as described in:
- # https://git-scm.com/docs/git-rev-list
- MERGE_BASE=$(git rev-list -n1 --merges HEAD)
- EXCLUDE_MERGE_BASE_ANCESTORS=
- # MERGE_BASE can be empty due to limited fetch-depth
- if test -n "$MERGE_BASE"; then
- EXCLUDE_MERGE_BASE_ANCESTORS=^${MERGE_BASE}^@
- fi
- echo "TEST_BASE=$(git rev-list -n$((${{ env.MAX_COUNT }} + 1)) --reverse HEAD $EXCLUDE_MERGE_BASE_ANCESTORS | head -1)" >> "$GITHUB_ENV"
- - run: |
- sudo apt-get update
- sudo apt-get install clang ccache build-essential cmake pkgconf python3-zmq libevent-dev libboost-dev libsqlite3-dev libdb++-dev systemtap-sdt-dev libzmq3-dev qtbase5-dev qttools5-dev qttools5-dev-tools qtwayland5 libqrencode-dev -y
- - name: Compile and run tests
- run: |
- # Run tests on commits after the last merge commit and before the PR head commit
- # Use clang++, because it is a bit faster and uses less memory than g++
- git rebase --exec "echo Running test-one-commit on \$( git log -1 ) && CC=clang CXX=clang++ cmake -B build -DWERROR=ON -DWITH_ZMQ=ON -DBUILD_GUI=ON -DBUILD_BENCH=ON -DBUILD_FUZZ_BINARY=ON -DWITH_BDB=ON -DWITH_USDT=ON -DCMAKE_CXX_FLAGS='-Wno-error=unused-member-function' && cmake --build build -j $(nproc) && ctest --output-on-failure --stop-on-failure --test-dir build -j $(nproc) && ./build/test/functional/test_runner.py -j $(( $(nproc) * 2 )) --combinedlogslen=99999999" ${{ env.TEST_BASE }}
+ dockerfile: ./ci/linux-debian.Dockerfile
+ scope: ${{ runner.arch }}-${{ needs.docker_cache.outputs.cache_scope }}
+ command: ./ci/ci.sh
- macos-native-arm64:
- name: ${{ matrix.job-name }}
- # Use any image to support the xcode-select below, but hardcode version to avoid silent upgrades (and breaks).
- # See: https://github.com/actions/runner-images#available-images.
- runs-on: macos-14
+ - &PRINT_LOGS
+ name: Print logs
+ uses: ./.github/actions/print-logs
+ if: ${{ !cancelled() }}
+
+ i686_debian:
+ name: "i686: Linux (Debian stable)"
+ runs-on: ubuntu-latest
+ needs: docker_cache
+
+ strategy:
+ fail-fast: false
+ matrix:
+ configuration:
+ - env_vars: {}
+ cc:
+ - 'i686-linux-gnu-gcc'
+ - 'clang --target=i686-pc-linux-gnu -isystem /usr/i686-linux-gnu/include'
+
+ env:
+ HOST: 'i686-linux-gnu'
+ ECDH: 'yes'
+ RECOVERY: 'yes'
+ EXTRAKEYS: 'yes'
+ SCHNORRSIG: 'yes'
+ MUSIG: 'yes'
+ ELLSWIFT: 'yes'
+ EXPERIMENTAL: 'yes'
+ ECDSA_S2C: 'yes'
+ RANGEPROOF: 'yes'
+ SURJECTIONPROOF: 'yes'
+ WHITELIST: 'yes'
+ GENERATOR: 'yes'
+ ECDSAADAPTOR: 'yes'
+ BPPP: 'yes'
+ SCHNORRSIG_HALFAGG: 'yes'
+ CC: ${{ matrix.cc }}
+
+ steps:
+ - *CHECKOUT
+ - *CI_SCRIPT_IN_DOCKER
+ - *PRINT_LOGS
+
+ s390x_debian:
+ name: "s390x (big-endian): Linux (Debian stable, QEMU)"
+ runs-on: ubuntu-latest
+ needs: docker_cache
+
+ strategy:
+ matrix:
+ configuration:
+ - env_vars: {}
- # When a contributor maintains a fork of the repo, any pull request they make
- # to their own fork, or to the main repository, will trigger two CI runs:
- # one for the branch push and one for the pull request.
- # This can be avoided by setting SKIP_BRANCH_PUSH=true as a custom env variable
- # in Github repository settings.
- if: ${{ vars.SKIP_BRANCH_PUSH != 'true' || github.event_name == 'pull_request' }}
+ env:
+ WRAPPER_CMD: 'qemu-s390x'
+ SECP256K1_TEST_ITERS: 16
+ HOST: 's390x-linux-gnu'
+ WITH_VALGRIND: 'no'
+ ECDH: 'yes'
+ RECOVERY: 'yes'
+ EXTRAKEYS: 'yes'
+ SCHNORRSIG: 'yes'
+ MUSIG: 'yes'
+ ELLSWIFT: 'yes'
+ EXPERIMENTAL: 'yes'
+ ECDSA_S2C: 'yes'
+ RANGEPROOF: 'yes'
+ SURJECTIONPROOF: 'yes'
+ WHITELIST: 'yes'
+ GENERATOR: 'yes'
+ ECDSAADAPTOR: 'yes'
+ BPPP: 'yes'
+ SCHNORRSIG_HALFAGG: 'yes'
+ CTIMETESTS: 'no'
+
+ steps:
+ - *CHECKOUT
+ - *CI_SCRIPT_IN_DOCKER
+ - *PRINT_LOGS
- timeout-minutes: 120
+ arm32_debian:
+ name: "ARM32: Linux (Debian stable, QEMU)"
+ runs-on: ubuntu-latest
+ needs: docker_cache
strategy:
fail-fast: false
matrix:
- job-type: [standard, fuzz]
- include:
- - job-type: standard
- file-env: './ci/test/00_setup_env_mac_native.sh'
- job-name: 'macOS 14 native, arm64, no depends, sqlite only, gui'
- - job-type: fuzz
- file-env: './ci/test/00_setup_env_mac_native_fuzz.sh'
- job-name: 'macOS 14 native, arm64, fuzz'
+ configuration:
+ - env_vars: {}
+ - env_vars: { EXPERIMENTAL: 'yes', ASM: 'arm32' }
env:
- DANGER_RUN_CI_ON_HOST: 1
- BASE_ROOT_DIR: ${{ github.workspace }}
+ WRAPPER_CMD: 'qemu-arm'
+ SECP256K1_TEST_ITERS: 16
+ HOST: 'arm-linux-gnueabihf'
+ WITH_VALGRIND: 'no'
+ ECDH: 'yes'
+ RECOVERY: 'yes'
+ EXTRAKEYS: 'yes'
+ SCHNORRSIG: 'yes'
+ MUSIG: 'yes'
+ ELLSWIFT: 'yes'
+ EXPERIMENTAL: 'yes'
+ ECDSA_S2C: 'yes'
+ GENERATOR: 'yes'
+ RANGEPROOF: 'yes'
+ SURJECTIONPROOF: 'yes'
+ WHITELIST: 'yes'
+ ECDSAADAPTOR: 'yes'
+ BPPP: 'yes'
+ SCHNORRSIG_HALFAGG: 'yes'
+ CTIMETESTS: 'no'
steps:
- - name: Checkout
- uses: actions/checkout@v4
+ - *CHECKOUT
+ - *CI_SCRIPT_IN_DOCKER
+ - *PRINT_LOGS
- - name: Clang version
- run: |
- # Use the earliest Xcode supported by the version of macOS denoted in
- # doc/release-notes-empty-template.md and providing at least the
- # minimum clang version denoted in doc/dependencies.md.
- # See: https://developer.apple.com/documentation/xcode-release-notes/xcode-15-release-notes
- sudo xcode-select --switch /Applications/Xcode_15.0.app
- clang --version
+ arm64-debian:
+ name: "arm64: Linux (Debian stable)"
+ runs-on: ubuntu-24.04-arm
+ needs: docker_cache
- - name: Install Homebrew packages
- env:
- HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1
- run: |
- # A workaround for "The `brew link` step did not complete successfully" error.
- brew install --quiet python@3 || brew link --overwrite python@3
- brew install --quiet coreutils ninja pkgconf gnu-getopt ccache boost libevent zeromq qt@5 qrencode
+ env:
+ SECP256K1_TEST_ITERS: 16
+ WITH_VALGRIND: 'no'
+ ECDH: 'yes'
+ RECOVERY: 'yes'
+ EXTRAKEYS: 'yes'
+ SCHNORRSIG: 'yes'
+ MUSIG: 'yes'
+ ELLSWIFT: 'yes'
+ EXPERIMENTAL: 'yes'
+ ECDSA_S2C: 'yes'
+ GENERATOR: 'yes'
+ RANGEPROOF: 'yes'
+ SURJECTIONPROOF: 'yes'
+ WHITELIST: 'yes'
+ ECDSAADAPTOR: 'yes'
+ BPPP: 'yes'
+ SCHNORRSIG_HALFAGG: 'yes'
+ CTIMETESTS: 'no'
+ CC: ${{ matrix.cc }}
- # ELEMENTS
- - name: Override boost@1.85
- run: |
- brew install boost@1.85
- brew link --force --overwrite boost@1.85
- echo "LDFLAGS=-L/opt/homebrew/opt/boost@1.85/lib" >> "$GITHUB_ENV"
- echo "CPPFLAGS=-I/opt/homebrew/opt/boost@1.85/include" >> "$GITHUB_ENV"
+ strategy:
+ fail-fast: false
+ matrix:
+ configuration:
+ - env_vars: {}
+ cc:
+ - 'gcc'
+ - 'clang'
+ - 'gcc-snapshot'
+ - 'clang-snapshot'
- - name: Set Ccache directory
- run: echo "CCACHE_DIR=${RUNNER_TEMP}/ccache_dir" >> "$GITHUB_ENV"
+ steps:
+ - *CHECKOUT
+ - *CI_SCRIPT_IN_DOCKER
+ - *PRINT_LOGS
- - name: Restore Ccache cache
- id: ccache-cache
- uses: actions/cache/restore@v4
- with:
- path: ${{ env.CCACHE_DIR }}
- key: ${{ github.job }}-${{ matrix.job-type }}-ccache-${{ github.run_id }}
- restore-keys: ${{ github.job }}-${{ matrix.job-type }}-ccache-
+ ppc64le_debian:
+ name: "ppc64le: Linux (Debian stable, QEMU)"
+ runs-on: ubuntu-latest
+ needs: docker_cache
- - name: CI script
- run: ./ci/test_run_all.sh
- env:
- FILE_ENV: ${{ matrix.file-env }}
+ strategy:
+ matrix:
+ configuration:
+ - env_vars: {}
- - name: Save Ccache cache
- uses: actions/cache/save@v4
- if: github.event_name != 'pull_request' && steps.ccache-cache.outputs.cache-hit != 'true'
- with:
- path: ${{ env.CCACHE_DIR }}
- # https://github.com/actions/cache/blob/main/tips-and-workarounds.md#update-a-cache
- key: ${{ github.job }}-${{ matrix.job-type }}-ccache-${{ github.run_id }}
+ env:
+ WRAPPER_CMD: 'qemu-ppc64le'
+ SECP256K1_TEST_ITERS: 16
+ HOST: 'powerpc64le-linux-gnu'
+ WITH_VALGRIND: 'no'
+ ECDH: 'yes'
+ RECOVERY: 'yes'
+ EXTRAKEYS: 'yes'
+ SCHNORRSIG: 'yes'
+ MUSIG: 'yes'
+ ELLSWIFT: 'yes'
+ EXPERIMENTAL: 'yes'
+ ECDSA_S2C: 'yes'
+ GENERATOR: 'yes'
+ RANGEPROOF: 'yes'
+ SURJECTIONPROOF: 'yes'
+ WHITELIST: 'yes'
+ ECDSAADAPTOR: 'yes'
+ BPPP: 'yes'
+ SCHNORRSIG_HALFAGG: 'yes'
+ CTIMETESTS: 'no'
- win64-native:
- name: ${{ matrix.job-name }}
- # Use latest image, but hardcode version to avoid silent upgrades (and breaks).
- # See: https://github.com/actions/runner-images#available-images.
- runs-on: windows-2022
+ steps:
+ - *CHECKOUT
+ - *CI_SCRIPT_IN_DOCKER
+ - *PRINT_LOGS
- if: ${{ vars.SKIP_BRANCH_PUSH != 'true' || github.event_name == 'pull_request' }}
+ valgrind_debian:
+ name: "Valgrind ${{ matrix.configuration.binary_arch }} (memcheck)"
+ runs-on: ${{ matrix.configuration.runner }}
+ needs: docker_cache
+
+ strategy:
+ fail-fast: false
+ matrix:
+ configuration:
+ - runner: ubuntu-latest
+ binary_arch: x64
+ env_vars: { CC: 'clang', ASM: 'auto' }
+ - runner: ubuntu-latest
+ binary_arch: i686
+ env_vars: { CC: 'i686-linux-gnu-gcc', HOST: 'i686-linux-gnu', ASM: 'auto' }
+ - runner: ubuntu-24.04-arm
+ binary_arch: arm64
+ env_vars: { CC: 'clang', ASM: 'auto' }
+ - runner: ubuntu-latest
+ binary_arch: x64
+ env_vars: { CC: 'clang', ASM: 'no', ECMULTGENKB: 2, ECMULTWINDOW: 2 }
+ - runner: ubuntu-latest
+ binary_arch: i686
+ env_vars: { CC: 'i686-linux-gnu-gcc', HOST: 'i686-linux-gnu', ASM: 'no', ECMULTGENKB: 2, ECMULTWINDOW: 2 }
+ - runner: ubuntu-24.04-arm
+ binary_arch: arm64
+ env_vars: { CC: 'clang', ASM: 'no', ECMULTGENKB: 2, ECMULTWINDOW: 2 }
env:
- PYTHONUTF8: 1
- TEST_RUNNER_TIMEOUT_FACTOR: 40
+ # The `--error-exitcode` is required to make the test fail if valgrind found errors,
+ # otherwise it will return 0 (https://www.valgrind.org/docs/manual/manual-core.html).
+ WRAPPER_CMD: 'valgrind --error-exitcode=42'
+ ECDH: 'yes'
+ RECOVERY: 'yes'
+ EXTRAKEYS: 'yes'
+ SCHNORRSIG: 'yes'
+ MUSIG: 'yes'
+ ELLSWIFT: 'yes'
+ EXPERIMENTAL: 'yes'
+ ECDSA_S2C: 'yes'
+ GENERATOR: 'yes'
+ RANGEPROOF: 'yes'
+ SURJECTIONPROOF: 'yes'
+ WHITELIST: 'yes'
+ ECDSAADAPTOR: 'yes'
+ BPPP: 'yes'
+ SCHNORRSIG_HALFAGG: 'yes'
+ CTIMETESTS: 'no'
+ SECP256K1_TEST_ITERS: 2
+
+ steps:
+ - *CHECKOUT
+ - *CI_SCRIPT_IN_DOCKER
+ - *PRINT_LOGS
+
+ sanitizers_debian:
+ name: "UBSan, ASan, LSan"
+ runs-on: ubuntu-latest
+ needs: docker_cache
strategy:
fail-fast: false
matrix:
- job-type: [standard, fuzz]
- include:
- - job-type: standard
- generate-options: '-DBUILD_GUI=ON -DWITH_BDB=ON -DWITH_ZMQ=ON -DBUILD_BENCH=ON -DWERROR=ON'
- job-name: 'Win64 native, VS 2022'
- - job-type: fuzz
- generate-options: '-DVCPKG_MANIFEST_NO_DEFAULT_FEATURES=ON -DVCPKG_MANIFEST_FEATURES="sqlite" -DBUILD_GUI=OFF -DBUILD_FOR_FUZZING=ON -DWERROR=ON'
- job-name: 'Win64 native fuzz, VS 2022'
+ 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 }
+
+ env:
+ ECDH: 'yes'
+ RECOVERY: 'yes'
+ EXTRAKEYS: 'yes'
+ SCHNORRSIG: 'yes'
+ MUSIG: 'yes'
+ ELLSWIFT: 'yes'
+ EXPERIMENTAL: 'yes'
+ ECDSA_S2C: 'yes'
+ GENERATOR: 'yes'
+ RANGEPROOF: 'yes'
+ SURJECTIONPROOF: 'yes'
+ WHITELIST: 'yes'
+ ECDSAADAPTOR: 'yes'
+ BPPP: 'yes'
+ SCHNORRSIG_HALFAGG: 'yes'
+ CTIMETESTS: 'no'
+ CFLAGS: '-fsanitize=undefined,address -g'
+ UBSAN_OPTIONS: 'print_stacktrace=1:halt_on_error=1'
+ ASAN_OPTIONS: 'strict_string_checks=1:detect_stack_use_after_return=1:detect_leaks=1'
+ LSAN_OPTIONS: 'use_unaligned=1'
+ SECP256K1_TEST_ITERS: 32
+ SYMBOL_CHECK: 'no'
steps:
- - name: Checkout
- uses: actions/checkout@v4
+ - *CHECKOUT
+ - *CI_SCRIPT_IN_DOCKER
+ - *PRINT_LOGS
- - name: Configure Developer Command Prompt for Microsoft Visual C++
- # Using microsoft/setup-msbuild is not enough.
- uses: ilammy/msvc-dev-cmd@v1
- with:
- arch: x64
+ msan_debian:
+ name: "MSan"
+ runs-on: ubuntu-latest
+ needs: docker_cache
+
+ strategy:
+ fail-fast: false
+ matrix:
+ configuration:
+ - env_vars:
+ CTIMETESTS: 'yes'
+ CFLAGS: '-fsanitize=memory -fsanitize-recover=memory -g'
+ - env_vars:
+ ECMULTGENKB: 2
+ ECMULTWINDOW: 2
+ CTIMETESTS: 'yes'
+ CFLAGS: '-fsanitize=memory -fsanitize-recover=memory -g -O3'
+ - env_vars:
+ # -fsanitize-memory-param-retval is clang's default, but our build system disables it
+ # when ctime_tests when enabled.
+ CFLAGS: '-fsanitize=memory -fsanitize-recover=memory -fsanitize-memory-param-retval -g'
+ CTIMETESTS: 'no'
+ cc:
+ - 'clang'
+ - 'clang-snapshot'
+
+ env:
+ ECDH: 'yes'
+ RECOVERY: 'yes'
+ EXTRAKEYS: 'yes'
+ SCHNORRSIG: 'yes'
+ MUSIG: 'yes'
+ ELLSWIFT: 'yes'
+ EXPERIMENTAL: 'yes'
+ ECDSA_S2C: 'yes'
+ GENERATOR: 'yes'
+ RANGEPROOF: 'yes'
+ SURJECTIONPROOF: 'yes'
+ WHITELIST: 'yes'
+ ECDSAADAPTOR: 'yes'
+ BPPP: 'yes'
+ SCHNORRSIG_HALFAGG: 'yes'
+ CC: ${{ matrix.cc }}
+ SECP256K1_TEST_ITERS: 32
+ ASM: 'no'
+ WITH_VALGRIND: 'no'
+ SYMBOL_CHECK: 'no'
+
+ steps:
+ - *CHECKOUT
+ - *CI_SCRIPT_IN_DOCKER
+ - *PRINT_LOGS
+
+ mingw_debian:
+ name: ${{ matrix.configuration.job_name }}
+ runs-on: ubuntu-latest
+ needs: docker_cache
- - name: Get tool information
+ env:
+ WRAPPER_CMD: 'wine'
+ WITH_VALGRIND: 'no'
+ ECDH: 'yes'
+ RECOVERY: 'yes'
+ EXTRAKEYS: 'yes'
+ SCHNORRSIG: 'yes'
+ MUSIG: 'yes'
+ ELLSWIFT: 'yes'
+ EXPERIMENTAL: 'yes'
+ ECDSA_S2C: 'yes'
+ GENERATOR: 'yes'
+ RANGEPROOF: 'yes'
+ SURJECTIONPROOF: 'yes'
+ WHITELIST: 'yes'
+ ECDSAADAPTOR: 'yes'
+ BPPP: 'yes'
+ SCHNORRSIG_HALFAGG: 'yes'
+ CTIMETESTS: 'no'
+
+ strategy:
+ fail-fast: false
+ matrix:
+ configuration:
+ - job_name: 'x86_64 (mingw32-w64): Windows (Debian stable, Wine)'
+ env_vars:
+ HOST: 'x86_64-w64-mingw32'
+ - job_name: 'i686 (mingw32-w64): Windows (Debian stable, Wine)'
+ env_vars:
+ HOST: 'i686-w64-mingw32'
+
+ steps:
+ - *CHECKOUT
+ - *CI_SCRIPT_IN_DOCKER
+ - *PRINT_LOGS
+
+ x86_64-macos-native:
+ name: "x86_64: macOS Sequoia, Valgrind"
+ runs-on: macos-15-intel
+
+ env:
+ CC: 'clang'
+ HOMEBREW_NO_AUTO_UPDATE: 1
+ HOMEBREW_NO_INSTALL_CLEANUP: 1
+ SYMBOL_CHECK: 'no'
+
+ strategy:
+ fail-fast: false
+ matrix:
+ env_vars:
+ - { WIDEMUL: 'int64', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: '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', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: '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', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: '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', SURJECTIONPROOF: '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', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', WRAPPER_CMD: 'valgrind --error-exitcode=42', SECP256K1_TEST_ITERS: 2 }
+ - { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', CC: 'gcc', WRAPPER_CMD: 'valgrind --error-exitcode=42', SECP256K1_TEST_ITERS: 2 }
+ - { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', CPPFLAGS: '-DVERIFY', CTIMETESTS: 'no' }
+ - BUILD: 'distcheck'
+
+ steps:
+ - *CHECKOUT
+
+ - name: Install Homebrew packages
run: |
- cmake -version | Tee-Object -FilePath "cmake_version"
- Write-Output "---"
- msbuild -version | Tee-Object -FilePath "msbuild_version"
- $env:VCToolsVersion | Tee-Object -FilePath "toolset_version"
- py -3 --version
- Write-Host "PowerShell version $($PSVersionTable.PSVersion.ToString())"
+ brew install --quiet automake libtool gcc
+ ln -s $(brew --prefix gcc)/bin/gcc-?? /usr/local/bin/gcc
+
+ - name: Install and cache Valgrind
+ uses: ./.github/actions/install-homebrew-valgrind
- - name: Using vcpkg with MSBuild
+ - &CI_SCRIPT_ON_HOST
+ name: CI script
+ env: ${{ matrix.env_vars }}
+ run: ./ci/ci.sh
+
+ - &SYMBOL_CHECK_MACOS
+ name: Symbol check
+ env:
+ VIRTUAL_ENV: '${{ github.workspace }}/venv'
run: |
- Set-Location "$env:VCPKG_INSTALLATION_ROOT"
- Add-Content -Path "triplets\x64-windows.cmake" -Value "set(VCPKG_BUILD_TYPE release)"
- Add-Content -Path "triplets\x64-windows-static.cmake" -Value "set(VCPKG_BUILD_TYPE release)"
+ python3 --version
+ python3 -m venv $VIRTUAL_ENV
+ export PATH="$VIRTUAL_ENV/bin:$PATH"
+ python3 -m pip install lief
+ python3 ./tools/symbol-check.py .libs/libsecp256k1.dylib
- - name: vcpkg tools cache
- uses: actions/cache@v4
- with:
- path: C:/vcpkg/downloads/tools
- key: ${{ github.job }}-vcpkg-tools
+ - *PRINT_LOGS
- - name: Restore vcpkg binary cache
- uses: actions/cache/restore@v4
- id: vcpkg-binary-cache
- with:
- path: ~/AppData/Local/vcpkg/archives
- key: ${{ github.job }}-vcpkg-binary-${{ hashFiles('cmake_version', 'msbuild_version', 'toolset_version', 'vcpkg.json') }}
+ arm64-macos-native:
+ name: "ARM64: macOS Sonoma"
+ # See: https://github.com/actions/runner-images#available-images.
+ runs-on: macos-14
+
+ env:
+ CC: 'clang'
+ HOMEBREW_NO_AUTO_UPDATE: 1
+ HOMEBREW_NO_INSTALL_CLEANUP: 1
+ WITH_VALGRIND: 'no'
+ CTIMETESTS: 'no'
+ SYMBOL_CHECK: 'no'
+
+ strategy:
+ fail-fast: false
+ matrix:
+ env_vars:
+ - { WIDEMUL: 'int64', RECOVERY: 'yes', ECDH: 'yes', EXTRAKEYS: 'yes', SCHNORRSIG: 'yes', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: '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', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: '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', MUSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', SURJECTIONPROOF: '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', SURJECTIONPROOF: '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', SURJECTIONPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', CPPFLAGS: '-DVERIFY' }
+ - BUILD: 'distcheck'
- - name: Generate build system
+ steps:
+ - *CHECKOUT
+
+ - name: Install Homebrew packages
run: |
- cmake -B build --preset vs2022-static -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_INSTALLATION_ROOT\scripts\buildsystems\vcpkg.cmake" -DCMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE="${{ github.workspace }}/build/bin" ${{ matrix.generate-options }}
+ brew install --quiet automake libtool gcc
+ ln -s $(brew --prefix gcc)/bin/gcc-?? /usr/local/bin/gcc
- - name: Save vcpkg binary cache
- uses: actions/cache/save@v4
- if: github.event_name != 'pull_request' && steps.vcpkg-binary-cache.outputs.cache-hit != 'true' && matrix.job-type == 'standard'
- with:
- path: ~/AppData/Local/vcpkg/archives
- key: ${{ github.job }}-vcpkg-binary-${{ hashFiles('cmake_version', 'msbuild_version', 'toolset_version', 'vcpkg.json') }}
+ - *CI_SCRIPT_ON_HOST
+ - *SYMBOL_CHECK_MACOS
+ - *PRINT_LOGS
+
+ win64-native:
+ name: ${{ matrix.configuration.job_name }}
+ # See: https://github.com/actions/runner-images#available-images.
+ runs-on: windows-2022
+
+ strategy:
+ fail-fast: false
+ matrix:
+ configuration:
+ - job_name: 'x64 (MSVC): Windows (VS 2022, shared)'
+ cmake_options: '-A x64 -DBUILD_SHARED_LIBS=ON'
+ symbol_check: 'true'
+ - job_name: 'x64 (MSVC): Windows (VS 2022, static)'
+ cmake_options: '-A x64 -DBUILD_SHARED_LIBS=OFF'
+ - job_name: 'x64 (MSVC): Windows (VS 2022, int128_struct)'
+ cmake_options: '-A x64 -DSECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY=int128_struct'
+ - job_name: 'x64 (MSVC): Windows (VS 2022, int128_struct with __(u)mulh)'
+ cmake_options: '-A x64 -DSECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY=int128_struct'
+ cpp_flags: '/DSECP256K1_MSVC_MULH_TEST_OVERRIDE'
+ - job_name: 'x86 (MSVC): Windows (VS 2022)'
+ cmake_options: '-A Win32'
+ - job_name: 'x64 (clang-cl): Windows (VS 2022, shared)'
+ cmake_options: '-T ClangCL -DBUILD_SHARED_LIBS=ON'
+ symbol_check: 'true'
+ - job_name: 'x64 (clang-cl): Windows (VS 2022, static)'
+ cmake_options: '-T ClangCL -DBUILD_SHARED_LIBS=OFF'
+ - job_name: 'x64 (clang-cl): Windows (VS 2022, int128_struct)'
+ cmake_options: '-T ClangCL -DSECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY=int128_struct'
+ - job_name: 'x64 (clang-cl): Windows (VS 2022, int128_struct with __(u)mulh)'
+ cmake_options: '-T ClangCL -DSECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY=int128_struct'
+ cpp_flags: '/DSECP256K1_MSVC_MULH_TEST_OVERRIDE'
+
+ steps:
+ - *CHECKOUT
+
+ - name: Generate buildsystem
+ run: cmake -E env CFLAGS="/WX ${{ matrix.configuration.cpp_flags }}" cmake -B build -DSECP256K1_ENABLE_MODULE_RECOVERY=ON -DSECP256K1_BUILD_EXAMPLES=ON ${{ matrix.configuration.cmake_options }}
- name: Build
- working-directory: build
- run: |
- cmake --build . -j $env:NUMBER_OF_PROCESSORS --config Release
+ run: cmake --build build --config RelWithDebInfo -- /p:UseMultiToolTask=true /maxCpuCount
- - name: Run test suite
- if: matrix.job-type == 'standard'
- working-directory: build
+ - name: Binaries info
+ # Use the bash shell included with Git for Windows.
+ shell: bash
run: |
- ctest --output-on-failure --stop-on-failure -j $env:NUMBER_OF_PROCESSORS -C Release
+ cd build/bin/RelWithDebInfo && file *tests.exe bench*.exe libsecp256k1-*.dll || true
- - name: Run functional tests
- if: matrix.job-type == 'standard'
- working-directory: build
- env:
- BITCOIND: '${{ github.workspace }}\build\bin\elementsd.exe'
- BITCOINCLI: '${{ github.workspace }}\build\bin\elements-cli.exe'
- BITCOINUTIL: '${{ github.workspace }}\build\bin\elements-util.exe'
- BITCOINWALLET: '${{ github.workspace }}\build\bin\elements-wallet.exe'
- TEST_RUNNER_EXTRA: ${{ github.event_name != 'pull_request' && '--extended' || '' }}
- shell: cmd
- run: py -3 test\functional\test_runner.py --jobs %NUMBER_OF_PROCESSORS% --ci --quiet --tmpdirprefix=%RUNNER_TEMP% --combinedlogslen=99999999 --timeout-factor=%TEST_RUNNER_TIMEOUT_FACTOR% %TEST_RUNNER_EXTRA%
+ - name: Symbol check
+ if: ${{ matrix.configuration.symbol_check }}
+ shell: bash
+ run: |
+ py -3 --version
+ py -3 -m pip install lief
+ py -3 ./tools/symbol-check.py build/bin/RelWithDebInfo/libsecp256k1-*.dll
- - name: Clone corpora
- if: matrix.job-type == 'fuzz'
+ - name: Check
run: |
- git clone --depth=1 https://github.com/ElementsProject/qa-assets "$env:RUNNER_TEMP\qa-assets"
- Set-Location "$env:RUNNER_TEMP\qa-assets"
- Write-Host "Using qa-assets repo from commit ..."
- git log -1
-
- - name: Run fuzz tests
- if: matrix.job-type == 'fuzz'
- working-directory: build
- env:
- BITCOINFUZZ: '${{ github.workspace }}\build\bin\fuzz.exe'
+ ctest -C RelWithDebInfo --test-dir build -j ([int]$env:NUMBER_OF_PROCESSORS + 1)
+ build\bin\RelWithDebInfo\bench_ecmult.exe
+ build\bin\RelWithDebInfo\bench_internal.exe
+ build\bin\RelWithDebInfo\bench.exe
+
+ win64-native-headers:
+ name: "x64 (MSVC): C++ (public headers)"
+ # See: https://github.com/actions/runner-images#available-images.
+ runs-on: windows-2022
+
+ steps:
+ - *CHECKOUT
+
+ - name: C++ (public headers)
shell: cmd
run: |
- py -3 test\fuzz\test_runner.py --par %NUMBER_OF_PROCESSORS% --loglevel DEBUG %RUNNER_TEMP%\qa-assets\fuzz_corpora
+ call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
+ cl.exe -c -WX -TP include/*.h
+
+ cxx_fpermissive_debian:
+ name: "C++ -fpermissive (entire project)"
+ runs-on: ubuntu-latest
+ needs: docker_cache
+
+ strategy:
+ matrix:
+ configuration:
+ - env_vars: {}
- asan-lsan-ubsan-integer-no-depends-usdt:
- name: 'ASan + LSan + UBSan + integer, no depends, USDT'
- runs-on: ubuntu-24.04 # has to match container in ci/test/00_setup_env_native_asan.sh for tracing tools
- if: ${{ vars.SKIP_BRANCH_PUSH != 'true' || github.event_name == 'pull_request' }}
- timeout-minutes: 120
env:
- FILE_ENV: "./ci/test/00_setup_env_native_asan.sh"
- DANGER_CI_ON_HOST_FOLDERS: 1
+ CC: 'g++'
+ CFLAGS: '-fpermissive -g'
+ CPPFLAGS: '-DSECP256K1_CPLUSPLUS_TEST_OVERRIDE'
+ WERROR_CFLAGS:
+ ECDH: 'yes'
+ RECOVERY: 'yes'
+ EXTRAKEYS: 'yes'
+ SCHNORRSIG: 'yes'
+ MUSIG: 'yes'
+ ELLSWIFT: 'yes'
+ EXPERIMENTAL: 'yes'
+ ECDSA_S2C: 'yes'
+ GENERATOR: 'yes'
+ RANGEPROOF: 'yes'
+ SURJECTIONPROOF: 'yes'
+ WHITELIST: 'yes'
+ ECDSAADAPTOR: 'yes'
+ BPPP: 'yes'
+ SCHNORRSIG_HALFAGG: 'yes'
+
steps:
- - name: Checkout
- uses: actions/checkout@v4
+ - *CHECKOUT
+ - *CI_SCRIPT_IN_DOCKER
+ - *PRINT_LOGS
- - name: Set CI directories
- run: |
- echo "CCACHE_DIR=${{ runner.temp }}/ccache_dir" >> "$GITHUB_ENV"
- echo "BASE_ROOT_DIR=${{ runner.temp }}" >> "$GITHUB_ENV"
- echo "BASE_BUILD_DIR=${{ runner.temp }}/build-asan" >> "$GITHUB_ENV"
+ cxx_headers_debian:
+ name: "C++ (public headers)"
+ runs-on: ubuntu-latest
+ needs: docker_cache
- - name: Restore Ccache cache
- id: ccache-cache
- uses: actions/cache/restore@v4
+ steps:
+ - *CHECKOUT
+
+ - name: CI script
+ uses: ./.github/actions/run-in-docker-action
with:
- path: ${{ env.CCACHE_DIR }}
- key: ${{ github.job }}-ccache-${{ github.run_id }}
- restore-keys: ${{ github.job }}-ccache-
+ dockerfile: ./ci/linux-debian.Dockerfile
+ scope: ${{ runner.arch }}-${{ needs.docker_cache.outputs.cache_scope }}
+ command: |
+ g++ -Werror include/*.h
+ clang -Werror -x c++-header include/*.h
+
+ sage:
+ name: "SageMath prover"
+ runs-on: ubuntu-latest
+ container:
+ image: sagemath/sagemath:latest
+ options: --user root
- - name: Enable bpfcc script
- # In the image build step, no external environment variables are available,
- # so any settings will need to be written to the settings env file:
- run: sed -i "s|\${INSTALL_BCC_TRACING_TOOLS}|true|g" ./ci/test/00_setup_env_native_asan.sh
+ steps:
+ - *CHECKOUT
- name: CI script
- run: ./ci/test_run_all.sh
+ run: |
+ cd sage
+ sage prove_group_implementations.sage
- - name: Save Ccache cache
- uses: actions/cache/save@v4
- if: github.event_name != 'pull_request' && steps.ccache-cache.outputs.cache-hit != 'true'
- with:
- path: ${{ env.CCACHE_DIR }}
- # https://github.com/actions/cache/blob/main/tips-and-workarounds.md#update-a-cache
- key: ${{ github.job }}-ccache-${{ github.run_id }}
+ release:
+ runs-on: ubuntu-latest
+
+ steps:
+ - *CHECKOUT
+
+ - run: ./autogen.sh && ./configure --enable-dev-mode && make distcheck
+
+ - name: Check installation with Autotools
+ env:
+ CI_INSTALL: ${{ runner.temp }}/${{ github.run_id }}${{ github.action }}/install
+ run: |
+ ./autogen.sh && ./configure --prefix=${{ env.CI_INSTALL }} && make clean && make install && ls -RlAh ${{ env.CI_INSTALL }}
+ gcc -o ecdsa examples/ecdsa.c $(PKG_CONFIG_PATH=${{ env.CI_INSTALL }}/lib/pkgconfig pkg-config --cflags --libs libsecp256k1) -Wl,-rpath,"${{ env.CI_INSTALL }}/lib" && ./ecdsa
+
+ - name: Check installation with CMake
+ env:
+ CI_BUILD: ${{ runner.temp }}/${{ github.run_id }}${{ github.action }}/build
+ CI_INSTALL: ${{ runner.temp }}/${{ github.run_id }}${{ github.action }}/install
+ run: |
+ cmake -B ${{ env.CI_BUILD }} -DCMAKE_INSTALL_PREFIX=${{ env.CI_INSTALL }} && cmake --build ${{ env.CI_BUILD }} && cmake --install ${{ env.CI_BUILD }} && ls -RlAh ${{ env.CI_INSTALL }}
+ gcc -o ecdsa examples/ecdsa.c -I ${{ env.CI_INSTALL }}/include -L ${{ env.CI_INSTALL }}/lib*/ -l secp256k1 -Wl,-rpath,"${{ env.CI_INSTALL }}/lib",-rpath,"${{ env.CI_INSTALL }}/lib64" && ./ecdsa
diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml
new file mode 100644
index 0000000..22e3a6a
--- /dev/null
+++ b/.github/workflows/sync.yml
@@ -0,0 +1,61 @@
+name: Upstream Sync
+
+on:
+ schedule:
+ - cron: '0 0 1 * *'
+ workflow_dispatch:
+
+jobs:
+ sync-upstream:
+ runs-on: ubuntu-latest
+ env:
+ UPSTREAM: "https://github.com/bitcoin-core/secp256k1.git"
+ BASE_BRANCH: "master"
+ UPSTREAM_REF: "upstream/master"
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v6
+ with:
+ fetch-depth: 0
+ token: ${{ secrets.SYNC_PAT }}
+
+ - name: Configure Git
+ run: |
+ git config user.name "github-actions[bot]"
+ git config user.email "github-actions[bot]@users.noreply.github.com"
+
+ - name: Fetch upstream
+ run: |
+ git remote add upstream ${{ env.UPSTREAM }}
+ git fetch upstream
+ gh repo set-default ${{ github.repository }}
+ env:
+ GH_TOKEN: ${{ secrets.SYNC_PAT }}
+
+ - name: Run sync-upstream.sh
+ id: sync
+ run: |
+ OUTPUT=$(./contrib/sync-upstream.sh --switch "${{ env.BASE_BRANCH }}" "${{ env.UPSTREAM_REF }}" 2>&1) || { echo "$OUTPUT"; exit 1; }
+ echo "$OUTPUT"
+ if echo "$OUTPUT" | grep -qv "^No merge commits"; then
+ echo "newcommits=true" >> "$GITHUB_OUTPUT"
+ else
+ echo "Skipping further workflow steps."
+ fi
+
+ - name: Push sync branch
+ id: push
+ if: steps.sync.outputs.newcommits == 'true'
+ run: |
+ if git push -u origin HEAD; then
+ echo "pushed=true" >> "$GITHUB_OUTPUT"
+ else
+ echo "Skipping further workflow steps."
+ fi
+
+ - name: Create pull request
+ if: steps.sync.outputs.newcommits == 'true' && steps.push.outputs.pushed == 'true'
+ env:
+ GH_TOKEN: ${{ secrets.SYNC_PAT }}
+ run: ./gh-pr-create.sh
diff --git a/.gitignore b/.gitignore
index 6bf1892..8658272 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,28 +1,65 @@
-# Build subdirectories.
-/*build*
-!/build_msvc
-
-*.pyc
-
-# Only ignore unexpected patches
-*.patch
-!contrib/guix/patches/*.patch
-!depends/patches/**/*.patch
+bench
+bench_bppp
+bench_ecmult
+bench_generator
+bench_rangeproof
+bench_internal
+bench_whitelist
+noverify_tests
+tests
+exhaustive_tests
+precompute_ecmult_gen
+precompute_ecmult
+ctime_tests
+ecdh_example
+ecdsa_example
+schnorr_example
+ellswift_example
+musig_example
+*.exe
+*.so
+*.a
+*.csv
+*.log
+*.trs
+*.sage.py
-/CMakeUserPresets.json
-# Merge script log
-/merge.log
+Makefile
+configure
+.libs/
+Makefile.in
+aclocal.m4
+autom4te.cache/
+config.log
+config.status
+conftest*
+*.tar.gz
+*.la
+libtool
+.deps/
+.dirstamp
+*.lo
+*.o
+*~
-# Test cache
-/test/cache/
-/test/config.ini
+coverage/
+coverage.html
+coverage.*.html
+*.gcda
+*.gcno
+*.gcov
-# Previous releases
-/releases
+/autotools-aux/
+!/autotools-aux/m4/bitcoin_secp.m4
-#build tests
-test/lint/test_runner/target/
+libsecp256k1.pc
+contrib/gh-pr-create.sh
-/guix-build-*
+### CMake
+/CMakeUserPresets.json
+# CMake build directories.
+/*build*
-/ci/scratch/
+### Python
+__pycache__/
+*.py[oc]
diff --git a/.python-version b/.python-version
deleted file mode 100644
index 1445aee..0000000
--- a/.python-version
+++ /dev/null
@@ -1 +0,0 @@
-3.10.14
diff --git a/.style.yapf b/.style.yapf
deleted file mode 100644
index 350ac63..0000000
--- a/.style.yapf
+++ /dev/null
@@ -1,261 +0,0 @@
-[style]
-# Align closing bracket with visual indentation.
-align_closing_bracket_with_visual_indent=True
-
-# Allow dictionary keys to exist on multiple lines. For example:
-#
-# x = {
-# ('this is the first element of a tuple',
-# 'this is the second element of a tuple'):
-# value,
-# }
-allow_multiline_dictionary_keys=False
-
-# Allow lambdas to be formatted on more than one line.
-allow_multiline_lambdas=False
-
-# Allow splits before the dictionary value.
-allow_split_before_dict_value=True
-
-# Number of blank lines surrounding top-level function and class
-# definitions.
-blank_lines_around_top_level_definition=2
-
-# Insert a blank line before a class-level docstring.
-blank_line_before_class_docstring=False
-
-# Insert a blank line before a module docstring.
-blank_line_before_module_docstring=False
-
-# Insert a blank line before a 'def' or 'class' immediately nested
-# within another 'def' or 'class'. For example:
-#
-# class Foo:
-# # <------ this blank line
-# def method():
-# ...
-blank_line_before_nested_class_or_def=False
-
-# Do not split consecutive brackets. Only relevant when
-# dedent_closing_brackets is set. For example:
-#
-# call_func_that_takes_a_dict(
-# {
-# 'key1': 'value1',
-# 'key2': 'value2',
-# }
-# )
-#
-# would reformat to:
-#
-# call_func_that_takes_a_dict({
-# 'key1': 'value1',
-# 'key2': 'value2',
-# })
-coalesce_brackets=False
-
-# The column limit.
-column_limit=160
-
-# The style for continuation alignment. Possible values are:
-#
-# - SPACE: Use spaces for continuation alignment. This is default behavior.
-# - FIXED: Use fixed number (CONTINUATION_INDENT_WIDTH) of columns
-# (ie: CONTINUATION_INDENT_WIDTH/INDENT_WIDTH tabs) for continuation
-# alignment.
-# - LESS: Slightly left if cannot vertically align continuation lines with
-# indent characters.
-# - VALIGN-RIGHT: Vertically align continuation lines with indent
-# characters. Slightly right (one more indent character) if cannot
-# vertically align continuation lines with indent characters.
-#
-# For options FIXED, and VALIGN-RIGHT are only available when USE_TABS is
-# enabled.
-continuation_align_style=SPACE
-
-# Indent width used for line continuations.
-continuation_indent_width=4
-
-# Put closing brackets on a separate line, dedented, if the bracketed
-# expression can't fit in a single line. Applies to all kinds of brackets,
-# including function definitions and calls. For example:
-#
-# config = {
-# 'key1': 'value1',
-# 'key2': 'value2',
-# } # <--- this bracket is dedented and on a separate line
-#
-# time_series = self.remote_client.query_entity_counters(
-# entity='dev3246.region1',
-# key='dns.query_latency_tcp',
-# transform=Transformation.AVERAGE(window=timedelta(seconds=60)),
-# start_ts=now()-timedelta(days=3),
-# end_ts=now(),
-# ) # <--- this bracket is dedented and on a separate line
-dedent_closing_brackets=False
-
-# Disable the heuristic which places each list element on a separate line
-# if the list is comma-terminated.
-disable_ending_comma_heuristic=False
-
-# Place each dictionary entry onto its own line.
-each_dict_entry_on_separate_line=True
-
-# The regex for an i18n comment. The presence of this comment stops
-# reformatting of that line, because the comments are required to be
-# next to the string they translate.
-i18n_comment=
-
-# The i18n function call names. The presence of this function stops
-# reformatting on that line, because the string it has cannot be moved
-# away from the i18n comment.
-i18n_function_call=
-
-# Indent the dictionary value if it cannot fit on the same line as the
-# dictionary key. For example:
-#
-# config = {
-# 'key1':
-# 'value1',
-# 'key2': value1 +
-# value2,
-# }
-indent_dictionary_value=False
-
-# The number of columns to use for indentation.
-indent_width=4
-
-# Join short lines into one line. E.g., single line 'if' statements.
-join_multiple_lines=True
-
-# Do not include spaces around selected binary operators. For example:
-#
-# 1 + 2 * 3 - 4 / 5
-#
-# will be formatted as follows when configured with "*,/":
-#
-# 1 + 2*3 - 4/5
-#
-no_spaces_around_selected_binary_operators=
-
-# Use spaces around default or named assigns.
-spaces_around_default_or_named_assign=False
-
-# Use spaces around the power operator.
-spaces_around_power_operator=False
-
-# The number of spaces required before a trailing comment.
-spaces_before_comment=2
-
-# Insert a space between the ending comma and closing bracket of a list,
-# etc.
-space_between_ending_comma_and_closing_bracket=True
-
-# Split before arguments
-split_all_comma_separated_values=False
-
-# Split before arguments if the argument list is terminated by a
-# comma.
-split_arguments_when_comma_terminated=False
-
-# Set to True to prefer splitting before '&', '|' or '^' rather than
-# after.
-split_before_bitwise_operator=True
-
-# Split before the closing bracket if a list or dict literal doesn't fit on
-# a single line.
-split_before_closing_bracket=True
-
-# Split before a dictionary or set generator (comp_for). For example, note
-# the split before the 'for':
-#
-# foo = {
-# variable: 'Hello world, have a nice day!'
-# for variable in bar if variable != 42
-# }
-split_before_dict_set_generator=True
-
-# Split before the '.' if we need to split a longer expression:
-#
-# foo = ('This is a really long string: {}, {}, {}, {}'.format(a, b, c, d))
-#
-# would reformat to something like:
-#
-# foo = ('This is a really long string: {}, {}, {}, {}'
-# .format(a, b, c, d))
-split_before_dot=False
-
-# Split after the opening paren which surrounds an expression if it doesn't
-# fit on a single line.
-split_before_expression_after_opening_paren=False
-
-# If an argument / parameter list is going to be split, then split before
-# the first argument.
-split_before_first_argument=False
-
-# Set to True to prefer splitting before 'and' or 'or' rather than
-# after.
-split_before_logical_operator=True
-
-# Split named assignments onto individual lines.
-split_before_named_assigns=True
-
-# Set to True to split list comprehensions and generators that have
-# non-trivial expressions and multiple clauses before each of these
-# clauses. For example:
-#
-# result = [
-# a_long_var + 100 for a_long_var in xrange(1000)
-# if a_long_var % 10]
-#
-# would reformat to something like:
-#
-# result = [
-# a_long_var + 100
-# for a_long_var in xrange(1000)
-# if a_long_var % 10]
-split_complex_comprehension=False
-
-# The penalty for splitting right after the opening bracket.
-split_penalty_after_opening_bracket=30
-
-# The penalty for splitting the line after a unary operator.
-split_penalty_after_unary_operator=10000
-
-# The penalty for splitting right before an if expression.
-split_penalty_before_if_expr=0
-
-# The penalty of splitting the line around the '&', '|', and '^'
-# operators.
-split_penalty_bitwise_operator=300
-
-# The penalty for splitting a list comprehension or generator
-# expression.
-split_penalty_comprehension=80
-
-# The penalty for characters over the column limit.
-split_penalty_excess_character=7000
-
-# The penalty incurred by adding a line split to the unwrapped line. The
-# more line splits added the higher the penalty.
-split_penalty_for_added_line_split=30
-
-# The penalty of splitting a list of "import as" names. For example:
-#
-# from a_very_long_or_indented_module_name_yada_yad import (long_argument_1,
-# long_argument_2,
-# long_argument_3)
-#
-# would reformat to something like:
-#
-# from a_very_long_or_indented_module_name_yada_yad import (
-# long_argument_1, long_argument_2, long_argument_3)
-split_penalty_import_names=0
-
-# The penalty of splitting the line around the 'and' and 'or'
-# operators.
-split_penalty_logical_operator=300
-
-# Use the Tab character for indentation.
-use_tabs=False
-
diff --git a/.tx/config b/.tx/config
deleted file mode 100644
index b5a9aba..0000000
--- a/.tx/config
+++ /dev/null
@@ -1,7 +0,0 @@
-[main]
-host = https://www.transifex.com
-
-[o:bitcoin:p:bitcoin:r:qt-translation-029x]
-file_filter = src/qt/locale/bitcoin_<lang>.xlf
-source_file = src/qt/locale/bitcoin_en.xlf
-source_lang = en
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..48cbdaf
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,217 @@
+**This changelog is not the libsecp256k1-zkp's changelog.**
+Instead, it is the changelog of the upstream library [libsecp256k1](https://github.com/bitcoin-core/secp256k1).
+
+# Changelog
+
+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/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## [Unreleased]
+
+## [0.7.1] - 2026-01-26
+
+#### Changed
+ - Tests: Introduced a unit test framework with support for parallel test execution, selective test running, and named command-line arguments. Run `./tests -help` for usage information.
+
+#### Fixed
+ - Increased the number of cases where the library attempts to clear secrets from the stack.
+ - build: Fixed x86_64 assembly feature check that could fail when user-provided `CFLAGS` included `-Werror`. This would cause the build to fall back to the slower C implementation instead of using the optimized x86_64 assembly.
+
+#### ABI Compatibility
+The ABI is backward compatible with version 0.7.0.
+
+## [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=<value>` 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
+ - New module `musig` implements the MuSig2 multisignature scheme according to the [BIP 327 specification](https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki). See:
+ - Header file `include/secp256k1_musig.h` which defines the new API.
+ - Document `doc/musig.md` for further notes on API usage.
+ - Usage example `examples/musig.c`.
+ - New CMake variable `SECP256K1_APPEND_LDFLAGS` for appending linker flags to the build command.
+
+#### Changed
+ - API functions now use a significantly more robust method to clear secrets from the stack before returning. However, secret clearing remains a best-effort security measure and cannot guarantee complete removal.
+ - Any type `secp256k1_foo` can now be forward-declared using `typedef struct secp256k1_foo secp256k1_foo;` (or also `struct secp256k1_foo;` in C++).
+ - Organized CMake build artifacts into dedicated directories (`bin/` for executables, `lib/` for libraries) to improve build output structure and Windows shared library compatibility.
+
+#### Removed
+ - Removed the `secp256k1_scratch_space` struct and its associated functions `secp256k1_scratch_space_create` and `secp256k1_scratch_space_destroy` because the scratch space was unused in the API.
+
+#### ABI Compatibility
+The symbols `secp256k1_scratch_space_create` and `secp256k1_scratch_space_destroy` were removed.
+Otherwise, the library maintains backward compatibility with versions 0.3.x through 0.5.x.
+
+## [0.5.1] - 2024-08-01
+
+#### Added
+ - Added usage example for an ElligatorSwift key exchange.
+
+#### Changed
+ - The default size of the precomputed table for signing was changed from 22 KiB to 86 KiB. The size can be changed with the configure option `--ecmult-gen-kb` (`SECP256K1_ECMULT_GEN_KB` for CMake).
+ - "auto" is no longer an accepted value for the `--with-ecmult-window` and `--with-ecmult-gen-kb` configure options (this also applies to `SECP256K1_ECMULT_WINDOW_SIZE` and `SECP256K1_ECMULT_GEN_KB` in CMake). To achieve the same configuration as previously provided by the "auto" value, omit setting the configure option explicitly.
+
+#### Fixed
+ - Fixed compilation when the extrakeys module is disabled.
+
+#### ABI Compatibility
+The ABI is backward compatible with versions 0.5.0, 0.4.x and 0.3.x.
+
+## [0.5.0] - 2024-05-06
+
+#### Added
+ - New function `secp256k1_ec_pubkey_sort` that sorts public keys using lexicographic (of compressed serialization) order.
+
+#### Changed
+ - The implementation of the point multiplication algorithm used for signing and public key generation was changed, resulting in improved performance for those operations.
+ - The related configure option `--ecmult-gen-precision` was replaced with `--ecmult-gen-kb` (`SECP256K1_ECMULT_GEN_KB` for CMake).
+ - This changes the supported precomputed table sizes for these operations. The new supported sizes are 2 KiB, 22 KiB, or 86 KiB (while the old supported sizes were 32 KiB, 64 KiB, or 512 KiB).
+
+#### ABI Compatibility
+The ABI is backward compatible with versions 0.4.x and 0.3.x.
+
+## [0.4.1] - 2023-12-21
+
+#### Changed
+ - The point multiplication algorithm used for ECDH operations (module `ecdh`) was replaced with a slightly faster one.
+ - Optional handwritten x86_64 assembly for field operations was removed because modern C compilers are able to output more efficient assembly. This change results in a significant speedup of some library functions when handwritten x86_64 assembly is enabled (`--with-asm=x86_64` in GNU Autotools, `-DSECP256K1_ASM=x86_64` in CMake), which is the default on x86_64. Benchmarks with GCC 10.5.0 show a 10% speedup for `secp256k1_ecdsa_verify` and `secp256k1_schnorrsig_verify`.
+
+#### ABI Compatibility
+The ABI is backward compatible with versions 0.4.0 and 0.3.x.
+
+## [0.4.0] - 2023-09-04
+
+#### Added
+ - New module `ellswift` implements ElligatorSwift encoding for public keys and x-only Diffie-Hellman key exchange for them.
+ ElligatorSwift permits representing secp256k1 public keys as 64-byte arrays which cannot be distinguished from uniformly random. See:
+ - Header file `include/secp256k1_ellswift.h` which defines the new API.
+ - Document `doc/ellswift.md` which explains the mathematical background of the scheme.
+ - The [paper](https://eprint.iacr.org/2022/759) on which the scheme is based.
+ - We now test the library with unreleased development snapshots of GCC and Clang. This gives us an early chance to catch miscompilations and constant-time issues introduced by the compiler (such as those that led to the previous two releases).
+
+#### Fixed
+ - Fixed symbol visibility in Windows DLL builds, where three internal library symbols were wrongly exported.
+
+#### Changed
+ - When consuming libsecp256k1 as a static library on Windows, the user must now define the `SECP256K1_STATIC` macro before including `secp256k1.h`.
+
+#### ABI Compatibility
+This release is backward compatible with the ABI of 0.3.0, 0.3.1, and 0.3.2. Symbol visibility is now believed to be handled properly on supported platforms and is now considered to be part of the ABI. Please report any improperly exported symbols as a bug.
+
+## [0.3.2] - 2023-05-13
+We strongly recommend updating to 0.3.2 if you use or plan to use GCC >=13 to compile libsecp256k1. When in doubt, check the GCC version using `gcc -v`.
+
+#### Security
+ - Module `ecdh`: Fix "constant-timeness" issue with GCC 13.1 (and potentially future versions of GCC) that could leave applications using libsecp256k1's ECDH module vulnerable to a timing side-channel attack. The fix avoids secret-dependent control flow during ECDH computations when libsecp256k1 is compiled with GCC 13.1.
+
+#### Fixed
+ - Fixed an old bug that permitted compilers to potentially output bad assembly code on x86_64. In theory, it could lead to a crash or a read of unrelated memory, but this has never been observed on any compilers so far.
+
+#### Changed
+ - Various improvements and changes to CMake builds. CMake builds remain experimental.
+ - Made API versioning consistent with GNU Autotools builds.
+ - Switched to `BUILD_SHARED_LIBS` variable for controlling whether to build a static or a shared library.
+ - Added `SECP256K1_INSTALL` variable for the controlling whether to install the build artefacts.
+ - Renamed asm build option `arm` to `arm32`. Use `--with-asm=arm32` instead of `--with-asm=arm` (GNU Autotools), and `-DSECP256K1_ASM=arm32` instead of `-DSECP256K1_ASM=arm` (CMake).
+
+#### ABI Compatibility
+The ABI is compatible with versions 0.3.0 and 0.3.1.
+
+## [0.3.1] - 2023-04-10
+We strongly recommend updating to 0.3.1 if you use or plan to use Clang >=14 to compile libsecp256k1, e.g., Xcode >=14 on macOS has Clang >=14. When in doubt, check the Clang version using `clang -v`.
+
+#### Security
+ - Fix "constant-timeness" issue with Clang >=14 that could leave applications using libsecp256k1 vulnerable to a timing side-channel attack. The fix avoids secret-dependent control flow and secret-dependent memory accesses in conditional moves of memory objects when libsecp256k1 is compiled with Clang >=14.
+
+#### Added
+ - Added tests against [Project Wycheproof's](https://github.com/C2SP/wycheproof/) set of ECDSA test vectors (Bitcoin "low-S" variant), a fixed set of test cases designed to trigger various edge cases.
+
+#### Changed
+ - Increased minimum required CMake version to 3.13. CMake builds remain experimental.
+
+#### ABI Compatibility
+The ABI is compatible with version 0.3.0.
+
+## [0.3.0] - 2023-03-08
+
+#### Added
+ - Added experimental support for CMake builds. Traditional GNU Autotools builds (`./configure` and `make`) remain fully supported.
+ - Usage examples: Added a recommended method for securely clearing sensitive data, e.g., secret keys, from memory.
+ - Tests: Added a new test binary `noverify_tests`. This binary runs the tests without some additional checks present in the ordinary `tests` binary and is thereby closer to production binaries. The `noverify_tests` binary is automatically run as part of the `make check` target.
+
+#### Fixed
+ - Fixed declarations of API variables for MSVC (`__declspec(dllimport)`). This fixes MSVC builds of programs which link against a libsecp256k1 DLL dynamically and use API variables (and not only API functions). Unfortunately, the MSVC linker now will emit warning `LNK4217` when trying to link against libsecp256k1 statically. Pass `/ignore:4217` to the linker to suppress this warning.
+
+#### Changed
+ - Forbade cloning or destroying `secp256k1_context_static`. Create a new context instead of cloning the static context. (If this change breaks your code, your code is probably wrong.)
+ - Forbade randomizing (copies of) `secp256k1_context_static`. Randomizing a copy of `secp256k1_context_static` did not have any effect and did not provide defense-in-depth protection against side-channel attacks. Create a new context if you want to benefit from randomization.
+
+#### Removed
+ - Removed the configuration header `src/libsecp256k1-config.h`. We recommend passing flags to `./configure` or `cmake` to set configuration options (see `./configure --help` or `cmake -LH`). If you cannot or do not want to use one of the supported build systems, pass configuration flags such as `-DSECP256K1_ENABLE_MODULE_SCHNORRSIG` manually to the compiler (see the file `configure.ac` for supported flags).
+
+#### ABI Compatibility
+Due to changes in the API regarding `secp256k1_context_static` described above, the ABI is *not* compatible with previous versions.
+
+## [0.2.0] - 2022-12-12
+
+#### Added
+ - Added usage examples for common use cases in a new `examples/` directory.
+ - Added `secp256k1_selftest`, to be used in conjunction with `secp256k1_context_static`.
+ - Added support for 128-bit wide multiplication on MSVC for x86_64 and arm64, giving roughly a 20% speedup on those platforms.
+
+#### Changed
+ - Enabled modules `schnorrsig`, `extrakeys` and `ecdh` by default in `./configure`.
+ - The `secp256k1_nonce_function_rfc6979` nonce function, used by default by `secp256k1_ecdsa_sign`, now reduces the message hash modulo the group order to match the specification. This only affects improper use of ECDSA signing API.
+
+#### Deprecated
+ - Deprecated context flags `SECP256K1_CONTEXT_VERIFY` and `SECP256K1_CONTEXT_SIGN`. Use `SECP256K1_CONTEXT_NONE` instead.
+ - Renamed `secp256k1_context_no_precomp` to `secp256k1_context_static`.
+ - Module `schnorrsig`: renamed `secp256k1_schnorrsig_sign` to `secp256k1_schnorrsig_sign32`.
+
+#### ABI Compatibility
+Since this is the first release, we do not compare application binary interfaces.
+However, there are earlier unreleased versions of libsecp256k1 that are *not* ABI compatible with this version.
+
+## [0.1.0] - 2013-03-05 to 2021-12-25
+
+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.7.1...HEAD
+[0.7.1]: https://github.com/bitcoin-core/secp256k1/compare/v0.7.0...v0.7.1
+[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
+[0.4.1]: https://github.com/bitcoin-core/secp256k1/compare/v0.4.0...v0.4.1
+[0.4.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.2...v0.4.0
+[0.3.2]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.1...v0.3.2
+[0.3.1]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.0...v0.3.1
+[0.3.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.2.0...v0.3.0
+[0.2.0]: https://github.com/bitcoin-core/secp256k1/compare/423b6d19d373f1224fd671a982584d7e7900bc93..v0.2.0
+[0.1.0]: https://github.com/bitcoin-core/secp256k1/commit/423b6d19d373f1224fd671a982584d7e7900bc93
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a540db7..c894f41 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,679 +1,331 @@
-# Copyright (c) 2023-present The Bitcoin Core developers
-# Distributed under the MIT software license, see the accompanying
-# file COPYING or https://opensource.org/license/mit/.
-
-# Ubuntu 22.04 LTS Jammy Jellyfish, https://wiki.ubuntu.com/Releases, EOSS in June 2027:
-# - CMake 3.22.1, https://packages.ubuntu.com/jammy/cmake
-#
-# Centos Stream 9, https://www.centos.org/cl-vs-cs/#end-of-life, EOL in May 2027:
-# - CMake 3.26.5, https://mirror.stream.centos.org/9-stream/AppStream/x86_64/os/Packages/
cmake_minimum_required(VERSION 3.22)
-if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
- message(FATAL_ERROR "In-source builds are not allowed.")
-endif()
-
-if(POLICY CMP0171)
- # `codegen` is a reserved target name.
- # See: https://cmake.org/cmake/help/latest/policy/CMP0171.html
- cmake_policy(SET CMP0171 NEW)
-endif()
-
#=============================
# Project / Package metadata
#=============================
-set(CLIENT_NAME "Elements Core")
-set(CLIENT_VERSION_MAJOR 28)
-set(CLIENT_VERSION_MINOR 99)
-set(CLIENT_VERSION_BUILD 0)
-set(CLIENT_VERSION_RC 0)
-set(CLIENT_VERSION_IS_RELEASE "false")
-set(COPYRIGHT_YEAR "2025")
-
-# During the enabling of the CXX and CXXOBJ languages, we modify
-# CMake's compiler/linker invocation strings by appending the content
-# of the user-defined `APPEND_*` variables, which allows overriding
-# any flag. We also ensure that the APPEND_* flags are considered
-# during CMake's tests, which use the `try_compile()` command.
-#
-# CMake's docs state that the `CMAKE_TRY_COMPILE_PLATFORM_VARIABLES`
-# variable "is meant to be set by CMake's platform information modules
-# for the current toolchain, or by a toolchain file." We do our best
-# to set it before the `project()` command.
-set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES
- CMAKE_CXX_COMPILE_OBJECT
- CMAKE_OBJCXX_COMPILE_OBJECT
- CMAKE_CXX_LINK_EXECUTABLE
-)
-
-project(ElementsCore
- VERSION ${CLIENT_VERSION_MAJOR}.${CLIENT_VERSION_MINOR}.${CLIENT_VERSION_BUILD}
- DESCRIPTION "Elements sidechain client software"
- HOMEPAGE_URL "https://elementsproject.org/"
- LANGUAGES NONE
+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.7.2
+ 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
)
-
-set(CLIENT_VERSION_STRING ${PROJECT_VERSION})
-if(CLIENT_VERSION_RC GREATER 0)
- string(APPEND CLIENT_VERSION_STRING "rc${CLIENT_VERSION_RC}")
-endif()
-
-set(COPYRIGHT_HOLDERS "The %s developers")
-set(COPYRIGHT_HOLDERS_FINAL "The Elements Project developers")
-set(CLIENT_BUGREPORT "https://github.com/ElementsProject/elements/issues")
+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
+# rules for updating the version can be found here:
+# 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 6)
+set(${PROJECT_NAME}_LIB_VERSION_REVISION 2)
+set(${PROJECT_NAME}_LIB_VERSION_AGE 0)
#=============================
# Language setup
#=============================
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT CMAKE_HOST_APPLE)
- # We do not use the install_name_tool when cross-compiling for macOS.
- # So disable this tool check in further enable_language() commands.
- set(CMAKE_PLATFORM_HAS_INSTALLNAME FALSE)
-endif()
-enable_language(CXX)
-set(CMAKE_CXX_STANDARD 20)
-set(CMAKE_CXX_STANDARD_REQUIRED ON)
-set(CMAKE_CXX_EXTENSIONS OFF)
-
-list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/module)
-include(ProcessConfigurations)
-
-# Flatten static lib dependencies.
-# Without this, if libfoo.a depends on libbar.a, libfoo's objects can't begin
-# to be compiled until libbar.a has been created.
-if (NOT DEFINED CMAKE_OPTIMIZE_DEPENDENCIES)
- set(CMAKE_OPTIMIZE_DEPENDENCIES TRUE)
-endif()
+set(CMAKE_C_STANDARD 90)
+set(CMAKE_C_EXTENSIONS OFF)
#=============================
# Configurable options
#=============================
-include(CMakeDependentOption)
-# When adding a new option, end the <help_text> with a full stop for consistency.
-option(BUILD_DAEMON "Build elementsd executable." ON)
-option(BUILD_GUI "Build elements-qt executable." OFF)
-option(BUILD_CLI "Build elements-cli executable." ON)
-
-option(BUILD_TESTS "Build test_bitcoin executable." ON)
-option(BUILD_TX "Build elements-tx executable." ${BUILD_TESTS})
-option(BUILD_UTIL "Build elements-util executable." ${BUILD_TESTS})
-
-option(BUILD_UTIL_CHAINSTATE "Build experimental bitcoin-chainstate executable." OFF)
-option(BUILD_KERNEL_LIB "Build experimental bitcoinkernel library." ${BUILD_UTIL_CHAINSTATE})
-
-option(ENABLE_WALLET "Enable wallet." ON)
-option(WITH_SQLITE "Enable SQLite wallet support." ${ENABLE_WALLET})
-if(WITH_SQLITE)
- if(VCPKG_TARGET_TRIPLET)
- # Use of the `unofficial::` namespace is a vcpkg package manager convention.
- find_package(unofficial-sqlite3 CONFIG REQUIRED)
+if(libsecp256k1_IS_TOP_LEVEL)
+ option(BUILD_SHARED_LIBS "Build shared libraries." ON)
+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
+# dependencies while processing.
+option(SECP256K1_ENABLE_MODULE_ECDH "Enable ECDH module." ON)
+option(SECP256K1_ENABLE_MODULE_RECOVERY "Enable ECDSA pubkey recovery module." OFF)
+option(SECP256K1_ENABLE_MODULE_EXTRAKEYS "Enable extrakeys module." ON)
+option(SECP256K1_ENABLE_MODULE_SCHNORRSIG "Enable schnorrsig module." ON)
+option(SECP256K1_ENABLE_MODULE_MUSIG "Enable musig module." ON)
+option(SECP256K1_ENABLE_MODULE_ELLSWIFT "Enable ElligatorSwift module." ON)
+
+option(SECP256K1_ENABLE_MODULE_GENERATOR "Enable NUMS generator module." ON)
+option(SECP256K1_ENABLE_MODULE_RANGEPROOF "Enable Range proof module." ON)
+option(SECP256K1_ENABLE_MODULE_SURJECTIONPROOF "Enable Surjection proof module." ON)
+option(SECP256K1_ENABLE_MODULE_WHITELIST "Enable key whitelist module." ON)
+option(SECP256K1_ENABLE_MODULE_ECDSA_ADAPTOR "Enable ecdsa adaptor signatures module." ON)
+option(SECP256K1_ENABLE_MODULE_ECDSA_S2C "Enable ECDSA sign-to-contract module." ON)
+option(SECP256K1_ENABLE_MODULE_BPPP "Enable Bulletproofs++ module." ON)
+option(SECP256K1_ENABLE_MODULE_SCHNORRSIG_HALFAGG "Enable schnorrsig half-aggregation module." ON)
+
+option(SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS "Enable external default callback functions." OFF)
+if(SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS)
+ add_compile_definitions(USE_EXTERNAL_DEFAULT_CALLBACKS=1)
+endif()
+
+set(SECP256K1_ECMULT_WINDOW_SIZE 15 CACHE STRING "Window size for ecmult precomputation for verification, specified as integer in range [2..24]. The default value is a reasonable setting for desktop machines (currently 15). [default=15]")
+set_property(CACHE SECP256K1_ECMULT_WINDOW_SIZE PROPERTY STRINGS 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24)
+include(CheckStringOptionValue)
+check_string_option_value(SECP256K1_ECMULT_WINDOW_SIZE)
+add_compile_definitions(ECMULT_WINDOW_SIZE=${SECP256K1_ECMULT_WINDOW_SIZE})
+
+set(SECP256K1_ECMULT_GEN_KB 86 CACHE STRING "The size of the precomputed table for signing in multiples of 1024 bytes (on typical platforms). Larger values result in possibly better signing or key generation performance at the cost of a larger table. Valid choices are 2, 22, 86. The default value is a reasonable setting for desktop machines (currently 86). [default=86]")
+set_property(CACHE SECP256K1_ECMULT_GEN_KB PROPERTY STRINGS 2 22 86)
+check_string_option_value(SECP256K1_ECMULT_GEN_KB)
+if(SECP256K1_ECMULT_GEN_KB EQUAL 2)
+ add_compile_definitions(COMB_BLOCKS=2)
+ add_compile_definitions(COMB_TEETH=5)
+elseif(SECP256K1_ECMULT_GEN_KB EQUAL 22)
+ add_compile_definitions(COMB_BLOCKS=11)
+ add_compile_definitions(COMB_TEETH=6)
+elseif(SECP256K1_ECMULT_GEN_KB EQUAL 86)
+ add_compile_definitions(COMB_BLOCKS=43)
+ add_compile_definitions(COMB_TEETH=6)
+endif()
+
+set(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY "OFF" CACHE STRING "Test-only override of the (autodetected by the C code) \"widemul\" setting. Legal values are: \"OFF\", \"int128_struct\", \"int128\" or \"int64\". [default=OFF]")
+set_property(CACHE SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY PROPERTY STRINGS "OFF" "int128_struct" "int128" "int64")
+check_string_option_value(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY)
+if(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY)
+ string(TOUPPER "${SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY}" widemul_upper_value)
+ add_compile_definitions(USE_FORCE_WIDEMUL_${widemul_upper_value}=1)
+endif()
+mark_as_advanced(FORCE SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY)
+
+set(SECP256K1_ASM "AUTO" CACHE STRING "Assembly to use: \"AUTO\", \"OFF\", \"x86_64\" or \"arm32\" (experimental). [default=AUTO]")
+set_property(CACHE SECP256K1_ASM PROPERTY STRINGS "AUTO" "OFF" "x86_64" "arm32")
+check_string_option_value(SECP256K1_ASM)
+if(SECP256K1_ASM STREQUAL "arm32")
+ enable_language(ASM)
+ include(CheckArm32Assembly)
+ check_arm32_assembly()
+ if(HAVE_ARM32_ASM)
+ add_compile_definitions(USE_EXTERNAL_ASM=1)
else()
- find_package(SQLite3 3.7.17 REQUIRED)
- endif()
- set(USE_SQLITE ON)
-endif()
-option(WITH_BDB "Enable Berkeley DB (BDB) wallet support." OFF)
-cmake_dependent_option(WARN_INCOMPATIBLE_BDB "Warn when using a Berkeley DB (BDB) version other than 4.8." ON "WITH_BDB" OFF)
-if(WITH_BDB)
- find_package(BerkeleyDB 4.8 MODULE REQUIRED)
- set(USE_BDB ON)
- if(NOT BerkeleyDB_VERSION VERSION_EQUAL 4.8)
- message(WARNING "Found Berkeley DB (BDB) other than 4.8.\n"
- "BDB (legacy) wallets opened by this build will not be portable!"
- )
- if(WARN_INCOMPATIBLE_BDB)
- message(WARNING "If this is intended, pass \"-DWARN_INCOMPATIBLE_BDB=OFF\".\n"
- "Passing \"-DWITH_BDB=OFF\" will suppress this warning."
- )
- endif()
- endif()
-endif()
-cmake_dependent_option(BUILD_WALLET_TOOL "Build elements-wallet tool." ${BUILD_TESTS} "ENABLE_WALLET" OFF)
-
-option(ENABLE_HARDENING "Attempt to harden the resulting executables." ON)
-option(REDUCE_EXPORTS "Attempt to reduce exported symbols in the resulting executables." OFF)
-option(WERROR "Treat compiler warnings as errors." OFF)
-option(WITH_CCACHE "Attempt to use ccache for compiling." ON)
-
-option(WITH_ZMQ "Enable ZMQ notifications." OFF)
-if(WITH_ZMQ)
- find_package(ZeroMQ 4.0.0 MODULE REQUIRED)
-endif()
-
-option(WITH_USDT "Enable tracepoints for Userspace, Statically Defined Tracing." OFF)
-if(WITH_USDT)
- find_package(USDT MODULE REQUIRED)
-endif()
-
-option(ENABLE_LIQUID "Enable build that defaults to -chain=liquidv1." OFF)
-if(ENABLE_LIQUID)
- add_compile_definitions(LIQUID=1)
-endif()
-
-cmake_dependent_option(ENABLE_EXTERNAL_SIGNER "Enable external signer support." ON "NOT WIN32" OFF)
-
-cmake_dependent_option(WITH_QRENCODE "Enable QR code support." ON "BUILD_GUI" OFF)
-if(WITH_QRENCODE)
- find_package(QRencode MODULE REQUIRED)
- set(USE_QRCODE TRUE)
-endif()
-
-cmake_dependent_option(WITH_DBUS "Enable DBus support." ON "CMAKE_SYSTEM_NAME STREQUAL \"Linux\" AND BUILD_GUI" OFF)
-
-option(WITH_MULTIPROCESS "Build multiprocess elements-node and elements-gui executables in addition to monolithic elementsd and elements-qt executables. Requires libmultiprocess library. Experimental." OFF)
-if(WITH_MULTIPROCESS)
- find_package(Libmultiprocess REQUIRED COMPONENTS Lib)
- find_package(LibmultiprocessNative REQUIRED COMPONENTS Bin
- NAMES Libmultiprocess
- )
-endif()
-
-cmake_dependent_option(BUILD_GUI_TESTS "Build test_elements-qt executable." ON "BUILD_GUI;BUILD_TESTS" OFF)
-if(BUILD_GUI)
- set(qt_components Core Gui Widgets LinguistTools)
- if(ENABLE_WALLET)
- list(APPEND qt_components Network)
- endif()
- if(WITH_DBUS)
- list(APPEND qt_components DBus)
- set(USE_DBUS TRUE)
- endif()
- if(BUILD_GUI_TESTS)
- list(APPEND qt_components Test)
- endif()
- find_package(Qt 5.11.3 MODULE REQUIRED
- COMPONENTS ${qt_components}
- )
- unset(qt_components)
-endif()
-
-option(BUILD_BENCH "Build bench_bitcoin executable." OFF)
-option(BUILD_FUZZ_BINARY "Build fuzz binary." OFF)
-option(BUILD_FOR_FUZZING "Build for fuzzing. Enabling this will disable all other targets and override BUILD_FUZZ_BINARY." OFF)
-
-option(INSTALL_MAN "Install man pages." ON)
-
-set(APPEND_CPPFLAGS "" CACHE STRING "Preprocessor flags that are appended to the command line after all other flags added by the build system. This variable is intended for debugging and special builds.")
-set(APPEND_CFLAGS "" CACHE STRING "C compiler flags that are appended to the command line after all other flags added by the build system. This variable is intended for debugging and special builds.")
-set(APPEND_CXXFLAGS "" CACHE STRING "(Objective) C++ compiler flags that are appended to the command line after all other flags added by the build system. This variable is intended for debugging and special builds.")
-set(APPEND_LDFLAGS "" CACHE STRING "Linker flags that are appended to the command line after all other flags added by the build system. This variable is intended for debugging and special builds.")
-# Appending to this low-level rule variables is the only way to
-# guarantee that the flags appear at the end of the command line.
-string(APPEND CMAKE_CXX_COMPILE_OBJECT " ${APPEND_CPPFLAGS} ${APPEND_CXXFLAGS}")
-string(APPEND CMAKE_CXX_CREATE_SHARED_LIBRARY " ${APPEND_LDFLAGS}")
-string(APPEND CMAKE_CXX_LINK_EXECUTABLE " ${APPEND_LDFLAGS}")
-
-set(configure_warnings)
-
-include(CheckLinkerSupportsPIE)
-check_linker_supports_pie(configure_warnings)
-
-# The core_interface library aims to encapsulate common build flags.
-# It is a usage requirement for all targets except for secp256k1, which
-# gets its flags by other means.
-add_library(core_interface INTERFACE)
-add_library(core_interface_relwithdebinfo INTERFACE)
-add_library(core_interface_debug INTERFACE)
-target_link_libraries(core_interface INTERFACE
- $<$<CONFIG:RelWithDebInfo>:core_interface_relwithdebinfo>
- $<$<CONFIG:Debug>:core_interface_debug>
-)
-# Elements: secp256k1.h is included from widely-used headers (confidential_validation.h, blind.h);
-# make the secp256k1 include directory available globally.
-target_include_directories(core_interface INTERFACE ${PROJECT_SOURCE_DIR}/src/secp256k1/include)
-
-if(BUILD_FOR_FUZZING)
- message(WARNING "BUILD_FOR_FUZZING=ON will disable all other targets and force BUILD_FUZZ_BINARY=ON.")
- set(BUILD_DAEMON OFF)
- set(BUILD_CLI OFF)
- set(BUILD_TX OFF)
- set(BUILD_UTIL OFF)
- set(BUILD_UTIL_CHAINSTATE OFF)
- set(BUILD_KERNEL_LIB OFF)
- set(BUILD_WALLET_TOOL OFF)
- set(BUILD_GUI OFF)
- set(ENABLE_EXTERNAL_SIGNER OFF)
- set(WITH_ZMQ OFF)
- set(BUILD_TESTS OFF)
- set(BUILD_GUI_TESTS OFF)
- set(BUILD_BENCH OFF)
- set(BUILD_FUZZ_BINARY ON)
-
- target_compile_definitions(core_interface INTERFACE
- FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
- )
-endif()
-
-include(TryAppendCXXFlags)
-include(TryAppendLinkerFlag)
-
-# Redefine/adjust per-configuration flags.
-target_compile_definitions(core_interface_debug INTERFACE
- DEBUG
- DEBUG_LOCKORDER
- DEBUG_LOCKCONTENTION
- RPC_DOC_CHECK
- ABORT_ON_FAILED_ASSUME
-)
-
-if(WIN32)
- #[=[
- This build system supports two ways to build binaries for Windows.
-
- 1. Building on Windows using MSVC.
- Implementation notes:
- - /DWIN32 and /D_WINDOWS definitions are included into the CMAKE_CXX_FLAGS_INIT
- and CMAKE_CXX_FLAGS_INIT variables by default.
- - A run-time library is selected using the CMAKE_MSVC_RUNTIME_LIBRARY variable.
- - MSVC-specific options, for example, /Zc:__cplusplus, are additionally required.
-
- 2. Cross-compiling using MinGW.
- Implementation notes:
- - WIN32 and _WINDOWS definitions must be provided explicitly.
- - A run-time library must be specified explicitly using _MT definition.
- ]=]
-
- target_compile_definitions(core_interface INTERFACE
- _WIN32_WINNT=0x0A00
- _WIN32_IE=0x0A00
- WIN32_LEAN_AND_MEAN
- NOMINMAX
- )
-
- if(MSVC)
- if(VCPKG_TARGET_TRIPLET MATCHES "-static")
- set(msvc_library_linkage "")
- else()
- set(msvc_library_linkage "DLL")
- endif()
- set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>${msvc_library_linkage}")
- unset(msvc_library_linkage)
-
- target_compile_definitions(core_interface INTERFACE
- _UNICODE;UNICODE
- )
- target_compile_options(core_interface INTERFACE
- /utf-8
- /Zc:preprocessor
- /Zc:__cplusplus
- /sdl
- )
- # Improve parallelism in MSBuild.
- # See: https://devblogs.microsoft.com/cppblog/improved-parallelism-in-msbuild/.
- list(APPEND CMAKE_VS_GLOBALS "UseMultiToolTask=true")
+ message(FATAL_ERROR "ARM32 assembly requested but not available.")
endif()
-
- if(MINGW)
- target_compile_definitions(core_interface INTERFACE
- WIN32
- _WINDOWS
- _MT
- )
- # Avoid the use of aligned vector instructions when building for Windows.
- # See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54412.
- try_append_cxx_flags("-Wa,-muse-unaligned-vector-move" TARGET core_interface SKIP_LINK)
- try_append_linker_flag("-static" TARGET core_interface)
- # We support Windows 10+, however it's not possible to set these values accordingly,
- # due to a bug in mingw-w64. See https://sourceforge.net/p/mingw-w64/bugs/968/.
- # As a best effort, target Windows 8.
- try_append_linker_flag("-Wl,--major-subsystem-version,6" TARGET core_interface)
- try_append_linker_flag("-Wl,--minor-subsystem-version,2" TARGET core_interface)
- endif()
-
- # Workaround producing large object files, which cannot be handled by the assembler.
- # More likely to happen with no, or lower levels of optimisation.
- # See discussion in https://github.com/bitcoin/bitcoin/issues/28109.
- if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
- try_append_cxx_flags("/bigobj" TARGET core_interface_debug SKIP_LINK)
+elseif(SECP256K1_ASM)
+ include(CheckX86_64Assembly)
+ check_x86_64_assembly()
+ if(HAVE_X86_64_ASM)
+ set(SECP256K1_ASM "x86_64")
+ add_compile_definitions(USE_ASM_X86_64=1)
+ elseif(SECP256K1_ASM STREQUAL "AUTO")
+ set(SECP256K1_ASM "OFF")
else()
- try_append_cxx_flags("-Wa,-mbig-obj" TARGET core_interface_debug SKIP_LINK)
+ message(FATAL_ERROR "x86_64 assembly requested but not available.")
endif()
endif()
-# Use 64-bit off_t on 32-bit Linux.
-if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SIZEOF_VOID_P EQUAL 4)
- # Ensure 64-bit offsets are used for filesystem accesses for 32-bit compilation.
- target_compile_definitions(core_interface INTERFACE
- _FILE_OFFSET_BITS=64
- )
-endif()
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
- target_compile_definitions(core_interface INTERFACE OBJC_OLD_DISPATCH_PROTOTYPES=0)
- # These flags are specific to ld64, and may cause issues with other linkers.
- # For example: GNU ld will interpret -dead_strip as -de and then try and use
- # "ad_strip" as the symbol for the entry point.
- try_append_linker_flag("-Wl,-dead_strip" TARGET core_interface)
- try_append_linker_flag("-Wl,-dead_strip_dylibs" TARGET core_interface)
- if(CMAKE_HOST_APPLE)
- try_append_linker_flag("-Wl,-headerpad_max_install_names" TARGET core_interface)
+option(SECP256K1_EXPERIMENTAL "Allow experimental configuration options." OFF)
+if(NOT SECP256K1_EXPERIMENTAL)
+ if(SECP256K1_ASM STREQUAL "arm32")
+ message(FATAL_ERROR "ARM32 assembly is experimental. Use -DSECP256K1_EXPERIMENTAL=ON to allow.")
endif()
endif()
-set(THREADS_PREFER_PTHREAD_FLAG ON)
-find_package(Threads REQUIRED)
-target_link_libraries(core_interface INTERFACE
- Threads::Threads
-)
-
-add_library(sanitize_interface INTERFACE)
-target_link_libraries(core_interface INTERFACE sanitize_interface)
-if(SANITIZERS)
- # First check if the compiler accepts flags. If an incompatible pair like
- # -fsanitize=address,thread is used here, this check will fail. This will also
- # fail if a bad argument is passed, e.g. -fsanitize=undfeined
- try_append_cxx_flags("-fsanitize=${SANITIZERS}" TARGET sanitize_interface
- RESULT_VAR cxx_supports_sanitizers
- SKIP_LINK
- )
- if(NOT cxx_supports_sanitizers)
- message(FATAL_ERROR "Compiler did not accept requested flags.")
- endif()
-
- # Some compilers (e.g. GCC) require additional libraries like libasan,
- # libtsan, libubsan, etc. Make sure linking still works with the sanitize
- # flag. This is a separate check so we can give a better error message when
- # the sanitize flags are supported by the compiler but the actual sanitizer
- # libs are missing.
- try_append_linker_flag("-fsanitize=${SANITIZERS}" VAR SANITIZER_LDFLAGS
- SOURCE "
- #include <cstdint>
- #include <cstddef>
- extern \"C\" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return 0; }
- __attribute__((weak)) // allow for libFuzzer linking
- int main() { return 0; }
- "
- RESULT_VAR linker_supports_sanitizers
- )
- if(NOT linker_supports_sanitizers)
- message(FATAL_ERROR "Linker did not accept requested flags, you are missing required libraries.")
+set(SECP256K1_VALGRIND "AUTO" CACHE STRING "Build with extra checks for running inside Valgrind. [default=AUTO]")
+set_property(CACHE SECP256K1_VALGRIND PROPERTY STRINGS "AUTO" "OFF" "ON")
+check_string_option_value(SECP256K1_VALGRIND)
+if(SECP256K1_VALGRIND)
+ find_package(Valgrind MODULE)
+ if(Valgrind_FOUND)
+ set(SECP256K1_VALGRIND ON)
+ include_directories(${Valgrind_INCLUDE_DIR})
+ add_compile_definitions(VALGRIND)
+ elseif(SECP256K1_VALGRIND STREQUAL "AUTO")
+ set(SECP256K1_VALGRIND OFF)
+ else()
+ message(FATAL_ERROR "Valgrind support requested but valgrind/memcheck.h header not available.")
endif()
endif()
-target_link_options(sanitize_interface INTERFACE ${SANITIZER_LDFLAGS})
-
-if(BUILD_FUZZ_BINARY)
- target_link_libraries(core_interface INTERFACE ${FUZZ_LIBS})
- include(CheckSourceCompilesWithFlags)
- check_cxx_source_compiles_with_flags("
- #include <cstdint>
- #include <cstddef>
- extern \"C\" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return 0; }
- // No main() function.
- " FUZZ_BINARY_LINKS_WITHOUT_MAIN_FUNCTION
- LDFLAGS ${SANITIZER_LDFLAGS}
- LINK_LIBRARIES ${FUZZ_LIBS}
- )
-endif()
-include(AddBoostIfNeeded)
-add_boost_if_needed()
+option(SECP256K1_BUILD_BENCHMARK "Build benchmarks." ON)
+option(SECP256K1_BUILD_TESTS "Build tests." ON)
+option(SECP256K1_BUILD_EXHAUSTIVE_TESTS "Build exhaustive tests." ON)
+option(SECP256K1_BUILD_CTIME_TESTS "Build constant-time tests." ${SECP256K1_VALGRIND})
+option(SECP256K1_BUILD_EXAMPLES "Build examples." OFF)
-if(BUILD_DAEMON OR BUILD_GUI OR BUILD_CLI OR BUILD_TESTS OR BUILD_BENCH OR BUILD_FUZZ_BINARY)
- find_package(Libevent 2.1.8 MODULE REQUIRED)
-endif()
-
-include(cmake/introspection.cmake)
-
-include(cmake/ccache.cmake)
-
-add_library(warn_interface INTERFACE)
-target_link_libraries(core_interface INTERFACE warn_interface)
+# Redefine configuration flags.
+# We leave assertions on, because they are only used in the examples, and we want them always on there.
if(MSVC)
- try_append_cxx_flags("/W3" TARGET warn_interface SKIP_LINK)
- try_append_cxx_flags("/wd4018" TARGET warn_interface SKIP_LINK)
- try_append_cxx_flags("/wd4146" TARGET warn_interface SKIP_LINK)
- try_append_cxx_flags("/wd4244" TARGET warn_interface SKIP_LINK)
- try_append_cxx_flags("/wd4267" TARGET warn_interface SKIP_LINK)
- try_append_cxx_flags("/wd4715" TARGET warn_interface SKIP_LINK)
- try_append_cxx_flags("/wd4805" TARGET warn_interface SKIP_LINK)
- target_compile_definitions(warn_interface INTERFACE
- _CRT_SECURE_NO_WARNINGS
- _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING
- )
+ string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
+ string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
+ string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}")
+ # Match GCC/Clang's size-optimization macro for the inline guard
+ add_compile_definitions($<$<CONFIG:MinSizeRel>:__OPTIMIZE_SIZE__=1>)
else()
- try_append_cxx_flags("-Wall" TARGET warn_interface SKIP_LINK)
- try_append_cxx_flags("-Wextra" TARGET warn_interface SKIP_LINK)
- try_append_cxx_flags("-Wgnu" TARGET warn_interface SKIP_LINK)
- # Some compilers will ignore -Wformat-security without -Wformat, so just combine the two here.
- try_append_cxx_flags("-Wformat -Wformat-security" TARGET warn_interface SKIP_LINK)
- try_append_cxx_flags("-Wvla" TARGET warn_interface SKIP_LINK)
- try_append_cxx_flags("-Wshadow-field" TARGET warn_interface SKIP_LINK)
- try_append_cxx_flags("-Wthread-safety" TARGET warn_interface SKIP_LINK)
- try_append_cxx_flags("-Wloop-analysis" TARGET warn_interface SKIP_LINK)
- try_append_cxx_flags("-Wredundant-decls" TARGET warn_interface SKIP_LINK)
- try_append_cxx_flags("-Wunused-member-function" TARGET warn_interface SKIP_LINK)
- try_append_cxx_flags("-Wdate-time" TARGET warn_interface SKIP_LINK)
- try_append_cxx_flags("-Wconditional-uninitialized" TARGET warn_interface SKIP_LINK)
- try_append_cxx_flags("-Wduplicated-branches" TARGET warn_interface SKIP_LINK)
- try_append_cxx_flags("-Wduplicated-cond" TARGET warn_interface SKIP_LINK)
- try_append_cxx_flags("-Wlogical-op" TARGET warn_interface SKIP_LINK)
- try_append_cxx_flags("-Woverloaded-virtual" TARGET warn_interface SKIP_LINK)
- try_append_cxx_flags("-Wsuggest-override" TARGET warn_interface SKIP_LINK)
- try_append_cxx_flags("-Wimplicit-fallthrough" TARGET warn_interface SKIP_LINK)
- try_append_cxx_flags("-Wunreachable-code" TARGET warn_interface SKIP_LINK)
- try_append_cxx_flags("-Wdocumentation" TARGET warn_interface SKIP_LINK)
- try_append_cxx_flags("-Wself-assign" TARGET warn_interface SKIP_LINK)
- try_append_cxx_flags("-Wbidi-chars=any" TARGET warn_interface SKIP_LINK)
- try_append_cxx_flags("-Wundef" TARGET warn_interface SKIP_LINK)
-
- # Some compilers (gcc) ignore unknown -Wno-* options, but warn about all
- # unknown options if any other warning is produced. Test the -Wfoo case, and
- # set the -Wno-foo case if it works.
- try_append_cxx_flags("-Wunused-parameter" TARGET warn_interface SKIP_LINK
- IF_CHECK_PASSED "-Wno-unused-parameter"
- )
+ string(REGEX REPLACE "-DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
+ string(REGEX REPLACE "-DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
+ string(REGEX REPLACE "-DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}")
+ # Prefer -O2 optimization level. (-O3 is CMake's default for Release for many compilers.)
+ string(REGEX REPLACE "-O3( |$)" "-O2\\1" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
endif()
-configure_file(cmake/script/Coverage.cmake Coverage.cmake USE_SOURCE_PERMISSIONS COPYONLY)
-configure_file(cmake/script/CoverageFuzz.cmake CoverageFuzz.cmake USE_SOURCE_PERMISSIONS COPYONLY)
-configure_file(cmake/script/CoverageInclude.cmake.in CoverageInclude.cmake USE_SOURCE_PERMISSIONS @ONLY)
-configure_file(cmake/script/cov_tool_wrapper.sh.in cov_tool_wrapper.sh.in USE_SOURCE_PERMISSIONS COPYONLY)
-configure_file(contrib/filter-lcov.py filter-lcov.py USE_SOURCE_PERMISSIONS COPYONLY)
-
-# Don't allow extended (non-ASCII) symbols in identifiers. This is easier for code review.
-try_append_cxx_flags("-fno-extended-identifiers" TARGET core_interface SKIP_LINK)
-
-# Avoiding the `-ffile-prefix-map` compiler option because it implies
-# `-fcoverage-prefix-map` on Clang or `-fprofile-prefix-map` on GCC,
-# which can cause issues with coverage builds, particularly when using
-# Clang in the OSS-Fuzz environment due to its use of other options
-# and a third party script, or with GCC.
-try_append_cxx_flags("-fdebug-prefix-map=A=B" TARGET core_interface SKIP_LINK
- IF_CHECK_PASSED "-fdebug-prefix-map=${PROJECT_SOURCE_DIR}/src=."
+# Define custom "Coverage" build type.
+set(CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O0 -DCOVERAGE=1 --coverage" CACHE STRING
+ "Flags used by the C compiler during \"Coverage\" builds."
+ FORCE
)
-try_append_cxx_flags("-fmacro-prefix-map=A=B" TARGET core_interface SKIP_LINK
- IF_CHECK_PASSED "-fmacro-prefix-map=${PROJECT_SOURCE_DIR}/src=."
+set(CMAKE_EXE_LINKER_FLAGS_COVERAGE "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} --coverage" CACHE STRING
+ "Flags used for linking binaries during \"Coverage\" builds."
+ FORCE
+)
+set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} --coverage" CACHE STRING
+ "Flags used by the shared libraries linker during \"Coverage\" builds."
+ FORCE
+)
+mark_as_advanced(
+ CMAKE_C_FLAGS_COVERAGE
+ CMAKE_EXE_LINKER_FLAGS_COVERAGE
+ CMAKE_SHARED_LINKER_FLAGS_COVERAGE
)
-# Currently all versions of gcc are subject to a class of bugs, see the
-# gccbug_90348 test case (only reproduces on GCC 11 and earlier) and
-# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111843. To work around that, set
-# -fstack-reuse=none for all gcc builds. (Only gcc understands this flag).
-try_append_cxx_flags("-fstack-reuse=none" TARGET core_interface)
-
-if(ENABLE_HARDENING)
- add_library(hardening_interface INTERFACE)
- target_link_libraries(core_interface INTERFACE hardening_interface)
- if(MSVC)
- try_append_linker_flag("/DYNAMICBASE" TARGET hardening_interface)
- try_append_linker_flag("/HIGHENTROPYVA" TARGET hardening_interface)
- try_append_linker_flag("/NXCOMPAT" TARGET hardening_interface)
+if(PROJECT_IS_TOP_LEVEL)
+ get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+ set(default_build_type "RelWithDebInfo")
+ if(is_multi_config)
+ set(CMAKE_CONFIGURATION_TYPES "${default_build_type}" "Release" "Debug" "MinSizeRel" "Coverage" CACHE STRING
+ "Supported configuration types."
+ FORCE
+ )
else()
-
- # _FORTIFY_SOURCE requires that there is some level of optimization,
- # otherwise it does nothing and just creates a compiler warning.
- try_append_cxx_flags("-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3"
- RESULT_VAR cxx_supports_fortify_source
- SOURCE "int main() {
- # if !defined __OPTIMIZE__ || __OPTIMIZE__ <= 0
- #error
- #endif
- }"
+ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY
+ STRINGS "${default_build_type}" "Release" "Debug" "MinSizeRel" "Coverage"
)
- if(cxx_supports_fortify_source)
- target_compile_options(hardening_interface INTERFACE
- -U_FORTIFY_SOURCE
- -D_FORTIFY_SOURCE=3
+ if(NOT CMAKE_BUILD_TYPE)
+ message(STATUS "Setting build type to \"${default_build_type}\" as none was specified")
+ set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING
+ "Choose the type of build."
+ FORCE
)
endif()
- unset(cxx_supports_fortify_source)
-
- try_append_cxx_flags("-Wstack-protector" TARGET hardening_interface SKIP_LINK)
- try_append_cxx_flags("-fstack-protector-all" TARGET hardening_interface)
- try_append_cxx_flags("-fcf-protection=full" TARGET hardening_interface)
-
- if(MINGW)
- # stack-clash-protection is a no-op for Windows.
- # See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90458 for more details.
- else()
- try_append_cxx_flags("-fstack-clash-protection" TARGET hardening_interface)
- endif()
-
- if(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
- if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
- try_append_cxx_flags("-mbranch-protection=bti" TARGET hardening_interface SKIP_LINK)
- else()
- try_append_cxx_flags("-mbranch-protection=standard" TARGET hardening_interface SKIP_LINK)
- endif()
- endif()
-
- try_append_linker_flag("-Wl,--enable-reloc-section" TARGET hardening_interface)
- try_append_linker_flag("-Wl,--dynamicbase" TARGET hardening_interface)
- try_append_linker_flag("-Wl,--nxcompat" TARGET hardening_interface)
- try_append_linker_flag("-Wl,--high-entropy-va" TARGET hardening_interface)
- try_append_linker_flag("-Wl,-z,relro" TARGET hardening_interface)
- try_append_linker_flag("-Wl,-z,now" TARGET hardening_interface)
- try_append_linker_flag("-Wl,-z,separate-code" TARGET hardening_interface)
- if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
- try_append_linker_flag("-Wl,-fixup_chains" TARGET hardening_interface)
- endif()
endif()
endif()
-if(REDUCE_EXPORTS)
- set(CMAKE_CXX_VISIBILITY_PRESET hidden)
- try_append_linker_flag("-Wl,--exclude-libs,ALL" TARGET core_interface)
- try_append_linker_flag("-Wl,-no_exported_symbols" VAR CMAKE_EXE_LINKER_FLAGS)
-endif()
-
-if(WERROR)
- if(MSVC)
- set(werror_flag "/WX")
- else()
- set(werror_flag "-Werror")
- endif()
- try_append_cxx_flags(${werror_flag} TARGET core_interface SKIP_LINK RESULT_VAR compiler_supports_werror)
- if(NOT compiler_supports_werror)
- message(FATAL_ERROR "WERROR set but ${werror_flag} is not usable.")
+include(TryAppendCFlags)
+if(MSVC)
+ # For both cl and clang-cl compilers.
+ try_append_c_flags(/W3) # Production quality warning level.
+ # Eliminate deprecation warnings for the older, less secure functions.
+ 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()
+ # Keep the following commands ordered lexicographically.
+ try_append_c_flags(-pedantic)
+ try_append_c_flags(-Wcast-align) # GCC >= 2.95.
+ try_append_c_flags(-Wcast-align=strict) # GCC >= 8.0.
+ try_append_c_flags(-Wconditional-uninitialized) # Clang >= 3.0 only.
+ try_append_c_flags(-Wextra) # GCC >= 3.4, this is the newer name of -W, which we don't use because older GCCs will warn about unused functions.
+ try_append_c_flags(-Wleading-whitespace=spaces) # GCC >= 15.0
+ try_append_c_flags(-Wnested-externs)
+ try_append_c_flags(-Wno-long-long) # GCC >= 3.0, -Wlong-long is implied by -pedantic.
+ try_append_c_flags(-Wno-overlength-strings) # GCC >= 4.2, -Woverlength-strings is implied by -pedantic.
+ try_append_c_flags(-Wno-unused-function) # GCC >= 3.0, -Wunused-function is implied by -Wall.
+ try_append_c_flags(-Wreserved-identifier) # Clang >= 13.0 only.
+ try_append_c_flags(-Wshadow)
+ try_append_c_flags(-Wstrict-prototypes)
+ try_append_c_flags(-Wtrailing-whitespace=any) # GCC >= 15.0
+ try_append_c_flags(-Wundef)
+endif()
+
+set(print_msan_notice)
+if(SECP256K1_BUILD_CTIME_TESTS)
+ include(CheckMemorySanitizer)
+ check_memory_sanitizer(msan_enabled)
+ if(msan_enabled)
+ try_append_c_flags(-fno-sanitize-memory-param-retval)
+ set(print_msan_notice YES)
endif()
- unset(werror_flag)
+ unset(msan_enabled)
endif()
-# Prefer Unix-style package components over frameworks on macOS.
-# This improves compatibility with Python version managers.
-set(Python3_FIND_FRAMEWORK LAST CACHE STRING "")
-# Search for generic names before more specialized ones. This
-# improves compatibility with Python version managers that use shims.
-set(Python3_FIND_UNVERSIONED_NAMES FIRST CACHE STRING "")
-mark_as_advanced(Python3_FIND_FRAMEWORK Python3_FIND_UNVERSIONED_NAMES)
-find_package(Python3 3.10 COMPONENTS Interpreter)
-if(Python3_EXECUTABLE)
- set(PYTHON_COMMAND ${Python3_EXECUTABLE})
-else()
- list(APPEND configure_warnings
- "Minimum required Python not found. Utils and rpcauth tests are disabled."
- )
+set(SECP256K1_APPEND_CFLAGS "" CACHE STRING "Compiler flags that are appended to the command line after all other flags added by the build system. This variable is intended for debugging and special builds.")
+if(SECP256K1_APPEND_CFLAGS)
+ # Appending to this low-level rule variable is the only way to
+ # guarantee that the flags appear at the end of the command line.
+ string(APPEND CMAKE_C_COMPILE_OBJECT " ${SECP256K1_APPEND_CFLAGS}")
endif()
-target_compile_definitions(core_interface INTERFACE ${DEPENDS_COMPILE_DEFINITIONS})
-target_compile_definitions(core_interface_relwithdebinfo INTERFACE ${DEPENDS_COMPILE_DEFINITIONS_RELWITHDEBINFO})
-target_compile_definitions(core_interface_debug INTERFACE ${DEPENDS_COMPILE_DEFINITIONS_DEBUG})
-
-# If the {CXX,LD}FLAGS environment variables are defined during building depends
-# and configuring this build system, their content might be duplicated.
-if(DEFINED ENV{CXXFLAGS})
- deduplicate_flags(CMAKE_CXX_FLAGS)
-endif()
-if(DEFINED ENV{LDFLAGS})
- deduplicate_flags(CMAKE_EXE_LINKER_FLAGS)
+set(SECP256K1_APPEND_LDFLAGS "" CACHE STRING "Linker flags that are appended to the command line after all other flags added by the build system. This variable is intended for debugging and special builds.")
+if(SECP256K1_APPEND_LDFLAGS)
+ # Appending to this low-level rule variable is the only way to
+ # guarantee that the flags appear at the end of the command line.
+ string(APPEND CMAKE_C_CREATE_SHARED_LIBRARY " ${SECP256K1_APPEND_LDFLAGS}")
+ string(APPEND CMAKE_C_LINK_EXECUTABLE " ${SECP256K1_APPEND_LDFLAGS}")
endif()
-if(BUILD_TESTS)
- enable_testing()
+if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY)
+ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
endif()
-
-if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.29)
- # have "make test" depend on "make all"
- set(CMAKE_SKIP_TEST_ALL_DEPENDENCY FALSE)
+if(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY)
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
endif()
-
-# TODO: The `CMAKE_SKIP_BUILD_RPATH` variable setting can be deleted
-# in the future after reordering Guix script commands to
-# perform binary checks after the installation step.
-# Relevant discussions:
-# - https://github.com/hebasto/bitcoin/pull/236#issuecomment-2183120953
-# - https://github.com/bitcoin/bitcoin/pull/30312#issuecomment-2191235833
-# NetBSD always requires runtime paths to be set for executables.
-if(CMAKE_SYSTEM_NAME STREQUAL "NetBSD")
- set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
-else()
- set(CMAKE_SKIP_BUILD_RPATH TRUE)
- set(CMAKE_SKIP_INSTALL_RPATH TRUE)
+if(NOT CMAKE_ARCHIVE_OUTPUT_DIRECTORY)
+ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
endif()
-add_subdirectory(test)
-add_subdirectory(doc)
-
add_subdirectory(src)
-
-include(cmake/tests.cmake)
-
-include(Maintenance)
-setup_split_debug_script()
-add_maintenance_targets()
-add_windows_deploy_target()
-add_macos_deploy_target()
+if(SECP256K1_BUILD_EXAMPLES)
+ add_subdirectory(examples)
+endif()
message("\n")
-message("Configure summary")
-message("=================")
-message("Executables:")
-message(" elementsd ............................ ${BUILD_DAEMON}")
-if(BUILD_DAEMON AND WITH_MULTIPROCESS)
- set(elements_daemon_status ON)
+message("secp256k1 configure summary")
+message("===========================")
+message("Build artifacts:")
+if(BUILD_SHARED_LIBS)
+ set(library_type "Shared")
else()
- set(elements_daemon_status OFF)
-endif()
-message(" elements-node (multiprocess) ......... ${elements_daemon_status}")
-message(" elements-qt (GUI) .................... ${BUILD_GUI}")
-if(BUILD_GUI AND WITH_MULTIPROCESS)
- set(bitcoin_gui_status ON)
-else()
- set(bitcoin_gui_status OFF)
-endif()
-message(" elements-gui (GUI, multiprocess) .... ${bitcoin_gui_status}")
-message(" elements-cli ........................ ${BUILD_CLI}")
-message(" elements-tx ......................... ${BUILD_TX}")
-message(" elements-util ....................... ${BUILD_UTIL}")
-message(" elements-wallet ..................... ${BUILD_WALLET_TOOL}")
-message(" bitcoin-chainstate (experimental) ... ${BUILD_UTIL_CHAINSTATE}")
-message(" libbitcoinkernel (experimental) ..... ${BUILD_KERNEL_LIB}")
+ set(library_type "Static")
+endif()
+
+message(" library type ........................ ${library_type}")
+message("Optional modules:")
+message(" ECDH ................................ ${SECP256K1_ENABLE_MODULE_ECDH}")
+message(" ECDSA pubkey recovery ............... ${SECP256K1_ENABLE_MODULE_RECOVERY}")
+message(" extrakeys ........................... ${SECP256K1_ENABLE_MODULE_EXTRAKEYS}")
+message(" schnorrsig .......................... ${SECP256K1_ENABLE_MODULE_SCHNORRSIG}")
+message(" musig ............................... ${SECP256K1_ENABLE_MODULE_MUSIG}")
+message(" ElligatorSwift ...................... ${SECP256K1_ENABLE_MODULE_ELLSWIFT}")
+message(" generator ........................... ${SECP256K1_ENABLE_MODULE_GENERATOR}")
+message(" rangeproof .......................... ${SECP256K1_ENABLE_MODULE_RANGEPROOF}")
+message(" surjectionproof ..................... ${SECP256K1_ENABLE_MODULE_SURJECTIONPROOF}")
+message(" whitelist ........................... ${SECP256K1_ENABLE_MODULE_WHITELIST}")
+message(" ecdsa-s2c ........................... ${SECP256K1_ENABLE_MODULE_ECDSA_S2C}")
+message(" ecdsa-adaptor ....................... ${SECP256K1_ENABLE_MODULE_ECDSA_ADAPTOR}")
+message(" bppp ................................ ${SECP256K1_ENABLE_MODULE_BPPP}")
+message(" schnorrsig-halfagg .................. ${SECP256K1_ENABLE_MODULE_SCHNORRSIG_HALFAGG}")
+message("Parameters:")
+message(" ecmult window size .................. ${SECP256K1_ECMULT_WINDOW_SIZE}")
+message(" ecmult gen table size ............... ${SECP256K1_ECMULT_GEN_KB} KiB")
message("Optional features:")
-message(" wallet support ...................... ${ENABLE_WALLET}")
-if(ENABLE_WALLET)
- message(" - descriptor wallets (SQLite) ...... ${WITH_SQLITE}")
- message(" - legacy wallets (Berkeley DB) ..... ${WITH_BDB}")
-endif()
-message(" liquid build ........................ ${ENABLE_LIQUID}")
-message(" external signer ..................... ${ENABLE_EXTERNAL_SIGNER}")
-message(" ZeroMQ .............................. ${WITH_ZMQ}")
-message(" USDT tracing ........................ ${WITH_USDT}")
-message(" QR code (GUI) ....................... ${WITH_QRENCODE}")
-message(" DBus (GUI, Linux only) .............. ${WITH_DBUS}")
-message("Tests:")
-message(" test_bitcoin ........................ ${BUILD_TESTS}")
-message(" test_elements-qt .................... ${BUILD_GUI_TESTS}")
-message(" bench_bitcoin ....................... ${BUILD_BENCH}")
-message(" fuzz binary ......................... ${BUILD_FUZZ_BINARY}")
+message(" assembly ............................ ${SECP256K1_ASM}")
+message(" external callbacks .................. ${SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS}")
+if(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY)
+ message(" wide multiplication (test-only) ..... ${SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY}")
+endif()
+message("Optional binaries:")
+message(" benchmark ........................... ${SECP256K1_BUILD_BENCHMARK}")
+message(" noverify_tests ...................... ${SECP256K1_BUILD_TESTS}")
+set(tests_status "${SECP256K1_BUILD_TESTS}")
+if(CMAKE_BUILD_TYPE STREQUAL "Coverage")
+ set(tests_status OFF)
+endif()
+message(" tests ............................... ${tests_status}")
+message(" exhaustive tests .................... ${SECP256K1_BUILD_EXHAUSTIVE_TESTS}")
+message(" ctime_tests ......................... ${SECP256K1_BUILD_CTIME_TESTS}")
+message(" examples ............................ ${SECP256K1_BUILD_EXAMPLES}")
message("")
if(CMAKE_CROSSCOMPILING)
set(cross_status "TRUE, for ${CMAKE_SYSTEM_NAME}, ${CMAKE_SYSTEM_PROCESSOR}")
@@ -681,20 +333,53 @@ else()
set(cross_status "FALSE")
endif()
message("Cross compiling ....................... ${cross_status}")
-message("C++ compiler .......................... ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}, ${CMAKE_CXX_COMPILER}")
-include(FlagsSummary)
-flags_summary()
-message("Attempt to harden executables ......... ${ENABLE_HARDENING}")
-message("Treat compiler warnings as errors ..... ${WERROR}")
-message("Use ccache for compiling .............. ${WITH_CCACHE}")
-message("\n")
-if(configure_warnings)
- message(" ******\n")
- foreach(warning IN LISTS configure_warnings)
- message(WARNING "${warning}")
- endforeach()
- message(" ******\n")
+message("API visibility attributes ............. ${SECP256K1_ENABLE_API_VISIBILITY_ATTRIBUTES}")
+message("Valgrind .............................. ${SECP256K1_VALGRIND}")
+get_directory_property(definitions COMPILE_DEFINITIONS)
+string(REPLACE ";" " " definitions "${definitions}")
+message("Preprocessor defined macros ........... ${definitions}")
+message("C compiler ............................ ${CMAKE_C_COMPILER_ID} ${CMAKE_C_COMPILER_VERSION}, ${CMAKE_C_COMPILER}")
+message("CFLAGS ................................ ${CMAKE_C_FLAGS}")
+get_directory_property(compile_options COMPILE_OPTIONS)
+string(REPLACE ";" " " compile_options "${compile_options}")
+message("Compile options ....................... " ${compile_options})
+if(NOT is_multi_config)
+ message("Build type:")
+ message(" - CMAKE_BUILD_TYPE ................... ${CMAKE_BUILD_TYPE}")
+ string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type)
+ message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_${build_type}}")
+ message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_${build_type}}")
+ message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_${build_type}}")
+else()
+ message("Supported configurations .............. ${CMAKE_CONFIGURATION_TYPES}")
+ message("RelWithDebInfo configuration:")
+ message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_RELWITHDEBINFO}")
+ message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}")
+ message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}")
+ message("Debug configuration:")
+ message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_DEBUG}")
+ message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
+ message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_DEBUG}")
+endif()
+if(SECP256K1_APPEND_CFLAGS)
+ message("SECP256K1_APPEND_CFLAGS ............... ${SECP256K1_APPEND_CFLAGS}")
+endif()
+if(SECP256K1_APPEND_LDFLAGS)
+ message("SECP256K1_APPEND_LDFLAGS .............. ${SECP256K1_APPEND_LDFLAGS}")
+endif()
+message("")
+if(print_msan_notice)
+ message(
+ "Note:\n"
+ " MemorySanitizer detected, tried to add -fno-sanitize-memory-param-retval to compile options\n"
+ " to avoid false positives in ctime_tests. Pass -DSECP256K1_BUILD_CTIME_TESTS=OFF to avoid this.\n"
+ )
+endif()
+if(SECP256K1_EXPERIMENTAL)
+ message(
+ " ******\n"
+ " WARNING: experimental build\n"
+ " Experimental features do not have stable APIs or properties, and may not be safe for production use.\n"
+ " ******\n"
+ )
endif()
-
-# We want all build properties to be encapsulated properly.
-include(WarnAboutGlobalProperties)
diff --git a/CMakePresets.json b/CMakePresets.json
index da838f2..6ed52b8 100644
--- a/CMakePresets.json
+++ b/CMakePresets.json
@@ -1,91 +1,17 @@
{
"version": 3,
- "cmakeMinimumRequired": {"major": 3, "minor": 21, "patch": 0},
"configurePresets": [
- {
- "name": "vs2022",
- "displayName": "Build using 'Visual Studio 17 2022' generator and 'x64-windows' triplet",
- "condition": {
- "type": "equals",
- "lhs": "${hostSystemName}",
- "rhs": "Windows"
- },
- "generator": "Visual Studio 17 2022",
- "architecture": "x64",
- "toolchainFile": "$env{VCPKG_ROOT}\\scripts\\buildsystems\\vcpkg.cmake",
- "cacheVariables": {
- "VCPKG_TARGET_TRIPLET": "x64-windows",
- "BUILD_GUI": "ON"
- }
- },
- {
- "name": "vs2022-static",
- "displayName": "Build using 'Visual Studio 17 2022' generator and 'x64-windows-static' triplet",
- "condition": {
- "type": "equals",
- "lhs": "${hostSystemName}",
- "rhs": "Windows"
- },
- "generator": "Visual Studio 17 2022",
- "architecture": "x64",
- "toolchainFile": "$env{VCPKG_ROOT}\\scripts\\buildsystems\\vcpkg.cmake",
- "cacheVariables": {
- "VCPKG_TARGET_TRIPLET": "x64-windows-static",
- "BUILD_GUI": "ON"
- }
- },
- {
- "name": "libfuzzer",
- "displayName": "Build for fuzzing with libfuzzer, and sanitizers enabled",
- "binaryDir": "${sourceDir}/build_fuzz",
- "cacheVariables": {
- "BUILD_FOR_FUZZING": "ON",
- "CMAKE_C_COMPILER": "clang",
- "CMAKE_C_FLAGS": "-ftrivial-auto-var-init=pattern",
- "CMAKE_CXX_COMPILER": "clang++",
- "CMAKE_CXX_FLAGS": "-ftrivial-auto-var-init=pattern",
- "SANITIZERS": "undefined,address,fuzzer"
- }
- },
- {
- "name": "libfuzzer-nosan",
- "displayName": "Build for fuzzing with libfuzzer, and sanitizers disabled",
- "binaryDir": "${sourceDir}/build_fuzz_nosan",
- "cacheVariables": {
- "BUILD_FOR_FUZZING": "ON",
- "CMAKE_C_COMPILER": "clang",
- "CMAKE_CXX_COMPILER": "clang++",
- "SANITIZERS": "fuzzer"
- }
- },
{
"name": "dev-mode",
- "displayName": "Developer mode, with all features/dependencies enabled",
- "binaryDir": "${sourceDir}/build_dev_mode",
+ "displayName": "Development mode (intended only for developers of the library)",
"cacheVariables": {
- "BUILD_BENCH": "ON",
- "BUILD_CLI": "ON",
- "BUILD_DAEMON": "ON",
- "BUILD_FUZZ_BINARY": "ON",
- "BUILD_GUI": "ON",
- "BUILD_GUI_TESTS": "ON",
- "BUILD_KERNEL_LIB": "ON",
- "BUILD_SHARED_LIBS": "ON",
- "BUILD_TESTS": "ON",
- "BUILD_TX": "ON",
- "BUILD_UTIL": "ON",
- "BUILD_UTIL_CHAINSTATE": "ON",
- "BUILD_WALLET_TOOL": "ON",
- "ENABLE_EXTERNAL_SIGNER": "ON",
- "ENABLE_HARDENING": "ON",
- "ENABLE_WALLET": "ON",
- "WARN_INCOMPATIBLE_BDB": "OFF",
- "WITH_BDB": "ON",
- "WITH_MULTIPROCESS": "ON",
- "WITH_QRENCODE": "ON",
- "WITH_SQLITE": "ON",
- "WITH_USDT": "ON",
- "WITH_ZMQ": "ON"
+ "SECP256K1_EXPERIMENTAL": "ON",
+ "SECP256K1_ENABLE_MODULE_RECOVERY": "ON",
+ "SECP256K1_BUILD_EXAMPLES": "ON"
+ },
+ "warnings": {
+ "dev": true,
+ "uninitialized": true
}
}
]
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index a4d2ef0..f001108 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,443 +1,111 @@
-Contributing to Bitcoin Core
-============================
+# Contributing to libsecp256k1
-The Bitcoin Core project operates an open contributor model where anyone is
-welcome to contribute towards development in the form of peer review, testing
-and patches. This document explains the practical process and guidelines for
-contributing.
+## Scope
-First, in terms of structure, there is no particular concept of "Bitcoin Core
-developers" in the sense of privileged people. Open source often naturally
-revolves around a meritocracy where contributors earn trust from the developer
-community over time. Nevertheless, some hierarchy is necessary for practical
-purposes. As such, there are repository maintainers who are responsible for
-merging pull requests, the [release cycle](/doc/release-process.md), and
-moderation.
+libsecp256k1 is a library for elliptic curve cryptography on the curve secp256k1, not a general-purpose cryptography library.
+The library primarily serves the needs of the Bitcoin Core project but provides additional functionality for the benefit of the wider Bitcoin ecosystem.
-Getting Started
----------------
+## Adding new functionality or modules
-New contributors are very welcome and needed.
+The libsecp256k1 project welcomes contributions in the form of new functionality or modules, provided they are within the project's scope.
-Reviewing and testing is highly valued and the most effective way you can contribute
-as a new contributor. It also will teach you much more about the code and
-process than opening pull requests. Please refer to the [peer review](#peer-review)
-section below.
+It is the responsibility of the contributors to convince the maintainers that the proposed functionality is within the project's scope, high-quality and maintainable.
+Contributors are recommended to provide the following in addition to the new code:
-Before you start contributing, familiarize yourself with the Bitcoin Core build
-system and tests. Refer to the documentation in the repository on how to build
-Bitcoin Core and how to run the unit tests, functional tests, and fuzz tests.
+* **Specification:**
+ A specification can help significantly in reviewing the new code as it provides documentation and context.
+ It may justify various design decisions, give a motivation and outline security goals.
+ If the specification contains pseudocode, a reference implementation or test vectors, these can be used to compare with the proposed libsecp256k1 code.
+* **Security Arguments:**
+ In addition to a defining the security goals, it should be argued that the new functionality meets these goals.
+ Depending on the nature of the new functionality, a wide range of security arguments are acceptable, ranging from being "obviously secure" to rigorous proofs of security.
+* **Relevance Arguments:**
+ The relevance of the new functionality for the Bitcoin ecosystem should be argued by outlining clear use cases.
-There are many open issues of varying difficulty waiting to be fixed.
-If you're looking for somewhere to start contributing, check out the
-[good first issue](https://github.com/bitcoin/bitcoin/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)
-list or changes that are
-[up for grabs](https://github.com/bitcoin/bitcoin/issues?utf8=%E2%9C%93&q=label%3A%22Up+for+grabs%22).
-Some of them might no longer be applicable. So if you are interested, but
-unsure, you might want to leave a comment on the issue first.
+These are not the only factors taken into account when considering to add new functionality.
+The proposed new libsecp256k1 code must be of high quality, including API documentation and tests, as well as featuring a misuse-resistant API design.
-You may also participate in the [Bitcoin Core PR Review Club](https://bitcoincore.reviews/).
+We recommend reaching out to other contributors (see [Communication Channels](#communication-channels)) and get feedback before implementing new functionality.
-### Good First Issue Label
+## Communication channels
-The purpose of the `good first issue` label is to highlight which issues are
-suitable for a new contributor without a deep understanding of the codebase.
+Most communication about libsecp256k1 occurs on the GitHub repository: in issues, pull request or on the discussion board.
-However, good first issues can be solved by anyone. If they remain unsolved
-for a longer time, a frequent contributor might address them.
+Additionally, there is an IRC channel dedicated to libsecp256k1, with biweekly meetings (see channel topic).
+The channel is `#secp256k1` on Libera Chat.
+The easiest way to participate on IRC is with the web client, [web.libera.chat](https://web.libera.chat/#secp256k1).
+Chat history logs can be found at https://gnusha.org/secp256k1/.
-You do not need to request permission to start working on an issue. However,
-you are encouraged to leave a comment if you are planning to work on it. This
-will help other contributors monitor which issues are actively being addressed
-and is also an effective way to request assistance if and when you need it.
+## Contributor workflow & peer review
-Communication Channels
-----------------------
-
-Most communication about Bitcoin Core development happens on IRC, in the
-`#bitcoin-core-dev` channel on Libera Chat. The easiest way to participate on IRC is
-with the web client, [web.libera.chat](https://web.libera.chat/#bitcoin-core-dev). Chat
-history logs can be found
-on [https://www.erisian.com.au/bitcoin-core-dev/](https://www.erisian.com.au/bitcoin-core-dev/)
-and [https://gnusha.org/bitcoin-core-dev/](https://gnusha.org/bitcoin-core-dev/).
+The Contributor Workflow & Peer Review in libsecp256k1 are similar to Bitcoin Core's workflow and review processes described in its [CONTRIBUTING.md](https://github.com/bitcoin/bitcoin/blob/master/CONTRIBUTING.md).
-Discussion about codebase improvements happens in GitHub issues and pull
-requests.
+### Coding conventions
-The developer
-[mailing list](https://groups.google.com/g/bitcoindev)
-should be used to discuss complicated or controversial consensus or P2P protocol changes before working on
-a patch set.
-Archives can be found on [https://gnusha.org/pi/bitcoindev/](https://gnusha.org/pi/bitcoindev/).
-
-
-Contributor Workflow
---------------------
-
-The codebase is maintained using the "contributor workflow" where everyone
-without exception contributes patch proposals using "pull requests" (PRs). This
-facilitates social contribution, easy testing and peer review.
-
-To contribute a patch, the workflow is as follows:
+In addition, libsecp256k1 tries to maintain the following coding conventions:
- 1. Fork repository ([only for the first time](https://docs.github.com/en/get-started/quickstart/fork-a-repo))
- 1. Create topic branch
- 1. Commit patches
+* No runtime heap allocation (e.g., no `malloc`) unless explicitly requested by the caller (via `secp256k1_context_create` or `secp256k1_scratch_space_create`, for example). Moreover, it should be possible to use the library without any heap allocations.
+* The tests should cover all lines and branches of the library (see [Test coverage](#coverage)).
+* Operations involving secret data should be tested for being constant time with respect to the secrets (see [src/ctime_tests.c](src/ctime_tests.c)).
+* Local variables containing secret data should be cleared explicitly to try to delete secrets from memory.
+* Use `secp256k1_memcmp_var` instead of `memcmp` (see [#823](https://github.com/bitcoin-core/secp256k1/issues/823)).
+* As a rule of thumb, the default values for configuration options should target standard desktop machines and align with Bitcoin Core's defaults, and the tests should mostly exercise the default configuration (see [#1549](https://github.com/bitcoin-core/secp256k1/issues/1549#issuecomment-2200559257)).
-For GUI-related issues or pull requests, the https://github.com/bitcoin-core/gui repository should be used.
-For all other issues and pull requests, the https://github.com/bitcoin/bitcoin node repository should be used.
+#### Style conventions
-The master branch for all monotree repositories is identical.
+* Commits should be atomic and diffs should be easy to read. For this reason, do not mix any formatting fixes or code moves with actual code changes. Make sure each individual commit is hygienic: that it builds successfully on its own without warnings, errors, regressions, or test failures.
+* New code should adhere to the style of existing, in particular surrounding, code. Other than that, we do not enforce strict rules for code formatting.
+* The code conforms to C89. Most notably, that means that only `/* ... */` comments are allowed (no `//` line comments). Moreover, any declarations in a `{ ... }` block (e.g., a function) must appear at the beginning of the block before any statements. When you would like to declare a variable in the middle of a block, you can open a new block:
+ ```C
+ void secp256k_foo(void) {
+ unsigned int x; /* declaration */
+ int y = 2*x; /* declaration */
+ x = 17; /* statement */
+ {
+ int a, b; /* declaration */
+ a = x + y; /* statement */
+ secp256k_bar(x, &b); /* statement */
+ }
+ }
+ ```
+* Use `unsigned int` instead of just `unsigned`.
+* Use `void *ptr` instead of `void* ptr`.
+* Arguments of the publicly-facing API must have a specific order defined in [include/secp256k1.h](include/secp256k1.h).
+* User-facing comment lines in headers should be limited to 80 chars if possible.
+* All identifiers in file scope should start with `secp256k1_`.
+* Avoid trailing whitespace.
+* Use the constants `EXIT_SUCCESS`/`EXIT_FAILURE` (defined in `stdlib.h`) to indicate program execution status for examples and other binaries.
-As a rule of thumb, everything that only modifies `src/qt` is a GUI-only pull
-request. However:
+### Tests
-* For global refactoring or other transversal changes the node repository
- should be used.
-* For GUI-related build system changes, the node repository should be used
- because the change needs review by the build systems reviewers.
-* Changes in `src/interfaces` need to go to the node repository because they
- might affect other components like the wallet.
+#### Coverage
-For large GUI changes that include build system and interface changes, it is
-recommended to first open a pull request against the GUI repository. When there
-is agreement to proceed with the changes, a pull request with the build system
-and interfaces changes can be submitted to the node repository.
+This library aims to have full coverage of reachable lines and branches.
-The project coding conventions in the [developer notes](doc/developer-notes.md)
-must be followed.
+To create a test coverage report, configure with `--enable-coverage` (use of GCC is necessary):
-### Committing Patches
+ $ ./configure --enable-coverage
-In general, [commits should be atomic](https://en.wikipedia.org/wiki/Atomic_commit#Atomic_commit_convention)
-and diffs should be easy to read. For this reason, do not mix any formatting
-fixes or code moves with actual code changes.
+Run the tests:
-Make sure each individual commit is hygienic: that it builds successfully on its
-own without warnings, errors, regressions, or test failures.
+ $ make check
-Commit messages should be verbose by default consisting of a short subject line
-(50 chars max), a blank line and detailed explanatory text as separate
-paragraph(s), unless the title alone is self-explanatory (like "Correct typo
-in init.cpp") in which case a single title line is sufficient. Commit messages should be
-helpful to people reading your code in the future, so explain the reasoning for
-your decisions. Further explanation [here](https://chris.beams.io/posts/git-commit/).
+To create a report, `gcovr` is recommended, as it includes branch coverage reporting:
-If a particular commit references another issue, please add the reference. For
-example: `refs #1234` or `fixes #4321`. Using the `fixes` or `closes` keywords
-will cause the corresponding issue to be closed when the pull request is merged.
+ $ gcovr --gcov-ignore-parse-errors=all --merge-mode-functions=separate --exclude 'src/bench*' --exclude 'src/modules/.*/bench_impl.h' --print-summary
-Commit messages should never contain any `@` mentions (usernames prefixed with "@").
+To create a HTML report with coloured and annotated source code:
-Please refer to the [Git manual](https://git-scm.com/doc) for more information
-about Git.
+ $ mkdir -p coverage
+ $ gcovr --gcov-ignore-parse-errors=all --merge-mode-functions=separate --exclude 'src/bench*' --exclude 'src/modules/.*/bench_impl.h' --html --html-details -o coverage/coverage.html
- - Push changes to your fork
- - Create pull request
+On `gcovr` >=8.3, `--gcov-ignore-parse-errors=all` can be replaced with `--gcov-suspicious-hits-threshold=140737488355330`.
-### Creating the Pull Request
+#### Exhaustive tests
-The title of the pull request should be prefixed by the component or area that
-the pull request affects. Valid areas as:
+There are tests of several functions in which a small group replaces secp256k1.
+These tests are *exhaustive* since they provide all elements and scalars of the small group as input arguments (see [src/tests_exhaustive.c](src/tests_exhaustive.c)).
- - `consensus` for changes to consensus critical code
- - `doc` for changes to the documentation
- - `qt` or `gui` for changes to elements-qt
- - `log` for changes to log messages
- - `mining` for changes to the mining code
- - `net` or `p2p` for changes to the peer-to-peer network code
- - `refactor` for structural changes that do not change behavior
- - `rpc`, `rest` or `zmq` for changes to the RPC, REST or ZMQ APIs
- - `contrib` or `cli` for changes to the scripts and tools
- - `test`, `qa` or `ci` for changes to the unit tests, QA tests or CI code
- - `util` or `lib` for changes to the utils or libraries
- - `wallet` for changes to the wallet code
- - `build` for changes to CMake
- - `guix` for changes to the GUIX reproducible builds
+### Benchmarks
-Examples:
-
- consensus: Add new opcode for BIP-XXXX OP_CHECKAWESOMESIG
- net: Automatically create onion service, listen on Tor
- qt: Add feed bump button
- log: Fix typo in log message
-
-The body of the pull request should contain sufficient description of *what* the
-patch does, and even more importantly, *why*, with justification and reasoning.
-You should include references to any discussions (for example, other issues or
-mailing list discussions).
-
-The description for a new pull request should not contain any `@` mentions. The
-PR description will be included in the commit message when the PR is merged and
-any users mentioned in the description will be annoyingly notified each time a
-fork of Bitcoin Core copies the merge. Instead, make any username mentions in a
-subsequent comment to the PR.
-
-### Translation changes
-
-Note that translations should not be submitted as pull requests. Please see
-[Translation Process](https://github.com/bitcoin/bitcoin/blob/master/doc/translation_process.md)
-for more information on helping with translations.
-
-### Work in Progress Changes and Requests for Comments
-
-If a pull request is not to be considered for merging (yet), please
-prefix the title with [WIP] or use [Tasks Lists](https://docs.github.com/en/github/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#task-lists)
-in the body of the pull request to indicate tasks are pending.
-
-### Address Feedback
-
-At this stage, one should expect comments and review from other contributors. You
-can add more commits to your pull request by committing them locally and pushing
-to your fork.
-
-You are expected to reply to any review comments before your pull request is
-merged. You may update the code or reject the feedback if you do not agree with
-it, but you should express so in a reply. If there is outstanding feedback and
-you are not actively working on it, your pull request may be closed.
-
-Please refer to the [peer review](#peer-review) section below for more details.
-
-### Squashing Commits
-
-If your pull request contains fixup commits (commits that change the same line of code repeatedly) or too fine-grained
-commits, you may be asked to [squash](https://git-scm.com/docs/git-rebase#_interactive_mode) your commits
-before it will be reviewed. The basic squashing workflow is shown below.
-
- git checkout your_branch_name
- git rebase -i HEAD~n
- # n is normally the number of commits in the pull request.
- # Set commits (except the one in the first line) from 'pick' to 'squash', save and quit.
- # On the next screen, edit/refine commit messages.
- # Save and quit.
- git push -f # (force push to GitHub)
-
-Please update the resulting commit message, if needed. It should read as a
-coherent message. In most cases, this means not just listing the interim
-commits.
-
-If your change contains a merge commit, the above workflow may not work and you
-will need to remove the merge commit first. See the next section for details on
-how to rebase.
-
-Please refrain from creating several pull requests for the same change.
-Use the pull request that is already open (or was created earlier) to amend
-changes. This preserves the discussion and review that happened earlier for
-the respective change set.
-
-The length of time required for peer review is unpredictable and will vary from
-pull request to pull request.
-
-### Rebasing Changes
-
-When a pull request conflicts with the target branch, you may be asked to rebase it on top of the current target branch.
-
- git fetch https://github.com/bitcoin/bitcoin # Fetch the latest upstream commit
- git rebase FETCH_HEAD # Rebuild commits on top of the new base
-
-This project aims to have a clean git history, where code changes are only made in non-merge commits. This simplifies
-auditability because merge commits can be assumed to not contain arbitrary code changes. Merge commits should be signed,
-and the resulting git tree hash must be deterministic and reproducible. The script in
-[/contrib/verify-commits](/contrib/verify-commits) checks that.
-
-After a rebase, reviewers are encouraged to sign off on the force push. This should be relatively straightforward with
-the `git range-diff` tool explained in the [productivity
-notes](/doc/productivity.md#diff-the-diffs-with-git-range-diff). To avoid needless review churn, maintainers will
-generally merge pull requests that received the most review attention first.
-
-Pull Request Philosophy
------------------------
-
-Patchsets should always be focused. For example, a pull request could add a
-feature, fix a bug, or refactor code; but not a mixture. Please also avoid super
-pull requests which attempt to do too much, are overly large, or overly complex
-as this makes review difficult.
-
-
-### Features
-
-When adding a new feature, thought must be given to the long term technical debt
-and maintenance that feature may require after inclusion. Before proposing a new
-feature that will require maintenance, please consider if you are willing to
-maintain it (including bug fixing). If features get orphaned with no maintainer
-in the future, they may be removed by the Repository Maintainer.
-
-
-### Refactoring
-
-Refactoring is a necessary part of any software project's evolution. The
-following guidelines cover refactoring pull requests for the project.
-
-There are three categories of refactoring: code-only moves, code style fixes, and
-code refactoring. In general, refactoring pull requests should not mix these
-three kinds of activities in order to make refactoring pull requests easy to
-review and uncontroversial. In all cases, refactoring PRs must not change the
-behaviour of code within the pull request (bugs must be preserved as is).
-
-Project maintainers aim for a quick turnaround on refactoring pull requests, so
-where possible keep them short, uncomplex and easy to verify.
-
-Pull requests that refactor the code should not be made by new contributors. It
-requires a certain level of experience to know where the code belongs to and to
-understand the full ramification (including rebase effort of open pull requests).
-
-Trivial pull requests or pull requests that refactor the code with no clear
-benefits may be immediately closed by the maintainers to reduce unnecessary
-workload on reviewing.
-
-
-"Decision Making" Process
--------------------------
-
-The following applies to code changes to the Bitcoin Core project (and related
-projects such as libsecp256k1), and is not to be confused with overall Bitcoin
-Network Protocol consensus changes.
-
-Whether a pull request is merged into Bitcoin Core rests with the project merge
-maintainers.
-
-Maintainers will take into consideration if a patch is in line with the general
-principles of the project; meets the minimum standards for inclusion; and will
-judge the general consensus of contributors.
-
-In general, all pull requests must:
-
- - Have a clear use case, fix a demonstrable bug or serve the greater good of
- the project (for example refactoring for modularisation);
- - Be well peer-reviewed;
- - Have unit tests, functional tests, and fuzz tests, where appropriate;
- - Follow code style guidelines ([C++](doc/developer-notes.md), [functional tests](test/functional/README.md));
- - Not break the existing test suite;
- - Where bugs are fixed, where possible, there should be unit tests
- demonstrating the bug and also proving the fix. This helps prevent regression.
- - Change relevant comments and documentation when behaviour of code changes.
-
-Patches that change Bitcoin consensus rules are considerably more involved than
-normal because they affect the entire ecosystem and so must be preceded by
-extensive mailing list discussions and have a numbered BIP. While each case will
-be different, one should be prepared to expend more time and effort than for
-other kinds of patches because of increased peer review and consensus building
-requirements.
-
-
-### Peer Review
-
-Anyone may participate in peer review which is expressed by comments in the pull
-request. Typically reviewers will review the code for obvious errors, as well as
-test out the patch set and opine on the technical merits of the patch. Project
-maintainers take into account the peer review when determining if there is
-consensus to merge a pull request (remember that discussions may have been
-spread out over GitHub, mailing list and IRC discussions).
-
-Code review is a burdensome but important part of the development process, and
-as such, certain types of pull requests are rejected. In general, if the
-**improvements** do not warrant the **review effort** required, the PR has a
-high chance of being rejected. It is up to the PR author to convince the
-reviewers that the changes warrant the review effort, and if reviewers are
-"Concept NACK'ing" the PR, the author may need to present arguments and/or do
-research backing their suggested changes.
-
-#### Conceptual Review
-
-A review can be a conceptual review, where the reviewer leaves a comment
- * `Concept (N)ACK`, meaning "I do (not) agree with the general goal of this pull
- request",
- * `Approach (N)ACK`, meaning `Concept ACK`, but "I do (not) agree with the
- approach of this change".
-
-A `NACK` needs to include a rationale why the change is not worthwhile.
-NACKs without accompanying reasoning may be disregarded.
-
-#### Code Review
-
-After conceptual agreement on the change, code review can be provided. A review
-begins with `ACK BRANCH_COMMIT`, where `BRANCH_COMMIT` is the top of the PR
-branch, followed by a description of how the reviewer did the review. The
-following language is used within pull request comments:
-
- - "I have tested the code", involving change-specific manual testing in
- addition to running the unit, functional, or fuzz tests, and in case it is
- not obvious how the manual testing was done, it should be described;
- - "I have not tested the code, but I have reviewed it and it looks
- OK, I agree it can be merged";
- - A "nit" refers to a trivial, often non-blocking issue.
-
-Project maintainers reserve the right to weigh the opinions of peer reviewers
-using common sense judgement and may also weigh based on merit. Reviewers that
-have demonstrated a deeper commitment and understanding of the project over time
-or who have clear domain expertise may naturally have more weight, as one would
-expect in all walks of life.
-
-Where a patch set affects consensus-critical code, the bar will be much
-higher in terms of discussion and peer review requirements, keeping in mind that
-mistakes could be very costly to the wider community. This includes refactoring
-of consensus-critical code.
-
-Where a patch set proposes to change the Bitcoin consensus, it must have been
-discussed extensively on the mailing list and IRC, be accompanied by a widely
-discussed BIP and have a generally widely perceived technical consensus of being
-a worthwhile change based on the judgement of the maintainers.
-
-### Finding Reviewers
-
-As most reviewers are themselves developers with their own projects, the review
-process can be quite lengthy, and some amount of patience is required. If you find
-that you've been waiting for a pull request to be given attention for several
-months, there may be a number of reasons for this, some of which you can do something
-about:
-
- - It may be because of a feature freeze due to an upcoming release. During this time,
- only bug fixes are taken into consideration. If your pull request is a new feature,
- it will not be prioritized until after the release. Wait for the release.
- - It may be because the changes you are suggesting do not appeal to people. Rather than
- nits and critique, which require effort and means they care enough to spend time on your
- contribution, thundering silence is a good sign of widespread (mild) dislike of a given change
- (because people don't assume *others* won't actually like the proposal). Don't take
- that personally, though! Instead, take another critical look at what you are suggesting
- and see if it: changes too much, is too broad, doesn't adhere to the
- [developer notes](doc/developer-notes.md), is dangerous or insecure, is messily written, etc.
- Identify and address any of the issues you find. Then ask e.g. on IRC if someone could give
- their opinion on the concept itself.
- - It may be because your code is too complex for all but a few people, and those people
- may not have realized your pull request even exists. A great way to find people who
- are qualified and care about the code you are touching is the
- [Git Blame feature](https://docs.github.com/en/github/managing-files-in-a-repository/managing-files-on-github/tracking-changes-in-a-file). Simply
- look up who last modified the code you are changing and see if you can find
- them and give them a nudge. Don't be incessant about the nudging, though.
- - Finally, if all else fails, ask on IRC or elsewhere for someone to give your pull request
- a look. If you think you've been waiting for an unreasonably long time (say,
- more than a month) for no particular reason (a few lines changed, etc.),
- this is totally fine. Try to return the favor when someone else is asking
- for feedback on their code, and the universe balances out.
- - Remember that the best thing you can do while waiting is give review to others!
-
-
-Backporting
------------
-
-Security and bug fixes can be backported from `master` to release
-branches.
-Maintainers will do backports in batches and
-use the proper `Needs backport (...)` labels
-when needed (the original author does not need to worry about it).
-
-A backport should contain the following metadata in the commit body:
-
-```
-Github-Pull: #<PR number>
-Rebased-From: <commit hash of the original commit>
-```
-
-Have a look at [an example backport PR](
-https://github.com/bitcoin/bitcoin/pull/16189).
-
-Also see the [backport.py script](
-https://github.com/bitcoin-core/bitcoin-maintainer-tools#backport).
-
-Copyright
----------
-
-By contributing to this repository, you agree to license your work under the
-MIT license unless specified otherwise in `contrib/debian/copyright` or at
-the top of the file itself. Any work contributed where you are not the original
-author must contain its license header with the original author(s) and source.
+See `src/bench*.c` for examples of benchmarks.
diff --git a/COPYING b/COPYING
index 23dc5e9..4522a59 100644
--- a/COPYING
+++ b/COPYING
@@ -1,7 +1,4 @@
-The MIT License (MIT)
-
-Copyright (c) 2009-2025 The Bitcoin Core developers
-Copyright (c) 2009-2025 Bitcoin Developers
+Copyright (c) 2013 Pieter Wuille
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/INSTALL.md b/INSTALL.md
deleted file mode 100644
index 4cead03..0000000
--- a/INSTALL.md
+++ /dev/null
@@ -1 +0,0 @@
-See [doc/build-\*.md](/doc)
\ No newline at end of file
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..51c8f6b
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,350 @@
+ACLOCAL_AMFLAGS = -I autotools-aux/m4
+
+# AM_CFLAGS will be automatically prepended to CFLAGS by Automake when compiling some foo
+# which does not have an explicit foo_CFLAGS variable set.
+AM_CFLAGS = $(SECP_CFLAGS)
+
+lib_LTLIBRARIES = libsecp256k1.la
+include_HEADERS = include/secp256k1.h
+include_HEADERS += include/secp256k1_preallocated.h
+noinst_HEADERS =
+noinst_HEADERS += src/scalar.h
+noinst_HEADERS += src/scalar_4x64.h
+noinst_HEADERS += src/scalar_8x32.h
+noinst_HEADERS += src/scalar_low.h
+noinst_HEADERS += src/scalar_impl.h
+noinst_HEADERS += src/scalar_4x64_impl.h
+noinst_HEADERS += src/scalar_8x32_impl.h
+noinst_HEADERS += src/scalar_low_impl.h
+noinst_HEADERS += src/group.h
+noinst_HEADERS += src/group_impl.h
+noinst_HEADERS += src/eccommit.h
+noinst_HEADERS += src/eccommit_impl.h
+noinst_HEADERS += src/ecdsa.h
+noinst_HEADERS += src/ecdsa_impl.h
+noinst_HEADERS += src/eckey.h
+noinst_HEADERS += src/eckey_impl.h
+noinst_HEADERS += src/ecmult.h
+noinst_HEADERS += src/ecmult_impl.h
+noinst_HEADERS += src/ecmult_compute_table.h
+noinst_HEADERS += src/ecmult_compute_table_impl.h
+noinst_HEADERS += src/ecmult_const.h
+noinst_HEADERS += src/ecmult_const_impl.h
+noinst_HEADERS += src/ecmult_gen.h
+noinst_HEADERS += src/ecmult_gen_impl.h
+noinst_HEADERS += src/ecmult_gen_compute_table.h
+noinst_HEADERS += src/ecmult_gen_compute_table_impl.h
+noinst_HEADERS += src/field_10x26.h
+noinst_HEADERS += src/field_10x26_impl.h
+noinst_HEADERS += src/field_5x52.h
+noinst_HEADERS += src/field_5x52_impl.h
+noinst_HEADERS += src/field_5x52_int128_impl.h
+noinst_HEADERS += src/modinv32.h
+noinst_HEADERS += src/modinv32_impl.h
+noinst_HEADERS += src/modinv64.h
+noinst_HEADERS += src/modinv64_impl.h
+noinst_HEADERS += src/precomputed_ecmult.h
+noinst_HEADERS += src/precomputed_ecmult_gen.h
+noinst_HEADERS += src/assumptions.h
+noinst_HEADERS += src/checkmem.h
+noinst_HEADERS += src/tests_common.h
+noinst_HEADERS += src/testutil.h
+noinst_HEADERS += src/unit_test.h
+noinst_HEADERS += src/unit_test.c
+noinst_HEADERS += src/util.h
+noinst_HEADERS += src/util_local_visibility.h
+noinst_HEADERS += src/int128.h
+noinst_HEADERS += src/int128_impl.h
+noinst_HEADERS += src/int128_native.h
+noinst_HEADERS += src/int128_native_impl.h
+noinst_HEADERS += src/int128_struct.h
+noinst_HEADERS += src/int128_struct_impl.h
+noinst_HEADERS += src/scratch.h
+noinst_HEADERS += src/scratch_impl.h
+noinst_HEADERS += src/selftest.h
+noinst_HEADERS += src/testrand.h
+noinst_HEADERS += src/testrand_impl.h
+noinst_HEADERS += src/hash.h
+noinst_HEADERS += src/hash_impl.h
+noinst_HEADERS += src/field.h
+noinst_HEADERS += src/field_impl.h
+noinst_HEADERS += src/bench.h
+noinst_HEADERS += src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h
+noinst_HEADERS += src/hsort.h
+noinst_HEADERS += src/hsort_impl.h
+noinst_HEADERS += contrib/lax_der_parsing.h
+noinst_HEADERS += contrib/lax_der_parsing.c
+noinst_HEADERS += contrib/lax_der_privatekey_parsing.h
+noinst_HEADERS += contrib/lax_der_privatekey_parsing.c
+noinst_HEADERS += examples/examples_util.h
+
+PRECOMPUTED_LIB = libsecp256k1_precomputed.la
+noinst_LTLIBRARIES = $(PRECOMPUTED_LIB)
+libsecp256k1_precomputed_la_SOURCES = src/precomputed_ecmult.c src/precomputed_ecmult_gen.c
+# We need `-I$(top_srcdir)/src` in VPATH builds if libsecp256k1_precomputed_la_SOURCES have been recreated in the build tree.
+# This helps users and packagers who insist on recreating the precomputed files (e.g., Gentoo).
+libsecp256k1_precomputed_la_CPPFLAGS = -I$(top_srcdir)/src $(SECP_CONFIG_DEFINES)
+
+if USE_EXTERNAL_ASM
+COMMON_LIB = libsecp256k1_common.la
+else
+COMMON_LIB =
+endif
+noinst_LTLIBRARIES += $(COMMON_LIB)
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libsecp256k1.pc
+
+if USE_EXTERNAL_ASM
+if USE_ASM_ARM
+libsecp256k1_common_la_SOURCES = src/asm/field_10x26_arm.s
+endif
+endif
+
+libsecp256k1_la_SOURCES = src/secp256k1.c
+libsecp256k1_la_CPPFLAGS = $(SECP_CONFIG_DEFINES)
+libsecp256k1_la_LIBADD = $(COMMON_LIB) $(PRECOMPUTED_LIB)
+libsecp256k1_la_LDFLAGS = -no-undefined -version-info $(LIB_VERSION_CURRENT):$(LIB_VERSION_REVISION):$(LIB_VERSION_AGE)
+
+noinst_PROGRAMS =
+if USE_BENCHMARK
+noinst_PROGRAMS += bench bench_internal bench_ecmult
+bench_SOURCES = src/bench.c
+bench_LDADD = libsecp256k1.la
+bench_CPPFLAGS = $(SECP_CONFIG_DEFINES)
+bench_internal_SOURCES = src/bench_internal.c
+bench_internal_LDADD = $(COMMON_LIB) $(PRECOMPUTED_LIB)
+bench_internal_CPPFLAGS = $(SECP_CONFIG_DEFINES)
+bench_ecmult_SOURCES = src/bench_ecmult.c
+bench_ecmult_LDADD = $(COMMON_LIB) $(PRECOMPUTED_LIB)
+bench_ecmult_CPPFLAGS = $(SECP_CONFIG_DEFINES)
+endif
+
+TESTS =
+if USE_TESTS
+TESTS += noverify_tests
+noinst_PROGRAMS += noverify_tests
+noverify_tests_SOURCES = src/tests.c
+noverify_tests_CPPFLAGS = $(SECP_CONFIG_DEFINES) $(TEST_DEFINES)
+noverify_tests_LDADD = $(COMMON_LIB) $(PRECOMPUTED_LIB)
+noverify_tests_LDFLAGS = -static
+if !ENABLE_COVERAGE
+TESTS += tests
+noinst_PROGRAMS += tests
+tests_SOURCES = $(noverify_tests_SOURCES)
+tests_CPPFLAGS = $(noverify_tests_CPPFLAGS) -DVERIFY
+tests_LDADD = $(noverify_tests_LDADD)
+tests_LDFLAGS = $(noverify_tests_LDFLAGS)
+endif
+endif
+
+if USE_CTIME_TESTS
+noinst_PROGRAMS += ctime_tests
+ctime_tests_SOURCES = src/ctime_tests.c
+ctime_tests_LDADD = libsecp256k1.la
+ctime_tests_CPPFLAGS = $(SECP_CONFIG_DEFINES)
+endif
+
+if USE_EXHAUSTIVE_TESTS
+noinst_PROGRAMS += exhaustive_tests
+exhaustive_tests_SOURCES = src/tests_exhaustive.c
+exhaustive_tests_CPPFLAGS = $(SECP_CONFIG_DEFINES)
+if !ENABLE_COVERAGE
+exhaustive_tests_CPPFLAGS += -DVERIFY
+endif
+# Note: do not include $(PRECOMPUTED_LIB) in exhaustive_tests (it uses runtime-generated tables).
+exhaustive_tests_LDADD = $(COMMON_LIB)
+exhaustive_tests_LDFLAGS = -static
+TESTS += exhaustive_tests
+endif
+
+if USE_EXAMPLES
+noinst_PROGRAMS += ecdsa_example
+ecdsa_example_SOURCES = examples/ecdsa.c
+ecdsa_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC
+ecdsa_example_LDADD = libsecp256k1.la
+ecdsa_example_LDFLAGS = -static
+if BUILD_WINDOWS
+ecdsa_example_LDFLAGS += -lbcrypt
+endif
+TESTS += ecdsa_example
+if ENABLE_MODULE_ECDH
+noinst_PROGRAMS += ecdh_example
+ecdh_example_SOURCES = examples/ecdh.c
+ecdh_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC
+ecdh_example_LDADD = libsecp256k1.la
+ecdh_example_LDFLAGS = -static
+if BUILD_WINDOWS
+ecdh_example_LDFLAGS += -lbcrypt
+endif
+TESTS += ecdh_example
+endif
+if ENABLE_MODULE_SCHNORRSIG
+noinst_PROGRAMS += schnorr_example
+schnorr_example_SOURCES = examples/schnorr.c
+schnorr_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC
+schnorr_example_LDADD = libsecp256k1.la
+schnorr_example_LDFLAGS = -static
+if BUILD_WINDOWS
+schnorr_example_LDFLAGS += -lbcrypt
+endif
+TESTS += schnorr_example
+endif
+if ENABLE_MODULE_ELLSWIFT
+noinst_PROGRAMS += ellswift_example
+ellswift_example_SOURCES = examples/ellswift.c
+ellswift_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC
+ellswift_example_LDADD = libsecp256k1.la
+ellswift_example_LDFLAGS = -static
+if BUILD_WINDOWS
+ellswift_example_LDFLAGS += -lbcrypt
+endif
+TESTS += ellswift_example
+endif
+if ENABLE_MODULE_MUSIG
+noinst_PROGRAMS += musig_example
+musig_example_SOURCES = examples/musig.c
+musig_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC
+musig_example_LDADD = libsecp256k1.la
+musig_example_LDFLAGS = -static
+if BUILD_WINDOWS
+musig_example_LDFLAGS += -lbcrypt
+endif
+TESTS += musig_example
+endif
+endif
+
+### Precomputed tables
+EXTRA_PROGRAMS = precompute_ecmult precompute_ecmult_gen
+CLEANFILES = $(EXTRA_PROGRAMS)
+
+precompute_ecmult_SOURCES = src/precompute_ecmult.c
+precompute_ecmult_CPPFLAGS = $(SECP_CONFIG_DEFINES) -DVERIFY
+precompute_ecmult_LDADD = $(COMMON_LIB)
+
+precompute_ecmult_gen_SOURCES = src/precompute_ecmult_gen.c
+precompute_ecmult_gen_CPPFLAGS = $(SECP_CONFIG_DEFINES) -DVERIFY
+precompute_ecmult_gen_LDADD = $(COMMON_LIB)
+
+# See Automake manual, Section "Errors with distclean".
+# We don't list any dependencies for the prebuilt files here because
+# otherwise make's decision whether to rebuild them (even in the first
+# build by a normal user) depends on mtimes, and thus is very fragile.
+# This means that rebuilds of the prebuilt files always need to be
+# forced by deleting them.
+src/precomputed_ecmult.c:
+ $(MAKE) $(AM_MAKEFLAGS) precompute_ecmult$(EXEEXT)
+ ./precompute_ecmult$(EXEEXT)
+src/precomputed_ecmult_gen.c:
+ $(MAKE) $(AM_MAKEFLAGS) precompute_ecmult_gen$(EXEEXT)
+ ./precompute_ecmult_gen$(EXEEXT)
+
+PRECOMP = src/precomputed_ecmult_gen.c src/precomputed_ecmult.c
+precomp: $(PRECOMP)
+
+# Ensure the prebuilt files will be build first (only if they don't exist,
+# e.g., after `make maintainer-clean`).
+BUILT_SOURCES = $(PRECOMP)
+
+.PHONY: clean-precomp
+clean-precomp:
+ rm -f $(PRECOMP)
+maintainer-clean-local: clean-precomp
+
+### Pregenerated test vectors
+### (see the comments in the previous section for detailed rationale)
+TESTVECTORS = src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h
+
+if ENABLE_MODULE_ECDH
+TESTVECTORS += src/wycheproof/ecdh_secp256k1_test.h
+endif
+
+src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h:
+ mkdir -p $(@D)
+ python3 $(top_srcdir)/tools/tests_wycheproof_generate_ecdsa.py $(top_srcdir)/src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.json > $@
+
+src/wycheproof/ecdh_secp256k1_test.h:
+ mkdir -p $(@D)
+ python3 $(top_srcdir)/tools/tests_wycheproof_generate_ecdh.py $(top_srcdir)/src/wycheproof/ecdh_secp256k1_test.json > $@
+
+testvectors: $(TESTVECTORS)
+
+BUILT_SOURCES += $(TESTVECTORS)
+
+.PHONY: clean-testvectors
+clean-testvectors:
+ rm -f $(TESTVECTORS)
+maintainer-clean-local: clean-testvectors
+
+### Additional files to distribute
+EXTRA_DIST = autogen.sh CHANGELOG.md SECURITY.md
+EXTRA_DIST += doc/release-process.md doc/safegcd_implementation.md
+EXTRA_DIST += doc/ellswift.md doc/musig.md
+EXTRA_DIST += examples/EXAMPLES_COPYING
+EXTRA_DIST += sage/gen_exhaustive_groups.sage
+EXTRA_DIST += sage/gen_split_lambda_constants.sage
+EXTRA_DIST += sage/group_prover.sage
+EXTRA_DIST += sage/prove_group_implementations.sage
+EXTRA_DIST += sage/secp256k1_params.sage
+EXTRA_DIST += sage/weierstrass_prover.sage
+EXTRA_DIST += src/wycheproof/WYCHEPROOF_COPYING
+EXTRA_DIST += src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.json
+EXTRA_DIST += src/wycheproof/ecdh_secp256k1_test.json
+EXTRA_DIST += tools/tests_wycheproof_generate_ecdsa.py
+EXTRA_DIST += tools/tests_wycheproof_generate_ecdh.py
+
+if ENABLE_MODULE_SCHNORRSIG_HALFAGG
+include src/modules/schnorrsig_halfagg/Makefile.am.include
+endif
+
+if ENABLE_MODULE_BPPP
+include src/modules/bppp/Makefile.am.include
+endif
+
+if ENABLE_MODULE_ECDH
+include src/modules/ecdh/Makefile.am.include
+endif
+
+if ENABLE_MODULE_RECOVERY
+include src/modules/recovery/Makefile.am.include
+endif
+
+if ENABLE_MODULE_GENERATOR
+include src/modules/generator/Makefile.am.include
+endif
+
+if ENABLE_MODULE_RANGEPROOF
+include src/modules/rangeproof/Makefile.am.include
+endif
+
+if ENABLE_MODULE_WHITELIST
+include src/modules/whitelist/Makefile.am.include
+endif
+
+if ENABLE_MODULE_SURJECTIONPROOF
+include src/modules/surjection/Makefile.am.include
+endif
+
+if ENABLE_MODULE_EXTRAKEYS
+include src/modules/extrakeys/Makefile.am.include
+endif
+
+if ENABLE_MODULE_SCHNORRSIG
+include src/modules/schnorrsig/Makefile.am.include
+endif
+
+if ENABLE_MODULE_MUSIG
+include src/modules/musig/Makefile.am.include
+endif
+
+if ENABLE_MODULE_ELLSWIFT
+include src/modules/ellswift/Makefile.am.include
+endif
+
+if ENABLE_MODULE_ECDSA_S2C
+include src/modules/ecdsa_s2c/Makefile.am.include
+endif
+
+if ENABLE_MODULE_ECDSA_ADAPTOR
+include src/modules/ecdsa_adaptor/Makefile.am.include
+endif
diff --git a/README.md b/README.md
index bf85860..69456dc 100644
--- a/README.md
+++ b/README.md
@@ -1,99 +1,134 @@
-Elements Project blockchain platform
-====================================
+libsecp256k1-zkp
+================
-[](https://github.com/ElementsProject/elements/releases)
+
-https://elementsproject.org
+A fork of [libsecp256k1](https://github.com/bitcoin-core/secp256k1) with support for advanced and experimental features
-This is the integration and staging tree for the Elements blockchain platform,
-a collection of feature experiments and extensions to the Bitcoin protocol.
-This platform enables anyone to build their own businesses or networks
-pegged to Bitcoin as a sidechain or run as a standalone blockchain with arbitrary asset tokens.
+Added features:
+* Experimental module for ECDSA adaptor signatures.
+* Experimental module for ECDSA sign-to-contract.
+* Experimental modules for Confidential Assets (Pedersen commitments, range proofs, and [surjection proofs](src/modules/surjection/surjection.md)).
+* Experimental module for [address whitelisting](src/modules/whitelist/whitelist.md).
+* Experimental module for Schnorr signature half-aggregation.
-Modes
------
+Experimental features are made available for testing and review by the community. The APIs of these features should not be considered stable.
-Elements supports a few different pre-set chains for syncing. Note though some are intended for QA and debugging only:
+Build steps
+-----------
-* Liquid mode: `elementsd -chain=liquidv1` (syncs with Liquid network)
-* Bitcoin mainnet mode: `elementsd -chain=main` (not intended to be run for commerce)
-* Bitcoin testnet mode: `elementsd -chain=testnet3`
-* Bitcoin regtest mode: `elementsd -chain=regtest`
-* Elements custom chains: Any other `-chain=` argument. It has regtest-like default parameters that can be over-ridden by the user by a rich set of start-up options.
+Obtaining and verifying
+-----------------------
-Confidential Assets
-----------------
-The latest feature in the Elements blockchain platform is Confidential Assets,
-the ability to issue multiple assets on a blockchain where asset identifiers
-and amounts are blinded yet auditable through the use of applied cryptography.
+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.
- * [Announcement of Confidential Assets](https://blockstream.com/2017/04/03/blockstream-releases-elements-confidential-assets.html)
- * [Confidential Assets Whitepaper](https://blockstream.com/bitcoin17-final41.pdf) to be presented [April 7th at Financial Cryptography 2017](http://fc17.ifca.ai/bitcoin/schedule.html) in Malta
- * [Confidential Assets Tutorial](contrib/assets_tutorial/assets_tutorial.py)
- * [Confidential Assets Demo](https://github.com/ElementsProject/confidential-assets-demo)
- * [Elements Code Tutorial](https://elementsproject.org/elements-code-tutorial/overview) covering blockchain configuration and how to use the main features.
+This can be done with the following steps:
-Features of the Elements blockchain platform
-----------------
+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.7.1
+ ```
+5. Use git to verify the GPG signature:
+ ```
+ % git tag -v v0.7.1 | grep -C 3 'Good signature'
-Compared to Bitcoin itself, it adds the following features:
- * [Confidential Assets][asset-issuance]
- * [Confidential Transactions][confidential-transactions]
- * [Federated Two-Way Peg][federated-peg]
- * [Signed Blocks][signed-blocks]
- * [Additional opcodes][opcodes]
+ gpg: Signature made Mon 26 Jan 2026 07:42:46 PM UTC
+ gpg: using RSA key 2840EAABF4BC9F0FFD716AFAFBAFCC46DE2D3FE2
+ gpg: Good signature from "Pieter Wuille <pieter@wuille.net>" [unknown]
+ gpg: aka "Pieter Wuille <pieter.wuille@gmail.com>" [full]
+ gpg: aka "[jpeg image of size 5996]" [undefined]
+ 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: 133E AC17 9436 F14A 5CF1 B794 860F EB80 4E66 9320
+ Subkey fingerprint: 2840 EAAB F4BC 9F0F FD71 6AFA FBAF CC46 DE2D 3FE2
+ ```
-Previous elements that have been integrated into Bitcoin:
- * Segregated Witness
- * Relative Lock Time
+Building with Autotools
+-----------------------
-Elements deferred for additional research and standardization:
- * [Schnorr Signatures][schnorr-signatures]
+ $ ./autogen.sh # Generate a ./configure script
+ $ ./configure # Generate a build system
+ $ make # Run the actual build process
+ $ make check # Run the test suite
+ $ sudo make install # Install the library into the system (optional)
-Additional RPC commands and parameters:
-* [RPC Docs](https://elementsproject.org/en/doc/)
+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. For experimental modules, you will also need `--enable-experimental` as well as a flag for each individual module, e.g. `--enable-module-rangeproof`.
-Testing and code review is the bottleneck for development; we get more pull
-requests than we can review and test on short notice. Please be patient and help out by testing
-other people's pull requests, and remember this is a security-critical project where any mistake might cost people
-lots of money.
+Building with CMake
+-------------------
-### Automated Testing
+To maintain a pristine source tree, CMake encourages to perform an out-of-source build by using a separate dedicated build tree.
-Developers are strongly encouraged to write [unit tests](src/test/README.md) for new code, and to
-submit new unit tests for old code. Unit tests can be compiled and run
-(assuming they weren't disabled during the generation of the build system) with: `ctest`. Further details on running
-and extending unit tests can be found in [/src/test/README.md](/src/test/README.md).
+### Building on POSIX systems
-There are also [regression and integration tests](/test), written
-in Python.
-These tests can be run (if the [test dependencies](/test) are installed) with: `build/test/functional/test_runner.py`
-(assuming `build` is your build directory).
+ $ cmake -B build # Generate a build system in subdirectory "build"
+ $ cmake --build build # Run the actual build process
+ $ ctest --test-dir build # Run the test suite
+ $ sudo cmake --install build # Install the library into the system (optional)
-The CI (Continuous Integration) systems make sure that every pull request is built for Windows, Linux, and macOS,
-and that unit/sanity tests are run automatically.
+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.
-License
--------
-Elements is released under the terms of the MIT license. See [COPYING](COPYING) for more
-information or see http://opensource.org/licenses/MIT.
+### Cross compiling
-[confidential-transactions]: https://elementsproject.org/features/confidential-transactions
-[opcodes]: https://elementsproject.org/features/opcodes
-[federated-peg]: https://elementsproject.org/features#federatedpeg
-[signed-blocks]: https://elementsproject.org/features#signedblocks
-[asset-issuance]: https://elementsproject.org/features/issued-assets
-[schnorr-signatures]: https://elementsproject.org/features/schnorr-signatures
+To alleviate issues with cross compiling, preconfigured toolchain files are available in the `cmake` directory.
+For example, to cross compile for Windows:
-What is the Elements Project?
------------------
-Elements is an open source, sidechain-capable blockchain platform. It also allows experiments to more rapidly bring technical innovation to the Bitcoin ecosystem.
+ $ cmake -B build -DCMAKE_TOOLCHAIN_FILE=cmake/x86_64-w64-mingw32.toolchain.cmake
-Learn more on the [Elements Project website](https://elementsproject.org)
+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):
-https://github.com/ElementsProject/elementsproject.github.io
+ $ cmake -B build -DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK_ROOT}/build/cmake/android.toolchain.cmake" -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=28
-Secure Reporting
-------------------
-See [our vulnerability reporting guide](SECURITY.md)
+### Building on Windows
+The following example assumes Visual Studio 2022. Using clang-cl is recommended.
+
+In "Developer Command Prompt for VS 2022":
+
+ >cmake -B build -T ClangCL
+ >cmake --build build --config RelWithDebInfo
+
+Usage examples
+-----------
+
+Usage examples can be found in the [examples](examples) directory. To compile them you need to configure with `--enable-examples`.
+ * [ECDSA example](examples/ecdsa.c)
+ * [Schnorr signatures example](examples/schnorr.c)
+ * [Deriving a shared secret (ECDH) example](examples/ecdh.c)
+ * [ElligatorSwift key exchange example](examples/ellswift.c)
+ * [MuSig2 Schnorr multi-signatures example](examples/musig.c)
+
+To compile the examples, make sure the corresponding modules are enabled.
+
+Benchmark
+------------
+If configured with `--enable-benchmark` (which is the default), binaries for benchmarking the libsecp256k1-zkp functions will be present in the root directory after the build.
+
+To print the benchmark result to the command line:
+
+ $ ./bench_name
+
+To create a CSV file for the benchmark result :
+
+ $ ./bench_name | sed '2d;s/ \{1,\}//g' > bench_name.csv
+
+Reporting a vulnerability
+------------
+
+See [SECURITY.md](SECURITY.md)
+
+Contributing to libsecp256k1
+------------
+
+See [CONTRIBUTING.md](CONTRIBUTING.md)
diff --git a/SECURITY.md b/SECURITY.md
index 6975097..4be32e4 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -2,97 +2,13 @@
## Reporting a Vulnerability
-Privately and confidentially send us a description of the vulnerability that you have discovered using an encrypted and authenticated channel. PGP encrypted email is preferred. Our contact information is given below.
-
-In your report, please include as much information as you can, including:
-
-* a description of the vulnerability and how it could be exploited
-* its potential impact (e.g. privacy leak, denial of service, theft of funds)
-* steps or code for reproducing it
-* a proposed patch for remedying it
-
-Also, provide us with a secure means to contact you with any follow up questions we might have.
-
-## Considerations
-
-Please take care not to violate the privacy of users in your report. For example, stack traces or exploit scripts sent to us should never contain private keys or personally identifiable information.
-
-Give us at least one week to investigate the vulnerability you found and up to 90 days to fix it. Also, please give us reasonable advanced notice if at any point you intend to disclose the vulnerability to anyone else.
-
-In general, please investigate and report bugs in a way that makes a reasonable, good faith effort not to be disruptive or harmful to us, this software's users, or the users of dependent projects.
-
-We will take care to inform the maintainers of dependent projects.
-
-## How to Contact Us
-
-Email security@blockstream.com
-
-## Reporting a Vulnerability
-
-To report security issues send an email to security@blockstream.com (not for support).
+To report security issues send an email to secp256k1-security@bitcoincore.org (not for support).
The following keys may be used to communicate sensitive information to developers:
| Name | Fingerprint |
|------|-------------|
-| security@blockstream.com | 1176 542D A98E 71E1 3372 2EF7 4AC8 CC88 6844 A2D6 |
+| Pieter Wuille | 133E AC17 9436 F14A 5CF1 B794 860F EB80 4E66 9320 |
+| Tim Ruffing | 09E0 3F87 1092 E40E 106E 902B 33BC 86AB 80FF 5516 |
You can import a key by running the following command with that individual’s fingerprint: `gpg --keyserver hkps://keys.openpgp.org --recv-keys "<fingerprint>"` Ensure that you put quotes around fingerprints containing spaces.
-
-Confirm this PGP key matches https://blockstream.com/pgp.txt
-
-```
------BEGIN PGP PUBLIC KEY BLOCK-----
-
-mQINBFv/XdQBEAC2iS1uQij2AJSnvQZxScnqf6v0db63QDbS6GjH5PndQ8cF0szv
-YJYCFBigkzj4BkKxbJJlnfPW6Jl3SfzCGDvBW3IYuB3S10InDqJFYcM1ZemWCGAs
-HA48NDfB4AIBIFH09H4dUE/J6yAdhX/+Qa/bjOhiwrCFVE2pVtMN8aTFnaLzxCP+
-fWZUaPrPv84B7uxEdLM77wIhsN+16FAr1qS42NfKDDolBAs//Bmv5fkNC7lzAVCf
-MA/QEcNlAvButPrNyZU3t25maUv5hhKUDdJ2G/iACf8tVgp+ygmD8NHQMLPSaFqa
-O5wy77Fd5OyX3Gii/E8MtPEsePViwecwJqc/3UXBx7zTRou2gxLikVFTnJb+Jit9
-F2kcljhCjHGxsuhf4Zr6zu+RTHHDgdBmpt4t1HA2jft/40r+uWQjL/rNP+01HgZj
-4OLHkSI5VfJsXRn1EqOGpBIzR56f0GaxA0jluQMfkE9PTMxg5+YbrGgdot3l7pQ3
-+mqMu3aim2EYZZHTsMCRt4j4pRn5g4BZan+w7STfA7rIMJu/MjP3G4s+IFMPVRki
-QLwktZSD+x2M9iIsOD4YVheMKtU6WRroFeCkXzIzLYwCuZ4ym/JFJMH+Keuyo254
-5hcymw+ivmPP+xuuoP1npQioRH4RKpfDgskABv8+t5rteV4BtUIWL33A/wARAQAB
-tDlCbG9ja3N0cmVhbSBTZWN1cml0eSBSZXBvcnRpbmcgPHNlY3VyaXR5QGJsb2Nr
-c3RyZWFtLmNvbT6JAk4EEwEKADgWIQQRdlQtqY5x4TNyLvdKyMyIaESi1gUCW/9d
-1AIbAwULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRBKyMyIaESi1lcQD/9HZmtP
-XhKtwC92zTsT5Xqt/K4ckaiJRaUlHeFtfkHpTdXIUFIJjZ1w1JJAWLtRf58MY45U
-5DAOOYQptoXiy4USZkIMH1uBtFSAvyCUXH5cDWK1347G5rUg6Ry8Cxe+wzXOlxfr
-f/9Vs28z+awfIrvk50sj4QW+mMlS69VwuHUl5CJ+BtcqQWQO85ummQxQq8rMw7rD
-AwkftqiMKz+YLw5/xECyiXDDdQr66kdkglbQGgiciS7HNo0SQ2XqTNcGZkRA3lmv
-HYCchZpgr9qxfnLjgVddJB+iNTwFZ7AQ7ZBlYWvu5UIMweuEz+yB7WGbQZLOsRZ8
-OaIPmZ150VX0sQYeXYhoFrraNW6obFqsSklnQbsfw6KsCaFvYhNZgHf177YlrAzq
-puR53H1sOjOQq8pnbjyf4XLhAGMC65LydWtkQK77m46kOBZad9UGg2WKg/SY+3pF
-WWdP7vlsR7oJyElEQfUwBsT16K/6kenyagQ6CzqnF/X+W7P1STndpBJp4lD0RfaD
-v6UyqxPYhUuQ24jP5jm8+RtS+OGB00czY2cVSDgjYVuU80WsW+Qt0XtLKeoVYdCb
-TaKgreicqbz0Afr9hbPIieW2wbQnYlRPjprTVhhGsxlaUb7Kcz7fapliJrKBFgy5
-odUljZ+iSompuiYtFhVYA8e6sx0pRUGOopnkGLkCDQRb/13UARAA3WAlRv6DofgG
-xu+L2ePZb1OCQTkn4Eq+24veGibPvlqFJivF1ebctUtxiKVsz0dXtWcAYk7Rh2I/
-xsEGxIzhjr5VLVOdldM5AgJna6WPvOA4sPXjdy47R71NfEQfg9Svv93mmkpbJsL3
-NuHxvpoeO4A9JrFfwn7WJevXOiUWdKJ+nn0ZPwjYle6i27OfIojyVmZVQEiHC/Il
-LxQEYaNDalAorjnn0b7X7S3Z8pMAb8HqD0RTXXed9LPgbasARyND2I2xy1txUDPI
-Qcq6tIbryGYlegEHuvsE31zRPoNjnXkwABb6qBkUUiZMbRJCYOQXSo7Z2tasKHIJ
-I/FnIj8dmT/IXDb9KiWr8wziGLdgnZx3QZGt5P0LIMFKrfXMNJO7EmO1QMbgZFgk
-JPhJ0o61PvMaVLMQVoxD6K7bKOzI2t4LTA0l5RxuMcadu8G13YzgVXX44Cac1qUn
-xriMzk62HXdSeZozcO/IRN7Kdw2bB++5EVYTQN1EEhIymXVUrBg2pXvLSXalg+kp
-0BhLVHcbTI51mKz8GY9NUShFI7ZEzxzzltcEA+F5TLrPMgT+tx+QvjDdGWIhWycI
-KW53hjKiGolhpG9Kqo9ogtCO2a3r6JspO0z+54/EF5rS2LI13pqk0qNgoYMYqChe
-XU8BJdZ9siCooQ+3o+Y/9TkQWSAwnWkAEQEAAYkCNgQYAQoAIBYhBBF2VC2pjnHh
-M3Iu90rIzIhoRKLWBQJb/13UAhsMAAoJEErIzIhoRKLWGhoP/jFfwRrda1RNR6OY
-NHOIa4x4PtjDuYwDYgI5X2NQXlglyOTWouKjY1eu7LRoQSS5blD7BA9GHhYRDBL/
-0NQo/EQn3JFoitGWs07Bry0A4DTOz0H7wRqVXtN+Ck13QdEemq+suLE+PcbRJ4Ei
-ANoNVgSRGqYO683oXEzGgzF+FXXPbcRTNHwvV8LgmUioe2cgHX3Q2PC3gUTmnNkq
-IhWirlT5cQVSLS2IzsP903uq8VtHl7lXLkS6Ba3CmwLoHYfhurGQNR6Av2WPgL2D
-oY8NOxPdz9QxBUzUVObiMm3UfD/eTF73NAmNJRDqYzpY/l54ZyxLFjlfXRpwKrx/
-islwezx+2fzns5u4xwdywVHzvgsmbXMIDdNTaTS8BDaKbAopLmbmuTnnTbJXWFbb
-mQ2/GHcB0mKuXDkzt+7JMQ0NHtrGC3qvEtnTXZGXr3uIhFDkJSOoaH68dqq5++pz
-GtT+aiv3L120r0pSSyTgbPsrqSlWgXEuJ4uzt3j69J0Qek0YrL0EDxHdnGPW4+fv
-AZiq1RFG8MHOy0Obahed5uqlzXCNtroHdgSQeR+6IkODSsEd+hVdXJs/hjcWLNG5
-VNztar/H4BSwlhKbgvFivOzhj8x5TNoqMM95G8Ew/5idiT/YQgsA6lcwsEZ78t9O
-lTHPj4G8vH5F/zIFb+uQNSlKzuH+
-=8mAH
-
------END PGP PUBLIC KEY BLOCK-----
-```
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000..65286b9
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+set -e
+autoreconf -if --warnings=all
diff --git a/autotools-aux/m4/bitcoin_secp.m4 b/autotools-aux/m4/bitcoin_secp.m4
new file mode 100644
index 0000000..1428d4d
--- /dev/null
+++ b/autotools-aux/m4/bitcoin_secp.m4
@@ -0,0 +1,91 @@
+dnl escape "$0x" below using the m4 quadrigaph @S|@, and escape it again with a \ for the shell.
+AC_DEFUN([SECP_X86_64_ASM_CHECK],[
+AC_MSG_CHECKING(for x86_64 assembly availability)
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+ #include <stdint.h>]],[[
+ uint64_t a = 11, tmp = 0;
+ __asm__ __volatile__("movq \@S|@0x100000000,%1; mulq %%rsi" : "+a"(a) : "S"(tmp) : "cc", "%rdx");
+ ]])], [has_x86_64_asm=yes], [has_x86_64_asm=no])
+AC_MSG_RESULT([$has_x86_64_asm])
+])
+
+AC_DEFUN([SECP_ARM32_ASM_CHECK], [
+ AC_MSG_CHECKING(for ARM32 assembly availability)
+ SECP_ARM32_ASM_CHECK_CFLAGS_saved_CFLAGS="$CFLAGS"
+ CFLAGS="-x assembler"
+ AC_LINK_IFELSE([AC_LANG_SOURCE([[
+ .syntax unified
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+ .text
+ .global main
+ main:
+ ldr r0, =0x002A
+ mov r7, #1
+ swi 0
+ ]])], [has_arm32_asm=yes], [has_arm32_asm=no])
+ AC_MSG_RESULT([$has_arm32_asm])
+ CFLAGS="$SECP_ARM32_ASM_CHECK_CFLAGS_saved_CFLAGS"
+])
+
+AC_DEFUN([SECP_VALGRIND_CHECK],[
+AC_MSG_CHECKING([for valgrind support])
+if test x"$has_valgrind" != x"yes"; then
+ CPPFLAGS_TEMP="$CPPFLAGS"
+ CPPFLAGS="$VALGRIND_CPPFLAGS $CPPFLAGS"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+ #include <valgrind/memcheck.h>
+ ]], [[
+ #if defined(NVALGRIND)
+ # error "Valgrind does not support this platform."
+ #endif
+ ]])], [has_valgrind=yes])
+ CPPFLAGS="$CPPFLAGS_TEMP"
+fi
+AC_MSG_RESULT($has_valgrind)
+])
+
+AC_DEFUN([SECP_MSAN_CHECK], [
+AC_MSG_CHECKING(whether MemorySanitizer is enabled)
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
+ #if defined(__has_feature)
+ # if __has_feature(memory_sanitizer)
+ /* MemorySanitizer is enabled. */
+ # elif
+ # error "MemorySanitizer is disabled."
+ # endif
+ #else
+ # error "__has_feature is not defined."
+ #endif
+ ]])], [msan_enabled=yes], [msan_enabled=no])
+AC_MSG_RESULT([$msan_enabled])
+])
+
+dnl SECP_TRY_APPEND_CFLAGS(flags, VAR)
+dnl Append flags to VAR if CC accepts them.
+AC_DEFUN([SECP_TRY_APPEND_CFLAGS], [
+ AC_MSG_CHECKING([if ${CC} supports $1])
+ SECP_TRY_APPEND_CFLAGS_saved_CFLAGS="$CFLAGS"
+ CFLAGS="$1 $CFLAGS"
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[char foo;]])], [flag_works=yes], [flag_works=no])
+ AC_MSG_RESULT($flag_works)
+ CFLAGS="$SECP_TRY_APPEND_CFLAGS_saved_CFLAGS"
+ if test x"$flag_works" = x"yes"; then
+ $2="$$2 $1"
+ fi
+ unset flag_works
+ AC_SUBST($2)
+])
+
+dnl SECP_SET_DEFAULT(VAR, default, default-dev-mode)
+dnl Set VAR to default or default-dev-mode, depending on whether dev mode is enabled
+AC_DEFUN([SECP_SET_DEFAULT], [
+ if test "${enable_dev_mode+set}" != set; then
+ AC_MSG_ERROR([[Set enable_dev_mode before calling SECP_SET_DEFAULT]])
+ fi
+ if test x"$enable_dev_mode" = x"yes"; then
+ $1="$3"
+ else
+ $1="$2"
+ fi
+])
diff --git a/build_msvc/libelementssimplicity/libelementssimplicity.vcxproj b/build_msvc/libelementssimplicity/libelementssimplicity.vcxproj
deleted file mode 100644
index 068b931..0000000
--- a/build_msvc/libelementssimplicity/libelementssimplicity.vcxproj
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="..\common.init.vcxproj" />
- <PropertyGroup Label="Globals">
- <ProjectGuid>{ABAE25F0-D700-46E1-9EF6-5D6DDFCF8B26}</ProjectGuid>
- </PropertyGroup>
- <PropertyGroup Label="Configuration">
- <ConfigurationType>StaticLibrary</ConfigurationType>
- </PropertyGroup>
- <ItemGroup>
- <ClCompile Include="..\..\src\simplicity\bitstream.c" />
- <ClCompile Include="..\..\src\simplicity\dag.c" />
- <ClCompile Include="..\..\src\simplicity\deserialize.c" />
- <ClCompile Include="..\..\src\simplicity\eval.c" />
- <ClCompile Include="..\..\src\simplicity\frame.c" />
- <ClCompile Include="..\..\src\simplicity\jets-secp256k1.c" />
- <ClCompile Include="..\..\src\simplicity\jets.c" />
- <ClCompile Include="..\..\src\simplicity\rsort.c" />
- <ClCompile Include="..\..\src\simplicity\sha256.c" />
- <ClCompile Include="..\..\src\simplicity\type.c" />
- <ClCompile Include="..\..\src\simplicity\typeInference.c" />
- <ClCompile Include="..\..\src\simplicity\elements\cmr.c" />
- <ClCompile Include="..\..\src\simplicity\elements\env.c" />
- <ClCompile Include="..\..\src\simplicity\elements\exec.c" />
- <ClCompile Include="..\..\src\simplicity\elements\elementsJets.c" />
- <ClCompile Include="..\..\src\simplicity\elements\ops.c" />
- <ClCompile Include="..\..\src\simplicity\elements\primitive.c" />
- <ClCompile Include="..\..\src\simplicity\elements\txEnv.c" />
- </ItemGroup>
- <ItemDefinitionGroup>
- <ClCompile>
- <LanguageStandard_C>stdc11</LanguageStandard_C>
- <DisableSpecificWarnings>4090;4146;4244;4715</DisableSpecificWarnings>
- </ClCompile>
- </ItemDefinitionGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <Import Project="..\common.vcxproj" />
-</Project>
diff --git a/ci/README.md b/ci/README.md
deleted file mode 100644
index 377aae7..0000000
--- a/ci/README.md
+++ /dev/null
@@ -1,56 +0,0 @@
-## CI Scripts
-
-This directory contains scripts for each build step in each build stage.
-
-### Running a Stage Locally
-
-Be aware that the tests will be built and run in-place, so please run at your own risk.
-If the repository is not a fresh git clone, you might have to clean files from previous builds or test runs first.
-
-The ci needs to perform various sysadmin tasks such as installing packages or writing to the user's home directory.
-While it should be fine to run
-the ci system locally on your development box, the ci scripts can generally be assumed to have received less review and
-testing compared to other parts of the codebase. If you want to keep the work tree clean, you might want to run the ci
-system in a virtual machine with a Linux operating system of your choice.
-
-To allow for a wide range of tested environments, but also ensure reproducibility to some extent, the test stage
-requires `bash`, `docker`, and `python3` to be installed. To run on different architectures than the host `qemu` is also required. To install all requirements on Ubuntu, run
-
-```
-sudo apt install bash docker.io python3 qemu-user-static
-```
-
-It is recommended to run the ci system in a clean env. To run the test stage
-with a specific configuration,
-
-```
-env -i HOME="$HOME" PATH="$PATH" USER="$USER" bash -c 'FILE_ENV="./ci/test/00_setup_env_arm.sh" ./ci/test_run_all.sh'
-```
-
-### Configurations
-
-The test files (`FILE_ENV`) are constructed to test a wide range of
-configurations, rather than a single pass/fail. This helps to catch build
-failures and logic errors that present on platforms other than the ones the
-author has tested.
-
-Some builders use the dependency-generator in `./depends`, rather than using
-the system package manager to install build dependencies. This guarantees that
-the tester is using the same versions as the release builds, which also use
-`./depends`.
-
-It is also possible to force a specific configuration without modifying the
-file. For example,
-
-```
-env -i HOME="$HOME" PATH="$PATH" USER="$USER" bash -c 'MAKEJOBS="-j1" FILE_ENV="./ci/test/00_setup_env_arm.sh" ./ci/test_run_all.sh'
-```
-
-The files starting with `0n` (`n` greater than 0) are the scripts that are run
-in order.
-
-### Cache
-
-In order to avoid rebuilding all dependencies for each build, the binaries are
-cached and reused when possible. Changes in the dependency-generator will
-trigger cache-invalidation and rebuilds as necessary.
diff --git a/ci/ci.sh b/ci/ci.sh
new file mode 100755
index 0000000..2185e78
--- /dev/null
+++ b/ci/ci.sh
@@ -0,0 +1,156 @@
+#!/bin/sh
+
+set -eux
+
+export LC_ALL=C
+
+# Print commit and relevant CI environment to allow reproducing the job outside of CI.
+git show --no-patch
+print_environment() {
+ # Turn off -x because it messes up the output
+ set +x
+ # There are many ways to print variable names and their content. This one
+ # does not rely on bash.
+ for var in WERROR_CFLAGS MAKEFLAGS BUILD \
+ ECMULTWINDOW ECMULTGENKB ASM WIDEMUL WITH_VALGRIND EXTRAFLAGS \
+ EXPERIMENTAL ECDH RECOVERY EXTRAKEYS SCHNORRSIG MUSIG SCHNORRSIG_HALFAGG ELLSWIFT \
+ ECDSA_S2C GENERATOR RANGEPROOF SURJECTIONPROOF WHITELIST ECDSAADAPTOR BPPP \
+ SECP256K1_TEST_ITERS BENCH SECP256K1_BENCH_ITERS CTIMETESTS SYMBOL_CHECK \
+ EXAMPLES \
+ HOST WRAPPER_CMD \
+ CC CFLAGS CPPFLAGS AR NM \
+ UBSAN_OPTIONS ASAN_OPTIONS LSAN_OPTIONS
+ do
+ eval "isset=\${$var+x}"
+ if [ -n "$isset" ]; then
+ eval "val=\${$var}"
+ # shellcheck disable=SC2154
+ printf '%s="%s" ' "$var" "$val"
+ fi
+ done
+ echo "$0"
+ set -x
+}
+print_environment
+
+env >> test_env.log
+
+# If gcc is requested, assert that it's in fact gcc (and not some symlinked Apple clang).
+case "${CC:-undefined}" in
+ *gcc*)
+ $CC -v 2>&1 | grep -q "gcc version" || exit 1;
+ ;;
+esac
+
+if [ -n "${CC+x}" ]; then
+ # The MSVC compiler "cl" doesn't understand "-v"
+ $CC -v || true
+fi
+if [ "$WITH_VALGRIND" = "yes" ]; then
+ valgrind --version
+fi
+if [ -n "$WRAPPER_CMD" ]; then
+ $WRAPPER_CMD --version
+fi
+
+./autogen.sh
+
+./configure \
+ --enable-experimental="$EXPERIMENTAL" \
+ --with-test-override-wide-multiply="$WIDEMUL" --with-asm="$ASM" \
+ --with-ecmult-window="$ECMULTWINDOW" \
+ --with-ecmult-gen-kb="$ECMULTGENKB" \
+ --enable-module-ecdh="$ECDH" --enable-module-recovery="$RECOVERY" \
+ --enable-module-ellswift="$ELLSWIFT" \
+ --enable-module-extrakeys="$EXTRAKEYS" \
+ --enable-module-ecdsa-s2c="$ECDSA_S2C" \
+ --enable-module-bppp="$BPPP" \
+ --enable-module-rangeproof="$RANGEPROOF" --enable-module-surjectionproof="$SURJECTIONPROOF" --enable-module-whitelist="$WHITELIST" --enable-module-generator="$GENERATOR" \
+ --enable-module-schnorrsig="$SCHNORRSIG" --enable-module-ecdsa-adaptor="$ECDSAADAPTOR" \
+ --enable-module-musig="$MUSIG" \
+ --enable-module-schnorrsig-halfagg="$SCHNORRSIG_HALFAGG" \
+ --enable-examples="$EXAMPLES" \
+ --enable-ctime-tests="$CTIMETESTS" \
+ --with-valgrind="$WITH_VALGRIND" \
+ --host="$HOST" $EXTRAFLAGS
+
+# We have set "-j<n>" in MAKEFLAGS.
+build_exit_code=0
+make > make.log 2>&1 || build_exit_code=$?
+cat make.log
+if [ $build_exit_code -ne 0 ]; then
+ case "${CC:-undefined}" in
+ *snapshot*)
+ # Ignore internal compiler errors in gcc-snapshot and clang-snapshot
+ grep -e "internal compiler error:" -e "PLEASE submit a bug report" make.log
+ exit $?
+ ;;
+ *)
+ exit 1
+ ;;
+ esac
+fi
+
+# Print information about binaries so that we can see that the architecture is correct
+file *tests* || true
+file bench* || 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-*.dll
+ ;;
+ *)
+ python3 ./tools/symbol-check.py .libs/libsecp256k1.so
+ ;;
+ esac
+fi
+
+# This tells `make check` to wrap test invocations.
+export LOG_COMPILER="$WRAPPER_CMD"
+
+make "$BUILD"
+
+# Using the local `libtool` because on macOS the system's libtool has nothing to do with GNU libtool
+EXEC='./libtool --mode=execute'
+if [ -n "$WRAPPER_CMD" ]
+then
+ EXEC="$EXEC $WRAPPER_CMD"
+fi
+
+if [ "$BENCH" = "yes" ]
+then
+ {
+ $EXEC ./bench_ecmult
+ $EXEC ./bench_internal
+ $EXEC ./bench
+ if [ "$BPPP" = "yes" ]
+ then
+ $EXEC ./bench_bppp
+ fi
+ } >> bench.log 2>&1
+fi
+
+if [ "$CTIMETESTS" = "yes" ]
+then
+ if [ "$WITH_VALGRIND" = "yes" ]; then
+ ./libtool --mode=execute valgrind --error-exitcode=42 ./ctime_tests > ctime_tests.log 2>&1
+ else
+ $EXEC ./ctime_tests > ctime_tests.log 2>&1
+ fi
+fi
+
+# Rebuild precomputed files (if not cross-compiling).
+if [ -z "$HOST" ]
+then
+ make clean-precomp clean-testvectors
+ make precomp testvectors
+fi
+
+# Check that no repo files have been modified by the build.
+# (This fails for example if the precomp files need to be updated in the repo.)
+git diff --exit-code
diff --git a/ci/lint/04_install.sh b/ci/lint/04_install.sh
deleted file mode 100755
index 9ef1f37..0000000
--- a/ci/lint/04_install.sh
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) 2018-present The Bitcoin Core developers
-# Distributed under the MIT software license, see the accompanying
-# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-export LC_ALL=C
-
-export CI_RETRY_EXE="/ci_retry --"
-
-pushd "/"
-
-${CI_RETRY_EXE} apt-get update
-# Lint dependencies:
-# - curl/xz-utils (to install shellcheck)
-# - git (used in many lint scripts)
-# - gpg (used by verify-commits)
-${CI_RETRY_EXE} apt-get install -y curl xz-utils git gpg
-
-PYTHON_PATH="/python_build"
-if [ ! -d "${PYTHON_PATH}/bin" ]; then
- (
- ${CI_RETRY_EXE} git clone --depth=1 https://github.com/pyenv/pyenv.git
- cd pyenv/plugins/python-build || exit 1
- ./install.sh
- )
- # For dependencies see https://github.com/pyenv/pyenv/wiki#suggested-build-environment
- ${CI_RETRY_EXE} apt-get install -y build-essential libssl-dev zlib1g-dev \
- libbz2-dev libreadline-dev libsqlite3-dev curl llvm \
- libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev \
- clang
- env CC=clang python-build "$(cat "/.python-version")" "${PYTHON_PATH}"
-fi
-export PATH="${PYTHON_PATH}/bin:${PATH}"
-command -v python3
-python3 --version
-
-export LINT_RUNNER_PATH="/lint_test_runner"
-if [ ! -d "${LINT_RUNNER_PATH}" ]; then
- ${CI_RETRY_EXE} apt-get install -y cargo
- (
- cd "/test/lint/test_runner" || exit 1
- cargo build
- mkdir -p "${LINT_RUNNER_PATH}"
- mv target/debug/test_runner "${LINT_RUNNER_PATH}"
- )
-fi
-
-${CI_RETRY_EXE} pip3 install \
- codespell==2.2.6 \
- lief==0.13.2 \
- mypy==1.4.1 \
- pyzmq==25.1.0 \
- ruff==0.5.5 \
- vulture==2.6
-
-SHELLCHECK_VERSION=v0.8.0
-curl -sL "https://github.com/koalaman/shellcheck/releases/download/${SHELLCHECK_VERSION}/shellcheck-${SHELLCHECK_VERSION}.linux.x86_64.tar.xz" | \
- tar --xz -xf - --directory /tmp/
-mv "/tmp/shellcheck-${SHELLCHECK_VERSION}/shellcheck" /usr/bin/
-
-MLC_VERSION=v0.19.0
-MLC_BIN=mlc-x86_64-linux
-curl -sL "https://github.com/becheran/mlc/releases/download/${MLC_VERSION}/${MLC_BIN}" -o "/usr/bin/mlc"
-chmod +x /usr/bin/mlc
-
-popd || exit
diff --git a/ci/lint/06_script.sh b/ci/lint/06_script.sh
deleted file mode 100755
index 7e27197..0000000
--- a/ci/lint/06_script.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) 2018-present The Bitcoin Core developers
-# Distributed under the MIT software license, see the accompanying
-# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-export LC_ALL=C
-
-set -ex
-
-if [ -n "$CIRRUS_PR" ]; then
- export COMMIT_RANGE="HEAD~..HEAD"
- if [ "$(git rev-list -1 HEAD)" != "$(git rev-list -1 --merges HEAD)" ]; then
- echo "Error: The top commit must be a merge commit, usually the remote 'pull/${PR_NUMBER}/merge' branch."
- false
- fi
-fi
-
-RUST_BACKTRACE=1 "${LINT_RUNNER_PATH}/test_runner"
-
-if [ "$CIRRUS_REPO_FULL_NAME" = "bitcoin/bitcoin" ] && [ "$CIRRUS_PR" = "" ] ; then
- # Sanity check only the last few commits to get notified of missing sigs,
- # missing keys, or expired keys. Usually there is only one new merge commit
- # per push on the master branch and a few commits on release branches, so
- # sanity checking only a few (10) commits seems sufficient and cheap.
- git log HEAD~10 -1 --format='%H' > ./contrib/verify-commits/trusted-sha512-root-commit
- git log HEAD~10 -1 --format='%H' > ./contrib/verify-commits/trusted-git-root
- mapfile -t KEYS < contrib/verify-commits/trusted-keys
- git config user.email "ci@ci.ci"
- git config user.name "ci"
- ${CI_RETRY_EXE} gpg --keyserver hkps://keys.openpgp.org --recv-keys "${KEYS[@]}" &&
- ./contrib/verify-commits/verify-commits.py;
-fi
diff --git a/ci/lint/container-entrypoint.sh b/ci/lint/container-entrypoint.sh
deleted file mode 100755
index c8519a3..0000000
--- a/ci/lint/container-entrypoint.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) The Bitcoin Core developers
-# Distributed under the MIT software license, see the accompanying
-# file COPYING or https://opensource.org/license/mit/.
-
-export LC_ALL=C
-
-# Fixes permission issues when there is a container UID/GID mismatch with the owner
-# of the mounted bitcoin src dir.
-git config --global --add safe.directory /bitcoin
-
-export PATH="/python_build/bin:${PATH}"
-export LINT_RUNNER_PATH="/lint_test_runner"
-
-if [ -z "$1" ]; then
- bash -ic "./ci/lint/06_script.sh"
-else
- exec "$@"
-fi
diff --git a/ci/lint_imagefile b/ci/lint_imagefile
deleted file mode 100644
index c05f210..0000000
--- a/ci/lint_imagefile
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (c) The Bitcoin Core developers
-# Distributed under the MIT software license, see the accompanying
-# file COPYING or https://opensource.org/license/mit/.
-
-# See test/lint/README.md for usage.
-
-FROM mirror.gcr.io/debian:bookworm
-
-ENV DEBIAN_FRONTEND=noninteractive
-ENV LC_ALL=C.UTF-8
-
-COPY ./ci/retry/retry /ci_retry
-COPY ./.python-version /.python-version
-COPY ./ci/lint/container-entrypoint.sh /entrypoint.sh
-COPY ./ci/lint/04_install.sh /install.sh
-COPY ./test/lint/test_runner /test/lint/test_runner
-
-RUN /install.sh && \
- echo 'alias lint="./ci/lint/06_script.sh"' >> ~/.bashrc && \
- chmod 755 /entrypoint.sh && \
- rm -rf /var/lib/apt/lists/*
-
-
-WORKDIR /bitcoin
-ENTRYPOINT ["/entrypoint.sh"]
diff --git a/ci/lint_run_all.sh b/ci/lint_run_all.sh
deleted file mode 100755
index c57261d..0000000
--- a/ci/lint_run_all.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) 2019-present The Bitcoin Core developers
-# Distributed under the MIT software license, see the accompanying
-# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-export LC_ALL=C.UTF-8
-
-# Only used in .cirrus.yml. Refer to test/lint/README.md on how to run locally.
-
-cp "./ci/retry/retry" "/ci_retry"
-cp "./.python-version" "/.python-version"
-mkdir --parents "/test/lint"
-cp --recursive "./test/lint/test_runner" "/test/lint/"
-set -o errexit; source ./ci/lint/04_install.sh
-set -o errexit
-./ci/lint/06_script.sh
diff --git a/ci/linux-debian.Dockerfile b/ci/linux-debian.Dockerfile
new file mode 100644
index 0000000..a609bc6
--- /dev/null
+++ b/ci/linux-debian.Dockerfile
@@ -0,0 +1,87 @@
+FROM debian:stable-slim
+
+SHELL ["/bin/bash", "-c"]
+
+WORKDIR /root
+
+# A too high maximum number of file descriptors (with the default value
+# inherited from the docker host) can cause issues with some of our tools:
+# - sanitizers hanging: https://github.com/google/sanitizers/issues/1662
+# - valgrind crashing: https://stackoverflow.com/a/75293014
+# This is not be a problem on our CI hosts, but developers who run the image
+# on their machines may run into this (e.g., on Arch Linux), so warn them.
+# (Note that .bashrc is only executed in interactive bash shells.)
+RUN echo 'if [[ $(ulimit -n) -gt 200000 ]]; then echo "WARNING: Very high value reported by \"ulimit -n\". Consider passing \"--ulimit nofile=32768\" to \"docker run\"."; fi' >> /root/.bashrc
+
+RUN dpkg --add-architecture i386 && \
+ dpkg --add-architecture s390x && \
+ dpkg --add-architecture armhf && \
+ dpkg --add-architecture arm64 && \
+ dpkg --add-architecture ppc64el
+
+# dpkg-dev: to make pkg-config work in cross-builds
+# llvm: for llvm-symbolizer, which is used by clang's UBSan for symbolized stack traces
+RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \
+ git ca-certificates \
+ make automake libtool pkg-config dpkg-dev valgrind qemu-user \
+ gcc clang llvm libclang-rt-dev libc6-dbg \
+ g++ \
+ gcc-i686-linux-gnu libc6-dev-i386-cross libc6-dbg:i386 libubsan1:i386 libasan8:i386 \
+ gcc-s390x-linux-gnu libc6-dev-s390x-cross libc6-dbg:s390x \
+ gcc-arm-linux-gnueabihf libc6-dev-armhf-cross libc6-dbg:armhf \
+ gcc-powerpc64le-linux-gnu libc6-dev-ppc64el-cross libc6-dbg:ppc64el \
+ gcc-mingw-w64-x86-64-win32 wine64 wine \
+ gcc-mingw-w64-i686-win32 wine32 \
+ python3-full && \
+ if ! ( dpkg --print-architecture | grep --quiet "arm64" ) ; then \
+ DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \
+ gcc-aarch64-linux-gnu libc6-dev-arm64-cross libc6-dbg:arm64 ;\
+ fi && \
+ apt-get clean && rm -rf /var/lib/apt/lists/*
+
+# Build and install gcc snapshot
+ARG GCC_SNAPSHOT_MAJOR=17
+RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \
+ wget libgmp-dev libmpfr-dev libmpc-dev flex && \
+ mkdir gcc && cd gcc && \
+ wget --progress=dot:giga --https-only --recursive --accept '*.tar.xz' --level 1 --no-directories "https://gcc.gnu.org/pub/gcc/snapshots/LATEST-${GCC_SNAPSHOT_MAJOR}" && \
+ wget "https://gcc.gnu.org/pub/gcc/snapshots/LATEST-${GCC_SNAPSHOT_MAJOR}/sha512.sum" && \
+ sha512sum --check --ignore-missing sha512.sum && \
+ # We should have downloaded exactly one tar.xz file
+ ls && \
+ [ $(ls *.tar.xz | wc -l) -eq "1" ] && \
+ tar xf *.tar.xz && \
+ mkdir gcc-build && cd gcc-build && \
+ ../*/configure --prefix=/opt/gcc-snapshot --enable-languages=c --disable-bootstrap --disable-multilib --without-isl && \
+ make -j $(nproc) && \
+ make install && \
+ cd ../.. && rm -rf gcc && \
+ ln -s /opt/gcc-snapshot/bin/gcc /usr/bin/gcc-snapshot && \
+ apt-get autoremove -y wget libgmp-dev libmpfr-dev libmpc-dev flex && \
+ apt-get clean && rm -rf /var/lib/apt/lists/*
+
+# Install clang snapshot, see https://apt.llvm.org/
+RUN \
+ # Setup GPG keys of LLVM repository
+ apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y wget && \
+ wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc && \
+ # Add repository for this Debian release
+ . /etc/os-release && echo "deb http://apt.llvm.org/${VERSION_CODENAME} llvm-toolchain-${VERSION_CODENAME} main" >> /etc/apt/sources.list && \
+ # Temporarily work around Sequoia PGP policy deadline for legacy repositories.
+ # See https://github.com/llvm/llvm-project/issues/153385.
+ sed -i 's/\(sha1\.second_preimage_resistance =\).*/\1 9999-01-01/' /usr/share/apt/default-sequoia.config && \
+ apt-get update && \
+ # Determine the version number of the LLVM development branch
+ LLVM_VERSION=$(apt-cache search --names-only '^clang-[0-9]+$' | sort -V | tail -1 | cut -f1 -d" " | cut -f2 -d"-" ) && \
+ # Install
+ DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y "clang-${LLVM_VERSION}" "libclang-rt-${LLVM_VERSION}-dev" && \
+ # Create symlink
+ ln -s "/usr/bin/clang-${LLVM_VERSION}" /usr/bin/clang-snapshot && \
+ # Clean up
+ apt-get autoremove -y wget && \
+ 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
diff --git a/ci/retry/README.md b/ci/retry/README.md
deleted file mode 100644
index 1b03c65..0000000
--- a/ci/retry/README.md
+++ /dev/null
@@ -1,123 +0,0 @@
-retry - The command line retry tool
-------------------------------------------
-
-Retry any shell command with exponential backoff or constant delay.
-
-### Instructions
-
-Install:
-
-retry is a shell script, so drop it somewhere and make sure it's added to your $PATH. Or you can use the following one-liner:
-
-```sh
-sudo sh -c "curl https://raw.githubusercontent.com/kadwanev/retry/master/retry -o /usr/local/bin/retry && chmod +x /usr/local/bin/retry"
-```
-
-If you're on OS X, retry is also on Homebrew:
-
-```
-brew pull 27283
-brew install retry
-```
-Not popular enough for homebrew-core. Please star this project to help.
-
-### Usage
-
-Help:
-
-`retry -?`
-
- Usage: retry [options] -- execute command
- -h, -?, --help
- -v, --verbose Verbose output
- -t, --tries=# Set max retries: Default 10
- -s, --sleep=secs Constant sleep amount (seconds)
- -m, --min=secs Exponential Backoff: minimum sleep amount (seconds): Default 0.3
- -x, --max=secs Exponential Backoff: maximum sleep amount (seconds): Default 60
- -f, --fail="script +cmds" Fail Script: run in case of final failure
-
-### Examples
-
-No problem:
-
-`retry echo u work good`
-
- u work good
-
-Test functionality:
-
-`retry 'echo "y u no work"; false'`
-
- y u no work
- Before retry #1: sleeping 0.3 seconds
- y u no work
- Before retry #2: sleeping 0.6 seconds
- y u no work
- Before retry #3: sleeping 1.2 seconds
- y u no work
- Before retry #4: sleeping 2.4 seconds
- y u no work
- Before retry #5: sleeping 4.8 seconds
- y u no work
- Before retry #6: sleeping 9.6 seconds
- y u no work
- Before retry #7: sleeping 19.2 seconds
- y u no work
- Before retry #8: sleeping 38.4 seconds
- y u no work
- Before retry #9: sleeping 60.0 seconds
- y u no work
- Before retry #10: sleeping 60.0 seconds
- y u no work
- etc..
-
-Limit retries:
-
-`retry -t 4 'echo "y u no work"; false'`
-
- y u no work
- Before retry #1: sleeping 0.3 seconds
- y u no work
- Before retry #2: sleeping 0.6 seconds
- y u no work
- Before retry #3: sleeping 1.2 seconds
- y u no work
- Before retry #4: sleeping 2.4 seconds
- y u no work
- Retries exhausted
-
-Bad command:
-
-`retry poop`
-
- bash: poop: command not found
-
-Fail command:
-
-`retry -t 3 -f 'echo "oh poopsickles"' 'echo "y u no work"; false'`
-
- y u no work
- Before retry #1: sleeping 0.3 seconds
- y u no work
- Before retry #2: sleeping 0.6 seconds
- y u no work
- Before retry #3: sleeping 1.2 seconds
- y u no work
- Retries exhausted, running fail script
- oh poopsickles
-
-Last attempt passed:
-
-`retry -t 3 -- 'if [ $RETRY_ATTEMPT -eq 3 ]; then echo Passed at attempt $RETRY_ATTEMPT; true; else echo Failed at attempt $RETRY_ATTEMPT; false; fi;'`
-
- Failed at attempt 0
- Before retry #1: sleeping 0.3 seconds
- Failed at attempt 1
- Before retry #2: sleeping 0.6 seconds
- Failed at attempt 2
- Before retry #3: sleeping 1.2 seconds
- Passed at attempt 3
-
-### License
-
-Apache 2.0 - go nuts
diff --git a/ci/retry/retry b/ci/retry/retry
deleted file mode 100755
index 3c06519..0000000
--- a/ci/retry/retry
+++ /dev/null
@@ -1,163 +0,0 @@
-#!/usr/bin/env bash
-
-GETOPT_BIN=$IN_GETOPT_BIN
-GETOPT_BIN=${GETOPT_BIN:-getopt}
-
-__sleep_amount() {
- if [ -n "$constant_sleep" ]; then
- sleep_time=$constant_sleep
- else
- #TODO: check for awk
- #TODO: check if user would rather use one of the other possible dependencies: python, ruby, bc, dc
- sleep_time=`awk "BEGIN {t = $min_sleep * $(( (1<<($attempts -1)) )); print (t > $max_sleep ? $max_sleep : t)}"`
- fi
-}
-
-__log_out() {
- echo "$1" 1>&2
-}
-
-# Parameters: max_tries min_sleep max_sleep constant_sleep fail_script EXECUTION_COMMAND
-retry()
-{
- local max_tries="$1"; shift
- local min_sleep="$1"; shift
- local max_sleep="$1"; shift
- local constant_sleep="$1"; shift
- local fail_script="$1"; shift
- if [ -n "$VERBOSE" ]; then
- __log_out "Retry Parameters: max_tries=$max_tries min_sleep=$min_sleep max_sleep=$max_sleep constant_sleep=$constant_sleep"
- if [ -n "$fail_script" ]; then __log_out "Fail script: $fail_script"; fi
- __log_out ""
- __log_out "Execution Command: $*"
- __log_out ""
- fi
-
- local attempts=0
- local return_code=1
-
-
- while [[ $return_code -ne 0 && $attempts -le $max_tries ]]; do
- if [ $attempts -gt 0 ]; then
- __sleep_amount
- __log_out "Before retry #$attempts: sleeping $sleep_time seconds"
- sleep $sleep_time
- fi
-
- P="$1"
- for param in "${@:2}"; do P="$P '$param'"; done
- #TODO: replace single quotes in each arg with '"'"' ?
- export RETRY_ATTEMPT=$attempts
- bash -c "$P"
- return_code=$?
- #__log_out "Process returned $return_code on attempt $attempts"
- if [ $return_code -eq 127 ]; then
- # command not found
- exit $return_code
- elif [ $return_code -ne 0 ]; then
- attempts=$[$attempts +1]
- fi
- done
-
- if [ $attempts -gt $max_tries ]; then
- if [ -n "$fail_script" ]; then
- __log_out "Retries exhausted, running fail script"
- eval $fail_script
- else
- __log_out "Retries exhausted"
- fi
- fi
-
- exit $return_code
-}
-
-# If we're being sourced, don't worry about such things
-if [ "$BASH_SOURCE" == "$0" ]; then
- # Prints the help text
- help()
- {
- local retry=$(basename $0)
- cat <<EOF
-Usage: $retry [options] -- execute command
- -h, -?, --help
- -v, --verbose Verbose output
- -t, --tries=# Set max retries: Default 10
- -s, --sleep=secs Constant sleep amount (seconds)
- -m, --min=secs Exponential Backoff: minimum sleep amount (seconds): Default 0.3
- -x, --max=secs Exponential Backoff: maximum sleep amount (seconds): Default 60
- -f, --fail="script +cmds" Fail Script: run in case of final failure
-EOF
- }
-
- # show help for no arguments if stdin is a terminal
- if { [ -z "$1" ] && [ -t 0 ] ; } || [ "$1" == '-h' ] || [ "$1" == '-?' ] || [ "$1" == '--help' ]
- then
- help
- exit 0
- fi
-
- $GETOPT_BIN --test > /dev/null
- if [[ $? -ne 4 ]]; then
- echo "I’m sorry, 'getopt --test' failed in this environment. Please load GNU getopt."
- exit 1
- fi
-
- OPTIONS=vt:s:m:x:f:
- LONGOPTIONS=verbose,tries:,sleep:,min:,max:,fail:
-
- PARSED=$($GETOPT_BIN --options="$OPTIONS" --longoptions="$LONGOPTIONS" --name "$0" -- "$@")
- if [[ $? -ne 0 ]]; then
- # e.g. $? == 1
- # then getopt has complained about wrong arguments to stdout
- exit 2
- fi
- # read getopt’s output this way to handle the quoting right:
- eval set -- "$PARSED"
-
- max_tries=10
- min_sleep=0.3
- max_sleep=60.0
- constant_sleep=
- fail_script=
-
- # now enjoy the options in order and nicely split until we see --
- while true; do
- case "$1" in
- -v|--verbose)
- VERBOSE=true
- shift
- ;;
- -t|--tries)
- max_tries="$2"
- shift 2
- ;;
- -s|--sleep)
- constant_sleep="$2"
- shift 2
- ;;
- -m|--min)
- min_sleep="$2"
- shift 2
- ;;
- -x|--max)
- max_sleep="$2"
- shift 2
- ;;
- -f|--fail)
- fail_script="$2"
- shift 2
- ;;
- --)
- shift
- break
- ;;
- *)
- echo "Programming error"
- exit 3
- ;;
- esac
- done
-
- retry "$max_tries" "$min_sleep" "$max_sleep" "$constant_sleep" "$fail_script" "$@"
-
-fi
diff --git a/ci/test/00_setup_env.sh b/ci/test/00_setup_env.sh
deleted file mode 100755
index 9f794c2..0000000
--- a/ci/test/00_setup_env.sh
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) 2019-present The Bitcoin Core developers
-# Distributed under the MIT software license, see the accompanying
-# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-export LC_ALL=C.UTF-8
-
-set -ex
-
-# The source root dir, usually from git, usually read-only.
-# The ci system copies this folder.
-BASE_READ_ONLY_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )"/../../ >/dev/null 2>&1 && pwd )
-export BASE_READ_ONLY_DIR
-# The destination root dir inside the container.
-# This folder will also hold any SDKs.
-# This folder only exists on the ci guest and will be a copy of BASE_READ_ONLY_DIR
-export BASE_ROOT_DIR="${BASE_ROOT_DIR:-/ci_container_base}"
-# The depends dir.
-# This folder exists only on the ci guest, and on the ci host as a volume.
-export DEPENDS_DIR=${DEPENDS_DIR:-$BASE_ROOT_DIR/depends}
-# A folder for the ci system to put temporary files (build result, datadirs for tests, ...)
-# This folder only exists on the ci guest.
-export BASE_SCRATCH_DIR=${BASE_SCRATCH_DIR:-$BASE_ROOT_DIR/ci/scratch}
-# A folder for the ci system to put executables.
-# This folder only exists on the ci guest.
-export BINS_SCRATCH_DIR="${BASE_SCRATCH_DIR}/bins/"
-
-echo "Setting specific values in env"
-if [ -n "${FILE_ENV}" ]; then
- set -o errexit;
- # shellcheck disable=SC1090
- source "${FILE_ENV}"
-fi
-
-echo "Fallback to default values in env (if not yet set)"
-# The number of parallel jobs to pass down to make and test_runner.py
-export MAKEJOBS=${MAKEJOBS:--j4}
-# Whether to prefer BusyBox over GNU utilities
-export USE_BUSY_BOX=${USE_BUSY_BOX:-false}
-
-export RUN_UNIT_TESTS=${RUN_UNIT_TESTS:-true}
-export RUN_FUNCTIONAL_TESTS=${RUN_FUNCTIONAL_TESTS:-true}
-export RUN_TIDY=${RUN_TIDY:-false}
-# By how much to scale the test_runner timeouts (option --timeout-factor).
-# This is needed because some ci machines have slow CPU or disk, so sanitizers
-# might be slow or a reindex might be waiting on disk IO.
-export TEST_RUNNER_TIMEOUT_FACTOR=${TEST_RUNNER_TIMEOUT_FACTOR:-40}
-export RUN_FUZZ_TESTS=${RUN_FUZZ_TESTS:-false}
-
-# Randomize test order.
-# See https://www.boost.org/doc/libs/1_71_0/libs/test/doc/html/boost_test/utf_reference/rt_param_reference/random.html
-export BOOST_TEST_RANDOM=${BOOST_TEST_RANDOM:-1}
-# See man 7 debconf
-export DEBIAN_FRONTEND=noninteractive
-export CCACHE_MAXSIZE=${CCACHE_MAXSIZE:-500M}
-export CCACHE_TEMPDIR=${CCACHE_TEMPDIR:-/tmp/.ccache-temp}
-export CCACHE_COMPRESS=${CCACHE_COMPRESS:-1}
-# The cache dir.
-# This folder exists only on the ci guest, and on the ci host as a volume.
-export CCACHE_DIR="${CCACHE_DIR:-$BASE_SCRATCH_DIR/ccache}"
-# Folder where the build result is put (bin and lib).
-export BASE_OUTDIR=${BASE_OUTDIR:-$BASE_SCRATCH_DIR/out}
-# The folder for previous release binaries.
-# This folder exists only on the ci guest, and on the ci host as a volume.
-export PREVIOUS_RELEASES_DIR=${PREVIOUS_RELEASES_DIR:-$BASE_ROOT_DIR/prev_releases}
-export CI_BASE_PACKAGES=${CI_BASE_PACKAGES:-build-essential pkgconf curl ca-certificates ccache python3 rsync git procps bison e2fsprogs cmake}
-export GOAL=${GOAL:-install}
-export DIR_QA_ASSETS=${DIR_QA_ASSETS:-${BASE_SCRATCH_DIR}/qa-assets}
-export CI_RETRY_EXE=${CI_RETRY_EXE:-"retry --"}
-
-# The --platform argument used with `docker build` and `docker run`.
-export CI_IMAGE_PLATFORM=${CI_IMAGE_PLATFORM:-"linux"} # Force linux, but use native arch by default
diff --git a/ci/test/00_setup_env_arm.sh b/ci/test/00_setup_env_arm.sh
deleted file mode 100755
index dfeb722..0000000
--- a/ci/test/00_setup_env_arm.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) 2019-present The Bitcoin Core developers
-# Distributed under the MIT software license, see the accompanying
-# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-export LC_ALL=C.UTF-8
-
-export HOST=arm-linux-gnueabihf
-export DPKG_ADD_ARCH="armhf"
-export PACKAGES="python3-zmq g++-arm-linux-gnueabihf busybox libc6:armhf libstdc++6:armhf libfontconfig1:armhf libxcb1:armhf"
-export CONTAINER_NAME=ci_arm_linux
-export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:noble" # Check that https://packages.ubuntu.com/noble/g++-arm-linux-gnueabihf (version 13.3, similar to guix) can cross-compile
-export CI_IMAGE_PLATFORM="linux/arm64"
-export USE_BUSY_BOX=true
-export RUN_UNIT_TESTS=true
-export RUN_FUNCTIONAL_TESTS=false
-export GOAL="install"
-# -Wno-psabi is to disable ABI warnings: "note: parameter passing for argument of type ... changed in GCC 7.1"
-# This could be removed once the ABI change warning does not show up by default
-export BITCOIN_CONFIG="-DREDUCE_EXPORTS=ON -DCMAKE_CXX_FLAGS='-Wno-psabi -Wno-error=maybe-uninitialized'"
diff --git a/ci/test/00_setup_env_i686_multiprocess.sh b/ci/test/00_setup_env_i686_multiprocess.sh
deleted file mode 100755
index c4d5e10..0000000
--- a/ci/test/00_setup_env_i686_multiprocess.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) 2020-present The Bitcoin Core developers
-# Distributed under the MIT software license, see the accompanying
-# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-export LC_ALL=C.UTF-8
-
-export HOST=i686-pc-linux-gnu
-export CONTAINER_NAME=ci_i686_multiprocess
-export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:24.04"
-export CI_IMAGE_PLATFORM="linux/amd64"
-export PACKAGES="llvm clang g++-multilib"
-export DEP_OPTS="DEBUG=1 MULTIPROCESS=1"
-export GOAL="install"
-export TEST_RUNNER_EXTRA="--v2transport"
-export BITCOIN_CONFIG="\
- -DCMAKE_BUILD_TYPE=Debug \
- -DCMAKE_C_COMPILER='clang;-m32' \
- -DCMAKE_CXX_COMPILER='clang++;-m32' \
- -DAPPEND_CPPFLAGS='-DBOOST_MULTI_INDEX_ENABLE_SAFE_MODE' \
-"
-export BITCOIND=elements-node # Used in functional tests
diff --git a/ci/test/00_setup_env_mac_cross.sh b/ci/test/00_setup_env_mac_cross.sh
deleted file mode 100755
index a0d9082..0000000
--- a/ci/test/00_setup_env_mac_cross.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) 2019-present The Bitcoin Core developers
-# Distributed under the MIT software license, see the accompanying
-# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-export LC_ALL=C.UTF-8
-
-export SDK_URL=${SDK_URL:-https://bitcoincore.org/depends-sources/sdks}
-
-export CONTAINER_NAME=ci_macos_cross
-export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:24.04"
-export HOST=x86_64-apple-darwin
-export PACKAGES="clang lld llvm zip"
-export XCODE_VERSION=15.0
-export XCODE_BUILD_ID=15A240d
-export RUN_UNIT_TESTS=false
-export RUN_FUNCTIONAL_TESTS=false
-export GOAL="deploy"
-export BITCOIN_CONFIG="-DBUILD_GUI=ON -DREDUCE_EXPORTS=ON"
diff --git a/ci/test/00_setup_env_mac_native.sh b/ci/test/00_setup_env_mac_native.sh
deleted file mode 100755
index c568dc2..0000000
--- a/ci/test/00_setup_env_mac_native.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) 2019-present The Bitcoin Core developers
-# Distributed under the MIT software license, see the accompanying
-# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-export LC_ALL=C.UTF-8
-
-# Homebrew's python@3.12 is marked as externally managed (PEP 668).
-# Therefore, `--break-system-packages` is needed.
-export PIP_PACKAGES="--break-system-packages zmq"
-export GOAL="install"
-export CMAKE_GENERATOR="Ninja"
-# ELEMENTS: add -fno-stack-check to work around clang bug on macos
-# ELEMENTS: add -Wno-error=deprecated-declarations for C++20 deprecation warnings with boost 1.85
-export BITCOIN_CONFIG="\
- -DBUILD_GUI=ON \
- -DWITH_ZMQ=ON \
- -DREDUCE_EXPORTS=ON \
- -DCMAKE_CXX_FLAGS='-fno-stack-check -Wno-error=deprecated-declarations' \
-"
-export CI_OS_NAME="macos"
-export NO_DEPENDS=1
-export OSX_SDK=""
diff --git a/ci/test/00_setup_env_mac_native_fuzz.sh b/ci/test/00_setup_env_mac_native_fuzz.sh
deleted file mode 100755
index cacf242..0000000
--- a/ci/test/00_setup_env_mac_native_fuzz.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) The Bitcoin Core developers
-# Distributed under the MIT software license, see the accompanying
-# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-export LC_ALL=C.UTF-8
-
-export CMAKE_GENERATOR="Ninja"
-export BITCOIN_CONFIG="-DBUILD_FOR_FUZZING=ON"
-export CI_OS_NAME="macos"
-export NO_DEPENDS=1
-export OSX_SDK=""
-export RUN_UNIT_TESTS=false
-export RUN_FUNCTIONAL_TESTS=false
-export RUN_FUZZ_TESTS=true
-export GOAL="all"
diff --git a/ci/test/00_setup_env_native_asan.sh b/ci/test/00_setup_env_native_asan.sh
deleted file mode 100755
index ead550a..0000000
--- a/ci/test/00_setup_env_native_asan.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) 2019-present The Bitcoin Core developers
-# Distributed under the MIT software license, see the accompanying
-# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-export LC_ALL=C.UTF-8
-
-export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:24.04"
-
-# Only install BCC tracing packages in CI. Container has to match the host for BCC to work.
-if [[ "${INSTALL_BCC_TRACING_TOOLS}" == "true" ]]; then
- # Required for USDT functional tests to run
- BPFCC_PACKAGE="bpfcc-tools linux-headers-$(uname --kernel-release)"
- export CI_CONTAINER_CAP="--privileged -v /sys/kernel:/sys/kernel:rw"
-else
- BPFCC_PACKAGE=""
- export CI_CONTAINER_CAP="--cap-add SYS_PTRACE" # If run with (ASan + LSan), the container needs access to ptrace (https://github.com/google/sanitizers/issues/764)
-fi
-
-export CONTAINER_NAME=ci_native_asan
-export APT_LLVM_V="20"
-export PACKAGES="systemtap-sdt-dev clang-${APT_LLVM_V} llvm-${APT_LLVM_V} libclang-rt-${APT_LLVM_V}-dev python3-zmq qtbase5-dev qttools5-dev qttools5-dev-tools libevent-dev libboost-dev libdb5.3++-dev libzmq3-dev libqrencode-dev libsqlite3-dev ${BPFCC_PACKAGE}"
-export NO_DEPENDS=1
-export GOAL="install"
-export BITCOIN_CONFIG="\
- -DWITH_USDT=ON -DWITH_ZMQ=ON -DWITH_BDB=ON -DWARN_INCOMPATIBLE_BDB=OFF -DBUILD_GUI=ON \
- -DSANITIZERS=address,float-divide-by-zero,integer,undefined \
- -DCMAKE_C_COMPILER=clang-${APT_LLVM_V} \
- -DCMAKE_CXX_COMPILER=clang++-${APT_LLVM_V} \
- -DCMAKE_C_FLAGS='-ftrivial-auto-var-init=pattern' \
- -DCMAKE_CXX_FLAGS='-ftrivial-auto-var-init=pattern -Wno-error=deprecated-declarations' \
- -DAPPEND_CXXFLAGS='-std=c++23' \
- -DAPPEND_CPPFLAGS='-DARENA_DEBUG -DDEBUG_LOCKORDER' \
-"
diff --git a/ci/test/00_setup_env_native_centos.sh b/ci/test/00_setup_env_native_centos.sh
deleted file mode 100755
index c423d78..0000000
--- a/ci/test/00_setup_env_native_centos.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) 2020-present The Bitcoin Core developers
-# Distributed under the MIT software license, see the accompanying
-# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-export LC_ALL=C.UTF-8
-
-export CONTAINER_NAME=ci_native_centos
-export CI_IMAGE_NAME_TAG="quay.io/centos/centos:stream10"
-export CI_BASE_PACKAGES="gcc-c++ glibc-devel libstdc++-devel ccache make git python3 python3-pip which patch xz procps-ng ksh rsync coreutils bison e2fsprogs cmake"
-export PIP_PACKAGES="pyzmq"
-export DEP_OPTS="DEBUG=1" # Temporarily enable a DEBUG=1 build to check for GCC-bug-117966 regressions. This can be removed once the minimum GCC version is bumped to 12 in the previous releases task, see https://github.com/bitcoin/bitcoin/issues/31436#issuecomment-2530717875
-export GOAL="install"
-export BITCOIN_CONFIG="-DWITH_ZMQ=ON -DBUILD_GUI=ON -DREDUCE_EXPORTS=ON -DCMAKE_BUILD_TYPE=Debug"
diff --git a/ci/test/00_setup_env_native_fuzz.sh b/ci/test/00_setup_env_native_fuzz.sh
deleted file mode 100755
index d581c97..0000000
--- a/ci/test/00_setup_env_native_fuzz.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) 2019-present The Bitcoin Core developers
-# Distributed under the MIT software license, see the accompanying
-# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-export LC_ALL=C.UTF-8
-
-export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntu:24.04"
-export CONTAINER_NAME=ci_native_fuzz
-export APT_LLVM_V="20"
-export PACKAGES="clang-${APT_LLVM_V} llvm-${APT_LLVM_V} libclang-rt-${APT_LLVM_V}-dev libevent-dev libboost-dev libsqlite3-dev"
-export NO_DEPENDS=1
-export RUN_UNIT_TESTS=false
-export RUN_FUNCTIONAL_TESTS=false
-export RUN_FUZZ_TESTS=true
-export FUZZ_TESTS_CONFIG="--exclude=coins_view" # work around https://github.com/bitcoin/bitcoin/issues/22233
-export GOAL="all"
-export CI_CONTAINER_CAP="--cap-add SYS_PTRACE" # If run with (ASan + LSan), the container needs access to ptrace (https://github.com/google/sanitizers/issues/764)
-export BITCOIN_CONFIG="\
- -DBUILD_FOR_FUZZING=ON \
- -DSANITIZERS=fuzzer,address,undefined,float-divide-by-zero,integer \
- -DCMAKE_C_COMPILER=clang-${APT_LLVM_V} \
- -DCMAKE_CXX_COMPILER=clang++-${APT_LLVM_V} \
- -DCMAKE_C_FLAGS='-ftrivial-auto-var-init=pattern' \
- -DCMAKE_CXX_FLAGS='-ftrivial-auto-var-init=pattern' \
-"
-export LLVM_SYMBOLIZER_PATH="/usr/bin/llvm-symbolizer-${APT_LLVM_V}"
-export FUZZ_TESTS_CONFIG="${FUZZ_TESTS_CONFIG},wallet_notifications,addrman_serdeser" # ELEMENTS: these take really long
diff --git a/ci/test/00_setup_env_native_fuzz_with_msan.sh b/ci/test/00_setup_env_native_fuzz_with_msan.sh
deleted file mode 100755
index a6e53dc..0000000
--- a/ci/test/00_setup_env_native_fuzz_with_msan.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) 2020-present The Bitcoin Core developers
-# Distributed under the MIT software license, see the accompanying
-# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-export LC_ALL=C.UTF-8
-
-export CI_IMAGE_NAME_TAG="mirror.gcr.io/ubuntuWhy this scored 63/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.