use amaters_core::{CipherBlob, Key, Predicate, col};
use amaters_sdk_rust::{AmateRSClient, FheEncryptor, query};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
tracing_subscriber::fmt::init();
println!("=== AmateRS SDK FHE Operations Example ===\n");
#[cfg(not(feature = "fhe"))]
println!("Note: Using stub FHE implementation (not secure!)");
#[cfg(not(feature = "fhe"))]
println!("Enable the 'fhe' feature for real encryption.\n");
println!("Example 1: Creating FHE encryptor");
println!(" Generating FHE keys...");
let encryptor = FheEncryptor::new()?;
println!(" ✓ Keys generated\n");
println!("Example 2: Encrypting data");
let plaintext = b"Sensitive medical record: Patient 123, Blood Type O+";
println!(" Plaintext: {} bytes", plaintext.len());
let ciphertext = encryptor.encrypt(plaintext)?;
println!(" ✓ Encrypted: {} bytes", ciphertext.len());
println!();
println!("Example 3: Decrypting data");
let decrypted = encryptor.decrypt(&ciphertext)?;
println!(" ✓ Decrypted: {} bytes", decrypted.len());
println!(" Data matches original: {}", decrypted == plaintext);
println!();
println!("Example 4: Using client with FHE encryptor");
let client = AmateRSClient::connect("http://localhost:50051")
.await?
.with_encryptor(encryptor);
println!(" ✓ Client configured with FHE encryptor");
println!(" Encryptor available: {}", client.encryptor().is_some());
println!();
println!("Example 5: Storing encrypted data");
let records = vec![
("patient:001", "Medical record for patient 001"),
("patient:002", "Medical record for patient 002"),
("patient:003", "Medical record for patient 003"),
];
let encryptor = client
.encryptor()
.expect("encryptor should be set")
.as_ref();
for (id, record) in &records {
let key = Key::from_str(id);
let encrypted = encryptor.encrypt(record.as_bytes())?;
client.set("medical_records", &key, &encrypted).await?;
println!(" ✓ Stored encrypted record: {}", id);
}
println!();
println!("Example 6: Retrieving and decrypting data");
let key = Key::from_str("patient:001");
if let Some(encrypted) = client.get("medical_records", &key).await? {
println!(" Retrieved encrypted record: {} bytes", encrypted.len());
let decrypted = encryptor.decrypt(&encrypted)?;
let record = String::from_utf8_lossy(&decrypted);
println!(" ✓ Decrypted record: {}", record);
} else {
println!(" Record not found");
}
println!();
println!("Example 7: Batch encryption");
let data: [&[u8]; 5] = [
b"Record 1",
b"Record 2",
b"Record 3",
b"Record 4",
b"Record 5",
];
println!(" Encrypting {} records in batch...", data.len());
let encrypted_batch = encryptor.encrypt_batch(&data)?;
println!(" ✓ Batch encrypted: {} items", encrypted_batch.len());
for (i, cipher) in encrypted_batch.iter().enumerate() {
let decrypted = encryptor.decrypt(cipher)?;
assert_eq!(decrypted, data[i], "Decryption mismatch at index {}", i);
}
println!(" ✓ All items decrypt correctly");
println!();
println!("Example 8: Building encrypted queries");
let status_value = encryptor.encrypt(b"active")?;
let age_value = encryptor.encrypt(b"18")?;
println!(" Creating filter with encrypted predicates...");
let q = query("users").filter(amaters_core::Predicate::And(
Box::new(amaters_core::Predicate::Eq(
amaters_core::col("status"),
status_value,
)),
Box::new(amaters_core::Predicate::Gt(
amaters_core::col("age"),
age_value,
)),
));
println!(" ✓ Query built with encrypted values");
println!(" Query: SELECT * FROM users WHERE status = <encrypted> AND age > <encrypted>");
let _result = client.execute_query(&q).await?;
println!(" ✓ Query executed");
println!();
println!("Example 9: Key management");
let keys = encryptor.keys();
let temp_dir = std::env::temp_dir();
let key_file = temp_dir.join("amaters_test_keys.bin");
println!(" Saving keys to {:?}...", key_file);
match keys.save_to_file(&key_file) {
Ok(()) => println!(" ✓ Keys saved"),
Err(e) => println!(" Note: {}", e),
}
println!();
println!("Example 10: FHE Filter Query - Server-side filtering on encrypted data");
println!(" This demonstrates the core FHE capability: filtering without seeing data\n");
println!(" Storing encrypted age values...");
let users_ages = vec![
("user:alice", 25u8),
("user:bob", 17u8),
("user:charlie", 35u8),
("user:dave", 70u8),
("user:eve", 22u8),
];
for (user_id, age) in &users_ages {
let key = Key::from_str(user_id);
let encrypted_age = encryptor.encrypt(&[*age])?;
client.set("users_with_ages", &key, &encrypted_age).await?;
println!(" Stored encrypted age for {}", user_id);
}
println!();
println!(" Building filter: age > 18 AND age < 65");
let encrypted_18 = encryptor.encrypt(&[18u8])?;
let encrypted_65 = encryptor.encrypt(&[65u8])?;
let predicate = Predicate::And(
Box::new(Predicate::Gt(col("age"), encrypted_18)),
Box::new(Predicate::Lt(col("age"), encrypted_65)),
);
let filter_query = query("users_with_ages").filter(predicate);
println!(" Executing filter on server (server never sees ages)...");
let result = client.execute_query(&filter_query).await?;
match result {
amaters_sdk_rust::QueryResult::Multi(values) => {
println!(" ✓ Filter executed: {} results", values.len());
println!(" Results (after client-side decryption):");
for (key, encrypted_value) in values {
let age_bytes = encryptor.decrypt(&encrypted_value)?;
if !age_bytes.is_empty() {
let age = age_bytes[0];
println!(" {} - age: {}", key, age);
}
}
println!("\n Expected: alice (25), charlie (35), eve (22)");
println!(" Filtered out: bob (17 - too young), dave (70 - too old)");
}
_ => println!(" Unexpected result type"),
}
println!();
println!("Example 11: FHE Properties and Security Model");
println!(" FHE allows computation on encrypted data:");
println!(" - Server can compare encrypted values (>, <, =)");
println!(" - Server can perform arithmetic on ciphertext (+, *, -)");
println!(" - Server NEVER sees plaintext");
println!(" - All results remain encrypted");
println!();
println!(" Security model:");
println!(" - Client holds private keys");
println!(" - Server stores only ciphertext");
println!(" - Zero-knowledge proofs possible");
println!(" - Post-quantum secure (TFHE)");
println!();
println!(" Use cases:");
println!(" - Healthcare: Query patient records without exposing data");
println!(" - Finance: Analyze credit scores while encrypted");
println!(" - Supply chain: Track sensitive logistics data");
println!(" - Genomics: Search DNA databases privately");
println!();
client.close();
println!("Done!");
Ok(())
}