gaia-crypt 0.1.0

A cryptographic library for secure communication in the GaiaNet ecosystem
Documentation
use rsa::{
    pkcs1::{DecodeRsaPrivateKey, EncodeRsaPrivateKey},
    pkcs8::{DecodePublicKey, EncodePublicKey, LineEnding},
    RsaPrivateKey, RsaPublicKey,
};
use std::fs;

fn save_public_key(
    public_key: &RsaPublicKey,
    path: &str,
) -> Result<(), Box<dyn std::error::Error>> {
    let pem = public_key.to_public_key_pem(LineEnding::LF)?;
    fs::write(path, pem)?;
    Ok(())
}

fn load_public_key(path: &str) -> Result<RsaPublicKey, Box<dyn std::error::Error>> {
    let pem = fs::read_to_string(path)?;
    let public_key = RsaPublicKey::from_public_key_pem(&pem)?;
    Ok(public_key)
}

fn save_private_key(
    private_key: &RsaPrivateKey,
    path: &str,
) -> Result<(), Box<dyn std::error::Error>> {
    private_key.write_pkcs1_pem_file(path, LineEnding::LF)?;
    Ok(())
}

fn load_private_key(path: &str) -> Result<RsaPrivateKey, Box<dyn std::error::Error>> {
    let pem = fs::read_to_string(path)?;
    let private_key = RsaPrivateKey::from_pkcs1_pem(&pem)?;
    Ok(private_key)
}

// Example client-server usage
fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Sample data to encrypt
    let data = b"This is a secret message from the client to the server.";

    // Load the server's key from environment variables in compilation time
    const SERVER_PUBLIC_KEY: &str = std::env!("SERVER_PUBLIC_KEY");
    const SERVER_PRIVATE_KEY: &str = std::env!("SERVER_PRIVATE_KEY");

    // Client-side: encrypt data
    let encrypted_data = gaia_crypt::encrypt(SERVER_PUBLIC_KEY, data)?;
    println!("Encrypted data size: {} bytes", encrypted_data.len());

    // At this point, encrypted_data would be sent to the server
    // ...

    // Server-side: decrypt data
    let decrypted_data = gaia_crypt::decrypt(SERVER_PRIVATE_KEY, &encrypted_data)?;

    // Verify the decryption worked
    assert_eq!(data, &decrypted_data[..]);
    println!(
        "Successfully decrypted: {}",
        String::from_utf8_lossy(&decrypted_data)
    );

    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_encrypt_decrypt() -> Result<(), Box<dyn std::error::Error>> {
        // Generate keys (in practice, this would be done once and saved)
        let (server_private_key, server_public_key) = gaia_crypt::generate_rsa_keypair()?;

        // In a real scenario, the client would obtain the server's public key
        // Save the public key (would be distributed to clients)
        save_public_key(&server_public_key, "server_public_key.pem")?;

        save_private_key(&server_private_key, "server_private_key.pem")?;

        let data = b"This is a secret message from the client to the server.";

        // Client-side: encrypt data
        let encrypted_data = gaia_crypt::raw_encrypt(&server_public_key, data)?;
        println!("Encrypted data size: {} bytes", encrypted_data.len());

        // Server-side: decrypt data
        let decrypted_data = gaia_crypt::raw_decrypt(&server_private_key, &encrypted_data)?;

        // Verify the decryption worked
        assert_eq!(data, &decrypted_data[..]);
        println!(
            "Successfully decrypted: {}",
            String::from_utf8_lossy(&decrypted_data)
        );

        Ok(())
    }
}