Skip to content

Commit a7907b1

Browse files
Merge #261: Schnorr (Incremental) Half Aggregation
3a9b1d4 New Experimental Module: Incremental Half-Aggregation for Schnorr Signatures (Benedikt) Pull request description: Revisited PR #130 by jonasnick. I am happy to hear your thoughts. **Summary of changes compared to #130:** - Address comments from rustyrussell - Use tagged hash - Compute hashes with common prefix by copying midstate - Allow Incremental Aggregation and make code consistent with the [draft spec](https://github.com/BlockstreamResearch/cross-input-aggregation/blob/master/half-aggregation.mediawiki) ACKs for top commit: real-or-random: ACK 3a9b1d4 Tree-SHA512: 27239033f8b28ecf87ea310b3dd5a19dbbe6fd07495db71ef7017f8f444ec25a12897087d1bea0a2e9c3df77d7f17c38b183d7fe768858da2180f26624add4aa
2 parents 900a437 + 3a9b1d4 commit a7907b1

File tree

10 files changed

+714
-23
lines changed

10 files changed

+714
-23
lines changed

.github/workflows/ci.yml

+22-11
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ env:
4040
MUSIG: 'no'
4141
ECDSAADAPTOR: 'no'
4242
BPPP: 'no'
43+
SCHNORRSIG_HALFAGG: 'no'
4344
### test options
4445
SECP256K1_TEST_ITERS:
4546
BENCH: 'yes'
@@ -78,14 +79,14 @@ jobs:
7879
matrix:
7980
configuration:
8081
- env_vars: { WIDEMUL: 'int64', RECOVERY: 'yes' }
81-
- env_vars: { WIDEMUL: 'int64', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes' }
82+
- env_vars: { WIDEMUL: 'int64', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes'}
8283
- env_vars: { WIDEMUL: 'int128' }
8384
- env_vars: { WIDEMUL: 'int128_struct', ELLSWIFT: 'yes' }
8485
- env_vars: { WIDEMUL: 'int128', RECOVERY: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes' }
85-
- env_vars: { WIDEMUL: 'int128', ECDH: 'yes', SCHNORRSIG: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes'}
86+
- env_vars: { WIDEMUL: 'int128', ECDH: 'yes', SCHNORRSIG: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes'}
8687
- env_vars: { WIDEMUL: 'int128', ASM: 'x86_64', ELLSWIFT: 'yes' }
87-
- env_vars: { RECOVERY: 'yes', SCHNORRSIG: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes'}
88-
- env_vars: { CTIMETESTS: 'no', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', CPPFLAGS: '-DVERIFY' }
88+
- env_vars: { RECOVERY: 'yes', SCHNORRSIG: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes'}
89+
- env_vars: { CTIMETESTS: 'no', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', CPPFLAGS: '-DVERIFY' }
8990
- env_vars: { BUILD: 'distcheck', WITH_VALGRIND: 'no', CTIMETESTS: 'no', BENCH: 'no' }
9091
- env_vars: { CPPFLAGS: '-DDETERMINISTIC' }
9192
- env_vars: { CFLAGS: '-O0', CTIMETESTS: 'no' }
@@ -156,6 +157,7 @@ jobs:
156157
MUSIG: 'yes'
157158
ECDSAADAPTOR: 'yes'
158159
BPPP: 'yes'
160+
SCHNORRSIG_HALFAGG: 'yes'
159161
CC: ${{ matrix.cc }}
160162

161163
steps:
@@ -208,6 +210,7 @@ jobs:
208210
MUSIG: 'yes'
209211
ECDSAADAPTOR: 'yes'
210212
BPPP: 'yes'
213+
SCHNORRSIG_HALFAGG: 'yes'
211214
CTIMETESTS: 'no'
212215

213216
steps:
@@ -267,6 +270,7 @@ jobs:
267270
MUSIG: 'yes'
268271
ECDSAADAPTOR: 'yes'
269272
BPPP: 'yes'
273+
SCHNORRSIG_HALFAGG: 'yes'
270274
CTIMETESTS: 'no'
271275

272276
steps:
@@ -320,6 +324,7 @@ jobs:
320324
MUSIG: 'yes'
321325
ECDSAADAPTOR: 'yes'
322326
BPPP: 'yes'
327+
SCHNORRSIG_HALFAGG: 'yes'
323328
CTIMETESTS: 'no'
324329

325330
strategy:
@@ -383,6 +388,7 @@ jobs:
383388
MUSIG: 'yes'
384389
ECDSAADAPTOR: 'yes'
385390
BPPP: 'yes'
391+
SCHNORRSIG_HALFAGG: 'yes'
386392
CTIMETESTS: 'no'
387393

388394
steps:
@@ -443,6 +449,7 @@ jobs:
443449
MUSIG: 'yes'
444450
ECDSAADAPTOR: 'yes'
445451
BPPP: 'yes'
452+
SCHNORRSIG_HALFAGG: 'yes'
446453
CTIMETESTS: 'no'
447454
SECP256K1_TEST_ITERS: 2
448455

@@ -502,6 +509,7 @@ jobs:
502509
MUSIG: 'yes'
503510
ECDSAADAPTOR: 'yes'
504511
BPPP: 'yes'
512+
SCHNORRSIG_HALFAGG: 'yes'
505513
CTIMETESTS: 'no'
506514
CFLAGS: '-fsanitize=undefined,address -g'
507515
UBSAN_OPTIONS: 'print_stacktrace=1:halt_on_error=1'
@@ -567,6 +575,7 @@ jobs:
567575
MUSIG: 'yes'
568576
ECDSAADAPTOR: 'yes'
569577
BPPP: 'yes'
578+
SCHNORRSIG_HALFAGG: 'yes'
570579
CTIMETESTS: 'yes'
571580
CC: 'clang'
572581
SECP256K1_TEST_ITERS: 32
@@ -622,6 +631,7 @@ jobs:
622631
MUSIG: 'yes'
623632
ECDSAADAPTOR: 'yes'
624633
BPPP: 'yes'
634+
SCHNORRSIG_HALFAGG: 'yes'
625635
CTIMETESTS: 'no'
626636

627637
strategy:
@@ -678,15 +688,15 @@ jobs:
678688
fail-fast: false
679689
matrix:
680690
env_vars:
681-
- { WIDEMUL: 'int64', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes' }
691+
- { WIDEMUL: 'int64', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes' }
682692
- { WIDEMUL: 'int128_struct', ECMULTGENPRECISION: 2, ECMULTWINDOW: 4 }
683-
- { WIDEMUL: 'int128', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes' }
693+
- { WIDEMUL: 'int128', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes' }
684694
- { WIDEMUL: 'int128', RECOVERY: 'yes' }
685-
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes' }
686-
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', CC: 'gcc' }
687-
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', WRAPPER_CMD: 'valgrind --error-exitcode=42', SECP256K1_TEST_ITERS: 2 }
688-
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', CC: 'gcc', WRAPPER_CMD: 'valgrind --error-exitcode=42', SECP256K1_TEST_ITERS: 2 }
689-
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', CPPFLAGS: '-DVERIFY', CTIMETESTS: 'no' }
695+
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes' }
696+
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', CC: 'gcc' }
697+
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', WRAPPER_CMD: 'valgrind --error-exitcode=42', SECP256K1_TEST_ITERS: 2 }
698+
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', CC: 'gcc', WRAPPER_CMD: 'valgrind --error-exitcode=42', SECP256K1_TEST_ITERS: 2 }
699+
- { WIDEMUL: 'int128', RECOVERY: 'yes', ECDH: 'yes', SCHNORRSIG: 'yes', ELLSWIFT: 'yes', EXPERIMENTAL: 'yes', ECDSA_S2C: 'yes', RANGEPROOF: 'yes', WHITELIST: 'yes', GENERATOR: 'yes', MUSIG: 'yes', ECDSAADAPTOR: 'yes', BPPP: 'yes', SCHNORRSIG_HALFAGG: 'yes', CPPFLAGS: '-DVERIFY', CTIMETESTS: 'no' }
690700
- BUILD: 'distcheck'
691701

692702
steps:
@@ -805,6 +815,7 @@ jobs:
805815
MUSIG: 'yes'
806816
ECDSAADAPTOR: 'yes'
807817
BPPP: 'yes'
818+
SCHNORRSIG_HALFAGG: 'yes'
808819

809820
steps:
810821
- name: Checkout

Makefile.am

+4
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,10 @@ EXTRA_DIST += src/wycheproof/WYCHEPROOF_COPYING
265265
EXTRA_DIST += src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.json
266266
EXTRA_DIST += tools/tests_wycheproof_generate.py
267267

268+
if ENABLE_MODULE_SCHNORRSIG_HALFAGG
269+
include src/modules/schnorrsig_halfagg/Makefile.am.include
270+
endif
271+
268272
if ENABLE_MODULE_BPPP
269273
include src/modules/bppp/Makefile.am.include
270274
endif

ci/ci.sh

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ print_environment() {
1313
# does not rely on bash.
1414
for var in WERROR_CFLAGS MAKEFLAGS BUILD \
1515
ECMULTWINDOW ECMULTGENPRECISION ASM WIDEMUL WITH_VALGRIND EXTRAFLAGS \
16-
EXPERIMENTAL ECDH RECOVERY SCHNORRSIG ELLSWIFT \
16+
EXPERIMENTAL ECDH RECOVERY SCHNORRSIG SCHNORRSIG_HALFAGG ELLSWIFT \
1717
ECDSA_S2C GENERATOR RANGEPROOF WHITELIST MUSIG ECDSAADAPTOR BPPP \
1818
SECP256K1_TEST_ITERS BENCH SECP256K1_BENCH_ITERS CTIMETESTS\
1919
EXAMPLES \
@@ -82,6 +82,7 @@ esac
8282
--enable-module-rangeproof="$RANGEPROOF" --enable-module-whitelist="$WHITELIST" --enable-module-generator="$GENERATOR" \
8383
--enable-module-schnorrsig="$SCHNORRSIG" --enable-module-musig="$MUSIG" --enable-module-ecdsa-adaptor="$ECDSAADAPTOR" \
8484
--enable-module-schnorrsig="$SCHNORRSIG" \
85+
--enable-module-schnorrsig-halfagg="$SCHNORRSIG_HALFAGG" \
8586
--enable-examples="$EXAMPLES" \
8687
--enable-ctime-tests="$CTIMETESTS" \
8788
--with-valgrind="$WITH_VALGRIND" \

configure.ac

+24-11
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,10 @@ AC_ARG_ENABLE(module_schnorrsig,
184184
AS_HELP_STRING([--enable-module-schnorrsig],[enable schnorrsig module [default=yes]]), [],
185185
[SECP_SET_DEFAULT([enable_module_schnorrsig], [yes], [yes])])
186186

187+
AC_ARG_ENABLE(module_schnorrsig_halfagg,
188+
AS_HELP_STRING([--enable-module-schnorrsig-halfagg],[enable schnorrsig half-aggregation module (experimental) [default=no]]), [],
189+
[SECP_SET_DEFAULT([enable_module_schnorrsig_halfagg], [no], [yes])])
190+
187191
AC_ARG_ENABLE(module_ellswift,
188192
AS_HELP_STRING([--enable-module-ellswift],[enable ElligatorSwift module [default=yes]]), [],
189193
[SECP_SET_DEFAULT([enable_module_ellswift], [yes], [yes])])
@@ -445,6 +449,11 @@ SECP_CFLAGS="$SECP_CFLAGS $WERROR_CFLAGS"
445449

446450
# Processing must be done in a reverse topological sorting of the dependency graph
447451
# (dependent module first).
452+
if test x"$enable_module_schnorrsig_halfagg" = x"yes"; then
453+
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_SCHNORRSIG_HALFAGG=1"
454+
enable_module_schnorrsig=yes
455+
fi
456+
448457
if test x"$enable_module_bppp" = x"yes"; then
449458
if test x"$enable_module_generator" = x"no"; then
450459
AC_MSG_ERROR([Module dependency error: You have disabled the generator module explicitly, but it is required by the bppp module.])
@@ -497,7 +506,6 @@ if test x"$enable_module_generator" = x"yes"; then
497506
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_GENERATOR=1"
498507
fi
499508

500-
501509
if test x"$enable_module_ellswift" = x"yes"; then
502510
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_ELLSWIFT=1"
503511
fi
@@ -544,6 +552,9 @@ else
544552
# module (which automatically enables the module dependencies) we want to
545553
# print an error for the dependent module, not the module dependency. Hence,
546554
# we first test dependent modules.
555+
if test x"$enable_module_schnorrsig_halfagg" = x"yes"; then
556+
AC_MSG_ERROR([Schnorrsig Half-Aggregation module is experimental. Use --enable-experimental to allow.])
557+
fi
547558
if test x"$enable_module_bppp" = x"yes"; then
548559
AC_MSG_ERROR([Bulletproofs++ module is experimental. Use --enable-experimental to allow.])
549560
fi
@@ -599,6 +610,7 @@ AM_CONDITIONAL([ENABLE_MODULE_MUSIG], [test x"$enable_module_musig" = x"yes"])
599610
AM_CONDITIONAL([ENABLE_MODULE_ECDSA_S2C], [test x"$enable_module_ecdsa_s2c" = x"yes"])
600611
AM_CONDITIONAL([ENABLE_MODULE_ECDSA_ADAPTOR], [test x"$enable_module_ecdsa_adaptor" = x"yes"])
601612
AM_CONDITIONAL([ENABLE_MODULE_BPPP], [test x"$enable_module_bppp" = x"yes"])
613+
AM_CONDITIONAL([ENABLE_MODULE_SCHNORRSIG_HALFAGG], [test x"$enable_module_schnorrsig_halfagg" = x"yes"])
602614
AM_CONDITIONAL([USE_REDUCED_SURJECTION_PROOF_SIZE], [test x"$use_reduced_surjection_proof_size" = x"yes"])
603615
AM_CONDITIONAL([USE_EXTERNAL_ASM], [test x"$enable_external_asm" = x"yes"])
604616
AM_CONDITIONAL([USE_ASM_ARM], [test x"$set_asm" = x"arm32"])
@@ -638,18 +650,19 @@ echo " module musig = $enable_module_musig"
638650
echo " module ecdsa-s2c = $enable_module_ecdsa_s2c"
639651
echo " module ecdsa-adaptor = $enable_module_ecdsa_adaptor"
640652
echo " module bppp = $enable_module_bppp"
653+
echo " module schnorrsig-halfagg = $enable_module_schnorrsig_halfagg"
641654
echo
642-
echo " asm = $set_asm"
643-
echo " ecmult window size = $set_ecmult_window"
644-
echo " ecmult gen prec. bits = $set_ecmult_gen_precision"
655+
echo " asm = $set_asm"
656+
echo " ecmult window size = $set_ecmult_window"
657+
echo " ecmult gen prec. bits = $set_ecmult_gen_precision"
645658
# Hide test-only options unless they're used.
646659
if test x"$set_widemul" != xauto; then
647-
echo " wide multiplication = $set_widemul"
660+
echo " wide multiplication = $set_widemul"
648661
fi
649662
echo
650-
echo " valgrind = $enable_valgrind"
651-
echo " CC = $CC"
652-
echo " CPPFLAGS = $CPPFLAGS"
653-
echo " SECP_CFLAGS = $SECP_CFLAGS"
654-
echo " CFLAGS = $CFLAGS"
655-
echo " LDFLAGS = $LDFLAGS"
663+
echo " valgrind = $enable_valgrind"
664+
echo " CC = $CC"
665+
echo " CPPFLAGS = $CPPFLAGS"
666+
echo " SECP_CFLAGS = $SECP_CFLAGS"
667+
echo " CFLAGS = $CFLAGS"
668+
echo " LDFLAGS = $LDFLAGS"
+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
#ifndef SECP256K1_SCHNORRSIG_HALFAGG_H
2+
#define SECP256K1_SCHNORRSIG_HALFAGG_H
3+
4+
#include "secp256k1.h"
5+
#include "secp256k1_extrakeys.h"
6+
7+
#ifdef __cplusplus
8+
extern "C" {
9+
#endif
10+
11+
12+
/** Incrementally (Half-)Aggregate a sequence of Schnorr
13+
* signatures to an existing half-aggregate signature.
14+
*
15+
* Returns 1 on success, 0 on failure.
16+
* Args: ctx: a secp256k1 context object.
17+
* In/Out: aggsig: pointer to the serialized aggregate signature
18+
* that is input. The first 32*(n_before+1) of this
19+
* array should hold the input aggsig. It will be
20+
* overwritten by the new serialized aggregate signature.
21+
* It should be large enough for that, see aggsig_len.
22+
* aggsig_len: size of aggsig array in bytes.
23+
* Should be large enough to hold the new
24+
* serialized aggregate signature, i.e.,
25+
* should satisfy aggsig_size >= 32*(n_before+n_new+1).
26+
* It will be overwritten to be the exact size of the
27+
* resulting aggsig.
28+
* In: all_pubkeys: Array of (n_before + n_new) many x-only public keys,
29+
* including both the ones for the already aggregated signature
30+
* and the ones for the signatures that should be added.
31+
* Can only be NULL if n_before + n_new is 0.
32+
* all_msgs32: Array of (n_before + n_new) many 32-byte messages,
33+
* including both the ones for the already aggregated signature
34+
* and the ones for the signatures that should be added.
35+
* Can only be NULL if n_before + n_new is 0.
36+
* new_sigs64: Array of n_new many 64-byte signatures, containing the new
37+
* signatures that should be added. Can only be NULL if n_new is 0.
38+
* n_before: Number of signatures that have already been aggregated
39+
* in the input aggregate signature.
40+
* n_new: Number of signatures that should now be added
41+
* to the aggregate signature.
42+
*/
43+
SECP256K1_API int secp256k1_schnorrsig_inc_aggregate(
44+
const secp256k1_context *ctx,
45+
unsigned char *aggsig,
46+
size_t *aggsig_len,
47+
const secp256k1_xonly_pubkey* all_pubkeys,
48+
const unsigned char *all_msgs32,
49+
const unsigned char *new_sigs64,
50+
size_t n_before,
51+
size_t n_new
52+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
53+
54+
/** (Half-)Aggregate a sequence of Schnorr signatures.
55+
*
56+
* Returns 1 on success, 0 on failure.
57+
* Args: ctx: a secp256k1 context object.
58+
* Out: aggsig: pointer to an array of aggsig_len many bytes to
59+
* store the serialized aggregate signature.
60+
* In/Out: aggsig_len: size of the aggsig array that is passed in bytes;
61+
* will be overwritten to be the exact size of aggsig.
62+
* In: pubkeys: Array of n many x-only public keys.
63+
* Can only be NULL if n is 0.
64+
* msgs32: Array of n many 32-byte messages.
65+
* Can only be NULL if n is 0.
66+
* sigs64: Array of n many 64-byte signatures.
67+
* Can only be NULL if n is 0.
68+
* n: number of signatures to be aggregated.
69+
*/
70+
SECP256K1_API int secp256k1_schnorrsig_aggregate(
71+
const secp256k1_context *ctx,
72+
unsigned char *aggsig,
73+
size_t *aggsig_len,
74+
const secp256k1_xonly_pubkey *pubkeys,
75+
const unsigned char *msgs32,
76+
const unsigned char *sigs64,
77+
size_t n
78+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
79+
80+
/** Verify a (Half-)aggregate Schnorr signature.
81+
*
82+
* Returns: 1: correct signature.
83+
* 0: incorrect signature.
84+
* Args: ctx: a secp256k1 context object.
85+
* In: pubkeys: Array of n many x-only public keys. Can only be NULL if n is 0.
86+
* msgs32: Array of n many 32-byte messages. Can only be NULL if n is 0.
87+
* n: number of signatures to that have been aggregated.
88+
* aggsig: Pointer to an array of aggsig_size many bytes
89+
* containing the serialized aggregate
90+
* signature to be verified.
91+
* aggsig_len: Size of the aggregate signature in bytes.
92+
* Should be aggsig_len = 32*(n+1)
93+
*/
94+
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorrsig_aggverify(
95+
const secp256k1_context *ctx,
96+
const secp256k1_xonly_pubkey *pubkeys,
97+
const unsigned char *msgs32,
98+
size_t n,
99+
const unsigned char *aggsig,
100+
size_t aggsig_len
101+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(5);
102+
103+
#ifdef __cplusplus
104+
}
105+
#endif
106+
107+
#endif /* SECP256K1_SCHNORRSIG_HALFAGG_H */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
include_HEADERS += include/secp256k1_schnorrsig_halfagg.h
2+
noinst_HEADERS += src/modules/schnorrsig_halfagg/main_impl.h
3+
noinst_HEADERS += src/modules/schnorrsig_halfagg/tests_impl.h

0 commit comments

Comments
 (0)