mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-10 03:47:29 -03:00
Squashed 'src/secp256k1/' changes from bdf39000b9..4258c54f4e
4258c54f4e Merge bitcoin-core/secp256k1#1276: autotools: Don't regenerate Wycheproof header automatically 06c67dea9f autotools: Don't regenerate Wycheproof header automatically 3bab71cf05 Merge bitcoin-core/secp256k1#1268: release cleanup: bump version after 0.3.1 656c6ea8d8 release cleanup: bump version after 0.3.1 346a053d4c Merge bitcoin-core/secp256k1#1269: changelog: Fix link 6a37b2a5ea changelog: Fix link ec98fcedd5 Merge bitcoin-core/secp256k1#1266: release: Prepare for 0.3.1 898e1c676e release: Prepare for 0.3.1 1d9a13fc26 changelog: Remove inconsistent newlines 0e091669a1 changelog: Catch up in preparation of 0.3.1 7b7503dac5 Merge bitcoin-core/secp256k1#1245: tests: Add Wycheproof ECDSA vectors 145078c418 Merge bitcoin-core/secp256k1#1118: Add x-only ecmult_const version with x specified as n/d e5de454609 tests: Add Wycheproof ECDSA vectors 0f8642079b Add exhaustive tests for ecmult_const_xonly 4485926ace Add x-only ecmult_const version for x=n/d a0f4644f7e Merge bitcoin-core/secp256k1#1252: Make position of * in pointer declarations in include/ consistent 4e682626a3 Merge bitcoin-core/secp256k1#1226: Add CMake instructions to release process 2d51a454fc Merge bitcoin-core/secp256k1#1257: ct: Use volatile "trick" in all fe/scalar cmov implementations 4a496a36fb ct: Use volatile "trick" in all fe/scalar cmov implementations 3d1f430f9f Make position of * in pointer declarations in include/ consistent 2bca0a5cbf Merge bitcoin-core/secp256k1#1241: build: Improve `SECP_TRY_APPEND_DEFAULT_CFLAGS` macro afd8b23b27 Merge bitcoin-core/secp256k1#1244: Suppress `-Wunused-parameter` when building for coverage analysis 1d8f367515 Merge bitcoin-core/secp256k1#1250: No need to subtract 1 before doing a right shift 3e43041be6 No need to subtract 1 before doing a right shift 3addb4c1e8 build: Improve `SECP_TRY_APPEND_DEFAULT_CFLAGS` macro 0c07c82834 Add CMake instructions to release process 464a9115b4 Merge bitcoin-core/secp256k1#1242: Set ARM ASM symbol visibility to `hidden` f16a709fd6 Merge bitcoin-core/secp256k1#1247: Apply Checks only in VERIFY mode. 70be3cade5 Merge bitcoin-core/secp256k1#1246: Typo 4ebd82852d Apply Checks only in VERIFY mode. d1e7ca192d Typo 5bb03c2911 Replace `SECP256K1_ECMULT_TABLE_VERIFY` macro by a function 9c8c4f443c Merge bitcoin-core/secp256k1#1238: build: bump CMake minimum requirement to 3.13 0cf2fb91ef Merge bitcoin-core/secp256k1#1243: build: Ensure no optimization when building for coverage analysis fd2a408647 Set ARM ASM symbol visibility to `hidden` 4429a8c218 Suppress `-Wunused-parameter` when building for coverage analysis 8e79c7ed11 build: Ensure no optimization when building for coverage analysis 96dd062511 build: bump CMake minimum requirement to 3.13 427bc3cdcf Merge bitcoin-core/secp256k1#1236: Update comment for secp256k1_modinv32_inv256 647f0a5cb1 Update comment for secp256k1_modinv32_inv256 5658209459 Merge bitcoin-core/secp256k1#1228: release cleanup: bump version after 0.3.0 28e63f7ea7 release cleanup: bump version after 0.3.0 git-subtree-dir: src/secp256k1 git-subtree-split: 4258c54f4ebfc09390168e8a43306c46b315134b
This commit is contained in:
parent
763079a3f1
commit
c981671e9b
29 changed files with 8742 additions and 131 deletions
20
CHANGELOG.md
20
CHANGELOG.md
|
@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [0.3.1] - 2023-04-10
|
||||||
|
We strongly recommend updating to 0.3.1 if you use or plan to use Clang >=14 to compile libsecp256k1, e.g., Xcode >=14 on macOS has Clang >=14. When in doubt, check the Clang version using `clang -v`.
|
||||||
|
|
||||||
|
#### Security
|
||||||
|
- Fix "constant-timeness" issue with Clang >=14 that could leave applications using libsecp256k1 vulnerable to a timing side-channel attack. The fix avoids secret-dependent control flow and secret-dependent memory accesses in conditional moves of memory objects when libsecp256k1 is compiled with Clang >=14.
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
- Added tests against [Project Wycheproof's](https://github.com/google/wycheproof/) set of ECDSA test vectors (Bitcoin "low-S" variant), a fixed set of test cases designed to trigger various edge cases.
|
||||||
|
|
||||||
|
#### Changed
|
||||||
|
- Increased minimum required CMake version to 3.13. CMake builds remain experimental.
|
||||||
|
|
||||||
|
#### ABI Compatibility
|
||||||
|
The ABI is compatible with version 0.3.0.
|
||||||
|
|
||||||
## [0.3.0] - 2023-03-08
|
## [0.3.0] - 2023-03-08
|
||||||
|
|
||||||
#### Added
|
#### Added
|
||||||
|
@ -25,7 +40,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
- Removed the configuration header `src/libsecp256k1-config.h`. We recommend passing flags to `./configure` or `cmake` to set configuration options (see `./configure --help` or `cmake -LH`). If you cannot or do not want to use one of the supported build systems, pass configuration flags such as `-DSECP256K1_ENABLE_MODULE_SCHNORRSIG` manually to the compiler (see the file `configure.ac` for supported flags).
|
- Removed the configuration header `src/libsecp256k1-config.h`. We recommend passing flags to `./configure` or `cmake` to set configuration options (see `./configure --help` or `cmake -LH`). If you cannot or do not want to use one of the supported build systems, pass configuration flags such as `-DSECP256K1_ENABLE_MODULE_SCHNORRSIG` manually to the compiler (see the file `configure.ac` for supported flags).
|
||||||
|
|
||||||
#### ABI Compatibility
|
#### ABI Compatibility
|
||||||
|
|
||||||
Due to changes in the API regarding `secp256k1_context_static` described above, the ABI is *not* compatible with previous versions.
|
Due to changes in the API regarding `secp256k1_context_static` described above, the ABI is *not* compatible with previous versions.
|
||||||
|
|
||||||
## [0.2.0] - 2022-12-12
|
## [0.2.0] - 2022-12-12
|
||||||
|
@ -45,7 +59,6 @@ Due to changes in the API regarding `secp256k1_context_static` described above,
|
||||||
- Module `schnorrsig`: renamed `secp256k1_schnorrsig_sign` to `secp256k1_schnorrsig_sign32`.
|
- Module `schnorrsig`: renamed `secp256k1_schnorrsig_sign` to `secp256k1_schnorrsig_sign32`.
|
||||||
|
|
||||||
#### ABI Compatibility
|
#### ABI Compatibility
|
||||||
|
|
||||||
Since this is the first release, we do not compare application binary interfaces.
|
Since this is the first release, we do not compare application binary interfaces.
|
||||||
However, there are earlier unreleased versions of libsecp256k1 that are *not* ABI compatible with this version.
|
However, there are earlier unreleased versions of libsecp256k1 that are *not* ABI compatible with this version.
|
||||||
|
|
||||||
|
@ -55,7 +68,8 @@ This version was in fact never released.
|
||||||
The number was given by the build system since the introduction of autotools in Jan 2014 (ea0fe5a5bf0c04f9cc955b2966b614f5f378c6f6).
|
The number was given by the build system since the introduction of autotools in Jan 2014 (ea0fe5a5bf0c04f9cc955b2966b614f5f378c6f6).
|
||||||
Therefore, this version number does not uniquely identify a set of source files.
|
Therefore, this version number does not uniquely identify a set of source files.
|
||||||
|
|
||||||
[unreleased]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.0...HEAD
|
[unreleased]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.1...HEAD
|
||||||
|
[0.3.1]: https://github.com/bitcoin-core/secp256k1/compare/v0.3.0...v0.3.1
|
||||||
[0.3.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.2.0...v0.3.0
|
[0.3.0]: https://github.com/bitcoin-core/secp256k1/compare/v0.2.0...v0.3.0
|
||||||
[0.2.0]: https://github.com/bitcoin-core/secp256k1/compare/423b6d19d373f1224fd671a982584d7e7900bc93..v0.2.0
|
[0.2.0]: https://github.com/bitcoin-core/secp256k1/compare/423b6d19d373f1224fd671a982584d7e7900bc93..v0.2.0
|
||||||
[0.1.0]: https://github.com/bitcoin-core/secp256k1/commit/423b6d19d373f1224fd671a982584d7e7900bc93
|
[0.1.0]: https://github.com/bitcoin-core/secp256k1/commit/423b6d19d373f1224fd671a982584d7e7900bc93
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
cmake_minimum_required(VERSION 3.1)
|
cmake_minimum_required(VERSION 3.13)
|
||||||
|
|
||||||
if(CMAKE_VERSION VERSION_GREATER 3.14)
|
if(CMAKE_VERSION VERSION_GREATER 3.14)
|
||||||
# MSVC runtime library flags are selected by the CMAKE_MSVC_RUNTIME_LIBRARY abstraction.
|
# MSVC runtime library flags are selected by the CMAKE_MSVC_RUNTIME_LIBRARY abstraction.
|
||||||
|
@ -10,7 +10,7 @@ endif()
|
||||||
# The package (a.k.a. release) version is based on semantic versioning 2.0.0 of
|
# The package (a.k.a. release) version is based on semantic versioning 2.0.0 of
|
||||||
# the API. All changes in experimental modules are treated as
|
# the API. All changes in experimental modules are treated as
|
||||||
# backwards-compatible and therefore at most increase the minor version.
|
# backwards-compatible and therefore at most increase the minor version.
|
||||||
project(libsecp256k1 VERSION 0.3.0 LANGUAGES C)
|
project(libsecp256k1 VERSION 0.3.2 LANGUAGES C)
|
||||||
|
|
||||||
# The library version is based on libtool versioning of the ABI. The set of
|
# The library version is based on libtool versioning of the ABI. The set of
|
||||||
# rules for updating the version can be found here:
|
# rules for updating the version can be found here:
|
||||||
|
@ -18,7 +18,7 @@ project(libsecp256k1 VERSION 0.3.0 LANGUAGES C)
|
||||||
# All changes in experimental modules are treated as if they don't affect the
|
# All changes in experimental modules are treated as if they don't affect the
|
||||||
# interface and therefore only increase the revision.
|
# interface and therefore only increase the revision.
|
||||||
set(${PROJECT_NAME}_LIB_VERSION_CURRENT 2)
|
set(${PROJECT_NAME}_LIB_VERSION_CURRENT 2)
|
||||||
set(${PROJECT_NAME}_LIB_VERSION_REVISION 0)
|
set(${PROJECT_NAME}_LIB_VERSION_REVISION 2)
|
||||||
set(${PROJECT_NAME}_LIB_VERSION_AGE 0)
|
set(${PROJECT_NAME}_LIB_VERSION_AGE 0)
|
||||||
|
|
||||||
set(CMAKE_C_STANDARD 90)
|
set(CMAKE_C_STANDARD 90)
|
||||||
|
@ -147,7 +147,7 @@ else()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Define custom "Coverage" build type.
|
# Define custom "Coverage" build type.
|
||||||
set(CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O0 -DCOVERAGE=1 --coverage -Wno-unused-parameter" CACHE STRING
|
set(CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O0 -DCOVERAGE=1 --coverage" CACHE STRING
|
||||||
"Flags used by the C compiler during \"Coverage\" builds."
|
"Flags used by the C compiler during \"Coverage\" builds."
|
||||||
FORCE
|
FORCE
|
||||||
)
|
)
|
||||||
|
@ -203,11 +203,6 @@ else()
|
||||||
try_add_compile_option(-Wundef)
|
try_add_compile_option(-Wundef)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CMAKE_VERSION VERSION_GREATER 3.2)
|
|
||||||
# Honor visibility properties for all target types.
|
|
||||||
# See: https://cmake.org/cmake/help/latest/policy/CMP0063.html
|
|
||||||
cmake_policy(SET CMP0063 NEW)
|
|
||||||
endif()
|
|
||||||
set(CMAKE_C_VISIBILITY_PRESET hidden)
|
set(CMAKE_C_VISIBILITY_PRESET hidden)
|
||||||
|
|
||||||
# Ask CTest to create a "check" target (e.g., make check) as alias for the "test" target.
|
# Ask CTest to create a "check" target (e.g., make check) as alias for the "test" target.
|
||||||
|
|
17
Makefile.am
17
Makefile.am
|
@ -247,3 +247,20 @@ endif
|
||||||
if ENABLE_MODULE_SCHNORRSIG
|
if ENABLE_MODULE_SCHNORRSIG
|
||||||
include src/modules/schnorrsig/Makefile.am.include
|
include src/modules/schnorrsig/Makefile.am.include
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
EXTRA_DIST += src/wycheproof/WYCHEPROOF_COPYING
|
||||||
|
EXTRA_DIST += src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h
|
||||||
|
EXTRA_DIST += src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.json
|
||||||
|
EXTRA_DIST += tools/tests_wycheproof_generate.py
|
||||||
|
|
||||||
|
TESTVECTORS = src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h
|
||||||
|
|
||||||
|
src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h:
|
||||||
|
python3 tools/tests_wycheproof_generate.py src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.json > $@
|
||||||
|
|
||||||
|
testvectors: $(TESTVECTORS)
|
||||||
|
|
||||||
|
maintainer-clean-testvectors: clean-testvectors
|
||||||
|
|
||||||
|
clean-testvectors:
|
||||||
|
rm -f $(TESTVECTORS)
|
||||||
|
|
|
@ -109,8 +109,8 @@ fi
|
||||||
# Rebuild precomputed files (if not cross-compiling).
|
# Rebuild precomputed files (if not cross-compiling).
|
||||||
if [ -z "$HOST" ]
|
if [ -z "$HOST" ]
|
||||||
then
|
then
|
||||||
make clean-precomp
|
make clean-precomp clean-testvectors
|
||||||
make precomp
|
make precomp testvectors
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check that no repo files have been modified by the build.
|
# Check that no repo files have been modified by the build.
|
||||||
|
|
28
configure.ac
28
configure.ac
|
@ -5,8 +5,8 @@ AC_PREREQ([2.60])
|
||||||
# backwards-compatible and therefore at most increase the minor version.
|
# backwards-compatible and therefore at most increase the minor version.
|
||||||
define(_PKG_VERSION_MAJOR, 0)
|
define(_PKG_VERSION_MAJOR, 0)
|
||||||
define(_PKG_VERSION_MINOR, 3)
|
define(_PKG_VERSION_MINOR, 3)
|
||||||
define(_PKG_VERSION_PATCH, 0)
|
define(_PKG_VERSION_PATCH, 2)
|
||||||
define(_PKG_VERSION_IS_RELEASE, true)
|
define(_PKG_VERSION_IS_RELEASE, false)
|
||||||
|
|
||||||
# The library version is based on libtool versioning of the ABI. The set of
|
# The library version is based on libtool versioning of the ABI. The set of
|
||||||
# rules for updating the version can be found here:
|
# rules for updating the version can be found here:
|
||||||
|
@ -14,7 +14,7 @@ define(_PKG_VERSION_IS_RELEASE, true)
|
||||||
# All changes in experimental modules are treated as if they don't affect the
|
# All changes in experimental modules are treated as if they don't affect the
|
||||||
# interface and therefore only increase the revision.
|
# interface and therefore only increase the revision.
|
||||||
define(_LIB_VERSION_CURRENT, 2)
|
define(_LIB_VERSION_CURRENT, 2)
|
||||||
define(_LIB_VERSION_REVISION, 0)
|
define(_LIB_VERSION_REVISION, 2)
|
||||||
define(_LIB_VERSION_AGE, 0)
|
define(_LIB_VERSION_AGE, 0)
|
||||||
|
|
||||||
AC_INIT([libsecp256k1],m4_join([.], _PKG_VERSION_MAJOR, _PKG_VERSION_MINOR, _PKG_VERSION_PATCH)m4_if(_PKG_VERSION_IS_RELEASE, [true], [], [-dev]),[https://github.com/bitcoin-core/secp256k1/issues],[libsecp256k1],[https://github.com/bitcoin-core/secp256k1])
|
AC_INIT([libsecp256k1],m4_join([.], _PKG_VERSION_MAJOR, _PKG_VERSION_MINOR, _PKG_VERSION_PATCH)m4_if(_PKG_VERSION_IS_RELEASE, [true], [], [-dev]),[https://github.com/bitcoin-core/secp256k1/issues],[libsecp256k1],[https://github.com/bitcoin-core/secp256k1])
|
||||||
|
@ -29,6 +29,11 @@ AM_INIT_AUTOMAKE([1.11.2 foreign subdir-objects])
|
||||||
# Make the compilation flags quiet unless V=1 is used.
|
# Make the compilation flags quiet unless V=1 is used.
|
||||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||||
|
|
||||||
|
if test "${CFLAGS+set}" = "set"; then
|
||||||
|
CFLAGS_overridden=yes
|
||||||
|
else
|
||||||
|
CFLAGS_overridden=no
|
||||||
|
fi
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
AM_PROG_AS
|
AM_PROG_AS
|
||||||
AM_PROG_AR
|
AM_PROG_AR
|
||||||
|
@ -88,11 +93,14 @@ esac
|
||||||
AC_DEFUN([SECP_TRY_APPEND_DEFAULT_CFLAGS], [
|
AC_DEFUN([SECP_TRY_APPEND_DEFAULT_CFLAGS], [
|
||||||
# GCC and compatible (incl. clang)
|
# GCC and compatible (incl. clang)
|
||||||
if test "x$GCC" = "xyes"; then
|
if test "x$GCC" = "xyes"; then
|
||||||
# Try to append -Werror=unknown-warning-option to CFLAGS temporarily. Otherwise clang will
|
# Try to append -Werror to CFLAGS temporarily. Otherwise checks for some unsupported
|
||||||
# not error out if it gets unknown warning flags and the checks here will always succeed
|
# flags will succeed.
|
||||||
# no matter if clang knows the flag or not.
|
# Note that failure to append -Werror does not necessarily mean that -Werror is not
|
||||||
|
# supported. The compiler may already be warning about something unrelated, for example
|
||||||
|
# about some path issue. If that is the case, -Werror cannot be used because all
|
||||||
|
# of those warnings would be turned into errors.
|
||||||
SECP_TRY_APPEND_DEFAULT_CFLAGS_saved_CFLAGS="$CFLAGS"
|
SECP_TRY_APPEND_DEFAULT_CFLAGS_saved_CFLAGS="$CFLAGS"
|
||||||
SECP_TRY_APPEND_CFLAGS([-Werror=unknown-warning-option], CFLAGS)
|
SECP_TRY_APPEND_CFLAGS([-Werror], CFLAGS)
|
||||||
|
|
||||||
SECP_TRY_APPEND_CFLAGS([-std=c89 -pedantic -Wno-long-long -Wnested-externs -Wshadow -Wstrict-prototypes -Wundef], $1) # GCC >= 3.0, -Wlong-long is implied by -pedantic.
|
SECP_TRY_APPEND_CFLAGS([-std=c89 -pedantic -Wno-long-long -Wnested-externs -Wshadow -Wstrict-prototypes -Wundef], $1) # GCC >= 3.0, -Wlong-long is implied by -pedantic.
|
||||||
SECP_TRY_APPEND_CFLAGS([-Wno-overlength-strings], $1) # GCC >= 4.2, -Woverlength-strings is implied by -pedantic.
|
SECP_TRY_APPEND_CFLAGS([-Wno-overlength-strings], $1) # GCC >= 4.2, -Woverlength-strings is implied by -pedantic.
|
||||||
|
@ -241,6 +249,12 @@ fi
|
||||||
if test x"$enable_coverage" = x"yes"; then
|
if test x"$enable_coverage" = x"yes"; then
|
||||||
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DCOVERAGE=1"
|
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DCOVERAGE=1"
|
||||||
SECP_CFLAGS="-O0 --coverage $SECP_CFLAGS"
|
SECP_CFLAGS="-O0 --coverage $SECP_CFLAGS"
|
||||||
|
# If coverage is enabled, and the user has not overridden CFLAGS,
|
||||||
|
# override Autoconf's value "-g -O2" with "-g". Otherwise we'd end up
|
||||||
|
# with "-O0 --coverage -g -O2".
|
||||||
|
if test "$CFLAGS_overridden" = "no"; then
|
||||||
|
CFLAGS="-g"
|
||||||
|
fi
|
||||||
LDFLAGS="--coverage $LDFLAGS"
|
LDFLAGS="--coverage $LDFLAGS"
|
||||||
else
|
else
|
||||||
# Most likely the CFLAGS already contain -O2 because that is autoconf's default.
|
# Most likely the CFLAGS already contain -O2 because that is autoconf's default.
|
||||||
|
|
|
@ -15,15 +15,20 @@ This process also assumes that there will be no minor releases for old major rel
|
||||||
## Regular release
|
## Regular release
|
||||||
|
|
||||||
1. Open a PR to the master branch with a commit (using message `"release: prepare for $MAJOR.$MINOR.$PATCH"`, for example) that
|
1. Open a PR to the master branch with a commit (using message `"release: prepare for $MAJOR.$MINOR.$PATCH"`, for example) that
|
||||||
* finalizes the release notes in [CHANGELOG.md](../CHANGELOG.md) (make sure to include an entry for `### ABI Compatibility`) and
|
* finalizes the release notes in [CHANGELOG.md](../CHANGELOG.md) (make sure to include an entry for `### ABI Compatibility`),
|
||||||
* updates `_PKG_VERSION_*`, `_LIB_VERSION_*`, and sets `_PKG_VERSION_IS_RELEASE` to `true` in `configure.ac`.
|
* updates `_PKG_VERSION_*` and `_LIB_VERSION_*` and sets `_PKG_VERSION_IS_RELEASE` to `true` in `configure.ac`, and
|
||||||
|
* updates `project(libsecp256k1 VERSION ...)` and `${PROJECT_NAME}_LIB_VERSION_*` in `CMakeLists.txt`.
|
||||||
2. After the PR is merged, tag the commit and push it:
|
2. After the PR is merged, tag the commit and push it:
|
||||||
```
|
```
|
||||||
RELEASE_COMMIT=<merge commit of step 1>
|
RELEASE_COMMIT=<merge commit of step 1>
|
||||||
git tag -s v$MAJOR.$MINOR.$PATCH -m "libsecp256k1 $MAJOR.$MINOR.$PATCH" $RELEASE_COMMIT
|
git tag -s v$MAJOR.$MINOR.$PATCH -m "libsecp256k1 $MAJOR.$MINOR.$PATCH" $RELEASE_COMMIT
|
||||||
git push git@github.com:bitcoin-core/secp256k1.git v$MAJOR.$MINOR.$PATCH
|
git push git@github.com:bitcoin-core/secp256k1.git v$MAJOR.$MINOR.$PATCH
|
||||||
```
|
```
|
||||||
3. Open a PR to the master branch with a commit (using message `"release cleanup: bump version after $MAJOR.$MINOR.$PATCH"`, for example) that sets `_PKG_VERSION_IS_RELEASE` to `false` and `_PKG_VERSION_PATCH` to `$PATCH + 1` and increases `_LIB_VERSION_REVISION`. If other maintainers are not present to approve the PR, it can be merged without ACKs.
|
3. Open a PR to the master branch with a commit (using message `"release cleanup: bump version after $MAJOR.$MINOR.$PATCH"`, for example) that
|
||||||
|
* sets `_PKG_VERSION_IS_RELEASE` to `false` and increments `_PKG_VERSION_PATCH` and `_LIB_VERSION_REVISION` in `configure.ac`, and
|
||||||
|
* increments the `$PATCH` component of `project(libsecp256k1 VERSION ...)` and `${PROJECT_NAME}_LIB_VERSION_REVISION` in `CMakeLists.txt`.
|
||||||
|
|
||||||
|
If other maintainers are not present to approve the PR, it can be merged without ACKs.
|
||||||
4. Create a new GitHub release with a link to the corresponding entry in [CHANGELOG.md](../CHANGELOG.md).
|
4. Create a new GitHub release with a link to the corresponding entry in [CHANGELOG.md](../CHANGELOG.md).
|
||||||
|
|
||||||
## Maintenance release
|
## Maintenance release
|
||||||
|
@ -38,7 +43,9 @@ Note that bugfixes only need to be backported to releases for which no compatibl
|
||||||
2. Open a pull request to the `$MAJOR.$MINOR` branch that
|
2. Open a pull request to the `$MAJOR.$MINOR` branch that
|
||||||
* includes the bugfixes,
|
* includes the bugfixes,
|
||||||
* finalizes the release notes,
|
* finalizes the release notes,
|
||||||
* bumps `_PKG_VERSION_PATCH` and `_LIB_VERSION_REVISION` in `configure.ac` (with commit message `"release: update PKG_ and LIB_VERSION for $MAJOR.$MINOR.$PATCH"`, for example).
|
* increments `_PKG_VERSION_PATCH` and `_LIB_VERSION_REVISION` in `configure.ac`
|
||||||
|
and the `$PATCH` component of `project(libsecp256k1 VERSION ...)` and `${PROJECT_NAME}_LIB_VERSION_REVISION` in `CMakeLists.txt`
|
||||||
|
(with commit message `"release: bump versions for $MAJOR.$MINOR.$PATCH"`, for example).
|
||||||
3. After the PRs are merged, update the release branch and tag the commit:
|
3. After the PRs are merged, update the release branch and tag the commit:
|
||||||
```
|
```
|
||||||
git checkout $MAJOR.$MINOR && git pull
|
git checkout $MAJOR.$MINOR && git pull
|
||||||
|
|
|
@ -288,7 +288,7 @@ SECP256K1_API void secp256k1_selftest(void);
|
||||||
* Do not create a new context object for each operation, as construction and
|
* Do not create a new context object for each operation, as construction and
|
||||||
* randomization can take non-negligible time.
|
* randomization can take non-negligible time.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API secp256k1_context* secp256k1_context_create(
|
SECP256K1_API secp256k1_context *secp256k1_context_create(
|
||||||
unsigned int flags
|
unsigned int flags
|
||||||
) SECP256K1_WARN_UNUSED_RESULT;
|
) SECP256K1_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
@ -304,8 +304,8 @@ SECP256K1_API secp256k1_context* secp256k1_context_create(
|
||||||
* Returns: a newly created context object.
|
* Returns: a newly created context object.
|
||||||
* Args: ctx: an existing context to copy (not secp256k1_context_static)
|
* Args: ctx: an existing context to copy (not secp256k1_context_static)
|
||||||
*/
|
*/
|
||||||
SECP256K1_API secp256k1_context* secp256k1_context_clone(
|
SECP256K1_API secp256k1_context *secp256k1_context_clone(
|
||||||
const secp256k1_context* ctx
|
const secp256k1_context *ctx
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT;
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
/** Destroy a secp256k1 context object (created in dynamically allocated memory).
|
/** Destroy a secp256k1 context object (created in dynamically allocated memory).
|
||||||
|
@ -323,7 +323,7 @@ SECP256K1_API secp256k1_context* secp256k1_context_clone(
|
||||||
* (i.e., not secp256k1_context_static).
|
* (i.e., not secp256k1_context_static).
|
||||||
*/
|
*/
|
||||||
SECP256K1_API void secp256k1_context_destroy(
|
SECP256K1_API void secp256k1_context_destroy(
|
||||||
secp256k1_context* ctx
|
secp256k1_context *ctx
|
||||||
) SECP256K1_ARG_NONNULL(1);
|
) SECP256K1_ARG_NONNULL(1);
|
||||||
|
|
||||||
/** Set a callback function to be called when an illegal argument is passed to
|
/** Set a callback function to be called when an illegal argument is passed to
|
||||||
|
@ -347,8 +347,8 @@ SECP256K1_API void secp256k1_context_destroy(
|
||||||
* USE_EXTERNAL_DEFAULT_CALLBACKS is defined, which is the case if the build
|
* USE_EXTERNAL_DEFAULT_CALLBACKS is defined, which is the case if the build
|
||||||
* has been configured with --enable-external-default-callbacks. Then the
|
* has been configured with --enable-external-default-callbacks. Then the
|
||||||
* following two symbols must be provided to link against:
|
* following two symbols must be provided to link against:
|
||||||
* - void secp256k1_default_illegal_callback_fn(const char* message, void* data);
|
* - void secp256k1_default_illegal_callback_fn(const char *message, void *data);
|
||||||
* - void secp256k1_default_error_callback_fn(const char* message, void* data);
|
* - void secp256k1_default_error_callback_fn(const char *message, void *data);
|
||||||
* The library can call these default handlers even before a proper callback data
|
* The library can call these default handlers even before a proper callback data
|
||||||
* pointer could have been set using secp256k1_context_set_illegal_callback or
|
* pointer could have been set using secp256k1_context_set_illegal_callback or
|
||||||
* secp256k1_context_set_error_callback, e.g., when the creation of a context
|
* secp256k1_context_set_error_callback, e.g., when the creation of a context
|
||||||
|
@ -364,9 +364,9 @@ SECP256K1_API void secp256k1_context_destroy(
|
||||||
* See also secp256k1_context_set_error_callback.
|
* See also secp256k1_context_set_error_callback.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API void secp256k1_context_set_illegal_callback(
|
SECP256K1_API void secp256k1_context_set_illegal_callback(
|
||||||
secp256k1_context* ctx,
|
secp256k1_context *ctx,
|
||||||
void (*fun)(const char* message, void* data),
|
void (*fun)(const char *message, void *data),
|
||||||
const void* data
|
const void *data
|
||||||
) SECP256K1_ARG_NONNULL(1);
|
) SECP256K1_ARG_NONNULL(1);
|
||||||
|
|
||||||
/** Set a callback function to be called when an internal consistency check
|
/** Set a callback function to be called when an internal consistency check
|
||||||
|
@ -392,9 +392,9 @@ SECP256K1_API void secp256k1_context_set_illegal_callback(
|
||||||
* See also secp256k1_context_set_illegal_callback.
|
* See also secp256k1_context_set_illegal_callback.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API void secp256k1_context_set_error_callback(
|
SECP256K1_API void secp256k1_context_set_error_callback(
|
||||||
secp256k1_context* ctx,
|
secp256k1_context *ctx,
|
||||||
void (*fun)(const char* message, void* data),
|
void (*fun)(const char *message, void *data),
|
||||||
const void* data
|
const void *data
|
||||||
) SECP256K1_ARG_NONNULL(1);
|
) SECP256K1_ARG_NONNULL(1);
|
||||||
|
|
||||||
/** Create a secp256k1 scratch space object.
|
/** Create a secp256k1 scratch space object.
|
||||||
|
@ -404,8 +404,8 @@ SECP256K1_API void secp256k1_context_set_error_callback(
|
||||||
* In: size: amount of memory to be available as scratch space. Some extra
|
* In: size: amount of memory to be available as scratch space. Some extra
|
||||||
* (<100 bytes) will be allocated for extra accounting.
|
* (<100 bytes) will be allocated for extra accounting.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT secp256k1_scratch_space* secp256k1_scratch_space_create(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT secp256k1_scratch_space *secp256k1_scratch_space_create(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
size_t size
|
size_t size
|
||||||
) SECP256K1_ARG_NONNULL(1);
|
) SECP256K1_ARG_NONNULL(1);
|
||||||
|
|
||||||
|
@ -416,8 +416,8 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT secp256k1_scratch_space* secp256k1_sc
|
||||||
* scratch: space to destroy
|
* scratch: space to destroy
|
||||||
*/
|
*/
|
||||||
SECP256K1_API void secp256k1_scratch_space_destroy(
|
SECP256K1_API void secp256k1_scratch_space_destroy(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
secp256k1_scratch_space* scratch
|
secp256k1_scratch_space *scratch
|
||||||
) SECP256K1_ARG_NONNULL(1);
|
) SECP256K1_ARG_NONNULL(1);
|
||||||
|
|
||||||
/** Parse a variable-length public key into the pubkey object.
|
/** Parse a variable-length public key into the pubkey object.
|
||||||
|
@ -435,8 +435,8 @@ SECP256K1_API void secp256k1_scratch_space_destroy(
|
||||||
* byte 0x06 or 0x07) format public keys.
|
* byte 0x06 or 0x07) format public keys.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
secp256k1_pubkey* pubkey,
|
secp256k1_pubkey *pubkey,
|
||||||
const unsigned char *input,
|
const unsigned char *input,
|
||||||
size_t inputlen
|
size_t inputlen
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||||
|
@ -457,10 +457,10 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse(
|
||||||
* compressed format, otherwise SECP256K1_EC_UNCOMPRESSED.
|
* compressed format, otherwise SECP256K1_EC_UNCOMPRESSED.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API int secp256k1_ec_pubkey_serialize(
|
SECP256K1_API int secp256k1_ec_pubkey_serialize(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
unsigned char *output,
|
unsigned char *output,
|
||||||
size_t *outputlen,
|
size_t *outputlen,
|
||||||
const secp256k1_pubkey* pubkey,
|
const secp256k1_pubkey *pubkey,
|
||||||
unsigned int flags
|
unsigned int flags
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||||
|
|
||||||
|
@ -474,9 +474,9 @@ SECP256K1_API int secp256k1_ec_pubkey_serialize(
|
||||||
* pubkey2: second public key to compare
|
* pubkey2: second public key to compare
|
||||||
*/
|
*/
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_cmp(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_cmp(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
const secp256k1_pubkey* pubkey1,
|
const secp256k1_pubkey *pubkey1,
|
||||||
const secp256k1_pubkey* pubkey2
|
const secp256k1_pubkey *pubkey2
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||||
|
|
||||||
/** Parse an ECDSA signature in compact (64 bytes) format.
|
/** Parse an ECDSA signature in compact (64 bytes) format.
|
||||||
|
@ -495,8 +495,8 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_cmp(
|
||||||
* any message and public key.
|
* any message and public key.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API int secp256k1_ecdsa_signature_parse_compact(
|
SECP256K1_API int secp256k1_ecdsa_signature_parse_compact(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
secp256k1_ecdsa_signature* sig,
|
secp256k1_ecdsa_signature *sig,
|
||||||
const unsigned char *input64
|
const unsigned char *input64
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||||
|
|
||||||
|
@ -516,8 +516,8 @@ SECP256K1_API int secp256k1_ecdsa_signature_parse_compact(
|
||||||
* guaranteed to fail for every message and public key.
|
* guaranteed to fail for every message and public key.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API int secp256k1_ecdsa_signature_parse_der(
|
SECP256K1_API int secp256k1_ecdsa_signature_parse_der(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
secp256k1_ecdsa_signature* sig,
|
secp256k1_ecdsa_signature *sig,
|
||||||
const unsigned char *input,
|
const unsigned char *input,
|
||||||
size_t inputlen
|
size_t inputlen
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||||
|
@ -534,10 +534,10 @@ SECP256K1_API int secp256k1_ecdsa_signature_parse_der(
|
||||||
* In: sig: a pointer to an initialized signature object
|
* In: sig: a pointer to an initialized signature object
|
||||||
*/
|
*/
|
||||||
SECP256K1_API int secp256k1_ecdsa_signature_serialize_der(
|
SECP256K1_API int secp256k1_ecdsa_signature_serialize_der(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
unsigned char *output,
|
unsigned char *output,
|
||||||
size_t *outputlen,
|
size_t *outputlen,
|
||||||
const secp256k1_ecdsa_signature* sig
|
const secp256k1_ecdsa_signature *sig
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||||
|
|
||||||
/** Serialize an ECDSA signature in compact (64 byte) format.
|
/** Serialize an ECDSA signature in compact (64 byte) format.
|
||||||
|
@ -550,9 +550,9 @@ SECP256K1_API int secp256k1_ecdsa_signature_serialize_der(
|
||||||
* See secp256k1_ecdsa_signature_parse_compact for details about the encoding.
|
* See secp256k1_ecdsa_signature_parse_compact for details about the encoding.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API int secp256k1_ecdsa_signature_serialize_compact(
|
SECP256K1_API int secp256k1_ecdsa_signature_serialize_compact(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
unsigned char *output64,
|
unsigned char *output64,
|
||||||
const secp256k1_ecdsa_signature* sig
|
const secp256k1_ecdsa_signature *sig
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||||
|
|
||||||
/** Verify an ECDSA signature.
|
/** Verify an ECDSA signature.
|
||||||
|
@ -581,7 +581,7 @@ SECP256K1_API int secp256k1_ecdsa_signature_serialize_compact(
|
||||||
* For details, see the comments for that function.
|
* For details, see the comments for that function.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
const secp256k1_ecdsa_signature *sig,
|
const secp256k1_ecdsa_signature *sig,
|
||||||
const unsigned char *msghash32,
|
const unsigned char *msghash32,
|
||||||
const secp256k1_pubkey *pubkey
|
const secp256k1_pubkey *pubkey
|
||||||
|
@ -629,7 +629,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify(
|
||||||
* secp256k1_ecdsa_signature_normalize must be called before verification.
|
* secp256k1_ecdsa_signature_normalize must be called before verification.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API int secp256k1_ecdsa_signature_normalize(
|
SECP256K1_API int secp256k1_ecdsa_signature_normalize(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
secp256k1_ecdsa_signature *sigout,
|
secp256k1_ecdsa_signature *sigout,
|
||||||
const secp256k1_ecdsa_signature *sigin
|
const secp256k1_ecdsa_signature *sigin
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3);
|
||||||
|
@ -662,7 +662,7 @@ SECP256K1_API_VAR const secp256k1_nonce_function secp256k1_nonce_function_defaul
|
||||||
* secp256k1_ecdsa_signature_normalize for more details.
|
* secp256k1_ecdsa_signature_normalize for more details.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API int secp256k1_ecdsa_sign(
|
SECP256K1_API int secp256k1_ecdsa_sign(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
secp256k1_ecdsa_signature *sig,
|
secp256k1_ecdsa_signature *sig,
|
||||||
const unsigned char *msghash32,
|
const unsigned char *msghash32,
|
||||||
const unsigned char *seckey,
|
const unsigned char *seckey,
|
||||||
|
@ -683,7 +683,7 @@ SECP256K1_API int secp256k1_ecdsa_sign(
|
||||||
* In: seckey: pointer to a 32-byte secret key.
|
* In: seckey: pointer to a 32-byte secret key.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
const unsigned char *seckey
|
const unsigned char *seckey
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
|
||||||
|
|
||||||
|
@ -696,7 +696,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify(
|
||||||
* In: seckey: pointer to a 32-byte secret key.
|
* In: seckey: pointer to a 32-byte secret key.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
secp256k1_pubkey *pubkey,
|
secp256k1_pubkey *pubkey,
|
||||||
const unsigned char *seckey
|
const unsigned char *seckey
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||||
|
@ -712,14 +712,14 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(
|
||||||
* seckey will be set to some unspecified value.
|
* seckey will be set to some unspecified value.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_negate(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_negate(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
unsigned char *seckey
|
unsigned char *seckey
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
|
||||||
|
|
||||||
/** Same as secp256k1_ec_seckey_negate, but DEPRECATED. Will be removed in
|
/** Same as secp256k1_ec_seckey_negate, but DEPRECATED. Will be removed in
|
||||||
* future versions. */
|
* future versions. */
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_negate(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_negate(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
unsigned char *seckey
|
unsigned char *seckey
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2)
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2)
|
||||||
SECP256K1_DEPRECATED("Use secp256k1_ec_seckey_negate instead");
|
SECP256K1_DEPRECATED("Use secp256k1_ec_seckey_negate instead");
|
||||||
|
@ -731,7 +731,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_negate(
|
||||||
* In/Out: pubkey: pointer to the public key to be negated.
|
* In/Out: pubkey: pointer to the public key to be negated.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_negate(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_negate(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
secp256k1_pubkey *pubkey
|
secp256k1_pubkey *pubkey
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
|
||||||
|
|
||||||
|
@ -751,7 +751,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_negate(
|
||||||
* is negligible (around 1 in 2^128).
|
* is negligible (around 1 in 2^128).
|
||||||
*/
|
*/
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_add(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_add(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
unsigned char *seckey,
|
unsigned char *seckey,
|
||||||
const unsigned char *tweak32
|
const unsigned char *tweak32
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||||
|
@ -759,7 +759,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_add(
|
||||||
/** Same as secp256k1_ec_seckey_tweak_add, but DEPRECATED. Will be removed in
|
/** Same as secp256k1_ec_seckey_tweak_add, but DEPRECATED. Will be removed in
|
||||||
* future versions. */
|
* future versions. */
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
unsigned char *seckey,
|
unsigned char *seckey,
|
||||||
const unsigned char *tweak32
|
const unsigned char *tweak32
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
|
||||||
|
@ -779,7 +779,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add(
|
||||||
* is negligible (around 1 in 2^128).
|
* is negligible (around 1 in 2^128).
|
||||||
*/
|
*/
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
secp256k1_pubkey *pubkey,
|
secp256k1_pubkey *pubkey,
|
||||||
const unsigned char *tweak32
|
const unsigned char *tweak32
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||||
|
@ -798,7 +798,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add(
|
||||||
* is negligible (around 1 in 2^128).
|
* is negligible (around 1 in 2^128).
|
||||||
*/
|
*/
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_mul(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_mul(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
unsigned char *seckey,
|
unsigned char *seckey,
|
||||||
const unsigned char *tweak32
|
const unsigned char *tweak32
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||||
|
@ -806,7 +806,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_mul(
|
||||||
/** Same as secp256k1_ec_seckey_tweak_mul, but DEPRECATED. Will be removed in
|
/** Same as secp256k1_ec_seckey_tweak_mul, but DEPRECATED. Will be removed in
|
||||||
* future versions. */
|
* future versions. */
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
unsigned char *seckey,
|
unsigned char *seckey,
|
||||||
const unsigned char *tweak32
|
const unsigned char *tweak32
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
|
||||||
|
@ -824,7 +824,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul(
|
||||||
* is negligible (around 1 in 2^128).
|
* is negligible (around 1 in 2^128).
|
||||||
*/
|
*/
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
secp256k1_pubkey *pubkey,
|
secp256k1_pubkey *pubkey,
|
||||||
const unsigned char *tweak32
|
const unsigned char *tweak32
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||||
|
@ -862,7 +862,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul(
|
||||||
* enhanced protection against side-channel leakage currently.
|
* enhanced protection against side-channel leakage currently.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize(
|
||||||
secp256k1_context* ctx,
|
secp256k1_context *ctx,
|
||||||
const unsigned char *seed32
|
const unsigned char *seed32
|
||||||
) SECP256K1_ARG_NONNULL(1);
|
) SECP256K1_ARG_NONNULL(1);
|
||||||
|
|
||||||
|
@ -876,9 +876,9 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize(
|
||||||
* n: the number of public keys to add together (must be at least 1).
|
* n: the number of public keys to add together (must be at least 1).
|
||||||
*/
|
*/
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_combine(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_combine(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
secp256k1_pubkey *out,
|
secp256k1_pubkey *out,
|
||||||
const secp256k1_pubkey * const * ins,
|
const secp256k1_pubkey * const *ins,
|
||||||
size_t n
|
size_t n
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||||
|
|
||||||
|
@ -899,7 +899,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_combine(
|
||||||
* msglen: length of the message array
|
* msglen: length of the message array
|
||||||
*/
|
*/
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_tagged_sha256(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_tagged_sha256(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
unsigned char *hash32,
|
unsigned char *hash32,
|
||||||
const unsigned char *tag,
|
const unsigned char *tag,
|
||||||
size_t taglen,
|
size_t taglen,
|
||||||
|
|
|
@ -48,7 +48,7 @@ SECP256K1_API_VAR const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_functio
|
||||||
* (can be NULL for secp256k1_ecdh_hash_function_sha256).
|
* (can be NULL for secp256k1_ecdh_hash_function_sha256).
|
||||||
*/
|
*/
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdh(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdh(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
unsigned char *output,
|
unsigned char *output,
|
||||||
const secp256k1_pubkey *pubkey,
|
const secp256k1_pubkey *pubkey,
|
||||||
const unsigned char *seckey,
|
const unsigned char *seckey,
|
||||||
|
|
|
@ -45,8 +45,8 @@ typedef struct {
|
||||||
* In: input32: pointer to a serialized xonly_pubkey.
|
* In: input32: pointer to a serialized xonly_pubkey.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_parse(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_parse(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
secp256k1_xonly_pubkey* pubkey,
|
secp256k1_xonly_pubkey *pubkey,
|
||||||
const unsigned char *input32
|
const unsigned char *input32
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||||
|
|
||||||
|
@ -59,9 +59,9 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_parse(
|
||||||
* In: pubkey: a pointer to a secp256k1_xonly_pubkey containing an initialized public key.
|
* In: pubkey: a pointer to a secp256k1_xonly_pubkey containing an initialized public key.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API int secp256k1_xonly_pubkey_serialize(
|
SECP256K1_API int secp256k1_xonly_pubkey_serialize(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
unsigned char *output32,
|
unsigned char *output32,
|
||||||
const secp256k1_xonly_pubkey* pubkey
|
const secp256k1_xonly_pubkey *pubkey
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||||
|
|
||||||
/** Compare two x-only public keys using lexicographic order
|
/** Compare two x-only public keys using lexicographic order
|
||||||
|
@ -74,9 +74,9 @@ SECP256K1_API int secp256k1_xonly_pubkey_serialize(
|
||||||
* pubkey2: second public key to compare
|
* pubkey2: second public key to compare
|
||||||
*/
|
*/
|
||||||
SECP256K1_API int secp256k1_xonly_pubkey_cmp(
|
SECP256K1_API int secp256k1_xonly_pubkey_cmp(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
const secp256k1_xonly_pubkey* pk1,
|
const secp256k1_xonly_pubkey *pk1,
|
||||||
const secp256k1_xonly_pubkey* pk2
|
const secp256k1_xonly_pubkey *pk2
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||||
|
|
||||||
/** Converts a secp256k1_pubkey into a secp256k1_xonly_pubkey.
|
/** Converts a secp256k1_pubkey into a secp256k1_xonly_pubkey.
|
||||||
|
@ -91,7 +91,7 @@ SECP256K1_API int secp256k1_xonly_pubkey_cmp(
|
||||||
* In: pubkey: pointer to a public key that is converted.
|
* In: pubkey: pointer to a public key that is converted.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_from_pubkey(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_from_pubkey(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
secp256k1_xonly_pubkey *xonly_pubkey,
|
secp256k1_xonly_pubkey *xonly_pubkey,
|
||||||
int *pk_parity,
|
int *pk_parity,
|
||||||
const secp256k1_pubkey *pubkey
|
const secp256k1_pubkey *pubkey
|
||||||
|
@ -118,7 +118,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_from_pubke
|
||||||
* chance of being invalid is negligible (around 1 in 2^128).
|
* chance of being invalid is negligible (around 1 in 2^128).
|
||||||
*/
|
*/
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
secp256k1_pubkey *output_pubkey,
|
secp256k1_pubkey *output_pubkey,
|
||||||
const secp256k1_xonly_pubkey *internal_pubkey,
|
const secp256k1_xonly_pubkey *internal_pubkey,
|
||||||
const unsigned char *tweak32
|
const unsigned char *tweak32
|
||||||
|
@ -148,7 +148,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add(
|
||||||
* tweak32: pointer to a 32-byte tweak.
|
* tweak32: pointer to a 32-byte tweak.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add_check(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add_check(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
const unsigned char *tweaked_pubkey32,
|
const unsigned char *tweaked_pubkey32,
|
||||||
int tweaked_pk_parity,
|
int tweaked_pk_parity,
|
||||||
const secp256k1_xonly_pubkey *internal_pubkey,
|
const secp256k1_xonly_pubkey *internal_pubkey,
|
||||||
|
@ -164,7 +164,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add_
|
||||||
* In: seckey: pointer to a 32-byte secret key.
|
* In: seckey: pointer to a 32-byte secret key.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_create(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_create(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
secp256k1_keypair *keypair,
|
secp256k1_keypair *keypair,
|
||||||
const unsigned char *seckey
|
const unsigned char *seckey
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||||
|
@ -177,7 +177,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_create(
|
||||||
* In: keypair: pointer to a keypair.
|
* In: keypair: pointer to a keypair.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_sec(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_sec(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
unsigned char *seckey,
|
unsigned char *seckey,
|
||||||
const secp256k1_keypair *keypair
|
const secp256k1_keypair *keypair
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||||
|
@ -191,7 +191,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_sec(
|
||||||
* In: keypair: pointer to a keypair.
|
* In: keypair: pointer to a keypair.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_pub(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_pub(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
secp256k1_pubkey *pubkey,
|
secp256k1_pubkey *pubkey,
|
||||||
const secp256k1_keypair *keypair
|
const secp256k1_keypair *keypair
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||||
|
@ -211,7 +211,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_pub(
|
||||||
* In: keypair: pointer to a keypair.
|
* In: keypair: pointer to a keypair.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_pub(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_pub(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
secp256k1_xonly_pubkey *pubkey,
|
secp256k1_xonly_pubkey *pubkey,
|
||||||
int *pk_parity,
|
int *pk_parity,
|
||||||
const secp256k1_keypair *keypair
|
const secp256k1_keypair *keypair
|
||||||
|
@ -237,7 +237,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_pub(
|
||||||
* is negligible (around 1 in 2^128).
|
* is negligible (around 1 in 2^128).
|
||||||
*/
|
*/
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_tweak_add(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_tweak_add(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
secp256k1_keypair *keypair,
|
secp256k1_keypair *keypair,
|
||||||
const unsigned char *tweak32
|
const unsigned char *tweak32
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||||
|
|
|
@ -63,8 +63,8 @@ SECP256K1_API size_t secp256k1_context_preallocated_size(
|
||||||
* See also secp256k1_context_randomize (in secp256k1.h)
|
* See also secp256k1_context_randomize (in secp256k1.h)
|
||||||
* and secp256k1_context_preallocated_destroy.
|
* and secp256k1_context_preallocated_destroy.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API secp256k1_context* secp256k1_context_preallocated_create(
|
SECP256K1_API secp256k1_context *secp256k1_context_preallocated_create(
|
||||||
void* prealloc,
|
void *prealloc,
|
||||||
unsigned int flags
|
unsigned int flags
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT;
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ SECP256K1_API secp256k1_context* secp256k1_context_preallocated_create(
|
||||||
* In: ctx: an existing context to copy.
|
* In: ctx: an existing context to copy.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API size_t secp256k1_context_preallocated_clone_size(
|
SECP256K1_API size_t secp256k1_context_preallocated_clone_size(
|
||||||
const secp256k1_context* ctx
|
const secp256k1_context *ctx
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT;
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
/** Copy a secp256k1 context object into caller-provided memory.
|
/** Copy a secp256k1 context object into caller-provided memory.
|
||||||
|
@ -97,9 +97,9 @@ SECP256K1_API size_t secp256k1_context_preallocated_clone_size(
|
||||||
* size at least secp256k1_context_preallocated_size(flags)
|
* size at least secp256k1_context_preallocated_size(flags)
|
||||||
* bytes, as detailed above.
|
* bytes, as detailed above.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API secp256k1_context* secp256k1_context_preallocated_clone(
|
SECP256K1_API secp256k1_context *secp256k1_context_preallocated_clone(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
void* prealloc
|
void *prealloc
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_WARN_UNUSED_RESULT;
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
/** Destroy a secp256k1 context object that has been created in
|
/** Destroy a secp256k1 context object that has been created in
|
||||||
|
@ -124,7 +124,7 @@ SECP256K1_API secp256k1_context* secp256k1_context_preallocated_clone(
|
||||||
* (i.e., not secp256k1_context_static).
|
* (i.e., not secp256k1_context_static).
|
||||||
*/
|
*/
|
||||||
SECP256K1_API void secp256k1_context_preallocated_destroy(
|
SECP256K1_API void secp256k1_context_preallocated_destroy(
|
||||||
secp256k1_context* ctx
|
secp256k1_context *ctx
|
||||||
) SECP256K1_ARG_NONNULL(1);
|
) SECP256K1_ARG_NONNULL(1);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -34,8 +34,8 @@ typedef struct {
|
||||||
* recid: the recovery id (0, 1, 2 or 3)
|
* recid: the recovery id (0, 1, 2 or 3)
|
||||||
*/
|
*/
|
||||||
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_parse_compact(
|
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_parse_compact(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
secp256k1_ecdsa_recoverable_signature* sig,
|
secp256k1_ecdsa_recoverable_signature *sig,
|
||||||
const unsigned char *input64,
|
const unsigned char *input64,
|
||||||
int recid
|
int recid
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||||
|
@ -48,9 +48,9 @@ SECP256K1_API int secp256k1_ecdsa_recoverable_signature_parse_compact(
|
||||||
* In: sigin: a pointer to a recoverable signature.
|
* In: sigin: a pointer to a recoverable signature.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_convert(
|
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_convert(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
secp256k1_ecdsa_signature* sig,
|
secp256k1_ecdsa_signature *sig,
|
||||||
const secp256k1_ecdsa_recoverable_signature* sigin
|
const secp256k1_ecdsa_recoverable_signature *sigin
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||||
|
|
||||||
/** Serialize an ECDSA signature in compact format (64 bytes + recovery id).
|
/** Serialize an ECDSA signature in compact format (64 bytes + recovery id).
|
||||||
|
@ -62,10 +62,10 @@ SECP256K1_API int secp256k1_ecdsa_recoverable_signature_convert(
|
||||||
* In: sig: a pointer to an initialized signature object.
|
* In: sig: a pointer to an initialized signature object.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_serialize_compact(
|
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_serialize_compact(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
unsigned char *output64,
|
unsigned char *output64,
|
||||||
int *recid,
|
int *recid,
|
||||||
const secp256k1_ecdsa_recoverable_signature* sig
|
const secp256k1_ecdsa_recoverable_signature *sig
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||||
|
|
||||||
/** Create a recoverable ECDSA signature.
|
/** Create a recoverable ECDSA signature.
|
||||||
|
@ -82,7 +82,7 @@ SECP256K1_API int secp256k1_ecdsa_recoverable_signature_serialize_compact(
|
||||||
* (can be NULL for secp256k1_nonce_function_default).
|
* (can be NULL for secp256k1_nonce_function_default).
|
||||||
*/
|
*/
|
||||||
SECP256K1_API int secp256k1_ecdsa_sign_recoverable(
|
SECP256K1_API int secp256k1_ecdsa_sign_recoverable(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
secp256k1_ecdsa_recoverable_signature *sig,
|
secp256k1_ecdsa_recoverable_signature *sig,
|
||||||
const unsigned char *msghash32,
|
const unsigned char *msghash32,
|
||||||
const unsigned char *seckey,
|
const unsigned char *seckey,
|
||||||
|
@ -100,7 +100,7 @@ SECP256K1_API int secp256k1_ecdsa_sign_recoverable(
|
||||||
* msghash32: the 32-byte message hash assumed to be signed.
|
* msghash32: the 32-byte message hash assumed to be signed.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
secp256k1_pubkey *pubkey,
|
secp256k1_pubkey *pubkey,
|
||||||
const secp256k1_ecdsa_recoverable_signature *sig,
|
const secp256k1_ecdsa_recoverable_signature *sig,
|
||||||
const unsigned char *msghash32
|
const unsigned char *msghash32
|
||||||
|
|
|
@ -82,7 +82,7 @@ SECP256K1_API_VAR const secp256k1_nonce_function_hardened secp256k1_nonce_functi
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned char magic[4];
|
unsigned char magic[4];
|
||||||
secp256k1_nonce_function_hardened noncefp;
|
secp256k1_nonce_function_hardened noncefp;
|
||||||
void* ndata;
|
void *ndata;
|
||||||
} secp256k1_schnorrsig_extraparams;
|
} secp256k1_schnorrsig_extraparams;
|
||||||
|
|
||||||
#define SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC { 0xda, 0x6f, 0xb3, 0x8c }
|
#define SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC { 0xda, 0x6f, 0xb3, 0x8c }
|
||||||
|
@ -117,7 +117,7 @@ typedef struct {
|
||||||
* argument and for guidance if randomness is expensive.
|
* argument and for guidance if randomness is expensive.
|
||||||
*/
|
*/
|
||||||
SECP256K1_API int secp256k1_schnorrsig_sign32(
|
SECP256K1_API int secp256k1_schnorrsig_sign32(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
unsigned char *sig64,
|
unsigned char *sig64,
|
||||||
const unsigned char *msg32,
|
const unsigned char *msg32,
|
||||||
const secp256k1_keypair *keypair,
|
const secp256k1_keypair *keypair,
|
||||||
|
@ -127,7 +127,7 @@ SECP256K1_API int secp256k1_schnorrsig_sign32(
|
||||||
/** Same as secp256k1_schnorrsig_sign32, but DEPRECATED. Will be removed in
|
/** Same as secp256k1_schnorrsig_sign32, but DEPRECATED. Will be removed in
|
||||||
* future versions. */
|
* future versions. */
|
||||||
SECP256K1_API int secp256k1_schnorrsig_sign(
|
SECP256K1_API int secp256k1_schnorrsig_sign(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
unsigned char *sig64,
|
unsigned char *sig64,
|
||||||
const unsigned char *msg32,
|
const unsigned char *msg32,
|
||||||
const secp256k1_keypair *keypair,
|
const secp256k1_keypair *keypair,
|
||||||
|
@ -149,7 +149,7 @@ SECP256K1_API int secp256k1_schnorrsig_sign(
|
||||||
* extraparams: pointer to a extraparams object (can be NULL)
|
* extraparams: pointer to a extraparams object (can be NULL)
|
||||||
*/
|
*/
|
||||||
SECP256K1_API int secp256k1_schnorrsig_sign_custom(
|
SECP256K1_API int secp256k1_schnorrsig_sign_custom(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
unsigned char *sig64,
|
unsigned char *sig64,
|
||||||
const unsigned char *msg,
|
const unsigned char *msg,
|
||||||
size_t msglen,
|
size_t msglen,
|
||||||
|
@ -168,7 +168,7 @@ SECP256K1_API int secp256k1_schnorrsig_sign_custom(
|
||||||
* pubkey: pointer to an x-only public key to verify with (cannot be NULL)
|
* pubkey: pointer to an x-only public key to verify with (cannot be NULL)
|
||||||
*/
|
*/
|
||||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorrsig_verify(
|
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorrsig_verify(
|
||||||
const secp256k1_context* ctx,
|
const secp256k1_context *ctx,
|
||||||
const unsigned char *sig64,
|
const unsigned char *sig64,
|
||||||
const unsigned char *msg,
|
const unsigned char *msg,
|
||||||
size_t msglen,
|
size_t msglen,
|
||||||
|
|
|
@ -29,6 +29,7 @@ Note:
|
||||||
.align 2
|
.align 2
|
||||||
.global secp256k1_fe_mul_inner
|
.global secp256k1_fe_mul_inner
|
||||||
.type secp256k1_fe_mul_inner, %function
|
.type secp256k1_fe_mul_inner, %function
|
||||||
|
.hidden secp256k1_fe_mul_inner
|
||||||
@ Arguments:
|
@ Arguments:
|
||||||
@ r0 r Restrict: can overlap with a, not with b
|
@ r0 r Restrict: can overlap with a, not with b
|
||||||
@ r1 a
|
@ r1 a
|
||||||
|
@ -516,6 +517,7 @@ secp256k1_fe_mul_inner:
|
||||||
.align 2
|
.align 2
|
||||||
.global secp256k1_fe_sqr_inner
|
.global secp256k1_fe_sqr_inner
|
||||||
.type secp256k1_fe_sqr_inner, %function
|
.type secp256k1_fe_sqr_inner, %function
|
||||||
|
.hidden secp256k1_fe_sqr_inner
|
||||||
@ Arguments:
|
@ Arguments:
|
||||||
@ r0 r Can overlap with a
|
@ r0 r Can overlap with a
|
||||||
@ r1 a
|
@ r1 a
|
||||||
|
|
|
@ -18,4 +18,25 @@
|
||||||
*/
|
*/
|
||||||
static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *q, int bits);
|
static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *q, int bits);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same as secp256k1_ecmult_const, but takes in an x coordinate of the base point
|
||||||
|
* only, specified as fraction n/d (numerator/denominator). Only the x coordinate of the result is
|
||||||
|
* returned.
|
||||||
|
*
|
||||||
|
* If known_on_curve is 0, a verification is performed that n/d is a valid X
|
||||||
|
* coordinate, and 0 is returned if not. Otherwise, 1 is returned.
|
||||||
|
*
|
||||||
|
* d being NULL is interpreted as d=1. If non-NULL, d must not be zero. q must not be zero.
|
||||||
|
*
|
||||||
|
* Constant time in the value of q, but not any other inputs.
|
||||||
|
*/
|
||||||
|
static int secp256k1_ecmult_const_xonly(
|
||||||
|
secp256k1_fe *r,
|
||||||
|
const secp256k1_fe *n,
|
||||||
|
const secp256k1_fe *d,
|
||||||
|
const secp256k1_scalar *q,
|
||||||
|
int bits,
|
||||||
|
int known_on_curve
|
||||||
|
);
|
||||||
|
|
||||||
#endif /* SECP256K1_ECMULT_CONST_H */
|
#endif /* SECP256K1_ECMULT_CONST_H */
|
||||||
|
|
|
@ -228,4 +228,139 @@ static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, cons
|
||||||
secp256k1_fe_mul(&r->z, &r->z, &Z);
|
secp256k1_fe_mul(&r->z, &r->z, &Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int secp256k1_ecmult_const_xonly(secp256k1_fe* r, const secp256k1_fe *n, const secp256k1_fe *d, const secp256k1_scalar *q, int bits, int known_on_curve) {
|
||||||
|
|
||||||
|
/* This algorithm is a generalization of Peter Dettman's technique for
|
||||||
|
* avoiding the square root in a random-basepoint x-only multiplication
|
||||||
|
* on a Weierstrass curve:
|
||||||
|
* https://mailarchive.ietf.org/arch/msg/cfrg/7DyYY6gg32wDgHAhgSb6XxMDlJA/
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* === Background: the effective affine technique ===
|
||||||
|
*
|
||||||
|
* Let phi_u be the isomorphism that maps (x, y) on secp256k1 curve y^2 = x^3 + 7 to
|
||||||
|
* x' = u^2*x, y' = u^3*y on curve y'^2 = x'^3 + u^6*7. This new curve has the same order as
|
||||||
|
* the original (it is isomorphic), but moreover, has the same addition/doubling formulas, as
|
||||||
|
* the curve b=7 coefficient does not appear in those formulas (or at least does not appear in
|
||||||
|
* the formulas implemented in this codebase, both affine and Jacobian). See also Example 9.5.2
|
||||||
|
* in https://www.math.auckland.ac.nz/~sgal018/crypto-book/ch9.pdf.
|
||||||
|
*
|
||||||
|
* This means any linear combination of secp256k1 points can be computed by applying phi_u
|
||||||
|
* (with non-zero u) on all input points (including the generator, if used), computing the
|
||||||
|
* linear combination on the isomorphic curve (using the same group laws), and then applying
|
||||||
|
* phi_u^{-1} to get back to secp256k1.
|
||||||
|
*
|
||||||
|
* Switching to Jacobian coordinates, note that phi_u applied to (X, Y, Z) is simply
|
||||||
|
* (X, Y, Z/u). Thus, if we want to compute (X1, Y1, Z) + (X2, Y2, Z), with identical Z
|
||||||
|
* coordinates, we can use phi_Z to transform it to (X1, Y1, 1) + (X2, Y2, 1) on an isomorphic
|
||||||
|
* curve where the affine addition formula can be used instead.
|
||||||
|
* If (X3, Y3, Z3) = (X1, Y1) + (X2, Y2) on that curve, then our answer on secp256k1 is
|
||||||
|
* (X3, Y3, Z3*Z).
|
||||||
|
*
|
||||||
|
* This is the effective affine technique: if we have a linear combination of group elements
|
||||||
|
* to compute, and all those group elements have the same Z coordinate, we can simply pretend
|
||||||
|
* that all those Z coordinates are 1, perform the computation that way, and then multiply the
|
||||||
|
* original Z coordinate back in.
|
||||||
|
*
|
||||||
|
* The technique works on any a=0 short Weierstrass curve. It is possible to generalize it to
|
||||||
|
* other curves too, but there the isomorphic curves will have different 'a' coefficients,
|
||||||
|
* which typically does affect the group laws.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* === Avoiding the square root for x-only point multiplication ===
|
||||||
|
*
|
||||||
|
* In this function, we want to compute the X coordinate of q*(n/d, y), for
|
||||||
|
* y = sqrt((n/d)^3 + 7). Its negation would also be a valid Y coordinate, but by convention
|
||||||
|
* we pick whatever sqrt returns (which we assume to be a deterministic function).
|
||||||
|
*
|
||||||
|
* Let g = y^2*d^3 = n^3 + 7*d^3. This also means y = sqrt(g/d^3).
|
||||||
|
* Further let v = sqrt(d*g), which must exist as d*g = y^2*d^4 = (y*d^2)^2.
|
||||||
|
*
|
||||||
|
* The input point (n/d, y) also has Jacobian coordinates:
|
||||||
|
*
|
||||||
|
* (n/d, y, 1)
|
||||||
|
* = (n/d * v^2, y * v^3, v)
|
||||||
|
* = (n/d * d*g, y * sqrt(d^3*g^3), v)
|
||||||
|
* = (n/d * d*g, sqrt(y^2 * d^3*g^3), v)
|
||||||
|
* = (n*g, sqrt(g/d^3 * d^3*g^3), v)
|
||||||
|
* = (n*g, sqrt(g^4), v)
|
||||||
|
* = (n*g, g^2, v)
|
||||||
|
*
|
||||||
|
* It is easy to verify that both (n*g, g^2, v) and its negation (n*g, -g^2, v) have affine X
|
||||||
|
* coordinate n/d, and this holds even when the square root function doesn't have a
|
||||||
|
* determinstic sign. We choose the (n*g, g^2, v) version.
|
||||||
|
*
|
||||||
|
* Now switch to the effective affine curve using phi_v, where the input point has coordinates
|
||||||
|
* (n*g, g^2). Compute (X, Y, Z) = q * (n*g, g^2) there.
|
||||||
|
*
|
||||||
|
* Back on secp256k1, that means q * (n*g, g^2, v) = (X, Y, v*Z). This last point has affine X
|
||||||
|
* coordinate X / (v^2*Z^2) = X / (d*g*Z^2). Determining the affine Y coordinate would involve
|
||||||
|
* a square root, but as long as we only care about the resulting X coordinate, no square root
|
||||||
|
* is needed anywhere in this computation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
secp256k1_fe g, i;
|
||||||
|
secp256k1_ge p;
|
||||||
|
secp256k1_gej rj;
|
||||||
|
|
||||||
|
/* Compute g = (n^3 + B*d^3). */
|
||||||
|
secp256k1_fe_sqr(&g, n);
|
||||||
|
secp256k1_fe_mul(&g, &g, n);
|
||||||
|
if (d) {
|
||||||
|
secp256k1_fe b;
|
||||||
|
#ifdef VERIFY
|
||||||
|
VERIFY_CHECK(!secp256k1_fe_normalizes_to_zero(d));
|
||||||
|
#endif
|
||||||
|
secp256k1_fe_sqr(&b, d);
|
||||||
|
VERIFY_CHECK(SECP256K1_B <= 8); /* magnitude of b will be <= 8 after the next call */
|
||||||
|
secp256k1_fe_mul_int(&b, SECP256K1_B);
|
||||||
|
secp256k1_fe_mul(&b, &b, d);
|
||||||
|
secp256k1_fe_add(&g, &b);
|
||||||
|
if (!known_on_curve) {
|
||||||
|
/* We need to determine whether (n/d)^3 + 7 is square.
|
||||||
|
*
|
||||||
|
* is_square((n/d)^3 + 7)
|
||||||
|
* <=> is_square(((n/d)^3 + 7) * d^4)
|
||||||
|
* <=> is_square((n^3 + 7*d^3) * d)
|
||||||
|
* <=> is_square(g * d)
|
||||||
|
*/
|
||||||
|
secp256k1_fe c;
|
||||||
|
secp256k1_fe_mul(&c, &g, d);
|
||||||
|
if (!secp256k1_fe_is_square_var(&c)) return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
secp256k1_fe_add_int(&g, SECP256K1_B);
|
||||||
|
if (!known_on_curve) {
|
||||||
|
/* g at this point equals x^3 + 7. Test if it is square. */
|
||||||
|
if (!secp256k1_fe_is_square_var(&g)) return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compute base point P = (n*g, g^2), the effective affine version of (n*g, g^2, v), which has
|
||||||
|
* corresponding affine X coordinate n/d. */
|
||||||
|
secp256k1_fe_mul(&p.x, &g, n);
|
||||||
|
secp256k1_fe_sqr(&p.y, &g);
|
||||||
|
p.infinity = 0;
|
||||||
|
|
||||||
|
/* Perform x-only EC multiplication of P with q. */
|
||||||
|
#ifdef VERIFY
|
||||||
|
VERIFY_CHECK(!secp256k1_scalar_is_zero(q));
|
||||||
|
#endif
|
||||||
|
secp256k1_ecmult_const(&rj, &p, q, bits);
|
||||||
|
#ifdef VERIFY
|
||||||
|
VERIFY_CHECK(!secp256k1_gej_is_infinity(&rj));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The resulting (X, Y, Z) point on the effective-affine isomorphic curve corresponds to
|
||||||
|
* (X, Y, Z*v) on the secp256k1 curve. The affine version of that has X coordinate
|
||||||
|
* (X / (Z^2*d*g)). */
|
||||||
|
secp256k1_fe_sqr(&i, &rj.z);
|
||||||
|
secp256k1_fe_mul(&i, &i, &g);
|
||||||
|
if (d) secp256k1_fe_mul(&i, &i, d);
|
||||||
|
secp256k1_fe_inv(&i, &i);
|
||||||
|
secp256k1_fe_mul(r, &rj.x, &i);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* SECP256K1_ECMULT_CONST_IMPL_H */
|
#endif /* SECP256K1_ECMULT_CONST_IMPL_H */
|
||||||
|
|
|
@ -97,7 +97,7 @@ static void secp256k1_ecmult_odd_multiples_table(int n, secp256k1_ge *pre_a, sec
|
||||||
secp256k1_gej_set_ge(&ai, &pre_a[0]);
|
secp256k1_gej_set_ge(&ai, &pre_a[0]);
|
||||||
ai.z = a->z;
|
ai.z = a->z;
|
||||||
|
|
||||||
/* pre_a[0] is the point (a.x*C^2, a.y*C^3, a.z*C) which is equvalent to a.
|
/* pre_a[0] is the point (a.x*C^2, a.y*C^3, a.z*C) which is equivalent to a.
|
||||||
* Set zr[0] to C, which is the ratio between the omitted z(pre_a[0]) value and a.z.
|
* Set zr[0] to C, which is the ratio between the omitted z(pre_a[0]) value and a.z.
|
||||||
*/
|
*/
|
||||||
zr[0] = d.z;
|
zr[0] = d.z;
|
||||||
|
@ -114,13 +114,16 @@ static void secp256k1_ecmult_odd_multiples_table(int n, secp256k1_ge *pre_a, sec
|
||||||
secp256k1_fe_mul(z, &ai.z, &d.z);
|
secp256k1_fe_mul(z, &ai.z, &d.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SECP256K1_ECMULT_TABLE_VERIFY(n,w) \
|
SECP256K1_INLINE static void secp256k1_ecmult_table_verify(int n, int w) {
|
||||||
VERIFY_CHECK(((n) & 1) == 1); \
|
(void)n;
|
||||||
VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \
|
(void)w;
|
||||||
|
VERIFY_CHECK(((n) & 1) == 1);
|
||||||
|
VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1));
|
||||||
VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1));
|
VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1));
|
||||||
|
}
|
||||||
|
|
||||||
SECP256K1_INLINE static void secp256k1_ecmult_table_get_ge(secp256k1_ge *r, const secp256k1_ge *pre, int n, int w) {
|
SECP256K1_INLINE static void secp256k1_ecmult_table_get_ge(secp256k1_ge *r, const secp256k1_ge *pre, int n, int w) {
|
||||||
SECP256K1_ECMULT_TABLE_VERIFY(n,w)
|
secp256k1_ecmult_table_verify(n,w);
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
*r = pre[(n-1)/2];
|
*r = pre[(n-1)/2];
|
||||||
} else {
|
} else {
|
||||||
|
@ -130,7 +133,7 @@ SECP256K1_INLINE static void secp256k1_ecmult_table_get_ge(secp256k1_ge *r, cons
|
||||||
}
|
}
|
||||||
|
|
||||||
SECP256K1_INLINE static void secp256k1_ecmult_table_get_ge_lambda(secp256k1_ge *r, const secp256k1_ge *pre, const secp256k1_fe *x, int n, int w) {
|
SECP256K1_INLINE static void secp256k1_ecmult_table_get_ge_lambda(secp256k1_ge *r, const secp256k1_ge *pre, const secp256k1_fe *x, int n, int w) {
|
||||||
SECP256K1_ECMULT_TABLE_VERIFY(n,w)
|
secp256k1_ecmult_table_verify(n,w);
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
secp256k1_ge_set_xy(r, &x[(n-1)/2], &pre[(n-1)/2].y);
|
secp256k1_ge_set_xy(r, &x[(n-1)/2], &pre[(n-1)/2].y);
|
||||||
} else {
|
} else {
|
||||||
|
@ -140,7 +143,7 @@ SECP256K1_INLINE static void secp256k1_ecmult_table_get_ge_lambda(secp256k1_ge *
|
||||||
}
|
}
|
||||||
|
|
||||||
SECP256K1_INLINE static void secp256k1_ecmult_table_get_ge_storage(secp256k1_ge *r, const secp256k1_ge_storage *pre, int n, int w) {
|
SECP256K1_INLINE static void secp256k1_ecmult_table_get_ge_storage(secp256k1_ge *r, const secp256k1_ge_storage *pre, int n, int w) {
|
||||||
SECP256K1_ECMULT_TABLE_VERIFY(n,w)
|
secp256k1_ecmult_table_verify(n,w);
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
secp256k1_ge_from_storage(r, &pre[(n-1)/2]);
|
secp256k1_ge_from_storage(r, &pre[(n-1)/2]);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1147,8 +1147,9 @@ static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a) {
|
||||||
|
|
||||||
static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) {
|
static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) {
|
||||||
uint32_t mask0, mask1;
|
uint32_t mask0, mask1;
|
||||||
|
volatile int vflag = flag;
|
||||||
SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n));
|
SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n));
|
||||||
mask0 = flag + ~((uint32_t)0);
|
mask0 = vflag + ~((uint32_t)0);
|
||||||
mask1 = ~mask0;
|
mask1 = ~mask0;
|
||||||
r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
|
r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
|
||||||
r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1);
|
r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1);
|
||||||
|
@ -1246,8 +1247,9 @@ static SECP256K1_INLINE void secp256k1_fe_half(secp256k1_fe *r) {
|
||||||
|
|
||||||
static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag) {
|
static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag) {
|
||||||
uint32_t mask0, mask1;
|
uint32_t mask0, mask1;
|
||||||
|
volatile int vflag = flag;
|
||||||
SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n));
|
SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n));
|
||||||
mask0 = flag + ~((uint32_t)0);
|
mask0 = vflag + ~((uint32_t)0);
|
||||||
mask1 = ~mask0;
|
mask1 = ~mask0;
|
||||||
r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
|
r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
|
||||||
r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1);
|
r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1);
|
||||||
|
@ -1363,7 +1365,9 @@ static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *x) {
|
||||||
secp256k1_modinv32(&s, &secp256k1_const_modinfo_fe);
|
secp256k1_modinv32(&s, &secp256k1_const_modinfo_fe);
|
||||||
secp256k1_fe_from_signed30(r, &s);
|
secp256k1_fe_from_signed30(r, &s);
|
||||||
|
|
||||||
|
#ifdef VERIFY
|
||||||
VERIFY_CHECK(secp256k1_fe_normalizes_to_zero(r) == secp256k1_fe_normalizes_to_zero(&tmp));
|
VERIFY_CHECK(secp256k1_fe_normalizes_to_zero(r) == secp256k1_fe_normalizes_to_zero(&tmp));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *x) {
|
static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *x) {
|
||||||
|
@ -1376,7 +1380,9 @@ static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *x) {
|
||||||
secp256k1_modinv32_var(&s, &secp256k1_const_modinfo_fe);
|
secp256k1_modinv32_var(&s, &secp256k1_const_modinfo_fe);
|
||||||
secp256k1_fe_from_signed30(r, &s);
|
secp256k1_fe_from_signed30(r, &s);
|
||||||
|
|
||||||
|
#ifdef VERIFY
|
||||||
VERIFY_CHECK(secp256k1_fe_normalizes_to_zero(r) == secp256k1_fe_normalizes_to_zero(&tmp));
|
VERIFY_CHECK(secp256k1_fe_normalizes_to_zero(r) == secp256k1_fe_normalizes_to_zero(&tmp));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int secp256k1_fe_is_square_var(const secp256k1_fe *x) {
|
static int secp256k1_fe_is_square_var(const secp256k1_fe *x) {
|
||||||
|
|
|
@ -487,8 +487,9 @@ static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a) {
|
||||||
|
|
||||||
static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) {
|
static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) {
|
||||||
uint64_t mask0, mask1;
|
uint64_t mask0, mask1;
|
||||||
|
volatile int vflag = flag;
|
||||||
SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n));
|
SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n));
|
||||||
mask0 = flag + ~((uint64_t)0);
|
mask0 = vflag + ~((uint64_t)0);
|
||||||
mask1 = ~mask0;
|
mask1 = ~mask0;
|
||||||
r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
|
r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
|
||||||
r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1);
|
r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1);
|
||||||
|
@ -570,8 +571,9 @@ static SECP256K1_INLINE void secp256k1_fe_half(secp256k1_fe *r) {
|
||||||
|
|
||||||
static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag) {
|
static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag) {
|
||||||
uint64_t mask0, mask1;
|
uint64_t mask0, mask1;
|
||||||
|
volatile int vflag = flag;
|
||||||
SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n));
|
SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n));
|
||||||
mask0 = flag + ~((uint64_t)0);
|
mask0 = vflag + ~((uint64_t)0);
|
||||||
mask1 = ~mask0;
|
mask1 = ~mask0;
|
||||||
r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
|
r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
|
||||||
r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1);
|
r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1);
|
||||||
|
|
|
@ -193,7 +193,7 @@ static SECP256K1_INLINE int secp256k1_i128_check_pow2(const secp256k1_int128 *r,
|
||||||
VERIFY_CHECK(n < 127);
|
VERIFY_CHECK(n < 127);
|
||||||
VERIFY_CHECK(sign == 1 || sign == -1);
|
VERIFY_CHECK(sign == 1 || sign == -1);
|
||||||
return n >= 64 ? r->hi == (uint64_t)sign << (n - 64) && r->lo == 0
|
return n >= 64 ? r->hi == (uint64_t)sign << (n - 64) && r->lo == 0
|
||||||
: r->hi == (uint64_t)((sign - 1) >> 1) && r->lo == (uint64_t)sign << n;
|
: r->hi == (uint64_t)(sign >> 1) && r->lo == (uint64_t)sign << n;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -232,7 +232,7 @@ static int32_t secp256k1_modinv32_divsteps_30(int32_t zeta, uint32_t f0, uint32_
|
||||||
return zeta;
|
return zeta;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* inv256[i] = -(2*i+1)^-1 (mod 256) */
|
/* secp256k1_modinv32_inv256[i] = -(2*i+1)^-1 (mod 256) */
|
||||||
static const uint8_t secp256k1_modinv32_inv256[128] = {
|
static const uint8_t secp256k1_modinv32_inv256[128] = {
|
||||||
0xFF, 0x55, 0x33, 0x49, 0xC7, 0x5D, 0x3B, 0x11, 0x0F, 0xE5, 0xC3, 0x59,
|
0xFF, 0x55, 0x33, 0x49, 0xC7, 0x5D, 0x3B, 0x11, 0x0F, 0xE5, 0xC3, 0x59,
|
||||||
0xD7, 0xED, 0xCB, 0x21, 0x1F, 0x75, 0x53, 0x69, 0xE7, 0x7D, 0x5B, 0x31,
|
0xD7, 0xED, 0xCB, 0x21, 0x1F, 0x75, 0x53, 0x69, 0xE7, 0x7D, 0x5B, 0x31,
|
||||||
|
|
|
@ -811,8 +811,9 @@ SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r,
|
||||||
|
|
||||||
static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag) {
|
static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag) {
|
||||||
uint64_t mask0, mask1;
|
uint64_t mask0, mask1;
|
||||||
|
volatile int vflag = flag;
|
||||||
SECP256K1_CHECKMEM_CHECK_VERIFY(r->d, sizeof(r->d));
|
SECP256K1_CHECKMEM_CHECK_VERIFY(r->d, sizeof(r->d));
|
||||||
mask0 = flag + ~((uint64_t)0);
|
mask0 = vflag + ~((uint64_t)0);
|
||||||
mask1 = ~mask0;
|
mask1 = ~mask0;
|
||||||
r->d[0] = (r->d[0] & mask0) | (a->d[0] & mask1);
|
r->d[0] = (r->d[0] & mask0) | (a->d[0] & mask1);
|
||||||
r->d[1] = (r->d[1] & mask0) | (a->d[1] & mask1);
|
r->d[1] = (r->d[1] & mask0) | (a->d[1] & mask1);
|
||||||
|
|
|
@ -632,8 +632,9 @@ SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r,
|
||||||
|
|
||||||
static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag) {
|
static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag) {
|
||||||
uint32_t mask0, mask1;
|
uint32_t mask0, mask1;
|
||||||
|
volatile int vflag = flag;
|
||||||
SECP256K1_CHECKMEM_CHECK_VERIFY(r->d, sizeof(r->d));
|
SECP256K1_CHECKMEM_CHECK_VERIFY(r->d, sizeof(r->d));
|
||||||
mask0 = flag + ~((uint32_t)0);
|
mask0 = vflag + ~((uint32_t)0);
|
||||||
mask1 = ~mask0;
|
mask1 = ~mask0;
|
||||||
r->d[0] = (r->d[0] & mask0) | (a->d[0] & mask1);
|
r->d[0] = (r->d[0] & mask0) | (a->d[0] & mask1);
|
||||||
r->d[1] = (r->d[1] & mask0) | (a->d[1] & mask1);
|
r->d[1] = (r->d[1] & mask0) | (a->d[1] & mask1);
|
||||||
|
|
|
@ -116,8 +116,9 @@ SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar *a, const
|
||||||
|
|
||||||
static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag) {
|
static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag) {
|
||||||
uint32_t mask0, mask1;
|
uint32_t mask0, mask1;
|
||||||
|
volatile int vflag = flag;
|
||||||
SECP256K1_CHECKMEM_CHECK_VERIFY(r, sizeof(*r));
|
SECP256K1_CHECKMEM_CHECK_VERIFY(r, sizeof(*r));
|
||||||
mask0 = flag + ~((uint32_t)0);
|
mask0 = vflag + ~((uint32_t)0);
|
||||||
mask1 = ~mask0;
|
mask1 = ~mask0;
|
||||||
*r = (*r & mask0) | (*a & mask1);
|
*r = (*r & mask0) | (*a & mask1);
|
||||||
}
|
}
|
||||||
|
|
102
src/tests.c
102
src/tests.c
|
@ -4452,6 +4452,68 @@ static void ecmult_const_mult_zero_one(void) {
|
||||||
ge_equals_ge(&res2, &point);
|
ge_equals_ge(&res2, &point);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ecmult_const_mult_xonly(void) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Test correspondence between secp256k1_ecmult_const and secp256k1_ecmult_const_xonly. */
|
||||||
|
for (i = 0; i < 2*COUNT; ++i) {
|
||||||
|
secp256k1_ge base;
|
||||||
|
secp256k1_gej basej, resj;
|
||||||
|
secp256k1_fe n, d, resx, v;
|
||||||
|
secp256k1_scalar q;
|
||||||
|
int res;
|
||||||
|
/* Random base point. */
|
||||||
|
random_group_element_test(&base);
|
||||||
|
/* Random scalar to multiply it with. */
|
||||||
|
random_scalar_order_test(&q);
|
||||||
|
/* If i is odd, n=d*base.x for random non-zero d */
|
||||||
|
if (i & 1) {
|
||||||
|
do {
|
||||||
|
random_field_element_test(&d);
|
||||||
|
} while (secp256k1_fe_normalizes_to_zero_var(&d));
|
||||||
|
secp256k1_fe_mul(&n, &base.x, &d);
|
||||||
|
} else {
|
||||||
|
n = base.x;
|
||||||
|
}
|
||||||
|
/* Perform x-only multiplication. */
|
||||||
|
res = secp256k1_ecmult_const_xonly(&resx, &n, (i & 1) ? &d : NULL, &q, 256, i & 2);
|
||||||
|
CHECK(res);
|
||||||
|
/* Perform normal multiplication. */
|
||||||
|
secp256k1_gej_set_ge(&basej, &base);
|
||||||
|
secp256k1_ecmult(&resj, &basej, &q, NULL);
|
||||||
|
/* Check that resj's X coordinate corresponds with resx. */
|
||||||
|
secp256k1_fe_sqr(&v, &resj.z);
|
||||||
|
secp256k1_fe_mul(&v, &v, &resx);
|
||||||
|
CHECK(check_fe_equal(&v, &resj.x));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test that secp256k1_ecmult_const_xonly correctly rejects X coordinates not on curve. */
|
||||||
|
for (i = 0; i < 2*COUNT; ++i) {
|
||||||
|
secp256k1_fe x, n, d, c, r;
|
||||||
|
int res;
|
||||||
|
secp256k1_scalar q;
|
||||||
|
random_scalar_order_test(&q);
|
||||||
|
/* Generate random X coordinate not on the curve. */
|
||||||
|
do {
|
||||||
|
random_field_element_test(&x);
|
||||||
|
secp256k1_fe_sqr(&c, &x);
|
||||||
|
secp256k1_fe_mul(&c, &c, &x);
|
||||||
|
secp256k1_fe_add(&c, &secp256k1_fe_const_b);
|
||||||
|
} while (secp256k1_fe_is_square_var(&c));
|
||||||
|
/* If i is odd, n=d*x for random non-zero d. */
|
||||||
|
if (i & 1) {
|
||||||
|
do {
|
||||||
|
random_field_element_test(&d);
|
||||||
|
} while (secp256k1_fe_normalizes_to_zero_var(&d));
|
||||||
|
secp256k1_fe_mul(&n, &x, &d);
|
||||||
|
} else {
|
||||||
|
n = x;
|
||||||
|
}
|
||||||
|
res = secp256k1_ecmult_const_xonly(&r, &n, (i & 1) ? &d : NULL, &q, 256, 0);
|
||||||
|
CHECK(res == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void ecmult_const_chain_multiply(void) {
|
static void ecmult_const_chain_multiply(void) {
|
||||||
/* Check known result (randomly generated test problem from sage) */
|
/* Check known result (randomly generated test problem from sage) */
|
||||||
const secp256k1_scalar scalar = SECP256K1_SCALAR_CONST(
|
const secp256k1_scalar scalar = SECP256K1_SCALAR_CONST(
|
||||||
|
@ -4483,6 +4545,7 @@ static void run_ecmult_const_tests(void) {
|
||||||
ecmult_const_random_mult();
|
ecmult_const_random_mult();
|
||||||
ecmult_const_commutativity();
|
ecmult_const_commutativity();
|
||||||
ecmult_const_chain_multiply();
|
ecmult_const_chain_multiply();
|
||||||
|
ecmult_const_mult_xonly();
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -7306,6 +7369,44 @@ static void run_ecdsa_edge_cases(void) {
|
||||||
test_ecdsa_edge_cases();
|
test_ecdsa_edge_cases();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Wycheproof tests
|
||||||
|
|
||||||
|
The tests check for known attacks (range checks in (r,s), arithmetic errors, malleability).
|
||||||
|
*/
|
||||||
|
static void test_ecdsa_wycheproof(void) {
|
||||||
|
#include "wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h"
|
||||||
|
|
||||||
|
int t;
|
||||||
|
for (t = 0; t < SECP256K1_ECDSA_WYCHEPROOF_NUMBER_TESTVECTORS; t++) {
|
||||||
|
secp256k1_ecdsa_signature signature;
|
||||||
|
secp256k1_sha256 hasher;
|
||||||
|
secp256k1_pubkey pubkey;
|
||||||
|
const unsigned char *msg, *sig, *pk;
|
||||||
|
unsigned char out[32] = {0};
|
||||||
|
int actual_verify = 0;
|
||||||
|
|
||||||
|
memset(&pubkey, 0, sizeof(pubkey));
|
||||||
|
pk = &wycheproof_ecdsa_public_keys[testvectors[t].pk_offset];
|
||||||
|
CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, pk, 65) == 1);
|
||||||
|
|
||||||
|
secp256k1_sha256_initialize(&hasher);
|
||||||
|
msg = &wycheproof_ecdsa_messages[testvectors[t].msg_offset];
|
||||||
|
secp256k1_sha256_write(&hasher, msg, testvectors[t].msg_len);
|
||||||
|
secp256k1_sha256_finalize(&hasher, out);
|
||||||
|
|
||||||
|
sig = &wycheproof_ecdsa_signatures[testvectors[t].sig_offset];
|
||||||
|
if (secp256k1_ecdsa_signature_parse_der(CTX, &signature, sig, testvectors[t].sig_len) == 1) {
|
||||||
|
actual_verify = secp256k1_ecdsa_verify(CTX, (const secp256k1_ecdsa_signature *)&signature, out, &pubkey);
|
||||||
|
}
|
||||||
|
CHECK(testvectors[t].expected_verify == actual_verify);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tests cases from Wycheproof test suite. */
|
||||||
|
static void run_ecdsa_wycheproof(void) {
|
||||||
|
test_ecdsa_wycheproof();
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_MODULE_ECDH
|
#ifdef ENABLE_MODULE_ECDH
|
||||||
# include "modules/ecdh/tests_impl.h"
|
# include "modules/ecdh/tests_impl.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -7638,6 +7739,7 @@ int main(int argc, char **argv) {
|
||||||
run_ecdsa_sign_verify();
|
run_ecdsa_sign_verify();
|
||||||
run_ecdsa_end_to_end();
|
run_ecdsa_end_to_end();
|
||||||
run_ecdsa_edge_cases();
|
run_ecdsa_edge_cases();
|
||||||
|
run_ecdsa_wycheproof();
|
||||||
|
|
||||||
#ifdef ENABLE_MODULE_RECOVERY
|
#ifdef ENABLE_MODULE_RECOVERY
|
||||||
/* ECDSA pubkey recovery tests */
|
/* ECDSA pubkey recovery tests */
|
||||||
|
|
|
@ -59,6 +59,19 @@ static void random_fe(secp256k1_fe *x) {
|
||||||
}
|
}
|
||||||
} while(1);
|
} while(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void random_fe_non_zero(secp256k1_fe *nz) {
|
||||||
|
int tries = 10;
|
||||||
|
while (--tries >= 0) {
|
||||||
|
random_fe(nz);
|
||||||
|
secp256k1_fe_normalize(nz);
|
||||||
|
if (!secp256k1_fe_is_zero(nz)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Infinitesimal probability of spurious failure here */
|
||||||
|
CHECK(tries >= 0);
|
||||||
|
}
|
||||||
/** END stolen from tests.c */
|
/** END stolen from tests.c */
|
||||||
|
|
||||||
static uint32_t num_cores = 1;
|
static uint32_t num_cores = 1;
|
||||||
|
@ -174,10 +187,37 @@ static void test_exhaustive_ecmult(const secp256k1_ge *group, const secp256k1_ge
|
||||||
secp256k1_ecmult(&tmp, &groupj[r_log], &na, &ng);
|
secp256k1_ecmult(&tmp, &groupj[r_log], &na, &ng);
|
||||||
ge_equals_gej(&group[(i * r_log + j) % EXHAUSTIVE_TEST_ORDER], &tmp);
|
ge_equals_gej(&group[(i * r_log + j) % EXHAUSTIVE_TEST_ORDER], &tmp);
|
||||||
|
|
||||||
if (i > 0) {
|
}
|
||||||
secp256k1_ecmult_const(&tmp, &group[i], &ng, 256);
|
}
|
||||||
ge_equals_gej(&group[(i * j) % EXHAUSTIVE_TEST_ORDER], &tmp);
|
}
|
||||||
}
|
|
||||||
|
for (j = 0; j < EXHAUSTIVE_TEST_ORDER; j++) {
|
||||||
|
for (i = 1; i < EXHAUSTIVE_TEST_ORDER; i++) {
|
||||||
|
int ret;
|
||||||
|
secp256k1_gej tmp;
|
||||||
|
secp256k1_fe xn, xd, tmpf;
|
||||||
|
secp256k1_scalar ng;
|
||||||
|
|
||||||
|
if (skip_section(&iter)) continue;
|
||||||
|
|
||||||
|
secp256k1_scalar_set_int(&ng, j);
|
||||||
|
|
||||||
|
/* Test secp256k1_ecmult_const. */
|
||||||
|
secp256k1_ecmult_const(&tmp, &group[i], &ng, 256);
|
||||||
|
ge_equals_gej(&group[(i * j) % EXHAUSTIVE_TEST_ORDER], &tmp);
|
||||||
|
|
||||||
|
if (j != 0) {
|
||||||
|
/* Test secp256k1_ecmult_const_xonly with all curve X coordinates, and xd=NULL. */
|
||||||
|
ret = secp256k1_ecmult_const_xonly(&tmpf, &group[i].x, NULL, &ng, 256, 0);
|
||||||
|
CHECK(ret);
|
||||||
|
CHECK(secp256k1_fe_equal_var(&tmpf, &group[(i * j) % EXHAUSTIVE_TEST_ORDER].x));
|
||||||
|
|
||||||
|
/* Test secp256k1_ecmult_const_xonly with all curve X coordinates, with random xd. */
|
||||||
|
random_fe_non_zero(&xd);
|
||||||
|
secp256k1_fe_mul(&xn, &xd, &group[i].x);
|
||||||
|
ret = secp256k1_ecmult_const_xonly(&tmpf, &xn, &xd, &ng, 256, 0);
|
||||||
|
CHECK(ret);
|
||||||
|
CHECK(secp256k1_fe_equal_var(&tmpf, &group[(i * j) % EXHAUSTIVE_TEST_ORDER].x));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
212
src/wycheproof/WYCHEPROOF_COPYING
Normal file
212
src/wycheproof/WYCHEPROOF_COPYING
Normal file
|
@ -0,0 +1,212 @@
|
||||||
|
* The file `ecdsa_secp256k1_sha256_bitcoin_test.json` in this directory
|
||||||
|
comes from Google's project Wycheproof with git commit
|
||||||
|
`b063b4aedae951c69df014cd25fa6d69ae9e8cb9`, see
|
||||||
|
https://github.com/google/wycheproof/blob/b063b4aedae951c69df014cd25fa6d69ae9e8cb9/testvectors_v1/ecdsa_secp256k1_sha256_bitcoin_test.json
|
||||||
|
|
||||||
|
* The file `ecdsa_secp256k1_sha256_bitcoin_test.h` is generated from
|
||||||
|
`ecdsa_secp256k1_sha256_bitcoin_test.json` using the script
|
||||||
|
`tests_wycheproof_generate.py`.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
1564
src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h
Normal file
1564
src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.h
Normal file
File diff suppressed because one or more lines are too long
6360
src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.json
Normal file
6360
src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.json
Normal file
File diff suppressed because one or more lines are too long
114
tools/tests_wycheproof_generate.py
Executable file
114
tools/tests_wycheproof_generate.py
Executable file
|
@ -0,0 +1,114 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# Copyright (c) 2023 Random "Randy" Lattice and Sean Andersen
|
||||||
|
# Distributed under the MIT software license, see the accompanying
|
||||||
|
# file COPYING or https://www.opensource.org/licenses/mit-license.php.
|
||||||
|
'''
|
||||||
|
Generate a C file with ECDSA testvectors from the Wycheproof project.
|
||||||
|
'''
|
||||||
|
|
||||||
|
import json
|
||||||
|
import hashlib
|
||||||
|
import urllib.request
|
||||||
|
import sys
|
||||||
|
|
||||||
|
filename_input = sys.argv[1]
|
||||||
|
|
||||||
|
with open(filename_input) as f:
|
||||||
|
doc = json.load(f)
|
||||||
|
|
||||||
|
num_groups = len(doc['testGroups'])
|
||||||
|
|
||||||
|
def to_c_array(x):
|
||||||
|
if x == "": return ""
|
||||||
|
s = ',0x'.join(a+b for a,b in zip(x[::2], x[1::2]))
|
||||||
|
return "0x" + s
|
||||||
|
|
||||||
|
|
||||||
|
num_vectors = 0
|
||||||
|
offset_msg_running, offset_pk_running, offset_sig = 0, 0, 0
|
||||||
|
out = ""
|
||||||
|
messages = ""
|
||||||
|
signatures = ""
|
||||||
|
public_keys = ""
|
||||||
|
cache_msgs = {}
|
||||||
|
cache_public_keys = {}
|
||||||
|
|
||||||
|
for i in range(num_groups):
|
||||||
|
group = doc['testGroups'][i]
|
||||||
|
num_tests = len(group['tests'])
|
||||||
|
public_key = group['publicKey']
|
||||||
|
for j in range(num_tests):
|
||||||
|
test_vector = group['tests'][j]
|
||||||
|
# // 2 to convert hex to byte length
|
||||||
|
sig_size = len(test_vector['sig']) // 2
|
||||||
|
msg_size = len(test_vector['msg']) // 2
|
||||||
|
|
||||||
|
if test_vector['result'] == "invalid": expected_verify = 0
|
||||||
|
elif test_vector['result'] == "valid": expected_verify = 1
|
||||||
|
else: raise ValueError("invalid result field")
|
||||||
|
|
||||||
|
if num_vectors != 0 and sig_size != 0: signatures += ",\n "
|
||||||
|
|
||||||
|
new_msg = False
|
||||||
|
msg = to_c_array(test_vector['msg'])
|
||||||
|
msg_offset = offset_msg_running
|
||||||
|
# check for repeated msg
|
||||||
|
if msg not in cache_msgs.keys():
|
||||||
|
if num_vectors != 0 and msg_size != 0: messages += ",\n "
|
||||||
|
cache_msgs[msg] = offset_msg_running
|
||||||
|
messages += msg
|
||||||
|
new_msg = True
|
||||||
|
else:
|
||||||
|
msg_offset = cache_msgs[msg]
|
||||||
|
|
||||||
|
new_pk = False
|
||||||
|
pk = to_c_array(public_key['uncompressed'])
|
||||||
|
pk_offset = offset_pk_running
|
||||||
|
# check for repeated pk
|
||||||
|
if pk not in cache_public_keys.keys():
|
||||||
|
if num_vectors != 0: public_keys += ",\n "
|
||||||
|
cache_public_keys[pk] = offset_pk_running
|
||||||
|
public_keys += pk
|
||||||
|
new_pk = True
|
||||||
|
else:
|
||||||
|
pk_offset = cache_public_keys[pk]
|
||||||
|
|
||||||
|
signatures += to_c_array(test_vector['sig'])
|
||||||
|
|
||||||
|
out += " /" + "* tcId: " + str(test_vector['tcId']) + ". " + test_vector['comment'] + " *" + "/\n"
|
||||||
|
out += " {" + "{0}, {1}, {2}, {3}, {4}, {5}".format(
|
||||||
|
pk_offset,
|
||||||
|
msg_offset,
|
||||||
|
msg_size,
|
||||||
|
offset_sig,
|
||||||
|
sig_size,
|
||||||
|
expected_verify) + " },\n"
|
||||||
|
if new_msg: offset_msg_running += msg_size
|
||||||
|
if new_pk: offset_pk_running += 65
|
||||||
|
offset_sig += sig_size
|
||||||
|
num_vectors += 1
|
||||||
|
|
||||||
|
struct_definition = """
|
||||||
|
typedef struct {
|
||||||
|
size_t pk_offset;
|
||||||
|
size_t msg_offset;
|
||||||
|
size_t msg_len;
|
||||||
|
size_t sig_offset;
|
||||||
|
size_t sig_len;
|
||||||
|
int expected_verify;
|
||||||
|
} wycheproof_ecdsa_testvector;
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
print("/* Note: this file was autogenerated using tests_wycheproof_generate.py. Do not edit. */")
|
||||||
|
print("#define SECP256K1_ECDSA_WYCHEPROOF_NUMBER_TESTVECTORS ({})".format(num_vectors))
|
||||||
|
|
||||||
|
print(struct_definition)
|
||||||
|
|
||||||
|
print("static const unsigned char wycheproof_ecdsa_messages[] = { " + messages + "};\n")
|
||||||
|
print("static const unsigned char wycheproof_ecdsa_public_keys[] = { " + public_keys + "};\n")
|
||||||
|
print("static const unsigned char wycheproof_ecdsa_signatures[] = { " + signatures + "};\n")
|
||||||
|
|
||||||
|
print("static const wycheproof_ecdsa_testvector testvectors[SECP256K1_ECDSA_WYCHEPROOF_NUMBER_TESTVECTORS] = {")
|
||||||
|
print(out)
|
||||||
|
print("};")
|
Loading…
Reference in a new issue