Merge rust-bitcoin/rust-bitcoin#3477: Polish the `hashes` crate

1cb24c1f15 hashes:: Polish crate level rustdocs (Tobin C. Harding)
98691186dc hashes: Move engine functions (Tobin C. Harding)
12f261c009 hashes: Re-order from_byte_array (Tobin C. Harding)
c11587d60d hashes: Rename hash_type macro (Tobin C. Harding)
62617cf9ac hashes: Move from_engine function to other macro (Tobin C. Harding)
bb7dd2c479 hashes: Move DISPLAY_BACKWARD to top of impl block (Tobin C. Harding)
71013afe07 hashes: Put attribute under doc (Tobin C. Harding)

Pull request description:

  `hashes 1.0.0` can't be far away, here is a quick polish (done while I waited for my car to get fixed).

  Everything here is internal except stuff to docs. Note please I claim "internal change only" in a bunch of patches that do code moves but these effect the docs build because order is preserved in some instances.

ACKs for top commit:
  apoelstra:
    ACK 1cb24c1f150bc2d65d0be439f2005f41d95ad23c; successfully ran local tests

Tree-SHA512: 430c451afab8fc92fb4596bf2d4b36c086333fe72b3fe5858925b75597641b8c4f5e49f7643888fa19b675d3070ce9a3606623cd56bdba6cfc59e459fbdda440
This commit is contained in:
merge-script 2024-10-22 22:24:49 +00:00
commit 79ff70255b
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
14 changed files with 60 additions and 57 deletions

View File

