#[path = "common/mod.rs"]
mod common;
use std::time::Instant;
fn main() {
let iterations = 1000;
println!("envseal benchmark — {iterations} iterations each\n");
bench_store_decrypt(iterations);
bench_policy_operations(iterations);
bench_hash_binary();
bench_guard_env_check(iterations);
println!("\nAll benchmarks complete.");
}
fn bench_store_decrypt(iterations: usize) {
let dir = common::vault_tempdir();
let key = envseal::keychain::MasterKey::from_test_bytes([0x42; 32]);
let vault = envseal::vault::Vault::open_with_key(dir.path(), key).unwrap();
let start = Instant::now();
for i in 0..iterations {
let name = format!("bench-{i}");
vault
.store(
&name,
b"benchmark-secret-value-that-is-realistic-length-for-api-keys",
false,
)
.unwrap();
}
let store_elapsed = start.elapsed();
println!(
"store: {iterations} ops in {:?} ({:.0} ops/sec)",
store_elapsed,
iterations as f64 / store_elapsed.as_secs_f64()
);
let start = Instant::now();
for i in 0..iterations {
let name = format!("bench-{i}");
let _ = vault.decrypt(&name).unwrap();
}
let decrypt_elapsed = start.elapsed();
println!(
"decrypt: {iterations} ops in {:?} ({:.0} ops/sec)",
decrypt_elapsed,
iterations as f64 / decrypt_elapsed.as_secs_f64()
);
}
fn bench_policy_operations(iterations: usize) {
let mut policy = envseal::policy::Policy::default();
let start = Instant::now();
for i in 0..iterations {
let binary = format!("/usr/bin/app-{i}");
policy.allow_key_with_hash(&binary, "secret", "hash123");
}
let elapsed = start.elapsed();
println!(
"policy allow_key: {iterations} ops in {:?} ({:.0} ops/sec)",
elapsed,
iterations as f64 / elapsed.as_secs_f64()
);
let start = Instant::now();
let mut hits = 0_usize;
for _ in 0..iterations {
if policy.is_authorized("/usr/bin/app-500", "secret") {
hits += 1;
}
}
let elapsed = start.elapsed();
println!(
"policy is_authorized (with {iterations} rules): {iterations} lookups in {elapsed:?} ({:.0} ops/sec, {hits} hits)",
iterations as f64 / elapsed.as_secs_f64()
);
}
fn bench_hash_binary() {
let dir = tempfile::tempdir().unwrap();
let path = dir.path().join("bench-binary");
std::fs::write(&path, vec![0xAB; 1024 * 1024]).unwrap();
let iterations = 100;
let start = Instant::now();
for _ in 0..iterations {
let _ = envseal::guard::hash_binary(&path).unwrap();
}
let elapsed = start.elapsed();
println!(
"hash_binary (1MB): {iterations} ops in {:?} ({:.0} ops/sec)",
elapsed,
iterations as f64 / elapsed.as_secs_f64()
);
}
fn bench_guard_env_check(iterations: usize) {
let saved_ld = std::env::var_os("LD_PRELOAD");
let saved_dbg = std::env::var_os("DEBUGINFOD_URLS");
let saved_ldlib = std::env::var_os("LD_LIBRARY_PATH");
std::env::remove_var("LD_PRELOAD");
std::env::remove_var("DEBUGINFOD_URLS");
std::env::remove_var("LD_LIBRARY_PATH");
let start = Instant::now();
for _ in 0..iterations {
let _ = envseal::guard::assess_environment();
}
let elapsed = start.elapsed();
println!(
"assess_environment: {iterations} ops in {:?} ({:.0} ops/sec)",
elapsed,
iterations as f64 / elapsed.as_secs_f64()
);
if let Some(v) = saved_ld {
std::env::set_var("LD_PRELOAD", v);
}
if let Some(v) = saved_dbg {
std::env::set_var("DEBUGINFOD_URLS", v);
}
if let Some(v) = saved_ldlib {
std::env::set_var("LD_LIBRARY_PATH", v);
}
}