@@ -54,8 +54,7 @@ int secp256k1_schnorrsig_sign(const secp256k1_context* ctx, secp256k1_schnorrsig
5454 secp256k1_ge r ;
5555 secp256k1_sha256 sha ;
5656 int overflow ;
57- unsigned char buf [33 ];
58- size_t buflen = sizeof (buf );
57+ unsigned char buf [32 ];
5958
6059 VERIFY_CHECK (ctx != NULL );
6160 ARG_CHECK (secp256k1_ecmult_gen_context_is_built (& ctx -> ecmult_gen_ctx ));
@@ -76,6 +75,13 @@ int secp256k1_schnorrsig_sign(const secp256k1_context* ctx, secp256k1_schnorrsig
7675 secp256k1_ecmult_gen (& ctx -> ecmult_gen_ctx , & pkj , & x );
7776 secp256k1_ge_set_gej (& pk , & pkj );
7877
78+ /* Because we are signing for a x-only pubkey, the secret key is negated
79+ * before signing if the point corresponding to the secret key is not
80+ * positive. */
81+ if (!secp256k1_fe_is_quad_var (& pk .y )) {
82+ secp256k1_scalar_negate (& x , & x );
83+ }
84+
7985 if (!noncefp (buf , msg32 , seckey , (unsigned char * ) "BIPSchnorrDerive" , (void * )ndata , 0 )) {
8086 return 0 ;
8187 }
@@ -93,12 +99,12 @@ int secp256k1_schnorrsig_sign(const secp256k1_context* ctx, secp256k1_schnorrsig
9399 secp256k1_fe_normalize (& r .x );
94100 secp256k1_fe_get_b32 (& sig -> data [0 ], & r .x );
95101
96-
97- /* tagged hash(r.x, pk, msg32) */
102+ /* tagged hash(r.x, pk.x, msg32) */
98103 secp256k1_schnorrsig_sha256_tagged (& sha );
99104 secp256k1_sha256_write (& sha , & sig -> data [0 ], 32 );
100- secp256k1_eckey_pubkey_serialize (& pk , buf , & buflen , 1 );
101- secp256k1_sha256_write (& sha , buf , buflen );
105+ secp256k1_fe_normalize (& pk .x );
106+ secp256k1_fe_get_b32 (buf , & pk .x );
107+ secp256k1_sha256_write (& sha , buf , sizeof (buf ));
102108 secp256k1_sha256_write (& sha , msg32 , 32 );
103109 secp256k1_sha256_finalize (& sha , buf );
104110
@@ -115,14 +121,14 @@ int secp256k1_schnorrsig_sign(const secp256k1_context* ctx, secp256k1_schnorrsig
115121
116122/* Helper function for verification and batch verification.
117123 * Computes R = sG - eP. */
118- static int secp256k1_schnorrsig_real_verify (const secp256k1_context * ctx , secp256k1_gej * rj , const secp256k1_scalar * s , const secp256k1_scalar * e , const secp256k1_pubkey * pk ) {
124+ static int secp256k1_schnorrsig_real_verify (const secp256k1_context * ctx , secp256k1_gej * rj , const secp256k1_scalar * s , const secp256k1_scalar * e , const secp256k1_xonly_pubkey * pk ) {
119125 secp256k1_scalar nege ;
120126 secp256k1_ge pkp ;
121127 secp256k1_gej pkj ;
122128
123129 secp256k1_scalar_negate (& nege , e );
124130
125- if (!secp256k1_pubkey_load (ctx , & pkp , pk )) {
131+ if (!secp256k1_pubkey_load (ctx , & pkp , ( secp256k1_pubkey * ) pk )) {
126132 return 0 ;
127133 }
128134 secp256k1_gej_set_ge (& pkj , & pkp );
@@ -132,14 +138,13 @@ static int secp256k1_schnorrsig_real_verify(const secp256k1_context* ctx, secp25
132138 return 1 ;
133139}
134140
135- int secp256k1_schnorrsig_verify (const secp256k1_context * ctx , const secp256k1_schnorrsig * sig , const unsigned char * msg32 , const secp256k1_pubkey * pk ) {
141+ int secp256k1_schnorrsig_verify (const secp256k1_context * ctx , const secp256k1_schnorrsig * sig , const unsigned char * msg32 , const secp256k1_xonly_pubkey * pk ) {
136142 secp256k1_scalar s ;
137143 secp256k1_scalar e ;
138144 secp256k1_gej rj ;
139145 secp256k1_fe rx ;
140146 secp256k1_sha256 sha ;
141- unsigned char buf [33 ];
142- size_t buflen = sizeof (buf );
147+ unsigned char buf [32 ];
143148 int overflow ;
144149
145150 VERIFY_CHECK (ctx != NULL );
@@ -159,8 +164,8 @@ int secp256k1_schnorrsig_verify(const secp256k1_context* ctx, const secp256k1_sc
159164
160165 secp256k1_schnorrsig_sha256_tagged (& sha );
161166 secp256k1_sha256_write (& sha , & sig -> data [0 ], 32 );
162- secp256k1_ec_pubkey_serialize (ctx , buf , & buflen , pk , SECP256K1_EC_COMPRESSED );
163- secp256k1_sha256_write (& sha , buf , buflen );
167+ secp256k1_xonly_pubkey_serialize (ctx , buf , pk );
168+ secp256k1_sha256_write (& sha , buf , sizeof ( buf ) );
164169 secp256k1_sha256_write (& sha , msg32 , 32 );
165170 secp256k1_sha256_finalize (& sha , buf );
166171 secp256k1_scalar_set_b32 (& e , buf , NULL );
@@ -186,7 +191,7 @@ typedef struct {
186191 /* Signature, message, public key tuples to verify */
187192 const secp256k1_schnorrsig * const * sig ;
188193 const unsigned char * const * msg32 ;
189- const secp256k1_pubkey * const * pk ;
194+ const secp256k1_xonly_pubkey * const * pk ;
190195 size_t n_sigs ;
191196} secp256k1_schnorrsig_verify_ecmult_context ;
192197
@@ -217,20 +222,19 @@ static int secp256k1_schnorrsig_verify_batch_ecmult_callback(secp256k1_scalar *s
217222 }
218223 /* eP */
219224 } else {
220- unsigned char buf [33 ];
221- size_t buflen = sizeof (buf );
225+ unsigned char buf [32 ];
222226 secp256k1_sha256 sha ;
223227 secp256k1_schnorrsig_sha256_tagged (& sha );
224228 secp256k1_sha256_write (& sha , & ecmult_context -> sig [idx / 2 ]-> data [0 ], 32 );
225- secp256k1_ec_pubkey_serialize (ecmult_context -> ctx , buf , & buflen , ecmult_context -> pk [idx / 2 ], SECP256K1_EC_COMPRESSED );
226- secp256k1_sha256_write (& sha , buf , buflen );
229+ secp256k1_xonly_pubkey_serialize (ecmult_context -> ctx , buf , ecmult_context -> pk [idx / 2 ]);
230+ secp256k1_sha256_write (& sha , buf , sizeof ( buf ) );
227231 secp256k1_sha256_write (& sha , ecmult_context -> msg32 [idx / 2 ], 32 );
228232 secp256k1_sha256_finalize (& sha , buf );
229233
230234 secp256k1_scalar_set_b32 (sc , buf , NULL );
231235 secp256k1_scalar_mul (sc , sc , & ecmult_context -> randomizer_cache [(idx / 2 ) % 2 ]);
232236
233- if (!secp256k1_pubkey_load (ecmult_context -> ctx , pt , ecmult_context -> pk [idx / 2 ])) {
237+ if (!secp256k1_pubkey_load (ecmult_context -> ctx , pt , ( secp256k1_pubkey * ) ecmult_context -> pk [idx / 2 ])) {
234238 return 0 ;
235239 }
236240 }
@@ -251,7 +255,7 @@ static int secp256k1_schnorrsig_verify_batch_ecmult_callback(secp256k1_scalar *s
251255 * pk: array of public keys, or NULL if there are no signatures
252256 * n_sigs: number of signatures in above arrays (must be 0 if they are NULL)
253257 */
254- static int secp256k1_schnorrsig_verify_batch_init_randomizer (const secp256k1_context * ctx , secp256k1_schnorrsig_verify_ecmult_context * ecmult_context , secp256k1_sha256 * sha , const secp256k1_schnorrsig * const * sig , const unsigned char * const * msg32 , const secp256k1_pubkey * const * pk , size_t n_sigs ) {
258+ static int secp256k1_schnorrsig_verify_batch_init_randomizer (const secp256k1_context * ctx , secp256k1_schnorrsig_verify_ecmult_context * ecmult_context , secp256k1_sha256 * sha , const secp256k1_schnorrsig * const * sig , const unsigned char * const * msg32 , const secp256k1_xonly_pubkey * const * pk , size_t n_sigs ) {
255259 size_t i ;
256260
257261 if (n_sigs > 0 ) {
@@ -265,7 +269,11 @@ static int secp256k1_schnorrsig_verify_batch_init_randomizer(const secp256k1_con
265269 size_t buflen = sizeof (buf );
266270 secp256k1_sha256_write (sha , sig [i ]-> data , 64 );
267271 secp256k1_sha256_write (sha , msg32 [i ], 32 );
268- secp256k1_ec_pubkey_serialize (ctx , buf , & buflen , pk [i ], SECP256K1_EC_COMPRESSED );
272+ /* We use compressed serialization here. If we would use
273+ * xonly_pubkey serialization and a user would wrongly memcpy
274+ * normal secp256k1_pubkeys into xonly_pubkeys then the randomizer
275+ * would be the same for two different pubkeys. */
276+ secp256k1_ec_pubkey_serialize (ctx , buf , & buflen , (secp256k1_pubkey * ) pk [i ], SECP256K1_EC_COMPRESSED );
269277 secp256k1_sha256_write (sha , buf , buflen );
270278 }
271279 ecmult_context -> ctx = ctx ;
@@ -313,7 +321,7 @@ static int secp256k1_schnorrsig_verify_batch_sum_s(secp256k1_scalar *s, unsigned
313321 * Seeds a random number generator with the inputs and derives a random number ai for every
314322 * signature i. Fails if y-coordinate of any R is not a quadratic residue or if
315323 * 0 != -(s1 + a2*s2 + ... + au*su)G + R1 + a2*R2 + ... + au*Ru + e1*P1 + (a2*e2)P2 + ... + (au*eu)Pu. */
316- int secp256k1_schnorrsig_verify_batch (const secp256k1_context * ctx , secp256k1_scratch * scratch , const secp256k1_schnorrsig * const * sig , const unsigned char * const * msg32 , const secp256k1_pubkey * const * pk , size_t n_sigs ) {
324+ int secp256k1_schnorrsig_verify_batch (const secp256k1_context * ctx , secp256k1_scratch * scratch , const secp256k1_schnorrsig * const * sig , const unsigned char * const * msg32 , const secp256k1_xonly_pubkey * const * pk , size_t n_sigs ) {
317325 secp256k1_schnorrsig_verify_ecmult_context ecmult_context ;
318326 secp256k1_sha256 sha ;
319327 secp256k1_scalar s ;
0 commit comments