Merge rust-bitcoin/rust-secp256k1#509: Improve feature usage bitcoin-hashes[-std]

b0d0b2afcb Improve feature usage bitcoin-hashes[-std] (Tobin C. Harding)

Pull request description:

  Currently we have a feature `bitcoin-hashes-std` and a dependency `bitcoin_hashes`, this means one has to think about and change the `_` and `-` when coding. The underscore in `bitcoin_hashes` is an artifact of days gone by and we cannot fix it but we can cover it up and make our lives easier, especially now we have `bitcoin-hashes-std`.

  Improve feature usage of the `bitcoin_hashes` library by:

  - Add a feature `bitcoin-hashes` that enables `bitcoin_hashes`.
  - Use the new feature in all feature gated code
  - Use `bitcoin-hashes-std` in feature gated code that includes other `std` features (e.g. `rand-std`)

ACKs for top commit:
  apoelstra:
    ACK b0d0b2afcb

Tree-SHA512: e6a86fe2c5b249a6c32b0fdedaeb8e25c47a30a4709f4fc4020cc1762747fe5d25883e2340ff77698079c9ee397491984889d3c1aaf195ca27eec09a77f62978
This commit is contained in:
Andrew Poelstra 2022-11-14 14:17:43 +00:00
commit 8508680c79
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
6 changed files with 30 additions and 27 deletions

View File

@ -22,7 +22,8 @@ default = ["std"]
std = ["alloc", "secp256k1-sys/std"] std = ["alloc", "secp256k1-sys/std"]
# allow use of Secp256k1::new and related API that requires an allocator # allow use of Secp256k1::new and related API that requires an allocator
alloc = ["secp256k1-sys/alloc"] alloc = ["secp256k1-sys/alloc"]
bitcoin-hashes-std = ["bitcoin_hashes/std"] bitcoin-hashes = ["bitcoin_hashes"] # Feature alias because of the underscore.
bitcoin-hashes-std = ["bitcoin-hashes", "bitcoin_hashes/std"]
rand-std = ["rand/std", "rand/std_rng"] rand-std = ["rand/std", "rand/std_rng"]
recovery = ["secp256k1-sys/recovery"] recovery = ["secp256k1-sys/recovery"]
lowmemory = ["secp256k1-sys/lowmemory"] lowmemory = ["secp256k1-sys/lowmemory"]

View File

@ -2,7 +2,7 @@
set -ex set -ex
FEATURES="bitcoin_hashes global-context lowmemory rand recovery serde std alloc" FEATURES="bitcoin-hashes global-context lowmemory rand recovery serde std alloc"
# These features are typically enabled along with the 'std' feature, so we test # These features are typically enabled along with the 'std' feature, so we test
# them together with 'std'. # them together with 'std'.
STD_FEATURES="rand-std bitcoin-hashes-std" STD_FEATURES="rand-std bitcoin-hashes-std"

View File

