sal/vault/_archive/src/keyspace/README.md
Mahmoud-Emad 6e5d9b35e8 feat: Update SAL Vault examples and documentation
- Renamed examples directory to `_archive` to reflect legacy status.
- Updated README.md to reflect current status of vault module,
  including migration from Sameh's implementation to Lee's.
- Temporarily disabled Rhai scripting integration for the vault.
- Added notes regarding current and future development steps.
2025-07-10 14:03:43 +03:00

9.0 KiB

Hero Vault Keypair Module

The Keypair module provides functionality for creating, managing, and using ECDSA keypairs for digital signatures and other cryptographic operations.

Module Structure

The Keypair module is organized into:

  • keypair_types.rs - Defines the KeyPair and related types.
  • session_manager.rs - Implements the core logic for managing keypairs and key spaces.
  • mod.rs - Module exports and public interface.

Key Types

KeyPair

The KeyPair type represents an ECDSA keypair used for digital signatures and other cryptographic operations.

pub struct KeyPair {
    // Private fields
    // ...
}

impl KeyPair {
    // Create a new random keypair
    pub fn new() -> Result<Self, CryptoError>;
    
    // Create a keypair from an existing private key
    pub fn from_private_key(private_key: &[u8]) -> Result<Self, CryptoError>;
    
    // Get the public key
    pub fn public_key(&self) -> &[u8];
    
    // Sign a message
    pub fn sign(&self, message: &[u8]) -> Result<Vec<u8>, CryptoError>;
    
    // Verify a signature
    pub fn verify(&self, message: &[u8], signature: &[u8]) -> Result<bool, CryptoError>;
    
    // Derive an Ethereum address from the public key
    pub fn to_ethereum_address(&self) -> Result<String, CryptoError>;
    
    // Export the private key (should be used with caution)
    pub fn export_private_key(&self) -> Result<Vec<u8>, CryptoError>;
}

KeySpace

The KeySpace type represents a secure container for multiple keypairs, which can be encrypted and stored on disk.

pub struct KeySpace {
    // Private fields
    // ...
}

impl KeySpace {
    // Create a new key space
    pub fn new(name: &str, password: &str) -> Result<Self, CryptoError>;
    
    // Load a key space from disk
    pub fn load(name: &str, password: &str) -> Result<Self, CryptoError>;
    
    // Save the key space to disk
    pub fn save(&self) -> Result<(), CryptoError>;
    
    // Create a new keypair in the key space
    pub fn create_keypair(&mut self, name: &str, password: &str) -> Result<&KeyPair, CryptoError>;
    
    // Select a keypair for use
    pub fn select_keypair(&mut self, name: &str) -> Result<&KeyPair, CryptoError>;
    
    // Get the currently selected keypair
    pub fn current_keypair(&self) -> Result<&KeyPair, CryptoError>;
    
    // List all keypairs in the key space
    pub fn list_keypairs(&self) -> Result<Vec<String>, CryptoError>;
    
    // Get a keypair by name
    pub fn get_keypair(&self, name: &str) -> Result<&KeyPair, CryptoError>;
    
    // Remove a keypair from the key space
    pub fn remove_keypair(&mut self, name: &str) -> Result<(), CryptoError>;
    
    // Rename a keypair
    pub fn rename_keypair(&mut self, old_name: &str, new_name: &str) -> Result<(), CryptoError>;
    
    // Get the name of the key space
    pub fn name(&self) -> &str;
}

Key Features

Key Space Management

The module provides functionality for creating, loading, and managing key spaces:

// Create a new key space
let mut space = KeySpace::new("my_space", "secure_password")?;

// Save the key space to disk
space.save()?;

// Load a key space from disk
let mut loaded_space = KeySpace::load("my_space", "secure_password")?;

Keypair Management

The module provides functionality for creating, selecting, and using keypairs:

use crate::vault::keypair::{KeySpace, KeyPair};
use crate::vault::error::CryptoError; // Assuming CryptoError is in vault::error

