Skip to content

Commit 3de6aed

Browse files
committed
use the magic in the schnorrsig extraparams struct for versioning
This ensures compatibility in that it makes sure that the `secp256k1_schnorrsig_sign_custom()` works for users using an older version of the headers but linking against a newer version of the library.
1 parent 602a484 commit 3de6aed

File tree

3 files changed

+43
-8
lines changed

3 files changed

+43
-8
lines changed

include/secp256k1_schnorrsig.h

+25-4
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,15 @@ typedef int (*secp256k1_nonce_function_hardened)(
122122
*/
123123
SECP256K1_API const secp256k1_nonce_function_hardened secp256k1_nonce_function_bip340;
124124

125+
/** First version of the extraparams struct. See `secp256k1_schnorrsig_extraparams` for the
126+
latest version and its documentation.
127+
*/
128+
typedef struct {
129+
unsigned char magic[4];
130+
secp256k1_nonce_function_hardened noncefp;
131+
void *ndata;
132+
} secp256k1_schnorrsig_extraparams_v0;
133+
125134
/** Data structure that contains additional arguments for schnorrsig_sign_custom.
126135
*
127136
* A schnorrsig_extraparams structure object can be initialized correctly by
@@ -150,16 +159,28 @@ typedef struct {
150159
void *ndata;
151160
secp256k1_schnorrsig_s2c_opening* s2c_opening;
152161
const unsigned char* s2c_data32;
153-
} secp256k1_schnorrsig_extraparams;
162+
} secp256k1_schnorrsig_extraparams_v1;
163+
164+
typedef secp256k1_schnorrsig_extraparams_v1 secp256k1_schnorrsig_extraparams;
165+
166+
#define SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC_V0 { 0xda, 0x6f, 0xb3, 0x8c }
167+
#define SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC_V1 { 0x05, 0x96, 0x5b, 0x5c }
168+
#define SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC_V1
169+
170+
#define SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT_V0 {\
171+
SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC_V0,\
172+
NULL,\
173+
NULL\
174+
}
154175

155-
#define SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC { 0xda, 0x6f, 0xb3, 0x8c }
156-
#define SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT {\
157-
SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC,\
176+
#define SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT_V1 {\
177+
SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC_V1,\
158178
NULL,\
159179
NULL,\
160180
NULL,\
161181
NULL\
162182
}
183+
#define SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT_V1
163184

164185
/** Create a Schnorr signature.
165186
*

src/modules/schnorrsig/main_impl.h

+12-4
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@ static void secp256k1_nonce_function_bip340_sha256_tagged_aux(secp256k1_sha256 *
108108
* by using the correct tagged hash function. */
109109
static const unsigned char bip340_algo[] = {'B', 'I', 'P', '0', '3', '4', '0', '/', 'n', 'o', 'n', 'c', 'e'};
110110

111-
static const unsigned char schnorrsig_extraparams_magic[4] = SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC;
111+
static const unsigned char schnorrsig_extraparams_magic_v0[4] = SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC_V0;
112+
static const unsigned char schnorrsig_extraparams_magic_v1[4] = SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC_V1;
112113

113114
static int nonce_function_bip340(unsigned char *nonce32, const unsigned char *msg, size_t msglen, const unsigned char *key32, const unsigned char *xonly_pk32, const unsigned char *algo, size_t algolen, void *data) {
114115
secp256k1_sha256 sha;
@@ -313,12 +314,19 @@ int secp256k1_schnorrsig_sign_custom(const secp256k1_context* ctx, unsigned char
313314

314315
if (extraparams != NULL) {
315316
ARG_CHECK(secp256k1_memcmp_var(extraparams->magic,
316-
schnorrsig_extraparams_magic,
317+
schnorrsig_extraparams_magic_v0,
318+
sizeof(extraparams->magic)) == 0 ||
319+
secp256k1_memcmp_var(extraparams->magic,
320+
schnorrsig_extraparams_magic_v1,
317321
sizeof(extraparams->magic)) == 0);
318322
noncefp = extraparams->noncefp;
319323
ndata = extraparams->ndata;
320-
s2c_opening = extraparams->s2c_opening;
321-
s2c_data32 = extraparams->s2c_data32;
324+
if (secp256k1_memcmp_var(extraparams->magic,
325+
schnorrsig_extraparams_magic_v1,
326+
sizeof(extraparams->magic)) == 0) {
327+
s2c_opening = extraparams->s2c_opening;
328+
s2c_data32 = extraparams->s2c_data32;
329+
}
322330
}
323331
return secp256k1_schnorrsig_sign_internal(ctx, sig64, msg, msglen, keypair, noncefp, ndata, s2c_opening, s2c_data32);
324332
}

src/modules/schnorrsig/tests_impl.h

+6
Original file line numberDiff line numberDiff line change
@@ -832,6 +832,7 @@ void test_schnorrsig_sign(void) {
832832
unsigned char sig[64];
833833
unsigned char sig2[64];
834834
unsigned char zeros64[64] = { 0 };
835+
secp256k1_schnorrsig_extraparams_v0 extraparams_v0 = SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT_V0;
835836
secp256k1_schnorrsig_extraparams extraparams = SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT;
836837
unsigned char aux_rand[32];
837838

@@ -868,6 +869,11 @@ void test_schnorrsig_sign(void) {
868869
CHECK(secp256k1_schnorrsig_sign_custom(CTX, sig, msg, sizeof(msg), &keypair, &extraparams) == 1);
869870
CHECK(secp256k1_schnorrsig_sign32(CTX, sig2, msg, &keypair, extraparams.ndata) == 1);
870871
CHECK(secp256k1_memcmp_var(sig, sig2, sizeof(sig)) == 0);
872+
873+
/* Test extraparams v0 to simulate users using old headers linking against a new version of the library */
874+
memset(sig, 1, sizeof(sig));
875+
CHECK(secp256k1_schnorrsig_sign_custom(CTX, sig, msg, sizeof(msg), &keypair, (secp256k1_schnorrsig_extraparams*)&extraparams_v0) == 1);
876+
CHECK(secp256k1_schnorrsig_verify(CTX, sig, msg, sizeof(msg), &pk));
871877
}
872878

873879
#define N_SIGS 3

0 commit comments

Comments
 (0)