@ -127,7 +127,7 @@ impl AsRef<[u8]> for SharedSecret {
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// # #[cfg(all(feature = "bitcoin_hashes", feature = "rand-std", feature = "std"))] { /// # #[cfg(all(feature = "bitcoin-hashes-std", feature = "rand-std", feature = "std"))] {
/// # use secp256k1::{ecdh, Secp256k1, PublicKey, SecretKey}; /// # use secp256k1::{ecdh, Secp256k1, PublicKey, SecretKey};
/// # use secp256k1::hashes::{Hash, sha512}; /// # use secp256k1::hashes::{Hash, sha512};
/// # use secp256k1::rand::thread_rng; /// # use secp256k1::rand::thread_rng;
@ -239,7 +239,7 @@ mod tests {
#[test] #[test]
#[cfg(not(fuzzing))] #[cfg(not(fuzzing))]
#[cfg(all(feature="rand-std", feature = "std", feature = "bitcoin_hashes"))] #[cfg(all(feature="std", feature = "rand-std", feature = "bitcoin-hashes-std"))]
fn bitcoin_hashes_and_sys_generate_same_secret() { fn bitcoin_hashes_and_sys_generate_same_secret() {
use bitcoin_hashes::{sha256, Hash, HashEngine}; use bitcoin_hashes::{sha256, Hash, HashEngine};
use crate::ecdh::shared_secret_point; use crate::ecdh::shared_secret_point;

View File

@ -25,7 +25,7 @@ use crate::Error::{self, InvalidPublicKey, InvalidPublicKeySum, InvalidSecretKey
use crate::ffi::{self, CPtr, impl_array_newtype}; use crate::ffi::{self, CPtr, impl_array_newtype};
use crate::ffi::types::c_uint; use crate::ffi::types::c_uint;
#[cfg(feature = "bitcoin_hashes")] #[cfg(feature = "bitcoin-hashes")]
use crate::{hashes, ThirtyTwoByteHash}; use crate::{hashes, ThirtyTwoByteHash};
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
@ -246,8 +246,8 @@ impl SecretKey {
/// assert_eq!(sk1, sk2); /// assert_eq!(sk1, sk2);
/// # } /// # }
/// ``` /// ```
#[cfg(feature = "bitcoin_hashes")] #[cfg(feature = "bitcoin-hashes")]
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoin_hashes")))] #[cfg_attr(docsrs, doc(cfg(feature = "bitcoin-hashes")))]
#[inline] #[inline]
pub fn from_hashed_data<H: ThirtyTwoByteHash + hashes::Hash>(data: &[u8]) -> Self { pub fn from_hashed_data<H: ThirtyTwoByteHash + hashes::Hash>(data: &[u8]) -> Self {
<H as hashes::Hash>::hash(data).into() <H as hashes::Hash>::hash(data).into()
@ -349,7 +349,7 @@ impl SecretKey {
} }
} }
#[cfg(feature = "bitcoin_hashes")] #[cfg(feature = "bitcoin-hashes")]
impl<T: ThirtyTwoByteHash> From<T> for SecretKey { impl<T: ThirtyTwoByteHash> From<T> for SecretKey {
/// Converts a 32-byte hash directly to a secret key without error paths. /// Converts a 32-byte hash directly to a secret key without error paths.
fn from(t: T) -> SecretKey { fn from(t: T) -> SecretKey {

View File

@ -41,7 +41,7 @@
//! trigger any assertion failures in the upstream library. //! trigger any assertion failures in the upstream library.
//! //!
//! ```rust //! ```rust
//! # #[cfg(all(feature = "std", feature="rand-std", feature="bitcoin_hashes"))] { //! # #[cfg(all(feature = "std", feature="rand-std", feature="bitcoin-hashes-std"))] {
//! use secp256k1::rand::rngs::OsRng; //! use secp256k1::rand::rngs::OsRng;
//! use secp256k1::{Secp256k1, Message}; //! use secp256k1::{Secp256k1, Message};
//! use secp256k1::hashes::sha256; //! use secp256k1::hashes::sha256;
@ -58,7 +58,7 @@
//! If the "global-context" feature is enabled you have access to an alternate API. //! If the "global-context" feature is enabled you have access to an alternate API.
//! //!
//! ```rust //! ```rust
//! # #[cfg(all(feature="global-context", feature = "std", feature="rand-std", features = "bitcoin_hashes"))] { //! # #[cfg(all(feature="global-context", feature = "std", feature="rand-std", features = "bitcoin-hashes-std"))] {
//! use secp256k1::rand::thread_rng; //! use secp256k1::rand::thread_rng;
//! use secp256k1::{generate_keypair, Message}; //! use secp256k1::{generate_keypair, Message};
//! use secp256k1::hashes::sha256; //! use secp256k1::hashes::sha256;
@ -71,7 +71,7 @@
//! # } //! # }
//! ``` //! ```
//! //!
//! The above code requires `rust-secp256k1` to be compiled with the `rand-std` and `bitcoin_hashes` //! The above code requires `rust-secp256k1` to be compiled with the `rand-std` and `bitcoin-hashes-std`
//! feature enabled, to get access to [`generate_keypair`](struct.Secp256k1.html#method.generate_keypair) //! feature enabled, to get access to [`generate_keypair`](struct.Secp256k1.html#method.generate_keypair)
//! Alternately, keys and messages can be parsed from slices, like //! Alternately, keys and messages can be parsed from slices, like
//! //!
@ -83,7 +83,7 @@
//! let secret_key = SecretKey::from_slice(&[0xcd; 32]).expect("32 bytes, within curve order"); //! let secret_key = SecretKey::from_slice(&[0xcd; 32]).expect("32 bytes, within curve order");
//! let public_key = PublicKey::from_secret_key(&secp, &secret_key); //! let public_key = PublicKey::from_secret_key(&secp, &secret_key);
//! // This is unsafe unless the supplied byte slice is the output of a cryptographic hash function. //! // This is unsafe unless the supplied byte slice is the output of a cryptographic hash function.
//! // See the above example for how to use this library together with `bitcoin_hashes`. //! // See the above example for how to use this library together with `bitcoin-hashes-std`.
//! let message = Message::from_slice(&[0xab; 32]).expect("32 bytes"); //! let message = Message::from_slice(&[0xab; 32]).expect("32 bytes");
//! //!
//! let sig = secp.sign_ecdsa(&message, &secret_key); //! let sig = secp.sign_ecdsa(&message, &secret_key);
@ -141,12 +141,14 @@
//! * `alloc` - use the `alloc` standard Rust library to provide heap allocations. //! * `alloc` - use the `alloc` standard Rust library to provide heap allocations.
//! * `rand` - use `rand` library to provide random generator (e.g. to generate keys). //! * `rand` - use `rand` library to provide random generator (e.g. to generate keys).
//! * `rand-std` - use `rand` library with its `std` feature enabled. (Implies `rand`.) //! * `rand-std` - use `rand` library with its `std` feature enabled. (Implies `rand`.)
//! * `bitcoin-hashes` - use the `bitcoin-hashes` library.
//! * `bitcoin-hashes-std` - use the `bitcoin-hashes` library with its `std` feature enabled (implies `bitcoin-hashes`).
//! * `recovery` - enable functions that can compute the public key from signature. //! * `recovery` - enable functions that can compute the public key from signature.
//! * `lowmemory` - optimize the library for low-memory environments. //! * `lowmemory` - optimize the library for low-memory environments.
//! * `global-context` - enable use of global secp256k1 context (implies `std`). //! * `global-context` - enable use of global secp256k1 context (implies `std`).
//! * `serde` - implements serialization and deserialization for types in this crate using `serde`. //! * `serde` - implements serialization and deserialization for types in this crate using `serde`.
//! **Important**: `serde` encoding is **not** the same as consensus encoding! //! **Important**: `serde` encoding is **not** the same as consensus encoding!
//! * `bitcoin_hashes` - enables interaction with the `bitcoin-hashes` crate (e.g. conversions). //!
// Coding conventions // Coding conventions
#![deny(non_upper_case_globals, non_camel_case_types, non_snake_case)] #![deny(non_upper_case_globals, non_camel_case_types, non_snake_case)]
@ -188,8 +190,8 @@ pub use rand;
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] #[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
pub use serde; pub use serde;
#[cfg(feature = "bitcoin_hashes")] #[cfg(feature = "bitcoin-hashes")]
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoin_hashes")))] #[cfg_attr(docsrs, doc(cfg(feature = "bitcoin-hashes")))]
pub use bitcoin_hashes as hashes; pub use bitcoin_hashes as hashes;
pub use secp256k1_sys as ffi; pub use secp256k1_sys as ffi;
pub use crate::key::{PublicKey, SecretKey}; pub use crate::key::{PublicKey, SecretKey};
@ -203,7 +205,7 @@ pub use context::global::SECP256K1;
use core::{fmt, str, mem, marker::PhantomData}; use core::{fmt, str, mem, marker::PhantomData};
use crate::ffi::{CPtr, impl_array_newtype, types::AlignedType}; use crate::ffi::{CPtr, impl_array_newtype, types::AlignedType};
#[cfg(feature = "bitcoin_hashes")] #[cfg(feature = "bitcoin-hashes")]
use crate::hashes::Hash; use crate::hashes::Hash;
/// Trait describing something that promises to be a 32-byte random number; in particular, /// Trait describing something that promises to be a 32-byte random number; in particular,
@ -214,24 +216,24 @@ pub trait ThirtyTwoByteHash {
fn into_32(self) -> [u8; 32]; fn into_32(self) -> [u8; 32];
} }
#[cfg(feature = "bitcoin_hashes")] #[cfg(feature = "bitcoin-hashes")]
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoin_hashes")))] #[cfg_attr(docsrs, doc(cfg(feature = "bitcoin-hashes")))]
impl ThirtyTwoByteHash for hashes::sha256::Hash { impl ThirtyTwoByteHash for hashes::sha256::Hash {
fn into_32(self) -> [u8; 32] { fn into_32(self) -> [u8; 32] {
self.into_inner() self.into_inner()
} }
} }
#[cfg(feature = "bitcoin_hashes")] #[cfg(feature = "bitcoin-hashes")]
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoin_hashes")))] #[cfg_attr(docsrs, doc(cfg(feature = "bitcoin-hashes")))]
impl ThirtyTwoByteHash for hashes::sha256d::Hash { impl ThirtyTwoByteHash for hashes::sha256d::Hash {
fn into_32(self) -> [u8; 32] { fn into_32(self) -> [u8; 32] {
self.into_inner() self.into_inner()
} }
} }
#[cfg(feature = "bitcoin_hashes")] #[cfg(feature = "bitcoin-hashes")]
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoin_hashes")))] #[cfg_attr(docsrs, doc(cfg(feature = "bitcoin-hashes")))]
impl<T: hashes::sha256t::Tag> ThirtyTwoByteHash for hashes::sha256t::Hash<T> { impl<T: hashes::sha256t::Tag> ThirtyTwoByteHash for hashes::sha256t::Hash<T> {
fn into_32(self) -> [u8; 32] { fn into_32(self) -> [u8; 32] {
self.into_inner() self.into_inner()
@ -280,8 +282,8 @@ impl Message {
/// assert_eq!(m1, m2); /// assert_eq!(m1, m2);
/// # } /// # }
/// ``` /// ```
#[cfg(feature = "bitcoin_hashes")] #[cfg(feature = "bitcoin-hashes")]
#[cfg_attr(docsrs, doc(cfg(feature = "bitcoin_hashes")))] #[cfg_attr(docsrs, doc(cfg(feature = "bitcoin-hashes")))]
pub fn from_hashed_data<H: ThirtyTwoByteHash + hashes::Hash>(data: &[u8]) -> Self { pub fn from_hashed_data<H: ThirtyTwoByteHash + hashes::Hash>(data: &[u8]) -> Self {
<H as hashes::Hash>::hash(data).into() <H as hashes::Hash>::hash(data).into()
} }
@ -1021,7 +1023,7 @@ mod tests {
assert!(SECP256K1.verify_ecdsa(&msg, &sig, &pk).is_ok()); assert!(SECP256K1.verify_ecdsa(&msg, &sig, &pk).is_ok());
} }
#[cfg(feature = "bitcoin_hashes")] #[cfg(feature = "bitcoin-hashes")]
#[test] #[test]
fn test_from_hash() { fn test_from_hash() {
use crate::hashes::{self, Hash}; use crate::hashes::{self, Hash};

View File

@ -43,7 +43,7 @@ macro_rules! impl_display_secret {
} }
} }
#[cfg(all(not(feature = "std"), feature = "bitcoin_hashes"))] #[cfg(all(not(feature = "std"), feature = "bitcoin-hashes"))]
impl ::core::fmt::Debug for $thing { impl ::core::fmt::Debug for $thing {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use crate::hashes::{sha256, Hash, HashEngine}; use crate::hashes::{sha256, Hash, HashEngine};
@ -63,7 +63,7 @@ macro_rules! impl_display_secret {
} }
} }
#[cfg(all(not(feature = "std"), not(feature = "bitcoin_hashes")))] #[cfg(all(not(feature = "std"), not(feature = "bitcoin-hashes")))]
impl ::core::fmt::Debug for $thing { impl ::core::fmt::Debug for $thing {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "<secret requires std or bitcoin_hashes feature to display>") write!(f, "<secret requires std or bitcoin_hashes feature to display>")