fn demonstrate_keypair_management() -> Result<(), CryptoError> {
    // Create a new key space
    let mut space = KeySpace::new("my_space", "secure_password")?;

    // Create a new keypair in the key space
    let keypair = space.create_keypair("my_keypair", "secure_password")?;
    println!("Created keypair: {}", keypair.public_key().iter().map(|b| format!("{:02x}", b)).collect::<String>());

    // Select a keypair for use
    space.select_keypair("my_keypair")?;
    println!("Selected keypair: {}", space.current_keypair()?.public_key().iter().map(|b| format!("{:02x}", b)).collect::<String>());

    // List all keypairs in the key space
    let keypairs = space.list_keypairs()?;
    println!("Keypairs in space: {:?}", keypairs);

    // Get a keypair by name
    let retrieved_keypair = space.get_keypair("my_keypair")?;
    println!("Retrieved keypair: {}", retrieved_keypair.public_key().iter().map(|b| format!("{:02x}", b)).collect::<String>());

    // Rename a keypair
    space.rename_keypair("my_keypair", "new_name")?;
    println!("Renamed keypair to new_name");
    let keypairs_after_rename = space.list_keypairs()?;
    println!("Keypairs in space after rename: {:?}", keypairs_after_rename);


    // Remove a keypair from the key space
    space.remove_keypair("new_name")?;
    println!("Removed keypair new_name");
    let keypairs_after_remove = space.list_keypairs()?;
    println!("Keypairs in space after removal: {:?}", keypairs_after_remove);

    Ok(())
}

Digital Signatures

The module provides functionality for signing and verifying messages using ECDSA:

use crate::vault::keypair::KeySpace;
use crate::vault::error::CryptoError; // Assuming CryptoError is in vault::error

fn demonstrate_digital_signatures() -> Result<(), CryptoError> {
    // Assuming a key space and selected keypair exist
    // let mut space = KeySpace::load("my_space", "secure_password")?; // Load existing space
    let mut space = KeySpace::new("temp_space_for_demo", "password")?; // Or create a new one for demo
    space.create_keypair("my_signing_key", "key_password")?;
    space.select_keypair("my_signing_key")?;


    // Sign a message using the selected keypair
    let keypair = space.current_keypair()?;
    let message = "This is a message to sign".as_bytes();
    let signature = keypair.sign(message)?;
    println!("Message signed. Signature: {:?}", signature);

    // Verify a signature
    let is_valid = keypair.verify(message, &signature)?;
    println!("Signature valid: {}", is_valid);

    // Example of invalid signature verification
    let invalid_signature = vec![0u8; signature.len()]; // A dummy invalid signature
    let is_valid_invalid = keypair.verify(message, &invalid_signature)?;
    println!("Invalid signature valid: {}", is_valid_invalid);


    Ok(())
}

Ethereum Address Derivation

The module provides functionality for deriving Ethereum addresses from keypairs:

use crate::vault::keypair::KeySpace;
use crate::vault::error::CryptoError; // Assuming CryptoError is in vault::error

fn demonstrate_ethereum_address_derivation() -> Result<(), CryptoError> {
    // Assuming a key space and selected keypair exist
    // let mut space = KeySpace::load("my_space", "secure_password")?; // Load existing space
     let mut space = KeySpace::new("temp_space_for_eth_demo", "password")?; // Or create a new one for demo
    space.create_keypair("my_eth_key", "key_password")?;
    space.select_keypair("my_eth_key")?;

    // Derive an Ethereum address from a keypair
    let keypair = space.current_keypair()?;
    let address = keypair.to_ethereum_address()?;
    println!("Derived Ethereum address: {}", address);

    Ok(())
}

Including in Your Project

To include the Hero Vault Keypair module in your Rust project, add the following to your Cargo.toml file:

[dependencies]
hero_vault = "0.1.0" # Replace with the actual version

Then, you can import and use the module in your Rust code:

use hero_vault::vault::keypair::{KeySpace, KeyPair};
use hero_vault::vault::error::CryptoError;

Testing

Tests for the Keypair module are included within the source files, likely in session_manager.rs or mod.rs as inline tests.

To run the tests, navigate to the root directory of the project in your terminal and execute the following command:

cargo test --lib vault::keypair

This command will run all tests specifically within the vault::keypair module.

Security Considerations

  • Key spaces are encrypted with ChaCha20Poly1305 using a key derived from the provided password
  • Private keys are never stored in plaintext
  • The module uses secure random number generation for key creation
  • All cryptographic operations use well-established libraries and algorithms

Error Handling

The module uses the CryptoError type for handling errors that can occur during keypair operations:

  • InvalidKeyLength - Invalid key length
  • SignatureFormatError - Signature format error
  • KeypairAlreadyExists - Keypair already exists
  • KeypairNotFound - Keypair not found
  • NoActiveSpace - No active key space
  • NoKeypairSelected - No keypair selected
  • SerializationError - Serialization error

Examples

For examples of how to use the Keypair module, see the examples/hero_vault directory, particularly:

  • example.rhai - Basic example demonstrating key management and signing
  • advanced_example.rhai - Advanced example with error handling
  • key_persistence_example.rhai - Demonstrates creating and saving a key space to disk
  • load_existing_space.rhai - Shows how to load a previously created key space