Skip to content

Commit 14b964c

Browse files
committed
Merge #493: Add method SecretKey::from_hashed_data
5417fad Add method SecretKey::from_hashed_data (Tobin C. Harding) Pull request description: Analogous to the method on `Message`; add a constructor method on `SecretKey` that hashes the input data. While we are at it improve the rustdocs on `Message::from_hashed_data` so docs on both methods are uniform. Fix: #487 ACKs for top commit: apoelstra: ACK 5417fad Tree-SHA512: d321c1e8fddaf5ee692a7f119d86749ea4c8b4f3796f06e8c6145aa03bc22f5c88992e193dd34aa7ba3da8a45cf8f60e72f61e415a092ad16d2bd8c2b6c8fa23
2 parents 15a8c20 + 5417fad commit 14b964c

File tree

2 files changed

+46
-7
lines changed

2 files changed

+46
-7
lines changed

src/key.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ use crate::Error::{self, InvalidPublicKey, InvalidPublicKeySum, InvalidSecretKey
2525
use crate::ffi::{self, CPtr, impl_array_newtype};
2626
use crate::ffi::types::c_uint;
2727

28+
#[cfg(feature = "bitcoin_hashes")]
29+
use crate::{hashes, ThirtyTwoByteHash};
30+
2831
#[cfg(feature = "serde")]
2932
use serde::ser::SerializeTuple;
3033

@@ -228,6 +231,31 @@ impl SecretKey {
228231
SecretKey(sk)
229232
}
230233

234+
/// Constructs a [`SecretKey`] by hashing `data` with hash algorithm `H`.
235+
///
236+
/// Requires the feature `bitcoin_hashes` to be enabled.
237+
///
238+
/// # Examples
239+
///
240+
/// ```
241+
/// # #[cfg(feature="bitcoin_hashes")] {
242+
/// use secp256k1::hashes::{sha256, Hash};
243+
/// use secp256k1::SecretKey;
244+
///
245+
/// let sk1 = SecretKey::from_hashed_data::<sha256::Hash>("Hello world!".as_bytes());
246+
/// // is equivalent to
247+
/// let sk2 = SecretKey::from(sha256::Hash::hash("Hello world!".as_bytes()));
248+
///
249+
/// assert_eq!(sk1, sk2);
250+
/// # }
251+
/// ```
252+
#[cfg(feature = "bitcoin_hashes")]
253+
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoin_hashes")))]
254+
#[inline]
255+
pub fn from_hashed_data<H: ThirtyTwoByteHash + hashes::Hash>(data: &[u8]) -> Self {
256+
<H as hashes::Hash>::hash(data).into()
257+
}
258+
231259
/// Returns the secret key as a byte value.
232260
#[inline]
233261
pub fn secret_bytes(&self) -> [u8; constants::SECRET_KEY_SIZE] {
@@ -352,6 +380,14 @@ impl SecretKey {
352380
}
353381
}
354382

383+
#[cfg(feature = "bitcoin_hashes")]
384+
impl<T: ThirtyTwoByteHash> From<T> for SecretKey {
385+
/// Converts a 32-byte hash directly to a secret key without error paths.
386+
fn from(t: T) -> SecretKey {
387+
SecretKey::from_slice(&t.into_32()).expect("failed to create secret key")
388+
}
389+
}
390+
355391
#[cfg(feature = "serde")]
356392
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
357393
impl serde::Serialize for SecretKey {

src/lib.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -281,20 +281,23 @@ impl Message {
281281
}
282282
}
283283

284-
/// Constructs a `Message` by hashing `data` with hash algorithm `H`. This requires the feature
285-
/// `bitcoin_hashes` to be enabled.
286-
/// ```rust
287-
/// extern crate bitcoin_hashes;
288-
/// # extern crate secp256k1;
284+
/// Constructs a [`Message`] by hashing `data` with hash algorithm `H`.
285+
///
286+
/// Requires the feature `bitcoin_hashes` to be enabled.
287+
///
288+
/// # Examples
289+
///
290+
/// ```
291+
/// # #[cfg(feature="bitcoin_hashes")] {
292+
/// use secp256k1::hashes::{sha256, Hash};
289293
/// use secp256k1::Message;
290-
/// use bitcoin_hashes::sha256;
291-
/// use bitcoin_hashes::Hash;
292294
///
293295
/// let m1 = Message::from_hashed_data::<sha256::Hash>("Hello world!".as_bytes());
294296
/// // is equivalent to
295297
/// let m2 = Message::from(sha256::Hash::hash("Hello world!".as_bytes()));
296298
///
297299
/// assert_eq!(m1, m2);
300+
/// # }
298301
/// ```
299302
#[cfg(feature = "bitcoin_hashes")]
300303
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoin_hashes")))]

0 commit comments

Comments
 (0)