#![allow(clippy::type_complexity)]
use crate::generic::{BabInstantiation, digest::BabDigest};
pub fn batch_hash<
const WIDTH: usize,
const CHUNK_SIZE: usize,
HashChunkContext,
HashInnerContext,
>(
bab_instantiation: &BabInstantiation<WIDTH, CHUNK_SIZE, HashChunkContext, HashInnerContext>,
bytes: &[u8],
out: &mut BabDigest<WIDTH>,
) {
do_batch_hash::<WIDTH, CHUNK_SIZE, _, _>(bab_instantiation, bytes, &mut out.0, true);
}
fn do_batch_hash<
const WIDTH: usize,
const CHUNK_SIZE: usize,
HashChunkContext,
HashInnerContext,
>(
bab_instantiation: &BabInstantiation<WIDTH, CHUNK_SIZE, HashChunkContext, HashInnerContext>,
bytes: &[u8],
out: &mut [u8; WIDTH],
is_root: bool,
) {
if bytes.len() <= CHUNK_SIZE {
(bab_instantiation.hash_chunk)(bytes, is_root, &bab_instantiation.hash_chunk_context, out);
} else {
let mut left_child_label = [0; WIDTH];
let mut right_child_label = [0; WIDTH];
let left_len = if bytes.len().is_power_of_two() {
bytes.len() / 2
} else {
1 << bytes.len().ilog2()
};
do_batch_hash::<WIDTH, CHUNK_SIZE, _, _>(
bab_instantiation,
&bytes[..left_len],
&mut left_child_label,
false,
);
do_batch_hash::<WIDTH, CHUNK_SIZE, _, _>(
bab_instantiation,
&bytes[left_len..],
&mut right_child_label,
false,
);
(bab_instantiation.hash_inner)(
&left_child_label,
&right_child_label,
bytes.len() as u64,
is_root,
&bab_instantiation.hash_inner_context,
out,
);
}
}