Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ derive = ["multihash-derive"]
arb = ["quickcheck", "rand"]
secure-hashes = ["blake2b", "blake2s", "blake3", "sha2", "sha3"]
scale-codec = ["parity-scale-codec"]
serde-codec = ["serde", "generic-array/serde"]
serde-codec = ["serde"]

blake2b = ["blake2b_simd"]
blake2s = ["blake2s_simd"]
Expand All @@ -32,7 +32,6 @@ sha3 = ["digest", "sha-3"]
strobe = ["strobe-rs"]

[dependencies]
generic-array = "0.14.4"
parity-scale-codec = { version = "1.3.5", optional = true, default-features = false, features = ["derive"] }
quickcheck = { version = "0.9.2", optional = true }
rand = { version = "0.7.3", optional = true }
Expand Down
4 changes: 2 additions & 2 deletions src/arb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ use rand::{
Rng,
};

use crate::{MultihashGeneric, U64};
use crate::{MultihashGeneric};

/// Generates a random valid multihash.
impl Arbitrary for MultihashGeneric<U64> {
impl Arbitrary for MultihashGeneric<64> {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
// In real world lower multihash codes are more likely to happen, hence distribute them
// with bias towards smaller values.
Expand Down
48 changes: 15 additions & 33 deletions src/hasher.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,13 @@
use crate::error::Error;
use core::fmt::Debug;
use generic_array::typenum::marker_traits::Unsigned;
use generic_array::{ArrayLength, GenericArray};

/// Size marker trait.
pub trait Size:
ArrayLength<u8> + Debug + Default + Eq + core::hash::Hash + Send + Sync + 'static
{
}

impl<T: ArrayLength<u8> + Debug + Default + Eq + core::hash::Hash + Send + Sync + 'static> Size
for T
{
}
use std::usize;

/// Stack allocated digest trait.
pub trait Digest<S: Size>:
pub trait Digest<const S: usize>:
AsRef<[u8]>
+ AsMut<[u8]>
+ From<GenericArray<u8, S>>
+ Into<GenericArray<u8, S>>
+ From<[u8; S]>
+ Into<[u8; S]>
+ Clone
+ core::hash::Hash
+ Debug
Expand All @@ -31,15 +19,15 @@ pub trait Digest<S: Size>:
{
/// Size of the digest.
fn size(&self) -> u8 {
S::to_u8()
S as u8
}

/// Wraps the digest bytes.
fn wrap(digest: &[u8]) -> Result<Self, Error> {
if digest.len() != S::to_usize() {
if digest.len() != S {
return Err(Error::InvalidSize(digest.len() as _));
}
let mut array = GenericArray::default();
let mut array = [0; S];
let len = digest.len().min(array.len());
array[..len].copy_from_slice(&digest[..len]);
Ok(array.into())
Expand All @@ -56,22 +44,20 @@ pub trait Digest<S: Size>:
use unsigned_varint::io::read_u64;

let size = read_u64(&mut r)?;
if size > S::to_u64() || size > u8::max_value() as u64 {
if size > S as u64 || size > u8::max_value() as u64 {
return Err(Error::InvalidSize(size));
}
let mut digest = GenericArray::default();
let mut digest = [0; S];
r.read_exact(&mut digest[..size as usize])?;
Ok(Self::from(digest))
}
}

/// Trait implemented by a hash function implementation.
pub trait StatefulHasher: Default + Send + Sync {
/// The maximum Digest size for that hasher (it is stack allocated).
type Size: Size;
pub trait StatefulHasher<const SIZE: usize>: Default + Send + Sync {

/// The Digest type to distinguish the output of different `Hasher` implementations.
type Digest: Digest<Self::Size>;
type Digest: Digest<SIZE>;

/// Consume input and update internal state.
fn update(&mut self, input: &[u8]);
Expand Down Expand Up @@ -106,16 +92,13 @@ pub trait StatefulHasher: Default + Send + Sync {
/// [Multihashes]: https://github.com/multiformats/multihash
/// [associated type]: https://doc.rust-lang.org/book/ch19-03-advanced-traits.html#specifying-placeholder-types-in-trait-definitions-with-associated-types
/// [`MultihashDigest`]: crate::MultihashDigest
pub trait Hasher: Default + Send + Sync {
/// The maximum Digest size for that hasher (it is stack allocated).
type Size: Size;

pub trait Hasher<const S: usize>: Default + Send + Sync {
/// The Digest type to distinguish the output of different `Hasher` implementations.
type Digest: Digest<Self::Size>;
type Digest: Digest<S>;

/// Returns the allocated size of the digest.
fn size() -> u8 {
Self::Size::to_u8()
S as u8
}

/// Hashes the given `input` data and returns its hash digest.
Expand All @@ -124,8 +107,7 @@ pub trait Hasher: Default + Send + Sync {
Self: Sized;
}

impl<T: StatefulHasher> Hasher for T {
type Size = T::Size;
impl<T: StatefulHasher<S>, const S: usize> Hasher<S> for T{
type Digest = T::Digest;

fn digest(input: &[u8]) -> Self::Digest {
Expand Down
Loading