From 368f4ef468ca97fd4757c896f53349d9fa4def1b Mon Sep 17 00:00:00 2001 From: Urgau Date: Sun, 14 Jul 2024 23:37:13 +0200 Subject: [PATCH] WIP: Blake3 stable hasher --- Cargo.lock | 46 ++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 3 +++ src/blake3.rs | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 9 ++++++++ 4 files changed, 116 insertions(+) create mode 100644 src/blake3.rs diff --git a/Cargo.lock b/Cargo.lock index d0752af..e3de2db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,52 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "blake3" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d08263faac5cde2a4d52b513dadb80846023aade56fcd8fc99ba73ba8050e92" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", +] + +[[package]] +name = "cc" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9711f33475c22aab363b05564a17d7b789bf3dfec5ebabb586adee56f0e271b5" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "constant_time_eq" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" + [[package]] name = "rustc-stable-hash" version = "0.1.0" +dependencies = [ + "blake3", +] diff --git a/Cargo.toml b/Cargo.toml index 976ab8c..c4d14f7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,5 +7,8 @@ readme = "README.md" repository = "https://github.com/rust-lang/rustc-stable-hash" edition = "2021" +[dependencies] +blake3 = { version = "1.5", default-features = false, optional = true } + [features] nightly = [] # for feature(hasher_prefixfree_extras) diff --git a/src/blake3.rs b/src/blake3.rs new file mode 100644 index 0000000..fc1eb48 --- /dev/null +++ b/src/blake3.rs @@ -0,0 +1,58 @@ +//! This is the adapted version of the official Blake 3 implementation providing 256 bit hashes. + +use std::hash::Hasher; + +use crate::ExtendedHasher; + +/// Hash type for the [`Blake3Hash`], providing 256 bit hashses. +pub type Blake3Hash = blake3::Hash; + +/// Blake 3 implementation +#[derive(Debug, Clone)] +pub struct Blake3Hasher { + state: blake3::Hasher, +} + +impl Default for Blake3Hasher { + fn default() -> Blake3Hasher { + Blake3Hasher { + state: Default::default(), + } + } +} + +impl ExtendedHasher for Blake3Hasher { + type Hash = Blake3Hash; + + #[inline] + fn finish(self) -> Self::Hash { + self.state.finalize() + } +} + +impl Hasher for Blake3Hasher { + #[inline] + fn write(&mut self, bytes: &[u8]) { + self.state.update(bytes); + } + + #[inline] + fn finish(&self) -> u64 { + let hash = self.state.finalize(); + + // todo: godbolt + let [a0, a1, a2, a3, a4, a5, a6, a7, b0, b1, b2, b3, b4, b5, b6, b7, c0, c1, c2, c3, c4, c5, c6, c7, d0, d1, d2, d3, d4, d5, d6, d7] = + *hash.as_bytes(); + + let p0 = u64::from_ne_bytes([a0, a1, a2, a3, a4, a5, a6, a7]); + let p1 = u64::from_ne_bytes([b0, b1, b2, b3, b4, b5, b6, b7]); + let p2 = u64::from_ne_bytes([c0, c1, c2, c3, c4, c5, c6, c7]); + let p3 = u64::from_ne_bytes([d0, d1, d2, d3, d4, d5, d6, d7]); + + p0.wrapping_mul(3) + .wrapping_add(p1) + .wrapping_add(p2) + .wrapping_mul(p3) + .to_le() + } +} diff --git a/src/lib.rs b/src/lib.rs index e68d2d1..95d6ac3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,8 @@ #![deny(unsafe_op_in_unsafe_fn)] #![deny(unreachable_pub)] +#[cfg(feature = "blake3")] +mod blake3; mod int_overflow; mod sip128; mod stable_hasher; @@ -14,12 +16,19 @@ pub mod hashers { #[doc(inline)] pub use super::sip128::{SipHasher128, SipHasher128Hash}; + #[cfg(feature = "blake3")] + #[doc(inline)] + pub use super::blake3::{Blake3Hash, Blake3Hasher}; + /// Stable 128-bits Sip Hasher /// /// [`StableHasher`] version of [`SipHasher128`]. /// /// [`StableHasher`]: super::StableHasher pub type StableSipHasher128 = super::StableHasher; + + #[cfg(feature = "blake3")] + pub type StableBlake3Hasher = super::StableHasher; } #[doc(inline)]