Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an experimental schnorr signature adaptor module #268

Closed
33 changes: 22 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ env:
MUSIG: 'no'
ECDSAADAPTOR: 'no'
BPPP: 'no'
SCHNORRADAPTOR: 'no'
### test options
SECP256K1_TEST_ITERS:
BENCH: 'yes'
Expand Down Expand Up @@ -78,14 +79,14 @@ jobs:
matrix:
configuration:
- env_vars: { WIDEMUL: 'int64', RECOVERY: 'yes' }
- env_vars: { WIDEMUL: 'int64', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes' }
- env_vars: { WIDEMUL: 'int64', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRADAPTOR: 'yes'}
- env_vars: { WIDEMUL: 'int128' }
- env_vars: { WIDEMUL: 'int128_struct', ELLSWIFT: 'yes' }
- env_vars: { WIDEMUL: 'int128', RECOVERY: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes' }
- env_vars: { WIDEMUL: 'int128', ECDH: 'yes', SCHNORRSIG: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes'}
- env_vars: { WIDEMUL: 'int128', ECDH: 'yes', SCHNORRSIG: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRADAPTOR: 'yes'}
- env_vars: { WIDEMUL: 'int128', ASM: 'x86_64', ELLSWIFT: 'yes' }
- env_vars: { RECOVERY: 'yes', SCHNORRSIG: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes'}
- env_vars: { CTIMETESTS: 'no', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', CPPFLAGS: '-DVERIFY' }
- env_vars: { RECOVERY: 'yes', SCHNORRSIG: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRADAPTOR: 'yes'}
- env_vars: { CTIMETESTS: 'no', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRADAPTOR: 'yes', CPPFLAGS: '-DVERIFY' }
- env_vars: { BUILD: 'distcheck', WITH_VALGRIND: 'no', CTIMETESTS: 'no', BENCH: 'no' }
- env_vars: { CPPFLAGS: '-DDETERMINISTIC' }
- env_vars: { CFLAGS: '-O0', CTIMETESTS: 'no' }
Expand Down Expand Up @@ -156,6 +157,7 @@ jobs:
MUSIG: 'yes'
ECDSAADAPTOR: 'yes'
BPPP: 'yes'
SCHNORRADAPTOR: 'yes'
CC: ${{ matrix.cc }}

steps:
Expand Down Expand Up @@ -208,6 +210,7 @@ jobs:
MUSIG: 'yes'
ECDSAADAPTOR: 'yes'
BPPP: 'yes'
SCHNORRADAPTOR: 'yes'
CTIMETESTS: 'no'

steps:
Expand Down Expand Up @@ -267,6 +270,7 @@ jobs:
MUSIG: 'yes'
ECDSAADAPTOR: 'yes'
BPPP: 'yes'
SCHNORRADAPTOR: 'yes'
CTIMETESTS: 'no'

steps:
Expand Down Expand Up @@ -320,6 +324,7 @@ jobs:
MUSIG: 'yes'
ECDSAADAPTOR: 'yes'
BPPP: 'yes'
SCHNORRADAPTOR: 'yes'
CTIMETESTS: 'no'

strategy:
Expand Down Expand Up @@ -383,6 +388,7 @@ jobs:
MUSIG: 'yes'
ECDSAADAPTOR: 'yes'
BPPP: 'yes'
SCHNORRADAPTOR: 'yes'
CTIMETESTS: 'no'

steps:
Expand Down Expand Up @@ -443,6 +449,7 @@ jobs:
MUSIG: 'yes'
ECDSAADAPTOR: 'yes'
BPPP: 'yes'
SCHNORRADAPTOR: 'yes'
CTIMETESTS: 'no'
SECP256K1_TEST_ITERS: 2

Expand Down Expand Up @@ -502,6 +509,7 @@ jobs:
MUSIG: 'yes'
ECDSAADAPTOR: 'yes'
BPPP: 'yes'
SCHNORRADAPTOR: 'yes'
CTIMETESTS: 'no'
CFLAGS: '-fsanitize=undefined,address -g'
UBSAN_OPTIONS: 'print_stacktrace=1:halt_on_error=1'
Expand Down Expand Up @@ -567,6 +575,7 @@ jobs:
MUSIG: 'yes'
ECDSAADAPTOR: 'yes'
BPPP: 'yes'
SCHNORRADAPTOR: 'yes'
CTIMETESTS: 'yes'
CC: 'clang'
SECP256K1_TEST_ITERS: 32
Expand Down Expand Up @@ -622,6 +631,7 @@ jobs:
MUSIG: 'yes'
ECDSAADAPTOR: 'yes'
BPPP: 'yes'
SCHNORRADAPTOR: 'yes'
CTIMETESTS: 'no'

strategy:
Expand Down Expand Up @@ -678,15 +688,15 @@ jobs:
fail-fast: false
matrix:
env_vars:
- { WIDEMUL: 'int64', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes' }
- { WIDEMUL: 'int64', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRADAPTOR: 'yes' }
- { WIDEMUL: 'int128_struct', ECMULTGENPRECISION: 2, ECMULTWINDOW: 4 }
- { WIDEMUL: 'int128', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes' }
- { WIDEMUL: 'int128', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRADAPTOR: 'yes' }
- { WIDEMUL: 'int128', RECOVERY: 'yes' }
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes' }
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', CC: 'gcc' }
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', WRAPPER_CMD: 'valgrind --error-exitcode=42', SECP256K1_TEST_ITERS: 2 }
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', CC: 'gcc', WRAPPER_CMD: 'valgrind --error-exitcode=42', SECP256K1_TEST_ITERS: 2 }
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', CPPFLAGS: '-DVERIFY', CTIMETESTS: 'no' }
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRADAPTOR: 'yes' }
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRADAPTOR: 'yes', CC: 'gcc' }
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRADAPTOR: 'yes', WRAPPER_CMD: 'valgrind --error-exitcode=42', SECP256K1_TEST_ITERS: 2 }
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRADAPTOR: 'yes', CC: 'gcc', WRAPPER_CMD: 'valgrind --error-exitcode=42', SECP256K1_TEST_ITERS: 2 }
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRADAPTOR: 'yes', CPPFLAGS: '-DVERIFY', CTIMETESTS: 'no' }
- BUILD: 'distcheck'

steps:
Expand Down Expand Up @@ -805,6 +815,7 @@ jobs:
MUSIG: 'yes'
ECDSAADAPTOR: 'yes'
BPPP: 'yes'
SCHNORRADAPTOR: 'yes'

steps:
- name: Checkout
Expand Down
4 changes: 4 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -317,3 +317,7 @@ endif
if ENABLE_MODULE_ECDSA_ADAPTOR
include src/modules/ecdsa_adaptor/Makefile.am.include
endif

if ENABLE_MODULE_SCHNORR_ADAPTOR
include src/modules/schnorr_adaptor/Makefile.am.include
endif
1 change: 1 addition & 0 deletions ci/ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ esac
--enable-module-rangeproof="$RANGEPROOF" --enable-module-whitelist="$WHITELIST" --enable-module-generator="$GENERATOR" \
--enable-module-schnorrsig="$SCHNORRSIG" --enable-module-musig="$MUSIG" --enable-module-ecdsa-adaptor="$ECDSAADAPTOR" \
--enable-module-schnorrsig="$SCHNORRSIG" \
--enable-module-schnorr-adaptor="$SCHNORRADAPTOR" \
ZhePang marked this conversation as resolved.
Show resolved Hide resolved
--enable-examples="$EXAMPLES" \
--enable-ctime-tests="$CTIMETESTS" \
--with-valgrind="$WITH_VALGRIND" \
Expand Down
15 changes: 15 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,10 @@ AC_ARG_ENABLE(module_ellswift,
AS_HELP_STRING([--enable-module-ellswift],[enable ElligatorSwift module [default=yes]]), [],
[SECP_SET_DEFAULT([enable_module_ellswift], [yes], [yes])])

AC_ARG_ENABLE(module_schnorr_adaptor,
AS_HELP_STRING([--enable-module-schnorr-adaptor],[enable schnorr adaptor module [default=no]]), [],
[SECP_SET_DEFAULT([enable_module_schnorr_adaptor], [no], [yes])])

AC_ARG_ENABLE(module_ecdsa_s2c,
AS_HELP_STRING([--enable-module-ecdsa-s2c],[enable ECDSA sign-to-contract module [default=no]]),
[],
Expand Down Expand Up @@ -490,6 +494,12 @@ if test x"$enable_module_schnorrsig" = x"yes"; then
enable_module_extrakeys=yes
fi

if test x"$enable_module_schnorr_adaptor" = x"yes"; then
AC_DEFINE(ENABLE_MODULE_SCHNORR_ADAPTOR, 1, [Define thsi symbol to enable the Schnorr adaptor module])
enable_module_extrakeys=yes
enable_module_schnorrsig=yes
fi

if test x"$enable_module_ellswift" = x"yes"; then
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_ELLSWIFT=1"
fi
Expand Down Expand Up @@ -557,6 +567,9 @@ else
if test x"$set_asm" = x"arm32"; then
AC_MSG_ERROR([ARM32 assembly optimization is experimental. Use --enable-experimental to allow.])
fi
if test x"$enable_module_schnorr_adaptor" = x"yes"; then
AC_MSG_ERROR([Schnorr adaptor signatures module is experimental. Use --enable-experimental to allow.])
fi
fi

###
Expand All @@ -581,6 +594,7 @@ 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_SCHNORR_ADAPTOR], [test x"$enable_module_schnorr_adaptor" = x"yes"])
AM_CONDITIONAL([ENABLE_MODULE_ELLSWIFT], [test x"$enable_module_ellswift" = 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"])
Expand All @@ -607,6 +621,7 @@ 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 schnorr-adaptor = $enable_module_schnorr_adaptor"
echo " module ellswift = $enable_module_ellswift"
echo " module generator = $enable_module_generator"
echo " module rangeproof = $enable_module_rangeproof"
Expand Down
127 changes: 127 additions & 0 deletions include/secp256k1_schnorr_adaptor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
#ifndef SECP256K1_SCHNORR_ADAPTOR_H
#define SECP256K1_SCHNORR_ADAPTOR_H

#include "secp256k1.h"
#include "secp256k1_extrakeys.h"

#ifdef __cplusplus
extern "C" {
#endif

/** A pointer to a function to deterministically generate a nonce.
*
* Same as secp256k1_schnorrsig_nonce function with the exception of accepting an
* additional adaptor point 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 being verified (will not be NULL)
* key32: pointer to a 32-byte secret key (will not be NULL)
* adaptor33: the 33-byte serialized adaptor point (will not be NULL)
* xonly_pk32: the 32-byte serialized xonly pubkey corresponding to key32
* (will not be NULL)
* algo: pointer to an array describing the signature
* algorithm (will not be NULL)
* 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 adaptor point, the pubkey, the algorithm description, and data.
*/
typedef int (*secp256k1_adaptor_nonce_function_hardened)(
unsigned char *nonce32,
const unsigned char *msg32,
const unsigned char *key32,
const unsigned char *adaptor33,
const unsigned char *xonly_pk32,
const unsigned char *algo,
size_t algolen,
void *data
);

/** A Schnorr Adaptor nonce generation function. */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we could just remove the reference to BIP340, instead of the whole paragraph. Something like:

A Schnorr Adaptor nonce generation function.

If a data pointer is passed, it is assumed to be a pointer to 32 bytes of auxiliary random data. If the data pointer is NULL, the nonce derivation procedure sets the auxiliary random data to zero. The algo argument must be non-NULL, otherwise the function will fail and return 0. The hash will be tagged with algo. Therefore, algo must be set to "SchnorrAdaptor/nonce" and algolen to 20.

SECP256K1_API const secp256k1_adaptor_nonce_function_hardened secp256k1_nonce_function_schnorr_adaptor;

/** Create a Schnorr adaptor signature.
ZhePang marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to replace the term "adaptor signature" with "pre-signature" to be consistent with the literature (see #268 (comment))?

*
* This function only signs 32-byte messages. If you have messages of a
* different size (or the same size but without a context-specific tag
* prefix), it is recommended to create a 32-byte message hash with
* secp256k1_tagged_sha256 and then sign the hash. Tagged hashing allows
* providing an context-specific tag for domain separation. This prevents
* signatures from being valid in multiple contexts by accident.
*
* Returns 1 on success, 0 on failure.
* Args: ctx: pointer to a context object (not secp256k1_context_static).
* Out: presig65: pointer to a 65-byte array to store the adaptor signature.
* In: msg32: the 32-byte message being signed.
* keypair: pointer to an initialized keypair.
* adaptor: pointer to an adaptor point.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: 344620e renamed adaptor to adaptor33. Just wanna make sure that this revert is intentional.

* aux_rand32: 32 bytes of fresh randomness. While recommended to provide
* this, it is only supplemental to security and can be NULL. A
* NULL argument is treated the same as an all-zero one. See
* BIP-340 "Default Signing" for a full explanation of this
* argument and for guidance if randomness is expensive.
*/
SECP256K1_API int secp256k1_schnorr_adaptor_presign(
const secp256k1_context *ctx,
unsigned char *presig65,
const unsigned char *msg32,
const secp256k1_keypair *keypair,
const secp256k1_pubkey *adaptor,
const unsigned char *aux_rand32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);

/** Extract an adaptor point from the signature.
*
* Returns 1 on success, 0 on failure.
* Args: ctx: pointer to a context object.
* Out: adaptor33: pointer to an adaptor point.
* In: presig65: pointer to a 65-byte adaptor signature.
* msg32: the 32-byte message being signed.
* pubkey: pointer to an x-only public key to verify with
*/
SECP256K1_API int secp256k1_schnorr_adaptor_extract(
const secp256k1_context *ctx,
secp256k1_pubkey *adaptor,
const unsigned char *presig65,
const unsigned char *msg32,
const secp256k1_xonly_pubkey *pubkey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);

/** Adapt an adaptor signature to result in a Schnorr signature.
*
* Returns 1 on success, 0 on failure.
* Args: ctx: pointer to a context object.
* Out: sig64: pointer to a 64-byte array to store the adapted Schnorr signature.
* In: presig65: pointer to a 65-byte adaptor signature.
* secadaptor: pointer to a 32-byte secadaptor.
*/
SECP256K1_API int secp256k1_schnorr_adaptor_adapt(
const secp256k1_context *ctx,
unsigned char *sig64,
const unsigned char *presig65,
const unsigned char *secadaptor
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);

/** Extract the secadaptor from a valid adaptor signature and a Schnorr signature.
*
* Returns 1 on success, 0 on failure.
* Args: ctx: pointer to a context object.
* Out: secadaptor: pointer to a 32-byte array to store the secadaptor.
* In: presig65: pointer to a 65-byte adaptor signature.
* sig64: pointer to a 64-byte adapted Schnorr signature.
*/
SECP256K1_API int secp256k1_schnorr_adaptor_extract_sec(
const secp256k1_context *ctx,
unsigned char *secadaptor,
const unsigned char *presig65,
const unsigned char *sig64
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);

#ifdef __cplusplus
}
#endif

#endif /* SECP256K1_SCHNORR_ADAPTOR_H */
22 changes: 22 additions & 0 deletions src/ctime_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
#include "../include/secp256k1_schnorrsig.h"
#endif

#ifdef ENABLE_MODULE_SCHNORR_ADAPTOR
#include "../include/secp256k1_schnorr_adaptor.h"
#endif

#ifdef ENABLE_MODULE_ELLSWIFT
#include "../include/secp256k1_ellswift.h"
#endif
Expand Down Expand Up @@ -193,6 +197,24 @@ static void run_tests(secp256k1_context *ctx, unsigned char *key) {
CHECK(ret == 1);
#endif

#ifdef ENABLE_MODULE_SCHNORR_ADAPTOR
{
unsigned char t[33];

for (i = 0; i < 33; i++) {
t[i] = i + 2;
}

SECP256K1_CHECKMEM_UNDEFINE(key, 32);
ret = secp256k1_keypair_create(ctx, &keypair, key);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
ret = secp256k1_schnorr_adaptor_presign(ctx, sig, msg, &keypair, t, NULL);
SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
CHECK(ret == 1);
}
#endif

#ifdef ENABLE_MODULE_ELLSWIFT
SECP256K1_CHECKMEM_UNDEFINE(key, 32);
ret = secp256k1_ellswift_create(ctx, ellswift, key, NULL);
Expand Down
3 changes: 3 additions & 0 deletions src/modules/schnorr_adaptor/Makefile.am.include
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
include_HEADERS += include/secp256k1_schnorr_adaptor.h
noinst_HEADERS += src/modules/schnorr_adaptor/main_impl.h
noinst_HEADERS += src/modules/schnorr_adaptor/tests_impl.h
Loading