#[cfg(not(feature = "serde-support"))]
compile_error!("This example requires the 'serde-support' feature. Run with: cargo run --example serde_example --features serde-support");
#[cfg(feature = "serde-support")]
fn main() -> Result<(), Box<dyn std::error::Error>> {
use crabgraph::{
aead::{AesGcm256, CrabAead},
asym::ed25519::Ed25519KeyPair,
};
println!("=== CrabGraph Serde Serialization Example ===\n");
println!("--- Example 1: AEAD Ciphertext Serialization ---");
let plaintext = b"Secret message that needs to be stored";
let key = AesGcm256::generate_key()?;
let cipher = AesGcm256::new(&key)?;
let ciphertext = cipher.encrypt(plaintext, None)?;
println!("Original plaintext: {:?}", String::from_utf8_lossy(plaintext));
let json = serde_json::to_string_pretty(&ciphertext)?;
println!("Serialized to JSON:\n{}", json);
let restored: crabgraph::aead::Ciphertext = serde_json::from_str(&json)?;
println!("Deserialized from JSON successfully");
let decrypted = cipher.decrypt(&restored, None)?;
println!("Decrypted: {:?}", String::from_utf8_lossy(&decrypted));
assert_eq!(decrypted, plaintext);
println!("✓ Roundtrip successful!\n");
println!("--- Example 2: Ed25519 Public Key Serialization ---");
let keypair = Ed25519KeyPair::generate()?;
let public_key = keypair.public_key();
println!("Public key (hex): {}", public_key.to_hex());
let json = serde_json::to_string(&public_key)?;
println!("Serialized to JSON: {}", json);
let restored_pubkey: crabgraph::asym::ed25519::Ed25519PublicKey = serde_json::from_str(&json)?;
println!("Deserialized from JSON successfully");
assert_eq!(public_key.as_bytes(), restored_pubkey.as_bytes());
println!("✓ Public key roundtrip successful!\n");
println!("--- Example 3: Ed25519 Signature Serialization ---");
let message = b"Important document to sign";
let signature = keypair.sign(message);
println!("Message: {:?}", String::from_utf8_lossy(message));
println!("Signature (hex): {}...", &signature.to_hex()[..32]);
let json = serde_json::to_string(&signature)?;
println!("Serialized to JSON: {}", json);
let restored_sig: crabgraph::asym::ed25519::Ed25519Signature = serde_json::from_str(&json)?;
println!("Deserialized from JSON successfully");
let is_valid = keypair.verify(message, &restored_sig)?;
println!("Signature verification: {}", is_valid);
assert!(is_valid);
println!("✓ Signature roundtrip successful!\n");
println!("--- Example 4: Configuration File Format ---");
#[derive(serde::Serialize, serde::Deserialize)]
struct ServerConfig {
server_name: String,
public_key: crabgraph::asym::ed25519::Ed25519PublicKey,
encrypted_token: crabgraph::aead::Ciphertext,
}
let config = ServerConfig {
server_name: "api.example.com".to_string(),
public_key: keypair.public_key(),
encrypted_token: cipher.encrypt(b"secret_api_token_12345", None)?,
};
let json = serde_json::to_string_pretty(&config)?;
println!("Server configuration:\n{}", json);
let restored_config: ServerConfig = serde_json::from_str(&json)?;
println!("\n✓ Configuration loaded successfully!");
println!(
"Server: {}, Public key: {}...",
restored_config.server_name,
&restored_config.public_key.to_hex()[..16]
);
println!("\n--- Example 5: Binary Serialization (compact) ---");
let binary_json = bincode::serialize(&ciphertext)?;
let binary_pubkey = bincode::serialize(&public_key)?;
let binary_sig = bincode::serialize(&signature)?;
println!("Ciphertext JSON size: {} bytes", json.len());
println!("Ciphertext binary size: {} bytes", binary_json.len());
println!("Space saved: {}%", 100 - (binary_json.len() * 100 / json.len()));
println!("\nPublic key binary: {} bytes", binary_pubkey.len());
println!("Signature binary: {} bytes", binary_sig.len());
let _: crabgraph::aead::Ciphertext = bincode::deserialize(&binary_json)?;
let _: crabgraph::asym::ed25519::Ed25519PublicKey = bincode::deserialize(&binary_pubkey)?;
let _: crabgraph::asym::ed25519::Ed25519Signature = bincode::deserialize(&binary_sig)?;
println!("✓ All binary deserializations successful!\n");
println!("--- Example 6: TOML Configuration ---");
#[derive(serde::Serialize, serde::Deserialize)]
struct AppConfig {
app_name: String,
version: String,
#[serde(with = "serde_bytes")]
public_key_bytes: Vec<u8>,
}
let app_config = AppConfig {
app_name: "MyApp".to_string(),
version: "1.0.0".to_string(),
public_key_bytes: public_key.as_bytes().to_vec(),
};
let toml_str = toml::to_string_pretty(&app_config)?;
println!("TOML configuration:\n{}", toml_str);
let _: AppConfig = toml::from_str(&toml_str)?;
println!("✓ TOML roundtrip successful!\n");
println!("=== All Examples Complete ===");
println!("\nKey Takeaways:");
println!("• Ciphertext, public keys, and signatures are serializable");
println!("• Supports JSON, binary (bincode), TOML, and other serde formats");
println!("• Binary serialization is more compact than JSON");
println!("• Perfect for storing encrypted data and cryptographic keys");
println!("• Always use secure storage for serialized sensitive data!");
Ok(())
}
#[cfg(not(feature = "serde-support"))]
fn main() {
eprintln!("This example requires the 'serde-support' feature.");
eprintln!("Run with: cargo run --example serde_example --features serde-support");
std::process::exit(1);
}