@@ -124,12 +124,7 @@ static void secp256k1_schnorrsig_challenge(secp256k1_scalar* e, const unsigned c
124
124
secp256k1_scalar_set_b32 (e , buf , NULL );
125
125
}
126
126
127
-
128
- int secp256k1_schnorrsig_sign (const secp256k1_context * ctx , unsigned char * sig64 , const unsigned char * msg , size_t msg_len , const secp256k1_keypair * keypair , unsigned char * aux_rand32 ) {
129
- return secp256k1_schnorrsig_sign_custom (ctx , sig64 , msg , msg_len , keypair , NULL , aux_rand32 );
130
- }
131
-
132
- int secp256k1_schnorrsig_sign_custom (const secp256k1_context * ctx , unsigned char * sig64 , const unsigned char * msg , size_t msg_len , const secp256k1_keypair * keypair , secp256k1_nonce_function_hardened noncefp , void * ndata ) {
127
+ int secp256k1_schnorrsig_sign_internal (const secp256k1_context * ctx , unsigned char * sig64 , const unsigned char * msg , size_t msg_len , const secp256k1_keypair * keypair , secp256k1_nonce_function_hardened noncefp , void * ndata ) {
133
128
secp256k1_scalar sk ;
134
129
secp256k1_scalar e ;
135
130
secp256k1_scalar k ;
@@ -192,6 +187,59 @@ int secp256k1_schnorrsig_sign_custom(const secp256k1_context* ctx, unsigned char
192
187
return ret ;
193
188
}
194
189
190
+
191
+ int secp256k1_schnorrsig_sign (const secp256k1_context * ctx , unsigned char * sig64 , const unsigned char * msg , size_t msg_len , const secp256k1_keypair * keypair , unsigned char * aux_rand32 ) {
192
+ return secp256k1_schnorrsig_sign_internal (ctx , sig64 , msg , msg_len , keypair , secp256k1_nonce_function_bip340 , aux_rand32 );
193
+ }
194
+
195
+ /* This implements versioned structs which are used as function parameters with
196
+ * forward and backward compatibility (see also
197
+ * https://lkml.org/lkml/2015/7/30/117). This function resembles the linux
198
+ * kernel function copy_struct_from_user
199
+ * (https://github.com/torvalds/linux/blob/0593c1b4598a77b5f835b278cde0ab71e2578588/include/linux/uaccess.h#L298).
200
+ */
201
+ static int copy_versioned_struct (void * dst , size_t dstsize , const void * src , size_t srcsize )
202
+ {
203
+ size_t size = dstsize < srcsize ? dstsize : srcsize ; /* min */
204
+ size_t rest = (dstsize > srcsize ? dstsize : srcsize ) /* max */
205
+ - size ;
206
+
207
+ /* Deal with trailing bytes. */
208
+ if (srcsize < dstsize ) {
209
+ memset ((unsigned char * )dst + size , 0 , rest );
210
+ } else if (srcsize > dstsize ) {
211
+ size_t i ;
212
+ for (i = 0 ; i < rest ; i ++ ) {
213
+ if (* ((unsigned char * )src + size + i ) != 0 ) {
214
+ return 0 ;
215
+ }
216
+ }
217
+ }
218
+ /* Copy the interoperable parts of the struct. */
219
+ memcpy (dst , src , size );
220
+ return 1 ;
221
+ }
222
+
223
+ static int copy_versioned_config (secp256k1_schnorrsig_config * config , secp256k1_schnorrsig_config * uconfig ) {
224
+ memset (config , 0 , sizeof (* config ));
225
+ return copy_versioned_struct (config , sizeof (* config ), uconfig , config -> size );
226
+ }
227
+
228
+ int secp256k1_schnorrsig_sign_custom (const secp256k1_context * ctx , unsigned char * sig64 , const unsigned char * msg , size_t msg_len , const secp256k1_keypair * keypair , secp256k1_schnorrsig_config * uconfig ) {
229
+ secp256k1_schnorrsig_config config ;
230
+
231
+ VERIFY_CHECK (ctx != NULL );
232
+ ARG_CHECK (uconfig != NULL );
233
+ ARG_CHECK (secp256k1_memcmp_var (uconfig -> magic ,
234
+ SECP256K1_SCHNORRSIG_CONFIG_MAGIC ,
235
+ sizeof (uconfig -> magic )) == 0 );
236
+
237
+ if (!copy_versioned_config (& config , uconfig )) {
238
+ return 0 ;
239
+ }
240
+ return secp256k1_schnorrsig_sign_internal (ctx , sig64 , msg , msg_len , keypair , config .noncefp , config .ndata );
241
+ }
242
+
195
243
int secp256k1_schnorrsig_verify (const secp256k1_context * ctx , const unsigned char * sig64 , const unsigned char * msg , size_t msg_len , const secp256k1_xonly_pubkey * pubkey ) {
196
244
secp256k1_scalar s ;
197
245
secp256k1_scalar e ;
0 commit comments