use pacha::crypto::{
decrypt_model, encrypt_model, encrypt_model_with_config, get_version, is_encrypted,
EncryptionConfig,
};
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== Pacha Encryption at Rest Demo ===\n");
let model_data = generate_mock_model_data();
println!("Original model size: {} bytes", model_data.len());
println!("\n--- Basic Encryption ---");
demo_basic_encryption(&model_data)?;
println!("\n--- Custom Configuration ---");
demo_custom_config(&model_data)?;
println!("\n--- Format Inspection ---");
demo_format_inspection(&model_data)?;
println!("\n--- Error Handling ---");
demo_error_handling(&model_data)?;
println!("\n=== Demo Complete ===");
Ok(())
}
fn generate_mock_model_data() -> Vec<u8> {
let mut data = Vec::new();
data.extend_from_slice(b"GGUF");
data.extend_from_slice(&[3, 0, 0, 0]); data.extend_from_slice(&[0; 8]); data.extend_from_slice(&[0; 8]);
for i in 0..1000 {
data.push((i % 256) as u8);
}
data
}
fn demo_basic_encryption(model_data: &[u8]) -> Result<(), Box<dyn std::error::Error>> {
let password = "my-secure-password-2024";
println!("Encrypting with password...");
let encrypted = encrypt_model(model_data, password)?;
println!("Encrypted size: {} bytes", encrypted.len());
println!("Overhead: {} bytes (header + auth tag)", encrypted.len() - model_data.len());
assert!(is_encrypted(&encrypted));
println!("File correctly identified as encrypted");
println!("Decrypting...");
let decrypted = decrypt_model(&encrypted, password)?;
assert_eq!(model_data, &decrypted);
println!("Round-trip successful: original == decrypted");
Ok(())
}
fn demo_custom_config(model_data: &[u8]) -> Result<(), Box<dyn std::error::Error>> {
let password = "custom-config-password";
let high_security = EncryptionConfig {
memory_cost_kib: 131072, time_cost: 5,
parallelism: 8,
};
println!("Using high-security config:");
println!(" Memory: {} KiB", high_security.memory_cost_kib);
println!(" Iterations: {}", high_security.time_cost);
println!(" Parallelism: {}", high_security.parallelism);
let encrypted = encrypt_model_with_config(model_data, password, &high_security)?;
println!("Encrypted size: {} bytes", encrypted.len());
let fast_config = EncryptionConfig {
memory_cost_kib: 16384, time_cost: 2,
parallelism: 2,
};
println!("\nUsing fast config:");
println!(" Memory: {} KiB", fast_config.memory_cost_kib);
println!(" Iterations: {}", fast_config.time_cost);
println!(" Parallelism: {}", fast_config.parallelism);
let encrypted_fast = encrypt_model_with_config(model_data, password, &fast_config)?;
println!("Encrypted size: {} bytes", encrypted_fast.len());
Ok(())
}
fn demo_format_inspection(model_data: &[u8]) -> Result<(), Box<dyn std::error::Error>> {
let password = "inspection-password";
let encrypted = encrypt_model(model_data, password)?;
println!("Is original encrypted? {}", is_encrypted(model_data));
println!("Is encrypted file encrypted? {}", is_encrypted(&encrypted));
let version = get_version(&encrypted)?;
println!("Encryption format version: {}", version);
println!("\nEncrypted file structure:");
println!(" Magic: PACHAENC (8 bytes)");
println!(" Version: {} (1 byte)", version);
println!(" Salt: 32 bytes (key derivation)");
println!(" Nonce: 12 bytes (encryption)");
println!(" Data: {} bytes (ciphertext)", model_data.len());
println!(" Tag: 16 bytes (authentication)");
println!(" Total: {} bytes", encrypted.len());
Ok(())
}
fn demo_error_handling(model_data: &[u8]) -> Result<(), Box<dyn std::error::Error>> {
let password = "correct-password";
let encrypted = encrypt_model(model_data, password)?;
println!("Testing wrong password...");
match decrypt_model(&encrypted, "wrong-password") {
Ok(_) => println!(" Unexpectedly succeeded!"),
Err(e) => println!(" Correctly failed: {}", e),
}
println!("Testing corrupted data...");
let mut corrupted = encrypted.clone();
corrupted[60] ^= 0xFF; match decrypt_model(&corrupted, password) {
Ok(_) => println!(" Unexpectedly succeeded!"),
Err(e) => println!(" Correctly failed: {}", e),
}
println!("Testing truncated data...");
let truncated = &encrypted[..encrypted.len() - 20];
match decrypt_model(truncated, password) {
Ok(_) => println!(" Unexpectedly succeeded!"),
Err(e) => println!(" Correctly failed: {}", e),
}
println!("Testing empty password...");
match encrypt_model(model_data, "") {
Ok(_) => println!(" Unexpectedly succeeded!"),
Err(e) => println!(" Correctly failed: {}", e),
}
println!("\nAll error cases handled correctly!");
Ok(())
}