Remove midstate from the GeneralHash and HashEngine traits
Midstates are not generic objects; they don't have universal cryptographic properties and if you are using them you should be using a specific midstate type. Therefore it shouldn't be part of `GeneralHash` or `HashEngine`. Furthermore, in practice it seems like `sha2` midstates are the only ones that anybody uses, at least in bitcoin. Remove the midstate stuff from the `GeneralHash` and `HashEngine` traits. Keep the `midstate` functionality as inherent functions if it is used internally. Keep the functionality on `sha256` as inherent public functions.
This commit is contained in:
parent
2fcd65ad97
commit
8dcecfc144
|
@ -32,9 +32,6 @@ impl Default for HashEngine {
|
|||
}
|
||||
|
||||
impl crate::HashEngine for HashEngine {
|
||||
type MidState = sha256::Midstate;
|
||||
fn midstate(&self) -> Self::MidState { self.0.midstate() }
|
||||
|
||||
const BLOCK_SIZE: usize = 64; // Same as sha256::HashEngine::BLOCK_SIZE;
|
||||
fn input(&mut self, data: &[u8]) { self.0.input(data) }
|
||||
fn n_bytes_hashed(&self) -> usize { self.0.n_bytes_hashed() }
|
||||
|
|
|
@ -35,14 +35,6 @@ impl<T: GeneralHash + str::FromStr> str::FromStr for Hmac<T> {
|
|||
fn from_str(s: &str) -> Result<Self, Self::Err> { Ok(Hmac(str::FromStr::from_str(s)?)) }
|
||||
}
|
||||
|
||||
/// Pair of underlying hash midstates which represent the current state of an `HmacEngine`.
|
||||
pub struct HmacMidState<T: GeneralHash> {
|
||||
/// Midstate of the inner hash engine
|
||||
pub inner: <T::Engine as HashEngine>::MidState,
|
||||
/// Midstate of the outer hash engine
|
||||
pub outer: <T::Engine as HashEngine>::MidState,
|
||||
}
|
||||
|
||||
/// Pair of underlying hash engines, used for the inner and outer hash of HMAC.
|
||||
#[derive(Clone)]
|
||||
pub struct HmacEngine<T: GeneralHash> {
|
||||
|
@ -101,12 +93,6 @@ impl<T: GeneralHash> HmacEngine<T> {
|
|||
}
|
||||
|
||||
impl<T: GeneralHash> HashEngine for HmacEngine<T> {
|
||||
type MidState = HmacMidState<T>;
|
||||
|
||||
fn midstate(&self) -> Self::MidState {
|
||||
HmacMidState { inner: self.iengine.midstate(), outer: self.oengine.midstate() }
|
||||
}
|
||||
|
||||
const BLOCK_SIZE: usize = T::Engine::BLOCK_SIZE;
|
||||
|
||||
fn n_bytes_hashed(&self) -> usize { self.iengine.n_bytes_hashed() }
|
||||
|
|
|
@ -178,13 +178,6 @@ pub type HkdfSha512 = Hkdf<sha512::Hash>;
|
|||
|
||||
/// A hashing engine which bytes can be serialized into.
|
||||
pub trait HashEngine: Clone + Default {
|
||||
/// Byte array representing the internal state of the hash engine.
|
||||
type MidState;
|
||||
|
||||
/// Outputs the midstate of the hash engine. This function should not be
|
||||
/// used directly unless you really know what you're doing.
|
||||
fn midstate(&self) -> Self::MidState;
|
||||
|
||||
/// Length of the hash's internal block size, in bytes.
|
||||
const BLOCK_SIZE: usize;
|
||||
|
||||
|
|
|
@ -60,14 +60,6 @@ impl HashEngine {
|
|||
buffer: [0; BLOCK_SIZE],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for HashEngine {
|
||||
fn default() -> Self { Self::new() }
|
||||
}
|
||||
|
||||
impl crate::HashEngine for HashEngine {
|
||||
type MidState = [u8; 20];
|
||||
|
||||
#[cfg(not(hashes_fuzz))]
|
||||
fn midstate(&self) -> [u8; 20] {
|
||||
|
@ -84,7 +76,13 @@ impl crate::HashEngine for HashEngine {
|
|||
ret.copy_from_slice(&self.buffer[..20]);
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for HashEngine {
|
||||
fn default() -> Self { Self::new() }
|
||||
}
|
||||
|
||||
impl crate::HashEngine for HashEngine {
|
||||
const BLOCK_SIZE: usize = 64;
|
||||
|
||||
fn n_bytes_hashed(&self) -> usize { self.length }
|
||||
|
|
|
@ -52,17 +52,9 @@ impl HashEngine {
|
|||
buffer: [0; BLOCK_SIZE],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for HashEngine {
|
||||
fn default() -> Self { Self::new() }
|
||||
}
|
||||
|
||||
impl crate::HashEngine for HashEngine {
|
||||
type MidState = [u8; 20];
|
||||
|
||||
#[cfg(not(hashes_fuzz))]
|
||||
fn midstate(&self) -> [u8; 20] {
|
||||
pub(crate) fn midstate(&self) -> [u8; 20] {
|
||||
let mut ret = [0; 20];
|
||||
for (val, ret_bytes) in self.h.iter().zip(ret.chunks_exact_mut(4)) {
|
||||
ret_bytes.copy_from_slice(&val.to_be_bytes())
|
||||
|
@ -71,12 +63,18 @@ impl crate::HashEngine for HashEngine {
|
|||
}
|
||||
|
||||
#[cfg(hashes_fuzz)]
|
||||
fn midstate(&self) -> [u8; 20] {
|
||||
pub(crate) fn midstate(&self) -> [u8; 20] {
|
||||
let mut ret = [0; 20];
|
||||
ret.copy_from_slice(&self.buffer[..20]);
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for HashEngine {
|
||||
fn default() -> Self { Self::new() }
|
||||
}
|
||||
|
||||
impl crate::HashEngine for HashEngine {
|
||||
const BLOCK_SIZE: usize = 64;
|
||||
|
||||
fn n_bytes_hashed(&self) -> usize { self.length }
|
||||
|
|
|
@ -71,17 +71,11 @@ impl HashEngine {
|
|||
buffer: [0; BLOCK_SIZE],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for HashEngine {
|
||||
fn default() -> Self { Self::new() }
|
||||
}
|
||||
|
||||
impl crate::HashEngine for HashEngine {
|
||||
type MidState = Midstate;
|
||||
|
||||
/// Outputs the midstate of the hash engine. This function should not be
|
||||
/// used directly unless you really know what you're doing.
|
||||
#[cfg(not(hashes_fuzz))]
|
||||
fn midstate(&self) -> Midstate {
|
||||
pub fn midstate(&self) -> Midstate {
|
||||
let mut ret = [0; 32];
|
||||
for (val, ret_bytes) in self.h.iter().zip(ret.chunks_exact_mut(4)) {
|
||||
ret_bytes.copy_from_slice(&val.to_be_bytes());
|
||||
|
@ -89,13 +83,21 @@ impl crate::HashEngine for HashEngine {
|
|||
Midstate(ret)
|
||||
}
|
||||
|
||||
/// Outputs the midstate of the hash engine. This function should not be
|
||||
/// used directly unless you really know what you're doing.
|
||||
#[cfg(hashes_fuzz)]
|
||||
fn midstate(&self) -> Midstate {
|
||||
pub fn midstate(&self) -> Midstate {
|
||||
let mut ret = [0; 32];
|
||||
ret.copy_from_slice(&self.buffer[..32]);
|
||||
Midstate(ret)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for HashEngine {
|
||||
fn default() -> Self { Self::new() }
|
||||
}
|
||||
|
||||
impl crate::HashEngine for HashEngine {
|
||||
const BLOCK_SIZE: usize = 64;
|
||||
|
||||
fn n_bytes_hashed(&self) -> usize { self.length }
|
||||
|
@ -895,7 +897,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
#[rustfmt::skip]
|
||||
fn midstate() {
|
||||
pub(crate) fn midstate() {
|
||||
// Test vector obtained by doing an asset issuance on Elements
|
||||
let mut engine = sha256::Hash::engine();
|
||||
// sha256dhash of outpoint
|
||||
|
@ -1001,7 +1003,7 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn midstate_fmt_roundtrip() {
|
||||
pub(crate) fn midstate_fmt_roundtrip() {
|
||||
let midstate = Midstate::hash_tag(b"ArbitraryTag");
|
||||
let hex = format!("{}", midstate);
|
||||
let rinsed = hex.parse::<Midstate>().expect("failed to parse hex");
|
||||
|
|
|
@ -27,9 +27,6 @@ impl Default for HashEngine {
|
|||
}
|
||||
|
||||
impl crate::HashEngine for HashEngine {
|
||||
type MidState = sha256::Midstate;
|
||||
fn midstate(&self) -> Self::MidState { self.0.midstate() }
|
||||
|
||||
const BLOCK_SIZE: usize = 64; // Same as sha256::HashEngine::BLOCK_SIZE;
|
||||
fn input(&mut self, data: &[u8]) { self.0.input(data) }
|
||||
fn n_bytes_hashed(&self) -> usize { self.0.n_bytes_hashed() }
|
||||
|
|
|
@ -33,10 +33,6 @@ impl Default for HashEngine {
|
|||
}
|
||||
|
||||
impl crate::HashEngine for HashEngine {
|
||||
type MidState = [u8; 64];
|
||||
|
||||
fn midstate(&self) -> [u8; 64] { self.0.midstate() }
|
||||
|
||||
const BLOCK_SIZE: usize = sha512::BLOCK_SIZE;
|
||||
|
||||
fn n_bytes_hashed(&self) -> usize { self.0.n_bytes_hashed() }
|
||||
|
|
|
@ -72,6 +72,22 @@ impl Default for HashEngine {
|
|||
}
|
||||
|
||||
impl HashEngine {
|
||||
#[cfg(not(hashes_fuzz))]
|
||||
pub(crate) fn midstate(&self) -> [u8; 64] {
|
||||
let mut ret = [0; 64];
|
||||
for (val, ret_bytes) in self.h.iter().zip(ret.chunks_exact_mut(8)) {
|
||||
ret_bytes.copy_from_slice(&val.to_be_bytes());
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
#[cfg(hashes_fuzz)]
|
||||
pub(crate) fn midstate(&self) -> [u8; 64] {
|
||||
let mut ret = [0; 64];
|
||||
ret.copy_from_slice(&self.buffer[..64]);
|
||||
ret
|
||||
}
|
||||
|
||||
/// Constructs a hash engine suitable for use constructing a `sha512_256::HashEngine`.
|
||||
#[rustfmt::skip]
|
||||
pub(crate) const fn sha512_256() -> Self {
|
||||
|
@ -100,24 +116,6 @@ impl HashEngine {
|
|||
}
|
||||
|
||||
impl crate::HashEngine for HashEngine {
|
||||
type MidState = [u8; 64];
|
||||
|
||||
#[cfg(not(hashes_fuzz))]
|
||||
fn midstate(&self) -> [u8; 64] {
|
||||
let mut ret = [0; 64];
|
||||
for (val, ret_bytes) in self.h.iter().zip(ret.chunks_exact_mut(8)) {
|
||||
ret_bytes.copy_from_slice(&val.to_be_bytes());
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
#[cfg(hashes_fuzz)]
|
||||
fn midstate(&self) -> [u8; 64] {
|
||||
let mut ret = [0; 64];
|
||||
ret.copy_from_slice(&self.buffer[..64]);
|
||||
ret
|
||||
}
|
||||
|
||||
const BLOCK_SIZE: usize = 128;
|
||||
|
||||
fn n_bytes_hashed(&self) -> usize { self.length }
|
||||
|
|
|
@ -43,10 +43,6 @@ impl Default for HashEngine {
|
|||
}
|
||||
|
||||
impl crate::HashEngine for HashEngine {
|
||||
type MidState = [u8; 64];
|
||||
|
||||
fn midstate(&self) -> [u8; 64] { self.0.midstate() }
|
||||
|
||||
const BLOCK_SIZE: usize = sha512::BLOCK_SIZE;
|
||||
|
||||
fn n_bytes_hashed(&self) -> usize { self.0.n_bytes_hashed() }
|
||||
|
|
|
@ -19,7 +19,7 @@ fn from_engine(e: HashEngine) -> Hash { Hash::from_u64(Hash::from_engine_to_u64(
|
|||
|
||||
#[cfg(hashes_fuzz)]
|
||||
fn from_engine(e: HashEngine) -> Hash {
|
||||
let state = e.midstate();
|
||||
let state = e.state.clone();
|
||||
Hash::from_u64(state.v0 ^ state.v1 ^ state.v2 ^ state.v3)
|
||||
}
|
||||
|
||||
|
@ -133,10 +133,6 @@ impl Default for HashEngine {
|
|||
}
|
||||
|
||||
impl crate::HashEngine for HashEngine {
|
||||
type MidState = State;
|
||||
|
||||
fn midstate(&self) -> State { self.state.clone() }
|
||||
|
||||
const BLOCK_SIZE: usize = 8;
|
||||
|
||||
#[inline]
|
||||
|
|
Loading…
Reference in New Issue