Struct OutputReader

struct OutputReader { ... }

An incremental reader for extended output, returned by Hasher::finalize_xof.

Shorter BLAKE3 outputs are prefixes of longer ones, and explicitly requesting a short output is equivalent to truncating the default-length output. Note that this is a difference between BLAKE2 and BLAKE3.

Security notes

Outputs shorter than the default length of 32 bytes (256 bits) provide less security. An N-bit BLAKE3 output is intended to provide N bits of first and second preimage resistance and N/2 bits of collision resistance, for any N up to 256. Longer outputs don't provide any additional security.

Avoid relying on the secrecy of the output offset, that is, the number of output bytes read or the arguments to seek or set_position. Block-Cipher-Based Tree Hashing by Aldo Gunsing shows that an attacker who knows both the message and the key (if any) can easily determine the offset of an extended output. For comparison, AES-CTR has a similar property: if you know the key, you can decrypt a block from an unknown position in the output stream to recover its block index. Callers with strong secret keys aren't affected in practice, but secret offsets are a design smell in any case.

Implementations

impl OutputReader

fn fill(self: &mut Self, buf: &mut [u8])

Fill a buffer with output bytes and advance the position of the OutputReader. This is equivalent to Read::read, except that it doesn't return a Result. Both methods always fill the entire buffer.

Note that OutputReader doesn't buffer output bytes internally, so calling fill repeatedly with a short-length or odd-length slice will end up performing the same compression multiple times. If you're reading output in a loop, prefer a slice length that's a multiple of 64.

The maximum output size of BLAKE3 is 264-1 bytes. If you try to extract more than that, for example by seeking near the end and reading further, the behavior is unspecified.

fn position(self: &Self) -> u64

Return the current read position in the output stream. This is equivalent to Seek::stream_position, except that it doesn't return a Result. The position of a new OutputReader starts at 0, and each call to fill or Read::read moves the position forward by the number of bytes read.

fn set_position(self: &mut Self, position: u64)

Seek to a new read position in the output stream. This is equivalent to calling Seek::seek with SeekFrom::Start, except that it doesn't return a Result.

impl Clone for OutputReader

fn clone(self: &Self) -> OutputReader

impl Debug for OutputReader

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

impl Freeze for OutputReader

impl Read for OutputReader

fn read(self: &mut Self, buf: &mut [u8]) -> std::io::Result<usize>

impl RefUnwindSafe for OutputReader

impl Seek for OutputReader

fn seek(self: &mut Self, pos: std::io::SeekFrom) -> std::io::Result<u64>

impl Send for OutputReader

impl Sync for OutputReader

impl Unpin for OutputReader

impl UnwindSafe for OutputReader

impl<T> Any for OutputReader

fn type_id(self: &Self) -> TypeId

impl<T> Borrow for OutputReader

fn borrow(self: &Self) -> &T

impl<T> BorrowMut for OutputReader

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

impl<T> CloneToUninit for OutputReader

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

impl<T> From for OutputReader

fn from(t: T) -> T

Returns the argument unchanged.

impl<T> ToOwned for OutputReader

fn to_owned(self: &Self) -> T
fn clone_into(self: &Self, target: &mut T)

impl<T, U> Into for OutputReader

fn into(self: Self) -> U

Calls U::from(self).

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

impl<T, U> TryFrom for OutputReader

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

impl<T, U> TryInto for OutputReader

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