snapper-box 0.0.4

Cryptographic storage for snapper
Documentation
use chacha20::{
    cipher::{NewCipher, StreamCipher},
    XChaCha20,
};
use criterion::{black_box, criterion_group, criterion_main, Criterion, Throughput};
use snapper_box::crypto::{ClearText, DerivedKey, Key, Nonce, RootKey};

fn derive(x: &RootKey) -> DerivedKey {
    x.derive("0123456789ABCDEF")
}

fn key_derivation(c: &mut Criterion) {
    // Make a root key and leak it, since we aren't benchmarking key creation time
    let root_key: &'static RootKey = Box::leak(Box::new(RootKey::random()));
    let mut group = c.benchmark_group("Key Derivation");
    group.throughput(Throughput::Elements(1));
    group.bench_function("RootKey::derive", |b| {
        b.iter(|| derive(black_box(root_key)))
    });
    // Test raw blake3 performance
    let data: &'static [u8; 256] = &[0_u8; 256];
    let context_string: &'static str =
        "snapper-box nonce: JAEi7eJ9WsdC7LR5xO9kRINecjxLTbn7 namespace: namespace";
    group.bench_function("blake3::derive_key", |b| {
        b.iter(|| blake3::derive_key(context_string, data))
    });
}

fn encryption(c: &mut Criterion) {
    // Make a root key and leak it, since we aren't benchmarking key creation time
    let root_key: &'static RootKey = Box::leak(Box::new(RootKey::random()));
    let nonce: &'static Nonce = Box::leak(Box::new(Nonce::random()));
    let data: &'static [u8] = &[0_u8; 4096];
    let mut group = c.benchmark_group("Encryption");
    // Encrypt 4kiB at a time
    group.throughput(Throughput::Bytes(4096));
    // First do the library function
    group.bench_function("CipherText::encrypt", |b| {
        b.iter(|| {
            ClearText::new(black_box(&data))
                .unwrap()
                .encrypt(root_key, None)
        })
    });
    // Then raw XChaCha20
    group.bench_function("XChaCha20", |b| {
        b.iter(|| {
            let mut data = [0_u8; 4096];
            let mut chacha = XChaCha20::new(root_key.encryption_key(), nonce.nonce());
            chacha.apply_keystream(&mut data[..]);
        })
    });
    // Then raw blake3
    group.bench_function("Blake3", |b| {
        b.iter(|| blake3::keyed_hash(root_key.hmac_key(), data))
    });
    // raw encrypt + verify
    group.bench_function("XChaCha20 + Blake3", |b| {
        b.iter(|| {
            let mut data = [0_u8; 4096];
            let mut chacha = XChaCha20::new(root_key.encryption_key(), nonce.nonce());
            chacha.apply_keystream(&mut data[..]);
            blake3::keyed_hash(root_key.hmac_key(), &data)
        })
    });
}

criterion_group!(benches, key_derivation, encryption);
criterion_main!(benches);