@@ -13,7 +13,7 @@ use core::{fmt, ptr, str};
1313pub use self :: recovery:: { RecoverableSignature , RecoveryId } ;
1414pub use self :: serialized_signature:: SerializedSignature ;
1515use crate :: ffi:: CPtr ;
16- use crate :: { ecdsa, ffi, from_hex, Error , Message , PublicKey , Secp256k1 , SecretKey } ;
16+ use crate :: { ecdsa, ffi, from_hex, Error , Message , PublicKey , Secp256k1 , SecretKey , Signing , Verification } ;
1717
1818/// An ECDSA signature
1919#[ derive( Copy , Clone , PartialOrd , Ord , PartialEq , Eq , Hash ) ]
@@ -341,6 +341,177 @@ pub fn sign_low_r(msg: impl Into<Message>, sk: &SecretKey) -> Signature {
341341 sign_grind_with_check ( msg, sk, compact_sig_has_zero_first_bit)
342342}
343343
344+ impl < C : Signing > Secp256k1 < C > {
345+ #[ deprecated( since = "0.32" , note = "use ecdsa::sign_ecdsa_with_noncedata_pointer instead" ) ]
346+ fn sign_ecdsa_with_noncedata_pointer (
347+ & self ,
348+ msg : impl Into < Message > ,
349+ sk : & SecretKey ,
350+ noncedata : Option < & [ u8 ; 32 ] > ,
351+ ) -> Signature {
352+ let msg = msg. into ( ) ;
353+ unsafe {
354+ let mut ret = ffi:: Signature :: new ( ) ;
355+ let noncedata_ptr = match noncedata {
356+ Some ( arr) => arr. as_c_ptr ( ) as * const _ ,
357+ None => ptr:: null ( ) ,
358+ } ;
359+ // We can assume the return value because it's not possible to construct
360+ // an invalid signature from a valid `Message` and `SecretKey`
361+ assert_eq ! (
362+ ffi:: secp256k1_ecdsa_sign(
363+ self . ctx. as_ptr( ) ,
364+ & mut ret,
365+ msg. as_c_ptr( ) ,
366+ sk. as_c_ptr( ) ,
367+ ffi:: secp256k1_nonce_function_rfc6979,
368+ noncedata_ptr
369+ ) ,
370+ 1
371+ ) ;
372+ Signature :: from ( ret)
373+ }
374+ }
375+
376+ /// Constructs a signature for `msg` using the secret key `sk` and RFC6979 nonce
377+ /// Requires a signing-capable context.
378+ #[ deprecated( since = "0.32" , note = "use ecdsa::sign_ecdsa instead" ) ]
379+ pub fn sign_ecdsa ( & self , msg : impl Into < Message > , sk : & SecretKey ) -> Signature {
380+ self . sign_ecdsa_with_noncedata_pointer ( msg, sk, None )
381+ }
382+
383+ /// Constructs a signature for `msg` using the secret key `sk` and RFC6979 nonce
384+ /// and includes 32 bytes of noncedata in the nonce generation via inclusion in
385+ /// one of the hash operations during nonce generation. This is useful when multiple
386+ /// signatures are needed for the same Message and SecretKey while still using RFC6979.
387+ /// Requires a signing-capable context.
388+ #[ deprecated( since = "0.32" , note = "use ecdsa::sign_ecdsa_with_noncedata instead" ) ]
389+ pub fn sign_ecdsa_with_noncedata (
390+ & self ,
391+ msg : impl Into < Message > ,
392+ sk : & SecretKey ,
393+ noncedata : & [ u8 ; 32 ] ,
394+ ) -> Signature {
395+ self . sign_ecdsa_with_noncedata_pointer ( msg, sk, Some ( noncedata) )
396+ }
397+
398+ fn sign_grind_with_check (
399+ & self ,
400+ msg : impl Into < Message > ,
401+ sk : & SecretKey ,
402+ check : impl Fn ( & ffi:: Signature ) -> bool ,
403+ ) -> Signature {
404+ let mut entropy_p: * const ffi:: types:: c_void = ptr:: null ( ) ;
405+ let mut counter: u32 = 0 ;
406+ let mut extra_entropy = [ 0u8 ; 32 ] ;
407+ let msg = msg. into ( ) ;
408+ loop {
409+ unsafe {
410+ let mut ret = ffi:: Signature :: new ( ) ;
411+ // We can assume the return value because it's not possible to construct
412+ // an invalid signature from a valid `Message` and `SecretKey`
413+ assert_eq ! (
414+ ffi:: secp256k1_ecdsa_sign(
415+ self . ctx. as_ptr( ) ,
416+ & mut ret,
417+ msg. as_c_ptr( ) ,
418+ sk. as_c_ptr( ) ,
419+ ffi:: secp256k1_nonce_function_rfc6979,
420+ entropy_p
421+ ) ,
422+ 1
423+ ) ;
424+ if check ( & ret) {
425+ return Signature :: from ( ret) ;
426+ }
427+
428+ counter += 1 ;
429+ extra_entropy[ ..4 ] . copy_from_slice ( & counter. to_le_bytes ( ) ) ;
430+ entropy_p = extra_entropy. as_c_ptr ( ) . cast :: < ffi:: types:: c_void > ( ) ;
431+
432+ // When fuzzing, these checks will usually spinloop forever, so just short-circuit them.
433+ #[ cfg( secp256k1_fuzz) ]
434+ return Signature :: from ( ret) ;
435+ }
436+ }
437+ }
438+
439+ /// Constructs a signature for `msg` using the secret key `sk`, RFC6979 nonce
440+ /// and "grinds" the nonce by passing extra entropy if necessary to produce
441+ /// a signature that is less than 71 - `bytes_to_grind` bytes. The number
442+ /// of signing operation performed by this function is exponential in the
443+ /// number of bytes grinded.
444+ /// Requires a signing capable context.
445+ #[ deprecated( since = "0.32" , note = "use ecdsa::sign_ecdsa_grind_r instead" ) ]
446+ pub fn sign_ecdsa_grind_r (
447+ & self ,
448+ msg : impl Into < Message > ,
449+ sk : & SecretKey ,
450+ bytes_to_grind : usize ,
451+ ) -> Signature {
452+ let len_check = |s : & ffi:: Signature | der_length_check ( s, 71 - bytes_to_grind) ;
453+ self . sign_grind_with_check ( msg, sk, len_check)
454+ }
455+
456+ /// Constructs a signature for `msg` using the secret key `sk`, RFC6979 nonce
457+ /// and "grinds" the nonce by passing extra entropy if necessary to produce
458+ /// a signature that is less than 71 bytes and compatible with the low r
459+ /// signature implementation of bitcoin core. In average, this function
460+ /// will perform two signing operations.
461+ /// Requires a signing capable context.
462+ #[ deprecated( since = "0.32" , note = "use ecdsa::sign_ecdsa_low_r instead" ) ]
463+ pub fn sign_ecdsa_low_r ( & self , msg : impl Into < Message > , sk : & SecretKey ) -> Signature {
464+ self . sign_grind_with_check ( msg, sk, compact_sig_has_zero_first_bit)
465+ }
466+ }
467+
468+ impl < C : Verification > Secp256k1 < C > {
469+ /// Checks that `sig` is a valid ECDSA signature for `msg` using the public
470+ /// key `pubkey`. Returns `Ok(())` on success. Note that this function cannot
471+ /// be used for Bitcoin consensus checking since there may exist signatures
472+ /// which OpenSSL would verify but not libsecp256k1, or vice-versa. Requires a
473+ /// verify-capable context.
474+ ///
475+ /// ```rust
476+ /// # #[cfg(all(feature = "rand", feature = "std"))] {
477+ /// # use secp256k1::{rand, Secp256k1, Message, Error};
478+ /// #
479+ /// # let secp = Secp256k1::new();
480+ /// # let (secret_key, public_key) = secp.generate_keypair(&mut rand::rng());
481+ /// #
482+ /// let message = Message::from_digest_slice(&[0xab; 32]).expect("32 bytes");
483+ /// let sig = secp.sign_ecdsa(message, &secret_key);
484+ /// assert_eq!(secp.verify_ecdsa(&sig, message, &public_key), Ok(()));
485+ ///
486+ /// let message = Message::from_digest_slice(&[0xcd; 32]).expect("32 bytes");
487+ /// assert_eq!(secp.verify_ecdsa(&sig, message, &public_key), Err(Error::IncorrectSignature));
488+ /// # }
489+ /// ```
490+ #[ inline]
491+ #[ deprecated( since = "0.32" , note = "use ecdsa::verify instead" ) ]
492+ pub fn verify_ecdsa (
493+ & self ,
494+ sig : & Signature ,
495+ msg : impl Into < Message > ,
496+ pk : & PublicKey ,
497+ ) -> Result < ( ) , Error > {
498+ let msg = msg. into ( ) ;
499+ unsafe {
500+ if ffi:: secp256k1_ecdsa_verify (
501+ self . ctx . as_ptr ( ) ,
502+ sig. as_c_ptr ( ) ,
503+ msg. as_c_ptr ( ) ,
504+ pk. as_c_ptr ( ) ,
505+ ) == 0
506+ {
507+ Err ( Error :: IncorrectSignature )
508+ } else {
509+ Ok ( ( ) )
510+ }
511+ }
512+ }
513+ }
514+
344515/// Checks that `sig` is a valid ECDSA signature for `msg` using the public
345516/// key `pubkey`. Returns `Ok(())` on success. Note that this function cannot
346517/// be used for Bitcoin consensus checking since there may exist signatures
0 commit comments