From 5e18126f6a06c8795ecb468ce3f20d3b5788ade4 Mon Sep 17 00:00:00 2001 From: moana Date: Thu, 4 Jul 2024 17:56:09 +0200 Subject: [PATCH] rusk-abi: Generate the BlsScalar hash without truncation --- rusk-abi/src/hash.rs | 53 +++++++++++++++++++++++-------------------- rusk-abi/src/lib.rs | 4 +--- rusk-abi/tests/lib.rs | 4 ++-- 3 files changed, 32 insertions(+), 29 deletions(-) diff --git a/rusk-abi/src/hash.rs b/rusk-abi/src/hash.rs index bf2b9db8b3..6bb95e7e83 100644 --- a/rusk-abi/src/hash.rs +++ b/rusk-abi/src/hash.rs @@ -5,13 +5,13 @@ // Copyright (c) DUSK NETWORK. All rights reserved. use blake2b_simd::{Params, State}; -use dusk_bytes::Serializable; use execution_core::BlsScalar; -/// Hashes scalars and arbitrary slices of bytes using Blake2b-256, returning -/// a valid [`BlsScalar`]. +/// Hashes scalars and arbitrary slices of bytes using Blake2b, returning a +/// valid [`BlsScalar`]. Using the `Hasher` yields the same result as when using +/// `BlsScalar::hash_to_scalar`. /// -/// The hashing cannot be proved inside a circuit, if that is desired, use +/// This hash cannot be proven inside a circuit, if that is desired, use /// `poseidon_hash` instead. pub struct Hasher { state: State, @@ -20,7 +20,7 @@ pub struct Hasher { impl Default for Hasher { fn default() -> Self { Hasher { - state: Params::new().hash_length(BlsScalar::SIZE).to_state(), + state: Params::new().hash_length(64).to_state(), } } } @@ -43,32 +43,37 @@ impl Hasher { hasher } - /// Get the output of the hasher. - pub fn output(self) -> [u8; BlsScalar::SIZE] { - let hasher = self; - let mut buf = [0u8; BlsScalar::SIZE]; - buf.copy_from_slice(hasher.state.finalize().as_ref()); - - // This is a workaround for the fact that `Blake2b` does not support - // bitlengths that are not a multiple of 8. - // We're going to zero out the last nibble of the hash to ensure - // that the result can fit in a `BlsScalar`. - buf[BlsScalar::SIZE - 1] &= 0xf; - - buf - } - /// Retrieve result and consume hasher instance. pub fn finalize(self) -> BlsScalar { - BlsScalar::from_bytes(&self.output()).expect( - "Conversion to BlsScalar should never fail after truncation", - ) + BlsScalar::from_bytes_wide(self.state.finalize().as_array()) } - /// Compute hash of arbitrary data into a valid [`BlsScalar`]. + /// Compute hash of arbitrary data into a valid [`BlsScalar`]. This + /// equivalent to using `BlsScalar::hash_to_scalar`. pub fn digest(data: impl AsRef<[u8]>) -> BlsScalar { let mut hasher = Hasher::new(); hasher.update(data.as_ref()); hasher.finalize() } } + +#[cfg(test)] +mod tests { + use super::*; + use rand_core::{OsRng, RngCore}; + + #[test] + fn test_hash() { + let mut input = [0u8; 100000]; + OsRng.fill_bytes(&mut input[..]); + + let mut hasher = Hasher::new(); + for input_chunk in input.chunks(100) { + hasher.update(input_chunk); + } + let hash = hasher.finalize(); + + assert_eq!(hash, BlsScalar::hash_to_scalar(&input)); + assert_eq!(hash, Hasher::digest(&input)); + } +} diff --git a/rusk-abi/src/lib.rs b/rusk-abi/src/lib.rs index 32814f37c8..986c186e6c 100644 --- a/rusk-abi/src/lib.rs +++ b/rusk-abi/src/lib.rs @@ -66,9 +66,7 @@ const fn reserved(b: u8) -> ContractId { /// Generate a [`ContractId`] address from the given slice of bytes, that is /// also a valid [`BlsScalar`] pub fn gen_contract_id(bytes: &[u8]) -> ContractId { - let mut hasher = Hasher::new(); - hasher.update(bytes); - ContractId::from_bytes(hasher.output()) + ContractId::from_bytes(Hasher::digest(bytes).into()) } /// Converts a `ContractId` to a `BlsScalar` diff --git a/rusk-abi/tests/lib.rs b/rusk-abi/tests/lib.rs index 4e2ffba0e5..9e8070c23a 100644 --- a/rusk-abi/tests/lib.rs +++ b/rusk-abi/tests/lib.rs @@ -43,7 +43,7 @@ fn hash_host() { } assert_eq!( - "0x0e17c56704c3ec2523d206e2e06e08b336e0079bb4c4c5b850d496125f73cdb9", + "0x58c751eca2d6a41227e0c52ef579f4688d698b3447a8bcc27fb2831e11d3239e", format!("{:?}", Hasher::digest(input)) ); } @@ -99,7 +99,7 @@ fn hash() { .data; assert_eq!( - "0x0e17c56704c3ec2523d206e2e06e08b336e0079bb4c4c5b850d496125f73cdb9", + "0x58c751eca2d6a41227e0c52ef579f4688d698b3447a8bcc27fb2831e11d3239e", format!("{scalar:?}") ); }