ICH: Replace old, transitive metadata hashing with direct hashing approach.

Instead of collecting all potential inputs to some metadata entry and
hashing those, we directly hash the values we are storing in metadata.
This is more accurate and doesn't suffer from quadratic blow-up when
many entries have the same dependencies.
This commit is contained in:
Michael Woerister 2017-04-05 23:39:02 +02:00
parent bc7af816f3
commit ca2dce9b48
27 changed files with 689 additions and 341 deletions

View file

@ -29,16 +29,23 @@ pub struct Blake2bCtx {
t: [u64; 2],
c: usize,
outlen: u16,
finalized: bool
finalized: bool,
#[cfg(debug_assertions)]
fnv_hash: u64,
}
#[cfg(debug_assertions)]
impl ::std::fmt::Debug for Blake2bCtx {
fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
try!(write!(fmt, "hash: "));
for v in &self.h {
try!(write!(fmt, "{:x}", v));
}
Ok(())
fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(fmt, "{:x}", self.fnv_hash)
}
}
#[cfg(not(debug_assertions))]
impl ::std::fmt::Debug for Blake2bCtx {
fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(fmt, "Enable debug_assertions() for more info.")
}
}
@ -157,6 +164,9 @@ fn blake2b_new(outlen: usize, key: &[u8]) -> Blake2bCtx {
c: 0,
outlen: outlen as u16,
finalized: false,
#[cfg(debug_assertions)]
fnv_hash: 0xcbf29ce484222325,
};
ctx.h[0] ^= 0x01010000 ^ ((key.len() << 8) as u64) ^ (outlen as u64);
@ -194,6 +204,16 @@ fn blake2b_update(ctx: &mut Blake2bCtx, mut data: &[u8]) {
checked_mem_copy(data, &mut ctx.b[ctx.c .. ], bytes_to_copy);
ctx.c += bytes_to_copy;
}
#[cfg(debug_assertions)]
{
// compute additional FNV hash for simpler to read debug output
const MAGIC_PRIME: u64 = 0x00000100000001b3;
for &byte in data {
ctx.fnv_hash = (ctx.fnv_hash ^ byte as u64).wrapping_mul(MAGIC_PRIME);
}
}
}
fn blake2b_final(ctx: &mut Blake2bCtx)

View file

@ -40,6 +40,7 @@
#![feature(discriminant_value)]
#![feature(specialization)]
#![feature(manually_drop)]
#![feature(struct_field_attributes)]
#![cfg_attr(unix, feature(libc))]
#![cfg_attr(test, feature(test))]

View file

@ -40,13 +40,18 @@ fn write_signed_leb128_to_buf(buf: &mut [u8; 16], value: i64) -> usize {
/// This hasher currently always uses the stable Blake2b algorithm
/// and allows for variable output lengths through its type
/// parameter.
#[derive(Debug)]
pub struct StableHasher<W> {
state: Blake2bHasher,
bytes_hashed: u64,
width: PhantomData<W>,
}
impl<W: StableHasherResult> ::std::fmt::Debug for StableHasher<W> {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
write!(f, "{:?}", self.state)
}
}
pub trait StableHasherResult: Sized {
fn finish(hasher: StableHasher<Self>) -> Self;
}