@ -9,7 +9,7 @@
use crate::{ripemd160, sha256}; use crate::{ripemd160, sha256};
crate::internal_macros::hash_type! { crate::internal_macros::general_hash_type! {
160, 160,
false, false,
"Output of the Bitcoin HASH160 hash function. (RIPEMD160(SHA256))" "Output of the Bitcoin HASH160 hash function. (RIPEMD160(SHA256))"

View File

@ -127,14 +127,14 @@ impl<T: GeneralHash> GeneralHash for Hmac<T> {
impl<T: GeneralHash> Hash for Hmac<T> { impl<T: GeneralHash> Hash for Hmac<T> {
type Bytes = T::Bytes; type Bytes = T::Bytes;
fn from_byte_array(bytes: T::Bytes) -> Self { Hmac(T::from_byte_array(bytes)) }
#[allow(deprecated_in_future)] #[allow(deprecated_in_future)]
fn from_slice(sl: &[u8]) -> Result<Hmac<T>, FromSliceError> { T::from_slice(sl).map(Hmac) } fn from_slice(sl: &[u8]) -> Result<Hmac<T>, FromSliceError> { T::from_slice(sl).map(Hmac) }
fn to_byte_array(self) -> Self::Bytes { self.0.to_byte_array() } fn to_byte_array(self) -> Self::Bytes { self.0.to_byte_array() }
fn as_byte_array(&self) -> &Self::Bytes { self.0.as_byte_array() } fn as_byte_array(&self) -> &Self::Bytes { self.0.as_byte_array() }
fn from_byte_array(bytes: T::Bytes) -> Self { Hmac(T::from_byte_array(bytes)) }
} }
#[cfg(feature = "serde")] #[cfg(feature = "serde")]

View File

@ -97,6 +97,8 @@ macro_rules! hash_trait_impls {
const DISPLAY_BACKWARD: bool = $reverse; const DISPLAY_BACKWARD: bool = $reverse;
fn from_byte_array(bytes: Self::Bytes) -> Self { Self::from_byte_array(bytes) }
#[allow(deprecated_in_future)] #[allow(deprecated_in_future)]
fn from_slice(sl: &[u8]) -> $crate::_export::_core::result::Result<Hash<$($gen),*>, $crate::FromSliceError> { fn from_slice(sl: &[u8]) -> $crate::_export::_core::result::Result<Hash<$($gen),*>, $crate::FromSliceError> {
Self::from_slice(sl) Self::from_slice(sl)
@ -105,14 +107,12 @@ macro_rules! hash_trait_impls {
fn to_byte_array(self) -> Self::Bytes { self.to_byte_array() } fn to_byte_array(self) -> Self::Bytes { self.to_byte_array() }
fn as_byte_array(&self) -> &Self::Bytes { self.as_byte_array() } fn as_byte_array(&self) -> &Self::Bytes { self.as_byte_array() }
fn from_byte_array(bytes: Self::Bytes) -> Self { Self::from_byte_array(bytes) }
} }
} }
} }
pub(crate) use hash_trait_impls; pub(crate) use hash_trait_impls;
/// Creates a type called `Hash` and implements standard interface for it. /// Creates a type called `Hash` and implements the standard general hashing interface for it.
/// ///
/// The created type has a single field and will have all standard derives as well as an /// The created type has a single field and will have all standard derives as well as an
/// implementation of [`crate::Hash`]. /// implementation of [`crate::Hash`].
@ -125,11 +125,14 @@ pub(crate) use hash_trait_impls;
/// ///
/// The `from_engine` free-standing function is still required with this macro. See the doc of /// The `from_engine` free-standing function is still required with this macro. See the doc of
/// [`hash_trait_impls`]. /// [`hash_trait_impls`].
macro_rules! hash_type { macro_rules! general_hash_type {
($bits:expr, $reverse:expr, $doc:literal) => { ($bits:expr, $reverse:expr, $doc:literal) => {
$crate::internal_macros::hash_type_no_default!($bits, $reverse, $doc); $crate::internal_macros::hash_type_no_default!($bits, $reverse, $doc);
impl Hash { impl Hash {
/// Produces a hash from the current state of a given engine.
pub fn from_engine(e: HashEngine) -> Hash { from_engine(e) }
/// Constructs a new engine. /// Constructs a new engine.
pub fn engine() -> HashEngine { Default::default() } pub fn engine() -> HashEngine { Default::default() }
@ -154,7 +157,7 @@ macro_rules! hash_type {
} }
}; };
} }
pub(crate) use hash_type; pub(crate) use general_hash_type;
macro_rules! hash_type_no_default { macro_rules! hash_type_no_default {
($bits:expr, $reverse:expr, $doc:literal) => { ($bits:expr, $reverse:expr, $doc:literal) => {
@ -166,6 +169,11 @@ macro_rules! hash_type_no_default {
impl Hash { impl Hash {
const fn internal_new(arr: [u8; $bits / 8]) -> Self { Hash(arr) } const fn internal_new(arr: [u8; $bits / 8]) -> Self { Hash(arr) }
/// Constructs a hash from the underlying byte array.
pub const fn from_byte_array(bytes: [u8; $bits / 8]) -> Self {
Self::internal_new(bytes)
}
/// Zero cost conversion between a fixed length byte array shared reference and /// Zero cost conversion between a fixed length byte array shared reference and
/// a shared reference to this Hash type. /// a shared reference to this Hash type.
pub fn from_bytes_ref(bytes: &[u8; $bits / 8]) -> &Self { pub fn from_bytes_ref(bytes: &[u8; $bits / 8]) -> &Self {
@ -180,9 +188,6 @@ macro_rules! hash_type_no_default {
unsafe { &mut *(bytes as *mut _ as *mut Self) } unsafe { &mut *(bytes as *mut _ as *mut Self) }
} }
/// Produces a hash from the current state of a given engine.
pub fn from_engine(e: HashEngine) -> Hash { from_engine(e) }
/// Copies a byte slice into a hash object. /// Copies a byte slice into a hash object.
pub fn from_slice( pub fn from_slice(
sl: &[u8], sl: &[u8],
@ -201,11 +206,6 @@ macro_rules! hash_type_no_default {
/// Returns a reference to the underlying byte array. /// Returns a reference to the underlying byte array.
pub const fn as_byte_array(&self) -> &[u8; $bits / 8] { &self.0 } pub const fn as_byte_array(&self) -> &[u8; $bits / 8] { &self.0 }
/// Constructs a hash from the underlying byte array.
pub const fn from_byte_array(bytes: [u8; $bits / 8]) -> Self {
Self::internal_new(bytes)
}
} }
$crate::internal_macros::hash_trait_impls!($bits, $reverse); $crate::internal_macros::hash_trait_impls!($bits, $reverse);

View File

@ -2,10 +2,8 @@
//! Rust hashes library. //! Rust hashes library.
//! //!
//! This is a simple, no-dependency library which implements the hash functions //! This library implements the hash functions needed by Bitcoin. As an ancillary thing, it exposes
//! needed by Bitcoin. These are SHA256, SHA256d, and RIPEMD160. As an ancillary //! hexadecimal serialization and deserialization, since these are needed to display hashes.
//! thing, it exposes hexadecimal serialization and deserialization, since these
//! are needed to display hashes anway.
//! //!
//! ## Commonly used operations //! ## Commonly used operations
//! //!
@ -23,9 +21,10 @@
//! Hashing content from a reader: //! Hashing content from a reader:
//! //!
//! ``` //! ```
//! #[cfg(feature = "std")] { //! # #[cfg(feature = "std")] {
//! use bitcoin_hashes::Sha256; //! use bitcoin_hashes::Sha256;
//! let mut reader: &[u8] = b"hello"; // in real code, this could be a `File` or `TcpStream` //!
//! let mut reader: &[u8] = b"hello"; // In real code, this could be a `File` or `TcpStream`.
//! let mut engine = Sha256::engine(); //! let mut engine = Sha256::engine();
//! std::io::copy(&mut reader, &mut engine).unwrap(); //! std::io::copy(&mut reader, &mut engine).unwrap();
//! let _hash = Sha256::from_engine(engine); //! let _hash = Sha256::from_engine(engine);
@ -33,12 +32,13 @@
//! ``` //! ```
//! //!
//! //!
//! Hashing content by [`std::io::Write`] on `HashEngine`: //! Hashing content using [`std::io::Write`] on a `HashEngine`:
//! //!
//! ``` //! ```
//! #[cfg(feature = "std")] { //! # #[cfg(feature = "std")] {
//! use std::io::Write as _; // Or `bitcoin-io::Write` if `bitcoin-io` feature is enabled. //! use std::io::Write as _;
//! use bitcoin_hashes::Sha256; //! use bitcoin_hashes::Sha256;
//!
//! let part1: &[u8] = b"hello"; //! let part1: &[u8] = b"hello";
//! let part2: &[u8] = b" "; //! let part2: &[u8] = b" ";
//! let part3: &[u8] = b"world"; //! let part3: &[u8] = b"world";
@ -74,8 +74,8 @@ extern crate core;
#[cfg(feature = "bitcoin-io")] #[cfg(feature = "bitcoin-io")]
extern crate bitcoin_io as io; extern crate bitcoin_io as io;
#[cfg(feature = "serde")]
/// A generic serialization/deserialization framework. /// A generic serialization/deserialization framework.
#[cfg(feature = "serde")]
pub extern crate serde; pub extern crate serde;
#[cfg(all(test, feature = "serde"))] #[cfg(all(test, feature = "serde"))]
@ -265,23 +265,23 @@ pub trait Hash:
/// Length of the hash, in bytes. /// Length of the hash, in bytes.
const LEN: usize = Self::Bytes::LEN; const LEN: usize = Self::Bytes::LEN;
/// Flag indicating whether user-visible serializations of this hash should be backward.
///
/// For some reason Satoshi decided this should be true for `Sha256dHash`, so here we are.
const DISPLAY_BACKWARD: bool = false;
/// Constructs a hash from the underlying byte array.
fn from_byte_array(bytes: Self::Bytes) -> Self;
/// Copies a byte slice into a hash object. /// Copies a byte slice into a hash object.
#[deprecated(since = "TBD", note = "use `from_byte_array` instead")] #[deprecated(since = "TBD", note = "use `from_byte_array` instead")]
fn from_slice(sl: &[u8]) -> Result<Self, FromSliceError>; fn from_slice(sl: &[u8]) -> Result<Self, FromSliceError>;
/// Flag indicating whether user-visible serializations of this hash
/// should be backward. For some reason Satoshi decided this should be
/// true for `Sha256dHash`, so here we are.
const DISPLAY_BACKWARD: bool = false;
/// Returns the underlying byte array. /// Returns the underlying byte array.
fn to_byte_array(self) -> Self::Bytes; fn to_byte_array(self) -> Self::Bytes;
/// Returns a reference to the underlying byte array. /// Returns a reference to the underlying byte array.
fn as_byte_array(&self) -> &Self::Bytes; fn as_byte_array(&self) -> &Self::Bytes;
/// Constructs a hash from the underlying byte array.
fn from_byte_array(bytes: Self::Bytes) -> Self;
} }
/// Ensures that a type is an array. /// Ensures that a type is an array.

View File

@ -6,7 +6,7 @@ use core::cmp;
use crate::{incomplete_block_len, HashEngine as _}; use crate::{incomplete_block_len, HashEngine as _};
crate::internal_macros::hash_type! { crate::internal_macros::general_hash_type! {
160, 160,
false, false,
"Output of the RIPEMD160 hash function." "Output of the RIPEMD160 hash function."

View File

@ -6,7 +6,7 @@ use core::cmp;
use crate::{incomplete_block_len, HashEngine as _}; use crate::{incomplete_block_len, HashEngine as _};
crate::internal_macros::hash_type! { crate::internal_macros::general_hash_type! {
160, 160,
false, false,
"Output of the SHA1 hash function." "Output of the SHA1 hash function."

View File

@ -14,7 +14,7 @@ use crate::{incomplete_block_len, sha256d, HashEngine as _};
#[cfg(doc)] #[cfg(doc)]
use crate::{sha256t, sha256t_tag}; use crate::{sha256t, sha256t_tag};
crate::internal_macros::hash_type! { crate::internal_macros::general_hash_type! {
256, 256,
false, false,
"Output of the SHA256 hash function." "Output of the SHA256 hash function."

View File

@ -4,7 +4,7 @@
use crate::sha256; use crate::sha256;
crate::internal_macros::hash_type! { crate::internal_macros::general_hash_type! {
256, 256,
true, true,
"Output of the SHA256d hash function." "Output of the SHA256d hash function."

View File

@ -25,6 +25,9 @@ where
{ {
const fn internal_new(arr: [u8; 32]) -> Self { Hash(arr, PhantomData) } const fn internal_new(arr: [u8; 32]) -> Self { Hash(arr, PhantomData) }
/// Constructs a hash from the underlying byte array.
pub const fn from_byte_array(bytes: [u8; 32]) -> Self { Self::internal_new(bytes) }
/// Zero cost conversion between a fixed length byte array shared reference and /// Zero cost conversion between a fixed length byte array shared reference and
/// a shared reference to this Hash type. /// a shared reference to this Hash type.
pub fn from_bytes_ref(bytes: &[u8; 32]) -> &Self { pub fn from_bytes_ref(bytes: &[u8; 32]) -> &Self {
@ -39,12 +42,6 @@ where
unsafe { &mut *(bytes as *mut _ as *mut Self) } unsafe { &mut *(bytes as *mut _ as *mut Self) }
} }
/// Constructs a new engine.
pub fn engine() -> HashEngine { T::engine() }
/// Produces a hash from the current state of a given engine.
pub fn from_engine(e: HashEngine) -> Hash<T> { from_engine(e) }
/// Copies a byte slice into a hash object. /// Copies a byte slice into a hash object.
#[deprecated(since = "TBD", note = "use `from_byte_array` instead")] #[deprecated(since = "TBD", note = "use `from_byte_array` instead")]
pub fn from_slice(sl: &[u8]) -> Result<Hash<T>, FromSliceError> { pub fn from_slice(sl: &[u8]) -> Result<Hash<T>, FromSliceError> {
@ -57,6 +54,12 @@ where
} }
} }
/// Produces a hash from the current state of a given engine.
pub fn from_engine(e: HashEngine) -> Hash<T> { from_engine(e) }
/// Constructs a new engine.
pub fn engine() -> HashEngine { T::engine() }
/// Hashes some bytes. /// Hashes some bytes.
#[allow(clippy::self_named_constructors)] // Hash is a noun and a verb. #[allow(clippy::self_named_constructors)] // Hash is a noun and a verb.
pub fn hash(data: &[u8]) -> Self { pub fn hash(data: &[u8]) -> Self {
@ -104,9 +107,6 @@ where
/// Returns a reference to the underlying byte array. /// Returns a reference to the underlying byte array.
pub const fn as_byte_array(&self) -> &[u8; 32] { &self.0 } pub const fn as_byte_array(&self) -> &[u8; 32] { &self.0 }
/// Constructs a hash from the underlying byte array.
pub const fn from_byte_array(bytes: [u8; 32]) -> Self { Self::internal_new(bytes) }
} }
impl<T: Tag> Copy for Hash<T> {} impl<T: Tag> Copy for Hash<T> {}

View File

@ -4,7 +4,7 @@
use crate::sha512; use crate::sha512;
crate::internal_macros::hash_type! { crate::internal_macros::general_hash_type! {
384, 384,
false, false,
"Output of the SHA384 hash function." "Output of the SHA384 hash function."

View File

@ -6,7 +6,7 @@ use core::cmp;
use crate::{incomplete_block_len, HashEngine as _}; use crate::{incomplete_block_len, HashEngine as _};
crate::internal_macros::hash_type! { crate::internal_macros::general_hash_type! {
512, 512,
false, false,
"Output of the SHA512 hash function." "Output of the SHA512 hash function."

View File

@ -9,7 +9,7 @@
use crate::sha512; use crate::sha512;
crate::internal_macros::hash_type! { crate::internal_macros::general_hash_type! {
256, 256,
false, false,
"Output of the SHA512/256 hash function.\n\nSHA512/256 is a hash function that uses the sha512 algorithm but it truncates the output to 256 bits. It has different initial constants than sha512 so it produces an entirely different hash compared to sha512. More information at <https://eprint.iacr.org/2010/548.pdf>." "Output of the SHA512/256 hash function.\n\nSHA512/256 is a hash function that uses the sha512 algorithm but it truncates the output to 256 bits. It has different initial constants than sha512 so it produces an entirely different hash compared to sha512. More information at <https://eprint.iacr.org/2010/548.pdf>."

View File

@ -168,6 +168,9 @@ impl crate::HashEngine for HashEngine {
} }
impl Hash { impl Hash {
/// Produces a hash from the current state of a given engine.
pub fn from_engine(e: HashEngine) -> Hash { from_engine(e) }
/// Hashes the given data with an engine with the provided keys. /// Hashes the given data with an engine with the provided keys.
pub fn hash_with_keys(k0: u64, k1: u64, data: &[u8]) -> Hash { pub fn hash_with_keys(k0: u64, k1: u64, data: &[u8]) -> Hash {
let mut engine = HashEngine::with_keys(k0, k1); let mut engine = HashEngine::with_keys(k0, k1);

View File

@ -195,6 +195,11 @@ macro_rules! hash_newtype {
#[allow(unused)] // Private wrapper types may not need all functions. #[allow(unused)] // Private wrapper types may not need all functions.
impl $newtype { impl $newtype {
/// Constructs a hash from the underlying byte array.
pub const fn from_byte_array(bytes: <$hash as $crate::Hash>::Bytes) -> Self {
$newtype(<$hash>::from_byte_array(bytes))
}
/// Copies a byte slice into a hash object. /// Copies a byte slice into a hash object.
#[deprecated(since = "TBD", note = "use `from_byte_array` instead")] #[deprecated(since = "TBD", note = "use `from_byte_array` instead")]
#[allow(deprecated_in_future)] #[allow(deprecated_in_future)]
@ -211,11 +216,6 @@ macro_rules! hash_newtype {
pub const fn as_byte_array(&self) -> &<$hash as $crate::Hash>::Bytes { pub const fn as_byte_array(&self) -> &<$hash as $crate::Hash>::Bytes {
self.0.as_byte_array() self.0.as_byte_array()
} }
/// Constructs a hash from the underlying byte array.
pub const fn from_byte_array(bytes: <$hash as $crate::Hash>::Bytes) -> Self {
$newtype(<$hash>::from_byte_array(bytes))
}
} }
impl $crate::_export::_core::convert::From<$hash> for $newtype { impl $crate::_export::_core::convert::From<$hash> for $newtype {
@ -236,6 +236,8 @@ macro_rules! hash_newtype {
const DISPLAY_BACKWARD: bool = $crate::hash_newtype_get_direction!($hash, $(#[$($type_attrs)*])*); const DISPLAY_BACKWARD: bool = $crate::hash_newtype_get_direction!($hash, $(#[$($type_attrs)*])*);
fn from_byte_array(bytes: Self::Bytes) -> Self { Self::from_byte_array(bytes) }
#[inline] #[inline]
#[allow(deprecated_in_future)] #[allow(deprecated_in_future)]
fn from_slice(sl: &[u8]) -> $crate::_export::_core::result::Result<$newtype, $crate::FromSliceError> { fn from_slice(sl: &[u8]) -> $crate::_export::_core::result::Result<$newtype, $crate::FromSliceError> {
@ -245,8 +247,6 @@ macro_rules! hash_newtype {
fn to_byte_array(self) -> Self::Bytes { self.to_byte_array() } fn to_byte_array(self) -> Self::Bytes { self.to_byte_array() }
fn as_byte_array(&self) -> &Self::Bytes { self.as_byte_array() } fn as_byte_array(&self) -> &Self::Bytes { self.as_byte_array() }
fn from_byte_array(bytes: Self::Bytes) -> Self { Self::from_byte_array(bytes) }
} }
impl $crate::_export::_core::str::FromStr for $newtype { impl $crate::_export::_core::str::FromStr for $newtype {