Skip to main content

Hasher

Struct Hasher 

Source
pub struct Hasher { /* private fields */ }
Expand description

A message’s hash, fed in pieces: update with each piece, in order, then finalize. The pieces may be of any lengths; the hash is the same as hash of them all at once.

A Hasher is about 18 KiB (it holds short pieces until it has 16 KiB to hash at once); box it where that matters.

§Examples

// Hash an input incrementally.
let mut hasher = blake3_servil::Hasher::new();
hasher.update(b"foo");
hasher.update(b"bar");
hasher.update(b"baz");
assert_eq!(hasher.finalize(), blake3_servil::hash(b"foobarbaz"));

// Extended output. OutputReader also implements Read and Seek.
let mut output = [0; 1000];
let mut output_reader = hasher.finalize_xof();
output_reader.fill(&mut output);
assert_eq!(&output[..32], blake3_servil::hash(b"foobarbaz").as_bytes());

Implementations§

Source§

impl Hasher

Many messages arriving at once, such as a server’s uploads, each with its own Hasher: one call takes the pieces that have arrived for all of them, which hash faster together than one update each.

Source

pub fn update_each(hashers: &mut [Hasher], pieces: &[(usize, &[u8])])

Feed each piece to its hasher: (i, bytes) does hashers[i].update(bytes), each hasher’s pieces in their order in pieces. Call it once with all the pieces your program has in hand (one turn of its event loop): never slower than one update each. Requires each i < hashers.len().

use blake3_servil::Hasher;
let mut hashers = vec![Hasher::new(), Hasher::new()];
Hasher::update_each(&mut hashers, &[(0, b"ab"), (1, b"xyz"), (0, b"c")]);
let mut out = [[0u8; 32]; 2];
Hasher::finalize_each(&hashers, &[0, 1], &mut out);
assert_eq!((&out[0], &out[1]), (blake3_servil::hash(b"abc").as_bytes(), blake3_servil::hash(b"xyz").as_bytes()));
Source

pub fn update_each_multithreaded( hashers: &mut [Hasher], pieces: &[(usize, &[u8])], )

update_each, using other CPU cores where that is faster (pieces of 512 KiB and more): the same result, never slower. Requires each i < hashers.len().

Source

pub fn finalize_each(hashers: &[Hasher], which: &[usize], out: &mut [[u8; 32]])

The hash of each message which names: out[k] is hashers[which[k]].finalize(). Requires out.len() == which.len() and each index < hashers.len().

Source§

impl Hasher

Source

pub fn new() -> Self

Construct a new Hasher for the regular hash function.

Source

pub fn new_with(mode: Mode<'_>) -> Self

Construct a new Hasher in a Mode: the keyed hash, or key derivation with a context string or a context hashed once.

Source

pub fn reset(&mut self) -> &mut Self

Reset the Hasher to its initial state.

This is functionally the same as overwriting the Hasher with a new one, using the same key or context string if any.

Source

pub fn update(&mut self, input: &[u8]) -> &mut Self

Add the message’s next piece, of any length, on the calling thread.

Speed: pieces of any size hash at nearly the speed of whole buffers: short pieces are copied into the Hasher until it holds 16 KiB, which then hash at once. Pieces of 16 KiB and more, starting at a multiple of 16 KiB of the message, skip the copy (about 5% of the time on an Apple M4). For a whole message in memory, hash is a little faster; for a file or reader, see update_reader.

Source

pub fn update_multithreaded(&mut self, input: &[u8]) -> &mut Self

update, using other CPU cores where that is faster: the same result, never slower. Pieces of 512 KiB and more use them, as hash_multithreaded does; shorter ones hash on the calling thread. One Hasher may mix the two calls. When reading the pieces keeps your thread busy, a stream is faster (Stream::submit_reader, or Stream::submit_with): it hashes each piece while your thread reads the next.

let input = vec![7u8; 3 << 20];
let mut hasher = blake3_servil::Hasher::new();
for piece in input.chunks(64 * 1024) {
    hasher.update_multithreaded(piece);
}
assert_eq!(hasher.finalize(), blake3_servil::hash(&input));
Source

pub fn finalize(&self) -> Hash

Finalize the hash state and return the Hash of the input.

This method is idempotent. Calling it twice will give the same result. You can also add more input and finalize again.

Source

pub fn finalize_xof(&self) -> OutputReader ⓘ

Finalize the hash state and return an OutputReader, which can supply any number of output bytes.

This method is idempotent. Calling it twice will give the same result. You can also add more input and finalize again.

Source

pub fn count(&self) -> u64

The number of bytes passed to update so far.

Source

pub fn update_reader(&mut self, reader: impl Read) -> Result<&mut Self>

As update, but reading from a std::io::Read implementation.

Hasher implements std::io::Write, so it’s possible to use std::io::copy to update a Hasher from any reader. Unfortunately, this standard approach can limit performance, because copy currently uses an internal 8 KiB buffer that isn’t big enough to take advantage of all SIMD instruction sets. (In particular, AVX-512 needs a 16 KiB buffer.) update_reader avoids this performance problem and is slightly more convenient.

The internal buffer size this method uses may change at any time, and it may be different for different targets. The only guarantee is that it will be large enough for all of this crate’s SIMD implementations on the current platform.

The most common implementer of std::io::Read might be std::fs::File.

This method requires the std Cargo feature, which is enabled by default.

§Example
// Hash standard input.
let mut hasher = blake3_servil::Hasher::new();
hasher.update_reader(std::io::stdin().lock())?;
println!("{}", hasher.finalize());

Trait Implementations§

Source§

impl Clone for Hasher

Source§

fn clone(&self) -> Hasher ⓘ

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Hasher

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Hasher

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Write for Hasher

Available on crate feature std only.
Source§

fn write(&mut self, input: &[u8]) -> Result<usize>

This is equivalent to update.

Source§

fn flush(&mut self) -> Result<()>

Flushes this output stream, ensuring that all intermediately buffered contents reach their destination. Read more
1.36.0 · Source§

fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize, Error>

Like write, except that it writes from a slice of buffers. Read more
Source§

fn is_write_vectored(&self) -> bool

🔬This is a nightly-only experimental API. (can_vector)
Determines if this Writer has an efficient write_vectored implementation. Read more
1.0.0 · Source§

fn write_all(&mut self, buf: &[u8]) -> Result<(), Error>

Attempts to write an entire buffer into this writer. Read more
Source§

fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> Result<(), Error>

🔬This is a nightly-only experimental API. (write_all_vectored)
Attempts to write multiple buffers into this writer. Read more
1.0.0 · Source§

fn write_fmt(&mut self, args: Arguments<'_>) -> Result<(), Error>

Writes a formatted string into this writer, returning any error encountered. Read more
1.0.0 · Source§

fn by_ref(&mut self) -> &mut Self
where Self: Sized,

Creates a “by reference” adapter for this instance of Write. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.