From 0d857533fae812c19e8c0d4f0f11e85a525fade2 Mon Sep 17 00:00:00 2001 From: Sebastian Geisler Date: Tue, 7 Apr 2020 22:43:53 +0200 Subject: [PATCH] Add optional bitcoin_hashes feature to implement ThirtyTwoByteHash --- .travis.yml | 2 ++ Cargo.toml | 4 ++++ src/lib.rs | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) diff --git a/.travis.yml b/.travis.yml index 7f75076..5030a8b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,6 +30,7 @@ script: cargo generate-lockfile --verbose && cargo update -p cc --precise "1.0.41" --verbose; fi - cargo build --verbose --no-default-features + - cargo build --verbose --no-default-features --features="bitcoin_hashes" - cargo build --verbose --no-default-features --features="serde" - cargo build --verbose --no-default-features --features="lowmemory" - cargo build --verbose --no-default-features --features="rand" @@ -37,6 +38,7 @@ script: - cargo build --verbose --no-default-features --features="fuzztarget recovery" - cargo build --verbose --features=rand - cargo test --no-run --features=fuzztarget + - cargo test --verbose --features="bitcoin_hashes" - cargo test --verbose --features=rand - cargo test --verbose --features="rand rand-std" - cargo test --verbose --features="rand serde" diff --git a/Cargo.toml b/Cargo.toml index 05ee0d0..3314622 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,6 +50,10 @@ bitcoin_hashes = "0.7" wasm-bindgen-test = "0.3" rand = { version = "0.6", features = ["wasm-bindgen"] } +[dependencies.bitcoin_hashes] +version = "0.7" +optional = true + [dependencies.rand] version = "0.6" optional = true diff --git a/src/lib.rs b/src/lib.rs index 92c9a91..1a66ecd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -147,6 +147,7 @@ pub extern crate secp256k1_sys; pub use secp256k1_sys as ffi; +#[cfg(feature = "bitcoin_hashes")] extern crate bitcoin_hashes; #[cfg(all(test, feature = "unstable"))] extern crate test; #[cfg(any(test, feature = "rand"))] pub extern crate rand; #[cfg(any(test))] extern crate rand_core; @@ -173,6 +174,9 @@ use core::marker::PhantomData; use core::ops::Deref; use ffi::CPtr; +#[cfg(feature = "bitcoin_hashes")] +use bitcoin_hashes::Hash; + /// An ECDSA signature #[derive(Copy, Clone, PartialEq, Eq)] pub struct Signature(ffi::Signature); @@ -219,6 +223,27 @@ pub trait ThirtyTwoByteHash { fn into_32(self) -> [u8; 32]; } +#[cfg(feature = "bitcoin_hashes")] +impl ThirtyTwoByteHash for bitcoin_hashes::sha256::Hash { + fn into_32(self) -> [u8; 32] { + self.into_inner() + } +} + +#[cfg(feature = "bitcoin_hashes")] +impl ThirtyTwoByteHash for bitcoin_hashes::sha256d::Hash { + fn into_32(self) -> [u8; 32] { + self.into_inner() + } +} + +#[cfg(feature = "bitcoin_hashes")] +impl ThirtyTwoByteHash for bitcoin_hashes::sha256t::Hash { + fn into_32(self) -> [u8; 32] { + self.into_inner() + } +} + impl SerializedSignature { /// Get a pointer to the underlying data with the specified capacity. pub(crate) fn get_data_mut_ptr(&mut self) -> *mut u8 { @@ -467,6 +492,24 @@ impl Message { _ => Err(Error::InvalidMessage) } } + + /// Constructs a `Message` by hashing `data` with hash algorithm `H`. + /// ```rust + /// extern crate bitcoin_hashes; + /// use secp256k1::Message; + /// use bitcoin_hashes::sha256; + /// use bitcoin_hashes::Hash; + /// + /// let m1 = Message::from_hashed_data::("Hello world!".as_bytes()); + /// // is equivalent to + /// let m2 = Message::from(sha256::Hash::hash("Hello world!".as_bytes())); + /// + /// assert_eq!(m1, m2); + /// ``` + #[cfg(feature = "bitcoin_hashes")] + pub fn from_hashed_data(data: &[u8]) -> Self { + ::hash(data).into() + } } impl From for Message { @@ -1110,6 +1153,31 @@ mod tests { test_bad_slice(); test_low_s(); } + + #[cfg(feature = "bitcoin_hashes")] + #[test] + fn test_from_hash() { + use bitcoin_hashes; + use bitcoin_hashes::Hash; + + let test_bytes = "Hello world!".as_bytes(); + + let hash = bitcoin_hashes::sha256::Hash::hash(test_bytes); + let msg = Message::from(hash); + assert_eq!(msg.0, hash.into_inner()); + assert_eq!( + msg, + Message::from_hashed_data::(test_bytes) + ); + + let hash = bitcoin_hashes::sha256d::Hash::hash(test_bytes); + let msg = Message::from(hash); + assert_eq!(msg.0, hash.into_inner()); + assert_eq!( + msg, + Message::from_hashed_data::(test_bytes) + ); + } } #[cfg(all(test, feature = "unstable"))]