Function blake2b_simd::update4

source ·
pub fn update4(
    state0: &mut State,
    state1: &mut State,
    state2: &mut State,
    state3: &mut State,
    input0: &[u8],
    input1: &[u8],
    input2: &[u8],
    input3: &[u8]
)
Expand description

Update four State objects at the same time.

Without SIMD, this is no different from making four separate calls to update. However, with SIMD, it can be implemented more efficiently. AVX2 is very good at doing four things in parallel, and the regular BLAKE2b implementation is able to take advantage of that somewhat, but actually hashing four separate inputs at once is a more natural fit for the instruction set. This parallel implementation shares its underlying machinery with BLAKE2bp, and like BLAKE2bp is has about double the throughput of serial BLAKE2b.

update4 can only operate in parallel as long as all four inputs still have bytes left. Once one or more of the inputs are exhausted, it falls back to regular serial hashing for the rest. To get the best throughput, try make your inputs roughly the same length.

Note that unlike BLAKE2bp, which is specifically designed to have four lanes, parallel BLAKE2b isn’t tied to any particular number of lanes. When the AVX-512 instruction set becomes more widespread, for example, we could add an update8 implementation to take full advantage of it.

Example

use blake2b_simd::{blake2b, finalize4, update4, State};

let mut state0 = State::new();
let mut state1 = State::new();
let mut state2 = State::new();
let mut state3 = State::new();

update4(
    &mut state0,
    &mut state1,
    &mut state2,
    &mut state3,
    b"foo",
    b"bar",
    b"baz",
    b"bing",
);

let parallel_hashes = finalize4(&mut state0, &mut state1, &mut state2, &mut state3);

let serial_hashes = [
    blake2b(b"foo"),
    blake2b(b"bar"),
    blake2b(b"baz"),
    blake2b(b"bing"),
];
assert_eq!(serial_hashes, parallel_hashes);