diff --git a/secp256k1-zkp-sys/build.rs b/secp256k1-zkp-sys/build.rs index ccd7e857..be4eacce 100644 --- a/secp256k1-zkp-sys/build.rs +++ b/secp256k1-zkp-sys/build.rs @@ -41,6 +41,7 @@ fn main() { .define("ENABLE_MODULE_SURJECTIONPROOF", Some("1")) .define("ENABLE_MODULE_GENERATOR", Some("1")) .define("ENABLE_MODULE_RANGEPROOF", Some("1")) + .define("ENABLE_MODULE_ECDSA_ADAPTOR", Some("1")) .define("ECMULT_GEN_PREC_BITS", Some("4")) // TODO these three should be changed to use libgmp, at least until secp PR 290 is merged .define("USE_NUM_NONE", Some("1")) diff --git a/secp256k1-zkp-sys/depend/secp256k1-HEAD-revision.txt b/secp256k1-zkp-sys/depend/secp256k1-HEAD-revision.txt index 91ea4ec9..a498b2f3 100644 --- a/secp256k1-zkp-sys/depend/secp256k1-HEAD-revision.txt +++ b/secp256k1-zkp-sys/depend/secp256k1-HEAD-revision.txt @@ -1,2 +1,2 @@ # This file was automatically created by ./vendor-libsecp.sh -0129b77767ea001e5693e39ac6deecea0c461817 +f3708a1ecb445b1b05a0f8fcd1da6a88f83d89c4 diff --git a/secp256k1-zkp-sys/depend/secp256k1/.cirrus.yml b/secp256k1-zkp-sys/depend/secp256k1/.cirrus.yml new file mode 100644 index 00000000..28a5d323 --- /dev/null +++ b/secp256k1-zkp-sys/depend/secp256k1/.cirrus.yml @@ -0,0 +1,241 @@ +env: + WIDEMUL: auto + BIGNUM: auto + STATICPRECOMPUTATION: yes + ECMULTGENPRECISION: auto + ASM: no + BUILD: check + WITH_VALGRIND: yes + RUN_VALGRIND: no + EXTRAFLAGS: + HOST: + ECDH: no + RECOVERY: no + SCHNORRSIG: no + ECDSA_S2C: no + GENERATOR: no + RANGEPROOF: no + WHITELIST: no + MUSIG: no + ECDSAADAPTOR: no + EXPERIMENTAL: no + CTIMETEST: yes + BENCH: yes + ITERS: 2 + MAKEFLAGS: -j2 + +cat_logs_snippet: &CAT_LOGS + always: + cat_tests_log_script: + - cat tests.log || true + cat_exhaustive_tests_log_script: + - cat exhaustive_tests.log || true + cat_valgrind_ctime_test_log_script: + - cat valgrind_ctime_test.log || true + cat_bench_log_script: + - cat bench.log || true + on_failure: + cat_config_log_script: + - cat config.log || true + cat_test_env_script: + - cat test_env.log || true + cat_ci_env_script: + - env + +merge_base_script_snippet: &MERGE_BASE + merge_base_script: + - if [ "$CIRRUS_PR" = "" ]; then exit 0; fi + - git fetch $CIRRUS_REPO_CLONE_URL $CIRRUS_BASE_BRANCH + - git config --global user.email "ci@ci.ci" + - git config --global user.name "ci" + - git merge FETCH_HEAD # Merge base to detect silent merge conflicts + +task: + name: "x86_64: Linux (Debian stable)" + container: + dockerfile: ci/linux-debian.Dockerfile + # Reduce number of CPUs to be able to do more builds in parallel. + cpu: 1 + # More than enough for our scripts. + memory: 1G + matrix: &ENV_MATRIX + - env: {WIDEMUL: int64, RECOVERY: yes} + - env: {WIDEMUL: int64, ECDH: yes, EXPERIMENTAL: yes, SCHNORRSIG: yes, ECDSA_S2C: yes, RANGEPROOF: yes, WHITELIST: yes, GENERATOR: yes, MUSIG: yes, ECDSAADAPTOR: yes} + - env: {WIDEMUL: int128} + - env: {WIDEMUL: int128, RECOVERY: yes, EXPERIMENTAL: yes, SCHNORRSIG: yes} + - env: {WIDEMUL: int128, ECDH: yes, EXPERIMENTAL: yes, SCHNORRSIG: yes, ECDSA_S2C: yes, RANGEPROOF: yes, WHITELIST: yes, GENERATOR: yes, MUSIG: yes, ECDSAADAPTOR: yes} + - env: {WIDEMUL: int128, ASM: x86_64} + - env: {BIGNUM: no} + - env: {BIGNUM: no, RECOVERY: yes, EXPERIMENTAL: yes, SCHNORRSIG: yes, ECDSA_S2C: yes, RANGEPROOF: yes, WHITELIST: yes, GENERATOR: yes, MUSIG: yes, ECDSAADAPTOR: yes} + - env: {BIGNUM: no, STATICPRECOMPUTATION: no} + - env: {BUILD: distcheck, WITH_VALGRIND: no, CTIMETEST: no, BENCH: no} + - env: {CPPFLAGS: -DDETERMINISTIC} + - env: {CFLAGS: -O0, CTIMETEST: no} + - env: + CFLAGS: "-fsanitize=undefined -fno-omit-frame-pointer" + LDFLAGS: "-fsanitize=undefined -fno-omit-frame-pointer" + UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1" + BIGNUM: no + ASM: x86_64 + ECDH: yes + RECOVERY: yes + EXPERIMENTAL: yes + SCHNORRSIG: yes + ECDSA_S2C: yes + RANGEPROOF: yes + WHITELIST: yes + GENERATOR: yes + MUSIG: yes + ECDSAADAPTOR: yes + CTIMETEST: no + - env: { ECMULTGENPRECISION: 2 } + - env: { ECMULTGENPRECISION: 8 } + - env: + RUN_VALGRIND: yes + BIGNUM: no + ASM: x86_64 + ECDH: yes + RECOVERY: yes + EXPERIMENTAL: yes + SCHNORRSIG: yes + ECDSA_S2C: yes + RANGEPROOF: yes + WHITELIST: yes + GENERATOR: yes + MUSIG: yes + ECDSAADAPTOR: yes + EXTRAFLAGS: "--disable-openssl-tests" + BUILD: + matrix: + - env: + CC: gcc + - env: + CC: clang + << : *MERGE_BASE + test_script: + - ./ci/cirrus.sh + << : *CAT_LOGS + +task: + name: "i686: Linux (Debian stable)" + container: + dockerfile: ci/linux-debian.Dockerfile + cpu: 1 + memory: 1G + env: + HOST: i686-linux-gnu + ECDH: yes + RECOVERY: yes + EXPERIMENTAL: yes + SCHNORRSIG: yes + ECDSA_S2C: yes + RANGEPROOF: yes + WHITELIST: yes + GENERATOR: yes + MUSIG: yes + ECDSAADAPTOR: yes + matrix: + - env: + CC: i686-linux-gnu-gcc + - env: + CC: clang --target=i686-pc-linux-gnu -isystem /usr/i686-linux-gnu/include + matrix: + - env: + BIGNUM: gmp + - env: + BIGNUM: no + << : *MERGE_BASE + test_script: + - ./ci/cirrus.sh + << : *CAT_LOGS + +task: + name: "x86_64: macOS Catalina" + macos_instance: + image: catalina-base + # As of d4ca81f48e tasks with valgrind enabled take about 60 minutes + timeout_in: 90m + env: + HOMEBREW_NO_AUTO_UPDATE: 1 + HOMEBREW_NO_INSTALL_CLEANUP: 1 + # Cirrus gives us a fixed number of 12 virtual CPUs. Not that we even have that many jobs at the moment... + MAKEFLAGS: -j13 + matrix: + << : *ENV_MATRIX + matrix: + - env: + CC: gcc-9 + - env: + CC: clang + # Update Command Line Tools + # Uncomment this if the Command Line Tools on the CirrusCI macOS image are too old to brew valgrind. + # See https://apple.stackexchange.com/a/195963 for the implementation. + ## update_clt_script: + ## - system_profiler SPSoftwareDataType + ## - touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress + ## - |- + ## PROD=$(softwareupdate -l | grep "*.*Command Line" | tail -n 1 | awk -F"*" '{print $2}' | sed -e 's/^ *//' | sed 's/Label: //g' | tr -d '\n') + ## # For debugging + ## - softwareupdate -l && echo "PROD: $PROD" + ## - softwareupdate -i "$PROD" --verbose + ## - rm /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress + ## + brew_valgrind_pre_script: + - brew config + - brew tap --shallow LouisBrunner/valgrind + # Fetch valgrind source but don't build it yet. + - brew fetch --HEAD LouisBrunner/valgrind/valgrind + brew_valgrind_cache: + # This is $(brew --cellar valgrind) but command substition does not work here. + folder: /usr/local/Cellar/valgrind + # Rebuild cache if ... + fingerprint_script: + # ... macOS version changes: + - sw_vers + # ... brew changes: + - brew config + # ... valgrind changes: + - git -C "$(brew --cache)/valgrind--git" rev-parse HEAD + populate_script: + # If there's no hit in the cache, build and install valgrind. + - brew install --HEAD LouisBrunner/valgrind/valgrind + brew_valgrind_post_script: + # If we have restored valgrind from the cache, tell brew to create symlink to the PATH. + # If we haven't restored from cached (and just run brew install), this is a no-op. + - brew link valgrind + brew_script: + - brew install automake libtool gmp gcc@9 + << : *MERGE_BASE + test_script: + - ./ci/cirrus.sh + << : *CAT_LOGS + +task: + name: "s390x (big-endian): Linux (Debian stable, QEMU)" + container: + dockerfile: ci/linux-debian.Dockerfile + cpu: 1 + memory: 1G + env: + QEMU_CMD: qemu-s390x + HOST: s390x-linux-gnu + BUILD: + WITH_VALGRIND: no + BIGNUM: no + ECDH: yes + RECOVERY: yes + EXPERIMENTAL: yes + SCHNORRSIG: yes + ECDSA_S2C: yes + RANGEPROOF: yes + WHITELIST: yes + GENERATOR: yes + MUSIG: yes + ECDSAADAPTOR: yes + CTIMETEST: no + << : *MERGE_BASE + test_script: + # https://sourceware.org/bugzilla/show_bug.cgi?id=27008 + - rm /etc/ld.so.cache + - ./ci/cirrus.sh + << : *CAT_LOGS diff --git a/secp256k1-zkp-sys/depend/secp256k1/.gitignore b/secp256k1-zkp-sys/depend/secp256k1/.gitignore index 085bd54d..cdfad486 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/.gitignore +++ b/secp256k1-zkp-sys/depend/secp256k1/.gitignore @@ -53,3 +53,4 @@ build-aux/compile build-aux/test-driver src/stamp-h1 libsecp256k1.pc +contrib/gh-pr-create.sh diff --git a/secp256k1-zkp-sys/depend/secp256k1/.travis.yml b/secp256k1-zkp-sys/depend/secp256k1/.travis.yml deleted file mode 100644 index 9b7fe6f3..00000000 --- a/secp256k1-zkp-sys/depend/secp256k1/.travis.yml +++ /dev/null @@ -1,111 +0,0 @@ -language: c -os: - - linux - - osx - -dist: bionic -# Valgrind currently supports upto macOS 10.13, the latest xcode of that version is 10.1 -osx_image: xcode10.1 -addons: - apt: - packages: - - libgmp-dev - - valgrind - - libtool-bin -compiler: - - clang - - gcc -env: - global: - - WIDEMUL=auto BIGNUM=auto STATICPRECOMPUTATION=yes ECMULTGENPRECISION=auto ASM=no BUILD=check WITH_VALGRIND=yes RUN_VALGRIND=no EXTRAFLAGS= HOST= ECDH=no RECOVERY=no SCHNORRSIG=no EXPERIMENTAL=no CTIMETEST=yes BENCH=yes ITERS=2 GENERATOR=no RANGEPROOF=no WHITELIST=no SCHNORRSIG=no MUSIG=no - matrix: - - WIDEMUL=int64 EXPERIMENTAL=yes RANGEPROOF=yes WHITELIST=yes GENERATOR=yes SCHNORRSIG=yes MUSIG=yes - - WIDEMUL=int128 EXPERIMENTAL=yes RANGEPROOF=yes WHITELIST=yes GENERATOR=yes SCHNORRSIG=yes MUSIG=yes - - WIDEMUL=int64 RECOVERY=yes - - WIDEMUL=int64 ECDH=yes EXPERIMENTAL=yes SCHNORRSIG=yes MUSIG=yes - - WIDEMUL=int128 - - WIDEMUL=int128 RECOVERY=yes EXPERIMENTAL=yes SCHNORRSIG=yes MUSIG=yes - - WIDEMUL=int128 ECDH=yes EXPERIMENTAL=yes SCHNORRSIG=yes MUSIG=yes - - WIDEMUL=int128 ASM=x86_64 - - BIGNUM=no - - BIGNUM=no RECOVERY=yes EXPERIMENTAL=yes SCHNORRSIG=yes MUSIG=yes - - BIGNUM=no STATICPRECOMPUTATION=no - - BUILD=distcheck WITH_VALGRIND=no CTIMETEST=no BENCH=no - - CPPFLAGS=-DDETERMINISTIC - - CFLAGS=-O0 CTIMETEST=no - - CFLAGS="-fsanitize=undefined -fno-omit-frame-pointer" LDFLAGS="-fsanitize=undefined -fno-omit-frame-pointer" UBSAN_OPTIONS="print_stacktrace=1:halt_on_error=1" BIGNUM=no ASM=x86_64 ECDH=yes RECOVERY=yes EXPERIMENTAL=yes SCHNORRSIG=yes MUSIG=yes CTIMETEST=no - - ECMULTGENPRECISION=2 - - ECMULTGENPRECISION=8 - - RUN_VALGRIND=yes BIGNUM=no ASM=x86_64 ECDH=yes RECOVERY=yes EXPERIMENTAL=yes SCHNORRSIG=yes MUSIG=yes EXTRAFLAGS="--disable-openssl-tests" BUILD= -matrix: - fast_finish: true - include: - - compiler: clang - os: linux - env: HOST=i686-linux-gnu - addons: - apt: - packages: - - gcc-multilib - - libgmp-dev:i386 - - valgrind - - libtool-bin - - libc6-dbg:i386 - - compiler: clang - env: HOST=i686-linux-gnu - os: linux - addons: - apt: - packages: - - gcc-multilib - - valgrind - - libtool-bin - - libc6-dbg:i386 - - compiler: gcc - env: HOST=i686-linux-gnu - os: linux - addons: - apt: - packages: - - gcc-multilib - - valgrind - - libtool-bin - - libc6-dbg:i386 - - compiler: gcc - os: linux - env: HOST=i686-linux-gnu - addons: - apt: - packages: - - gcc-multilib - - libgmp-dev:i386 - - valgrind - - libtool-bin - - libc6-dbg:i386 - # S390x build (big endian system) - - compiler: gcc - env: HOST=s390x-unknown-linux-gnu ECDH=yes RECOVERY=yes EXPERIMENTAL=yes SCHNORRSIG=yes MUSIG=yes CTIMETEST= - arch: s390x - -# We use this to install macOS dependencies instead of the built in `homebrew` plugin, -# because in xcode earlier than 11 they have a bug requiring updating the system which overall takes ~8 minutes. -# https://travis-ci.community/t/macos-build-fails-because-of-homebrew-bundle-unknown-command/7296 -before_install: - - if [ "${TRAVIS_OS_NAME}" = "osx" ]; then HOMEBREW_NO_AUTO_UPDATE=1 brew install gmp valgrind gcc@9; fi - -before_script: ./autogen.sh - -# travis auto terminates jobs that go for 10 minutes without printing to stdout, but travis_wait doesn't work well with forking programs like valgrind (https://docs.travis-ci.com/user/common-build-problems/#build-times-out-because-no-output-was-received https://github.com/bitcoin-core/secp256k1/pull/750#issuecomment-623476860) -script: - - function keep_alive() { while true; do echo -en "\a"; sleep 60; done } - - keep_alive & - - ./contrib/travis.sh - - kill %keep_alive - -after_script: - - cat ./tests.log - - cat ./exhaustive_tests.log - - cat ./valgrind_ctime_test.log - - cat ./bench.log - - $CC --version - - valgrind --version diff --git a/secp256k1-zkp-sys/depend/secp256k1/Makefile.am b/secp256k1-zkp-sys/depend/secp256k1/Makefile.am index 03af169e..8aac4480 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/Makefile.am +++ b/secp256k1-zkp-sys/depend/secp256k1/Makefile.am @@ -16,6 +16,8 @@ noinst_HEADERS += src/group.h noinst_HEADERS += src/group_impl.h noinst_HEADERS += src/num_gmp.h noinst_HEADERS += src/num_gmp_impl.h +noinst_HEADERS += src/eccommit.h +noinst_HEADERS += src/eccommit_impl.h noinst_HEADERS += src/ecdsa.h noinst_HEADERS += src/ecdsa_impl.h noinst_HEADERS += src/eckey.h @@ -182,3 +184,11 @@ endif if ENABLE_MODULE_SCHNORRSIG include src/modules/schnorrsig/Makefile.am.include endif + +if ENABLE_MODULE_ECDSA_S2C +include src/modules/ecdsa_s2c/Makefile.am.include +endif + +if ENABLE_MODULE_ECDSA_ADAPTOR +include src/modules/ecdsa_adaptor/Makefile.am.include +endif diff --git a/secp256k1-zkp-sys/depend/secp256k1/README.md b/secp256k1-zkp-sys/depend/secp256k1/README.md index e0709372..43dc4238 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/README.md +++ b/secp256k1-zkp-sys/depend/secp256k1/README.md @@ -1,7 +1,7 @@ libsecp256k1 ============ -[![Build Status](https://travis-ci.org/bitcoin-core/secp256k1.svg?branch=master)](https://travis-ci.org/bitcoin-core/secp256k1) +[![Build Status](https://api.cirrus-ci.com/github/bitcoin-core/secp256k1.svg?branch=master)](https://cirrus-ci.com/github/bitcoin-core/secp256k1) Optimized C library for ECDSA signatures and secret/public key operations on curve secp256k1. @@ -17,6 +17,7 @@ Features: * Suitable for embedded systems. * Optional module for public key recovery. * Optional module for ECDH key exchange. +* Optional module for ECDSA adaptor signatures (experimental). Experimental features have not received enough scrutiny to satisfy the standard of quality of this library but are made available for testing and review by the community. The APIs of these features should not be considered stable. diff --git a/secp256k1-zkp-sys/depend/secp256k1/build-aux/m4/ax_prog_cc_for_build.m4 b/secp256k1-zkp-sys/depend/secp256k1/build-aux/m4/ax_prog_cc_for_build.m4 index 77fd346a..7bcbf320 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/build-aux/m4/ax_prog_cc_for_build.m4 +++ b/secp256k1-zkp-sys/depend/secp256k1/build-aux/m4/ax_prog_cc_for_build.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_prog_cc_for_build.html +# https://www.gnu.org/software/autoconf-archive/ax_prog_cc_for_build.html # =========================================================================== # # SYNOPSIS diff --git a/secp256k1-zkp-sys/depend/secp256k1/build-aux/m4/bitcoin_secp.m4 b/secp256k1-zkp-sys/depend/secp256k1/build-aux/m4/bitcoin_secp.m4 index ece3d655..7b48a5e5 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/build-aux/m4/bitcoin_secp.m4 +++ b/secp256k1-zkp-sys/depend/secp256k1/build-aux/m4/bitcoin_secp.m4 @@ -87,3 +87,11 @@ if test x"$has_gmp" != x"yes"; then LIBS="$LIBS_TEMP" fi ]) + +AC_DEFUN([SECP_VALGRIND_CHECK],[ +if test x"$has_valgrind" != x"yes"; then + CPPFLAGS_TEMP="$CPPFLAGS" + CPPFLAGS="$VALGRIND_CPPFLAGS $CPPFLAGS" + AC_CHECK_HEADER([valgrind/memcheck.h], [has_valgrind=yes; AC_DEFINE(HAVE_VALGRIND,1,[Define this symbol if valgrind is installed])]) +fi +]) diff --git a/secp256k1-zkp-sys/depend/secp256k1/contrib/travis.sh b/secp256k1-zkp-sys/depend/secp256k1/ci/cirrus.sh similarity index 65% rename from secp256k1-zkp-sys/depend/secp256k1/contrib/travis.sh rename to secp256k1-zkp-sys/depend/secp256k1/ci/cirrus.sh index c667c151..785a522a 100755 --- a/secp256k1-zkp-sys/depend/secp256k1/contrib/travis.sh +++ b/secp256k1-zkp-sys/depend/secp256k1/ci/cirrus.sh @@ -3,46 +3,65 @@ set -e set -x -if [ "$HOST" = "i686-linux-gnu" ] -then - export CC="$CC -m32" -fi -if [ "$TRAVIS_OS_NAME" = "osx" ] && [ "$TRAVIS_COMPILER" = "gcc" ] -then - export CC="gcc-9" -fi +export LC_ALL=C + +env >> test_env.log + +$CC -v || true +valgrind --version || true + +./autogen.sh ./configure \ --enable-experimental="$EXPERIMENTAL" \ --with-test-override-wide-multiply="$WIDEMUL" --with-bignum="$BIGNUM" --with-asm="$ASM" \ --enable-ecmult-static-precomputation="$STATICPRECOMPUTATION" --with-ecmult-gen-precision="$ECMULTGENPRECISION" \ --enable-module-ecdh="$ECDH" --enable-module-recovery="$RECOVERY" \ + --enable-module-ecdsa-s2c="$ECDSA_S2C" \ --enable-module-rangeproof="$RANGEPROOF" --enable-module-whitelist="$WHITELIST" --enable-module-generator="$GENERATOR" \ - --enable-module-schnorrsig="$SCHNORRSIG" --enable-module-musig="$MUSIG"\ + --enable-module-schnorrsig="$SCHNORRSIG" --enable-module-musig="$MUSIG" --enable-module-ecdsa-adaptor="$ECDSAADAPTOR" \ --with-valgrind="$WITH_VALGRIND" \ --host="$HOST" $EXTRAFLAGS +# We have set "-j" in MAKEFLAGS. +make + +# Print information about binaries so that we can see that the architecture is correct +file *tests || true +file bench_* || true +file .libs/* || true + if [ -n "$BUILD" ] then - make -j2 "$BUILD" + make "$BUILD" fi + if [ "$RUN_VALGRIND" = "yes" ] then - make -j2 - # the `--error-exitcode` is required to make the test fail if valgrind found errors, otherwise it'll return 0 (http://valgrind.org/docs/manual/manual-core.html) + # the `--error-exitcode` is required to make the test fail if valgrind found errors, otherwise it'll return 0 (https://www.valgrind.org/docs/manual/manual-core.html) valgrind --error-exitcode=42 ./tests 16 valgrind --error-exitcode=42 ./exhaustive_tests fi + +if [ -n "$QEMU_CMD" ] +then + $QEMU_CMD ./tests 16 + $QEMU_CMD ./exhaustive_tests +fi + if [ "$BENCH" = "yes" ] then + # Using the local `libtool` because on macOS the system's libtool has nothing to do with GNU libtool + EXEC='./libtool --mode=execute' + if [ -n "$QEMU_CMD" ] + then + EXEC="$EXEC $QEMU_CMD" + fi if [ "$RUN_VALGRIND" = "yes" ] then - # Using the local `libtool` because on macOS the system's libtool has nothing to do with GNU libtool - EXEC='./libtool --mode=execute valgrind --error-exitcode=42' - else - EXEC= + EXEC="$EXEC valgrind --error-exitcode=42" fi - # This limits the iterations in the benchmarks below to ITER(set in .travis.yml) iterations. + # This limits the iterations in the benchmarks below to ITER iterations. export SECP256K1_BENCH_ITERS="$ITERS" { $EXEC ./bench_ecmult diff --git a/secp256k1-zkp-sys/depend/secp256k1/ci/linux-debian.Dockerfile b/secp256k1-zkp-sys/depend/secp256k1/ci/linux-debian.Dockerfile new file mode 100644 index 00000000..201ace4f --- /dev/null +++ b/secp256k1-zkp-sys/depend/secp256k1/ci/linux-debian.Dockerfile @@ -0,0 +1,13 @@ +FROM debian:stable + +RUN dpkg --add-architecture i386 +RUN dpkg --add-architecture s390x +RUN apt-get update + +# dkpg-dev: to make pkg-config work in cross-builds +RUN apt-get install --no-install-recommends --no-upgrade -y \ + git ca-certificates \ + make automake libtool pkg-config dpkg-dev valgrind qemu-user \ + gcc clang libc6-dbg libgmp-dev \ + gcc-i686-linux-gnu libc6-dev-i386-cross libc6-dbg:i386 libgmp-dev:i386 \ + gcc-s390x-linux-gnu libc6-dev-s390x-cross libc6-dbg:s390x diff --git a/secp256k1-zkp-sys/depend/secp256k1/configure.ac b/secp256k1-zkp-sys/depend/secp256k1/configure.ac index f4a341bc..17e52078 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/configure.ac +++ b/secp256k1-zkp-sys/depend/secp256k1/configure.ac @@ -14,7 +14,7 @@ AM_INIT_AUTOMAKE([foreign subdir-objects]) : ${CFLAGS="-g"} LT_INIT -dnl 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])]) PKG_PROG_PKG_CONFIG @@ -22,9 +22,16 @@ PKG_PROG_PKG_CONFIG AC_PATH_TOOL(AR, ar) AC_PATH_TOOL(RANLIB, ranlib) AC_PATH_TOOL(STRIP, strip) -AX_PROG_CC_FOR_BUILD +# Save definition of AC_PROG_CC because AM_PROG_CC_C_O in automake<=1.13 will +# redefine AC_PROG_CC to exit with an error, which avoids the user calling it +# accidently and screwing up the effect of AM_PROG_CC_C_O. However, we'll need +# AC_PROG_CC later on in AX_PROG_CC_FOR_BUILD, where its usage is fine, and +# we'll carefully make sure not to call AC_PROG_CC anywhere else. +m4_copy([AC_PROG_CC], [saved_AC_PROG_CC]) AM_PROG_CC_C_O +# Restore AC_PROG_CC +m4_rename_force([saved_AC_PROG_CC], [AC_PROG_CC]) AC_PROG_CC_C89 if test x"$ac_cv_prog_cc_c89" = x"no"; then @@ -37,12 +44,12 @@ case $host_os in if test x$cross_compiling != xyes; then AC_PATH_PROG([BREW],brew,) if test x$BREW != x; then - dnl These Homebrew packages may be keg-only, meaning that they won't be found - dnl in expected paths because they may conflict with system files. Ask - dnl Homebrew where each one is located, then adjust paths accordingly. - + # These Homebrew packages may be keg-only, meaning that they won't be found + # in expected paths because they may conflict with system files. Ask + # Homebrew where each one is located, then adjust paths accordingly. openssl_prefix=`$BREW --prefix openssl 2>/dev/null` gmp_prefix=`$BREW --prefix gmp 2>/dev/null` + valgrind_prefix=`$BREW --prefix valgrind 2>/dev/null` if test x$openssl_prefix != x; then PKG_CONFIG_PATH="$openssl_prefix/lib/pkgconfig:$PKG_CONFIG_PATH" export PKG_CONFIG_PATH @@ -52,10 +59,13 @@ case $host_os in GMP_CPPFLAGS="-I$gmp_prefix/include" GMP_LIBS="-L$gmp_prefix/lib" fi + if test x$valgrind_prefix != x; then + VALGRIND_CPPFLAGS="-I$valgrind_prefix/include" + fi else AC_PATH_PROG([PORT],port,) - dnl if homebrew isn't installed and macports is, add the macports default paths - dnl as a last resort. + # If homebrew isn't installed and macports is, add the macports default paths + # as a last resort. if test x$PORT != x; then CPPFLAGS="$CPPFLAGS -isystem /opt/local/include" LDFLAGS="$LDFLAGS -L/opt/local/lib" @@ -86,6 +96,10 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[char foo;]])], CFLAGS="$saved_CFLAGS" ]) +### +### Define config arguments +### + AC_ARG_ENABLE(benchmark, AS_HELP_STRING([--enable-benchmark],[compile benchmark [default=yes]]), [use_benchmark=$enableval], @@ -161,6 +175,16 @@ AC_ARG_ENABLE(module_schnorrsig, [enable_module_schnorrsig=$enableval], [enable_module_schnorrsig=no]) +AC_ARG_ENABLE(module_ecdsa_s2c, + AS_HELP_STRING([--enable-module-ecdsa-s2c],[enable ECDSA sign-to-contract module [default=no]]), + [enable_module_ecdsa_s2c=$enableval], + [enable_module_ecdsa_s2c=no]) + +AC_ARG_ENABLE(module_ecdsa-adaptor, + AS_HELP_STRING([--enable-module-ecdsa-adaptor],[enable ECDSA adaptor module [default=no]]), + [enable_module_ecdsa_adaptor=$enableval], + [enable_module_ecdsa_adaptor=no]) + AC_ARG_ENABLE(external_default_callbacks, AS_HELP_STRING([--enable-external-default-callbacks],[enable external default callback functions [default=no]]), [use_external_default_callbacks=$enableval], @@ -176,8 +200,8 @@ AC_ARG_ENABLE(reduced_surjection_proof_size, [use_reduced_surjection_proof_size=$enableval], [use_reduced_surjection_proof_size=no]) -dnl Test-only override of the (autodetected by the C code) "widemul" setting. -dnl Legal values are int64 (for [u]int64_t), int128 (for [unsigned] __int128), and auto (the default). +# Test-only override of the (autodetected by the C code) "widemul" setting. +# Legal values are int64 (for [u]int64_t), int128 (for [unsigned] __int128), and auto (the default). AC_ARG_WITH([test-override-wide-multiply], [] ,[set_widemul=$withval], [set_widemul=auto]) AC_ARG_WITH([bignum], [AS_HELP_STRING([--with-bignum=gmp|no|auto], @@ -207,15 +231,22 @@ AC_ARG_WITH([valgrind], [AS_HELP_STRING([--with-valgrind=yes|no|auto], )], [req_valgrind=$withval], [req_valgrind=auto]) +### +### Handle config options (except for modules) +### + if test x"$req_valgrind" = x"no"; then enable_valgrind=no else - AC_CHECK_HEADER([valgrind/memcheck.h], [enable_valgrind=yes], [ + SECP_VALGRIND_CHECK + if test x"$has_valgrind" != x"yes"; then if test x"$req_valgrind" = x"yes"; then AC_MSG_ERROR([Valgrind support explicitly requested but valgrind/memcheck.h header not available]) fi enable_valgrind=no - ], []) + else + enable_valgrind=yes + fi fi AM_CONDITIONAL([VALGRIND_ENABLED],[test "$enable_valgrind" = "yes"]) @@ -233,61 +264,6 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[void myfunc() {__builtin_popcount(0);}]])], [ AC_MSG_RESULT([no]) ]) -if test x"$use_ecmult_static_precomputation" != x"no"; then - # Temporarily switch to an environment for the native compiler - save_cross_compiling=$cross_compiling - cross_compiling=no - SAVE_CC="$CC" - CC="$CC_FOR_BUILD" - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS_FOR_BUILD" - SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS_FOR_BUILD" - SAVE_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS_FOR_BUILD" - - warn_CFLAGS_FOR_BUILD="-Wall -Wextra -Wno-unused-function" - saved_CFLAGS="$CFLAGS" - CFLAGS="$warn_CFLAGS_FOR_BUILD $CFLAGS" - AC_MSG_CHECKING([if native ${CC_FOR_BUILD} supports ${warn_CFLAGS_FOR_BUILD}]) - AC_COMPILE_IFELSE([AC_LANG_SOURCE([[char foo;]])], - [ AC_MSG_RESULT([yes]) ], - [ AC_MSG_RESULT([no]) - CFLAGS="$saved_CFLAGS" - ]) - - AC_MSG_CHECKING([for working native compiler: ${CC_FOR_BUILD}]) - AC_RUN_IFELSE( - [AC_LANG_PROGRAM([], [])], - [working_native_cc=yes], - [working_native_cc=no],[:]) - - CFLAGS_FOR_BUILD="$CFLAGS" - - # Restore the environment - cross_compiling=$save_cross_compiling - CC="$SAVE_CC" - CFLAGS="$SAVE_CFLAGS" - CPPFLAGS="$SAVE_CPPFLAGS" - LDFLAGS="$SAVE_LDFLAGS" - - if test x"$working_native_cc" = x"no"; then - AC_MSG_RESULT([no]) - set_precomp=no - m4_define([please_set_for_build], [Please set CC_FOR_BUILD, CFLAGS_FOR_BUILD, CPPFLAGS_FOR_BUILD, and/or LDFLAGS_FOR_BUILD.]) - if test x"$use_ecmult_static_precomputation" = x"yes"; then - AC_MSG_ERROR([native compiler ${CC_FOR_BUILD} does not produce working binaries. please_set_for_build]) - else - AC_MSG_WARN([Disabling statically generated ecmult table because the native compiler ${CC_FOR_BUILD} does not produce working binaries. please_set_for_build]) - fi - else - AC_MSG_RESULT([yes]) - set_precomp=yes - fi -else - set_precomp=no -fi - AC_MSG_CHECKING([for __builtin_clzll]) AC_COMPILE_IFELSE([AC_LANG_SOURCE([[void myfunc() { __builtin_clzll(1);}]])], [ AC_MSG_RESULT([yes]);AC_DEFINE(HAVE_BUILTIN_CLZLL,1,[Define this symbol if __builtin_clzll is available]) ], @@ -347,7 +323,7 @@ else esac fi -# select assembly optimization +# Select assembly optimization use_external_asm=no case $set_asm in @@ -364,7 +340,12 @@ no) ;; esac -# select wide multiplication implementation +if test x"$use_external_asm" = x"yes"; then + AC_DEFINE(USE_EXTERNAL_ASM, 1, [Define this symbol if an external (non-inline) assembly implementation is used]) +fi + + +# Select wide multiplication implementation case $set_widemul in int128) AC_DEFINE(USE_FORCE_WIDEMUL_INT128, 1, [Define this symbol to force the use of the (unsigned) __int128 based wide multiplication implementation]) @@ -379,7 +360,7 @@ auto) ;; esac -# select bignum implementation +# Select bignum implementation case $set_bignum in gmp) AC_DEFINE(HAVE_LIBGMP, 1, [Define this symbol if libgmp is installed]) @@ -397,7 +378,7 @@ no) ;; esac -#set ecmult window size +# Set ecmult window size if test x"$req_ecmult_window" = x"auto"; then set_ecmult_window=15 else @@ -419,7 +400,7 @@ case $set_ecmult_window in ;; esac -#set ecmult gen precision +# Set ecmult gen precision if test x"$req_ecmult_gen_precision" = x"auto"; then set_ecmult_gen_precision=4 else @@ -466,10 +447,93 @@ if test x"$set_bignum" = x"gmp"; then SECP_INCLUDES="$SECP_INCLUDES $GMP_CPPFLAGS" fi +if test x"$enable_valgrind" = x"yes"; then + SECP_INCLUDES="$SECP_INCLUDES $VALGRIND_CPPFLAGS" +fi + +# Handle static precomputation (after everything which modifies CFLAGS and friends) +if test x"$use_ecmult_static_precomputation" != x"no"; then + if test x"$cross_compiling" = x"no"; then + set_precomp=yes + if test x"${CC_FOR_BUILD+x}${CFLAGS_FOR_BUILD+x}${CPPFLAGS_FOR_BUILD+x}${LDFLAGS_FOR_BUILD+x}" != x; then + AC_MSG_WARN([CC_FOR_BUILD, CFLAGS_FOR_BUILD, CPPFLAGS_FOR_BUILD, and/or LDFLAGS_FOR_BUILD is set but ignored because we are not cross-compiling.]) + fi + # If we're not cross-compiling, simply use the same compiler for building the static precompation code. + CC_FOR_BUILD="$CC" + CFLAGS_FOR_BUILD="$CFLAGS" + CPPFLAGS_FOR_BUILD="$CPPFLAGS" + LDFLAGS_FOR_BUILD="$LDFLAGS" + else + AX_PROG_CC_FOR_BUILD + + # Temporarily switch to an environment for the native compiler + save_cross_compiling=$cross_compiling + cross_compiling=no + SAVE_CC="$CC" + CC="$CC_FOR_BUILD" + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS_FOR_BUILD" + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS_FOR_BUILD" + SAVE_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS_FOR_BUILD" + + warn_CFLAGS_FOR_BUILD="-Wall -Wextra -Wno-unused-function" + saved_CFLAGS="$CFLAGS" + CFLAGS="$warn_CFLAGS_FOR_BUILD $CFLAGS" + AC_MSG_CHECKING([if native ${CC_FOR_BUILD} supports ${warn_CFLAGS_FOR_BUILD}]) + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[char foo;]])], + [ AC_MSG_RESULT([yes]) ], + [ AC_MSG_RESULT([no]) + CFLAGS="$saved_CFLAGS" + ]) + + AC_MSG_CHECKING([for working native compiler: ${CC_FOR_BUILD}]) + AC_RUN_IFELSE( + [AC_LANG_PROGRAM([], [])], + [working_native_cc=yes], + [working_native_cc=no],[:]) + + CFLAGS_FOR_BUILD="$CFLAGS" + + # Restore the environment + cross_compiling=$save_cross_compiling + CC="$SAVE_CC" + CFLAGS="$SAVE_CFLAGS" + CPPFLAGS="$SAVE_CPPFLAGS" + LDFLAGS="$SAVE_LDFLAGS" + + if test x"$working_native_cc" = x"no"; then + AC_MSG_RESULT([no]) + set_precomp=no + m4_define([please_set_for_build], [Please set CC_FOR_BUILD, CFLAGS_FOR_BUILD, CPPFLAGS_FOR_BUILD, and/or LDFLAGS_FOR_BUILD.]) + if test x"$use_ecmult_static_precomputation" = x"yes"; then + AC_MSG_ERROR([native compiler ${CC_FOR_BUILD} does not produce working binaries. please_set_for_build]) + else + AC_MSG_WARN([Disabling statically generated ecmult table because the native compiler ${CC_FOR_BUILD} does not produce working binaries. please_set_for_build]) + fi + else + AC_MSG_RESULT([yes]) + set_precomp=yes + fi + fi + + AC_SUBST(CC_FOR_BUILD) + AC_SUBST(CFLAGS_FOR_BUILD) + AC_SUBST(CPPFLAGS_FOR_BUILD) + AC_SUBST(LDFLAGS_FOR_BUILD) +else + set_precomp=no +fi + if test x"$set_precomp" = x"yes"; then AC_DEFINE(USE_ECMULT_STATIC_PRECOMPUTATION, 1, [Define this symbol to use a statically generated ecmult table]) fi +### +### Handle module options +### + if test x"$enable_module_ecdh" = x"yes"; then AC_DEFINE(ENABLE_MODULE_ECDH, 1, [Define this symbol to enable the ECDH module]) fi @@ -509,8 +573,8 @@ if test x"$enable_module_extrakeys" = x"yes"; then AC_DEFINE(ENABLE_MODULE_EXTRAKEYS, 1, [Define this symbol to enable the extrakeys module]) fi -if test x"$use_external_asm" = x"yes"; then - AC_DEFINE(USE_EXTERNAL_ASM, 1, [Define this symbol if an external (non-inline) assembly implementation is used]) +if test x"$enable_module_ecdsa_s2c" = x"yes"; then + AC_DEFINE(ENABLE_MODULE_ECDSA_S2C, 1, [Define this symbol to enable the ECDSA sign-to-contract module]) fi if test x"$use_external_default_callbacks" = x"yes"; then @@ -521,6 +585,14 @@ if test x"$use_reduced_surjection_proof_size" = x"yes"; then AC_DEFINE(USE_REDUCED_SURJECTION_PROOF_SIZE, 1, [Define this symbol to reduce SECP256K1_SURJECTIONPROOF_MAX_N_INPUTS to 16, disabling parsing and verification]) fi +if test x"$enable_module_ecdsa_adaptor" = x"yes"; then + AC_DEFINE(ENABLE_MODULE_ECDSA_ADAPTOR, 1, [Define this symbol to enable the ECDSA adaptor module]) +fi + +### +### Check for --enable-experimental if necessary +### + if test x"$enable_experimental" = x"yes"; then AC_MSG_NOTICE([******]) AC_MSG_NOTICE([WARNING: experimental build]) @@ -532,6 +604,8 @@ if test x"$enable_experimental" = x"yes"; then AC_MSG_NOTICE([Building MuSig module: $enable_module_musig]) AC_MSG_NOTICE([Building extrakeys module: $enable_module_extrakeys]) AC_MSG_NOTICE([Building schnorrsig module: $enable_module_schnorrsig]) + AC_MSG_NOTICE([Building ECDSA sign-to-contract module: $enable_module_ecdsa_s2c]) + AC_MSG_NOTICE([Building ECDSA adaptor signatures module: $enable_module_ecdsa_adaptor]) AC_MSG_NOTICE([******]) @@ -565,6 +639,12 @@ else if test x"$enable_module_schnorrsig" = x"yes"; then AC_MSG_ERROR([schnorrsig module is experimental. Use --enable-experimental to allow.]) fi + if test x"$enable_module_ecdsa_s2c" = x"yes"; then + AC_MSG_ERROR([ECDSA sign-to-contract module module is experimental. Use --enable-experimental to allow.]) + fi + if test x"$enable_module_ecdsa_adaptor" = x"yes"; then + AC_MSG_ERROR([ecdsa adaptor signatures module is experimental. Use --enable-experimental to allow.]) + fi if test x"$set_asm" = x"arm"; then AC_MSG_ERROR([ARM assembly optimization is experimental. Use --enable-experimental to allow.]) fi @@ -582,6 +662,10 @@ else fi fi +### +### Generate output +### + AC_CONFIG_HEADERS([src/libsecp256k1-config.h]) AC_CONFIG_FILES([Makefile libsecp256k1.pc]) AC_SUBST(SECP_INCLUDES) @@ -601,12 +685,14 @@ AM_CONDITIONAL([ENABLE_MODULE_RANGEPROOF], [test x"$enable_module_rangeproof" = AM_CONDITIONAL([ENABLE_MODULE_WHITELIST], [test x"$enable_module_whitelist" = x"yes"]) AM_CONDITIONAL([ENABLE_MODULE_EXTRAKEYS], [test x"$enable_module_extrakeys" = x"yes"]) AM_CONDITIONAL([ENABLE_MODULE_SCHNORRSIG], [test x"$enable_module_schnorrsig" = x"yes"]) +AM_CONDITIONAL([ENABLE_MODULE_ECDSA_S2C], [test x"$enable_module_ecdsa_s2c" = x"yes"]) +AM_CONDITIONAL([ENABLE_MODULE_ECDSA_ADAPTOR], [test x"$enable_module_ecdsa_adaptor" = x"yes"]) AM_CONDITIONAL([USE_EXTERNAL_ASM], [test x"$use_external_asm" = x"yes"]) AM_CONDITIONAL([USE_ASM_ARM], [test x"$set_asm" = x"arm"]) AM_CONDITIONAL([ENABLE_MODULE_SURJECTIONPROOF], [test x"$enable_module_surjectionproof" = x"yes"]) AM_CONDITIONAL([USE_REDUCED_SURJECTION_PROOF_SIZE], [test x"$use_reduced_surjection_proof_size" = x"yes"]) -dnl make sure nothing new is exported so that we don't break the cache +# Make sure nothing new is exported so that we don't break the cache. PKGCONFIG_PATH_TEMP="$PKG_CONFIG_PATH" unset PKG_CONFIG_PATH PKG_CONFIG_PATH="$PKGCONFIG_PATH_TEMP" @@ -625,12 +711,14 @@ echo " module ecdh = $enable_module_ecdh" echo " module recovery = $enable_module_recovery" echo " module extrakeys = $enable_module_extrakeys" echo " module schnorrsig = $enable_module_schnorrsig" +echo " module ecdsa-s2c = $enable_module_ecdsa_s2c" +echo " module ecdsa-adaptor = $enable_module_ecdsa_adaptor" echo echo " asm = $set_asm" echo " bignum = $set_bignum" echo " ecmult window size = $set_ecmult_window" echo " ecmult gen prec. bits = $set_ecmult_gen_precision" -dnl Hide test-only options unless they're used. +# Hide test-only options unless they're used. if test x"$set_widemul" != xauto; then echo " wide multiplication = $set_widemul" fi @@ -641,3 +729,9 @@ echo " CFLAGS = $CFLAGS" echo " CPPFLAGS = $CPPFLAGS" echo " LDFLAGS = $LDFLAGS" echo +if test x"$set_precomp" = x"yes"; then +echo " CC_FOR_BUILD = $CC_FOR_BUILD" +echo " CFLAGS_FOR_BUILD = $CFLAGS_FOR_BUILD" +echo " CPPFLAGS_FOR_BUILD = $CPPFLAGS_FOR_BUILD" +echo " LDFLAGS_FOR_BUILD = $LDFLAGS_FOR_BUILD" +fi diff --git a/secp256k1-zkp-sys/depend/secp256k1/contrib/lax_der_parsing.c b/secp256k1-zkp-sys/depend/secp256k1/contrib/lax_der_parsing.c index e345943a..514e22d4 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/contrib/lax_der_parsing.c +++ b/secp256k1-zkp-sys/depend/secp256k1/contrib/lax_der_parsing.c @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #include #include diff --git a/secp256k1-zkp-sys/depend/secp256k1/contrib/lax_der_parsing.h b/secp256k1-zkp-sys/depend/secp256k1/contrib/lax_der_parsing.h index 0d13fb41..987bdfae 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/contrib/lax_der_parsing.h +++ b/secp256k1-zkp-sys/depend/secp256k1/contrib/lax_der_parsing.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ /**** * Please do not link this file directly. It is not part of the libsecp256k1 diff --git a/secp256k1-zkp-sys/depend/secp256k1/contrib/lax_der_privatekey_parsing.c b/secp256k1-zkp-sys/depend/secp256k1/contrib/lax_der_privatekey_parsing.c index eee64d80..afab4dd7 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/contrib/lax_der_privatekey_parsing.c +++ b/secp256k1-zkp-sys/depend/secp256k1/contrib/lax_der_privatekey_parsing.c @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2014, 2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2014, 2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #include #include diff --git a/secp256k1-zkp-sys/depend/secp256k1/contrib/lax_der_privatekey_parsing.h b/secp256k1-zkp-sys/depend/secp256k1/contrib/lax_der_privatekey_parsing.h index 640b5c76..88a506f3 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/contrib/lax_der_privatekey_parsing.h +++ b/secp256k1-zkp-sys/depend/secp256k1/contrib/lax_der_privatekey_parsing.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2014, 2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2014, 2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ /**** * Please do not link this file directly. It is not part of the libsecp256k1 diff --git a/secp256k1-zkp-sys/depend/secp256k1/contrib/sync-upstream.sh b/secp256k1-zkp-sys/depend/secp256k1/contrib/sync-upstream.sh new file mode 100755 index 00000000..c9f47d2e --- /dev/null +++ b/secp256k1-zkp-sys/depend/secp256k1/contrib/sync-upstream.sh @@ -0,0 +1,115 @@ +#!/bin/bash + +set -eou pipefail + +help() { + echo "$0 range [end]" + echo " merges every merge commit present in upstream and missing locally." + echo " If the optional [end] commit is provided, only merges up to [end]." + echo + echo "$0 select ... " + echo " merges every selected merge commit" + echo + echo "This tool creates a branch and a script that can be executed to create the" + echo "PR automatically. The script requires the github-cli tool (aka gh)." + echo "" + echo "Tip: \`git log --oneline upstream/master --merges\` shows merge commits." + exit 1 +} + +if [ "$#" -lt 1 ]; then + help +fi + +REMOTE=upstream +REMOTE_BRANCH=$REMOTE/master +# Makes sure you have a remote "upstream" that is up-to-date +setup() { + ret=0 + git fetch $REMOTE &> /dev/null || ret=$? + if [ ${ret} == 0 ]; then + return + fi + echo "Adding remote \"$REMOTE\" with URL git@github.com:bitcoin-core/secp256k1.git. Continue with y" + read -r yn + case $yn in + [Yy]* ) ;; + * ) exit 1;; + esac + git remote add $REMOTE git@github.com:bitcoin-core/secp256k1.git &> /dev/null + git fetch $REMOTE &> /dev/null +} + +range() { + RANGESTART_COMMIT=$(git merge-base $REMOTE_BRANCH master) + RANGEEND_COMMIT=$(git rev-parse $REMOTE_BRANCH) + if [ "$#" = 1 ]; then + RANGEEND_COMMIT=$1 + fi + + COMMITS=$(git --no-pager log --oneline "$REMOTE_BRANCH" --merges "$RANGESTART_COMMIT".."$RANGEEND_COMMIT") + COMMITS=$(echo "$COMMITS" | tac | awk '{ print $1 }' ORS=' ') + echo "Merging $COMMITS. Continue with y" + read -r yn + case $yn in + [Yy]* ) ;; + * ) exit 1;; + esac +} + +case $1 in + range) + shift + setup + range "$@" + REPRODUCE_COMMAND="$0 range $RANGEEND_COMMIT" + ;; + select) + shift + setup + COMMITS=$* + REPRODUCE_COMMAND="$0 $@" + ;; + help) + help + ;; + *) + help +esac + +TITLE="Upstream PRs" +BODY="" +for COMMIT in $COMMITS +do + PRNUM=$(git log -1 "$COMMIT" --pretty=format:%s | sed s/'Merge #\([0-9]*\).*'/'\1'/) + TITLE="$TITLE $PRNUM," + BODY=$(printf "%s\n%s" "$BODY" "$(git log -1 "$COMMIT" --pretty=format:%s | sed s/'Merge #\([0-9]*\)'/'[bitcoin-core\/secp256k1#\1]'/)") +done +# Remove trailing "," +TITLE=${TITLE%?} + +BODY=$(printf "%s\n\n%s" "$BODY" "This PR can be recreated with \`$REPRODUCE_COMMAND\`.") + +echo "-----------------------------------" +echo "$TITLE" +echo "-----------------------------------" +echo "$BODY" +echo "-----------------------------------" +# Create branch from PR commit and create PR +git checkout master +git pull +git checkout -b temp-merge-"$PRNUM" + +BASEDIR=$(dirname "$0") +FNAME=$BASEDIR/gh-pr-create.sh +cat < "$FNAME" +#!/bin/sh +gh pr create -t "$TITLE" -b "$BODY" --web +# Remove temporary branch +git checkout master +git branch -D temp-merge-"$PRNUM" +EOT +chmod +x "$FNAME" +echo Run "$FNAME" after solving the merge conflicts + +git merge --no-edit -m "Merge commits '$COMMITS' into temp-merge-$PRNUM" $COMMITS diff --git a/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1.h b/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1.h index 23a9e252..c3eca643 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1.h +++ b/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1.h @@ -11,7 +11,7 @@ extern "C" { * * 1. Context pointers go first, followed by output arguments, combined * output/input arguments, and finally input-only arguments. - * 2. Array lengths always immediately the follow the argument whose length + * 2. Array lengths always immediately follow the argument whose length * they describe, even if this violates rule 1. * 3. Within the OUT/OUTIN/IN groups, pointers to data that is typically generated * later go first. This means: signatures, public nonces, secret nonces, @@ -435,7 +435,14 @@ SECP256K1_API int rustsecp256k1zkp_v0_2_0_ecdsa_signature_serialize_compact( * 0: incorrect or unparseable signature * Args: ctx: a secp256k1 context object, initialized for verification. * In: sig: the signature being verified (cannot be NULL) - * msg32: the 32-byte message hash being verified (cannot be NULL) + * msghash32: the 32-byte message hash being verified (cannot be NULL). + * The verifier must make sure to apply a cryptographic + * hash function to the message by itself and not accept an + * msghash32 value directly. Otherwise, it would be easy to + * create a "valid" signature without knowledge of the + * secret key. See also + * https://bitcoin.stackexchange.com/a/81116/35586 for more + * background on this topic. * pubkey: pointer to an initialized public key to verify with (cannot be NULL) * * To avoid accepting malleable signatures, only ECDSA signatures in lower-S @@ -450,7 +457,7 @@ SECP256K1_API int rustsecp256k1zkp_v0_2_0_ecdsa_signature_serialize_compact( SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ecdsa_verify( const rustsecp256k1zkp_v0_2_0_context* ctx, const rustsecp256k1zkp_v0_2_0_ecdsa_signature *sig, - const unsigned char *msg32, + const unsigned char *msghash32, const rustsecp256k1zkp_v0_2_0_pubkey *pubkey ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); @@ -515,12 +522,12 @@ SECP256K1_API extern const rustsecp256k1zkp_v0_2_0_nonce_function rustsecp256k1z * * Returns: 1: signature created * 0: the nonce generation function failed, or the secret key was invalid. - * Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) - * Out: sig: pointer to an array where the signature will be placed (cannot be NULL) - * In: msg32: the 32-byte message hash being signed (cannot be NULL) - * seckey: pointer to a 32-byte secret key (cannot be NULL) - * noncefp:pointer to a nonce generation function. If NULL, rustsecp256k1zkp_v0_2_0_nonce_function_default is used - * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL) + * Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) + * Out: sig: pointer to an array where the signature will be placed (cannot be NULL) + * In: msghash32: the 32-byte message hash being signed (cannot be NULL) + * seckey: pointer to a 32-byte secret key (cannot be NULL) + * noncefp: pointer to a nonce generation function. If NULL, rustsecp256k1zkp_v0_2_0_nonce_function_default is used + * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL) * * The created signature is always in lower-S form. See * rustsecp256k1zkp_v0_2_0_ecdsa_signature_normalize for more details. @@ -528,7 +535,7 @@ SECP256K1_API extern const rustsecp256k1zkp_v0_2_0_nonce_function rustsecp256k1z SECP256K1_API int rustsecp256k1zkp_v0_2_0_ecdsa_sign( const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_ecdsa_signature *sig, - const unsigned char *msg32, + const unsigned char *msghash32, const unsigned char *seckey, rustsecp256k1zkp_v0_2_0_nonce_function noncefp, const void *ndata @@ -609,7 +616,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_pubkey * invalid according to rustsecp256k1zkp_v0_2_0_ec_seckey_verify, this * function returns 0. seckey will be set to some unspecified * value if this function returns 0. (cannot be NULL) - * In: tweak: pointer to a 32-byte tweak. If the tweak is invalid according to + * In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid according to * rustsecp256k1zkp_v0_2_0_ec_seckey_verify, this function returns 0. For * uniformly random 32-byte arrays the chance of being invalid * is negligible (around 1 in 2^128) (cannot be NULL). @@ -617,7 +624,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_pubkey SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_add( const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char *seckey, - const unsigned char *tweak + const unsigned char *tweak32 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Same as rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_add, but DEPRECATED. Will be removed in @@ -625,7 +632,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_seckey SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_privkey_tweak_add( const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char *seckey, - const unsigned char *tweak + const unsigned char *tweak32 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Tweak a public key by adding tweak times the generator to it. @@ -637,7 +644,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_privke * (cannot be NULL). * In/Out: pubkey: pointer to a public key object. pubkey will be set to an * invalid value if this function returns 0 (cannot be NULL). - * In: tweak: pointer to a 32-byte tweak. If the tweak is invalid according to + * In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid according to * rustsecp256k1zkp_v0_2_0_ec_seckey_verify, this function returns 0. For * uniformly random 32-byte arrays the chance of being invalid * is negligible (around 1 in 2^128) (cannot be NULL). @@ -645,7 +652,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_privke SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_pubkey_tweak_add( const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_pubkey *pubkey, - const unsigned char *tweak + const unsigned char *tweak32 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Tweak a secret key by multiplying it by a tweak. @@ -656,7 +663,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_pubkey * invalid according to rustsecp256k1zkp_v0_2_0_ec_seckey_verify, this * function returns 0. seckey will be set to some unspecified * value if this function returns 0. (cannot be NULL) - * In: tweak: pointer to a 32-byte tweak. If the tweak is invalid according to + * In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid according to * rustsecp256k1zkp_v0_2_0_ec_seckey_verify, this function returns 0. For * uniformly random 32-byte arrays the chance of being invalid * is negligible (around 1 in 2^128) (cannot be NULL). @@ -664,7 +671,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_pubkey SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_mul( const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char *seckey, - const unsigned char *tweak + const unsigned char *tweak32 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Same as rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_mul, but DEPRECATED. Will be removed in @@ -672,7 +679,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_seckey SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_privkey_tweak_mul( const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char *seckey, - const unsigned char *tweak + const unsigned char *tweak32 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Tweak a public key by multiplying it by a tweak value. @@ -682,7 +689,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_privke * (cannot be NULL). * In/Out: pubkey: pointer to a public key object. pubkey will be set to an * invalid value if this function returns 0 (cannot be NULL). - * In: tweak: pointer to a 32-byte tweak. If the tweak is invalid according to + * In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid according to * rustsecp256k1zkp_v0_2_0_ec_seckey_verify, this function returns 0. For * uniformly random 32-byte arrays the chance of being invalid * is negligible (around 1 in 2^128) (cannot be NULL). @@ -690,7 +697,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_privke SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_pubkey_tweak_mul( const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_pubkey *pubkey, - const unsigned char *tweak + const unsigned char *tweak32 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Updates the context randomization to protect against side-channel leakage. diff --git a/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1.h.orig b/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1.h.orig index 85e1a943..ea34d06f 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1.h.orig +++ b/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1.h.orig @@ -11,7 +11,7 @@ extern "C" { * * 1. Context pointers go first, followed by output arguments, combined * output/input arguments, and finally input-only arguments. - * 2. Array lengths always immediately the follow the argument whose length + * 2. Array lengths always immediately follow the argument whose length * they describe, even if this violates rule 1. * 3. Within the OUT/OUTIN/IN groups, pointers to data that is typically generated * later go first. This means: signatures, public nonces, secret nonces, @@ -452,7 +452,14 @@ SECP256K1_API int rustsecp256k1zkp_v0_2_0_ecdsa_signature_serialize_compact( * 0: incorrect or unparseable signature * Args: ctx: a secp256k1 context object, initialized for verification. * In: sig: the signature being verified (cannot be NULL) - * msg32: the 32-byte message hash being verified (cannot be NULL) + * msghash32: the 32-byte message hash being verified (cannot be NULL). + * The verifier must make sure to apply a cryptographic + * hash function to the message by itself and not accept an + * msghash32 value directly. Otherwise, it would be easy to + * create a "valid" signature without knowledge of the + * secret key. See also + * https://bitcoin.stackexchange.com/a/81116/35586 for more + * background on this topic. * pubkey: pointer to an initialized public key to verify with (cannot be NULL) * * To avoid accepting malleable signatures, only ECDSA signatures in lower-S @@ -467,7 +474,7 @@ SECP256K1_API int rustsecp256k1zkp_v0_2_0_ecdsa_signature_serialize_compact( SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ecdsa_verify( const rustsecp256k1zkp_v0_2_0_context* ctx, const rustsecp256k1zkp_v0_2_0_ecdsa_signature *sig, - const unsigned char *msg32, + const unsigned char *msghash32, const rustsecp256k1zkp_v0_2_0_pubkey *pubkey ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); @@ -532,12 +539,12 @@ SECP256K1_API extern const rustsecp256k1zkp_v0_2_0_nonce_function rustsecp256k1z * * Returns: 1: signature created * 0: the nonce generation function failed, or the secret key was invalid. - * Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) - * Out: sig: pointer to an array where the signature will be placed (cannot be NULL) - * In: msg32: the 32-byte message hash being signed (cannot be NULL) - * seckey: pointer to a 32-byte secret key (cannot be NULL) - * noncefp:pointer to a nonce generation function. If NULL, rustsecp256k1zkp_v0_2_0_nonce_function_default is used - * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL) + * Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) + * Out: sig: pointer to an array where the signature will be placed (cannot be NULL) + * In: msghash32: the 32-byte message hash being signed (cannot be NULL) + * seckey: pointer to a 32-byte secret key (cannot be NULL) + * noncefp: pointer to a nonce generation function. If NULL, rustsecp256k1zkp_v0_2_0_nonce_function_default is used + * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL) * * The created signature is always in lower-S form. See * rustsecp256k1zkp_v0_2_0_ecdsa_signature_normalize for more details. @@ -545,7 +552,7 @@ SECP256K1_API extern const rustsecp256k1zkp_v0_2_0_nonce_function rustsecp256k1z SECP256K1_API int rustsecp256k1zkp_v0_2_0_ecdsa_sign( const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_ecdsa_signature *sig, - const unsigned char *msg32, + const unsigned char *msghash32, const unsigned char *seckey, rustsecp256k1zkp_v0_2_0_nonce_function noncefp, const void *ndata @@ -626,7 +633,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_pubkey * invalid according to rustsecp256k1zkp_v0_2_0_ec_seckey_verify, this * function returns 0. seckey will be set to some unspecified * value if this function returns 0. (cannot be NULL) - * In: tweak: pointer to a 32-byte tweak. If the tweak is invalid according to + * In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid according to * rustsecp256k1zkp_v0_2_0_ec_seckey_verify, this function returns 0. For * uniformly random 32-byte arrays the chance of being invalid * is negligible (around 1 in 2^128) (cannot be NULL). @@ -634,7 +641,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_pubkey SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_add( const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char *seckey, - const unsigned char *tweak + const unsigned char *tweak32 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Same as rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_add, but DEPRECATED. Will be removed in @@ -642,7 +649,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_seckey SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_privkey_tweak_add( const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char *seckey, - const unsigned char *tweak + const unsigned char *tweak32 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Tweak a public key by adding tweak times the generator to it. @@ -654,7 +661,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_privke * (cannot be NULL). * In/Out: pubkey: pointer to a public key object. pubkey will be set to an * invalid value if this function returns 0 (cannot be NULL). - * In: tweak: pointer to a 32-byte tweak. If the tweak is invalid according to + * In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid according to * rustsecp256k1zkp_v0_2_0_ec_seckey_verify, this function returns 0. For * uniformly random 32-byte arrays the chance of being invalid * is negligible (around 1 in 2^128) (cannot be NULL). @@ -662,7 +669,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_privke SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_pubkey_tweak_add( const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_pubkey *pubkey, - const unsigned char *tweak + const unsigned char *tweak32 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Tweak a secret key by multiplying it by a tweak. @@ -673,7 +680,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_pubkey * invalid according to rustsecp256k1zkp_v0_2_0_ec_seckey_verify, this * function returns 0. seckey will be set to some unspecified * value if this function returns 0. (cannot be NULL) - * In: tweak: pointer to a 32-byte tweak. If the tweak is invalid according to + * In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid according to * rustsecp256k1zkp_v0_2_0_ec_seckey_verify, this function returns 0. For * uniformly random 32-byte arrays the chance of being invalid * is negligible (around 1 in 2^128) (cannot be NULL). @@ -681,7 +688,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_pubkey SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_mul( const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char *seckey, - const unsigned char *tweak + const unsigned char *tweak32 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Same as rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_mul, but DEPRECATED. Will be removed in @@ -689,7 +696,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_seckey SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_privkey_tweak_mul( const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char *seckey, - const unsigned char *tweak + const unsigned char *tweak32 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Tweak a public key by multiplying it by a tweak value. @@ -699,7 +706,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_privke * (cannot be NULL). * In/Out: pubkey: pointer to a public key object. pubkey will be set to an * invalid value if this function returns 0 (cannot be NULL). - * In: tweak: pointer to a 32-byte tweak. If the tweak is invalid according to + * In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid according to * rustsecp256k1zkp_v0_2_0_ec_seckey_verify, this function returns 0. For * uniformly random 32-byte arrays the chance of being invalid * is negligible (around 1 in 2^128) (cannot be NULL). @@ -707,7 +714,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_privke SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ec_pubkey_tweak_mul( const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_pubkey *pubkey, - const unsigned char *tweak + const unsigned char *tweak32 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Updates the context randomization to protect against side-channel leakage. diff --git a/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1_ecdsa_adaptor.h b/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1_ecdsa_adaptor.h new file mode 100644 index 00000000..36caad37 --- /dev/null +++ b/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1_ecdsa_adaptor.h @@ -0,0 +1,162 @@ +#ifndef SECP256K1_ECDSA_ADAPTOR_H +#define SECP256K1_ECDSA_ADAPTOR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** This module implements single signer ECDSA adaptor signatures following + * "One-Time Verifiably Encrypted Signatures A.K.A. Adaptor Signatures" by + * Lloyd Fournier + * (https://lists.linuxfoundation.org/pipermail/lightning-dev/2019-November/002316.html + * and https://github.com/LLFourn/one-time-VES/blob/master/main.pdf). + * + * WARNING! DANGER AHEAD! + * As mentioned in Lloyd Fournier's paper, the adaptor signature leaks the + * Elliptic-curve Diffie–Hellman (ECDH) key between the signing key and the + * encryption key. This is not a problem for ECDSA adaptor signatures + * themselves, but may result in a complete loss of security when they are + * composed with other schemes. More specifically, let us refer to the + * signer's public key as X = x*G, and to the encryption key as Y = y*G. + * Given X, Y and the adaptor signature, it is trivial to compute Y^x = X^y. + * + * A defense is to not reuse the signing key of ECDSA adaptor signatures in + * protocols that rely on the hardness of the CDH problem, e.g., Diffie-Hellman + * key exchange and ElGamal encryption. In general, it is a well-established + * cryptographic practice to seperate keys for different purposes whenever + * possible. + */ + +/** A pointer to a function to deterministically generate a nonce. + * + * Same as rustsecp256k1zkp_v0_2_0_nonce_function_hardened with the exception of using the + * compressed 33-byte encoding for the pubkey argument. + * + * Returns: 1 if a nonce was successfully generated. 0 will cause signing to + * return an error. + * Out: nonce32: pointer to a 32-byte array to be filled by the function + * In: msg32: the 32-byte message hash being verified + * key32: pointer to a 32-byte secret key + * pk33: the 33-byte serialized pubkey corresponding to key32 + * algo: pointer to an array describing the signature algorithm + * algolen: the length of the algo array + * data: arbitrary data pointer that is passed through + * + * Except for test cases, this function should compute some cryptographic hash of + * the message, the key, the pubkey, the algorithm description, and data. + */ +typedef int (*rustsecp256k1zkp_v0_2_0_nonce_function_hardened_ecdsa_adaptor)( + unsigned char *nonce32, + const unsigned char *msg32, + const unsigned char *key32, + const unsigned char *pk33, + const unsigned char *algo, + size_t algolen, + void *data +); + +/** A modified BIP-340 nonce generation function. If a data pointer is passed, it is + * assumed to be a pointer to 32 bytes of auxiliary random data as defined in BIP-340. + * The hash will be tagged with algo after removing all terminating null bytes. + */ +SECP256K1_API extern const rustsecp256k1zkp_v0_2_0_nonce_function_hardened_ecdsa_adaptor rustsecp256k1zkp_v0_2_0_nonce_function_ecdsa_adaptor; + +/** Encrypted Signing + * + * Creates an adaptor signature, which includes a proof to verify the adaptor + * signature. + * WARNING: Make sure you have read and understood the WARNING at the top of + * this file and applied the suggested countermeasures. + * + * Returns: 1 on success, 0 on failure + * Args: ctx: a secp256k1 context object, initialized for signing + * Out: adaptor_sig162: pointer to 162 byte to store the returned signature + * In: seckey32: pointer to 32 byte secret key that will be used for + * signing + * enckey: pointer to the encryption public key + * msg32: pointer to the 32-byte message hash to sign + * noncefp: pointer to a nonce generation function. If NULL, + * rustsecp256k1zkp_v0_2_0_nonce_function_ecdsa_adaptor is used + * ndata: pointer to arbitrary data used by the nonce generation + * function (can be NULL). If it is non-NULL and + * rustsecp256k1zkp_v0_2_0_nonce_function_ecdsa_adaptor is used, then + * ndata must be a pointer to 32-byte auxiliary randomness + * as per BIP-340. + */ +SECP256K1_API int rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_encrypt( + const rustsecp256k1zkp_v0_2_0_context* ctx, + unsigned char *adaptor_sig162, + unsigned char *seckey32, + const rustsecp256k1zkp_v0_2_0_pubkey *enckey, + const unsigned char *msg32, + rustsecp256k1zkp_v0_2_0_nonce_function_hardened_ecdsa_adaptor noncefp, + void *ndata +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5); + +/** Encryption Verification + * + * Verifies that the adaptor decryption key can be extracted from the adaptor signature + * and the completed ECDSA signature. + * + * Returns: 1 on success, 0 on failure + * Args: ctx: a secp256k1 context object, initialized for verification + * In: adaptor_sig162: pointer to 162-byte signature to verify + * pubkey: pointer to the public key corresponding to the secret key + * used for signing + * msg32: pointer to the 32-byte message hash being verified + * enckey: pointer to the adaptor encryption public key + */ +SECP256K1_API int rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_verify( + const rustsecp256k1zkp_v0_2_0_context* ctx, + const unsigned char *adaptor_sig162, + const rustsecp256k1zkp_v0_2_0_pubkey *pubkey, + const unsigned char *msg32, + const rustsecp256k1zkp_v0_2_0_pubkey *enckey +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5); + +/** Signature Decryption + * + * Derives an ECDSA signature from an adaptor signature and an adaptor decryption key. + * + * Returns: 1 on success, 0 on failure + * Args: ctx: a secp256k1 context object + * Out: sig: pointer to the ECDSA signature to create + * In: deckey32: pointer to 32-byte decryption secret key for the adaptor + * encryption public key + * adaptor_sig162: pointer to 162-byte adaptor sig + */ +SECP256K1_API int rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_decrypt( + const rustsecp256k1zkp_v0_2_0_context* ctx, + rustsecp256k1zkp_v0_2_0_ecdsa_signature *sig, + const unsigned char *deckey32, + const unsigned char *adaptor_sig162 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Decryption Key Recovery + * + * Extracts the adaptor decryption key from the complete signature and the adaptor + * signature. + * + * Returns: 1 on success, 0 on failure + * Args: ctx: a secp256k1 context object, initialized for signing + * Out: deckey32: pointer to 32-byte adaptor decryption key for the adaptor + * encryption public key + * In: sig: pointer to ECDSA signature to recover the adaptor decryption + * key from + * adaptor_sig162: pointer to adaptor signature to recover the adaptor + * decryption key from + * enckey: pointer to the adaptor encryption public key + */ +SECP256K1_API int rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_recover( + const rustsecp256k1zkp_v0_2_0_context* ctx, + unsigned char *deckey32, + const rustsecp256k1zkp_v0_2_0_ecdsa_signature *sig, + const unsigned char *adaptor_sig162, + const rustsecp256k1zkp_v0_2_0_pubkey *enckey +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5); + +#ifdef __cplusplus +} +#endif + +#endif /* SECP256K1_ECDSA_ADAPTOR_H */ diff --git a/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1_ecdsa_s2c.h b/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1_ecdsa_s2c.h new file mode 100644 index 00000000..0412fc55 --- /dev/null +++ b/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1_ecdsa_s2c.h @@ -0,0 +1,234 @@ +#ifndef SECP256K1_ECDSA_S2C_H +#define SECP256K1_ECDSA_S2C_H + +#include "secp256k1.h" + +/** This module implements the sign-to-contract scheme for ECDSA signatures, as + * well as the "ECDSA Anti-Exfil Protocol" that is based on sign-to-contract + * and is specified further down. The sign-to-contract scheme allows creating a + * signature that also commits to some data. This works by offsetting the public + * nonce point of the signature R by hash(R, data)*G where G is the secp256k1 + * group generator. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** Data structure that holds a sign-to-contract ("s2c") opening information. + * Sign-to-contract allows a signer to commit to some data as part of a signature. It + * can be used as an Out-argument in certain signing functions. + * + * The exact representation of data inside is implementation defined and not + * guaranteed to be portable between different platforms or versions. It is + * however guaranteed to be 64 bytes in size, and can be safely copied/moved. + * If you need to convert to a format suitable for storage, transmission, or + * comparison, use rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_serialize and rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_parse. + */ +typedef struct { + unsigned char data[64]; +} rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening; + +/** Parse a sign-to-contract opening. + * + * Returns: 1 if the opening could be parsed + * 0 if the opening could not be parsed + * Args: ctx: a secp256k1 context object. + * Out: opening: pointer to an opening object. If 1 is returned, it is set to a + * parsed version of input. If not, its value is unspecified. + * In: input33: pointer to 33-byte array with a serialized opening + * + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_parse( + const rustsecp256k1zkp_v0_2_0_context* ctx, + rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening* opening, + const unsigned char* input33 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Serialize a sign-to-contract opening into a byte sequence. + * + * Returns: 1 if the opening was successfully serialized. + * 0 if the opening could not be serialized + * Args: ctx: a secp256k1 context object + * Out: output33: pointer to a 33-byte array to place the serialized opening in + * In: opening: a pointer to an initialized `rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening` + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_serialize( + const rustsecp256k1zkp_v0_2_0_context* ctx, + unsigned char* output33, + const rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening* opening +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Same as rustsecp256k1zkp_v0_2_0_ecdsa_sign, but s2c_data32 is committed to inside the nonce + * + * Returns: 1: signature created + * 0: the nonce generation function failed, or the private key was invalid. + * Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) + * Out: sig: pointer to an array where the signature will be placed (cannot be NULL) + * s2c_opening: if non-NULL, pointer to an rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening structure to populate + * In: msg32: the 32-byte message hash being signed (cannot be NULL) + * seckey: pointer to a 32-byte secret key (cannot be NULL) + * s2c_data32: pointer to a 32-byte data to commit to in the nonce (cannot be NULL) + */ +SECP256K1_API int rustsecp256k1zkp_v0_2_0_ecdsa_s2c_sign( + const rustsecp256k1zkp_v0_2_0_context* ctx, + rustsecp256k1zkp_v0_2_0_ecdsa_signature* sig, + rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening* s2c_opening, + const unsigned char* msg32, + const unsigned char* seckey, + const unsigned char* s2c_data32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6); + +/** Verify a sign-to-contract commitment. + * + * Returns: 1: the signature contains a commitment to data32 (though it does + * not necessarily need to be a valid siganture!) + * 0: incorrect opening + * Args: ctx: a secp256k1 context object, initialized for verification. + * In: sig: the signature containing the sign-to-contract commitment (cannot be NULL) + * data32: the 32-byte data that was committed to (cannot be NULL) + * opening: pointer to the opening created during signing (cannot be NULL) + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ecdsa_s2c_verify_commit( + const rustsecp256k1zkp_v0_2_0_context* ctx, + const rustsecp256k1zkp_v0_2_0_ecdsa_signature *sig, + const unsigned char *data32, + const rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening *opening +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + + +/** ECDSA Anti-Exfil Protocol + * + * The ecdsa_anti_exfil_* functions can be used to prevent a signing device from + * exfiltrating the secret signing keys through biased signature nonces. The general + * idea is that a host provides additional randomness to the signing device client + * and the client commits to the randomness in the nonce using sign-to-contract. + * + * The following scheme is described by Stepan Snigirev here: + * https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-February/017655.html + * and by Pieter Wuille (as "Scheme 6") here: + * https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-March/017667.html + * + * In order to ensure the host cannot trick the signing device into revealing its + * keys, or the signing device to bias the nonce despite the host's contributions, + * the host and client must engage in a commit-reveal protocol as follows: + * 1. The host draws randomness `rho` and computes a sha256 commitment to it using + * `rustsecp256k1zkp_v0_2_0_ecdsa_anti_exfil_host_commit`. It sends this to the signing device. + * 2. The signing device computes a public nonce `R` using the host's commitment + * as auxiliary randomness, using `rustsecp256k1zkp_v0_2_0_ecdsa_anti_exfil_signer_commit`. + * The signing device sends the resulting `R` to the host as a s2c_opening. + * + * If, at any point from this step onward, the hardware device fails, it is + * okay to restart the protocol using **exactly the same `rho`** and checking + * that the hardware device proposes **exactly the same** `R`. Otherwise, the + * hardware device may be selectively aborting and thereby biasing the set of + * nonces that are used in actual signatures. + * + * It takes many (>100) such aborts before there is a plausible attack, given + * current knowledge in 2020. However such aborts accumulate even across a total + * replacement of all relevant devices (but not across replacement of the actual + * signing keys with new independently random ones). + * + * In case the hardware device cannot be made to sign with the given `rho`, `R` + * pair, wallet authors should alert the user and present a very scary message + * implying that if this happens more than even a few times, say 20 or more times + * EVER, they should change hardware vendors and perhaps sweep their coins. + * + * 3. The host replies with `rho` generated in step 1. + * 4. The device signs with `rustsecp256k1zkp_v0_2_0_anti_exfil_sign`, using `rho` as `host_data32`, + * and sends the signature to the host. + * 5. The host verifies that the signature's public nonce matches the opening from + * step 2 and its original randomness `rho`, using `rustsecp256k1zkp_v0_2_0_anti_exfil_host_verify`. + * + * Rationale: + * - The reason for having a host commitment is to allow the signing device to + * deterministically derive a unique nonce even if the host restarts the protocol + * using the same message and keys. Otherwise the signer might reuse the original + * nonce in two iterations of the protocol with different `rho`, which leaks the + * the secret key. + * - The signer does not need to check that the host commitment matches the host's + * claimed `rho`. Instead it re-derives the commitment (and its original `R`) from + * the provided `rho`. If this differs from the original commitment, the result + * will be an invalid `s2c_opening`, but since `R` was unique there is no risk to + * the signer's secret keys. Because of this, the signing device does not need to + * maintain any state about the progress of the protocol. + */ + +/** Create the initial host commitment to `rho`. Part of the ECDSA Anti-Exfil Protocol. + * + * Returns 1 on success, 0 on failure. + * Args: ctx: pointer to a context object (cannot be NULL) + * Out: rand_commitment32: pointer to 32-byte array to store the returned commitment (cannot be NULL) + * In: rand32: the 32-byte randomness to commit to (cannot be NULL). It must come from + * a cryptographically secure RNG. As per the protocol, this value must not + * be revealed to the client until after the host has received the client + * commitment. + */ +SECP256K1_API int rustsecp256k1zkp_v0_2_0_ecdsa_anti_exfil_host_commit( + const rustsecp256k1zkp_v0_2_0_context* ctx, + unsigned char* rand_commitment32, + const unsigned char* rand32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Compute signer's original nonce. Part of the ECDSA Anti-Exfil Protocol. + * + * Returns 1 on success, 0 on failure. + * Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) + * Out: s2c_opening: pointer to an s2c_opening where the signer's public nonce will be + * placed. (cannot be NULL) + * In: msg32: the 32-byte message hash to be signed (cannot be NULL) + * seckey32: the 32-byte secret key used for signing (cannot be NULL) + * rand_commitment32: the 32-byte randomness commitment from the host (cannot be NULL) + */ +SECP256K1_API int rustsecp256k1zkp_v0_2_0_ecdsa_anti_exfil_signer_commit( + const rustsecp256k1zkp_v0_2_0_context* ctx, + rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening* s2c_opening, + const unsigned char* msg32, + const unsigned char* seckey32, + const unsigned char* rand_commitment32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5); + +/** Same as rustsecp256k1zkp_v0_2_0_ecdsa_sign, but commits to host randomness in the nonce. Part of the + * ECDSA Anti-Exfil Protocol. + * + * Returns: 1: signature created + * 0: the nonce generation function failed, or the private key was invalid. + * Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) + * Out: sig: pointer to an array where the signature will be placed (cannot be NULL) + * In: msg32: the 32-byte message hash being signed (cannot be NULL) + * seckey: pointer to a 32-byte secret key (cannot be NULL) + * host_data32: pointer to 32-byte host-provided randomness (cannot be NULL) + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_anti_exfil_sign( + const rustsecp256k1zkp_v0_2_0_context* ctx, + rustsecp256k1zkp_v0_2_0_ecdsa_signature* sig, + const unsigned char* msg32, + const unsigned char* seckey, + const unsigned char* host_data32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5); + +/** Verify a signature was correctly constructed using the ECDSA Anti-Exfil Protocol. + * + * Returns: 1: the signature is valid and contains a commitment to host_data32 + * 0: incorrect opening + * Args: ctx: a secp256k1 context object, initialized for verification. + * In: sig: the signature produced by the signer (cannot be NULL) + * msghash32: the 32-byte message hash being verified (cannot be NULL) + * pubkey: pointer to the signer's public key (cannot be NULL) + * host_data32: the 32-byte data provided by the host (cannot be NULL) + * opening: the s2c opening provided by the signer (cannot be NULL) + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_anti_exfil_host_verify( + const rustsecp256k1zkp_v0_2_0_context* ctx, + const rustsecp256k1zkp_v0_2_0_ecdsa_signature *sig, + const unsigned char *msg32, + const rustsecp256k1zkp_v0_2_0_pubkey *pubkey, + const unsigned char *host_data32, + const rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening *opening +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6); + +#ifdef __cplusplus +} +#endif + +#endif /* SECP256K1_ECDSA_S2C_H */ diff --git a/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1_extrakeys.h b/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1_extrakeys.h index 34b3cd77..80e5c18a 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1_extrakeys.h +++ b/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1_extrakeys.h @@ -165,6 +165,19 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_keypair_c const unsigned char *seckey ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); +/** Get the secret key from a keypair. + * + * Returns: 0 if the arguments are invalid. 1 otherwise. + * Args: ctx: pointer to a context object (cannot be NULL) + * Out: seckey: pointer to a 32-byte buffer for the secret key (cannot be NULL) + * In: keypair: pointer to a keypair (cannot be NULL) + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_keypair_sec( + const rustsecp256k1zkp_v0_2_0_context* ctx, + unsigned char *seckey, + const rustsecp256k1zkp_v0_2_0_keypair *keypair +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + /** Get the public key from a keypair. * * Returns: 0 if the arguments are invalid. 1 otherwise. diff --git a/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1_generator.h b/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1_generator.h index 948f8299..6fd7820d 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1_generator.h +++ b/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1_generator.h @@ -82,7 +82,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_generator SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_generator_generate_blinded( const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_generator* gen, - const unsigned char *key32, + const unsigned char *seed32, const unsigned char *blind32 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); diff --git a/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1_rangeproof.h b/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1_rangeproof.h index bf29a340..4525b516 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1_rangeproof.h +++ b/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1_rangeproof.h @@ -197,7 +197,9 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_rangeproo * In/Out: blind_out: storage for the 32-byte blinding factor used for the commitment * value_out: pointer to an unsigned int64 which has the exact value of the commitment. * message_out: pointer to a 4096 byte character array to receive message data from the proof author. - * outlen: length of message data written to message_out. + * outlen: length of message data written to message_out. This is generally not equal to the + * msg_len used by the signer. However, for all i with msg_len <= i < outlen, it is + * guaranteed that message_out[i] == 0. * min_value: pointer to an unsigned int64 which will be updated with the minimum value that commit could have. (cannot be NULL) * max_value: pointer to an unsigned int64 which will be updated with the maximum value that commit could have. (cannot be NULL) */ diff --git a/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1_recovery.h b/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1_recovery.h index 8c26099a..7297c5df 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1_recovery.h +++ b/secp256k1-zkp-sys/depend/secp256k1/include/secp256k1_recovery.h @@ -71,17 +71,17 @@ SECP256K1_API int rustsecp256k1zkp_v0_2_0_ecdsa_recoverable_signature_serialize_ * * Returns: 1: signature created * 0: the nonce generation function failed, or the secret key was invalid. - * Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) - * Out: sig: pointer to an array where the signature will be placed (cannot be NULL) - * In: msg32: the 32-byte message hash being signed (cannot be NULL) - * seckey: pointer to a 32-byte secret key (cannot be NULL) - * noncefp:pointer to a nonce generation function. If NULL, rustsecp256k1zkp_v0_2_0_nonce_function_default is used - * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL) + * Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) + * Out: sig: pointer to an array where the signature will be placed (cannot be NULL) + * In: msghash32: the 32-byte message hash being signed (cannot be NULL) + * seckey: pointer to a 32-byte secret key (cannot be NULL) + * noncefp: pointer to a nonce generation function. If NULL, rustsecp256k1zkp_v0_2_0_nonce_function_default is used + * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL) */ SECP256K1_API int rustsecp256k1zkp_v0_2_0_ecdsa_sign_recoverable( const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_ecdsa_recoverable_signature *sig, - const unsigned char *msg32, + const unsigned char *msghash32, const unsigned char *seckey, rustsecp256k1zkp_v0_2_0_nonce_function noncefp, const void *ndata @@ -91,16 +91,16 @@ SECP256K1_API int rustsecp256k1zkp_v0_2_0_ecdsa_sign_recoverable( * * Returns: 1: public key successfully recovered (which guarantees a correct signature). * 0: otherwise. - * Args: ctx: pointer to a context object, initialized for verification (cannot be NULL) - * Out: pubkey: pointer to the recovered public key (cannot be NULL) - * In: sig: pointer to initialized signature that supports pubkey recovery (cannot be NULL) - * msg32: the 32-byte message hash assumed to be signed (cannot be NULL) + * Args: ctx: pointer to a context object, initialized for verification (cannot be NULL) + * Out: pubkey: pointer to the recovered public key (cannot be NULL) + * In: sig: pointer to initialized signature that supports pubkey recovery (cannot be NULL) + * msghash32: the 32-byte message hash assumed to be signed (cannot be NULL) */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int rustsecp256k1zkp_v0_2_0_ecdsa_recover( const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_pubkey *pubkey, const rustsecp256k1zkp_v0_2_0_ecdsa_recoverable_signature *sig, - const unsigned char *msg32 + const unsigned char *msghash32 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); #ifdef __cplusplus diff --git a/secp256k1-zkp-sys/depend/secp256k1/sage/gen_exhaustive_groups.sage b/secp256k1-zkp-sys/depend/secp256k1/sage/gen_exhaustive_groups.sage index 4f96155b..bed11df6 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/sage/gen_exhaustive_groups.sage +++ b/secp256k1-zkp-sys/depend/secp256k1/sage/gen_exhaustive_groups.sage @@ -1,9 +1,4 @@ -# Define field size and field -P = 2^256 - 2^32 - 977 -F = GF(P) -BETA = F(0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee) - -assert(BETA != F(1) and BETA^3 == F(1)) +load("rustsecp256k1zkp_v0_2_0_params.sage") orders_done = set() results = {} diff --git a/secp256k1-zkp-sys/depend/secp256k1/sage/gen_split_lambda_constants.sage b/secp256k1-zkp-sys/depend/secp256k1/sage/gen_split_lambda_constants.sage new file mode 100644 index 00000000..af372a5d --- /dev/null +++ b/secp256k1-zkp-sys/depend/secp256k1/sage/gen_split_lambda_constants.sage @@ -0,0 +1,114 @@ +""" Generates the constants used in rustsecp256k1zkp_v0_2_0_scalar_split_lambda. + +See the comments for rustsecp256k1zkp_v0_2_0_scalar_split_lambda in src/scalar_impl.h for detailed explanations. +""" + +load("rustsecp256k1zkp_v0_2_0_params.sage") + +def inf_norm(v): + """Returns the infinity norm of a vector.""" + return max(map(abs, v)) + +def gauss_reduction(i1, i2): + v1, v2 = i1.copy(), i2.copy() + while True: + if inf_norm(v2) < inf_norm(v1): + v1, v2 = v2, v1 + # This is essentially + # m = round((v1[0]*v2[0] + v1[1]*v2[1]) / (inf_norm(v1)**2)) + # (rounding to the nearest integer) without relying on floating point arithmetic. + m = ((v1[0]*v2[0] + v1[1]*v2[1]) + (inf_norm(v1)**2) // 2) // (inf_norm(v1)**2) + if m == 0: + return v1, v2 + v2[0] -= m*v1[0] + v2[1] -= m*v1[1] + +def find_split_constants_gauss(): + """Find constants for rustsecp256k1zkp_v0_2_0_scalar_split_lamdba using gauss reduction.""" + (v11, v12), (v21, v22) = gauss_reduction([0, N], [1, int(LAMBDA)]) + + # We use related vectors in rustsecp256k1zkp_v0_2_0_scalar_split_lambda. + A1, B1 = -v21, -v11 + A2, B2 = v22, -v21 + + return A1, B1, A2, B2 + +def find_split_constants_explicit_tof(): + """Find constants for rustsecp256k1zkp_v0_2_0_scalar_split_lamdba using the trace of Frobenius. + + See Benjamin Smith: "Easy scalar decompositions for efficient scalar multiplication on + elliptic curves and genus 2 Jacobians" (https://eprint.iacr.org/2013/672), Example 2 + """ + assert P % 3 == 1 # The paper says P % 3 == 2 but that appears to be a mistake, see [10]. + assert C.j_invariant() == 0 + + t = C.trace_of_frobenius() + + c = Integer(sqrt((4*P - t**2)/3)) + A1 = Integer((t - c)/2 - 1) + B1 = c + + A2 = Integer((t + c)/2 - 1) + B2 = Integer(1 - (t - c)/2) + + # We use a negated b values in rustsecp256k1zkp_v0_2_0_scalar_split_lambda. + B1, B2 = -B1, -B2 + + return A1, B1, A2, B2 + +A1, B1, A2, B2 = find_split_constants_explicit_tof() + +# For extra fun, use an independent method to recompute the constants. +assert (A1, B1, A2, B2) == find_split_constants_gauss() + +# PHI : Z[l] -> Z_n where phi(a + b*l) == a + b*lambda mod n. +def PHI(a,b): + return Z(a + LAMBDA*b) + +# Check that (A1, B1) and (A2, B2) are in the kernel of PHI. +assert PHI(A1, B1) == Z(0) +assert PHI(A2, B2) == Z(0) + +# Check that the parallelogram generated by (A1, A2) and (B1, B2) +# is a fundamental domain by containing exactly N points. +# Since the LHS is the determinant and N != 0, this also checks that +# (A1, A2) and (B1, B2) are linearly independent. By the previous +# assertions, (A1, A2) and (B1, B2) are a basis of the kernel. +assert A1*B2 - B1*A2 == N + +# Check that their components are short enough. +assert (A1 + A2)/2 < sqrt(N) +assert B1 < sqrt(N) +assert B2 < sqrt(N) + +G1 = round((2**384)*B2/N) +G2 = round((2**384)*(-B1)/N) + +def rnddiv2(v): + if v & 1: + v += 1 + return v >> 1 + +def scalar_lambda_split(k): + """Equivalent to rustsecp256k1zkp_v0_2_0_scalar_lambda_split().""" + c1 = rnddiv2((k * G1) >> 383) + c2 = rnddiv2((k * G2) >> 383) + c1 = (c1 * -B1) % N + c2 = (c2 * -B2) % N + r2 = (c1 + c2) % N + r1 = (k + r2 * -LAMBDA) % N + return (r1, r2) + +# The result of scalar_lambda_split can depend on the representation of k (mod n). +SPECIAL = (2**383) // G2 + 1 +assert scalar_lambda_split(SPECIAL) != scalar_lambda_split(SPECIAL + N) + +print(' A1 =', hex(A1)) +print(' -B1 =', hex(-B1)) +print(' A2 =', hex(A2)) +print(' -B2 =', hex(-B2)) +print(' =', hex(Z(-B2))) +print(' -LAMBDA =', hex(-LAMBDA)) + +print(' G1 =', hex(G1)) +print(' G2 =', hex(G2)) diff --git a/secp256k1-zkp-sys/depend/secp256k1/sage/group_prover.sage b/secp256k1-zkp-sys/depend/secp256k1/sage/group_prover.sage index 53ffee24..b200bfea 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/sage/group_prover.sage +++ b/secp256k1-zkp-sys/depend/secp256k1/sage/group_prover.sage @@ -42,7 +42,7 @@ # as we assume that all constraints in it are complementary with each other. # # Based on the sage verification scripts used in the Explicit-Formulas Database -# by Tanja Lange and others, see http://hyperelliptic.org/EFD +# by Tanja Lange and others, see https://hyperelliptic.org/EFD class fastfrac: """Fractions over rings.""" diff --git a/secp256k1-zkp-sys/depend/secp256k1/sage/secp256k1.sage b/secp256k1-zkp-sys/depend/secp256k1/sage/prove_group_implementations.sage similarity index 100% rename from secp256k1-zkp-sys/depend/secp256k1/sage/secp256k1.sage rename to secp256k1-zkp-sys/depend/secp256k1/sage/prove_group_implementations.sage diff --git a/secp256k1-zkp-sys/depend/secp256k1/sage/secp256k1_params.sage b/secp256k1-zkp-sys/depend/secp256k1/sage/secp256k1_params.sage new file mode 100644 index 00000000..4e000726 --- /dev/null +++ b/secp256k1-zkp-sys/depend/secp256k1/sage/secp256k1_params.sage @@ -0,0 +1,36 @@ +"""Prime order of finite field underlying secp256k1 (2^256 - 2^32 - 977)""" +P = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F + +"""Finite field underlying secp256k1""" +F = FiniteField(P) + +"""Elliptic curve secp256k1: y^2 = x^3 + 7""" +C = EllipticCurve([F(0), F(7)]) + +"""Base point of secp256k1""" +G = C.lift_x(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798) + +"""Prime order of secp256k1""" +N = C.order() + +"""Finite field of scalars of secp256k1""" +Z = FiniteField(N) + +""" Beta value of secp256k1 non-trivial endomorphism: lambda * (x, y) = (beta * x, y)""" +BETA = F(2)^((P-1)/3) + +""" Lambda value of secp256k1 non-trivial endomorphism: lambda * (x, y) = (beta * x, y)""" +LAMBDA = Z(3)^((N-1)/3) + +assert is_prime(P) +assert is_prime(N) + +assert BETA != F(1) +assert BETA^3 == F(1) +assert BETA^2 + BETA + 1 == 0 + +assert LAMBDA != Z(1) +assert LAMBDA^3 == Z(1) +assert LAMBDA^2 + LAMBDA + 1 == 0 + +assert Integer(LAMBDA)*G == C(BETA*G[0], G[1]) diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/asm/field_10x26_arm.s b/secp256k1-zkp-sys/depend/secp256k1/src/asm/field_10x26_arm.s index 3523f16b..0457ff6b 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/asm/field_10x26_arm.s +++ b/secp256k1-zkp-sys/depend/secp256k1/src/asm/field_10x26_arm.s @@ -1,9 +1,9 @@ @ vim: set tabstop=8 softtabstop=8 shiftwidth=8 noexpandtab syntax=armasm: -/********************************************************************** - * Copyright (c) 2014 Wladimir J. van der Laan * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2014 Wladimir J. van der Laan * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ /* ARM implementation of field_10x26 inner loops. diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/assumptions.h b/secp256k1-zkp-sys/depend/secp256k1/src/assumptions.h index 31031607..79655eda 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/assumptions.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/assumptions.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2020 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2020 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_ASSUMPTIONS_H #define SECP256K1_ASSUMPTIONS_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/basic-config.h b/secp256k1-zkp-sys/depend/secp256k1/src/basic-config.h index b0d82e89..bb6b5825 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/basic-config.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/basic-config.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_BASIC_CONFIG_H #define SECP256K1_BASIC_CONFIG_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/bench.h b/secp256k1-zkp-sys/depend/secp256k1/src/bench.h index 9bfed903..63c55df4 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/bench.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/bench.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_BENCH_H #define SECP256K1_BENCH_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/bench_ecdh.c b/secp256k1-zkp-sys/depend/secp256k1/src/bench_ecdh.c index 7bac5c6d..a54284dc 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/bench_ecdh.c +++ b/secp256k1-zkp-sys/depend/secp256k1/src/bench_ecdh.c @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2015 Pieter Wuille, Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2015 Pieter Wuille, Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #include diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/bench_ecmult.c b/secp256k1-zkp-sys/depend/secp256k1/src/bench_ecmult.c index 07e1504e..b65604fd 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/bench_ecmult.c +++ b/secp256k1-zkp-sys/depend/secp256k1/src/bench_ecmult.c @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2017 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2017 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #include #include "include/secp256k1.h" diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/bench_internal.c b/secp256k1-zkp-sys/depend/secp256k1/src/bench_internal.c index e8d7612c..3cf514dd 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/bench_internal.c +++ b/secp256k1-zkp-sys/depend/secp256k1/src/bench_internal.c @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2014-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2014-2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #include #include "include/secp256k1.h" diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/bench_recover.c b/secp256k1-zkp-sys/depend/secp256k1/src/bench_recover.c index d5c2b764..1becba2c 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/bench_recover.c +++ b/secp256k1-zkp-sys/depend/secp256k1/src/bench_recover.c @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2014-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2014-2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #include "include/secp256k1.h" #include "include/secp256k1_recovery.h" diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/bench_schnorrsig.c b/secp256k1-zkp-sys/depend/secp256k1/src/bench_schnorrsig.c index 5a55bc83..6c289a1d 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/bench_schnorrsig.c +++ b/secp256k1-zkp-sys/depend/secp256k1/src/bench_schnorrsig.c @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2018-2020 Andrew Poelstra, Jonas Nick * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2018-2020 Andrew Poelstra, Jonas Nick * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #include #include diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/bench_sign.c b/secp256k1-zkp-sys/depend/secp256k1/src/bench_sign.c index 2c21d566..2dad7b2f 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/bench_sign.c +++ b/secp256k1-zkp-sys/depend/secp256k1/src/bench_sign.c @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #include "include/secp256k1.h" #include "util.h" diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/bench_verify.c b/secp256k1-zkp-sys/depend/secp256k1/src/bench_verify.c index 99de86b2..6aaf06a5 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/bench_verify.c +++ b/secp256k1-zkp-sys/depend/secp256k1/src/bench_verify.c @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #include #include diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/eccommit.h b/secp256k1-zkp-sys/depend/secp256k1/src/eccommit.h new file mode 100644 index 00000000..dfdafda9 --- /dev/null +++ b/secp256k1-zkp-sys/depend/secp256k1/src/eccommit.h @@ -0,0 +1,28 @@ +/********************************************************************** + * Copyright (c) 2020 The libsecp256k1-zkp Developers * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef SECP256K1_ECCOMMIT_H +#define SECP256K1_ECCOMMIT_H + +/** Helper function to add a 32-byte value to a scalar */ +static int rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_add_helper(rustsecp256k1zkp_v0_2_0_scalar *sec, const unsigned char *tweak); +/** Helper function to add a 32-byte value, times G, to an EC point */ +static int rustsecp256k1zkp_v0_2_0_ec_pubkey_tweak_add_helper(const rustsecp256k1zkp_v0_2_0_ecmult_context* ecmult_ctx, rustsecp256k1zkp_v0_2_0_ge *p, const unsigned char *tweak); + +/** Serializes elem as a 33 byte array. This is non-constant time with respect to + * whether pubp is the point at infinity. Thus, you may need to declassify + * pubp->infinity before calling this function. */ +static int rustsecp256k1zkp_v0_2_0_ec_commit_pubkey_serialize_const(rustsecp256k1zkp_v0_2_0_ge *pubp, unsigned char *buf33); +/** Compute an ec commitment tweak as hash(pubkey, data). */ +static int rustsecp256k1zkp_v0_2_0_ec_commit_tweak(unsigned char *tweak32, rustsecp256k1zkp_v0_2_0_ge* pubp, rustsecp256k1zkp_v0_2_0_sha256* sha, const unsigned char *data, size_t data_size); +/** Compute an ec commitment as pubkey + hash(pubkey, data)*G. */ +static int rustsecp256k1zkp_v0_2_0_ec_commit(const rustsecp256k1zkp_v0_2_0_ecmult_context* ecmult_ctx, rustsecp256k1zkp_v0_2_0_ge* commitp, const rustsecp256k1zkp_v0_2_0_ge* pubp, rustsecp256k1zkp_v0_2_0_sha256* sha, const unsigned char *data, size_t data_size); +/** Compute a secret key commitment as seckey + hash(pubkey, data). */ +static int rustsecp256k1zkp_v0_2_0_ec_commit_seckey(const rustsecp256k1zkp_v0_2_0_ecmult_gen_context* ecmult_gen_ctx, rustsecp256k1zkp_v0_2_0_scalar* seckey, rustsecp256k1zkp_v0_2_0_ge* pubp, rustsecp256k1zkp_v0_2_0_sha256* sha, const unsigned char *data, size_t data_size); +/** Verify an ec commitment as pubkey + hash(pubkey, data)*G ?= commitment. */ +static int rustsecp256k1zkp_v0_2_0_ec_commit_verify(const rustsecp256k1zkp_v0_2_0_ecmult_context* ecmult_ctx, const rustsecp256k1zkp_v0_2_0_ge* commitp, const rustsecp256k1zkp_v0_2_0_ge* pubp, rustsecp256k1zkp_v0_2_0_sha256* sha, const unsigned char *data, size_t data_size); + +#endif /* SECP256K1_ECCOMMIT_H */ diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/eccommit_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/eccommit_impl.h new file mode 100644 index 00000000..81bce5e9 --- /dev/null +++ b/secp256k1-zkp-sys/depend/secp256k1/src/eccommit_impl.h @@ -0,0 +1,73 @@ +/********************************************************************** + * Copyright (c) 2020 The libsecp256k1 Developers * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#include + +#include "eckey.h" +#include "hash.h" + +/* from secp256k1.c */ +static int rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_add_helper(rustsecp256k1zkp_v0_2_0_scalar *sec, const unsigned char *tweak); +static int rustsecp256k1zkp_v0_2_0_ec_pubkey_tweak_add_helper(const rustsecp256k1zkp_v0_2_0_ecmult_context* ecmult_ctx, rustsecp256k1zkp_v0_2_0_ge *pubp, const unsigned char *tweak); + +static int rustsecp256k1zkp_v0_2_0_ec_commit_pubkey_serialize_const(rustsecp256k1zkp_v0_2_0_ge *pubp, unsigned char *buf33) { + if (rustsecp256k1zkp_v0_2_0_ge_is_infinity(pubp)) { + return 0; + } + rustsecp256k1zkp_v0_2_0_fe_normalize(&pubp->x); + rustsecp256k1zkp_v0_2_0_fe_normalize(&pubp->y); + rustsecp256k1zkp_v0_2_0_fe_get_b32(&buf33[1], &pubp->x); + buf33[0] = rustsecp256k1zkp_v0_2_0_fe_is_odd(&pubp->y) ? SECP256K1_TAG_PUBKEY_ODD : SECP256K1_TAG_PUBKEY_EVEN; + return 1; +} + +/* Compute an ec commitment tweak as hash(pubp, data). */ +static int rustsecp256k1zkp_v0_2_0_ec_commit_tweak(unsigned char *tweak32, rustsecp256k1zkp_v0_2_0_ge* pubp, rustsecp256k1zkp_v0_2_0_sha256* sha, const unsigned char *data, size_t data_size) +{ + unsigned char rbuf[33]; + + if (!rustsecp256k1zkp_v0_2_0_ec_commit_pubkey_serialize_const(pubp, rbuf)) { + return 0; + } + rustsecp256k1zkp_v0_2_0_sha256_write(sha, rbuf, sizeof(rbuf)); + rustsecp256k1zkp_v0_2_0_sha256_write(sha, data, data_size); + rustsecp256k1zkp_v0_2_0_sha256_finalize(sha, tweak32); + return 1; +} + +/* Compute an ec commitment as pubp + hash(pubp, data)*G. */ +static int rustsecp256k1zkp_v0_2_0_ec_commit(const rustsecp256k1zkp_v0_2_0_ecmult_context* ecmult_ctx, rustsecp256k1zkp_v0_2_0_ge* commitp, const rustsecp256k1zkp_v0_2_0_ge* pubp, rustsecp256k1zkp_v0_2_0_sha256* sha, const unsigned char *data, size_t data_size) { + unsigned char tweak[32]; + + *commitp = *pubp; + return rustsecp256k1zkp_v0_2_0_ec_commit_tweak(tweak, commitp, sha, data, data_size) + && rustsecp256k1zkp_v0_2_0_ec_pubkey_tweak_add_helper(ecmult_ctx, commitp, tweak); +} + +/* Compute the seckey of an ec commitment from the original secret key of the pubkey as seckey + + * hash(pubp, data). */ +static int rustsecp256k1zkp_v0_2_0_ec_commit_seckey(rustsecp256k1zkp_v0_2_0_scalar* seckey, rustsecp256k1zkp_v0_2_0_ge* pubp, rustsecp256k1zkp_v0_2_0_sha256* sha, const unsigned char *data, size_t data_size) { + unsigned char tweak[32]; + return rustsecp256k1zkp_v0_2_0_ec_commit_tweak(tweak, pubp, sha, data, data_size) + && rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_add_helper(seckey, tweak); +} + +/* Verify an ec commitment as pubp + hash(pubp, data)*G ?= commitment. */ +static int rustsecp256k1zkp_v0_2_0_ec_commit_verify(const rustsecp256k1zkp_v0_2_0_ecmult_context* ecmult_ctx, const rustsecp256k1zkp_v0_2_0_ge* commitp, const rustsecp256k1zkp_v0_2_0_ge* pubp, rustsecp256k1zkp_v0_2_0_sha256* sha, const unsigned char *data, size_t data_size) { + rustsecp256k1zkp_v0_2_0_gej pj; + rustsecp256k1zkp_v0_2_0_ge p; + + if (!rustsecp256k1zkp_v0_2_0_ec_commit(ecmult_ctx, &p, pubp, sha, data, data_size)) { + return 0; + } + + /* Return p == commitp */ + rustsecp256k1zkp_v0_2_0_ge_neg(&p, &p); + rustsecp256k1zkp_v0_2_0_gej_set_ge(&pj, &p); + rustsecp256k1zkp_v0_2_0_gej_add_ge_var(&pj, &pj, commitp, NULL); + return rustsecp256k1zkp_v0_2_0_gej_is_infinity(&pj); +} + diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/ecdsa.h b/secp256k1-zkp-sys/depend/secp256k1/src/ecdsa.h index 6d547342..b846f54f 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/ecdsa.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/ecdsa.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_ECDSA_H #define SECP256K1_ECDSA_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/ecdsa_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/ecdsa_impl.h index d3c5ecb3..1249199b 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/ecdsa_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/ecdsa_impl.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013-2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_ECDSA_IMPL_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/eckey.h b/secp256k1-zkp-sys/depend/secp256k1/src/eckey.h index bb14900f..c6e79937 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/eckey.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/eckey.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_ECKEY_H #define SECP256K1_ECKEY_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/eckey_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/eckey_impl.h index a721bcae..e29fa7c4 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/eckey_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/eckey_impl.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_ECKEY_IMPL_H #define SECP256K1_ECKEY_IMPL_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/ecmult.h b/secp256k1-zkp-sys/depend/secp256k1/src/ecmult.h index 8083f0ea..bab0ae46 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/ecmult.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/ecmult.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013, 2014, 2017 Pieter Wuille, Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014, 2017 Pieter Wuille, Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_ECMULT_H #define SECP256K1_ECMULT_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/ecmult_const.h b/secp256k1-zkp-sys/depend/secp256k1/src/ecmult_const.h index 8e32289b..f56d29fc 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/ecmult_const.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/ecmult_const.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2015 Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2015 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_ECMULT_CONST_H #define SECP256K1_ECMULT_CONST_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/ecmult_const_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/ecmult_const_impl.h index f82bddf7..e8ab099d 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/ecmult_const_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/ecmult_const_impl.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2015 Pieter Wuille, Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2015 Pieter Wuille, Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_ECMULT_CONST_IMPL_H #define SECP256K1_ECMULT_CONST_IMPL_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/ecmult_gen.h b/secp256k1-zkp-sys/depend/secp256k1/src/ecmult_gen.h index af117816..071eff8a 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/ecmult_gen.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/ecmult_gen.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_ECMULT_GEN_H #define SECP256K1_ECMULT_GEN_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/ecmult_gen_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/ecmult_gen_impl.h index 46b2d185..7d9831b5 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/ecmult_gen_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/ecmult_gen_impl.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013, 2014, 2015 Pieter Wuille, Gregory Maxwell * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014, 2015 Pieter Wuille, Gregory Maxwell * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_ECMULT_GEN_IMPL_H #define SECP256K1_ECMULT_GEN_IMPL_H @@ -144,7 +144,7 @@ static void rustsecp256k1zkp_v0_2_0_ecmult_gen(const rustsecp256k1zkp_v0_2_0_ecm * (https://cryptojedi.org/peter/data/chesrump-20130822.pdf) and * "Cache Attacks and Countermeasures: the Case of AES", RSA 2006, * by Dag Arne Osvik, Adi Shamir, and Eran Tromer - * (http://www.tau.ac.il/~tromer/papers/cache.pdf) + * (https://www.tau.ac.il/~tromer/papers/cache.pdf) */ rustsecp256k1zkp_v0_2_0_ge_storage_cmov(&adds, &(*ctx->prec)[j][i], i == bits); } diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/ecmult_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/ecmult_impl.h index dce19fb3..dd18b0a8 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/ecmult_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/ecmult_impl.h @@ -1,8 +1,8 @@ -/***************************************************************************** - * Copyright (c) 2013, 2014, 2017 Pieter Wuille, Andrew Poelstra, Jonas Nick * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php. * - *****************************************************************************/ +/****************************************************************************** + * Copyright (c) 2013, 2014, 2017 Pieter Wuille, Andrew Poelstra, Jonas Nick * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php. * + ******************************************************************************/ #ifndef SECP256K1_ECMULT_IMPL_H #define SECP256K1_ECMULT_IMPL_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/field.h b/secp256k1-zkp-sys/depend/secp256k1/src/field.h index 8fcd3401..545634e6 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/field.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/field.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_FIELD_H #define SECP256K1_FIELD_H @@ -114,11 +114,6 @@ static void rustsecp256k1zkp_v0_2_0_fe_inv(rustsecp256k1zkp_v0_2_0_fe *r, const /** Potentially faster version of rustsecp256k1zkp_v0_2_0_fe_inv, without constant-time guarantee. */ static void rustsecp256k1zkp_v0_2_0_fe_inv_var(rustsecp256k1zkp_v0_2_0_fe *r, const rustsecp256k1zkp_v0_2_0_fe *a); -/** Calculate the (modular) inverses of a batch of field elements. Requires the inputs' magnitudes to be - * at most 8. The output magnitudes are 1 (but not guaranteed to be normalized). The inputs and - * outputs must not overlap in memory. */ -static void rustsecp256k1zkp_v0_2_0_fe_inv_all_var(rustsecp256k1zkp_v0_2_0_fe *r, const rustsecp256k1zkp_v0_2_0_fe *a, size_t len); - /** Convert a field element to the storage type. */ static void rustsecp256k1zkp_v0_2_0_fe_to_storage(rustsecp256k1zkp_v0_2_0_fe_storage *r, const rustsecp256k1zkp_v0_2_0_fe *a); diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/field_10x26.h b/secp256k1-zkp-sys/depend/secp256k1/src/field_10x26.h index ab33b2bd..852e17f9 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/field_10x26.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/field_10x26.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_FIELD_REPR_H #define SECP256K1_FIELD_REPR_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/field_10x26_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/field_10x26_impl.h index 7ed978ea..bed03ae0 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/field_10x26_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/field_10x26_impl.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_FIELD_REPR_IMPL_H #define SECP256K1_FIELD_REPR_IMPL_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/field_5x52.h b/secp256k1-zkp-sys/depend/secp256k1/src/field_5x52.h index c0fbbab6..a2bfe943 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/field_5x52.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/field_5x52.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_FIELD_REPR_H #define SECP256K1_FIELD_REPR_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/field_5x52_asm_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/field_5x52_asm_impl.h index 4b9fb009..188842d5 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/field_5x52_asm_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/field_5x52_asm_impl.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013-2014 Diederik Huys, Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013-2014 Diederik Huys, Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ /** * Changelog: diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/field_5x52_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/field_5x52_impl.h index a7c3f03f..eee74d51 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/field_5x52_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/field_5x52_impl.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_FIELD_REPR_IMPL_H #define SECP256K1_FIELD_REPR_IMPL_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/field_5x52_int128_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/field_5x52_int128_impl.h index fc34e7fa..8ec43856 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/field_5x52_int128_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/field_5x52_int128_impl.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_FIELD_INNER5X52_IMPL_H #define SECP256K1_FIELD_INNER5X52_IMPL_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/field_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/field_impl.h index 4a2f26ea..909ab10e 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/field_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/field_impl.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_FIELD_IMPL_H #define SECP256K1_FIELD_IMPL_H @@ -263,33 +263,6 @@ static void rustsecp256k1zkp_v0_2_0_fe_inv_var(rustsecp256k1zkp_v0_2_0_fe *r, co #endif } -static void rustsecp256k1zkp_v0_2_0_fe_inv_all_var(rustsecp256k1zkp_v0_2_0_fe *r, const rustsecp256k1zkp_v0_2_0_fe *a, size_t len) { - rustsecp256k1zkp_v0_2_0_fe u; - size_t i; - if (len < 1) { - return; - } - - VERIFY_CHECK((r + len <= a) || (a + len <= r)); - - r[0] = a[0]; - - i = 0; - while (++i < len) { - rustsecp256k1zkp_v0_2_0_fe_mul(&r[i], &r[i - 1], &a[i]); - } - - rustsecp256k1zkp_v0_2_0_fe_inv_var(&u, &r[--i]); - - while (i > 0) { - size_t j = i--; - rustsecp256k1zkp_v0_2_0_fe_mul(&r[j], &r[i], &u); - rustsecp256k1zkp_v0_2_0_fe_mul(&u, &u, &a[j]); - } - - r[0] = u; -} - static int rustsecp256k1zkp_v0_2_0_fe_is_quad_var(const rustsecp256k1zkp_v0_2_0_fe *a) { #ifndef USE_NUM_NONE unsigned char b[32]; diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/gen_context.c b/secp256k1-zkp-sys/depend/secp256k1/src/gen_context.c index 4b606635..a5b74f79 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/gen_context.c +++ b/secp256k1-zkp-sys/depend/secp256k1/src/gen_context.c @@ -1,11 +1,11 @@ -/********************************************************************** - * Copyright (c) 2013, 2014, 2015 Thomas Daede, Cory Fields * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014, 2015 Thomas Daede, Cory Fields * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -// Autotools creates libsecp256k1-config.h, of which ECMULT_GEN_PREC_BITS is needed. -// ifndef guard so downstream users can define their own if they do not use autotools. +/* Autotools creates libsecp256k1-config.h, of which ECMULT_GEN_PREC_BITS is needed. + ifndef guard so downstream users can define their own if they do not use autotools. */ #if !defined(ECMULT_GEN_PREC_BITS) #include "libsecp256k1-config.h" #endif @@ -47,8 +47,8 @@ int main(int argc, char **argv) { return -1; } - fprintf(fp, "#ifndef _SECP256K1_ECMULT_STATIC_CONTEXT_\n"); - fprintf(fp, "#define _SECP256K1_ECMULT_STATIC_CONTEXT_\n"); + fprintf(fp, "#ifndef SECP256K1_ECMULT_STATIC_CONTEXT_H\n"); + fprintf(fp, "#define SECP256K1_ECMULT_STATIC_CONTEXT_H\n"); fprintf(fp, "#include \"src/group.h\"\n"); fprintf(fp, "#define SC SECP256K1_GE_STORAGE_CONST\n"); fprintf(fp, "#if ECMULT_GEN_PREC_N != %d || ECMULT_GEN_PREC_G != %d\n", ECMULT_GEN_PREC_N, ECMULT_GEN_PREC_G); diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/group.h b/secp256k1-zkp-sys/depend/secp256k1/src/group.h index 658c9e6d..9995dda8 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/group.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/group.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_GROUP_H #define SECP256K1_GROUP_H @@ -62,9 +62,12 @@ static int rustsecp256k1zkp_v0_2_0_ge_is_valid_var(const rustsecp256k1zkp_v0_2_0 /** Set r equal to the inverse of a (i.e., mirrored around the X axis) */ static void rustsecp256k1zkp_v0_2_0_ge_neg(rustsecp256k1zkp_v0_2_0_ge *r, const rustsecp256k1zkp_v0_2_0_ge *a); -/** Set a group element equal to another which is given in jacobian coordinates */ +/** Set a group element equal to another which is given in jacobian coordinates. Constant time. */ static void rustsecp256k1zkp_v0_2_0_ge_set_gej(rustsecp256k1zkp_v0_2_0_ge *r, rustsecp256k1zkp_v0_2_0_gej *a); +/** Set a group element equal to another which is given in jacobian coordinates. */ +static void rustsecp256k1zkp_v0_2_0_ge_set_gej_var(rustsecp256k1zkp_v0_2_0_ge *r, rustsecp256k1zkp_v0_2_0_gej *a); + /** Set a batch of group elements equal to the inputs given in jacobian coordinates */ static void rustsecp256k1zkp_v0_2_0_ge_set_all_gej_var(rustsecp256k1zkp_v0_2_0_ge *r, const rustsecp256k1zkp_v0_2_0_gej *a, size_t len); diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/group_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/group_impl.h index 5c19acc4..6cad2d97 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/group_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/group_impl.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_GROUP_IMPL_H #define SECP256K1_GROUP_IMPL_H @@ -591,7 +591,7 @@ static void rustsecp256k1zkp_v0_2_0_gej_add_ge(rustsecp256k1zkp_v0_2_0_gej *r, c rustsecp256k1zkp_v0_2_0_fe_cmov(&n, &m, degenerate); /* n = M^3 * Malt (2) */ rustsecp256k1zkp_v0_2_0_fe_sqr(&t, &rr_alt); /* t = Ralt^2 (1) */ rustsecp256k1zkp_v0_2_0_fe_mul(&r->z, &a->z, &m_alt); /* r->z = Malt*Z (1) */ - infinity = rustsecp256k1zkp_v0_2_0_fe_normalizes_to_zero(&r->z) * (1 - a->infinity); + infinity = rustsecp256k1zkp_v0_2_0_fe_normalizes_to_zero(&r->z) & ~a->infinity; rustsecp256k1zkp_v0_2_0_fe_mul_int(&r->z, 2); /* r->z = Z3 = 2*Malt*Z (2) */ rustsecp256k1zkp_v0_2_0_fe_negate(&q, &q, 1); /* q = -Q (2) */ rustsecp256k1zkp_v0_2_0_fe_add(&t, &q); /* t = Ralt^2-Q (3) */ @@ -674,7 +674,7 @@ static int rustsecp256k1zkp_v0_2_0_ge_is_in_correct_subgroup(const rustsecp256k1 rustsecp256k1zkp_v0_2_0_gej out; int i; - /* A very simple EC multiplication ladder that avoids a dependecy on ecmult. */ + /* A very simple EC multiplication ladder that avoids a dependency on ecmult. */ rustsecp256k1zkp_v0_2_0_gej_set_infinity(&out); for (i = 0; i < 32; ++i) { rustsecp256k1zkp_v0_2_0_gej_double_var(&out, &out, NULL); diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/hash.h b/secp256k1-zkp-sys/depend/secp256k1/src/hash.h index f6abc5c0..1eacafac 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/hash.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/hash.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_HASH_H #define SECP256K1_HASH_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/hash_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/hash_impl.h index eb362111..36625840 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/hash_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/hash_impl.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_HASH_IMPL_H #define SECP256K1_HASH_IMPL_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/modules/ecdh/main_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/modules/ecdh/main_impl.h index f70a1b87..9655644e 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/modules/ecdh/main_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/modules/ecdh/main_impl.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2015 Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2015 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_MODULE_ECDH_MAIN_H #define SECP256K1_MODULE_ECDH_MAIN_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/modules/ecdh/tests_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/modules/ecdh/tests_impl.h index dc31358b..034b6b9f 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/modules/ecdh/tests_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/modules/ecdh/tests_impl.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2015 Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2015 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_MODULE_ECDH_TESTS_H #define SECP256K1_MODULE_ECDH_TESTS_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/modules/ecdsa_adaptor/Makefile.am.include b/secp256k1-zkp-sys/depend/secp256k1/src/modules/ecdsa_adaptor/Makefile.am.include new file mode 100644 index 00000000..0b4acf11 --- /dev/null +++ b/secp256k1-zkp-sys/depend/secp256k1/src/modules/ecdsa_adaptor/Makefile.am.include @@ -0,0 +1,4 @@ +include_HEADERS += include/rustsecp256k1zkp_v0_2_0_ecdsa_adaptor.h +noinst_HEADERS += src/modules/ecdsa_adaptor/main_impl.h +noinst_HEADERS += src/modules/ecdsa_adaptor/dleq_impl.h +noinst_HEADERS += src/modules/ecdsa_adaptor/tests_impl.h diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/modules/ecdsa_adaptor/dleq_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/modules/ecdsa_adaptor/dleq_impl.h new file mode 100644 index 00000000..06dc47ab --- /dev/null +++ b/secp256k1-zkp-sys/depend/secp256k1/src/modules/ecdsa_adaptor/dleq_impl.h @@ -0,0 +1,158 @@ +#ifndef SECP256K1_DLEQ_IMPL_H +#define SECP256K1_DLEQ_IMPL_H + +/* Initializes SHA256 with fixed midstate. This midstate was computed by applying + * SHA256 to SHA256("DLEQ")||SHA256("DLEQ"). */ +static void rustsecp256k1zkp_v0_2_0_nonce_function_dleq_sha256_tagged(rustsecp256k1zkp_v0_2_0_sha256 *sha) { + rustsecp256k1zkp_v0_2_0_sha256_initialize(sha); + sha->s[0] = 0x8cc4beacul; + sha->s[1] = 0x2e011f3ful; + sha->s[2] = 0x355c75fbul; + sha->s[3] = 0x3ba6a2c5ul; + sha->s[4] = 0xe96f3aeful; + sha->s[5] = 0x180530fdul; + sha->s[6] = 0x94582499ul; + sha->s[7] = 0x577fd564ul; + + sha->bytes = 64; +} + +/* algo argument for nonce_function_ecdsa_adaptor to derive the nonce using a tagged hash function. */ +static const unsigned char dleq_algo[4] = "DLEQ"; + +static int rustsecp256k1zkp_v0_2_0_dleq_hash_point(rustsecp256k1zkp_v0_2_0_sha256 *sha, rustsecp256k1zkp_v0_2_0_ge *p) { + unsigned char buf[33]; + size_t size = 33; + + if (!rustsecp256k1zkp_v0_2_0_eckey_pubkey_serialize(p, buf, &size, 1)) { + return 0; + } + + rustsecp256k1zkp_v0_2_0_sha256_write(sha, buf, size); + return 1; +} + +static int rustsecp256k1zkp_v0_2_0_dleq_nonce(rustsecp256k1zkp_v0_2_0_scalar *k, const unsigned char *sk32, const unsigned char *gen2_33, const unsigned char *p1_33, const unsigned char *p2_33, rustsecp256k1zkp_v0_2_0_nonce_function_hardened_ecdsa_adaptor noncefp, void *ndata) { + rustsecp256k1zkp_v0_2_0_sha256 sha; + unsigned char buf[32]; + unsigned char nonce[32]; + size_t size = 33; + + if (noncefp == NULL) { + noncefp = rustsecp256k1zkp_v0_2_0_nonce_function_ecdsa_adaptor; + } + + rustsecp256k1zkp_v0_2_0_sha256_initialize(&sha); + rustsecp256k1zkp_v0_2_0_sha256_write(&sha, p1_33, size); + rustsecp256k1zkp_v0_2_0_sha256_write(&sha, p2_33, size); + rustsecp256k1zkp_v0_2_0_sha256_finalize(&sha, buf); + + if (!noncefp(nonce, buf, sk32, gen2_33, dleq_algo, sizeof(dleq_algo), ndata)) { + return 0; + } + rustsecp256k1zkp_v0_2_0_scalar_set_b32(k, nonce, NULL); + if (rustsecp256k1zkp_v0_2_0_scalar_is_zero(k)) { + return 0; + } + + return 1; +} + +/* Generates a challenge as defined in the DLC Specification at + * https://github.com/discreetlogcontracts/dlcspecs */ +static void rustsecp256k1zkp_v0_2_0_dleq_challenge(rustsecp256k1zkp_v0_2_0_scalar *e, rustsecp256k1zkp_v0_2_0_ge *gen2, rustsecp256k1zkp_v0_2_0_ge *r1, rustsecp256k1zkp_v0_2_0_ge *r2, rustsecp256k1zkp_v0_2_0_ge *p1, rustsecp256k1zkp_v0_2_0_ge *p2) { + unsigned char buf[32]; + rustsecp256k1zkp_v0_2_0_sha256 sha; + + rustsecp256k1zkp_v0_2_0_nonce_function_dleq_sha256_tagged(&sha); + rustsecp256k1zkp_v0_2_0_dleq_hash_point(&sha, p1); + rustsecp256k1zkp_v0_2_0_dleq_hash_point(&sha, gen2); + rustsecp256k1zkp_v0_2_0_dleq_hash_point(&sha, p2); + rustsecp256k1zkp_v0_2_0_dleq_hash_point(&sha, r1); + rustsecp256k1zkp_v0_2_0_dleq_hash_point(&sha, r2); + rustsecp256k1zkp_v0_2_0_sha256_finalize(&sha, buf); + + rustsecp256k1zkp_v0_2_0_scalar_set_b32(e, buf, NULL); +} + +/* P1 = x*G, P2 = x*Y */ +static void rustsecp256k1zkp_v0_2_0_dleq_pair(const rustsecp256k1zkp_v0_2_0_ecmult_gen_context *ecmult_gen_ctx, rustsecp256k1zkp_v0_2_0_ge *p1, rustsecp256k1zkp_v0_2_0_ge *p2, const rustsecp256k1zkp_v0_2_0_scalar *sk, const rustsecp256k1zkp_v0_2_0_ge *gen2) { + rustsecp256k1zkp_v0_2_0_gej p1j, p2j; + + rustsecp256k1zkp_v0_2_0_ecmult_gen(ecmult_gen_ctx, &p1j, sk); + rustsecp256k1zkp_v0_2_0_ge_set_gej(p1, &p1j); + rustsecp256k1zkp_v0_2_0_ecmult_const(&p2j, gen2, sk, 256); + rustsecp256k1zkp_v0_2_0_ge_set_gej(p2, &p2j); +} + +/* Generates a proof that the discrete logarithm of P1 to the secp256k1 base G is the + * same as the discrete logarithm of P2 to the base Y */ +static int rustsecp256k1zkp_v0_2_0_dleq_prove(const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_scalar *s, rustsecp256k1zkp_v0_2_0_scalar *e, const rustsecp256k1zkp_v0_2_0_scalar *sk, rustsecp256k1zkp_v0_2_0_ge *gen2, rustsecp256k1zkp_v0_2_0_ge *p1, rustsecp256k1zkp_v0_2_0_ge *p2, rustsecp256k1zkp_v0_2_0_nonce_function_hardened_ecdsa_adaptor noncefp, void *ndata) { + rustsecp256k1zkp_v0_2_0_ge r1, r2; + rustsecp256k1zkp_v0_2_0_scalar k = { 0 }; + unsigned char sk32[32]; + unsigned char gen2_33[33]; + unsigned char p1_33[33]; + unsigned char p2_33[33]; + int ret = 1; + size_t pubkey_size = 33; + + rustsecp256k1zkp_v0_2_0_scalar_get_b32(sk32, sk); + if (!rustsecp256k1zkp_v0_2_0_eckey_pubkey_serialize(gen2, gen2_33, &pubkey_size, 1)) { + return 0; + } + if (!rustsecp256k1zkp_v0_2_0_eckey_pubkey_serialize(p1, p1_33, &pubkey_size, 1)) { + return 0; + } + if (!rustsecp256k1zkp_v0_2_0_eckey_pubkey_serialize(p2, p2_33, &pubkey_size, 1)) { + return 0; + } + + ret &= rustsecp256k1zkp_v0_2_0_dleq_nonce(&k, sk32, gen2_33, p1_33, p2_33, noncefp, ndata); + /* R1 = k*G, R2 = k*Y */ + rustsecp256k1zkp_v0_2_0_dleq_pair(&ctx->ecmult_gen_ctx, &r1, &r2, &k, gen2); + /* We declassify the non-secret values r1 and r2 to allow using them as + * branch points. */ + rustsecp256k1zkp_v0_2_0_declassify(ctx, &r1, sizeof(r1)); + rustsecp256k1zkp_v0_2_0_declassify(ctx, &r2, sizeof(r2)); + + /* e = tagged hash(p1, gen2, p2, r1, r2) */ + /* s = k + e * sk */ + rustsecp256k1zkp_v0_2_0_dleq_challenge(e, gen2, &r1, &r2, p1, p2); + rustsecp256k1zkp_v0_2_0_scalar_mul(s, e, sk); + rustsecp256k1zkp_v0_2_0_scalar_add(s, s, &k); + + rustsecp256k1zkp_v0_2_0_scalar_clear(&k); + return ret; +} + +static int rustsecp256k1zkp_v0_2_0_dleq_verify(const rustsecp256k1zkp_v0_2_0_ecmult_context *ecmult_ctx, const rustsecp256k1zkp_v0_2_0_scalar *s, const rustsecp256k1zkp_v0_2_0_scalar *e, rustsecp256k1zkp_v0_2_0_ge *p1, rustsecp256k1zkp_v0_2_0_ge *gen2, rustsecp256k1zkp_v0_2_0_ge *p2) { + rustsecp256k1zkp_v0_2_0_scalar e_neg; + rustsecp256k1zkp_v0_2_0_scalar e_expected; + rustsecp256k1zkp_v0_2_0_gej gen2j; + rustsecp256k1zkp_v0_2_0_gej p1j, p2j; + rustsecp256k1zkp_v0_2_0_gej r1j, r2j; + rustsecp256k1zkp_v0_2_0_ge r1, r2; + rustsecp256k1zkp_v0_2_0_gej tmpj; + + rustsecp256k1zkp_v0_2_0_gej_set_ge(&p1j, p1); + rustsecp256k1zkp_v0_2_0_gej_set_ge(&p2j, p2); + + rustsecp256k1zkp_v0_2_0_scalar_negate(&e_neg, e); + /* R1 = s*G - e*P1 */ + rustsecp256k1zkp_v0_2_0_ecmult(ecmult_ctx, &r1j, &p1j, &e_neg, s); + /* R2 = s*gen2 - e*P2 */ + rustsecp256k1zkp_v0_2_0_ecmult(ecmult_ctx, &tmpj, &p2j, &e_neg, &rustsecp256k1zkp_v0_2_0_scalar_zero); + rustsecp256k1zkp_v0_2_0_gej_set_ge(&gen2j, gen2); + rustsecp256k1zkp_v0_2_0_ecmult(ecmult_ctx, &r2j, &gen2j, s, &rustsecp256k1zkp_v0_2_0_scalar_zero); + rustsecp256k1zkp_v0_2_0_gej_add_var(&r2j, &r2j, &tmpj, NULL); + + rustsecp256k1zkp_v0_2_0_ge_set_gej(&r1, &r1j); + rustsecp256k1zkp_v0_2_0_ge_set_gej(&r2, &r2j); + rustsecp256k1zkp_v0_2_0_dleq_challenge(&e_expected, gen2, &r1, &r2, p1, p2); + + rustsecp256k1zkp_v0_2_0_scalar_add(&e_expected, &e_expected, &e_neg); + return rustsecp256k1zkp_v0_2_0_scalar_is_zero(&e_expected); +} + +#endif diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/modules/ecdsa_adaptor/main_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/modules/ecdsa_adaptor/main_impl.h new file mode 100644 index 00000000..a0f9f3fd --- /dev/null +++ b/secp256k1-zkp-sys/depend/secp256k1/src/modules/ecdsa_adaptor/main_impl.h @@ -0,0 +1,365 @@ +/********************************************************************** + * Copyright (c) 2020-2021 Jonas Nick, Jesse Posner * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef SECP256K1_MODULE_ECDSA_ADAPTOR_MAIN_H +#define SECP256K1_MODULE_ECDSA_ADAPTOR_MAIN_H + +#include "include/secp256k1_ecdsa_adaptor.h" +#include "modules/ecdsa_adaptor/dleq_impl.h" + +/* (R, R', s', dleq_proof) */ +static int rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_sig_serialize(unsigned char *adaptor_sig162, rustsecp256k1zkp_v0_2_0_ge *r, rustsecp256k1zkp_v0_2_0_ge *rp, const rustsecp256k1zkp_v0_2_0_scalar *sp, const rustsecp256k1zkp_v0_2_0_scalar *dleq_proof_e, const rustsecp256k1zkp_v0_2_0_scalar *dleq_proof_s) { + size_t size = 33; + + if (!rustsecp256k1zkp_v0_2_0_eckey_pubkey_serialize(r, adaptor_sig162, &size, 1)) { + return 0; + } + if (!rustsecp256k1zkp_v0_2_0_eckey_pubkey_serialize(rp, &adaptor_sig162[33], &size, 1)) { + return 0; + } + rustsecp256k1zkp_v0_2_0_scalar_get_b32(&adaptor_sig162[66], sp); + rustsecp256k1zkp_v0_2_0_scalar_get_b32(&adaptor_sig162[98], dleq_proof_e); + rustsecp256k1zkp_v0_2_0_scalar_get_b32(&adaptor_sig162[130], dleq_proof_s); + + return 1; +} + +static int rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_sig_deserialize(rustsecp256k1zkp_v0_2_0_ge *r, rustsecp256k1zkp_v0_2_0_scalar *sigr, rustsecp256k1zkp_v0_2_0_ge *rp, rustsecp256k1zkp_v0_2_0_scalar *sp, rustsecp256k1zkp_v0_2_0_scalar *dleq_proof_e, rustsecp256k1zkp_v0_2_0_scalar *dleq_proof_s, const unsigned char *adaptor_sig162) { + /* If r is deserialized, require that a sigr is provided to receive + * the X-coordinate */ + VERIFY_CHECK((r == NULL) || (r != NULL && sigr != NULL)); + if (r != NULL) { + if (!rustsecp256k1zkp_v0_2_0_eckey_pubkey_parse(r, &adaptor_sig162[0], 33)) { + return 0; + } + } + if (sigr != NULL) { + rustsecp256k1zkp_v0_2_0_scalar_set_b32(sigr, &adaptor_sig162[1], NULL); + if (rustsecp256k1zkp_v0_2_0_scalar_is_zero(sigr)) { + return 0; + } + } + if (rp != NULL) { + if (!rustsecp256k1zkp_v0_2_0_eckey_pubkey_parse(rp, &adaptor_sig162[33], 33)) { + return 0; + } + } + if (sp != NULL) { + if (!rustsecp256k1zkp_v0_2_0_scalar_set_b32_seckey(sp, &adaptor_sig162[66])) { + return 0; + } + } + if (dleq_proof_e != NULL) { + rustsecp256k1zkp_v0_2_0_scalar_set_b32(dleq_proof_e, &adaptor_sig162[98], NULL); + } + if (dleq_proof_s != NULL) { + int overflow; + rustsecp256k1zkp_v0_2_0_scalar_set_b32(dleq_proof_s, &adaptor_sig162[130], &overflow); + if (overflow) { + return 0; + } + } + return 1; +} + +/* Initializes SHA256 with fixed midstate. This midstate was computed by applying + * SHA256 to SHA256("ECDSAadaptor/non")||SHA256("ECDSAadaptor/non"). */ +static void rustsecp256k1zkp_v0_2_0_nonce_function_ecdsa_adaptor_sha256_tagged(rustsecp256k1zkp_v0_2_0_sha256 *sha) { + rustsecp256k1zkp_v0_2_0_sha256_initialize(sha); + sha->s[0] = 0x791dae43ul; + sha->s[1] = 0xe52d3b44ul; + sha->s[2] = 0x37f9edeaul; + sha->s[3] = 0x9bfd2ab1ul; + sha->s[4] = 0xcfb0f44dul; + sha->s[5] = 0xccf1d880ul; + sha->s[6] = 0xd18f2c13ul; + sha->s[7] = 0xa37b9024ul; + + sha->bytes = 64; +} + +/* Initializes SHA256 with fixed midstate. This midstate was computed by applying + * SHA256 to SHA256("ECDSAadaptor/aux")||SHA256("ECDSAadaptor/aux"). */ +static void rustsecp256k1zkp_v0_2_0_nonce_function_ecdsa_adaptor_sha256_tagged_aux(rustsecp256k1zkp_v0_2_0_sha256 *sha) { + rustsecp256k1zkp_v0_2_0_sha256_initialize(sha); + sha->s[0] = 0xd14c7bd9ul; + sha->s[1] = 0x095d35e6ul; + sha->s[2] = 0xb8490a88ul; + sha->s[3] = 0xfb00ef74ul; + sha->s[4] = 0x0baa488ful; + sha->s[5] = 0x69366693ul; + sha->s[6] = 0x1c81c5baul; + sha->s[7] = 0xc33b296aul; + + sha->bytes = 64; +} + +/* algo argument for nonce_function_ecdsa_adaptor to derive the nonce using a tagged hash function. */ +static const unsigned char ecdsa_adaptor_algo[16] = "ECDSAadaptor/non"; + +/* Modified BIP-340 nonce function */ +static int nonce_function_ecdsa_adaptor(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *pk33, const unsigned char *algo, size_t algolen, void *data) { + rustsecp256k1zkp_v0_2_0_sha256 sha; + unsigned char masked_key[32]; + int i; + + if (algo == NULL) { + return 0; + } + + if (data != NULL) { + rustsecp256k1zkp_v0_2_0_nonce_function_ecdsa_adaptor_sha256_tagged_aux(&sha); + rustsecp256k1zkp_v0_2_0_sha256_write(&sha, data, 32); + rustsecp256k1zkp_v0_2_0_sha256_finalize(&sha, masked_key); + for (i = 0; i < 32; i++) { + masked_key[i] ^= key32[i]; + } + } + + /* Tag the hash with algo which is important to avoid nonce reuse across + * algorithims. An optimized tagging implementation is used if the default + * tag is provided. */ + if (algolen == sizeof(ecdsa_adaptor_algo) + && rustsecp256k1zkp_v0_2_0_memcmp_var(algo, ecdsa_adaptor_algo, algolen) == 0) { + rustsecp256k1zkp_v0_2_0_nonce_function_ecdsa_adaptor_sha256_tagged(&sha); + } else if (algolen == sizeof(dleq_algo) + && rustsecp256k1zkp_v0_2_0_memcmp_var(algo, dleq_algo, algolen) == 0) { + rustsecp256k1zkp_v0_2_0_nonce_function_dleq_sha256_tagged(&sha); + } else { + rustsecp256k1zkp_v0_2_0_sha256_initialize_tagged(&sha, algo, algolen); + } + + /* Hash (masked-)key||pk||msg using the tagged hash as per BIP-340 */ + if (data != NULL) { + rustsecp256k1zkp_v0_2_0_sha256_write(&sha, masked_key, 32); + } else { + rustsecp256k1zkp_v0_2_0_sha256_write(&sha, key32, 32); + } + rustsecp256k1zkp_v0_2_0_sha256_write(&sha, pk33, 33); + rustsecp256k1zkp_v0_2_0_sha256_write(&sha, msg32, 32); + rustsecp256k1zkp_v0_2_0_sha256_finalize(&sha, nonce32); + return 1; +} + +const rustsecp256k1zkp_v0_2_0_nonce_function_hardened_ecdsa_adaptor rustsecp256k1zkp_v0_2_0_nonce_function_ecdsa_adaptor = nonce_function_ecdsa_adaptor; + +int rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_encrypt(const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char *adaptor_sig162, unsigned char *seckey32, const rustsecp256k1zkp_v0_2_0_pubkey *enckey, const unsigned char *msg32, rustsecp256k1zkp_v0_2_0_nonce_function_hardened_ecdsa_adaptor noncefp, void *ndata) { + rustsecp256k1zkp_v0_2_0_scalar k; + rustsecp256k1zkp_v0_2_0_gej rj, rpj; + rustsecp256k1zkp_v0_2_0_ge r, rp; + rustsecp256k1zkp_v0_2_0_ge enckey_ge; + rustsecp256k1zkp_v0_2_0_scalar dleq_proof_s; + rustsecp256k1zkp_v0_2_0_scalar dleq_proof_e; + rustsecp256k1zkp_v0_2_0_scalar sk; + rustsecp256k1zkp_v0_2_0_scalar msg; + rustsecp256k1zkp_v0_2_0_scalar sp; + rustsecp256k1zkp_v0_2_0_scalar sigr; + rustsecp256k1zkp_v0_2_0_scalar n; + unsigned char nonce32[32] = { 0 }; + unsigned char buf33[33]; + size_t size = 33; + int ret = 1; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(rustsecp256k1zkp_v0_2_0_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + ARG_CHECK(adaptor_sig162 != NULL); + ARG_CHECK(seckey32 != NULL); + ARG_CHECK(enckey != NULL); + ARG_CHECK(msg32 != NULL); + + rustsecp256k1zkp_v0_2_0_scalar_clear(&dleq_proof_e); + rustsecp256k1zkp_v0_2_0_scalar_clear(&dleq_proof_s); + + if (noncefp == NULL) { + noncefp = rustsecp256k1zkp_v0_2_0_nonce_function_ecdsa_adaptor; + } + + ret &= rustsecp256k1zkp_v0_2_0_pubkey_load(ctx, &enckey_ge, enckey); + ret &= rustsecp256k1zkp_v0_2_0_eckey_pubkey_serialize(&enckey_ge, buf33, &size, 1); + ret &= !!noncefp(nonce32, msg32, seckey32, buf33, ecdsa_adaptor_algo, sizeof(ecdsa_adaptor_algo), ndata); + rustsecp256k1zkp_v0_2_0_scalar_set_b32(&k, nonce32, NULL); + ret &= !rustsecp256k1zkp_v0_2_0_scalar_is_zero(&k); + rustsecp256k1zkp_v0_2_0_scalar_cmov(&k, &rustsecp256k1zkp_v0_2_0_scalar_one, !ret); + + /* R' := k*G */ + rustsecp256k1zkp_v0_2_0_ecmult_gen(&ctx->ecmult_gen_ctx, &rpj, &k); + rustsecp256k1zkp_v0_2_0_ge_set_gej(&rp, &rpj); + /* R = k*Y; */ + rustsecp256k1zkp_v0_2_0_ecmult_const(&rj, &enckey_ge, &k, 256); + rustsecp256k1zkp_v0_2_0_ge_set_gej(&r, &rj); + /* We declassify the non-secret values rp and r to allow using them + * as branch points. */ + rustsecp256k1zkp_v0_2_0_declassify(ctx, &rp, sizeof(rp)); + rustsecp256k1zkp_v0_2_0_declassify(ctx, &r, sizeof(r)); + + /* dleq_proof = DLEQ_prove(k, (R', Y, R)) */ + ret &= rustsecp256k1zkp_v0_2_0_dleq_prove(ctx, &dleq_proof_s, &dleq_proof_e, &k, &enckey_ge, &rp, &r, noncefp, ndata); + + ret &= rustsecp256k1zkp_v0_2_0_scalar_set_b32_seckey(&sk, seckey32); + rustsecp256k1zkp_v0_2_0_scalar_cmov(&sk, &rustsecp256k1zkp_v0_2_0_scalar_one, !ret); + rustsecp256k1zkp_v0_2_0_scalar_set_b32(&msg, msg32, NULL); + rustsecp256k1zkp_v0_2_0_fe_normalize(&r.x); + rustsecp256k1zkp_v0_2_0_fe_get_b32(buf33, &r.x); + rustsecp256k1zkp_v0_2_0_scalar_set_b32(&sigr, buf33, NULL); + ret &= !rustsecp256k1zkp_v0_2_0_scalar_is_zero(&sigr); + /* s' = k⁻¹(m + R.x * x) */ + rustsecp256k1zkp_v0_2_0_scalar_mul(&n, &sigr, &sk); + rustsecp256k1zkp_v0_2_0_scalar_add(&n, &n, &msg); + rustsecp256k1zkp_v0_2_0_scalar_inverse(&sp, &k); + rustsecp256k1zkp_v0_2_0_scalar_mul(&sp, &sp, &n); + ret &= !rustsecp256k1zkp_v0_2_0_scalar_is_zero(&sp); + + /* return (R, R', s', dleq_proof) */ + ret &= rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_sig_serialize(adaptor_sig162, &r, &rp, &sp, &dleq_proof_e, &dleq_proof_s); + + rustsecp256k1zkp_v0_2_0_memczero(adaptor_sig162, 162, !ret); + rustsecp256k1zkp_v0_2_0_scalar_clear(&n); + rustsecp256k1zkp_v0_2_0_scalar_clear(&k); + rustsecp256k1zkp_v0_2_0_scalar_clear(&sk); + + return ret; +} + +int rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_verify(const rustsecp256k1zkp_v0_2_0_context* ctx, const unsigned char *adaptor_sig162, const rustsecp256k1zkp_v0_2_0_pubkey *pubkey, const unsigned char *msg32, const rustsecp256k1zkp_v0_2_0_pubkey *enckey) { + rustsecp256k1zkp_v0_2_0_scalar dleq_proof_s, dleq_proof_e; + rustsecp256k1zkp_v0_2_0_scalar msg; + rustsecp256k1zkp_v0_2_0_ge pubkey_ge; + rustsecp256k1zkp_v0_2_0_ge r, rp; + rustsecp256k1zkp_v0_2_0_scalar sp; + rustsecp256k1zkp_v0_2_0_scalar sigr; + rustsecp256k1zkp_v0_2_0_ge enckey_ge; + rustsecp256k1zkp_v0_2_0_gej derived_rp; + rustsecp256k1zkp_v0_2_0_scalar sn, u1, u2; + rustsecp256k1zkp_v0_2_0_gej pubkeyj; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(rustsecp256k1zkp_v0_2_0_ecmult_context_is_built(&ctx->ecmult_ctx)); + ARG_CHECK(adaptor_sig162 != NULL); + ARG_CHECK(pubkey != NULL); + ARG_CHECK(msg32 != NULL); + ARG_CHECK(enckey != NULL); + + if (!rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_sig_deserialize(&r, &sigr, &rp, &sp, &dleq_proof_e, &dleq_proof_s, adaptor_sig162)) { + return 0; + } + if (!rustsecp256k1zkp_v0_2_0_pubkey_load(ctx, &enckey_ge, enckey)) { + return 0; + } + /* DLEQ_verify((R', Y, R), dleq_proof) */ + if(!rustsecp256k1zkp_v0_2_0_dleq_verify(&ctx->ecmult_ctx, &dleq_proof_s, &dleq_proof_e, &rp, &enckey_ge, &r)) { + return 0; + } + rustsecp256k1zkp_v0_2_0_scalar_set_b32(&msg, msg32, NULL); + if (!rustsecp256k1zkp_v0_2_0_pubkey_load(ctx, &pubkey_ge, pubkey)) { + return 0; + } + + /* return R' == s'⁻¹(m * G + R.x * X) */ + rustsecp256k1zkp_v0_2_0_scalar_inverse_var(&sn, &sp); + rustsecp256k1zkp_v0_2_0_scalar_mul(&u1, &sn, &msg); + rustsecp256k1zkp_v0_2_0_scalar_mul(&u2, &sn, &sigr); + rustsecp256k1zkp_v0_2_0_gej_set_ge(&pubkeyj, &pubkey_ge); + rustsecp256k1zkp_v0_2_0_ecmult(&ctx->ecmult_ctx, &derived_rp, &pubkeyj, &u2, &u1); + if (rustsecp256k1zkp_v0_2_0_gej_is_infinity(&derived_rp)) { + return 0; + } + rustsecp256k1zkp_v0_2_0_gej_neg(&derived_rp, &derived_rp); + rustsecp256k1zkp_v0_2_0_gej_add_ge_var(&derived_rp, &derived_rp, &rp, NULL); + return rustsecp256k1zkp_v0_2_0_gej_is_infinity(&derived_rp); +} + +int rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_decrypt(const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_ecdsa_signature *sig, const unsigned char *deckey32, const unsigned char *adaptor_sig162) { + rustsecp256k1zkp_v0_2_0_scalar deckey; + rustsecp256k1zkp_v0_2_0_scalar sp; + rustsecp256k1zkp_v0_2_0_scalar s; + rustsecp256k1zkp_v0_2_0_scalar sigr; + int overflow; + int high; + int ret = 1; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(sig != NULL); + ARG_CHECK(deckey32 != NULL); + ARG_CHECK(adaptor_sig162 != NULL); + + rustsecp256k1zkp_v0_2_0_scalar_clear(&sp); + rustsecp256k1zkp_v0_2_0_scalar_set_b32(&deckey, deckey32, &overflow); + ret &= !overflow; + ret &= rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_sig_deserialize(NULL, &sigr, NULL, &sp, NULL, NULL, adaptor_sig162); + ret &= !rustsecp256k1zkp_v0_2_0_scalar_is_zero(&deckey); + rustsecp256k1zkp_v0_2_0_scalar_inverse(&s, &deckey); + /* s = s' * y⁻¹ */ + rustsecp256k1zkp_v0_2_0_scalar_mul(&s, &s, &sp); + high = rustsecp256k1zkp_v0_2_0_scalar_is_high(&s); + rustsecp256k1zkp_v0_2_0_scalar_cond_negate(&s, high); + rustsecp256k1zkp_v0_2_0_ecdsa_signature_save(sig, &sigr, &s); + + rustsecp256k1zkp_v0_2_0_memczero(&sig->data[0], 64, !ret); + rustsecp256k1zkp_v0_2_0_scalar_clear(&deckey); + rustsecp256k1zkp_v0_2_0_scalar_clear(&sp); + rustsecp256k1zkp_v0_2_0_scalar_clear(&s); + + return ret; +} + +int rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_recover(const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char *deckey32, const rustsecp256k1zkp_v0_2_0_ecdsa_signature *sig, const unsigned char *adaptor_sig162, const rustsecp256k1zkp_v0_2_0_pubkey *enckey) { + rustsecp256k1zkp_v0_2_0_scalar sp, adaptor_sigr; + rustsecp256k1zkp_v0_2_0_scalar s, r; + rustsecp256k1zkp_v0_2_0_scalar deckey; + rustsecp256k1zkp_v0_2_0_ge enckey_expected_ge; + rustsecp256k1zkp_v0_2_0_gej enckey_expected_gej; + unsigned char enckey33[33]; + unsigned char enckey_expected33[33]; + size_t size = 33; + int ret = 1; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(rustsecp256k1zkp_v0_2_0_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + ARG_CHECK(deckey32 != NULL); + ARG_CHECK(sig != NULL); + ARG_CHECK(adaptor_sig162 != NULL); + ARG_CHECK(enckey != NULL); + + if (!rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_sig_deserialize(NULL, &adaptor_sigr, NULL, &sp, NULL, NULL, adaptor_sig162)) { + return 0; + } + rustsecp256k1zkp_v0_2_0_ecdsa_signature_load(ctx, &r, &s, sig); + /* Check that we're not looking at some unrelated signature */ + ret &= rustsecp256k1zkp_v0_2_0_scalar_eq(&adaptor_sigr, &r); + /* y = s⁻¹ * s' */ + ret &= !rustsecp256k1zkp_v0_2_0_scalar_is_zero(&s); + rustsecp256k1zkp_v0_2_0_scalar_inverse(&deckey, &s); + rustsecp256k1zkp_v0_2_0_scalar_mul(&deckey, &deckey, &sp); + + /* Deal with ECDSA malleability */ + rustsecp256k1zkp_v0_2_0_ecmult_gen(&ctx->ecmult_gen_ctx, &enckey_expected_gej, &deckey); + rustsecp256k1zkp_v0_2_0_ge_set_gej(&enckey_expected_ge, &enckey_expected_gej); + /* We declassify non-secret enckey_expected_ge to allow using it as a + * branch point. */ + rustsecp256k1zkp_v0_2_0_declassify(ctx, &enckey_expected_ge, sizeof(enckey_expected_ge)); + if (!rustsecp256k1zkp_v0_2_0_eckey_pubkey_serialize(&enckey_expected_ge, enckey_expected33, &size, SECP256K1_EC_COMPRESSED)) { + return 0; + } + if (!rustsecp256k1zkp_v0_2_0_ec_pubkey_serialize(ctx, enckey33, &size, enckey, SECP256K1_EC_COMPRESSED)) { + return 0; + } + if (rustsecp256k1zkp_v0_2_0_memcmp_var(&enckey_expected33[1], &enckey33[1], 32) != 0) { + return 0; + } + if (enckey_expected33[0] != enckey33[0]) { + /* try Y_implied == -Y */ + rustsecp256k1zkp_v0_2_0_scalar_negate(&deckey, &deckey); + } + rustsecp256k1zkp_v0_2_0_scalar_get_b32(deckey32, &deckey); + + rustsecp256k1zkp_v0_2_0_scalar_clear(&deckey); + rustsecp256k1zkp_v0_2_0_scalar_clear(&sp); + rustsecp256k1zkp_v0_2_0_scalar_clear(&s); + + return ret; +} + +#endif diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/modules/ecdsa_adaptor/tests_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/modules/ecdsa_adaptor/tests_impl.h new file mode 100644 index 00000000..542aedc5 --- /dev/null +++ b/secp256k1-zkp-sys/depend/secp256k1/src/modules/ecdsa_adaptor/tests_impl.h @@ -0,0 +1,1221 @@ +#ifndef SECP256K1_MODULE_ECDSA_ADAPTOR_TESTS_H +#define SECP256K1_MODULE_ECDSA_ADAPTOR_TESTS_H + +#include "include/secp256k1_ecdsa_adaptor.h" + +void rand_scalar(rustsecp256k1zkp_v0_2_0_scalar *scalar) { + unsigned char buf32[32]; + rustsecp256k1zkp_v0_2_0_testrand256(buf32); + rustsecp256k1zkp_v0_2_0_scalar_set_b32(scalar, buf32, NULL); +} + +void rand_point(rustsecp256k1zkp_v0_2_0_ge *point) { + rustsecp256k1zkp_v0_2_0_scalar x; + rustsecp256k1zkp_v0_2_0_gej pointj; + rand_scalar(&x); + + rustsecp256k1zkp_v0_2_0_ecmult_gen(&ctx->ecmult_gen_ctx, &pointj, &x); + rustsecp256k1zkp_v0_2_0_ge_set_gej(point, &pointj); +} + +void dleq_nonce_bitflip(unsigned char **args, size_t n_flip, size_t n_bytes) { + rustsecp256k1zkp_v0_2_0_scalar k1, k2; + + CHECK(rustsecp256k1zkp_v0_2_0_dleq_nonce(&k1, args[0], args[1], args[2], args[3], NULL, args[4]) == 1); + rustsecp256k1zkp_v0_2_0_testrand_flip(args[n_flip], n_bytes); + CHECK(rustsecp256k1zkp_v0_2_0_dleq_nonce(&k2, args[0], args[1], args[2], args[3], NULL, args[4]) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_scalar_eq(&k1, &k2) == 0); +} + +void dleq_tests(void) { + rustsecp256k1zkp_v0_2_0_scalar s, e, sk, k; + rustsecp256k1zkp_v0_2_0_ge gen2, p1, p2; + unsigned char *args[5]; + unsigned char sk32[32]; + unsigned char gen2_33[33]; + unsigned char p1_33[33]; + unsigned char p2_33[33]; + unsigned char aux_rand[32]; + int i; + size_t pubkey_size = 33; + + rand_point(&gen2); + rand_scalar(&sk); + rustsecp256k1zkp_v0_2_0_dleq_pair(&ctx->ecmult_gen_ctx, &p1, &p2, &sk, &gen2); + CHECK(rustsecp256k1zkp_v0_2_0_dleq_prove(ctx, &s, &e, &sk, &gen2, &p1, &p2, NULL, NULL) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_dleq_verify(&ctx->ecmult_ctx, &s, &e, &p1, &gen2, &p2) == 1); + + { + rustsecp256k1zkp_v0_2_0_scalar tmp; + rustsecp256k1zkp_v0_2_0_scalar_set_int(&tmp, 1); + CHECK(rustsecp256k1zkp_v0_2_0_dleq_verify(&ctx->ecmult_ctx, &tmp, &e, &p1, &gen2, &p2) == 0); + CHECK(rustsecp256k1zkp_v0_2_0_dleq_verify(&ctx->ecmult_ctx, &s, &tmp, &p1, &gen2, &p2) == 0); + } + { + rustsecp256k1zkp_v0_2_0_ge p_tmp; + rand_point(&p_tmp); + CHECK(rustsecp256k1zkp_v0_2_0_dleq_verify(&ctx->ecmult_ctx, &s, &e, &p_tmp, &gen2, &p2) == 0); + CHECK(rustsecp256k1zkp_v0_2_0_dleq_verify(&ctx->ecmult_ctx, &s, &e, &p1, &p_tmp, &p2) == 0); + CHECK(rustsecp256k1zkp_v0_2_0_dleq_verify(&ctx->ecmult_ctx, &s, &e, &p1, &gen2, &p_tmp) == 0); + } + { + rustsecp256k1zkp_v0_2_0_ge p_inf; + rustsecp256k1zkp_v0_2_0_ge_set_infinity(&p_inf); + CHECK(rustsecp256k1zkp_v0_2_0_dleq_prove(ctx, &s, &e, &sk, &p_inf, &p1, &p2, NULL, NULL) == 0); + CHECK(rustsecp256k1zkp_v0_2_0_dleq_prove(ctx, &s, &e, &sk, &gen2, &p_inf, &p2, NULL, NULL) == 0); + CHECK(rustsecp256k1zkp_v0_2_0_dleq_prove(ctx, &s, &e, &sk, &gen2, &p1, &p_inf, NULL, NULL) == 0); + } + + /* Nonce tests */ + rustsecp256k1zkp_v0_2_0_scalar_get_b32(sk32, &sk); + CHECK(rustsecp256k1zkp_v0_2_0_eckey_pubkey_serialize(&gen2, gen2_33, &pubkey_size, 1)); + CHECK(rustsecp256k1zkp_v0_2_0_eckey_pubkey_serialize(&p1, p1_33, &pubkey_size, 1)); + CHECK(rustsecp256k1zkp_v0_2_0_eckey_pubkey_serialize(&p2, p2_33, &pubkey_size, 1)); + CHECK(rustsecp256k1zkp_v0_2_0_dleq_nonce(&k, sk32, gen2_33, p1_33, p2_33, NULL, NULL) == 1); + + rustsecp256k1zkp_v0_2_0_rfc6979_hmac_sha256_generate(&rustsecp256k1zkp_v0_2_0_test_rng, sk32, sizeof(sk32)); + rustsecp256k1zkp_v0_2_0_rfc6979_hmac_sha256_generate(&rustsecp256k1zkp_v0_2_0_test_rng, gen2_33, sizeof(gen2_33)); + rustsecp256k1zkp_v0_2_0_rfc6979_hmac_sha256_generate(&rustsecp256k1zkp_v0_2_0_test_rng, p1_33, sizeof(p1_33)); + rustsecp256k1zkp_v0_2_0_rfc6979_hmac_sha256_generate(&rustsecp256k1zkp_v0_2_0_test_rng, p2_33, sizeof(p2_33)); + rustsecp256k1zkp_v0_2_0_rfc6979_hmac_sha256_generate(&rustsecp256k1zkp_v0_2_0_test_rng, aux_rand, sizeof(aux_rand)); + + /* Check that a bitflip in an argument results in different nonces. */ + args[0] = sk32; + args[1] = gen2_33; + args[2] = p1_33; + args[3] = p2_33; + args[4] = aux_rand; + for (i = 0; i < count; i++) { + dleq_nonce_bitflip(args, 0, sizeof(sk32)); + dleq_nonce_bitflip(args, 1, sizeof(gen2_33)); + dleq_nonce_bitflip(args, 2, sizeof(p1_33)); + /* Flip p2 */ + dleq_nonce_bitflip(args, 3, sizeof(p2_33)); + /* Flip p2 again */ + dleq_nonce_bitflip(args, 3, sizeof(p2_33)); + dleq_nonce_bitflip(args, 4, sizeof(aux_rand)); + } + + /* NULL aux_rand argument is allowed. */ + CHECK(rustsecp256k1zkp_v0_2_0_dleq_nonce(&k, sk32, gen2_33, p1_33, p2_33, NULL, NULL) == 1); +} + +void rand_flip_bit(unsigned char *array, size_t n) { + array[rustsecp256k1zkp_v0_2_0_testrand_int(n)] ^= 1 << rustsecp256k1zkp_v0_2_0_testrand_int(8); +} + +/* Helper function for test_ecdsa_adaptor_spec_vectors + * Checks that the adaptor signature is valid for the public and encryption keys. */ +void test_ecdsa_adaptor_spec_vectors_check_verify(const unsigned char *adaptor_sig162, const unsigned char *msg32, const unsigned char *pubkey33, const unsigned char *encryption_key33, int expected) { + rustsecp256k1zkp_v0_2_0_pubkey pubkey; + rustsecp256k1zkp_v0_2_0_ge pubkey_ge; + rustsecp256k1zkp_v0_2_0_pubkey encryption_key; + rustsecp256k1zkp_v0_2_0_ge encryption_key_ge; + + CHECK(rustsecp256k1zkp_v0_2_0_eckey_pubkey_parse(&encryption_key_ge, encryption_key33, 33) == 1); + rustsecp256k1zkp_v0_2_0_pubkey_save(&encryption_key, &encryption_key_ge); + CHECK(rustsecp256k1zkp_v0_2_0_eckey_pubkey_parse(&pubkey_ge, pubkey33, 33) == 1); + rustsecp256k1zkp_v0_2_0_pubkey_save(&pubkey, &pubkey_ge); + + CHECK(expected == rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_verify(ctx, adaptor_sig162, &pubkey, msg32, &encryption_key)); +} + +/* Helper function for test_ecdsa_adaptor_spec_vectors + * Checks that the signature can be decrypted from the adaptor signature and the decryption key. */ +void test_ecdsa_adaptor_spec_vectors_check_decrypt(const unsigned char *adaptor_sig162, const unsigned char *decryption_key32, const unsigned char *signature64, int expected) { + unsigned char signature[64]; + rustsecp256k1zkp_v0_2_0_ecdsa_signature s; + + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_decrypt(ctx, &s, decryption_key32, adaptor_sig162) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_signature_serialize_compact(ctx, signature, &s) == 1); + + CHECK(expected == !(rustsecp256k1zkp_v0_2_0_memcmp_var(signature, signature64, 64))); +} + +/* Helper function for test_ecdsa_adaptor_spec_vectors + * Checks that the decryption key can be recovered from the adaptor signature, encryption key, and the signature. */ +void test_ecdsa_adaptor_spec_vectors_check_recover(const unsigned char *adaptor_sig162, const unsigned char *encryption_key33, const unsigned char *decryption_key32, const unsigned char *signature64, int expected) { + unsigned char deckey32[32] = { 0 }; + rustsecp256k1zkp_v0_2_0_ecdsa_signature sig; + rustsecp256k1zkp_v0_2_0_pubkey encryption_key; + rustsecp256k1zkp_v0_2_0_ge encryption_key_ge; + + CHECK(rustsecp256k1zkp_v0_2_0_eckey_pubkey_parse(&encryption_key_ge, encryption_key33, 33) == 1); + rustsecp256k1zkp_v0_2_0_pubkey_save(&encryption_key, &encryption_key_ge); + + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_signature_parse_compact(ctx, &sig, signature64) == 1); + CHECK(expected == rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_recover(ctx, deckey32, &sig, adaptor_sig162, &encryption_key)); + if (decryption_key32 != NULL) { + CHECK(expected == !(rustsecp256k1zkp_v0_2_0_memcmp_var(deckey32, decryption_key32, 32))); + } +} + +/* Helper function for test_ecdsa_adaptor_spec_vectors + * Checks deserialization and serialization. */ +void test_ecdsa_adaptor_spec_vectors_check_serialization(const unsigned char *adaptor_sig162, int expected) { + unsigned char buf[162]; + rustsecp256k1zkp_v0_2_0_scalar dleq_proof_s, dleq_proof_e; + rustsecp256k1zkp_v0_2_0_ge r, rp; + rustsecp256k1zkp_v0_2_0_scalar sp; + rustsecp256k1zkp_v0_2_0_scalar sigr; + + CHECK(expected == rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_sig_deserialize(&r, &sigr, &rp, &sp, &dleq_proof_e, &dleq_proof_s, adaptor_sig162)); + if (expected == 1) { + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_sig_serialize(buf, &r, &rp, &sp, &dleq_proof_e, &dleq_proof_s) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_memcmp_var(buf, adaptor_sig162, 162) == 0); + } +} + +/* Test vectors according to ECDSA adaptor signature spec. See + * https://github.com/discreetlogcontracts/dlcspecs/blob/596a177375932a47306f07e7385f398f52519a83/test/ecdsa_adaptor.json. */ +void test_ecdsa_adaptor_spec_vectors(void) { + { + /* Test vector 0 */ + /* kind: verification test */ + /* plain valid adaptor signature */ + const unsigned char adaptor_sig[162] = { + 0x03, 0x42, 0x4d, 0x14, 0xa5, 0x47, 0x1c, 0x04, + 0x8a, 0xb8, 0x7b, 0x3b, 0x83, 0xf6, 0x08, 0x5d, + 0x12, 0x5d, 0x58, 0x64, 0x24, 0x9a, 0xe4, 0x29, + 0x7a, 0x57, 0xc8, 0x4e, 0x74, 0x71, 0x0b, 0xb6, + 0x73, 0x02, 0x23, 0xf3, 0x25, 0x04, 0x2f, 0xce, + 0x53, 0x5d, 0x04, 0x0f, 0xee, 0x52, 0xec, 0x13, + 0x23, 0x1b, 0xf7, 0x09, 0xcc, 0xd8, 0x42, 0x33, + 0xc6, 0x94, 0x4b, 0x90, 0x31, 0x7e, 0x62, 0x52, + 0x8b, 0x25, 0x27, 0xdf, 0xf9, 0xd6, 0x59, 0xa9, + 0x6d, 0xb4, 0xc9, 0x9f, 0x97, 0x50, 0x16, 0x83, + 0x08, 0x63, 0x3c, 0x18, 0x67, 0xb7, 0x0f, 0x3a, + 0x18, 0xfb, 0x0f, 0x45, 0x39, 0xa1, 0xae, 0xce, + 0xdc, 0xd1, 0xfc, 0x01, 0x48, 0xfc, 0x22, 0xf3, + 0x6b, 0x63, 0x03, 0x08, 0x3e, 0xce, 0x3f, 0x87, + 0x2b, 0x18, 0xe3, 0x5d, 0x36, 0x8b, 0x39, 0x58, + 0xef, 0xe5, 0xfb, 0x08, 0x1f, 0x77, 0x16, 0x73, + 0x6c, 0xcb, 0x59, 0x8d, 0x26, 0x9a, 0xa3, 0x08, + 0x4d, 0x57, 0xe1, 0x85, 0x5e, 0x1e, 0xa9, 0xa4, + 0x5e, 0xfc, 0x10, 0x46, 0x3b, 0xbf, 0x32, 0xae, + 0x37, 0x80, 0x29, 0xf5, 0x76, 0x3c, 0xeb, 0x40, + 0x17, 0x3f + }; + const unsigned char message_hash[32] = { + 0x81, 0x31, 0xe6, 0xf4, 0xb4, 0x57, 0x54, 0xf2, + 0xc9, 0x0b, 0xd0, 0x66, 0x88, 0xce, 0xea, 0xbc, + 0x0c, 0x45, 0x05, 0x54, 0x60, 0x72, 0x99, 0x28, + 0xb4, 0xee, 0xcf, 0x11, 0x02, 0x6a, 0x9e, 0x2d + }; + const unsigned char pubkey[33] = { + 0x03, 0x5b, 0xe5, 0xe9, 0x47, 0x82, 0x09, 0x67, + 0x4a, 0x96, 0xe6, 0x0f, 0x1f, 0x03, 0x7f, 0x61, + 0x76, 0x54, 0x0f, 0xd0, 0x01, 0xfa, 0x1d, 0x64, + 0x69, 0x47, 0x70, 0xc5, 0x6a, 0x77, 0x09, 0xc4, + 0x2c + }; + const unsigned char encryption_key[33] = { + 0x02, 0xc2, 0x66, 0x2c, 0x97, 0x48, 0x8b, 0x07, + 0xb6, 0xe8, 0x19, 0x12, 0x4b, 0x89, 0x89, 0x84, + 0x92, 0x06, 0x33, 0x4a, 0x4c, 0x2f, 0xbd, 0xf6, + 0x91, 0xf7, 0xb3, 0x4d, 0x2b, 0x16, 0xe9, 0xc2, + 0x93 + }; + const unsigned char decryption_key[32] = { + 0x0b, 0x2a, 0xba, 0x63, 0xb8, 0x85, 0xa0, 0xf0, + 0xe9, 0x6f, 0xa0, 0xf3, 0x03, 0x92, 0x0c, 0x7f, + 0xb7, 0x43, 0x1d, 0xdf, 0xa9, 0x43, 0x76, 0xad, + 0x94, 0xd9, 0x69, 0xfb, 0xf4, 0x10, 0x9d, 0xc8 + }; + const unsigned char signature[64] = { + 0x42, 0x4d, 0x14, 0xa5, 0x47, 0x1c, 0x04, 0x8a, + 0xb8, 0x7b, 0x3b, 0x83, 0xf6, 0x08, 0x5d, 0x12, + 0x5d, 0x58, 0x64, 0x24, 0x9a, 0xe4, 0x29, 0x7a, + 0x57, 0xc8, 0x4e, 0x74, 0x71, 0x0b, 0xb6, 0x73, + 0x29, 0xe8, 0x0e, 0x0e, 0xe6, 0x0e, 0x57, 0xaf, + 0x3e, 0x62, 0x5b, 0xba, 0xe1, 0x67, 0x2b, 0x1e, + 0xca, 0xa5, 0x8e, 0xff, 0xe6, 0x13, 0x42, 0x6b, + 0x02, 0x4f, 0xa1, 0x62, 0x1d, 0x90, 0x33, 0x94 + }; + test_ecdsa_adaptor_spec_vectors_check_verify(adaptor_sig, message_hash, pubkey, encryption_key, 1); + test_ecdsa_adaptor_spec_vectors_check_decrypt(adaptor_sig, decryption_key, signature, 1); + test_ecdsa_adaptor_spec_vectors_check_recover(adaptor_sig, encryption_key, decryption_key, signature, 1); + } + { + /* Test vector 1 */ + /* verification test */ + /* the decrypted signature is high so it must be negated first + * AND the extracted decryption key must be negated */ + const unsigned char adaptor_sig[162] = { + 0x03, 0x60, 0x35, 0xc8, 0x98, 0x60, 0xec, 0x62, + 0xad, 0x15, 0x3f, 0x69, 0xb5, 0xb3, 0x07, 0x7b, + 0xcd, 0x08, 0xfb, 0xb0, 0xd2, 0x8d, 0xc7, 0xf7, + 0xf6, 0xdf, 0x4a, 0x05, 0xcc, 0xa3, 0x54, 0x55, + 0xbe, 0x03, 0x70, 0x43, 0xb6, 0x3c, 0x56, 0xf6, + 0x31, 0x7d, 0x99, 0x28, 0xe8, 0xf9, 0x10, 0x07, + 0x33, 0x57, 0x48, 0xc4, 0x98, 0x24, 0x22, 0x0d, + 0xb1, 0x4a, 0xd1, 0x0d, 0x80, 0xa5, 0xd0, 0x0a, + 0x96, 0x54, 0xaf, 0x09, 0x96, 0xc1, 0x82, 0x4c, + 0x64, 0xc9, 0x0b, 0x95, 0x1b, 0xb2, 0x73, 0x4a, + 0xae, 0xcf, 0x78, 0xd4, 0xb3, 0x61, 0x31, 0xa4, + 0x72, 0x38, 0xc3, 0xfa, 0x2b, 0xa2, 0x5e, 0x2c, + 0xed, 0x54, 0x25, 0x5b, 0x06, 0xdf, 0x69, 0x6d, + 0xe1, 0x48, 0x3c, 0x37, 0x67, 0x24, 0x2a, 0x37, + 0x28, 0x82, 0x6e, 0x05, 0xf7, 0x9e, 0x39, 0x81, + 0xe1, 0x25, 0x53, 0x35, 0x5b, 0xba, 0x8a, 0x01, + 0x31, 0xcd, 0x37, 0x0e, 0x63, 0xe3, 0xda, 0x73, + 0x10, 0x6f, 0x63, 0x85, 0x76, 0xa5, 0xaa, 0xb0, + 0xea, 0x6d, 0x45, 0xc0, 0x42, 0x57, 0x4c, 0x0c, + 0x8d, 0x0b, 0x14, 0xb8, 0xc7, 0xc0, 0x1c, 0xfe, + 0x90, 0x72 + }; + const unsigned char message_hash[32] = { + 0x81, 0x31, 0xe6, 0xf4, 0xb4, 0x57, 0x54, 0xf2, + 0xc9, 0x0b, 0xd0, 0x66, 0x88, 0xce, 0xea, 0xbc, + 0x0c, 0x45, 0x05, 0x54, 0x60, 0x72, 0x99, 0x28, + 0xb4, 0xee, 0xcf, 0x11, 0x02, 0x6a, 0x9e, 0x2d + }; + const unsigned char pubkey[33] = { + 0x03, 0x5b, 0xe5, 0xe9, 0x47, 0x82, 0x09, 0x67, + 0x4a, 0x96, 0xe6, 0x0f, 0x1f, 0x03, 0x7f, 0x61, + 0x76, 0x54, 0x0f, 0xd0, 0x01, 0xfa, 0x1d, 0x64, + 0x69, 0x47, 0x70, 0xc5, 0x6a, 0x77, 0x09, 0xc4, + 0x2c + }; + const unsigned char encryption_key[33] = { + 0x02, 0x4e, 0xee, 0x18, 0xbe, 0x9a, 0x5a, 0x52, + 0x24, 0x00, 0x0f, 0x91, 0x6c, 0x80, 0xb3, 0x93, + 0x44, 0x79, 0x89, 0xe7, 0x19, 0x4b, 0xc0, 0xb0, + 0xf1, 0xad, 0x7a, 0x03, 0x36, 0x97, 0x02, 0xbb, + 0x51 + }; + const unsigned char decryption_key[32] = { + 0xdb, 0x2d, 0xeb, 0xdd, 0xb0, 0x02, 0x47, 0x3a, + 0x00, 0x1d, 0xd7, 0x0b, 0x06, 0xf6, 0xc9, 0x7b, + 0xdc, 0xd1, 0xc4, 0x6b, 0xa1, 0x00, 0x12, 0x37, + 0xfe, 0x0e, 0xe1, 0xae, 0xff, 0xb2, 0xb6, 0xc4 + }; + const unsigned char signature[64] = { + 0x60, 0x35, 0xc8, 0x98, 0x60, 0xec, 0x62, 0xad, + 0x15, 0x3f, 0x69, 0xb5, 0xb3, 0x07, 0x7b, 0xcd, + 0x08, 0xfb, 0xb0, 0xd2, 0x8d, 0xc7, 0xf7, 0xf6, + 0xdf, 0x4a, 0x05, 0xcc, 0xa3, 0x54, 0x55, 0xbe, + 0x4c, 0xea, 0xcf, 0x92, 0x15, 0x46, 0xc0, 0x3d, + 0xd1, 0xbe, 0x59, 0x67, 0x23, 0xad, 0x1e, 0x76, + 0x91, 0xbd, 0xac, 0x73, 0xd8, 0x8c, 0xc3, 0x6c, + 0x42, 0x1c, 0x5e, 0x7f, 0x08, 0x38, 0x43, 0x05 + }; + test_ecdsa_adaptor_spec_vectors_check_verify(adaptor_sig, message_hash, pubkey, encryption_key, 1); + test_ecdsa_adaptor_spec_vectors_check_decrypt(adaptor_sig, decryption_key, signature, 1); + test_ecdsa_adaptor_spec_vectors_check_recover(adaptor_sig, encryption_key, decryption_key, signature, 1); + } + { + /* Test vector 2 */ + /* verification test */ + /* proof is wrong */ + const unsigned char adaptor_sig[162] = { + 0x03, 0xf9, 0x4d, 0xca, 0x20, 0x6d, 0x75, 0x82, + 0xc0, 0x15, 0xfb, 0x9b, 0xff, 0xe4, 0xe4, 0x3b, + 0x14, 0x59, 0x1b, 0x30, 0xef, 0x7d, 0x2b, 0x46, + 0x4d, 0x10, 0x3e, 0xc5, 0xe1, 0x16, 0x59, 0x5d, + 0xba, 0x03, 0x12, 0x7f, 0x8a, 0xc3, 0x53, 0x3d, + 0x24, 0x92, 0x80, 0x33, 0x24, 0x74, 0x33, 0x90, + 0x00, 0x92, 0x2e, 0xb6, 0xa5, 0x8e, 0x3b, 0x9b, + 0xf4, 0xfc, 0x7e, 0x01, 0xe4, 0xb4, 0xdf, 0x2b, + 0x7a, 0x41, 0x00, 0xa1, 0xe0, 0x89, 0xf1, 0x6e, + 0x5d, 0x70, 0xbb, 0x89, 0xf9, 0x61, 0x51, 0x6f, + 0x1d, 0xe0, 0x68, 0x4c, 0xc7, 0x9d, 0xb9, 0x78, + 0x49, 0x5d, 0xf2, 0xf3, 0x99, 0xb0, 0xd0, 0x1e, + 0xd7, 0x24, 0x0f, 0xa6, 0xe3, 0x25, 0x2a, 0xed, + 0xb5, 0x8b, 0xdc, 0x6b, 0x58, 0x77, 0xb0, 0xc6, + 0x02, 0x62, 0x8a, 0x23, 0x5d, 0xd1, 0xcc, 0xae, + 0xbd, 0xdd, 0xcb, 0xe9, 0x61, 0x98, 0xc0, 0xc2, + 0x1b, 0xea, 0xd7, 0xb0, 0x5f, 0x42, 0x3b, 0x67, + 0x3d, 0x14, 0xd2, 0x06, 0xfa, 0x15, 0x07, 0xb2, + 0xdb, 0xe2, 0x72, 0x2a, 0xf7, 0x92, 0xb8, 0xc2, + 0x66, 0xfc, 0x25, 0xa2, 0xd9, 0x01, 0xd7, 0xe2, + 0xc3, 0x35 + }; + const unsigned char message_hash[32] = { + 0x81, 0x31, 0xe6, 0xf4, 0xb4, 0x57, 0x54, 0xf2, + 0xc9, 0x0b, 0xd0, 0x66, 0x88, 0xce, 0xea, 0xbc, + 0x0c, 0x45, 0x05, 0x54, 0x60, 0x72, 0x99, 0x28, + 0xb4, 0xee, 0xcf, 0x11, 0x02, 0x6a, 0x9e, 0x2d + }; + const unsigned char pubkey[33] = { + 0x03, 0x5b, 0xe5, 0xe9, 0x47, 0x82, 0x09, 0x67, + 0x4a, 0x96, 0xe6, 0x0f, 0x1f, 0x03, 0x7f, 0x61, + 0x76, 0x54, 0x0f, 0xd0, 0x01, 0xfa, 0x1d, 0x64, + 0x69, 0x47, 0x70, 0xc5, 0x6a, 0x77, 0x09, 0xc4, + 0x2c + }; + const unsigned char encryption_key[33] = { + 0x02, 0x14, 0xcc, 0xb7, 0x56, 0x24, 0x9a, 0xd6, + 0xe7, 0x33, 0xc8, 0x02, 0x85, 0xea, 0x7a, 0xc2, + 0xee, 0x12, 0xff, 0xeb, 0xbc, 0xee, 0x4e, 0x55, + 0x6e, 0x68, 0x10, 0x79, 0x3a, 0x60, 0xc4, 0x5a, + 0xd4 + }; + const unsigned char decryption_key[32] = { + 0x1d, 0xfc, 0xfc, 0x08, 0x80, 0xe7, 0x25, 0x09, + 0x76, 0x8a, 0xb4, 0x6f, 0x25, 0x45, 0xb3, 0x31, + 0x68, 0xb8, 0xb8, 0xdf, 0x8e, 0x4f, 0x5f, 0xeb, + 0x50, 0x59, 0xaa, 0x37, 0x50, 0xee, 0x59, 0xd0 + }; + const unsigned char signature[64] = { + 0x42, 0x4d, 0x14, 0xa5, 0x47, 0x1c, 0x04, 0x8a, + 0xb8, 0x7b, 0x3b, 0x83, 0xf6, 0x08, 0x5d, 0x12, + 0x5d, 0x58, 0x64, 0x24, 0x9a, 0xe4, 0x29, 0x7a, + 0x57, 0xc8, 0x4e, 0x74, 0x71, 0x0b, 0xb6, 0x73, + 0x29, 0xe8, 0x0e, 0x0e, 0xe6, 0x0e, 0x57, 0xaf, + 0x3e, 0x62, 0x5b, 0xba, 0xe1, 0x67, 0x2b, 0x1e, + 0xca, 0xa5, 0x8e, 0xff, 0xe6, 0x13, 0x42, 0x6b, + 0x02, 0x4f, 0xa1, 0x62, 0x1d, 0x90, 0x33, 0x94 + }; + test_ecdsa_adaptor_spec_vectors_check_verify(adaptor_sig, message_hash, pubkey, encryption_key, 0); + test_ecdsa_adaptor_spec_vectors_check_decrypt(adaptor_sig, decryption_key, signature, 0); + test_ecdsa_adaptor_spec_vectors_check_recover(adaptor_sig, encryption_key, decryption_key, signature, 0); + } + { + /* Test vector 3 */ + /* recovery test */ + /* plain recovery */ + const unsigned char adaptor_sig[162] = { + 0x03, 0xf2, 0xdb, 0x6e, 0x9e, 0xd3, 0x30, 0x92, + 0xcc, 0x0b, 0x89, 0x8f, 0xd6, 0xb2, 0x82, 0xe9, + 0x9b, 0xda, 0xec, 0xcb, 0x3d, 0xe8, 0x5c, 0x2d, + 0x25, 0x12, 0xd8, 0xd5, 0x07, 0xf9, 0xab, 0xab, + 0x29, 0x02, 0x10, 0xc0, 0x1b, 0x5b, 0xed, 0x70, + 0x94, 0xa1, 0x26, 0x64, 0xae, 0xaa, 0xb3, 0x40, + 0x2d, 0x87, 0x09, 0xa8, 0xf3, 0x62, 0xb1, 0x40, + 0x32, 0x8d, 0x1b, 0x36, 0xdd, 0x7c, 0xb4, 0x20, + 0xd0, 0x2f, 0xb6, 0x6b, 0x12, 0x30, 0xd6, 0x1c, + 0x16, 0xd0, 0xcd, 0x0a, 0x2a, 0x02, 0x24, 0x6d, + 0x5a, 0xc7, 0x84, 0x8d, 0xcd, 0x6f, 0x04, 0xfe, + 0x62, 0x70, 0x53, 0xcd, 0x3c, 0x70, 0x15, 0xa7, + 0xd4, 0xaa, 0x6a, 0xc2, 0xb0, 0x43, 0x47, 0x34, + 0x8b, 0xd6, 0x7d, 0xa4, 0x3b, 0xe8, 0x72, 0x25, + 0x15, 0xd9, 0x9a, 0x79, 0x85, 0xfb, 0xfa, 0x66, + 0xf0, 0x36, 0x5c, 0x70, 0x1d, 0xe7, 0x6f, 0xf0, + 0x40, 0x0d, 0xff, 0xdc, 0x9f, 0xa8, 0x4d, 0xdd, + 0xf4, 0x13, 0xa7, 0x29, 0x82, 0x3b, 0x16, 0xaf, + 0x60, 0xaa, 0x63, 0x61, 0xbc, 0x32, 0xe7, 0xcf, + 0xd6, 0x70, 0x1e, 0x32, 0x95, 0x7c, 0x72, 0xac, + 0xe6, 0x7b + }; + const unsigned char encryption_key[33] = { + 0x02, 0x7e, 0xe4, 0xf8, 0x99, 0xbc, 0x9c, 0x5f, + 0x2b, 0x62, 0x6f, 0xa1, 0xa9, 0xb3, 0x7c, 0xe2, + 0x91, 0xc0, 0x38, 0x8b, 0x52, 0x27, 0xe9, 0x0b, + 0x0f, 0xd8, 0xf4, 0xfa, 0x57, 0x61, 0x64, 0xed, + 0xe7 + }; + const unsigned char decryption_key[32] = { + 0x9c, 0xf3, 0xea, 0x9b, 0xe5, 0x94, 0x36, 0x6b, + 0x78, 0xc4, 0x57, 0x16, 0x29, 0x08, 0xaf, 0x3c, + 0x2e, 0xa1, 0x77, 0x05, 0x81, 0x77, 0xe9, 0xc6, + 0xbf, 0x99, 0x04, 0x79, 0x27, 0x77, 0x3a, 0x06 + }; + const unsigned char signature[64] = { + 0xf2, 0xdb, 0x6e, 0x9e, 0xd3, 0x30, 0x92, 0xcc, + 0x0b, 0x89, 0x8f, 0xd6, 0xb2, 0x82, 0xe9, 0x9b, + 0xda, 0xec, 0xcb, 0x3d, 0xe8, 0x5c, 0x2d, 0x25, + 0x12, 0xd8, 0xd5, 0x07, 0xf9, 0xab, 0xab, 0x29, + 0x21, 0x81, 0x1f, 0xe7, 0xb5, 0x3b, 0xec, 0xf3, + 0xb7, 0xaf, 0xfa, 0x94, 0x42, 0xab, 0xaa, 0x93, + 0xc0, 0xab, 0x8a, 0x8e, 0x45, 0xcd, 0x7e, 0xe2, + 0xea, 0x8d, 0x25, 0x8b, 0xfc, 0x25, 0xd4, 0x64 + }; + test_ecdsa_adaptor_spec_vectors_check_decrypt(adaptor_sig, decryption_key, signature, 1); + test_ecdsa_adaptor_spec_vectors_check_recover(adaptor_sig, encryption_key, decryption_key, signature, 1); + } + { + /* Test vector 4 */ + /* recovery test */ + /* the R value of the signature does not match */ + const unsigned char adaptor_sig[162] = { + 0x03, 0xaa, 0x86, 0xd7, 0x80, 0x59, 0xa9, 0x10, + 0x59, 0xc2, 0x9e, 0xc1, 0xa7, 0x57, 0xc4, 0xdc, + 0x02, 0x9f, 0xf6, 0x36, 0xa1, 0xe6, 0xc1, 0x14, + 0x2f, 0xef, 0xe1, 0xe9, 0xd7, 0x33, 0x96, 0x17, + 0xc0, 0x03, 0xa8, 0x15, 0x3e, 0x50, 0xc0, 0xc8, + 0x57, 0x4a, 0x38, 0xd3, 0x89, 0xe6, 0x1b, 0xbb, + 0x0b, 0x58, 0x15, 0x16, 0x9e, 0x06, 0x09, 0x24, + 0xe4, 0xb5, 0xf2, 0xe7, 0x8f, 0xf1, 0x3a, 0xa7, + 0xad, 0x85, 0x8e, 0x0c, 0x27, 0xc4, 0xb9, 0xee, + 0xd9, 0xd6, 0x05, 0x21, 0xb3, 0xf5, 0x4f, 0xf8, + 0x3c, 0xa4, 0x77, 0x4b, 0xe5, 0xfb, 0x3a, 0x68, + 0x0f, 0x82, 0x0a, 0x35, 0xe8, 0x84, 0x0f, 0x4a, + 0xaf, 0x2d, 0xe8, 0x8e, 0x7c, 0x5c, 0xff, 0x38, + 0xa3, 0x7b, 0x78, 0x72, 0x59, 0x04, 0xef, 0x97, + 0xbb, 0x82, 0x34, 0x13, 0x28, 0xd5, 0x59, 0x87, + 0x01, 0x9b, 0xd3, 0x8a, 0xe1, 0x74, 0x5e, 0x3e, + 0xfe, 0x0f, 0x8e, 0xa8, 0xbd, 0xfe, 0xde, 0x0d, + 0x37, 0x8f, 0xc1, 0xf9, 0x6e, 0x94, 0x4a, 0x75, + 0x05, 0x24, 0x9f, 0x41, 0xe9, 0x37, 0x81, 0x50, + 0x9e, 0xe0, 0xba, 0xde, 0x77, 0x29, 0x0d, 0x39, + 0xcd, 0x12 + }; + const unsigned char encryption_key[33] = { + 0x03, 0x51, 0x76, 0xd2, 0x41, 0x29, 0x74, 0x1b, + 0x0f, 0xca, 0xa5, 0xfd, 0x67, 0x50, 0x72, 0x7c, + 0xe3, 0x08, 0x60, 0x44, 0x7e, 0x0a, 0x92, 0xc9, + 0xeb, 0xeb, 0xde, 0xb7, 0xc3, 0xf9, 0x39, 0x95, + 0xed + }; + const unsigned char signature[64] = { + 0xf7, 0xf7, 0xfe, 0x6b, 0xd0, 0x56, 0xfc, 0x4a, + 0xbd, 0x70, 0xd3, 0x35, 0xf7, 0x2d, 0x0a, 0xa1, + 0xe8, 0x40, 0x6b, 0xba, 0x68, 0xf3, 0xe5, 0x79, + 0xe4, 0x78, 0x94, 0x75, 0x32, 0x35, 0x64, 0xa4, + 0x52, 0xc4, 0x61, 0x76, 0xc7, 0xfb, 0x40, 0xaa, + 0x37, 0xd5, 0x65, 0x13, 0x41, 0xf5, 0x56, 0x97, + 0xda, 0xb2, 0x7d, 0x84, 0xa2, 0x13, 0xb3, 0x0c, + 0x93, 0x01, 0x1a, 0x77, 0x90, 0xba, 0xce, 0x8c + }; + test_ecdsa_adaptor_spec_vectors_check_recover(adaptor_sig, encryption_key, NULL, signature, 0); + } + { + /* Test vector 5 */ + /* recovery test */ + /* recovery from high s signature */ + const unsigned char adaptor_sig[162] = { + 0x03, 0x2c, 0x63, 0x7c, 0xd7, 0x97, 0xdd, 0x8c, + 0x2c, 0xe2, 0x61, 0x90, 0x7e, 0xd4, 0x3e, 0x82, + 0xd6, 0xd1, 0xa4, 0x8c, 0xba, 0xbb, 0xbe, 0xce, + 0x80, 0x11, 0x33, 0xdd, 0x8d, 0x70, 0xa0, 0x1b, + 0x14, 0x03, 0xeb, 0x61, 0x5a, 0x3e, 0x59, 0xb1, + 0xcb, 0xbf, 0x4f, 0x87, 0xac, 0xaf, 0x64, 0x5b, + 0xe1, 0xed, 0xa3, 0x2a, 0x06, 0x66, 0x11, 0xf3, + 0x5d, 0xd5, 0x55, 0x78, 0x02, 0x80, 0x2b, 0x14, + 0xb1, 0x9c, 0x81, 0xc0, 0x4c, 0x3f, 0xef, 0xac, + 0x57, 0x83, 0xb2, 0x07, 0x7b, 0xd4, 0x3f, 0xa0, + 0xa3, 0x9a, 0xb8, 0xa6, 0x4d, 0x4d, 0x78, 0x33, + 0x2a, 0x5d, 0x62, 0x1e, 0xa2, 0x3e, 0xca, 0x46, + 0xbc, 0x01, 0x10, 0x11, 0xab, 0x82, 0xdd, 0xa6, + 0xde, 0xb8, 0x56, 0x99, 0xf5, 0x08, 0x74, 0x4d, + 0x70, 0xd4, 0x13, 0x4b, 0xea, 0x03, 0xf7, 0x84, + 0xd2, 0x85, 0xb5, 0xc6, 0xc1, 0x5a, 0x56, 0xe4, + 0xe1, 0xfa, 0xb4, 0xbc, 0x35, 0x6a, 0xbb, 0xde, + 0xbb, 0x3b, 0x8f, 0xe1, 0xe5, 0x5e, 0x6d, 0xd6, + 0xd2, 0xa9, 0xea, 0x45, 0x7e, 0x91, 0xb2, 0xe6, + 0x64, 0x2f, 0xae, 0x69, 0xf9, 0xdb, 0xb5, 0x25, + 0x88, 0x54 + }; + const unsigned char encryption_key[33] = { + 0x02, 0x04, 0x25, 0x37, 0xe9, 0x13, 0xad, 0x74, + 0xc4, 0xbb, 0xd8, 0xda, 0x96, 0x07, 0xad, 0x3b, + 0x9c, 0xb2, 0x97, 0xd0, 0x8e, 0x01, 0x4a, 0xfc, + 0x51, 0x13, 0x30, 0x83, 0xf1, 0xbd, 0x68, 0x7a, + 0x62 + }; + const unsigned char decryption_key[32] = { + 0x32, 0x47, 0x19, 0xb5, 0x1f, 0xf2, 0x47, 0x4c, + 0x94, 0x38, 0xeb, 0x76, 0x49, 0x4b, 0x0d, 0xc0, + 0xbc, 0xce, 0xeb, 0x52, 0x9f, 0x0a, 0x54, 0x28, + 0xfd, 0x19, 0x8a, 0xd8, 0xf8, 0x86, 0xe9, 0x9c + }; + const unsigned char signature[64] = { + 0x2c, 0x63, 0x7c, 0xd7, 0x97, 0xdd, 0x8c, 0x2c, + 0xe2, 0x61, 0x90, 0x7e, 0xd4, 0x3e, 0x82, 0xd6, + 0xd1, 0xa4, 0x8c, 0xba, 0xbb, 0xbe, 0xce, 0x80, + 0x11, 0x33, 0xdd, 0x8d, 0x70, 0xa0, 0x1b, 0x14, + 0xb5, 0xf2, 0x43, 0x21, 0xf5, 0x50, 0xb7, 0xb9, + 0xdd, 0x06, 0xee, 0x4f, 0xcf, 0xd8, 0x2b, 0xda, + 0xd8, 0xb1, 0x42, 0xff, 0x93, 0xa7, 0x90, 0xcc, + 0x4d, 0x9f, 0x79, 0x62, 0xb3, 0x8c, 0x6a, 0x3b + }; + test_ecdsa_adaptor_spec_vectors_check_decrypt(adaptor_sig, decryption_key, signature, 0); + test_ecdsa_adaptor_spec_vectors_check_recover(adaptor_sig, encryption_key, decryption_key, signature, 1); + } + { + /* Test vector 6 */ + /* serialization test */ + const unsigned char adaptor_sig[162] = { + 0x03, 0xe6, 0xd5, 0x1d, 0xa7, 0xbc, 0x2b, 0xf2, + 0x4c, 0xf9, 0xdf, 0xd9, 0xac, 0xc6, 0xc4, 0xf0, + 0xa3, 0xe7, 0x4d, 0x8a, 0x62, 0x73, 0xee, 0x5a, + 0x57, 0x3e, 0xd6, 0x81, 0x8e, 0x30, 0x95, 0xb6, + 0x09, 0x03, 0xf3, 0x3b, 0xc9, 0x8f, 0x9d, 0x2e, + 0xa3, 0x51, 0x1f, 0x2e, 0x24, 0xf3, 0x35, 0x85, + 0x57, 0xc8, 0x15, 0xab, 0xd7, 0x71, 0x3c, 0x93, + 0x18, 0xaf, 0x9f, 0x4d, 0xfa, 0xb4, 0x44, 0x18, + 0x98, 0xec, 0xd6, 0x19, 0xac, 0xb1, 0xcb, 0x75, + 0xc1, 0xa5, 0x94, 0x6f, 0xba, 0xf7, 0x16, 0xd2, + 0x27, 0x19, 0x9a, 0x64, 0x79, 0xa6, 0x78, 0xd1, + 0x0a, 0x6d, 0x95, 0x51, 0x2d, 0x67, 0x4f, 0xb7, + 0x70, 0x3d, 0x85, 0xb5, 0x89, 0x80, 0xb8, 0xe6, + 0xc5, 0x4b, 0xd2, 0x06, 0x16, 0xbd, 0xb9, 0x46, + 0x1d, 0xcc, 0xd8, 0xee, 0xbb, 0x7d, 0x7e, 0x7c, + 0x83, 0xa9, 0x14, 0x52, 0xcc, 0x20, 0xed, 0xf5, + 0x3b, 0xe5, 0xb0, 0xfe, 0x0d, 0xb4, 0x4d, 0xdd, + 0xaa, 0xaf, 0xbe, 0x73, 0x76, 0x78, 0xc6, 0x84, + 0xb6, 0xe8, 0x9b, 0x9b, 0x4b, 0x67, 0x9b, 0x18, + 0x55, 0xaa, 0x6e, 0xd6, 0x44, 0x49, 0x8b, 0x89, + 0xc9, 0x18 + }; + test_ecdsa_adaptor_spec_vectors_check_serialization(adaptor_sig, 1); + } + { + /* Test vector 7 */ + /* serialization test */ + /* R can be above curve order */ + const unsigned char adaptor_sig[162] = { + 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, + 0x2c, 0x03, 0xf3, 0x3b, 0xc9, 0x8f, 0x9d, 0x2e, + 0xa3, 0x51, 0x1f, 0x2e, 0x24, 0xf3, 0x35, 0x85, + 0x57, 0xc8, 0x15, 0xab, 0xd7, 0x71, 0x3c, 0x93, + 0x18, 0xaf, 0x9f, 0x4d, 0xfa, 0xb4, 0x44, 0x18, + 0x98, 0xec, 0xd6, 0x19, 0xac, 0xb1, 0xcb, 0x75, + 0xc1, 0xa5, 0x94, 0x6f, 0xba, 0xf7, 0x16, 0xd2, + 0x27, 0x19, 0x9a, 0x64, 0x79, 0xa6, 0x78, 0xd1, + 0x0a, 0x6d, 0x95, 0x51, 0x2d, 0x67, 0x4f, 0xb7, + 0x70, 0x3d, 0x85, 0xb5, 0x89, 0x80, 0xb8, 0xe6, + 0xc5, 0x4b, 0xd2, 0x06, 0x16, 0xbd, 0xb9, 0x46, + 0x1d, 0xcc, 0xd8, 0xee, 0xbb, 0x7d, 0x7e, 0x7c, + 0x83, 0xa9, 0x14, 0x52, 0xcc, 0x20, 0xed, 0xf5, + 0x3b, 0xe5, 0xb0, 0xfe, 0x0d, 0xb4, 0x4d, 0xdd, + 0xaa, 0xaf, 0xbe, 0x73, 0x76, 0x78, 0xc6, 0x84, + 0xb6, 0xe8, 0x9b, 0x9b, 0x4b, 0x67, 0x9b, 0x18, + 0x55, 0xaa, 0x6e, 0xd6, 0x44, 0x49, 0x8b, 0x89, + 0xc9, 0x18 + }; + test_ecdsa_adaptor_spec_vectors_check_serialization(adaptor_sig, 1); + } + { + /* Test vector 8 */ + /* serialization test */ + /* R_a can be above curve order */ + const unsigned char adaptor_sig[162] = { + 0x03, 0xe6, 0xd5, 0x1d, 0xa7, 0xbc, 0x2b, 0xf2, + 0x4c, 0xf9, 0xdf, 0xd9, 0xac, 0xc6, 0xc4, 0xf0, + 0xa3, 0xe7, 0x4d, 0x8a, 0x62, 0x73, 0xee, 0x5a, + 0x57, 0x3e, 0xd6, 0x81, 0x8e, 0x30, 0x95, 0xb6, + 0x09, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, + 0xfc, 0x2c, 0xd6, 0x19, 0xac, 0xb1, 0xcb, 0x75, + 0xc1, 0xa5, 0x94, 0x6f, 0xba, 0xf7, 0x16, 0xd2, + 0x27, 0x19, 0x9a, 0x64, 0x79, 0xa6, 0x78, 0xd1, + 0x0a, 0x6d, 0x95, 0x51, 0x2d, 0x67, 0x4f, 0xb7, + 0x70, 0x3d, 0x85, 0xb5, 0x89, 0x80, 0xb8, 0xe6, + 0xc5, 0x4b, 0xd2, 0x06, 0x16, 0xbd, 0xb9, 0x46, + 0x1d, 0xcc, 0xd8, 0xee, 0xbb, 0x7d, 0x7e, 0x7c, + 0x83, 0xa9, 0x14, 0x52, 0xcc, 0x20, 0xed, 0xf5, + 0x3b, 0xe5, 0xb0, 0xfe, 0x0d, 0xb4, 0x4d, 0xdd, + 0xaa, 0xaf, 0xbe, 0x73, 0x76, 0x78, 0xc6, 0x84, + 0xb6, 0xe8, 0x9b, 0x9b, 0x4b, 0x67, 0x9b, 0x18, + 0x55, 0xaa, 0x6e, 0xd6, 0x44, 0x49, 0x8b, 0x89, + 0xc9, 0x18 + }; + test_ecdsa_adaptor_spec_vectors_check_serialization(adaptor_sig, 1); + } + { + /* Test vector 9 */ + /* serialization test */ + /* s_a cannot be zero */ + const unsigned char adaptor_sig[162] = { + 0x03, 0xe6, 0xd5, 0x1d, 0xa7, 0xbc, 0x2b, 0xf2, + 0x4c, 0xf9, 0xdf, 0xd9, 0xac, 0xc6, 0xc4, 0xf0, + 0xa3, 0xe7, 0x4d, 0x8a, 0x62, 0x73, 0xee, 0x5a, + 0x57, 0x3e, 0xd6, 0x81, 0x8e, 0x30, 0x95, 0xb6, + 0x09, 0x03, 0xf3, 0x3b, 0xc9, 0x8f, 0x9d, 0x2e, + 0xa3, 0x51, 0x1f, 0x2e, 0x24, 0xf3, 0x35, 0x85, + 0x57, 0xc8, 0x15, 0xab, 0xd7, 0x71, 0x3c, 0x93, + 0x18, 0xaf, 0x9f, 0x4d, 0xfa, 0xb4, 0x44, 0x18, + 0x98, 0xec, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x85, 0xb5, 0x89, 0x80, 0xb8, 0xe6, + 0xc5, 0x4b, 0xd2, 0x06, 0x16, 0xbd, 0xb9, 0x46, + 0x1d, 0xcc, 0xd8, 0xee, 0xbb, 0x7d, 0x7e, 0x7c, + 0x83, 0xa9, 0x14, 0x52, 0xcc, 0x20, 0xed, 0xf5, + 0x3b, 0xe5, 0xb0, 0xfe, 0x0d, 0xb4, 0x4d, 0xdd, + 0xaa, 0xaf, 0xbe, 0x73, 0x76, 0x78, 0xc6, 0x84, + 0xb6, 0xe8, 0x9b, 0x9b, 0x4b, 0x67, 0x9b, 0x18, + 0x55, 0xaa, 0x6e, 0xd6, 0x44, 0x49, 0x8b, 0x89, + 0xc9, 0x18 + }; + test_ecdsa_adaptor_spec_vectors_check_serialization(adaptor_sig, 0); + } + { + /* Test vector 10 */ + /* serialization test */ + /* s_a too high */ + const unsigned char adaptor_sig[162] = { + 0x03, 0xe6, 0xd5, 0x1d, 0xa7, 0xbc, 0x2b, 0xf2, + 0x4c, 0xf9, 0xdf, 0xd9, 0xac, 0xc6, 0xc4, 0xf0, + 0xa3, 0xe7, 0x4d, 0x8a, 0x62, 0x73, 0xee, 0x5a, + 0x57, 0x3e, 0xd6, 0x81, 0x8e, 0x30, 0x95, 0xb6, + 0x09, 0x03, 0xf3, 0x3b, 0xc9, 0x8f, 0x9d, 0x2e, + 0xa3, 0x51, 0x1f, 0x2e, 0x24, 0xf3, 0x35, 0x85, + 0x57, 0xc8, 0x15, 0xab, 0xd7, 0x71, 0x3c, 0x93, + 0x18, 0xaf, 0x9f, 0x4d, 0xfa, 0xb4, 0x44, 0x18, + 0x98, 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfe, 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, + 0xa0, 0x3b, 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, + 0x41, 0x41, 0x85, 0xb5, 0x89, 0x80, 0xb8, 0xe6, + 0xc5, 0x4b, 0xd2, 0x06, 0x16, 0xbd, 0xb9, 0x46, + 0x1d, 0xcc, 0xd8, 0xee, 0xbb, 0x7d, 0x7e, 0x7c, + 0x83, 0xa9, 0x14, 0x52, 0xcc, 0x20, 0xed, 0xf5, + 0x3b, 0xe5, 0xb0, 0xfe, 0x0d, 0xb4, 0x4d, 0xdd, + 0xaa, 0xaf, 0xbe, 0x73, 0x76, 0x78, 0xc6, 0x84, + 0xb6, 0xe8, 0x9b, 0x9b, 0x4b, 0x67, 0x9b, 0x18, + 0x55, 0xaa, 0x6e, 0xd6, 0x44, 0x49, 0x8b, 0x89, + 0xc9, 0x18 + }; + test_ecdsa_adaptor_spec_vectors_check_serialization(adaptor_sig, 0); + } +} + +/* Nonce function that returns constant 0 */ +static int ecdsa_adaptor_nonce_function_failing(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *encryption_key33, const unsigned char *algo, size_t algolen, void *data) { + (void) msg32; + (void) key32; + (void) encryption_key33; + (void) algo; + (void) algolen; + (void) data; + (void) nonce32; + return 0; +} + +/* Nonce function that sets nonce to 0 */ +static int ecdsa_adaptor_nonce_function_0(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *encryption_key33, const unsigned char *algo, size_t algolen, void *data) { + (void) msg32; + (void) key32; + (void) encryption_key33; + (void) algo; + (void) algolen; + (void) data; + + memset(nonce32, 0, 32); + return 1; +} + +/* Nonce function that sets nonce to 0xFF...0xFF */ +static int ecdsa_adaptor_nonce_function_overflowing(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *encryption_key33, const unsigned char *algo, size_t algolen, void *data) { + (void) msg32; + (void) key32; + (void) encryption_key33; + (void) algo; + (void) algolen; + (void) data; + + memset(nonce32, 0xFF, 32); + return 1; +} + +/* Checks that a bit flip in the n_flip-th argument (that has n_bytes many + * bytes) changes the hash function + */ +void nonce_function_ecdsa_adaptor_bitflip(unsigned char **args, size_t n_flip, size_t n_bytes, size_t algolen) { + unsigned char nonces[2][32]; + CHECK(nonce_function_ecdsa_adaptor(nonces[0], args[0], args[1], args[2], args[3], algolen, args[4]) == 1); + rustsecp256k1zkp_v0_2_0_testrand_flip(args[n_flip], n_bytes); + CHECK(nonce_function_ecdsa_adaptor(nonces[1], args[0], args[1], args[2], args[3], algolen, args[4]) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_memcmp_var(nonces[0], nonces[1], 32) != 0); +} + +/* Tests for the equality of two sha256 structs. This function only produces a + * correct result if an integer multiple of 64 many bytes have been written + * into the hash functions. */ +void ecdsa_adaptor_test_sha256_eq(const rustsecp256k1zkp_v0_2_0_sha256 *sha1, const rustsecp256k1zkp_v0_2_0_sha256 *sha2) { + /* Is buffer fully consumed? */ + CHECK((sha1->bytes & 0x3F) == 0); + + CHECK(sha1->bytes == sha2->bytes); + CHECK(rustsecp256k1zkp_v0_2_0_memcmp_var(sha1->s, sha2->s, sizeof(sha1->s)) == 0); +} + +void run_nonce_function_ecdsa_adaptor_tests(void) { + unsigned char tag[16] = "ECDSAadaptor/non"; + unsigned char aux_tag[16] = "ECDSAadaptor/aux"; + unsigned char algo[16] = "ECDSAadaptor/non"; + size_t algolen = sizeof(algo); + unsigned char dleq_tag[4] = "DLEQ"; + rustsecp256k1zkp_v0_2_0_sha256 sha; + rustsecp256k1zkp_v0_2_0_sha256 sha_optimized; + unsigned char nonce[32]; + unsigned char msg[32]; + unsigned char key[32]; + unsigned char pk[33]; + unsigned char aux_rand[32]; + unsigned char *args[5]; + int i; + + /* Check that hash initialized by + * rustsecp256k1zkp_v0_2_0_nonce_function_ecdsa_adaptor_sha256_tagged has the expected + * state. */ + rustsecp256k1zkp_v0_2_0_sha256_initialize_tagged(&sha, tag, sizeof(tag)); + rustsecp256k1zkp_v0_2_0_nonce_function_ecdsa_adaptor_sha256_tagged(&sha_optimized); + ecdsa_adaptor_test_sha256_eq(&sha, &sha_optimized); + + /* Check that hash initialized by + * rustsecp256k1zkp_v0_2_0_nonce_function_ecdsa_adaptor_sha256_tagged_aux has the expected + * state. */ + rustsecp256k1zkp_v0_2_0_sha256_initialize_tagged(&sha, aux_tag, sizeof(aux_tag)); + rustsecp256k1zkp_v0_2_0_nonce_function_ecdsa_adaptor_sha256_tagged_aux(&sha_optimized); + ecdsa_adaptor_test_sha256_eq(&sha, &sha_optimized); + + /* Check that hash initialized by + * rustsecp256k1zkp_v0_2_0_nonce_function_dleq_sha256_tagged_aux has the expected + * state. */ + rustsecp256k1zkp_v0_2_0_sha256_initialize_tagged(&sha, dleq_tag, sizeof(dleq_tag)); + rustsecp256k1zkp_v0_2_0_nonce_function_dleq_sha256_tagged(&sha_optimized); + ecdsa_adaptor_test_sha256_eq(&sha, &sha_optimized); + + rustsecp256k1zkp_v0_2_0_rfc6979_hmac_sha256_generate(&rustsecp256k1zkp_v0_2_0_test_rng, msg, sizeof(msg)); + rustsecp256k1zkp_v0_2_0_rfc6979_hmac_sha256_generate(&rustsecp256k1zkp_v0_2_0_test_rng, key, sizeof(key)); + rustsecp256k1zkp_v0_2_0_rfc6979_hmac_sha256_generate(&rustsecp256k1zkp_v0_2_0_test_rng, pk, sizeof(pk)); + rustsecp256k1zkp_v0_2_0_rfc6979_hmac_sha256_generate(&rustsecp256k1zkp_v0_2_0_test_rng, aux_rand, sizeof(aux_rand)); + + /* Check that a bitflip in an argument results in different nonces. */ + args[0] = msg; + args[1] = key; + args[2] = pk; + args[3] = algo; + args[4] = aux_rand; + for (i = 0; i < count; i++) { + nonce_function_ecdsa_adaptor_bitflip(args, 0, sizeof(msg), algolen); + nonce_function_ecdsa_adaptor_bitflip(args, 1, sizeof(key), algolen); + nonce_function_ecdsa_adaptor_bitflip(args, 2, sizeof(pk), algolen); + /* Flip algo special case "ECDSAadaptor/non" */ + nonce_function_ecdsa_adaptor_bitflip(args, 3, sizeof(algo), algolen); + /* Flip algo again */ + nonce_function_ecdsa_adaptor_bitflip(args, 3, sizeof(algo), algolen); + nonce_function_ecdsa_adaptor_bitflip(args, 4, sizeof(aux_rand), algolen); + } + + /* NULL algo is disallowed */ + CHECK(nonce_function_ecdsa_adaptor(nonce, msg, key, pk, NULL, 0, NULL) == 0); + /* Empty algo is fine */ + memset(algo, 0x00, algolen); + CHECK(nonce_function_ecdsa_adaptor(nonce, msg, key, pk, algo, algolen, NULL) == 1); + /* Other algo is fine */ + memset(algo, 0xFF, algolen); + CHECK(nonce_function_ecdsa_adaptor(nonce, msg, key, pk, algo, algolen, NULL) == 1); + /* dleq algo is fine */ + CHECK(nonce_function_ecdsa_adaptor(nonce, msg, key, pk, dleq_algo, sizeof(dleq_algo), NULL) == 1); + + /* Different algolen gives different nonce */ + for (i = 0; i < count; i++) { + unsigned char nonce2[32]; + uint32_t offset = rustsecp256k1zkp_v0_2_0_testrand_int(algolen - 1); + size_t algolen_tmp = (algolen + offset) % algolen; + + CHECK(nonce_function_ecdsa_adaptor(nonce2, msg, key, pk, algo, algolen_tmp, NULL) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_memcmp_var(nonce, nonce2, 32) != 0); + } + + /* NULL aux_rand argument is allowed. */ + CHECK(nonce_function_ecdsa_adaptor(nonce, msg, key, pk, algo, algolen, NULL) == 1); +} + +void test_ecdsa_adaptor_api(void) { + rustsecp256k1zkp_v0_2_0_pubkey pubkey; + rustsecp256k1zkp_v0_2_0_pubkey enckey; + rustsecp256k1zkp_v0_2_0_pubkey zero_pk; + rustsecp256k1zkp_v0_2_0_ecdsa_signature sig; + unsigned char sk[32]; + unsigned char msg[32]; + unsigned char asig[162]; + unsigned char deckey[32]; + + /** setup **/ + rustsecp256k1zkp_v0_2_0_context *none = rustsecp256k1zkp_v0_2_0_context_create(SECP256K1_CONTEXT_NONE); + rustsecp256k1zkp_v0_2_0_context *sign = rustsecp256k1zkp_v0_2_0_context_create(SECP256K1_CONTEXT_SIGN); + rustsecp256k1zkp_v0_2_0_context *vrfy = rustsecp256k1zkp_v0_2_0_context_create(SECP256K1_CONTEXT_VERIFY); + rustsecp256k1zkp_v0_2_0_context *both = rustsecp256k1zkp_v0_2_0_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + int ecount; + + rustsecp256k1zkp_v0_2_0_context_set_error_callback(none, counting_illegal_callback_fn, &ecount); + rustsecp256k1zkp_v0_2_0_context_set_error_callback(sign, counting_illegal_callback_fn, &ecount); + rustsecp256k1zkp_v0_2_0_context_set_error_callback(vrfy, counting_illegal_callback_fn, &ecount); + rustsecp256k1zkp_v0_2_0_context_set_error_callback(both, counting_illegal_callback_fn, &ecount); + rustsecp256k1zkp_v0_2_0_context_set_illegal_callback(none, counting_illegal_callback_fn, &ecount); + rustsecp256k1zkp_v0_2_0_context_set_illegal_callback(sign, counting_illegal_callback_fn, &ecount); + rustsecp256k1zkp_v0_2_0_context_set_illegal_callback(vrfy, counting_illegal_callback_fn, &ecount); + rustsecp256k1zkp_v0_2_0_context_set_illegal_callback(both, counting_illegal_callback_fn, &ecount); + + rustsecp256k1zkp_v0_2_0_testrand256(sk); + rustsecp256k1zkp_v0_2_0_testrand256(msg); + rustsecp256k1zkp_v0_2_0_testrand256(deckey); + CHECK(rustsecp256k1zkp_v0_2_0_ec_pubkey_create(ctx, &pubkey, sk) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ec_pubkey_create(ctx, &enckey, deckey) == 1); + memset(&zero_pk, 0, sizeof(zero_pk)); + + /** main test body **/ + ecount = 0; + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_encrypt(none, asig, sk, &enckey, msg, NULL, NULL) == 0); + CHECK(ecount == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_encrypt(vrfy, asig, sk, &enckey, msg, NULL, NULL) == 0); + CHECK(ecount == 2); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_encrypt(sign, asig, sk, &enckey, msg, NULL, NULL) == 1); + CHECK(ecount == 2); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_encrypt(sign, NULL, sk, &enckey, msg, NULL, NULL) == 0); + CHECK(ecount == 3); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_encrypt(sign, asig, sk, &enckey, NULL, NULL, NULL) == 0); + CHECK(ecount == 4); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_encrypt(sign, asig, NULL, &enckey, msg, NULL, NULL) == 0); + CHECK(ecount == 5); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_encrypt(sign, asig, sk, NULL, msg, NULL, NULL) == 0); + CHECK(ecount == 6); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_encrypt(sign, asig, sk, &zero_pk, msg, NULL, NULL) == 0); + CHECK(ecount == 7); + + ecount = 0; + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_encrypt(sign, asig, sk, &enckey, msg, NULL, NULL) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_verify(none, asig, &pubkey, msg, &enckey) == 0); + CHECK(ecount == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_verify(sign, asig, &pubkey, msg, &enckey) == 0); + CHECK(ecount == 2); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_verify(vrfy, asig, &pubkey, msg, &enckey) == 1); + CHECK(ecount == 2); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_verify(vrfy, NULL, &pubkey, msg, &enckey) == 0); + CHECK(ecount == 3); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_verify(vrfy, asig, &pubkey, NULL, &enckey) == 0); + CHECK(ecount == 4); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_verify(vrfy, asig, &pubkey, msg, NULL) == 0); + CHECK(ecount == 5); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_verify(vrfy, asig, NULL, msg, &enckey) == 0); + CHECK(ecount == 6); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_verify(vrfy, asig, &zero_pk, msg, &enckey) == 0); + CHECK(ecount == 7); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_verify(vrfy, asig, &pubkey, msg, &zero_pk) == 0); + CHECK(ecount == 8); + + ecount = 0; + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_decrypt(none, &sig, deckey, asig) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_decrypt(sign, &sig, deckey, asig) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_decrypt(vrfy, &sig, deckey, asig) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_decrypt(both, &sig, deckey, asig) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_decrypt(both, NULL, deckey, asig) == 0); + CHECK(ecount == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_decrypt(both, &sig, NULL, asig) == 0); + CHECK(ecount == 2); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_decrypt(both, &sig, deckey, NULL) == 0); + CHECK(ecount == 3); + + ecount = 0; + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_decrypt(both, &sig, deckey, asig) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_recover(none, deckey, &sig, asig, &enckey) == 0); + CHECK(ecount == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_recover(vrfy, deckey, &sig, asig, &enckey) == 0); + CHECK(ecount == 2); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_recover(sign, deckey, &sig, asig, &enckey) == 1); + CHECK(ecount == 2); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_recover(sign, NULL, &sig, asig, &enckey) == 0); + CHECK(ecount == 3); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_recover(sign, deckey, NULL, asig, &enckey) == 0); + CHECK(ecount == 4); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_recover(sign, deckey, &sig, NULL, &enckey) == 0); + CHECK(ecount == 5); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_recover(sign, deckey, &sig, asig, NULL) == 0); + CHECK(ecount == 6); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_recover(sign, deckey, &sig, asig, &zero_pk) == 0); + CHECK(ecount == 7); + + rustsecp256k1zkp_v0_2_0_context_destroy(none); + rustsecp256k1zkp_v0_2_0_context_destroy(sign); + rustsecp256k1zkp_v0_2_0_context_destroy(vrfy); + rustsecp256k1zkp_v0_2_0_context_destroy(both); +} + +void adaptor_tests(void) { + unsigned char seckey[32]; + rustsecp256k1zkp_v0_2_0_pubkey pubkey; + unsigned char msg[32]; + unsigned char deckey[32]; + rustsecp256k1zkp_v0_2_0_pubkey enckey; + unsigned char adaptor_sig[162]; + rustsecp256k1zkp_v0_2_0_ecdsa_signature sig; + unsigned char zeros162[162] = { 0 }; + unsigned char zeros64[64] = { 0 }; + unsigned char big[32]; + + rustsecp256k1zkp_v0_2_0_testrand256(seckey); + rustsecp256k1zkp_v0_2_0_testrand256(msg); + rustsecp256k1zkp_v0_2_0_testrand256(deckey); + + CHECK(rustsecp256k1zkp_v0_2_0_ec_pubkey_create(ctx, &pubkey, seckey) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ec_pubkey_create(ctx, &enckey, deckey) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_encrypt(ctx, adaptor_sig, seckey, &enckey, msg, NULL, NULL) == 1); + + { + /* Test overflowing seckey */ + memset(big, 0xFF, 32); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_encrypt(ctx, adaptor_sig, big, &enckey, msg, NULL, NULL) == 0); + CHECK(rustsecp256k1zkp_v0_2_0_memcmp_var(adaptor_sig, zeros162, sizeof(adaptor_sig)) == 0); + + /* Test different nonce functions */ + memset(adaptor_sig, 1, sizeof(adaptor_sig)); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_encrypt(ctx, adaptor_sig, seckey, &enckey, msg, ecdsa_adaptor_nonce_function_failing, NULL) == 0); + CHECK(rustsecp256k1zkp_v0_2_0_memcmp_var(adaptor_sig, zeros162, sizeof(adaptor_sig)) == 0); + memset(&adaptor_sig, 1, sizeof(adaptor_sig)); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_encrypt(ctx, adaptor_sig, seckey, &enckey, msg, ecdsa_adaptor_nonce_function_0, NULL) == 0); + CHECK(rustsecp256k1zkp_v0_2_0_memcmp_var(adaptor_sig, zeros162, sizeof(adaptor_sig)) == 0); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_encrypt(ctx, adaptor_sig, seckey, &enckey, msg, ecdsa_adaptor_nonce_function_overflowing, NULL) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_memcmp_var(adaptor_sig, zeros162, sizeof(adaptor_sig)) != 0); + } + { + /* Test adaptor_sig_serialize roundtrip */ + rustsecp256k1zkp_v0_2_0_ge r, rp; + rustsecp256k1zkp_v0_2_0_scalar sigr; + rustsecp256k1zkp_v0_2_0_scalar sp; + rustsecp256k1zkp_v0_2_0_scalar dleq_proof_s, dleq_proof_e; + rustsecp256k1zkp_v0_2_0_ge p_inf; + unsigned char adaptor_sig_tmp[162]; + + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_sig_deserialize(&r, &sigr, &rp, &sp, &dleq_proof_e, &dleq_proof_s, adaptor_sig) == 1); + + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_sig_serialize(adaptor_sig_tmp, &r, &rp, &sp, &dleq_proof_e, &dleq_proof_s) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_memcmp_var(adaptor_sig_tmp, adaptor_sig, sizeof(adaptor_sig_tmp)) == 0); + + /* Test adaptor_sig_serialize points at infinity */ + rustsecp256k1zkp_v0_2_0_ge_set_infinity(&p_inf); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_sig_serialize(adaptor_sig_tmp, &p_inf, &rp, &sp, &dleq_proof_e, &dleq_proof_s) == 0); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_sig_serialize(adaptor_sig_tmp, &r, &p_inf, &sp, &dleq_proof_e, &dleq_proof_s) == 0); + } + { + /* Test adaptor_sig_deserialize */ + rustsecp256k1zkp_v0_2_0_ge r, rp; + rustsecp256k1zkp_v0_2_0_scalar sigr; + rustsecp256k1zkp_v0_2_0_scalar sp; + rustsecp256k1zkp_v0_2_0_scalar dleq_proof_s, dleq_proof_e; + unsigned char adaptor_sig_tmp[162]; + + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_sig_deserialize(&r, &sigr, &rp, &sp, &dleq_proof_e, &dleq_proof_s, adaptor_sig) == 1); + + /* r */ + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_sig_deserialize(&r, &sigr, NULL, NULL, NULL, NULL, adaptor_sig) == 1); + memcpy(adaptor_sig_tmp, adaptor_sig, sizeof(adaptor_sig_tmp)); + memset(&adaptor_sig_tmp[0], 0xFF, 33); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_sig_deserialize(&r, &sigr, NULL, NULL, NULL, NULL, adaptor_sig_tmp) == 0); + + /* sigr */ + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_sig_deserialize(NULL, &sigr, NULL, NULL, NULL, NULL, adaptor_sig) == 1); + memcpy(adaptor_sig_tmp, adaptor_sig, sizeof(adaptor_sig_tmp)); + memset(&adaptor_sig_tmp[1], 0xFF, 32); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_sig_deserialize(NULL, &sigr, NULL, NULL, NULL, NULL, adaptor_sig_tmp) == 1); + memset(&adaptor_sig_tmp[1], 0, 32); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_sig_deserialize(NULL, &sigr, NULL, NULL, NULL, NULL, adaptor_sig_tmp) == 0); + + /* rp */ + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_sig_deserialize(NULL, NULL, &rp, NULL, NULL, NULL, adaptor_sig) == 1); + memcpy(adaptor_sig_tmp, adaptor_sig, sizeof(adaptor_sig_tmp)); + memset(&adaptor_sig_tmp[33], 0xFF, 33); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_sig_deserialize(NULL, NULL, &rp, NULL, NULL, NULL, adaptor_sig_tmp) == 0); + + /* sp */ + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_sig_deserialize(NULL, NULL, NULL, &sp, NULL, NULL, adaptor_sig) == 1); + memcpy(adaptor_sig_tmp, adaptor_sig, sizeof(adaptor_sig_tmp)); + memset(&adaptor_sig_tmp[66], 0xFF, 32); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_sig_deserialize(NULL, NULL, NULL, &sp, NULL, NULL, adaptor_sig_tmp) == 0); + + /* dleq_proof_e */ + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_sig_deserialize(NULL, NULL, NULL, NULL, &dleq_proof_e, NULL, adaptor_sig) == 1); + memcpy(adaptor_sig_tmp, adaptor_sig, sizeof(adaptor_sig_tmp)); + memset(&adaptor_sig_tmp[98], 0xFF, 32); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_sig_deserialize(NULL, NULL, NULL, NULL, &dleq_proof_e, NULL, adaptor_sig_tmp) == 1); + + /* dleq_proof_s */ + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_sig_deserialize(NULL, NULL, NULL, NULL, NULL, &dleq_proof_s, adaptor_sig) == 1); + memcpy(adaptor_sig_tmp, adaptor_sig, sizeof(adaptor_sig_tmp)); + memset(&adaptor_sig_tmp[130], 0xFF, 32); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_sig_deserialize(NULL, NULL, NULL, NULL, NULL, &dleq_proof_s, adaptor_sig_tmp) == 0); + } + + /* Test adaptor_sig_verify */ + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_verify(ctx, adaptor_sig, &pubkey, msg, &enckey) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_verify(ctx, adaptor_sig, &enckey, msg, &enckey) == 0); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_verify(ctx, adaptor_sig, &pubkey, msg, &pubkey) == 0); + { + unsigned char adaptor_sig_tmp[65]; + memcpy(adaptor_sig_tmp, adaptor_sig, sizeof(adaptor_sig_tmp)); + rand_flip_bit(&adaptor_sig_tmp[1], sizeof(adaptor_sig_tmp) - 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_verify(ctx, adaptor_sig_tmp, &pubkey, msg, &enckey) == 0); + } + { + unsigned char msg_tmp[32]; + memcpy(msg_tmp, msg, sizeof(msg_tmp)); + rand_flip_bit(msg_tmp, sizeof(msg_tmp)); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_verify(ctx, adaptor_sig, &pubkey, msg_tmp, &enckey) == 0); + } + { + /* Verification must check that the derived R' is not equal to the point at + * infinity before negating it. R' is derived as follows: + * + * R' == s'⁻¹(m * G + R.x * X) + * + * When the base point, G, is multiplied by the subgroup order, q, the + * result is the point at infinity, 0: + * + * q * G = 0 + * + * Thus, if we set s' equal to R.x, m equal to (q - 1) * R.x, and X equal to + * G, then our derived R' will be 0: + * + * R' = R.x⁻¹((q - 1 * R.x) * G + R.x * G) = q * G = 0 */ + + /* t := q - 1 */ + const unsigned char target[32] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, + 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x40 + }; + unsigned char seckey_tmp[32] = { 0 }; + unsigned char msg_tmp[32]; + unsigned char adaptor_sig_tmp[162]; + rustsecp256k1zkp_v0_2_0_pubkey pubkey_tmp; + rustsecp256k1zkp_v0_2_0_scalar sigr, t, m; + + /* m := t * sigr */ + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_sig_deserialize(NULL, &sigr, NULL, NULL, NULL, NULL, adaptor_sig) == 1); + rustsecp256k1zkp_v0_2_0_scalar_set_b32(&t, target, NULL); + rustsecp256k1zkp_v0_2_0_scalar_mul(&m, &t, &sigr); + rustsecp256k1zkp_v0_2_0_scalar_get_b32(msg_tmp, &m); + + /* X := G */ + seckey_tmp[31] = 1; + CHECK(rustsecp256k1zkp_v0_2_0_ec_pubkey_create(ctx, &pubkey_tmp, seckey_tmp) == 1); + + /* sp := sigr */ + memcpy(adaptor_sig_tmp, adaptor_sig, sizeof(adaptor_sig_tmp)); + memcpy(&adaptor_sig_tmp[66], &adaptor_sig_tmp[1], 32); + + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_verify(ctx, adaptor_sig_tmp, &pubkey_tmp, msg_tmp, &enckey) == 0); + } + + /* Test decryption */ + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_decrypt(ctx, &sig, deckey, adaptor_sig) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_verify(ctx, &sig, msg, &pubkey) == 1); + + { + /* Test overflowing decryption key */ + rustsecp256k1zkp_v0_2_0_ecdsa_signature s; + memset(big, 0xFF, 32); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_decrypt(ctx, &s, big, adaptor_sig) == 0); + CHECK(rustsecp256k1zkp_v0_2_0_memcmp_var(&s.data[0], zeros64, sizeof(&s.data[0])) == 0); + } + { + /* Test key recover */ + rustsecp256k1zkp_v0_2_0_ecdsa_signature sig_tmp; + unsigned char decryption_key_tmp[32]; + unsigned char adaptor_sig_tmp[162]; + const unsigned char order_le[32] = { + 0x41, 0x41, 0x36, 0xd0, 0x8c, 0x5e, 0xd2, 0xbf, + 0x3b, 0xa0, 0x48, 0xaf, 0xe6, 0xdc, 0xae, 0xba, + 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; + + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_recover(ctx, decryption_key_tmp, &sig, adaptor_sig, &enckey) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_memcmp_var(deckey, decryption_key_tmp, sizeof(deckey)) == 0); + + /* Test failed sp deserialization */ + memcpy(adaptor_sig_tmp, adaptor_sig, sizeof(adaptor_sig_tmp)); + memset(&adaptor_sig_tmp[66], 0xFF, 32); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_recover(ctx, decryption_key_tmp, &sig, adaptor_sig_tmp, &enckey) == 0); + + /* Test failed enckey_expected serialization */ + memcpy(sig_tmp.data, sig.data, 32); + memcpy(&sig_tmp.data[32], order_le, 32); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_recover(ctx, decryption_key_tmp, &sig_tmp, adaptor_sig, &enckey) == 0); + } +} + +void multi_hop_lock_tests(void) { + unsigned char seckey_a[32]; + unsigned char seckey_b[32]; + unsigned char pop[32]; + unsigned char tx_ab[32]; + unsigned char tx_bc[32]; + unsigned char buf[32]; + unsigned char asig_ab[162]; + unsigned char asig_bc[162]; + rustsecp256k1zkp_v0_2_0_pubkey pubkey_pop; + rustsecp256k1zkp_v0_2_0_pubkey pubkey_a, pubkey_b; + rustsecp256k1zkp_v0_2_0_pubkey l, r; + rustsecp256k1zkp_v0_2_0_ge l_ge, r_ge; + rustsecp256k1zkp_v0_2_0_scalar t1, t2, tp; + rustsecp256k1zkp_v0_2_0_scalar deckey; + rustsecp256k1zkp_v0_2_0_ecdsa_signature sig_ab, sig_bc; + + rustsecp256k1zkp_v0_2_0_testrand256(seckey_a); + rustsecp256k1zkp_v0_2_0_testrand256(seckey_b); + + CHECK(rustsecp256k1zkp_v0_2_0_ec_pubkey_create(ctx, &pubkey_a, seckey_a)); + CHECK(rustsecp256k1zkp_v0_2_0_ec_pubkey_create(ctx, &pubkey_b, seckey_b)); + + /* Carol setup */ + /* Proof of payment */ + rustsecp256k1zkp_v0_2_0_testrand256(pop); + CHECK(rustsecp256k1zkp_v0_2_0_ec_pubkey_create(ctx, &pubkey_pop, pop)); + + /* Alice setup */ + rustsecp256k1zkp_v0_2_0_testrand256(tx_ab); + rand_scalar(&t1); + rand_scalar(&t2); + rustsecp256k1zkp_v0_2_0_scalar_add(&tp, &t1, &t2); + /* Left lock */ + rustsecp256k1zkp_v0_2_0_pubkey_load(ctx, &l_ge, &pubkey_pop); + CHECK(rustsecp256k1zkp_v0_2_0_eckey_pubkey_tweak_add(&ctx->ecmult_ctx, &l_ge, &t1)); + rustsecp256k1zkp_v0_2_0_pubkey_save(&l, &l_ge); + /* Right lock */ + rustsecp256k1zkp_v0_2_0_pubkey_load(ctx, &r_ge, &pubkey_pop); + CHECK(rustsecp256k1zkp_v0_2_0_eckey_pubkey_tweak_add(&ctx->ecmult_ctx, &r_ge, &tp)); + rustsecp256k1zkp_v0_2_0_pubkey_save(&r, &r_ge); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_encrypt(ctx, asig_ab, seckey_a, &l, tx_ab, NULL, NULL)); + + /* Bob setup */ + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_verify(ctx, asig_ab, &pubkey_a, tx_ab, &l)); + rustsecp256k1zkp_v0_2_0_testrand256(tx_bc); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_encrypt(ctx, asig_bc, seckey_b, &r, tx_bc, NULL, NULL)); + + /* Carol decrypt */ + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_verify(ctx, asig_bc, &pubkey_b, tx_bc, &r)); + rustsecp256k1zkp_v0_2_0_scalar_set_b32(&deckey, pop, NULL); + rustsecp256k1zkp_v0_2_0_scalar_add(&deckey, &deckey, &tp); + rustsecp256k1zkp_v0_2_0_scalar_get_b32(buf, &deckey); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_decrypt(ctx, &sig_bc, buf, asig_bc)); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_verify(ctx, &sig_bc, tx_bc, &pubkey_b)); + + /* Bob recover and decrypt */ + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_recover(ctx, buf, &sig_bc, asig_bc, &r)); + rustsecp256k1zkp_v0_2_0_scalar_set_b32(&deckey, buf, NULL); + rustsecp256k1zkp_v0_2_0_scalar_negate(&t2, &t2); + rustsecp256k1zkp_v0_2_0_scalar_add(&deckey, &deckey, &t2); + rustsecp256k1zkp_v0_2_0_scalar_get_b32(buf, &deckey); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_decrypt(ctx, &sig_ab, buf, asig_ab)); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_verify(ctx, &sig_ab, tx_ab, &pubkey_a)); + + /* Alice recover and derive proof of payment */ + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_recover(ctx, buf, &sig_ab, asig_ab, &l)); + rustsecp256k1zkp_v0_2_0_scalar_set_b32(&deckey, buf, NULL); + rustsecp256k1zkp_v0_2_0_scalar_negate(&t1, &t1); + rustsecp256k1zkp_v0_2_0_scalar_add(&deckey, &deckey, &t1); + rustsecp256k1zkp_v0_2_0_scalar_get_b32(buf, &deckey); + CHECK(rustsecp256k1zkp_v0_2_0_memcmp_var(buf, pop, 32) == 0); +} + +void run_ecdsa_adaptor_tests(void) { + int i; + run_nonce_function_ecdsa_adaptor_tests(); + + test_ecdsa_adaptor_api(); + test_ecdsa_adaptor_spec_vectors(); + for (i = 0; i < count; i++) { + dleq_tests(); + } + for (i = 0; i < count; i++) { + adaptor_tests(); + } + for (i = 0; i < count; i++) { + multi_hop_lock_tests(); + } +} + +#endif /* SECP256K1_MODULE_ECDSA_ADAPTOR_TESTS_H */ diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/modules/ecdsa_s2c/Makefile.am.include b/secp256k1-zkp-sys/depend/secp256k1/src/modules/ecdsa_s2c/Makefile.am.include new file mode 100644 index 00000000..9d9b8460 --- /dev/null +++ b/secp256k1-zkp-sys/depend/secp256k1/src/modules/ecdsa_s2c/Makefile.am.include @@ -0,0 +1,3 @@ +include_HEADERS += include/rustsecp256k1zkp_v0_2_0_ecdsa_s2c.h +noinst_HEADERS += src/modules/ecdsa_s2c/main_impl.h +noinst_HEADERS += src/modules/ecdsa_s2c/tests_impl.h diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/modules/ecdsa_s2c/main_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/modules/ecdsa_s2c/main_impl.h new file mode 100755 index 00000000..7d773dae --- /dev/null +++ b/secp256k1-zkp-sys/depend/secp256k1/src/modules/ecdsa_s2c/main_impl.h @@ -0,0 +1,198 @@ +/********************************************************************** + * Copyright (c) 2019-2020 Marko Bencun, Jonas Nick * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef SECP256K1_MODULE_ECDSA_S2C_MAIN_H +#define SECP256K1_MODULE_ECDSA_S2C_MAIN_H + +#include "include/secp256k1.h" +#include "include/secp256k1_ecdsa_s2c.h" + +static void rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_save(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening* opening, rustsecp256k1zkp_v0_2_0_ge* ge) { + rustsecp256k1zkp_v0_2_0_pubkey_save((rustsecp256k1zkp_v0_2_0_pubkey*) opening, ge); +} + +static int rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_load(const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_ge* ge, const rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening* opening) { + return rustsecp256k1zkp_v0_2_0_pubkey_load(ctx, ge, (const rustsecp256k1zkp_v0_2_0_pubkey*) opening); +} + +int rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_parse(const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening* opening, const unsigned char* input33) { + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(opening != NULL); + ARG_CHECK(input33 != NULL); + return rustsecp256k1zkp_v0_2_0_ec_pubkey_parse(ctx, (rustsecp256k1zkp_v0_2_0_pubkey*) opening, input33, 33); +} + +int rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_serialize(const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char* output33, const rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening* opening) { + size_t out_len = 33; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(output33 != NULL); + ARG_CHECK(opening != NULL); + return rustsecp256k1zkp_v0_2_0_ec_pubkey_serialize(ctx, output33, &out_len, (const rustsecp256k1zkp_v0_2_0_pubkey*) opening, SECP256K1_EC_COMPRESSED); +} + +/* Initializes SHA256 with fixed midstate. This midstate was computed by applying + * SHA256 to SHA256("s2c/ecdsa/point")||SHA256("s2c/ecdsa/point"). */ +static void rustsecp256k1zkp_v0_2_0_s2c_ecdsa_point_sha256_tagged(rustsecp256k1zkp_v0_2_0_sha256 *sha) { + rustsecp256k1zkp_v0_2_0_sha256_initialize(sha); + sha->s[0] = 0xa9b21c7bul; + sha->s[1] = 0x358c3e3eul; + sha->s[2] = 0x0b6863d1ul; + sha->s[3] = 0xc62b2035ul; + sha->s[4] = 0xb44b40ceul; + sha->s[5] = 0x254a8912ul; + sha->s[6] = 0x0f85d0d4ul; + sha->s[7] = 0x8a5bf91cul; + + sha->bytes = 64; +} + +/* Initializes SHA256 with fixed midstate. This midstate was computed by applying + * SHA256 to SHA256("s2c/ecdsa/data")||SHA256("s2c/ecdsa/data"). */ +static void rustsecp256k1zkp_v0_2_0_s2c_ecdsa_data_sha256_tagged(rustsecp256k1zkp_v0_2_0_sha256 *sha) { + rustsecp256k1zkp_v0_2_0_sha256_initialize(sha); + sha->s[0] = 0xfeefd675ul; + sha->s[1] = 0x73166c99ul; + sha->s[2] = 0xe2309cb8ul; + sha->s[3] = 0x6d458113ul; + sha->s[4] = 0x01d3a512ul; + sha->s[5] = 0x00e18112ul; + sha->s[6] = 0x37ee0874ul; + sha->s[7] = 0x421fc55ful; + + sha->bytes = 64; +} + +int rustsecp256k1zkp_v0_2_0_ecdsa_s2c_sign(const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_ecdsa_signature* signature, rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening* s2c_opening, const unsigned char + *msg32, const unsigned char *seckey, const unsigned char* s2c_data32) { + rustsecp256k1zkp_v0_2_0_scalar r, s; + int ret; + unsigned char ndata[32]; + rustsecp256k1zkp_v0_2_0_sha256 s2c_sha; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(rustsecp256k1zkp_v0_2_0_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + ARG_CHECK(msg32 != NULL); + ARG_CHECK(signature != NULL); + ARG_CHECK(seckey != NULL); + ARG_CHECK(s2c_data32 != NULL); + + /* Provide `s2c_data32` to the nonce function as additional data to + * derive the nonce. It is first hashed because it should be possible + * to derive nonces even if only a SHA256 commitment to the data is + * known. This is important in the ECDSA anti-exfil protocol. */ + rustsecp256k1zkp_v0_2_0_s2c_ecdsa_data_sha256_tagged(&s2c_sha); + rustsecp256k1zkp_v0_2_0_sha256_write(&s2c_sha, s2c_data32, 32); + rustsecp256k1zkp_v0_2_0_sha256_finalize(&s2c_sha, ndata); + + rustsecp256k1zkp_v0_2_0_s2c_ecdsa_point_sha256_tagged(&s2c_sha); + ret = rustsecp256k1zkp_v0_2_0_ecdsa_sign_inner(ctx, &r, &s, NULL, &s2c_sha, s2c_opening, s2c_data32, msg32, seckey, NULL, ndata); + rustsecp256k1zkp_v0_2_0_scalar_cmov(&r, &rustsecp256k1zkp_v0_2_0_scalar_zero, !ret); + rustsecp256k1zkp_v0_2_0_scalar_cmov(&s, &rustsecp256k1zkp_v0_2_0_scalar_zero, !ret); + rustsecp256k1zkp_v0_2_0_ecdsa_signature_save(signature, &r, &s); + return ret; +} + +int rustsecp256k1zkp_v0_2_0_ecdsa_s2c_verify_commit(const rustsecp256k1zkp_v0_2_0_context* ctx, const rustsecp256k1zkp_v0_2_0_ecdsa_signature* sig, const unsigned char* data32, const rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening* opening) { + rustsecp256k1zkp_v0_2_0_ge commitment_ge; + rustsecp256k1zkp_v0_2_0_ge original_pubnonce_ge; + unsigned char x_bytes[32]; + rustsecp256k1zkp_v0_2_0_scalar sigr, sigs, x_scalar; + rustsecp256k1zkp_v0_2_0_sha256 s2c_sha; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(rustsecp256k1zkp_v0_2_0_ecmult_context_is_built(&ctx->ecmult_ctx)); + ARG_CHECK(sig != NULL); + ARG_CHECK(data32 != NULL); + ARG_CHECK(opening != NULL); + + if (!rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_load(ctx, &original_pubnonce_ge, opening)) { + return 0; + } + rustsecp256k1zkp_v0_2_0_s2c_ecdsa_point_sha256_tagged(&s2c_sha); + if (!rustsecp256k1zkp_v0_2_0_ec_commit(&ctx->ecmult_ctx, &commitment_ge, &original_pubnonce_ge, &s2c_sha, data32, 32)) { + return 0; + } + + /* Check that sig_r == commitment_x (mod n) + * sig_r is the x coordinate of R represented by a scalar. + * commitment_x is the x coordinate of the commitment (field element). + * + * Note that we are only checking the x-coordinate -- this is because the y-coordinate + * is not part of the ECDSA signature (and therefore not part of the commitment!) + */ + rustsecp256k1zkp_v0_2_0_ecdsa_signature_load(ctx, &sigr, &sigs, sig); + + rustsecp256k1zkp_v0_2_0_fe_normalize(&commitment_ge.x); + rustsecp256k1zkp_v0_2_0_fe_get_b32(x_bytes, &commitment_ge.x); + /* Do not check overflow; overflowing a scalar does not affect whether + * or not the R value is a cryptographic commitment, only whether it + * is a valid R value for an ECDSA signature. If users care about that + * they should use `ecdsa_verify` or `anti_exfil_host_verify`. In other + * words, this check would be (at best) unnecessary, and (at worst) + * insufficient. */ + rustsecp256k1zkp_v0_2_0_scalar_set_b32(&x_scalar, x_bytes, NULL); + return rustsecp256k1zkp_v0_2_0_scalar_eq(&sigr, &x_scalar); +} + +/*** anti-exfil ***/ +int rustsecp256k1zkp_v0_2_0_ecdsa_anti_exfil_host_commit(const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char* rand_commitment32, const unsigned char* rand32) { + rustsecp256k1zkp_v0_2_0_sha256 sha; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(rand_commitment32 != NULL); + ARG_CHECK(rand32 != NULL); + + rustsecp256k1zkp_v0_2_0_s2c_ecdsa_data_sha256_tagged(&sha); + rustsecp256k1zkp_v0_2_0_sha256_write(&sha, rand32, 32); + rustsecp256k1zkp_v0_2_0_sha256_finalize(&sha, rand_commitment32); + return 1; +} + +int rustsecp256k1zkp_v0_2_0_ecdsa_anti_exfil_signer_commit(const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening* opening, const unsigned char* msg32, const unsigned char* seckey32, const unsigned char* rand_commitment32) { + unsigned char nonce32[32]; + rustsecp256k1zkp_v0_2_0_scalar k; + rustsecp256k1zkp_v0_2_0_gej rj; + rustsecp256k1zkp_v0_2_0_ge r; + unsigned int count = 0; + int is_nonce_valid = 0; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(rustsecp256k1zkp_v0_2_0_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + ARG_CHECK(opening != NULL); + ARG_CHECK(msg32 != NULL); + ARG_CHECK(seckey32 != NULL); + ARG_CHECK(rand_commitment32 != NULL); + + memset(nonce32, 0, 32); + while (!is_nonce_valid) { + /* cast to void* removes const qualifier, but rustsecp256k1zkp_v0_2_0_nonce_function_default does not modify it */ + if (!rustsecp256k1zkp_v0_2_0_nonce_function_default(nonce32, msg32, seckey32, NULL, (void*)rand_commitment32, count)) { + rustsecp256k1zkp_v0_2_0_callback_call(&ctx->error_callback, "(cryptographically unreachable) generated bad nonce"); + } + is_nonce_valid = rustsecp256k1zkp_v0_2_0_scalar_set_b32_seckey(&k, nonce32); + /* The nonce is still secret here, but it being invalid is is less likely than 1:2^255. */ + rustsecp256k1zkp_v0_2_0_declassify(ctx, &is_nonce_valid, sizeof(is_nonce_valid)); + count++; + } + + rustsecp256k1zkp_v0_2_0_ecmult_gen(&ctx->ecmult_gen_ctx, &rj, &k); + rustsecp256k1zkp_v0_2_0_ge_set_gej(&r, &rj); + rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_save(opening, &r); + memset(nonce32, 0, 32); + rustsecp256k1zkp_v0_2_0_scalar_clear(&k); + return 1; +} + +int rustsecp256k1zkp_v0_2_0_anti_exfil_sign(const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_ecdsa_signature* sig, const unsigned char* msg32, const unsigned char* seckey, const unsigned char* host_data32) { + return rustsecp256k1zkp_v0_2_0_ecdsa_s2c_sign(ctx, sig, NULL, msg32, seckey, host_data32); +} + +int rustsecp256k1zkp_v0_2_0_anti_exfil_host_verify(const rustsecp256k1zkp_v0_2_0_context* ctx, const rustsecp256k1zkp_v0_2_0_ecdsa_signature *sig, const unsigned char *msg32, const rustsecp256k1zkp_v0_2_0_pubkey *pubkey, const unsigned char *host_data32, const rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening *opening) { + return rustsecp256k1zkp_v0_2_0_ecdsa_s2c_verify_commit(ctx, sig, host_data32, opening) && + rustsecp256k1zkp_v0_2_0_ecdsa_verify(ctx, sig, msg32, pubkey); +} + +#endif /* SECP256K1_ECDSA_S2C_MAIN_H */ diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/modules/ecdsa_s2c/tests_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/modules/ecdsa_s2c/tests_impl.h new file mode 100644 index 00000000..c4570eda --- /dev/null +++ b/secp256k1-zkp-sys/depend/secp256k1/src/modules/ecdsa_s2c/tests_impl.h @@ -0,0 +1,416 @@ +/********************************************************************** + * Copyright (c) 2019-2020 Marko Bencun, Jonas Nick * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef SECP256K1_MODULE_ECDSA_S2C_TESTS_H +#define SECP256K1_MODULE_ECDSA_S2C_TESTS_H + +#include "include/secp256k1_ecdsa_s2c.h" + +static void test_ecdsa_s2c_tagged_hash(void) { + unsigned char tag_data[14] = "s2c/ecdsa/data"; + unsigned char tag_point[15] = "s2c/ecdsa/point"; + rustsecp256k1zkp_v0_2_0_sha256 sha; + rustsecp256k1zkp_v0_2_0_sha256 sha_optimized; + unsigned char output[32]; + unsigned char output_optimized[32]; + + rustsecp256k1zkp_v0_2_0_sha256_initialize_tagged(&sha, tag_data, sizeof(tag_data)); + rustsecp256k1zkp_v0_2_0_s2c_ecdsa_data_sha256_tagged(&sha_optimized); + rustsecp256k1zkp_v0_2_0_sha256_finalize(&sha, output); + rustsecp256k1zkp_v0_2_0_sha256_finalize(&sha_optimized, output_optimized); + CHECK(rustsecp256k1zkp_v0_2_0_memcmp_var(output, output_optimized, 32) == 0); + + rustsecp256k1zkp_v0_2_0_sha256_initialize_tagged(&sha, tag_point, sizeof(tag_point)); + rustsecp256k1zkp_v0_2_0_s2c_ecdsa_point_sha256_tagged(&sha_optimized); + rustsecp256k1zkp_v0_2_0_sha256_finalize(&sha, output); + rustsecp256k1zkp_v0_2_0_sha256_finalize(&sha_optimized, output_optimized); + CHECK(rustsecp256k1zkp_v0_2_0_memcmp_var(output, output_optimized, 32) == 0); +} + +void run_s2c_opening_test(void) { + int i = 0; + unsigned char output[33]; + rustsecp256k1zkp_v0_2_0_context *none = rustsecp256k1zkp_v0_2_0_context_create(SECP256K1_CONTEXT_NONE); + + unsigned char input[33] = { + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02 + }; + rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening opening; + int32_t ecount = 0; + + rustsecp256k1zkp_v0_2_0_context_set_illegal_callback(none, counting_illegal_callback_fn, &ecount); + + /* First parsing, then serializing works */ + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_parse(none, &opening, input) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_serialize(none, output, &opening) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_parse(none, &opening, input) == 1); + CHECK(ecount == 0); + + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_parse(none, NULL, input) == 0); + CHECK(ecount == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_parse(none, &opening, NULL) == 0); + CHECK(ecount == 2); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_parse(none, &opening, input) == 1); + + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_serialize(none, NULL, &opening) == 0); + CHECK(ecount == 3); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_serialize(none, output, NULL) == 0); + + CHECK(ecount == 4); + /* Invalid pubkey makes parsing fail */ + input[0] = 0; /* bad oddness bit */ + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_parse(none, &opening, input) == 0); + input[0] = 2; + input[31] = 1; /* point not on the curve */ + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_parse(none, &opening, input) == 0); + CHECK(ecount == 4); /* neither of the above are API errors */ + + /* Try parsing and serializing a bunch of openings */ + for (i = 0; i < count; i++) { + /* This is expected to fail in about 50% of iterations because the + * points' x-coordinates are uniformly random */ + if (rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_parse(none, &opening, input) == 1) { + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_serialize(none, output, &opening) == 1); + CHECK(memcmp(output, input, sizeof(output)) == 0); + } + rustsecp256k1zkp_v0_2_0_testrand256(&input[1]); + /* Set pubkey oddness tag to first bit of input[1] */ + input[0] = (input[1] & 1) + 2; + } + + rustsecp256k1zkp_v0_2_0_context_destroy(none); +} + +static void test_ecdsa_s2c_api(void) { + rustsecp256k1zkp_v0_2_0_context *none = rustsecp256k1zkp_v0_2_0_context_create(SECP256K1_CONTEXT_NONE); + rustsecp256k1zkp_v0_2_0_context *sign = rustsecp256k1zkp_v0_2_0_context_create(SECP256K1_CONTEXT_SIGN); + rustsecp256k1zkp_v0_2_0_context *vrfy = rustsecp256k1zkp_v0_2_0_context_create(SECP256K1_CONTEXT_VERIFY); + rustsecp256k1zkp_v0_2_0_context *both = rustsecp256k1zkp_v0_2_0_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + + rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening s2c_opening; + rustsecp256k1zkp_v0_2_0_ecdsa_signature sig; + const unsigned char msg[32] = "mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm"; + const unsigned char sec[32] = "ssssssssssssssssssssssssssssssss"; + const unsigned char s2c_data[32] = "dddddddddddddddddddddddddddddddd"; + const unsigned char hostrand[32] = "hrhrhrhrhrhrhrhrhrhrhrhrhrhrhrhr"; + unsigned char hostrand_commitment[32]; + rustsecp256k1zkp_v0_2_0_pubkey pk; + + int32_t ecount; + rustsecp256k1zkp_v0_2_0_context_set_illegal_callback(none, counting_illegal_callback_fn, &ecount); + rustsecp256k1zkp_v0_2_0_context_set_illegal_callback(sign, counting_illegal_callback_fn, &ecount); + rustsecp256k1zkp_v0_2_0_context_set_illegal_callback(vrfy, counting_illegal_callback_fn, &ecount); + rustsecp256k1zkp_v0_2_0_context_set_illegal_callback(both, counting_illegal_callback_fn, &ecount); + CHECK(rustsecp256k1zkp_v0_2_0_ec_pubkey_create(ctx, &pk, sec)); + + ecount = 0; + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_sign(both, NULL, &s2c_opening, msg, sec, s2c_data) == 0); + CHECK(ecount == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_sign(both, &sig, NULL, msg, sec, s2c_data) == 1); + CHECK(ecount == 1); /* NULL opening is not an API error */ + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_sign(both, &sig, &s2c_opening, NULL, sec, s2c_data) == 0); + CHECK(ecount == 2); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_sign(both, &sig, &s2c_opening, msg, NULL, s2c_data) == 0); + CHECK(ecount == 3); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_sign(both, &sig, &s2c_opening, msg, sec, NULL) == 0); + CHECK(ecount == 4); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_sign(none, &sig, &s2c_opening, msg, sec, s2c_data) == 0); + CHECK(ecount == 5); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_sign(vrfy, &sig, &s2c_opening, msg, sec, s2c_data) == 0); + CHECK(ecount == 6); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_sign(sign, &sig, &s2c_opening, msg, sec, s2c_data) == 1); + CHECK(ecount == 6); + + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_verify(ctx, &sig, msg, &pk) == 1); + + ecount = 0; + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_verify_commit(both, NULL, s2c_data, &s2c_opening) == 0); + CHECK(ecount == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_verify_commit(both, &sig, NULL, &s2c_opening) == 0); + CHECK(ecount == 2); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_verify_commit(both, &sig, s2c_data, NULL) == 0); + CHECK(ecount == 3); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_verify_commit(none, &sig, s2c_data, &s2c_opening) == 0); + CHECK(ecount == 4); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_verify_commit(sign, &sig, s2c_data, &s2c_opening) == 0); + CHECK(ecount == 5); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_verify_commit(vrfy, &sig, s2c_data, &s2c_opening) == 1); + CHECK(ecount == 5); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_verify_commit(vrfy, &sig, sec, &s2c_opening) == 0); + CHECK(ecount == 5); /* wrong data is not an API error */ + + /* Signing with NULL s2c_opening gives the same result */ + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_sign(sign, &sig, NULL, msg, sec, s2c_data) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_verify_commit(vrfy, &sig, s2c_data, &s2c_opening) == 1); + + /* anti-exfil */ + ecount = 0; + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_anti_exfil_host_commit(none, NULL, hostrand) == 0); + CHECK(ecount == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_anti_exfil_host_commit(none, hostrand_commitment, NULL) == 0); + CHECK(ecount == 2); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_anti_exfil_host_commit(none, hostrand_commitment, hostrand) == 1); + CHECK(ecount == 2); + + ecount = 0; + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_anti_exfil_signer_commit(both, NULL, msg, sec, hostrand_commitment) == 0); + CHECK(ecount == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_anti_exfil_signer_commit(both, &s2c_opening, NULL, sec, hostrand_commitment) == 0); + CHECK(ecount == 2); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_anti_exfil_signer_commit(both, &s2c_opening, msg, NULL, hostrand_commitment) == 0); + CHECK(ecount == 3); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_anti_exfil_signer_commit(both, &s2c_opening, msg, sec, NULL) == 0); + CHECK(ecount == 4); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_anti_exfil_signer_commit(none, &s2c_opening, msg, sec, hostrand_commitment) == 0); + CHECK(ecount == 5); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_anti_exfil_signer_commit(vrfy, &s2c_opening, msg, sec, hostrand_commitment) == 0); + CHECK(ecount == 6); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_anti_exfil_signer_commit(sign, &s2c_opening, msg, sec, hostrand_commitment) == 1); + CHECK(ecount == 6); + + ecount = 0; + CHECK(rustsecp256k1zkp_v0_2_0_anti_exfil_sign(both, NULL, msg, sec, hostrand) == 0); + CHECK(ecount == 1); + CHECK(rustsecp256k1zkp_v0_2_0_anti_exfil_sign(both, &sig, NULL, sec, hostrand) == 0); + CHECK(ecount == 2); + CHECK(rustsecp256k1zkp_v0_2_0_anti_exfil_sign(both, &sig, msg, NULL, hostrand) == 0); + CHECK(ecount == 3); + CHECK(rustsecp256k1zkp_v0_2_0_anti_exfil_sign(both, &sig, msg, sec, NULL) == 0); + CHECK(ecount == 4); + CHECK(rustsecp256k1zkp_v0_2_0_anti_exfil_sign(none, &sig, msg, sec, hostrand) == 0); + CHECK(ecount == 5); + CHECK(rustsecp256k1zkp_v0_2_0_anti_exfil_sign(vrfy, &sig, msg, sec, hostrand) == 0); + CHECK(ecount == 6); + CHECK(rustsecp256k1zkp_v0_2_0_anti_exfil_sign(both, &sig, msg, sec, hostrand) == 1); + CHECK(ecount == 6); + + ecount = 0; + CHECK(rustsecp256k1zkp_v0_2_0_anti_exfil_host_verify(both, NULL, msg, &pk, hostrand, &s2c_opening) == 0); + CHECK(ecount == 1); + CHECK(rustsecp256k1zkp_v0_2_0_anti_exfil_host_verify(both, &sig, NULL, &pk, hostrand, &s2c_opening) == 0); + CHECK(ecount == 2); + CHECK(rustsecp256k1zkp_v0_2_0_anti_exfil_host_verify(both, &sig, msg, NULL, hostrand, &s2c_opening) == 0); + CHECK(ecount == 3); + CHECK(rustsecp256k1zkp_v0_2_0_anti_exfil_host_verify(both, &sig, msg, &pk, NULL, &s2c_opening) == 0); + CHECK(ecount == 4); + CHECK(rustsecp256k1zkp_v0_2_0_anti_exfil_host_verify(both, &sig, msg, &pk, hostrand, NULL) == 0); + CHECK(ecount == 5); + CHECK(rustsecp256k1zkp_v0_2_0_anti_exfil_host_verify(none, &sig, msg, &pk, hostrand, &s2c_opening) == 0); + CHECK(ecount == 6); + CHECK(rustsecp256k1zkp_v0_2_0_anti_exfil_host_verify(sign, &sig, msg, &pk, hostrand, &s2c_opening) == 0); + CHECK(ecount == 7); + CHECK(rustsecp256k1zkp_v0_2_0_anti_exfil_host_verify(vrfy, &sig, msg, &pk, hostrand, &s2c_opening) == 1); + CHECK(ecount == 7); + + rustsecp256k1zkp_v0_2_0_context_destroy(both); + rustsecp256k1zkp_v0_2_0_context_destroy(vrfy); + rustsecp256k1zkp_v0_2_0_context_destroy(sign); + rustsecp256k1zkp_v0_2_0_context_destroy(none); +} + +/* When using sign-to-contract commitments, the nonce function is fixed, so we can use fixtures to test. */ +typedef struct { + /* Data to commit to */ + unsigned char s2c_data[32]; + /* Original nonce */ + unsigned char expected_s2c_opening[33]; + /* Original nonce (anti-exfil protocol, which mixes in host randomness) */ + unsigned char expected_s2c_exfil_opening[33]; +} ecdsa_s2c_test; + +static ecdsa_s2c_test ecdsa_s2c_tests[] = { + { + "\x1b\xf6\xfb\x42\xf4\x1e\xb8\x76\xc4\xd7\xaa\x0d\x67\x24\x2b\x00\xba\xab\x99\xdc\x20\x84\x49\x3e\x4e\x63\x27\x7f\xa1\xf7\x7f\x22", + "\x03\xf0\x30\xde\xf3\x18\x8c\x0f\x56\xfc\xea\x87\x43\x5b\x30\x76\x43\xf4\x5d\xaf\xe2\x2c\xbc\x82\xfd\x56\x03\x4f\xae\x97\x41\x7d\x3a", + "\x02\xdf\x63\x75\x5d\x1f\x32\x92\xbf\xfe\xd8\x29\x86\xb1\x06\x49\x7c\x93\xb1\xf8\xbd\xc0\x45\x4b\x6b\x0b\x0a\x47\x79\xc0\xef\x71\x88", + }, + { + "\x35\x19\x9a\x8f\xbf\x84\xad\x6e\xf6\x9a\x18\x4c\x1b\x19\x28\x5b\xef\xbe\x06\xe6\x0b\x62\x64\xe6\xd3\x73\x89\x3f\x68\x55\xe2\x4a", + "\x03\x90\x17\x17\xce\x7c\x74\x84\xa2\xce\x1b\x7d\xc7\x40\x3b\x14\xe0\x35\x49\x71\x39\x3e\xc0\x92\xa7\xf3\xe0\xc8\xe4\xe2\xd2\x63\x9d", + "\x02\xc0\x4a\xc7\xf7\x71\xe8\xeb\xdb\xf3\x15\xff\x5e\x58\xb7\xfe\x95\x16\x10\x21\x03\x50\x00\x66\x17\x2c\x4f\xac\x5b\x20\xf9\xe0\xea", + }, +}; + +static void test_ecdsa_s2c_fixed_vectors(void) { + const unsigned char privkey[32] = { + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + }; + const unsigned char message[32] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + }; + size_t i; + + for (i = 0; i < sizeof(ecdsa_s2c_tests) / sizeof(ecdsa_s2c_tests[0]); i++) { + rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening s2c_opening; + unsigned char opening_ser[33]; + const ecdsa_s2c_test *test = &ecdsa_s2c_tests[i]; + rustsecp256k1zkp_v0_2_0_ecdsa_signature signature; + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_sign(ctx, &signature, &s2c_opening, message, privkey, test->s2c_data) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_serialize(ctx, opening_ser, &s2c_opening) == 1); + CHECK(memcmp(test->expected_s2c_opening, opening_ser, sizeof(opening_ser)) == 0); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_verify_commit(ctx, &signature, test->s2c_data, &s2c_opening) == 1); + } +} + +static void test_ecdsa_s2c_sign_verify(void) { + unsigned char privkey[32]; + rustsecp256k1zkp_v0_2_0_pubkey pubkey; + unsigned char message[32]; + unsigned char noncedata[32]; + unsigned char s2c_data[32]; + unsigned char s2c_data2[32]; + rustsecp256k1zkp_v0_2_0_ecdsa_signature signature; + rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening s2c_opening; + + /* Generate a random key, message, noncedata and s2c_data. */ + { + rustsecp256k1zkp_v0_2_0_scalar key; + random_scalar_order_test(&key); + rustsecp256k1zkp_v0_2_0_scalar_get_b32(privkey, &key); + CHECK(rustsecp256k1zkp_v0_2_0_ec_pubkey_create(ctx, &pubkey, privkey) == 1); + + rustsecp256k1zkp_v0_2_0_testrand256_test(message); + rustsecp256k1zkp_v0_2_0_testrand256_test(noncedata); + rustsecp256k1zkp_v0_2_0_testrand256_test(s2c_data); + rustsecp256k1zkp_v0_2_0_testrand256_test(s2c_data2); + } + + { /* invalid privkeys */ + unsigned char zero_privkey[32] = {0}; + unsigned char overflow_privkey[32] = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"; + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_sign(ctx, &signature, NULL, message, zero_privkey, s2c_data) == 0); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_sign(ctx, &signature, NULL, message, overflow_privkey, s2c_data) == 0); + } + /* Check that the sign-to-contract signature is valid, with s2c_data. Also check the commitment. */ + { + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_sign(ctx, &signature, &s2c_opening, message, privkey, s2c_data) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_verify(ctx, &signature, message, &pubkey) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_verify_commit(ctx, &signature, s2c_data, &s2c_opening) == 1); + } + /* Check that an invalid commitment does not verify */ + { + unsigned char sigbytes[64]; + size_t i; + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_sign(ctx, &signature, &s2c_opening, message, privkey, s2c_data) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_verify(ctx, &signature, message, &pubkey) == 1); + + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_signature_serialize_compact(ctx, sigbytes, &signature) == 1); + for(i = 0; i < 32; i++) { + /* change one byte */ + sigbytes[i] = (((int)sigbytes[i]) + 1) % 256; + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_signature_parse_compact(ctx, &signature, sigbytes) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_verify_commit(ctx, &signature, s2c_data, &s2c_opening) == 0); + /* revert */ + sigbytes[i] = (((int)sigbytes[i]) + 255) % 256; + } + } +} + +static void test_ecdsa_anti_exfil_signer_commit(void) { + size_t i; + unsigned char privkey[32] = { + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + }; + unsigned char message[32] = { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, + }; + /* Check that original pubnonce is derived from s2c_data */ + for (i = 0; i < sizeof(ecdsa_s2c_tests) / sizeof(ecdsa_s2c_tests[0]); i++) { + rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening s2c_opening; + unsigned char buf[33]; + const ecdsa_s2c_test *test = &ecdsa_s2c_tests[i]; + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_anti_exfil_signer_commit(ctx, &s2c_opening, message, privkey, test->s2c_data) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_serialize(ctx, buf, &s2c_opening) == 1); + CHECK(memcmp(test->expected_s2c_exfil_opening, buf, sizeof(buf)) == 0); + } +} + +/* This tests the full ECDSA Anti-Exfil Protocol */ +static void test_ecdsa_anti_exfil(void) { + unsigned char signer_privkey[32]; + unsigned char host_msg[32]; + unsigned char host_commitment[32]; + unsigned char host_nonce_contribution[32]; + rustsecp256k1zkp_v0_2_0_pubkey signer_pubkey; + rustsecp256k1zkp_v0_2_0_ecdsa_signature signature; + rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening s2c_opening; + + /* Generate a random key, message. */ + { + rustsecp256k1zkp_v0_2_0_scalar key; + random_scalar_order_test(&key); + rustsecp256k1zkp_v0_2_0_scalar_get_b32(signer_privkey, &key); + CHECK(rustsecp256k1zkp_v0_2_0_ec_pubkey_create(ctx, &signer_pubkey, signer_privkey) == 1); + rustsecp256k1zkp_v0_2_0_testrand256_test(host_msg); + rustsecp256k1zkp_v0_2_0_testrand256_test(host_nonce_contribution); + } + + /* Protocol step 1. */ + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_anti_exfil_host_commit(ctx, host_commitment, host_nonce_contribution) == 1); + /* Protocol step 2. */ + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_anti_exfil_signer_commit(ctx, &s2c_opening, host_msg, signer_privkey, host_commitment) == 1); + /* Protocol step 3: host_nonce_contribution send to signer to be used in step 4. */ + /* Protocol step 4. */ + CHECK(rustsecp256k1zkp_v0_2_0_anti_exfil_sign(ctx, &signature, host_msg, signer_privkey, host_nonce_contribution) == 1); + /* Protocol step 5. */ + CHECK(rustsecp256k1zkp_v0_2_0_anti_exfil_host_verify(ctx, &signature, host_msg, &signer_pubkey, host_nonce_contribution, &s2c_opening) == 1); + /* Protocol step 5 (explicitly) */ + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_verify_commit(ctx, &signature, host_nonce_contribution, &s2c_opening) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_verify(ctx, &signature, host_msg, &signer_pubkey) == 1); + + { /* host_verify: commitment does not match */ + unsigned char sigbytes[64]; + size_t i; + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_signature_serialize_compact(ctx, sigbytes, &signature) == 1); + for(i = 0; i < 32; i++) { + /* change one byte */ + sigbytes[i] += 1; + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_signature_parse_compact(ctx, &signature, sigbytes) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_verify_commit(ctx, &signature, host_nonce_contribution, &s2c_opening) == 0); + CHECK(rustsecp256k1zkp_v0_2_0_anti_exfil_host_verify(ctx, &signature, host_msg, &signer_pubkey, host_nonce_contribution, &s2c_opening) == 0); + /* revert */ + sigbytes[i] -= 1; + } + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_signature_parse_compact(ctx, &signature, sigbytes) == 1); + } + { /* host_verify: message does not match */ + unsigned char bad_msg[32]; + rustsecp256k1zkp_v0_2_0_testrand256_test(bad_msg); + CHECK(rustsecp256k1zkp_v0_2_0_anti_exfil_host_verify(ctx, &signature, host_msg, &signer_pubkey, host_nonce_contribution, &s2c_opening) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_anti_exfil_host_verify(ctx, &signature, bad_msg, &signer_pubkey, host_nonce_contribution, &s2c_opening) == 0); + } + { /* s2c_sign: host provided data that didn't match commitment */ + rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening orig_opening = s2c_opening; + unsigned char bad_nonce_contribution[32] = { 1, 2, 3, 4 }; + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_sign(ctx, &signature, &s2c_opening, host_msg, signer_privkey, bad_nonce_contribution) == 1); + /* good signature but the opening (original public nonce does not match the original */ + CHECK(rustsecp256k1zkp_v0_2_0_ecdsa_verify(ctx, &signature, host_msg, &signer_pubkey) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_anti_exfil_host_verify(ctx, &signature, host_msg, &signer_pubkey, host_nonce_contribution, &s2c_opening) == 0); + CHECK(rustsecp256k1zkp_v0_2_0_anti_exfil_host_verify(ctx, &signature, host_msg, &signer_pubkey, bad_nonce_contribution, &s2c_opening) == 1); + CHECK(memcmp(&s2c_opening, &orig_opening, sizeof(s2c_opening)) != 0); + } +} + +static void run_ecdsa_s2c_tests(void) { + run_s2c_opening_test(); + test_ecdsa_s2c_tagged_hash(); + test_ecdsa_s2c_api(); + test_ecdsa_s2c_fixed_vectors(); + test_ecdsa_s2c_sign_verify(); + + test_ecdsa_anti_exfil_signer_commit(); + test_ecdsa_anti_exfil(); +} + +#endif /* SECP256K1_MODULE_ECDSA_S2C_TESTS_H */ diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/modules/extrakeys/main_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/modules/extrakeys/main_impl.h index d34e6b87..90989999 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/modules/extrakeys/main_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/modules/extrakeys/main_impl.h @@ -1,11 +1,11 @@ -/********************************************************************** - * Copyright (c) 2020 Jonas Nick * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2020 Jonas Nick * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_MODULE_EXTRAKEYS_MAIN_ -#define _SECP256K1_MODULE_EXTRAKEYS_MAIN_ +#ifndef SECP256K1_MODULE_EXTRAKEYS_MAIN_H +#define SECP256K1_MODULE_EXTRAKEYS_MAIN_H #include "include/secp256k1.h" #include "include/secp256k1_extrakeys.h" @@ -186,6 +186,16 @@ int rustsecp256k1zkp_v0_2_0_keypair_create(const rustsecp256k1zkp_v0_2_0_context return ret; } +int rustsecp256k1zkp_v0_2_0_keypair_sec(const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char *seckey, const rustsecp256k1zkp_v0_2_0_keypair *keypair) { + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(seckey != NULL); + memset(seckey, 0, 32); + ARG_CHECK(keypair != NULL); + + memcpy(seckey, &keypair->data[0], 32); + return 1; +} + int rustsecp256k1zkp_v0_2_0_keypair_pub(const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_pubkey *pubkey, const rustsecp256k1zkp_v0_2_0_keypair *keypair) { VERIFY_CHECK(ctx != NULL); ARG_CHECK(pubkey != NULL); diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/modules/extrakeys/tests_exhaustive_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/modules/extrakeys/tests_exhaustive_impl.h index 01dad0dd..5917bd9c 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/modules/extrakeys/tests_exhaustive_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/modules/extrakeys/tests_exhaustive_impl.h @@ -1,11 +1,11 @@ -/********************************************************************** - * Copyright (c) 2020 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2020 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_MODULE_EXTRAKEYS_TESTS_EXHAUSTIVE_ -#define _SECP256K1_MODULE_EXTRAKEYS_TESTS_EXHAUSTIVE_ +#ifndef SECP256K1_MODULE_EXTRAKEYS_TESTS_EXHAUSTIVE_H +#define SECP256K1_MODULE_EXTRAKEYS_TESTS_EXHAUSTIVE_H #include "src/modules/extrakeys/main_impl.h" #include "include/secp256k1_extrakeys.h" diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/modules/extrakeys/tests_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/modules/extrakeys/tests_impl.h index 9ee9523e..3e762b48 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/modules/extrakeys/tests_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/modules/extrakeys/tests_impl.h @@ -1,11 +1,11 @@ -/********************************************************************** - * Copyright (c) 2020 Jonas Nick * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2020 Jonas Nick * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_MODULE_EXTRAKEYS_TESTS_ -#define _SECP256K1_MODULE_EXTRAKEYS_TESTS_ +#ifndef SECP256K1_MODULE_EXTRAKEYS_TESTS_H +#define SECP256K1_MODULE_EXTRAKEYS_TESTS_H #include "secp256k1_extrakeys.h" @@ -311,6 +311,7 @@ void test_xonly_pubkey_tweak_recursive(void) { void test_keypair(void) { unsigned char sk[32]; + unsigned char sk_tmp[32]; unsigned char zeros96[96] = { 0 }; unsigned char overflows[32]; rustsecp256k1zkp_v0_2_0_keypair keypair; @@ -396,6 +397,28 @@ void test_keypair(void) { CHECK(rustsecp256k1zkp_v0_2_0_memcmp_var(&xonly_pk, &xonly_pk_tmp, sizeof(pk)) == 0); CHECK(pk_parity == pk_parity_tmp); + /* Test keypair_seckey */ + ecount = 0; + rustsecp256k1zkp_v0_2_0_testrand256(sk); + CHECK(rustsecp256k1zkp_v0_2_0_keypair_create(ctx, &keypair, sk) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_keypair_sec(none, sk_tmp, &keypair) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_keypair_sec(none, NULL, &keypair) == 0); + CHECK(ecount == 1); + CHECK(rustsecp256k1zkp_v0_2_0_keypair_sec(none, sk_tmp, NULL) == 0); + CHECK(ecount == 2); + CHECK(rustsecp256k1zkp_v0_2_0_memcmp_var(zeros96, sk_tmp, sizeof(sk_tmp)) == 0); + + /* keypair returns the same seckey it got */ + CHECK(rustsecp256k1zkp_v0_2_0_keypair_create(sign, &keypair, sk) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_keypair_sec(none, sk_tmp, &keypair) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_memcmp_var(sk, sk_tmp, sizeof(sk_tmp)) == 0); + + + /* Using an invalid keypair is fine for keypair_seckey */ + memset(&keypair, 0, sizeof(keypair)); + CHECK(rustsecp256k1zkp_v0_2_0_keypair_sec(none, sk_tmp, &keypair) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_memcmp_var(zeros96, sk_tmp, sizeof(sk_tmp)) == 0); + rustsecp256k1zkp_v0_2_0_context_destroy(none); rustsecp256k1zkp_v0_2_0_context_destroy(sign); rustsecp256k1zkp_v0_2_0_context_destroy(verify); @@ -484,6 +507,7 @@ void test_keypair_add(void) { rustsecp256k1zkp_v0_2_0_pubkey output_pk_xy; rustsecp256k1zkp_v0_2_0_pubkey output_pk_expected; unsigned char pk32[32]; + unsigned char sk32[32]; int pk_parity; rustsecp256k1zkp_v0_2_0_testrand256(tweak); @@ -501,7 +525,8 @@ void test_keypair_add(void) { CHECK(rustsecp256k1zkp_v0_2_0_memcmp_var(&output_pk_xy, &output_pk_expected, sizeof(output_pk_xy)) == 0); /* Check that the secret key in the keypair is tweaked correctly */ - CHECK(rustsecp256k1zkp_v0_2_0_ec_pubkey_create(ctx, &output_pk_expected, &keypair.data[0]) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_keypair_sec(none, sk32, &keypair) == 1); + CHECK(rustsecp256k1zkp_v0_2_0_ec_pubkey_create(ctx, &output_pk_expected, sk32) == 1); CHECK(rustsecp256k1zkp_v0_2_0_memcmp_var(&output_pk_xy, &output_pk_expected, sizeof(output_pk_xy)) == 0); } rustsecp256k1zkp_v0_2_0_context_destroy(none); diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/modules/musig/example.c b/secp256k1-zkp-sys/depend/secp256k1/src/modules/musig/example.c index d4699347..588bb175 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/modules/musig/example.c +++ b/secp256k1-zkp-sys/depend/secp256k1/src/modules/musig/example.c @@ -107,7 +107,7 @@ int sign(const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char seckeys[][32] for (i = 0; i < N_SIGNERS; i++) { for (j = 0; j < N_SIGNERS; j++) { /* To check whether signing was successful, it suffices to either verify - * the the combined signature with the combined public key using + * the combined signature with the combined public key using * rustsecp256k1zkp_v0_2_0_schnorrsig_verify, or verify all partial signatures of all * signers individually. Verifying the combined signature is cheaper but * verifying the individual partial signatures has the advantage that it diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/modules/musig/tests_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/modules/musig/tests_impl.h index 56c49718..7cde8f93 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/modules/musig/tests_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/modules/musig/tests_impl.h @@ -237,8 +237,10 @@ void musig_api_tests(rustsecp256k1zkp_v0_2_0_scratch_space *scratch) { * rejects n_signers that high. */ if (SIZE_MAX > UINT32_MAX) { CHECK(rustsecp256k1zkp_v0_2_0_musig_session_init(sign, &session[0], signer0, nonce_commitment[0], session_id[0], msg, &combined_pk, &pre_session, ((size_t) UINT32_MAX) + 2, 0, sk[0]) == 0); + CHECK(ecount == 11); + } else { + ecount = 11; } - CHECK(ecount == 11); CHECK(rustsecp256k1zkp_v0_2_0_musig_session_init(sign, &session[0], signer0, nonce_commitment[0], session_id[0], msg, &combined_pk, &pre_session, 2, 0, NULL) == 0); CHECK(ecount == 12); /* secret key overflows */ @@ -267,8 +269,10 @@ void musig_api_tests(rustsecp256k1zkp_v0_2_0_scratch_space *scratch) { CHECK(ecount == 6); if (SIZE_MAX > UINT32_MAX) { CHECK(rustsecp256k1zkp_v0_2_0_musig_session_init_verifier(none, &verifier_session, verifier_signer_data, msg, &combined_pk, &pre_session, ncs, ((size_t) UINT32_MAX) + 2) == 0); + CHECK(ecount == 7); + } else { + ecount = 7; } - CHECK(ecount == 7); CHECK(rustsecp256k1zkp_v0_2_0_musig_session_init_verifier(none, &verifier_session, verifier_signer_data, msg, &combined_pk, &pre_session, ncs, 2) == 1); /** Signing step 0 -- exchange nonce commitments */ diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/modules/recovery/main_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/modules/recovery/main_impl.h index e1c40b5b..38d1ab17 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/modules/recovery/main_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/modules/recovery/main_impl.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013-2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_MODULE_RECOVERY_MAIN_H #define SECP256K1_MODULE_RECOVERY_MAIN_H @@ -120,34 +120,34 @@ static int rustsecp256k1zkp_v0_2_0_ecdsa_sig_recover(const rustsecp256k1zkp_v0_2 return !rustsecp256k1zkp_v0_2_0_gej_is_infinity(&qj); } -int rustsecp256k1zkp_v0_2_0_ecdsa_sign_recoverable(const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_ecdsa_recoverable_signature *signature, const unsigned char *msg32, const unsigned char *seckey, rustsecp256k1zkp_v0_2_0_nonce_function noncefp, const void* noncedata) { +int rustsecp256k1zkp_v0_2_0_ecdsa_sign_recoverable(const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_ecdsa_recoverable_signature *signature, const unsigned char *msghash32, const unsigned char *seckey, rustsecp256k1zkp_v0_2_0_nonce_function noncefp, const void* noncedata) { rustsecp256k1zkp_v0_2_0_scalar r, s; int ret, recid; VERIFY_CHECK(ctx != NULL); ARG_CHECK(rustsecp256k1zkp_v0_2_0_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - ARG_CHECK(msg32 != NULL); + ARG_CHECK(msghash32 != NULL); ARG_CHECK(signature != NULL); ARG_CHECK(seckey != NULL); - ret = rustsecp256k1zkp_v0_2_0_ecdsa_sign_inner(ctx, &r, &s, &recid, msg32, seckey, noncefp, noncedata); + ret = rustsecp256k1zkp_v0_2_0_ecdsa_sign_inner(ctx, &r, &s, &recid, NULL, NULL, NULL, msghash32, seckey, noncefp, noncedata); rustsecp256k1zkp_v0_2_0_ecdsa_recoverable_signature_save(signature, &r, &s, recid); return ret; } -int rustsecp256k1zkp_v0_2_0_ecdsa_recover(const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_pubkey *pubkey, const rustsecp256k1zkp_v0_2_0_ecdsa_recoverable_signature *signature, const unsigned char *msg32) { +int rustsecp256k1zkp_v0_2_0_ecdsa_recover(const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_pubkey *pubkey, const rustsecp256k1zkp_v0_2_0_ecdsa_recoverable_signature *signature, const unsigned char *msghash32) { rustsecp256k1zkp_v0_2_0_ge q; rustsecp256k1zkp_v0_2_0_scalar r, s; rustsecp256k1zkp_v0_2_0_scalar m; int recid; VERIFY_CHECK(ctx != NULL); ARG_CHECK(rustsecp256k1zkp_v0_2_0_ecmult_context_is_built(&ctx->ecmult_ctx)); - ARG_CHECK(msg32 != NULL); + ARG_CHECK(msghash32 != NULL); ARG_CHECK(signature != NULL); ARG_CHECK(pubkey != NULL); rustsecp256k1zkp_v0_2_0_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, signature); VERIFY_CHECK(recid >= 0 && recid < 4); /* should have been caught in parse_compact */ - rustsecp256k1zkp_v0_2_0_scalar_set_b32(&m, msg32, NULL); + rustsecp256k1zkp_v0_2_0_scalar_set_b32(&m, msghash32, NULL); if (rustsecp256k1zkp_v0_2_0_ecdsa_sig_recover(&ctx->ecmult_ctx, &r, &s, &q, &m, recid)) { rustsecp256k1zkp_v0_2_0_pubkey_save(pubkey, &q); return 1; diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/modules/recovery/tests_exhaustive_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/modules/recovery/tests_exhaustive_impl.h index 030d2b3c..067c9bab 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/modules/recovery/tests_exhaustive_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/modules/recovery/tests_exhaustive_impl.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2016 Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2016 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_MODULE_RECOVERY_EXHAUSTIVE_TESTS_H #define SECP256K1_MODULE_RECOVERY_EXHAUSTIVE_TESTS_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/modules/recovery/tests_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/modules/recovery/tests_impl.h index 66e1eefb..295b7ae1 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/modules/recovery/tests_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/modules/recovery/tests_impl.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013-2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_MODULE_RECOVERY_TESTS_H #define SECP256K1_MODULE_RECOVERY_TESTS_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/modules/schnorrsig/main_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/modules/schnorrsig/main_impl.h index c651f67f..92676f2f 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/modules/schnorrsig/main_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/modules/schnorrsig/main_impl.h @@ -1,11 +1,11 @@ -/********************************************************************** - * Copyright (c) 2018-2020 Andrew Poelstra, Jonas Nick * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef _SECP256K1_MODULE_SCHNORRSIG_MAIN_ -#define _SECP256K1_MODULE_SCHNORRSIG_MAIN_ +/*********************************************************************** + * Copyright (c) 2018-2020 Andrew Poelstra, Jonas Nick * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_SCHNORRSIG_MAIN_H +#define SECP256K1_MODULE_SCHNORRSIG_MAIN_H #include "include/secp256k1.h" #include "include/secp256k1_schnorrsig.h" diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/modules/schnorrsig/tests_exhaustive_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/modules/schnorrsig/tests_exhaustive_impl.h index ffa46bce..42ded95b 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/modules/schnorrsig/tests_exhaustive_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/modules/schnorrsig/tests_exhaustive_impl.h @@ -1,11 +1,11 @@ -/********************************************************************** - * Copyright (c) 2020 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2020 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_MODULE_SCHNORRSIG_TESTS_EXHAUSTIVE_ -#define _SECP256K1_MODULE_SCHNORRSIG_TESTS_EXHAUSTIVE_ +#ifndef SECP256K1_MODULE_SCHNORRSIG_TESTS_EXHAUSTIVE_H +#define SECP256K1_MODULE_SCHNORRSIG_TESTS_EXHAUSTIVE_H #include "include/secp256k1_schnorrsig.h" #include "src/modules/schnorrsig/main_impl.h" diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/modules/schnorrsig/tests_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/modules/schnorrsig/tests_impl.h index 351adf1c..895cdf34 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/modules/schnorrsig/tests_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/modules/schnorrsig/tests_impl.h @@ -1,11 +1,11 @@ -/********************************************************************** - * Copyright (c) 2018-2020 Andrew Poelstra, Jonas Nick * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef _SECP256K1_MODULE_SCHNORRSIG_TESTS_ -#define _SECP256K1_MODULE_SCHNORRSIG_TESTS_ +/*********************************************************************** + * Copyright (c) 2018-2020 Andrew Poelstra, Jonas Nick * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_MODULE_SCHNORRSIG_TESTS_H +#define SECP256K1_MODULE_SCHNORRSIG_TESTS_H #include "secp256k1_schnorrsig.h" diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/modules/whitelist/Makefile.am.include b/secp256k1-zkp-sys/depend/secp256k1/src/modules/whitelist/Makefile.am.include index b28f9d50..1f7ead17 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/modules/whitelist/Makefile.am.include +++ b/secp256k1-zkp-sys/depend/secp256k1/src/modules/whitelist/Makefile.am.include @@ -5,6 +5,7 @@ noinst_HEADERS += src/modules/whitelist/tests_impl.h if USE_BENCHMARK noinst_PROGRAMS += bench_whitelist bench_whitelist_SOURCES = src/bench_whitelist.c +bench_whitelist_CPPFLAGS = -DSECP256K1_BUILD $(SECP_INCLUDES) bench_whitelist_LDADD = libsecp256k1.la $(SECP_LIBS) bench_generator_LDFLAGS = -static endif diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/num.h b/secp256k1-zkp-sys/depend/secp256k1/src/num.h index 443face4..b08c60d9 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/num.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/num.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_NUM_H #define SECP256K1_NUM_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/num_gmp.h b/secp256k1-zkp-sys/depend/secp256k1/src/num_gmp.h index f05e6c8f..ef5cefba 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/num_gmp.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/num_gmp.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_NUM_REPR_H #define SECP256K1_NUM_REPR_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/num_gmp_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/num_gmp_impl.h index e8d93f14..423d5af3 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/num_gmp_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/num_gmp_impl.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_NUM_REPR_IMPL_H #define SECP256K1_NUM_REPR_IMPL_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/num_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/num_impl.h index c45193b0..880598ef 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/num_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/num_impl.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_NUM_IMPL_H #define SECP256K1_NUM_IMPL_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/scalar.h b/secp256k1-zkp-sys/depend/secp256k1/src/scalar.h index 35da7337..a7c01209 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/scalar.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/scalar.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_SCALAR_H #define SECP256K1_SCALAR_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/scalar_4x64.h b/secp256k1-zkp-sys/depend/secp256k1/src/scalar_4x64.h index 8466998b..37e9b853 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/scalar_4x64.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/scalar_4x64.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_SCALAR_REPR_H #define SECP256K1_SCALAR_REPR_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/scalar_4x64_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/scalar_4x64_impl.h index cdb44092..77dad9bc 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/scalar_4x64_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/scalar_4x64_impl.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_SCALAR_REPR_IMPL_H #define SECP256K1_SCALAR_REPR_IMPL_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/scalar_8x32.h b/secp256k1-zkp-sys/depend/secp256k1/src/scalar_8x32.h index 66faf591..9d689946 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/scalar_8x32.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/scalar_8x32.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_SCALAR_REPR_H #define SECP256K1_SCALAR_REPR_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/scalar_8x32_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/scalar_8x32_impl.h index ca136950..48a9b005 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/scalar_8x32_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/scalar_8x32_impl.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_SCALAR_REPR_IMPL_H #define SECP256K1_SCALAR_REPR_IMPL_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/scalar_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/scalar_impl.h index 65896880..fa89612c 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/scalar_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/scalar_impl.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_SCALAR_IMPL_H #define SECP256K1_SCALAR_IMPL_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/scalar_low.h b/secp256k1-zkp-sys/depend/secp256k1/src/scalar_low.h index 30a57b52..12b8dd56 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/scalar_low.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/scalar_low.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2015 Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2015 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_SCALAR_REPR_H #define SECP256K1_SCALAR_REPR_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/scalar_low_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/scalar_low_impl.h index d7ced244..535870e1 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/scalar_low_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/scalar_low_impl.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2015 Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2015 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_SCALAR_REPR_IMPL_H #define SECP256K1_SCALAR_REPR_IMPL_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/scratch.h b/secp256k1-zkp-sys/depend/secp256k1/src/scratch.h index bc456afb..7f82353a 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/scratch.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/scratch.h @@ -1,11 +1,11 @@ -/********************************************************************** - * Copyright (c) 2017 Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ - -#ifndef _SECP256K1_SCRATCH_ -#define _SECP256K1_SCRATCH_ +/*********************************************************************** + * Copyright (c) 2017 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ + +#ifndef SECP256K1_SCRATCH_H +#define SECP256K1_SCRATCH_H /* The typedef is used internally; the struct name is used in the public API * (where it is exposed as a different typedef) */ diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/scratch_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/scratch_impl.h index 0919b780..21c84d8f 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/scratch_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/scratch_impl.h @@ -1,11 +1,11 @@ -/********************************************************************** - * Copyright (c) 2017 Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2017 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ -#ifndef _SECP256K1_SCRATCH_IMPL_H_ -#define _SECP256K1_SCRATCH_IMPL_H_ +#ifndef SECP256K1_SCRATCH_IMPL_H +#define SECP256K1_SCRATCH_IMPL_H #include "util.h" #include "scratch.h" diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/secp256k1.c b/secp256k1-zkp-sys/depend/secp256k1/src/secp256k1.c index 715e0983..f49a6c54 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/secp256k1.c +++ b/secp256k1-zkp-sys/depend/secp256k1/src/secp256k1.c @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013-2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #include "include/secp256k1.h" #include "include/secp256k1_preallocated.h" @@ -13,6 +13,7 @@ #include "field_impl.h" #include "scalar_impl.h" #include "group_impl.h" +#include "eccommit_impl.h" #include "ecmult_impl.h" #include "ecmult_const_impl.h" #include "ecmult_gen_impl.h" @@ -36,6 +37,18 @@ #include "modules/rangeproof/rangeproof.h" #endif +#ifdef ENABLE_MODULE_ECDSA_S2C +#include "include/secp256k1_ecdsa_s2c.h" +static void rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_save(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening* opening, rustsecp256k1zkp_v0_2_0_ge* ge); +#else +typedef void rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening; +static void rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_save(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening* opening, rustsecp256k1zkp_v0_2_0_ge* ge) { + (void) opening; + (void) ge; + VERIFY_CHECK(0); +} +#endif + #define ARG_CHECK(cond) do { \ if (EXPECT(!(cond), 0)) { \ rustsecp256k1zkp_v0_2_0_callback_call(&ctx->illegal_callback, #cond); \ @@ -393,17 +406,17 @@ int rustsecp256k1zkp_v0_2_0_ecdsa_signature_normalize(const rustsecp256k1zkp_v0_ return ret; } -int rustsecp256k1zkp_v0_2_0_ecdsa_verify(const rustsecp256k1zkp_v0_2_0_context* ctx, const rustsecp256k1zkp_v0_2_0_ecdsa_signature *sig, const unsigned char *msg32, const rustsecp256k1zkp_v0_2_0_pubkey *pubkey) { +int rustsecp256k1zkp_v0_2_0_ecdsa_verify(const rustsecp256k1zkp_v0_2_0_context* ctx, const rustsecp256k1zkp_v0_2_0_ecdsa_signature *sig, const unsigned char *msghash32, const rustsecp256k1zkp_v0_2_0_pubkey *pubkey) { rustsecp256k1zkp_v0_2_0_ge q; rustsecp256k1zkp_v0_2_0_scalar r, s; rustsecp256k1zkp_v0_2_0_scalar m; VERIFY_CHECK(ctx != NULL); ARG_CHECK(rustsecp256k1zkp_v0_2_0_ecmult_context_is_built(&ctx->ecmult_ctx)); - ARG_CHECK(msg32 != NULL); + ARG_CHECK(msghash32 != NULL); ARG_CHECK(sig != NULL); ARG_CHECK(pubkey != NULL); - rustsecp256k1zkp_v0_2_0_scalar_set_b32(&m, msg32, NULL); + rustsecp256k1zkp_v0_2_0_scalar_set_b32(&m, msghash32, NULL); rustsecp256k1zkp_v0_2_0_ecdsa_signature_load(ctx, &r, &s, sig); return (!rustsecp256k1zkp_v0_2_0_scalar_is_high(&s) && rustsecp256k1zkp_v0_2_0_pubkey_load(ctx, &q, pubkey) && @@ -448,7 +461,7 @@ static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *m const rustsecp256k1zkp_v0_2_0_nonce_function rustsecp256k1zkp_v0_2_0_nonce_function_rfc6979 = nonce_function_rfc6979; const rustsecp256k1zkp_v0_2_0_nonce_function rustsecp256k1zkp_v0_2_0_nonce_function_default = nonce_function_rfc6979; -static int rustsecp256k1zkp_v0_2_0_ecdsa_sign_inner(const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_scalar* r, rustsecp256k1zkp_v0_2_0_scalar* s, int* recid, const unsigned char *msg32, const unsigned char *seckey, rustsecp256k1zkp_v0_2_0_nonce_function noncefp, const void* noncedata) { +static int rustsecp256k1zkp_v0_2_0_ecdsa_sign_inner(const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_scalar* r, rustsecp256k1zkp_v0_2_0_scalar* s, int* recid, rustsecp256k1zkp_v0_2_0_sha256* s2c_sha, rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening *s2c_opening, const unsigned char* s2c_data32, const unsigned char *msg32, const unsigned char *seckey, rustsecp256k1zkp_v0_2_0_nonce_function noncefp, const void* noncedata) { rustsecp256k1zkp_v0_2_0_scalar sec, non, msg; int ret = 0; int is_sec_valid; @@ -463,6 +476,11 @@ static int rustsecp256k1zkp_v0_2_0_ecdsa_sign_inner(const rustsecp256k1zkp_v0_2_ if (noncefp == NULL) { noncefp = rustsecp256k1zkp_v0_2_0_nonce_function_default; } + /* sign-to-contract commitments only work with the default nonce function, + * because we need to ensure that s2c_data is actually hashed into the nonce and + * not just ignored. Otherwise an attacker can exfiltrate the secret key by + * signing the same message thrice with different commitments. */ + VERIFY_CHECK(s2c_data32 == NULL || noncefp == rustsecp256k1zkp_v0_2_0_nonce_function_default); /* Fail if the secret key is invalid. */ is_sec_valid = rustsecp256k1zkp_v0_2_0_scalar_set_b32_seckey(&sec, seckey); @@ -478,6 +496,30 @@ static int rustsecp256k1zkp_v0_2_0_ecdsa_sign_inner(const rustsecp256k1zkp_v0_2_ /* The nonce is still secret here, but it being invalid is is less likely than 1:2^255. */ rustsecp256k1zkp_v0_2_0_declassify(ctx, &is_nonce_valid, sizeof(is_nonce_valid)); if (is_nonce_valid) { + if (s2c_data32 != NULL) { + rustsecp256k1zkp_v0_2_0_gej nonce_pj; + rustsecp256k1zkp_v0_2_0_ge nonce_p; + + /* Compute original nonce commitment/pubkey */ + rustsecp256k1zkp_v0_2_0_ecmult_gen(&ctx->ecmult_gen_ctx, &nonce_pj, &non); + rustsecp256k1zkp_v0_2_0_ge_set_gej(&nonce_p, &nonce_pj); + if (s2c_opening != NULL) { + rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_save(s2c_opening, &nonce_p); + } + + /* Because the nonce is valid, the nonce point isn't the point + * at infinity and we can declassify that information to be able to + * serialize the point. */ + rustsecp256k1zkp_v0_2_0_declassify(ctx, &nonce_p.infinity, sizeof(nonce_p.infinity)); + + /* Tweak nonce with s2c commitment. */ + ret = rustsecp256k1zkp_v0_2_0_ec_commit_seckey(&non, &nonce_p, s2c_sha, s2c_data32, 32); + rustsecp256k1zkp_v0_2_0_declassify(ctx, &ret, sizeof(ret)); /* may be secret that the tweak falied, but happens with negligible probability */ + if (!ret) { + break; + } + } + ret = rustsecp256k1zkp_v0_2_0_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, r, s, &sec, &msg, &non, recid); /* The final signature is no longer a secret, nor is the fact that we were successful or not. */ rustsecp256k1zkp_v0_2_0_declassify(ctx, &ret, sizeof(ret)); @@ -504,16 +546,16 @@ static int rustsecp256k1zkp_v0_2_0_ecdsa_sign_inner(const rustsecp256k1zkp_v0_2_ return ret; } -int rustsecp256k1zkp_v0_2_0_ecdsa_sign(const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_ecdsa_signature *signature, const unsigned char *msg32, const unsigned char *seckey, rustsecp256k1zkp_v0_2_0_nonce_function noncefp, const void* noncedata) { +int rustsecp256k1zkp_v0_2_0_ecdsa_sign(const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_ecdsa_signature *signature, const unsigned char *msghash32, const unsigned char *seckey, rustsecp256k1zkp_v0_2_0_nonce_function noncefp, const void* noncedata) { rustsecp256k1zkp_v0_2_0_scalar r, s; int ret; VERIFY_CHECK(ctx != NULL); ARG_CHECK(rustsecp256k1zkp_v0_2_0_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - ARG_CHECK(msg32 != NULL); + ARG_CHECK(msghash32 != NULL); ARG_CHECK(signature != NULL); ARG_CHECK(seckey != NULL); - ret = rustsecp256k1zkp_v0_2_0_ecdsa_sign_inner(ctx, &r, &s, NULL, msg32, seckey, noncefp, noncedata); + ret = rustsecp256k1zkp_v0_2_0_ecdsa_sign_inner(ctx, &r, &s, NULL, NULL, NULL, NULL, msghash32, seckey, noncefp, noncedata); rustsecp256k1zkp_v0_2_0_ecdsa_signature_save(signature, &r, &s); return ret; } @@ -594,26 +636,26 @@ int rustsecp256k1zkp_v0_2_0_ec_pubkey_negate(const rustsecp256k1zkp_v0_2_0_conte } -static int rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_add_helper(rustsecp256k1zkp_v0_2_0_scalar *sec, const unsigned char *tweak) { +static int rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_add_helper(rustsecp256k1zkp_v0_2_0_scalar *sec, const unsigned char *tweak32) { rustsecp256k1zkp_v0_2_0_scalar term; int overflow = 0; int ret = 0; - rustsecp256k1zkp_v0_2_0_scalar_set_b32(&term, tweak, &overflow); + rustsecp256k1zkp_v0_2_0_scalar_set_b32(&term, tweak32, &overflow); ret = (!overflow) & rustsecp256k1zkp_v0_2_0_eckey_privkey_tweak_add(sec, &term); rustsecp256k1zkp_v0_2_0_scalar_clear(&term); return ret; } -int rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_add(const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char *seckey, const unsigned char *tweak) { +int rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_add(const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char *seckey, const unsigned char *tweak32) { rustsecp256k1zkp_v0_2_0_scalar sec; int ret = 0; VERIFY_CHECK(ctx != NULL); ARG_CHECK(seckey != NULL); - ARG_CHECK(tweak != NULL); + ARG_CHECK(tweak32 != NULL); ret = rustsecp256k1zkp_v0_2_0_scalar_set_b32_seckey(&sec, seckey); - ret &= rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_add_helper(&sec, tweak); + ret &= rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_add_helper(&sec, tweak32); rustsecp256k1zkp_v0_2_0_scalar_cmov(&sec, &rustsecp256k1zkp_v0_2_0_scalar_zero, !ret); rustsecp256k1zkp_v0_2_0_scalar_get_b32(seckey, &sec); @@ -621,28 +663,28 @@ int rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_add(const rustsecp256k1zkp_v0_2_0_co return ret; } -int rustsecp256k1zkp_v0_2_0_ec_privkey_tweak_add(const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char *seckey, const unsigned char *tweak) { - return rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_add(ctx, seckey, tweak); +int rustsecp256k1zkp_v0_2_0_ec_privkey_tweak_add(const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char *seckey, const unsigned char *tweak32) { + return rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_add(ctx, seckey, tweak32); } -static int rustsecp256k1zkp_v0_2_0_ec_pubkey_tweak_add_helper(const rustsecp256k1zkp_v0_2_0_ecmult_context* ecmult_ctx, rustsecp256k1zkp_v0_2_0_ge *p, const unsigned char *tweak) { +static int rustsecp256k1zkp_v0_2_0_ec_pubkey_tweak_add_helper(const rustsecp256k1zkp_v0_2_0_ecmult_context* ecmult_ctx, rustsecp256k1zkp_v0_2_0_ge *p, const unsigned char *tweak32) { rustsecp256k1zkp_v0_2_0_scalar term; int overflow = 0; - rustsecp256k1zkp_v0_2_0_scalar_set_b32(&term, tweak, &overflow); + rustsecp256k1zkp_v0_2_0_scalar_set_b32(&term, tweak32, &overflow); return !overflow && rustsecp256k1zkp_v0_2_0_eckey_pubkey_tweak_add(ecmult_ctx, p, &term); } -int rustsecp256k1zkp_v0_2_0_ec_pubkey_tweak_add(const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_pubkey *pubkey, const unsigned char *tweak) { +int rustsecp256k1zkp_v0_2_0_ec_pubkey_tweak_add(const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_pubkey *pubkey, const unsigned char *tweak32) { rustsecp256k1zkp_v0_2_0_ge p; int ret = 0; VERIFY_CHECK(ctx != NULL); ARG_CHECK(rustsecp256k1zkp_v0_2_0_ecmult_context_is_built(&ctx->ecmult_ctx)); ARG_CHECK(pubkey != NULL); - ARG_CHECK(tweak != NULL); + ARG_CHECK(tweak32 != NULL); ret = rustsecp256k1zkp_v0_2_0_pubkey_load(ctx, &p, pubkey); memset(pubkey, 0, sizeof(*pubkey)); - ret = ret && rustsecp256k1zkp_v0_2_0_ec_pubkey_tweak_add_helper(&ctx->ecmult_ctx, &p, tweak); + ret = ret && rustsecp256k1zkp_v0_2_0_ec_pubkey_tweak_add_helper(&ctx->ecmult_ctx, &p, tweak32); if (ret) { rustsecp256k1zkp_v0_2_0_pubkey_save(pubkey, &p); } @@ -650,16 +692,16 @@ int rustsecp256k1zkp_v0_2_0_ec_pubkey_tweak_add(const rustsecp256k1zkp_v0_2_0_co return ret; } -int rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_mul(const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char *seckey, const unsigned char *tweak) { +int rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_mul(const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char *seckey, const unsigned char *tweak32) { rustsecp256k1zkp_v0_2_0_scalar factor; rustsecp256k1zkp_v0_2_0_scalar sec; int ret = 0; int overflow = 0; VERIFY_CHECK(ctx != NULL); ARG_CHECK(seckey != NULL); - ARG_CHECK(tweak != NULL); + ARG_CHECK(tweak32 != NULL); - rustsecp256k1zkp_v0_2_0_scalar_set_b32(&factor, tweak, &overflow); + rustsecp256k1zkp_v0_2_0_scalar_set_b32(&factor, tweak32, &overflow); ret = rustsecp256k1zkp_v0_2_0_scalar_set_b32_seckey(&sec, seckey); ret &= (!overflow) & rustsecp256k1zkp_v0_2_0_eckey_privkey_tweak_mul(&sec, &factor); rustsecp256k1zkp_v0_2_0_scalar_cmov(&sec, &rustsecp256k1zkp_v0_2_0_scalar_zero, !ret); @@ -670,11 +712,11 @@ int rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_mul(const rustsecp256k1zkp_v0_2_0_co return ret; } -int rustsecp256k1zkp_v0_2_0_ec_privkey_tweak_mul(const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char *seckey, const unsigned char *tweak) { - return rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_mul(ctx, seckey, tweak); +int rustsecp256k1zkp_v0_2_0_ec_privkey_tweak_mul(const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char *seckey, const unsigned char *tweak32) { + return rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_mul(ctx, seckey, tweak32); } -int rustsecp256k1zkp_v0_2_0_ec_pubkey_tweak_mul(const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_pubkey *pubkey, const unsigned char *tweak) { +int rustsecp256k1zkp_v0_2_0_ec_pubkey_tweak_mul(const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_pubkey *pubkey, const unsigned char *tweak32) { rustsecp256k1zkp_v0_2_0_ge p; rustsecp256k1zkp_v0_2_0_scalar factor; int ret = 0; @@ -682,9 +724,9 @@ int rustsecp256k1zkp_v0_2_0_ec_pubkey_tweak_mul(const rustsecp256k1zkp_v0_2_0_co VERIFY_CHECK(ctx != NULL); ARG_CHECK(rustsecp256k1zkp_v0_2_0_ecmult_context_is_built(&ctx->ecmult_ctx)); ARG_CHECK(pubkey != NULL); - ARG_CHECK(tweak != NULL); + ARG_CHECK(tweak32 != NULL); - rustsecp256k1zkp_v0_2_0_scalar_set_b32(&factor, tweak, &overflow); + rustsecp256k1zkp_v0_2_0_scalar_set_b32(&factor, tweak32, &overflow); ret = !overflow && rustsecp256k1zkp_v0_2_0_pubkey_load(ctx, &p, pubkey); memset(pubkey, 0, sizeof(*pubkey)); if (ret) { @@ -746,6 +788,14 @@ int rustsecp256k1zkp_v0_2_0_ec_pubkey_combine(const rustsecp256k1zkp_v0_2_0_cont #include "modules/schnorrsig/main_impl.h" #endif +#ifdef ENABLE_MODULE_ECDSA_S2C +#include "modules/ecdsa_s2c/main_impl.h" +#endif + +#ifdef ENABLE_MODULE_ECDSA_ADAPTOR +#include "modules/ecdsa_adaptor/main_impl.h" +#endif + #ifdef ENABLE_MODULE_MUSIG #include "modules/musig/main_impl.h" #endif diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/secp256k1.c.orig b/secp256k1-zkp-sys/depend/secp256k1/src/secp256k1.c.orig index d8eb8838..ad22279c 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/secp256k1.c.orig +++ b/secp256k1-zkp-sys/depend/secp256k1/src/secp256k1.c.orig @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013-2015 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013-2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #include "include/secp256k1.h" #include "include/secp256k1_preallocated.h" @@ -13,6 +13,7 @@ #include "field_impl.h" #include "scalar_impl.h" #include "group_impl.h" +#include "eccommit_impl.h" #include "ecmult_impl.h" #include "ecmult_const_impl.h" #include "ecmult_gen_impl.h" @@ -36,6 +37,18 @@ #include "modules/rangeproof/rangeproof.h" #endif +#ifdef ENABLE_MODULE_ECDSA_S2C +#include "include/secp256k1_ecdsa_s2c.h" +static void rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_save(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening* opening, rustsecp256k1zkp_v0_2_0_ge* ge); +#else +typedef void rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening; +static void rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_save(rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening* opening, rustsecp256k1zkp_v0_2_0_ge* ge) { + (void) opening; + (void) ge; + VERIFY_CHECK(0); +} +#endif + #define ARG_CHECK(cond) do { \ if (EXPECT(!(cond), 0)) { \ rustsecp256k1zkp_v0_2_0_callback_call(&ctx->illegal_callback, #cond); \ @@ -432,17 +445,17 @@ int rustsecp256k1zkp_v0_2_0_ecdsa_signature_normalize(const rustsecp256k1zkp_v0_ return ret; } -int rustsecp256k1zkp_v0_2_0_ecdsa_verify(const rustsecp256k1zkp_v0_2_0_context* ctx, const rustsecp256k1zkp_v0_2_0_ecdsa_signature *sig, const unsigned char *msg32, const rustsecp256k1zkp_v0_2_0_pubkey *pubkey) { +int rustsecp256k1zkp_v0_2_0_ecdsa_verify(const rustsecp256k1zkp_v0_2_0_context* ctx, const rustsecp256k1zkp_v0_2_0_ecdsa_signature *sig, const unsigned char *msghash32, const rustsecp256k1zkp_v0_2_0_pubkey *pubkey) { rustsecp256k1zkp_v0_2_0_ge q; rustsecp256k1zkp_v0_2_0_scalar r, s; rustsecp256k1zkp_v0_2_0_scalar m; VERIFY_CHECK(ctx != NULL); ARG_CHECK(rustsecp256k1zkp_v0_2_0_ecmult_context_is_built(&ctx->ecmult_ctx)); - ARG_CHECK(msg32 != NULL); + ARG_CHECK(msghash32 != NULL); ARG_CHECK(sig != NULL); ARG_CHECK(pubkey != NULL); - rustsecp256k1zkp_v0_2_0_scalar_set_b32(&m, msg32, NULL); + rustsecp256k1zkp_v0_2_0_scalar_set_b32(&m, msghash32, NULL); rustsecp256k1zkp_v0_2_0_ecdsa_signature_load(ctx, &r, &s, sig); return (!rustsecp256k1zkp_v0_2_0_scalar_is_high(&s) && rustsecp256k1zkp_v0_2_0_pubkey_load(ctx, &q, pubkey) && @@ -487,7 +500,7 @@ static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *m const rustsecp256k1zkp_v0_2_0_nonce_function rustsecp256k1zkp_v0_2_0_nonce_function_rfc6979 = nonce_function_rfc6979; const rustsecp256k1zkp_v0_2_0_nonce_function rustsecp256k1zkp_v0_2_0_nonce_function_default = nonce_function_rfc6979; -static int rustsecp256k1zkp_v0_2_0_ecdsa_sign_inner(const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_scalar* r, rustsecp256k1zkp_v0_2_0_scalar* s, int* recid, const unsigned char *msg32, const unsigned char *seckey, rustsecp256k1zkp_v0_2_0_nonce_function noncefp, const void* noncedata) { +static int rustsecp256k1zkp_v0_2_0_ecdsa_sign_inner(const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_scalar* r, rustsecp256k1zkp_v0_2_0_scalar* s, int* recid, rustsecp256k1zkp_v0_2_0_sha256* s2c_sha, rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening *s2c_opening, const unsigned char* s2c_data32, const unsigned char *msg32, const unsigned char *seckey, rustsecp256k1zkp_v0_2_0_nonce_function noncefp, const void* noncedata) { rustsecp256k1zkp_v0_2_0_scalar sec, non, msg; int ret = 0; int is_sec_valid; @@ -502,6 +515,11 @@ static int rustsecp256k1zkp_v0_2_0_ecdsa_sign_inner(const rustsecp256k1zkp_v0_2_ if (noncefp == NULL) { noncefp = rustsecp256k1zkp_v0_2_0_nonce_function_default; } + /* sign-to-contract commitments only work with the default nonce function, + * because we need to ensure that s2c_data is actually hashed into the nonce and + * not just ignored. Otherwise an attacker can exfiltrate the secret key by + * signing the same message thrice with different commitments. */ + VERIFY_CHECK(s2c_data32 == NULL || noncefp == rustsecp256k1zkp_v0_2_0_nonce_function_default); /* Fail if the secret key is invalid. */ is_sec_valid = rustsecp256k1zkp_v0_2_0_scalar_set_b32_seckey(&sec, seckey); @@ -517,6 +535,30 @@ static int rustsecp256k1zkp_v0_2_0_ecdsa_sign_inner(const rustsecp256k1zkp_v0_2_ /* The nonce is still secret here, but it being invalid is is less likely than 1:2^255. */ rustsecp256k1zkp_v0_2_0_declassify(ctx, &is_nonce_valid, sizeof(is_nonce_valid)); if (is_nonce_valid) { + if (s2c_data32 != NULL) { + rustsecp256k1zkp_v0_2_0_gej nonce_pj; + rustsecp256k1zkp_v0_2_0_ge nonce_p; + + /* Compute original nonce commitment/pubkey */ + rustsecp256k1zkp_v0_2_0_ecmult_gen(&ctx->ecmult_gen_ctx, &nonce_pj, &non); + rustsecp256k1zkp_v0_2_0_ge_set_gej(&nonce_p, &nonce_pj); + if (s2c_opening != NULL) { + rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening_save(s2c_opening, &nonce_p); + } + + /* Because the nonce is valid, the nonce point isn't the point + * at infinity and we can declassify that information to be able to + * serialize the point. */ + rustsecp256k1zkp_v0_2_0_declassify(ctx, &nonce_p.infinity, sizeof(nonce_p.infinity)); + + /* Tweak nonce with s2c commitment. */ + ret = rustsecp256k1zkp_v0_2_0_ec_commit_seckey(&non, &nonce_p, s2c_sha, s2c_data32, 32); + rustsecp256k1zkp_v0_2_0_declassify(ctx, &ret, sizeof(ret)); /* may be secret that the tweak falied, but happens with negligible probability */ + if (!ret) { + break; + } + } + ret = rustsecp256k1zkp_v0_2_0_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, r, s, &sec, &msg, &non, recid); /* The final signature is no longer a secret, nor is the fact that we were successful or not. */ rustsecp256k1zkp_v0_2_0_declassify(ctx, &ret, sizeof(ret)); @@ -543,16 +585,16 @@ static int rustsecp256k1zkp_v0_2_0_ecdsa_sign_inner(const rustsecp256k1zkp_v0_2_ return ret; } -int rustsecp256k1zkp_v0_2_0_ecdsa_sign(const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_ecdsa_signature *signature, const unsigned char *msg32, const unsigned char *seckey, rustsecp256k1zkp_v0_2_0_nonce_function noncefp, const void* noncedata) { +int rustsecp256k1zkp_v0_2_0_ecdsa_sign(const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_ecdsa_signature *signature, const unsigned char *msghash32, const unsigned char *seckey, rustsecp256k1zkp_v0_2_0_nonce_function noncefp, const void* noncedata) { rustsecp256k1zkp_v0_2_0_scalar r, s; int ret; VERIFY_CHECK(ctx != NULL); ARG_CHECK(rustsecp256k1zkp_v0_2_0_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - ARG_CHECK(msg32 != NULL); + ARG_CHECK(msghash32 != NULL); ARG_CHECK(signature != NULL); ARG_CHECK(seckey != NULL); - ret = rustsecp256k1zkp_v0_2_0_ecdsa_sign_inner(ctx, &r, &s, NULL, msg32, seckey, noncefp, noncedata); + ret = rustsecp256k1zkp_v0_2_0_ecdsa_sign_inner(ctx, &r, &s, NULL, NULL, NULL, NULL, msghash32, seckey, noncefp, noncedata); rustsecp256k1zkp_v0_2_0_ecdsa_signature_save(signature, &r, &s); return ret; } @@ -633,26 +675,26 @@ int rustsecp256k1zkp_v0_2_0_ec_pubkey_negate(const rustsecp256k1zkp_v0_2_0_conte } -static int rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_add_helper(rustsecp256k1zkp_v0_2_0_scalar *sec, const unsigned char *tweak) { +static int rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_add_helper(rustsecp256k1zkp_v0_2_0_scalar *sec, const unsigned char *tweak32) { rustsecp256k1zkp_v0_2_0_scalar term; int overflow = 0; int ret = 0; - rustsecp256k1zkp_v0_2_0_scalar_set_b32(&term, tweak, &overflow); + rustsecp256k1zkp_v0_2_0_scalar_set_b32(&term, tweak32, &overflow); ret = (!overflow) & rustsecp256k1zkp_v0_2_0_eckey_privkey_tweak_add(sec, &term); rustsecp256k1zkp_v0_2_0_scalar_clear(&term); return ret; } -int rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_add(const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char *seckey, const unsigned char *tweak) { +int rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_add(const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char *seckey, const unsigned char *tweak32) { rustsecp256k1zkp_v0_2_0_scalar sec; int ret = 0; VERIFY_CHECK(ctx != NULL); ARG_CHECK(seckey != NULL); - ARG_CHECK(tweak != NULL); + ARG_CHECK(tweak32 != NULL); ret = rustsecp256k1zkp_v0_2_0_scalar_set_b32_seckey(&sec, seckey); - ret &= rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_add_helper(&sec, tweak); + ret &= rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_add_helper(&sec, tweak32); rustsecp256k1zkp_v0_2_0_scalar_cmov(&sec, &rustsecp256k1zkp_v0_2_0_scalar_zero, !ret); rustsecp256k1zkp_v0_2_0_scalar_get_b32(seckey, &sec); @@ -660,28 +702,28 @@ int rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_add(const rustsecp256k1zkp_v0_2_0_co return ret; } -int rustsecp256k1zkp_v0_2_0_ec_privkey_tweak_add(const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char *seckey, const unsigned char *tweak) { - return rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_add(ctx, seckey, tweak); +int rustsecp256k1zkp_v0_2_0_ec_privkey_tweak_add(const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char *seckey, const unsigned char *tweak32) { + return rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_add(ctx, seckey, tweak32); } -static int rustsecp256k1zkp_v0_2_0_ec_pubkey_tweak_add_helper(const rustsecp256k1zkp_v0_2_0_ecmult_context* ecmult_ctx, rustsecp256k1zkp_v0_2_0_ge *p, const unsigned char *tweak) { +static int rustsecp256k1zkp_v0_2_0_ec_pubkey_tweak_add_helper(const rustsecp256k1zkp_v0_2_0_ecmult_context* ecmult_ctx, rustsecp256k1zkp_v0_2_0_ge *p, const unsigned char *tweak32) { rustsecp256k1zkp_v0_2_0_scalar term; int overflow = 0; - rustsecp256k1zkp_v0_2_0_scalar_set_b32(&term, tweak, &overflow); + rustsecp256k1zkp_v0_2_0_scalar_set_b32(&term, tweak32, &overflow); return !overflow && rustsecp256k1zkp_v0_2_0_eckey_pubkey_tweak_add(ecmult_ctx, p, &term); } -int rustsecp256k1zkp_v0_2_0_ec_pubkey_tweak_add(const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_pubkey *pubkey, const unsigned char *tweak) { +int rustsecp256k1zkp_v0_2_0_ec_pubkey_tweak_add(const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_pubkey *pubkey, const unsigned char *tweak32) { rustsecp256k1zkp_v0_2_0_ge p; int ret = 0; VERIFY_CHECK(ctx != NULL); ARG_CHECK(rustsecp256k1zkp_v0_2_0_ecmult_context_is_built(&ctx->ecmult_ctx)); ARG_CHECK(pubkey != NULL); - ARG_CHECK(tweak != NULL); + ARG_CHECK(tweak32 != NULL); ret = rustsecp256k1zkp_v0_2_0_pubkey_load(ctx, &p, pubkey); memset(pubkey, 0, sizeof(*pubkey)); - ret = ret && rustsecp256k1zkp_v0_2_0_ec_pubkey_tweak_add_helper(&ctx->ecmult_ctx, &p, tweak); + ret = ret && rustsecp256k1zkp_v0_2_0_ec_pubkey_tweak_add_helper(&ctx->ecmult_ctx, &p, tweak32); if (ret) { rustsecp256k1zkp_v0_2_0_pubkey_save(pubkey, &p); } @@ -689,16 +731,16 @@ int rustsecp256k1zkp_v0_2_0_ec_pubkey_tweak_add(const rustsecp256k1zkp_v0_2_0_co return ret; } -int rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_mul(const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char *seckey, const unsigned char *tweak) { +int rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_mul(const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char *seckey, const unsigned char *tweak32) { rustsecp256k1zkp_v0_2_0_scalar factor; rustsecp256k1zkp_v0_2_0_scalar sec; int ret = 0; int overflow = 0; VERIFY_CHECK(ctx != NULL); ARG_CHECK(seckey != NULL); - ARG_CHECK(tweak != NULL); + ARG_CHECK(tweak32 != NULL); - rustsecp256k1zkp_v0_2_0_scalar_set_b32(&factor, tweak, &overflow); + rustsecp256k1zkp_v0_2_0_scalar_set_b32(&factor, tweak32, &overflow); ret = rustsecp256k1zkp_v0_2_0_scalar_set_b32_seckey(&sec, seckey); ret &= (!overflow) & rustsecp256k1zkp_v0_2_0_eckey_privkey_tweak_mul(&sec, &factor); rustsecp256k1zkp_v0_2_0_scalar_cmov(&sec, &rustsecp256k1zkp_v0_2_0_scalar_zero, !ret); @@ -709,11 +751,11 @@ int rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_mul(const rustsecp256k1zkp_v0_2_0_co return ret; } -int rustsecp256k1zkp_v0_2_0_ec_privkey_tweak_mul(const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char *seckey, const unsigned char *tweak) { - return rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_mul(ctx, seckey, tweak); +int rustsecp256k1zkp_v0_2_0_ec_privkey_tweak_mul(const rustsecp256k1zkp_v0_2_0_context* ctx, unsigned char *seckey, const unsigned char *tweak32) { + return rustsecp256k1zkp_v0_2_0_ec_seckey_tweak_mul(ctx, seckey, tweak32); } -int rustsecp256k1zkp_v0_2_0_ec_pubkey_tweak_mul(const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_pubkey *pubkey, const unsigned char *tweak) { +int rustsecp256k1zkp_v0_2_0_ec_pubkey_tweak_mul(const rustsecp256k1zkp_v0_2_0_context* ctx, rustsecp256k1zkp_v0_2_0_pubkey *pubkey, const unsigned char *tweak32) { rustsecp256k1zkp_v0_2_0_ge p; rustsecp256k1zkp_v0_2_0_scalar factor; int ret = 0; @@ -721,9 +763,9 @@ int rustsecp256k1zkp_v0_2_0_ec_pubkey_tweak_mul(const rustsecp256k1zkp_v0_2_0_co VERIFY_CHECK(ctx != NULL); ARG_CHECK(rustsecp256k1zkp_v0_2_0_ecmult_context_is_built(&ctx->ecmult_ctx)); ARG_CHECK(pubkey != NULL); - ARG_CHECK(tweak != NULL); + ARG_CHECK(tweak32 != NULL); - rustsecp256k1zkp_v0_2_0_scalar_set_b32(&factor, tweak, &overflow); + rustsecp256k1zkp_v0_2_0_scalar_set_b32(&factor, tweak32, &overflow); ret = !overflow && rustsecp256k1zkp_v0_2_0_pubkey_load(ctx, &p, pubkey); memset(pubkey, 0, sizeof(*pubkey)); if (ret) { @@ -785,6 +827,14 @@ int rustsecp256k1zkp_v0_2_0_ec_pubkey_combine(const rustsecp256k1zkp_v0_2_0_cont #include "modules/schnorrsig/main_impl.h" #endif +#ifdef ENABLE_MODULE_ECDSA_S2C +#include "modules/ecdsa_s2c/main_impl.h" +#endif + +#ifdef ENABLE_MODULE_ECDSA_ADAPTOR +#include "modules/ecdsa_adaptor/main_impl.h" +#endif + #ifdef ENABLE_MODULE_MUSIG #include "modules/musig/main_impl.h" #endif diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/selftest.h b/secp256k1-zkp-sys/depend/secp256k1/src/selftest.h index 19739d88..fb0717d1 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/selftest.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/selftest.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2020 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2020 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_SELFTEST_H #define SECP256K1_SELFTEST_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/testrand.h b/secp256k1-zkp-sys/depend/secp256k1/src/testrand.h index 2655eef9..b28a4d66 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/testrand.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/testrand.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_TESTRAND_H #define SECP256K1_TESTRAND_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/testrand_impl.h b/secp256k1-zkp-sys/depend/secp256k1/src/testrand_impl.h index b09744cc..d8348bc5 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/testrand_impl.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/testrand_impl.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013-2015 Pieter Wuille, Gregory Maxwell * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013-2015 Pieter Wuille, Gregory Maxwell * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_TESTRAND_IMPL_H #define SECP256K1_TESTRAND_IMPL_H diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/tests.c b/secp256k1-zkp-sys/depend/secp256k1/src/tests.c index 1ab6ff61..808f792a 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/tests.c +++ b/secp256k1-zkp-sys/depend/secp256k1/src/tests.c @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013-2015 Pieter Wuille, Gregory Maxwell * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013-2015 Pieter Wuille, Gregory Maxwell * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #if defined HAVE_CONFIG_H #include "libsecp256k1-config.h" @@ -2120,28 +2120,6 @@ void run_field_inv_var(void) { } } -void run_field_inv_all_var(void) { - rustsecp256k1zkp_v0_2_0_fe x[16], xi[16], xii[16]; - int i; - /* Check it's safe to call for 0 elements */ - rustsecp256k1zkp_v0_2_0_fe_inv_all_var(xi, x, 0); - for (i = 0; i < count; i++) { - size_t j; - size_t len = rustsecp256k1zkp_v0_2_0_testrand_int(15) + 1; - for (j = 0; j < len; j++) { - random_fe_non_zero(&x[j]); - } - rustsecp256k1zkp_v0_2_0_fe_inv_all_var(xi, x, len); - for (j = 0; j < len; j++) { - CHECK(check_fe_inverse(&x[j], &xi[j])); - } - rustsecp256k1zkp_v0_2_0_fe_inv_all_var(xii, xi, len); - for (j = 0; j < len; j++) { - CHECK(check_fe_equal(&x[j], &xii[j])); - } - } -} - void run_sqr(void) { rustsecp256k1zkp_v0_2_0_fe x, s; @@ -2267,7 +2245,6 @@ void test_ge(void) { */ rustsecp256k1zkp_v0_2_0_ge *ge = (rustsecp256k1zkp_v0_2_0_ge *)checked_malloc(&ctx->error_callback, sizeof(rustsecp256k1zkp_v0_2_0_ge) * (1 + 4 * runs)); rustsecp256k1zkp_v0_2_0_gej *gej = (rustsecp256k1zkp_v0_2_0_gej *)checked_malloc(&ctx->error_callback, sizeof(rustsecp256k1zkp_v0_2_0_gej) * (1 + 4 * runs)); - rustsecp256k1zkp_v0_2_0_fe *zinv = (rustsecp256k1zkp_v0_2_0_fe *)checked_malloc(&ctx->error_callback, sizeof(rustsecp256k1zkp_v0_2_0_fe) * (1 + 4 * runs)); rustsecp256k1zkp_v0_2_0_fe zf; rustsecp256k1zkp_v0_2_0_fe zfi2, zfi3; @@ -2301,23 +2278,6 @@ void test_ge(void) { } } - /* Compute z inverses. */ - { - rustsecp256k1zkp_v0_2_0_fe *zs = checked_malloc(&ctx->error_callback, sizeof(rustsecp256k1zkp_v0_2_0_fe) * (1 + 4 * runs)); - for (i = 0; i < 4 * runs + 1; i++) { - if (i == 0) { - /* The point at infinity does not have a meaningful z inverse. Any should do. */ - do { - random_field_element_test(&zs[i]); - } while(rustsecp256k1zkp_v0_2_0_fe_is_zero(&zs[i])); - } else { - zs[i] = gej[i].z; - } - } - rustsecp256k1zkp_v0_2_0_fe_inv_all_var(zinv, zs, 4 * runs + 1); - free(zs); - } - /* Generate random zf, and zfi2 = 1/zf^2, zfi3 = 1/zf^3 */ do { random_field_element_test(&zf); @@ -2426,16 +2386,9 @@ void test_ge(void) { free(gej_shuffled); } - /* Test batch gej -> ge conversion with and without known z ratios. */ + /* Test batch gej -> ge conversion without known z ratios. */ { - rustsecp256k1zkp_v0_2_0_fe *zr = (rustsecp256k1zkp_v0_2_0_fe *)checked_malloc(&ctx->error_callback, (4 * runs + 1) * sizeof(rustsecp256k1zkp_v0_2_0_fe)); rustsecp256k1zkp_v0_2_0_ge *ge_set_all = (rustsecp256k1zkp_v0_2_0_ge *)checked_malloc(&ctx->error_callback, (4 * runs + 1) * sizeof(rustsecp256k1zkp_v0_2_0_ge)); - for (i = 0; i < 4 * runs + 1; i++) { - /* Compute gej[i + 1].z / gez[i].z (with gej[n].z taken to be 1). */ - if (i < 4 * runs) { - rustsecp256k1zkp_v0_2_0_fe_mul(&zr[i + 1], &zinv[i], &gej[i + 1].z); - } - } rustsecp256k1zkp_v0_2_0_ge_set_all_gej_var(ge_set_all, gej, 4 * runs + 1); for (i = 0; i < 4 * runs + 1; i++) { rustsecp256k1zkp_v0_2_0_fe s; @@ -2444,7 +2397,6 @@ void test_ge(void) { ge_equals_gej(&ge_set_all[i], &gej[i]); } free(ge_set_all); - free(zr); } /* Test batch gej -> ge conversion with many infinities. */ @@ -2465,7 +2417,6 @@ void test_ge(void) { free(ge); free(gej); - free(zinv); } @@ -2609,6 +2560,83 @@ void run_ec_combine(void) { } } +void test_ec_commit(void) { + rustsecp256k1zkp_v0_2_0_scalar seckey_s; + rustsecp256k1zkp_v0_2_0_ge pubkey; + rustsecp256k1zkp_v0_2_0_gej pubkeyj; + rustsecp256k1zkp_v0_2_0_ge commitment; + unsigned char data[32]; + rustsecp256k1zkp_v0_2_0_sha256 sha; + + /* Create random keypair and data */ + random_scalar_order_test(&seckey_s); + rustsecp256k1zkp_v0_2_0_ecmult_gen(&ctx->ecmult_gen_ctx, &pubkeyj, &seckey_s); + rustsecp256k1zkp_v0_2_0_ge_set_gej(&pubkey, &pubkeyj); + rustsecp256k1zkp_v0_2_0_testrand256_test(data); + + /* Commit to data and verify */ + rustsecp256k1zkp_v0_2_0_sha256_initialize(&sha); + CHECK(rustsecp256k1zkp_v0_2_0_ec_commit(&ctx->ecmult_ctx, &commitment, &pubkey, &sha, data, 32) == 1); + rustsecp256k1zkp_v0_2_0_sha256_initialize(&sha); + CHECK(rustsecp256k1zkp_v0_2_0_ec_commit_verify(&ctx->ecmult_ctx, &commitment, &pubkey, &sha, data, 32) == 1); + rustsecp256k1zkp_v0_2_0_sha256_initialize(&sha); + CHECK(rustsecp256k1zkp_v0_2_0_ec_commit_seckey(&seckey_s, &pubkey, &sha, data, 32) == 1); + rustsecp256k1zkp_v0_2_0_ecmult_gen(&ctx->ecmult_gen_ctx, &pubkeyj, &seckey_s); + ge_equals_gej(&commitment, &pubkeyj); + + /* Check that verification fails with different data */ + rustsecp256k1zkp_v0_2_0_sha256_initialize(&sha); + CHECK(rustsecp256k1zkp_v0_2_0_ec_commit_verify(&ctx->ecmult_ctx, &commitment, &pubkey, &sha, data, 31) == 0); + + /* Check that commmitting fails when the inner pubkey is the point at + * infinity */ + rustsecp256k1zkp_v0_2_0_sha256_initialize(&sha); + rustsecp256k1zkp_v0_2_0_ge_set_infinity(&pubkey); + CHECK(rustsecp256k1zkp_v0_2_0_ec_commit(&ctx->ecmult_ctx, &commitment, &pubkey, &sha, data, 32) == 0); + rustsecp256k1zkp_v0_2_0_scalar_set_int(&seckey_s, 0); + CHECK(rustsecp256k1zkp_v0_2_0_ec_commit_seckey(&seckey_s, &pubkey, &sha, data, 32) == 0); + CHECK(rustsecp256k1zkp_v0_2_0_ec_commit_verify(&ctx->ecmult_ctx, &commitment, &pubkey, &sha, data, 32) == 0); +} + +void test_ec_commit_api(void) { + unsigned char seckey[32]; + rustsecp256k1zkp_v0_2_0_scalar seckey_s; + rustsecp256k1zkp_v0_2_0_ge pubkey; + rustsecp256k1zkp_v0_2_0_gej pubkeyj; + rustsecp256k1zkp_v0_2_0_ge commitment; + unsigned char data[32]; + rustsecp256k1zkp_v0_2_0_sha256 sha; + + memset(data, 23, sizeof(data)); + + /* Create random keypair */ + random_scalar_order_test(&seckey_s); + rustsecp256k1zkp_v0_2_0_scalar_get_b32(seckey, &seckey_s); + rustsecp256k1zkp_v0_2_0_ecmult_gen(&ctx->ecmult_gen_ctx, &pubkeyj, &seckey_s); + rustsecp256k1zkp_v0_2_0_ge_set_gej(&pubkey, &pubkeyj); + + rustsecp256k1zkp_v0_2_0_sha256_initialize(&sha); + CHECK(rustsecp256k1zkp_v0_2_0_ec_commit(&ctx->ecmult_ctx, &commitment, &pubkey, &sha, data, 1) == 1); + /* The same pubkey can be both input and output of the function */ + { + rustsecp256k1zkp_v0_2_0_ge pubkey_tmp = pubkey; + rustsecp256k1zkp_v0_2_0_sha256_initialize(&sha); + CHECK(rustsecp256k1zkp_v0_2_0_ec_commit(&ctx->ecmult_ctx, &pubkey_tmp, &pubkey_tmp, &sha, data, 1) == 1); + ge_equals_ge(&commitment, &pubkey_tmp); + } + + rustsecp256k1zkp_v0_2_0_sha256_initialize(&sha); + CHECK(rustsecp256k1zkp_v0_2_0_ec_commit_verify(&ctx->ecmult_ctx, &commitment, &pubkey, &sha, data, 1) == 1); +} + +void run_ec_commit(void) { + int i; + for (i = 0; i < count * 8; i++) { + test_ec_commit(); + } + test_ec_commit_api(); +} + void test_group_decompress(const rustsecp256k1zkp_v0_2_0_fe* x) { /* The input itself, normalized. */ rustsecp256k1zkp_v0_2_0_fe fex = *x; @@ -5620,6 +5648,14 @@ void run_ecdsa_openssl(void) { #include "modules/schnorrsig/tests_impl.h" #endif +#ifdef ENABLE_MODULE_ECDSA_S2C +#include "modules/ecdsa_s2c/tests_impl.h" +#endif + +#ifdef ENABLE_MODULE_ECDSA_ADAPTOR +#include "modules/ecdsa_adaptor/tests_impl.h" +#endif + void run_rustsecp256k1zkp_v0_2_0_memczero_test(void) { unsigned char buf1[6] = {1, 2, 3, 4, 5, 6}; unsigned char buf2[sizeof(buf1)]; @@ -5847,7 +5883,6 @@ int main(int argc, char **argv) { /* field tests */ run_field_inv(); run_field_inv_var(); - run_field_inv_all_var(); run_field_misc(); run_field_convert(); run_sqr(); @@ -5867,6 +5902,7 @@ int main(int argc, char **argv) { run_ecmult_const_tests(); run_ecmult_multi_tests(); run_ec_combine(); + run_ec_commit(); /* endomorphism tests */ run_endomorphism_tests(); @@ -5929,6 +5965,15 @@ int main(int argc, char **argv) { run_schnorrsig_tests(); #endif +#ifdef ENABLE_MODULE_ECDSA_S2C + /* ECDSA sign to contract */ + run_ecdsa_s2c_tests(); +#endif + +#ifdef ENABLE_MODULE_ECDSA_ADAPTOR + run_ecdsa_adaptor_tests(); +#endif + /* util tests */ run_rustsecp256k1zkp_v0_2_0_memczero_test(); diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/tests_exhaustive.c b/secp256k1-zkp-sys/depend/secp256k1/src/tests_exhaustive.c index f6f0c5a1..9292ab0f 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/tests_exhaustive.c +++ b/secp256k1-zkp-sys/depend/secp256k1/src/tests_exhaustive.c @@ -1,8 +1,8 @@ /*********************************************************************** - * Copyright (c) 2016 Andrew Poelstra * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ + * Copyright (c) 2016 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #if defined HAVE_CONFIG_H #include "libsecp256k1-config.h" diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/util.h b/secp256k1-zkp-sys/depend/secp256k1/src/util.h index caa437bc..dd6dff5a 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/util.h +++ b/secp256k1-zkp-sys/depend/secp256k1/src/util.h @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013-2015 Pieter Wuille, Gregory Maxwell * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013-2015 Pieter Wuille, Gregory Maxwell * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_UTIL_H #define SECP256K1_UTIL_H @@ -97,7 +97,7 @@ static SECP256K1_INLINE void rustsecp256k1zkp_v0_2_0_callback_call(const rustsec #define ALIGNMENT 16 #endif -#define ROUND_TO_ALIGN(size) (((size + ALIGNMENT - 1) / ALIGNMENT) * ALIGNMENT) +#define ROUND_TO_ALIGN(size) ((((size) + ALIGNMENT - 1) / ALIGNMENT) * ALIGNMENT) /* Assume there is a contiguous memory object with bounds [base, base + max_size) * of which the memory range [base, *prealloc_ptr) is already allocated for usage, @@ -125,7 +125,7 @@ static SECP256K1_INLINE void *manual_alloc(void** prealloc_ptr, size_t alloc_siz VERIFY_CHECK(((unsigned char*)*prealloc_ptr - (unsigned char*)base) % ALIGNMENT == 0); VERIFY_CHECK((unsigned char*)*prealloc_ptr - (unsigned char*)base + aligned_alloc_size <= max_size); ret = *prealloc_ptr; - *((unsigned char**)prealloc_ptr) += aligned_alloc_size; + *prealloc_ptr = (unsigned char*)*prealloc_ptr + aligned_alloc_size; return ret; } diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/util.h.orig b/secp256k1-zkp-sys/depend/secp256k1/src/util.h.orig index 5b447617..cfe55008 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/util.h.orig +++ b/secp256k1-zkp-sys/depend/secp256k1/src/util.h.orig @@ -1,8 +1,8 @@ -/********************************************************************** - * Copyright (c) 2013-2015 Pieter Wuille, Gregory Maxwell * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2013-2015 Pieter Wuille, Gregory Maxwell * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #ifndef SECP256K1_UTIL_H #define SECP256K1_UTIL_H @@ -113,7 +113,7 @@ static SECP256K1_INLINE void *checked_realloc(const rustsecp256k1zkp_v0_2_0_call #define ALIGNMENT 16 #endif -#define ROUND_TO_ALIGN(size) (((size + ALIGNMENT - 1) / ALIGNMENT) * ALIGNMENT) +#define ROUND_TO_ALIGN(size) ((((size) + ALIGNMENT - 1) / ALIGNMENT) * ALIGNMENT) /* Assume there is a contiguous memory object with bounds [base, base + max_size) * of which the memory range [base, *prealloc_ptr) is already allocated for usage, @@ -141,7 +141,7 @@ static SECP256K1_INLINE void *manual_alloc(void** prealloc_ptr, size_t alloc_siz VERIFY_CHECK(((unsigned char*)*prealloc_ptr - (unsigned char*)base) % ALIGNMENT == 0); VERIFY_CHECK((unsigned char*)*prealloc_ptr - (unsigned char*)base + aligned_alloc_size <= max_size); ret = *prealloc_ptr; - *((unsigned char**)prealloc_ptr) += aligned_alloc_size; + *prealloc_ptr = (unsigned char*)*prealloc_ptr + aligned_alloc_size; return ret; } diff --git a/secp256k1-zkp-sys/depend/secp256k1/src/valgrind_ctime_test.c b/secp256k1-zkp-sys/depend/secp256k1/src/valgrind_ctime_test.c index 2567d1eb..4c04b3c6 100644 --- a/secp256k1-zkp-sys/depend/secp256k1/src/valgrind_ctime_test.c +++ b/secp256k1-zkp-sys/depend/secp256k1/src/valgrind_ctime_test.c @@ -1,10 +1,12 @@ -/********************************************************************** - * Copyright (c) 2020 Gregory Maxwell * - * Distributed under the MIT software license, see the accompanying * - * file COPYING or http://www.opensource.org/licenses/mit-license.php.* - **********************************************************************/ +/*********************************************************************** + * Copyright (c) 2020 Gregory Maxwell * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or https://www.opensource.org/licenses/mit-license.php.* + ***********************************************************************/ #include +#include + #include "include/secp256k1.h" #include "assumptions.h" #include "util.h" @@ -25,8 +27,50 @@ #include "include/secp256k1_schnorrsig.h" #endif +#ifdef ENABLE_MODULE_ECDSA_S2C +#include "include/secp256k1_ecdsa_s2c.h" +#endif + +#ifdef ENABLE_MODULE_ECDSA_ADAPTOR +#include "include/secp256k1_ecdsa_adaptor.h" +#endif + +void run_tests(rustsecp256k1zkp_v0_2_0_context *ctx, unsigned char *key); + int main(void) { rustsecp256k1zkp_v0_2_0_context* ctx; + unsigned char key[32]; + int ret, i; + + if (!RUNNING_ON_VALGRIND) { + fprintf(stderr, "This test can only usefully be run inside valgrind.\n"); + fprintf(stderr, "Usage: libtool --mode=execute valgrind ./valgrind_ctime_test\n"); + return 1; + } + ctx = rustsecp256k1zkp_v0_2_0_context_create(SECP256K1_CONTEXT_SIGN + | SECP256K1_CONTEXT_VERIFY + | SECP256K1_CONTEXT_DECLASSIFY); + /** In theory, testing with a single secret input should be sufficient: + * If control flow depended on secrets the tool would generate an error. + */ + for (i = 0; i < 32; i++) { + key[i] = i + 65; + } + + run_tests(ctx, key); + + /* Test context randomisation. Do this last because it leaves the context + * tainted. */ + VALGRIND_MAKE_MEM_UNDEFINED(key, 32); + ret = rustsecp256k1zkp_v0_2_0_context_randomize(ctx, key); + VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret)); + CHECK(ret); + + rustsecp256k1zkp_v0_2_0_context_destroy(ctx); + return 0; +} + +void run_tests(rustsecp256k1zkp_v0_2_0_context *ctx, unsigned char *key) { rustsecp256k1zkp_v0_2_0_ecdsa_signature signature; rustsecp256k1zkp_v0_2_0_pubkey pubkey; size_t siglen = 74; @@ -34,7 +78,6 @@ int main(void) { int i; int ret; unsigned char msg[32]; - unsigned char key[32]; unsigned char sig[74]; unsigned char spubkey[33]; #ifdef ENABLE_MODULE_RECOVERY @@ -45,26 +88,10 @@ int main(void) { rustsecp256k1zkp_v0_2_0_keypair keypair; #endif - if (!RUNNING_ON_VALGRIND) { - fprintf(stderr, "This test can only usefully be run inside valgrind.\n"); - fprintf(stderr, "Usage: libtool --mode=execute valgrind ./valgrind_ctime_test\n"); - exit(1); - } - - /** In theory, testing with a single secret input should be sufficient: - * If control flow depended on secrets the tool would generate an error. - */ - for (i = 0; i < 32; i++) { - key[i] = i + 65; - } for (i = 0; i < 32; i++) { msg[i] = i + 1; } - ctx = rustsecp256k1zkp_v0_2_0_context_create(SECP256K1_CONTEXT_SIGN - | SECP256K1_CONTEXT_VERIFY - | SECP256K1_CONTEXT_DECLASSIFY); - /* Test keygen. */ VALGRIND_MAKE_MEM_UNDEFINED(key, 32); ret = rustsecp256k1zkp_v0_2_0_ec_pubkey_create(ctx, &pubkey, key); @@ -122,12 +149,6 @@ int main(void) { VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret)); CHECK(ret == 1); - /* Test context randomisation. Do this last because it leaves the context tainted. */ - VALGRIND_MAKE_MEM_UNDEFINED(key, 32); - ret = rustsecp256k1zkp_v0_2_0_context_randomize(ctx, key); - VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret)); - CHECK(ret); - /* Test keypair_create and keypair_xonly_tweak_add. */ #ifdef ENABLE_MODULE_EXTRAKEYS VALGRIND_MAKE_MEM_UNDEFINED(key, 32); @@ -140,6 +161,12 @@ int main(void) { ret = rustsecp256k1zkp_v0_2_0_keypair_xonly_tweak_add(ctx, &keypair, msg); VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret)); CHECK(ret == 1); + + VALGRIND_MAKE_MEM_UNDEFINED(key, 32); + VALGRIND_MAKE_MEM_UNDEFINED(&keypair, sizeof(keypair)); + ret = rustsecp256k1zkp_v0_2_0_keypair_sec(ctx, key, &keypair); + VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret)); + CHECK(ret == 1); #endif #ifdef ENABLE_MODULE_SCHNORRSIG @@ -152,6 +179,66 @@ int main(void) { CHECK(ret == 1); #endif - rustsecp256k1zkp_v0_2_0_context_destroy(ctx); - return 0; +#ifdef ENABLE_MODULE_ECDSA_S2C + { + unsigned char s2c_data[32] = {0}; + unsigned char s2c_data_comm[32] = {0}; + rustsecp256k1zkp_v0_2_0_ecdsa_s2c_opening s2c_opening; + + VALGRIND_MAKE_MEM_UNDEFINED(key, 32); + VALGRIND_MAKE_MEM_UNDEFINED(s2c_data, 32); + ret = rustsecp256k1zkp_v0_2_0_ecdsa_s2c_sign(ctx, &signature, &s2c_opening, msg, key, s2c_data); + VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret)); + CHECK(ret == 1); + + VALGRIND_MAKE_MEM_UNDEFINED(s2c_data, 32); + ret = rustsecp256k1zkp_v0_2_0_ecdsa_anti_exfil_host_commit(ctx, s2c_data_comm, s2c_data); + VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret)); + CHECK(ret == 1); + + VALGRIND_MAKE_MEM_UNDEFINED(key, 32); + VALGRIND_MAKE_MEM_UNDEFINED(s2c_data, 32); + ret = rustsecp256k1zkp_v0_2_0_ecdsa_anti_exfil_signer_commit(ctx, &s2c_opening, msg, key, s2c_data); + VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret)); + CHECK(ret == 1); + } +#endif + +#ifdef ENABLE_MODULE_ECDSA_ADAPTOR + { + unsigned char adaptor_sig[162]; + unsigned char deckey[32]; + unsigned char expected_deckey[32]; + rustsecp256k1zkp_v0_2_0_pubkey enckey; + + for (i = 0; i < 32; i++) { + deckey[i] = i + 2; + } + + ret = rustsecp256k1zkp_v0_2_0_ec_pubkey_create(ctx, &enckey, deckey); + CHECK(ret == 1); + + VALGRIND_MAKE_MEM_UNDEFINED(key, 32); + ret = rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_encrypt(ctx, adaptor_sig, key, &enckey, msg, NULL, NULL); + VALGRIND_MAKE_MEM_DEFINED(adaptor_sig, sizeof(adaptor_sig)); + VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret)); + CHECK(ret == 1); + + VALGRIND_MAKE_MEM_UNDEFINED(deckey, 32); + ret = rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_decrypt(ctx, &signature, deckey, adaptor_sig); + VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret)); + CHECK(ret == 1); + + VALGRIND_MAKE_MEM_UNDEFINED(&signature, 32); + ret = rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_recover(ctx, expected_deckey, &signature, adaptor_sig, &enckey); + VALGRIND_MAKE_MEM_DEFINED(expected_deckey, sizeof(expected_deckey)); + VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret)); + CHECK(ret == 1); + + VALGRIND_MAKE_MEM_DEFINED(deckey, sizeof(deckey)); + ret = rustsecp256k1zkp_v0_2_0_memcmp_var(deckey, expected_deckey, sizeof(expected_deckey)); + VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret)); + CHECK(ret == 0); + } +#endif } diff --git a/secp256k1-zkp-sys/src/zkp.rs b/secp256k1-zkp-sys/src/zkp.rs index e3fbf54a..a9486c94 100644 --- a/secp256k1-zkp-sys/src/zkp.rs +++ b/secp256k1-zkp-sys/src/zkp.rs @@ -1,8 +1,9 @@ use core::{fmt, hash}; -use {types::*, Context, PublicKey}; +use {types::*, Context, PublicKey, Signature}; /// Rangeproof maximum length pub const RANGEPROOF_MAX_LENGTH: size_t = 5134; +pub const ECDSA_ADAPTOR_SIGNATURE_LENGTH: size_t = 162; extern "C" { #[cfg_attr( @@ -278,6 +279,61 @@ extern "C" { output: *mut PublicKey, bytes: *const c_uchar, ) -> c_int; + + #[cfg_attr( + not(feature = "external-symbols"), + link_name = "rustsecp256k1zkp_v0_2_0_nonce_function_ecdsa_adaptor" + )] + pub static secp256k1_nonce_function_ecdsa_adaptor: EcdsaAdaptorNonceFn; + + #[cfg_attr( + not(feature = "external-symbols"), + link_name = "rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_encrypt" + )] + pub fn secp256k1_ecdsa_adaptor_encrypt( + cx: *const Context, + adaptor_sig162: *mut EcdsaAdaptorSignature, + seckey32: *const c_uchar, + enckey: *const PublicKey, + msg32: *const c_uchar, + noncefp: EcdsaAdaptorNonceFn, + ndata: *mut c_void, + ) -> c_int; + + #[cfg_attr( + not(feature = "external-symbols"), + link_name = "rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_verify" + )] + pub fn secp256k1_ecdsa_adaptor_verify( + cx: *const Context, + adaptor_sig162: *const EcdsaAdaptorSignature, + pubkey: *const PublicKey, + msg32: *const c_uchar, + enckey: *const PublicKey, + ) -> c_int; + + #[cfg_attr( + not(feature = "external-symbols"), + link_name = "rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_decrypt" + )] + pub fn secp256k1_ecdsa_adaptor_decrypt( + cx: *const Context, + sig: *mut Signature, + deckey32: *const c_uchar, + adaptor_sig162: *const EcdsaAdaptorSignature, + ) -> c_int; + + #[cfg_attr( + not(feature = "external-symbols"), + link_name = "rustsecp256k1zkp_v0_2_0_ecdsa_adaptor_recover" + )] + pub fn secp256k1_ecdsa_adaptor_recover( + cx: *const Context, + deckey32: *mut c_uchar, + sig: *const Signature, + adaptor_sig162: *const EcdsaAdaptorSignature, + enckey: *const PublicKey, + ) -> c_int; } #[repr(C)] @@ -407,3 +463,38 @@ impl hash::Hash for PedersenCommitment { state.write(&self.0) } } + +/// Same as secp256k1_nonce_function_hardened with the exception of using the +/// compressed 33-byte encoding for the pubkey argument. +pub type EcdsaAdaptorNonceFn = Option< + unsafe extern "C" fn( + nonce32: *mut c_uchar, + msg32: *const c_uchar, + key32: *const c_uchar, + pk33: *const c_uchar, + algo: *const c_uchar, + algo_len: size_t, + data: *mut c_void, + ) -> c_int, +>; + +#[repr(C)] +pub struct EcdsaAdaptorSignature([u8; ECDSA_ADAPTOR_SIGNATURE_LENGTH]); +impl_array_newtype!(EcdsaAdaptorSignature, u8, ECDSA_ADAPTOR_SIGNATURE_LENGTH); +impl_raw_debug!(EcdsaAdaptorSignature); + +impl From<[u8; 162]> for EcdsaAdaptorSignature { + fn from(bytes: [u8; ECDSA_ADAPTOR_SIGNATURE_LENGTH]) -> Self { + EcdsaAdaptorSignature(bytes) + } +} + +impl EcdsaAdaptorSignature { + pub fn new() -> EcdsaAdaptorSignature { + EcdsaAdaptorSignature([0; ECDSA_ADAPTOR_SIGNATURE_LENGTH]) + } + + pub fn as_bytes(&self) -> &[u8; ECDSA_ADAPTOR_SIGNATURE_LENGTH] { + &self.0 + } +} diff --git a/src/lib.rs b/src/lib.rs index a075119d..abec89c7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -95,6 +95,14 @@ pub enum Error { InvalidRangeProof, /// Bad generator InvalidGenerator, + /// Given bytes don't represent a valid adaptor signature + InvalidEcdsaAdaptorSignature, + /// Failed to decrypt an adaptor signature because of an internal error within `libsecp256k1-zkp` + CannotDecryptAdaptorSignature, + /// Failed to recover an adaptor secret from an adaptor signature because of an internal error within `libsecp256k1-zkp` + CannotRecoverAdaptorSecret, + /// Given adaptor signature is not valid for the provided combination of public key, encryption key and message + CannotVerifyAdaptorSignature, } // Passthrough Debug to Display, since errors should be user-visible @@ -107,6 +115,10 @@ impl fmt::Display for Error { Error::CannotMakeRangeProof => "failed to generate range proof", Error::InvalidRangeProof => "failed to verify range proof", Error::InvalidGenerator => "malformed generator", + Error::InvalidEcdsaAdaptorSignature => "malformed ecdsa adaptor signature", + Error::CannotDecryptAdaptorSignature => "failed to decrypt adaptor signature", + Error::CannotRecoverAdaptorSecret => "failed to recover adaptor secret", + Error::CannotVerifyAdaptorSignature => "failed to verify adaptor signature", Error::Upstream(inner) => return write!(f, "{}", inner), }; diff --git a/src/zkp/ecdsa_adaptor.rs b/src/zkp/ecdsa_adaptor.rs new file mode 100644 index 00000000..15402b72 --- /dev/null +++ b/src/zkp/ecdsa_adaptor.rs @@ -0,0 +1,313 @@ +//! # ECDSA Adaptor +//! Support for ECDSA based adaptor signatures. +//! +//! WARNING: ECDSA adaptor signatures are insecure when the secret key is reused +//! in certain other crypto schemes. See +//! https://github.com/ElementsProject/secp256k1-zkp/blob/6955af5ca8930aa674e5fdbc4343e722b25e0ca8/include/secp256k1_ecdsa_adaptor.h#L14 +//! for details. +//! + +use core::{fmt, ptr, str}; +use ffi::{self, CPtr, ECDSA_ADAPTOR_SIGNATURE_LENGTH}; +use {constants, PublicKey, Secp256k1, SecretKey}; +use {from_hex, Error}; +use {Message, Signing}; +use {Signature, Verification}; + +/// Represents an adaptor signature and dleq proof. +#[derive(Debug, PartialEq, Clone, Copy, Eq)] +pub struct EcdsaAdaptorSignature(ffi::EcdsaAdaptorSignature); + +impl fmt::LowerHex for EcdsaAdaptorSignature { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + for ch in self.0.as_bytes().iter() { + write!(f, "{:02x}", ch)?; + } + Ok(()) + } +} + +impl fmt::Display for EcdsaAdaptorSignature { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::LowerHex::fmt(self, f) + } +} + +impl str::FromStr for EcdsaAdaptorSignature { + type Err = Error; + fn from_str(s: &str) -> Result { + let mut res = [0; ECDSA_ADAPTOR_SIGNATURE_LENGTH]; + match from_hex(s, &mut res) { + Ok(ECDSA_ADAPTOR_SIGNATURE_LENGTH) => { + EcdsaAdaptorSignature::from_slice(&res[0..ECDSA_ADAPTOR_SIGNATURE_LENGTH]) + } + _ => Err(Error::InvalidEcdsaAdaptorSignature), + } + } +} + +impl CPtr for EcdsaAdaptorSignature { + type Target = ffi::EcdsaAdaptorSignature; + fn as_c_ptr(&self) -> *const Self::Target { + self.as_ptr() + } + + fn as_mut_c_ptr(&mut self) -> *mut Self::Target { + self.as_mut_ptr() + } +} + +impl EcdsaAdaptorSignature { + /// Creates an [`EcdsaAdaptorSignature`] directly from a slice + #[inline] + pub fn from_slice(data: &[u8]) -> Result { + match data.len() { + ECDSA_ADAPTOR_SIGNATURE_LENGTH => { + let mut ret = [0; ECDSA_ADAPTOR_SIGNATURE_LENGTH]; + ret[..].copy_from_slice(data); + Ok(EcdsaAdaptorSignature(ffi::EcdsaAdaptorSignature::from(ret))) + } + _ => Err(Error::InvalidEcdsaAdaptorSignature), + } + } + + /// Obtains a raw const pointer suitable for use with FFI functions + #[inline] + pub fn as_ptr(&self) -> *const ffi::EcdsaAdaptorSignature { + &self.0 + } + + /// Obtains a raw mutable pointer suitable for use with FFI functions + #[inline] + pub fn as_mut_ptr(&mut self) -> *mut ffi::EcdsaAdaptorSignature { + &mut self.0 + } +} + +impl EcdsaAdaptorSignature { + /// Creates an adaptor signature along with a proof to verify the adaptor signature. + pub fn encrypt( + secp: &Secp256k1, + msg: &Message, + sk: &SecretKey, + enckey: &PublicKey, + ) -> EcdsaAdaptorSignature { + let mut adaptor_sig = ffi::EcdsaAdaptorSignature::new(); + + unsafe { + debug_assert!( + ffi::secp256k1_ecdsa_adaptor_encrypt( + *secp.ctx(), + &mut adaptor_sig, + sk.as_c_ptr(), + enckey.as_c_ptr(), + msg.as_c_ptr(), + None, + ptr::null_mut(), + ) == 1 + ); + }; + + EcdsaAdaptorSignature(adaptor_sig) + } + + /// Creates an ECDSA signature from an adaptor signature and an adaptor secret. + pub fn decrypt(&self, decryption_key: &SecretKey) -> Result { + unsafe { + let mut signature = ffi::Signature::new(); + let ret = ffi::secp256k1_ecdsa_adaptor_decrypt( + ffi::secp256k1_context_no_precomp, + &mut signature, + decryption_key.as_c_ptr(), + self.as_c_ptr(), + ); + + if ret != 1 { + return Err(Error::CannotDecryptAdaptorSignature); + } + + Ok(Signature::from(signature)) + } + } + + /// Extracts the adaptor secret from the complete signature and the adaptor signature. + pub fn recover( + &self, + secp: &Secp256k1, + sig: &Signature, + encryption_key: &PublicKey, + ) -> Result { + let mut data: [u8; constants::SECRET_KEY_SIZE] = [0; constants::SECRET_KEY_SIZE]; + + let ret = unsafe { + ffi::secp256k1_ecdsa_adaptor_recover( + *secp.ctx(), + data.as_mut_c_ptr(), + sig.as_c_ptr(), + self.as_c_ptr(), + encryption_key.as_c_ptr(), + ) + }; + + if ret != 1 { + return Err(Error::CannotRecoverAdaptorSecret); + } + + Ok(SecretKey::from_slice(&data)?) + } + + /// Verifies that the adaptor secret can be extracted from the adaptor signature and the completed ECDSA signature. + pub fn verify( + &self, + secp: &Secp256k1, + msg: &Message, + pubkey: &PublicKey, + encryption_key: &PublicKey, + ) -> Result<(), Error> { + let res = unsafe { + ffi::secp256k1_ecdsa_adaptor_verify( + *secp.ctx(), + self.as_c_ptr(), + pubkey.as_c_ptr(), + msg.as_c_ptr(), + encryption_key.as_c_ptr(), + ) + }; + + if res != 1 { + return Err(Error::CannotVerifyAdaptorSignature); + }; + + Ok(()) + } +} + +#[cfg(all(test, feature = "global-context"))] +mod tests { + use super::Message; + use super::*; + use rand::thread_rng; + use SECP256K1; + + #[test] + #[cfg(not(rust_secp_fuzz))] + fn test_ecdsa_adaptor_signature() { + let (seckey, pubkey) = SECP256K1.generate_keypair(&mut thread_rng()); + let (adaptor_secret, adaptor) = SECP256K1.generate_keypair(&mut thread_rng()); + let msg = Message::from_slice(&[2u8; 32]).unwrap(); + let adaptor_sig = EcdsaAdaptorSignature::encrypt(&SECP256K1, &msg, &seckey, &adaptor); + + adaptor_sig + .verify(&SECP256K1, &msg, &pubkey, &adaptor) + .expect("adaptor signature to be valid"); + adaptor_sig + .verify(&SECP256K1, &msg, &adaptor, &pubkey) + .expect_err("adaptor signature to be invalid"); + let sig = adaptor_sig + .decrypt(&adaptor_secret) + .expect("to be able to decrypt using the correct secret"); + SECP256K1 + .verify(&msg, &sig, &pubkey) + .expect("signature to be valid"); + let recovered = adaptor_sig + .recover(&SECP256K1, &sig, &adaptor) + .expect("to be able to recover the secret"); + assert_eq!(adaptor_secret, recovered); + } + + #[test] + fn test_ecdsa_adaptor_signature_plain_valid() { + let msg = msg_from_str("8131e6f4b45754f2c90bd06688ceeabc0c45055460729928b4eecf11026a9e2d"); + let pubkey = "035be5e9478209674a96e60f1f037f6176540fd001fa1d64694770c56a7709c42c" + .parse() + .unwrap(); + let encryption_key = "02c2662c97488b07b6e819124b8989849206334a4c2fbdf691f7b34d2b16e9c293" + .parse() + .unwrap(); + let adaptor_sig : EcdsaAdaptorSignature = "03424d14a5471c048ab87b3b83f6085d125d5864249ae4297a57c84e74710bb6730223f325042fce535d040fee52ec13231bf709ccd84233c6944b90317e62528b2527dff9d659a96db4c99f9750168308633c1867b70f3a18fb0f4539a1aecedcd1fc0148fc22f36b6303083ece3f872b18e35d368b3958efe5fb081f7716736ccb598d269aa3084d57e1855e1ea9a45efc10463bbf32ae378029f5763ceb40173f" + .parse() + .unwrap(); + + adaptor_sig + .verify(&SECP256K1, &msg, &pubkey, &encryption_key) + .expect("adaptor signature verification to pass"); + + let sig = compact_sig_from_str("424d14a5471c048ab87b3b83f6085d125d5864249ae4297a57c84e74710bb67329e80e0ee60e57af3e625bbae1672b1ecaa58effe613426b024fa1621d903394"); + let expected_decryption_key: SecretKey = + "0b2aba63b885a0f0e96fa0f303920c7fb7431ddfa94376ad94d969fbf4109dc8" + .parse() + .unwrap(); + + let recovered = adaptor_sig + .recover(&SECP256K1, &sig, &encryption_key) + .expect("to be able to recover the decryption key"); + + assert_eq!(expected_decryption_key, recovered); + } + + #[test] + fn test_ecdsa_adaptor_signature_wrong_proof() { + let msg = msg_from_str("8131e6f4b45754f2c90bd06688ceeabc0c45055460729928b4eecf11026a9e2d"); + let pubkey = "035be5e9478209674a96e60f1f037f6176540fd001fa1d64694770c56a7709c42c" + .parse() + .unwrap(); + let encryption_key = "0214ccb756249ad6e733c80285ea7ac2ee12ffebbcee4e556e6810793a60c45ad4" + .parse() + .unwrap(); + let adaptor_sig: EcdsaAdaptorSignature = "03f94dca206d7582c015fb9bffe4e43b14591b30ef7d2b464d103ec5e116595dba03127f8ac3533d249280332474339000922eb6a58e3b9bf4fc7e01e4b4df2b7a4100a1e089f16e5d70bb89f961516f1de0684cc79db978495df2f399b0d01ed7240fa6e3252aedb58bdc6b5877b0c602628a235dd1ccaebdddcbe96198c0c21bead7b05f423b673d14d206fa1507b2dbe2722af792b8c266fc25a2d901d7e2c335" + .parse() + .unwrap(); + + adaptor_sig + .verify(&SECP256K1, &msg, &pubkey, &encryption_key) + .expect_err("providing a wrong proof should fail validation"); + } + + #[test] + fn test_ecdsa_adaptor_signature_recover_wrong_sig_r_value() { + let encryption_key = "035176d24129741b0fcaa5fd6750727ce30860447e0a92c9ebebdeb7c3f93995ed" + .parse() + .unwrap(); + let adaptor_sig: EcdsaAdaptorSignature = "03aa86d78059a91059c29ec1a757c4dc029ff636a1e6c1142fefe1e9d7339617c003a8153e50c0c8574a38d389e61bbb0b5815169e060924e4b5f2e78ff13aa7ad858e0c27c4b9eed9d60521b3f54ff83ca4774be5fb3a680f820a35e8840f4aaf2de88e7c5cff38a37b78725904ef97bb82341328d55987019bd38ae1745e3efe0f8ea8bdfede0d378fc1f96e944a7505249f41e93781509ee0bade77290d39cd12" + .parse() + .unwrap(); + + let sig = compact_sig_from_str("f7f7fe6bd056fc4abd70d335f72d0aa1e8406bba68f3e579e4789475323564a452c46176c7fb40aa37d5651341f55697dab27d84a213b30c93011a7790bace8c"); + adaptor_sig + .recover(&SECP256K1, &sig, &encryption_key) + .expect_err("providing wrong r value should prevent us from recovering decryption key"); + } + + #[test] + fn test_ecdsa_adaptor_signature_recover_from_high_s_signature() { + let encryption_key = "02042537e913ad74c4bbd8da9607ad3b9cb297d08e014afc51133083f1bd687a62" + .parse() + .unwrap(); + let adaptor_sig: EcdsaAdaptorSignature = "032c637cd797dd8c2ce261907ed43e82d6d1a48cbabbbece801133dd8d70a01b1403eb615a3e59b1cbbf4f87acaf645be1eda32a066611f35dd5557802802b14b19c81c04c3fefac5783b2077bd43fa0a39ab8a64d4d78332a5d621ea23eca46bc011011ab82dda6deb85699f508744d70d4134bea03f784d285b5c6c15a56e4e1fab4bc356abbdebb3b8fe1e55e6dd6d2a9ea457e91b2e6642fae69f9dbb5258854" + .parse() + .unwrap(); + + let sig = compact_sig_from_str("2c637cd797dd8c2ce261907ed43e82d6d1a48cbabbbece801133dd8d70a01b14b5f24321f550b7b9dd06ee4fcfd82bdad8b142ff93a790cc4d9f7962b38c6a3b"); + let expected_decryption_key: SecretKey = + "324719b51ff2474c9438eb76494b0dc0bcceeb529f0a5428fd198ad8f886e99c" + .parse() + .unwrap(); + let recovered = adaptor_sig + .recover(&SECP256K1, &sig, &encryption_key) + .expect("with high s we should still be able to recover the decryption key"); + + assert_eq!(expected_decryption_key, recovered); + } + + fn msg_from_str(input: &str) -> Message { + let mut buf = [0u8; 32]; + from_hex(input, &mut buf).unwrap(); + Message::from_slice(&buf).unwrap() + } + + fn compact_sig_from_str(input: &str) -> Signature { + let mut buf = [0u8; 64]; + from_hex(input, &mut buf).unwrap(); + Signature::from_compact(&buf).unwrap() + } +} diff --git a/src/zkp/mod.rs b/src/zkp/mod.rs index b9a08cdb..ec800fc4 100644 --- a/src/zkp/mod.rs +++ b/src/zkp/mod.rs @@ -1,3 +1,4 @@ +mod ecdsa_adaptor; mod generator; #[cfg(feature = "std")] mod pedersen; @@ -7,6 +8,7 @@ mod rangeproof; mod surjection_proof; mod tag; +pub use self::ecdsa_adaptor::*; pub use self::generator::*; #[cfg(feature = "std")] pub use self::pedersen::*;