Merge rust-bitcoin/rust-bitcoin#2165: Use macro to define `sha512::Hash`

71454d438a Use hash_type macro for sha512::Hash (Tobin C. Harding)
d51c1857fd sha512: Move from_engine functions (Tobin C. Harding)

Pull request description:

  This PR does not introduce any logic changes.

  - Patch 1 is a code move.
  - Patch 2 uses the `hash_type!` macro to define the `sha512::Hash` type.

ACKs for top commit:
  Kixunil:
    ACK 71454d438a
  apoelstra:
    ACK 71454d438a

Tree-SHA512: c0148391fbea3602f0c52e5e08883faac6b5cb3f75ae62bfb53b1d2762e28871d349b3d3fb589f59d8bf2912dd63934f8f9a6fe6390afd378e5391eb2c91c237
This commit is contained in:
Andrew Poelstra 2023-11-03 21:05:43 +00:00
commit 9b2e1c591a
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
1 changed files with 34 additions and 47 deletions

View File

@ -10,7 +10,40 @@ use core::{cmp, str};
use crate::{FromSliceError, HashEngine as _}; use crate::{FromSliceError, HashEngine as _};
crate::internal_macros::hash_trait_impls!(512, false); crate::internal_macros::hash_type! {
512,
false,
"Output of the SHA512 hash function.",
"crate::util::json_hex_string::len_64"
}
#[cfg(not(hashes_fuzz))]
pub(crate) fn from_engine(mut e: HashEngine) -> Hash {
// pad buffer with a single 1-bit then all 0s, until there are exactly 16 bytes remaining
let data_len = e.length as u64;
let zeroes = [0; BLOCK_SIZE - 16];
e.input(&[0x80]);
if e.length % BLOCK_SIZE > zeroes.len() {
e.input(&zeroes);
}
let pad_length = zeroes.len() - (e.length % BLOCK_SIZE);
e.input(&zeroes[..pad_length]);
debug_assert_eq!(e.length % BLOCK_SIZE, zeroes.len());
e.input(&[0; 8]);
e.input(&(8 * data_len).to_be_bytes());
debug_assert_eq!(e.length % BLOCK_SIZE, 0);
Hash(e.midstate())
}
#[cfg(hashes_fuzz)]
pub(crate) fn from_engine(e: HashEngine) -> Hash {
let mut hash = e.midstate();
hash[0] ^= 0xff; // Make this distinct from SHA-256
Hash(hash)
}
pub(crate) const BLOCK_SIZE: usize = 128; pub(crate) const BLOCK_SIZE: usize = 128;
@ -77,52 +110,6 @@ impl crate::HashEngine for HashEngine {
engine_input_impl!(); engine_input_impl!();
} }
/// Output of the SHA512 hash function.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[repr(transparent)]
pub struct Hash(
#[cfg_attr(
feature = "schemars",
schemars(schema_with = "crate::util::json_hex_string::len_64")
)]
[u8; 64],
);
impl Hash {
fn internal_new(arr: [u8; 64]) -> Self { Hash(arr) }
fn internal_engine() -> HashEngine { Default::default() }
}
#[cfg(not(hashes_fuzz))]
pub(crate) fn from_engine(mut e: HashEngine) -> Hash {
// pad buffer with a single 1-bit then all 0s, until there are exactly 16 bytes remaining
let data_len = e.length as u64;
let zeroes = [0; BLOCK_SIZE - 16];
e.input(&[0x80]);
if e.length % BLOCK_SIZE > zeroes.len() {
e.input(&zeroes);
}
let pad_length = zeroes.len() - (e.length % BLOCK_SIZE);
e.input(&zeroes[..pad_length]);
debug_assert_eq!(e.length % BLOCK_SIZE, zeroes.len());
e.input(&[0; 8]);
e.input(&(8 * data_len).to_be_bytes());
debug_assert_eq!(e.length % BLOCK_SIZE, 0);
Hash(e.midstate())
}
#[cfg(hashes_fuzz)]
pub(crate) fn from_engine(e: HashEngine) -> Hash {
let mut hash = e.midstate();
hash[0] ^= 0xff; // Make this distinct from SHA-256
Hash(hash)
}
#[allow(non_snake_case)] #[allow(non_snake_case)]
fn Ch(x: u64, y: u64, z: u64) -> u64 { z ^ (x & (y ^ z)) } fn Ch(x: u64, y: u64, z: u64) -> u64 { z ^ (x & (y ^ z)) }
#[allow(non_snake_case)] #[allow(non_snake_case)]