mirror of
https://github.com/bitcoin/bitcoin.git
synced 2024-11-19 09:53:47 +01: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
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]
|
||||
|
||||
## [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
|
||||
|
||||
#### 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).
|
||||
|
||||
#### ABI Compatibility
|
||||
|
||||
Due to changes in the API regarding `secp256k1_context_static` described above, the ABI is *not* compatible with previous versions.
|
||||
|
||||
## [0.2.0] - 2022-12-12
|
||||
@ -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`.
|
||||
|
||||
#### ABI Compatibility
|
||||
|
||||
Since this is the first release, we do not compare application binary interfaces.
|
||||
However, there are earlier unreleased versions of libsecp256k1 that are *not* ABI compatible with this version.
|
||||
|
||||
@ -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).
|
||||
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.2.0]: https://github.com/bitcoin-core/secp256k1/compare/423b6d19d373f1224fd671a982584d7e7900bc93..v0.2.0
|
||||
[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)
|
||||
# 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 API. All changes in experimental modules are treated as
|
||||
# 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
|
||||
# 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
|
||||
# interface and therefore only increase the revision.
|
||||
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(CMAKE_C_STANDARD 90)
|
||||
@ -147,7 +147,7 @@ else()
|
||||
endif()
|
||||
|
||||
# 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."
|
||||
FORCE
|
||||
)
|
||||
@ -203,11 +203,6 @@ else()
|
||||
try_add_compile_option(-Wundef)
|
||||
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)
|
||||
|
||||
# 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
|
||||
include src/modules/schnorrsig/Makefile.am.include
|
||||
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).
|
||||
if [ -z "$HOST" ]
|
||||
then
|
||||
make clean-precomp
|
||||
make precomp
|
||||
make clean-precomp clean-testvectors
|
||||
make precomp testvectors
|
||||
fi
|
||||
|
||||
# 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.
|
||||
define(_PKG_VERSION_MAJOR, 0)
|
||||
define(_PKG_VERSION_MINOR, 3)
|
||||
define(_PKG_VERSION_PATCH, 0)
|
||||
define(_PKG_VERSION_IS_RELEASE, true)
|
||||
define(_PKG_VERSION_PATCH, 2)
|
||||
define(_PKG_VERSION_IS_RELEASE, false)
|
||||
|
||||
# The library version is based on libtool versioning of the ABI. The set of
|
||||
# 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
|
||||
# interface and therefore only increase the revision.
|
||||
define(_LIB_VERSION_CURRENT, 2)
|
||||
define(_LIB_VERSION_REVISION, 0)
|
||||
define(_LIB_VERSION_REVISION, 2)
|
||||
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])
|
||||
@ -29,6 +29,11 @@ AM_INIT_AUTOMAKE([1.11.2 foreign subdir-objects])
|
||||
# Make the compilation flags quiet unless V=1 is used.
|
||||
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
|
||||
AM_PROG_AS
|
||||
AM_PROG_AR
|
||||
@ -88,11 +93,14 @@ esac
|
||||
AC_DEFUN([SECP_TRY_APPEND_DEFAULT_CFLAGS], [
|
||||
# GCC and compatible (incl. clang)
|
||||
if test "x$GCC" = "xyes"; then
|
||||
# Try to append -Werror=unknown-warning-option to CFLAGS temporarily. Otherwise clang will
|
||||
# not error out if it gets unknown warning flags and the checks here will always succeed
|
||||
# no matter if clang knows the flag or not.
|
||||
# Try to append -Werror to CFLAGS temporarily. Otherwise checks for some unsupported
|
||||
# flags will succeed.
|
||||
# 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_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([-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
|
||||
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DCOVERAGE=1"
|
||||
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"
|
||||
else
|
||||
# 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
|
||||
|
||||
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
|
||||
* updates `_PKG_VERSION_*`, `_LIB_VERSION_*`, and sets `_PKG_VERSION_IS_RELEASE` to `true` in `configure.ac`.
|
||||
* finalizes the release notes in [CHANGELOG.md](../CHANGELOG.md) (make sure to include an entry for `### ABI Compatibility`),
|
||||
* 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:
|
||||
```
|
||||
RELEASE_COMMIT=<merge commit of step 1>
|
||||
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
|
||||
```
|
||||
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).
|
||||
|
||||
## 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
|
||||
* includes the bugfixes,
|
||||
* 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:
|
||||
```
|
||||
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
|
||||
* randomization can take non-negligible time.
|
||||
*/
|
||||
SECP256K1_API secp256k1_context* secp256k1_context_create(
|
||||
SECP256K1_API secp256k1_context *secp256k1_context_create(
|
||||
unsigned int flags
|
||||
) SECP256K1_WARN_UNUSED_RESULT;
|
||||
|
||||
@ -304,8 +304,8 @@ SECP256K1_API secp256k1_context* secp256k1_context_create(
|
||||
* Returns: a newly created context object.
|
||||
* Args: ctx: an existing context to copy (not secp256k1_context_static)
|
||||
*/
|
||||
SECP256K1_API secp256k1_context* secp256k1_context_clone(
|
||||
const secp256k1_context* ctx
|
||||
SECP256K1_API secp256k1_context *secp256k1_context_clone(
|
||||
const secp256k1_context *ctx
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT;
|
||||
|
||||
/** 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).
|
||||
*/
|
||||
SECP256K1_API void secp256k1_context_destroy(
|
||||
secp256k1_context* ctx
|
||||
secp256k1_context *ctx
|
||||
) SECP256K1_ARG_NONNULL(1);
|
||||
|
||||
/** 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
|
||||
* has been configured with --enable-external-default-callbacks. Then the
|
||||
* following two symbols must be provided to link against:
|
||||
* - 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_illegal_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
|
||||
* 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
|
||||
@ -364,9 +364,9 @@ SECP256K1_API void secp256k1_context_destroy(
|
||||
* See also secp256k1_context_set_error_callback.
|
||||
*/
|
||||
SECP256K1_API void secp256k1_context_set_illegal_callback(
|
||||
secp256k1_context* ctx,
|
||||
void (*fun)(const char* message, void* data),
|
||||
const void* data
|
||||
secp256k1_context *ctx,
|
||||
void (*fun)(const char *message, void *data),
|
||||
const void *data
|
||||
) SECP256K1_ARG_NONNULL(1);
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
SECP256K1_API void secp256k1_context_set_error_callback(
|
||||
secp256k1_context* ctx,
|
||||
void (*fun)(const char* message, void* data),
|
||||
const void* data
|
||||
secp256k1_context *ctx,
|
||||
void (*fun)(const char *message, void *data),
|
||||
const void *data
|
||||
) SECP256K1_ARG_NONNULL(1);
|
||||
|
||||
/** 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
|
||||
* (<100 bytes) will be allocated for extra accounting.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT secp256k1_scratch_space* secp256k1_scratch_space_create(
|
||||
const secp256k1_context* ctx,
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT secp256k1_scratch_space *secp256k1_scratch_space_create(
|
||||
const secp256k1_context *ctx,
|
||||
size_t size
|
||||
) SECP256K1_ARG_NONNULL(1);
|
||||
|
||||
@ -416,8 +416,8 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT secp256k1_scratch_space* secp256k1_sc
|
||||
* scratch: space to destroy
|
||||
*/
|
||||
SECP256K1_API void secp256k1_scratch_space_destroy(
|
||||
const secp256k1_context* ctx,
|
||||
secp256k1_scratch_space* scratch
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_scratch_space *scratch
|
||||
) SECP256K1_ARG_NONNULL(1);
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse(
|
||||
const secp256k1_context* ctx,
|
||||
secp256k1_pubkey* pubkey,
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_pubkey *pubkey,
|
||||
const unsigned char *input,
|
||||
size_t inputlen
|
||||
) 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.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ec_pubkey_serialize(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *output,
|
||||
size_t *outputlen,
|
||||
const secp256k1_pubkey* pubkey,
|
||||
const secp256k1_pubkey *pubkey,
|
||||
unsigned int flags
|
||||
) 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
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_cmp(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_pubkey* pubkey1,
|
||||
const secp256k1_pubkey* pubkey2
|
||||
const secp256k1_context *ctx,
|
||||
const secp256k1_pubkey *pubkey1,
|
||||
const secp256k1_pubkey *pubkey2
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ecdsa_signature_parse_compact(
|
||||
const secp256k1_context* ctx,
|
||||
secp256k1_ecdsa_signature* sig,
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_ecdsa_signature *sig,
|
||||
const unsigned char *input64
|
||||
) 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.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ecdsa_signature_parse_der(
|
||||
const secp256k1_context* ctx,
|
||||
secp256k1_ecdsa_signature* sig,
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_ecdsa_signature *sig,
|
||||
const unsigned char *input,
|
||||
size_t inputlen
|
||||
) 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
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ecdsa_signature_serialize_der(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *output,
|
||||
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);
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ecdsa_signature_serialize_compact(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
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);
|
||||
|
||||
/** Verify an ECDSA signature.
|
||||
@ -581,7 +581,7 @@ SECP256K1_API int secp256k1_ecdsa_signature_serialize_compact(
|
||||
* For details, see the comments for that function.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
const secp256k1_ecdsa_signature *sig,
|
||||
const unsigned char *msghash32,
|
||||
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_API int secp256k1_ecdsa_signature_normalize(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_ecdsa_signature *sigout,
|
||||
const secp256k1_ecdsa_signature *sigin
|
||||
) 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_API int secp256k1_ecdsa_sign(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_ecdsa_signature *sig,
|
||||
const unsigned char *msghash32,
|
||||
const unsigned char *seckey,
|
||||
@ -683,7 +683,7 @@ SECP256K1_API int secp256k1_ecdsa_sign(
|
||||
* In: seckey: pointer to a 32-byte secret key.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
const unsigned char *seckey
|
||||
) 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.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_pubkey *pubkey,
|
||||
const unsigned char *seckey
|
||||
) 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.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_negate(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *seckey
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
|
||||
|
||||
/** Same as secp256k1_ec_seckey_negate, but DEPRECATED. Will be removed in
|
||||
* future versions. */
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_negate(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *seckey
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2)
|
||||
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.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_negate(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_pubkey *pubkey
|
||||
) 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).
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_add(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *seckey,
|
||||
const unsigned char *tweak32
|
||||
) 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
|
||||
* future versions. */
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *seckey,
|
||||
const unsigned char *tweak32
|
||||
) 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).
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_pubkey *pubkey,
|
||||
const unsigned char *tweak32
|
||||
) 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).
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_mul(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *seckey,
|
||||
const unsigned char *tweak32
|
||||
) 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
|
||||
* future versions. */
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *seckey,
|
||||
const unsigned char *tweak32
|
||||
) 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).
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_pubkey *pubkey,
|
||||
const unsigned char *tweak32
|
||||
) 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.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize(
|
||||
secp256k1_context* ctx,
|
||||
secp256k1_context *ctx,
|
||||
const unsigned char *seed32
|
||||
) 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).
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_combine(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_pubkey *out,
|
||||
const secp256k1_pubkey * const * ins,
|
||||
const secp256k1_pubkey * const *ins,
|
||||
size_t n
|
||||
) 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
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_tagged_sha256(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *hash32,
|
||||
const unsigned char *tag,
|
||||
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).
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdh(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *output,
|
||||
const secp256k1_pubkey *pubkey,
|
||||
const unsigned char *seckey,
|
||||
|
@ -45,8 +45,8 @@ typedef struct {
|
||||
* In: input32: pointer to a serialized xonly_pubkey.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_parse(
|
||||
const secp256k1_context* ctx,
|
||||
secp256k1_xonly_pubkey* pubkey,
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_xonly_pubkey *pubkey,
|
||||
const unsigned char *input32
|
||||
) 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.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_xonly_pubkey_serialize(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
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);
|
||||
|
||||
/** 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
|
||||
*/
|
||||
SECP256K1_API int secp256k1_xonly_pubkey_cmp(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_xonly_pubkey* pk1,
|
||||
const secp256k1_xonly_pubkey* pk2
|
||||
const secp256k1_context *ctx,
|
||||
const secp256k1_xonly_pubkey *pk1,
|
||||
const secp256k1_xonly_pubkey *pk2
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
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,
|
||||
int *pk_parity,
|
||||
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).
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_pubkey *output_pubkey,
|
||||
const secp256k1_xonly_pubkey *internal_pubkey,
|
||||
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.
|
||||
*/
|
||||
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,
|
||||
int tweaked_pk_parity,
|
||||
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.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_create(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_keypair *keypair,
|
||||
const unsigned char *seckey
|
||||
) 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.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_sec(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *seckey,
|
||||
const secp256k1_keypair *keypair
|
||||
) 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.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_pub(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_pubkey *pubkey,
|
||||
const secp256k1_keypair *keypair
|
||||
) 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.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_pub(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_xonly_pubkey *pubkey,
|
||||
int *pk_parity,
|
||||
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).
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_tweak_add(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_keypair *keypair,
|
||||
const unsigned char *tweak32
|
||||
) 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)
|
||||
* and secp256k1_context_preallocated_destroy.
|
||||
*/
|
||||
SECP256K1_API secp256k1_context* secp256k1_context_preallocated_create(
|
||||
void* prealloc,
|
||||
SECP256K1_API secp256k1_context *secp256k1_context_preallocated_create(
|
||||
void *prealloc,
|
||||
unsigned int flags
|
||||
) 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.
|
||||
*/
|
||||
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;
|
||||
|
||||
/** 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)
|
||||
* bytes, as detailed above.
|
||||
*/
|
||||
SECP256K1_API secp256k1_context* secp256k1_context_preallocated_clone(
|
||||
const secp256k1_context* ctx,
|
||||
void* prealloc
|
||||
SECP256K1_API secp256k1_context *secp256k1_context_preallocated_clone(
|
||||
const secp256k1_context *ctx,
|
||||
void *prealloc
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_WARN_UNUSED_RESULT;
|
||||
|
||||
/** 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).
|
||||
*/
|
||||
SECP256K1_API void secp256k1_context_preallocated_destroy(
|
||||
secp256k1_context* ctx
|
||||
secp256k1_context *ctx
|
||||
) SECP256K1_ARG_NONNULL(1);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -34,8 +34,8 @@ typedef struct {
|
||||
* recid: the recovery id (0, 1, 2 or 3)
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_parse_compact(
|
||||
const secp256k1_context* ctx,
|
||||
secp256k1_ecdsa_recoverable_signature* sig,
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_ecdsa_recoverable_signature *sig,
|
||||
const unsigned char *input64,
|
||||
int recid
|
||||
) 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.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_convert(
|
||||
const secp256k1_context* ctx,
|
||||
secp256k1_ecdsa_signature* sig,
|
||||
const secp256k1_ecdsa_recoverable_signature* sigin
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_ecdsa_signature *sig,
|
||||
const secp256k1_ecdsa_recoverable_signature *sigin
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_serialize_compact(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *output64,
|
||||
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);
|
||||
|
||||
/** 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).
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ecdsa_sign_recoverable(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_ecdsa_recoverable_signature *sig,
|
||||
const unsigned char *msghash32,
|
||||
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.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
secp256k1_pubkey *pubkey,
|
||||
const secp256k1_ecdsa_recoverable_signature *sig,
|
||||
const unsigned char *msghash32
|
||||
|
@ -82,7 +82,7 @@ SECP256K1_API_VAR const secp256k1_nonce_function_hardened secp256k1_nonce_functi
|
||||
typedef struct {
|
||||
unsigned char magic[4];
|
||||
secp256k1_nonce_function_hardened noncefp;
|
||||
void* ndata;
|
||||
void *ndata;
|
||||
} secp256k1_schnorrsig_extraparams;
|
||||
|
||||
#define SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC { 0xda, 0x6f, 0xb3, 0x8c }
|
||||
@ -117,7 +117,7 @@ typedef struct {
|
||||
* argument and for guidance if randomness is expensive.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_schnorrsig_sign32(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *sig64,
|
||||
const unsigned char *msg32,
|
||||
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
|
||||
* future versions. */
|
||||
SECP256K1_API int secp256k1_schnorrsig_sign(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *sig64,
|
||||
const unsigned char *msg32,
|
||||
const secp256k1_keypair *keypair,
|
||||
@ -149,7 +149,7 @@ SECP256K1_API int secp256k1_schnorrsig_sign(
|
||||
* extraparams: pointer to a extraparams object (can be NULL)
|
||||
*/
|
||||
SECP256K1_API int secp256k1_schnorrsig_sign_custom(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_context *ctx,
|
||||
unsigned char *sig64,
|
||||
const unsigned char *msg,
|
||||
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)
|
||||
*/
|
||||
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 *msg,
|
||||
size_t msglen,
|
||||
|
@ -29,6 +29,7 @@ Note:
|
||||
.align 2
|
||||
.global secp256k1_fe_mul_inner
|
||||
.type secp256k1_fe_mul_inner, %function
|
||||
.hidden secp256k1_fe_mul_inner
|
||||
@ Arguments:
|
||||
@ r0 r Restrict: can overlap with a, not with b
|
||||
@ r1 a
|
||||
@ -516,6 +517,7 @@ secp256k1_fe_mul_inner:
|
||||
.align 2
|
||||
.global secp256k1_fe_sqr_inner
|
||||
.type secp256k1_fe_sqr_inner, %function
|
||||
.hidden secp256k1_fe_sqr_inner
|
||||
@ Arguments:
|
||||
@ r0 r Can overlap with 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);
|
||||
|
||||
/**
|
||||
* 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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
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 */
|
||||
|
@ -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]);
|
||||
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.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
#define SECP256K1_ECMULT_TABLE_VERIFY(n,w) \
|
||||
VERIFY_CHECK(((n) & 1) == 1); \
|
||||
VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \
|
||||
SECP256K1_INLINE static void secp256k1_ecmult_table_verify(int n, int w) {
|
||||
(void)n;
|
||||
(void)w;
|
||||
VERIFY_CHECK(((n) & 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_ECMULT_TABLE_VERIFY(n,w)
|
||||
secp256k1_ecmult_table_verify(n,w);
|
||||
if (n > 0) {
|
||||
*r = pre[(n-1)/2];
|
||||
} 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_ECMULT_TABLE_VERIFY(n,w)
|
||||
secp256k1_ecmult_table_verify(n,w);
|
||||
if (n > 0) {
|
||||
secp256k1_ge_set_xy(r, &x[(n-1)/2], &pre[(n-1)/2].y);
|
||||
} 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_ECMULT_TABLE_VERIFY(n,w)
|
||||
secp256k1_ecmult_table_verify(n,w);
|
||||
if (n > 0) {
|
||||
secp256k1_ge_from_storage(r, &pre[(n-1)/2]);
|
||||
} 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) {
|
||||
uint32_t mask0, mask1;
|
||||
volatile int vflag = flag;
|
||||
SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n));
|
||||
mask0 = flag + ~((uint32_t)0);
|
||||
mask0 = vflag + ~((uint32_t)0);
|
||||
mask1 = ~mask0;
|
||||
r->n[0] = (r->n[0] & mask0) | (a->n[0] & 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) {
|
||||
uint32_t mask0, mask1;
|
||||
volatile int vflag = flag;
|
||||
SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n));
|
||||
mask0 = flag + ~((uint32_t)0);
|
||||
mask0 = vflag + ~((uint32_t)0);
|
||||
mask1 = ~mask0;
|
||||
r->n[0] = (r->n[0] & mask0) | (a->n[0] & 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_fe_from_signed30(r, &s);
|
||||
|
||||
#ifdef VERIFY
|
||||
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) {
|
||||
@ -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_fe_from_signed30(r, &s);
|
||||
|
||||
#ifdef VERIFY
|
||||
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) {
|
||||
|
@ -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) {
|
||||
uint64_t mask0, mask1;
|
||||
volatile int vflag = flag;
|
||||
SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n));
|
||||
mask0 = flag + ~((uint64_t)0);
|
||||
mask0 = vflag + ~((uint64_t)0);
|
||||
mask1 = ~mask0;
|
||||
r->n[0] = (r->n[0] & mask0) | (a->n[0] & 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) {
|
||||
uint64_t mask0, mask1;
|
||||
volatile int vflag = flag;
|
||||
SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n));
|
||||
mask0 = flag + ~((uint64_t)0);
|
||||
mask0 = vflag + ~((uint64_t)0);
|
||||
mask1 = ~mask0;
|
||||
r->n[0] = (r->n[0] & mask0) | (a->n[0] & 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(sign == 1 || sign == -1);
|
||||
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
|
||||
|
@ -232,7 +232,7 @@ static int32_t secp256k1_modinv32_divsteps_30(int32_t zeta, uint32_t f0, uint32_
|
||||
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] = {
|
||||
0xFF, 0x55, 0x33, 0x49, 0xC7, 0x5D, 0x3B, 0x11, 0x0F, 0xE5, 0xC3, 0x59,
|
||||
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) {
|
||||
uint64_t mask0, mask1;
|
||||
volatile int vflag = flag;
|
||||
SECP256K1_CHECKMEM_CHECK_VERIFY(r->d, sizeof(r->d));
|
||||
mask0 = flag + ~((uint64_t)0);
|
||||
mask0 = vflag + ~((uint64_t)0);
|
||||
mask1 = ~mask0;
|
||||
r->d[0] = (r->d[0] & mask0) | (a->d[0] & 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) {
|
||||
uint32_t mask0, mask1;
|
||||
volatile int vflag = flag;
|
||||
SECP256K1_CHECKMEM_CHECK_VERIFY(r->d, sizeof(r->d));
|
||||
mask0 = flag + ~((uint32_t)0);
|
||||
mask0 = vflag + ~((uint32_t)0);
|
||||
mask1 = ~mask0;
|
||||
r->d[0] = (r->d[0] & mask0) | (a->d[0] & 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) {
|
||||
uint32_t mask0, mask1;
|
||||
volatile int vflag = flag;
|
||||
SECP256K1_CHECKMEM_CHECK_VERIFY(r, sizeof(*r));
|
||||
mask0 = flag + ~((uint32_t)0);
|
||||
mask0 = vflag + ~((uint32_t)0);
|
||||
mask1 = ~mask0;
|
||||
*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);
|
||||
}
|
||||
|
||||
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) {
|
||||
/* Check known result (randomly generated test problem from sage) */
|
||||
const secp256k1_scalar scalar = SECP256K1_SCALAR_CONST(
|
||||
@ -4483,6 +4545,7 @@ static void run_ecmult_const_tests(void) {
|
||||
ecmult_const_random_mult();
|
||||
ecmult_const_commutativity();
|
||||
ecmult_const_chain_multiply();
|
||||
ecmult_const_mult_xonly();
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
@ -7306,6 +7369,44 @@ static void run_ecdsa_edge_cases(void) {
|
||||
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
|
||||
# include "modules/ecdh/tests_impl.h"
|
||||
#endif
|
||||
@ -7638,6 +7739,7 @@ int main(int argc, char **argv) {
|
||||
run_ecdsa_sign_verify();
|
||||
run_ecdsa_end_to_end();
|
||||
run_ecdsa_edge_cases();
|
||||
run_ecdsa_wycheproof();
|
||||
|
||||
#ifdef ENABLE_MODULE_RECOVERY
|
||||
/* ECDSA pubkey recovery tests */
|
||||
|
@ -59,6 +59,19 @@ static void random_fe(secp256k1_fe *x) {
|
||||
}
|
||||
} 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 */
|
||||
|
||||
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);
|
||||
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 New Issue
Block a user