Skip to content

Commit e6978c4

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 82557b4 commit e6978c4

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
@@ -104,7 +104,8 @@ static void secp256k1_nonce_function_bip340_sha256_tagged_aux(secp256k1_sha256 *
104104
* by using the correct tagged hash function. */
105105
static const unsigned char bip340_algo[13] = "BIP0340/nonce";
106106

107-
static const unsigned char schnorrsig_extraparams_magic[4] = SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC;
107+
static const unsigned char schnorrsig_extraparams_magic_v0[4] = SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC_V0;
108+
static const unsigned char schnorrsig_extraparams_magic_v1[4] = SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC_V1;
108109

109110
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) {
110111
secp256k1_sha256 sha;
@@ -309,12 +310,19 @@ int secp256k1_schnorrsig_sign_custom(const secp256k1_context* ctx, unsigned char
309310

310311
if (extraparams != NULL) {
311312
ARG_CHECK(secp256k1_memcmp_var(extraparams->magic,
312-
schnorrsig_extraparams_magic,
313+
schnorrsig_extraparams_magic_v0,
314+
sizeof(extraparams->magic)) == 0 ||
315+
secp256k1_memcmp_var(extraparams->magic,
316+
schnorrsig_extraparams_magic_v1,
313317
sizeof(extraparams->magic)) == 0);
314318
noncefp = extraparams->noncefp;
315319
ndata = extraparams->ndata;
316-
s2c_opening = extraparams->s2c_opening;
317-
s2c_data32 = extraparams->s2c_data32;
320+
if (secp256k1_memcmp_var(extraparams->magic,
321+
schnorrsig_extraparams_magic_v1,
322+
sizeof(extraparams->magic)) == 0) {
323+
s2c_opening = extraparams->s2c_opening;
324+
s2c_data32 = extraparams->s2c_data32;
325+
}
318326
}
319327
return secp256k1_schnorrsig_sign_internal(ctx, sig64, msg, msglen, keypair, noncefp, ndata, s2c_opening, s2c_data32);
320328
}

src/modules/schnorrsig/tests_impl.h

+6
Original file line numberDiff line numberDiff line change
@@ -881,6 +881,7 @@ void test_schnorrsig_sign(void) {
881881
unsigned char sig[64];
882882
unsigned char sig2[64];
883883
unsigned char zeros64[64] = { 0 };
884+
secp256k1_schnorrsig_extraparams_v0 extraparams_v0 = SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT_V0;
884885
secp256k1_schnorrsig_extraparams extraparams = SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT;
885886
unsigned char aux_rand[32];
886887

@@ -917,6 +918,11 @@ void test_schnorrsig_sign(void) {
917918
CHECK(secp256k1_schnorrsig_sign_custom(CTX, sig, msg, sizeof(msg), &keypair, &extraparams) == 1);
918919
CHECK(secp256k1_schnorrsig_sign32(CTX, sig2, msg, &keypair, extraparams.ndata) == 1);
919920
CHECK(secp256k1_memcmp_var(sig, sig2, sizeof(sig)) == 0);
921+
922+
/* Test extraparams v0 to simulate users using old headers linking against a new version of the library */
923+
memset(sig, 1, sizeof(sig));
924+
CHECK(secp256k1_schnorrsig_sign_custom(CTX, sig, msg, sizeof(msg), &keypair, (secp256k1_schnorrsig_extraparams*)&extraparams_v0) == 1);
925+
CHECK(secp256k1_schnorrsig_verify(CTX, sig, msg, sizeof(msg), &pk));
920926
}
921927

922928
#define N_SIGS 3

0 commit comments

Comments
 (0)