sal-vault 0.1.0

SAL Vault - Cryptographic functionality including key management, digital signatures, symmetric encryption, Ethereum wallets, and encrypted key-value store
Documentation
# 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.

```rust
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.

```rust
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:

```rust
// 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:

```rust
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:

```rust
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:

```rust
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:

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

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

```rust
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:

```bash
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