use criterion::{criterion_group, criterion_main, Criterion};
#[derive(Debug)]
pub enum DigestAlgorithm {
SHA1,
SHA256,
SHA384,
SHA512,
SHA512_256,
}
pub struct DigestConfig {
algorithm: DigestAlgorithm,
}
impl DigestConfig {
#[must_use]
pub fn new(algorithm: DigestAlgorithm) -> DigestConfig {
DigestConfig { algorithm }
}
}
macro_rules! benchmark_digest {
( $pkg:ident ) => {
paste::item! {
mod [<$pkg _benchmarks>] {
use $pkg::{digest};
use std::hint::black_box;
use crate::DigestConfig;
use digest::{Context, Digest};
fn algorithm(config: &crate::DigestConfig) -> &'static digest::Algorithm {
black_box(match &config.algorithm {
crate::DigestAlgorithm::SHA1 => &digest::SHA1_FOR_LEGACY_USE_ONLY,
crate::DigestAlgorithm::SHA256 => &digest::SHA256,
crate::DigestAlgorithm::SHA384 => &digest::SHA384,
crate::DigestAlgorithm::SHA512 => &digest::SHA512,
crate::DigestAlgorithm::SHA512_256 => &digest::SHA512_256
})
}
pub fn run_digest_incremental(config: &DigestConfig, chunk: &[u8]) {
let mut ctx = Context::new(algorithm(&config));
ctx.update(&chunk);
let _: Digest = ctx.finish();
}
#[expect(unused_must_use)]
pub fn run_digest_one_shot(config: &DigestConfig, chunk: &[u8]) {
digest::digest(algorithm(&config), &chunk);
}
}
}
};
}
benchmark_digest!(wolfcrypt_ring_compat);
#[cfg(feature = "ring-benchmarks")]
benchmark_digest!(ring);
fn bench_sha1(c: &mut Criterion) {
let config = DigestConfig::new(DigestAlgorithm::SHA1);
bench_digest_one_shot(c, &config);
bench_digest_incremental(c, &config);
}
fn bench_sha256(c: &mut Criterion) {
let config = DigestConfig::new(DigestAlgorithm::SHA256);
bench_digest_one_shot(c, &config);
bench_digest_incremental(c, &config);
}
fn bench_sha384(c: &mut Criterion) {
let config = DigestConfig::new(DigestAlgorithm::SHA384);
bench_digest_one_shot(c, &config);
bench_digest_incremental(c, &config);
}
fn bench_sha512(c: &mut Criterion) {
let config = DigestConfig::new(DigestAlgorithm::SHA512);
bench_digest_one_shot(c, &config);
bench_digest_incremental(c, &config);
}
fn bench_sha512_256(c: &mut Criterion) {
let config = DigestConfig::new(DigestAlgorithm::SHA512_256);
bench_digest_one_shot(c, &config);
bench_digest_incremental(c, &config);
}
const G_CHUNK_LENGTHS: [usize; 5] = [16, 256, 1350, 8192, 16384];
fn bench_digest_one_shot(c: &mut Criterion, config: &DigestConfig) {
for &chunk_len in &G_CHUNK_LENGTHS {
let chunk = vec![1u8; chunk_len];
let bench_group_name =
format!("DIGEST-{:?}-one-shot-{}-bytes", config.algorithm, chunk_len);
let mut group = c.benchmark_group(bench_group_name);
group.bench_function("wolfcrypt-ring-compat", |b| {
b.iter(|| {
wolfcrypt_ring_compat_benchmarks::run_digest_one_shot(config, &chunk);
});
});
#[cfg(feature = "ring-benchmarks")]
{
group.bench_function("Ring", |b| {
b.iter(|| {
ring_benchmarks::run_digest_one_shot(config, &chunk);
});
});
}
}
}
fn bench_digest_incremental(c: &mut Criterion, config: &DigestConfig) {
for &chunk_len in &G_CHUNK_LENGTHS {
let chunk = vec![1u8; chunk_len];
let bench_group_name = format!(
"DIGEST-{:?}-incremental-{}-bytes",
config.algorithm, chunk_len
);
let mut group = c.benchmark_group(bench_group_name);
group.bench_function("wolfcrypt-ring-compat", |b| {
b.iter(|| {
wolfcrypt_ring_compat_benchmarks::run_digest_incremental(config, &chunk);
});
});
#[cfg(feature = "ring-benchmarks")]
{
group.bench_function("Ring", |b| {
b.iter(|| {
ring_benchmarks::run_digest_incremental(config, &chunk);
});
});
}
}
}
criterion_group!(
benches,
bench_sha1,
bench_sha256,
bench_sha384,
bench_sha512,
bench_sha512_256
);
criterion_main!(benches);