Unverified Commit 46b28234 authored by Hero Bird's avatar Hero Bird Committed by GitHub

Refactor and improve hash module (#372)

* [core] refactor and improve hash module

* [core] rename hash_raw[_using] -> hash_bytes[_using]

* [examples] fix runtime-storage contract example
parent e1fdb557
Pipeline #85457 passed with stages
in 6 minutes and 34 seconds
...@@ -18,6 +18,14 @@ use super::{ ...@@ -18,6 +18,14 @@ use super::{
}; };
use core::marker::PhantomData; use core::marker::PhantomData;
/// Type indicating that no accumulator is in use.
///
/// # Note
///
/// This means that a hash builder with this type as accumulator cannot
/// build hashes for instances based on their SCALE encoding.
pub enum NoAccumulator {}
/// Generic hash builder to construct hashes given a builder strategy. /// Generic hash builder to construct hashes given a builder strategy.
/// ///
/// - `H` defines the crytographic hash to be conducted. /// - `H` defines the crytographic hash to be conducted.
...@@ -34,7 +42,7 @@ use core::marker::PhantomData; ...@@ -34,7 +42,7 @@ use core::marker::PhantomData;
/// - [`Keccak256`](`crate::hash::Keccak256`) /// - [`Keccak256`](`crate::hash::Keccak256`)
/// - [`Blake2x256`](`crate::hash::Blake2x256`) /// - [`Blake2x256`](`crate::hash::Blake2x256`)
/// - [`Blake2x128`](`crate::hash::Blake2x128`) /// - [`Blake2x128`](`crate::hash::Blake2x128`)
pub struct HashBuilder<H, S> { pub struct HashBuilder<H, S = NoAccumulator> {
/// The strategy used to build up the hash. /// The strategy used to build up the hash.
strategy: S, strategy: S,
/// The underlying cryptographic hasher. /// The underlying cryptographic hasher.
...@@ -62,6 +70,41 @@ where ...@@ -62,6 +70,41 @@ where
} }
} }
impl<H, S> HashBuilder<H, S>
where
H: Hasher,
{
/// Conducts the hash for the given bytes.
///
/// Puts the resulting hash into the provided output buffer.
///
/// # Note
///
/// Prefer the simpler [`hash_bytes`](`HashBuilder::hash_bytes`)
/// if you do _not_ need full control over the `output` buffer.
pub fn hash_bytes_using(input: &[u8], output: &mut <H as Hasher>::Output)
where
H: Hasher,
{
<H as Hasher>::finalize_immediate(input, output)
}
/// Returns the hash for the given bytes.
///
/// # Note
///
/// Use [`hash_bytes_using`](`HashBuilder::hash_bytes_using`)
/// if you need full control over the `output` buffer.
pub fn hash_bytes(input: &[u8]) -> <H as Hasher>::Output
where
H: Hasher,
{
let mut output = <<H as Hasher>::Output as Default>::default();
Self::hash_bytes_using(input, &mut output);
output
}
}
pub trait Finalize<H> pub trait Finalize<H>
where where
H: Hasher, H: Hasher,
...@@ -88,39 +131,9 @@ where ...@@ -88,39 +131,9 @@ where
impl<H, S> HashBuilder<H, S> impl<H, S> HashBuilder<H, S>
where where
Self: Finalize<H> + scale::Output,
H: Hasher, H: Hasher,
S: Accumulator,
{ {
/// Conducts the hash for the given bytes.
///
/// Puts the resulting hash into the provided output buffer.
///
/// # Note
///
/// Prefer the simpler [`hash_raw`](`HashBuilder::hash_raw`)
/// if you do _not_ need full control over the `output` buffer.
pub fn hash_raw_using(&mut self, input: &[u8], output: &mut <H as Hasher>::Output)
where
H: Hasher,
{
<Self as scale::Output>::write(self, input);
self.finalize_using(output)
}
/// Returns the hash for the given bytes.
///
/// # Note
///
/// Use [`hash_raw_using`](`HashBuilder::hash_raw_using`)
/// if you need full control over the `output` buffer.
pub fn hash_raw(&mut self, input: &[u8]) -> <H as Hasher>::Output
where
H: Hasher,
{
<Self as scale::Output>::write(self, input);
self.finalize()
}
/// Conducts the hash for the encoded input. /// Conducts the hash for the encoded input.
/// ///
/// Puts the resulting hash into the provided output buffer. /// Puts the resulting hash into the provided output buffer.
......
...@@ -23,14 +23,17 @@ pub use self::{ ...@@ -23,14 +23,17 @@ pub use self::{
Accumulator, Accumulator,
Wrap, Wrap,
}, },
builder::HashBuilder, builder::{
HashBuilder,
NoAccumulator,
},
}; };
/// SHA2 256-bit hash builder. /// SHA2 256-bit hash builder.
pub type Sha2x256<S> = HashBuilder<hasher::Sha2x256Hasher, S>; pub type Sha2x256<S = NoAccumulator> = HashBuilder<hasher::Sha2x256Hasher, S>;
/// KECCAK 256-bit hash builder. /// KECCAK 256-bit hash builder.
pub type Keccak256<S> = HashBuilder<hasher::Keccak256Hasher, S>; pub type Keccak256<S = NoAccumulator> = HashBuilder<hasher::Keccak256Hasher, S>;
/// BLAKE2 256-bit hash builder. /// BLAKE2 256-bit hash builder.
pub type Blake2x256<S> = HashBuilder<hasher::Blake2x256Hasher, S>; pub type Blake2x256<S = NoAccumulator> = HashBuilder<hasher::Blake2x256Hasher, S>;
/// BLAKE2 128-bit hash builder. /// BLAKE2 128-bit hash builder.
pub type Blake2x128<S> = HashBuilder<hasher::Blake2x128Hasher, S>; pub type Blake2x128<S = NoAccumulator> = HashBuilder<hasher::Blake2x128Hasher, S>;
...@@ -25,7 +25,6 @@ mod runtime { ...@@ -25,7 +25,6 @@ mod runtime {
use ink_prelude::{ use ink_prelude::{
format, format,
vec, vec,
vec::Vec,
}; };
use scale::{ use scale::{
Decode, Decode,
...@@ -83,10 +82,8 @@ mod runtime { ...@@ -83,10 +82,8 @@ mod runtime {
185, 157, 136, 14, 198, 129, 121, 156, 12, 243, 14, 136, 134, 55, 29, 169, 185, 157, 136, 14, 198, 129, 121, 156, 12, 243, 14, 136, 134, 55, 29, 169,
]; ];
let encoded_account = &account.encode(); let encoded_account = account.encode();
let hashed_account = <Blake2x128>::hash_bytes(&encoded_account);
let mut blake2_128 = Blake2x128::from(Vec::new());
let hashed_account = blake2_128.hash_raw(&encoded_account);
// The hasher is `Blake2_128Concat` which appends the unhashed account to the hashed account // The hasher is `Blake2_128Concat` which appends the unhashed account to the hashed account
key.extend_from_slice(&hashed_account); key.extend_from_slice(&hashed_account);
...@@ -146,8 +143,7 @@ mod runtime { ...@@ -146,8 +143,7 @@ mod runtime {
185, 157, 136, 14, 198, 129, 121, 156, 12, 243, 14, 136, 134, 55, 29, 169, 185, 157, 136, 14, 198, 129, 121, 156, 12, 243, 14, 136, 134, 55, 29, 169,
]; ];
let mut blake2_128 = Blake2x128::from(Vec::new()); let hashed_account = <Blake2x128>::hash_bytes(&encoded_account);
let hashed_account = blake2_128.hash_raw(&encoded_account);
key.extend_from_slice(&hashed_account); key.extend_from_slice(&hashed_account);
key.extend_from_slice(&encoded_account); key.extend_from_slice(&encoded_account);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment