147147pub extern crate secp256k1_sys;
148148pub use secp256k1_sys as ffi;
149149
150+ #[ cfg( feature = "bitcoin_hashes" ) ] extern crate bitcoin_hashes;
150151#[ cfg( all( test, feature = "unstable" ) ) ] extern crate test;
151152#[ cfg( any( test, feature = "rand" ) ) ] pub extern crate rand;
152153#[ cfg( any( test) ) ] extern crate rand_core;
@@ -173,6 +174,9 @@ use core::marker::PhantomData;
173174use core:: ops:: Deref ;
174175use ffi:: CPtr ;
175176
177+ #[ cfg( feature = "bitcoin_hashes" ) ]
178+ use bitcoin_hashes:: Hash ;
179+
176180/// An ECDSA signature
177181#[ derive( Copy , Clone , PartialEq , Eq ) ]
178182pub struct Signature ( ffi:: Signature ) ;
@@ -219,6 +223,27 @@ pub trait ThirtyTwoByteHash {
219223 fn into_32 ( self ) -> [ u8 ; 32 ] ;
220224}
221225
226+ #[ cfg( feature = "bitcoin_hashes" ) ]
227+ impl ThirtyTwoByteHash for bitcoin_hashes:: sha256:: Hash {
228+ fn into_32 ( self ) -> [ u8 ; 32 ] {
229+ self . into_inner ( )
230+ }
231+ }
232+
233+ #[ cfg( feature = "bitcoin_hashes" ) ]
234+ impl ThirtyTwoByteHash for bitcoin_hashes:: sha256d:: Hash {
235+ fn into_32 ( self ) -> [ u8 ; 32 ] {
236+ self . into_inner ( )
237+ }
238+ }
239+
240+ #[ cfg( feature = "bitcoin_hashes" ) ]
241+ impl < T : bitcoin_hashes:: sha256t:: Tag > ThirtyTwoByteHash for bitcoin_hashes:: sha256t:: Hash < T > {
242+ fn into_32 ( self ) -> [ u8 ; 32 ] {
243+ self . into_inner ( )
244+ }
245+ }
246+
222247impl SerializedSignature {
223248 /// Get a pointer to the underlying data with the specified capacity.
224249 pub ( crate ) fn get_data_mut_ptr ( & mut self ) -> * mut u8 {
@@ -467,6 +492,24 @@ impl Message {
467492 _ => Err ( Error :: InvalidMessage )
468493 }
469494 }
495+
496+ /// Constructs a `Message` by hashing `data` with hash algorithm `H`.
497+ /// ```rust
498+ /// extern crate bitcoin_hashes;
499+ /// use secp256k1::Message;
500+ /// use bitcoin_hashes::sha256;
501+ /// use bitcoin_hashes::Hash;
502+ ///
503+ /// let m1 = Message::from_hashed_data::<sha256::Hash>("Hello world!".as_bytes());
504+ /// // is equivalent to
505+ /// let m2 = Message::from(sha256::Hash::hash("Hello world!".as_bytes()));
506+ ///
507+ /// assert_eq!(m1, m2);
508+ /// ```
509+ #[ cfg( feature = "bitcoin_hashes" ) ]
510+ pub fn from_hashed_data < H : ThirtyTwoByteHash + bitcoin_hashes:: Hash > ( data : & [ u8 ] ) -> Self {
511+ <H as bitcoin_hashes:: Hash >:: hash ( data) . into ( )
512+ }
470513}
471514
472515impl < T : ThirtyTwoByteHash > From < T > for Message {
@@ -1110,6 +1153,31 @@ mod tests {
11101153 test_bad_slice ( ) ;
11111154 test_low_s ( ) ;
11121155 }
1156+
1157+ #[ cfg( feature = "bitcoin_hashes" ) ]
1158+ #[ test]
1159+ fn test_from_hash ( ) {
1160+ use bitcoin_hashes;
1161+ use bitcoin_hashes:: Hash ;
1162+
1163+ let test_bytes = "Hello world!" . as_bytes ( ) ;
1164+
1165+ let hash = bitcoin_hashes:: sha256:: Hash :: hash ( test_bytes) ;
1166+ let msg = Message :: from ( hash) ;
1167+ assert_eq ! ( msg. 0 , hash. into_inner( ) ) ;
1168+ assert_eq ! (
1169+ msg,
1170+ Message :: from_hashed_data:: <bitcoin_hashes:: sha256:: Hash >( test_bytes)
1171+ ) ;
1172+
1173+ let hash = bitcoin_hashes:: sha256d:: Hash :: hash ( test_bytes) ;
1174+ let msg = Message :: from ( hash) ;
1175+ assert_eq ! ( msg. 0 , hash. into_inner( ) ) ;
1176+ assert_eq ! (
1177+ msg,
1178+ Message :: from_hashed_data:: <bitcoin_hashes:: sha256d:: Hash >( test_bytes)
1179+ ) ;
1180+ }
11131181}
11141182
11151183#[ cfg( all( test, feature = "unstable" ) ) ]
0 commit comments