├── .github └── workflows │ ├── README.md │ ├── cron-semi-weekly-update-nightly.yml │ ├── cross.yml │ ├── rust.yml │ └── shellcheck.yml ├── .gitignore ├── CHANGELOG.md ├── Cargo-minimal.lock ├── Cargo-recent.lock ├── Cargo.toml ├── Cross.toml ├── LICENSE ├── README.md ├── clippy.toml ├── contrib ├── crates.sh ├── extra_tests.sh ├── no-std.sh ├── sanitizer.sh ├── test_vars.sh ├── update-lock-files.sh └── wasm.sh ├── examples ├── generate_keys.rs ├── musig.rs ├── sign_verify.rs └── sign_verify_recovery.rs ├── githooks └── pre-commit ├── justfile ├── nightly-version ├── no_std_test ├── Cargo.toml ├── Xargo.toml └── src │ └── main.rs ├── rustfmt.toml ├── secp256k1-sys ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE ├── README.md ├── build.rs ├── depend │ ├── check_uint128_t.c │ ├── lax_der_parsing.c.patch │ ├── scratch.h.patch │ ├── scratch_impl.h.patch │ ├── secp256k1-HEAD-revision.txt │ ├── secp256k1.c.patch │ ├── secp256k1.h.patch │ ├── secp256k1 │ │ ├── .cirrus.yml │ │ ├── .gitattributes │ │ ├── .github │ │ │ ├── actions │ │ │ │ ├── install-homebrew-valgrind │ │ │ │ │ └── action.yml │ │ │ │ └── run-in-docker-action │ │ │ │ │ └── action.yml │ │ │ └── workflows │ │ │ │ └── ci.yml │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── CMakeLists.txt │ │ ├── CMakePresets.json │ │ ├── CONTRIBUTING.md │ │ ├── COPYING │ │ ├── Makefile.am │ │ ├── README.md │ │ ├── SECURITY.md │ │ ├── autogen.sh │ │ ├── build-aux │ │ │ └── m4 │ │ │ │ └── bitcoin_secp.m4 │ │ ├── ci │ │ │ ├── ci.sh │ │ │ └── linux-debian.Dockerfile │ │ ├── cmake │ │ │ ├── CheckArm32Assembly.cmake │ │ │ ├── CheckMemorySanitizer.cmake │ │ │ ├── CheckStringOptionValue.cmake │ │ │ ├── CheckX86_64Assembly.cmake │ │ │ ├── FindValgrind.cmake │ │ │ ├── GeneratePkgConfigFile.cmake │ │ │ ├── TryAppendCFlags.cmake │ │ │ ├── arm-linux-gnueabihf.toolchain.cmake │ │ │ ├── config.cmake.in │ │ │ ├── source_arm32.s │ │ │ └── x86_64-w64-mingw32.toolchain.cmake │ │ ├── configure.ac │ │ ├── contrib │ │ │ ├── lax_der_parsing.c │ │ │ ├── lax_der_parsing.h │ │ │ ├── lax_der_privatekey_parsing.c │ │ │ └── lax_der_privatekey_parsing.h │ │ ├── doc │ │ │ ├── ellswift.md │ │ │ ├── musig.md │ │ │ ├── release-process.md │ │ │ └── safegcd_implementation.md │ │ ├── examples │ │ │ ├── CMakeLists.txt │ │ │ ├── EXAMPLES_COPYING │ │ │ ├── ecdh.c │ │ │ ├── ecdsa.c │ │ │ ├── ellswift.c │ │ │ ├── examples_util.h │ │ │ ├── musig.c │ │ │ └── schnorr.c │ │ ├── include │ │ │ ├── secp256k1.h │ │ │ ├── secp256k1_ecdh.h │ │ │ ├── secp256k1_ellswift.h │ │ │ ├── secp256k1_extrakeys.h │ │ │ ├── secp256k1_musig.h │ │ │ ├── secp256k1_preallocated.h │ │ │ ├── secp256k1_recovery.h │ │ │ └── secp256k1_schnorrsig.h │ │ ├── libsecp256k1.pc.in │ │ ├── sage │ │ │ ├── gen_exhaustive_groups.sage │ │ │ ├── gen_split_lambda_constants.sage │ │ │ ├── group_prover.sage │ │ │ ├── prove_group_implementations.sage │ │ │ ├── secp256k1_params.sage │ │ │ └── weierstrass_prover.sage │ │ ├── src │ │ │ ├── CMakeLists.txt │ │ │ ├── asm │ │ │ │ └── field_10x26_arm.s │ │ │ ├── assumptions.h │ │ │ ├── bench.c │ │ │ ├── bench.h │ │ │ ├── bench_ecmult.c │ │ │ ├── bench_internal.c │ │ │ ├── checkmem.h │ │ │ ├── ctime_tests.c │ │ │ ├── ecdsa.h │ │ │ ├── ecdsa_impl.h │ │ │ ├── eckey.h │ │ │ ├── eckey_impl.h │ │ │ ├── ecmult.h │ │ │ ├── ecmult_compute_table.h │ │ │ ├── ecmult_compute_table_impl.h │ │ │ ├── ecmult_const.h │ │ │ ├── ecmult_const_impl.h │ │ │ ├── ecmult_gen.h │ │ │ ├── ecmult_gen_compute_table.h │ │ │ ├── ecmult_gen_compute_table_impl.h │ │ │ ├── ecmult_gen_impl.h │ │ │ ├── ecmult_impl.h │ │ │ ├── field.h │ │ │ ├── field_10x26.h │ │ │ ├── field_10x26_impl.h │ │ │ ├── field_5x52.h │ │ │ ├── field_5x52_impl.h │ │ │ ├── field_5x52_int128_impl.h │ │ │ ├── field_impl.h │ │ │ ├── group.h │ │ │ ├── group_impl.h │ │ │ ├── hash.h │ │ │ ├── hash_impl.h │ │ │ ├── hsort.h │ │ │ ├── hsort_impl.h │ │ │ ├── int128.h │ │ │ ├── int128_impl.h │ │ │ ├── int128_native.h │ │ │ ├── int128_native_impl.h │ │ │ ├── int128_struct.h │ │ │ ├── int128_struct_impl.h │ │ │ ├── modinv32.h │ │ │ ├── modinv32_impl.h │ │ │ ├── modinv64.h │ │ │ ├── modinv64_impl.h │ │ │ ├── modules │ │ │ │ ├── ecdh │ │ │ │ │ ├── Makefile.am.include │ │ │ │ │ ├── bench_impl.h │ │ │ │ │ ├── main_impl.h │ │ │ │ │ └── tests_impl.h │ │ │ │ ├── ellswift │ │ │ │ │ ├── Makefile.am.include │ │ │ │ │ ├── bench_impl.h │ │ │ │ │ ├── main_impl.h │ │ │ │ │ ├── tests_exhaustive_impl.h │ │ │ │ │ └── tests_impl.h │ │ │ │ ├── extrakeys │ │ │ │ │ ├── Makefile.am.include │ │ │ │ │ ├── main_impl.h │ │ │ │ │ ├── tests_exhaustive_impl.h │ │ │ │ │ └── tests_impl.h │ │ │ │ ├── musig │ │ │ │ │ ├── Makefile.am.include │ │ │ │ │ ├── keyagg.h │ │ │ │ │ ├── keyagg_impl.h │ │ │ │ │ ├── main_impl.h │ │ │ │ │ ├── session.h │ │ │ │ │ ├── session_impl.h │ │ │ │ │ ├── tests_impl.h │ │ │ │ │ └── vectors.h │ │ │ │ ├── recovery │ │ │ │ │ ├── Makefile.am.include │ │ │ │ │ ├── bench_impl.h │ │ │ │ │ ├── main_impl.h │ │ │ │ │ ├── tests_exhaustive_impl.h │ │ │ │ │ └── tests_impl.h │ │ │ │ └── schnorrsig │ │ │ │ │ ├── Makefile.am.include │ │ │ │ │ ├── bench_impl.h │ │ │ │ │ ├── main_impl.h │ │ │ │ │ ├── tests_exhaustive_impl.h │ │ │ │ │ └── tests_impl.h │ │ │ ├── precompute_ecmult.c │ │ │ ├── precompute_ecmult_gen.c │ │ │ ├── precomputed_ecmult.c │ │ │ ├── precomputed_ecmult.h │ │ │ ├── precomputed_ecmult_gen.c │ │ │ ├── precomputed_ecmult_gen.h │ │ │ ├── scalar.h │ │ │ ├── scalar_4x64.h │ │ │ ├── scalar_4x64_impl.h │ │ │ ├── scalar_8x32.h │ │ │ ├── scalar_8x32_impl.h │ │ │ ├── scalar_impl.h │ │ │ ├── scalar_low.h │ │ │ ├── scalar_low_impl.h │ │ │ ├── scratch.h │ │ │ ├── scratch_impl.h │ │ │ ├── secp256k1.c │ │ │ ├── selftest.h │ │ │ ├── testrand.h │ │ │ ├── testrand_impl.h │ │ │ ├── tests.c │ │ │ ├── tests_exhaustive.c │ │ │ ├── testutil.h │ │ │ ├── util.h │ │ │ └── wycheproof │ │ │ │ ├── WYCHEPROOF_COPYING │ │ │ │ ├── ecdsa_secp256k1_sha256_bitcoin_test.h │ │ │ │ └── ecdsa_secp256k1_sha256_bitcoin_test.json │ │ └── tools │ │ │ ├── check-abi.sh │ │ │ ├── test_vectors_musig2_generate.py │ │ │ └── tests_wycheproof_generate.py │ └── util.h.patch ├── src │ ├── lib.rs │ ├── macros.rs │ ├── recovery.rs │ └── types.rs ├── vendor-libsecp.sh └── wasm │ ├── wasm-sysroot │ ├── stdio.h │ ├── stdlib.h │ └── string.h │ └── wasm.c ├── src ├── constants.rs ├── context.rs ├── ecdh.rs ├── ecdsa │ ├── mod.rs │ ├── recovery.rs │ └── serialized_signature.rs ├── ellswift.rs ├── key.rs ├── lib.rs ├── macros.rs ├── musig.rs ├── scalar.rs ├── schnorr.rs ├── secret.rs └── serde_util.rs └── tests └── serde.rs /.github/workflows/README.md: -------------------------------------------------------------------------------- 1 | # rust-bitcoin workflow notes 2 | 3 | We are attempting to run max 20 parallel jobs using GitHub actions (usage limit for free tier). 4 | 5 | ref: https://docs.github.com/en/actions/learn-github-actions/usage-limits-billing-and-administration 6 | 7 | The minimal/recent lock files are handled by CI (`rust.yml`). 8 | 9 | ## Jobs 10 | 11 | Run from `rust.yml` unless stated otherwise. Total 21 jobs but 12 | `Prepare` is quick and must be run first anyway. 13 | 14 | 0. `Prepare` 15 | 1. `Stable - minimal` 16 | 2. `Stable - recent` 17 | 3. `Nightly - minimal` 18 | 4. `Nightly - recent` 19 | 5. `MSRV - minimal` 20 | 6. `MSRV - recent` 21 | 7. `Lint` 22 | 8. `Docs` 23 | 9. `Docsrs` 24 | 10. `Bench` 25 | 11. `Format` 26 | 12. `ASAN` 27 | 13. `Arch32Bit` 28 | 14. `WASM` 29 | 15. `NoStd` 30 | 31 | 16. `Cross testing - aarch64-unknown-linux-gnu` 32 | 17. `Cross testing - i686-unknown-linux-gnu` 33 | 18. `Cross testing - x86_64-pc-windows-gnu` 34 | 19. `Cross testing - x86_64-unknown-linux-gnu` 35 | 20. `Cross testing - aarch64-unknown-linux-musl` 36 | 21. `Cross testing - arm-unknown-linux-gnueabi` 37 | 22. `Cross testing - arm-unknown-linux-gnueabihf` 38 | 23. `Cross testing - armv7-unknown-linux-gnueabihf` 39 | 24. `Cross testing - powerpc-unknown-linux-gnu` 40 | 25. `Cross testing - powerpc64le-unknown-linux-gnu` 41 | 26. `Cross testing - riscv64gc-unknown-linux-gnu` 42 | 27. `Cross testing - s390x-unknown-linux-gnu` 43 | 28. `Cross testing - x86_64-unknown-linux-musl` 44 | -------------------------------------------------------------------------------- /.github/workflows/cron-semi-weekly-update-nightly.yml: -------------------------------------------------------------------------------- 1 | name: Update Nightly rustc 2 | on: 3 | schedule: 4 | - cron: "5 0 * * 1,4" # runs every Monday and Thursday at 00:05 UTC 5 | workflow_dispatch: # allows manual triggering 6 | jobs: 7 | format: 8 | name: Update nightly rustc 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v4 12 | - uses: dtolnay/rust-toolchain@nightly 13 | - name: Update rust.yml to use latest nightly 14 | run: | 15 | set -x 16 | # Not every night has a nightly, so extract the date from whatever 17 | # version of the compiler dtolnay/rust-toolchain gives us. 18 | NIGHTLY_DATE=$(rustc +nightly --verbose --version | sed -ne 's/^commit-date: //p') 19 | # Update the nightly version in the reference file. 20 | echo "nightly-${NIGHTLY_DATE}" > nightly-version 21 | echo "nightly_date=${NIGHTLY_DATE}" >> $GITHUB_ENV 22 | # Some days there is no new nightly. In this case don't make an empty PR. 23 | if ! git diff --exit-code > /dev/null; then 24 | echo "Updated nightly. Opening PR." 25 | echo "changes_made=true" >> $GITHUB_ENV 26 | else 27 | echo "Attempted to update nightly but the latest-nightly date did not change. Not opening any PR." 28 | echo "changes_made=false" >> $GITHUB_ENV 29 | fi 30 | - name: Create Pull Request 31 | if: env.changes_made == 'true' 32 | uses: peter-evans/create-pull-request@v6 33 | with: 34 | token: ${{ secrets.APOELSTRA_CREATE_PR_TOKEN }} 35 | author: Update Nightly Rustc Bot 36 | committer: Update Nightly Rustc Bot 37 | title: Automated daily update to rustc (to nightly-${{ env.nightly_date }}) 38 | body: | 39 | Automated update to Github CI workflow `rust.yml` by [create-pull-request](https://github.com/peter-evans/create-pull-request) GitHub action 40 | commit-message: Automated update to Github CI to rustc nightly-${{ env.nightly_date }} 41 | branch: create-pull-request/daily-nightly-update 42 | -------------------------------------------------------------------------------- /.github/workflows/cross.yml: -------------------------------------------------------------------------------- 1 | on: [push, pull_request] 2 | 3 | name: Cross testing 4 | 5 | jobs: 6 | 7 | Cross: 8 | name: Cross 9 | runs-on: ubuntu-latest 10 | strategy: 11 | fail-fast: false 12 | matrix: 13 | arch: 14 | ############ Tier 1 15 | - aarch64-unknown-linux-gnu 16 | # - i686-pc-windows-gnu # not supported by cross 17 | # - i686-pc-windows-msvc # not supported by cross 18 | - i686-unknown-linux-gnu 19 | # - x86_64-apple-darwin # proprietary apple stuff 20 | - x86_64-pc-windows-gnu 21 | # - x86_64-pc-windows-msvc # not supported by cross 22 | - x86_64-unknown-linux-gnu 23 | ############ Tier 2 with Host Tools 24 | # - aarch64-apple-darwin # proprietary apple stuff 25 | # - aarch64-pc-windows-msvc # not supported by cross 26 | - aarch64-unknown-linux-musl 27 | - arm-unknown-linux-gnueabi 28 | - arm-unknown-linux-gnueabihf 29 | - armv7-unknown-linux-gnueabihf 30 | - powerpc-unknown-linux-gnu 31 | # - powerpc64-unknown-linux-gnu # not supported by cross 32 | - powerpc64le-unknown-linux-gnu 33 | - riscv64gc-unknown-linux-gnu 34 | - s390x-unknown-linux-gnu 35 | # - x86_64-unknown-freebsd # not supported by cross 36 | # - x86_64-unknown-illumos # not supported by cross 37 | - x86_64-unknown-linux-musl 38 | # - x86_64-unknown-netbsd # error in tests "error: test failed, to rerun pass '--lib'", disabled for now 39 | steps: 40 | - name: "Checkout repo" 41 | uses: actions/checkout@v4 42 | - uses: Swatinem/rust-cache@v1.2.0 43 | with: 44 | key: ${{ matrix.feature }}${{ matrix.os }} 45 | - name: "Select toolchain" 46 | uses: dtolnay/rust-toolchain@stable 47 | - name: "Install target" 48 | run: rustup target add ${{ matrix.arch }} 49 | - name: "Install cross" 50 | run: cargo install cross 51 | - name: "Run cross test" 52 | run: cross test --target ${{ matrix.arch }} --verbose 53 | -------------------------------------------------------------------------------- /.github/workflows/shellcheck.yml: -------------------------------------------------------------------------------- 1 | name: Shellcheck 2 | on: 3 | pull_request: 4 | branches: 5 | - master 6 | jobs: 7 | shellcheck: 8 | name: Shellcheck 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v4 12 | - name: Run ShellCheck 13 | uses: ludeeus/action-shellcheck@2.0.0 14 | env: 15 | SHELLCHECK_OPTS: -x # allow outside sources 16 | with: 17 | # This code comes directly from upstream libsecp256k1 18 | # and should not be linted here. 19 | ignore_paths: ./secp256k1-sys/depend/**/*.sh 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | Cargo.lock 3 | *.orig 4 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "secp256k1" 3 | version = "0.31.0" 4 | authors = [ "Dawid Ciężarkiewicz ", 5 | "Andrew Poelstra " ] 6 | license = "CC0-1.0" 7 | homepage = "https://github.com/rust-bitcoin/rust-secp256k1/" 8 | repository = "https://github.com/rust-bitcoin/rust-secp256k1/" 9 | documentation = "https://docs.rs/secp256k1/" 10 | description = "Rust wrapper library for Pieter Wuille's `libsecp256k1`. Implements ECDSA and BIP 340 signatures for the SECG elliptic curve group secp256k1 and related utilities." 11 | keywords = [ "crypto", "ECDSA", "secp256k1", "libsecp256k1", "bitcoin" ] 12 | readme = "README.md" 13 | edition = "2021" 14 | rust-version = "1.63.0" 15 | 16 | [package.metadata.docs.rs] 17 | all-features = true 18 | rustdoc-args = ["--cfg", "docsrs"] 19 | 20 | [features] 21 | default = ["std"] 22 | std = ["alloc", "secp256k1-sys/std", "rand?/std", "rand?/std_rng", "rand?/thread_rng", "hashes?/std"] 23 | # allow use of Secp256k1::new and related API that requires an allocator 24 | alloc = ["secp256k1-sys/alloc"] 25 | recovery = ["secp256k1-sys/recovery"] 26 | lowmemory = ["secp256k1-sys/lowmemory"] 27 | global-context = ["std"] 28 | # disable re-randomization of the global context, which provides some 29 | # defense-in-depth against sidechannel attacks. You should only use 30 | # this feature if you expect the `rand` crate's thread_rng to panic. 31 | # (If you are sure the `rand` and `std` features will not be enabled, e.g. 32 | # if you are doing a no-std build, then this feature does nothing 33 | # and is not necessary.) 34 | global-context-less-secure = ["global-context"] 35 | 36 | [dependencies] 37 | secp256k1-sys = { version = "0.11.0", default-features = false, path = "./secp256k1-sys" } 38 | 39 | hashes = { package = "bitcoin_hashes", version = "0.14", default-features = false, optional = true } 40 | rand = { version = "0.9", default-features = false, optional = true } 41 | serde = { version = "1.0.103", default-features = false, optional = true } 42 | 43 | [dev-dependencies] 44 | rand_core = "0.9" 45 | serde_cbor = "0.10.0" 46 | serde_test = "1.0.19" 47 | bincode = "1.3.3" 48 | hex_lit = "0.1.1" 49 | 50 | [target.wasm32-unknown-unknown.dev-dependencies] 51 | wasm-bindgen-test = "0.3" 52 | getrandom = { version = "0.3", features = ["wasm_js"] } 53 | 54 | [lints.rust] 55 | unexpected_cfgs = { level = "deny", check-cfg = ['cfg(bench)', 'cfg(secp256k1_fuzz)', 'cfg(rust_secp_no_symbol_renaming)'] } 56 | 57 | [[example]] 58 | name = "sign_verify_recovery" 59 | required-features = ["recovery", "hashes", "std"] 60 | 61 | [[example]] 62 | name = "sign_verify" 63 | required-features = ["hashes", "std"] 64 | 65 | [[example]] 66 | name = "generate_keys" 67 | required-features = ["rand", "std"] 68 | 69 | [[example]] 70 | name = "musig" 71 | required-features = ["rand", "std"] 72 | 73 | [workspace] 74 | members = ["secp256k1-sys"] 75 | exclude = ["no_std_test"] 76 | -------------------------------------------------------------------------------- /Cross.toml: -------------------------------------------------------------------------------- 1 | [target.x86_64-pc-windows-gnu] 2 | image = "ghcr.io/cross-rs/x86_64-pc-windows-gnu:main" 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |

Rust Secp256k1

3 | 4 |

5 | Crate Info 6 | CC0 1.0 Universal Licensed 7 | CI Status 8 | API Docs 9 | Rustc Version 1.56.1+ 10 |

