rose-squared-sdk 0.1.0

Privacy-preserving encrypted search SDK implementing the SWiSSSE protocol with forward/backward security and volume-hiding, compilable to WebAssembly
Documentation
use rand::Rng;
use rose_squared_sdk::crypto::kdf::MasterKeySet;
use rose_squared_sdk::server::edb::MockStore;
use rose_squared_sdk::{PrivacyVault, VolumeConfig};
use std::time::Instant;
use uuid::Uuid;

#[tokio::main]
async fn main() {
    println!("Benchmarking RO(SE)² Vault...");

    let salt = [0u8; 16];
    let store = MockStore::new();
    
    // 1. Unpadded (Bare RO(SE)²) config
    let mut bare_config = VolumeConfig::default();
    bare_config.n_max = 1; // Essentially disables padding overhead 
    
    let mut vault = PrivacyVault::new("test-password", &salt, bare_config).unwrap();

    // Bench: add_document (1)
    let doc_id = Uuid::new_v4();
    let start = Instant::now();
    vault.add_document(&["test1"], doc_id, &store).await.unwrap();
    let add_1 = start.elapsed();
    println!("add_document (1): {:?}", add_1);

    // Bench: add_document (10,000)
    let mut docs10k = vec![];
    for _ in 0..10_000 {
        docs10k.push(Uuid::new_v4());
    }
    let start = Instant::now();
    for d in &docs10k {
        vault.add_document(&["bulk_test"], *d, &store).await.unwrap();
    }
    let add_10k = start.elapsed();
    println!("add_document (10,000): {:?}", add_10k);

    // Bench: search (10 results)
    let mut config10 = VolumeConfig::default();
    config10.n_max = 10;
    let mut vault10 = PrivacyVault::new("test", &salt, config10).unwrap();
    for _ in 0..10 {
        vault10.add_document(&["search_10"], Uuid::new_v4(), &store).await.unwrap();
    }
    let start = Instant::now();
    let _ = vault10.search("search_10", &store).await.unwrap();
    let search_10 = start.elapsed();
    println!("search (10 results): {:?}", search_10);

    // Bench: search (100 results)
    let mut config100 = VolumeConfig::default();
    config100.n_max = 100;
    let mut vault100 = PrivacyVault::new("test", &salt, config100).unwrap();
    for _ in 0..100 {
        vault100.add_document(&["search_100"], Uuid::new_v4(), &store).await.unwrap();
    }
    let start = Instant::now();
    let _ = vault100.search("search_100", &store).await.unwrap();
    let search_100 = start.elapsed();
    println!("search (100 results): {:?}", search_100);

    // Bench: delete_document (10 remaining results)
    let del_target = Uuid::new_v4();
    vault10.add_document(&["del_10"], del_target, &store).await.unwrap();
    let start = Instant::now();
    vault10.delete_document("del_10", del_target, &store).await.unwrap();
    let del_10 = start.elapsed();
    println!("delete_document (10 remaining results): {:?}", del_10);

    // Bench: delete_document (100 remaining results)
    let del_target100 = Uuid::new_v4();
    vault100.add_document(&["del_100"], del_target100, &store).await.unwrap();
    let start = Instant::now();
    vault100.delete_document("del_100", del_target100, &store).await.unwrap();
    let del_100 = start.elapsed();
    println!("delete_document (100 remaining results): {:?}", del_100);

    // Bench: VH-add
    let mut padded_config = VolumeConfig::default();
    padded_config.n_max = 256; 
    let mut padded_vault = PrivacyVault::new("test-password", &salt, padded_config).unwrap();
    let vh_target = Uuid::new_v4();
    let start = Instant::now();
    padded_vault.add_document(&["vh_test"], vh_target, &store).await.unwrap();
    let vh_add = start.elapsed();
    println!("VH-add (Novelty, N_max=256): {:?}", vh_add);

    // Bench: VH-search
    for _ in 0..100 {
        padded_vault.add_document(&["vh_search"], Uuid::new_v4(), &store).await.unwrap();
    }
    let start = Instant::now();
    let _ = padded_vault.search("vh_search", &store).await.unwrap();
    let vh_search = start.elapsed();
    println!("VH-search (Novelty, N_max=256, 100 items): {:?}", vh_search);
}