clock-hash 1.0.0

ClockHash-256: Consensus hash function for ClockinChain
Documentation
//! Comprehensive benchmarking suite for ClockHash-256
//!
//! This module provides detailed performance benchmarks for all ClockHash-256
//! components including one-shot hashing, incremental hashing, domain separation,
//! and individual cryptographic primitives.

use clock_hash::{
    ClockHasher, DomainTag, clockhash256, clockhash256_domain, clockhash256_with_domain, tags,
};
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use std::hint::black_box;

/// Benchmark one-shot hashing with various input sizes
fn bench_oneshot_hashing(c: &mut Criterion) {
    let mut group = c.benchmark_group("oneshot_hashing");

    // Test different input sizes from small to large
    let sizes = [0, 1, 16, 64, 256, 1024, 4096, 16384, 65536, 262144, 1048576];

    for &size in &sizes {
        let data = vec![0x42u8; size]; // Fill with pattern for consistent benchmarking

        group.bench_with_input(BenchmarkId::from_parameter(size), &data, |b, data| {
            b.iter(|| {
                let hash = clockhash256(black_box(data));
                black_box(hash);
            });
        });
    }

    group.finish();
}

/// Benchmark incremental hashing
fn bench_incremental_hashing(c: &mut Criterion) {
    let mut group = c.benchmark_group("incremental_hashing");

    let sizes = [1024, 4096, 16384, 65536, 262144];

    for &size in &sizes {
        let data = vec![0x42u8; size];

        group.bench_with_input(BenchmarkId::from_parameter(size), &data, |b, data| {
            b.iter(|| {
                let mut hasher = ClockHasher::new();
                hasher.update(black_box(data));
                let hash = hasher.finalize();
                black_box(hash);
            });
        });
    }

    group.finish();
}

/// Benchmark chunked incremental hashing (simulating streaming)
fn bench_chunked_hashing(c: &mut Criterion) {
    let mut group = c.benchmark_group("chunked_hashing");

    let total_size = 65536; // 64KB total
    let chunk_sizes = [1024, 4096, 8192];

    for &chunk_size in &chunk_sizes {
        let data = vec![0x42u8; total_size];
        let chunks: Vec<&[u8]> = data.chunks(chunk_size).collect();

        group.bench_with_input(
            BenchmarkId::from_parameter(format!("{}_chunks", chunk_size)),
            &chunks,
            |b, chunks| {
                b.iter(|| {
                    let mut hasher = ClockHasher::new();
                    for chunk in chunks.iter() {
                        hasher.update(black_box(chunk));
                    }
                    let hash = hasher.finalize();
                    black_box(hash);
                });
            },
        );
    }

    group.finish();
}

/// Benchmark domain separation performance
fn bench_domain_separation(c: &mut Criterion) {
    let mut group = c.benchmark_group("domain_separation");

    let data = vec![0x42u8; 4096]; // 4KB test data
    let domains = [
        ("CLK_BLOCK", tags::CLK_BLOCK),
        ("CLK_TX", tags::CLK_TX),
        ("CLK_MERKLE", tags::CLK_MERKLE),
        ("CLK_NONCE", tags::CLK_NONCE),
        ("CLK_RNG", tags::CLK_RNG),
    ];

    for (name, domain) in &domains {
        group.bench_with_input(
            BenchmarkId::from_parameter(*name),
            &(domain, &data),
            |b, (domain, data)| {
                b.iter(|| {
                    let hash = clockhash256_domain(black_box(domain), black_box(data));
                    black_box(hash);
                });
            },
        );
    }

    group.finish();
}

/// Benchmark typed domain separation
fn bench_typed_domain_separation(c: &mut Criterion) {
    let mut group = c.benchmark_group("typed_domain_separation");

    let data = vec![0x42u8; 4096];
    let domains = [
        ("Block", DomainTag::Block),
        ("Transaction", DomainTag::Transaction),
        ("Merkle", DomainTag::Merkle),
        ("Nonce", DomainTag::Nonce),
        ("Rng", DomainTag::Rng),
    ];

    for (name, domain) in &domains {
        group.bench_with_input(
            BenchmarkId::from_parameter(*name),
            &(*domain, &data),
            |b, (domain, data)| {
                b.iter(|| {
                    let hash = clockhash256_with_domain(black_box(*domain), black_box(data));
                    black_box(hash);
                });
            },
        );
    }

    group.finish();
}

