diff --git a/.gitignore b/.gitignore
index 82bdcf81..e24dcda4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,7 +7,6 @@ bench_internal
bench_whitelist
noverify_tests
tests
-example_musig
exhaustive_tests
precompute_ecmult_gen
precompute_ecmult
@@ -66,8 +65,6 @@ build-aux/test-driver
libsecp256k1.pc
contrib/gh-pr-create.sh
-musig_example
-
### CMake
/CMakeUserPresets.json
# Default CMake build directory.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 44e8b0e8..76a9e09e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -66,7 +66,6 @@ option(SECP256K1_ENABLE_MODULE_GENERATOR "Enable NUMS generator module." ON)
option(SECP256K1_ENABLE_MODULE_RANGEPROOF "Enable Range proof module." ON)
option(SECP256K1_ENABLE_MODULE_SURJECTIONPROOF "Enable Surjection proof module." ON)
option(SECP256K1_ENABLE_MODULE_WHITELIST "Enable key whitelist module." ON)
-option(SECP256K1_ENABLE_MODULE_MUSIG "Enable MuSig module." ON)
option(SECP256K1_ENABLE_MODULE_ECDSA_ADAPTOR "Enable ecdsa adaptor signatures module." ON)
option(SECP256K1_ENABLE_MODULE_ECDSA_S2C "Enable ECDSA sign-to-contract module." ON)
option(SECP256K1_ENABLE_MODULE_BPPP "Enable Bulletproofs++ module." ON)
@@ -89,14 +88,6 @@ if(SECP256K1_ENABLE_MODULE_ECDSA_ADAPTOR)
add_compile_definitions(ENABLE_MODULE_ECDSA_ADAPTOR=1)
endif()
-if(SECP256K1_ENABLE_MODULE_MUSIG)
- if(DEFINED SECP256K1_ENABLE_MODULE_SCHNORRSIG AND NOT SECP256K1_ENABLE_MODULE_SCHNORRSIG)
- message(FATAL_ERROR "Module dependency error: You have disabled the schnorrsig module explicitly, but it is required by the musig module.")
- endif()
- set(SECP256K1_ENABLE_MODULE_SCHNORRSIG ON)
- add_compile_definitions(ENABLE_MODULE_MUSIG=1)
-endif()
-
if(SECP256K1_ENABLE_MODULE_WHITELIST)
if(DEFINED SECP256K1_ENABLE_MODULE_RANGEPROOF AND NOT SECP256K1_ENABLE_MODULE_RANGEPROOF)
message(FATAL_ERROR "Module dependency error: You have disabled the rangeproof module explicitly, but it is required by the whitelist module.")
@@ -374,7 +365,6 @@ message(" generator ........................... ${SECP256K1_ENABLE_MODULE_GENER
message(" rangeproof .......................... ${SECP256K1_ENABLE_MODULE_RANGEPROOF}")
message(" surjectionproof ..................... ${SECP256K1_ENABLE_MODULE_SURJECTIONPROOF}")
message(" whitelist ........................... ${SECP256K1_ENABLE_MODULE_WHITELIST}")
-message(" musig ............................... ${SECP256K1_ENABLE_MODULE_MUSIG}")
message(" ecdsa-s2c ........................... ${SECP256K1_ENABLE_MODULE_ECDSA_S2C}")
message(" ecdsa-adaptor ....................... ${SECP256K1_ENABLE_MODULE_ECDSA_ADAPTOR}")
message(" bppp ................................ ${SECP256K1_ENABLE_MODULE_BPPP}")
diff --git a/Makefile.am b/Makefile.am
index 04bc4c51..e142c9a9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -197,17 +197,6 @@ ellswift_example_LDFLAGS += -lbcrypt
endif
TESTS += ellswift_example
endif
-if ENABLE_MODULE_MUSIG
-noinst_PROGRAMS += musig_example
-musig_example_SOURCES = examples/musig.c
-musig_example_CPPFLAGS = -I$(top_srcdir)/include -DSECP256K1_STATIC
-musig_example_LDADD = libsecp256k1.la
-musig_example_LDFLAGS = -static
-if BUILD_WINDOWS
-musig_example_LDFLAGS += -lbcrypt
-endif
-TESTS += musig_example
-endif
endif
### Precomputed tables
@@ -290,10 +279,6 @@ if ENABLE_MODULE_ECDH
include src/modules/ecdh/Makefile.am.include
endif
-if ENABLE_MODULE_MUSIG
-include src/modules/musig/Makefile.am.include
-endif
-
if ENABLE_MODULE_RECOVERY
include src/modules/recovery/Makefile.am.include
endif
diff --git a/README.md b/README.md
index eddd67a7..488044b4 100644
--- a/README.md
+++ b/README.md
@@ -3,12 +3,11 @@ libsecp256k1-zkp

-A fork of [libsecp256k1](https://github.com/bitcoin-core/secp256k1) with support for advanced and experimental features such as Confidential Assets and MuSig2
+A fork of [libsecp256k1](https://github.com/bitcoin-core/secp256k1) with support for advanced and experimental features such as Confidential Assets and Bulletproofs++ range proofs
Added features:
* Experimental module for ECDSA adaptor signatures.
* Experimental module for ECDSA sign-to-contract.
-* Experimental module for [MuSig2](src/modules/musig/musig.md).
* Experimental module for Confidential Assets (Pedersen commitments, range proofs, and [surjection proofs](src/modules/surjection/surjection.md)).
* Experimental module for Bulletproofs++ range proofs.
* Experimental module for [address whitelisting](src/modules/whitelist/whitelist.md).
@@ -27,7 +26,7 @@ Building with Autotools
$ make check # run the test suite
$ sudo make install # optional
-To compile optional modules (such as Schnorr signatures), you need to run `./configure` with additional flags (such as `--enable-module-schnorrsig`). Run `./configure --help` to see the full list of available flags. For experimental modules, you will also need `--enable-experimental` as well as a flag for each individual module, e.g. `--enable-module-musig`.
+To compile optional modules (such as Schnorr signatures), you need to run `./configure` with additional flags (such as `--enable-module-schnorrsig`). Run `./configure --help` to see the full list of available flags. For experimental modules, you will also need `--enable-experimental` as well as a flag for each individual module, e.g. `--enable-module-rangeproof`.
Building with CMake (experimental)
----------------------------------
@@ -74,9 +73,8 @@ Usage examples can be found in the [examples](examples) directory. To compile th
* [Schnorr signatures example](examples/schnorr.c)
* [Deriving a shared secret (ECDH) example](examples/ecdh.c)
* [ElligatorSwift key exchange example](examples/ellswift.c)
- * [MuSig example](examples/musig.c)
-To compile the Schnorr signature, ECDH and MuSig examples, you need to enable the corresponding module by providing a flag to the `configure` script, for example `--enable-module-schnorrsig`.
+To compile the Schnorr signature and ECDH examples, you need to enable the corresponding module by providing a flag to the `configure` script, for example `--enable-module-schnorrsig`.
Benchmark
------------
diff --git a/ci/ci.sh b/ci/ci.sh
index 828ff4b6..7c786bfe 100755
--- a/ci/ci.sh
+++ b/ci/ci.sh
@@ -14,7 +14,7 @@ print_environment() {
for var in WERROR_CFLAGS MAKEFLAGS BUILD \
ECMULTWINDOW ECMULTGENKB ASM WIDEMUL WITH_VALGRIND EXTRAFLAGS \
EXPERIMENTAL ECDH RECOVERY EXTRAKEYS SCHNORRSIG SCHNORRSIG_HALFAGG ELLSWIFT \
- ECDSA_S2C GENERATOR RANGEPROOF WHITELIST MUSIG ECDSAADAPTOR BPPP \
+ ECDSA_S2C GENERATOR RANGEPROOF WHITELIST ECDSAADAPTOR BPPP \
SECP256K1_TEST_ITERS BENCH SECP256K1_BENCH_ITERS CTIMETESTS\
EXAMPLES \
HOST WRAPPER_CMD \
@@ -82,7 +82,7 @@ esac
--enable-module-ecdsa-s2c="$ECDSA_S2C" \
--enable-module-bppp="$BPPP" \
--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-ecdsa-adaptor="$ECDSAADAPTOR" \
--enable-module-schnorrsig="$SCHNORRSIG" \
--enable-module-schnorrsig-halfagg="$SCHNORRSIG_HALFAGG" \
--enable-examples="$EXAMPLES" \
diff --git a/configure.ac b/configure.ac
index e0007537..37e36760 100644
--- a/configure.ac
+++ b/configure.ac
@@ -216,11 +216,6 @@ AC_ARG_ENABLE(module_whitelist,
[],
[SECP_SET_DEFAULT([enable_module_whitelist], [no], [yes])])
-AC_ARG_ENABLE(module_musig,
- AS_HELP_STRING([--enable-module-musig],[enable MuSig module (experimental)]),
- [],
- [SECP_SET_DEFAULT([enable_module_musig], [no], [yes])])
-
AC_ARG_ENABLE(module_ecdsa_s2c,
AS_HELP_STRING([--enable-module-ecdsa-s2c],[enable ECDSA sign-to-contract module [default=no]]),
[],
@@ -475,14 +470,6 @@ if test x"$enable_module_ecdsa_adaptor" = x"yes"; then
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_ECDSA_ADAPTOR=1"
fi
-if test x"$enable_module_musig" = x"yes"; then
- if test x"$enable_module_schnorrsig" = x"no"; then
- AC_MSG_ERROR([Module dependency error: You have disabled the schnorrsig module explicitly, but it is required by the musig module.])
- fi
- SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_MUSIG=1"
- enable_module_schnorrsig=yes
-fi
-
if test x"$enable_module_whitelist" = x"yes"; then
if test x"$enable_module_rangeproof" = x"no"; then
AC_MSG_ERROR([Module dependency error: You have disabled the rangeproof module explicitly, but it is required by the whitelist module.])
@@ -564,9 +551,6 @@ if test x"$enable_experimental" = x"no"; then
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_musig" = x"yes"; then
- AC_MSG_ERROR([MuSig module is experimental. Use --enable-experimental to allow.])
- fi
if test x"$enable_module_whitelist" = x"yes"; then
AC_MSG_ERROR([Key whitelisting module is experimental. Use --enable-experimental to allow.])
fi
@@ -606,7 +590,6 @@ AM_CONDITIONAL([ENABLE_MODULE_GENERATOR], [test x"$enable_module_generator" = x"
AM_CONDITIONAL([ENABLE_MODULE_RANGEPROOF], [test x"$enable_module_rangeproof" = x"yes"])
AM_CONDITIONAL([ENABLE_MODULE_SURJECTIONPROOF], [test x"$enable_module_surjectionproof" = x"yes"])
AM_CONDITIONAL([ENABLE_MODULE_WHITELIST], [test x"$enable_module_whitelist" = x"yes"])
-AM_CONDITIONAL([ENABLE_MODULE_MUSIG], [test x"$enable_module_musig" = 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([ENABLE_MODULE_BPPP], [test x"$enable_module_bppp" = x"yes"])
@@ -646,7 +629,6 @@ if test x"$enable_module_surjectionproof" = x"yes" && test x"$enable_reduced_sur
echo " reduced proof size = $enable_reduced_surjection_proof_size"
fi
echo " module whitelist = $enable_module_whitelist"
-echo " module musig = $enable_module_musig"
echo " module ecdsa-s2c = $enable_module_ecdsa_s2c"
echo " module ecdsa-adaptor = $enable_module_ecdsa_adaptor"
echo " module bppp = $enable_module_bppp"
diff --git a/contrib/musig2-vectors.py b/contrib/musig2-vectors.py
deleted file mode 100755
index 97424419..00000000
--- a/contrib/musig2-vectors.py
+++ /dev/null
@@ -1,656 +0,0 @@
-#!/usr/bin/env python3
-
-import sys
-import json
-import textwrap
-
-max_pubkeys = 0
-
-if len(sys.argv) < 2:
- print(
- "This script converts BIP MuSig2 test vectors in a given directory to a C file that can be used in the test framework."
- )
- print("Usage: %s
" % sys.argv[0])
- sys.exit(1)
-
-
-def hexstr_to_intarray(str):
- return ", ".join([f"0x{b:02X}" for b in bytes.fromhex(str)])
-
-
-def create_init(name):
- return """
-static const struct musig_%s_vector musig_%s_vector = {
-""" % (
- name,
- name,
- )
-
-
-def init_array(key):
- return textwrap.indent("{ %s },\n" % hexstr_to_intarray(data[key]), 4 * " ")
-
-
-def init_arrays(key):
- s = textwrap.indent("{\n", 4 * " ")
- s += textwrap.indent(
- ",\n".join(["{ %s }" % hexstr_to_intarray(x) for x in data[key]]), 8 * " "
- )
- s += textwrap.indent("\n},\n", 4 * " ")
- return s
-
-
-def init_indices(array):
- return " %d, { %s }" % (
- len(array),
- ", ".join(map(str, array) if len(array) > 0 else "0"),
- )
-
-
-def init_is_xonly(case):
- if len(case["tweak_indices"]) > 0:
- return ", ".join(map(lambda x: "1" if x else "0", case["is_xonly"]))
- return "0"
-
-
-def init_optional_expected(case):
- return hexstr_to_intarray(case["expected"]) if "expected" in case else 0
-
-
-def init_cases(cases, f):
- s = textwrap.indent("{\n", 4 * " ")
- for (i, case) in enumerate(cases):
- s += textwrap.indent("%s\n" % f(case), 8 * " ")
- s += textwrap.indent("},\n", 4 * " ")
- return s
-
-
-def finish_init():
- return "};\n"
-
-
-s = (
- """/**
- * Automatically generated by %s.
- *
- * The test vectors for the KeySort function are included in this file. They can
- * be found in src/modules/extrakeys/tests_impl.h. */
-"""
- % sys.argv[0]
-)
-
-
-s += """
-enum MUSIG_ERROR {
- MUSIG_PUBKEY,
- MUSIG_TWEAK,
- MUSIG_PUBNONCE,
- MUSIG_AGGNONCE,
- MUSIG_SECNONCE,
- MUSIG_SIG,
- MUSIG_SIG_VERIFY,
- MUSIG_OTHER
-};
-"""
-
-# key agg vectors
-with open(sys.argv[1] + "/key_agg_vectors.json", "r") as f:
- data = json.load(f)
-
- max_key_indices = max(
- len(test_case["key_indices"]) for test_case in data["valid_test_cases"]
- )
- max_tweak_indices = max(
- len(test_case["tweak_indices"]) for test_case in data["error_test_cases"]
- )
- num_pubkeys = len(data["pubkeys"])
- max_pubkeys = max(num_pubkeys, max_pubkeys)
- num_tweaks = len(data["tweaks"])
- num_valid_cases = len(data["valid_test_cases"])
- num_error_cases = len(data["error_test_cases"])
-
- # Add structures for valid and error cases
- s += (
- """
-struct musig_key_agg_valid_test_case {
- size_t key_indices_len;
- size_t key_indices[%d];
- unsigned char expected[32];
-};
-"""
- % max_key_indices
- )
- s += """
-struct musig_key_agg_error_test_case {
- size_t key_indices_len;
- size_t key_indices[%d];
- size_t tweak_indices_len;
- size_t tweak_indices[%d];
- int is_xonly[%d];
- enum MUSIG_ERROR error;
-};
-""" % (
- max_key_indices,
- max_tweak_indices,
- max_tweak_indices,
- )
-
- # Add structure for entire vector
- s += """
-struct musig_key_agg_vector {
- unsigned char pubkeys[%d][33];
- unsigned char tweaks[%d][32];
- struct musig_key_agg_valid_test_case valid_case[%d];
- struct musig_key_agg_error_test_case error_case[%d];
-};
-""" % (
- num_pubkeys,
- num_tweaks,
- num_valid_cases,
- num_error_cases,
- )
-
- s += create_init("key_agg")
- # Add pubkeys and tweaks to the vector
- s += init_arrays("pubkeys")
- s += init_arrays("tweaks")
-
- # Add valid cases to the vector
- s += init_cases(
- data["valid_test_cases"],
- lambda case: "{ %s, { %s }},"
- % (init_indices(case["key_indices"]), hexstr_to_intarray(case["expected"])),
- )
-
- def comment_to_error(case):
- comment = case["comment"]
- if "public key" in comment.lower():
- return "MUSIG_PUBKEY"
- elif "tweak" in comment.lower():
- return "MUSIG_TWEAK"
- else:
- sys.exit("Unknown error")
-
- # Add error cases to the vector
- s += init_cases(
- data["error_test_cases"],
- lambda case: "{ %s, %s, { %s }, %s },"
- % (
- init_indices(case["key_indices"]),
- init_indices(case["tweak_indices"]),
- init_is_xonly(case),
- comment_to_error(case),
- ),
- )
-
- s += finish_init()
-
-# nonce gen vectors
-with open(sys.argv[1] + "/nonce_gen_vectors.json", "r") as f:
- data = json.load(f)
-
- # The MuSig2 implementation only allows messages of length 32
- data["test_cases"] = list(
- filter(lambda c: c["msg"] is None or len(c["msg"]) == 64, data["test_cases"])
- )
-
- num_tests = len(data["test_cases"])
-
- s += """
-struct musig_nonce_gen_test_case {
- unsigned char rand_[32];
- int has_sk;
- unsigned char sk[32];
- unsigned char pk[33];
- int has_aggpk;
- unsigned char aggpk[32];
- int has_msg;
- unsigned char msg[32];
- int has_extra_in;
- unsigned char extra_in[32];
- unsigned char expected_secnonce[97];
- unsigned char expected_pubnonce[66];
-};
-"""
-
- s += (
- """
-struct musig_nonce_gen_vector {
- struct musig_nonce_gen_test_case test_case[%d];
-};
-"""
- % num_tests
- )
-
- s += create_init("nonce_gen")
-
- def init_array_maybe(array):
- return "%d , { %s }" % (
- 0 if array is None else 1,
- hexstr_to_intarray(array) if array is not None else 0,
- )
-
- s += init_cases(
- data["test_cases"],
- lambda case: "{ { %s }, %s, { %s }, %s, %s, %s, { %s }, { %s } },"
- % (
- hexstr_to_intarray(case["rand_"]),
- init_array_maybe(case["sk"]),
- hexstr_to_intarray(case["pk"]),
- init_array_maybe(case["aggpk"]),
- init_array_maybe(case["msg"]),
- init_array_maybe(case["extra_in"]),
- hexstr_to_intarray(case["expected_secnonce"]),
- hexstr_to_intarray(case["expected_pubnonce"]),
- ),
- )
-
- s += finish_init()
-
-# nonce agg vectors
-with open(sys.argv[1] + "/nonce_agg_vectors.json", "r") as f:
- data = json.load(f)
-
- num_pnonces = len(data["pnonces"])
- num_valid_cases = len(data["valid_test_cases"])
- num_error_cases = len(data["error_test_cases"])
-
- pnonce_indices_len = 2
- for case in data["valid_test_cases"] + data["error_test_cases"]:
- assert len(case["pnonce_indices"]) == pnonce_indices_len
-
- # Add structures for valid and error cases
- s += """
-struct musig_nonce_agg_test_case {
- size_t pnonce_indices[2];
- /* if valid case */
- unsigned char expected[66];
- /* if error case */
- int invalid_nonce_idx;
-};
-"""
- # Add structure for entire vector
- s += """
-struct musig_nonce_agg_vector {
- unsigned char pnonces[%d][66];
- struct musig_nonce_agg_test_case valid_case[%d];
- struct musig_nonce_agg_test_case error_case[%d];
-};
-""" % (
- num_pnonces,
- num_valid_cases,
- num_error_cases,
- )
-
- s += create_init("nonce_agg")
- s += init_arrays("pnonces")
-
- for cases in (data["valid_test_cases"], data["error_test_cases"]):
- s += init_cases(
- cases,
- lambda case: "{ { %s }, { %s }, %d },"
- % (
- ", ".join(map(str, case["pnonce_indices"])),
- init_optional_expected(case),
- case["error"]["signer"] if "error" in case else 0,
- ),
- )
- s += finish_init()
-
-# sign/verify vectors
-with open(sys.argv[1] + "/sign_verify_vectors.json", "r") as f:
- data = json.load(f)
-
- # The MuSig2 implementation only allows messages of length 32
- assert list(filter(lambda x: len(x) == 64, data["msgs"]))[0] == data["msgs"][0]
- data["msgs"] = [data["msgs"][0]]
-
- def filter_msg32(k):
- return list(filter(lambda x: x["msg_index"] == 0, data[k]))
-
- data["valid_test_cases"] = filter_msg32("valid_test_cases")
- data["sign_error_test_cases"] = filter_msg32("sign_error_test_cases")
- data["verify_error_test_cases"] = filter_msg32("verify_error_test_cases")
- data["verify_fail_test_cases"] = filter_msg32("verify_fail_test_cases")
-
- num_pubkeys = len(data["pubkeys"])
- max_pubkeys = max(num_pubkeys, max_pubkeys)
- num_secnonces = len(data["secnonces"])
- num_pubnonces = len(data["pnonces"])
- num_aggnonces = len(data["aggnonces"])
- num_msgs = len(data["msgs"])
- num_valid_cases = len(data["valid_test_cases"])
- num_sign_error_cases = len(data["sign_error_test_cases"])
- num_verify_fail_cases = len(data["verify_fail_test_cases"])
- num_verify_error_cases = len(data["verify_error_test_cases"])
-
- all_cases = (
- data["valid_test_cases"]
- + data["sign_error_test_cases"]
- + data["verify_error_test_cases"]
- + data["verify_fail_test_cases"]
- )
- max_key_indices = max(len(test_case["key_indices"]) for test_case in all_cases)
- max_nonce_indices = max(
- len(test_case["nonce_indices"]) if "nonce_indices" in test_case else 0
- for test_case in all_cases
- )
- # Add structures for valid and error cases
- s += (
- """
-/* Omit pubnonces in the test vectors because our partial signature verification
- * implementation is able to accept the aggnonce directly. */
-struct musig_valid_case {
- size_t key_indices_len;
- size_t key_indices[%d];
- size_t aggnonce_index;
- size_t msg_index;
- size_t signer_index;
- unsigned char expected[32];
-};
-"""
- % max_key_indices
- )
-
- s += (
- """
-struct musig_sign_error_case {
- size_t key_indices_len;
- size_t key_indices[%d];
- size_t aggnonce_index;
- size_t msg_index;
- size_t secnonce_index;
- enum MUSIG_ERROR error;
-};
-"""
- % max_key_indices
- )
-
- s += """
-struct musig_verify_fail_error_case {
- unsigned char sig[32];
- size_t key_indices_len;
- size_t key_indices[%d];
- size_t nonce_indices_len;
- size_t nonce_indices[%d];
- size_t msg_index;
- size_t signer_index;
- enum MUSIG_ERROR error;
-};
-""" % (
- max_key_indices,
- max_nonce_indices,
- )
-
- # Add structure for entire vector
- s += """
-struct musig_sign_verify_vector {
- unsigned char sk[32];
- unsigned char pubkeys[%d][33];
- unsigned char secnonces[%d][194];
- unsigned char pubnonces[%d][194];
- unsigned char aggnonces[%d][66];
- unsigned char msgs[%d][32];
- struct musig_valid_case valid_case[%d];
- struct musig_sign_error_case sign_error_case[%d];
- struct musig_verify_fail_error_case verify_fail_case[%d];
- struct musig_verify_fail_error_case verify_error_case[%d];
-};
-""" % (
- num_pubkeys,
- num_secnonces,
- num_pubnonces,
- num_aggnonces,
- num_msgs,
- num_valid_cases,
- num_sign_error_cases,
- num_verify_fail_cases,
- num_verify_error_cases,
- )
-
- s += create_init("sign_verify")
- s += init_array("sk")
- s += init_arrays("pubkeys")
- s += init_arrays("secnonces")
- s += init_arrays("pnonces")
- s += init_arrays("aggnonces")
- s += init_arrays("msgs")
-
- s += init_cases(
- data["valid_test_cases"],
- lambda case: "{ %s, %d, %d, %d, { %s }},"
- % (
- init_indices(case["key_indices"]),
- case["aggnonce_index"],
- case["msg_index"],
- case["signer_index"],
- init_optional_expected(case),
- ),
- )
-
- def sign_error(case):
- comment = case["comment"]
- if "pubkey" in comment or "public key" in comment:
- return "MUSIG_PUBKEY"
- elif "Aggregate nonce" in comment:
- return "MUSIG_AGGNONCE"
- elif "Secnonce" in comment:
- return "MUSIG_SECNONCE"
- else:
- sys.exit("Unknown sign error")
-
- s += init_cases(
- data["sign_error_test_cases"],
- lambda case: "{ %s, %d, %d, %d, %s },"
- % (
- init_indices(case["key_indices"]),
- case["aggnonce_index"],
- case["msg_index"],
- case["secnonce_index"],
- sign_error(case),
- ),
- )
-
- def verify_error(case):
- comment = case["comment"]
- if "exceeds" in comment:
- return "MUSIG_SIG"
- elif "Wrong signer" in comment or "Wrong signature" in comment:
- return "MUSIG_SIG_VERIFY"
- elif "pubnonce" in comment:
- return "MUSIG_PUBNONCE"
- elif "pubkey" in comment:
- return "MUSIG_PUBKEY"
- else:
- sys.exit("Unknown verify error")
-
- for cases in ("verify_fail_test_cases", "verify_error_test_cases"):
- s += init_cases(
- data[cases],
- lambda case: "{ { %s }, %s, %s, %d, %d, %s },"
- % (
- hexstr_to_intarray(case["sig"]),
- init_indices(case["key_indices"]),
- init_indices(case["nonce_indices"]),
- case["msg_index"],
- case["signer_index"],
- verify_error(case),
- ),
- )
-
- s += finish_init()
-
-# tweak vectors
-with open(sys.argv[1] + "/tweak_vectors.json", "r") as f:
- data = json.load(f)
-
- num_pubkeys = len(data["pubkeys"])
- max_pubkeys = max(num_pubkeys, max_pubkeys)
- num_pubnonces = len(data["pnonces"])
- num_tweaks = len(data["tweaks"])
- num_valid_cases = len(data["valid_test_cases"])
- num_error_cases = len(data["error_test_cases"])
-
- all_cases = data["valid_test_cases"] + data["error_test_cases"]
- max_key_indices = max(len(test_case["key_indices"]) for test_case in all_cases)
- max_tweak_indices = max(len(test_case["tweak_indices"]) for test_case in all_cases)
- max_nonce_indices = max(len(test_case["nonce_indices"]) for test_case in all_cases)
- # Add structures for valid and error cases
- s += """
-struct musig_tweak_case {
- size_t key_indices_len;
- size_t key_indices[%d];
- size_t nonce_indices_len;
- size_t nonce_indices[%d];
- size_t tweak_indices_len;
- size_t tweak_indices[%d];
- int is_xonly[%d];
- size_t signer_index;
- unsigned char expected[32];
-};
-""" % (
- max_key_indices,
- max_nonce_indices,
- max_tweak_indices,
- max_tweak_indices,
- )
-
- # Add structure for entire vector
- s += """
-struct musig_tweak_vector {
- unsigned char sk[32];
- unsigned char secnonce[97];
- unsigned char aggnonce[66];
- unsigned char msg[32];
- unsigned char pubkeys[%d][33];
- unsigned char pubnonces[%d][194];
- unsigned char tweaks[%d][32];
- struct musig_tweak_case valid_case[%d];
- struct musig_tweak_case error_case[%d];
-};
-""" % (
- num_pubkeys,
- num_pubnonces,
- num_tweaks,
- num_valid_cases,
- num_error_cases,
- )
- s += create_init("tweak")
- s += init_array("sk")
- s += init_array("secnonce")
- s += init_array("aggnonce")
- s += init_array("msg")
- s += init_arrays("pubkeys")
- s += init_arrays("pnonces")
- s += init_arrays("tweaks")
-
- s += init_cases(
- data["valid_test_cases"],
- lambda case: "{ %s, %s, %s, { %s }, %d, { %s }},"
- % (
- init_indices(case["key_indices"]),
- init_indices(case["nonce_indices"]),
- init_indices(case["tweak_indices"]),
- init_is_xonly(case),
- case["signer_index"],
- init_optional_expected(case),
- ),
- )
-
- s += init_cases(
- data["error_test_cases"],
- lambda case: "{ %s, %s, %s, { %s }, %d, { %s }},"
- % (
- init_indices(case["key_indices"]),
- init_indices(case["nonce_indices"]),
- init_indices(case["tweak_indices"]),
- init_is_xonly(case),
- case["signer_index"],
- init_optional_expected(case),
- ),
- )
-
- s += finish_init()
-
-# sigagg vectors
-with open(sys.argv[1] + "/sig_agg_vectors.json", "r") as f:
- data = json.load(f)
-
- num_pubkeys = len(data["pubkeys"])
- max_pubkeys = max(num_pubkeys, max_pubkeys)
- num_tweaks = len(data["tweaks"])
- num_psigs = len(data["psigs"])
- num_valid_cases = len(data["valid_test_cases"])
- num_error_cases = len(data["error_test_cases"])
-
- all_cases = data["valid_test_cases"] + data["error_test_cases"]
- max_key_indices = max(len(test_case["key_indices"]) for test_case in all_cases)
- max_tweak_indices = max(len(test_case["tweak_indices"]) for test_case in all_cases)
- max_psig_indices = max(len(test_case["psig_indices"]) for test_case in all_cases)
-
- # Add structures for valid and error cases
- s += """
-/* Omit pubnonces in the test vectors because they're only needed for
- * implementations that do not directly accept an aggnonce. */
-struct musig_sig_agg_case {
- size_t key_indices_len;
- size_t key_indices[%d];
- size_t tweak_indices_len;
- size_t tweak_indices[%d];
- int is_xonly[%d];
- unsigned char aggnonce[66];
- size_t psig_indices_len;
- size_t psig_indices[%d];
- /* if valid case */
- unsigned char expected[64];
- /* if error case */
- int invalid_sig_idx;
-};
-""" % (
- max_key_indices,
- max_tweak_indices,
- max_tweak_indices,
- max_psig_indices,
- )
-
- # Add structure for entire vector
- s += """
-struct musig_sig_agg_vector {
- unsigned char pubkeys[%d][33];
- unsigned char tweaks[%d][32];
- unsigned char psigs[%d][32];
- unsigned char msg[32];
- struct musig_sig_agg_case valid_case[%d];
- struct musig_sig_agg_case error_case[%d];
-};
-""" % (
- num_pubkeys,
- num_tweaks,
- num_psigs,
- num_valid_cases,
- num_error_cases,
- )
-
- s += create_init("sig_agg")
- s += init_arrays("pubkeys")
- s += init_arrays("tweaks")
- s += init_arrays("psigs")
- s += init_array("msg")
-
- for cases in (data["valid_test_cases"], data["error_test_cases"]):
- s += init_cases(
- cases,
- lambda case: "{ %s, %s, { %s }, { %s }, %s, { %s }, %d },"
- % (
- init_indices(case["key_indices"]),
- init_indices(case["tweak_indices"]),
- init_is_xonly(case),
- hexstr_to_intarray(case["aggnonce"]),
- init_indices(case["psig_indices"]),
- init_optional_expected(case),
- case["error"]["signer"] if "error" in case else 0,
- ),
- )
- s += finish_init()
-s += "enum { MUSIG_VECTORS_MAX_PUBKEYS = %d };" % max_pubkeys
-print(s)
diff --git a/doc/musig-spec.mediawiki b/doc/musig-spec.mediawiki
deleted file mode 100644
index 017a0c3e..00000000
--- a/doc/musig-spec.mediawiki
+++ /dev/null
@@ -1 +0,0 @@
-This document was moved to [https://github.com/jonasnick/bips/blob/musig2/bip-musig2.mediawiki https://github.com/jonasnick/bips/blob/musig2/bip-musig2.mediawiki].
\ No newline at end of file
diff --git a/examples/musig.c b/examples/musig.c
deleted file mode 100644
index d4a02195..00000000
--- a/examples/musig.c
+++ /dev/null
@@ -1,214 +0,0 @@
-/*************************************************************************
- * Written in 2018 by Jonas Nick *
- * To the extent possible under law, the author(s) have dedicated all *
- * copyright and related and neighboring rights to the software in this *
- * file to the public domain worldwide. This software is distributed *
- * without any warranty. For the CC0 Public Domain Dedication, see *
- * EXAMPLES_COPYING or https://creativecommons.org/publicdomain/zero/1.0 *
- *************************************************************************/
-
-/** This file demonstrates how to use the MuSig module to create a
- * 3-of-3 multisignature. Additionally, see the documentation in
- * include/secp256k1_musig.h and src/modules/musig/musig.md.
- */
-
-#include
-#include
-#include
-
-#include
-#include
-#include
-
-#include "examples_util.h"
-
-struct signer_secrets {
- secp256k1_keypair keypair;
- secp256k1_musig_secnonce secnonce;
-};
-
-struct signer {
- secp256k1_pubkey pubkey;
- secp256k1_musig_pubnonce pubnonce;
- secp256k1_musig_partial_sig partial_sig;
-};
-
- /* Number of public keys involved in creating the aggregate signature */
-#define N_SIGNERS 3
-/* Create a key pair, store it in signer_secrets->keypair and signer->pubkey */
-static int create_keypair(const secp256k1_context* ctx, struct signer_secrets *signer_secrets, struct signer *signer) {
- unsigned char seckey[32];
- while (1) {
- if (!fill_random(seckey, sizeof(seckey))) {
- printf("Failed to generate randomness\n");
- return 1;
- }
- if (secp256k1_keypair_create(ctx, &signer_secrets->keypair, seckey)) {
- break;
- }
- }
- if (!secp256k1_keypair_pub(ctx, &signer->pubkey, &signer_secrets->keypair)) {
- return 0;
- }
- return 1;
-}
-
-/* Tweak the pubkey corresponding to the provided keyagg cache, update the cache
- * and return the tweaked aggregate pk. */
-static int tweak(const secp256k1_context* ctx, secp256k1_xonly_pubkey *agg_pk, secp256k1_musig_keyagg_cache *cache) {
- secp256k1_pubkey output_pk;
- unsigned char plain_tweak[32] = "this could be a BIP32 tweak....";
- unsigned char xonly_tweak[32] = "this could be a taproot tweak..";
-
-
- /* Plain tweaking which, for example, allows deriving multiple child
- * public keys from a single aggregate key using BIP32 */
- if (!secp256k1_musig_pubkey_ec_tweak_add(ctx, NULL, cache, plain_tweak)) {
- return 0;
- }
- /* Note that we did not provided an output_pk argument, because the
- * resulting pk is also saved in the cache and so if one is just interested
- * in signing the output_pk argument is unnecessary. On the other hand, if
- * one is not interested in signing, the same output_pk can be obtained by
- * calling `secp256k1_musig_pubkey_get` right after key aggregation to get
- * the full pubkey and then call `secp256k1_ec_pubkey_tweak_add`. */
-
- /* Xonly tweaking which, for example, allows creating taproot commitments */
- if (!secp256k1_musig_pubkey_xonly_tweak_add(ctx, &output_pk, cache, xonly_tweak)) {
- return 0;
- }
- /* Note that if we wouldn't care about signing, we can arrive at the same
- * output_pk by providing the untweaked public key to
- * `secp256k1_xonly_pubkey_tweak_add` (after converting it to an xonly pubkey
- * if necessary with `secp256k1_xonly_pubkey_from_pubkey`). */
-
- /* Now we convert the output_pk to an xonly pubkey to allow to later verify
- * the Schnorr signature against it. For this purpose we can ignore the
- * `pk_parity` output argument; we would need it if we would have to open
- * the taproot commitment. */
- if (!secp256k1_xonly_pubkey_from_pubkey(ctx, agg_pk, NULL, &output_pk)) {
- return 0;
- }
- return 1;
-}
-
-/* Sign a message hash with the given key pairs and store the result in sig */
-static int sign(const secp256k1_context* ctx, struct signer_secrets *signer_secrets, struct signer *signer, const secp256k1_musig_keyagg_cache *cache, const unsigned char *msg32, unsigned char *sig64) {
- int i;
- const secp256k1_musig_pubnonce *pubnonces[N_SIGNERS];
- const secp256k1_musig_partial_sig *partial_sigs[N_SIGNERS];
- /* The same for all signers */
- secp256k1_musig_session session;
-
- for (i = 0; i < N_SIGNERS; i++) {
- unsigned char seckey[32];
- unsigned char session_id[32];
- /* Create random session ID. It is absolutely necessary that the session ID
- * is unique for every call of secp256k1_musig_nonce_gen. Otherwise
- * it's trivial for an attacker to extract the secret key! */
- if (!fill_random(session_id, sizeof(session_id))) {
- return 0;
- }
- if (!secp256k1_keypair_sec(ctx, seckey, &signer_secrets[i].keypair)) {
- return 0;
- }
- /* Initialize session and create secret nonce for signing and public
- * nonce to send to the other signers. */
- if (!secp256k1_musig_nonce_gen(ctx, &signer_secrets[i].secnonce, &signer[i].pubnonce, session_id, seckey, &signer[i].pubkey, msg32, NULL, NULL)) {
- return 0;
- }
- pubnonces[i] = &signer[i].pubnonce;
- }
- /* Communication round 1: A production system would exchange public nonces
- * here before moving on. */
- for (i = 0; i < N_SIGNERS; i++) {
- secp256k1_musig_aggnonce agg_pubnonce;
-
- /* Create aggregate nonce and initialize the session */
- if (!secp256k1_musig_nonce_agg(ctx, &agg_pubnonce, pubnonces, N_SIGNERS)) {
- return 0;
- }
- if (!secp256k1_musig_nonce_process(ctx, &session, &agg_pubnonce, msg32, cache, NULL)) {
- return 0;
- }
- /* partial_sign will clear the secnonce by setting it to 0. That's because
- * you must _never_ reuse the secnonce (or use the same session_id to
- * create a secnonce). If you do, you effectively reuse the nonce and
- * leak the secret key. */
- if (!secp256k1_musig_partial_sign(ctx, &signer[i].partial_sig, &signer_secrets[i].secnonce, &signer_secrets[i].keypair, cache, &session)) {
- return 0;
- }
- partial_sigs[i] = &signer[i].partial_sig;
- }
- /* Communication round 2: A production system would exchange
- * partial signatures here before moving on. */
- for (i = 0; i < N_SIGNERS; i++) {
- /* To check whether signing was successful, it suffices to either verify
- * the aggregate signature with the aggregate public key using
- * secp256k1_schnorrsig_verify, or verify all partial signatures of all
- * signers individually. Verifying the aggregate signature is cheaper but
- * verifying the individual partial signatures has the advantage that it
- * can be used to determine which of the partial signatures are invalid
- * (if any), i.e., which of the partial signatures cause the aggregate
- * signature to be invalid and thus the protocol run to fail. It's also
- * fine to first verify the aggregate sig, and only verify the individual
- * sigs if it does not work.
- */
- if (!secp256k1_musig_partial_sig_verify(ctx, &signer[i].partial_sig, &signer[i].pubnonce, &signer[i].pubkey, cache, &session)) {
- return 0;
- }
- }
- return secp256k1_musig_partial_sig_agg(ctx, sig64, &session, partial_sigs, N_SIGNERS);
-}
-
- int main(void) {
- secp256k1_context* ctx;
- int i;
- struct signer_secrets signer_secrets[N_SIGNERS];
- struct signer signers[N_SIGNERS];
- const secp256k1_pubkey *pubkeys_ptr[N_SIGNERS];
- secp256k1_xonly_pubkey agg_pk;
- secp256k1_musig_keyagg_cache cache;
- unsigned char msg[] = {'t', 'h', 'i', 's', '_', 'c', 'o', 'u', 'l', 'd', ' ', 'b', 'e', ' ', 't', 'h', 'e', '_', 'h', 'a', 's', 'h', '_', 'o', 'f', '_', 'a', '_', 'm', 's', 'g', '!'};
- unsigned char sig[64];
-
- /* Create a secp256k1 context */
- ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
- printf("Creating key pairs......");
- for (i = 0; i < N_SIGNERS; i++) {
- if (!create_keypair(ctx, &signer_secrets[i], &signers[i])) {
- printf("FAILED\n");
- return 1;
- }
- pubkeys_ptr[i] = &signers[i].pubkey;
- }
- printf("ok\n");
- printf("Combining public keys...");
- /* If you just want to aggregate and not sign the cache can be NULL */
- if (!secp256k1_musig_pubkey_agg(ctx, NULL, &agg_pk, &cache, pubkeys_ptr, N_SIGNERS)) {
- printf("FAILED\n");
- return 1;
- }
- printf("ok\n");
- printf("Tweaking................");
- /* Optionally tweak the aggregate key */
- if (!tweak(ctx, &agg_pk, &cache)) {
- printf("FAILED\n");
- return 1;
- }
- printf("ok\n");
- printf("Signing message.........");
- if (!sign(ctx, signer_secrets, signers, &cache, msg, sig)) {
- printf("FAILED\n");
- return 1;
- }
- printf("ok\n");
- printf("Verifying signature.....");
- if (!secp256k1_schnorrsig_verify(ctx, sig, msg, 32, &agg_pk)) {
- printf("FAILED\n");
- return 1;
- }
- printf("ok\n");
- secp256k1_context_destroy(ctx);
- return 0;
-}
diff --git a/include/secp256k1_musig.h b/include/secp256k1_musig.h
deleted file mode 100644
index 0c539e8a..00000000
--- a/include/secp256k1_musig.h
+++ /dev/null
@@ -1,609 +0,0 @@
-#ifndef SECP256K1_MUSIG_H
-#define SECP256K1_MUSIG_H
-
-#include "secp256k1_extrakeys.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include
-
-/** This module implements BIP 327 "MuSig2 for BIP340-compatible
- * Multi-Signatures"
- * (https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki)
- * v1.0.0. You can find an example demonstrating the musig module in
- * examples/musig.c.
- *
- * The module also supports BIP-341 ("Taproot") public key tweaking and adaptor
- * signatures as described in
- * https://github.com/ElementsProject/scriptless-scripts/pull/24.
- *
- * It is recommended to read the documentation in this include file carefully.
- * Further notes on API usage can be found in src/modules/musig/musig.md
- *
- * Since the first version of MuSig is essentially replaced by MuSig2, we use
- * MuSig, musig and MuSig2 synonymously unless noted otherwise.
- */
-
-/** Opaque data structures
- *
- * The exact representation of data inside is implementation defined and not
- * guaranteed to be portable between different platforms or versions. If you
- * need to convert to a format suitable for storage, transmission, or
- * comparison, use the corresponding serialization and parsing functions.
- */
-
-/** Opaque data structure that caches information about public key aggregation.
- *
- * Guaranteed to be 197 bytes in size. It can be safely copied/moved. No
- * serialization and parsing functions (yet).
- */
-typedef struct {
- unsigned char data[197];
-} secp256k1_musig_keyagg_cache;
-
-/** Opaque data structure that holds a signer's _secret_ nonce.
- *
- * Guaranteed to be 132 bytes in size.
- *
- * WARNING: This structure MUST NOT be copied or read or written to directly. A
- * signer who is online throughout the whole process and can keep this
- * structure in memory can use the provided API functions for a safe standard
- * workflow. See
- * https://blockstream.com/2019/02/18/musig-a-new-multisignature-standard/ for
- * more details about the risks associated with serializing or deserializing
- * this structure.
- *
- * We repeat, copying this data structure can result in nonce reuse which will
- * leak the secret signing key.
- */
-typedef struct {
- unsigned char data[132];
-} secp256k1_musig_secnonce;
-
-/** Opaque data structure that holds a signer's public nonce.
-*
-* Guaranteed to be 132 bytes in size. It can be safely copied/moved. Serialized
-* and parsed with `musig_pubnonce_serialize` and `musig_pubnonce_parse`.
-*/
-typedef struct {
- unsigned char data[132];
-} secp256k1_musig_pubnonce;
-
-/** Opaque data structure that holds an aggregate public nonce.
- *
- * Guaranteed to be 132 bytes in size. It can be safely copied/moved.
- * Serialized and parsed with `musig_aggnonce_serialize` and
- * `musig_aggnonce_parse`.
- */
-typedef struct {
- unsigned char data[132];
-} secp256k1_musig_aggnonce;
-
-/** Opaque data structure that holds a MuSig session.
- *
- * This structure is not required to be kept secret for the signing protocol to
- * be secure. Guaranteed to be 133 bytes in size. It can be safely
- * copied/moved. No serialization and parsing functions (yet).
- */
-typedef struct {
- unsigned char data[133];
-} secp256k1_musig_session;
-
-/** Opaque data structure that holds a partial MuSig signature.
- *
- * Guaranteed to be 36 bytes in size. Serialized and parsed with
- * `musig_partial_sig_serialize` and `musig_partial_sig_parse`.
- */
-typedef struct {
- unsigned char data[36];
-} secp256k1_musig_partial_sig;
-
-/** Parse a signer's public nonce.
- *
- * Returns: 1 when the nonce could be parsed, 0 otherwise.
- * Args: ctx: pointer to a context object
- * Out: nonce: pointer to a nonce object
- * In: in66: pointer to the 66-byte nonce to be parsed
- */
-SECP256K1_API int secp256k1_musig_pubnonce_parse(
- const secp256k1_context *ctx,
- secp256k1_musig_pubnonce *nonce,
- const unsigned char *in66
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
-
-/** Serialize a signer's public nonce
- *
- * Returns: 1 when the nonce could be serialized, 0 otherwise
- * Args: ctx: pointer to a context object
- * Out: out66: pointer to a 66-byte array to store the serialized nonce
- * In: nonce: pointer to the nonce
- */
-SECP256K1_API int secp256k1_musig_pubnonce_serialize(
- const secp256k1_context *ctx,
- unsigned char *out66,
- const secp256k1_musig_pubnonce *nonce
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
-
-/** Parse an aggregate public nonce.
- *
- * Returns: 1 when the nonce could be parsed, 0 otherwise.
- * Args: ctx: pointer to a context object
- * Out: nonce: pointer to a nonce object
- * In: in66: pointer to the 66-byte nonce to be parsed
- */
-SECP256K1_API int secp256k1_musig_aggnonce_parse(
- const secp256k1_context *ctx,
- secp256k1_musig_aggnonce *nonce,
- const unsigned char *in66
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
-
-/** Serialize an aggregate public nonce
- *
- * Returns: 1 when the nonce could be serialized, 0 otherwise
- * Args: ctx: pointer to a context object
- * Out: out66: pointer to a 66-byte array to store the serialized nonce
- * In: nonce: pointer to the nonce
- */
-SECP256K1_API int secp256k1_musig_aggnonce_serialize(
- const secp256k1_context *ctx,
- unsigned char *out66,
- const secp256k1_musig_aggnonce *nonce
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
-
-/** Serialize a MuSig partial signature
- *
- * Returns: 1 when the signature could be serialized, 0 otherwise
- * Args: ctx: pointer to a context object
- * Out: out32: pointer to a 32-byte array to store the serialized signature
- * In: sig: pointer to the signature
- */
-SECP256K1_API int secp256k1_musig_partial_sig_serialize(
- const secp256k1_context *ctx,
- unsigned char *out32,
- const secp256k1_musig_partial_sig *sig
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
-
-/** Parse a MuSig partial signature.
- *
- * Returns: 1 when the signature could be parsed, 0 otherwise.
- * Args: ctx: pointer to a context object
- * Out: sig: pointer to a signature object
- * In: in32: pointer to the 32-byte signature to be parsed
- *
- * After the call, sig will always be initialized. If parsing failed or the
- * encoded numbers are out of range, signature verification with it is
- * guaranteed to fail for every message and public key.
- */
-SECP256K1_API int secp256k1_musig_partial_sig_parse(
- const secp256k1_context *ctx,
- secp256k1_musig_partial_sig *sig,
- const unsigned char *in32
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
-
-/** Computes an aggregate public key and uses it to initialize a keyagg_cache
- *
- * Different orders of `pubkeys` result in different `agg_pk`s.
- *
- * Before aggregating, the pubkeys can be sorted with `secp256k1_ec_pubkey_sort`
- * which ensures the same `agg_pk` result for the same multiset of pubkeys.
- * This is useful to do before `pubkey_agg`, such that the order of pubkeys
- * does not affect the aggregate public key.
- *
- * Returns: 0 if the arguments are invalid, 1 otherwise
- * Args: ctx: pointer to a context object
- * scratch: should be NULL because it is not yet implemented. If it
- * was implemented then the scratch space would be used to
- * compute the aggregate pubkey by multiexponentiation.
- * Generally, the larger the scratch space, the faster this
- * function. However, the returns of providing a larger
- * scratch space are diminishing. If NULL, an inefficient
- * algorithm is used.
- * Out: agg_pk: the MuSig-aggregated x-only public key. If you do not need it,
- * this arg can be NULL.
- * keyagg_cache: if non-NULL, pointer to a musig_keyagg_cache struct that
- * is required for signing (or observing the signing session
- * and verifying partial signatures).
- * In: pubkeys: input array of pointers to public keys to aggregate. The order
- * is important; a different order will result in a different
- * aggregate public key.
- * n_pubkeys: length of pubkeys array. Must be greater than 0.
- */
-SECP256K1_API int secp256k1_musig_pubkey_agg(
- const secp256k1_context *ctx,
- secp256k1_scratch_space *scratch,
- secp256k1_xonly_pubkey *agg_pk,
- secp256k1_musig_keyagg_cache *keyagg_cache,
- const secp256k1_pubkey * const *pubkeys,
- size_t n_pubkeys
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(5);
-
-/** Obtain the aggregate public key from a keyagg_cache.
- *
- * This is only useful if you need the non-xonly public key, in particular for
- * plain (non-xonly) tweaking or batch-verifying multiple key aggregations
- * (not implemented).
- *
- * Returns: 0 if the arguments are invalid, 1 otherwise
- * Args: ctx: pointer to a context object
- * Out: agg_pk: the MuSig-aggregated public key.
- * In: keyagg_cache: pointer to a `musig_keyagg_cache` struct initialized by
- * `musig_pubkey_agg`
- */
-SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_pubkey_get(
- const secp256k1_context *ctx,
- secp256k1_pubkey *agg_pk,
- const secp256k1_musig_keyagg_cache *keyagg_cache
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
-
-/** Apply plain "EC" tweaking to a public key in a given keyagg_cache by
- * adding the generator multiplied with `tweak32` to it. This is useful for
- * deriving child keys from an aggregate public key via BIP32.
- *
- * The tweaking method is the same as `secp256k1_ec_pubkey_tweak_add`. So after
- * the following pseudocode buf and buf2 have identical contents (absent
- * earlier failures).
- *
- * secp256k1_musig_pubkey_agg(..., keyagg_cache, pubkeys, ...)
- * secp256k1_musig_pubkey_get(..., agg_pk, keyagg_cache)
- * secp256k1_musig_pubkey_ec_tweak_add(..., output_pk, tweak32, keyagg_cache)
- * secp256k1_ec_pubkey_serialize(..., buf, output_pk)
- * secp256k1_ec_pubkey_tweak_add(..., agg_pk, tweak32)
- * secp256k1_ec_pubkey_serialize(..., buf2, agg_pk)
- *
- * This function is required if you want to _sign_ for a tweaked aggregate key.
- * On the other hand, if you are only computing a public key, but not intending
- * to create a signature for it, you can just use
- * `secp256k1_ec_pubkey_tweak_add`.
- *
- * Returns: 0 if the arguments are invalid or the resulting public key would be
- * invalid (only when the tweak is the negation of the corresponding
- * secret key). 1 otherwise.
- * Args: ctx: pointer to a context object
- * Out: output_pubkey: pointer to a public key to store the result. Will be set
- * to an invalid value if this function returns 0. If you
- * do not need it, this arg can be NULL.
- * In/Out: keyagg_cache: pointer to a `musig_keyagg_cache` struct initialized by
- * `musig_pubkey_agg`
- * In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid
- * according to `secp256k1_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).
- */
-SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_pubkey_ec_tweak_add(
- const secp256k1_context *ctx,
- secp256k1_pubkey *output_pubkey,
- secp256k1_musig_keyagg_cache *keyagg_cache,
- const unsigned char *tweak32
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
-
-/** Apply x-only tweaking to a public key in a given keyagg_cache by adding the
- * generator multiplied with `tweak32` to it. This is useful for creating
- * Taproot outputs.
- *
- * The tweaking method is the same as `secp256k1_xonly_pubkey_tweak_add`. So in
- * the following pseudocode xonly_pubkey_tweak_add_check (absent earlier
- * failures) returns 1.
- *
- * secp256k1_musig_pubkey_agg(..., agg_pk, keyagg_cache, pubkeys, ...)
- * secp256k1_musig_pubkey_xonly_tweak_add(..., output_pk, tweak32, keyagg_cache)
- * secp256k1_xonly_pubkey_serialize(..., buf, output_pk)
- * secp256k1_xonly_pubkey_tweak_add_check(..., buf, ..., agg_pk, tweak32)
- *
- * This function is required if you want to _sign_ for a tweaked aggregate key.
- * On the other hand, if you are only computing a public key, but not intending
- * to create a signature for it, you can just use
- * `secp256k1_xonly_pubkey_tweak_add`.
- *
- * Returns: 0 if the arguments are invalid or the resulting public key would be
- * invalid (only when the tweak is the negation of the corresponding
- * secret key). 1 otherwise.
- * Args: ctx: pointer to a context object
- * Out: output_pubkey: pointer to a public key to store the result. Will be set
- * to an invalid value if this function returns 0. If you
- * do not need it, this arg can be NULL.
- * In/Out: keyagg_cache: pointer to a `musig_keyagg_cache` struct initialized by
- * `musig_pubkey_agg`
- * In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid
- * according to secp256k1_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).
- */
-SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_pubkey_xonly_tweak_add(
- const secp256k1_context *ctx,
- secp256k1_pubkey *output_pubkey,
- secp256k1_musig_keyagg_cache *keyagg_cache,
- const unsigned char *tweak32
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
-
-/** Starts a signing session by generating a nonce
- *
- * This function outputs a secret nonce that will be required for signing and a
- * corresponding public nonce that is intended to be sent to other signers.
- *
- * MuSig differs from regular Schnorr signing in that implementers _must_ take
- * special care to not reuse a nonce. This can be ensured by following these rules:
- *
- * 1. Each call to this function must have a UNIQUE session_id32 that must NOT BE
- * REUSED in subsequent calls to this function.
- * If you do not provide a seckey, session_id32 _must_ be UNIFORMLY RANDOM
- * AND KEPT SECRET (even from other signers). If you do provide a seckey,
- * session_id32 can instead be a counter (that must never repeat!). However,
- * it is recommended to always choose session_id32 uniformly at random.
- * 2. If you already know the seckey, message or aggregate public key
- * cache, they can be optionally provided to derive the nonce and increase
- * misuse-resistance. The extra_input32 argument can be used to provide
- * additional data that does not repeat in normal scenarios, such as the
- * current time.
- * 3. Avoid copying (or serializing) the secnonce. This reduces the possibility
- * that it is used more than once for signing.
- *
- * Remember that nonce reuse will leak the secret key!
- * Note that using the same seckey for multiple MuSig sessions is fine.
- *
- * Returns: 0 if the arguments are invalid and 1 otherwise
- * Args: ctx: pointer to a context object (not secp256k1_context_static)
- * Out: secnonce: pointer to a structure to store the secret nonce
- * pubnonce: pointer to a structure to store the public nonce
- * In: session_id32: a 32-byte session_id32 as explained above. Must be unique to this
- * call to secp256k1_musig_nonce_gen and must be uniformly random
- * unless you really know what you are doing.
- * seckey: the 32-byte secret key that will later be used for signing, if
- * already known (can be NULL)
- * pubkey: public key of the signer creating the nonce. The secnonce
- * output of this function cannot be used to sign for any
- * other public key.
- * msg32: the 32-byte message that will later be signed, if already known
- * (can be NULL)
- * keyagg_cache: pointer to the keyagg_cache that was used to create the aggregate
- * (and potentially tweaked) public key if already known
- * (can be NULL)
- * extra_input32: an optional 32-byte array that is input to the nonce
- * derivation function (can be NULL)
- */
-SECP256K1_API int secp256k1_musig_nonce_gen(
- const secp256k1_context *ctx,
- secp256k1_musig_secnonce *secnonce,
- secp256k1_musig_pubnonce *pubnonce,
- const unsigned char *session_id32,
- const unsigned char *seckey,
- const secp256k1_pubkey *pubkey,
- const unsigned char *msg32,
- const secp256k1_musig_keyagg_cache *keyagg_cache,
- const unsigned char *extra_input32
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(6);
-
-/** Aggregates the nonces of all signers into a single nonce
- *
- * This can be done by an untrusted party to reduce the communication
- * between signers. Instead of everyone sending nonces to everyone else, there
- * can be one party receiving all nonces, aggregating the nonces with this
- * function and then sending only the aggregate nonce back to the signers.
- *
- * Returns: 0 if the arguments are invalid, 1 otherwise
- * Args: ctx: pointer to a context object
- * Out: aggnonce: pointer to an aggregate public nonce object for
- * musig_nonce_process
- * In: pubnonces: array of pointers to public nonces sent by the
- * signers
- * n_pubnonces: number of elements in the pubnonces array. Must be
- * greater than 0.
- */
-SECP256K1_API int secp256k1_musig_nonce_agg(
- const secp256k1_context *ctx,
- secp256k1_musig_aggnonce *aggnonce,
- const secp256k1_musig_pubnonce * const *pubnonces,
- size_t n_pubnonces
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
-
-/** Takes the public nonces of all signers and computes a session that is
- * required for signing and verification of partial signatures.
- *
- * If the adaptor argument is non-NULL, then the output of
- * musig_partial_sig_agg will be a pre-signature which is not a valid Schnorr
- * signature. In order to create a valid signature, the pre-signature and the
- * secret adaptor must be provided to `musig_adapt`.
- *
- * Returns: 0 if the arguments are invalid or if some signer sent invalid
- * pubnonces, 1 otherwise
- * Args: ctx: pointer to a context object
- * Out: session: pointer to a struct to store the session
- * In: aggnonce: pointer to an aggregate public nonce object that is the
- * output of musig_nonce_agg
- * msg32: the 32-byte message to sign
- * keyagg_cache: pointer to the keyagg_cache that was used to create the
- * aggregate (and potentially tweaked) pubkey
- * adaptor: optional pointer to an adaptor point encoded as a public
- * key if this signing session is part of an adaptor
- * signature protocol (can be NULL)
- */
-SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_nonce_process(
- const secp256k1_context *ctx,
- secp256k1_musig_session *session,
- const secp256k1_musig_aggnonce *aggnonce,
- const unsigned char *msg32,
- const secp256k1_musig_keyagg_cache *keyagg_cache,
- const secp256k1_pubkey *adaptor
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
-
-/** Produces a partial signature
- *
- * This function overwrites the given secnonce with zeros and will abort if given a
- * secnonce that is all zeros. This is a best effort attempt to protect against nonce
- * reuse. However, this is of course easily defeated if the secnonce has been
- * copied (or serialized). Remember that nonce reuse will leak the secret key!
- *
- * For signing to succeed, the secnonce provided to this function must have
- * been generated for the provided keypair. This means that when signing for a
- * keypair consisting of a seckey and pubkey, the secnonce must have been
- * created by calling musig_nonce_gen with that pubkey. Otherwise, the
- * illegal_callback is called.
- *
- * This function does not verify the output partial signature, deviating from
- * the BIP 327 specification. It is recommended to verify the output partial
- * signature with `secp256k1_musig_partial_sig_verify` to prevent random or
- * adversarially provoked computation errors.
- *
- * Returns: 0 if the arguments are invalid or the provided secnonce has already
- * been used for signing, 1 otherwise
- * Args: ctx: pointer to a context object
- * Out: partial_sig: pointer to struct to store the partial signature
- * In/Out: secnonce: pointer to the secnonce struct created in
- * musig_nonce_gen that has been never used in a
- * partial_sign call before and has been created for the
- * keypair
- * In: keypair: pointer to keypair to sign the message with
- * keyagg_cache: pointer to the keyagg_cache that was output when the
- * aggregate public key for this session
- * session: pointer to the session that was created with
- * musig_nonce_process
- */
-SECP256K1_API int secp256k1_musig_partial_sign(
- const secp256k1_context *ctx,
- secp256k1_musig_partial_sig *partial_sig,
- secp256k1_musig_secnonce *secnonce,
- const secp256k1_keypair *keypair,
- const secp256k1_musig_keyagg_cache *keyagg_cache,
- const secp256k1_musig_session *session
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6);
-
-/** Verifies an individual signer's partial signature
- *
- * The signature is verified for a specific signing session. In order to avoid
- * accidentally verifying a signature from a different or non-existing signing
- * session, you must ensure the following:
- * 1. The `keyagg_cache` argument is identical to the one used to create the
- * `session` with `musig_nonce_process`.
- * 2. The `pubkey` argument must be identical to the one sent by the signer
- * before aggregating it with `musig_pubkey_agg` to create the
- * `keyagg_cache`.
- * 3. The `pubnonce` argument must be identical to the one sent by the signer
- * before aggregating it with `musig_nonce_agg` and using the result to
- * create the `session` with `musig_nonce_process`.
- *
- * This function is essential when using protocols with adaptor signatures.
- * However, it is not essential for regular MuSig sessions, in the sense that if any
- * partial signature does not verify, the full signature will not verify either, so the
- * problem will be caught. But this function allows determining the specific party
- * who produced an invalid signature.
- *
- * Returns: 0 if the arguments are invalid or the partial signature does not
- * verify, 1 otherwise
- * Args ctx: pointer to a context object
- * In: partial_sig: pointer to partial signature to verify, sent by
- * the signer associated with `pubnonce` and `pubkey`
- * pubnonce: public nonce of the signer in the signing session
- * pubkey: public key of the signer in the signing session
- * keyagg_cache: pointer to the keyagg_cache that was output when the
- * aggregate public key for this signing session
- * session: pointer to the session that was created with
- * `musig_nonce_process`
- */
-SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_partial_sig_verify(
- const secp256k1_context *ctx,
- const secp256k1_musig_partial_sig *partial_sig,
- const secp256k1_musig_pubnonce *pubnonce,
- const secp256k1_pubkey *pubkey,
- const secp256k1_musig_keyagg_cache *keyagg_cache,
- const secp256k1_musig_session *session
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6);
-
-/** Aggregates partial signatures
- *
- * Returns: 0 if the arguments are invalid, 1 otherwise (which does NOT mean
- * the resulting signature verifies).
- * Args: ctx: pointer to a context object
- * Out: sig64: complete (but possibly invalid) Schnorr signature
- * In: session: pointer to the session that was created with
- * musig_nonce_process
- * partial_sigs: array of pointers to partial signatures to aggregate
- * n_sigs: number of elements in the partial_sigs array. Must be
- * greater than 0.
- */
-SECP256K1_API int secp256k1_musig_partial_sig_agg(
- const secp256k1_context *ctx,
- unsigned char *sig64,
- const secp256k1_musig_session *session,
- const secp256k1_musig_partial_sig * const *partial_sigs,
- size_t n_sigs
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
-
-/** Extracts the nonce_parity bit from a session
- *
- * This is used for adaptor signatures.
- *
- * Returns: 0 if the arguments are invalid, 1 otherwise
- * Args: ctx: pointer to a context object
- * Out: nonce_parity: pointer to an integer that indicates the parity
- * of the aggregate public nonce. Used for adaptor
- * signatures.
- * In: session: pointer to the session that was created with
- * musig_nonce_process
- */
-SECP256K1_API int secp256k1_musig_nonce_parity(
- const secp256k1_context *ctx,
- int *nonce_parity,
- const secp256k1_musig_session *session
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
-
-/** Creates a signature from a pre-signature and an adaptor.
- *
- * If the sec_adaptor32 argument is incorrect, the output signature will be
- * invalid. This function does not verify the signature.
- *
- * Returns: 0 if the arguments are invalid, or pre_sig64 or sec_adaptor32 contain
- * invalid (overflowing) values. 1 otherwise (which does NOT mean the
- * signature or the adaptor are valid!)
- * Args: ctx: pointer to a context object
- * Out: sig64: 64-byte signature. This pointer may point to the same
- * memory area as `pre_sig`.
- * In: pre_sig64: 64-byte pre-signature
- * sec_adaptor32: 32-byte secret adaptor to add to the pre-signature
- * nonce_parity: the output of `musig_nonce_parity` called with the
- * session used for producing the pre-signature
- */
-SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_adapt(
- const secp256k1_context *ctx,
- unsigned char *sig64,
- const unsigned char *pre_sig64,
- const unsigned char *sec_adaptor32,
- int nonce_parity
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
-
-/** Extracts a secret adaptor from a MuSig pre-signature and corresponding
- * signature
- *
- * This function will not fail unless given grossly invalid data; if it is
- * merely given signatures that do not verify, the returned value will be
- * nonsense. It is therefore important that all data be verified at earlier
- * steps of any protocol that uses this function. In particular, this includes
- * verifying all partial signatures that were aggregated into pre_sig64.
- *
- * Returns: 0 if the arguments are NULL, or sig64 or pre_sig64 contain
- * grossly invalid (overflowing) values. 1 otherwise (which does NOT
- * mean the signatures or the adaptor are valid!)
- * Args: ctx: pointer to a context object
- * Out:sec_adaptor32: 32-byte secret adaptor
- * In: sig64: complete, valid 64-byte signature
- * pre_sig64: the pre-signature corresponding to sig64, i.e., the
- * aggregate of partial signatures without the secret
- * adaptor
- * nonce_parity: the output of `musig_nonce_parity` called with the
- * session used for producing sig64
- */
-SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_extract_adaptor(
- const secp256k1_context *ctx,
- unsigned char *sec_adaptor32,
- const unsigned char *sig64,
- const unsigned char *pre_sig64,
- int nonce_parity
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 27e90204..7c0871ba 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -129,9 +129,6 @@ if(SECP256K1_INSTALL)
if(SECP256K1_ENABLE_MODULE_ECDSA_ADAPTOR)
list(APPEND ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/include/secp256k1_ecdsa_adaptor.h")
endif()
- if(SECP256K1_ENABLE_MODULE_MUSIG)
- list(APPEND ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/include/secp256k1_musig.h")
- endif()
if(SECP256K1_ENABLE_MODULE_WHITELIST)
list(APPEND ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/include/secp256k1_whitelist.h")
endif()
diff --git a/src/ctime_tests.c b/src/ctime_tests.c
index 407d2cc6..0b72f281 100644
--- a/src/ctime_tests.c
+++ b/src/ctime_tests.c
@@ -43,10 +43,6 @@
#include "../include/secp256k1_ecdsa_adaptor.h"
#endif
-#ifdef ENABLE_MODULE_MUSIG
-#include "../include/secp256k1_musig.h"
-#endif
-
static void run_tests(secp256k1_context *ctx, unsigned char *key);
int main(void) {
@@ -281,72 +277,4 @@ static void run_tests(secp256k1_context *ctx, unsigned char *key) {
CHECK(ret == 0);
}
#endif
-
-#ifdef ENABLE_MODULE_MUSIG
- {
- secp256k1_pubkey pk;
- const secp256k1_pubkey *pk_ptr[1];
- secp256k1_xonly_pubkey agg_pk;
- unsigned char session_id[32];
- secp256k1_musig_secnonce secnonce;
- secp256k1_musig_pubnonce pubnonce;
- const secp256k1_musig_pubnonce *pubnonce_ptr[1];
- secp256k1_musig_aggnonce aggnonce;
- secp256k1_musig_keyagg_cache cache;
- secp256k1_musig_session session;
- secp256k1_musig_partial_sig partial_sig;
- const secp256k1_musig_partial_sig *partial_sig_ptr[1];
- unsigned char extra_input[32];
- unsigned char sec_adaptor[32];
- secp256k1_pubkey adaptor;
- unsigned char pre_sig[64];
- int nonce_parity;
-
- pk_ptr[0] = &pk;
- pubnonce_ptr[0] = &pubnonce;
- SECP256K1_CHECKMEM_DEFINE(key, 32);
- memcpy(session_id, key, sizeof(session_id));
- session_id[0] = session_id[0] + 1;
- memcpy(extra_input, key, sizeof(extra_input));
- extra_input[0] = extra_input[0] + 2;
- memcpy(sec_adaptor, key, sizeof(sec_adaptor));
- sec_adaptor[0] = extra_input[0] + 3;
- partial_sig_ptr[0] = &partial_sig;
-
- CHECK(secp256k1_keypair_create(ctx, &keypair, key));
- CHECK(secp256k1_keypair_pub(ctx, &pk, &keypair));
- CHECK(secp256k1_musig_pubkey_agg(ctx, NULL, &agg_pk, &cache, pk_ptr, 1));
- CHECK(secp256k1_ec_pubkey_create(ctx, &adaptor, sec_adaptor));
- SECP256K1_CHECKMEM_UNDEFINE(key, 32);
- SECP256K1_CHECKMEM_UNDEFINE(session_id, sizeof(session_id));
- SECP256K1_CHECKMEM_UNDEFINE(extra_input, sizeof(extra_input));
- SECP256K1_CHECKMEM_UNDEFINE(sec_adaptor, sizeof(sec_adaptor));
- ret = secp256k1_musig_nonce_gen(ctx, &secnonce, &pubnonce, session_id, key, &pk, msg, &cache, extra_input);
- SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
- CHECK(ret == 1);
- CHECK(secp256k1_musig_nonce_agg(ctx, &aggnonce, pubnonce_ptr, 1));
- /* Make sure that previous tests don't undefine msg. It's not used as a secret here. */
- SECP256K1_CHECKMEM_DEFINE(msg, sizeof(msg));
- CHECK(secp256k1_musig_nonce_process(ctx, &session, &aggnonce, msg, &cache, &adaptor) == 1);
-
- ret = secp256k1_keypair_create(ctx, &keypair, key);
- SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
- CHECK(ret == 1);
- ret = secp256k1_musig_partial_sign(ctx, &partial_sig, &secnonce, &keypair, &cache, &session);
- SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
- CHECK(ret == 1);
-
- SECP256K1_CHECKMEM_DEFINE(&partial_sig, sizeof(partial_sig));
- CHECK(secp256k1_musig_partial_sig_agg(ctx, pre_sig, &session, partial_sig_ptr, 1));
- SECP256K1_CHECKMEM_DEFINE(pre_sig, sizeof(pre_sig));
-
- CHECK(secp256k1_musig_nonce_parity(ctx, &nonce_parity, &session));
- ret = secp256k1_musig_adapt(ctx, sig, pre_sig, sec_adaptor, nonce_parity);
- SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
- CHECK(ret == 1);
- ret = secp256k1_musig_extract_adaptor(ctx, sec_adaptor, sig, pre_sig, nonce_parity);
- SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
- CHECK(ret == 1);
- }
-#endif
}
diff --git a/src/modules/musig/Makefile.am.include b/src/modules/musig/Makefile.am.include
deleted file mode 100644
index dc2f77f1..00000000
--- a/src/modules/musig/Makefile.am.include
+++ /dev/null
@@ -1,8 +0,0 @@
-include_HEADERS += include/secp256k1_musig.h
-noinst_HEADERS += src/modules/musig/main_impl.h
-noinst_HEADERS += src/modules/musig/keyagg.h
-noinst_HEADERS += src/modules/musig/keyagg_impl.h
-noinst_HEADERS += src/modules/musig/session.h
-noinst_HEADERS += src/modules/musig/session_impl.h
-noinst_HEADERS += src/modules/musig/adaptor_impl.h
-noinst_HEADERS += src/modules/musig/tests_impl.h
diff --git a/src/modules/musig/adaptor_impl.h b/src/modules/musig/adaptor_impl.h
deleted file mode 100644
index 3830e8a2..00000000
--- a/src/modules/musig/adaptor_impl.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/***********************************************************************
- * Copyright (c) 2021 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_MUSIG_ADAPTOR_IMPL_H
-#define SECP256K1_MODULE_MUSIG_ADAPTOR_IMPL_H
-
-#include
-
-#include "../../../include/secp256k1.h"
-#include "../../../include/secp256k1_musig.h"
-
-#include "session.h"
-#include "../../scalar.h"
-
-int secp256k1_musig_nonce_parity(const secp256k1_context* ctx, int *nonce_parity, const secp256k1_musig_session *session) {
- secp256k1_musig_session_internal session_i;
- VERIFY_CHECK(ctx != NULL);
- ARG_CHECK(nonce_parity != NULL);
- ARG_CHECK(session != NULL);
-
- if (!secp256k1_musig_session_load(ctx, &session_i, session)) {
- return 0;
- }
- *nonce_parity = session_i.fin_nonce_parity;
- return 1;
-}
-
-int secp256k1_musig_adapt(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *pre_sig64, const unsigned char *sec_adaptor32, int nonce_parity) {
- secp256k1_scalar s;
- secp256k1_scalar t;
- int overflow;
- int ret = 1;
-
- VERIFY_CHECK(ctx != NULL);
- ARG_CHECK(sig64 != NULL);
- ARG_CHECK(pre_sig64 != NULL);
- ARG_CHECK(sec_adaptor32 != NULL);
- ARG_CHECK(nonce_parity == 0 || nonce_parity == 1);
-
- secp256k1_scalar_set_b32(&s, &pre_sig64[32], &overflow);
- if (overflow) {
- return 0;
- }
- secp256k1_scalar_set_b32(&t, sec_adaptor32, &overflow);
- ret &= !overflow;
-
- /* Determine if the secret adaptor should be negated.
- *
- * The musig_session stores the X-coordinate and the parity of the "final nonce"
- * (r + t)*G, where r*G is the aggregate public nonce and t is the secret adaptor.
- *
- * Since a BIP340 signature requires an x-only public nonce, in the case where
- * (r + t)*G has odd Y-coordinate (i.e. nonce_parity == 1), the x-only public nonce
- * corresponding to the signature is actually (-r - t)*G. Thus adapting a
- * pre-signature requires negating t in this case.
- */
- if (nonce_parity) {
- secp256k1_scalar_negate(&t, &t);
- }
-
- secp256k1_scalar_add(&s, &s, &t);
- secp256k1_scalar_get_b32(&sig64[32], &s);
- memmove(sig64, pre_sig64, 32);
- secp256k1_scalar_clear(&t);
- return ret;
-}
-
-int secp256k1_musig_extract_adaptor(const secp256k1_context* ctx, unsigned char *sec_adaptor32, const unsigned char *sig64, const unsigned char *pre_sig64, int nonce_parity) {
- secp256k1_scalar t;
- secp256k1_scalar s;
- int overflow;
- int ret = 1;
-
- VERIFY_CHECK(ctx != NULL);
- ARG_CHECK(sec_adaptor32 != NULL);
- ARG_CHECK(sig64 != NULL);
- ARG_CHECK(pre_sig64 != NULL);
- ARG_CHECK(nonce_parity == 0 || nonce_parity == 1);
-
- secp256k1_scalar_set_b32(&t, &sig64[32], &overflow);
- ret &= !overflow;
- secp256k1_scalar_negate(&t, &t);
-
- secp256k1_scalar_set_b32(&s, &pre_sig64[32], &overflow);
- if (overflow) {
- return 0;
- }
- secp256k1_scalar_add(&t, &t, &s);
-
- if (!nonce_parity) {
- secp256k1_scalar_negate(&t, &t);
- }
- secp256k1_scalar_get_b32(sec_adaptor32, &t);
- secp256k1_scalar_clear(&t);
- return ret;
-}
-
-#endif
diff --git a/src/modules/musig/keyagg.h b/src/modules/musig/keyagg.h
deleted file mode 100644
index 620522fe..00000000
--- a/src/modules/musig/keyagg.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/***********************************************************************
- * Copyright (c) 2021 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_MUSIG_KEYAGG_H
-#define SECP256K1_MODULE_MUSIG_KEYAGG_H
-
-#include "../../../include/secp256k1.h"
-#include "../../../include/secp256k1_musig.h"
-
-#include "../../field.h"
-#include "../../group.h"
-#include "../../scalar.h"
-
-typedef struct {
- secp256k1_ge pk;
- /* If there is no "second" public key, second_pk is set to the point at
- * infinity */
- secp256k1_ge second_pk;
- unsigned char pk_hash[32];
- /* tweak is identical to value tacc[v] in the specification. */
- secp256k1_scalar tweak;
- /* parity_acc corresponds to gacc[v] in the spec. If gacc[v] is -1,
- * parity_acc is 1. Otherwise, parity_acc is 0. */
- int parity_acc;
-} secp256k1_keyagg_cache_internal;
-
-/* point_save_ext and point_load_ext are identical to point_save and point_load
- * except that they allow saving and loading the point at infinity */
-static void secp256k1_point_save_ext(unsigned char *data, secp256k1_ge *ge);
-
-static void secp256k1_point_load_ext(secp256k1_ge *ge, const unsigned char *data);
-
-static int secp256k1_keyagg_cache_load(const secp256k1_context* ctx, secp256k1_keyagg_cache_internal *cache_i, const secp256k1_musig_keyagg_cache *cache);
-
-static void secp256k1_musig_keyaggcoef(secp256k1_scalar *r, const secp256k1_keyagg_cache_internal *cache_i, secp256k1_ge *pk);
-
-#endif
diff --git a/src/modules/musig/keyagg_impl.h b/src/modules/musig/keyagg_impl.h
deleted file mode 100644
index aff95542..00000000
--- a/src/modules/musig/keyagg_impl.h
+++ /dev/null
@@ -1,311 +0,0 @@
-/***********************************************************************
- * Copyright (c) 2021 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_MUSIG_KEYAGG_IMPL_H
-#define SECP256K1_MODULE_MUSIG_KEYAGG_IMPL_H
-
-#include
-
-#include "keyagg.h"
-#include "../../eckey.h"
-#include "../../ecmult.h"
-#include "../../field.h"
-#include "../../group.h"
-#include "../../hash.h"
-#include "../../util.h"
-
-static void secp256k1_point_save_ext(unsigned char *data, secp256k1_ge *ge) {
- if (secp256k1_ge_is_infinity(ge)) {
- memset(data, 0, 64);
- } else {
- secp256k1_ge_to_bytes(data, ge);
- }
-}
-
-static void secp256k1_point_load_ext(secp256k1_ge *ge, const unsigned char *data) {
- unsigned char zeros[64] = { 0 };
- if (secp256k1_memcmp_var(data, zeros, sizeof(zeros)) == 0) {
- secp256k1_ge_set_infinity(ge);
- } else {
- secp256k1_ge_from_bytes(ge, data);
- }
-}
-
-static const unsigned char secp256k1_musig_keyagg_cache_magic[4] = { 0xf4, 0xad, 0xbb, 0xdf };
-
-/* A keyagg cache consists of
- * - 4 byte magic set during initialization to allow detecting an uninitialized
- * object.
- * - 64 byte aggregate (and potentially tweaked) public key
- * - 64 byte "second" public key (set to the point at infinity if not present)
- * - 32 byte hash of all public keys
- * - 1 byte the parity of the internal key (if tweaked, otherwise 0)
- * - 32 byte tweak
- */
-/* Requires that cache_i->pk is not infinity and cache_i->second_pk_x to be normalized. */
-static void secp256k1_keyagg_cache_save(secp256k1_musig_keyagg_cache *cache, secp256k1_keyagg_cache_internal *cache_i) {
- unsigned char *ptr = cache->data;
- memcpy(ptr, secp256k1_musig_keyagg_cache_magic, 4);
- ptr += 4;
- secp256k1_ge_to_bytes(ptr, &cache_i->pk);
- ptr += 64;
- secp256k1_point_save_ext(ptr, &cache_i->second_pk);
- ptr += 64;
- memcpy(ptr, cache_i->pk_hash, 32);
- ptr += 32;
- *ptr = cache_i->parity_acc;
- ptr += 1;
- secp256k1_scalar_get_b32(ptr, &cache_i->tweak);
-}
-
-static int secp256k1_keyagg_cache_load(const secp256k1_context* ctx, secp256k1_keyagg_cache_internal *cache_i, const secp256k1_musig_keyagg_cache *cache) {
- const unsigned char *ptr = cache->data;
- ARG_CHECK(secp256k1_memcmp_var(ptr, secp256k1_musig_keyagg_cache_magic, 4) == 0);
- ptr += 4;
- secp256k1_ge_from_bytes(&cache_i->pk, ptr);
- ptr += 64;
- secp256k1_point_load_ext(&cache_i->second_pk, ptr);
- ptr += 64;
- memcpy(cache_i->pk_hash, ptr, 32);
- ptr += 32;
- cache_i->parity_acc = *ptr & 1;
- ptr += 1;
- secp256k1_scalar_set_b32(&cache_i->tweak, ptr, NULL);
- return 1;
-}
-
-/* Initializes SHA256 with fixed midstate. This midstate was computed by applying
- * SHA256 to SHA256("KeyAgg list")||SHA256("KeyAgg list"). */
-static void secp256k1_musig_keyagglist_sha256(secp256k1_sha256 *sha) {
- secp256k1_sha256_initialize(sha);
-
- sha->s[0] = 0xb399d5e0ul;
- sha->s[1] = 0xc8fff302ul;
- sha->s[2] = 0x6badac71ul;
- sha->s[3] = 0x07c5b7f1ul;
- sha->s[4] = 0x9701e2eful;
- sha->s[5] = 0x2a72ecf8ul;
- sha->s[6] = 0x201a4c7bul;
- sha->s[7] = 0xab148a38ul;
- sha->bytes = 64;
-}
-
-/* Computes pk_hash = tagged_hash(pk[0], ..., pk[np-1]) */
-static int secp256k1_musig_compute_pk_hash(const secp256k1_context *ctx, unsigned char *pk_hash, const secp256k1_pubkey * const* pk, size_t np) {
- secp256k1_sha256 sha;
- size_t i;
-
- secp256k1_musig_keyagglist_sha256(&sha);
- for (i = 0; i < np; i++) {
- unsigned char ser[33];
- size_t ser_len = sizeof(ser);
- if (!secp256k1_ec_pubkey_serialize(ctx, ser, &ser_len, pk[i], SECP256K1_EC_COMPRESSED)) {
- return 0;
- }
- VERIFY_CHECK(ser_len == sizeof(ser));
- secp256k1_sha256_write(&sha, ser, sizeof(ser));
- }
- secp256k1_sha256_finalize(&sha, pk_hash);
- return 1;
-}
-
-/* Initializes SHA256 with fixed midstate. This midstate was computed by applying
- * SHA256 to SHA256("KeyAgg coefficient")||SHA256("KeyAgg coefficient"). */
-static void secp256k1_musig_keyaggcoef_sha256(secp256k1_sha256 *sha) {
- secp256k1_sha256_initialize(sha);
-
- sha->s[0] = 0x6ef02c5aul;
- sha->s[1] = 0x06a480deul;
- sha->s[2] = 0x1f298665ul;
- sha->s[3] = 0x1d1134f2ul;
- sha->s[4] = 0x56a0b063ul;
- sha->s[5] = 0x52da4147ul;
- sha->s[6] = 0xf280d9d4ul;
- sha->s[7] = 0x4484be15ul;
- sha->bytes = 64;
-}
-
-/* Compute KeyAgg coefficient which is constant 1 for the second pubkey and
- * otherwise tagged_hash(pk_hash, x) where pk_hash is the hash of public keys.
- * second_pk is the point at infinity in case there is no second_pk. Assumes
- * that pk is not the point at infinity and that the Y-coordinates of pk and
- * second_pk are normalized. */
-static void secp256k1_musig_keyaggcoef_internal(secp256k1_scalar *r, const unsigned char *pk_hash, secp256k1_ge *pk, const secp256k1_ge *second_pk) {
- secp256k1_sha256 sha;
-
- VERIFY_CHECK(!secp256k1_ge_is_infinity(pk));
-
- if (!secp256k1_ge_is_infinity(second_pk)
- && secp256k1_fe_equal(&pk->x, &second_pk->x)
- && secp256k1_fe_is_odd(&pk->y) == secp256k1_fe_is_odd(&second_pk->y)) {
- secp256k1_scalar_set_int(r, 1);
- } else {
- unsigned char buf[33];
- size_t buflen = sizeof(buf);
- int ret;
- secp256k1_musig_keyaggcoef_sha256(&sha);
- secp256k1_sha256_write(&sha, pk_hash, 32);
- ret = secp256k1_eckey_pubkey_serialize(pk, buf, &buflen, 1);
-#ifdef VERIFY
- /* Serialization does not fail since the pk is not the point at infinity
- * (according to this function's precondition). */
- VERIFY_CHECK(ret && buflen == sizeof(buf));
-#else
- (void) ret;
-#endif
- secp256k1_sha256_write(&sha, buf, sizeof(buf));
- secp256k1_sha256_finalize(&sha, buf);
- secp256k1_scalar_set_b32(r, buf, NULL);
- }
-}
-
-/* Assumes both field elements x and second_pk_x are normalized. */
-static void secp256k1_musig_keyaggcoef(secp256k1_scalar *r, const secp256k1_keyagg_cache_internal *cache_i, secp256k1_ge *pk) {
- secp256k1_musig_keyaggcoef_internal(r, cache_i->pk_hash, pk, &cache_i->second_pk);
-}
-
-typedef struct {
- const secp256k1_context *ctx;
- /* pk_hash is the hash of the public keys */
- unsigned char pk_hash[32];
- const secp256k1_pubkey * const* pks;
- secp256k1_ge second_pk;
-} secp256k1_musig_pubkey_agg_ecmult_data;
-
-/* Callback for batch EC multiplication to compute keyaggcoef_0*P0 + keyaggcoef_1*P1 + ... */
-static int secp256k1_musig_pubkey_agg_callback(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx, void *data) {
- secp256k1_musig_pubkey_agg_ecmult_data *ctx = (secp256k1_musig_pubkey_agg_ecmult_data *) data;
- int ret;
- ret = secp256k1_pubkey_load(ctx->ctx, pt, ctx->pks[idx]);
-#ifdef VERIFY
- /* pubkey_load can't fail because the same pks have already been loaded in
- * `musig_compute_pk_hash` (and we test this). */
- VERIFY_CHECK(ret);
-#else
- (void) ret;
-#endif
- secp256k1_musig_keyaggcoef_internal(sc, ctx->pk_hash, pt, &ctx->second_pk);
- return 1;
-}
-
-int secp256k1_musig_pubkey_agg(const secp256k1_context* ctx, secp256k1_scratch_space *scratch, secp256k1_xonly_pubkey *agg_pk, secp256k1_musig_keyagg_cache *keyagg_cache, const secp256k1_pubkey * const* pubkeys, size_t n_pubkeys) {
- secp256k1_musig_pubkey_agg_ecmult_data ecmult_data;
- secp256k1_gej pkj;
- secp256k1_ge pkp;
- size_t i;
- (void) scratch;
-
- VERIFY_CHECK(ctx != NULL);
- if (agg_pk != NULL) {
- memset(agg_pk, 0, sizeof(*agg_pk));
- }
- ARG_CHECK(pubkeys != NULL);
- ARG_CHECK(n_pubkeys > 0);
-
- ecmult_data.ctx = ctx;
- ecmult_data.pks = pubkeys;
-
- secp256k1_ge_set_infinity(&ecmult_data.second_pk);
- for (i = 1; i < n_pubkeys; i++) {
- if (secp256k1_memcmp_var(pubkeys[0], pubkeys[i], sizeof(*pubkeys[0])) != 0) {
- secp256k1_ge pk;
- if (!secp256k1_pubkey_load(ctx, &pk, pubkeys[i])) {
- return 0;
- }
- ecmult_data.second_pk = pk;
- break;
- }
- }
-
- if (!secp256k1_musig_compute_pk_hash(ctx, ecmult_data.pk_hash, pubkeys, n_pubkeys)) {
- return 0;
- }
- /* TODO: actually use optimized ecmult_multi algorithms by providing a
- * scratch space */
- if (!secp256k1_ecmult_multi_var(&ctx->error_callback, NULL, &pkj, NULL, secp256k1_musig_pubkey_agg_callback, (void *) &ecmult_data, n_pubkeys)) {
- /* In order to reach this line with the current implementation of
- * ecmult_multi_var one would need to provide a callback that can
- * fail. */
- return 0;
- }
- secp256k1_ge_set_gej(&pkp, &pkj);
- secp256k1_fe_normalize_var(&pkp.y);
- /* The resulting public key is infinity with negligible probability */
- VERIFY_CHECK(!secp256k1_ge_is_infinity(&pkp));
- if (keyagg_cache != NULL) {
- secp256k1_keyagg_cache_internal cache_i = { 0 };
- cache_i.pk = pkp;
- cache_i.second_pk = ecmult_data.second_pk;
- memcpy(cache_i.pk_hash, ecmult_data.pk_hash, sizeof(cache_i.pk_hash));
- secp256k1_keyagg_cache_save(keyagg_cache, &cache_i);
- }
-
- secp256k1_extrakeys_ge_even_y(&pkp);
- if (agg_pk != NULL) {
- secp256k1_xonly_pubkey_save(agg_pk, &pkp);
- }
- return 1;
-}
-
-int secp256k1_musig_pubkey_get(const secp256k1_context* ctx, secp256k1_pubkey *agg_pk, const secp256k1_musig_keyagg_cache *keyagg_cache) {
- secp256k1_keyagg_cache_internal cache_i;
- VERIFY_CHECK(ctx != NULL);
- ARG_CHECK(agg_pk != NULL);
- memset(agg_pk, 0, sizeof(*agg_pk));
- ARG_CHECK(keyagg_cache != NULL);
-
- if(!secp256k1_keyagg_cache_load(ctx, &cache_i, keyagg_cache)) {
- return 0;
- }
- secp256k1_pubkey_save(agg_pk, &cache_i.pk);
- return 1;
-}
-
-static int secp256k1_musig_pubkey_tweak_add_internal(const secp256k1_context* ctx, secp256k1_pubkey *output_pubkey, secp256k1_musig_keyagg_cache *keyagg_cache, const unsigned char *tweak32, int xonly) {
- secp256k1_keyagg_cache_internal cache_i;
- int overflow = 0;
- secp256k1_scalar tweak;
-
- VERIFY_CHECK(ctx != NULL);
- if (output_pubkey != NULL) {
- memset(output_pubkey, 0, sizeof(*output_pubkey));
- }
- ARG_CHECK(keyagg_cache != NULL);
- ARG_CHECK(tweak32 != NULL);
-
- if (!secp256k1_keyagg_cache_load(ctx, &cache_i, keyagg_cache)) {
- return 0;
- }
- secp256k1_scalar_set_b32(&tweak, tweak32, &overflow);
- if (overflow) {
- return 0;
- }
- if (xonly && secp256k1_extrakeys_ge_even_y(&cache_i.pk)) {
- cache_i.parity_acc ^= 1;
- secp256k1_scalar_negate(&cache_i.tweak, &cache_i.tweak);
- }
- secp256k1_scalar_add(&cache_i.tweak, &cache_i.tweak, &tweak);
- if (!secp256k1_eckey_pubkey_tweak_add(&cache_i.pk, &tweak)) {
- return 0;
- }
- /* eckey_pubkey_tweak_add fails if cache_i.pk is infinity */
- VERIFY_CHECK(!secp256k1_ge_is_infinity(&cache_i.pk));
- secp256k1_keyagg_cache_save(keyagg_cache, &cache_i);
- if (output_pubkey != NULL) {
- secp256k1_pubkey_save(output_pubkey, &cache_i.pk);
- }
- return 1;
-}
-
-int secp256k1_musig_pubkey_ec_tweak_add(const secp256k1_context* ctx, secp256k1_pubkey *output_pubkey, secp256k1_musig_keyagg_cache *keyagg_cache, const unsigned char *tweak32) {
- return secp256k1_musig_pubkey_tweak_add_internal(ctx, output_pubkey, keyagg_cache, tweak32, 0);
-}
-
-int secp256k1_musig_pubkey_xonly_tweak_add(const secp256k1_context* ctx, secp256k1_pubkey *output_pubkey, secp256k1_musig_keyagg_cache *keyagg_cache, const unsigned char *tweak32) {
- return secp256k1_musig_pubkey_tweak_add_internal(ctx, output_pubkey, keyagg_cache, tweak32, 1);
-}
-
-#endif
diff --git a/src/modules/musig/main_impl.h b/src/modules/musig/main_impl.h
deleted file mode 100644
index e69afed5..00000000
--- a/src/modules/musig/main_impl.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/**********************************************************************
- * Copyright (c) 2018 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_MUSIG_MAIN_H
-#define SECP256K1_MODULE_MUSIG_MAIN_H
-
-#include "keyagg_impl.h"
-#include "session_impl.h"
-#include "adaptor_impl.h"
-
-#endif
diff --git a/src/modules/musig/musig.md b/src/modules/musig/musig.md
deleted file mode 100644
index 44b0de4f..00000000
--- a/src/modules/musig/musig.md
+++ /dev/null
@@ -1,63 +0,0 @@
-Notes on the musig module API
-===========================
-
-The following sections contain additional notes on the API of the musig module (`include/secp256k1_musig.h`).
-A usage example can be found in `examples/musig.c`.
-
-# API misuse
-
-The musig API is designed to be as misuse resistant as possible.
-However, the MuSig protocol has some additional failure modes (mainly due to interactivity) that do not appear in single-signing.
-While the results can be catastrophic (e.g. leaking of the secret key), it is unfortunately not possible for the musig implementation to rule out all such failure modes.
-
-Therefore, users of the musig module must take great care to make sure of the following:
-
-1. A unique nonce per signing session is generated in `secp256k1_musig_nonce_gen`.
- See the corresponding comment in `include/secp256k1_musig.h` for how to ensure that.
-2. The `secp256k1_musig_secnonce` structure is never copied or serialized.
- See also the comment on `secp256k1_musig_secnonce` in `include/secp256k1_musig.h`.
-3. Opaque data structures are never written to or read from directly.
- Instead, only the provided accessor functions are used.
-4. If adaptor signatures are used, all partial signatures are verified.
-
-# Key Aggregation and (Taproot) Tweaking
-
-Given a set of public keys, the aggregate public key is computed with `secp256k1_musig_pubkey_agg`.
-A (Taproot) tweak can be added to the resulting public key with `secp256k1_xonly_pubkey_tweak_add` and a plain tweak can be added with `secp256k1_ec_pubkey_tweak_add`.
-
-# Signing
-
-This is covered by `examples/musig.c`.
-Essentially, the protocol proceeds in the following steps:
-
-1. Generate a keypair with `secp256k1_keypair_create` and obtain the public key with `secp256k1_keypair_pub`.
-2. Call `secp256k1_musig_pubkey_agg` with the pubkeys of all participants.
-3. Optionally add a (Taproot) tweak with `secp256k1_musig_pubkey_xonly_tweak_add` and a plain tweak with `secp256k1_musig_pubkey_ec_tweak_add`.
-4. Generate a pair of secret and public nonce with `secp256k1_musig_nonce_gen` and send the public nonce to the other signers.
-5. Someone (not necessarily the signer) aggregates the public nonce with `secp256k1_musig_nonce_agg` and sends it to the signers.
-6. Process the aggregate nonce with `secp256k1_musig_nonce_process`.
-7. Create a partial signature with `secp256k1_musig_partial_sign`.
-8. Verify the partial signatures (optional in some scenarios) with `secp256k1_musig_partial_sig_verify`.
-9. Someone (not necessarily the signer) obtains all partial signatures and aggregates them into the final Schnorr signature using `secp256k1_musig_partial_sig_agg`.
-
-The aggregate signature can be verified with `secp256k1_schnorrsig_verify`.
-
-Note that steps 1 to 5 can happen before the message to be signed is known to the signers.
-Therefore, the communication round to exchange nonces can be viewed as a pre-processing step that is run whenever convenient to the signers.
-This disables some of the defense-in-depth measures that may protect against API misuse in some cases.
-Similarly, the API supports an alternative protocol flow where generating the aggregate key (steps 1 to 3) is allowed to happen after exchanging nonces (steps 4 to 5).
-
-# Verification
-
-A participant who wants to verify the partial signatures, but does not sign itself may do so using the above instructions except that the verifier skips steps 1, 4 and 7.
-
-# Atomic Swaps
-
-The signing API supports the production of "adaptor signatures", modified partial signatures
-which are offset by an auxiliary secret known to one party. That is,
-1. One party generates a (secret) adaptor `t` with corresponding (public) adaptor `T = t*G`.
-2. When calling `secp256k1_musig_nonce_process`, the public adaptor `T` is provided as the `adaptor` argument.
-3. The party who is going to extract the secret adaptor `t` later must verify all partial signatures.
-4. Due to step 2, the signature output of `secp256k1_musig_partial_sig_agg` is a pre-signature and not a valid Schnorr signature. All parties involved extract this session's `nonce_parity` with `secp256k1_musig_nonce_parity`.
-5. The party who knows `t` must "adapt" the pre-signature with `t` (and the `nonce_parity` using `secp256k1_musig_adapt` to complete the signature.
-6. Any party who sees both the final signature and the pre-signature (and has the `nonce_parity`) can extract `t` with `secp256k1_musig_extract_adaptor`.
diff --git a/src/modules/musig/session.h b/src/modules/musig/session.h
deleted file mode 100644
index dfaa5e0d..00000000
--- a/src/modules/musig/session.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/***********************************************************************
- * Copyright (c) 2021 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_MUSIG_SESSION_H
-#define SECP256K1_MODULE_MUSIG_SESSION_H
-
-#include "../../../include/secp256k1.h"
-#include "../../../include/secp256k1_musig.h"
-
-#include "../../scalar.h"
-
-typedef struct {
- int fin_nonce_parity;
- unsigned char fin_nonce[32];
- secp256k1_scalar noncecoef;
- secp256k1_scalar challenge;
- secp256k1_scalar s_part;
-} secp256k1_musig_session_internal;
-
-static int secp256k1_musig_session_load(const secp256k1_context* ctx, secp256k1_musig_session_internal *session_i, const secp256k1_musig_session *session);
-
-#endif
diff --git a/src/modules/musig/session_impl.h b/src/modules/musig/session_impl.h
deleted file mode 100644
index ff87f2fd..00000000
--- a/src/modules/musig/session_impl.h
+++ /dev/null
@@ -1,705 +0,0 @@
-/***********************************************************************
- * Copyright (c) 2021 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_MUSIG_SESSION_IMPL_H
-#define SECP256K1_MODULE_MUSIG_SESSION_IMPL_H
-
-#include
-
-#include "../../../include/secp256k1.h"
-#include "../../../include/secp256k1_extrakeys.h"
-#include "../../../include/secp256k1_musig.h"
-
-#include "keyagg.h"
-#include "session.h"
-#include "../../eckey.h"
-#include "../../hash.h"
-#include "../../scalar.h"
-#include "../../util.h"
-
-static const unsigned char secp256k1_musig_secnonce_magic[4] = { 0x22, 0x0e, 0xdc, 0xf1 };
-
-static void secp256k1_musig_secnonce_save(secp256k1_musig_secnonce *secnonce, const secp256k1_scalar *k, secp256k1_ge *pk) {
- memcpy(&secnonce->data[0], secp256k1_musig_secnonce_magic, 4);
- secp256k1_scalar_get_b32(&secnonce->data[4], &k[0]);
- secp256k1_scalar_get_b32(&secnonce->data[36], &k[1]);
- secp256k1_ge_to_bytes(&secnonce->data[68], pk);
-}
-
-static int secp256k1_musig_secnonce_load(const secp256k1_context* ctx, secp256k1_scalar *k, secp256k1_ge *pk, secp256k1_musig_secnonce *secnonce) {
- int is_zero;
- ARG_CHECK(secp256k1_memcmp_var(&secnonce->data[0], secp256k1_musig_secnonce_magic, 4) == 0);
- secp256k1_scalar_set_b32(&k[0], &secnonce->data[4], NULL);
- secp256k1_scalar_set_b32(&k[1], &secnonce->data[36], NULL);
- secp256k1_ge_from_bytes(pk, &secnonce->data[68]);
- /* We make very sure that the nonce isn't invalidated by checking the values
- * in addition to the magic. */
- is_zero = secp256k1_scalar_is_zero(&k[0]) & secp256k1_scalar_is_zero(&k[1]);
- secp256k1_declassify(ctx, &is_zero, sizeof(is_zero));
- ARG_CHECK(!is_zero);
- return 1;
-}
-
-/* If flag is true, invalidate the secnonce; otherwise leave it. Constant-time. */
-static void secp256k1_musig_secnonce_invalidate(const secp256k1_context* ctx, secp256k1_musig_secnonce *secnonce, int flag) {
- secp256k1_memczero(secnonce->data, sizeof(secnonce->data), flag);
- /* The flag argument is usually classified. So, the line above makes the
- * magic and public key classified. However, we need both to be
- * declassified. Note that we don't declassify the entire object, because if
- * flag is 0, then k[0] and k[1] have not been zeroed. */
- secp256k1_declassify(ctx, secnonce->data, sizeof(secp256k1_musig_secnonce_magic));
- secp256k1_declassify(ctx, &secnonce->data[68], 64);
-}
-
-static const unsigned char secp256k1_musig_pubnonce_magic[4] = { 0xf5, 0x7a, 0x3d, 0xa0 };
-
-/* Saves two group elements into a pubnonce. Requires that none of the provided
- * group elements is infinity. */
-static void secp256k1_musig_pubnonce_save(secp256k1_musig_pubnonce* nonce, secp256k1_ge* ge) {
- int i;
- memcpy(&nonce->data[0], secp256k1_musig_pubnonce_magic, 4);
- for (i = 0; i < 2; i++) {
- secp256k1_ge_to_bytes(nonce->data + 4+64*i, &ge[i]);
- }
-}
-
-/* Loads two group elements from a pubnonce. Returns 1 unless the nonce wasn't
- * properly initialized */
-static int secp256k1_musig_pubnonce_load(const secp256k1_context* ctx, secp256k1_ge* ge, const secp256k1_musig_pubnonce* nonce) {
- int i;
-
- ARG_CHECK(secp256k1_memcmp_var(&nonce->data[0], secp256k1_musig_pubnonce_magic, 4) == 0);
- for (i = 0; i < 2; i++) {
- secp256k1_ge_from_bytes(&ge[i], nonce->data + 4 + 64*i);
- }
- return 1;
-}
-
-static const unsigned char secp256k1_musig_aggnonce_magic[4] = { 0xa8, 0xb7, 0xe4, 0x67 };
-
-static void secp256k1_musig_aggnonce_save(secp256k1_musig_aggnonce* nonce, secp256k1_ge* ge) {
- int i;
- memcpy(&nonce->data[0], secp256k1_musig_aggnonce_magic, 4);
- for (i = 0; i < 2; i++) {
- secp256k1_point_save_ext(&nonce->data[4 + 64*i], &ge[i]);
- }
-}
-
-static int secp256k1_musig_aggnonce_load(const secp256k1_context* ctx, secp256k1_ge* ge, const secp256k1_musig_aggnonce* nonce) {
- int i;
-
- ARG_CHECK(secp256k1_memcmp_var(&nonce->data[0], secp256k1_musig_aggnonce_magic, 4) == 0);
- for (i = 0; i < 2; i++) {
- secp256k1_point_load_ext(&ge[i], &nonce->data[4 + 64*i]);
- }
- return 1;
-}
-
-static const unsigned char secp256k1_musig_session_cache_magic[4] = { 0x9d, 0xed, 0xe9, 0x17 };
-
-/* A session consists of
- * - 4 byte session cache magic
- * - 1 byte the parity of the final nonce
- * - 32 byte serialized x-only final nonce
- * - 32 byte nonce coefficient b
- * - 32 byte signature challenge hash e
- * - 32 byte scalar s that is added to the partial signatures of the signers
- */
-static void secp256k1_musig_session_save(secp256k1_musig_session *session, const secp256k1_musig_session_internal *session_i) {
- unsigned char *ptr = session->data;
-
- memcpy(ptr, secp256k1_musig_session_cache_magic, 4);
- ptr += 4;
- *ptr = session_i->fin_nonce_parity;
- ptr += 1;
- memcpy(ptr, session_i->fin_nonce, 32);
- ptr += 32;
- secp256k1_scalar_get_b32(ptr, &session_i->noncecoef);
- ptr += 32;
- secp256k1_scalar_get_b32(ptr, &session_i->challenge);
- ptr += 32;
- secp256k1_scalar_get_b32(ptr, &session_i->s_part);
-}
-
-static int secp256k1_musig_session_load(const secp256k1_context* ctx, secp256k1_musig_session_internal *session_i, const secp256k1_musig_session *session) {
- const unsigned char *ptr = session->data;
-
- ARG_CHECK(secp256k1_memcmp_var(ptr, secp256k1_musig_session_cache_magic, 4) == 0);
- ptr += 4;
- session_i->fin_nonce_parity = *ptr;
- ptr += 1;
- memcpy(session_i->fin_nonce, ptr, 32);
- ptr += 32;
- secp256k1_scalar_set_b32(&session_i->noncecoef, ptr, NULL);
- ptr += 32;
- secp256k1_scalar_set_b32(&session_i->challenge, ptr, NULL);
- ptr += 32;
- secp256k1_scalar_set_b32(&session_i->s_part, ptr, NULL);
- return 1;
-}
-
-static const unsigned char secp256k1_musig_partial_sig_magic[4] = { 0xeb, 0xfb, 0x1a, 0x32 };
-
-static void secp256k1_musig_partial_sig_save(secp256k1_musig_partial_sig* sig, secp256k1_scalar *s) {
- memcpy(&sig->data[0], secp256k1_musig_partial_sig_magic, 4);
- secp256k1_scalar_get_b32(&sig->data[4], s);
-}
-
-static int secp256k1_musig_partial_sig_load(const secp256k1_context* ctx, secp256k1_scalar *s, const secp256k1_musig_partial_sig* sig) {
- int overflow;
-
- ARG_CHECK(secp256k1_memcmp_var(&sig->data[0], secp256k1_musig_partial_sig_magic, 4) == 0);
- secp256k1_scalar_set_b32(s, &sig->data[4], &overflow);
- /* Parsed signatures can not overflow */
- VERIFY_CHECK(!overflow);
- return 1;
-}
-
-int secp256k1_musig_pubnonce_serialize(const secp256k1_context* ctx, unsigned char *out66, const secp256k1_musig_pubnonce* nonce) {
- secp256k1_ge ge[2];
- int i;
-
- VERIFY_CHECK(ctx != NULL);
- ARG_CHECK(out66 != NULL);
- memset(out66, 0, 66);
- ARG_CHECK(nonce != NULL);
-
- if (!secp256k1_musig_pubnonce_load(ctx, ge, nonce)) {
- return 0;
- }
- for (i = 0; i < 2; i++) {
- int ret;
- size_t size = 33;
- ret = secp256k1_eckey_pubkey_serialize(&ge[i], &out66[33*i], &size, 1);
-#ifdef VERIFY
- /* serialize must succeed because the point was just loaded */
- VERIFY_CHECK(ret && size == 33);
-#else
- (void) ret;
-#endif
- }
- return 1;
-}
-
-int secp256k1_musig_pubnonce_parse(const secp256k1_context* ctx, secp256k1_musig_pubnonce* nonce, const unsigned char *in66) {
- secp256k1_ge ge[2];
- int i;
-
- VERIFY_CHECK(ctx != NULL);
- ARG_CHECK(nonce != NULL);
- ARG_CHECK(in66 != NULL);
-
- for (i = 0; i < 2; i++) {
- if (!secp256k1_eckey_pubkey_parse(&ge[i], &in66[33*i], 33)) {
- return 0;
- }
- if (!secp256k1_ge_is_in_correct_subgroup(&ge[i])) {
- return 0;
- }
- }
- secp256k1_musig_pubnonce_save(nonce, ge);
- return 1;
-}
-
-int secp256k1_musig_aggnonce_serialize(const secp256k1_context* ctx, unsigned char *out66, const secp256k1_musig_aggnonce* nonce) {
- secp256k1_ge ge[2];
- int i;
-
- VERIFY_CHECK(ctx != NULL);
- ARG_CHECK(out66 != NULL);
- memset(out66, 0, 66);
- ARG_CHECK(nonce != NULL);
-
- if (!secp256k1_musig_aggnonce_load(ctx, ge, nonce)) {
- return 0;
- }
- for (i = 0; i < 2; i++) {
- secp256k1_ge_serialize_ext(&out66[33*i], &ge[i]);
- }
- return 1;
-}
-
-int secp256k1_musig_aggnonce_parse(const secp256k1_context* ctx, secp256k1_musig_aggnonce* nonce, const unsigned char *in66) {
- secp256k1_ge ge[2];
- int i;
-
- VERIFY_CHECK(ctx != NULL);
- ARG_CHECK(nonce != NULL);
- ARG_CHECK(in66 != NULL);
-
- for (i = 0; i < 2; i++) {
- if (!secp256k1_ge_parse_ext(&ge[i], &in66[33*i])) {
- return 0;
- }
- }
- secp256k1_musig_aggnonce_save(nonce, ge);
- return 1;
-}
-
-int secp256k1_musig_partial_sig_serialize(const secp256k1_context* ctx, unsigned char *out32, const secp256k1_musig_partial_sig* sig) {
- VERIFY_CHECK(ctx != NULL);
- ARG_CHECK(out32 != NULL);
- ARG_CHECK(sig != NULL);
- memcpy(out32, &sig->data[4], 32);
- return 1;
-}
-
-int secp256k1_musig_partial_sig_parse(const secp256k1_context* ctx, secp256k1_musig_partial_sig* sig, const unsigned char *in32) {
- secp256k1_scalar tmp;
- int overflow;
- VERIFY_CHECK(ctx != NULL);
- ARG_CHECK(sig != NULL);
- ARG_CHECK(in32 != NULL);
-
- secp256k1_scalar_set_b32(&tmp, in32, &overflow);
- if (overflow) {
- return 0;
- }
- secp256k1_musig_partial_sig_save(sig, &tmp);
- return 1;
-}
-
-/* Write optional inputs into the hash */
-static void secp256k1_nonce_function_musig_helper(secp256k1_sha256 *sha, unsigned int prefix_size, const unsigned char *data, unsigned char len) {
- unsigned char zero[7] = { 0 };
- /* The spec requires length prefixes to be between 1 and 8 bytes
- * (inclusive) */
- VERIFY_CHECK(prefix_size <= 8);
- /* Since the length of all input data fits in a byte, we can always pad the
- * length prefix with prefix_size - 1 zero bytes. */
- secp256k1_sha256_write(sha, zero, prefix_size - 1);
- if (data != NULL) {
- secp256k1_sha256_write(sha, &len, 1);
- secp256k1_sha256_write(sha, data, len);
- } else {
- len = 0;
- secp256k1_sha256_write(sha, &len, 1);
- }
-}
-
-static void secp256k1_nonce_function_musig(secp256k1_scalar *k, const unsigned char *session_id, const unsigned char *msg32, const unsigned char *seckey32, const unsigned char *pk33, const unsigned char *agg_pk32, const unsigned char *extra_input32) {
- secp256k1_sha256 sha;
- unsigned char rand[32];
- unsigned char i;
- unsigned char msg_present;
-
- if (seckey32 != NULL) {
- secp256k1_sha256_initialize_tagged(&sha, (unsigned char*)"MuSig/aux", sizeof("MuSig/aux") - 1);
- secp256k1_sha256_write(&sha, session_id, 32);
- secp256k1_sha256_finalize(&sha, rand);
- for (i = 0; i < 32; i++) {
- rand[i] ^= seckey32[i];
- }
- } else {
- memcpy(rand, session_id, sizeof(rand));
- }
-
- /* Subtract one from `sizeof` to avoid hashing the implicit null byte */
- secp256k1_sha256_initialize_tagged(&sha, (unsigned char*)"MuSig/nonce", sizeof("MuSig/nonce") - 1);
- secp256k1_sha256_write(&sha, rand, sizeof(rand));
- secp256k1_nonce_function_musig_helper(&sha, 1, pk33, 33);
- secp256k1_nonce_function_musig_helper(&sha, 1, agg_pk32, 32);
- msg_present = msg32 != NULL;
- secp256k1_sha256_write(&sha, &msg_present, 1);
- if (msg_present) {
- secp256k1_nonce_function_musig_helper(&sha, 8, msg32, 32);
- }
- secp256k1_nonce_function_musig_helper(&sha, 4, extra_input32, 32);
-
- for (i = 0; i < 2; i++) {
- unsigned char buf[32];
- secp256k1_sha256 sha_tmp = sha;
- secp256k1_sha256_write(&sha_tmp, &i, 1);
- secp256k1_sha256_finalize(&sha_tmp, buf);
- secp256k1_scalar_set_b32(&k[i], buf, NULL);
- }
-}
-
-int secp256k1_musig_nonce_gen(const secp256k1_context* ctx, secp256k1_musig_secnonce *secnonce, secp256k1_musig_pubnonce *pubnonce, const unsigned char *session_id32, const unsigned char *seckey, const secp256k1_pubkey *pubkey, const unsigned char *msg32, const secp256k1_musig_keyagg_cache *keyagg_cache, const unsigned char *extra_input32) {
- secp256k1_keyagg_cache_internal cache_i;
- secp256k1_scalar k[2];
- secp256k1_ge nonce_pt[2];
- int i;
- unsigned char pk_ser[33];
- size_t pk_ser_len = sizeof(pk_ser);
- unsigned char aggpk_ser[32];
- unsigned char *aggpk_ser_ptr = NULL;
- secp256k1_ge pk;
- int pk_serialize_success;
- int ret = 1;
-
- VERIFY_CHECK(ctx != NULL);
- ARG_CHECK(secnonce != NULL);
- memset(secnonce, 0, sizeof(*secnonce));
- ARG_CHECK(pubnonce != NULL);
- memset(pubnonce, 0, sizeof(*pubnonce));
- ARG_CHECK(session_id32 != NULL);
- ARG_CHECK(pubkey != NULL);
- ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
- if (seckey == NULL) {
- /* Check in constant time that the session_id is not 0 as a
- * defense-in-depth measure that may protect against a faulty RNG. */
- unsigned char acc = 0;
- for (i = 0; i < 32; i++) {
- acc |= session_id32[i];
- }
- ret &= !!acc;
- memset(&acc, 0, sizeof(acc));
- }
-
- /* Check that the seckey is valid to be able to sign for it later. */
- if (seckey != NULL) {
- secp256k1_scalar sk;
- ret &= secp256k1_scalar_set_b32_seckey(&sk, seckey);
- secp256k1_scalar_clear(&sk);
- }
-
- if (keyagg_cache != NULL) {
- if (!secp256k1_keyagg_cache_load(ctx, &cache_i, keyagg_cache)) {
- return 0;
- }
- /* The loaded point cache_i.pk can not be the point at infinity. */
- secp256k1_fe_get_b32(aggpk_ser, &cache_i.pk.x);
- aggpk_ser_ptr = aggpk_ser;
- }
- if (!secp256k1_pubkey_load(ctx, &pk, pubkey)) {
- return 0;
- }
- pk_serialize_success = secp256k1_eckey_pubkey_serialize(&pk, pk_ser, &pk_ser_len, SECP256K1_EC_COMPRESSED);
-
-#ifdef VERIFY
- /* A pubkey cannot be the point at infinity */
- VERIFY_CHECK(pk_serialize_success);
- VERIFY_CHECK(pk_ser_len == sizeof(pk_ser));
-#else
- (void) pk_serialize_success;
-#endif
-
- secp256k1_nonce_function_musig(k, session_id32, msg32, seckey, pk_ser, aggpk_ser_ptr, extra_input32);
- VERIFY_CHECK(!secp256k1_scalar_is_zero(&k[0]));
- VERIFY_CHECK(!secp256k1_scalar_is_zero(&k[1]));
- VERIFY_CHECK(!secp256k1_scalar_eq(&k[0], &k[1]));
- secp256k1_musig_secnonce_save(secnonce, k, &pk);
- secp256k1_musig_secnonce_invalidate(ctx, secnonce, !ret);
-
- for (i = 0; i < 2; i++) {
- secp256k1_gej nonce_ptj;
- secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &nonce_ptj, &k[i]);
- secp256k1_ge_set_gej(&nonce_pt[i], &nonce_ptj);
- secp256k1_declassify(ctx, &nonce_pt[i], sizeof(nonce_pt));
- secp256k1_scalar_clear(&k[i]);
- }
- /* nonce_pt won't be infinity because k != 0 with overwhelming probability */
- secp256k1_musig_pubnonce_save(pubnonce, nonce_pt);
- return ret;
-}
-
-static int secp256k1_musig_sum_nonces(const secp256k1_context* ctx, secp256k1_gej *summed_nonces, const secp256k1_musig_pubnonce * const* pubnonces, size_t n_pubnonces) {
- size_t i;
- int j;
-
- secp256k1_gej_set_infinity(&summed_nonces[0]);
- secp256k1_gej_set_infinity(&summed_nonces[1]);
-
- for (i = 0; i < n_pubnonces; i++) {
- secp256k1_ge nonce_pt[2];
- if (!secp256k1_musig_pubnonce_load(ctx, nonce_pt, pubnonces[i])) {
- return 0;
- }
- for (j = 0; j < 2; j++) {
- secp256k1_gej_add_ge_var(&summed_nonces[j], &summed_nonces[j], &nonce_pt[j], NULL);
- }
- }
- return 1;
-}
-
-int secp256k1_musig_nonce_agg(const secp256k1_context* ctx, secp256k1_musig_aggnonce *aggnonce, const secp256k1_musig_pubnonce * const* pubnonces, size_t n_pubnonces) {
- secp256k1_gej aggnonce_ptj[2];
- secp256k1_ge aggnonce_pt[2];
- int i;
- VERIFY_CHECK(ctx != NULL);
- ARG_CHECK(aggnonce != NULL);
- ARG_CHECK(pubnonces != NULL);
- ARG_CHECK(n_pubnonces > 0);
-
- if (!secp256k1_musig_sum_nonces(ctx, aggnonce_ptj, pubnonces, n_pubnonces)) {
- return 0;
- }
- for (i = 0; i < 2; i++) {
- secp256k1_ge_set_gej(&aggnonce_pt[i], &aggnonce_ptj[i]);
- }
- secp256k1_musig_aggnonce_save(aggnonce, aggnonce_pt);
- return 1;
-}
-
-/* tagged_hash(aggnonce[0], aggnonce[1], agg_pk, msg) */
-static int secp256k1_musig_compute_noncehash(unsigned char *noncehash, secp256k1_ge *aggnonce, const unsigned char *agg_pk32, const unsigned char *msg) {
- unsigned char buf[33];
- secp256k1_sha256 sha;
- int i;
-
- secp256k1_sha256_initialize_tagged(&sha, (unsigned char*)"MuSig/noncecoef", sizeof("MuSig/noncecoef") - 1);
- for (i = 0; i < 2; i++) {
- secp256k1_ge_serialize_ext(buf, &aggnonce[i]);
- secp256k1_sha256_write(&sha, buf, sizeof(buf));
- }
- secp256k1_sha256_write(&sha, agg_pk32, 32);
- secp256k1_sha256_write(&sha, msg, 32);
- secp256k1_sha256_finalize(&sha, noncehash);
- return 1;
-}
-
-static int secp256k1_musig_nonce_process_internal(int *fin_nonce_parity, unsigned char *fin_nonce, secp256k1_scalar *b, secp256k1_gej *aggnoncej, const unsigned char *agg_pk32, const unsigned char *msg) {
- unsigned char noncehash[32];
- secp256k1_ge fin_nonce_pt;
- secp256k1_gej fin_nonce_ptj;
- secp256k1_ge aggnonce[2];
-
- secp256k1_ge_set_gej(&aggnonce[0], &aggnoncej[0]);
- secp256k1_ge_set_gej(&aggnonce[1], &aggnoncej[1]);
- if (!secp256k1_musig_compute_noncehash(noncehash, aggnonce, agg_pk32, msg)) {
- return 0;
- }
- /* fin_nonce = aggnonce[0] + b*aggnonce[1] */
- secp256k1_scalar_set_b32(b, noncehash, NULL);
- secp256k1_gej_set_infinity(&fin_nonce_ptj);
- secp256k1_ecmult(&fin_nonce_ptj, &aggnoncej[1], b, NULL);
- secp256k1_gej_add_ge_var(&fin_nonce_ptj, &fin_nonce_ptj, &aggnonce[0], NULL);
- secp256k1_ge_set_gej(&fin_nonce_pt, &fin_nonce_ptj);
- if (secp256k1_ge_is_infinity(&fin_nonce_pt)) {
- fin_nonce_pt = secp256k1_ge_const_g;
- }
- /* fin_nonce_pt is not the point at infinity */
- secp256k1_fe_normalize_var(&fin_nonce_pt.x);
- secp256k1_fe_get_b32(fin_nonce, &fin_nonce_pt.x);
- secp256k1_fe_normalize_var(&fin_nonce_pt.y);
- *fin_nonce_parity = secp256k1_fe_is_odd(&fin_nonce_pt.y);
- return 1;
-}
-
-int secp256k1_musig_nonce_process(const secp256k1_context* ctx, secp256k1_musig_session *session, const secp256k1_musig_aggnonce *aggnonce, const unsigned char *msg32, const secp256k1_musig_keyagg_cache *keyagg_cache, const secp256k1_pubkey *adaptor) {
- secp256k1_keyagg_cache_internal cache_i;
- secp256k1_ge aggnonce_pt[2];
- secp256k1_gej aggnonce_ptj[2];
- unsigned char fin_nonce[32];
- secp256k1_musig_session_internal session_i;
- unsigned char agg_pk32[32];
-
- VERIFY_CHECK(ctx != NULL);
- ARG_CHECK(session != NULL);
- ARG_CHECK(aggnonce != NULL);
- ARG_CHECK(msg32 != NULL);
- ARG_CHECK(keyagg_cache != NULL);
-
- if (!secp256k1_keyagg_cache_load(ctx, &cache_i, keyagg_cache)) {
- return 0;
- }
- secp256k1_fe_get_b32(agg_pk32, &cache_i.pk.x);
-
- if (!secp256k1_musig_aggnonce_load(ctx, aggnonce_pt, aggnonce)) {
- return 0;
- }
- secp256k1_gej_set_ge(&aggnonce_ptj[0], &aggnonce_pt[0]);
- secp256k1_gej_set_ge(&aggnonce_ptj[1], &aggnonce_pt[1]);
- /* Add public adaptor to nonce */
- if (adaptor != NULL) {
- secp256k1_ge adaptorp;
- if (!secp256k1_pubkey_load(ctx, &adaptorp, adaptor)) {
- return 0;
- }
- secp256k1_gej_add_ge_var(&aggnonce_ptj[0], &aggnonce_ptj[0], &adaptorp, NULL);
- }
- if (!secp256k1_musig_nonce_process_internal(&session_i.fin_nonce_parity, fin_nonce, &session_i.noncecoef, aggnonce_ptj, agg_pk32, msg32)) {
- return 0;
- }
-
- secp256k1_schnorrsig_challenge(&session_i.challenge, fin_nonce, msg32, 32, agg_pk32);
-
- /* If there is a tweak then set `challenge` times `tweak` to the `s`-part.*/
- secp256k1_scalar_set_int(&session_i.s_part, 0);
- if (!secp256k1_scalar_is_zero(&cache_i.tweak)) {
- secp256k1_scalar e_tmp;
- secp256k1_scalar_mul(&e_tmp, &session_i.challenge, &cache_i.tweak);
- if (secp256k1_fe_is_odd(&cache_i.pk.y)) {
- secp256k1_scalar_negate(&e_tmp, &e_tmp);
- }
- secp256k1_scalar_add(&session_i.s_part, &session_i.s_part, &e_tmp);
- }
- memcpy(session_i.fin_nonce, fin_nonce, sizeof(session_i.fin_nonce));
- secp256k1_musig_session_save(session, &session_i);
- return 1;
-}
-
-static void secp256k1_musig_partial_sign_clear(secp256k1_scalar *sk, secp256k1_scalar *k) {
- secp256k1_scalar_clear(sk);
- secp256k1_scalar_clear(&k[0]);
- secp256k1_scalar_clear(&k[1]);
-}
-
-int secp256k1_musig_partial_sign(const secp256k1_context* ctx, secp256k1_musig_partial_sig *partial_sig, secp256k1_musig_secnonce *secnonce, const secp256k1_keypair *keypair, const secp256k1_musig_keyagg_cache *keyagg_cache, const secp256k1_musig_session *session) {
- secp256k1_scalar sk;
- secp256k1_ge pk, keypair_pk;
- secp256k1_scalar k[2];
- secp256k1_scalar mu, s;
- secp256k1_keyagg_cache_internal cache_i;
- secp256k1_musig_session_internal session_i;
- int ret;
-
- VERIFY_CHECK(ctx != NULL);
-
- ARG_CHECK(secnonce != NULL);
- /* Fails if the magic doesn't match */
- ret = secp256k1_musig_secnonce_load(ctx, k, &pk, secnonce);
- /* Set nonce to zero to avoid nonce reuse. This will cause subsequent calls
- * of this function to fail */
- memset(secnonce, 0, sizeof(*secnonce));
- if (!ret) {
- secp256k1_musig_partial_sign_clear(&sk, k);
- return 0;
- }
-
- ARG_CHECK(partial_sig != NULL);
- ARG_CHECK(keypair != NULL);
- ARG_CHECK(keyagg_cache != NULL);
- ARG_CHECK(session != NULL);
-
- if (!secp256k1_keypair_load(ctx, &sk, &keypair_pk, keypair)) {
- secp256k1_musig_partial_sign_clear(&sk, k);
- return 0;
- }
- ARG_CHECK(secp256k1_fe_equal(&pk.x, &keypair_pk.x)
- && secp256k1_fe_equal(&pk.y, &keypair_pk.y));
- if (!secp256k1_keyagg_cache_load(ctx, &cache_i, keyagg_cache)) {
- secp256k1_musig_partial_sign_clear(&sk, k);
- return 0;
- }
- secp256k1_fe_normalize_var(&pk.y);
-
- /* Negate sk if secp256k1_fe_is_odd(&cache_i.pk.y)) XOR cache_i.parity_acc.
- * This corresponds to the line "Let d = gâ‹…gaccâ‹…d' mod n" in the
- * specification. */
- if ((secp256k1_fe_is_odd(&cache_i.pk.y)
- != cache_i.parity_acc)) {
- secp256k1_scalar_negate(&sk, &sk);
- }
-
- /* Multiply KeyAgg coefficient */
- secp256k1_fe_normalize_var(&pk.x);
- /* TODO Cache mu */
- secp256k1_musig_keyaggcoef(&mu, &cache_i, &pk);
- secp256k1_scalar_mul(&sk, &sk, &mu);
-
- if (!secp256k1_musig_session_load(ctx, &session_i, session)) {
- secp256k1_musig_partial_sign_clear(&sk, k);
- return 0;
- }
-
- if (session_i.fin_nonce_parity) {
- secp256k1_scalar_negate(&k[0], &k[0]);
- secp256k1_scalar_negate(&k[1], &k[1]);
- }
-
- /* Sign */
- secp256k1_scalar_mul(&s, &session_i.challenge, &sk);
- secp256k1_scalar_mul(&k[1], &session_i.noncecoef, &k[1]);
- secp256k1_scalar_add(&k[0], &k[0], &k[1]);
- secp256k1_scalar_add(&s, &s, &k[0]);
- secp256k1_musig_partial_sig_save(partial_sig, &s);
- secp256k1_musig_partial_sign_clear(&sk, k);
- return 1;
-}
-
-int secp256k1_musig_partial_sig_verify(const secp256k1_context* ctx, const secp256k1_musig_partial_sig *partial_sig, const secp256k1_musig_pubnonce *pubnonce, const secp256k1_pubkey *pubkey, const secp256k1_musig_keyagg_cache *keyagg_cache, const secp256k1_musig_session *session) {
- secp256k1_keyagg_cache_internal cache_i;
- secp256k1_musig_session_internal session_i;
- secp256k1_scalar mu, e, s;
- secp256k1_gej pkj;
- secp256k1_ge nonce_pt[2];
- secp256k1_gej rj;
- secp256k1_gej tmp;
- secp256k1_ge pkp;
-
- VERIFY_CHECK(ctx != NULL);
- ARG_CHECK(partial_sig != NULL);
- ARG_CHECK(pubnonce != NULL);
- ARG_CHECK(pubkey != NULL);
- ARG_CHECK(keyagg_cache != NULL);
- ARG_CHECK(session != NULL);
-
- if (!secp256k1_musig_session_load(ctx, &session_i, session)) {
- return 0;
- }
-
- /* Compute "effective" nonce rj = aggnonce[0] + b*aggnonce[1] */
- /* TODO: use multiexp to compute -s*G + e*mu*pubkey + aggnonce[0] + b*aggnonce[1] */
- if (!secp256k1_musig_pubnonce_load(ctx, nonce_pt, pubnonce)) {
- return 0;
- }
- secp256k1_gej_set_ge(&rj, &nonce_pt[1]);
- secp256k1_ecmult(&rj, &rj, &session_i.noncecoef, NULL);
- secp256k1_gej_add_ge_var(&rj, &rj, &nonce_pt[0], NULL);
-
- if (!secp256k1_pubkey_load(ctx, &pkp, pubkey)) {
- return 0;
- }
- if (!secp256k1_keyagg_cache_load(ctx, &cache_i, keyagg_cache)) {
- return 0;
- }
- /* Multiplying the challenge by the KeyAgg coefficient is equivalent
- * to multiplying the signer's public key by the coefficient, except
- * much easier to do. */
- secp256k1_musig_keyaggcoef(&mu, &cache_i, &pkp);
- secp256k1_scalar_mul(&e, &session_i.challenge, &mu);
-
- /* Negate e if secp256k1_fe_is_odd(&cache_i.pk.y)) XOR cache_i.parity_acc.
- * This corresponds to the line "Let g' = gâ‹…gacc mod n" and the multiplication "g'â‹…e"
- * in the specification. */
- if (secp256k1_fe_is_odd(&cache_i.pk.y)
- != cache_i.parity_acc) {
- secp256k1_scalar_negate(&e, &e);
- }
-
- if (!secp256k1_musig_partial_sig_load(ctx, &s, partial_sig)) {
- return 0;
- }
- /* Compute -s*G + e*pkj + rj (e already includes the keyagg coefficient mu) */
- secp256k1_scalar_negate(&s, &s);
- secp256k1_gej_set_ge(&pkj, &pkp);
- secp256k1_ecmult(&tmp, &pkj, &e, &s);
- if (session_i.fin_nonce_parity) {
- secp256k1_gej_neg(&rj, &rj);
- }
- secp256k1_gej_add_var(&tmp, &tmp, &rj, NULL);
-
- return secp256k1_gej_is_infinity(&tmp);
-}
-
-int secp256k1_musig_partial_sig_agg(const secp256k1_context* ctx, unsigned char *sig64, const secp256k1_musig_session *session, const secp256k1_musig_partial_sig * const* partial_sigs, size_t n_sigs) {
- size_t i;
- secp256k1_musig_session_internal session_i;
-
- VERIFY_CHECK(ctx != NULL);
- ARG_CHECK(sig64 != NULL);
- ARG_CHECK(session != NULL);
- ARG_CHECK(partial_sigs != NULL);
- ARG_CHECK(n_sigs > 0);
-
- if (!secp256k1_musig_session_load(ctx, &session_i, session)) {
- return 0;
- }
- for (i = 0; i < n_sigs; i++) {
- secp256k1_scalar term;
- if (!secp256k1_musig_partial_sig_load(ctx, &term, partial_sigs[i])) {
- return 0;
- }
- secp256k1_scalar_add(&session_i.s_part, &session_i.s_part, &term);
- }
- secp256k1_scalar_get_b32(&sig64[32], &session_i.s_part);
- memcpy(&sig64[0], session_i.fin_nonce, 32);
- return 1;
-}
-
-#endif
diff --git a/src/modules/musig/tests_impl.h b/src/modules/musig/tests_impl.h
deleted file mode 100644
index 13b41249..00000000
--- a/src/modules/musig/tests_impl.h
+++ /dev/null
@@ -1,1193 +0,0 @@
-/***********************************************************************
- * Copyright (c) 2018 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_MUSIG_TESTS_IMPL_H
-#define SECP256K1_MODULE_MUSIG_TESTS_IMPL_H
-
-#include
-#include
-
-#include "../../../include/secp256k1.h"
-#include "../../../include/secp256k1_extrakeys.h"
-#include "../../../include/secp256k1_musig.h"
-
-#include "session.h"
-#include "keyagg.h"
-#include "../../scalar.h"
-#include "../../scratch.h"
-#include "../../field.h"
-#include "../../group.h"
-#include "../../hash.h"
-#include "../../util.h"
-
-#include "vectors.h"
-
-static int create_keypair_and_pk(secp256k1_keypair *keypair, secp256k1_pubkey *pk, const unsigned char *sk) {
- int ret;
- secp256k1_keypair keypair_tmp;
- ret = secp256k1_keypair_create(CTX, &keypair_tmp, sk);
- ret &= secp256k1_keypair_pub(CTX, pk, &keypair_tmp);
- if (keypair != NULL) {
- *keypair = keypair_tmp;
- }
- return ret;
-}
-
-/* Just a simple (non-adaptor, non-tweaked) 2-of-2 MuSig aggregate, sign, verify
- * test. */
-static void musig_simple_test(secp256k1_scratch_space *scratch) {
- unsigned char sk[2][32];
- secp256k1_keypair keypair[2];
- secp256k1_musig_pubnonce pubnonce[2];
- const secp256k1_musig_pubnonce *pubnonce_ptr[2];
- secp256k1_musig_aggnonce aggnonce;
- unsigned char msg[32];
- secp256k1_xonly_pubkey agg_pk;
- secp256k1_musig_keyagg_cache keyagg_cache;
- unsigned char session_id[2][32];
- secp256k1_musig_secnonce secnonce[2];
- secp256k1_pubkey pk[2];
- const secp256k1_pubkey *pk_ptr[2];
- secp256k1_musig_partial_sig partial_sig[2];
- const secp256k1_musig_partial_sig *partial_sig_ptr[2];
- unsigned char final_sig[64];
- secp256k1_musig_session session;
- int i;
-
- testrand256(msg);
- for (i = 0; i < 2; i++) {
- testrand256(session_id[i]);
- testrand256(sk[i]);
- pk_ptr[i] = &pk[i];
- pubnonce_ptr[i] = &pubnonce[i];
- partial_sig_ptr[i] = &partial_sig[i];
-
- CHECK(create_keypair_and_pk(&keypair[i], &pk[i], sk[i]));
- CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce[i], &pubnonce[i], session_id[i], sk[i], &pk[i], NULL, NULL, NULL) == 1);
- }
-
- CHECK(secp256k1_musig_pubkey_agg(CTX, scratch, &agg_pk, &keyagg_cache, pk_ptr, 2) == 1);
- CHECK(secp256k1_musig_nonce_agg(CTX, &aggnonce, pubnonce_ptr, 2) == 1);
- CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, msg, &keyagg_cache, NULL) == 1);
-
- for (i = 0; i < 2; i++) {
- CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig[i], &secnonce[i], &keypair[i], &keyagg_cache, &session) == 1);
- CHECK(secp256k1_musig_partial_sig_verify(CTX, &partial_sig[i], &pubnonce[i], &pk[i], &keyagg_cache, &session) == 1);
- }
-
- CHECK(secp256k1_musig_partial_sig_agg(CTX, final_sig, &session, partial_sig_ptr, 2) == 1);
- CHECK(secp256k1_schnorrsig_verify(CTX, final_sig, msg, sizeof(msg), &agg_pk) == 1);
-}
-
-static void pubnonce_summing_to_inf(secp256k1_musig_pubnonce *pubnonce) {
- secp256k1_ge ge[2];
- int i;
- secp256k1_gej summed_nonces[2];
- const secp256k1_musig_pubnonce *pubnonce_ptr[2];
-
- ge[0] = secp256k1_ge_const_g;
- ge[1] = secp256k1_ge_const_g;
-
- for (i = 0; i < 2; i++) {
- secp256k1_musig_pubnonce_save(&pubnonce[i], ge);
- pubnonce_ptr[i] = &pubnonce[i];
- secp256k1_ge_neg(&ge[0], &ge[0]);
- secp256k1_ge_neg(&ge[1], &ge[1]);
- }
-
- secp256k1_musig_sum_nonces(CTX, summed_nonces, pubnonce_ptr, 2);
- CHECK(secp256k1_gej_is_infinity(&summed_nonces[0]));
- CHECK(secp256k1_gej_is_infinity(&summed_nonces[1]));
-}
-
-int memcmp_and_randomize(unsigned char *value, const unsigned char *expected, size_t len) {
- int ret;
- size_t i;
- ret = secp256k1_memcmp_var(value, expected, len);
- for (i = 0; i < len; i++) {
- value[i] = testrand_bits(8);
- }
- return ret;
-}
-
-static void musig_api_tests(secp256k1_scratch_space *scratch) {
- secp256k1_scratch_space *scratch_small;
- secp256k1_musig_partial_sig partial_sig[2];
- const secp256k1_musig_partial_sig *partial_sig_ptr[2];
- secp256k1_musig_partial_sig invalid_partial_sig;
- const secp256k1_musig_partial_sig *invalid_partial_sig_ptr[2];
- unsigned char final_sig[64];
- unsigned char pre_sig[64];
- unsigned char buf[32];
- unsigned char sk[2][32];
- secp256k1_keypair keypair[2];
- secp256k1_keypair invalid_keypair;
- unsigned char max64[64];
- unsigned char zeros132[132] = { 0 };
- unsigned char session_id[2][32];
- secp256k1_musig_secnonce secnonce[2];
- secp256k1_musig_secnonce secnonce_tmp;
- secp256k1_musig_secnonce invalid_secnonce;
- secp256k1_musig_pubnonce pubnonce[2];
- const secp256k1_musig_pubnonce *pubnonce_ptr[2];
- unsigned char pubnonce_ser[66];
- secp256k1_musig_pubnonce inf_pubnonce[2];
- const secp256k1_musig_pubnonce *inf_pubnonce_ptr[2];
- secp256k1_musig_pubnonce invalid_pubnonce;
- const secp256k1_musig_pubnonce *invalid_pubnonce_ptr[1];
- secp256k1_musig_aggnonce aggnonce;
- unsigned char aggnonce_ser[66];
- unsigned char msg[32];
- secp256k1_xonly_pubkey agg_pk;
- secp256k1_pubkey full_agg_pk;
- secp256k1_musig_keyagg_cache keyagg_cache;
- secp256k1_musig_keyagg_cache invalid_keyagg_cache;
- secp256k1_musig_session session;
- secp256k1_musig_session invalid_session;
- secp256k1_pubkey pk[2];
- const secp256k1_pubkey *pk_ptr[2];
- secp256k1_pubkey invalid_pk;
- const secp256k1_pubkey *invalid_pk_ptr2[2];
- const secp256k1_pubkey *invalid_pk_ptr3[3];
- unsigned char tweak[32];
- int nonce_parity;
- unsigned char sec_adaptor[32];
- unsigned char sec_adaptor1[32];
- secp256k1_pubkey adaptor;
- int i;
-
- /** setup **/
- memset(max64, 0xff, sizeof(max64));
- memset(&invalid_keypair, 0, sizeof(invalid_keypair));
- memset(&invalid_pk, 0, sizeof(invalid_pk));
- memset(&invalid_secnonce, 0, sizeof(invalid_secnonce));
- memset(&invalid_partial_sig, 0, sizeof(invalid_partial_sig));
- pubnonce_summing_to_inf(inf_pubnonce);
- /* Simulate structs being uninitialized by setting it to 0s. We don't want
- * to produce undefined behavior by actually providing uninitialized
- * structs. */
- memset(&invalid_keyagg_cache, 0, sizeof(invalid_keyagg_cache));
- memset(&invalid_pk, 0, sizeof(invalid_pk));
- memset(&invalid_pubnonce, 0, sizeof(invalid_pubnonce));
- memset(&invalid_session, 0, sizeof(invalid_session));
-
- testrand256(sec_adaptor);
- testrand256(msg);
- testrand256(tweak);
- CHECK(secp256k1_ec_pubkey_create(CTX, &adaptor, sec_adaptor) == 1);
- for (i = 0; i < 2; i++) {
- pk_ptr[i] = &pk[i];
- invalid_pk_ptr2[i] = &invalid_pk;
- invalid_pk_ptr3[i] = &pk[i];
- pubnonce_ptr[i] = &pubnonce[i];
- inf_pubnonce_ptr[i] = &inf_pubnonce[i];
- partial_sig_ptr[i] = &partial_sig[i];
- invalid_partial_sig_ptr[i] = &partial_sig[i];
- testrand256(session_id[i]);
- testrand256(sk[i]);
- CHECK(create_keypair_and_pk(&keypair[i], &pk[i], sk[i]));
- }
- invalid_pubnonce_ptr[0] = &invalid_pubnonce;
- invalid_partial_sig_ptr[0] = &invalid_partial_sig;
- /* invalid_pk_ptr3 has two valid, one invalid pk, which is important to test
- * musig_pubkey_agg */
- invalid_pk_ptr3[2] = &invalid_pk;
-
- /** main test body **/
-
- /** Key aggregation **/
- CHECK(secp256k1_musig_pubkey_agg(CTX, scratch, &agg_pk, &keyagg_cache, pk_ptr, 2) == 1);
- /* pubkey_agg does not require a scratch space */
- CHECK(secp256k1_musig_pubkey_agg(CTX, NULL, &agg_pk, &keyagg_cache, pk_ptr, 2) == 1);
- /* A small scratch space works too, but will result in using an ineffecient algorithm */
- scratch_small = secp256k1_scratch_space_create(CTX, 1);
- CHECK(secp256k1_musig_pubkey_agg(CTX, scratch_small, &agg_pk, &keyagg_cache, pk_ptr, 2) == 1);
- secp256k1_scratch_space_destroy(CTX, scratch_small);
- CHECK(secp256k1_musig_pubkey_agg(CTX, scratch, NULL, &keyagg_cache, pk_ptr, 2) == 1);
- CHECK(secp256k1_musig_pubkey_agg(CTX, scratch, &agg_pk, NULL, pk_ptr, 2) == 1);
- CHECK_ILLEGAL(CTX, secp256k1_musig_pubkey_agg(CTX, scratch, &agg_pk, &keyagg_cache, NULL, 2));
- CHECK(memcmp_and_randomize(agg_pk.data, zeros132, sizeof(agg_pk.data)) == 0);
- CHECK_ILLEGAL(CTX, secp256k1_musig_pubkey_agg(CTX, scratch, &agg_pk, &keyagg_cache, invalid_pk_ptr2, 2));
- CHECK(memcmp_and_randomize(agg_pk.data, zeros132, sizeof(agg_pk.data)) == 0);
- CHECK_ILLEGAL(CTX, secp256k1_musig_pubkey_agg(CTX, scratch, &agg_pk, &keyagg_cache, invalid_pk_ptr3, 3));
- CHECK(memcmp_and_randomize(agg_pk.data, zeros132, sizeof(agg_pk.data)) == 0);
- CHECK_ILLEGAL(CTX, secp256k1_musig_pubkey_agg(CTX, scratch, &agg_pk, &keyagg_cache, pk_ptr, 0));
- CHECK(memcmp_and_randomize(agg_pk.data, zeros132, sizeof(agg_pk.data)) == 0);
- CHECK_ILLEGAL(CTX, secp256k1_musig_pubkey_agg(CTX, scratch, &agg_pk, &keyagg_cache, NULL, 0));
- CHECK(memcmp_and_randomize(agg_pk.data, zeros132, sizeof(agg_pk.data)) == 0);
-
- CHECK(secp256k1_musig_pubkey_agg(CTX, scratch, &agg_pk, &keyagg_cache, pk_ptr, 2) == 1);
-
- /* pubkey_get */
- CHECK(secp256k1_musig_pubkey_get(CTX, &full_agg_pk, &keyagg_cache) == 1);
- CHECK_ILLEGAL(CTX, secp256k1_musig_pubkey_get(CTX, NULL, &keyagg_cache));
- CHECK_ILLEGAL(CTX, secp256k1_musig_pubkey_get(CTX, &full_agg_pk, NULL));
- CHECK(secp256k1_memcmp_var(&full_agg_pk, zeros132, sizeof(full_agg_pk)) == 0);
-
- /** Tweaking **/
- {
- int (*tweak_func[2]) (const secp256k1_context* ctx, secp256k1_pubkey *output_pubkey, secp256k1_musig_keyagg_cache *keyagg_cache, const unsigned char *tweak32);
- tweak_func[0] = secp256k1_musig_pubkey_ec_tweak_add;
- tweak_func[1] = secp256k1_musig_pubkey_xonly_tweak_add;
- for (i = 0; i < 2; i++) {
- secp256k1_pubkey tmp_output_pk;
- secp256k1_musig_keyagg_cache tmp_keyagg_cache = keyagg_cache;
- CHECK((*tweak_func[i])(CTX, &tmp_output_pk, &tmp_keyagg_cache, tweak) == 1);
- /* Reset keyagg_cache */
- tmp_keyagg_cache = keyagg_cache;
- CHECK((*tweak_func[i])(CTX, &tmp_output_pk, &tmp_keyagg_cache, tweak) == 1);
- tmp_keyagg_cache = keyagg_cache;
- CHECK((*tweak_func[i])(CTX, NULL, &tmp_keyagg_cache, tweak) == 1);
- tmp_keyagg_cache = keyagg_cache;
- CHECK_ILLEGAL(CTX, (*tweak_func[i])(CTX, &tmp_output_pk, NULL, tweak));
- CHECK(memcmp_and_randomize(tmp_output_pk.data, zeros132, sizeof(tmp_output_pk.data)) == 0);
- tmp_keyagg_cache = keyagg_cache;
- CHECK_ILLEGAL(CTX, (*tweak_func[i])(CTX, &tmp_output_pk, &tmp_keyagg_cache, NULL));
- CHECK(memcmp_and_randomize(tmp_output_pk.data, zeros132, sizeof(tmp_output_pk.data)) == 0);
- tmp_keyagg_cache = keyagg_cache;
- CHECK((*tweak_func[i])(CTX, &tmp_output_pk, &tmp_keyagg_cache, max64) == 0);
- CHECK(memcmp_and_randomize(tmp_output_pk.data, zeros132, sizeof(tmp_output_pk.data)) == 0);
- tmp_keyagg_cache = keyagg_cache;
- /* Uninitialized keyagg_cache */
- CHECK_ILLEGAL(CTX, (*tweak_func[i])(CTX, &tmp_output_pk, &invalid_keyagg_cache, tweak));
- CHECK(memcmp_and_randomize(tmp_output_pk.data, zeros132, sizeof(tmp_output_pk.data)) == 0);
- }
- }
-
- /** Session creation **/
- CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce[0], &pubnonce[0], session_id[0], sk[0], &pk[0], msg, &keyagg_cache, max64) == 1);
- CHECK_ILLEGAL(STATIC_CTX, secp256k1_musig_nonce_gen(STATIC_CTX, &secnonce[0], &pubnonce[0], session_id[0], sk[0], &pk[0], msg, &keyagg_cache, max64));
- CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_gen(CTX, NULL, &pubnonce[0], session_id[0], sk[0], &pk[0], msg, &keyagg_cache, max64));
- CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_gen(CTX, &secnonce[0], NULL, session_id[0], sk[0], &pk[0], msg, &keyagg_cache, max64));
- CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_gen(CTX, &secnonce[0], &pubnonce[0], NULL, sk[0], &pk[0], msg, &keyagg_cache, max64));
- CHECK(memcmp_and_randomize(secnonce[0].data, zeros132, sizeof(secnonce[0].data)) == 0);
- /* no seckey and session_id is 0 */
- CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce[0], &pubnonce[0], zeros132, NULL, &pk[0], msg, &keyagg_cache, max64) == 0);
- CHECK(memcmp_and_randomize(secnonce[0].data, zeros132, sizeof(secnonce[0].data)) == 0);
- /* session_id 0 is fine when a seckey is provided */
- CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce[0], &pubnonce[0], zeros132, sk[0], &pk[0], msg, &keyagg_cache, max64) == 1);
- CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce[0], &pubnonce[0], session_id[0], NULL, &pk[0], msg, &keyagg_cache, max64) == 1);
- /* invalid seckey */
- CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce[0], &pubnonce[0], session_id[0], max64, &pk[0], msg, &keyagg_cache, max64) == 0);
- CHECK(memcmp_and_randomize(secnonce[0].data, zeros132, sizeof(secnonce[0].data)) == 0);
- CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_gen(CTX, &secnonce[0], &pubnonce[0], session_id[0], sk[0], NULL, msg, &keyagg_cache, max64));
- CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_gen(CTX, &secnonce[0], &pubnonce[0], session_id[0], sk[0], &invalid_pk, msg, &keyagg_cache, max64));
- CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce[0], &pubnonce[0], session_id[0], sk[0], &pk[0], NULL, &keyagg_cache, max64) == 1);
- CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce[0], &pubnonce[0], session_id[0], sk[0], &pk[0], msg, NULL, max64) == 1);
- CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_gen(CTX, &secnonce[0], &pubnonce[0], session_id[0], sk[0], &pk[0], msg, &invalid_keyagg_cache, max64));
- CHECK(memcmp_and_randomize(secnonce[0].data, zeros132, sizeof(secnonce[0].data)) == 0);
- CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce[0], &pubnonce[0], session_id[0], sk[0], &pk[0], msg, &keyagg_cache, NULL) == 1);
-
- /* Every in-argument except session_id and pubkey can be NULL */
- CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce[0], &pubnonce[0], session_id[0], NULL, &pk[0], NULL, NULL, NULL) == 1);
- CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce[1], &pubnonce[1], session_id[1], sk[1], &pk[1], NULL, NULL, NULL) == 1);
-
- /** Serialize and parse public nonces **/
- CHECK_ILLEGAL(CTX, secp256k1_musig_pubnonce_serialize(CTX, NULL, &pubnonce[0]));
- CHECK_ILLEGAL(CTX, secp256k1_musig_pubnonce_serialize(CTX, pubnonce_ser, NULL));
- CHECK(memcmp_and_randomize(pubnonce_ser, zeros132, sizeof(pubnonce_ser)) == 0);
- CHECK_ILLEGAL(CTX, secp256k1_musig_pubnonce_serialize(CTX, pubnonce_ser, &invalid_pubnonce));
- CHECK(memcmp_and_randomize(pubnonce_ser, zeros132, sizeof(pubnonce_ser)) == 0);
- CHECK(secp256k1_musig_pubnonce_serialize(CTX, pubnonce_ser, &pubnonce[0]) == 1);
-
- CHECK(secp256k1_musig_pubnonce_parse(CTX, &pubnonce[0], pubnonce_ser) == 1);
- CHECK_ILLEGAL(CTX, secp256k1_musig_pubnonce_parse(CTX, NULL, pubnonce_ser));
- CHECK_ILLEGAL(CTX, secp256k1_musig_pubnonce_parse(CTX, &pubnonce[0], NULL));
- CHECK(secp256k1_musig_pubnonce_parse(CTX, &pubnonce[0], zeros132) == 0);
- CHECK(secp256k1_musig_pubnonce_parse(CTX, &pubnonce[0], pubnonce_ser) == 1);
-
- {
- /* Check that serialize and parse results in the same value */
- secp256k1_musig_pubnonce tmp;
- CHECK(secp256k1_musig_pubnonce_serialize(CTX, pubnonce_ser, &pubnonce[0]) == 1);
- CHECK(secp256k1_musig_pubnonce_parse(CTX, &tmp, pubnonce_ser) == 1);
- CHECK(secp256k1_memcmp_var(&tmp, &pubnonce[0], sizeof(tmp)) == 0);
- }
-
- /** Receive nonces and aggregate **/
- CHECK(secp256k1_musig_nonce_agg(CTX, &aggnonce, pubnonce_ptr, 2) == 1);
- CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_agg(CTX, NULL, pubnonce_ptr, 2));
- CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_agg(CTX, &aggnonce, NULL, 2));
- CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_agg(CTX, &aggnonce, pubnonce_ptr, 0));
- CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_agg(CTX, &aggnonce, invalid_pubnonce_ptr, 1));
- CHECK(secp256k1_musig_nonce_agg(CTX, &aggnonce, inf_pubnonce_ptr, 2) == 1);
- {
- /* Check that the aggnonce encodes two points at infinity */
- secp256k1_ge aggnonce_pt[2];
- secp256k1_musig_aggnonce_load(CTX, aggnonce_pt, &aggnonce);
- for (i = 0; i < 2; i++) {
- secp256k1_ge_is_infinity(&aggnonce_pt[i]);
- }
- }
- CHECK(secp256k1_musig_nonce_agg(CTX, &aggnonce, pubnonce_ptr, 2) == 1);
-
- /** Serialize and parse aggregate nonces **/
- CHECK(secp256k1_musig_aggnonce_serialize(CTX, aggnonce_ser, &aggnonce) == 1);
- CHECK_ILLEGAL(CTX, secp256k1_musig_aggnonce_serialize(CTX, NULL, &aggnonce));
- CHECK_ILLEGAL(CTX, secp256k1_musig_aggnonce_serialize(CTX, aggnonce_ser, NULL));
- CHECK(memcmp_and_randomize(aggnonce_ser, zeros132, sizeof(aggnonce_ser)) == 0);
- CHECK_ILLEGAL(CTX, secp256k1_musig_aggnonce_serialize(CTX, aggnonce_ser, (secp256k1_musig_aggnonce*) &invalid_pubnonce));
- CHECK(memcmp_and_randomize(aggnonce_ser, zeros132, sizeof(aggnonce_ser)) == 0);
- CHECK(secp256k1_musig_aggnonce_serialize(CTX, aggnonce_ser, &aggnonce) == 1);
-
- CHECK(secp256k1_musig_aggnonce_parse(CTX, &aggnonce, aggnonce_ser) == 1);
- CHECK_ILLEGAL(CTX, secp256k1_musig_aggnonce_parse(CTX, NULL, aggnonce_ser));
- CHECK_ILLEGAL(CTX, secp256k1_musig_aggnonce_parse(CTX, &aggnonce, NULL));
- CHECK(secp256k1_musig_aggnonce_parse(CTX, &aggnonce, zeros132) == 1);
- CHECK(secp256k1_musig_aggnonce_parse(CTX, &aggnonce, aggnonce_ser) == 1);
-
- {
- /* Check that serialize and parse results in the same value */
- secp256k1_musig_aggnonce tmp;
- CHECK(secp256k1_musig_aggnonce_serialize(CTX, aggnonce_ser, &aggnonce) == 1);
- CHECK(secp256k1_musig_aggnonce_parse(CTX, &tmp, aggnonce_ser) == 1);
- CHECK(secp256k1_memcmp_var(&tmp, &aggnonce, sizeof(tmp)) == 0);
- }
-
- /** Process nonces **/
- CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, msg, &keyagg_cache, &adaptor) == 1);
- CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_process(CTX, NULL, &aggnonce, msg, &keyagg_cache, &adaptor));
- CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_process(CTX, &session, NULL, msg, &keyagg_cache, &adaptor));
- CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_process(CTX, &session, (secp256k1_musig_aggnonce*) &invalid_pubnonce, msg, &keyagg_cache, &adaptor));
- CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_process(CTX, &session, &aggnonce, NULL, &keyagg_cache, &adaptor));
- CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_process(CTX, &session, &aggnonce, msg, NULL, &adaptor));
- CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_process(CTX, &session, &aggnonce, msg, &invalid_keyagg_cache, &adaptor));
- CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, msg, &keyagg_cache, NULL) == 1);
- CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_process(CTX, &session, &aggnonce, msg, &keyagg_cache, (secp256k1_pubkey *)&invalid_pk));
-
- CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, msg, &keyagg_cache, &adaptor) == 1);
-
- memcpy(&secnonce_tmp, &secnonce[0], sizeof(secnonce_tmp));
- CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig[0], &secnonce_tmp, &keypair[0], &keyagg_cache, &session) == 1);
- /* The secnonce is set to 0 and subsequent signing attempts fail */
- CHECK(secp256k1_memcmp_var(&secnonce_tmp, zeros132, sizeof(secnonce_tmp)) == 0);
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sign(CTX, &partial_sig[0], &secnonce_tmp, &keypair[0], &keyagg_cache, &session));
- memcpy(&secnonce_tmp, &secnonce[0], sizeof(secnonce_tmp));
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sign(CTX, NULL, &secnonce_tmp, &keypair[0], &keyagg_cache, &session));
- memcpy(&secnonce_tmp, &secnonce[0], sizeof(secnonce_tmp));
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sign(CTX, &partial_sig[0], NULL, &keypair[0], &keyagg_cache, &session));
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sign(CTX, &partial_sig[0], &invalid_secnonce, &keypair[0], &keyagg_cache, &session));
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sign(CTX, &partial_sig[0], &secnonce_tmp, NULL, &keyagg_cache, &session));
- memcpy(&secnonce_tmp, &secnonce[0], sizeof(secnonce_tmp));
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sign(CTX, &partial_sig[0], &secnonce_tmp, &invalid_keypair, &keyagg_cache, &session));
- memcpy(&secnonce_tmp, &secnonce[0], sizeof(secnonce_tmp));
- {
- unsigned char sk_tmp[32];
- secp256k1_keypair keypair_tmp;
- testrand256(sk_tmp);
- CHECK(secp256k1_keypair_create(CTX, &keypair_tmp, sk_tmp));
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sign(CTX, &partial_sig[0], &secnonce_tmp, &keypair_tmp, &keyagg_cache, &session));
- memcpy(&secnonce_tmp, &secnonce[0], sizeof(secnonce_tmp));
- }
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sign(CTX, &partial_sig[0], &secnonce_tmp, &keypair[0], NULL, &session));
- memcpy(&secnonce_tmp, &secnonce[0], sizeof(secnonce_tmp));
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sign(CTX, &partial_sig[0], &secnonce_tmp, &keypair[0], &invalid_keyagg_cache, &session));
- memcpy(&secnonce_tmp, &secnonce[0], sizeof(secnonce_tmp));
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sign(CTX, &partial_sig[0], &secnonce_tmp, &keypair[0], &keyagg_cache, NULL));
- memcpy(&secnonce_tmp, &secnonce[0], sizeof(secnonce_tmp));
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sign(CTX, &partial_sig[0], &secnonce_tmp, &keypair[0], &keyagg_cache, &invalid_session));
- memcpy(&secnonce_tmp, &secnonce[0], sizeof(secnonce_tmp));
-
- CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig[0], &secnonce[0], &keypair[0], &keyagg_cache, &session) == 1);
- CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig[1], &secnonce[1], &keypair[1], &keyagg_cache, &session) == 1);
-
- CHECK(secp256k1_musig_partial_sig_serialize(CTX, buf, &partial_sig[0]) == 1);
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_serialize(CTX, NULL, &partial_sig[0]));
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_serialize(CTX, buf, NULL));
- CHECK(secp256k1_musig_partial_sig_parse(CTX, &partial_sig[0], buf) == 1);
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_parse(CTX, NULL, buf));
- CHECK(secp256k1_musig_partial_sig_parse(CTX, &partial_sig[0], max64) == 0);
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_parse(CTX, &partial_sig[0], NULL));
-
- {
- /* Check that serialize and parse results in the same value */
- secp256k1_musig_partial_sig tmp;
- CHECK(secp256k1_musig_partial_sig_serialize(CTX, buf, &partial_sig[0]) == 1);
- CHECK(secp256k1_musig_partial_sig_parse(CTX, &tmp, buf) == 1);
- CHECK(secp256k1_memcmp_var(&tmp, &partial_sig[0], sizeof(tmp)) == 0);
- }
-
- /** Partial signature verification */
- CHECK(secp256k1_musig_partial_sig_verify(CTX, &partial_sig[0], &pubnonce[0], &pk[0], &keyagg_cache, &session) == 1);
- CHECK(secp256k1_musig_partial_sig_verify(CTX, &partial_sig[1], &pubnonce[0], &pk[0], &keyagg_cache, &session) == 0);
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_verify(CTX, NULL, &pubnonce[0], &pk[0], &keyagg_cache, &session));
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_verify(CTX, &invalid_partial_sig, &pubnonce[0], &pk[0], &keyagg_cache, &session));
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_verify(CTX, &partial_sig[0], NULL, &pk[0], &keyagg_cache, &session));
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_verify(CTX, &partial_sig[0], &invalid_pubnonce, &pk[0], &keyagg_cache, &session));
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_verify(CTX, &partial_sig[0], &pubnonce[0], NULL, &keyagg_cache, &session));
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_verify(CTX, &partial_sig[0], &pubnonce[0], &invalid_pk, &keyagg_cache, &session));
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_verify(CTX, &partial_sig[0], &pubnonce[0], &pk[0], NULL, &session));
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_verify(CTX, &partial_sig[0], &pubnonce[0], &pk[0], &invalid_keyagg_cache, &session));
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_verify(CTX, &partial_sig[0], &pubnonce[0], &pk[0], &keyagg_cache, NULL));
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_verify(CTX, &partial_sig[0], &pubnonce[0], &pk[0], &keyagg_cache, &invalid_session));
-
- CHECK(secp256k1_musig_partial_sig_verify(CTX, &partial_sig[0], &pubnonce[0], &pk[0], &keyagg_cache, &session) == 1);
- CHECK(secp256k1_musig_partial_sig_verify(CTX, &partial_sig[1], &pubnonce[1], &pk[1], &keyagg_cache, &session) == 1);
-
- /** Signature aggregation and verification */
- CHECK(secp256k1_musig_partial_sig_agg(CTX, pre_sig, &session, partial_sig_ptr, 2) == 1);
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_agg(CTX, NULL, &session, partial_sig_ptr, 2));
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_agg(CTX, pre_sig, NULL, partial_sig_ptr, 2));
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_agg(CTX, pre_sig, &invalid_session, partial_sig_ptr, 2));
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_agg(CTX, pre_sig, &session, NULL, 2));
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_agg(CTX, pre_sig, &session, invalid_partial_sig_ptr, 2));
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_agg(CTX, pre_sig, &session, partial_sig_ptr, 0));
- CHECK(secp256k1_musig_partial_sig_agg(CTX, pre_sig, &session, partial_sig_ptr, 1) == 1);
- CHECK(secp256k1_musig_partial_sig_agg(CTX, pre_sig, &session, partial_sig_ptr, 2) == 1);
-
- /** Adaptor signature verification */
- CHECK(secp256k1_musig_nonce_parity(CTX, &nonce_parity, &session) == 1);
- CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_parity(CTX, NULL, &session));
- CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_parity(CTX, &nonce_parity, NULL));
- CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_parity(CTX, &nonce_parity, &invalid_session));
-
- CHECK(secp256k1_musig_adapt(CTX, final_sig, pre_sig, sec_adaptor, nonce_parity) == 1);
- CHECK_ILLEGAL(CTX, secp256k1_musig_adapt(CTX, NULL, pre_sig, sec_adaptor, 0));
- CHECK_ILLEGAL(CTX, secp256k1_musig_adapt(CTX, final_sig, NULL, sec_adaptor, 0));
- CHECK(secp256k1_musig_adapt(CTX, final_sig, max64, sec_adaptor, 0) == 0);
- CHECK_ILLEGAL(CTX, secp256k1_musig_adapt(CTX, final_sig, pre_sig, NULL, 0));
- CHECK(secp256k1_musig_adapt(CTX, final_sig, pre_sig, max64, 0) == 0);
- CHECK_ILLEGAL(CTX, secp256k1_musig_adapt(CTX, final_sig, pre_sig, sec_adaptor, 2));
- /* sig and pre_sig argument point to the same location */
- memcpy(final_sig, pre_sig, sizeof(final_sig));
- CHECK(secp256k1_musig_adapt(CTX, final_sig, final_sig, sec_adaptor, nonce_parity) == 1);
- CHECK(secp256k1_schnorrsig_verify(CTX, final_sig, msg, sizeof(msg), &agg_pk) == 1);
-
- CHECK(secp256k1_musig_adapt(CTX, final_sig, pre_sig, sec_adaptor, nonce_parity) == 1);
- CHECK(secp256k1_schnorrsig_verify(CTX, final_sig, msg, sizeof(msg), &agg_pk) == 1);
-
- /** Secret adaptor can be extracted from signature */
- CHECK(secp256k1_musig_extract_adaptor(CTX, sec_adaptor1, final_sig, pre_sig, nonce_parity) == 1);
- CHECK(secp256k1_memcmp_var(sec_adaptor, sec_adaptor1, 32) == 0);
- /* wrong nonce parity */
- CHECK(secp256k1_musig_extract_adaptor(CTX, sec_adaptor1, final_sig, pre_sig, !nonce_parity) == 1);
- CHECK(secp256k1_memcmp_var(sec_adaptor, sec_adaptor1, 32) != 0);
- CHECK_ILLEGAL(CTX, secp256k1_musig_extract_adaptor(CTX, NULL, final_sig, pre_sig, 0));
- CHECK_ILLEGAL(CTX, secp256k1_musig_extract_adaptor(CTX, sec_adaptor1, NULL, pre_sig, 0));
- CHECK(secp256k1_musig_extract_adaptor(CTX, sec_adaptor1, max64, pre_sig, 0) == 0);
- CHECK_ILLEGAL(CTX, secp256k1_musig_extract_adaptor(CTX, sec_adaptor1, final_sig, NULL, 0));
- CHECK(secp256k1_musig_extract_adaptor(CTX, sec_adaptor1, final_sig, max64, 0) == 0);
- CHECK_ILLEGAL(CTX, secp256k1_musig_extract_adaptor(CTX, sec_adaptor1, final_sig, pre_sig, 2));
-}
-
-static void musig_nonce_bitflip(unsigned char **args, size_t n_flip, size_t n_bytes) {
- secp256k1_scalar k1[2], k2[2];
-
- secp256k1_nonce_function_musig(k1, args[0], args[1], args[2], args[3], args[4], args[5]);
- testrand_flip(args[n_flip], n_bytes);
- secp256k1_nonce_function_musig(k2, args[0], args[1], args[2], args[3], args[4], args[5]);
- CHECK(secp256k1_scalar_eq(&k1[0], &k2[0]) == 0);
- CHECK(secp256k1_scalar_eq(&k1[1], &k2[1]) == 0);
-}
-
-static void musig_nonce_test(void) {
- unsigned char *args[6];
- unsigned char session_id[32];
- unsigned char sk[32];
- unsigned char pk[33];
- unsigned char msg[32];
- unsigned char agg_pk[32];
- unsigned char extra_input[32];
- int i, j;
- secp256k1_scalar k[6][2];
-
- testrand_bytes_test(session_id, sizeof(session_id));
- testrand_bytes_test(sk, sizeof(sk));
- testrand_bytes_test(pk, sizeof(pk));
- testrand_bytes_test(msg, sizeof(msg));
- testrand_bytes_test(agg_pk, sizeof(agg_pk));
- testrand_bytes_test(extra_input, sizeof(extra_input));
-
- /* Check that a bitflip in an argument results in different nonces. */
- args[0] = session_id;
- args[1] = msg;
- args[2] = sk;
- args[3] = pk;
- args[4] = agg_pk;
- args[5] = extra_input;
- for (i = 0; i < COUNT; i++) {
- musig_nonce_bitflip(args, 0, sizeof(session_id));
- musig_nonce_bitflip(args, 1, sizeof(msg));
- musig_nonce_bitflip(args, 2, sizeof(sk));
- musig_nonce_bitflip(args, 3, sizeof(pk));
- musig_nonce_bitflip(args, 4, sizeof(agg_pk));
- musig_nonce_bitflip(args, 5, sizeof(extra_input));
- }
- /* Check that if any argument is NULL, a different nonce is produced than if
- * any other argument is NULL. */
- memcpy(msg, session_id, sizeof(msg));
- memcpy(sk, session_id, sizeof(sk));
- memcpy(pk, session_id, sizeof(session_id));
- memcpy(agg_pk, session_id, sizeof(agg_pk));
- memcpy(extra_input, session_id, sizeof(extra_input));
- secp256k1_nonce_function_musig(k[0], args[0], args[1], args[2], args[3], args[4], args[5]);
- secp256k1_nonce_function_musig(k[1], args[0], NULL, args[2], args[3], args[4], args[5]);
- secp256k1_nonce_function_musig(k[2], args[0], args[1], NULL, args[3], args[4], args[5]);
- secp256k1_nonce_function_musig(k[3], args[0], args[1], args[2], NULL, args[4], args[5]);
- secp256k1_nonce_function_musig(k[4], args[0], args[1], args[2], args[3], NULL, args[5]);
- secp256k1_nonce_function_musig(k[5], args[0], args[1], args[2], args[3], args[4], NULL);
- for (i = 0; i < 6; i++) {
- CHECK(!secp256k1_scalar_eq(&k[i][0], &k[i][1]));
- for (j = i+1; j < 6; j++) {
- CHECK(!secp256k1_scalar_eq(&k[i][0], &k[j][0]));
- CHECK(!secp256k1_scalar_eq(&k[i][1], &k[j][1]));
- }
- }
-}
-
-static void scriptless_atomic_swap(secp256k1_scratch_space *scratch) {
- /* Throughout this test "a" and "b" refer to two hypothetical blockchains,
- * while the indices 0 and 1 refer to the two signers. Here signer 0 is
- * sending a-coins to signer 1, while signer 1 is sending b-coins to signer
- * 0. Signer 0 produces the adaptor signatures. */
- unsigned char pre_sig_a[64];
- unsigned char final_sig_a[64];
- unsigned char pre_sig_b[64];
- unsigned char final_sig_b[64];
- secp256k1_musig_partial_sig partial_sig_a[2];
- const secp256k1_musig_partial_sig *partial_sig_a_ptr[2];
- secp256k1_musig_partial_sig partial_sig_b[2];
- const secp256k1_musig_partial_sig *partial_sig_b_ptr[2];
- unsigned char sec_adaptor[32];
- unsigned char sec_adaptor_extracted[32];
- secp256k1_pubkey pub_adaptor;
- unsigned char sk_a[2][32];
- unsigned char sk_b[2][32];
- secp256k1_keypair keypair_a[2];
- secp256k1_keypair keypair_b[2];
- secp256k1_pubkey pk_a[2];
- const secp256k1_pubkey *pk_a_ptr[2];
- secp256k1_pubkey pk_b[2];
- const secp256k1_pubkey *pk_b_ptr[2];
- secp256k1_musig_keyagg_cache keyagg_cache_a;
- secp256k1_musig_keyagg_cache keyagg_cache_b;
- secp256k1_xonly_pubkey agg_pk_a;
- secp256k1_xonly_pubkey agg_pk_b;
- secp256k1_musig_secnonce secnonce_a[2];
- secp256k1_musig_secnonce secnonce_b[2];
- secp256k1_musig_pubnonce pubnonce_a[2];
- secp256k1_musig_pubnonce pubnonce_b[2];
- const secp256k1_musig_pubnonce *pubnonce_ptr_a[2];
- const secp256k1_musig_pubnonce *pubnonce_ptr_b[2];
- secp256k1_musig_aggnonce aggnonce_a;
- secp256k1_musig_aggnonce aggnonce_b;
- secp256k1_musig_session session_a, session_b;
- int nonce_parity_a;
- int nonce_parity_b;
- unsigned char seed_a[2][32] = { "a0", "a1" };
- unsigned char seed_b[2][32] = { "b0", "b1" };
- const unsigned char msg32_a[32] = {'t', 'h', 'i', 's', ' ', 'i', 's', ' ', 't', 'h', 'e', ' ', 'm', 'e', 's', 's', 'a', 'g', 'e', ' ', 'b', 'l', 'o', 'c', 'k', 'c', 'h', 'a', 'i', 'n', ' ', 'a'};
- const unsigned char msg32_b[32] = {'t', 'h', 'i', 's', ' ', 'i', 's', ' ', 't', 'h', 'e', ' ', 'm', 'e', 's', 's', 'a', 'g', 'e', ' ', 'b', 'l', 'o', 'c', 'k', 'c', 'h', 'a', 'i', 'n', ' ', 'b'};
- int i;
-
- /* Step 1: key setup */
- for (i = 0; i < 2; i++) {
- pk_a_ptr[i] = &pk_a[i];
- pk_b_ptr[i] = &pk_b[i];
- pubnonce_ptr_a[i] = &pubnonce_a[i];
- pubnonce_ptr_b[i] = &pubnonce_b[i];
- partial_sig_a_ptr[i] = &partial_sig_a[i];
- partial_sig_b_ptr[i] = &partial_sig_b[i];
-
- testrand256(sk_a[i]);
- testrand256(sk_b[i]);
- CHECK(create_keypair_and_pk(&keypair_a[i], &pk_a[i], sk_a[i]) == 1);
- CHECK(create_keypair_and_pk(&keypair_b[i], &pk_b[i], sk_b[i]) == 1);
- }
- testrand256(sec_adaptor);
- CHECK(secp256k1_ec_pubkey_create(CTX, &pub_adaptor, sec_adaptor) == 1);
-
- CHECK(secp256k1_musig_pubkey_agg(CTX, scratch, &agg_pk_a, &keyagg_cache_a, pk_a_ptr, 2) == 1);
- CHECK(secp256k1_musig_pubkey_agg(CTX, scratch, &agg_pk_b, &keyagg_cache_b, pk_b_ptr, 2) == 1);
-
- CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce_a[0], &pubnonce_a[0], seed_a[0], sk_a[0], &pk_a[0], NULL, NULL, NULL) == 1);
- CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce_a[1], &pubnonce_a[1], seed_a[1], sk_a[1], &pk_a[1], NULL, NULL, NULL) == 1);
- CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce_b[0], &pubnonce_b[0], seed_b[0], sk_b[0], &pk_b[0], NULL, NULL, NULL) == 1);
- CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce_b[1], &pubnonce_b[1], seed_b[1], sk_b[1], &pk_b[1], NULL, NULL, NULL) == 1);
-
- /* Step 2: Exchange nonces */
- CHECK(secp256k1_musig_nonce_agg(CTX, &aggnonce_a, pubnonce_ptr_a, 2) == 1);
- CHECK(secp256k1_musig_nonce_process(CTX, &session_a, &aggnonce_a, msg32_a, &keyagg_cache_a, &pub_adaptor) == 1);
- CHECK(secp256k1_musig_nonce_parity(CTX, &nonce_parity_a, &session_a) == 1);
- CHECK(secp256k1_musig_nonce_agg(CTX, &aggnonce_b, pubnonce_ptr_b, 2) == 1);
- CHECK(secp256k1_musig_nonce_process(CTX, &session_b, &aggnonce_b, msg32_b, &keyagg_cache_b, &pub_adaptor) == 1);
- CHECK(secp256k1_musig_nonce_parity(CTX, &nonce_parity_b, &session_b) == 1);
-
- /* Step 3: Signer 0 produces partial signatures for both chains. */
- CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig_a[0], &secnonce_a[0], &keypair_a[0], &keyagg_cache_a, &session_a) == 1);
- CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig_b[0], &secnonce_b[0], &keypair_b[0], &keyagg_cache_b, &session_b) == 1);
-
- /* Step 4: Signer 1 receives partial signatures, verifies them and creates a
- * partial signature to send B-coins to signer 0. */
- CHECK(secp256k1_musig_partial_sig_verify(CTX, &partial_sig_a[0], &pubnonce_a[0], &pk_a[0], &keyagg_cache_a, &session_a) == 1);
- CHECK(secp256k1_musig_partial_sig_verify(CTX, &partial_sig_b[0], &pubnonce_b[0], &pk_b[0], &keyagg_cache_b, &session_b) == 1);
- CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig_b[1], &secnonce_b[1], &keypair_b[1], &keyagg_cache_b, &session_b) == 1);
-
- /* Step 5: Signer 0 aggregates its own partial signature with the partial
- * signature from signer 1 and adapts it. This results in a complete
- * signature which is broadcasted by signer 0 to take B-coins. */
- CHECK(secp256k1_musig_partial_sig_agg(CTX, pre_sig_b, &session_b, partial_sig_b_ptr, 2) == 1);
- CHECK(secp256k1_musig_adapt(CTX, final_sig_b, pre_sig_b, sec_adaptor, nonce_parity_b) == 1);
- CHECK(secp256k1_schnorrsig_verify(CTX, final_sig_b, msg32_b, sizeof(msg32_b), &agg_pk_b) == 1);
-
- /* Step 6: Signer 1 signs, extracts adaptor from the published signature,
- * and adapts the signature to take A-coins. */
- CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig_a[1], &secnonce_a[1], &keypair_a[1], &keyagg_cache_a, &session_a) == 1);
- CHECK(secp256k1_musig_partial_sig_agg(CTX, pre_sig_a, &session_a, partial_sig_a_ptr, 2) == 1);
- CHECK(secp256k1_musig_extract_adaptor(CTX, sec_adaptor_extracted, final_sig_b, pre_sig_b, nonce_parity_b) == 1);
- CHECK(secp256k1_memcmp_var(sec_adaptor_extracted, sec_adaptor, sizeof(sec_adaptor)) == 0); /* in real life we couldn't check this, of course */
- CHECK(secp256k1_musig_adapt(CTX, final_sig_a, pre_sig_a, sec_adaptor_extracted, nonce_parity_a) == 1);
- CHECK(secp256k1_schnorrsig_verify(CTX, final_sig_a, msg32_a, sizeof(msg32_a), &agg_pk_a) == 1);
-}
-
-static void sha256_tag_test_internal(secp256k1_sha256 *sha_tagged, unsigned char *tag, size_t taglen) {
- secp256k1_sha256 sha;
- unsigned char buf[32];
- unsigned char buf2[32];
- size_t i;
-
- secp256k1_sha256_initialize(&sha);
- secp256k1_sha256_write(&sha, tag, taglen);
- secp256k1_sha256_finalize(&sha, buf);
- /* buf = SHA256(tag) */
-
- secp256k1_sha256_initialize(&sha);
- secp256k1_sha256_write(&sha, buf, 32);
- secp256k1_sha256_write(&sha, buf, 32);
- /* Is buffer fully consumed? */
- CHECK((sha.bytes & 0x3F) == 0);
-
- /* Compare with tagged SHA */
- for (i = 0; i < 8; i++) {
- CHECK(sha_tagged->s[i] == sha.s[i]);
- }
- secp256k1_sha256_write(&sha, buf, 32);
- secp256k1_sha256_write(sha_tagged, buf, 32);
- secp256k1_sha256_finalize(&sha, buf);
- secp256k1_sha256_finalize(sha_tagged, buf2);
- CHECK(secp256k1_memcmp_var(buf, buf2, 32) == 0);
-}
-
-/* Checks that the initialized tagged hashes initialized have the expected
- * state. */
-static void sha256_tag_test(void) {
- secp256k1_sha256 sha_tagged;
- {
- char tag[] = {'K', 'e', 'y', 'A', 'g', 'g', ' ', 'l', 'i', 's', 't'};
- secp256k1_musig_keyagglist_sha256(&sha_tagged);
- sha256_tag_test_internal(&sha_tagged, (unsigned char*)tag, sizeof(tag));
- }
- {
- char tag[] = {'K', 'e', 'y', 'A', 'g', 'g', ' ', 'c', 'o', 'e', 'f', 'f', 'i', 'c', 'i', 'e', 'n', 't'};
- secp256k1_musig_keyaggcoef_sha256(&sha_tagged);
- sha256_tag_test_internal(&sha_tagged, (unsigned char*)tag, sizeof(tag));
- }
-}
-
-/* Attempts to create a signature for the aggregate public key using given secret
- * keys and keyagg_cache. */
-static void musig_tweak_test_helper(const secp256k1_xonly_pubkey* agg_pk, const unsigned char *sk0, const unsigned char *sk1, secp256k1_musig_keyagg_cache *keyagg_cache) {
- secp256k1_pubkey pk[2];
- unsigned char session_id[2][32];
- unsigned char msg[32];
- secp256k1_musig_secnonce secnonce[2];
- secp256k1_musig_pubnonce pubnonce[2];
- const secp256k1_musig_pubnonce *pubnonce_ptr[2];
- secp256k1_musig_aggnonce aggnonce;
- secp256k1_keypair keypair[2];
- secp256k1_musig_session session;
- secp256k1_musig_partial_sig partial_sig[2];
- const secp256k1_musig_partial_sig *partial_sig_ptr[2];
- unsigned char final_sig[64];
- int i;
-
- for (i = 0; i < 2; i++) {
- pubnonce_ptr[i] = &pubnonce[i];
- partial_sig_ptr[i] = &partial_sig[i];
-
- testrand256(session_id[i]);
- }
- CHECK(create_keypair_and_pk(&keypair[0], &pk[0], sk0) == 1);
- CHECK(create_keypair_and_pk(&keypair[1], &pk[1], sk1) == 1);
- testrand256(msg);
-
- CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce[0], &pubnonce[0], session_id[0], sk0, &pk[0], NULL, NULL, NULL) == 1);
- CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce[1], &pubnonce[1], session_id[1], sk1, &pk[1], NULL, NULL, NULL) == 1);
-
- CHECK(secp256k1_musig_nonce_agg(CTX, &aggnonce, pubnonce_ptr, 2) == 1);
- CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, msg, keyagg_cache, NULL) == 1);
-
- CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig[0], &secnonce[0], &keypair[0], keyagg_cache, &session) == 1);
- CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig[1], &secnonce[1], &keypair[1], keyagg_cache, &session) == 1);
-
- CHECK(secp256k1_musig_partial_sig_verify(CTX, &partial_sig[0], &pubnonce[0], &pk[0], keyagg_cache, &session) == 1);
- CHECK(secp256k1_musig_partial_sig_verify(CTX, &partial_sig[1], &pubnonce[1], &pk[1], keyagg_cache, &session) == 1);
-
- CHECK(secp256k1_musig_partial_sig_agg(CTX, final_sig, &session, partial_sig_ptr, 2) == 1);
- CHECK(secp256k1_schnorrsig_verify(CTX, final_sig, msg, sizeof(msg), agg_pk) == 1);
-}
-
-/* Create aggregate public key P[0], tweak multiple times (using xonly and
- * plain tweaking) and test signing. */
-static void musig_tweak_test(secp256k1_scratch_space *scratch) {
- unsigned char sk[2][32];
- secp256k1_pubkey pk[2];
- const secp256k1_pubkey *pk_ptr[2];
- secp256k1_musig_keyagg_cache keyagg_cache;
- enum { N_TWEAKS = 8 };
- secp256k1_pubkey P[N_TWEAKS + 1];
- secp256k1_xonly_pubkey P_xonly[N_TWEAKS + 1];
- int i;
-
- /* Key Setup */
- for (i = 0; i < 2; i++) {
- pk_ptr[i] = &pk[i];
- testrand256(sk[i]);
- CHECK(create_keypair_and_pk(NULL, &pk[i], sk[i]) == 1);
- }
- /* Compute P0 = keyagg(pk0, pk1) and test signing for it */
- CHECK(secp256k1_musig_pubkey_agg(CTX, scratch, &P_xonly[0], &keyagg_cache, pk_ptr, 2) == 1);
- musig_tweak_test_helper(&P_xonly[0], sk[0], sk[1], &keyagg_cache);
- CHECK(secp256k1_musig_pubkey_get(CTX, &P[0], &keyagg_cache));
-
- /* Compute Pi = f(Pj) + tweaki*G where where j = i-1 and try signing for
- * that key. If xonly is set to true, the function f is normalizes the input
- * point to have an even X-coordinate ("xonly-tweaking").
- * Otherwise, the function f is the identity function. */
- for (i = 1; i <= N_TWEAKS; i++) {
- unsigned char tweak[32];
- int P_parity;
- int xonly = testrand_bits(1);
-
- testrand256(tweak);
- if (xonly) {
- CHECK(secp256k1_musig_pubkey_xonly_tweak_add(CTX, &P[i], &keyagg_cache, tweak) == 1);
- } else {
- CHECK(secp256k1_musig_pubkey_ec_tweak_add(CTX, &P[i], &keyagg_cache, tweak) == 1);
- }
- CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &P_xonly[i], &P_parity, &P[i]));
- /* Check that musig_pubkey_tweak_add produces same result as
- * xonly_pubkey_tweak_add or ec_pubkey_tweak_add. */
- if (xonly) {
- unsigned char P_serialized[32];
- CHECK(secp256k1_xonly_pubkey_serialize(CTX, P_serialized, &P_xonly[i]));
- CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, P_serialized, P_parity, &P_xonly[i-1], tweak) == 1);
- } else {
- secp256k1_pubkey tmp_key = P[i-1];
- CHECK(secp256k1_ec_pubkey_tweak_add(CTX, &tmp_key, tweak));
- CHECK(secp256k1_memcmp_var(&tmp_key, &P[i], sizeof(tmp_key)) == 0);
- }
- /* Test signing for P[i] */
- musig_tweak_test_helper(&P_xonly[i], sk[0], sk[1], &keyagg_cache);
- }
-}
-
-int musig_vectors_keyagg_and_tweak(enum MUSIG_ERROR *error,
- secp256k1_musig_keyagg_cache *keyagg_cache,
- unsigned char *agg_pk_ser,
- const unsigned char pubkeys33[][33],
- const unsigned char tweaks32[][32],
- size_t key_indices_len,
- const size_t *key_indices,
- size_t tweak_indices_len,
- const size_t *tweak_indices,
- const int *is_xonly) {
- secp256k1_pubkey pubkeys[MUSIG_VECTORS_MAX_PUBKEYS];
- const secp256k1_pubkey *pk_ptr[MUSIG_VECTORS_MAX_PUBKEYS];
- int i;
- secp256k1_pubkey agg_pk;
- secp256k1_xonly_pubkey agg_pk_xonly;
-
- for (i = 0; i < (int)key_indices_len; i++) {
- if (!secp256k1_ec_pubkey_parse(CTX, &pubkeys[i], pubkeys33[key_indices[i]], 33)) {
- *error = MUSIG_PUBKEY;
- return 0;
- }
- pk_ptr[i] = &pubkeys[i];
- }
- if (!secp256k1_musig_pubkey_agg(CTX, NULL, NULL, keyagg_cache, pk_ptr, key_indices_len)) {
- *error = MUSIG_OTHER;
- return 0;
- }
-
- for (i = 0; i < (int)tweak_indices_len; i++) {
- if (is_xonly[i]) {
- if (!secp256k1_musig_pubkey_xonly_tweak_add(CTX, NULL, keyagg_cache, tweaks32[tweak_indices[i]])) {
- *error = MUSIG_TWEAK;
- return 0;
- }
- } else {
- if (!secp256k1_musig_pubkey_ec_tweak_add(CTX, NULL, keyagg_cache, tweaks32[tweak_indices[i]])) {
- *error = MUSIG_TWEAK;
- return 0;
- }
- }
- }
- if (!secp256k1_musig_pubkey_get(CTX, &agg_pk, keyagg_cache)) {
- *error = MUSIG_OTHER;
- return 0;
- }
-
- if (!secp256k1_xonly_pubkey_from_pubkey(CTX, &agg_pk_xonly, NULL, &agg_pk)) {
- *error = MUSIG_OTHER;
- return 0;
- }
-
- if (agg_pk_ser != NULL) {
- if (!secp256k1_xonly_pubkey_serialize(CTX, agg_pk_ser, &agg_pk_xonly)) {
- *error = MUSIG_OTHER;
- return 0;
- }
- }
-
- return 1;
-}
-
-static void musig_test_vectors_keyagg(void) {
- size_t i;
- const struct musig_key_agg_vector *vector = &musig_key_agg_vector;
-
- for (i = 0; i < sizeof(vector->valid_case)/sizeof(vector->valid_case[0]); i++) {
- const struct musig_key_agg_valid_test_case *c = &vector->valid_case[i];
- enum MUSIG_ERROR error;
- secp256k1_musig_keyagg_cache keyagg_cache;
- unsigned char agg_pk[32];
-
- CHECK(musig_vectors_keyagg_and_tweak(&error, &keyagg_cache, agg_pk, vector->pubkeys, vector->tweaks, c->key_indices_len, c->key_indices, 0, NULL, NULL));
- CHECK(secp256k1_memcmp_var(agg_pk, c->expected, sizeof(agg_pk)) == 0);
- }
-
- for (i = 0; i < sizeof(vector->error_case)/sizeof(vector->error_case[0]); i++) {
- const struct musig_key_agg_error_test_case *c = &vector->error_case[i];
- enum MUSIG_ERROR error;
- secp256k1_musig_keyagg_cache keyagg_cache;
-
- CHECK(!musig_vectors_keyagg_and_tweak(&error, &keyagg_cache, NULL, vector->pubkeys, vector->tweaks, c->key_indices_len, c->key_indices, c->tweak_indices_len, c->tweak_indices, c->is_xonly));
- CHECK(c->error == error);
- }
-}
-
-static void musig_test_vectors_noncegen(void) {
- size_t i;
- const struct musig_nonce_gen_vector *vector = &musig_nonce_gen_vector;
-
- for (i = 0; i < sizeof(vector->test_case)/sizeof(vector->test_case[0]); i++) {
- const struct musig_nonce_gen_test_case *c = &vector->test_case[i];
- secp256k1_musig_keyagg_cache keyagg_cache;
- secp256k1_musig_keyagg_cache *keyagg_cache_ptr = NULL;
- secp256k1_musig_secnonce secnonce;
- secp256k1_musig_pubnonce pubnonce;
- const unsigned char *sk = NULL;
- const unsigned char *msg = NULL;
- const unsigned char *extra_in = NULL;
- secp256k1_pubkey pk;
- unsigned char pubnonce66[66];
-
- if (c->has_sk) {
- sk = c->sk;
- }
- if (c->has_aggpk) {
- /* Create keyagg_cache from aggpk */
- secp256k1_keyagg_cache_internal cache_i;
- secp256k1_xonly_pubkey aggpk;
- memset(&cache_i, 0, sizeof(cache_i));
- CHECK(secp256k1_xonly_pubkey_parse(CTX, &aggpk, c->aggpk));
- CHECK(secp256k1_xonly_pubkey_load(CTX, &cache_i.pk, &aggpk));
- secp256k1_keyagg_cache_save(&keyagg_cache, &cache_i);
- keyagg_cache_ptr = &keyagg_cache;
- }
- if (c->has_msg) {
- msg = c->msg;
- }
- if (c->has_extra_in) {
- extra_in = c->extra_in;
- }
-
- CHECK(secp256k1_ec_pubkey_parse(CTX, &pk, c->pk, sizeof(c->pk)));
- CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce, &pubnonce, c->rand_, sk, &pk, msg, keyagg_cache_ptr, extra_in) == 1);
- CHECK(secp256k1_memcmp_var(&secnonce.data[4], c->expected_secnonce, 2*32) == 0);
- CHECK(secp256k1_memcmp_var(&secnonce.data[4+2*32], &pk, sizeof(pk)) == 0);
-
- CHECK(secp256k1_musig_pubnonce_serialize(CTX, pubnonce66, &pubnonce) == 1);
- CHECK(sizeof(c->expected_pubnonce) == sizeof(pubnonce66));
- CHECK(secp256k1_memcmp_var(pubnonce66, c->expected_pubnonce, sizeof(pubnonce66)) == 0);
- }
-}
-
-
-static void musig_test_vectors_nonceagg(void) {
- size_t i;
- int j;
- const struct musig_nonce_agg_vector *vector = &musig_nonce_agg_vector;
-
- for (i = 0; i < sizeof(vector->valid_case)/sizeof(vector->valid_case[0]); i++) {
- const struct musig_nonce_agg_test_case *c = &vector->valid_case[i];
- secp256k1_musig_pubnonce pubnonce[2];
- const secp256k1_musig_pubnonce *pubnonce_ptr[2];
- secp256k1_musig_aggnonce aggnonce;
- unsigned char aggnonce66[66];
-
- for (j = 0; j < 2; j++) {
- CHECK(secp256k1_musig_pubnonce_parse(CTX, &pubnonce[j], vector->pnonces[c->pnonce_indices[j]]) == 1);
- pubnonce_ptr[j] = &pubnonce[j];
- }
- CHECK(secp256k1_musig_nonce_agg(CTX, &aggnonce, pubnonce_ptr, 2));
- CHECK(secp256k1_musig_aggnonce_serialize(CTX, aggnonce66, &aggnonce));
- CHECK(secp256k1_memcmp_var(aggnonce66, c->expected, 33) == 0);
- }
- for (i = 0; i < sizeof(vector->error_case)/sizeof(vector->error_case[0]); i++) {
- const struct musig_nonce_agg_test_case *c = &vector->error_case[i];
- secp256k1_musig_pubnonce pubnonce[2];
- for (j = 0; j < 2; j++) {
- int expected = c->invalid_nonce_idx != j;
- CHECK(expected == secp256k1_musig_pubnonce_parse(CTX, &pubnonce[j], vector->pnonces[c->pnonce_indices[j]]));
- }
- }
-}
-
-static void musig_test_set_secnonce(secp256k1_musig_secnonce *secnonce, const unsigned char *secnonce64, const secp256k1_pubkey *pubkey) {
- secp256k1_ge pk;
- secp256k1_scalar k[2];
-
- secp256k1_scalar_set_b32(&k[0], &secnonce64[0], NULL);
- secp256k1_scalar_set_b32(&k[1], &secnonce64[32], NULL);
- CHECK(secp256k1_pubkey_load(CTX, &pk, pubkey));
- secp256k1_musig_secnonce_save(secnonce, k, &pk);
-}
-
-static void musig_test_vectors_signverify(void) {
- size_t i;
- const struct musig_sign_verify_vector *vector = &musig_sign_verify_vector;
-
- for (i = 0; i < sizeof(vector->valid_case)/sizeof(vector->valid_case[0]); i++) {
- const struct musig_valid_case *c = &vector->valid_case[i];
- enum MUSIG_ERROR error;
- secp256k1_musig_keyagg_cache keyagg_cache;
- secp256k1_pubkey pubkey;
- secp256k1_musig_pubnonce pubnonce;
- secp256k1_musig_aggnonce aggnonce;
- secp256k1_musig_session session;
- secp256k1_musig_partial_sig partial_sig;
- secp256k1_musig_secnonce secnonce;
- secp256k1_keypair keypair;
- unsigned char partial_sig32[32];
-
- CHECK(secp256k1_keypair_create(CTX, &keypair, vector->sk));
- CHECK(musig_vectors_keyagg_and_tweak(&error, &keyagg_cache, NULL, vector->pubkeys, NULL, c->key_indices_len, c->key_indices, 0, NULL, NULL));
-
- CHECK(secp256k1_musig_aggnonce_parse(CTX, &aggnonce, vector->aggnonces[c->aggnonce_index]));
- CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, vector->msgs[c->msg_index], &keyagg_cache, NULL));
-
- CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, vector->pubkeys[0], sizeof(vector->pubkeys[0])));
- musig_test_set_secnonce(&secnonce, vector->secnonces[0], &pubkey);
- CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig, &secnonce, &keypair, &keyagg_cache, &session));
- CHECK(secp256k1_musig_partial_sig_serialize(CTX, partial_sig32, &partial_sig));
- CHECK(secp256k1_memcmp_var(partial_sig32, c->expected, sizeof(partial_sig32)) == 0);
-
- CHECK(secp256k1_musig_pubnonce_parse(CTX, &pubnonce, vector->pubnonces[0]));
- CHECK(secp256k1_musig_partial_sig_verify(CTX, &partial_sig, &pubnonce, &pubkey, &keyagg_cache, &session));
- }
- for (i = 0; i < sizeof(vector->sign_error_case)/sizeof(vector->sign_error_case[0]); i++) {
- const struct musig_sign_error_case *c = &vector->sign_error_case[i];
- enum MUSIG_ERROR error;
- secp256k1_musig_keyagg_cache keyagg_cache;
- secp256k1_pubkey pubkey;
- secp256k1_musig_aggnonce aggnonce;
- secp256k1_musig_session session;
- secp256k1_musig_partial_sig partial_sig;
- secp256k1_musig_secnonce secnonce;
- secp256k1_keypair keypair;
- int expected;
-
- if (i == 0) {
- /* Skip this vector since the implementation does not error out when
- * the signing key does not belong to any pubkey. */
- continue;
- }
- expected = c->error != MUSIG_PUBKEY;
- CHECK(expected == musig_vectors_keyagg_and_tweak(&error, &keyagg_cache, NULL, vector->pubkeys, NULL, c->key_indices_len, c->key_indices, 0, NULL, NULL));
- CHECK(expected || c->error == error);
- if (!expected) {
- continue;
- }
- CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, vector->pubkeys[0], sizeof(vector->pubkeys[0])));
- CHECK(secp256k1_keypair_create(CTX, &keypair, vector->sk));
-
- expected = c->error != MUSIG_AGGNONCE;
- CHECK(expected == secp256k1_musig_aggnonce_parse(CTX, &aggnonce, vector->aggnonces[c->aggnonce_index]));
- if (!expected) {
- continue;
- }
- CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, vector->msgs[c->msg_index], &keyagg_cache, NULL));
-
- CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, vector->pubkeys[0], sizeof(vector->pubkeys[0])));
- expected = c->error != MUSIG_SECNONCE;
- CHECK(!expected);
- musig_test_set_secnonce(&secnonce, vector->secnonces[c->secnonce_index], &pubkey);
- CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sign(CTX, &partial_sig, &secnonce, &keypair, &keyagg_cache, &session));
- }
- for (i = 0; i < sizeof(vector->verify_fail_case)/sizeof(vector->verify_fail_case[0]); i++) {
- const struct musig_verify_fail_error_case *c = &vector->verify_fail_case[i];
- enum MUSIG_ERROR error;
- secp256k1_musig_keyagg_cache keyagg_cache;
- secp256k1_musig_aggnonce aggnonce;
- secp256k1_musig_session session;
- secp256k1_musig_partial_sig partial_sig;
- enum { NUM_PUBNONCES = 3 };
- secp256k1_musig_pubnonce pubnonce[NUM_PUBNONCES];
- const secp256k1_musig_pubnonce *pubnonce_ptr[NUM_PUBNONCES];
- secp256k1_pubkey pubkey;
- int expected;
- size_t j;
-
- CHECK(NUM_PUBNONCES <= c->nonce_indices_len);
- for (j = 0; j < c->nonce_indices_len; j++) {
- CHECK(secp256k1_musig_pubnonce_parse(CTX, &pubnonce[j], vector->pubnonces[c->nonce_indices[j]]));
- pubnonce_ptr[j] = &pubnonce[j];
- }
-
- CHECK(musig_vectors_keyagg_and_tweak(&error, &keyagg_cache, NULL, vector->pubkeys, NULL, c->key_indices_len, c->key_indices, 0, NULL, NULL));
- CHECK(secp256k1_musig_nonce_agg(CTX, &aggnonce, pubnonce_ptr, c->nonce_indices_len) == 1);
- CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, vector->msgs[c->msg_index], &keyagg_cache, NULL));
-
- CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, vector->pubkeys[c->signer_index], sizeof(vector->pubkeys[0])));
-
- expected = c->error != MUSIG_SIG;
- CHECK(expected == secp256k1_musig_partial_sig_parse(CTX, &partial_sig, c->sig));
- if (!expected) {
- continue;
- }
- expected = c->error != MUSIG_SIG_VERIFY;
- CHECK(expected == secp256k1_musig_partial_sig_verify(CTX, &partial_sig, pubnonce, &pubkey, &keyagg_cache, &session));
- }
- for (i = 0; i < sizeof(vector->verify_error_case)/sizeof(vector->verify_error_case[0]); i++) {
- const struct musig_verify_fail_error_case *c = &vector->verify_error_case[i];
- enum MUSIG_ERROR error;
- secp256k1_musig_keyagg_cache keyagg_cache;
- secp256k1_musig_pubnonce pubnonce;
- int expected;
-
- expected = c->error != MUSIG_PUBKEY;
- CHECK(expected == musig_vectors_keyagg_and_tweak(&error, &keyagg_cache, NULL, vector->pubkeys, NULL, c->key_indices_len, c->key_indices, 0, NULL, NULL));
- CHECK(expected || c->error == error);
- if (!expected) {
- continue;
- }
- expected = c->error != MUSIG_PUBNONCE;
- CHECK(expected == secp256k1_musig_pubnonce_parse(CTX, &pubnonce, vector->pubnonces[c->nonce_indices[c->signer_index]]));
- }
-}
-
-static void musig_test_vectors_tweak(void) {
- size_t i;
- const struct musig_tweak_vector *vector = &musig_tweak_vector;
- secp256k1_pubkey pubkey;
- secp256k1_musig_aggnonce aggnonce;
- secp256k1_musig_secnonce secnonce;
-
- CHECK(secp256k1_musig_aggnonce_parse(CTX, &aggnonce, vector->aggnonce));
- CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, vector->pubkeys[0], sizeof(vector->pubkeys[0])));
-
- for (i = 0; i < sizeof(vector->valid_case)/sizeof(vector->valid_case[0]); i++) {
- const struct musig_tweak_case *c = &vector->valid_case[i];
- enum MUSIG_ERROR error;
- secp256k1_musig_keyagg_cache keyagg_cache;
- secp256k1_musig_pubnonce pubnonce;
- secp256k1_musig_session session;
- secp256k1_musig_partial_sig partial_sig;
- secp256k1_keypair keypair;
- unsigned char partial_sig32[32];
-
- musig_test_set_secnonce(&secnonce, vector->secnonce, &pubkey);
-
- CHECK(secp256k1_keypair_create(CTX, &keypair, vector->sk));
- CHECK(musig_vectors_keyagg_and_tweak(&error, &keyagg_cache, NULL, vector->pubkeys, vector->tweaks, c->key_indices_len, c->key_indices, c->tweak_indices_len, c->tweak_indices, c->is_xonly));
-
- CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, vector->msg, &keyagg_cache, NULL));
-
- CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig, &secnonce, &keypair, &keyagg_cache, &session));
- CHECK(secp256k1_musig_partial_sig_serialize(CTX, partial_sig32, &partial_sig));
- CHECK(secp256k1_memcmp_var(partial_sig32, c->expected, sizeof(partial_sig32)) == 0);
-
- CHECK(secp256k1_musig_pubnonce_parse(CTX, &pubnonce, vector->pubnonces[c->nonce_indices[c->signer_index]]));
- CHECK(secp256k1_musig_partial_sig_verify(CTX, &partial_sig, &pubnonce, &pubkey, &keyagg_cache, &session));
- }
- for (i = 0; i < sizeof(vector->error_case)/sizeof(vector->error_case[0]); i++) {
- const struct musig_tweak_case *c = &vector->error_case[i];
- enum MUSIG_ERROR error;
- secp256k1_musig_keyagg_cache keyagg_cache;
- CHECK(!musig_vectors_keyagg_and_tweak(&error, &keyagg_cache, NULL, vector->pubkeys, vector->tweaks, c->key_indices_len, c->key_indices, c->tweak_indices_len, c->tweak_indices, c->is_xonly));
- CHECK(error == MUSIG_TWEAK);
- }
-}
-
-static void musig_test_vectors_sigagg(void) {
- size_t i, j;
- const struct musig_sig_agg_vector *vector = &musig_sig_agg_vector;
-
- for (i = 0; i < sizeof(vector->valid_case)/sizeof(vector->valid_case[0]); i++) {
- const struct musig_sig_agg_case *c = &vector->valid_case[i];
- enum MUSIG_ERROR error;
- unsigned char final_sig[64];
- secp256k1_musig_keyagg_cache keyagg_cache;
- unsigned char agg_pk32[32];
- secp256k1_xonly_pubkey agg_pk;
- secp256k1_musig_aggnonce aggnonce;
- secp256k1_musig_session session;
- secp256k1_musig_partial_sig partial_sig[(sizeof(vector->psigs)/sizeof(vector->psigs[0]))];
- const secp256k1_musig_partial_sig *partial_sig_ptr[(sizeof(vector->psigs)/sizeof(vector->psigs[0]))];
-
- CHECK(musig_vectors_keyagg_and_tweak(&error, &keyagg_cache, agg_pk32, vector->pubkeys, vector->tweaks, c->key_indices_len, c->key_indices, c->tweak_indices_len, c->tweak_indices, c->is_xonly));
- CHECK(secp256k1_musig_aggnonce_parse(CTX, &aggnonce, c->aggnonce));
- CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, vector->msg, &keyagg_cache, NULL));
- for (j = 0; j < c->psig_indices_len; j++) {
- CHECK(secp256k1_musig_partial_sig_parse(CTX, &partial_sig[j], vector->psigs[c->psig_indices[j]]));
- partial_sig_ptr[j] = &partial_sig[j];
- }
-
- CHECK(secp256k1_musig_partial_sig_agg(CTX, final_sig, &session, partial_sig_ptr, c->psig_indices_len) == 1);
- CHECK(secp256k1_memcmp_var(final_sig, c->expected, sizeof(final_sig)) == 0);
-
- CHECK(secp256k1_xonly_pubkey_parse(CTX, &agg_pk, agg_pk32));
- CHECK(secp256k1_schnorrsig_verify(CTX, final_sig, vector->msg, sizeof(vector->msg), &agg_pk) == 1);
- }
- for (i = 0; i < sizeof(vector->error_case)/sizeof(vector->error_case[0]); i++) {
- const struct musig_sig_agg_case *c = &vector->error_case[i];
- secp256k1_musig_partial_sig partial_sig[(sizeof(vector->psigs)/sizeof(vector->psigs[0]))];
- for (j = 0; j < c->psig_indices_len; j++) {
- int expected = c->invalid_sig_idx != (int)j;
- CHECK(expected == secp256k1_musig_partial_sig_parse(CTX, &partial_sig[j], vector->psigs[c->psig_indices[j]]));
- }
- }
-}
-
-static void run_musig_tests(void) {
- int i;
- secp256k1_scratch_space *scratch = secp256k1_scratch_space_create(CTX, 1024 * 1024);
-
- for (i = 0; i < COUNT; i++) {
- musig_simple_test(scratch);
- }
- musig_api_tests(scratch);
- musig_nonce_test();
- for (i = 0; i < COUNT; i++) {
- /* Run multiple times to ensure that pk and nonce have different y
- * parities */
- scriptless_atomic_swap(scratch);
- musig_tweak_test(scratch);
- }
- sha256_tag_test();
- musig_test_vectors_keyagg();
- musig_test_vectors_noncegen();
- musig_test_vectors_nonceagg();
- musig_test_vectors_signverify();
- musig_test_vectors_tweak();
- musig_test_vectors_sigagg();
-
- secp256k1_scratch_space_destroy(CTX, scratch);
-}
-
-#endif
diff --git a/src/modules/musig/vectors.h b/src/modules/musig/vectors.h
deleted file mode 100644
index b959e0a2..00000000
--- a/src/modules/musig/vectors.h
+++ /dev/null
@@ -1,346 +0,0 @@
-/**
- * Automatically generated by contrib/musig2-vectors.py.
- *
- * The test vectors for the KeySort function are included in this file. They can
- * be found in src/modules/extrakeys/tests_impl.h. */
-
-enum MUSIG_ERROR {
- MUSIG_PUBKEY,
- MUSIG_TWEAK,
- MUSIG_PUBNONCE,
- MUSIG_AGGNONCE,
- MUSIG_SECNONCE,
- MUSIG_SIG,
- MUSIG_SIG_VERIFY,
- MUSIG_OTHER
-};
-
-struct musig_key_agg_valid_test_case {
- size_t key_indices_len;
- size_t key_indices[4];
- unsigned char expected[32];
-};
-
-struct musig_key_agg_error_test_case {
- size_t key_indices_len;
- size_t key_indices[4];
- size_t tweak_indices_len;
- size_t tweak_indices[1];
- int is_xonly[1];
- enum MUSIG_ERROR error;
-};
-
-struct musig_key_agg_vector {
- unsigned char pubkeys[7][33];
- unsigned char tweaks[2][32];
- struct musig_key_agg_valid_test_case valid_case[4];
- struct musig_key_agg_error_test_case error_case[5];
-};
-
-static const struct musig_key_agg_vector musig_key_agg_vector = {
- {
- { 0x02, 0xF9, 0x30, 0x8A, 0x01, 0x92, 0x58, 0xC3, 0x10, 0x49, 0x34, 0x4F, 0x85, 0xF8, 0x9D, 0x52, 0x29, 0xB5, 0x31, 0xC8, 0x45, 0x83, 0x6F, 0x99, 0xB0, 0x86, 0x01, 0xF1, 0x13, 0xBC, 0xE0, 0x36, 0xF9 },
- { 0x03, 0xDF, 0xF1, 0xD7, 0x7F, 0x2A, 0x67, 0x1C, 0x5F, 0x36, 0x18, 0x37, 0x26, 0xDB, 0x23, 0x41, 0xBE, 0x58, 0xFE, 0xAE, 0x1D, 0xA2, 0xDE, 0xCE, 0xD8, 0x43, 0x24, 0x0F, 0x7B, 0x50, 0x2B, 0xA6, 0x59 },
- { 0x02, 0x35, 0x90, 0xA9, 0x4E, 0x76, 0x8F, 0x8E, 0x18, 0x15, 0xC2, 0xF2, 0x4B, 0x4D, 0x80, 0xA8, 0xE3, 0x14, 0x93, 0x16, 0xC3, 0x51, 0x8C, 0xE7, 0xB7, 0xAD, 0x33, 0x83, 0x68, 0xD0, 0x38, 0xCA, 0x66 },
- { 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, 0x05 },
- { 0x02, 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, 0x30 },
- { 0x04, 0xF9, 0x30, 0x8A, 0x01, 0x92, 0x58, 0xC3, 0x10, 0x49, 0x34, 0x4F, 0x85, 0xF8, 0x9D, 0x52, 0x29, 0xB5, 0x31, 0xC8, 0x45, 0x83, 0x6F, 0x99, 0xB0, 0x86, 0x01, 0xF1, 0x13, 0xBC, 0xE0, 0x36, 0xF9 },
- { 0x03, 0x93, 0x5F, 0x97, 0x2D, 0xA0, 0x13, 0xF8, 0x0A, 0xE0, 0x11, 0x89, 0x0F, 0xA8, 0x9B, 0x67, 0xA2, 0x7B, 0x7B, 0xE6, 0xCC, 0xB2, 0x4D, 0x32, 0x74, 0xD1, 0x8B, 0x2D, 0x40, 0x67, 0xF2, 0x61, 0xA9 }
- },
- {
- { 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 },
- { 0x25, 0x2E, 0x4B, 0xD6, 0x74, 0x10, 0xA7, 0x6C, 0xDF, 0x93, 0x3D, 0x30, 0xEA, 0xA1, 0x60, 0x82, 0x14, 0x03, 0x7F, 0x1B, 0x10, 0x5A, 0x01, 0x3E, 0xCC, 0xD3, 0xC5, 0xC1, 0x84, 0xA6, 0x11, 0x0B }
- },
- {
- { 3, { 0, 1, 2 }, { 0x90, 0x53, 0x9E, 0xED, 0xE5, 0x65, 0xF5, 0xD0, 0x54, 0xF3, 0x2C, 0xC0, 0xC2, 0x20, 0x12, 0x68, 0x89, 0xED, 0x1E, 0x5D, 0x19, 0x3B, 0xAF, 0x15, 0xAE, 0xF3, 0x44, 0xFE, 0x59, 0xD4, 0x61, 0x0C }},
- { 3, { 2, 1, 0 }, { 0x62, 0x04, 0xDE, 0x8B, 0x08, 0x34, 0x26, 0xDC, 0x6E, 0xAF, 0x95, 0x02, 0xD2, 0x70, 0x24, 0xD5, 0x3F, 0xC8, 0x26, 0xBF, 0x7D, 0x20, 0x12, 0x14, 0x8A, 0x05, 0x75, 0x43, 0x5D, 0xF5, 0x4B, 0x2B }},
- { 3, { 0, 0, 0 }, { 0xB4, 0x36, 0xE3, 0xBA, 0xD6, 0x2B, 0x8C, 0xD4, 0x09, 0x96, 0x9A, 0x22, 0x47, 0x31, 0xC1, 0x93, 0xD0, 0x51, 0x16, 0x2D, 0x8C, 0x5A, 0xE8, 0xB1, 0x09, 0x30, 0x61, 0x27, 0xDA, 0x3A, 0xA9, 0x35 }},
- { 4, { 0, 0, 1, 1 }, { 0x69, 0xBC, 0x22, 0xBF, 0xA5, 0xD1, 0x06, 0x30, 0x6E, 0x48, 0xA2, 0x06, 0x79, 0xDE, 0x1D, 0x73, 0x89, 0x38, 0x61, 0x24, 0xD0, 0x75, 0x71, 0xD0, 0xD8, 0x72, 0x68, 0x60, 0x28, 0xC2, 0x6A, 0x3E }},
- },
- {
- { 2, { 0, 3 }, 0, { 0 }, { 0 }, MUSIG_PUBKEY },
- { 2, { 0, 4 }, 0, { 0 }, { 0 }, MUSIG_PUBKEY },
- { 2, { 5, 0 }, 0, { 0 }, { 0 }, MUSIG_PUBKEY },
- { 2, { 0, 1 }, 1, { 0 }, { 1 }, MUSIG_TWEAK },
- { 1, { 6 }, 1, { 1 }, { 0 }, MUSIG_TWEAK },
- },
-};
-
-struct musig_nonce_gen_test_case {
- unsigned char rand_[32];
- int has_sk;
- unsigned char sk[32];
- unsigned char pk[33];
- int has_aggpk;
- unsigned char aggpk[32];
- int has_msg;
- unsigned char msg[32];
- int has_extra_in;
- unsigned char extra_in[32];
- unsigned char expected_secnonce[97];
- unsigned char expected_pubnonce[66];
-};
-
-struct musig_nonce_gen_vector {
- struct musig_nonce_gen_test_case test_case[2];
-};
-
-static const struct musig_nonce_gen_vector musig_nonce_gen_vector = {
- {
- { { 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F }, 1 , { 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 }, { 0x02, 0x4D, 0x4B, 0x6C, 0xD1, 0x36, 0x10, 0x32, 0xCA, 0x9B, 0xD2, 0xAE, 0xB9, 0xD9, 0x00, 0xAA, 0x4D, 0x45, 0xD9, 0xEA, 0xD8, 0x0A, 0xC9, 0x42, 0x33, 0x74, 0xC4, 0x51, 0xA7, 0x25, 0x4D, 0x07, 0x66 }, 1 , { 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07 }, 1 , { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, 1 , { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 }, { 0xB1, 0x14, 0xE5, 0x02, 0xBE, 0xAA, 0x4E, 0x30, 0x1D, 0xD0, 0x8A, 0x50, 0x26, 0x41, 0x72, 0xC8, 0x4E, 0x41, 0x65, 0x0E, 0x6C, 0xB7, 0x26, 0xB4, 0x10, 0xC0, 0x69, 0x4D, 0x59, 0xEF, 0xFB, 0x64, 0x95, 0xB5, 0xCA, 0xF2, 0x8D, 0x04, 0x5B, 0x97, 0x3D, 0x63, 0xE3, 0xC9, 0x9A, 0x44, 0xB8, 0x07, 0xBD, 0xE3, 0x75, 0xFD, 0x6C, 0xB3, 0x9E, 0x46, 0xDC, 0x4A, 0x51, 0x17, 0x08, 0xD0, 0xE9, 0xD2, 0x02, 0x4D, 0x4B, 0x6C, 0xD1, 0x36, 0x10, 0x32, 0xCA, 0x9B, 0xD2, 0xAE, 0xB9, 0xD9, 0x00, 0xAA, 0x4D, 0x45, 0xD9, 0xEA, 0xD8, 0x0A, 0xC9, 0x42, 0x33, 0x74, 0xC4, 0x51, 0xA7, 0x25, 0x4D, 0x07, 0x66 }, { 0x02, 0xF7, 0xBE, 0x70, 0x89, 0xE8, 0x37, 0x6E, 0xB3, 0x55, 0x27, 0x23, 0x68, 0x76, 0x6B, 0x17, 0xE8, 0x8E, 0x7D, 0xB7, 0x20, 0x47, 0xD0, 0x5E, 0x56, 0xAA, 0x88, 0x1E, 0xA5, 0x2B, 0x3B, 0x35, 0xDF, 0x02, 0xC2, 0x9C, 0x80, 0x46, 0xFD, 0xD0, 0xDE, 0xD4, 0xC7, 0xE5, 0x58, 0x69, 0x13, 0x72, 0x00, 0xFB, 0xDB, 0xFE, 0x2E, 0xB6, 0x54, 0x26, 0x7B, 0x6D, 0x70, 0x13, 0x60, 0x2C, 0xAE, 0xD3, 0x11, 0x5A } },
- { { 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F }, 0 , { 0 }, { 0x02, 0xF9, 0x30, 0x8A, 0x01, 0x92, 0x58, 0xC3, 0x10, 0x49, 0x34, 0x4F, 0x85, 0xF8, 0x9D, 0x52, 0x29, 0xB5, 0x31, 0xC8, 0x45, 0x83, 0x6F, 0x99, 0xB0, 0x86, 0x01, 0xF1, 0x13, 0xBC, 0xE0, 0x36, 0xF9 }, 0 , { 0 }, 0 , { 0 }, 0 , { 0 }, { 0x89, 0xBD, 0xD7, 0x87, 0xD0, 0x28, 0x4E, 0x5E, 0x4D, 0x5F, 0xC5, 0x72, 0xE4, 0x9E, 0x31, 0x6B, 0xAB, 0x7E, 0x21, 0xE3, 0xB1, 0x83, 0x0D, 0xE3, 0x7D, 0xFE, 0x80, 0x15, 0x6F, 0xA4, 0x1A, 0x6D, 0x0B, 0x17, 0xAE, 0x8D, 0x02, 0x4C, 0x53, 0x67, 0x96, 0x99, 0xA6, 0xFD, 0x79, 0x44, 0xD9, 0xC4, 0xA3, 0x66, 0xB5, 0x14, 0xBA, 0xF4, 0x30, 0x88, 0xE0, 0x70, 0x8B, 0x10, 0x23, 0xDD, 0x28, 0x97, 0x02, 0xF9, 0x30, 0x8A, 0x01, 0x92, 0x58, 0xC3, 0x10, 0x49, 0x34, 0x4F, 0x85, 0xF8, 0x9D, 0x52, 0x29, 0xB5, 0x31, 0xC8, 0x45, 0x83, 0x6F, 0x99, 0xB0, 0x86, 0x01, 0xF1, 0x13, 0xBC, 0xE0, 0x36, 0xF9 }, { 0x02, 0xC9, 0x6E, 0x7C, 0xB1, 0xE8, 0xAA, 0x5D, 0xAC, 0x64, 0xD8, 0x72, 0x94, 0x79, 0x14, 0x19, 0x8F, 0x60, 0x7D, 0x90, 0xEC, 0xDE, 0x52, 0x00, 0xDE, 0x52, 0x97, 0x8A, 0xD5, 0xDE, 0xD6, 0x3C, 0x00, 0x02, 0x99, 0xEC, 0x51, 0x17, 0xC2, 0xD2, 0x9E, 0xDE, 0xE8, 0xA2, 0x09, 0x25, 0x87, 0xC3, 0x90, 0x9B, 0xE6, 0x94, 0xD5, 0xCF, 0xF0, 0x66, 0x7D, 0x6C, 0x02, 0xEA, 0x40, 0x59, 0xF7, 0xCD, 0x97, 0x86 } },
- },
-};
-
-struct musig_nonce_agg_test_case {
- size_t pnonce_indices[2];
- /* if valid case */
- unsigned char expected[66];
- /* if error case */
- int invalid_nonce_idx;
-};
-
-struct musig_nonce_agg_vector {
- unsigned char pnonces[7][66];
- struct musig_nonce_agg_test_case valid_case[2];
- struct musig_nonce_agg_test_case error_case[3];
-};
-
-static const struct musig_nonce_agg_vector musig_nonce_agg_vector = {
- {
- { 0x02, 0x01, 0x51, 0xC8, 0x0F, 0x43, 0x56, 0x48, 0xDF, 0x67, 0xA2, 0x2B, 0x74, 0x9C, 0xD7, 0x98, 0xCE, 0x54, 0xE0, 0x32, 0x1D, 0x03, 0x4B, 0x92, 0xB7, 0x09, 0xB5, 0x67, 0xD6, 0x0A, 0x42, 0xE6, 0x66, 0x03, 0xBA, 0x47, 0xFB, 0xC1, 0x83, 0x44, 0x37, 0xB3, 0x21, 0x2E, 0x89, 0xA8, 0x4D, 0x84, 0x25, 0xE7, 0xBF, 0x12, 0xE0, 0x24, 0x5D, 0x98, 0x26, 0x22, 0x68, 0xEB, 0xDC, 0xB3, 0x85, 0xD5, 0x06, 0x41 },
- { 0x03, 0xFF, 0x40, 0x6F, 0xFD, 0x8A, 0xDB, 0x9C, 0xD2, 0x98, 0x77, 0xE4, 0x98, 0x50, 0x14, 0xF6, 0x6A, 0x59, 0xF6, 0xCD, 0x01, 0xC0, 0xE8, 0x8C, 0xAA, 0x8E, 0x5F, 0x31, 0x66, 0xB1, 0xF6, 0x76, 0xA6, 0x02, 0x48, 0xC2, 0x64, 0xCD, 0xD5, 0x7D, 0x3C, 0x24, 0xD7, 0x99, 0x90, 0xB0, 0xF8, 0x65, 0x67, 0x4E, 0xB6, 0x2A, 0x0F, 0x90, 0x18, 0x27, 0x7A, 0x95, 0x01, 0x1B, 0x41, 0xBF, 0xC1, 0x93, 0xB8, 0x33 },
- { 0x02, 0x01, 0x51, 0xC8, 0x0F, 0x43, 0x56, 0x48, 0xDF, 0x67, 0xA2, 0x2B, 0x74, 0x9C, 0xD7, 0x98, 0xCE, 0x54, 0xE0, 0x32, 0x1D, 0x03, 0x4B, 0x92, 0xB7, 0x09, 0xB5, 0x67, 0xD6, 0x0A, 0x42, 0xE6, 0x66, 0x02, 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, 0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98 },
- { 0x03, 0xFF, 0x40, 0x6F, 0xFD, 0x8A, 0xDB, 0x9C, 0xD2, 0x98, 0x77, 0xE4, 0x98, 0x50, 0x14, 0xF6, 0x6A, 0x59, 0xF6, 0xCD, 0x01, 0xC0, 0xE8, 0x8C, 0xAA, 0x8E, 0x5F, 0x31, 0x66, 0xB1, 0xF6, 0x76, 0xA6, 0x03, 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, 0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98 },
- { 0x04, 0xFF, 0x40, 0x6F, 0xFD, 0x8A, 0xDB, 0x9C, 0xD2, 0x98, 0x77, 0xE4, 0x98, 0x50, 0x14, 0xF6, 0x6A, 0x59, 0xF6, 0xCD, 0x01, 0xC0, 0xE8, 0x8C, 0xAA, 0x8E, 0x5F, 0x31, 0x66, 0xB1, 0xF6, 0x76, 0xA6, 0x02, 0x48, 0xC2, 0x64, 0xCD, 0xD5, 0x7D, 0x3C, 0x24, 0xD7, 0x99, 0x90, 0xB0, 0xF8, 0x65, 0x67, 0x4E, 0xB6, 0x2A, 0x0F, 0x90, 0x18, 0x27, 0x7A, 0x95, 0x01, 0x1B, 0x41, 0xBF, 0xC1, 0x93, 0xB8, 0x33 },
- { 0x03, 0xFF, 0x40, 0x6F, 0xFD, 0x8A, 0xDB, 0x9C, 0xD2, 0x98, 0x77, 0xE4, 0x98, 0x50, 0x14, 0xF6, 0x6A, 0x59, 0xF6, 0xCD, 0x01, 0xC0, 0xE8, 0x8C, 0xAA, 0x8E, 0x5F, 0x31, 0x66, 0xB1, 0xF6, 0x76, 0xA6, 0x02, 0x48, 0xC2, 0x64, 0xCD, 0xD5, 0x7D, 0x3C, 0x24, 0xD7, 0x99, 0x90, 0xB0, 0xF8, 0x65, 0x67, 0x4E, 0xB6, 0x2A, 0x0F, 0x90, 0x18, 0x27, 0x7A, 0x95, 0x01, 0x1B, 0x41, 0xBF, 0xC1, 0x93, 0xB8, 0x31 },
- { 0x03, 0xFF, 0x40, 0x6F, 0xFD, 0x8A, 0xDB, 0x9C, 0xD2, 0x98, 0x77, 0xE4, 0x98, 0x50, 0x14, 0xF6, 0x6A, 0x59, 0xF6, 0xCD, 0x01, 0xC0, 0xE8, 0x8C, 0xAA, 0x8E, 0x5F, 0x31, 0x66, 0xB1, 0xF6, 0x76, 0xA6, 0x02, 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, 0x30 }
- },
- {
- { { 0, 1 }, { 0x03, 0x5F, 0xE1, 0x87, 0x3B, 0x4F, 0x29, 0x67, 0xF5, 0x2F, 0xEA, 0x4A, 0x06, 0xAD, 0x5A, 0x8E, 0xCC, 0xBE, 0x9D, 0x0F, 0xD7, 0x30, 0x68, 0x01, 0x2C, 0x89, 0x4E, 0x2E, 0x87, 0xCC, 0xB5, 0x80, 0x4B, 0x02, 0x47, 0x25, 0x37, 0x73, 0x45, 0xBD, 0xE0, 0xE9, 0xC3, 0x3A, 0xF3, 0xC4, 0x3C, 0x0A, 0x29, 0xA9, 0x24, 0x9F, 0x2F, 0x29, 0x56, 0xFA, 0x8C, 0xFE, 0xB5, 0x5C, 0x85, 0x73, 0xD0, 0x26, 0x2D, 0xC8 }, 0 },
- { { 2, 3 }, { 0x03, 0x5F, 0xE1, 0x87, 0x3B, 0x4F, 0x29, 0x67, 0xF5, 0x2F, 0xEA, 0x4A, 0x06, 0xAD, 0x5A, 0x8E, 0xCC, 0xBE, 0x9D, 0x0F, 0xD7, 0x30, 0x68, 0x01, 0x2C, 0x89, 0x4E, 0x2E, 0x87, 0xCC, 0xB5, 0x80, 0x4B, 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, 0x00 }, 0 },
- },
- {
- { { 0, 4 }, { 0 }, 1 },
- { { 5, 1 }, { 0 }, 0 },
- { { 6, 1 }, { 0 }, 0 },
- },
-};
-
-/* Omit pubnonces in the test vectors because our partial signature verification
- * implementation is able to accept the aggnonce directly. */
-struct musig_valid_case {
- size_t key_indices_len;
- size_t key_indices[3];
- size_t aggnonce_index;
- size_t msg_index;
- size_t signer_index;
- unsigned char expected[32];
-};
-
-struct musig_sign_error_case {
- size_t key_indices_len;
- size_t key_indices[3];
- size_t aggnonce_index;
- size_t msg_index;
- size_t secnonce_index;
- enum MUSIG_ERROR error;
-};
-
-struct musig_verify_fail_error_case {
- unsigned char sig[32];
- size_t key_indices_len;
- size_t key_indices[3];
- size_t nonce_indices_len;
- size_t nonce_indices[3];
- size_t msg_index;
- size_t signer_index;
- enum MUSIG_ERROR error;
-};
-
-struct musig_sign_verify_vector {
- unsigned char sk[32];
- unsigned char pubkeys[4][33];
- unsigned char secnonces[2][194];
- unsigned char pubnonces[5][194];
- unsigned char aggnonces[5][66];
- unsigned char msgs[1][32];
- struct musig_valid_case valid_case[4];
- struct musig_sign_error_case sign_error_case[6];
- struct musig_verify_fail_error_case verify_fail_case[3];
- struct musig_verify_fail_error_case verify_error_case[2];
-};
-
-static const struct musig_sign_verify_vector musig_sign_verify_vector = {
- { 0x7F, 0xB9, 0xE0, 0xE6, 0x87, 0xAD, 0xA1, 0xEE, 0xBF, 0x7E, 0xCF, 0xE2, 0xF2, 0x1E, 0x73, 0xEB, 0xDB, 0x51, 0xA7, 0xD4, 0x50, 0x94, 0x8D, 0xFE, 0x8D, 0x76, 0xD7, 0xF2, 0xD1, 0x00, 0x76, 0x71 },
- {
- { 0x03, 0x93, 0x5F, 0x97, 0x2D, 0xA0, 0x13, 0xF8, 0x0A, 0xE0, 0x11, 0x89, 0x0F, 0xA8, 0x9B, 0x67, 0xA2, 0x7B, 0x7B, 0xE6, 0xCC, 0xB2, 0x4D, 0x32, 0x74, 0xD1, 0x8B, 0x2D, 0x40, 0x67, 0xF2, 0x61, 0xA9 },
- { 0x02, 0xF9, 0x30, 0x8A, 0x01, 0x92, 0x58, 0xC3, 0x10, 0x49, 0x34, 0x4F, 0x85, 0xF8, 0x9D, 0x52, 0x29, 0xB5, 0x31, 0xC8, 0x45, 0x83, 0x6F, 0x99, 0xB0, 0x86, 0x01, 0xF1, 0x13, 0xBC, 0xE0, 0x36, 0xF9 },
- { 0x02, 0xDF, 0xF1, 0xD7, 0x7F, 0x2A, 0x67, 0x1C, 0x5F, 0x36, 0x18, 0x37, 0x26, 0xDB, 0x23, 0x41, 0xBE, 0x58, 0xFE, 0xAE, 0x1D, 0xA2, 0xDE, 0xCE, 0xD8, 0x43, 0x24, 0x0F, 0x7B, 0x50, 0x2B, 0xA6, 0x61 },
- { 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, 0x07 }
- },
- {
- { 0x50, 0x8B, 0x81, 0xA6, 0x11, 0xF1, 0x00, 0xA6, 0xB2, 0xB6, 0xB2, 0x96, 0x56, 0x59, 0x08, 0x98, 0xAF, 0x48, 0x8B, 0xCF, 0x2E, 0x1F, 0x55, 0xCF, 0x22, 0xE5, 0xCF, 0xB8, 0x44, 0x21, 0xFE, 0x61, 0xFA, 0x27, 0xFD, 0x49, 0xB1, 0xD5, 0x00, 0x85, 0xB4, 0x81, 0x28, 0x5E, 0x1C, 0xA2, 0x05, 0xD5, 0x5C, 0x82, 0xCC, 0x1B, 0x31, 0xFF, 0x5C, 0xD5, 0x4A, 0x48, 0x98, 0x29, 0x35, 0x59, 0x01, 0xF7, 0x03, 0x93, 0x5F, 0x97, 0x2D, 0xA0, 0x13, 0xF8, 0x0A, 0xE0, 0x11, 0x89, 0x0F, 0xA8, 0x9B, 0x67, 0xA2, 0x7B, 0x7B, 0xE6, 0xCC, 0xB2, 0x4D, 0x32, 0x74, 0xD1, 0x8B, 0x2D, 0x40, 0x67, 0xF2, 0x61, 0xA9 },
- { 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, 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, 0x03, 0x93, 0x5F, 0x97, 0x2D, 0xA0, 0x13, 0xF8, 0x0A, 0xE0, 0x11, 0x89, 0x0F, 0xA8, 0x9B, 0x67, 0xA2, 0x7B, 0x7B, 0xE6, 0xCC, 0xB2, 0x4D, 0x32, 0x74, 0xD1, 0x8B, 0x2D, 0x40, 0x67, 0xF2, 0x61, 0xA9 }
- },
- {
- { 0x03, 0x37, 0xC8, 0x78, 0x21, 0xAF, 0xD5, 0x0A, 0x86, 0x44, 0xD8, 0x20, 0xA8, 0xF3, 0xE0, 0x2E, 0x49, 0x9C, 0x93, 0x18, 0x65, 0xC2, 0x36, 0x0F, 0xB4, 0x3D, 0x0A, 0x0D, 0x20, 0xDA, 0xFE, 0x07, 0xEA, 0x02, 0x87, 0xBF, 0x89, 0x1D, 0x2A, 0x6D, 0xEA, 0xEB, 0xAD, 0xC9, 0x09, 0x35, 0x2A, 0xA9, 0x40, 0x5D, 0x14, 0x28, 0xC1, 0x5F, 0x4B, 0x75, 0xF0, 0x4D, 0xAE, 0x64, 0x2A, 0x95, 0xC2, 0x54, 0x84, 0x80 },
- { 0x02, 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, 0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98, 0x02, 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, 0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98 },
- { 0x03, 0x2D, 0xE2, 0x66, 0x26, 0x28, 0xC9, 0x0B, 0x03, 0xF5, 0xE7, 0x20, 0x28, 0x4E, 0xB5, 0x2F, 0xF7, 0xD7, 0x1F, 0x42, 0x84, 0xF6, 0x27, 0xB6, 0x8A, 0x85, 0x3D, 0x78, 0xC7, 0x8E, 0x1F, 0xFE, 0x93, 0x03, 0xE4, 0xC5, 0x52, 0x4E, 0x83, 0xFF, 0xE1, 0x49, 0x3B, 0x90, 0x77, 0xCF, 0x1C, 0xA6, 0xBE, 0xB2, 0x09, 0x0C, 0x93, 0xD9, 0x30, 0x32, 0x10, 0x71, 0xAD, 0x40, 0xB2, 0xF4, 0x4E, 0x59, 0x90, 0x46 },
- { 0x02, 0x37, 0xC8, 0x78, 0x21, 0xAF, 0xD5, 0x0A, 0x86, 0x44, 0xD8, 0x20, 0xA8, 0xF3, 0xE0, 0x2E, 0x49, 0x9C, 0x93, 0x18, 0x65, 0xC2, 0x36, 0x0F, 0xB4, 0x3D, 0x0A, 0x0D, 0x20, 0xDA, 0xFE, 0x07, 0xEA, 0x03, 0x87, 0xBF, 0x89, 0x1D, 0x2A, 0x6D, 0xEA, 0xEB, 0xAD, 0xC9, 0x09, 0x35, 0x2A, 0xA9, 0x40, 0x5D, 0x14, 0x28, 0xC1, 0x5F, 0x4B, 0x75, 0xF0, 0x4D, 0xAE, 0x64, 0x2A, 0x95, 0xC2, 0x54, 0x84, 0x80 },
- { 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, 0x09, 0x02, 0x87, 0xBF, 0x89, 0x1D, 0x2A, 0x6D, 0xEA, 0xEB, 0xAD, 0xC9, 0x09, 0x35, 0x2A, 0xA9, 0x40, 0x5D, 0x14, 0x28, 0xC1, 0x5F, 0x4B, 0x75, 0xF0, 0x4D, 0xAE, 0x64, 0x2A, 0x95, 0xC2, 0x54, 0x84, 0x80 }
- },
- {
- { 0x02, 0x84, 0x65, 0xFC, 0xF0, 0xBB, 0xDB, 0xCF, 0x44, 0x3A, 0xAB, 0xCC, 0xE5, 0x33, 0xD4, 0x2B, 0x4B, 0x5A, 0x10, 0x96, 0x6A, 0xC0, 0x9A, 0x49, 0x65, 0x5E, 0x8C, 0x42, 0xDA, 0xAB, 0x8F, 0xCD, 0x61, 0x03, 0x74, 0x96, 0xA3, 0xCC, 0x86, 0x92, 0x6D, 0x45, 0x2C, 0xAF, 0xCF, 0xD5, 0x5D, 0x25, 0x97, 0x2C, 0xA1, 0x67, 0x5D, 0x54, 0x93, 0x10, 0xDE, 0x29, 0x6B, 0xFF, 0x42, 0xF7, 0x2E, 0xEE, 0xA8, 0xC9 },
- { 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, 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, 0x00, 0x00 },
- { 0x04, 0x84, 0x65, 0xFC, 0xF0, 0xBB, 0xDB, 0xCF, 0x44, 0x3A, 0xAB, 0xCC, 0xE5, 0x33, 0xD4, 0x2B, 0x4B, 0x5A, 0x10, 0x96, 0x6A, 0xC0, 0x9A, 0x49, 0x65, 0x5E, 0x8C, 0x42, 0xDA, 0xAB, 0x8F, 0xCD, 0x61, 0x03, 0x74, 0x96, 0xA3, 0xCC, 0x86, 0x92, 0x6D, 0x45, 0x2C, 0xAF, 0xCF, 0xD5, 0x5D, 0x25, 0x97, 0x2C, 0xA1, 0x67, 0x5D, 0x54, 0x93, 0x10, 0xDE, 0x29, 0x6B, 0xFF, 0x42, 0xF7, 0x2E, 0xEE, 0xA8, 0xC9 },
- { 0x02, 0x84, 0x65, 0xFC, 0xF0, 0xBB, 0xDB, 0xCF, 0x44, 0x3A, 0xAB, 0xCC, 0xE5, 0x33, 0xD4, 0x2B, 0x4B, 0x5A, 0x10, 0x96, 0x6A, 0xC0, 0x9A, 0x49, 0x65, 0x5E, 0x8C, 0x42, 0xDA, 0xAB, 0x8F, 0xCD, 0x61, 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, 0x09 },
- { 0x02, 0x84, 0x65, 0xFC, 0xF0, 0xBB, 0xDB, 0xCF, 0x44, 0x3A, 0xAB, 0xCC, 0xE5, 0x33, 0xD4, 0x2B, 0x4B, 0x5A, 0x10, 0x96, 0x6A, 0xC0, 0x9A, 0x49, 0x65, 0x5E, 0x8C, 0x42, 0xDA, 0xAB, 0x8F, 0xCD, 0x61, 0x02, 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, 0x30 }
- },
- {
- { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF }
- },
- {
- { 3, { 0, 1, 2 }, 0, 0, 0, { 0x01, 0x2A, 0xBB, 0xCB, 0x52, 0xB3, 0x01, 0x6A, 0xC0, 0x3A, 0xD8, 0x23, 0x95, 0xA1, 0xA4, 0x15, 0xC4, 0x8B, 0x93, 0xDE, 0xF7, 0x87, 0x18, 0xE6, 0x2A, 0x7A, 0x90, 0x05, 0x2F, 0xE2, 0x24, 0xFB }},
- { 3, { 1, 0, 2 }, 0, 0, 1, { 0x9F, 0xF2, 0xF7, 0xAA, 0xA8, 0x56, 0x15, 0x0C, 0xC8, 0x81, 0x92, 0x54, 0x21, 0x8D, 0x3A, 0xDE, 0xEB, 0x05, 0x35, 0x26, 0x90, 0x51, 0x89, 0x77, 0x24, 0xF9, 0xDB, 0x37, 0x89, 0x51, 0x3A, 0x52 }},
- { 3, { 1, 2, 0 }, 0, 0, 2, { 0xFA, 0x23, 0xC3, 0x59, 0xF6, 0xFA, 0xC4, 0xE7, 0x79, 0x6B, 0xB9, 0x3B, 0xC9, 0xF0, 0x53, 0x2A, 0x95, 0x46, 0x8C, 0x53, 0x9B, 0xA2, 0x0F, 0xF8, 0x6D, 0x7C, 0x76, 0xED, 0x92, 0x22, 0x79, 0x00 }},
- { 2, { 0, 1 }, 1, 0, 0, { 0xAE, 0x38, 0x60, 0x64, 0xB2, 0x61, 0x05, 0x40, 0x47, 0x98, 0xF7, 0x5D, 0xE2, 0xEB, 0x9A, 0xF5, 0xED, 0xA5, 0x38, 0x7B, 0x06, 0x4B, 0x83, 0xD0, 0x49, 0xCB, 0x7C, 0x5E, 0x08, 0x87, 0x95, 0x31 }},
- },
- {
- { 2, { 1, 2 }, 0, 0, 0, MUSIG_PUBKEY },
- { 3, { 1, 0, 3 }, 0, 0, 0, MUSIG_PUBKEY },
- { 3, { 1, 2, 0 }, 2, 0, 0, MUSIG_AGGNONCE },
- { 3, { 1, 2, 0 }, 3, 0, 0, MUSIG_AGGNONCE },
- { 3, { 1, 2, 0 }, 4, 0, 0, MUSIG_AGGNONCE },
- { 3, { 0, 1, 2 }, 0, 0, 1, MUSIG_SECNONCE },
- },
- {
- { { 0x97, 0xAC, 0x83, 0x3A, 0xDC, 0xB1, 0xAF, 0xA4, 0x2E, 0xBF, 0x9E, 0x07, 0x25, 0x61, 0x6F, 0x3C, 0x9A, 0x0D, 0x5B, 0x61, 0x4F, 0x6F, 0xE2, 0x83, 0xCE, 0xAA, 0xA3, 0x7A, 0x8F, 0xFA, 0xF4, 0x06 }, 3, { 0, 1, 2 }, 3, { 0, 1, 2 }, 0, 0, MUSIG_SIG_VERIFY },
- { { 0x68, 0x53, 0x7C, 0xC5, 0x23, 0x4E, 0x50, 0x5B, 0xD1, 0x40, 0x61, 0xF8, 0xDA, 0x9E, 0x90, 0xC2, 0x20, 0xA1, 0x81, 0x85, 0x5F, 0xD8, 0xBD, 0xB7, 0xF1, 0x27, 0xBB, 0x12, 0x40, 0x3B, 0x4D, 0x3B }, 3, { 0, 1, 2 }, 3, { 0, 1, 2 }, 0, 1, MUSIG_SIG_VERIFY },
- { { 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 }, 3, { 0, 1, 2 }, 3, { 0, 1, 2 }, 0, 0, MUSIG_SIG },
- },
- {
- { { 0x68, 0x53, 0x7C, 0xC5, 0x23, 0x4E, 0x50, 0x5B, 0xD1, 0x40, 0x61, 0xF8, 0xDA, 0x9E, 0x90, 0xC2, 0x20, 0xA1, 0x81, 0x85, 0x5F, 0xD8, 0xBD, 0xB7, 0xF1, 0x27, 0xBB, 0x12, 0x40, 0x3B, 0x4D, 0x3B }, 3, { 0, 1, 2 }, 3, { 4, 1, 2 }, 0, 0, MUSIG_PUBNONCE },
- { { 0x68, 0x53, 0x7C, 0xC5, 0x23, 0x4E, 0x50, 0x5B, 0xD1, 0x40, 0x61, 0xF8, 0xDA, 0x9E, 0x90, 0xC2, 0x20, 0xA1, 0x81, 0x85, 0x5F, 0xD8, 0xBD, 0xB7, 0xF1, 0x27, 0xBB, 0x12, 0x40, 0x3B, 0x4D, 0x3B }, 3, { 3, 1, 2 }, 3, { 0, 1, 2 }, 0, 0, MUSIG_PUBKEY },
- },
-};
-
-struct musig_tweak_case {
- size_t key_indices_len;
- size_t key_indices[3];
- size_t nonce_indices_len;
- size_t nonce_indices[3];
- size_t tweak_indices_len;
- size_t tweak_indices[4];
- int is_xonly[4];
- size_t signer_index;
- unsigned char expected[32];
-};
-
-struct musig_tweak_vector {
- unsigned char sk[32];
- unsigned char secnonce[97];
- unsigned char aggnonce[66];
- unsigned char msg[32];
- unsigned char pubkeys[3][33];
- unsigned char pubnonces[3][194];
- unsigned char tweaks[5][32];
- struct musig_tweak_case valid_case[5];
- struct musig_tweak_case error_case[1];
-};
-
-static const struct musig_tweak_vector musig_tweak_vector = {
- { 0x7F, 0xB9, 0xE0, 0xE6, 0x87, 0xAD, 0xA1, 0xEE, 0xBF, 0x7E, 0xCF, 0xE2, 0xF2, 0x1E, 0x73, 0xEB, 0xDB, 0x51, 0xA7, 0xD4, 0x50, 0x94, 0x8D, 0xFE, 0x8D, 0x76, 0xD7, 0xF2, 0xD1, 0x00, 0x76, 0x71 },
- { 0x50, 0x8B, 0x81, 0xA6, 0x11, 0xF1, 0x00, 0xA6, 0xB2, 0xB6, 0xB2, 0x96, 0x56, 0x59, 0x08, 0x98, 0xAF, 0x48, 0x8B, 0xCF, 0x2E, 0x1F, 0x55, 0xCF, 0x22, 0xE5, 0xCF, 0xB8, 0x44, 0x21, 0xFE, 0x61, 0xFA, 0x27, 0xFD, 0x49, 0xB1, 0xD5, 0x00, 0x85, 0xB4, 0x81, 0x28, 0x5E, 0x1C, 0xA2, 0x05, 0xD5, 0x5C, 0x82, 0xCC, 0x1B, 0x31, 0xFF, 0x5C, 0xD5, 0x4A, 0x48, 0x98, 0x29, 0x35, 0x59, 0x01, 0xF7, 0x03, 0x93, 0x5F, 0x97, 0x2D, 0xA0, 0x13, 0xF8, 0x0A, 0xE0, 0x11, 0x89, 0x0F, 0xA8, 0x9B, 0x67, 0xA2, 0x7B, 0x7B, 0xE6, 0xCC, 0xB2, 0x4D, 0x32, 0x74, 0xD1, 0x8B, 0x2D, 0x40, 0x67, 0xF2, 0x61, 0xA9 },
- { 0x02, 0x84, 0x65, 0xFC, 0xF0, 0xBB, 0xDB, 0xCF, 0x44, 0x3A, 0xAB, 0xCC, 0xE5, 0x33, 0xD4, 0x2B, 0x4B, 0x5A, 0x10, 0x96, 0x6A, 0xC0, 0x9A, 0x49, 0x65, 0x5E, 0x8C, 0x42, 0xDA, 0xAB, 0x8F, 0xCD, 0x61, 0x03, 0x74, 0x96, 0xA3, 0xCC, 0x86, 0x92, 0x6D, 0x45, 0x2C, 0xAF, 0xCF, 0xD5, 0x5D, 0x25, 0x97, 0x2C, 0xA1, 0x67, 0x5D, 0x54, 0x93, 0x10, 0xDE, 0x29, 0x6B, 0xFF, 0x42, 0xF7, 0x2E, 0xEE, 0xA8, 0xC9 },
- { 0xF9, 0x54, 0x66, 0xD0, 0x86, 0x77, 0x0E, 0x68, 0x99, 0x64, 0x66, 0x42, 0x19, 0x26, 0x6F, 0xE5, 0xED, 0x21, 0x5C, 0x92, 0xAE, 0x20, 0xBA, 0xB5, 0xC9, 0xD7, 0x9A, 0xDD, 0xDD, 0xF3, 0xC0, 0xCF },
- {
- { 0x03, 0x93, 0x5F, 0x97, 0x2D, 0xA0, 0x13, 0xF8, 0x0A, 0xE0, 0x11, 0x89, 0x0F, 0xA8, 0x9B, 0x67, 0xA2, 0x7B, 0x7B, 0xE6, 0xCC, 0xB2, 0x4D, 0x32, 0x74, 0xD1, 0x8B, 0x2D, 0x40, 0x67, 0xF2, 0x61, 0xA9 },
- { 0x02, 0xF9, 0x30, 0x8A, 0x01, 0x92, 0x58, 0xC3, 0x10, 0x49, 0x34, 0x4F, 0x85, 0xF8, 0x9D, 0x52, 0x29, 0xB5, 0x31, 0xC8, 0x45, 0x83, 0x6F, 0x99, 0xB0, 0x86, 0x01, 0xF1, 0x13, 0xBC, 0xE0, 0x36, 0xF9 },
- { 0x02, 0xDF, 0xF1, 0xD7, 0x7F, 0x2A, 0x67, 0x1C, 0x5F, 0x36, 0x18, 0x37, 0x26, 0xDB, 0x23, 0x41, 0xBE, 0x58, 0xFE, 0xAE, 0x1D, 0xA2, 0xDE, 0xCE, 0xD8, 0x43, 0x24, 0x0F, 0x7B, 0x50, 0x2B, 0xA6, 0x59 }
- },
- {
- { 0x03, 0x37, 0xC8, 0x78, 0x21, 0xAF, 0xD5, 0x0A, 0x86, 0x44, 0xD8, 0x20, 0xA8, 0xF3, 0xE0, 0x2E, 0x49, 0x9C, 0x93, 0x18, 0x65, 0xC2, 0x36, 0x0F, 0xB4, 0x3D, 0x0A, 0x0D, 0x20, 0xDA, 0xFE, 0x07, 0xEA, 0x02, 0x87, 0xBF, 0x89, 0x1D, 0x2A, 0x6D, 0xEA, 0xEB, 0xAD, 0xC9, 0x09, 0x35, 0x2A, 0xA9, 0x40, 0x5D, 0x14, 0x28, 0xC1, 0x5F, 0x4B, 0x75, 0xF0, 0x4D, 0xAE, 0x64, 0x2A, 0x95, 0xC2, 0x54, 0x84, 0x80 },
- { 0x02, 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, 0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98, 0x02, 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, 0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98 },
- { 0x03, 0x2D, 0xE2, 0x66, 0x26, 0x28, 0xC9, 0x0B, 0x03, 0xF5, 0xE7, 0x20, 0x28, 0x4E, 0xB5, 0x2F, 0xF7, 0xD7, 0x1F, 0x42, 0x84, 0xF6, 0x27, 0xB6, 0x8A, 0x85, 0x3D, 0x78, 0xC7, 0x8E, 0x1F, 0xFE, 0x93, 0x03, 0xE4, 0xC5, 0x52, 0x4E, 0x83, 0xFF, 0xE1, 0x49, 0x3B, 0x90, 0x77, 0xCF, 0x1C, 0xA6, 0xBE, 0xB2, 0x09, 0x0C, 0x93, 0xD9, 0x30, 0x32, 0x10, 0x71, 0xAD, 0x40, 0xB2, 0xF4, 0x4E, 0x59, 0x90, 0x46 }
- },
- {
- { 0xE8, 0xF7, 0x91, 0xFF, 0x92, 0x25, 0xA2, 0xAF, 0x01, 0x02, 0xAF, 0xFF, 0x4A, 0x9A, 0x72, 0x3D, 0x96, 0x12, 0xA6, 0x82, 0xA2, 0x5E, 0xBE, 0x79, 0x80, 0x2B, 0x26, 0x3C, 0xDF, 0xCD, 0x83, 0xBB },
- { 0xAE, 0x2E, 0xA7, 0x97, 0xCC, 0x0F, 0xE7, 0x2A, 0xC5, 0xB9, 0x7B, 0x97, 0xF3, 0xC6, 0x95, 0x7D, 0x7E, 0x41, 0x99, 0xA1, 0x67, 0xA5, 0x8E, 0xB0, 0x8B, 0xCA, 0xFF, 0xDA, 0x70, 0xAC, 0x04, 0x55 },
- { 0xF5, 0x2E, 0xCB, 0xC5, 0x65, 0xB3, 0xD8, 0xBE, 0xA2, 0xDF, 0xD5, 0xB7, 0x5A, 0x4F, 0x45, 0x7E, 0x54, 0x36, 0x98, 0x09, 0x32, 0x2E, 0x41, 0x20, 0x83, 0x16, 0x26, 0xF2, 0x90, 0xFA, 0x87, 0xE0 },
- { 0x19, 0x69, 0xAD, 0x73, 0xCC, 0x17, 0x7F, 0xA0, 0xB4, 0xFC, 0xED, 0x6D, 0xF1, 0xF7, 0xBF, 0x99, 0x07, 0xE6, 0x65, 0xFD, 0xE9, 0xBA, 0x19, 0x6A, 0x74, 0xFE, 0xD0, 0xA3, 0xCF, 0x5A, 0xEF, 0x9D },
- { 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 }
- },
- {
- { 3, { 1, 2, 0 }, 3, { 1, 2, 0 }, 1, { 0 }, { 1 }, 2, { 0xE2, 0x8A, 0x5C, 0x66, 0xE6, 0x1E, 0x17, 0x8C, 0x2B, 0xA1, 0x9D, 0xB7, 0x7B, 0x6C, 0xF9, 0xF7, 0xE2, 0xF0, 0xF5, 0x6C, 0x17, 0x91, 0x8C, 0xD1, 0x31, 0x35, 0xE6, 0x0C, 0xC8, 0x48, 0xFE, 0x91 }},
- { 3, { 1, 2, 0 }, 3, { 1, 2, 0 }, 1, { 0 }, { 0 }, 2, { 0x38, 0xB0, 0x76, 0x77, 0x98, 0x25, 0x2F, 0x21, 0xBF, 0x57, 0x02, 0xC4, 0x80, 0x28, 0xB0, 0x95, 0x42, 0x83, 0x20, 0xF7, 0x3A, 0x4B, 0x14, 0xDB, 0x1E, 0x25, 0xDE, 0x58, 0x54, 0x3D, 0x2D, 0x2D }},
- { 3, { 1, 2, 0 }, 3, { 1, 2, 0 }, 2, { 0, 1 }, { 0, 1 }, 2, { 0x40, 0x8A, 0x0A, 0x21, 0xC4, 0xA0, 0xF5, 0xDA, 0xCA, 0xF9, 0x64, 0x6A, 0xD6, 0xEB, 0x6F, 0xEC, 0xD7, 0xF7, 0xA1, 0x1F, 0x03, 0xED, 0x1F, 0x48, 0xDF, 0xFF, 0x21, 0x85, 0xBC, 0x2C, 0x24, 0x08 }},
- { 3, { 1, 2, 0 }, 3, { 1, 2, 0 }, 4, { 0, 1, 2, 3 }, { 0, 0, 1, 1 }, 2, { 0x45, 0xAB, 0xD2, 0x06, 0xE6, 0x1E, 0x3D, 0xF2, 0xEC, 0x9E, 0x26, 0x4A, 0x6F, 0xEC, 0x82, 0x92, 0x14, 0x1A, 0x63, 0x3C, 0x28, 0x58, 0x63, 0x88, 0x23, 0x55, 0x41, 0xF9, 0xAD, 0xE7, 0x54, 0x35 }},
- { 3, { 1, 2, 0 }, 3, { 1, 2, 0 }, 4, { 0, 1, 2, 3 }, { 1, 0, 1, 0 }, 2, { 0xB2, 0x55, 0xFD, 0xCA, 0xC2, 0x7B, 0x40, 0xC7, 0xCE, 0x78, 0x48, 0xE2, 0xD3, 0xB7, 0xBF, 0x5E, 0xA0, 0xED, 0x75, 0x6D, 0xA8, 0x15, 0x65, 0xAC, 0x80, 0x4C, 0xCC, 0xA3, 0xE1, 0xD5, 0xD2, 0x39 }},
- },
- {
- { 3, { 1, 2, 0 }, 3, { 1, 2, 0 }, 1, { 4 }, { 0 }, 2, { 0 }},
- },
-};
-
-/* Omit pubnonces in the test vectors because they're only needed for
- * implementations that do not directly accept an aggnonce. */
-struct musig_sig_agg_case {
- size_t key_indices_len;
- size_t key_indices[2];
- size_t tweak_indices_len;
- size_t tweak_indices[3];
- int is_xonly[3];
- unsigned char aggnonce[66];
- size_t psig_indices_len;
- size_t psig_indices[2];
- /* if valid case */
- unsigned char expected[64];
- /* if error case */
- int invalid_sig_idx;
-};
-
-struct musig_sig_agg_vector {
- unsigned char pubkeys[4][33];
- unsigned char tweaks[3][32];
- unsigned char psigs[9][32];
- unsigned char msg[32];
- struct musig_sig_agg_case valid_case[4];
- struct musig_sig_agg_case error_case[1];
-};
-
-static const struct musig_sig_agg_vector musig_sig_agg_vector = {
- {
- { 0x03, 0x93, 0x5F, 0x97, 0x2D, 0xA0, 0x13, 0xF8, 0x0A, 0xE0, 0x11, 0x89, 0x0F, 0xA8, 0x9B, 0x67, 0xA2, 0x7B, 0x7B, 0xE6, 0xCC, 0xB2, 0x4D, 0x32, 0x74, 0xD1, 0x8B, 0x2D, 0x40, 0x67, 0xF2, 0x61, 0xA9 },
- { 0x02, 0xD2, 0xDC, 0x6F, 0x5D, 0xF7, 0xC5, 0x6A, 0xCF, 0x38, 0xC7, 0xFA, 0x0A, 0xE7, 0xA7, 0x59, 0xAE, 0x30, 0xE1, 0x9B, 0x37, 0x35, 0x9D, 0xFD, 0xE0, 0x15, 0x87, 0x23, 0x24, 0xC7, 0xEF, 0x6E, 0x05 },
- { 0x03, 0xC7, 0xFB, 0x10, 0x1D, 0x97, 0xFF, 0x93, 0x0A, 0xCD, 0x0C, 0x67, 0x60, 0x85, 0x2E, 0xF6, 0x4E, 0x69, 0x08, 0x3D, 0xE0, 0xB0, 0x6A, 0xC6, 0x33, 0x57, 0x24, 0x75, 0x4B, 0xB4, 0xB0, 0x52, 0x2C },
- { 0x02, 0x35, 0x24, 0x33, 0xB2, 0x1E, 0x7E, 0x05, 0xD3, 0xB4, 0x52, 0xB8, 0x1C, 0xAE, 0x56, 0x6E, 0x06, 0xD2, 0xE0, 0x03, 0xEC, 0xE1, 0x6D, 0x10, 0x74, 0xAA, 0xBA, 0x42, 0x89, 0xE0, 0xE3, 0xD5, 0x81 }
- },
- {
- { 0xB5, 0x11, 0xDA, 0x49, 0x21, 0x82, 0xA9, 0x1B, 0x0F, 0xFB, 0x9A, 0x98, 0x02, 0x0D, 0x55, 0xF2, 0x60, 0xAE, 0x86, 0xD7, 0xEC, 0xBD, 0x03, 0x99, 0xC7, 0x38, 0x3D, 0x59, 0xA5, 0xF2, 0xAF, 0x7C },
- { 0xA8, 0x15, 0xFE, 0x04, 0x9E, 0xE3, 0xC5, 0xAA, 0xB6, 0x63, 0x10, 0x47, 0x7F, 0xBC, 0x8B, 0xCC, 0xCA, 0xC2, 0xF3, 0x39, 0x5F, 0x59, 0xF9, 0x21, 0xC3, 0x64, 0xAC, 0xD7, 0x8A, 0x2F, 0x48, 0xDC },
- { 0x75, 0x44, 0x8A, 0x87, 0x27, 0x4B, 0x05, 0x64, 0x68, 0xB9, 0x77, 0xBE, 0x06, 0xEB, 0x1E, 0x9F, 0x65, 0x75, 0x77, 0xB7, 0x32, 0x0B, 0x0A, 0x33, 0x76, 0xEA, 0x51, 0xFD, 0x42, 0x0D, 0x18, 0xA8 }
- },
- {
- { 0xB1, 0x5D, 0x2C, 0xD3, 0xC3, 0xD2, 0x2B, 0x04, 0xDA, 0xE4, 0x38, 0xCE, 0x65, 0x3F, 0x6B, 0x4E, 0xCF, 0x04, 0x2F, 0x42, 0xCF, 0xDE, 0xD7, 0xC4, 0x1B, 0x64, 0xAA, 0xF9, 0xB4, 0xAF, 0x53, 0xFB },
- { 0x61, 0x93, 0xD6, 0xAC, 0x61, 0xB3, 0x54, 0xE9, 0x10, 0x5B, 0xBD, 0xC8, 0x93, 0x7A, 0x34, 0x54, 0xA6, 0xD7, 0x05, 0xB6, 0xD5, 0x73, 0x22, 0xA5, 0xA4, 0x72, 0xA0, 0x2C, 0xE9, 0x9F, 0xCB, 0x64 },
- { 0x9A, 0x87, 0xD3, 0xB7, 0x9E, 0xC6, 0x72, 0x28, 0xCB, 0x97, 0x87, 0x8B, 0x76, 0x04, 0x9B, 0x15, 0xDB, 0xD0, 0x5B, 0x81, 0x58, 0xD1, 0x7B, 0x5B, 0x91, 0x14, 0xD3, 0xC2, 0x26, 0x88, 0x75, 0x05 },
- { 0x66, 0xF8, 0x2E, 0xA9, 0x09, 0x23, 0x68, 0x9B, 0x85, 0x5D, 0x36, 0xC6, 0xB7, 0xE0, 0x32, 0xFB, 0x99, 0x70, 0x30, 0x14, 0x81, 0xB9, 0x9E, 0x01, 0xCD, 0xB4, 0xD6, 0xAC, 0x7C, 0x34, 0x7A, 0x15 },
- { 0x4F, 0x5A, 0xEE, 0x41, 0x51, 0x08, 0x48, 0xA6, 0x44, 0x7D, 0xCD, 0x1B, 0xBC, 0x78, 0x45, 0x7E, 0xF6, 0x90, 0x24, 0x94, 0x4C, 0x87, 0xF4, 0x02, 0x50, 0xD3, 0xEF, 0x2C, 0x25, 0xD3, 0x3E, 0xFE },
- { 0xDD, 0xEF, 0x42, 0x7B, 0xBB, 0x84, 0x7C, 0xC0, 0x27, 0xBE, 0xFF, 0x4E, 0xDB, 0x01, 0x03, 0x81, 0x48, 0x91, 0x78, 0x32, 0x25, 0x3E, 0xBC, 0x35, 0x5F, 0xC3, 0x3F, 0x4A, 0x8E, 0x2F, 0xCC, 0xE4 },
- { 0x97, 0xB8, 0x90, 0xA2, 0x6C, 0x98, 0x1D, 0xA8, 0x10, 0x2D, 0x3B, 0xC2, 0x94, 0x15, 0x9D, 0x17, 0x1D, 0x72, 0x81, 0x0F, 0xDF, 0x7C, 0x6A, 0x69, 0x1D, 0xEF, 0x02, 0xF0, 0xF7, 0xAF, 0x3F, 0xDC },
- { 0x53, 0xFA, 0x9E, 0x08, 0xBA, 0x52, 0x43, 0xCB, 0xCB, 0x0D, 0x79, 0x7C, 0x5E, 0xE8, 0x3B, 0xC6, 0x72, 0x8E, 0x53, 0x9E, 0xB7, 0x6C, 0x2D, 0x0B, 0xF0, 0xF9, 0x71, 0xEE, 0x4E, 0x90, 0x99, 0x71 },
- { 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 }
- },
- { 0x59, 0x9C, 0x67, 0xEA, 0x41, 0x0D, 0x00, 0x5B, 0x9D, 0xA9, 0x08, 0x17, 0xCF, 0x03, 0xED, 0x3B, 0x1C, 0x86, 0x8E, 0x4D, 0xA4, 0xED, 0xF0, 0x0A, 0x58, 0x80, 0xB0, 0x08, 0x2C, 0x23, 0x78, 0x69 },
- {
- { 2, { 0, 1 }, 0, { 0 }, { 0 }, { 0x03, 0x41, 0x43, 0x27, 0x22, 0xC5, 0xCD, 0x02, 0x68, 0xD8, 0x29, 0xC7, 0x02, 0xCF, 0x0D, 0x1C, 0xBC, 0xE5, 0x70, 0x33, 0xEE, 0xD2, 0x01, 0xFD, 0x33, 0x51, 0x91, 0x38, 0x52, 0x27, 0xC3, 0x21, 0x0C, 0x03, 0xD3, 0x77, 0xF2, 0xD2, 0x58, 0xB6, 0x4A, 0xAD, 0xC0, 0xE1, 0x6F, 0x26, 0x46, 0x23, 0x23, 0xD7, 0x01, 0xD2, 0x86, 0x04, 0x6A, 0x2E, 0xA9, 0x33, 0x65, 0x65, 0x6A, 0xFD, 0x98, 0x75, 0x98, 0x2B }, 2, { 0, 1 }, { 0x04, 0x1D, 0xA2, 0x22, 0x23, 0xCE, 0x65, 0xC9, 0x2C, 0x9A, 0x0D, 0x6C, 0x2C, 0xAC, 0x82, 0x8A, 0xAF, 0x1E, 0xEE, 0x56, 0x30, 0x4F, 0xEC, 0x37, 0x1D, 0xDF, 0x91, 0xEB, 0xB2, 0xB9, 0xEF, 0x09, 0x12, 0xF1, 0x03, 0x80, 0x25, 0x85, 0x7F, 0xED, 0xEB, 0x3F, 0xF6, 0x96, 0xF8, 0xB9, 0x9F, 0xA4, 0xBB, 0x2C, 0x58, 0x12, 0xF6, 0x09, 0x5A, 0x2E, 0x00, 0x04, 0xEC, 0x99, 0xCE, 0x18, 0xDE, 0x1E }, 0 },
- { 2, { 0, 2 }, 0, { 0 }, { 0 }, { 0x02, 0x24, 0xAF, 0xD3, 0x6C, 0x90, 0x20, 0x84, 0x05, 0x8B, 0x51, 0xB5, 0xD3, 0x66, 0x76, 0xBB, 0xA4, 0xDC, 0x97, 0xC7, 0x75, 0x87, 0x37, 0x68, 0xE5, 0x88, 0x22, 0xF8, 0x7F, 0xE4, 0x37, 0xD7, 0x92, 0x02, 0x8C, 0xB1, 0x59, 0x29, 0x09, 0x9E, 0xEE, 0x2F, 0x5D, 0xAE, 0x40, 0x4C, 0xD3, 0x93, 0x57, 0x59, 0x1B, 0xA3, 0x2E, 0x9A, 0xF4, 0xE1, 0x62, 0xB8, 0xD3, 0xE7, 0xCB, 0x5E, 0xFE, 0x31, 0xCB, 0x20 }, 2, { 2, 3 }, { 0x10, 0x69, 0xB6, 0x7E, 0xC3, 0xD2, 0xF3, 0xC7, 0xC0, 0x82, 0x91, 0xAC, 0xCB, 0x17, 0xA9, 0xC9, 0xB8, 0xF2, 0x81, 0x9A, 0x52, 0xEB, 0x5D, 0xF8, 0x72, 0x6E, 0x17, 0xE7, 0xD6, 0xB5, 0x2E, 0x9F, 0x01, 0x80, 0x02, 0x60, 0xA7, 0xE9, 0xDA, 0xC4, 0x50, 0xF4, 0xBE, 0x52, 0x2D, 0xE4, 0xCE, 0x12, 0xBA, 0x91, 0xAE, 0xAF, 0x2B, 0x42, 0x79, 0x21, 0x9E, 0xF7, 0x4B, 0xE1, 0xD2, 0x86, 0xAD, 0xD9 }, 0 },
- { 2, { 0, 2 }, 1, { 0 }, { 0 }, { 0x02, 0x08, 0xC5, 0xC4, 0x38, 0xC7, 0x10, 0xF4, 0xF9, 0x6A, 0x61, 0xE9, 0xFF, 0x3C, 0x37, 0x75, 0x88, 0x14, 0xB8, 0xC3, 0xAE, 0x12, 0xBF, 0xEA, 0x0E, 0xD2, 0xC8, 0x7F, 0xF6, 0x95, 0x4F, 0xF1, 0x86, 0x02, 0x0B, 0x18, 0x16, 0xEA, 0x10, 0x4B, 0x4F, 0xCA, 0x2D, 0x30, 0x4D, 0x73, 0x3E, 0x0E, 0x19, 0xCE, 0xAD, 0x51, 0x30, 0x3F, 0xF6, 0x42, 0x0B, 0xFD, 0x22, 0x23, 0x35, 0xCA, 0xA4, 0x02, 0x91, 0x6D }, 2, { 4, 5 }, { 0x5C, 0x55, 0x8E, 0x1D, 0xCA, 0xDE, 0x86, 0xDA, 0x0B, 0x2F, 0x02, 0x62, 0x6A, 0x51, 0x2E, 0x30, 0xA2, 0x2C, 0xF5, 0x25, 0x5C, 0xAE, 0xA7, 0xEE, 0x32, 0xC3, 0x8E, 0x9A, 0x71, 0xA0, 0xE9, 0x14, 0x8B, 0xA6, 0xC0, 0xE6, 0xEC, 0x76, 0x83, 0xB6, 0x42, 0x20, 0xF0, 0x29, 0x86, 0x96, 0xF1, 0xB8, 0x78, 0xCD, 0x47, 0xB1, 0x07, 0xB8, 0x1F, 0x71, 0x88, 0x81, 0x2D, 0x59, 0x39, 0x71, 0xE0, 0xCC }, 0 },
- { 2, { 0, 3 }, 3, { 0, 1, 2 }, { 1, 0, 1 }, { 0x02, 0xB5, 0xAD, 0x07, 0xAF, 0xCD, 0x99, 0xB6, 0xD9, 0x2C, 0xB4, 0x33, 0xFB, 0xD2, 0xA2, 0x8F, 0xDE, 0xB9, 0x8E, 0xAE, 0x2E, 0xB0, 0x9B, 0x60, 0x14, 0xEF, 0x0F, 0x81, 0x97, 0xCD, 0x58, 0x40, 0x33, 0x02, 0xE8, 0x61, 0x69, 0x10, 0xF9, 0x29, 0x3C, 0xF6, 0x92, 0xC4, 0x9F, 0x35, 0x1D, 0xB8, 0x6B, 0x25, 0xE3, 0x52, 0x90, 0x1F, 0x0E, 0x23, 0x7B, 0xAF, 0xDA, 0x11, 0xF1, 0xC1, 0xCE, 0xF2, 0x9F, 0xFD }, 2, { 6, 7 }, { 0x83, 0x9B, 0x08, 0x82, 0x0B, 0x68, 0x1D, 0xBA, 0x8D, 0xAF, 0x4C, 0xC7, 0xB1, 0x04, 0xE8, 0xF2, 0x63, 0x8F, 0x93, 0x88, 0xF8, 0xD7, 0xA5, 0x55, 0xDC, 0x17, 0xB6, 0xE6, 0x97, 0x1D, 0x74, 0x26, 0xCE, 0x07, 0xBF, 0x6A, 0xB0, 0x1F, 0x1D, 0xB5, 0x0E, 0x4E, 0x33, 0x71, 0x92, 0x95, 0xF4, 0x09, 0x45, 0x72, 0xB7, 0x98, 0x68, 0xE4, 0x40, 0xFB, 0x3D, 0xEF, 0xD3, 0xFA, 0xC1, 0xDB, 0x58, 0x9E }, 0 },
- },
- {
- { 2, { 0, 3 }, 3, { 0, 1, 2 }, { 1, 0, 1 }, { 0x02, 0xB5, 0xAD, 0x07, 0xAF, 0xCD, 0x99, 0xB6, 0xD9, 0x2C, 0xB4, 0x33, 0xFB, 0xD2, 0xA2, 0x8F, 0xDE, 0xB9, 0x8E, 0xAE, 0x2E, 0xB0, 0x9B, 0x60, 0x14, 0xEF, 0x0F, 0x81, 0x97, 0xCD, 0x58, 0x40, 0x33, 0x02, 0xE8, 0x61, 0x69, 0x10, 0xF9, 0x29, 0x3C, 0xF6, 0x92, 0xC4, 0x9F, 0x35, 0x1D, 0xB8, 0x6B, 0x25, 0xE3, 0x52, 0x90, 0x1F, 0x0E, 0x23, 0x7B, 0xAF, 0xDA, 0x11, 0xF1, 0xC1, 0xCE, 0xF2, 0x9F, 0xFD }, 2, { 7, 8 }, { 0 }, 1 },
- },
-};
-enum { MUSIG_VECTORS_MAX_PUBKEYS = 7 };
diff --git a/src/secp256k1.c b/src/secp256k1.c
index b9567015..cfd129cc 100644
--- a/src/secp256k1.c
+++ b/src/secp256k1.c
@@ -918,10 +918,6 @@ static int secp256k1_ge_parse_ext(secp256k1_ge* ge, const unsigned char *in33) {
# include "modules/ecdsa_adaptor/main_impl.h"
#endif
-#ifdef ENABLE_MODULE_MUSIG
-# include "modules/musig/main_impl.h"
-#endif
-
#ifdef ENABLE_MODULE_GENERATOR
# include "modules/generator/main_impl.h"
#endif
diff --git a/src/tests.c b/src/tests.c
index aef75618..7663527c 100644
--- a/src/tests.c
+++ b/src/tests.c
@@ -7592,10 +7592,6 @@ static void run_ecdsa_wycheproof(void) {
# include "modules/ecdh/tests_impl.h"
#endif
-#ifdef ENABLE_MODULE_MUSIG
-# include "modules/musig/tests_impl.h"
-#endif
-
#ifdef ENABLE_MODULE_RECOVERY
# include "modules/recovery/tests_impl.h"
#endif
@@ -7972,10 +7968,6 @@ int main(int argc, char **argv) {
run_ecdh_tests();
#endif
-#ifdef ENABLE_MODULE_MUSIG
- run_musig_tests();
-#endif
-
/* ecdsa tests */
run_ec_illegal_argument_tests();
run_pubkey_comparison();