Skip to content

Commit 00b66df

Browse files
committed
Stop implementing ThirtyTwoByteHash
The implementations of `ThirtyTwoByteHash` for types from the `hashes` crate are problematic during upgrades because both `bitcoin` and `secp256k1` depend on `hashes` and when the versions of `hashes` get out of sync usage of the trait breaks. - Deprecate `ThirtyTwoByteHash` - Remove the two `from_hashed_data` functions
1 parent b370f67 commit 00b66df

7 files changed

+6
-126
lines changed

api/all-features.txt

-12
Original file line numberDiff line numberDiff line change
@@ -519,8 +519,6 @@ impl secp256k1_sys::CPtr for secp256k1::PublicKey
519519
impl secp256k1_sys::CPtr for secp256k1::schnorr::Signature
520520
impl secp256k1_sys::CPtr for secp256k1::SecretKey
521521
impl secp256k1_sys::CPtr for secp256k1::XOnlyPublicKey
522-
impl secp256k1::ThirtyTwoByteHash for bitcoin_hashes::sha256d::Hash
523-
impl secp256k1::ThirtyTwoByteHash for bitcoin_hashes::sha256::Hash
524522
impl secp256k1::Verification for secp256k1::All
525523
impl secp256k1::Verification for secp256k1::VerifyOnly
526524
impl secp256k1::XOnlyPublicKey
@@ -532,9 +530,6 @@ impl serde::ser::Serialize for secp256k1::PublicKey
532530
impl serde::ser::Serialize for secp256k1::schnorr::Signature
533531
impl serde::ser::Serialize for secp256k1::SecretKey
534532
impl serde::ser::Serialize for secp256k1::XOnlyPublicKey
535-
impl<T: bitcoin_hashes::sha256t::Tag> secp256k1::ThirtyTwoByteHash for bitcoin_hashes::sha256t::Hash<T>
536-
impl<T: secp256k1::ThirtyTwoByteHash> core::convert::From<T> for secp256k1::Message
537-
impl<T: secp256k1::ThirtyTwoByteHash> core::convert::From<T> for secp256k1::SecretKey
538533
#[non_exhaustive] pub struct secp256k1::scalar::OutOfRangeError
539534
pub const fn secp256k1::ellswift::ElligatorSwiftSharedSecret::as_secret_bytes(&self) -> &[u8; 32]
540535
pub const fn secp256k1::ellswift::ElligatorSwiftSharedSecret::from_secret_bytes(bytes: [u8; 32]) -> Self
@@ -580,9 +575,6 @@ pub enum secp256k1::SignOnly
580575
pub enum secp256k1::VerifyOnly
581576
pub extern crate secp256k1::hashes
582577
pub fn &'a secp256k1::ecdsa::serialized_signature::SerializedSignature::into_iter(self) -> Self::IntoIter
583-
pub fn bitcoin_hashes::sha256d::Hash::into_32(self) -> [u8; 32]
584-
pub fn bitcoin_hashes::sha256::Hash::into_32(self) -> [u8; 32]
585-
pub fn bitcoin_hashes::sha256t::Hash<T>::into_32(self) -> [u8; 32]
586578
pub fn i32::from(parity: secp256k1::Parity) -> i32
587579
pub fn secp256k1::All::clone(&self) -> secp256k1::All
588580
pub fn secp256k1::All::cmp(&self, other: &secp256k1::All) -> core::cmp::Ordering
@@ -772,9 +764,7 @@ pub fn secp256k1::Message::eq(&self, other: &secp256k1::Message) -> bool
772764
pub fn secp256k1::Message::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
773765
pub fn secp256k1::Message::from_digest(digest: [u8; 32]) -> secp256k1::Message
774766
pub fn secp256k1::Message::from_digest_slice(digest: &[u8]) -> core::result::Result<secp256k1::Message, secp256k1::Error>
775-
pub fn secp256k1::Message::from_hashed_data<H: secp256k1::ThirtyTwoByteHash + bitcoin_hashes::Hash>(data: &[u8]) -> Self
776767
pub fn secp256k1::Message::from_slice(digest: &[u8]) -> core::result::Result<secp256k1::Message, secp256k1::Error>
777-
pub fn secp256k1::Message::from(t: T) -> secp256k1::Message
778768
pub fn secp256k1::Message::hash<__H: core::hash::Hasher>(&self, state: &mut __H)
779769
pub fn secp256k1::Message::index(&self, index: I) -> &Self::Output
780770
pub fn secp256k1::Message::partial_cmp(&self, other: &secp256k1::Message) -> core::option::Option<core::cmp::Ordering>
@@ -904,13 +894,11 @@ pub fn secp256k1::SecretKey::deserialize<D: serde::de::Deserializer<'de>>(d: D)
904894
pub fn secp256k1::SecretKey::display_secret(&self) -> DisplaySecret
905895
pub fn secp256k1::SecretKey::eq(&self, other: &Self) -> bool
906896
pub fn secp256k1::SecretKey::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
907-
pub fn secp256k1::SecretKey::from_hashed_data<H: secp256k1::ThirtyTwoByteHash + bitcoin_hashes::Hash>(data: &[u8]) -> Self
908897
pub fn secp256k1::SecretKey::from_keypair(keypair: &secp256k1::Keypair) -> Self
909898
pub fn secp256k1::SecretKey::from(pair: &'a secp256k1::Keypair) -> Self
910899
pub fn secp256k1::SecretKey::from(pair: secp256k1::Keypair) -> Self
911900
pub fn secp256k1::SecretKey::from_slice(data: &[u8]) -> core::result::Result<secp256k1::SecretKey, secp256k1::Error>
912901
pub fn secp256k1::SecretKey::from_str(s: &str) -> core::result::Result<secp256k1::SecretKey, secp256k1::Error>
913-
pub fn secp256k1::SecretKey::from(t: T) -> secp256k1::SecretKey
914902
pub fn secp256k1::SecretKey::index(&self, index: I) -> &Self::Output
915903
pub fn secp256k1::SecretKey::keypair<C: secp256k1::Signing>(&self, secp: &secp256k1::Secp256k1<C>) -> secp256k1::Keypair
916904
pub fn secp256k1::SecretKey::mul_tweak(self, tweak: &secp256k1::scalar::Scalar) -> core::result::Result<secp256k1::SecretKey, secp256k1::Error>

api/alloc.txt

-2
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,6 @@ impl secp256k1_sys::CPtr for secp256k1::XOnlyPublicKey
468468
impl secp256k1::Verification for secp256k1::All
469469
impl secp256k1::Verification for secp256k1::VerifyOnly
470470
impl secp256k1::XOnlyPublicKey
471-
impl<T: secp256k1::ThirtyTwoByteHash> core::convert::From<T> for secp256k1::Message
472471
#[non_exhaustive] pub struct secp256k1::scalar::OutOfRangeError
473472
pub const fn secp256k1::ellswift::ElligatorSwiftSharedSecret::as_secret_bytes(&self) -> &[u8; 32]
474473
pub const fn secp256k1::ellswift::ElligatorSwiftSharedSecret::from_secret_bytes(bytes: [u8; 32]) -> Self
@@ -665,7 +664,6 @@ pub fn secp256k1::Message::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core:
665664
pub fn secp256k1::Message::from_digest(digest: [u8; 32]) -> secp256k1::Message
666665
pub fn secp256k1::Message::from_digest_slice(digest: &[u8]) -> core::result::Result<secp256k1::Message, secp256k1::Error>
667666
pub fn secp256k1::Message::from_slice(digest: &[u8]) -> core::result::Result<secp256k1::Message, secp256k1::Error>
668-
pub fn secp256k1::Message::from(t: T) -> secp256k1::Message
669667
pub fn secp256k1::Message::hash<__H: core::hash::Hasher>(&self, state: &mut __H)
670668
pub fn secp256k1::Message::index(&self, index: I) -> &Self::Output
671669
pub fn secp256k1::Message::partial_cmp(&self, other: &secp256k1::Message) -> core::option::Option<core::cmp::Ordering>

api/default-features.txt

-2
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,6 @@ impl secp256k1_sys::CPtr for secp256k1::XOnlyPublicKey
471471
impl secp256k1::Verification for secp256k1::All
472472
impl secp256k1::Verification for secp256k1::VerifyOnly
473473
impl secp256k1::XOnlyPublicKey
474-
impl<T: secp256k1::ThirtyTwoByteHash> core::convert::From<T> for secp256k1::Message
475474
#[non_exhaustive] pub struct secp256k1::scalar::OutOfRangeError
476475
pub const fn secp256k1::ellswift::ElligatorSwiftSharedSecret::as_secret_bytes(&self) -> &[u8; 32]
477476
pub const fn secp256k1::ellswift::ElligatorSwiftSharedSecret::from_secret_bytes(bytes: [u8; 32]) -> Self
@@ -669,7 +668,6 @@ pub fn secp256k1::Message::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core:
669668
pub fn secp256k1::Message::from_digest(digest: [u8; 32]) -> secp256k1::Message
670669
pub fn secp256k1::Message::from_digest_slice(digest: &[u8]) -> core::result::Result<secp256k1::Message, secp256k1::Error>
671670
pub fn secp256k1::Message::from_slice(digest: &[u8]) -> core::result::Result<secp256k1::Message, secp256k1::Error>
672-
pub fn secp256k1::Message::from(t: T) -> secp256k1::Message
673671
pub fn secp256k1::Message::hash<__H: core::hash::Hasher>(&self, state: &mut __H)
674672
pub fn secp256k1::Message::index(&self, index: I) -> &Self::Output
675673
pub fn secp256k1::Message::partial_cmp(&self, other: &secp256k1::Message) -> core::option::Option<core::cmp::Ordering>

api/global-context.txt

-2
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,6 @@ impl secp256k1_sys::CPtr for secp256k1::XOnlyPublicKey
481481
impl secp256k1::Verification for secp256k1::All
482482
impl secp256k1::Verification for secp256k1::VerifyOnly
483483
impl secp256k1::XOnlyPublicKey
484-
impl<T: secp256k1::ThirtyTwoByteHash> core::convert::From<T> for secp256k1::Message
485484
#[non_exhaustive] pub struct secp256k1::scalar::OutOfRangeError
486485
pub const fn secp256k1::ellswift::ElligatorSwiftSharedSecret::as_secret_bytes(&self) -> &[u8; 32]
487486
pub const fn secp256k1::ellswift::ElligatorSwiftSharedSecret::from_secret_bytes(bytes: [u8; 32]) -> Self
@@ -684,7 +683,6 @@ pub fn secp256k1::Message::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core:
684683
pub fn secp256k1::Message::from_digest(digest: [u8; 32]) -> secp256k1::Message
685684
pub fn secp256k1::Message::from_digest_slice(digest: &[u8]) -> core::result::Result<secp256k1::Message, secp256k1::Error>
686685
pub fn secp256k1::Message::from_slice(digest: &[u8]) -> core::result::Result<secp256k1::Message, secp256k1::Error>
687-
pub fn secp256k1::Message::from(t: T) -> secp256k1::Message
688686
pub fn secp256k1::Message::hash<__H: core::hash::Hasher>(&self, state: &mut __H)
689687
pub fn secp256k1::Message::index(&self, index: I) -> &Self::Output
690688
pub fn secp256k1::Message::partial_cmp(&self, other: &secp256k1::Message) -> core::option::Option<core::cmp::Ordering>

api/no-default-features.txt

-2
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,6 @@ impl secp256k1_sys::CPtr for secp256k1::schnorr::Signature
411411
impl secp256k1_sys::CPtr for secp256k1::SecretKey
412412
impl secp256k1_sys::CPtr for secp256k1::XOnlyPublicKey
413413
impl secp256k1::XOnlyPublicKey
414-
impl<T: secp256k1::ThirtyTwoByteHash> core::convert::From<T> for secp256k1::Message
415414
#[non_exhaustive] pub struct secp256k1::scalar::OutOfRangeError
416415
pub const fn secp256k1::ellswift::ElligatorSwiftSharedSecret::as_secret_bytes(&self) -> &[u8; 32]
417416
pub const fn secp256k1::ellswift::ElligatorSwiftSharedSecret::from_secret_bytes(bytes: [u8; 32]) -> Self
@@ -593,7 +592,6 @@ pub fn secp256k1::Message::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core:
593592
pub fn secp256k1::Message::from_digest(digest: [u8; 32]) -> secp256k1::Message
594593
pub fn secp256k1::Message::from_digest_slice(digest: &[u8]) -> core::result::Result<secp256k1::Message, secp256k1::Error>
595594
pub fn secp256k1::Message::from_slice(digest: &[u8]) -> core::result::Result<secp256k1::Message, secp256k1::Error>
596-
pub fn secp256k1::Message::from(t: T) -> secp256k1::Message
597595
pub fn secp256k1::Message::hash<__H: core::hash::Hasher>(&self, state: &mut __H)
598596
pub fn secp256k1::Message::index(&self, index: I) -> &Self::Output
599597
pub fn secp256k1::Message::partial_cmp(&self, other: &secp256k1::Message) -> core::option::Option<core::cmp::Ordering>

src/key.rs

-34
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ use crate::SECP256K1;
1919
use crate::{
2020
constants, ecdsa, from_hex, schnorr, Message, Scalar, Secp256k1, Signing, Verification,
2121
};
22-
#[cfg(feature = "hashes")]
23-
use crate::{hashes, ThirtyTwoByteHash};
2422

2523
/// Secret key - a 256-bit key used to create ECDSA and Taproot signatures.
2624
///
@@ -257,30 +255,6 @@ impl SecretKey {
257255
SecretKey(sk)
258256
}
259257

260-
/// Constructs a [`SecretKey`] by hashing `data` with hash algorithm `H`.
261-
///
262-
/// Requires the feature `hashes` to be enabled.
263-
///
264-
/// # Examples
265-
///
266-
/// ```
267-
/// # #[cfg(feature="hashes")] {
268-
/// use secp256k1::hashes::{sha256, Hash};
269-
/// use secp256k1::SecretKey;
270-
///
271-
/// let sk1 = SecretKey::from_hashed_data::<sha256::Hash>("Hello world!".as_bytes());
272-
/// // is equivalent to
273-
/// let sk2 = SecretKey::from(sha256::Hash::hash("Hello world!".as_bytes()));
274-
///
275-
/// assert_eq!(sk1, sk2);
276-
/// # }
277-
/// ```
278-
#[cfg(feature = "hashes")]
279-
#[inline]
280-
pub fn from_hashed_data<H: ThirtyTwoByteHash + hashes::Hash>(data: &[u8]) -> Self {
281-
<H as hashes::Hash>::hash(data).into()
282-
}
283-
284258
/// Returns the secret key as a byte value.
285259
#[inline]
286260
pub fn secret_bytes(&self) -> [u8; constants::SECRET_KEY_SIZE] { self.0 }
@@ -372,14 +346,6 @@ impl SecretKey {
372346
}
373347
}
374348

