From cea75d6626e2775472c3f4db6a0c0048f4010af7 Mon Sep 17 00:00:00 2001 From: Nicolas Di Prima Date: Mon, 17 Jan 2022 18:36:43 +0000 Subject: [PATCH] Propose a faster way to hash without allocating a huge chunk of memory --- pallas-alonzo/src/crypto.rs | 42 ++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/pallas-alonzo/src/crypto.rs b/pallas-alonzo/src/crypto.rs index f9d3e94..4951a39 100644 --- a/pallas-alonzo/src/crypto.rs +++ b/pallas-alonzo/src/crypto.rs @@ -1,18 +1,50 @@ use crate::{AuxiliaryData, Header, PlutusData, TransactionBody}; use cryptoxide::blake2b::Blake2b; -use minicbor::{to_vec, Encode}; +use minicbor::Encode; pub type Hash32 = [u8; 32]; pub type Error = Box; +struct Hasher { + inner: Blake2b, +} + +impl Hasher<256> { + #[inline] + fn new() -> Self { + Self { + inner: Blake2b::new(32), + } + } + + #[inline] + fn result(mut self) -> Hash32 { + use cryptoxide::digest::Digest as _; + + let mut hash = [0; 32]; + self.inner.result(&mut hash); + hash + } +} + +impl<'a, const N: usize> minicbor::encode::write::Write for &'a mut Hasher { + type Error = std::convert::Infallible; + + fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> { + use cryptoxide::digest::Digest as _; + self.inner.input(buf); + Ok(()) + } +} + // TODO: think if we should turn this into a blanket implementation of a new // trait fn hash_cbor_encodable(data: &impl Encode) -> Result { - let bytes = to_vec(data)?; - let mut hash = [0; 32]; - Blake2b::blake2b(&mut hash, &bytes[..], &[]); - Ok(hash) + let mut hasher = Hasher::<256>::new(); + let () = minicbor::encode(data, &mut hasher)?; + + Ok(hasher.result()) } pub fn hash_block_header(data: &Header) -> Result {