From 80dd5ec98465186d25c4b6118ee58b0cc20e2241 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 | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/.travis.yml b/.travis.yml index 15302cf13..db01f4fa0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,6 +22,7 @@ matrix: script: - 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" @@ -29,6 +30,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 d93d7f07c..9ccdb3120 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,6 +46,10 @@ rand_core = "0.4" serde_test = "1.0" bitcoin_hashes = "0.7" +[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 5e66c46e5..69fd29fc4 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,13 @@ impl Message { _ => Err(Error::InvalidMessage) } } + + /// Constructs a `Message` by hashing `data` with hash algorithm `H` + #[cfg(feature = "bitcoin_hashes")] + pub fn from_hashed_data(data: &[u8]) -> Self { + let hash: H = bitcoin_hashes::Hash::hash(data); + Message::from(hash) + } } impl From for Message { @@ -1060,6 +1092,31 @@ mod tests { assert_tokens(&sig.compact(), &[Token::BorrowedBytes(&SIG_BYTES[..])]); assert_tokens(&sig.readable(), &[Token::BorrowedStr(SIG_STR)]); } + + #[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"))]