11 |
12 | 13 | `rust-secp256k1` is a wrapper around [libsecp256k1](https://github.com/bitcoin-core/secp256k1), a C 14 | library implementing various cryptographic functions using the [SECG](https://www.secg.org/) curve 15 | [secp256k1](https://en.bitcoin.it/wiki/Secp256k1). 16 | 17 | This library: 18 | 19 | * exposes type-safe Rust bindings for all `libsecp256k1` functions 20 | * implements key generation 21 | * implements deterministic nonce generation via RFC6979 22 | * implements many unit tests, adding to those already present in `libsecp256k1` 23 | * makes no allocations (except in unit tests) for efficiency and use in freestanding implementations 24 | 25 | ### Contributing 26 | 27 | Contributions to this library are welcome. A few guidelines: 28 | 29 | * Any breaking changes must have an accompanied entry in CHANGELOG.md 30 | * No new dependencies, please. 31 | * No crypto should be implemented in Rust, with the possible exception of hash functions. Cryptographic contributions should be directed upstream to libsecp256k1. 32 | * This library should always compile with any combination of features on **Rust 1.56.1**. 33 | 34 | ### Githooks 35 | 36 | To assist devs in catching errors _before_ running CI we provide some githooks. If you do not 37 | already have locally configured githooks you can use the ones in this repository by running, in the 38 | root directory of the repository: 39 | ``` 40 | git config --local core.hooksPath githooks/ 41 | ``` 42 | 43 | Alternatively add symlinks in your `.git/hooks` directory to any of the githooks we provide. 44 | 45 | ### Benchmarks 46 | 47 | We use a custom Rust compiler configuration conditional to guard the bench mark code. To run the 48 | bench marks use: `RUSTFLAGS='--cfg=bench' cargo +nightly bench --features=recovery`. 49 | 50 | ### A note on `non_secure_erase` 51 | 52 | This crate's secret types (`SecretKey`, `Keypair`, `SharedSecret`, `Scalar`, and `DisplaySecret`) 53 | have a method called `non_secure_erase` that *attempts* to overwrite the contained secret. This 54 | method is provided to assist other libraries in building secure secret erasure. However, this 55 | library makes no guarantees about the security of using `non_secure_erase`. In particular, 56 | the compiler doesn't have any concept of secrets and in most cases can arbitrarily move or copy 57 | values anywhere it pleases. For more information, consult the [`zeroize`](https://docs.rs/zeroize) 58 | documentation. 59 | 60 | ## Fuzzing 61 | 62 | If you want to fuzz this library, or any library which depends on it, you will 63 | probably want to disable the actual cryptography, since fuzzers are unable to 64 | forge signatures and therefore won't test many interesting codepaths. To instead 65 | use a trivially-broken but fuzzer-accessible signature scheme, compile with 66 | `--cfg=secp256k1_fuzz` in your `RUSTFLAGS` variable. 67 | 68 | Note that `cargo hfuzz` does **not** set this config flag automatically. In 0.27.0 69 | and earlier versions, we used the `--cfg=fuzzing` which honggfuzz does set, but we 70 | changed this because there was no way to override it. 71 | 72 | -------------------------------------------------------------------------------- /clippy.toml: -------------------------------------------------------------------------------- 1 | msrv = "1.63.0" 2 | -------------------------------------------------------------------------------- /contrib/crates.sh: -------------------------------------------------------------------------------- 1 | # No shebang, this file should not be executed. 2 | # shellcheck disable=SC2148 3 | # 4 | # disable verify unused vars, despite the fact that they are used when sourced 5 | # shellcheck disable=SC2034 6 | 7 | # Dot for single crate in workspace to test. 8 | CRATES=(".") 9 | -------------------------------------------------------------------------------- /contrib/extra_tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -ex 4 | 5 | REPO_DIR=$(git rev-parse --show-toplevel) 6 | 7 | # Make all cargo invocations verbose. 8 | export CARGO_TERM_VERBOSE=true 9 | 10 | # Set to false to turn off verbose output. 11 | flag_verbose=true 12 | 13 | # Use the current `Cargo.lock` file without updating it. 14 | cargo="cargo --locked" 15 | 16 | main() { 17 | source_test_vars # Get feature list. 18 | local features="$FEATURES_WITH_STD" 19 | 20 | RUSTFLAGS='--cfg=secp256k1_fuzz' RUSTDOCFLAGS='--cfg=secp256k1_fuzz' $cargo test --locked --all 21 | RUSTFLAGS='--cfg=secp256k1_fuzz' RUSTDOCFLAGS='--cfg=secp256k1_fuzz' $cargo test --locked --all --features="$features" 22 | 23 | $cargo test --all --features="rand serde" 24 | } 25 | 26 | # ShellCheck can't follow non-constant source, `test_vars_script` is correct. 27 | # shellcheck disable=SC1090 28 | source_test_vars() { 29 | local test_vars_script="$REPO_DIR/contrib/test_vars.sh" 30 | 31 | verbose_say "Sourcing $test_vars_script" 32 | 33 | if [ -e "$test_vars_script" ]; then 34 | # Set crate specific variables. 35 | . "$test_vars_script" 36 | else 37 | err "Missing $test_vars_script" 38 | fi 39 | } 40 | 41 | say() { 42 | echo "extra_tests: $1" 43 | } 44 | 45 | verbose_say() { 46 | if [ "$flag_verbose" = true ]; then 47 | say "$1" 48 | fi 49 | } 50 | 51 | err() { 52 | echo "$1" >&2 53 | exit 1 54 | } 55 | 56 | # 57 | # Main script 58 | # 59 | main "$@" 60 | exit 0 61 | -------------------------------------------------------------------------------- /contrib/no-std.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Run no-std tests, requires nightly toolchain. 4 | 5 | set -euox pipefail 6 | 7 | main() { 8 | need_nightly 9 | check_required_commands 10 | 11 | pushd no_std_test > /dev/null 12 | 13 | xargo run --release --target=x86_64-unknown-linux-gnu | grep -q "Verified Successfully" 14 | xargo run --release --target=x86_64-unknown-linux-gnu --features=alloc | grep -q "Verified alloc Successfully" 15 | 16 | popd 17 | } 18 | 19 | # Check all the commands we use are present in the current environment. 20 | check_required_commands() { 21 | need_cmd xargo 22 | } 23 | 24 | need_cmd() { 25 | if ! command -v "$1" > /dev/null 2>&1 26 | then err "need '$1' (command not found)" 27 | fi 28 | } 29 | 30 | err() { 31 | echo "$1" >&2 32 | exit 1 33 | } 34 | 35 | need_nightly() { 36 | cargo_ver=$(cargo --version) 37 | if echo "$cargo_ver" | grep -q -v nightly; then 38 | err "Need a nightly compiler; have $(cargo --version)" 39 | fi 40 | } 41 | 42 | # 43 | # Main script 44 | # 45 | main "$@" 46 | exit 0 47 | -------------------------------------------------------------------------------- /contrib/sanitizer.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Run the Address/Memory Sanitizer tests. 4 | 5 | set -euox pipefail 6 | 7 | REPO_DIR=$(git rev-parse --show-toplevel) 8 | 9 | # Set to true to enable verbose output. 10 | flag_verbose=false 11 | 12 | main() { 13 | source_test_vars # Get feature list. 14 | local features="$FEATURES_WITH_STD" 15 | 16 | clang --version 17 | cargo clean 18 | 19 | CC='clang -fsanitize=address -fno-omit-frame-pointer' \ 20 | RUSTFLAGS='-Zsanitizer=address -Clinker=clang -Cforce-frame-pointers=yes' \ 21 | ASAN_OPTIONS='detect_leaks=1 detect_invalid_pointer_pairs=1 detect_stack_use_after_return=1' \ 22 | cargo test --lib --all --features="$features" -Zbuild-std --target x86_64-unknown-linux-gnu 23 | cargo clean 24 | 25 | # The -Cllvm-args=-msan-eager-checks=0 flag was added to overcome this issue: 26 | # https://github.com/rust-bitcoin/rust-secp256k1/pull/573#issuecomment-1399465995 27 | CC='clang -fsanitize=memory -fno-omit-frame-pointer' \ 28 | RUSTFLAGS='-Zsanitizer=memory -Zsanitizer-memory-track-origins -Cforce-frame-pointers=yes -Cllvm-args=-msan-eager-checks=0' \ 29 | cargo test --lib --all --features="$features" -Zbuild-std --target x86_64-unknown-linux-gnu 30 | } 31 | 32 | # ShellCheck can't follow non-constant source, `test_vars_script` is correct. 33 | # shellcheck disable=SC1090 34 | source_test_vars() { 35 | local test_vars_script="$REPO_DIR/contrib/test_vars.sh" 36 | 37 | verbose_say "Sourcing $test_vars_script" 38 | 39 | if [ -e "$test_vars_script" ]; then 40 | # Set crate specific variables. 41 | . "$test_vars_script" 42 | else 43 | err "Missing $test_vars_script" 44 | fi 45 | } 46 | 47 | say() { 48 | echo "extra_tests: $1" 49 | } 50 | 51 | verbose_say() { 52 | if [ "$flag_verbose" = true ]; then 53 | say "$1" 54 | fi 55 | } 56 | 57 | err() { 58 | echo "$1" >&2 59 | exit 1 60 | } 61 | 62 | # 63 | # Main script 64 | # 65 | main "$@" 66 | exit 0 67 | -------------------------------------------------------------------------------- /contrib/test_vars.sh: -------------------------------------------------------------------------------- 1 | # No shebang, this file should not be executed. 2 | # shellcheck disable=SC2148 3 | # 4 | # disable verify unused vars, despite the fact that they are used when sourced 5 | # shellcheck disable=SC2034 6 | 7 | # Test all these features with "std" enabled. 8 | FEATURES_WITH_STD="hashes global-context global-context-less-secure lowmemory rand recovery serde" 9 | 10 | # Test all these features without "std" enabled. 11 | FEATURES_WITHOUT_STD="hashes global-context global-context-less-secure lowmemory rand recovery serde alloc" 12 | 13 | # Run these examples. 14 | EXAMPLES="sign_verify:hashes,std sign_verify_recovery:hashes,std,recovery generate_keys:rand,std" 15 | -------------------------------------------------------------------------------- /contrib/update-lock-files.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Update the minimal/recent lock file 4 | 5 | set -euo pipefail 6 | 7 | for file in Cargo-minimal.lock Cargo-recent.lock; do 8 | cp --force "$file" Cargo.lock 9 | cargo check 10 | cp --force Cargo.lock "$file" 11 | done 12 | -------------------------------------------------------------------------------- /contrib/wasm.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Run the WASM tests. 4 | # 5 | # The wasm-pack command does not correctly pass args to cargo so we cannot use --locked and test 6 | # with per-commited lockfiles (recent/minimal). Just run the WASM tests from here instead. 7 | 8 | set -euox pipefail 9 | 10 | clang --version 11 | CARGO_TARGET_DIR=wasm cargo install --force wasm-pack 12 | printf '\n[lib]\ncrate-type = ["cdylib", "rlib"]\n' >> Cargo.toml 13 | CC=clang wasm-pack build 14 | CC=clang wasm-pack test --node 15 | -------------------------------------------------------------------------------- /examples/generate_keys.rs: -------------------------------------------------------------------------------- 1 | extern crate secp256k1; 2 | 3 | use secp256k1::{PublicKey, Secp256k1, SecretKey}; 4 | 5 | fn main() { 6 | let secp = Secp256k1::new(); 7 | let mut rng = rand::rng(); 8 | // First option: 9 | let (seckey, pubkey) = secp.generate_keypair(&mut rng); 10 | 11 | assert_eq!(pubkey, PublicKey::from_secret_key(&secp, &seckey)); 12 | 13 | // Second option: 14 | let seckey = SecretKey::new(&mut rng); 15 | let _pubkey = PublicKey::from_secret_key(&secp, &seckey); 16 | } 17 | -------------------------------------------------------------------------------- /examples/musig.rs: -------------------------------------------------------------------------------- 1 | extern crate secp256k1; 2 | 3 | use secp256k1::musig::{ 4 | new_nonce_pair, AggregatedNonce, KeyAggCache, PartialSignature, PublicNonce, Session, 5 | SessionSecretRand, 6 | }; 7 | use secp256k1::{pubkey_sort, Keypair, Message, PublicKey, Scalar, Secp256k1, SecretKey}; 8 | 9 | fn main() { 10 | let secp = Secp256k1::new(); 11 | let mut rng = rand::thread_rng(); 12 | 13 | let (seckey1, pubkey1) = secp.generate_keypair(&mut rng); 14 | 15 | let seckey2 = SecretKey::new(&mut rng); 16 | let pubkey2 = PublicKey::from_secret_key(&secp, &seckey2); 17 | 18 | let pubkeys = [pubkey1, pubkey2]; 19 | let mut pubkeys_ref: Vec<&PublicKey> = pubkeys.iter().collect(); 20 | let pubkeys_ref = pubkeys_ref.as_mut_slice(); 21 | 22 | pubkey_sort(&secp, pubkeys_ref); 23 | 24 | let mut musig_key_agg_cache = KeyAggCache::new(&secp, pubkeys_ref); 25 | 26 | let plain_tweak: [u8; 32] = *b"this could be a BIP32 tweak....\0"; 27 | let xonly_tweak: [u8; 32] = *b"this could be a Taproot tweak..\0"; 28 | 29 | let plain_tweak = Scalar::from_be_bytes(plain_tweak).unwrap(); 30 | musig_key_agg_cache.pubkey_ec_tweak_add(&secp, &plain_tweak).unwrap(); 31 | 32 | let xonly_tweak = Scalar::from_be_bytes(xonly_tweak).unwrap(); 33 | let tweaked_agg_pk = musig_key_agg_cache.pubkey_xonly_tweak_add(&secp, &xonly_tweak).unwrap(); 34 | 35 | let agg_pk = musig_key_agg_cache.agg_pk(); 36 | 37 | assert_eq!(agg_pk, tweaked_agg_pk.x_only_public_key().0); 38 | 39 | let msg_bytes: [u8; 32] = *b"this_could_be_the_hash_of_a_msg!"; 40 | let msg = Message::from_digest_slice(&msg_bytes).unwrap(); 41 | 42 | let musig_session_sec_rand1 = SessionSecretRand::from_rng(&mut rng); 43 | 44 | let nonce_pair1 = new_nonce_pair( 45 | &secp, 46 | musig_session_sec_rand1, 47 | Some(&musig_key_agg_cache), 48 | Some(seckey1), 49 | pubkey1, 50 | Some(msg), 51 | None, 52 | ); 53 | 54 | let musig_session_sec_rand2 = SessionSecretRand::from_rng(&mut rng); 55 | 56 | let nonce_pair2 = new_nonce_pair( 57 | &secp, 58 | musig_session_sec_rand2, 59 | Some(&musig_key_agg_cache), 60 | Some(seckey2), 61 | pubkey2, 62 | Some(msg), 63 | None, 64 | ); 65 | 66 | let sec_nonce1 = nonce_pair1.0; 67 | let pub_nonce1 = nonce_pair1.1; 68 | 69 | let sec_nonce2 = nonce_pair2.0; 70 | let pub_nonce2 = nonce_pair2.1; 71 | 72 | let nonces = [pub_nonce1, pub_nonce2]; 73 | let nonces_ref: Vec<&PublicNonce> = nonces.iter().collect(); 74 | let nonces_ref = nonces_ref.as_slice(); 75 | 76 | let agg_nonce = AggregatedNonce::new(&secp, nonces_ref); 77 | 78 | let session = Session::new(&secp, &musig_key_agg_cache, agg_nonce, msg); 79 | 80 | let keypair1 = Keypair::from_secret_key(&secp, &seckey1); 81 | let partial_sign1 = session.partial_sign(&secp, sec_nonce1, &keypair1, &musig_key_agg_cache); 82 | 83 | let keypair2 = Keypair::from_secret_key(&secp, &seckey2); 84 | let partial_sign2 = session.partial_sign(&secp, sec_nonce2, &keypair2, &musig_key_agg_cache); 85 | 86 | let is_partial_signature_valid = 87 | session.partial_verify(&secp, &musig_key_agg_cache, partial_sign1, pub_nonce1, pubkey1); 88 | assert!(is_partial_signature_valid); 89 | 90 | let is_partial_signature_valid = 91 | session.partial_verify(&secp, &musig_key_agg_cache, partial_sign2, pub_nonce2, pubkey2); 92 | assert!(is_partial_signature_valid); 93 | 94 | let partial_sigs = [partial_sign1, partial_sign2]; 95 | let partial_sigs_ref: Vec<&PartialSignature> = partial_sigs.iter().collect(); 96 | let partial_sigs_ref = partial_sigs_ref.as_slice(); 97 | 98 | let aggregated_signature = session.partial_sig_agg(partial_sigs_ref); 99 | 100 | assert!(aggregated_signature.verify(&secp, &agg_pk, &msg_bytes).is_ok()); 101 | } 102 | -------------------------------------------------------------------------------- /examples/sign_verify.rs: -------------------------------------------------------------------------------- 1 | extern crate hashes; 2 | extern crate secp256k1; 3 | 4 | use hashes::{sha256, Hash}; 5 | use secp256k1::{ecdsa, Error, Message, PublicKey, Secp256k1, SecretKey, Signing, Verification}; 6 | 7 | fn verify( 8 | secp: &Secp256k1, 9 | msg: &[u8], 10 | sig: [u8; 64], 11 | pubkey: [u8; 33], 12 | ) -> Result { 13 | let msg = sha256::Hash::hash(msg); 14 | let msg = Message::from_digest_slice(msg.as_ref())?; 15 | let sig = ecdsa::Signature::from_compact(&sig)?; 16 | let pubkey = PublicKey::from_slice(&pubkey)?; 17 | 18 | Ok(secp.verify_ecdsa(msg, &sig, &pubkey).is_ok()) 19 | } 20 | 21 | fn sign( 22 | secp: &Secp256k1, 23 | msg: &[u8], 24 | seckey: [u8; 32], 25 | ) -> Result { 26 | let msg = sha256::Hash::hash(msg); 27 | let msg = Message::from_digest_slice(msg.as_ref())?; 28 | let seckey = SecretKey::from_slice(&seckey)?; 29 | Ok(secp.sign_ecdsa(msg, &seckey)) 30 | } 31 | 32 | fn main() { 33 | let secp = Secp256k1::new(); 34 | 35 | let seckey = [ 36 | 59, 148, 11, 85, 134, 130, 61, 253, 2, 174, 59, 70, 27, 180, 51, 107, 94, 203, 174, 253, 37 | 102, 39, 170, 146, 46, 252, 4, 143, 236, 12, 136, 28, 38 | ]; 39 | let pubkey = [ 40 | 2, 29, 21, 35, 7, 198, 183, 43, 14, 208, 65, 139, 14, 112, 205, 128, 231, 245, 41, 91, 141, 41 | 134, 245, 114, 45, 63, 82, 19, 251, 210, 57, 79, 54, 42 | ]; 43 | let msg = b"This is some message"; 44 | 45 | let signature = sign(&secp, msg, seckey).unwrap(); 46 | 47 | let serialize_sig = signature.serialize_compact(); 48 | 49 | assert!(verify(&secp, msg, serialize_sig, pubkey).unwrap()); 50 | } 51 | -------------------------------------------------------------------------------- /examples/sign_verify_recovery.rs: -------------------------------------------------------------------------------- 1 | extern crate hashes; 2 | extern crate secp256k1; 3 | 4 | use hashes::{sha256, Hash}; 5 | use secp256k1::{ecdsa, Error, Message, PublicKey, Secp256k1, SecretKey, Signing, Verification}; 6 | 7 | fn recover( 8 | secp: &Secp256k1, 9 | msg: &[u8], 10 | sig: [u8; 64], 11 | recovery_id: u8, 12 | ) -> Result { 13 | let msg = sha256::Hash::hash(msg); 14 | let msg = Message::from_digest_slice(msg.as_ref())?; 15 | let id = ecdsa::RecoveryId::try_from(i32::from(recovery_id))?; 16 | let sig = ecdsa::RecoverableSignature::from_compact(&sig, id)?; 17 | 18 | secp.recover_ecdsa(msg, &sig) 19 | } 20 | 21 | fn sign_recovery( 22 | secp: &Secp256k1, 23 | msg: &[u8], 24 | seckey: [u8; 32], 25 | ) -> Result { 26 | let msg = sha256::Hash::hash(msg); 27 | let msg = Message::from_digest_slice(msg.as_ref())?; 28 | let seckey = SecretKey::from_slice(&seckey)?; 29 | Ok(secp.sign_ecdsa_recoverable(msg, &seckey)) 30 | } 31 | 32 | fn main() { 33 | let secp = Secp256k1::new(); 34 | 35 | let seckey = [ 36 | 59, 148, 11, 85, 134, 130, 61, 253, 2, 174, 59, 70, 27, 180, 51, 107, 94, 203, 174, 253, 37 | 102, 39, 170, 146, 46, 252, 4, 143, 236, 12, 136, 28, 38 | ]; 39 | let pubkey = PublicKey::from_slice(&[ 40 | 2, 29, 21, 35, 7, 198, 183, 43, 14, 208, 65, 139, 14, 112, 205, 128, 231, 245, 41, 91, 141, 41 | 134, 245, 114, 45, 63, 82, 19, 251, 210, 57, 79, 54, 42 | ]) 43 | .unwrap(); 44 | let msg = b"This is some message"; 45 | 46 | let signature = sign_recovery(&secp, msg, seckey).unwrap(); 47 | 48 | let (recovery_id, serialize_sig) = signature.serialize_compact(); 49 | 50 | assert_eq!( 51 | recover(&secp, msg, serialize_sig, Into::::into(recovery_id) as u8), 52 | Ok(pubkey) 53 | ); 54 | } 55 | -------------------------------------------------------------------------------- /githooks/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # A hook script to verify what is about to be committed. 4 | # Called by "git commit" with no arguments. The hook should 5 | # exit with non-zero status after issuing an appropriate message if 6 | # it wants to stop the commit. 7 | 8 | if git rev-parse --verify HEAD >/dev/null 2>&1 9 | then 10 | against=HEAD 11 | else 12 | # Initial commit: diff against an empty tree object 13 | against=$(git hash-object -t tree /dev/null) 14 | fi 15 | 16 | # If you want to allow non-ASCII filenames set this variable to true. 17 | allownonascii=$(git config --bool hooks.allownonascii) 18 | 19 | # Redirect output to stderr. 20 | exec 1>&2 21 | 22 | # Cross platform projects tend to avoid non-ASCII filenames; prevent 23 | # them from being added to the repository. We exploit the fact that the 24 | # printable range starts at the space character and ends with tilde. 25 | if [ "$allownonascii" != "true" ] && 26 | # Note that the use of brackets around a tr range is ok here, (it's 27 | # even required, for portability to Solaris 10's /usr/bin/tr), since 28 | # the square bracket bytes happen to fall in the designated range. 29 | test "$(git diff --cached --name-only --diff-filter=A -z "$against" | 30 | LC_ALL=C tr -d '[ -~]\0' | wc -c)" != 0 31 | then 32 | cat <<\EOF 33 | Error: Attempt to add a non-ASCII file name. 34 | 35 | This can cause problems if you want to work with people on other platforms. 36 | 37 | To be portable it is advisable to rename the file. 38 | 39 | If you know what you are doing you can disable this check using: 40 | 41 | git config hooks.allownonascii true 42 | EOF 43 | exit 1 44 | fi 45 | 46 | # If there are whitespace errors, print the offending file names and fail. 47 | git diff-index --check --cached "$against" -- || exit 1 48 | 49 | # Check that code lints cleanly. 50 | cargo clippy --features=rand,std,recovery,lowmemory,global-context --all-targets -- -D warnings || exit 1 51 | 52 | # Check that there are no formatting issues. 53 | cargo +nightly fmt --check || exit 1 54 | -------------------------------------------------------------------------------- /justfile: -------------------------------------------------------------------------------- 1 | default: 2 | @just --list 3 | 4 | # Cargo build everything. 5 | build: 6 | cargo build --workspace --all-targets --all-features 7 | 8 | # Cargo check everything. 9 | check: 10 | cargo check --workspace --all-targets --all-features 11 | 12 | # Lint everything. 13 | lint: 14 | cargo +$(cat ./nightly-version) clippy --workspace --all-targets --all-features -- --deny warnings 15 | 16 | # Run cargo fmt. 17 | fmt: 18 | cargo +$(cat ./nightly-version) fmt --all 19 | 20 | # Check the formatting. 21 | format: 22 | cargo +$(cat ./nightly-version) fmt --all --check 23 | 24 | # Quick and dirty CI useful for pre-push checks. 25 | sane: lint 26 | cargo test --quiet --workspace --all-targets --no-default-features > /dev/null || exit 1 27 | cargo test --quiet --workspace --all-targets > /dev/null || exit 1 28 | cargo test --quiet --workspace --all-targets --all-features > /dev/null || exit 1 29 | 30 | # doctests don't get run from workspace root with `cargo test`. 31 | cargo test --quiet --workspace --doc || exit 1 32 | 33 | # Make an attempt to catch feature gate problems in doctests 34 | cargo test --doc --no-default-features > /dev/null || exit 1 35 | 36 | # Update the recent and minimal lock files. 37 | update-lock-files: 38 | ./contrib/update-lock-files.sh 39 | -------------------------------------------------------------------------------- /nightly-version: -------------------------------------------------------------------------------- 1 | nightly-2024-08-04 2 | -------------------------------------------------------------------------------- /no_std_test/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "no_std_test" 3 | version = "0.1.0" 4 | authors = ["Elichai Turkel "] 5 | edition = "2021" 6 | 7 | [features] 8 | alloc = ["secp256k1/alloc", "wee_alloc"] 9 | 10 | [dependencies] 11 | wee_alloc = { version = "0.4.5", optional = true } 12 | secp256k1 = { path = "../", default-features = false, features = ["serde", "rand", "recovery"] } 13 | libc = { version = "0.2", default-features = false } 14 | serde_cbor = { version = "0.10", default-features = false } # A random serializer that supports no-std. 15 | 16 | 17 | [profile.release] 18 | panic = "abort" 19 | 20 | [profile.dev] 21 | panic = "abort" 22 | -------------------------------------------------------------------------------- /no_std_test/Xargo.toml: -------------------------------------------------------------------------------- 1 | [dependencies] 2 | alloc = {} 3 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | # Eventually this shoud be: ignore = [] 2 | ignore = [ 3 | "secp256k1-sys" 4 | ] 5 | 6 | hard_tabs = false 7 | tab_spaces = 4 8 | newline_style = "Auto" 9 | indent_style = "Block" 10 | 11 | max_width = 100 # This is number of characters. 12 | # `use_small_heuristics` is ignored if the granular width config values are explicitly set. 13 | use_small_heuristics = "Max" # "Max" == All granular width settings same as `max_width`. 14 | # # Granular width configuration settings. These are percentages of `max_width`. 15 | # fn_call_width = 60 16 | # attr_fn_like_width = 70 17 | # struct_lit_width = 18 18 | # struct_variant_width = 35 19 | # array_width = 60 20 | # chain_width = 60 21 | # single_line_if_else_max_width = 50 22 | 23 | wrap_comments = false 24 | format_code_in_doc_comments = false 25 | comment_width = 100 # Default 80 26 | normalize_comments = false 27 | normalize_doc_attributes = false 28 | format_strings = false 29 | format_macro_matchers = false 30 | format_macro_bodies = true 31 | hex_literal_case = "Preserve" 32 | empty_item_single_line = true 33 | struct_lit_single_line = true 34 | fn_single_line = true # Default false 35 | where_single_line = false 36 | imports_indent = "Block" 37 | imports_layout = "Mixed" 38 | imports_granularity = "Module" # Default "Preserve" 39 | group_imports = "StdExternalCrate" # Default "Preserve" 40 | reorder_imports = true 41 | reorder_modules = true 42 | reorder_impl_items = false 43 | type_punctuation_density = "Wide" 44 | space_before_colon = false 45 | space_after_colon = true 46 | spaces_around_ranges = false 47 | binop_separator = "Front" 48 | remove_nested_parens = true 49 | combine_control_expr = true 50 | overflow_delimited_expr = false 51 | struct_field_align_threshold = 0 52 | enum_discrim_align_threshold = 0 53 | match_arm_blocks = false # Default true 54 | match_arm_leading_pipes = "Never" 55 | force_multiline_blocks = false 56 | fn_params_layout = "Tall" 57 | brace_style = "SameLineWhere" 58 | control_brace_style = "AlwaysSameLine" 59 | trailing_semicolon = true 60 | trailing_comma = "Vertical" 61 | match_block_trailing_comma = false 62 | blank_lines_upper_bound = 1 63 | blank_lines_lower_bound = 0 64 | edition = "2018" 65 | version = "One" 66 | inline_attribute_width = 0 67 | format_generated_files = true 68 | merge_derives = true 69 | use_try_shorthand = false 70 | use_field_init_shorthand = false 71 | force_explicit_abi = true 72 | condense_wildcard_suffixes = false 73 | color = "Auto" 74 | unstable_features = false 75 | disable_all_formatting = false 76 | skip_children = false 77 | show_parse_errors = true 78 | error_on_line_overflow = false 79 | error_on_unformatted = false 80 | emit_mode = "Files" 81 | make_backup = false 82 | -------------------------------------------------------------------------------- /secp256k1-sys/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 0.10.0 - 2024-03-28 2 | 3 | * Bump MSRV to Rust `v1.56.1` [#693](https://github.com/rust-bitcoin/rust-secp256k1/pull/693) 4 | * Vendor `secp256k1 v0.4.1` [#688](https://github.com/rust-bitcoin/rust-secp256k1/pull/688) 5 | 6 | # 0.9.2 - 2023-12-18 7 | 8 | * Fix incorrect FFI binding for `secp256k1_pubkey_combine` 9 | 10 | # 0.9.1 - 2023-12-07 11 | 12 | * Patch out any instances of printf in upstream [#663](https://github.com/rust-bitcoin/rust-secp256k1/pull/663) 13 | 14 | # 0.9.0 - 2023-10-23 15 | 16 | * Add bindings to the ElligatorSwift implementation [#627](https://github.com/rust-bitcoin/rust-secp256k1/pull/627) 17 | * Update vendored lib secp256k1 to v0.4.0 [#653](https://github.com/rust-bitcoin/rust-secp256k1/pull/653) 18 | * Bump MSRV to 1.48 [#595](https://github.com/rust-bitcoin/rust-secp256k1/pull/595) 19 | 20 | # 0.8.1 - 2023-03-16 21 | 22 | * [Implement `insecure-erase`](https://github.com/rust-bitcoin/rust-secp256k1/pull/582). 23 | 24 | # 0.8.0 - 2202-12-19 25 | 26 | * Update libsecp25k1 to v0.2.0 27 | 28 | # 0.7.0 - 2022-12-01 29 | 30 | * [Make comparison functions stable across library versions](https://github.com/rust-bitcoin/rust-secp256k1/pull/518) 31 | * Add public methods `cmp_fast_unstable` and `eq_fast_unstable` for types that contain an inner array (see PR linked above). 32 | 33 | # 0.6.0 - 2022-06-21 34 | 35 | * [Bump MSRV to 1.41](https://github.com/rust-bitcoin/rust-secp256k1/pull/331) 36 | * [Re-implement `Ord` on `PublicKey` using upstream ordering function](https://github.com/rust-bitcoin/rust-secp256k1/pull/449) 37 | 38 | # 0.5.1 - 2022-04-30 39 | 40 | * [Fix WASM build](https://github.com/rust-bitcoin/rust-secp256k1/pull/421) 41 | 42 | # 0.3.0 - 2020-08-27 43 | 44 | * **Update MSRV to 1.29.0** 45 | 46 | # 0.2.0 - 2020-08-26 47 | 48 | * Update upstream to `670cdd3f8be25f81472b2d16dcd228b0d24a5c45` 49 | * [Add missing return](https://github.com/rust-bitcoin/rust-secp256k1/pull/195) `c_int` to `NonceFn` 50 | * [Got wasm support working again](https://github.com/rust-bitcoin/rust-secp256k1/pull/208) 51 | * Removed `cc` restriction, rustc 1.22 support [now requires some downstream effort](https://github.com/rust-bitcoin/rust-secp256k1/pull/204) 52 | * [Exposed a reference to the underlying byte array](https://github.com/rust-bitcoin/rust-secp256k1/pull/219) for all byte-array-wrapping types 53 | * Allow all-zeroes `Message` [to be constructed](https://github.com/rust-bitcoin/rust-secp256k1/pull/207) 54 | * Expose `secp256k1_ec_pubkey_negate` [from upstream](https://github.com/rust-bitcoin/rust-secp256k1/pull/222) 55 | 56 | -------------------------------------------------------------------------------- /secp256k1-sys/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "secp256k1-sys" 3 | version = "0.11.0" 4 | authors = [ "Dawid Ciężarkiewicz ", 5 | "Andrew Poelstra ", 6 | "Steven Roose " ] 7 | license = "CC0-1.0" 8 | homepage = "https://github.com/rust-bitcoin/rust-secp256k1/" 9 | repository = "https://github.com/rust-bitcoin/rust-secp256k1/" 10 | documentation = "https://docs.rs/secp256k1-sys/" 11 | description = "FFI for Pieter Wuille's `libsecp256k1` library." 12 | keywords = [ "secp256k1", "libsecp256k1", "ffi" ] 13 | readme = "README.md" 14 | build = "build.rs" 15 | links = "rustsecp256k1_v0_11" 16 | edition = "2021" 17 | rust-version = "1.63.0" 18 | 19 | [package.metadata.docs.rs] 20 | all-features = true 21 | rustdoc-args = ["--cfg", "docsrs"] 22 | 23 | [build-dependencies] 24 | cc = "1.0.28" 25 | 26 | [dev-dependencies] 27 | libc = "0.2" 28 | 29 | [features] 30 | default = ["std"] 31 | recovery = [] 32 | lowmemory = [] 33 | std = ["alloc"] 34 | alloc = [] 35 | 36 | [lints.rust] 37 | unexpected_cfgs = { level = "deny", check-cfg = ['cfg(bench)', 'cfg(secp256k1_fuzz)', 'cfg(rust_secp_no_symbol_renaming)'] } 38 | -------------------------------------------------------------------------------- /secp256k1-sys/README.md: -------------------------------------------------------------------------------- 1 |
2 |

Rust secp256k1-sys

3 | 4 |

5 | Crate Info 6 | CC0 1.0 Universal Licensed 7 | API Docs 8 | Rustc Version 1.56.1+ 9 |

10 |
11 | 12 | Provides low-level bindings to the C FFI exposed by [libsecp256k1](https://github.com/bitcoin-core/secp256k1). 13 | 14 | ## Vendoring 15 | 16 | The default build process is to build using the vendored `libsecp256k1` sources in the `depend` 17 | directory. These sources are prefixed with a special rust-secp256k1-sys-specific prefix 18 | `rustsecp256k1_v1_2_3_`. 19 | 20 | This prefix ensures that no symbol collision can happen: 21 | 22 | - When a Rust project has two different versions of `rust-secp256k1` in its depepdency tree, or 23 | - When `rust-secp256k1` is used for building a static library in a context where existing 24 | `libsecp256k1` symbols are already linked. 25 | 26 | To update the vendored sources, use the `vendor-libsecp.sh` script: `./vendor-libsecp.sh ` 27 | 28 | - Where `` is the git revision of `libsecp256k1` to checkout. If you do not specify a revision, 29 | the script will simply clone the repo and use whatever revision the default branch is pointing to. 30 | 31 | ## Linking to external symbols 32 | 33 | **Danger: doing this incorrectly may have catastrophic consequences!** 34 | 35 | This is mainly intended for applications consisting of various programming languages that intend to 36 | link the same library to save space, or bundles of multiple binaries coming from the same source. Do 37 | not use this to link to a random secp256k1 library you found in your OS! If you are packaging 38 | software that depends on `rust-secp256k1`, using this flag to link to another package, make sure you 39 | stay within the binary compatibility guarantees of that package. For example, in Debian if you need 40 | `libsecp256k1 1.2.3`, make sure your package requires a version strictly`>= 1.2.3 << 1.2.4`. Note 41 | also that unless you're packaging the library for an official repository you should prefix your 42 | package and the library with a string specific to you. E.g. if you have a set of packages called 43 | `my-awesome-packages` you should package `libsecp256k1` as `libmy-awesome-packages-secp256k1` and 44 | depend on that library/package name from your application. 45 | 46 | If you want to compile this library without using the bundled symbols (which may be required for 47 | integration into other build systems), you can do so by adding `--cfg=rust_secp_no_symbol_renaming'` 48 | to your `RUSTFLAGS` variable. 49 | 50 | ## Minimum Supported Rust Version 51 | 52 | This library should always compile with any combination of features on **Rust 1.56.1**. 53 | -------------------------------------------------------------------------------- /secp256k1-sys/build.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: CC0-1.0 2 | 3 | //! # Build script 4 | 5 | // Coding conventions 6 | #![deny(non_upper_case_globals)] 7 | #![deny(non_camel_case_types)] 8 | #![deny(non_snake_case)] 9 | #![deny(unused_mut)] 10 | #![warn(missing_docs)] 11 | 12 | extern crate cc; 13 | 14 | use std::env; 15 | 16 | fn main() { 17 | // Actual build 18 | let mut base_config = cc::Build::new(); 19 | base_config.include("depend/secp256k1/") 20 | .include("depend/secp256k1/include") 21 | .include("depend/secp256k1/src") 22 | .flag_if_supported("-Wno-unused-function") // some ecmult stuff is defined but not used upstream 23 | .flag_if_supported("-Wno-unused-parameter") // patching out printf causes this warning 24 | .define("SECP256K1_API", Some("")) 25 | .define("ENABLE_MODULE_ECDH", Some("1")) 26 | .define("ENABLE_MODULE_SCHNORRSIG", Some("1")) 27 | .define("ENABLE_MODULE_EXTRAKEYS", Some("1")) 28 | .define("ENABLE_MODULE_ELLSWIFT", Some("1")) 29 | .define("ENABLE_MODULE_MUSIG", Some("1")) 30 | // upstream sometimes introduces calls to printf, which we cannot compile 31 | // with WASM due to its lack of libc. printf is never necessary and we can 32 | // just #define it away. 33 | .define("printf(...)", Some("")); 34 | 35 | if cfg!(feature = "lowmemory") { 36 | base_config.define("ECMULT_WINDOW_SIZE", Some("4")); // A low-enough value to consume negligible memory 37 | base_config.define("ECMULT_GEN_PREC_BITS", Some("2")); 38 | } else { 39 | base_config.define("ECMULT_GEN_PREC_BITS", Some("4")); 40 | base_config.define("ECMULT_WINDOW_SIZE", Some("15")); // This is the default in the configure file (`auto`) 41 | } 42 | base_config.define("USE_EXTERNAL_DEFAULT_CALLBACKS", Some("1")); 43 | #[cfg(feature = "recovery")] 44 | base_config.define("ENABLE_MODULE_RECOVERY", Some("1")); 45 | 46 | // WASM headers and size/align defines. 47 | if env::var("CARGO_CFG_TARGET_ARCH").unwrap() == "wasm32" { 48 | base_config.include("wasm/wasm-sysroot") 49 | .file("wasm/wasm.c"); 50 | } 51 | 52 | // secp256k1 53 | base_config.file("depend/secp256k1/contrib/lax_der_parsing.c") 54 | .file("depend/secp256k1/src/precomputed_ecmult_gen.c") 55 | .file("depend/secp256k1/src/precomputed_ecmult.c") 56 | .file("depend/secp256k1/src/secp256k1.c"); 57 | 58 | if base_config.try_compile("libsecp256k1.a").is_err() { 59 | // Some embedded platforms may not have, eg, string.h available, so if the build fails 60 | // simply try again with the wasm sysroot (but without the wasm type sizes) in the hopes 61 | // that it works. 62 | base_config.include("wasm/wasm-sysroot"); 63 | base_config.compile("libsecp256k1.a"); 64 | } 65 | } 66 | 67 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/check_uint128_t.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | int main(void) { 5 | __uint128_t var_128; 6 | uint64_t var_64; 7 | 8 | /* Try to shut up "unused variable" warnings */ 9 | var_64 = 100; 10 | var_128 = 100; 11 | if (var_64 == var_128) { 12 | var_64 = 20; 13 | } 14 | return 0; 15 | } 16 | 17 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/lax_der_parsing.c.patch: -------------------------------------------------------------------------------- 1 | 10c10,12 2 | < 3 | --- 4 | > extern int secp256k1_ecdsa_signature_parse_compact( 5 | > const secp256k1_context *ctx, 6 | > secp256k1_ecdsa_signature *sig, const unsigned char *input64); 7 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/scratch.h.patch: -------------------------------------------------------------------------------- 1 | 26,29d25 2 | < static secp256k1_scratch* secp256k1_scratch_create(const secp256k1_callback* error_callback, size_t max_size); 3 | < 4 | < static void secp256k1_scratch_destroy(const secp256k1_callback* error_callback, secp256k1_scratch* scratch); 5 | < 6 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/scratch_impl.h.patch: -------------------------------------------------------------------------------- 1 | 13,37d12 2 | < static secp256k1_scratch* secp256k1_scratch_create(const secp256k1_callback* error_callback, size_t size) { 3 | < const size_t base_alloc = ROUND_TO_ALIGN(sizeof(secp256k1_scratch)); 4 | < void *alloc = checked_malloc(error_callback, base_alloc + size); 5 | < secp256k1_scratch* ret = (secp256k1_scratch *)alloc; 6 | < if (ret != NULL) { 7 | < memset(ret, 0, sizeof(*ret)); 8 | < memcpy(ret->magic, "scratch", 8); 9 | < ret->data = (void *) ((char *) alloc + base_alloc); 10 | < ret->max_size = size; 11 | < } 12 | < return ret; 13 | < } 14 | < 15 | < static void secp256k1_scratch_destroy(const secp256k1_callback* error_callback, secp256k1_scratch* scratch) { 16 | < if (scratch != NULL) { 17 | < if (secp256k1_memcmp_var(scratch->magic, "scratch", 8) != 0) { 18 | < secp256k1_callback_call(error_callback, "invalid scratch space"); 19 | < return; 20 | < } 21 | < VERIFY_CHECK(scratch->alloc_size == 0); /* all checkpoints should be applied */ 22 | < memset(scratch->magic, 0, sizeof(scratch->magic)); 23 | < free(scratch); 24 | < } 25 | < } 26 | < 27 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1-HEAD-revision.txt: -------------------------------------------------------------------------------- 1 | # This file was automatically created by vendor-libsecp.sh 2 | 0cdc758a56360bf58a851fe91085a327ec97685a 3 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1.c.patch: -------------------------------------------------------------------------------- 1 | 140,150d139 2 | < secp256k1_context* secp256k1_context_create(unsigned int flags) { 3 | < size_t const prealloc_size = secp256k1_context_preallocated_size(flags); 4 | < secp256k1_context* ctx = (secp256k1_context*)checked_malloc(&default_error_callback, prealloc_size); 5 | < if (EXPECT(secp256k1_context_preallocated_create(ctx, flags) == NULL, 0)) { 6 | < free(ctx); 7 | < return NULL; 8 | < } 9 | < 10 | < return ctx; 11 | < } 12 | < 13 | 162,174d150 14 | < secp256k1_context* secp256k1_context_clone(const secp256k1_context* ctx) { 15 | < secp256k1_context* ret; 16 | < size_t prealloc_size; 17 | < 18 | < VERIFY_CHECK(ctx != NULL); 19 | < ARG_CHECK(secp256k1_context_is_proper(ctx)); 20 | < 21 | < prealloc_size = secp256k1_context_preallocated_clone_size(ctx); 22 | < ret = (secp256k1_context*)checked_malloc(&ctx->error_callback, prealloc_size); 23 | < ret = secp256k1_context_preallocated_clone(ctx, ret); 24 | < return ret; 25 | < } 26 | < 27 | 186,197d161 28 | < void secp256k1_context_destroy(secp256k1_context* ctx) { 29 | < ARG_CHECK_VOID(ctx == NULL || secp256k1_context_is_proper(ctx)); 30 | < 31 | < /* Defined as noop */ 32 | < if (ctx == NULL) { 33 | < return; 34 | < } 35 | < 36 | < secp256k1_context_preallocated_destroy(ctx); 37 | < free(ctx); 38 | < } 39 | < 40 | 223,232d185 41 | < } 42 | < 43 | < static secp256k1_scratch_space* secp256k1_scratch_space_create(const secp256k1_context* ctx, size_t max_size) { 44 | < VERIFY_CHECK(ctx != NULL); 45 | < return secp256k1_scratch_create(&ctx->error_callback, max_size); 46 | < } 47 | < 48 | < static void secp256k1_scratch_space_destroy(const secp256k1_context *ctx, secp256k1_scratch_space* scratch) { 49 | < VERIFY_CHECK(ctx != NULL); 50 | < secp256k1_scratch_destroy(&ctx->error_callback, scratch); 51 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1.h.patch: -------------------------------------------------------------------------------- 1 | 236d235 2 | < SECP256K1_API const secp256k1_context *secp256k1_context_static; 3 | 239,240d237 4 | < SECP256K1_API const secp256k1_context *secp256k1_context_no_precomp 5 | < SECP256K1_DEPRECATED("Use secp256k1_context_static instead"); 6 | 286,289d282 7 | < SECP256K1_API secp256k1_context *secp256k1_context_create( 8 | < unsigned int flags 9 | < ) SECP256K1_WARN_UNUSED_RESULT; 10 | < 11 | 302,305d294 12 | < SECP256K1_API secp256k1_context *secp256k1_context_clone( 13 | < const secp256k1_context *ctx 14 | < ) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT; 15 | < 16 | 320,323d308 17 | < SECP256K1_API void secp256k1_context_destroy( 18 | < secp256k1_context *ctx 19 | < ) SECP256K1_ARG_NONNULL(1); 20 | < 21 | 636d610 22 | < SECP256K1_API const secp256k1_nonce_function secp256k1_nonce_function_rfc6979; 23 | 639d612 24 | < SECP256K1_API const secp256k1_nonce_function secp256k1_nonce_function_default; 25 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/.cirrus.yml: -------------------------------------------------------------------------------- 1 | env: 2 | ### cirrus config 3 | CIRRUS_CLONE_DEPTH: 1 4 | ### compiler options 5 | HOST: 6 | WRAPPER_CMD: 7 | # Specific warnings can be disabled with -Wno-error=foo. 8 | # -pedantic-errors is not equivalent to -Werror=pedantic and thus not implied by -Werror according to the GCC manual. 9 | WERROR_CFLAGS: -Werror -pedantic-errors 10 | MAKEFLAGS: -j4 11 | BUILD: check 12 | ### secp256k1 config 13 | ECMULTWINDOW: 15 14 | ECMULTGENKB: 22 15 | ASM: no 16 | WIDEMUL: auto 17 | WITH_VALGRIND: yes 18 | EXTRAFLAGS: 19 | ### secp256k1 modules 20 | EXPERIMENTAL: no 21 | ECDH: no 22 | RECOVERY: no 23 | EXTRAKEYS: no 24 | SCHNORRSIG: no 25 | MUSIG: no 26 | ELLSWIFT: no 27 | ### test options 28 | SECP256K1_TEST_ITERS: 64 29 | BENCH: yes 30 | SECP256K1_BENCH_ITERS: 2 31 | CTIMETESTS: yes 32 | # Compile and run the tests 33 | EXAMPLES: yes 34 | 35 | cat_logs_snippet: &CAT_LOGS 36 | always: 37 | cat_tests_log_script: 38 | - cat tests.log || true 39 | cat_noverify_tests_log_script: 40 | - cat noverify_tests.log || true 41 | cat_exhaustive_tests_log_script: 42 | - cat exhaustive_tests.log || true 43 | cat_ctime_tests_log_script: 44 | - cat ctime_tests.log || true 45 | cat_bench_log_script: 46 | - cat bench.log || true 47 | cat_config_log_script: 48 | - cat config.log || true 49 | cat_test_env_script: 50 | - cat test_env.log || true 51 | cat_ci_env_script: 52 | - env 53 | 54 | linux_arm64_container_snippet: &LINUX_ARM64_CONTAINER 55 | env_script: 56 | - env | tee /tmp/env 57 | build_script: 58 | - DOCKER_BUILDKIT=1 docker build --file "ci/linux-debian.Dockerfile" --tag="ci_secp256k1_arm" 59 | - docker image prune --force # Cleanup stale layers 60 | test_script: 61 | - docker run --rm --mount "type=bind,src=./,dst=/ci_secp256k1" --env-file /tmp/env --replace --name "ci_secp256k1_arm" "ci_secp256k1_arm" bash -c "cd /ci_secp256k1/ && ./ci/ci.sh" 62 | 63 | task: 64 | name: "ARM64: Linux (Debian stable)" 65 | persistent_worker: 66 | labels: 67 | type: arm64 68 | env: 69 | ECDH: yes 70 | RECOVERY: yes 71 | EXTRAKEYS: yes 72 | SCHNORRSIG: yes 73 | MUSIG: yes 74 | ELLSWIFT: yes 75 | matrix: 76 | # Currently only gcc-snapshot, the other compilers are tested on GHA with QEMU 77 | - env: { CC: 'gcc-snapshot' } 78 | << : *LINUX_ARM64_CONTAINER 79 | << : *CAT_LOGS 80 | 81 | task: 82 | name: "ARM64: Linux (Debian stable), Valgrind" 83 | persistent_worker: 84 | labels: 85 | type: arm64 86 | env: 87 | ECDH: yes 88 | RECOVERY: yes 89 | EXTRAKEYS: yes 90 | SCHNORRSIG: yes 91 | MUSIG: yes 92 | ELLSWIFT: yes 93 | WRAPPER_CMD: 'valgrind --error-exitcode=42' 94 | SECP256K1_TEST_ITERS: 2 95 | matrix: 96 | - env: { CC: 'gcc' } 97 | - env: { CC: 'clang' } 98 | - env: { CC: 'gcc-snapshot' } 99 | - env: { CC: 'clang-snapshot' } 100 | << : *LINUX_ARM64_CONTAINER 101 | << : *CAT_LOGS 102 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/.gitattributes: -------------------------------------------------------------------------------- 1 | src/precomputed_ecmult.c linguist-generated 2 | src/precomputed_ecmult_gen.c linguist-generated 3 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/.github/actions/install-homebrew-valgrind/action.yml: -------------------------------------------------------------------------------- 1 | name: "Install Valgrind" 2 | description: "Install Homebrew's Valgrind package and cache it." 3 | runs: 4 | using: "composite" 5 | steps: 6 | - run: | 7 | brew tap LouisBrunner/valgrind 8 | brew fetch --HEAD LouisBrunner/valgrind/valgrind 9 | echo "CI_HOMEBREW_CELLAR_VALGRIND=$(brew --cellar valgrind)" >> "$GITHUB_ENV" 10 | shell: bash 11 | 12 | - run: | 13 | sw_vers > valgrind_fingerprint 14 | brew --version >> valgrind_fingerprint 15 | git -C "$(brew --cache)/valgrind--git" rev-parse HEAD >> valgrind_fingerprint 16 | cat valgrind_fingerprint 17 | shell: bash 18 | 19 | - uses: actions/cache@v4 20 | id: cache 21 | with: 22 | path: ${{ env.CI_HOMEBREW_CELLAR_VALGRIND }} 23 | key: ${{ github.job }}-valgrind-${{ hashFiles('valgrind_fingerprint') }} 24 | 25 | - if: steps.cache.outputs.cache-hit != 'true' 26 | run: | 27 | brew install --HEAD LouisBrunner/valgrind/valgrind 28 | shell: bash 29 | 30 | - if: steps.cache.outputs.cache-hit == 'true' 31 | run: | 32 | brew link valgrind 33 | shell: bash 34 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/.github/actions/run-in-docker-action/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Run in Docker with environment' 2 | description: 'Run a command in a Docker container, while passing explicitly set environment variables into the container.' 3 | inputs: 4 | dockerfile: 5 | description: 'A Dockerfile that defines an image' 6 | required: true 7 | tag: 8 | description: 'A tag of an image' 9 | required: true 10 | command: 11 | description: 'A command to run in a container' 12 | required: false 13 | default: ./ci/ci.sh 14 | runs: 15 | using: "composite" 16 | steps: 17 | - uses: docker/setup-buildx-action@v3 18 | 19 | - uses: docker/build-push-action@v5 20 | id: main_builder 21 | continue-on-error: true 22 | with: 23 | context: . 24 | file: ${{ inputs.dockerfile }} 25 | tags: ${{ inputs.tag }} 26 | load: true 27 | cache-from: type=gha 28 | 29 | - uses: docker/build-push-action@v5 30 | id: retry_builder 31 | if: steps.main_builder.outcome == 'failure' 32 | with: 33 | context: . 34 | file: ${{ inputs.dockerfile }} 35 | tags: ${{ inputs.tag }} 36 | load: true 37 | cache-from: type=gha 38 | 39 | - # Workaround for https://github.com/google/sanitizers/issues/1614 . 40 | # The underlying issue has been fixed in clang 18.1.3. 41 | run: sudo sysctl -w vm.mmap_rnd_bits=28 42 | shell: bash 43 | 44 | - # Tell Docker to pass environment variables in `env` into the container. 45 | run: > 46 | docker run \ 47 | $(echo '${{ toJSON(env) }}' | jq -r 'keys[] | "--env \(.) "') \ 48 | --volume ${{ github.workspace }}:${{ github.workspace }} \ 49 | --workdir ${{ github.workspace }} \ 50 | ${{ inputs.tag }} bash -c " 51 | git config --global --add safe.directory ${{ github.workspace }} 52 | ${{ inputs.command }} 53 | " 54 | shell: bash 55 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/.gitignore: -------------------------------------------------------------------------------- 1 | bench 2 | bench_ecmult 3 | bench_internal 4 | noverify_tests 5 | tests 6 | exhaustive_tests 7 | precompute_ecmult_gen 8 | precompute_ecmult 9 | ctime_tests 10 | ecdh_example 11 | ecdsa_example 12 | schnorr_example 13 | ellswift_example 14 | musig_example 15 | *.exe 16 | *.so 17 | *.a 18 | *.csv 19 | *.log 20 | *.trs 21 | *.sage.py 22 | 23 | Makefile 24 | configure 25 | .libs/ 26 | Makefile.in 27 | aclocal.m4 28 | autom4te.cache/ 29 | config.log 30 | config.status 31 | conftest* 32 | *.tar.gz 33 | *.la 34 | libtool 35 | .deps/ 36 | .dirstamp 37 | *.lo 38 | *.o 39 | *~ 40 | 41 | coverage/ 42 | coverage.html 43 | coverage.*.html 44 | *.gcda 45 | *.gcno 46 | *.gcov 47 | 48 | build-aux/ar-lib 49 | build-aux/config.guess 50 | build-aux/config.sub 51 | build-aux/depcomp 52 | build-aux/install-sh 53 | build-aux/ltmain.sh 54 | build-aux/m4/libtool.m4 55 | build-aux/m4/lt~obsolete.m4 56 | build-aux/m4/ltoptions.m4 57 | build-aux/m4/ltsugar.m4 58 | build-aux/m4/ltversion.m4 59 | build-aux/missing 60 | build-aux/compile 61 | build-aux/test-driver 62 | libsecp256k1.pc 63 | 64 | ### CMake 65 | /CMakeUserPresets.json 66 | # Default CMake build directory. 67 | /build 68 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/CMakePresets.json: -------------------------------------------------------------------------------- 1 | { 2 | "cmakeMinimumRequired": {"major": 3, "minor": 21, "patch": 0}, 3 | "version": 3, 4 | "configurePresets": [ 5 | { 6 | "name": "dev-mode", 7 | "displayName": "Development mode (intended only for developers of the library)", 8 | "cacheVariables": { 9 | "SECP256K1_EXPERIMENTAL": "ON", 10 | "SECP256K1_ENABLE_MODULE_RECOVERY": "ON", 11 | "SECP256K1_BUILD_EXAMPLES": "ON" 12 | }, 13 | "warnings": { 14 | "dev": true, 15 | "uninitialized": true 16 | } 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/COPYING: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Pieter Wuille 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Reporting a Vulnerability 4 | 5 | To report security issues send an email to secp256k1-security@bitcoincore.org (not for support). 6 | 7 | The following keys may be used to communicate sensitive information to developers: 8 | 9 | | Name | Fingerprint | 10 | |------|-------------| 11 | | Pieter Wuille | 133E AC17 9436 F14A 5CF1 B794 860F EB80 4E66 9320 | 12 | | Jonas Nick | 36C7 1A37 C9D9 88BD E825 08D9 B1A7 0E4F 8DCD 0366 | 13 | | Tim Ruffing | 09E0 3F87 1092 E40E 106E 902B 33BC 86AB 80FF 5516 | 14 | 15 | You can import a key by running the following command with that individual’s fingerprint: `gpg --keyserver hkps://keys.openpgp.org --recv-keys ""` Ensure that you put quotes around fingerprints containing spaces. 16 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | autoreconf -if --warnings=all 4 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/build-aux/m4/bitcoin_secp.m4: -------------------------------------------------------------------------------- 1 | dnl escape "$0x" below using the m4 quadrigaph @S|@, and escape it again with a \ for the shell. 2 | AC_DEFUN([SECP_X86_64_ASM_CHECK],[ 3 | AC_MSG_CHECKING(for x86_64 assembly availability) 4 | AC_LINK_IFELSE([AC_LANG_PROGRAM([[ 5 | #include ]],[[ 6 | uint64_t a = 11, tmp; 7 | __asm__ __volatile__("movq \@S|@0x100000000,%1; mulq %%rsi" : "+a"(a) : "S"(tmp) : "cc", "%rdx"); 8 | ]])], [has_x86_64_asm=yes], [has_x86_64_asm=no]) 9 | AC_MSG_RESULT([$has_x86_64_asm]) 10 | ]) 11 | 12 | AC_DEFUN([SECP_ARM32_ASM_CHECK], [ 13 | AC_MSG_CHECKING(for ARM32 assembly availability) 14 | SECP_ARM32_ASM_CHECK_CFLAGS_saved_CFLAGS="$CFLAGS" 15 | CFLAGS="-x assembler" 16 | AC_LINK_IFELSE([AC_LANG_SOURCE([[ 17 | .syntax unified 18 | .eabi_attribute 24, 1 19 | .eabi_attribute 25, 1 20 | .text 21 | .global main 22 | main: 23 | ldr r0, =0x002A 24 | mov r7, #1 25 | swi 0 26 | ]])], [has_arm32_asm=yes], [has_arm32_asm=no]) 27 | AC_MSG_RESULT([$has_arm32_asm]) 28 | CFLAGS="$SECP_ARM32_ASM_CHECK_CFLAGS_saved_CFLAGS" 29 | ]) 30 | 31 | AC_DEFUN([SECP_VALGRIND_CHECK],[ 32 | AC_MSG_CHECKING([for valgrind support]) 33 | if test x"$has_valgrind" != x"yes"; then 34 | CPPFLAGS_TEMP="$CPPFLAGS" 35 | CPPFLAGS="$VALGRIND_CPPFLAGS $CPPFLAGS" 36 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ 37 | #include 38 | ]], [[ 39 | #if defined(NVALGRIND) 40 | # error "Valgrind does not support this platform." 41 | #endif 42 | ]])], [has_valgrind=yes]) 43 | CPPFLAGS="$CPPFLAGS_TEMP" 44 | fi 45 | AC_MSG_RESULT($has_valgrind) 46 | ]) 47 | 48 | AC_DEFUN([SECP_MSAN_CHECK], [ 49 | AC_MSG_CHECKING(whether MemorySanitizer is enabled) 50 | AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ 51 | #if defined(__has_feature) 52 | # if __has_feature(memory_sanitizer) 53 | /* MemorySanitizer is enabled. */ 54 | # elif 55 | # error "MemorySanitizer is disabled." 56 | # endif 57 | #else 58 | # error "__has_feature is not defined." 59 | #endif 60 | ]])], [msan_enabled=yes], [msan_enabled=no]) 61 | AC_MSG_RESULT([$msan_enabled]) 62 | ]) 63 | 64 | dnl SECP_TRY_APPEND_CFLAGS(flags, VAR) 65 | dnl Append flags to VAR if CC accepts them. 66 | AC_DEFUN([SECP_TRY_APPEND_CFLAGS], [ 67 | AC_MSG_CHECKING([if ${CC} supports $1]) 68 | SECP_TRY_APPEND_CFLAGS_saved_CFLAGS="$CFLAGS" 69 | CFLAGS="$1 $CFLAGS" 70 | AC_COMPILE_IFELSE([AC_LANG_SOURCE([[char foo;]])], [flag_works=yes], [flag_works=no]) 71 | AC_MSG_RESULT($flag_works) 72 | CFLAGS="$SECP_TRY_APPEND_CFLAGS_saved_CFLAGS" 73 | if test x"$flag_works" = x"yes"; then 74 | $2="$$2 $1" 75 | fi 76 | unset flag_works 77 | AC_SUBST($2) 78 | ]) 79 | 80 | dnl SECP_SET_DEFAULT(VAR, default, default-dev-mode) 81 | dnl Set VAR to default or default-dev-mode, depending on whether dev mode is enabled 82 | AC_DEFUN([SECP_SET_DEFAULT], [ 83 | if test "${enable_dev_mode+set}" != set; then 84 | AC_MSG_ERROR([[Set enable_dev_mode before calling SECP_SET_DEFAULT]]) 85 | fi 86 | if test x"$enable_dev_mode" = x"yes"; then 87 | $1="$3" 88 | else 89 | $1="$2" 90 | fi 91 | ]) 92 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/ci/linux-debian.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:stable-slim 2 | 3 | SHELL ["/bin/bash", "-c"] 4 | 5 | WORKDIR /root 6 | 7 | # A too high maximum number of file descriptors (with the default value 8 | # inherited from the docker host) can cause issues with some of our tools: 9 | # - sanitizers hanging: https://github.com/google/sanitizers/issues/1662 10 | # - valgrind crashing: https://stackoverflow.com/a/75293014 11 | # This is not be a problem on our CI hosts, but developers who run the image 12 | # on their machines may run into this (e.g., on Arch Linux), so warn them. 13 | # (Note that .bashrc is only executed in interactive bash shells.) 14 | RUN echo 'if [[ $(ulimit -n) -gt 200000 ]]; then echo "WARNING: Very high value reported by \"ulimit -n\". Consider passing \"--ulimit nofile=32768\" to \"docker run\"."; fi' >> /root/.bashrc 15 | 16 | RUN dpkg --add-architecture i386 && \ 17 | dpkg --add-architecture s390x && \ 18 | dpkg --add-architecture armhf && \ 19 | dpkg --add-architecture arm64 && \ 20 | dpkg --add-architecture ppc64el 21 | 22 | # dkpg-dev: to make pkg-config work in cross-builds 23 | # llvm: for llvm-symbolizer, which is used by clang's UBSan for symbolized stack traces 24 | RUN apt-get update && apt-get install --no-install-recommends -y \ 25 | git ca-certificates \ 26 | make automake libtool pkg-config dpkg-dev valgrind qemu-user \ 27 | gcc clang llvm libclang-rt-dev libc6-dbg \ 28 | g++ \ 29 | gcc-i686-linux-gnu libc6-dev-i386-cross libc6-dbg:i386 libubsan1:i386 libasan8:i386 \ 30 | gcc-s390x-linux-gnu libc6-dev-s390x-cross libc6-dbg:s390x \ 31 | gcc-arm-linux-gnueabihf libc6-dev-armhf-cross libc6-dbg:armhf \ 32 | gcc-powerpc64le-linux-gnu libc6-dev-ppc64el-cross libc6-dbg:ppc64el \ 33 | gcc-mingw-w64-x86-64-win32 wine64 wine \ 34 | gcc-mingw-w64-i686-win32 wine32 \ 35 | python3 && \ 36 | if ! ( dpkg --print-architecture | grep --quiet "arm64" ) ; then \ 37 | apt-get install --no-install-recommends -y \ 38 | gcc-aarch64-linux-gnu libc6-dev-arm64-cross libc6-dbg:arm64 ;\ 39 | fi && \ 40 | apt-get clean && rm -rf /var/lib/apt/lists/* 41 | 42 | # Build and install gcc snapshot 43 | ARG GCC_SNAPSHOT_MAJOR=15 44 | RUN apt-get update && apt-get install --no-install-recommends -y wget libgmp-dev libmpfr-dev libmpc-dev flex && \ 45 | mkdir gcc && cd gcc && \ 46 | 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}" && \ 47 | wget "https://gcc.gnu.org/pub/gcc/snapshots/LATEST-${GCC_SNAPSHOT_MAJOR}/sha512.sum" && \ 48 | sha512sum --check --ignore-missing sha512.sum && \ 49 | # We should have downloaded exactly one tar.xz file 50 | ls && \ 51 | [ $(ls *.tar.xz | wc -l) -eq "1" ] && \ 52 | tar xf *.tar.xz && \ 53 | mkdir gcc-build && cd gcc-build && \ 54 | ../*/configure --prefix=/opt/gcc-snapshot --enable-languages=c --disable-bootstrap --disable-multilib --without-isl && \ 55 | make -j $(nproc) && \ 56 | make install && \ 57 | cd ../.. && rm -rf gcc && \ 58 | ln -s /opt/gcc-snapshot/bin/gcc /usr/bin/gcc-snapshot && \ 59 | apt-get autoremove -y wget libgmp-dev libmpfr-dev libmpc-dev flex && \ 60 | apt-get clean && rm -rf /var/lib/apt/lists/* 61 | 62 | # Install clang snapshot, see https://apt.llvm.org/ 63 | RUN \ 64 | # Setup GPG keys of LLVM repository 65 | apt-get update && apt-get install --no-install-recommends -y wget && \ 66 | wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc && \ 67 | # Add repository for this Debian release 68 | . /etc/os-release && echo "deb http://apt.llvm.org/${VERSION_CODENAME} llvm-toolchain-${VERSION_CODENAME} main" >> /etc/apt/sources.list && \ 69 | apt-get update && \ 70 | # Determine the version number of the LLVM development branch 71 | LLVM_VERSION=$(apt-cache search --names-only '^clang-[0-9]+$' | sort -V | tail -1 | cut -f1 -d" " | cut -f2 -d"-" ) && \ 72 | # Install 73 | apt-get install --no-install-recommends -y "clang-${LLVM_VERSION}" && \ 74 | # Create symlink 75 | ln -s "/usr/bin/clang-${LLVM_VERSION}" /usr/bin/clang-snapshot && \ 76 | # Clean up 77 | apt-get autoremove -y wget && \ 78 | apt-get clean && rm -rf /var/lib/apt/lists/* 79 | 80 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/cmake/CheckArm32Assembly.cmake: -------------------------------------------------------------------------------- 1 | function(check_arm32_assembly) 2 | try_compile(HAVE_ARM32_ASM 3 | ${PROJECT_BINARY_DIR}/check_arm32_assembly 4 | SOURCES ${PROJECT_SOURCE_DIR}/cmake/source_arm32.s 5 | ) 6 | endfunction() 7 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/cmake/CheckMemorySanitizer.cmake: -------------------------------------------------------------------------------- 1 | include_guard(GLOBAL) 2 | include(CheckCSourceCompiles) 3 | 4 | function(check_memory_sanitizer output) 5 | set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) 6 | check_c_source_compiles(" 7 | #if defined(__has_feature) 8 | # if __has_feature(memory_sanitizer) 9 | /* MemorySanitizer is enabled. */ 10 | # elif 11 | # error \"MemorySanitizer is disabled.\" 12 | # endif 13 | #else 14 | # error \"__has_feature is not defined.\" 15 | #endif 16 | " HAVE_MSAN) 17 | set(${output} ${HAVE_MSAN} PARENT_SCOPE) 18 | endfunction() 19 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/cmake/CheckStringOptionValue.cmake: -------------------------------------------------------------------------------- 1 | function(check_string_option_value option) 2 | get_property(expected_values CACHE ${option} PROPERTY STRINGS) 3 | if(expected_values) 4 | if(${option} IN_LIST expected_values) 5 | return() 6 | endif() 7 | message(FATAL_ERROR "${option} value is \"${${option}}\", but must be one of ${expected_values}.") 8 | endif() 9 | message(AUTHOR_WARNING "The STRINGS property must be set before invoking `check_string_option_value' function.") 10 | endfunction() 11 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/cmake/CheckX86_64Assembly.cmake: -------------------------------------------------------------------------------- 1 | include(CheckCSourceCompiles) 2 | 3 | function(check_x86_64_assembly) 4 | check_c_source_compiles(" 5 | #include 6 | 7 | int main() 8 | { 9 | uint64_t a = 11, tmp; 10 | __asm__ __volatile__(\"movq $0x100000000,%1; mulq %%rsi\" : \"+a\"(a) : \"S\"(tmp) : \"cc\", \"%rdx\"); 11 | } 12 | " HAVE_X86_64_ASM) 13 | set(HAVE_X86_64_ASM ${HAVE_X86_64_ASM} PARENT_SCOPE) 14 | endfunction() 15 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/cmake/FindValgrind.cmake: -------------------------------------------------------------------------------- 1 | if(CMAKE_HOST_APPLE) 2 | find_program(BREW_COMMAND brew) 3 | execute_process( 4 | COMMAND ${BREW_COMMAND} --prefix valgrind 5 | OUTPUT_VARIABLE valgrind_brew_prefix 6 | ERROR_QUIET 7 | OUTPUT_STRIP_TRAILING_WHITESPACE 8 | ) 9 | endif() 10 | 11 | set(hints_paths) 12 | if(valgrind_brew_prefix) 13 | set(hints_paths ${valgrind_brew_prefix}/include) 14 | endif() 15 | 16 | find_path(Valgrind_INCLUDE_DIR 17 | NAMES valgrind/memcheck.h 18 | HINTS ${hints_paths} 19 | ) 20 | 21 | if(Valgrind_INCLUDE_DIR) 22 | include(CheckCSourceCompiles) 23 | set(CMAKE_REQUIRED_INCLUDES ${Valgrind_INCLUDE_DIR}) 24 | check_c_source_compiles(" 25 | #include 26 | #if defined(NVALGRIND) 27 | # error \"Valgrind does not support this platform.\" 28 | #endif 29 | 30 | int main() {} 31 | " Valgrind_WORKS) 32 | endif() 33 | 34 | include(FindPackageHandleStandardArgs) 35 | find_package_handle_standard_args(Valgrind 36 | REQUIRED_VARS Valgrind_INCLUDE_DIR Valgrind_WORKS 37 | ) 38 | 39 | mark_as_advanced( 40 | Valgrind_INCLUDE_DIR 41 | ) 42 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/cmake/GeneratePkgConfigFile.cmake: -------------------------------------------------------------------------------- 1 | function(generate_pkg_config_file in_file) 2 | set(prefix ${CMAKE_INSTALL_PREFIX}) 3 | set(exec_prefix \${prefix}) 4 | set(libdir \${exec_prefix}/${CMAKE_INSTALL_LIBDIR}) 5 | set(includedir \${prefix}/${CMAKE_INSTALL_INCLUDEDIR}) 6 | set(PACKAGE_VERSION ${PROJECT_VERSION}) 7 | configure_file(${in_file} ${PROJECT_NAME}.pc @ONLY) 8 | endfunction() 9 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/cmake/TryAppendCFlags.cmake: -------------------------------------------------------------------------------- 1 | include(CheckCCompilerFlag) 2 | 3 | function(rustsecp256k1_v0_11_check_c_flags_internal flags output) 4 | string(MAKE_C_IDENTIFIER "${flags}" result) 5 | string(TOUPPER "${result}" result) 6 | set(result "C_SUPPORTS_${result}") 7 | if(NOT MSVC) 8 | set(CMAKE_REQUIRED_FLAGS "-Werror") 9 | endif() 10 | 11 | # This avoids running a linker. 12 | set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) 13 | check_c_compiler_flag("${flags}" ${result}) 14 | 15 | set(${output} ${${result}} PARENT_SCOPE) 16 | endfunction() 17 | 18 | # Append flags to the COMPILE_OPTIONS directory property if CC accepts them. 19 | macro(try_append_c_flags) 20 | rustsecp256k1_v0_11_check_c_flags_internal("${ARGV}" result) 21 | if(result) 22 | add_compile_options(${ARGV}) 23 | endif() 24 | endmacro() 25 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/cmake/arm-linux-gnueabihf.toolchain.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_SYSTEM_NAME Linux) 2 | set(CMAKE_SYSTEM_PROCESSOR arm) 3 | set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc) 4 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/cmake/config.cmake.in: -------------------------------------------------------------------------------- 1 | @PACKAGE_INIT@ 2 | 3 | include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@-targets.cmake") 4 | 5 | check_required_components(@PROJECT_NAME@) 6 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/cmake/source_arm32.s: -------------------------------------------------------------------------------- 1 | .syntax unified 2 | .eabi_attribute 24, 1 3 | .eabi_attribute 25, 1 4 | .text 5 | .global main 6 | main: 7 | ldr r0, =0x002A 8 | mov r7, #1 9 | swi 0 10 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/cmake/x86_64-w64-mingw32.toolchain.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_SYSTEM_NAME Windows) 2 | set(CMAKE_SYSTEM_PROCESSOR x86_64) 3 | set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) 4 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/contrib/lax_der_parsing.c: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Copyright (c) 2015 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 | ***********************************************************************/ 6 | 7 | #include 8 | 9 | #include "lax_der_parsing.h" 10 | extern int rustsecp256k1_v0_11_ecdsa_signature_parse_compact( 11 | const rustsecp256k1_v0_11_context *ctx, 12 | rustsecp256k1_v0_11_ecdsa_signature *sig, const unsigned char *input64); 13 | int rustsecp256k1_v0_11_ecdsa_signature_parse_der_lax(const rustsecp256k1_v0_11_context* ctx, rustsecp256k1_v0_11_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) { 14 | size_t rpos, rlen, spos, slen; 15 | size_t pos = 0; 16 | size_t lenbyte; 17 | unsigned char tmpsig[64] = {0}; 18 | int overflow = 0; 19 | 20 | /* Hack to initialize sig with a correctly-parsed but invalid signature. */ 21 | rustsecp256k1_v0_11_ecdsa_signature_parse_compact(ctx, sig, tmpsig); 22 | 23 | /* Sequence tag byte */ 24 | if (pos == inputlen || input[pos] != 0x30) { 25 | return 0; 26 | } 27 | pos++; 28 | 29 | /* Sequence length bytes */ 30 | if (pos == inputlen) { 31 | return 0; 32 | } 33 | lenbyte = input[pos++]; 34 | if (lenbyte & 0x80) { 35 | lenbyte -= 0x80; 36 | if (lenbyte > inputlen - pos) { 37 | return 0; 38 | } 39 | pos += lenbyte; 40 | } 41 | 42 | /* Integer tag byte for R */ 43 | if (pos == inputlen || input[pos] != 0x02) { 44 | return 0; 45 | } 46 | pos++; 47 | 48 | /* Integer length for R */ 49 | if (pos == inputlen) { 50 | return 0; 51 | } 52 | lenbyte = input[pos++]; 53 | if (lenbyte & 0x80) { 54 | lenbyte -= 0x80; 55 | if (lenbyte > inputlen - pos) { 56 | return 0; 57 | } 58 | while (lenbyte > 0 && input[pos] == 0) { 59 | pos++; 60 | lenbyte--; 61 | } 62 | if (lenbyte >= sizeof(size_t)) { 63 | return 0; 64 | } 65 | rlen = 0; 66 | while (lenbyte > 0) { 67 | rlen = (rlen << 8) + input[pos]; 68 | pos++; 69 | lenbyte--; 70 | } 71 | } else { 72 | rlen = lenbyte; 73 | } 74 | if (rlen > inputlen - pos) { 75 | return 0; 76 | } 77 | rpos = pos; 78 | pos += rlen; 79 | 80 | /* Integer tag byte for S */ 81 | if (pos == inputlen || input[pos] != 0x02) { 82 | return 0; 83 | } 84 | pos++; 85 | 86 | /* Integer length for S */ 87 | if (pos == inputlen) { 88 | return 0; 89 | } 90 | lenbyte = input[pos++]; 91 | if (lenbyte & 0x80) { 92 | lenbyte -= 0x80; 93 | if (lenbyte > inputlen - pos) { 94 | return 0; 95 | } 96 | while (lenbyte > 0 && input[pos] == 0) { 97 | pos++; 98 | lenbyte--; 99 | } 100 | if (lenbyte >= sizeof(size_t)) { 101 | return 0; 102 | } 103 | slen = 0; 104 | while (lenbyte > 0) { 105 | slen = (slen << 8) + input[pos]; 106 | pos++; 107 | lenbyte--; 108 | } 109 | } else { 110 | slen = lenbyte; 111 | } 112 | if (slen > inputlen - pos) { 113 | return 0; 114 | } 115 | spos = pos; 116 | 117 | /* Ignore leading zeroes in R */ 118 | while (rlen > 0 && input[rpos] == 0) { 119 | rlen--; 120 | rpos++; 121 | } 122 | /* Copy R value */ 123 | if (rlen > 32) { 124 | overflow = 1; 125 | } else if (rlen) { 126 | memcpy(tmpsig + 32 - rlen, input + rpos, rlen); 127 | } 128 | 129 | /* Ignore leading zeroes in S */ 130 | while (slen > 0 && input[spos] == 0) { 131 | slen--; 132 | spos++; 133 | } 134 | /* Copy S value */ 135 | if (slen > 32) { 136 | overflow = 1; 137 | } else if (slen) { 138 | memcpy(tmpsig + 64 - slen, input + spos, slen); 139 | } 140 | 141 | if (!overflow) { 142 | overflow = !rustsecp256k1_v0_11_ecdsa_signature_parse_compact(ctx, sig, tmpsig); 143 | } 144 | if (overflow) { 145 | memset(tmpsig, 0, 64); 146 | rustsecp256k1_v0_11_ecdsa_signature_parse_compact(ctx, sig, tmpsig); 147 | } 148 | return 1; 149 | } 150 | 151 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/contrib/lax_der_parsing.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Copyright (c) 2015 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 | ***********************************************************************/ 6 | 7 | /**** 8 | * Please do not link this file directly. It is not part of the libsecp256k1 9 | * project and does not promise any stability in its API, functionality or 10 | * presence. Projects which use this code should instead copy this header 11 | * and its accompanying .c file directly into their codebase. 12 | ****/ 13 | 14 | /* This file defines a function that parses DER with various errors and 15 | * violations. This is not a part of the library itself, because the allowed 16 | * violations are chosen arbitrarily and do not follow or establish any 17 | * standard. 18 | * 19 | * In many places it matters that different implementations do not only accept 20 | * the same set of valid signatures, but also reject the same set of signatures. 21 | * The only means to accomplish that is by strictly obeying a standard, and not 22 | * accepting anything else. 23 | * 24 | * Nonetheless, sometimes there is a need for compatibility with systems that 25 | * use signatures which do not strictly obey DER. The snippet below shows how 26 | * certain violations are easily supported. You may need to adapt it. 27 | * 28 | * Do not use this for new systems. Use well-defined DER or compact signatures 29 | * instead if you have the choice (see rustsecp256k1_v0_11_ecdsa_signature_parse_der and 30 | * rustsecp256k1_v0_11_ecdsa_signature_parse_compact). 31 | * 32 | * The supported violations are: 33 | * - All numbers are parsed as nonnegative integers, even though X.609-0207 34 | * section 8.3.3 specifies that integers are always encoded as two's 35 | * complement. 36 | * - Integers can have length 0, even though section 8.3.1 says they can't. 37 | * - Integers with overly long padding are accepted, violation section 38 | * 8.3.2. 39 | * - 127-byte long length descriptors are accepted, even though section 40 | * 8.1.3.5.c says that they are not. 41 | * - Trailing garbage data inside or after the signature is ignored. 42 | * - The length descriptor of the sequence is ignored. 43 | * 44 | * Compared to for example OpenSSL, many violations are NOT supported: 45 | * - Using overly long tag descriptors for the sequence or integers inside, 46 | * violating section 8.1.2.2. 47 | * - Encoding primitive integers as constructed values, violating section 48 | * 8.3.1. 49 | */ 50 | 51 | #ifndef SECP256K1_CONTRIB_LAX_DER_PARSING_H 52 | #define SECP256K1_CONTRIB_LAX_DER_PARSING_H 53 | 54 | /* #include secp256k1.h only when it hasn't been included yet. 55 | This enables this file to be #included directly in other project 56 | files (such as tests.c) without the need to set an explicit -I flag, 57 | which would be necessary to locate secp256k1.h. */ 58 | #ifndef SECP256K1_H 59 | #include 60 | #endif 61 | 62 | #ifdef __cplusplus 63 | extern "C" { 64 | #endif 65 | 66 | /** Parse a signature in "lax DER" format 67 | * 68 | * Returns: 1 when the signature could be parsed, 0 otherwise. 69 | * Args: ctx: a secp256k1 context object 70 | * Out: sig: pointer to a signature object 71 | * In: input: pointer to the signature to be parsed 72 | * inputlen: the length of the array pointed to be input 73 | * 74 | * This function will accept any valid DER encoded signature, even if the 75 | * encoded numbers are out of range. In addition, it will accept signatures 76 | * which violate the DER spec in various ways. Its purpose is to allow 77 | * validation of the Bitcoin blockchain, which includes non-DER signatures 78 | * from before the network rules were updated to enforce DER. Note that 79 | * the set of supported violations is a strict subset of what OpenSSL will 80 | * accept. 81 | * 82 | * After the call, sig will always be initialized. If parsing failed or the 83 | * encoded numbers are out of range, signature validation with it is 84 | * guaranteed to fail for every message and public key. 85 | */ 86 | int rustsecp256k1_v0_11_ecdsa_signature_parse_der_lax( 87 | const rustsecp256k1_v0_11_context* ctx, 88 | rustsecp256k1_v0_11_ecdsa_signature* sig, 89 | const unsigned char *input, 90 | size_t inputlen 91 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); 92 | 93 | #ifdef __cplusplus 94 | } 95 | #endif 96 | 97 | #endif /* SECP256K1_CONTRIB_LAX_DER_PARSING_H */ 98 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/contrib/lax_der_privatekey_parsing.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Copyright (c) 2014, 2015 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 | ***********************************************************************/ 6 | 7 | /**** 8 | * Please do not link this file directly. It is not part of the libsecp256k1 9 | * project and does not promise any stability in its API, functionality or 10 | * presence. Projects which use this code should instead copy this header 11 | * and its accompanying .c file directly into their codebase. 12 | ****/ 13 | 14 | /* This file contains code snippets that parse DER private keys with 15 | * various errors and violations. This is not a part of the library 16 | * itself, because the allowed violations are chosen arbitrarily and 17 | * do not follow or establish any standard. 18 | * 19 | * It also contains code to serialize private keys in a compatible 20 | * manner. 21 | * 22 | * These functions are meant for compatibility with applications 23 | * that require BER encoded keys. When working with secp256k1-specific 24 | * code, the simple 32-byte private keys normally used by the 25 | * library are sufficient. 26 | */ 27 | 28 | #ifndef SECP256K1_CONTRIB_BER_PRIVATEKEY_H 29 | #define SECP256K1_CONTRIB_BER_PRIVATEKEY_H 30 | 31 | /* #include secp256k1.h only when it hasn't been included yet. 32 | This enables this file to be #included directly in other project 33 | files (such as tests.c) without the need to set an explicit -I flag, 34 | which would be necessary to locate secp256k1.h. */ 35 | #ifndef SECP256K1_H 36 | #include 37 | #endif 38 | 39 | #ifdef __cplusplus 40 | extern "C" { 41 | #endif 42 | 43 | /** Export a private key in DER format. 44 | * 45 | * Returns: 1 if the private key was valid. 46 | * Args: ctx: pointer to a context object (not rustsecp256k1_v0_11_context_static). 47 | * Out: privkey: pointer to an array for storing the private key in BER. 48 | * Should have space for 279 bytes, and cannot be NULL. 49 | * privkeylen: Pointer to an int where the length of the private key in 50 | * privkey will be stored. 51 | * In: seckey: pointer to a 32-byte secret key to export. 52 | * compressed: 1 if the key should be exported in 53 | * compressed format, 0 otherwise 54 | * 55 | * This function is purely meant for compatibility with applications that 56 | * require BER encoded keys. When working with secp256k1-specific code, the 57 | * simple 32-byte private keys are sufficient. 58 | * 59 | * Note that this function does not guarantee correct DER output. It is 60 | * guaranteed to be parsable by rustsecp256k1_v0_11_ec_privkey_import_der 61 | */ 62 | SECP256K1_WARN_UNUSED_RESULT int ec_privkey_export_der( 63 | const rustsecp256k1_v0_11_context* ctx, 64 | unsigned char *privkey, 65 | size_t *privkeylen, 66 | const unsigned char *seckey, 67 | int compressed 68 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); 69 | 70 | /** Import a private key in DER format. 71 | * Returns: 1 if a private key was extracted. 72 | * Args: ctx: pointer to a context object (cannot be NULL). 73 | * Out: seckey: pointer to a 32-byte array for storing the private key. 74 | * (cannot be NULL). 75 | * In: privkey: pointer to a private key in DER format (cannot be NULL). 76 | * privkeylen: length of the DER private key pointed to be privkey. 77 | * 78 | * This function will accept more than just strict DER, and even allow some BER 79 | * violations. The public key stored inside the DER-encoded private key is not 80 | * verified for correctness, nor are the curve parameters. Use this function 81 | * only if you know in advance it is supposed to contain a secp256k1 private 82 | * key. 83 | */ 84 | SECP256K1_WARN_UNUSED_RESULT int ec_privkey_import_der( 85 | const rustsecp256k1_v0_11_context* ctx, 86 | unsigned char *seckey, 87 | const unsigned char *privkey, 88 | size_t privkeylen 89 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); 90 | 91 | #ifdef __cplusplus 92 | } 93 | #endif 94 | 95 | #endif /* SECP256K1_CONTRIB_BER_PRIVATEKEY_H */ 96 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/doc/musig.md: -------------------------------------------------------------------------------- 1 | Notes on the musig module API 2 | =========================== 3 | 4 | The following sections contain additional notes on the API of the musig module (`include/rustsecp256k1_v0_11_musig.h`). 5 | A usage example can be found in `examples/musig.c`. 6 | 7 | ## API misuse 8 | 9 | The musig API is designed with a focus on misuse resistance. 10 | However, due to the interactive nature of the MuSig protocol, there are additional failure modes that are not present in regular (single-party) Schnorr signature creation. 11 | While the results can be catastrophic (e.g. leaking of the secret key), it is unfortunately not possible for the musig implementation to prevent all such failure modes. 12 | 13 | Therefore, users of the musig module must take great care to make sure of the following: 14 | 15 | 1. A unique nonce per signing session is generated in `rustsecp256k1_v0_11_musig_nonce_gen`. 16 | See the corresponding comment in `include/rustsecp256k1_v0_11_musig.h` for how to ensure that. 17 | 2. The `rustsecp256k1_v0_11_musig_secnonce` structure is never copied or serialized. 18 | See also the comment on `rustsecp256k1_v0_11_musig_secnonce` in `include/rustsecp256k1_v0_11_musig.h`. 19 | 3. Opaque data structures are never written to or read from directly. 20 | Instead, only the provided accessor functions are used. 21 | 22 | ## Key Aggregation and (Taproot) Tweaking 23 | 24 | Given a set of public keys, the aggregate public key is computed with `rustsecp256k1_v0_11_musig_pubkey_agg`. 25 | A plain tweak can be added to the resulting public key with `rustsecp256k1_v0_11_ec_pubkey_tweak_add` by setting the `tweak32` argument to the hash defined in BIP 32. Similarly, a Taproot tweak can be added with `rustsecp256k1_v0_11_xonly_pubkey_tweak_add` by setting the `tweak32` argument to the TapTweak hash defined in BIP 341. 26 | Both types of tweaking can be combined and invoked multiple times if the specific application requires it. 27 | 28 | ## Signing 29 | 30 | This is covered by `examples/musig.c`. 31 | Essentially, the protocol proceeds in the following steps: 32 | 33 | 1. Generate a keypair with `rustsecp256k1_v0_11_keypair_create` and obtain the public key with `rustsecp256k1_v0_11_keypair_pub`. 34 | 2. Call `rustsecp256k1_v0_11_musig_pubkey_agg` with the pubkeys of all participants. 35 | 3. Optionally add a (Taproot) tweak with `rustsecp256k1_v0_11_musig_pubkey_xonly_tweak_add` and a plain tweak with `rustsecp256k1_v0_11_musig_pubkey_ec_tweak_add`. 36 | 4. Generate a pair of secret and public nonce with `rustsecp256k1_v0_11_musig_nonce_gen` and send the public nonce to the other signers. 37 | 5. Someone (not necessarily the signer) aggregates the public nonces with `rustsecp256k1_v0_11_musig_nonce_agg` and sends it to the signers. 38 | 6. Process the aggregate nonce with `rustsecp256k1_v0_11_musig_nonce_process`. 39 | 7. Create a partial signature with `rustsecp256k1_v0_11_musig_partial_sign`. 40 | 8. Verify the partial signatures (optional in some scenarios) with `rustsecp256k1_v0_11_musig_partial_sig_verify`. 41 | 9. Someone (not necessarily the signer) obtains all partial signatures and aggregates them into the final Schnorr signature using `rustsecp256k1_v0_11_musig_partial_sig_agg`. 42 | 43 | The aggregate signature can be verified with `rustsecp256k1_v0_11_schnorrsig_verify`. 44 | 45 | Steps 1 through 5 above can occur before or after the signers are aware of the message to be signed. 46 | Whenever possible, it is recommended to generate the nonces only after the message is known. 47 | This provides enhanced defense-in-depth measures, protecting against potential API misuse in certain scenarios. 48 | However, it does require two rounds of communication during the signing process. 49 | The alternative, generating the nonces in a pre-processing step before the message is known, eliminates these additional protective measures but allows for non-interactive signing. 50 | Similarly, the API supports an alternative protocol flow where generating the aggregate key (steps 1 to 3) is allowed to happen after exchanging nonces (steps 4 to 5). 51 | 52 | ## Verification 53 | 54 | A participant who wants to verify the partial signatures, but does not sign itself may do so using the above instructions except that the verifier skips steps 1, 4 and 7. 55 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | function(add_example name) 2 | set(target_name ${name}_example) 3 | add_executable(${target_name} ${name}.c) 4 | target_include_directories(${target_name} PRIVATE 5 | ${PROJECT_SOURCE_DIR}/include 6 | ) 7 | target_link_libraries(${target_name} 8 | secp256k1 9 | $<$:bcrypt> 10 | ) 11 | set(test_name ${name}_example) 12 | add_test(NAME rustsecp256k1_v0_11_${test_name} COMMAND ${target_name}) 13 | endfunction() 14 | 15 | add_example(ecdsa) 16 | 17 | if(SECP256K1_ENABLE_MODULE_ECDH) 18 | add_example(ecdh) 19 | endif() 20 | 21 | if(SECP256K1_ENABLE_MODULE_SCHNORRSIG) 22 | add_example(schnorr) 23 | endif() 24 | 25 | if(SECP256K1_ENABLE_MODULE_ELLSWIFT) 26 | add_example(ellswift) 27 | endif() 28 | 29 | if(SECP256K1_ENABLE_MODULE_MUSIG) 30 | add_example(musig) 31 | endif() 32 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/include/secp256k1_ecdh.h: -------------------------------------------------------------------------------- 1 | #ifndef SECP256K1_ECDH_H 2 | #define SECP256K1_ECDH_H 3 | 4 | #include "secp256k1.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | /** A pointer to a function that hashes an EC point to obtain an ECDH secret 11 | * 12 | * Returns: 1 if the point was successfully hashed. 13 | * 0 will cause rustsecp256k1_v0_11_ecdh to fail and return 0. 14 | * Other return values are not allowed, and the behaviour of 15 | * rustsecp256k1_v0_11_ecdh is undefined for other return values. 16 | * Out: output: pointer to an array to be filled by the function 17 | * In: x32: pointer to a 32-byte x coordinate 18 | * y32: pointer to a 32-byte y coordinate 19 | * data: arbitrary data pointer that is passed through 20 | */ 21 | typedef int (*rustsecp256k1_v0_11_ecdh_hash_function)( 22 | unsigned char *output, 23 | const unsigned char *x32, 24 | const unsigned char *y32, 25 | void *data 26 | ); 27 | 28 | /** An implementation of SHA256 hash function that applies to compressed public key. 29 | * Populates the output parameter with 32 bytes. */ 30 | SECP256K1_API const rustsecp256k1_v0_11_ecdh_hash_function rustsecp256k1_v0_11_ecdh_hash_function_sha256; 31 | 32 | /** A default ECDH hash function (currently equal to rustsecp256k1_v0_11_ecdh_hash_function_sha256). 33 | * Populates the output parameter with 32 bytes. */ 34 | SECP256K1_API const rustsecp256k1_v0_11_ecdh_hash_function rustsecp256k1_v0_11_ecdh_hash_function_default; 35 | 36 | /** Compute an EC Diffie-Hellman secret in constant time 37 | * 38 | * Returns: 1: exponentiation was successful 39 | * 0: scalar was invalid (zero or overflow) or hashfp returned 0 40 | * Args: ctx: pointer to a context object. 41 | * Out: output: pointer to an array to be filled by hashfp. 42 | * In: pubkey: pointer to a rustsecp256k1_v0_11_pubkey containing an initialized public key. 43 | * seckey: a 32-byte scalar with which to multiply the point. 44 | * hashfp: pointer to a hash function. If NULL, 45 | * rustsecp256k1_v0_11_ecdh_hash_function_sha256 is used 46 | * (in which case, 32 bytes will be written to output). 47 | * data: arbitrary data pointer that is passed through to hashfp 48 | * (can be NULL for rustsecp256k1_v0_11_ecdh_hash_function_sha256). 49 | */ 50 | SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1_v0_11_ecdh( 51 | const rustsecp256k1_v0_11_context *ctx, 52 | unsigned char *output, 53 | const rustsecp256k1_v0_11_pubkey *pubkey, 54 | const unsigned char *seckey, 55 | rustsecp256k1_v0_11_ecdh_hash_function hashfp, 56 | void *data 57 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); 58 | 59 | #ifdef __cplusplus 60 | } 61 | #endif 62 | 63 | #endif /* SECP256K1_ECDH_H */ 64 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/libsecp256k1.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: libsecp256k1 7 | Description: Optimized C library for EC operations on curve secp256k1 8 | URL: https://github.com/bitcoin-core/secp256k1 9 | Version: @PACKAGE_VERSION@ 10 | Cflags: -I${includedir} 11 | Libs: -L${libdir} -lsecp256k1 12 | 13 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/sage/gen_split_lambda_constants.sage: -------------------------------------------------------------------------------- 1 | """ Generates the constants used in rustsecp256k1_v0_11_scalar_split_lambda. 2 | 3 | See the comments for rustsecp256k1_v0_11_scalar_split_lambda in src/scalar_impl.h for detailed explanations. 4 | """ 5 | 6 | load("rustsecp256k1_v0_11_params.sage") 7 | 8 | def inf_norm(v): 9 | """Returns the infinity norm of a vector.""" 10 | return max(map(abs, v)) 11 | 12 | def gauss_reduction(i1, i2): 13 | v1, v2 = i1.copy(), i2.copy() 14 | while True: 15 | if inf_norm(v2) < inf_norm(v1): 16 | v1, v2 = v2, v1 17 | # This is essentially 18 | # m = round((v1[0]*v2[0] + v1[1]*v2[1]) / (inf_norm(v1)**2)) 19 | # (rounding to the nearest integer) without relying on floating point arithmetic. 20 | m = ((v1[0]*v2[0] + v1[1]*v2[1]) + (inf_norm(v1)**2) // 2) // (inf_norm(v1)**2) 21 | if m == 0: 22 | return v1, v2 23 | v2[0] -= m*v1[0] 24 | v2[1] -= m*v1[1] 25 | 26 | def find_split_constants_gauss(): 27 | """Find constants for rustsecp256k1_v0_11_scalar_split_lamdba using gauss reduction.""" 28 | (v11, v12), (v21, v22) = gauss_reduction([0, N], [1, int(LAMBDA)]) 29 | 30 | # We use related vectors in rustsecp256k1_v0_11_scalar_split_lambda. 31 | A1, B1 = -v21, -v11 32 | A2, B2 = v22, -v21 33 | 34 | return A1, B1, A2, B2 35 | 36 | def find_split_constants_explicit_tof(): 37 | """Find constants for rustsecp256k1_v0_11_scalar_split_lamdba using the trace of Frobenius. 38 | 39 | See Benjamin Smith: "Easy scalar decompositions for efficient scalar multiplication on 40 | elliptic curves and genus 2 Jacobians" (https://eprint.iacr.org/2013/672), Example 2 41 | """ 42 | assert P % 3 == 1 # The paper says P % 3 == 2 but that appears to be a mistake, see [10]. 43 | assert C.j_invariant() == 0 44 | 45 | t = C.trace_of_frobenius() 46 | 47 | c = Integer(sqrt((4*P - t**2)/3)) 48 | A1 = Integer((t - c)/2 - 1) 49 | B1 = c 50 | 51 | A2 = Integer((t + c)/2 - 1) 52 | B2 = Integer(1 - (t - c)/2) 53 | 54 | # We use a negated b values in rustsecp256k1_v0_11_scalar_split_lambda. 55 | B1, B2 = -B1, -B2 56 | 57 | return A1, B1, A2, B2 58 | 59 | A1, B1, A2, B2 = find_split_constants_explicit_tof() 60 | 61 | # For extra fun, use an independent method to recompute the constants. 62 | assert (A1, B1, A2, B2) == find_split_constants_gauss() 63 | 64 | # PHI : Z[l] -> Z_n where phi(a + b*l) == a + b*lambda mod n. 65 | def PHI(a,b): 66 | return Z(a + LAMBDA*b) 67 | 68 | # Check that (A1, B1) and (A2, B2) are in the kernel of PHI. 69 | assert PHI(A1, B1) == Z(0) 70 | assert PHI(A2, B2) == Z(0) 71 | 72 | # Check that the parallelogram generated by (A1, A2) and (B1, B2) 73 | # is a fundamental domain by containing exactly N points. 74 | # Since the LHS is the determinant and N != 0, this also checks that 75 | # (A1, A2) and (B1, B2) are linearly independent. By the previous 76 | # assertions, (A1, A2) and (B1, B2) are a basis of the kernel. 77 | assert A1*B2 - B1*A2 == N 78 | 79 | # Check that their components are short enough. 80 | assert (A1 + A2)/2 < sqrt(N) 81 | assert B1 < sqrt(N) 82 | assert B2 < sqrt(N) 83 | 84 | G1 = round((2**384)*B2/N) 85 | G2 = round((2**384)*(-B1)/N) 86 | 87 | def rnddiv2(v): 88 | if v & 1: 89 | v += 1 90 | return v >> 1 91 | 92 | def scalar_lambda_split(k): 93 | """Equivalent to rustsecp256k1_v0_11_scalar_lambda_split().""" 94 | c1 = rnddiv2((k * G1) >> 383) 95 | c2 = rnddiv2((k * G2) >> 383) 96 | c1 = (c1 * -B1) % N 97 | c2 = (c2 * -B2) % N 98 | r2 = (c1 + c2) % N 99 | r1 = (k + r2 * -LAMBDA) % N 100 | return (r1, r2) 101 | 102 | # The result of scalar_lambda_split can depend on the representation of k (mod n). 103 | SPECIAL = (2**383) // G2 + 1 104 | assert scalar_lambda_split(SPECIAL) != scalar_lambda_split(SPECIAL + N) 105 | 106 | print(' A1 =', hex(A1)) 107 | print(' -B1 =', hex(-B1)) 108 | print(' A2 =', hex(A2)) 109 | print(' -B2 =', hex(-B2)) 110 | print(' =', hex(Z(-B2))) 111 | print(' -LAMBDA =', hex(-LAMBDA)) 112 | 113 | print(' G1 =', hex(G1)) 114 | print(' G2 =', hex(G2)) 115 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/sage/secp256k1_params.sage: -------------------------------------------------------------------------------- 1 | """Prime order of finite field underlying secp256k1 (2^256 - 2^32 - 977)""" 2 | P = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F 3 | 4 | """Finite field underlying secp256k1""" 5 | F = FiniteField(P) 6 | 7 | """Elliptic curve secp256k1: y^2 = x^3 + 7""" 8 | C = EllipticCurve([F(0), F(7)]) 9 | 10 | """Base point of secp256k1""" 11 | G = C.lift_x(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798) 12 | if int(G[1]) & 1: 13 | # G.y is even 14 | G = -G 15 | 16 | """Prime order of secp256k1""" 17 | N = C.order() 18 | 19 | """Finite field of scalars of secp256k1""" 20 | Z = FiniteField(N) 21 | 22 | """ Beta value of secp256k1 non-trivial endomorphism: lambda * (x, y) = (beta * x, y)""" 23 | BETA = F(2)^((P-1)/3) 24 | 25 | """ Lambda value of secp256k1 non-trivial endomorphism: lambda * (x, y) = (beta * x, y)""" 26 | LAMBDA = Z(3)^((N-1)/3) 27 | 28 | assert is_prime(P) 29 | assert is_prime(N) 30 | 31 | assert BETA != F(1) 32 | assert BETA^3 == F(1) 33 | assert BETA^2 + BETA + 1 == 0 34 | 35 | assert LAMBDA != Z(1) 36 | assert LAMBDA^3 == Z(1) 37 | assert LAMBDA^2 + LAMBDA + 1 == 0 38 | 39 | assert Integer(LAMBDA)*G == C(BETA*G[0], G[1]) 40 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/ecdsa.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 | ***********************************************************************/ 6 | 7 | #ifndef SECP256K1_ECDSA_H 8 | #define SECP256K1_ECDSA_H 9 | 10 | #include 11 | 12 | #include "scalar.h" 13 | #include "group.h" 14 | #include "ecmult.h" 15 | 16 | static int rustsecp256k1_v0_11_ecdsa_sig_parse(rustsecp256k1_v0_11_scalar *r, rustsecp256k1_v0_11_scalar *s, const unsigned char *sig, size_t size); 17 | static int rustsecp256k1_v0_11_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const rustsecp256k1_v0_11_scalar *r, const rustsecp256k1_v0_11_scalar *s); 18 | static int rustsecp256k1_v0_11_ecdsa_sig_verify(const rustsecp256k1_v0_11_scalar* r, const rustsecp256k1_v0_11_scalar* s, const rustsecp256k1_v0_11_ge *pubkey, const rustsecp256k1_v0_11_scalar *message); 19 | static int rustsecp256k1_v0_11_ecdsa_sig_sign(const rustsecp256k1_v0_11_ecmult_gen_context *ctx, rustsecp256k1_v0_11_scalar* r, rustsecp256k1_v0_11_scalar* s, const rustsecp256k1_v0_11_scalar *seckey, const rustsecp256k1_v0_11_scalar *message, const rustsecp256k1_v0_11_scalar *nonce, int *recid); 20 | 21 | #endif /* SECP256K1_ECDSA_H */ 22 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/eckey.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 | ***********************************************************************/ 6 | 7 | #ifndef SECP256K1_ECKEY_H 8 | #define SECP256K1_ECKEY_H 9 | 10 | #include 11 | 12 | #include "group.h" 13 | #include "scalar.h" 14 | #include "ecmult.h" 15 | #include "ecmult_gen.h" 16 | 17 | static int rustsecp256k1_v0_11_eckey_pubkey_parse(rustsecp256k1_v0_11_ge *elem, const unsigned char *pub, size_t size); 18 | static int rustsecp256k1_v0_11_eckey_pubkey_serialize(rustsecp256k1_v0_11_ge *elem, unsigned char *pub, size_t *size, int compressed); 19 | 20 | static int rustsecp256k1_v0_11_eckey_privkey_tweak_add(rustsecp256k1_v0_11_scalar *key, const rustsecp256k1_v0_11_scalar *tweak); 21 | static int rustsecp256k1_v0_11_eckey_pubkey_tweak_add(rustsecp256k1_v0_11_ge *key, const rustsecp256k1_v0_11_scalar *tweak); 22 | static int rustsecp256k1_v0_11_eckey_privkey_tweak_mul(rustsecp256k1_v0_11_scalar *key, const rustsecp256k1_v0_11_scalar *tweak); 23 | static int rustsecp256k1_v0_11_eckey_pubkey_tweak_mul(rustsecp256k1_v0_11_ge *key, const rustsecp256k1_v0_11_scalar *tweak); 24 | 25 | #endif /* SECP256K1_ECKEY_H */ 26 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/eckey_impl.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 | ***********************************************************************/ 6 | 7 | #ifndef SECP256K1_ECKEY_IMPL_H 8 | #define SECP256K1_ECKEY_IMPL_H 9 | 10 | #include "eckey.h" 11 | 12 | #include "scalar.h" 13 | #include "field.h" 14 | #include "group.h" 15 | #include "ecmult_gen.h" 16 | 17 | static int rustsecp256k1_v0_11_eckey_pubkey_parse(rustsecp256k1_v0_11_ge *elem, const unsigned char *pub, size_t size) { 18 | if (size == 33 && (pub[0] == SECP256K1_TAG_PUBKEY_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_ODD)) { 19 | rustsecp256k1_v0_11_fe x; 20 | return rustsecp256k1_v0_11_fe_set_b32_limit(&x, pub+1) && rustsecp256k1_v0_11_ge_set_xo_var(elem, &x, pub[0] == SECP256K1_TAG_PUBKEY_ODD); 21 | } else if (size == 65 && (pub[0] == SECP256K1_TAG_PUBKEY_UNCOMPRESSED || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD)) { 22 | rustsecp256k1_v0_11_fe x, y; 23 | if (!rustsecp256k1_v0_11_fe_set_b32_limit(&x, pub+1) || !rustsecp256k1_v0_11_fe_set_b32_limit(&y, pub+33)) { 24 | return 0; 25 | } 26 | rustsecp256k1_v0_11_ge_set_xy(elem, &x, &y); 27 | if ((pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD) && 28 | rustsecp256k1_v0_11_fe_is_odd(&y) != (pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD)) { 29 | return 0; 30 | } 31 | return rustsecp256k1_v0_11_ge_is_valid_var(elem); 32 | } else { 33 | return 0; 34 | } 35 | } 36 | 37 | static int rustsecp256k1_v0_11_eckey_pubkey_serialize(rustsecp256k1_v0_11_ge *elem, unsigned char *pub, size_t *size, int compressed) { 38 | if (rustsecp256k1_v0_11_ge_is_infinity(elem)) { 39 | return 0; 40 | } 41 | rustsecp256k1_v0_11_fe_normalize_var(&elem->x); 42 | rustsecp256k1_v0_11_fe_normalize_var(&elem->y); 43 | rustsecp256k1_v0_11_fe_get_b32(&pub[1], &elem->x); 44 | if (compressed) { 45 | *size = 33; 46 | pub[0] = rustsecp256k1_v0_11_fe_is_odd(&elem->y) ? SECP256K1_TAG_PUBKEY_ODD : SECP256K1_TAG_PUBKEY_EVEN; 47 | } else { 48 | *size = 65; 49 | pub[0] = SECP256K1_TAG_PUBKEY_UNCOMPRESSED; 50 | rustsecp256k1_v0_11_fe_get_b32(&pub[33], &elem->y); 51 | } 52 | return 1; 53 | } 54 | 55 | static int rustsecp256k1_v0_11_eckey_privkey_tweak_add(rustsecp256k1_v0_11_scalar *key, const rustsecp256k1_v0_11_scalar *tweak) { 56 | rustsecp256k1_v0_11_scalar_add(key, key, tweak); 57 | return !rustsecp256k1_v0_11_scalar_is_zero(key); 58 | } 59 | 60 | static int rustsecp256k1_v0_11_eckey_pubkey_tweak_add(rustsecp256k1_v0_11_ge *key, const rustsecp256k1_v0_11_scalar *tweak) { 61 | rustsecp256k1_v0_11_gej pt; 62 | rustsecp256k1_v0_11_gej_set_ge(&pt, key); 63 | rustsecp256k1_v0_11_ecmult(&pt, &pt, &rustsecp256k1_v0_11_scalar_one, tweak); 64 | 65 | if (rustsecp256k1_v0_11_gej_is_infinity(&pt)) { 66 | return 0; 67 | } 68 | rustsecp256k1_v0_11_ge_set_gej(key, &pt); 69 | return 1; 70 | } 71 | 72 | static int rustsecp256k1_v0_11_eckey_privkey_tweak_mul(rustsecp256k1_v0_11_scalar *key, const rustsecp256k1_v0_11_scalar *tweak) { 73 | int ret; 74 | ret = !rustsecp256k1_v0_11_scalar_is_zero(tweak); 75 | 76 | rustsecp256k1_v0_11_scalar_mul(key, key, tweak); 77 | return ret; 78 | } 79 | 80 | static int rustsecp256k1_v0_11_eckey_pubkey_tweak_mul(rustsecp256k1_v0_11_ge *key, const rustsecp256k1_v0_11_scalar *tweak) { 81 | rustsecp256k1_v0_11_gej pt; 82 | if (rustsecp256k1_v0_11_scalar_is_zero(tweak)) { 83 | return 0; 84 | } 85 | 86 | rustsecp256k1_v0_11_gej_set_ge(&pt, key); 87 | rustsecp256k1_v0_11_ecmult(&pt, &pt, tweak, &rustsecp256k1_v0_11_scalar_zero); 88 | rustsecp256k1_v0_11_ge_set_gej(key, &pt); 89 | return 1; 90 | } 91 | 92 | #endif /* SECP256K1_ECKEY_IMPL_H */ 93 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/ecmult.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Copyright (c) 2013, 2014, 2017 Pieter Wuille, Andrew Poelstra * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 | ***********************************************************************/ 6 | 7 | #ifndef SECP256K1_ECMULT_H 8 | #define SECP256K1_ECMULT_H 9 | 10 | #include "group.h" 11 | #include "scalar.h" 12 | #include "scratch.h" 13 | 14 | #ifndef ECMULT_WINDOW_SIZE 15 | # define ECMULT_WINDOW_SIZE 15 16 | # ifdef DEBUG_CONFIG 17 | # pragma message DEBUG_CONFIG_MSG("ECMULT_WINDOW_SIZE undefined, assuming default value") 18 | # endif 19 | #endif 20 | 21 | #ifdef DEBUG_CONFIG 22 | # pragma message DEBUG_CONFIG_DEF(ECMULT_WINDOW_SIZE) 23 | #endif 24 | 25 | /* No one will ever need more than a window size of 24. The code might 26 | * be correct for larger values of ECMULT_WINDOW_SIZE but this is not 27 | * tested. 28 | * 29 | * The following limitations are known, and there are probably more: 30 | * If WINDOW_G > 27 and size_t has 32 bits, then the code is incorrect 31 | * because the size of the memory object that we allocate (in bytes) 32 | * will not fit in a size_t. 33 | * If WINDOW_G > 31 and int has 32 bits, then the code is incorrect 34 | * because certain expressions will overflow. 35 | */ 36 | #if ECMULT_WINDOW_SIZE < 2 || ECMULT_WINDOW_SIZE > 24 37 | # error Set ECMULT_WINDOW_SIZE to an integer in range [2..24]. 38 | #endif 39 | 40 | /** The number of entries a table with precomputed multiples needs to have. */ 41 | #define ECMULT_TABLE_SIZE(w) (1L << ((w)-2)) 42 | 43 | /** Double multiply: R = na*A + ng*G */ 44 | static void rustsecp256k1_v0_11_ecmult(rustsecp256k1_v0_11_gej *r, const rustsecp256k1_v0_11_gej *a, const rustsecp256k1_v0_11_scalar *na, const rustsecp256k1_v0_11_scalar *ng); 45 | 46 | typedef int (rustsecp256k1_v0_11_ecmult_multi_callback)(rustsecp256k1_v0_11_scalar *sc, rustsecp256k1_v0_11_ge *pt, size_t idx, void *data); 47 | 48 | /** 49 | * Multi-multiply: R = inp_g_sc * G + sum_i ni * Ai. 50 | * Chooses the right algorithm for a given number of points and scratch space 51 | * size. Resets and overwrites the given scratch space. If the points do not 52 | * fit in the scratch space the algorithm is repeatedly run with batches of 53 | * points. If no scratch space is given then a simple algorithm is used that 54 | * simply multiplies the points with the corresponding scalars and adds them up. 55 | * Returns: 1 on success (including when inp_g_sc is NULL and n is 0) 56 | * 0 if there is not enough scratch space for a single point or 57 | * callback returns 0 58 | */ 59 | static int rustsecp256k1_v0_11_ecmult_multi_var(const rustsecp256k1_v0_11_callback* error_callback, rustsecp256k1_v0_11_scratch *scratch, rustsecp256k1_v0_11_gej *r, const rustsecp256k1_v0_11_scalar *inp_g_sc, rustsecp256k1_v0_11_ecmult_multi_callback cb, void *cbdata, size_t n); 60 | 61 | #endif /* SECP256K1_ECMULT_H */ 62 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/ecmult_compute_table.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************************************** 2 | * Copyright (c) 2013, 2014, 2017, 2021 Pieter Wuille, Andrew Poelstra, Jonas Nick, Russell O'Connor * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php. * 5 | *****************************************************************************************************/ 6 | 7 | #ifndef SECP256K1_ECMULT_COMPUTE_TABLE_H 8 | #define SECP256K1_ECMULT_COMPUTE_TABLE_H 9 | 10 | /* Construct table of all odd multiples of gen in range 1..(2**(window_g-1)-1). */ 11 | static void rustsecp256k1_v0_11_ecmult_compute_table(rustsecp256k1_v0_11_ge_storage* table, int window_g, const rustsecp256k1_v0_11_gej* gen); 12 | 13 | /* Like rustsecp256k1_v0_11_ecmult_compute_table, but one for both gen and gen*2^128. */ 14 | static void rustsecp256k1_v0_11_ecmult_compute_two_tables(rustsecp256k1_v0_11_ge_storage* table, rustsecp256k1_v0_11_ge_storage* table_128, int window_g, const rustsecp256k1_v0_11_ge* gen); 15 | 16 | #endif /* SECP256K1_ECMULT_COMPUTE_TABLE_H */ 17 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/ecmult_compute_table_impl.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************************************** 2 | * Copyright (c) 2013, 2014, 2017, 2021 Pieter Wuille, Andrew Poelstra, Jonas Nick, Russell O'Connor * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php. * 5 | *****************************************************************************************************/ 6 | 7 | #ifndef SECP256K1_ECMULT_COMPUTE_TABLE_IMPL_H 8 | #define SECP256K1_ECMULT_COMPUTE_TABLE_IMPL_H 9 | 10 | #include "ecmult_compute_table.h" 11 | #include "group_impl.h" 12 | #include "field_impl.h" 13 | #include "ecmult.h" 14 | #include "util.h" 15 | 16 | static void rustsecp256k1_v0_11_ecmult_compute_table(rustsecp256k1_v0_11_ge_storage* table, int window_g, const rustsecp256k1_v0_11_gej* gen) { 17 | rustsecp256k1_v0_11_gej gj; 18 | rustsecp256k1_v0_11_ge ge, dgen; 19 | int j; 20 | 21 | gj = *gen; 22 | rustsecp256k1_v0_11_ge_set_gej_var(&ge, &gj); 23 | rustsecp256k1_v0_11_ge_to_storage(&table[0], &ge); 24 | 25 | rustsecp256k1_v0_11_gej_double_var(&gj, gen, NULL); 26 | rustsecp256k1_v0_11_ge_set_gej_var(&dgen, &gj); 27 | 28 | for (j = 1; j < ECMULT_TABLE_SIZE(window_g); ++j) { 29 | rustsecp256k1_v0_11_gej_set_ge(&gj, &ge); 30 | rustsecp256k1_v0_11_gej_add_ge_var(&gj, &gj, &dgen, NULL); 31 | rustsecp256k1_v0_11_ge_set_gej_var(&ge, &gj); 32 | rustsecp256k1_v0_11_ge_to_storage(&table[j], &ge); 33 | } 34 | } 35 | 36 | /* Like rustsecp256k1_v0_11_ecmult_compute_table, but one for both gen and gen*2^128. */ 37 | static void rustsecp256k1_v0_11_ecmult_compute_two_tables(rustsecp256k1_v0_11_ge_storage* table, rustsecp256k1_v0_11_ge_storage* table_128, int window_g, const rustsecp256k1_v0_11_ge* gen) { 38 | rustsecp256k1_v0_11_gej gj; 39 | int i; 40 | 41 | rustsecp256k1_v0_11_gej_set_ge(&gj, gen); 42 | rustsecp256k1_v0_11_ecmult_compute_table(table, window_g, &gj); 43 | for (i = 0; i < 128; ++i) { 44 | rustsecp256k1_v0_11_gej_double_var(&gj, &gj, NULL); 45 | } 46 | rustsecp256k1_v0_11_ecmult_compute_table(table_128, window_g, &gj); 47 | } 48 | 49 | #endif /* SECP256K1_ECMULT_COMPUTE_TABLE_IMPL_H */ 50 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/ecmult_const.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Copyright (c) 2015 Andrew Poelstra * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 | ***********************************************************************/ 6 | 7 | #ifndef SECP256K1_ECMULT_CONST_H 8 | #define SECP256K1_ECMULT_CONST_H 9 | 10 | #include "scalar.h" 11 | #include "group.h" 12 | 13 | /** 14 | * Multiply: R = q*A (in constant-time for q) 15 | */ 16 | static void rustsecp256k1_v0_11_ecmult_const(rustsecp256k1_v0_11_gej *r, const rustsecp256k1_v0_11_ge *a, const rustsecp256k1_v0_11_scalar *q); 17 | 18 | /** 19 | * Same as rustsecp256k1_v0_11_ecmult_const, but takes in an x coordinate of the base point 20 | * only, specified as fraction n/d (numerator/denominator). Only the x coordinate of the result is 21 | * returned. 22 | * 23 | * If known_on_curve is 0, a verification is performed that n/d is a valid X 24 | * coordinate, and 0 is returned if not. Otherwise, 1 is returned. 25 | * 26 | * d being NULL is interpreted as d=1. If non-NULL, d must not be zero. q must not be zero. 27 | * 28 | * Constant time in the value of q, but not any other inputs. 29 | */ 30 | static int rustsecp256k1_v0_11_ecmult_const_xonly( 31 | rustsecp256k1_v0_11_fe *r, 32 | const rustsecp256k1_v0_11_fe *n, 33 | const rustsecp256k1_v0_11_fe *d, 34 | const rustsecp256k1_v0_11_scalar *q, 35 | int known_on_curve 36 | ); 37 | 38 | #endif /* SECP256K1_ECMULT_CONST_H */ 39 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/ecmult_gen_compute_table.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Copyright (c) Pieter Wuille, Gregory Maxwell * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 | ***********************************************************************/ 6 | 7 | #ifndef SECP256K1_ECMULT_GEN_COMPUTE_TABLE_H 8 | #define SECP256K1_ECMULT_GEN_COMPUTE_TABLE_H 9 | 10 | #include "ecmult_gen.h" 11 | 12 | static void rustsecp256k1_v0_11_ecmult_gen_compute_table(rustsecp256k1_v0_11_ge_storage* table, const rustsecp256k1_v0_11_ge* gen, int blocks, int teeth, int spacing); 13 | 14 | #endif /* SECP256K1_ECMULT_GEN_COMPUTE_TABLE_H */ 15 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/field_10x26.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 | ***********************************************************************/ 6 | 7 | #ifndef SECP256K1_FIELD_REPR_H 8 | #define SECP256K1_FIELD_REPR_H 9 | 10 | #include 11 | 12 | /** This field implementation represents the value as 10 uint32_t limbs in base 13 | * 2^26. */ 14 | typedef struct { 15 | /* A field element f represents the sum(i=0..9, f.n[i] << (i*26)) mod p, 16 | * where p is the field modulus, 2^256 - 2^32 - 977. 17 | * 18 | * The individual limbs f.n[i] can exceed 2^26; the field's magnitude roughly 19 | * corresponds to how much excess is allowed. The value 20 | * sum(i=0..9, f.n[i] << (i*26)) may exceed p, unless the field element is 21 | * normalized. */ 22 | uint32_t n[10]; 23 | /* 24 | * Magnitude m requires: 25 | * n[i] <= 2 * m * (2^26 - 1) for i=0..8 26 | * n[9] <= 2 * m * (2^22 - 1) 27 | * 28 | * Normalized requires: 29 | * n[i] <= (2^26 - 1) for i=0..8 30 | * sum(i=0..9, n[i] << (i*26)) < p 31 | * (together these imply n[9] <= 2^22 - 1) 32 | */ 33 | SECP256K1_FE_VERIFY_FIELDS 34 | } rustsecp256k1_v0_11_fe; 35 | 36 | /* Unpacks a constant into a overlapping multi-limbed FE element. */ 37 | #define SECP256K1_FE_CONST_INNER(d7, d6, d5, d4, d3, d2, d1, d0) { \ 38 | (d0) & 0x3FFFFFFUL, \ 39 | (((uint32_t)d0) >> 26) | (((uint32_t)(d1) & 0xFFFFFUL) << 6), \ 40 | (((uint32_t)d1) >> 20) | (((uint32_t)(d2) & 0x3FFFUL) << 12), \ 41 | (((uint32_t)d2) >> 14) | (((uint32_t)(d3) & 0xFFUL) << 18), \ 42 | (((uint32_t)d3) >> 8) | (((uint32_t)(d4) & 0x3UL) << 24), \ 43 | (((uint32_t)d4) >> 2) & 0x3FFFFFFUL, \ 44 | (((uint32_t)d4) >> 28) | (((uint32_t)(d5) & 0x3FFFFFUL) << 4), \ 45 | (((uint32_t)d5) >> 22) | (((uint32_t)(d6) & 0xFFFFUL) << 10), \ 46 | (((uint32_t)d6) >> 16) | (((uint32_t)(d7) & 0x3FFUL) << 16), \ 47 | (((uint32_t)d7) >> 10) \ 48 | } 49 | 50 | typedef struct { 51 | uint32_t n[8]; 52 | } rustsecp256k1_v0_11_fe_storage; 53 | 54 | #define SECP256K1_FE_STORAGE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{ (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }} 55 | #define SECP256K1_FE_STORAGE_CONST_GET(d) d.n[7], d.n[6], d.n[5], d.n[4],d.n[3], d.n[2], d.n[1], d.n[0] 56 | 57 | #endif /* SECP256K1_FIELD_REPR_H */ 58 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/field_5x52.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 | ***********************************************************************/ 6 | 7 | #ifndef SECP256K1_FIELD_REPR_H 8 | #define SECP256K1_FIELD_REPR_H 9 | 10 | #include 11 | 12 | /** This field implementation represents the value as 5 uint64_t limbs in base 13 | * 2^52. */ 14 | typedef struct { 15 | /* A field element f represents the sum(i=0..4, f.n[i] << (i*52)) mod p, 16 | * where p is the field modulus, 2^256 - 2^32 - 977. 17 | * 18 | * The individual limbs f.n[i] can exceed 2^52; the field's magnitude roughly 19 | * corresponds to how much excess is allowed. The value 20 | * sum(i=0..4, f.n[i] << (i*52)) may exceed p, unless the field element is 21 | * normalized. */ 22 | uint64_t n[5]; 23 | /* 24 | * Magnitude m requires: 25 | * n[i] <= 2 * m * (2^52 - 1) for i=0..3 26 | * n[4] <= 2 * m * (2^48 - 1) 27 | * 28 | * Normalized requires: 29 | * n[i] <= (2^52 - 1) for i=0..3 30 | * sum(i=0..4, n[i] << (i*52)) < p 31 | * (together these imply n[4] <= 2^48 - 1) 32 | */ 33 | SECP256K1_FE_VERIFY_FIELDS 34 | } rustsecp256k1_v0_11_fe; 35 | 36 | /* Unpacks a constant into a overlapping multi-limbed FE element. */ 37 | #define SECP256K1_FE_CONST_INNER(d7, d6, d5, d4, d3, d2, d1, d0) { \ 38 | (d0) | (((uint64_t)(d1) & 0xFFFFFUL) << 32), \ 39 | ((uint64_t)(d1) >> 20) | (((uint64_t)(d2)) << 12) | (((uint64_t)(d3) & 0xFFUL) << 44), \ 40 | ((uint64_t)(d3) >> 8) | (((uint64_t)(d4) & 0xFFFFFFFUL) << 24), \ 41 | ((uint64_t)(d4) >> 28) | (((uint64_t)(d5)) << 4) | (((uint64_t)(d6) & 0xFFFFUL) << 36), \ 42 | ((uint64_t)(d6) >> 16) | (((uint64_t)(d7)) << 16) \ 43 | } 44 | 45 | typedef struct { 46 | uint64_t n[4]; 47 | } rustsecp256k1_v0_11_fe_storage; 48 | 49 | #define SECP256K1_FE_STORAGE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{ \ 50 | (d0) | (((uint64_t)(d1)) << 32), \ 51 | (d2) | (((uint64_t)(d3)) << 32), \ 52 | (d4) | (((uint64_t)(d5)) << 32), \ 53 | (d6) | (((uint64_t)(d7)) << 32) \ 54 | }} 55 | 56 | #define SECP256K1_FE_STORAGE_CONST_GET(d) \ 57 | (uint32_t)(d.n[3] >> 32), (uint32_t)d.n[3], \ 58 | (uint32_t)(d.n[2] >> 32), (uint32_t)d.n[2], \ 59 | (uint32_t)(d.n[1] >> 32), (uint32_t)d.n[1], \ 60 | (uint32_t)(d.n[0] >> 32), (uint32_t)d.n[0] 61 | 62 | #endif /* SECP256K1_FIELD_REPR_H */ 63 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/hash.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Copyright (c) 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 | ***********************************************************************/ 6 | 7 | #ifndef SECP256K1_HASH_H 8 | #define SECP256K1_HASH_H 9 | 10 | #include 11 | #include 12 | 13 | typedef struct { 14 | uint32_t s[8]; 15 | unsigned char buf[64]; 16 | uint64_t bytes; 17 | } rustsecp256k1_v0_11_sha256; 18 | 19 | static void rustsecp256k1_v0_11_sha256_initialize(rustsecp256k1_v0_11_sha256 *hash); 20 | static void rustsecp256k1_v0_11_sha256_write(rustsecp256k1_v0_11_sha256 *hash, const unsigned char *data, size_t size); 21 | static void rustsecp256k1_v0_11_sha256_finalize(rustsecp256k1_v0_11_sha256 *hash, unsigned char *out32); 22 | static void rustsecp256k1_v0_11_sha256_clear(rustsecp256k1_v0_11_sha256 *hash); 23 | 24 | typedef struct { 25 | rustsecp256k1_v0_11_sha256 inner, outer; 26 | } rustsecp256k1_v0_11_hmac_sha256; 27 | 28 | static void rustsecp256k1_v0_11_hmac_sha256_initialize(rustsecp256k1_v0_11_hmac_sha256 *hash, const unsigned char *key, size_t size); 29 | static void rustsecp256k1_v0_11_hmac_sha256_write(rustsecp256k1_v0_11_hmac_sha256 *hash, const unsigned char *data, size_t size); 30 | static void rustsecp256k1_v0_11_hmac_sha256_finalize(rustsecp256k1_v0_11_hmac_sha256 *hash, unsigned char *out32); 31 | static void rustsecp256k1_v0_11_hmac_sha256_clear(rustsecp256k1_v0_11_hmac_sha256 *hash); 32 | 33 | typedef struct { 34 | unsigned char v[32]; 35 | unsigned char k[32]; 36 | int retry; 37 | } rustsecp256k1_v0_11_rfc6979_hmac_sha256; 38 | 39 | static void rustsecp256k1_v0_11_rfc6979_hmac_sha256_initialize(rustsecp256k1_v0_11_rfc6979_hmac_sha256 *rng, const unsigned char *key, size_t keylen); 40 | static void rustsecp256k1_v0_11_rfc6979_hmac_sha256_generate(rustsecp256k1_v0_11_rfc6979_hmac_sha256 *rng, unsigned char *out, size_t outlen); 41 | static void rustsecp256k1_v0_11_rfc6979_hmac_sha256_finalize(rustsecp256k1_v0_11_rfc6979_hmac_sha256 *rng); 42 | static void rustsecp256k1_v0_11_rfc6979_hmac_sha256_clear(rustsecp256k1_v0_11_rfc6979_hmac_sha256 *rng); 43 | 44 | #endif /* SECP256K1_HASH_H */ 45 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/hsort.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Copyright (c) 2021 Russell O'Connor, Jonas Nick * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 | ***********************************************************************/ 6 | 7 | #ifndef SECP256K1_HSORT_H 8 | #define SECP256K1_HSORT_H 9 | 10 | #include 11 | #include 12 | 13 | /* In-place, iterative heapsort with an interface matching glibc's qsort_r. This 14 | * is preferred over standard library implementations because they generally 15 | * make no guarantee about being fast for malicious inputs. 16 | * Remember that heapsort is unstable. 17 | * 18 | * In/Out: ptr: pointer to the array to sort. The contents of the array are 19 | * sorted in ascending order according to the comparison function. 20 | * In: count: number of elements in the array. 21 | * size: size in bytes of each element. 22 | * cmp: pointer to a comparison function that is called with two 23 | * arguments that point to the objects being compared. The cmp_data 24 | * argument of rustsecp256k1_v0_11_hsort is passed as third argument. The 25 | * function must return an integer less than, equal to, or greater 26 | * than zero if the first argument is considered to be respectively 27 | * less than, equal to, or greater than the second. 28 | * cmp_data: pointer passed as third argument to cmp. 29 | */ 30 | static void rustsecp256k1_v0_11_hsort(void *ptr, size_t count, size_t size, 31 | int (*cmp)(const void *, const void *, void *), 32 | void *cmp_data); 33 | #endif 34 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/int128.h: -------------------------------------------------------------------------------- 1 | #ifndef SECP256K1_INT128_H 2 | #define SECP256K1_INT128_H 3 | 4 | #include "util.h" 5 | 6 | #if defined(SECP256K1_WIDEMUL_INT128) 7 | # if defined(SECP256K1_INT128_NATIVE) 8 | # include "int128_native.h" 9 | # elif defined(SECP256K1_INT128_STRUCT) 10 | # include "int128_struct.h" 11 | # else 12 | # error "Please select int128 implementation" 13 | # endif 14 | 15 | /* Construct an unsigned 128-bit value from a high and a low 64-bit value. */ 16 | static SECP256K1_INLINE void rustsecp256k1_v0_11_u128_load(rustsecp256k1_v0_11_uint128 *r, uint64_t hi, uint64_t lo); 17 | 18 | /* Multiply two unsigned 64-bit values a and b and write the result to r. */ 19 | static SECP256K1_INLINE void rustsecp256k1_v0_11_u128_mul(rustsecp256k1_v0_11_uint128 *r, uint64_t a, uint64_t b); 20 | 21 | /* Multiply two unsigned 64-bit values a and b and add the result to r. 22 | * The final result is taken modulo 2^128. 23 | */ 24 | static SECP256K1_INLINE void rustsecp256k1_v0_11_u128_accum_mul(rustsecp256k1_v0_11_uint128 *r, uint64_t a, uint64_t b); 25 | 26 | /* Add an unsigned 64-bit value a to r. 27 | * The final result is taken modulo 2^128. 28 | */ 29 | static SECP256K1_INLINE void rustsecp256k1_v0_11_u128_accum_u64(rustsecp256k1_v0_11_uint128 *r, uint64_t a); 30 | 31 | /* Unsigned (logical) right shift. 32 | * Non-constant time in n. 33 | */ 34 | static SECP256K1_INLINE void rustsecp256k1_v0_11_u128_rshift(rustsecp256k1_v0_11_uint128 *r, unsigned int n); 35 | 36 | /* Return the low 64-bits of a 128-bit value as an unsigned 64-bit value. */ 37 | static SECP256K1_INLINE uint64_t rustsecp256k1_v0_11_u128_to_u64(const rustsecp256k1_v0_11_uint128 *a); 38 | 39 | /* Return the high 64-bits of a 128-bit value as an unsigned 64-bit value. */ 40 | static SECP256K1_INLINE uint64_t rustsecp256k1_v0_11_u128_hi_u64(const rustsecp256k1_v0_11_uint128 *a); 41 | 42 | /* Write an unsigned 64-bit value to r. */ 43 | static SECP256K1_INLINE void rustsecp256k1_v0_11_u128_from_u64(rustsecp256k1_v0_11_uint128 *r, uint64_t a); 44 | 45 | /* Tests if r is strictly less than to 2^n. 46 | * n must be strictly less than 128. 47 | */ 48 | static SECP256K1_INLINE int rustsecp256k1_v0_11_u128_check_bits(const rustsecp256k1_v0_11_uint128 *r, unsigned int n); 49 | 50 | /* Construct an signed 128-bit value from a high and a low 64-bit value. */ 51 | static SECP256K1_INLINE void rustsecp256k1_v0_11_i128_load(rustsecp256k1_v0_11_int128 *r, int64_t hi, uint64_t lo); 52 | 53 | /* Multiply two signed 64-bit values a and b and write the result to r. */ 54 | static SECP256K1_INLINE void rustsecp256k1_v0_11_i128_mul(rustsecp256k1_v0_11_int128 *r, int64_t a, int64_t b); 55 | 56 | /* Multiply two signed 64-bit values a and b and add the result to r. 57 | * Overflow or underflow from the addition is undefined behaviour. 58 | */ 59 | static SECP256K1_INLINE void rustsecp256k1_v0_11_i128_accum_mul(rustsecp256k1_v0_11_int128 *r, int64_t a, int64_t b); 60 | 61 | /* Compute a*d - b*c from signed 64-bit values and write the result to r. */ 62 | static SECP256K1_INLINE void rustsecp256k1_v0_11_i128_det(rustsecp256k1_v0_11_int128 *r, int64_t a, int64_t b, int64_t c, int64_t d); 63 | 64 | /* Signed (arithmetic) right shift. 65 | * Non-constant time in b. 66 | */ 67 | static SECP256K1_INLINE void rustsecp256k1_v0_11_i128_rshift(rustsecp256k1_v0_11_int128 *r, unsigned int b); 68 | 69 | /* Return the input value modulo 2^64. */ 70 | static SECP256K1_INLINE uint64_t rustsecp256k1_v0_11_i128_to_u64(const rustsecp256k1_v0_11_int128 *a); 71 | 72 | /* Return the value as a signed 64-bit value. 73 | * Requires the input to be between INT64_MIN and INT64_MAX. 74 | */ 75 | static SECP256K1_INLINE int64_t rustsecp256k1_v0_11_i128_to_i64(const rustsecp256k1_v0_11_int128 *a); 76 | 77 | /* Write a signed 64-bit value to r. */ 78 | static SECP256K1_INLINE void rustsecp256k1_v0_11_i128_from_i64(rustsecp256k1_v0_11_int128 *r, int64_t a); 79 | 80 | /* Compare two 128-bit values for equality. */ 81 | static SECP256K1_INLINE int rustsecp256k1_v0_11_i128_eq_var(const rustsecp256k1_v0_11_int128 *a, const rustsecp256k1_v0_11_int128 *b); 82 | 83 | /* Tests if r is equal to sign*2^n (sign must be 1 or -1). 84 | * n must be strictly less than 127. 85 | */ 86 | static SECP256K1_INLINE int rustsecp256k1_v0_11_i128_check_pow2(const rustsecp256k1_v0_11_int128 *r, unsigned int n, int sign); 87 | 88 | #endif 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/int128_impl.h: -------------------------------------------------------------------------------- 1 | #ifndef SECP256K1_INT128_IMPL_H 2 | #define SECP256K1_INT128_IMPL_H 3 | 4 | #include "util.h" 5 | 6 | #include "int128.h" 7 | 8 | #if defined(SECP256K1_WIDEMUL_INT128) 9 | # if defined(SECP256K1_INT128_NATIVE) 10 | # include "int128_native_impl.h" 11 | # elif defined(SECP256K1_INT128_STRUCT) 12 | # include "int128_struct_impl.h" 13 | # else 14 | # error "Please select int128 implementation" 15 | # endif 16 | #endif 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/int128_native.h: -------------------------------------------------------------------------------- 1 | #ifndef SECP256K1_INT128_NATIVE_H 2 | #define SECP256K1_INT128_NATIVE_H 3 | 4 | #include 5 | #include "util.h" 6 | 7 | #if !defined(UINT128_MAX) && defined(__SIZEOF_INT128__) 8 | SECP256K1_GNUC_EXT typedef unsigned __int128 uint128_t; 9 | SECP256K1_GNUC_EXT typedef __int128 int128_t; 10 | # define UINT128_MAX ((uint128_t)(-1)) 11 | # define INT128_MAX ((int128_t)(UINT128_MAX >> 1)) 12 | # define INT128_MIN (-INT128_MAX - 1) 13 | /* No (U)INT128_C macros because compilers providing __int128 do not support 128-bit literals. */ 14 | #endif 15 | 16 | typedef uint128_t rustsecp256k1_v0_11_uint128; 17 | typedef int128_t rustsecp256k1_v0_11_int128; 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/int128_native_impl.h: -------------------------------------------------------------------------------- 1 | #ifndef SECP256K1_INT128_NATIVE_IMPL_H 2 | #define SECP256K1_INT128_NATIVE_IMPL_H 3 | 4 | #include "int128.h" 5 | #include "util.h" 6 | 7 | static SECP256K1_INLINE void rustsecp256k1_v0_11_u128_load(rustsecp256k1_v0_11_uint128 *r, uint64_t hi, uint64_t lo) { 8 | *r = (((uint128_t)hi) << 64) + lo; 9 | } 10 | 11 | static SECP256K1_INLINE void rustsecp256k1_v0_11_u128_mul(rustsecp256k1_v0_11_uint128 *r, uint64_t a, uint64_t b) { 12 | *r = (uint128_t)a * b; 13 | } 14 | 15 | static SECP256K1_INLINE void rustsecp256k1_v0_11_u128_accum_mul(rustsecp256k1_v0_11_uint128 *r, uint64_t a, uint64_t b) { 16 | *r += (uint128_t)a * b; 17 | } 18 | 19 | static SECP256K1_INLINE void rustsecp256k1_v0_11_u128_accum_u64(rustsecp256k1_v0_11_uint128 *r, uint64_t a) { 20 | *r += a; 21 | } 22 | 23 | static SECP256K1_INLINE void rustsecp256k1_v0_11_u128_rshift(rustsecp256k1_v0_11_uint128 *r, unsigned int n) { 24 | VERIFY_CHECK(n < 128); 25 | *r >>= n; 26 | } 27 | 28 | static SECP256K1_INLINE uint64_t rustsecp256k1_v0_11_u128_to_u64(const rustsecp256k1_v0_11_uint128 *a) { 29 | return (uint64_t)(*a); 30 | } 31 | 32 | static SECP256K1_INLINE uint64_t rustsecp256k1_v0_11_u128_hi_u64(const rustsecp256k1_v0_11_uint128 *a) { 33 | return (uint64_t)(*a >> 64); 34 | } 35 | 36 | static SECP256K1_INLINE void rustsecp256k1_v0_11_u128_from_u64(rustsecp256k1_v0_11_uint128 *r, uint64_t a) { 37 | *r = a; 38 | } 39 | 40 | static SECP256K1_INLINE int rustsecp256k1_v0_11_u128_check_bits(const rustsecp256k1_v0_11_uint128 *r, unsigned int n) { 41 | VERIFY_CHECK(n < 128); 42 | return (*r >> n == 0); 43 | } 44 | 45 | static SECP256K1_INLINE void rustsecp256k1_v0_11_i128_load(rustsecp256k1_v0_11_int128 *r, int64_t hi, uint64_t lo) { 46 | *r = (((uint128_t)(uint64_t)hi) << 64) + lo; 47 | } 48 | 49 | static SECP256K1_INLINE void rustsecp256k1_v0_11_i128_mul(rustsecp256k1_v0_11_int128 *r, int64_t a, int64_t b) { 50 | *r = (int128_t)a * b; 51 | } 52 | 53 | static SECP256K1_INLINE void rustsecp256k1_v0_11_i128_accum_mul(rustsecp256k1_v0_11_int128 *r, int64_t a, int64_t b) { 54 | int128_t ab = (int128_t)a * b; 55 | VERIFY_CHECK(0 <= ab ? *r <= INT128_MAX - ab : INT128_MIN - ab <= *r); 56 | *r += ab; 57 | } 58 | 59 | static SECP256K1_INLINE void rustsecp256k1_v0_11_i128_det(rustsecp256k1_v0_11_int128 *r, int64_t a, int64_t b, int64_t c, int64_t d) { 60 | int128_t ad = (int128_t)a * d; 61 | int128_t bc = (int128_t)b * c; 62 | VERIFY_CHECK(0 <= bc ? INT128_MIN + bc <= ad : ad <= INT128_MAX + bc); 63 | *r = ad - bc; 64 | } 65 | 66 | static SECP256K1_INLINE void rustsecp256k1_v0_11_i128_rshift(rustsecp256k1_v0_11_int128 *r, unsigned int n) { 67 | VERIFY_CHECK(n < 128); 68 | *r >>= n; 69 | } 70 | 71 | static SECP256K1_INLINE uint64_t rustsecp256k1_v0_11_i128_to_u64(const rustsecp256k1_v0_11_int128 *a) { 72 | return (uint64_t)*a; 73 | } 74 | 75 | static SECP256K1_INLINE int64_t rustsecp256k1_v0_11_i128_to_i64(const rustsecp256k1_v0_11_int128 *a) { 76 | VERIFY_CHECK(INT64_MIN <= *a && *a <= INT64_MAX); 77 | return *a; 78 | } 79 | 80 | static SECP256K1_INLINE void rustsecp256k1_v0_11_i128_from_i64(rustsecp256k1_v0_11_int128 *r, int64_t a) { 81 | *r = a; 82 | } 83 | 84 | static SECP256K1_INLINE int rustsecp256k1_v0_11_i128_eq_var(const rustsecp256k1_v0_11_int128 *a, const rustsecp256k1_v0_11_int128 *b) { 85 | return *a == *b; 86 | } 87 | 88 | static SECP256K1_INLINE int rustsecp256k1_v0_11_i128_check_pow2(const rustsecp256k1_v0_11_int128 *r, unsigned int n, int sign) { 89 | VERIFY_CHECK(n < 127); 90 | VERIFY_CHECK(sign == 1 || sign == -1); 91 | return (*r == (int128_t)((uint128_t)sign << n)); 92 | } 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/int128_struct.h: -------------------------------------------------------------------------------- 1 | #ifndef SECP256K1_INT128_STRUCT_H 2 | #define SECP256K1_INT128_STRUCT_H 3 | 4 | #include 5 | #include "util.h" 6 | 7 | typedef struct { 8 | uint64_t lo; 9 | uint64_t hi; 10 | } rustsecp256k1_v0_11_uint128; 11 | 12 | typedef rustsecp256k1_v0_11_uint128 rustsecp256k1_v0_11_int128; 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/modinv32.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Copyright (c) 2020 Peter Dettman * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_MODINV32_H 8 | #define SECP256K1_MODINV32_H 9 | 10 | #include "util.h" 11 | 12 | /* A signed 30-bit limb representation of integers. 13 | * 14 | * Its value is sum(v[i] * 2^(30*i), i=0..8). */ 15 | typedef struct { 16 | int32_t v[9]; 17 | } rustsecp256k1_v0_11_modinv32_signed30; 18 | 19 | typedef struct { 20 | /* The modulus in signed30 notation, must be odd and in [3, 2^256]. */ 21 | rustsecp256k1_v0_11_modinv32_signed30 modulus; 22 | 23 | /* modulus^{-1} mod 2^30 */ 24 | uint32_t modulus_inv30; 25 | } rustsecp256k1_v0_11_modinv32_modinfo; 26 | 27 | /* Replace x with its modular inverse mod modinfo->modulus. x must be in range [0, modulus). 28 | * If x is zero, the result will be zero as well. If not, the inverse must exist (i.e., the gcd of 29 | * x and modulus must be 1). These rules are automatically satisfied if the modulus is prime. 30 | * 31 | * On output, all of x's limbs will be in [0, 2^30). 32 | */ 33 | static void rustsecp256k1_v0_11_modinv32_var(rustsecp256k1_v0_11_modinv32_signed30 *x, const rustsecp256k1_v0_11_modinv32_modinfo *modinfo); 34 | 35 | /* Same as rustsecp256k1_v0_11_modinv32_var, but constant time in x (not in the modulus). */ 36 | static void rustsecp256k1_v0_11_modinv32(rustsecp256k1_v0_11_modinv32_signed30 *x, const rustsecp256k1_v0_11_modinv32_modinfo *modinfo); 37 | 38 | /* Compute the Jacobi symbol for (x | modinfo->modulus). x must be coprime with modulus (and thus 39 | * cannot be 0, as modulus >= 3). All limbs of x must be non-negative. Returns 0 if the result 40 | * cannot be computed. */ 41 | static int rustsecp256k1_v0_11_jacobi32_maybe_var(const rustsecp256k1_v0_11_modinv32_signed30 *x, const rustsecp256k1_v0_11_modinv32_modinfo *modinfo); 42 | 43 | #endif /* SECP256K1_MODINV32_H */ 44 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/modinv64.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Copyright (c) 2020 Peter Dettman * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_MODINV64_H 8 | #define SECP256K1_MODINV64_H 9 | 10 | #include "util.h" 11 | 12 | #ifndef SECP256K1_WIDEMUL_INT128 13 | #error "modinv64 requires 128-bit wide multiplication support" 14 | #endif 15 | 16 | /* A signed 62-bit limb representation of integers. 17 | * 18 | * Its value is sum(v[i] * 2^(62*i), i=0..4). */ 19 | typedef struct { 20 | int64_t v[5]; 21 | } rustsecp256k1_v0_11_modinv64_signed62; 22 | 23 | typedef struct { 24 | /* The modulus in signed62 notation, must be odd and in [3, 2^256]. */ 25 | rustsecp256k1_v0_11_modinv64_signed62 modulus; 26 | 27 | /* modulus^{-1} mod 2^62 */ 28 | uint64_t modulus_inv62; 29 | } rustsecp256k1_v0_11_modinv64_modinfo; 30 | 31 | /* Replace x with its modular inverse mod modinfo->modulus. x must be in range [0, modulus). 32 | * If x is zero, the result will be zero as well. If not, the inverse must exist (i.e., the gcd of 33 | * x and modulus must be 1). These rules are automatically satisfied if the modulus is prime. 34 | * 35 | * On output, all of x's limbs will be in [0, 2^62). 36 | */ 37 | static void rustsecp256k1_v0_11_modinv64_var(rustsecp256k1_v0_11_modinv64_signed62 *x, const rustsecp256k1_v0_11_modinv64_modinfo *modinfo); 38 | 39 | /* Same as rustsecp256k1_v0_11_modinv64_var, but constant time in x (not in the modulus). */ 40 | static void rustsecp256k1_v0_11_modinv64(rustsecp256k1_v0_11_modinv64_signed62 *x, const rustsecp256k1_v0_11_modinv64_modinfo *modinfo); 41 | 42 | /* Compute the Jacobi symbol for (x | modinfo->modulus). x must be coprime with modulus (and thus 43 | * cannot be 0, as modulus >= 3). All limbs of x must be non-negative. Returns 0 if the result 44 | * cannot be computed. */ 45 | static int rustsecp256k1_v0_11_jacobi64_maybe_var(const rustsecp256k1_v0_11_modinv64_signed62 *x, const rustsecp256k1_v0_11_modinv64_modinfo *modinfo); 46 | 47 | #endif /* SECP256K1_MODINV64_H */ 48 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/modules/ecdh/Makefile.am.include: -------------------------------------------------------------------------------- 1 | include_HEADERS += include/rustsecp256k1_v0_11_ecdh.h 2 | noinst_HEADERS += src/modules/ecdh/main_impl.h 3 | noinst_HEADERS += src/modules/ecdh/tests_impl.h 4 | noinst_HEADERS += src/modules/ecdh/bench_impl.h 5 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/modules/ecdh/bench_impl.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Copyright (c) 2015 Pieter Wuille, Andrew Poelstra * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 | ***********************************************************************/ 6 | 7 | #ifndef SECP256K1_MODULE_ECDH_BENCH_H 8 | #define SECP256K1_MODULE_ECDH_BENCH_H 9 | 10 | #include "../../../include/secp256k1_ecdh.h" 11 | 12 | typedef struct { 13 | rustsecp256k1_v0_11_context *ctx; 14 | rustsecp256k1_v0_11_pubkey point; 15 | unsigned char scalar[32]; 16 | } bench_ecdh_data; 17 | 18 | static void bench_ecdh_setup(void* arg) { 19 | int i; 20 | bench_ecdh_data *data = (bench_ecdh_data*)arg; 21 | const unsigned char point[] = { 22 | 0x03, 23 | 0x54, 0x94, 0xc1, 0x5d, 0x32, 0x09, 0x97, 0x06, 24 | 0xc2, 0x39, 0x5f, 0x94, 0x34, 0x87, 0x45, 0xfd, 25 | 0x75, 0x7c, 0xe3, 0x0e, 0x4e, 0x8c, 0x90, 0xfb, 26 | 0xa2, 0xba, 0xd1, 0x84, 0xf8, 0x83, 0xc6, 0x9f 27 | }; 28 | 29 | for (i = 0; i < 32; i++) { 30 | data->scalar[i] = i + 1; 31 | } 32 | CHECK(rustsecp256k1_v0_11_ec_pubkey_parse(data->ctx, &data->point, point, sizeof(point)) == 1); 33 | } 34 | 35 | static void bench_ecdh(void* arg, int iters) { 36 | int i; 37 | unsigned char res[32]; 38 | bench_ecdh_data *data = (bench_ecdh_data*)arg; 39 | 40 | for (i = 0; i < iters; i++) { 41 | CHECK(rustsecp256k1_v0_11_ecdh(data->ctx, res, &data->point, data->scalar, NULL, NULL) == 1); 42 | } 43 | } 44 | 45 | static void run_ecdh_bench(int iters, int argc, char** argv) { 46 | bench_ecdh_data data; 47 | int d = argc == 1; 48 | 49 | /* create a context with no capabilities */ 50 | data.ctx = rustsecp256k1_v0_11_context_create(SECP256K1_FLAGS_TYPE_CONTEXT); 51 | 52 | if (d || have_flag(argc, argv, "ecdh")) run_benchmark("ecdh", bench_ecdh, bench_ecdh_setup, NULL, &data, 10, iters); 53 | 54 | rustsecp256k1_v0_11_context_destroy(data.ctx); 55 | } 56 | 57 | #endif /* SECP256K1_MODULE_ECDH_BENCH_H */ 58 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/modules/ecdh/main_impl.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Copyright (c) 2015 Andrew Poelstra * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 | ***********************************************************************/ 6 | 7 | #ifndef SECP256K1_MODULE_ECDH_MAIN_H 8 | #define SECP256K1_MODULE_ECDH_MAIN_H 9 | 10 | #include "../../../include/secp256k1_ecdh.h" 11 | #include "../../ecmult_const_impl.h" 12 | 13 | static int ecdh_hash_function_sha256(unsigned char *output, const unsigned char *x32, const unsigned char *y32, void *data) { 14 | unsigned char version = (y32[31] & 0x01) | 0x02; 15 | rustsecp256k1_v0_11_sha256 sha; 16 | (void)data; 17 | 18 | rustsecp256k1_v0_11_sha256_initialize(&sha); 19 | rustsecp256k1_v0_11_sha256_write(&sha, &version, 1); 20 | rustsecp256k1_v0_11_sha256_write(&sha, x32, 32); 21 | rustsecp256k1_v0_11_sha256_finalize(&sha, output); 22 | rustsecp256k1_v0_11_sha256_clear(&sha); 23 | 24 | return 1; 25 | } 26 | 27 | const rustsecp256k1_v0_11_ecdh_hash_function rustsecp256k1_v0_11_ecdh_hash_function_sha256 = ecdh_hash_function_sha256; 28 | const rustsecp256k1_v0_11_ecdh_hash_function rustsecp256k1_v0_11_ecdh_hash_function_default = ecdh_hash_function_sha256; 29 | 30 | int rustsecp256k1_v0_11_ecdh(const rustsecp256k1_v0_11_context* ctx, unsigned char *output, const rustsecp256k1_v0_11_pubkey *point, const unsigned char *scalar, rustsecp256k1_v0_11_ecdh_hash_function hashfp, void *data) { 31 | int ret = 0; 32 | int overflow = 0; 33 | rustsecp256k1_v0_11_gej res; 34 | rustsecp256k1_v0_11_ge pt; 35 | rustsecp256k1_v0_11_scalar s; 36 | unsigned char x[32]; 37 | unsigned char y[32]; 38 | 39 | VERIFY_CHECK(ctx != NULL); 40 | ARG_CHECK(output != NULL); 41 | ARG_CHECK(point != NULL); 42 | ARG_CHECK(scalar != NULL); 43 | 44 | if (hashfp == NULL) { 45 | hashfp = rustsecp256k1_v0_11_ecdh_hash_function_default; 46 | } 47 | 48 | rustsecp256k1_v0_11_pubkey_load(ctx, &pt, point); 49 | rustsecp256k1_v0_11_scalar_set_b32(&s, scalar, &overflow); 50 | 51 | overflow |= rustsecp256k1_v0_11_scalar_is_zero(&s); 52 | rustsecp256k1_v0_11_scalar_cmov(&s, &rustsecp256k1_v0_11_scalar_one, overflow); 53 | 54 | rustsecp256k1_v0_11_ecmult_const(&res, &pt, &s); 55 | rustsecp256k1_v0_11_ge_set_gej(&pt, &res); 56 | 57 | /* Compute a hash of the point */ 58 | rustsecp256k1_v0_11_fe_normalize(&pt.x); 59 | rustsecp256k1_v0_11_fe_normalize(&pt.y); 60 | rustsecp256k1_v0_11_fe_get_b32(x, &pt.x); 61 | rustsecp256k1_v0_11_fe_get_b32(y, &pt.y); 62 | 63 | ret = hashfp(output, x, y, data); 64 | 65 | rustsecp256k1_v0_11_memclear(x, sizeof(x)); 66 | rustsecp256k1_v0_11_memclear(y, sizeof(y)); 67 | rustsecp256k1_v0_11_scalar_clear(&s); 68 | rustsecp256k1_v0_11_ge_clear(&pt); 69 | rustsecp256k1_v0_11_gej_clear(&res); 70 | 71 | return !!ret & !overflow; 72 | } 73 | 74 | #endif /* SECP256K1_MODULE_ECDH_MAIN_H */ 75 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/modules/ellswift/Makefile.am.include: -------------------------------------------------------------------------------- 1 | include_HEADERS += include/rustsecp256k1_v0_11_ellswift.h 2 | noinst_HEADERS += src/modules/ellswift/bench_impl.h 3 | noinst_HEADERS += src/modules/ellswift/main_impl.h 4 | noinst_HEADERS += src/modules/ellswift/tests_impl.h 5 | noinst_HEADERS += src/modules/ellswift/tests_exhaustive_impl.h 6 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/modules/ellswift/tests_exhaustive_impl.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Distributed under the MIT software license, see the accompanying * 3 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 4 | ***********************************************************************/ 5 | 6 | #ifndef SECP256K1_MODULE_ELLSWIFT_TESTS_EXHAUSTIVE_H 7 | #define SECP256K1_MODULE_ELLSWIFT_TESTS_EXHAUSTIVE_H 8 | 9 | #include "../../../include/secp256k1_ellswift.h" 10 | #include "main_impl.h" 11 | 12 | static void test_exhaustive_ellswift(const rustsecp256k1_v0_11_context *ctx, const rustsecp256k1_v0_11_ge *group) { 13 | int i; 14 | 15 | /* Note that SwiftEC/ElligatorSwift are inherently curve operations, not 16 | * group operations, and this test only checks the curve points which are in 17 | * a tiny subgroup. In that sense it can't be really seen as exhaustive as 18 | * it doesn't (and for computational reasons obviously cannot) test the 19 | * entire domain ellswift operates under. */ 20 | for (i = 1; i < EXHAUSTIVE_TEST_ORDER; i++) { 21 | rustsecp256k1_v0_11_scalar scalar_i; 22 | unsigned char sec32[32]; 23 | unsigned char ell64[64]; 24 | rustsecp256k1_v0_11_pubkey pub_decoded; 25 | rustsecp256k1_v0_11_ge ge_decoded; 26 | 27 | /* Construct ellswift pubkey from exhaustive loop scalar i. */ 28 | rustsecp256k1_v0_11_scalar_set_int(&scalar_i, i); 29 | rustsecp256k1_v0_11_scalar_get_b32(sec32, &scalar_i); 30 | CHECK(rustsecp256k1_v0_11_ellswift_create(ctx, ell64, sec32, NULL)); 31 | 32 | /* Decode ellswift pubkey and check that it matches the precomputed group element. */ 33 | rustsecp256k1_v0_11_ellswift_decode(ctx, &pub_decoded, ell64); 34 | rustsecp256k1_v0_11_pubkey_load(ctx, &ge_decoded, &pub_decoded); 35 | CHECK(rustsecp256k1_v0_11_ge_eq_var(&ge_decoded, &group[i])); 36 | } 37 | } 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/modules/extrakeys/Makefile.am.include: -------------------------------------------------------------------------------- 1 | include_HEADERS += include/rustsecp256k1_v0_11_extrakeys.h 2 | noinst_HEADERS += src/modules/extrakeys/tests_impl.h 3 | noinst_HEADERS += src/modules/extrakeys/tests_exhaustive_impl.h 4 | noinst_HEADERS += src/modules/extrakeys/main_impl.h 5 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/modules/extrakeys/tests_exhaustive_impl.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Copyright (c) 2020 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 | ***********************************************************************/ 6 | 7 | #ifndef SECP256K1_MODULE_EXTRAKEYS_TESTS_EXHAUSTIVE_H 8 | #define SECP256K1_MODULE_EXTRAKEYS_TESTS_EXHAUSTIVE_H 9 | 10 | #include "../../../include/secp256k1_extrakeys.h" 11 | #include "main_impl.h" 12 | 13 | static void test_exhaustive_extrakeys(const rustsecp256k1_v0_11_context *ctx, const rustsecp256k1_v0_11_ge* group) { 14 | rustsecp256k1_v0_11_keypair keypair[EXHAUSTIVE_TEST_ORDER - 1]; 15 | rustsecp256k1_v0_11_pubkey pubkey[EXHAUSTIVE_TEST_ORDER - 1]; 16 | rustsecp256k1_v0_11_xonly_pubkey xonly_pubkey[EXHAUSTIVE_TEST_ORDER - 1]; 17 | int parities[EXHAUSTIVE_TEST_ORDER - 1]; 18 | unsigned char xonly_pubkey_bytes[EXHAUSTIVE_TEST_ORDER - 1][32]; 19 | int i; 20 | 21 | for (i = 1; i < EXHAUSTIVE_TEST_ORDER; i++) { 22 | rustsecp256k1_v0_11_fe fe; 23 | rustsecp256k1_v0_11_scalar scalar_i; 24 | unsigned char buf[33]; 25 | int parity; 26 | 27 | rustsecp256k1_v0_11_scalar_set_int(&scalar_i, i); 28 | rustsecp256k1_v0_11_scalar_get_b32(buf, &scalar_i); 29 | 30 | /* Construct pubkey and keypair. */ 31 | CHECK(rustsecp256k1_v0_11_keypair_create(ctx, &keypair[i - 1], buf)); 32 | CHECK(rustsecp256k1_v0_11_ec_pubkey_create(ctx, &pubkey[i - 1], buf)); 33 | 34 | /* Construct serialized xonly_pubkey from keypair. */ 35 | CHECK(rustsecp256k1_v0_11_keypair_xonly_pub(ctx, &xonly_pubkey[i - 1], &parities[i - 1], &keypair[i - 1])); 36 | CHECK(rustsecp256k1_v0_11_xonly_pubkey_serialize(ctx, xonly_pubkey_bytes[i - 1], &xonly_pubkey[i - 1])); 37 | 38 | /* Parse the xonly_pubkey back and verify it matches the previously serialized value. */ 39 | CHECK(rustsecp256k1_v0_11_xonly_pubkey_parse(ctx, &xonly_pubkey[i - 1], xonly_pubkey_bytes[i - 1])); 40 | CHECK(rustsecp256k1_v0_11_xonly_pubkey_serialize(ctx, buf, &xonly_pubkey[i - 1])); 41 | CHECK(rustsecp256k1_v0_11_memcmp_var(xonly_pubkey_bytes[i - 1], buf, 32) == 0); 42 | 43 | /* Construct the xonly_pubkey from the pubkey, and verify it matches the same. */ 44 | CHECK(rustsecp256k1_v0_11_xonly_pubkey_from_pubkey(ctx, &xonly_pubkey[i - 1], &parity, &pubkey[i - 1])); 45 | CHECK(parity == parities[i - 1]); 46 | CHECK(rustsecp256k1_v0_11_xonly_pubkey_serialize(ctx, buf, &xonly_pubkey[i - 1])); 47 | CHECK(rustsecp256k1_v0_11_memcmp_var(xonly_pubkey_bytes[i - 1], buf, 32) == 0); 48 | 49 | /* Compare the xonly_pubkey bytes against the precomputed group. */ 50 | rustsecp256k1_v0_11_fe_set_b32_mod(&fe, xonly_pubkey_bytes[i - 1]); 51 | CHECK(rustsecp256k1_v0_11_fe_equal(&fe, &group[i].x)); 52 | 53 | /* Check the parity against the precomputed group. */ 54 | fe = group[i].y; 55 | rustsecp256k1_v0_11_fe_normalize_var(&fe); 56 | CHECK(rustsecp256k1_v0_11_fe_is_odd(&fe) == parities[i - 1]); 57 | 58 | /* Verify that the higher half is identical to the lower half mirrored. */ 59 | if (i > EXHAUSTIVE_TEST_ORDER / 2) { 60 | CHECK(rustsecp256k1_v0_11_memcmp_var(xonly_pubkey_bytes[i - 1], xonly_pubkey_bytes[EXHAUSTIVE_TEST_ORDER - i - 1], 32) == 0); 61 | CHECK(parities[i - 1] == 1 - parities[EXHAUSTIVE_TEST_ORDER - i - 1]); 62 | } 63 | } 64 | 65 | /* TODO: keypair/xonly_pubkey tweak tests */ 66 | } 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/modules/musig/Makefile.am.include: -------------------------------------------------------------------------------- 1 | include_HEADERS += include/rustsecp256k1_v0_11_musig.h 2 | noinst_HEADERS += src/modules/musig/main_impl.h 3 | noinst_HEADERS += src/modules/musig/keyagg.h 4 | noinst_HEADERS += src/modules/musig/keyagg_impl.h 5 | noinst_HEADERS += src/modules/musig/session.h 6 | noinst_HEADERS += src/modules/musig/session_impl.h 7 | noinst_HEADERS += src/modules/musig/tests_impl.h 8 | noinst_HEADERS += src/modules/musig/vectors.h 9 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/modules/musig/keyagg.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Distributed under the MIT software license, see the accompanying * 3 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 4 | ***********************************************************************/ 5 | 6 | #ifndef SECP256K1_MODULE_MUSIG_KEYAGG_H 7 | #define SECP256K1_MODULE_MUSIG_KEYAGG_H 8 | 9 | #include "../../../include/secp256k1.h" 10 | #include "../../../include/secp256k1_musig.h" 11 | 12 | #include "../../group.h" 13 | #include "../../scalar.h" 14 | 15 | typedef struct { 16 | rustsecp256k1_v0_11_ge pk; 17 | /* If there is no "second" public key, second_pk is set to the point at 18 | * infinity */ 19 | rustsecp256k1_v0_11_ge second_pk; 20 | unsigned char pks_hash[32]; 21 | /* tweak is identical to value tacc[v] in the specification. */ 22 | rustsecp256k1_v0_11_scalar tweak; 23 | /* parity_acc corresponds to (1 - gacc[v])/2 in the spec. So if gacc[v] is 24 | * -1, parity_acc is 1. Otherwise, parity_acc is 0. */ 25 | int parity_acc; 26 | } rustsecp256k1_v0_11_keyagg_cache_internal; 27 | 28 | static int rustsecp256k1_v0_11_keyagg_cache_load(const rustsecp256k1_v0_11_context* ctx, rustsecp256k1_v0_11_keyagg_cache_internal *cache_i, const rustsecp256k1_v0_11_musig_keyagg_cache *cache); 29 | 30 | static void rustsecp256k1_v0_11_musig_keyaggcoef(rustsecp256k1_v0_11_scalar *r, const rustsecp256k1_v0_11_keyagg_cache_internal *cache_i, rustsecp256k1_v0_11_ge *pk); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/modules/musig/main_impl.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Distributed under the MIT software license, see the accompanying * 3 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 4 | **********************************************************************/ 5 | 6 | #ifndef SECP256K1_MODULE_MUSIG_MAIN_H 7 | #define SECP256K1_MODULE_MUSIG_MAIN_H 8 | 9 | #include "keyagg_impl.h" 10 | #include "session_impl.h" 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/modules/musig/session.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Distributed under the MIT software license, see the accompanying * 3 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 4 | ***********************************************************************/ 5 | 6 | #ifndef SECP256K1_MODULE_MUSIG_SESSION_H 7 | #define SECP256K1_MODULE_MUSIG_SESSION_H 8 | 9 | #include "../../../include/secp256k1.h" 10 | #include "../../../include/secp256k1_musig.h" 11 | 12 | #include "../../scalar.h" 13 | 14 | typedef struct { 15 | int fin_nonce_parity; 16 | unsigned char fin_nonce[32]; 17 | rustsecp256k1_v0_11_scalar noncecoef; 18 | rustsecp256k1_v0_11_scalar challenge; 19 | rustsecp256k1_v0_11_scalar s_part; 20 | } rustsecp256k1_v0_11_musig_session_internal; 21 | 22 | static int rustsecp256k1_v0_11_musig_session_load(const rustsecp256k1_v0_11_context* ctx, rustsecp256k1_v0_11_musig_session_internal *session_i, const rustsecp256k1_v0_11_musig_session *session); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/modules/recovery/Makefile.am.include: -------------------------------------------------------------------------------- 1 | include_HEADERS += include/rustsecp256k1_v0_11_recovery.h 2 | noinst_HEADERS += src/modules/recovery/main_impl.h 3 | noinst_HEADERS += src/modules/recovery/tests_impl.h 4 | noinst_HEADERS += src/modules/recovery/tests_exhaustive_impl.h 5 | noinst_HEADERS += src/modules/recovery/bench_impl.h 6 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/modules/recovery/bench_impl.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Copyright (c) 2014-2015 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 | ***********************************************************************/ 6 | 7 | #ifndef SECP256K1_MODULE_RECOVERY_BENCH_H 8 | #define SECP256K1_MODULE_RECOVERY_BENCH_H 9 | 10 | #include "../../../include/secp256k1_recovery.h" 11 | 12 | typedef struct { 13 | rustsecp256k1_v0_11_context *ctx; 14 | unsigned char msg[32]; 15 | unsigned char sig[64]; 16 | } bench_recover_data; 17 | 18 | static void bench_recover(void* arg, int iters) { 19 | int i; 20 | bench_recover_data *data = (bench_recover_data*)arg; 21 | rustsecp256k1_v0_11_pubkey pubkey; 22 | unsigned char pubkeyc[33]; 23 | 24 | for (i = 0; i < iters; i++) { 25 | int j; 26 | size_t pubkeylen = 33; 27 | rustsecp256k1_v0_11_ecdsa_recoverable_signature sig; 28 | CHECK(rustsecp256k1_v0_11_ecdsa_recoverable_signature_parse_compact(data->ctx, &sig, data->sig, i % 2)); 29 | CHECK(rustsecp256k1_v0_11_ecdsa_recover(data->ctx, &pubkey, &sig, data->msg)); 30 | CHECK(rustsecp256k1_v0_11_ec_pubkey_serialize(data->ctx, pubkeyc, &pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED)); 31 | for (j = 0; j < 32; j++) { 32 | data->sig[j + 32] = data->msg[j]; /* Move former message to S. */ 33 | data->msg[j] = data->sig[j]; /* Move former R to message. */ 34 | data->sig[j] = pubkeyc[j + 1]; /* Move recovered pubkey X coordinate to R (which must be a valid X coordinate). */ 35 | } 36 | } 37 | } 38 | 39 | static void bench_recover_setup(void* arg) { 40 | int i; 41 | bench_recover_data *data = (bench_recover_data*)arg; 42 | 43 | for (i = 0; i < 32; i++) { 44 | data->msg[i] = 1 + i; 45 | } 46 | for (i = 0; i < 64; i++) { 47 | data->sig[i] = 65 + i; 48 | } 49 | } 50 | 51 | static void run_recovery_bench(int iters, int argc, char** argv) { 52 | bench_recover_data data; 53 | int d = argc == 1; 54 | 55 | data.ctx = rustsecp256k1_v0_11_context_create(SECP256K1_CONTEXT_NONE); 56 | 57 | if (d || have_flag(argc, argv, "ecdsa") || have_flag(argc, argv, "recover") || have_flag(argc, argv, "ecdsa_recover")) run_benchmark("ecdsa_recover", bench_recover, bench_recover_setup, NULL, &data, 10, iters); 58 | 59 | rustsecp256k1_v0_11_context_destroy(data.ctx); 60 | } 61 | 62 | #endif /* SECP256K1_MODULE_RECOVERY_BENCH_H */ 63 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/modules/schnorrsig/Makefile.am.include: -------------------------------------------------------------------------------- 1 | include_HEADERS += include/rustsecp256k1_v0_11_schnorrsig.h 2 | noinst_HEADERS += src/modules/schnorrsig/main_impl.h 3 | noinst_HEADERS += src/modules/schnorrsig/tests_impl.h 4 | noinst_HEADERS += src/modules/schnorrsig/tests_exhaustive_impl.h 5 | noinst_HEADERS += src/modules/schnorrsig/bench_impl.h 6 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/modules/schnorrsig/bench_impl.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Copyright (c) 2018-2020 Andrew Poelstra, Jonas Nick * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 | ***********************************************************************/ 6 | 7 | #ifndef SECP256K1_MODULE_SCHNORRSIG_BENCH_H 8 | #define SECP256K1_MODULE_SCHNORRSIG_BENCH_H 9 | 10 | #include "../../../include/secp256k1_schnorrsig.h" 11 | 12 | #define MSGLEN 32 13 | 14 | typedef struct { 15 | rustsecp256k1_v0_11_context *ctx; 16 | int n; 17 | 18 | const rustsecp256k1_v0_11_keypair **keypairs; 19 | const unsigned char **pk; 20 | const unsigned char **sigs; 21 | const unsigned char **msgs; 22 | } bench_schnorrsig_data; 23 | 24 | static void bench_schnorrsig_sign(void* arg, int iters) { 25 | bench_schnorrsig_data *data = (bench_schnorrsig_data *)arg; 26 | int i; 27 | unsigned char msg[MSGLEN] = {0}; 28 | unsigned char sig[64]; 29 | 30 | for (i = 0; i < iters; i++) { 31 | msg[0] = i; 32 | msg[1] = i >> 8; 33 | CHECK(rustsecp256k1_v0_11_schnorrsig_sign_custom(data->ctx, sig, msg, MSGLEN, data->keypairs[i], NULL)); 34 | } 35 | } 36 | 37 | static void bench_schnorrsig_verify(void* arg, int iters) { 38 | bench_schnorrsig_data *data = (bench_schnorrsig_data *)arg; 39 | int i; 40 | 41 | for (i = 0; i < iters; i++) { 42 | rustsecp256k1_v0_11_xonly_pubkey pk; 43 | CHECK(rustsecp256k1_v0_11_xonly_pubkey_parse(data->ctx, &pk, data->pk[i]) == 1); 44 | CHECK(rustsecp256k1_v0_11_schnorrsig_verify(data->ctx, data->sigs[i], data->msgs[i], MSGLEN, &pk)); 45 | } 46 | } 47 | 48 | static void run_schnorrsig_bench(int iters, int argc, char** argv) { 49 | int i; 50 | bench_schnorrsig_data data; 51 | int d = argc == 1; 52 | 53 | data.ctx = rustsecp256k1_v0_11_context_create(SECP256K1_CONTEXT_NONE); 54 | data.keypairs = (const rustsecp256k1_v0_11_keypair **)malloc(iters * sizeof(rustsecp256k1_v0_11_keypair *)); 55 | data.pk = (const unsigned char **)malloc(iters * sizeof(unsigned char *)); 56 | data.msgs = (const unsigned char **)malloc(iters * sizeof(unsigned char *)); 57 | data.sigs = (const unsigned char **)malloc(iters * sizeof(unsigned char *)); 58 | 59 | CHECK(MSGLEN >= 4); 60 | for (i = 0; i < iters; i++) { 61 | unsigned char sk[32]; 62 | unsigned char *msg = (unsigned char *)malloc(MSGLEN); 63 | unsigned char *sig = (unsigned char *)malloc(64); 64 | rustsecp256k1_v0_11_keypair *keypair = (rustsecp256k1_v0_11_keypair *)malloc(sizeof(*keypair)); 65 | unsigned char *pk_char = (unsigned char *)malloc(32); 66 | rustsecp256k1_v0_11_xonly_pubkey pk; 67 | msg[0] = sk[0] = i; 68 | msg[1] = sk[1] = i >> 8; 69 | msg[2] = sk[2] = i >> 16; 70 | msg[3] = sk[3] = i >> 24; 71 | memset(&msg[4], 'm', MSGLEN - 4); 72 | memset(&sk[4], 's', 28); 73 | 74 | data.keypairs[i] = keypair; 75 | data.pk[i] = pk_char; 76 | data.msgs[i] = msg; 77 | data.sigs[i] = sig; 78 | 79 | CHECK(rustsecp256k1_v0_11_keypair_create(data.ctx, keypair, sk)); 80 | CHECK(rustsecp256k1_v0_11_schnorrsig_sign_custom(data.ctx, sig, msg, MSGLEN, keypair, NULL)); 81 | CHECK(rustsecp256k1_v0_11_keypair_xonly_pub(data.ctx, &pk, NULL, keypair)); 82 | CHECK(rustsecp256k1_v0_11_xonly_pubkey_serialize(data.ctx, pk_char, &pk) == 1); 83 | } 84 | 85 | if (d || have_flag(argc, argv, "schnorrsig") || have_flag(argc, argv, "sign") || have_flag(argc, argv, "schnorrsig_sign")) run_benchmark("schnorrsig_sign", bench_schnorrsig_sign, NULL, NULL, (void *) &data, 10, iters); 86 | if (d || have_flag(argc, argv, "schnorrsig") || have_flag(argc, argv, "verify") || have_flag(argc, argv, "schnorrsig_verify")) run_benchmark("schnorrsig_verify", bench_schnorrsig_verify, NULL, NULL, (void *) &data, 10, iters); 87 | 88 | for (i = 0; i < iters; i++) { 89 | free((void *)data.keypairs[i]); 90 | free((void *)data.pk[i]); 91 | free((void *)data.msgs[i]); 92 | free((void *)data.sigs[i]); 93 | } 94 | 95 | /* Casting to (void *) avoids a stupid warning in MSVC. */ 96 | free((void *)data.keypairs); 97 | free((void *)data.pk); 98 | free((void *)data.msgs); 99 | free((void *)data.sigs); 100 | 101 | rustsecp256k1_v0_11_context_destroy(data.ctx); 102 | } 103 | 104 | #endif 105 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/precompute_ecmult.c: -------------------------------------------------------------------------------- 1 | /***************************************************************************************************** 2 | * Copyright (c) 2013, 2014, 2017, 2021 Pieter Wuille, Andrew Poelstra, Jonas Nick, Russell O'Connor * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php. * 5 | *****************************************************************************************************/ 6 | 7 | #include 8 | #include 9 | 10 | #include "../include/secp256k1.h" 11 | 12 | #include "assumptions.h" 13 | #include "util.h" 14 | 15 | #include "field_impl.h" 16 | #include "group_impl.h" 17 | #include "int128_impl.h" 18 | #include "ecmult.h" 19 | #include "ecmult_compute_table_impl.h" 20 | 21 | static void print_table(FILE *fp, const char *name, int window_g, const rustsecp256k1_v0_11_ge_storage* table) { 22 | int j; 23 | int i; 24 | 25 | fprintf(fp, "const rustsecp256k1_v0_11_ge_storage %s[ECMULT_TABLE_SIZE(WINDOW_G)] = {\n", name); 26 | fprintf(fp, " S(%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32 27 | ",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32")\n", 28 | SECP256K1_GE_STORAGE_CONST_GET(table[0])); 29 | 30 | j = 1; 31 | for(i = 3; i <= window_g; ++i) { 32 | fprintf(fp, "#if WINDOW_G > %d\n", i-1); 33 | for(;j < ECMULT_TABLE_SIZE(i); ++j) { 34 | fprintf(fp, ",S(%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32 35 | ",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32")\n", 36 | SECP256K1_GE_STORAGE_CONST_GET(table[j])); 37 | } 38 | fprintf(fp, "#endif\n"); 39 | } 40 | fprintf(fp, "};\n"); 41 | } 42 | 43 | static void print_two_tables(FILE *fp, int window_g) { 44 | rustsecp256k1_v0_11_ge_storage* table = malloc(ECMULT_TABLE_SIZE(window_g) * sizeof(rustsecp256k1_v0_11_ge_storage)); 45 | rustsecp256k1_v0_11_ge_storage* table_128 = malloc(ECMULT_TABLE_SIZE(window_g) * sizeof(rustsecp256k1_v0_11_ge_storage)); 46 | 47 | rustsecp256k1_v0_11_ecmult_compute_two_tables(table, table_128, window_g, &rustsecp256k1_v0_11_ge_const_g); 48 | 49 | print_table(fp, "rustsecp256k1_v0_11_pre_g", window_g, table); 50 | print_table(fp, "rustsecp256k1_v0_11_pre_g_128", window_g, table_128); 51 | 52 | free(table); 53 | free(table_128); 54 | } 55 | 56 | int main(void) { 57 | /* Always compute all tables for window sizes up to 15. */ 58 | int window_g = (ECMULT_WINDOW_SIZE < 15) ? 15 : ECMULT_WINDOW_SIZE; 59 | const char outfile[] = "src/precomputed_ecmult.c"; 60 | FILE* fp; 61 | 62 | fp = fopen(outfile, "w"); 63 | if (fp == NULL) { 64 | fprintf(stderr, "Could not open %s for writing!\n", outfile); 65 | return -1; 66 | } 67 | 68 | fprintf(fp, "/* This file was automatically generated by precompute_ecmult. */\n"); 69 | fprintf(fp, "/* This file contains an array rustsecp256k1_v0_11_pre_g with odd multiples of the base point G and\n"); 70 | fprintf(fp, " * an array rustsecp256k1_v0_11_pre_g_128 with odd multiples of 2^128*G for accelerating the computation of a*P + b*G.\n"); 71 | fprintf(fp, " */\n"); 72 | fprintf(fp, "#include \"group.h\"\n"); 73 | fprintf(fp, "#include \"ecmult.h\"\n"); 74 | fprintf(fp, "#include \"precomputed_ecmult.h\"\n"); 75 | fprintf(fp, "#define S(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) SECP256K1_GE_STORAGE_CONST(0x##a##u,0x##b##u,0x##c##u,0x##d##u,0x##e##u,0x##f##u,0x##g##u,0x##h##u,0x##i##u,0x##j##u,0x##k##u,0x##l##u,0x##m##u,0x##n##u,0x##o##u,0x##p##u)\n"); 76 | fprintf(fp, "#if ECMULT_WINDOW_SIZE > %d\n", window_g); 77 | fprintf(fp, " #error configuration mismatch, invalid ECMULT_WINDOW_SIZE. Try deleting precomputed_ecmult.c before the build.\n"); 78 | fprintf(fp, "#endif\n"); 79 | fprintf(fp, "#ifdef EXHAUSTIVE_TEST_ORDER\n"); 80 | fprintf(fp, "# error Cannot compile precomputed_ecmult.c in exhaustive test mode\n"); 81 | fprintf(fp, "#endif /* EXHAUSTIVE_TEST_ORDER */\n"); 82 | fprintf(fp, "#define WINDOW_G ECMULT_WINDOW_SIZE\n"); 83 | 84 | print_two_tables(fp, window_g); 85 | 86 | fprintf(fp, "#undef S\n"); 87 | fclose(fp); 88 | 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/precompute_ecmult_gen.c: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * Copyright (c) 2013, 2014, 2015, 2021 Thomas Daede, Cory Fields, Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php. * 5 | *********************************************************************************/ 6 | 7 | #include 8 | #include 9 | 10 | #include "../include/secp256k1.h" 11 | 12 | #include "assumptions.h" 13 | #include "util.h" 14 | 15 | #include "group.h" 16 | #include "int128_impl.h" 17 | #include "ecmult_gen.h" 18 | #include "ecmult_gen_compute_table_impl.h" 19 | 20 | static const int CONFIGS[][2] = { 21 | {2, 5}, 22 | {11, 6}, 23 | {43, 6} 24 | }; 25 | 26 | static void print_table(FILE* fp, int blocks, int teeth) { 27 | int spacing = CEIL_DIV(256, blocks * teeth); 28 | size_t points = ((size_t)1) << (teeth - 1); 29 | int outer; 30 | size_t inner; 31 | 32 | rustsecp256k1_v0_11_ge_storage* table = checked_malloc(&default_error_callback, blocks * points * sizeof(rustsecp256k1_v0_11_ge_storage)); 33 | rustsecp256k1_v0_11_ecmult_gen_compute_table(table, &rustsecp256k1_v0_11_ge_const_g, blocks, teeth, spacing); 34 | 35 | fprintf(fp, "#elif (COMB_BLOCKS == %d) && (COMB_TEETH == %d) && (COMB_SPACING == %d)\n", blocks, teeth, spacing); 36 | for (outer = 0; outer != blocks; outer++) { 37 | fprintf(fp,"{"); 38 | for (inner = 0; inner != points; inner++) { 39 | fprintf(fp, "S(%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32 40 | ",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32",%"PRIx32")", 41 | SECP256K1_GE_STORAGE_CONST_GET(table[outer * points + inner])); 42 | if (inner != points - 1) { 43 | fprintf(fp,",\n"); 44 | } 45 | } 46 | if (outer != blocks - 1) { 47 | fprintf(fp,"},\n"); 48 | } else { 49 | fprintf(fp,"}\n"); 50 | } 51 | } 52 | free(table); 53 | } 54 | 55 | int main(int argc, char **argv) { 56 | const char outfile[] = "src/precomputed_ecmult_gen.c"; 57 | FILE* fp; 58 | size_t config; 59 | int did_current_config = 0; 60 | 61 | (void)argc; 62 | (void)argv; 63 | 64 | fp = fopen(outfile, "w"); 65 | if (fp == NULL) { 66 | fprintf(stderr, "Could not open %s for writing!\n", outfile); 67 | return -1; 68 | } 69 | 70 | fprintf(fp, "/* This file was automatically generated by precompute_ecmult_gen. */\n"); 71 | fprintf(fp, "/* See ecmult_gen_impl.h for details about the contents of this file. */\n"); 72 | fprintf(fp, "#include \"group.h\"\n"); 73 | fprintf(fp, "#include \"ecmult_gen.h\"\n"); 74 | fprintf(fp, "#include \"precomputed_ecmult_gen.h\"\n"); 75 | fprintf(fp, "#ifdef EXHAUSTIVE_TEST_ORDER\n"); 76 | fprintf(fp, "# error Cannot compile precomputed_ecmult_gen.c in exhaustive test mode\n"); 77 | fprintf(fp, "#endif /* EXHAUSTIVE_TEST_ORDER */\n"); 78 | fprintf(fp, "#define S(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) SECP256K1_GE_STORAGE_CONST(0x##a##u,0x##b##u,0x##c##u,0x##d##u,0x##e##u,0x##f##u,0x##g##u,0x##h##u,0x##i##u,0x##j##u,0x##k##u,0x##l##u,0x##m##u,0x##n##u,0x##o##u,0x##p##u)\n"); 79 | 80 | fprintf(fp, "const rustsecp256k1_v0_11_ge_storage rustsecp256k1_v0_11_ecmult_gen_prec_table[COMB_BLOCKS][COMB_POINTS] = {\n"); 81 | fprintf(fp, "#if 0\n"); 82 | for (config = 0; config < sizeof(CONFIGS) / sizeof(*CONFIGS); ++config) { 83 | print_table(fp, CONFIGS[config][0], CONFIGS[config][1]); 84 | if (CONFIGS[config][0] == COMB_BLOCKS && CONFIGS[config][1] == COMB_TEETH) { 85 | did_current_config = 1; 86 | } 87 | } 88 | if (!did_current_config) { 89 | print_table(fp, COMB_BLOCKS, COMB_TEETH); 90 | } 91 | fprintf(fp, "#else\n"); 92 | fprintf(fp, "# error Configuration mismatch, invalid COMB_* parameters. Try deleting precomputed_ecmult_gen.c before the build.\n"); 93 | fprintf(fp, "#endif\n"); 94 | 95 | fprintf(fp, "};\n"); 96 | fprintf(fp, "#undef S\n"); 97 | fclose(fp); 98 | 99 | return 0; 100 | } 101 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/precomputed_ecmult.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************************************** 2 | * Copyright (c) 2013, 2014, 2017, 2021 Pieter Wuille, Andrew Poelstra, Jonas Nick, Russell O'Connor * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php. * 5 | *****************************************************************************************************/ 6 | 7 | #ifndef SECP256K1_PRECOMPUTED_ECMULT_H 8 | #define SECP256K1_PRECOMPUTED_ECMULT_H 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | #include "ecmult.h" 15 | #include "group.h" 16 | #if defined(EXHAUSTIVE_TEST_ORDER) 17 | # if EXHAUSTIVE_TEST_ORDER == 7 18 | # define WINDOW_G 3 19 | # elif EXHAUSTIVE_TEST_ORDER == 13 20 | # define WINDOW_G 4 21 | # elif EXHAUSTIVE_TEST_ORDER == 199 22 | # define WINDOW_G 8 23 | # else 24 | # error No known generator for the specified exhaustive test group order. 25 | # endif 26 | static rustsecp256k1_v0_11_ge_storage rustsecp256k1_v0_11_pre_g[ECMULT_TABLE_SIZE(WINDOW_G)]; 27 | static rustsecp256k1_v0_11_ge_storage rustsecp256k1_v0_11_pre_g_128[ECMULT_TABLE_SIZE(WINDOW_G)]; 28 | #else /* !defined(EXHAUSTIVE_TEST_ORDER) */ 29 | # define WINDOW_G ECMULT_WINDOW_SIZE 30 | extern const rustsecp256k1_v0_11_ge_storage rustsecp256k1_v0_11_pre_g[ECMULT_TABLE_SIZE(WINDOW_G)]; 31 | extern const rustsecp256k1_v0_11_ge_storage rustsecp256k1_v0_11_pre_g_128[ECMULT_TABLE_SIZE(WINDOW_G)]; 32 | #endif /* defined(EXHAUSTIVE_TEST_ORDER) */ 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif 37 | 38 | #endif /* SECP256K1_PRECOMPUTED_ECMULT_H */ 39 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/precomputed_ecmult_gen.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * Copyright (c) 2013, 2014, 2015, 2021 Thomas Daede, Cory Fields, Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php. * 5 | *********************************************************************************/ 6 | 7 | #ifndef SECP256K1_PRECOMPUTED_ECMULT_GEN_H 8 | #define SECP256K1_PRECOMPUTED_ECMULT_GEN_H 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | #include "group.h" 15 | #include "ecmult_gen.h" 16 | #ifdef EXHAUSTIVE_TEST_ORDER 17 | static rustsecp256k1_v0_11_ge_storage rustsecp256k1_v0_11_ecmult_gen_prec_table[COMB_BLOCKS][COMB_POINTS]; 18 | #else 19 | extern const rustsecp256k1_v0_11_ge_storage rustsecp256k1_v0_11_ecmult_gen_prec_table[COMB_BLOCKS][COMB_POINTS]; 20 | #endif /* defined(EXHAUSTIVE_TEST_ORDER) */ 21 | 22 | #ifdef __cplusplus 23 | } 24 | #endif 25 | 26 | #endif /* SECP256K1_PRECOMPUTED_ECMULT_GEN_H */ 27 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/scalar_4x64.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Copyright (c) 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 | ***********************************************************************/ 6 | 7 | #ifndef SECP256K1_SCALAR_REPR_H 8 | #define SECP256K1_SCALAR_REPR_H 9 | 10 | #include 11 | 12 | /** A scalar modulo the group order of the secp256k1 curve. */ 13 | typedef struct { 14 | uint64_t d[4]; 15 | } rustsecp256k1_v0_11_scalar; 16 | 17 | #define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{((uint64_t)(d1)) << 32 | (d0), ((uint64_t)(d3)) << 32 | (d2), ((uint64_t)(d5)) << 32 | (d4), ((uint64_t)(d7)) << 32 | (d6)}} 18 | 19 | #endif /* SECP256K1_SCALAR_REPR_H */ 20 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/scalar_8x32.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Copyright (c) 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 | ***********************************************************************/ 6 | 7 | #ifndef SECP256K1_SCALAR_REPR_H 8 | #define SECP256K1_SCALAR_REPR_H 9 | 10 | #include 11 | 12 | /** A scalar modulo the group order of the secp256k1 curve. */ 13 | typedef struct { 14 | uint32_t d[8]; 15 | } rustsecp256k1_v0_11_scalar; 16 | 17 | #define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{(d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7)}} 18 | 19 | #endif /* SECP256K1_SCALAR_REPR_H */ 20 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/scalar_low.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Copyright (c) 2015, 2022 Andrew Poelstra, Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 | ***********************************************************************/ 6 | 7 | #ifndef SECP256K1_SCALAR_REPR_H 8 | #define SECP256K1_SCALAR_REPR_H 9 | 10 | #include 11 | 12 | /** A scalar modulo the group order of the secp256k1 curve. */ 13 | typedef uint32_t rustsecp256k1_v0_11_scalar; 14 | 15 | /* A compile-time constant equal to 2^32 (modulo order). */ 16 | #define SCALAR_2P32 ((0xffffffffUL % EXHAUSTIVE_TEST_ORDER) + 1U) 17 | 18 | /* Compute a*2^32 + b (modulo order). */ 19 | #define SCALAR_HORNER(a, b) (((uint64_t)(a) * SCALAR_2P32 + (b)) % EXHAUSTIVE_TEST_ORDER) 20 | 21 | /* Evaluates to the provided 256-bit constant reduced modulo order. */ 22 | #define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0) SCALAR_HORNER(SCALAR_HORNER(SCALAR_HORNER(SCALAR_HORNER(SCALAR_HORNER(SCALAR_HORNER(SCALAR_HORNER((d7), (d6)), (d5)), (d4)), (d3)), (d2)), (d1)), (d0)) 23 | 24 | #endif /* SECP256K1_SCALAR_REPR_H */ 25 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/scratch.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Copyright (c) 2017 Andrew Poelstra * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 | ***********************************************************************/ 6 | 7 | #ifndef SECP256K1_SCRATCH_H 8 | #define SECP256K1_SCRATCH_H 9 | 10 | /* The typedef is used internally; the struct name is used in the public API 11 | * (where it is exposed as a different typedef) */ 12 | typedef struct rustsecp256k1_v0_11_scratch_space_struct { 13 | /** guard against interpreting this object as other types */ 14 | unsigned char magic[8]; 15 | /** actual allocated data */ 16 | void *data; 17 | /** amount that has been allocated (i.e. `data + offset` is the next 18 | * available pointer) */ 19 | size_t alloc_size; 20 | /** maximum size available to allocate */ 21 | size_t max_size; 22 | } rustsecp256k1_v0_11_scratch; 23 | 24 | typedef struct rustsecp256k1_v0_11_scratch_space_struct rustsecp256k1_v0_11_scratch_space; 25 | 26 | /** Returns an opaque object used to "checkpoint" a scratch space. Used 27 | * with `rustsecp256k1_v0_11_scratch_apply_checkpoint` to undo allocations. */ 28 | static size_t rustsecp256k1_v0_11_scratch_checkpoint(const rustsecp256k1_v0_11_callback* error_callback, const rustsecp256k1_v0_11_scratch* scratch); 29 | 30 | /** Applies a check point received from `rustsecp256k1_v0_11_scratch_checkpoint`, 31 | * undoing all allocations since that point. */ 32 | static void rustsecp256k1_v0_11_scratch_apply_checkpoint(const rustsecp256k1_v0_11_callback* error_callback, rustsecp256k1_v0_11_scratch* scratch, size_t checkpoint); 33 | 34 | /** Returns the maximum allocation the scratch space will allow */ 35 | static size_t rustsecp256k1_v0_11_scratch_max_allocation(const rustsecp256k1_v0_11_callback* error_callback, const rustsecp256k1_v0_11_scratch* scratch, size_t n_objects); 36 | 37 | /** Returns a pointer into the most recently allocated frame, or NULL if there is insufficient available space */ 38 | static void *rustsecp256k1_v0_11_scratch_alloc(const rustsecp256k1_v0_11_callback* error_callback, rustsecp256k1_v0_11_scratch* scratch, size_t n); 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/scratch_impl.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Copyright (c) 2017 Andrew Poelstra * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 | ***********************************************************************/ 6 | 7 | #ifndef SECP256K1_SCRATCH_IMPL_H 8 | #define SECP256K1_SCRATCH_IMPL_H 9 | 10 | #include "util.h" 11 | #include "scratch.h" 12 | 13 | static size_t rustsecp256k1_v0_11_scratch_checkpoint(const rustsecp256k1_v0_11_callback* error_callback, const rustsecp256k1_v0_11_scratch* scratch) { 14 | if (rustsecp256k1_v0_11_memcmp_var(scratch->magic, "scratch", 8) != 0) { 15 | rustsecp256k1_v0_11_callback_call(error_callback, "invalid scratch space"); 16 | return 0; 17 | } 18 | return scratch->alloc_size; 19 | } 20 | 21 | static void rustsecp256k1_v0_11_scratch_apply_checkpoint(const rustsecp256k1_v0_11_callback* error_callback, rustsecp256k1_v0_11_scratch* scratch, size_t checkpoint) { 22 | if (rustsecp256k1_v0_11_memcmp_var(scratch->magic, "scratch", 8) != 0) { 23 | rustsecp256k1_v0_11_callback_call(error_callback, "invalid scratch space"); 24 | return; 25 | } 26 | if (checkpoint > scratch->alloc_size) { 27 | rustsecp256k1_v0_11_callback_call(error_callback, "invalid checkpoint"); 28 | return; 29 | } 30 | scratch->alloc_size = checkpoint; 31 | } 32 | 33 | static size_t rustsecp256k1_v0_11_scratch_max_allocation(const rustsecp256k1_v0_11_callback* error_callback, const rustsecp256k1_v0_11_scratch* scratch, size_t objects) { 34 | if (rustsecp256k1_v0_11_memcmp_var(scratch->magic, "scratch", 8) != 0) { 35 | rustsecp256k1_v0_11_callback_call(error_callback, "invalid scratch space"); 36 | return 0; 37 | } 38 | /* Ensure that multiplication will not wrap around */ 39 | if (ALIGNMENT > 1 && objects > SIZE_MAX/(ALIGNMENT - 1)) { 40 | return 0; 41 | } 42 | if (scratch->max_size - scratch->alloc_size <= objects * (ALIGNMENT - 1)) { 43 | return 0; 44 | } 45 | return scratch->max_size - scratch->alloc_size - objects * (ALIGNMENT - 1); 46 | } 47 | 48 | static void *rustsecp256k1_v0_11_scratch_alloc(const rustsecp256k1_v0_11_callback* error_callback, rustsecp256k1_v0_11_scratch* scratch, size_t size) { 49 | void *ret; 50 | size_t rounded_size; 51 | 52 | rounded_size = ROUND_TO_ALIGN(size); 53 | /* Check that rounding did not wrap around */ 54 | if (rounded_size < size) { 55 | return NULL; 56 | } 57 | size = rounded_size; 58 | 59 | if (rustsecp256k1_v0_11_memcmp_var(scratch->magic, "scratch", 8) != 0) { 60 | rustsecp256k1_v0_11_callback_call(error_callback, "invalid scratch space"); 61 | return NULL; 62 | } 63 | 64 | if (size > scratch->max_size - scratch->alloc_size) { 65 | return NULL; 66 | } 67 | ret = (void *) ((char *) scratch->data + scratch->alloc_size); 68 | memset(ret, 0, size); 69 | scratch->alloc_size += size; 70 | 71 | return ret; 72 | } 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/selftest.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Copyright (c) 2020 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 | ***********************************************************************/ 6 | 7 | #ifndef SECP256K1_SELFTEST_H 8 | #define SECP256K1_SELFTEST_H 9 | 10 | #include "hash.h" 11 | 12 | #include 13 | 14 | static int rustsecp256k1_v0_11_selftest_sha256(void) { 15 | static const char *input63 = "For this sample, this 63-byte string will be used as input data"; 16 | static const unsigned char output32[32] = { 17 | 0xf0, 0x8a, 0x78, 0xcb, 0xba, 0xee, 0x08, 0x2b, 0x05, 0x2a, 0xe0, 0x70, 0x8f, 0x32, 0xfa, 0x1e, 18 | 0x50, 0xc5, 0xc4, 0x21, 0xaa, 0x77, 0x2b, 0xa5, 0xdb, 0xb4, 0x06, 0xa2, 0xea, 0x6b, 0xe3, 0x42, 19 | }; 20 | unsigned char out[32]; 21 | rustsecp256k1_v0_11_sha256 hasher; 22 | rustsecp256k1_v0_11_sha256_initialize(&hasher); 23 | rustsecp256k1_v0_11_sha256_write(&hasher, (const unsigned char*)input63, 63); 24 | rustsecp256k1_v0_11_sha256_finalize(&hasher, out); 25 | return rustsecp256k1_v0_11_memcmp_var(out, output32, 32) == 0; 26 | } 27 | 28 | static int rustsecp256k1_v0_11_selftest_passes(void) { 29 | return rustsecp256k1_v0_11_selftest_sha256(); 30 | } 31 | 32 | #endif /* SECP256K1_SELFTEST_H */ 33 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/src/testrand.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 | ***********************************************************************/ 6 | 7 | #ifndef SECP256K1_TESTRAND_H 8 | #define SECP256K1_TESTRAND_H 9 | 10 | #include "util.h" 11 | 12 | /* A non-cryptographic RNG used only for test infrastructure. */ 13 | 14 | /** Seed the pseudorandom number generator for testing. */ 15 | SECP256K1_INLINE static void testrand_seed(const unsigned char *seed16); 16 | 17 | /** Generate a pseudorandom number in the range [0..2**32-1]. */ 18 | SECP256K1_INLINE static uint32_t testrand32(void); 19 | 20 | /** Generate a pseudorandom number in the range [0..2**64-1]. */ 21 | SECP256K1_INLINE static uint64_t testrand64(void); 22 | 23 | /** Generate a pseudorandom number in the range [0..2**bits-1]. Bits must be 1 or 24 | * more. */ 25 | SECP256K1_INLINE static uint64_t testrand_bits(int bits); 26 | 27 | /** Generate a pseudorandom number in the range [0..range-1]. */ 28 | static uint32_t testrand_int(uint32_t range); 29 | 30 | /** Generate a pseudorandom 32-byte array. */ 31 | static void testrand256(unsigned char *b32); 32 | 33 | /** Generate a pseudorandom 32-byte array with long sequences of zero and one bits. */ 34 | static void testrand256_test(unsigned char *b32); 35 | 36 | /** Generate pseudorandom bytes with long sequences of zero and one bits. */ 37 | static void testrand_bytes_test(unsigned char *bytes, size_t len); 38 | 39 | /** Flip a single random bit in a byte array */ 40 | static void testrand_flip(unsigned char *b, size_t len); 41 | 42 | /** Initialize the test RNG using (hex encoded) array up to 16 bytes, or randomly if hexseed is NULL. */ 43 | static void testrand_init(const char* hexseed); 44 | 45 | /** Print final test information. */ 46 | static void testrand_finish(void); 47 | 48 | #endif /* SECP256K1_TESTRAND_H */ 49 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/tools/check-abi.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -eu 4 | 5 | default_base_version="$(git describe --match "v*.*.*" --abbrev=0)" 6 | default_new_version="HEAD" 7 | 8 | display_help_and_exit() { 9 | echo "Usage: $0 [ []]" 10 | echo "" 11 | echo "Description: This script uses the ABI Compliance Checker tool to determine if the ABI" 12 | echo " of a new version of libsecp256k1 has changed in a backward-incompatible way." 13 | echo "" 14 | echo "Options:" 15 | echo " base_ver Specify the base version as a git commit-ish" 16 | echo " (default: most recent reachable tag matching \"v.*.*\", currently \"$default_base_version\")" 17 | echo " new_ver Specify the new version as a git commit-ish" 18 | echo " (default: $default_new_version)" 19 | echo " -h, --help Display this help message" 20 | exit 0 21 | } 22 | 23 | if [ "$#" -eq 0 ]; then 24 | base_version="$default_base_version" 25 | new_version="$default_new_version" 26 | elif [ "$#" -eq 1 ] && { [ "$1" = "-h" ] || [ "$1" = "--help" ]; }; then 27 | display_help_and_exit 28 | elif [ "$#" -eq 1 ] || [ "$#" -eq 2 ]; then 29 | base_version="$1" 30 | if [ "$#" -eq 2 ]; then 31 | new_version="$2" 32 | fi 33 | else 34 | echo "Invalid usage. See help:" 35 | echo "" 36 | display_help_and_exit 37 | fi 38 | 39 | checkout_and_build() { 40 | _orig_dir="$(pwd)" 41 | git worktree add --detach "$1" "$2" 42 | cd "$1" 43 | mkdir build && cd build 44 | cmake -S .. --preset dev-mode \ 45 | -DCMAKE_C_COMPILER=gcc -DCMAKE_BUILD_TYPE=None -DCMAKE_C_FLAGS="-g -Og -gdwarf-4" \ 46 | -DSECP256K1_BUILD_BENCHMARK=OFF \ 47 | -DSECP256K1_BUILD_TESTS=OFF \ 48 | -DSECP256K1_BUILD_EXHAUSTIVE_TESTS=OFF \ 49 | -DSECP256K1_BUILD_CTIME_TESTS=OFF \ 50 | -DSECP256K1_BUILD_EXAMPLES=OFF 51 | cmake --build . -j "$(nproc)" 52 | # FIXME: Just set LIBPATH to lib/libsecp256k1.so once version 0.6.0 is 53 | # released. 54 | if [ -f "src/libsecp256k1.so" ]; then 55 | LIBPATH="src/libsecp256k1.so" 56 | else 57 | LIBPATH="lib/libsecp256k1.so" 58 | fi 59 | abi-dumper $LIBPATH -o ABI.dump -lver "$2" -public-headers ../include/ 60 | cd "$_orig_dir" 61 | } 62 | 63 | echo "Comparing $base_version (base version) to $new_version (new version)" 64 | echo 65 | 66 | base_source_dir="$(mktemp -d)" 67 | checkout_and_build "$base_source_dir" "$base_version" 68 | 69 | new_source_dir="$(mktemp -d)" 70 | checkout_and_build "$new_source_dir" "$new_version" 71 | 72 | abi-compliance-checker -lib libsecp256k1 -old "${base_source_dir}/build/ABI.dump" -new "${new_source_dir}/build/ABI.dump" 73 | git worktree remove "$base_source_dir" 74 | git worktree remove "$new_source_dir" 75 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/secp256k1/tools/tests_wycheproof_generate.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Copyright (c) 2023 Random "Randy" Lattice and Sean Andersen 3 | # Distributed under the MIT software license, see the accompanying 4 | # file COPYING or https://www.opensource.org/licenses/mit-license.php. 5 | ''' 6 | Generate a C file with ECDSA testvectors from the Wycheproof project. 7 | ''' 8 | 9 | import json 10 | import sys 11 | 12 | filename_input = sys.argv[1] 13 | 14 | with open(filename_input) as f: 15 | doc = json.load(f) 16 | 17 | num_groups = len(doc['testGroups']) 18 | 19 | def to_c_array(x): 20 | if x == "": 21 | return "" 22 | s = ',0x'.join(a+b for a,b in zip(x[::2], x[1::2])) 23 | return "0x" + s 24 | 25 | 26 | num_vectors = 0 27 | offset_msg_running, offset_pk_running, offset_sig = 0, 0, 0 28 | out = "" 29 | messages = "" 30 | signatures = "" 31 | public_keys = "" 32 | cache_msgs = {} 33 | cache_public_keys = {} 34 | 35 | for i in range(num_groups): 36 | group = doc['testGroups'][i] 37 | num_tests = len(group['tests']) 38 | public_key = group['publicKey'] 39 | for j in range(num_tests): 40 | test_vector = group['tests'][j] 41 | # // 2 to convert hex to byte length 42 | sig_size = len(test_vector['sig']) // 2 43 | msg_size = len(test_vector['msg']) // 2 44 | 45 | if test_vector['result'] == "invalid": 46 | expected_verify = 0 47 | elif test_vector['result'] == "valid": 48 | expected_verify = 1 49 | else: 50 | raise ValueError("invalid result field") 51 | 52 | if num_vectors != 0 and sig_size != 0: 53 | signatures += ",\n " 54 | 55 | new_msg = False 56 | msg = to_c_array(test_vector['msg']) 57 | msg_offset = offset_msg_running 58 | # check for repeated msg 59 | if msg not in cache_msgs: 60 | if num_vectors != 0 and msg_size != 0: 61 | messages += ",\n " 62 | cache_msgs[msg] = offset_msg_running 63 | messages += msg 64 | new_msg = True 65 | else: 66 | msg_offset = cache_msgs[msg] 67 | 68 | new_pk = False 69 | pk = to_c_array(public_key['uncompressed']) 70 | pk_offset = offset_pk_running 71 | # check for repeated pk 72 | if pk not in cache_public_keys: 73 | if num_vectors != 0: 74 | public_keys += ",\n " 75 | cache_public_keys[pk] = offset_pk_running 76 | public_keys += pk 77 | new_pk = True 78 | else: 79 | pk_offset = cache_public_keys[pk] 80 | 81 | signatures += to_c_array(test_vector['sig']) 82 | 83 | out += " /" + "* tcId: " + str(test_vector['tcId']) + ". " + test_vector['comment'] + " *" + "/\n" 84 | out += f" {{{pk_offset}, {msg_offset}, {msg_size}, {offset_sig}, {sig_size}, {expected_verify} }},\n" 85 | if new_msg: 86 | offset_msg_running += msg_size 87 | if new_pk: 88 | offset_pk_running += 65 89 | offset_sig += sig_size 90 | num_vectors += 1 91 | 92 | struct_definition = """ 93 | typedef struct { 94 | size_t pk_offset; 95 | size_t msg_offset; 96 | size_t msg_len; 97 | size_t sig_offset; 98 | size_t sig_len; 99 | int expected_verify; 100 | } wycheproof_ecdsa_testvector; 101 | """ 102 | 103 | 104 | print("/* Note: this file was autogenerated using tests_wycheproof_generate.py. Do not edit. */") 105 | print(f"#define SECP256K1_ECDSA_WYCHEPROOF_NUMBER_TESTVECTORS ({num_vectors})") 106 | 107 | print(struct_definition) 108 | 109 | print("static const unsigned char wycheproof_ecdsa_messages[] = { " + messages + "};\n") 110 | print("static const unsigned char wycheproof_ecdsa_public_keys[] = { " + public_keys + "};\n") 111 | print("static const unsigned char wycheproof_ecdsa_signatures[] = { " + signatures + "};\n") 112 | 113 | print("static const wycheproof_ecdsa_testvector testvectors[SECP256K1_ECDSA_WYCHEPROOF_NUMBER_TESTVECTORS] = {") 114 | print(out) 115 | print("};") 116 | -------------------------------------------------------------------------------- /secp256k1-sys/depend/util.h.patch: -------------------------------------------------------------------------------- 1 | 14d13 2 | < #include 3 | 22,41d20 4 | < /* Debug helper for printing arrays of unsigned char. */ 5 | < #define PRINT_BUF(buf, len) do { \ 6 | < printf("%s[%lu] = ", #buf, (unsigned long)len); \ 7 | < print_buf_plain(buf, len); \ 8 | < } while(0) 9 | < 10 | < static void print_buf_plain(const unsigned char *buf, size_t len) { 11 | < size_t i; 12 | < printf("{"); 13 | < for (i = 0; i < len; i++) { 14 | < if (i % 8 == 0) { 15 | < printf("\n "); 16 | < } else { 17 | < printf(" "); 18 | < } 19 | < printf("0x%02X,", buf[i]); 20 | < } 21 | < printf("\n}\n"); 22 | < } 23 | < 24 | 148,152c127,129 25 | < void *ret = malloc(size); 26 | < if (ret == NULL) { 27 | < secp256k1_callback_call(cb, "Out of memory"); 28 | < } 29 | < return ret; 30 | --- 31 | > (void) cb; 32 | > (void) size; 33 | > return NULL; 34 | -------------------------------------------------------------------------------- /secp256k1-sys/src/macros.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: CC0-1.0 2 | 3 | /// Implement methods and traits for types that contain an inner array. 4 | #[macro_export] 5 | macro_rules! impl_array_newtype { 6 | ($thing:ident, $ty:ty, $len:expr) => { 7 | impl $thing { 8 | /// Like `cmp::Ord` but faster and with no guarantees across library versions. 9 | /// 10 | /// The inner byte array of `Self` is passed across the FFI boundry, as such there are 11 | /// no guarantees on its layout and it is subject to change across library versions, 12 | /// even minor versions. For this reason comparison function implementations (e.g. 13 | /// `Ord`, `PartialEq`) take measures to ensure the data will remain constant (e.g., by 14 | /// serializing it to a guaranteed format). This means they may be slow, this function 15 | /// provides a faster comparison if you know that your types come from the same library 16 | /// version. 17 | pub fn cmp_fast_unstable(&self, other: &Self) -> core::cmp::Ordering { 18 | self[..].cmp(&other[..]) 19 | } 20 | 21 | /// Like `cmp::Eq` but faster and with no guarantees across library versions. 22 | /// 23 | /// The inner byte array of `Self` is passed across the FFI boundry, as such there are 24 | /// no guarantees on its layout and it is subject to change across library versions, 25 | /// even minor versions. For this reason comparison function implementations (e.g. 26 | /// `Ord`, `PartialEq`) take measures to ensure the data will remain constant (e.g., by 27 | /// serializing it to a guaranteed format). This means they may be slow, this function 28 | /// provides a faster equality check if you know that your types come from the same 29 | /// library version. 30 | pub fn eq_fast_unstable(&self, other: &Self) -> bool { 31 | self[..].eq(&other[..]) 32 | } 33 | } 34 | 35 | impl AsRef<[$ty; $len]> for $thing { 36 | #[inline] 37 | /// Gets a reference to the underlying array 38 | fn as_ref(&self) -> &[$ty; $len] { 39 | let &$thing(ref dat) = self; 40 | dat 41 | } 42 | } 43 | 44 | impl core::ops::Index for $thing 45 | where 46 | [$ty]: core::ops::Index, 47 | { 48 | type Output = <[$ty] as core::ops::Index>::Output; 49 | 50 | #[inline] 51 | fn index(&self, index: I) -> &Self::Output { &self.0[index] } 52 | } 53 | 54 | impl $crate::CPtr for $thing { 55 | type Target = $ty; 56 | 57 | fn as_c_ptr(&self) -> *const Self::Target { 58 | let &$thing(ref dat) = self; 59 | dat.as_ptr() 60 | } 61 | 62 | fn as_mut_c_ptr(&mut self) -> *mut Self::Target { 63 | let &mut $thing(ref mut dat) = self; 64 | dat.as_mut_ptr() 65 | } 66 | } 67 | } 68 | } 69 | 70 | #[macro_export] 71 | macro_rules! impl_raw_debug { 72 | ($thing:ident) => { 73 | impl core::fmt::Debug for $thing { 74 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 75 | for i in self[..].iter().cloned() { 76 | write!(f, "{:02x}", i)?; 77 | } 78 | Ok(()) 79 | } 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /secp256k1-sys/src/types.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: CC0-1.0 2 | 3 | #![allow(non_camel_case_types)] 4 | 5 | pub type c_int = i32; 6 | pub type c_uchar = u8; 7 | pub type c_uint = u32; 8 | pub type size_t = usize; 9 | 10 | /// This might not match C's `c_char` exactly. 11 | /// The way we use it makes it fine either way but this type shouldn't be used outside of the library. 12 | pub type c_char = i8; 13 | 14 | pub use core::ffi::c_void; 15 | 16 | /// A type that is as aligned as the biggest alignment for fundamental types in C 17 | /// since C11 that means as aligned as `max_align_t` is. 18 | /// the exact size/alignment is unspecified. 19 | // 16 matches is as big as the biggest alignment in any arch that rust currently supports https://github.com/rust-lang/rust/blob/2c31b45ae878b821975c4ebd94cc1e49f6073fd0/library/std/src/sys_common/alloc.rs 20 | #[repr(align(16))] 21 | #[derive(Default, Copy, Clone)] 22 | #[allow(dead_code)] // We never access the inner data directly, only by way of a pointer. 23 | pub struct AlignedType([u8; 16]); 24 | 25 | impl AlignedType { 26 | pub fn zeroed() -> Self { 27 | AlignedType([0u8; 16]) 28 | } 29 | 30 | /// A static zeroed out AlignedType for use in static assignments of [AlignedType; _] 31 | pub const ZERO: AlignedType = AlignedType([0u8; 16]); 32 | } 33 | 34 | #[cfg(all(feature = "alloc", not(rust_secp_no_symbol_renaming)))] 35 | pub(crate) const ALIGN_TO: usize = core::mem::align_of::(); 36 | 37 | #[cfg(test)] 38 | mod tests { 39 | extern crate libc; 40 | use std::any::TypeId; 41 | use std::mem; 42 | use std::os::raw; 43 | use crate::{types, AlignedType}; 44 | 45 | #[test] 46 | fn verify_types() { 47 | assert_eq!(TypeId::of::(), TypeId::of::()); 48 | assert_eq!(TypeId::of::(), TypeId::of::()); 49 | assert_eq!(TypeId::of::(), TypeId::of::()); 50 | assert_eq!(TypeId::of::(), TypeId::of::()); 51 | 52 | assert!(mem::align_of::() >= mem::align_of::()); 53 | } 54 | } 55 | 56 | #[doc(hidden)] 57 | #[cfg(target_arch = "wasm32")] 58 | pub fn sanity_checks_for_wasm() { 59 | use core::mem::{align_of, size_of}; 60 | extern "C" { 61 | pub static WASM32_INT_SIZE: c_uchar; 62 | pub static WASM32_INT_ALIGN: c_uchar; 63 | 64 | pub static WASM32_UNSIGNED_INT_SIZE: c_uchar; 65 | pub static WASM32_UNSIGNED_INT_ALIGN: c_uchar; 66 | 67 | pub static WASM32_SIZE_T_SIZE: c_uchar; 68 | pub static WASM32_SIZE_T_ALIGN: c_uchar; 69 | 70 | pub static WASM32_UNSIGNED_CHAR_SIZE: c_uchar; 71 | pub static WASM32_UNSIGNED_CHAR_ALIGN: c_uchar; 72 | 73 | pub static WASM32_PTR_SIZE: c_uchar; 74 | pub static WASM32_PTR_ALIGN: c_uchar; 75 | } 76 | unsafe { 77 | assert_eq!(size_of::(), WASM32_INT_SIZE as usize); 78 | assert_eq!(align_of::(), WASM32_INT_ALIGN as usize); 79 | 80 | assert_eq!(size_of::(), WASM32_UNSIGNED_INT_SIZE as usize); 81 | assert_eq!(align_of::(), WASM32_UNSIGNED_INT_ALIGN as usize); 82 | 83 | assert_eq!(size_of::(), WASM32_SIZE_T_SIZE as usize); 84 | assert_eq!(align_of::(), WASM32_SIZE_T_ALIGN as usize); 85 | 86 | assert_eq!(size_of::(), WASM32_UNSIGNED_CHAR_SIZE as usize); 87 | assert_eq!(align_of::(), WASM32_UNSIGNED_CHAR_ALIGN as usize); 88 | 89 | assert_eq!(size_of::<*const ()>(), WASM32_PTR_SIZE as usize); 90 | assert_eq!(align_of::<*const ()>(), WASM32_PTR_ALIGN as usize); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /secp256k1-sys/wasm/wasm-sysroot/stdio.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rust-bitcoin/rust-secp256k1/4d36fefdddb118425bb9bcf611bb6e4dff306cfc/secp256k1-sys/wasm/wasm-sysroot/stdio.h -------------------------------------------------------------------------------- /secp256k1-sys/wasm/wasm-sysroot/stdlib.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rust-bitcoin/rust-secp256k1/4d36fefdddb118425bb9bcf611bb6e4dff306cfc/secp256k1-sys/wasm/wasm-sysroot/stdlib.h -------------------------------------------------------------------------------- /secp256k1-sys/wasm/wasm-sysroot/string.h: -------------------------------------------------------------------------------- 1 | #include 2 | void *memset(void *s, int c, size_t n); 3 | void *memcpy(void *dest, const void *src, size_t n); 4 | int memcmp(const void *s1, const void *s2, size_t n); 5 | -------------------------------------------------------------------------------- /secp256k1-sys/wasm/wasm.c: -------------------------------------------------------------------------------- 1 | #include 2 | #define alignof(type) offsetof (struct { char c; type member; }, member) 3 | 4 | const unsigned char WASM32_INT_SIZE = sizeof(int); 5 | const unsigned char WASM32_INT_ALIGN = alignof(int); 6 | 7 | const unsigned char WASM32_UNSIGNED_INT_SIZE = sizeof(unsigned int); 8 | const unsigned char WASM32_UNSIGNED_INT_ALIGN = alignof(unsigned int); 9 | 10 | const unsigned char WASM32_SIZE_T_SIZE = sizeof(size_t); 11 | const unsigned char WASM32_SIZE_T_ALIGN = alignof(size_t); 12 | 13 | const unsigned char WASM32_UNSIGNED_CHAR_SIZE = sizeof(unsigned char); 14 | const unsigned char WASM32_UNSIGNED_CHAR_ALIGN = alignof(unsigned char); 15 | 16 | const unsigned char WASM32_PTR_SIZE = sizeof(void*); 17 | const unsigned char WASM32_PTR_ALIGN = alignof(void*); 18 | -------------------------------------------------------------------------------- /src/constants.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: CC0-1.0 2 | 3 | //! Constants related to the API and the underlying curve. 4 | //! 5 | 6 | /// The size (in bytes) of a message. 7 | pub const MESSAGE_SIZE: usize = 32; 8 | 9 | /// The size (in bytes) of a secret key. 10 | pub const SECRET_KEY_SIZE: usize = 32; 11 | 12 | /// The size (in bytes) of a serialized public key. 13 | pub const PUBLIC_KEY_SIZE: usize = 33; 14 | 15 | /// The size (in bytes) of an serialized uncompressed public key. 16 | pub const UNCOMPRESSED_PUBLIC_KEY_SIZE: usize = 65; 17 | 18 | /// The maximum size of a signature. 19 | pub const MAX_SIGNATURE_SIZE: usize = 72; 20 | 21 | /// The maximum size of a compact signature. 22 | pub const COMPACT_SIGNATURE_SIZE: usize = 64; 23 | 24 | /// The size of a schnorr signature. 25 | pub const SCHNORR_SIGNATURE_SIZE: usize = 64; 26 | 27 | /// The size of a schnorr public key. 28 | pub const SCHNORR_PUBLIC_KEY_SIZE: usize = 32; 29 | 30 | /// The size of a key pair. 31 | pub const KEY_PAIR_SIZE: usize = 96; 32 | 33 | /// The size of a full ElligatorSwift encoding. 34 | pub const ELLSWIFT_ENCODING_SIZE: usize = 64; 35 | 36 | /// The Prime for the secp256k1 field element. 37 | #[rustfmt::skip] 38 | pub const FIELD_SIZE: [u8; 32] = [ 39 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 40 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 41 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 42 | 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f 43 | ]; 44 | 45 | /// The order of the secp256k1 curve. 46 | #[rustfmt::skip] 47 | pub const CURVE_ORDER: [u8; 32] = [ 48 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 49 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 50 | 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, 51 | 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41 52 | ]; 53 | 54 | /// The X coordinate of the generator. 55 | #[rustfmt::skip] 56 | pub const GENERATOR_X: [u8; 32] = [ 57 | 0x79, 0xbe, 0x66, 0x7e, 0xf9, 0xdc, 0xbb, 0xac, 58 | 0x55, 0xa0, 0x62, 0x95, 0xce, 0x87, 0x0b, 0x07, 59 | 0x02, 0x9b, 0xfc, 0xdb, 0x2d, 0xce, 0x28, 0xd9, 60 | 0x59, 0xf2, 0x81, 0x5b, 0x16, 0xf8, 0x17, 0x98 61 | ]; 62 | 63 | /// The Y coordinate of the generator. 64 | #[rustfmt::skip] 65 | pub const GENERATOR_Y: [u8; 32] = [ 66 | 0x48, 0x3a, 0xda, 0x77, 0x26, 0xa3, 0xc4, 0x65, 67 | 0x5d, 0xa4, 0xfb, 0xfc, 0x0e, 0x11, 0x08, 0xa8, 68 | 0xfd, 0x17, 0xb4, 0x48, 0xa6, 0x85, 0x54, 0x19, 69 | 0x9c, 0x47, 0xd0, 0x8f, 0xfb, 0x10, 0xd4, 0xb8 70 | ]; 71 | 72 | /// The value zero as an array of bytes. 73 | pub const ZERO: [u8; 32] = [0; 32]; 74 | 75 | /// The value one as big-endian array of bytes. 76 | pub const ONE: [u8; 32] = [ 77 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 78 | ]; 79 | -------------------------------------------------------------------------------- /src/macros.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: CC0-1.0 2 | 3 | /// Implement methods and traits for types that contain an inner array. 4 | #[macro_export] 5 | macro_rules! impl_array_newtype { 6 | ($thing:ident, $ty:ty, $len:expr) => { 7 | impl AsRef<[$ty; $len]> for $thing { 8 | #[inline] 9 | /// Gets a reference to the underlying array 10 | fn as_ref(&self) -> &[$ty; $len] { 11 | let &$thing(ref dat) = self; 12 | dat 13 | } 14 | } 15 | 16 | impl core::ops::Index for $thing 17 | where 18 | [$ty]: core::ops::Index, 19 | { 20 | type Output = <[$ty] as core::ops::Index>::Output; 21 | 22 | #[inline] 23 | fn index(&self, index: I) -> &Self::Output { &self.0[index] } 24 | } 25 | 26 | impl $crate::ffi::CPtr for $thing { 27 | type Target = $ty; 28 | 29 | fn as_c_ptr(&self) -> *const Self::Target { 30 | let &$thing(ref dat) = self; 31 | dat.as_ptr() 32 | } 33 | 34 | fn as_mut_c_ptr(&mut self) -> *mut Self::Target { 35 | let &mut $thing(ref mut dat) = self; 36 | dat.as_mut_ptr() 37 | } 38 | } 39 | }; 40 | } 41 | 42 | macro_rules! impl_pretty_debug { 43 | ($thing:ident) => { 44 | impl core::fmt::Debug for $thing { 45 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 46 | write!(f, "{}(", stringify!($thing))?; 47 | for i in &self[..] { 48 | write!(f, "{:02x}", i)?; 49 | } 50 | f.write_str(")") 51 | } 52 | } 53 | }; 54 | } 55 | 56 | macro_rules! impl_non_secure_erase { 57 | ($thing:ident, $target:tt, $value:expr) => { 58 | impl $thing { 59 | /// Attempts to erase the contents of the underlying array. 60 | /// 61 | /// Note, however, that the compiler is allowed to freely copy or move the 62 | /// contents of this array to other places in memory. Preventing this behavior 63 | /// is very subtle. For more discussion on this, please see the documentation 64 | /// of the [`zeroize`](https://docs.rs/zeroize) crate. 65 | #[inline] 66 | pub fn non_secure_erase(&mut self) { 67 | secp256k1_sys::non_secure_erase_impl(&mut self.$target, $value); 68 | } 69 | } 70 | }; 71 | } 72 | 73 | /// Formats error. If `std` feature is OFF appends error source (delimited by `: `). We do this 74 | /// because `e.source()` is only available in std builds, without this macro the error source is 75 | /// lost for no-std builds. 76 | macro_rules! write_err { 77 | ($writer:expr, $string:literal $(, $args:expr),*; $source:expr) => { 78 | { 79 | #[cfg(feature = "std")] 80 | { 81 | let _ = &$source; // Prevents clippy warnings. 82 | write!($writer, $string $(, $args)*) 83 | } 84 | #[cfg(not(feature = "std"))] 85 | { 86 | write!($writer, concat!($string, ": {}") $(, $args)*, $source) 87 | } 88 | } 89 | } 90 | } 91 | 92 | /// Implements fast unstable comparison methods for `$ty`. 93 | macro_rules! impl_fast_comparisons { 94 | ($ty:ident) => { 95 | impl $ty { 96 | /// Like `cmp::Cmp` but faster and with no guarantees across library versions. 97 | /// 98 | /// The `Cmp` implementation for FFI types is stable but slow because it first 99 | /// serializes `self` and `other` before comparing them. This function provides a faster 100 | /// comparison if you know that your types come from the same library version. 101 | pub fn cmp_fast_unstable(&self, other: &Self) -> core::cmp::Ordering { 102 | self.0.cmp_fast_unstable(&other.0) 103 | } 104 | 105 | /// Like `cmp::Eq` but faster and with no guarantees across library versions. 106 | /// 107 | /// The `Eq` implementation for FFI types is stable but slow because it first serializes 108 | /// `self` and `other` before comparing them. This function provides a faster equality 109 | /// check if you know that your types come from the same library version. 110 | pub fn eq_fast_unstable(&self, other: &Self) -> bool { 111 | self.0.eq_fast_unstable(&other.0) 112 | } 113 | } 114 | }; 115 | } 116 | -------------------------------------------------------------------------------- /src/serde_util.rs: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: CC0-1.0 2 | 3 | use core::fmt; 4 | use core::marker::PhantomData; 5 | use core::str::{self, FromStr}; 6 | 7 | use serde::de; 8 | 9 | /// A serde visitor that works for `T`s implementing `FromStr`. 10 | pub struct FromStrVisitor { 11 | expectation: &'static str, 12 | _pd: PhantomData, 13 | } 14 | 15 | impl FromStrVisitor { 16 | pub fn new(expectation: &'static str) -> Self { 17 | FromStrVisitor { expectation, _pd: PhantomData } 18 | } 19 | } 20 | 21 | impl de::Visitor<'_> for FromStrVisitor 22 | where 23 | T: FromStr, 24 | ::Err: fmt::Display, 25 | { 26 | type Value = T; 27 | 28 | fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 29 | formatter.write_str(self.expectation) 30 | } 31 | 32 | fn visit_str(self, v: &str) -> Result { 33 | FromStr::from_str(v).map_err(E::custom) 34 | } 35 | } 36 | 37 | pub struct BytesVisitor { 38 | expectation: &'static str, 39 | parse_fn: F, 40 | } 41 | 42 | impl BytesVisitor 43 | where 44 | F: FnOnce(&[u8]) -> Result, 45 | Err: fmt::Display, 46 | { 47 | pub fn new(expectation: &'static str, parse_fn: F) -> Self { 48 | BytesVisitor { expectation, parse_fn } 49 | } 50 | } 51 | 52 | impl de::Visitor<'_> for BytesVisitor 53 | where 54 | F: FnOnce(&[u8]) -> Result, 55 | Err: fmt::Display, 56 | { 57 | type Value = T; 58 | 59 | fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 60 | formatter.write_str(self.expectation) 61 | } 62 | 63 | fn visit_bytes(self, v: &[u8]) -> Result { 64 | (self.parse_fn)(v).map_err(E::custom) 65 | } 66 | } 67 | 68 | macro_rules! impl_tuple_visitor { 69 | ($thing:ident, $len:expr) => { 70 | pub(crate) struct $thing { 71 | expectation: &'static str, 72 | parse_fn: F, 73 | } 74 | 75 | impl $thing 76 | where 77 | F: FnOnce([u8; $len]) -> Result, 78 | E: fmt::Display, 79 | { 80 | pub fn new(expectation: &'static str, parse_fn: F) -> Self { 81 | $thing { expectation, parse_fn } 82 | } 83 | } 84 | 85 | impl<'de, F, T, E> de::Visitor<'de> for $thing 86 | where 87 | F: FnOnce([u8; $len]) -> Result, 88 | E: fmt::Display, 89 | { 90 | type Value = T; 91 | 92 | fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 93 | formatter.write_str(self.expectation) 94 | } 95 | 96 | fn visit_seq(self, mut seq: V) -> Result 97 | where 98 | V: de::SeqAccess<'de>, 99 | { 100 | let mut bytes = [0u8; $len]; 101 | 102 | for (i, byte) in bytes.iter_mut().enumerate() { 103 | if let Some(value) = seq.next_element()? { 104 | *byte = value; 105 | } else { 106 | return Err(de::Error::invalid_length(i, &self)); 107 | } 108 | } 109 | (self.parse_fn)(bytes).map_err(de::Error::custom) 110 | } 111 | } 112 | }; 113 | } 114 | 115 | impl_tuple_visitor!(Tuple32Visitor, 32); 116 | impl_tuple_visitor!(Tuple33Visitor, 33); 117 | -------------------------------------------------------------------------------- /tests/serde.rs: -------------------------------------------------------------------------------- 1 | #![cfg(feature = "serde")] 2 | 3 | extern crate bincode; 4 | extern crate secp256k1; 5 | extern crate serde_cbor; 6 | 7 | #[cfg(feature = "global-context")] 8 | use secp256k1::{Keypair, Secp256k1}; 9 | use secp256k1::{PublicKey, SecretKey, XOnlyPublicKey}; 10 | 11 | // Arbitrary key data. 12 | 13 | #[rustfmt::skip] 14 | static SK_BYTES: [u8; 32] = [ 15 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 16 | 0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, 0x23, 17 | 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 0x31, 18 | 0x0f, 0x10, 0x1f, 0xa0, 0xa9, 0xaa, 0xaf, 0xff, 19 | ]; 20 | 21 | #[rustfmt::skip] 22 | static PK_BYTES: [u8; 33] = [ 23 | 0x02, 24 | 0x18, 0x84, 0x57, 0x81, 0xf6, 0x31, 0xc4, 0x8f, 25 | 0x1c, 0x97, 0x09, 0xe2, 0x30, 0x92, 0x06, 0x7d, 26 | 0x06, 0x83, 0x7f, 0x30, 0xaa, 0x0c, 0xd0, 0x54, 27 | 0x4a, 0xc8, 0x87, 0xfe, 0x91, 0xdd, 0xd1, 0x66, 28 | ]; 29 | 30 | #[rustfmt::skip] 31 | static XONLY_PK_BYTES: [u8; 32] = [ 32 | 0x18, 0x84, 0x57, 0x81, 0xf6, 0x31, 0xc4, 0x8f, 33 | 0x1c, 0x97, 0x09, 0xe2, 0x30, 0x92, 0x06, 0x7d, 34 | 0x06, 0x83, 0x7f, 0x30, 0xaa, 0x0c, 0xd0, 0x54, 35 | 0x4a, 0xc8, 0x87, 0xfe, 0x91, 0xdd, 0xd1, 0x66, 36 | ]; 37 | 38 | fn secret_key() -> SecretKey { 39 | SecretKey::from_slice(&SK_BYTES).expect("failed to create sk from slice") 40 | } 41 | 42 | // Our current serde serialization implementation is only guaranteed to be fixed 43 | // width for bincode. https://docs.rs/bincode/latest/bincode/index.html 44 | #[test] 45 | fn bincode_secret_key() { 46 | let sk = secret_key(); 47 | let ser = bincode::serialize(&sk).unwrap(); 48 | 49 | assert_eq!(ser, SK_BYTES); 50 | } 51 | 52 | #[test] 53 | fn bincode_public_key() { 54 | let pk = PublicKey::from_slice(&PK_BYTES).expect("failed to create pk from slice"); 55 | let ser = bincode::serialize(&pk).unwrap(); 56 | 57 | assert_eq!(ser, &PK_BYTES as &[u8]) 58 | } 59 | 60 | #[test] 61 | #[cfg(feature = "global-context")] 62 | fn bincode_keypair() { 63 | let secp = Secp256k1::new(); 64 | let kp = Keypair::from_seckey_byte_array(&secp, SK_BYTES).expect("failed to create keypair"); 65 | let ser = bincode::serialize(&kp).unwrap(); 66 | 67 | assert_eq!(ser, SK_BYTES); 68 | } 69 | 70 | #[test] 71 | fn bincode_x_only_public_key() { 72 | let pk = 73 | XOnlyPublicKey::from_slice(&XONLY_PK_BYTES).expect("failed to create xonly pk from slice"); 74 | let ser = bincode::serialize(&pk).unwrap(); 75 | 76 | assert_eq!(ser, XONLY_PK_BYTES); 77 | } 78 | 79 | #[test] 80 | fn cbor() { 81 | let sk = secret_key(); 82 | let e = serde_cbor::to_vec(&sk).unwrap(); 83 | // Secret key is 32 bytes. CBOR adds a byte of metadata for 20 of these bytes, 84 | // (Apparently, any byte whose value is <24 gets an extra byte.) 85 | // It also adds a 1-byte length prefix and a byte of metadata for the whole vector. 86 | assert_eq!(e.len(), 54); 87 | } 88 | --------------------------------------------------------------------------------