Skip to content

Commit 662a093

Browse files
committed
schnorrsig: add extra parameter struct for sign_custom
This simplifies the interface of sign_custom and allows adding more parameters later in a backward compatible way.
1 parent 46f3d69 commit 662a093

File tree

4 files changed

+75
-20
lines changed

4 files changed

+75
-20
lines changed

include/secp256k1_schnorrsig.h

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,35 @@ typedef int (*secp256k1_nonce_function_hardened)(
6262
*/
6363
SECP256K1_API extern const secp256k1_nonce_function_hardened secp256k1_nonce_function_bip340;
6464

65+
/** Data structure that contains additional arguments for schnorrsig_sign_custom.
66+
*
67+
* A schnorrsig_extraparams structure object can be initialized correctly by
68+
* setting it to SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT.
69+
*
70+
* Members:
71+
* magic: set to SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC at initialization
72+
* and has no other function than making sure the object is
73+
* initialized.
74+
* noncefp: pointer to a nonce generation function. If NULL,
75+
* secp256k1_nonce_function_bip340 is used
76+
* ndata: pointer to arbitrary data used by the nonce generation function
77+
* (can be NULL). If it is non-NULL and
78+
* secp256k1_nonce_function_bip340 is used, then ndata must be a
79+
* pointer to 32-byte auxiliary randomness as per BIP-340.
80+
*/
81+
typedef struct {
82+
unsigned char magic[4];
83+
secp256k1_nonce_function_hardened noncefp;
84+
void* ndata;
85+
} secp256k1_schnorrsig_extraparams;
86+
87+
#define SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC "\xda\x6f\xb3\x8c"
88+
#define SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT {\
89+
SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC,\
90+
NULL,\
91+
NULL\
92+
}
93+
6594
/** Create a Schnorr signature.
6695
*
6796
* Does _not_ strictly follow BIP-340 because it does not verify the resulting
@@ -96,26 +125,23 @@ SECP256K1_API int secp256k1_schnorrsig_sign(
96125
/** Create a Schnorr signature with a more flexible API.
97126
*
98127
* Same arguments as secp256k1_schnorrsig_sign except that it allows signing
99-
* variable length messages and allows providing a different nonce derivation
100-
* function with its own data argument.
128+
* variable length messages and accepts a pointer to an extraparams object that
129+
* allows customizing signing by passing additional arguments.
130+
*
131+
* Creates the same signatures as schnorrsig_sign if msglen is 32 and the
132+
* extraparams.ndata is the same as aux_rand32.
101133
*
102134
* In: msg: the message being signed. Can only be NULL if msglen is 0.
103135
* msglen: length of the message
104-
* noncefp: pointer to a nonce generation function. If NULL,
105-
* secp256k1_nonce_function_bip340 is used.
106-
* ndata: pointer to arbitrary data used by the nonce generation function
107-
* (can be NULL). If it is non-NULL and
108-
* secp256k1_nonce_function_bip340 is used, then ndata must be a
109-
* pointer to 32-byte auxiliary randomness as per BIP-340.
136+
* extraparams: pointer to a extraparams object (can be NULL)
110137
*/
111138
SECP256K1_API int secp256k1_schnorrsig_sign_custom(
112139
const secp256k1_context* ctx,
113140
unsigned char *sig64,
114141
const unsigned char *msg,
115142
size_t msglen,
116143
const secp256k1_keypair *keypair,
117-
secp256k1_nonce_function_hardened noncefp,
118-
void *ndata
144+
secp256k1_schnorrsig_extraparams *extraparams
119145
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(5);
120146

121147
/** Verify a Schnorr signature.

src/modules/schnorrsig/main_impl.h

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,7 @@ static void secp256k1_schnorrsig_challenge(secp256k1_scalar* e, const unsigned c
120120
secp256k1_scalar_set_b32(e, buf, NULL);
121121
}
122122

123-
int secp256k1_schnorrsig_sign(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg32, const secp256k1_keypair *keypair, unsigned char *aux_rand32) {
124-
return secp256k1_schnorrsig_sign_custom(ctx, sig64, msg32, 32, keypair, NULL, aux_rand32);
125-
}
126-
127-
int secp256k1_schnorrsig_sign_custom(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg, size_t msglen, const secp256k1_keypair *keypair, secp256k1_nonce_function_hardened noncefp, void *ndata) {
123+
int secp256k1_schnorrsig_sign_internal(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg, size_t msglen, const secp256k1_keypair *keypair, secp256k1_nonce_function_hardened noncefp, void *ndata) {
128124
secp256k1_scalar sk;
129125
secp256k1_scalar e;
130126
secp256k1_scalar k;
@@ -187,6 +183,25 @@ int secp256k1_schnorrsig_sign_custom(const secp256k1_context* ctx, unsigned char
187183
return ret;
188184
}
189185

186+
int secp256k1_schnorrsig_sign(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg32, const secp256k1_keypair *keypair, unsigned char *aux_rand32) {
187+
return secp256k1_schnorrsig_sign_internal(ctx, sig64, msg32, 32, keypair, secp256k1_nonce_function_bip340, aux_rand32);
188+
}
189+
190+
int secp256k1_schnorrsig_sign_custom(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg, size_t msglen, const secp256k1_keypair *keypair, secp256k1_schnorrsig_extraparams *extraparams) {
191+
secp256k1_nonce_function_hardened noncefp = NULL;
192+
void *ndata = NULL;
193+
VERIFY_CHECK(ctx != NULL);
194+
195+
if (extraparams != NULL) {
196+
ARG_CHECK(secp256k1_memcmp_var(extraparams->magic,
197+
SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC,
198+
sizeof(extraparams->magic)) == 0);
199+
noncefp = extraparams->noncefp;
200+
ndata = extraparams->ndata;
201+
}
202+
return secp256k1_schnorrsig_sign_internal(ctx, sig64, msg, msglen, keypair, noncefp, ndata);
203+
}
204+
190205
int secp256k1_schnorrsig_verify(const secp256k1_context* ctx, const unsigned char *sig64, const unsigned char *msg, size_t msglen, const secp256k1_xonly_pubkey *pubkey) {
191206
secp256k1_scalar s;
192207
secp256k1_scalar e;

src/modules/schnorrsig/tests_exhaustive_impl.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ static void test_exhaustive_schnorrsig_verify(const secp256k1_context *ctx, cons
141141
static void test_exhaustive_schnorrsig_sign(const secp256k1_context *ctx, unsigned char (*xonly_pubkey_bytes)[32], const secp256k1_keypair* keypairs, const int* parities) {
142142
int d, k;
143143
uint64_t iter = 0;
144+
secp256k1_schnorrsig_extraparams extraparams = SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT;
145+
144146
/* Loop over keys. */
145147
for (d = 1; d < EXHAUSTIVE_TEST_ORDER; ++d) {
146148
int actual_d = d;
@@ -153,6 +155,8 @@ static void test_exhaustive_schnorrsig_sign(const secp256k1_context *ctx, unsign
153155
unsigned char sig64[64];
154156
int actual_k = k;
155157
if (skip_section(&iter)) continue;
158+
extraparams.noncefp = secp256k1_hardened_nonce_function_smallint;
159+
extraparams.ndata = &k;
156160
if (parities[k - 1]) actual_k = EXHAUSTIVE_TEST_ORDER - k;
157161
/* Generate random messages until all challenges have been tried. */
158162
while (e_count_done < EXHAUSTIVE_TEST_ORDER) {
@@ -165,7 +169,7 @@ static void test_exhaustive_schnorrsig_sign(const secp256k1_context *ctx, unsign
165169
unsigned char expected_s_bytes[32];
166170
secp256k1_scalar_get_b32(expected_s_bytes, &expected_s);
167171
/* Invoke the real function to construct a signature. */
168-
CHECK(secp256k1_schnorrsig_sign_custom(ctx, sig64, msg32, sizeof(msg32), &keypairs[d - 1], secp256k1_hardened_nonce_function_smallint, &k));
172+
CHECK(secp256k1_schnorrsig_sign_custom(ctx, sig64, msg32, sizeof(msg32), &keypairs[d - 1], &extraparams));
169173
/* The first 32 bytes must match the xonly pubkey for the specified k. */
170174
CHECK(secp256k1_memcmp_var(sig64, xonly_pubkey_bytes[k - 1], 32) == 0);
171175
/* The last 32 bytes must match the expected s value. */

src/modules/schnorrsig/tests_impl.h

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -692,24 +692,34 @@ static int nonce_function_overflowing(unsigned char *nonce32, const unsigned cha
692692

693693
void test_schnorrsig_sign(void) {
694694
unsigned char sk[32];
695+
secp256k1_xonly_pubkey pk;
695696
secp256k1_keypair keypair;
696697
const unsigned char msg[32] = "this is a msg for a schnorrsig..";
697698
unsigned char sig[64];
698699
unsigned char zeros64[64] = { 0 };
700+
secp256k1_schnorrsig_extraparams extraparams = SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT;
699701

700702
secp256k1_testrand256(sk);
701703
CHECK(secp256k1_keypair_create(ctx, &keypair, sk));
704+
CHECK(secp256k1_keypair_xonly_pub(ctx, &pk, NULL, &keypair));
702705
CHECK(secp256k1_schnorrsig_sign(ctx, sig, msg, &keypair, NULL) == 1);
706+
CHECK(secp256k1_schnorrsig_verify(ctx, sig, msg, sizeof(msg), &pk));
703707

704708
/* Test different nonce functions */
709+
CHECK(secp256k1_schnorrsig_sign_custom(ctx, sig, msg, sizeof(msg), &keypair, &extraparams) == 1);
710+
CHECK(secp256k1_schnorrsig_verify(ctx, sig, msg, sizeof(msg), &pk));
705711
memset(sig, 1, sizeof(sig));
706-
CHECK(secp256k1_schnorrsig_sign_custom(ctx, sig, msg, sizeof(msg), &keypair, nonce_function_failing, NULL) == 0);
712+
extraparams.noncefp = nonce_function_failing;
713+
CHECK(secp256k1_schnorrsig_sign_custom(ctx, sig, msg, sizeof(msg), &keypair, &extraparams) == 0);
707714
CHECK(secp256k1_memcmp_var(sig, zeros64, sizeof(sig)) == 0);
708715
memset(&sig, 1, sizeof(sig));
709-
CHECK(secp256k1_schnorrsig_sign_custom(ctx, sig, msg, sizeof(msg), &keypair, nonce_function_0, NULL) == 0);
716+
extraparams.noncefp = nonce_function_0;
717+
CHECK(secp256k1_schnorrsig_sign_custom(ctx, sig, msg, sizeof(msg), &keypair, &extraparams) == 0);
710718
CHECK(secp256k1_memcmp_var(sig, zeros64, sizeof(sig)) == 0);
711-
CHECK(secp256k1_schnorrsig_sign_custom(ctx, sig, msg, sizeof(msg), &keypair, nonce_function_overflowing, NULL) == 1);
712-
CHECK(secp256k1_memcmp_var(sig, zeros64, sizeof(sig)) != 0);
719+
memset(&sig, 1, sizeof(sig));
720+
extraparams.noncefp = nonce_function_overflowing;
721+
CHECK(secp256k1_schnorrsig_sign_custom(ctx, sig, msg, sizeof(msg), &keypair, &extraparams) == 1);
722+
CHECK(secp256k1_schnorrsig_verify(ctx, sig, msg, sizeof(msg), &pk));
713723
}
714724

715725
#define N_SIGS 3

0 commit comments

Comments
 (0)