Skip to content

Commit

Permalink
Add optional bitcoin_hashes feature to implement ThirtyTwoByteHash
Browse files Browse the repository at this point in the history
  • Loading branch information
sgeisler committed Apr 8, 2020
1 parent 9aa768d commit c905de2
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Expand Up @@ -22,13 +22,15 @@ 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"
- cargo build --verbose --no-default-features --features="rand serde recovery endomorphism"
- 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"
Expand Down
4 changes: 4 additions & 0 deletions Cargo.toml
Expand Up @@ -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
Expand Down
69 changes: 69 additions & 0 deletions src/lib.rs
Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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<T: bitcoin_hashes::sha256t::Tag> ThirtyTwoByteHash for bitcoin_hashes::sha256t::Hash<T> {
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 {
Expand Down Expand Up @@ -467,6 +492,25 @@ 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::<sha256::Hash>("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<H: ThirtyTwoByteHash + bitcoin_hashes::Hash>(data: &[u8]) -> Self {
let hash: H = bitcoin_hashes::Hash::hash(data);
Message::from(hash)
}
}

impl<T: ThirtyTwoByteHash> From<T> for Message {
Expand Down Expand Up @@ -1060,6 +1104,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::<bitcoin_hashes::sha256::Hash>(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::<bitcoin_hashes::sha256d::Hash>(test_bytes)
);
}
}

#[cfg(all(test, feature = "unstable"))]
Expand Down

0 comments on commit c905de2

Please sign in to comment.