375-
#[cfg(feature = "hashes")]
376-
impl<T: ThirtyTwoByteHash> From<T> for SecretKey {
377-
/// Converts a 32-byte hash directly to a secret key without error paths.
378-
fn from(t: T) -> SecretKey {
379-
SecretKey::from_slice(&t.into_32()).expect("failed to create secret key")
380-
}
381-
}
382-
383349
#[cfg(feature = "serde")]
384350
impl serde::Serialize for SecretKey {
385351
fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {

src/lib.rs

+6-72
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@
3131
//! # #[cfg(all(feature = "rand-std", feature = "hashes-std"))] {
3232
//! use secp256k1::rand::rngs::OsRng;
3333
//! use secp256k1::{Secp256k1, Message};
34-
//! use secp256k1::hashes::sha256;
34+
//! use secp256k1::hashes::{sha256, Hash};
3535
//!
3636
//! let secp = Secp256k1::new();
3737
//! let (secret_key, public_key) = secp.generate_keypair(&mut OsRng);
38-
//! let message = Message::from_hashed_data::<sha256::Hash>("Hello World!".as_bytes());
38+
//! let message = Message::from_digest(sha256::Hash::hash("Hello world!".as_bytes()).to_byte_array());
3939
//!
4040
//! let sig = secp.sign_ecdsa(&message, &secret_key);
4141
//! assert!(secp.verify_ecdsa(&message, &sig, &public_key).is_ok());
@@ -47,10 +47,10 @@
4747
//! ```rust
4848
//! # #[cfg(all(feature = "global-context", feature = "hashes-std", feature = "rand-std"))] {
4949
//! use secp256k1::{generate_keypair, Message};
50-
//! use secp256k1::hashes::sha256;
50+
//! use secp256k1::hashes::{sha256, Hash};
5151
//!
5252
//! let (secret_key, public_key) = generate_keypair(&mut rand::thread_rng());
53-
//! let message = Message::from_hashed_data::<sha256::Hash>("Hello World!".as_bytes());
53+
//! let message = Message::from_digest(sha256::Hash::hash("Hello world!".as_bytes()).to_byte_array());
5454
//!
5555
//! let sig = secret_key.sign_ecdsa(message);
5656
//! assert!(sig.verify(&message, &public_key).is_ok());
@@ -176,8 +176,6 @@ use core::{fmt, mem, str};
176176

177177
#[cfg(all(feature = "global-context", feature = "std"))]
178178
pub use context::global::{self, SECP256K1};
179-
#[cfg(feature = "hashes")]
180-
use hashes::Hash;
181179
#[cfg(feature = "rand")]
182180
pub use rand;
183181
pub use secp256k1_sys as ffi;
@@ -198,34 +196,20 @@ pub use crate::scalar::Scalar;
198196
/// Trait describing something that promises to be a 32-byte random number; in particular,
199197
/// it has negligible probability of being zero or overflowing the group order. Such objects
200198
/// may be converted to `Message`s without any error paths.
199+
#[deprecated(since = "0.29.0", note = "this will be removed soon")]
201200
pub trait ThirtyTwoByteHash {
202201
/// Converts the object into a 32-byte array
203202
fn into_32(self) -> [u8; 32];
204203
}
205204

206-
#[cfg(feature = "hashes")]
207-
impl ThirtyTwoByteHash for hashes::sha256::Hash {
208-
fn into_32(self) -> [u8; 32] { self.to_byte_array() }
209-
}
210-
211-
#[cfg(feature = "hashes")]
212-
impl ThirtyTwoByteHash for hashes::sha256d::Hash {
213-
fn into_32(self) -> [u8; 32] { self.to_byte_array() }
214-
}
215-
216-
#[cfg(feature = "hashes")]
217-
impl<T: hashes::sha256t::Tag> ThirtyTwoByteHash for hashes::sha256t::Hash<T> {
218-
fn into_32(self) -> [u8; 32] { self.to_byte_array() }
219-
}
220-
221205
/// A (hashed) message input to an ECDSA signature.
222206
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
223207
pub struct Message([u8; constants::MESSAGE_SIZE]);
224208
impl_array_newtype!(Message, u8, constants::MESSAGE_SIZE);
225209
impl_pretty_debug!(Message);
226210

227211
impl Message {
228-
/// **If you just want to sign an arbitrary message use `Message::from_hashed_data` instead.**
212+
/// Creates a [`Message`] from a 32 byte slice `digest`.
229213
///
230214
/// Converts a `MESSAGE_SIZE`-byte slice to a message object. **WARNING:** the slice has to be a
231215
/// cryptographically secure hash of the actual message that's going to be signed. Otherwise
@@ -239,8 +223,6 @@ impl Message {
239223

240224
/// Creates a [`Message`] from a `digest`.
241225
///
242-
/// **If you just want to sign an arbitrary message use `Message::from_hashed_data` instead.**
243-
///
244226
/// The `digest` array has to be a cryptographically secure hash of the actual message that's
245227
/// going to be signed. Otherwise the result of signing isn't a [secure signature].
246228
///
@@ -250,8 +232,6 @@ impl Message {
250232

251233
/// Creates a [`Message`] from a 32 byte slice `digest`.
252234
///
253-
/// **If you just want to sign an arbitrary message use `Message::from_hashed_data` instead.**
254-
///
255235
/// The slice has to be 32 bytes long and be a cryptographically secure hash of the actual
256236
/// message that's going to be signed. Otherwise the result of signing isn't a [secure
257237
/// signature].
@@ -272,34 +252,6 @@ impl Message {
272252
_ => Err(Error::InvalidMessage),
273253
}
274254
}
275-
276-
/// Constructs a [`Message`] by hashing `data` with hash algorithm `H`.
277-
///
278-
/// Requires the feature `hashes` to be enabled.
279-
///
280-
/// # Examples
281-
///
282-
/// ```
283-
/// # #[cfg(feature = "hashes")] {
284-
/// use secp256k1::hashes::{sha256, Hash};
285-
/// use secp256k1::Message;
286-
///
287-
/// let m1 = Message::from_hashed_data::<sha256::Hash>("Hello world!".as_bytes());
288-
/// // is equivalent to
289-
/// let m2 = Message::from(sha256::Hash::hash("Hello world!".as_bytes()));
290-
///
291-
/// assert_eq!(m1, m2);
292-
/// # }
293-
/// ```
294-
#[cfg(feature = "hashes")]
295-
pub fn from_hashed_data<H: ThirtyTwoByteHash + hashes::Hash>(data: &[u8]) -> Self {
296-
<H as hashes::Hash>::hash(data).into()
297-
}
298-
}
299-
300-
impl<T: ThirtyTwoByteHash> From<T> for Message {
301-
/// Converts a 32-byte hash directly to a message without error paths.
302-
fn from(t: T) -> Message { Message(t.into_32()) }
303255
}
304256

305257
impl fmt::LowerHex for Message {
@@ -1043,24 +995,6 @@ mod tests {
1043995
let sig = SECP256K1.sign_ecdsa(&msg, &sk);
1044996
assert!(SECP256K1.verify_ecdsa(&msg, &sig, &pk).is_ok());
1045997
}
1046-
1047-
#[cfg(feature = "hashes")]
1048-
#[test]
1049-
fn test_from_hash() {
1050-
use hashes::{sha256, sha256d, Hash};
1051-
1052-
let test_bytes = "Hello world!".as_bytes();
1053-
1054-
let hash = sha256::Hash::hash(test_bytes);
1055-
let msg = Message::from(hash);
1056-
assert_eq!(msg.0, hash.to_byte_array());
1057-
assert_eq!(msg, Message::from_hashed_data::<hashes::sha256::Hash>(test_bytes));
1058-
1059-
let hash = sha256d::Hash::hash(test_bytes);
1060-
let msg = Message::from(hash);
1061-
assert_eq!(msg.0, hash.to_byte_array());
1062-
assert_eq!(msg, Message::from_hashed_data::<hashes::sha256d::Hash>(test_bytes));
1063-
}
1064998
}
1065999

10661000
#[cfg(bench)]

0 commit comments

Comments
 (0)