@@ -124,12 +124,7 @@ static void secp256k1_schnorrsig_challenge(secp256k1_scalar* e, const unsigned c
124124 secp256k1_scalar_set_b32 (e , buf , NULL );
125125}
126126
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 ) {
133128 secp256k1_scalar sk ;
134129 secp256k1_scalar e ;
135130 secp256k1_scalar k ;
@@ -192,6 +187,59 @@ int secp256k1_schnorrsig_sign_custom(const secp256k1_context* ctx, unsigned char
192187 return ret ;
193188}
194189
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+
195243int secp256k1_schnorrsig_verify (const secp256k1_context * ctx , const unsigned char * sig64 , const unsigned char * msg , size_t msg_len , const secp256k1_xonly_pubkey * pubkey ) {
196244 secp256k1_scalar s ;
197245 secp256k1_scalar e ;
0 commit comments