/// Benchmark comparison: domain separation vs regular hashing
fn bench_domain_vs_regular(c: &mut Criterion) {
    let mut group = c.benchmark_group("domain_vs_regular");

    let data = vec![0x42u8; 8192];

    group.bench_function("regular_hash", |b| {
        b.iter(|| {
            let hash = clockhash256(black_box(&data));
            black_box(hash);
        });
    });

    group.bench_function("domain_hash", |b| {
        b.iter(|| {
            let hash = clockhash256_domain(black_box(tags::CLK_BLOCK), black_box(&data));
            black_box(hash);
        });
    });

    group.finish();
}

/// Benchmark empty input (padding overhead)
fn bench_empty_input(c: &mut Criterion) {
    let mut group = c.benchmark_group("empty_input");

    group.bench_function("empty_oneshot", |b| {
        b.iter(|| {
            let hash = clockhash256(black_box(&[]));
            black_box(hash);
        });
    });

    group.bench_function("empty_incremental", |b| {
        b.iter(|| {
            let hasher = ClockHasher::new();
            let hash = hasher.finalize();
            black_box(hash);
        });
    });

    group.finish();
}

/// Benchmark throughput for large inputs
fn bench_throughput(c: &mut Criterion) {
    let mut group = c.benchmark_group("throughput");
    group.throughput(criterion::Throughput::Elements(1048576)); // 1MB

    let data = vec![0x42u8; 1048576]; // 1MB

    group.bench_function("1MB_oneshot", |b| {
        b.iter(|| {
            let hash = clockhash256(black_box(&data));
            black_box(hash);
        });
    });

    group.finish();
}

/// Benchmark construction overhead
fn bench_construction(c: &mut Criterion) {
    let mut group = c.benchmark_group("construction");

    group.bench_function("new_hasher", |b| {
        b.iter(|| {
            let hasher = ClockHasher::new();
            black_box(hasher);
        });
    });

    group.finish();
}

/// Benchmark SIMD-accelerated hashing performance
///
/// This benchmark compares hashing performance with SIMD acceleration enabled.
/// On systems with AVX2/AVX-512 support, this will use vectorized implementations.
/// On systems without SIMD support, it falls back to scalar implementations.
///
/// The benchmark shows the real-world performance impact of SIMD acceleration.
fn bench_simd_accelerated_hashing(c: &mut Criterion) {
    let mut group = c.benchmark_group("simd_accelerated_hashing");

    // Test various input sizes to show SIMD scaling
    let sizes = [1024, 4096, 16384, 65536];

    for &size in &sizes {
        let data = vec![0x42u8; size];

        group.bench_with_input(
            BenchmarkId::from_parameter(format!("{}_bytes_simd", size)),
            &data,
            |b, data| {
                b.iter(|| {
                    let hash = clockhash256(black_box(data));
                    black_box(hash);
                });
            },
        );
    }

    group.finish();
}

/// Benchmark incremental hashing with SIMD acceleration
fn bench_simd_incremental_hashing(c: &mut Criterion) {
    let mut group = c.benchmark_group("simd_incremental_hashing");

    let sizes = [4096, 16384, 65536];

    for &size in &sizes {
        let data = vec![0x42u8; size];
        let chunks: Vec<&[u8]> = data.chunks(1024).collect();

        group.bench_with_input(
            BenchmarkId::from_parameter(format!("{}_bytes_chunked_simd", size)),
            &chunks,
            |b, chunks| {
                b.iter(|| {
                    let mut hasher = ClockHasher::new();
                    for chunk in chunks.iter() {
                        hasher.update(black_box(chunk));
                    }
                    let hash = hasher.finalize();
                    black_box(hash);
                });
            },
        );
    }

    group.finish();
}

criterion_group!(
    benches,
    bench_oneshot_hashing,
    bench_incremental_hashing,
    bench_chunked_hashing,
    bench_domain_separation,
    bench_typed_domain_separation,
    bench_domain_vs_regular,
    bench_empty_input,
    bench_throughput,
    bench_construction,
    bench_simd_accelerated_hashing,
    bench_simd_incremental_hashing,
);
criterion_main!(benches);