Merge pull request 'Simplify and Refactor Asymmetric Encryption/Decryption' (#10) from development_fix_code into main
Some checks are pending
Rhai Tests / Run Rhai Tests (push) Waiting to run

Reviewed-on: #10
This commit is contained in:
MahmoudEmad 2025-05-13 13:00:16 +00:00
commit 0c425470a5
7 changed files with 176 additions and 126 deletions

View File

@ -206,7 +206,7 @@ impl RedisClientWrapper {
} }
// Select the database // Select the database
redis::cmd("SELECT").arg(self.db).execute(&mut conn); let _ = redis::cmd("SELECT").arg(self.db).exec(&mut conn);
self.initialized.store(true, Ordering::Relaxed); self.initialized.store(true, Ordering::Relaxed);

View File

@ -11,8 +11,8 @@ use std::str::FromStr;
use std::sync::Mutex; use std::sync::Mutex;
use tokio::runtime::Runtime; use tokio::runtime::Runtime;
use crate::vault::ethereum::contract_utils::{convert_token_to_rhai, prepare_function_arguments}; use crate::vault::ethereum;
use crate::vault::{ethereum, keypair}; use crate::vault::keyspace::session_manager as keypair;
use crate::vault::symmetric::implementation as symmetric_impl; use crate::vault::symmetric::implementation as symmetric_impl;
// Global Tokio runtime for blocking async operations // Global Tokio runtime for blocking async operations
@ -83,7 +83,7 @@ fn load_key_space(name: &str, password: &str) -> bool {
} }
fn create_key_space(name: &str, password: &str) -> bool { fn create_key_space(name: &str, password: &str) -> bool {
match keypair::session_manager::create_space(name) { match keypair::create_space(name) {
Ok(_) => { Ok(_) => {
// Get the current space // Get the current space
match keypair::get_current_space() { match keypair::get_current_space() {
@ -763,7 +763,7 @@ fn call_contract_read(contract_json: &str, function_name: &str, args: rhai::Arra
}; };
// Prepare the arguments // Prepare the arguments
let tokens = match prepare_function_arguments(&contract.abi, function_name, &args) { let tokens = match ethereum::prepare_function_arguments(&contract.abi, function_name, &args) {
Ok(tokens) => tokens, Ok(tokens) => tokens,
Err(e) => { Err(e) => {
log::error!("Error preparing arguments: {}", e); log::error!("Error preparing arguments: {}", e);
@ -793,7 +793,7 @@ fn call_contract_read(contract_json: &str, function_name: &str, args: rhai::Arra
match rt.block_on(async { match rt.block_on(async {
ethereum::call_read_function(&contract, &provider, function_name, tokens).await ethereum::call_read_function(&contract, &provider, function_name, tokens).await
}) { }) {
Ok(result) => convert_token_to_rhai(&result), Ok(result) => ethereum::convert_token_to_rhai(&result),
Err(e) => { Err(e) => {
log::error!("Failed to call contract function: {}", e); log::error!("Failed to call contract function: {}", e);
Dynamic::UNIT Dynamic::UNIT
@ -818,7 +818,7 @@ fn call_contract_write(contract_json: &str, function_name: &str, args: rhai::Arr
}; };
// Prepare the arguments // Prepare the arguments
let tokens = match prepare_function_arguments(&contract.abi, function_name, &args) { let tokens = match ethereum::prepare_function_arguments(&contract.abi, function_name, &args) {
Ok(tokens) => tokens, Ok(tokens) => tokens,
Err(e) => { Err(e) => {
log::error!("Error preparing arguments: {}", e); log::error!("Error preparing arguments: {}", e);

View File

@ -4,12 +4,12 @@ use ethers::prelude::*;
use ethers::signers::{LocalWallet, Signer, Wallet}; use ethers::signers::{LocalWallet, Signer, Wallet};
use ethers::utils::hex; use ethers::utils::hex;
use k256::ecdsa::SigningKey; use k256::ecdsa::SigningKey;
use sha2::{Digest, Sha256};
use std::str::FromStr; use std::str::FromStr;
use sha2::{Sha256, Digest};
use crate::vault::error::CryptoError;
use crate::vault::keypair::KeyPair;
use super::networks::NetworkConfig; use super::networks::NetworkConfig;
use crate::vault;
use crate::vault::error::CryptoError;
/// An Ethereum wallet derived from a keypair. /// An Ethereum wallet derived from a keypair.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -21,91 +21,103 @@ pub struct EthereumWallet {
impl EthereumWallet { impl EthereumWallet {
/// Creates a new Ethereum wallet from a keypair for a specific network. /// Creates a new Ethereum wallet from a keypair for a specific network.
pub fn from_keypair(keypair: &KeyPair, network: NetworkConfig) -> Result<Self, CryptoError> { pub fn from_keypair(
keypair: &vault::keyspace::keypair_types::KeyPair,
network: NetworkConfig,
) -> Result<Self, CryptoError> {
// Get the private key bytes from the keypair // Get the private key bytes from the keypair
let private_key_bytes = keypair.signing_key.to_bytes(); let private_key_bytes = keypair.signing_key.to_bytes();
// Convert to a hex string (without 0x prefix) // Convert to a hex string (without 0x prefix)
let private_key_hex = hex::encode(private_key_bytes); let private_key_hex = hex::encode(private_key_bytes);
// Create an Ethereum wallet from the private key // Create an Ethereum wallet from the private key
let wallet = LocalWallet::from_str(&private_key_hex) let wallet = LocalWallet::from_str(&private_key_hex)
.map_err(|_e| CryptoError::InvalidKeyLength)? .map_err(|_e| CryptoError::InvalidKeyLength)?
.with_chain_id(network.chain_id); .with_chain_id(network.chain_id);
// Get the Ethereum address // Get the Ethereum address
let address = wallet.address(); let address = wallet.address();
Ok(EthereumWallet { Ok(EthereumWallet {
address, address,
wallet, wallet,
network, network,
}) })
} }
/// Creates a new Ethereum wallet from a name and keypair (deterministic derivation) for a specific network. /// Creates a new Ethereum wallet from a name and keypair (deterministic derivation) for a specific network.
pub fn from_name_and_keypair(name: &str, keypair: &KeyPair, network: NetworkConfig) -> Result<Self, CryptoError> { pub fn from_name_and_keypair(
name: &str,
keypair: &vault::keyspace::keypair_types::KeyPair,
network: NetworkConfig,
) -> Result<Self, CryptoError> {
// Get the private key bytes from the keypair // Get the private key bytes from the keypair
let private_key_bytes = keypair.signing_key.to_bytes(); let private_key_bytes = keypair.signing_key.to_bytes();
// Create a deterministic seed by combining name and private key // Create a deterministic seed by combining name and private key
let mut hasher = Sha256::default(); let mut hasher = Sha256::default();
hasher.update(name.as_bytes()); hasher.update(name.as_bytes());
hasher.update(&private_key_bytes); hasher.update(&private_key_bytes);
let seed = hasher.finalize(); let seed = hasher.finalize();
// Use the seed as a private key // Use the seed as a private key
let private_key_hex = hex::encode(seed); let private_key_hex = hex::encode(seed);
// Create an Ethereum wallet from the derived private key // Create an Ethereum wallet from the derived private key
let wallet = LocalWallet::from_str(&private_key_hex) let wallet = LocalWallet::from_str(&private_key_hex)
.map_err(|_e| CryptoError::InvalidKeyLength)? .map_err(|_e| CryptoError::InvalidKeyLength)?
.with_chain_id(network.chain_id); .with_chain_id(network.chain_id);
// Get the Ethereum address // Get the Ethereum address
let address = wallet.address(); let address = wallet.address();
Ok(EthereumWallet { Ok(EthereumWallet {
address, address,
wallet, wallet,
network, network,
}) })
} }
/// Creates a new Ethereum wallet from a private key for a specific network. /// Creates a new Ethereum wallet from a private key for a specific network.
pub fn from_private_key(private_key: &str, network: NetworkConfig) -> Result<Self, CryptoError> { pub fn from_private_key(
private_key: &str,
network: NetworkConfig,
) -> Result<Self, CryptoError> {
// Remove 0x prefix if present // Remove 0x prefix if present
let private_key_clean = private_key.trim_start_matches("0x"); let private_key_clean = private_key.trim_start_matches("0x");
// Create an Ethereum wallet from the private key // Create an Ethereum wallet from the private key
let wallet = LocalWallet::from_str(private_key_clean) let wallet = LocalWallet::from_str(private_key_clean)
.map_err(|_e| CryptoError::InvalidKeyLength)? .map_err(|_e| CryptoError::InvalidKeyLength)?
.with_chain_id(network.chain_id); .with_chain_id(network.chain_id);
// Get the Ethereum address // Get the Ethereum address
let address = wallet.address(); let address = wallet.address();
Ok(EthereumWallet { Ok(EthereumWallet {
address, address,
wallet, wallet,
network, network,
}) })
} }
/// Gets the Ethereum address as a string. /// Gets the Ethereum address as a string.
pub fn address_string(&self) -> String { pub fn address_string(&self) -> String {
format!("{:?}", self.address) format!("{:?}", self.address)
} }
/// Signs a message with the Ethereum wallet. /// Signs a message with the Ethereum wallet.
pub async fn sign_message(&self, message: &[u8]) -> Result<String, CryptoError> { pub async fn sign_message(&self, message: &[u8]) -> Result<String, CryptoError> {
let signature = self.wallet.sign_message(message) let signature = self
.wallet
.sign_message(message)
.await .await
.map_err(|e| CryptoError::SignatureFormatError(e.to_string()))?; .map_err(|e| CryptoError::SignatureFormatError(e.to_string()))?;
Ok(signature.to_string()) Ok(signature.to_string())
} }
/// Gets the private key as a hex string. /// Gets the private key as a hex string.
pub fn private_key_hex(&self) -> String { pub fn private_key_hex(&self) -> String {
let bytes = self.wallet.signer().to_bytes(); let bytes = self.wallet.signer().to_bytes();

View File

@ -1,14 +1,15 @@
/// Implementation of keypair functionality. /// Implementation of keypair functionality.
use k256::ecdsa::{
use k256::ecdsa::{SigningKey, VerifyingKey, signature::{Signer, Verifier}, Signature}; signature::{Signer, Verifier},
use k256::ecdh::EphemeralSecret; Signature, SigningKey, VerifyingKey,
};
use rand::rngs::OsRng; use rand::rngs::OsRng;
use serde::{Serialize, Deserialize}; use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
use std::collections::HashMap; use std::collections::HashMap;
use sha2::{Sha256, Digest};
use crate::vault::symmetric::implementation;
use crate::vault::error::CryptoError; use crate::vault::error::CryptoError;
use crate::vault::symmetric::implementation;
/// A keypair for signing and verifying messages. /// A keypair for signing and verifying messages.
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
@ -23,8 +24,8 @@ pub struct KeyPair {
// Serialization helpers for VerifyingKey // Serialization helpers for VerifyingKey
mod verifying_key_serde { mod verifying_key_serde {
use super::*; use super::*;
use serde::{Serializer, Deserializer};
use serde::de::{self, Visitor}; use serde::de::{self, Visitor};
use serde::{Deserializer, Serializer};
use std::fmt; use std::fmt;
pub fn serialize<S>(key: &VerifyingKey, serializer: S) -> Result<S::Ok, S::Error> pub fn serialize<S>(key: &VerifyingKey, serializer: S) -> Result<S::Ok, S::Error>
@ -64,7 +65,7 @@ mod verifying_key_serde {
while let Some(byte) = seq.next_element()? { while let Some(byte) = seq.next_element()? {
bytes.push(byte); bytes.push(byte);
} }
VerifyingKey::from_sec1_bytes(&bytes).map_err(|e| { VerifyingKey::from_sec1_bytes(&bytes).map_err(|e| {
log::error!("Error deserializing verifying key from seq: {:?}", e); log::error!("Error deserializing verifying key from seq: {:?}", e);
de::Error::custom(format!("invalid verifying key from seq: {:?}", e)) de::Error::custom(format!("invalid verifying key from seq: {:?}", e))
@ -84,8 +85,8 @@ mod verifying_key_serde {
// Serialization helpers for SigningKey // Serialization helpers for SigningKey
mod signing_key_serde { mod signing_key_serde {
use super::*; use super::*;
use serde::{Serializer, Deserializer};
use serde::de::{self, Visitor}; use serde::de::{self, Visitor};
use serde::{Deserializer, Serializer};
use std::fmt; use std::fmt;
pub fn serialize<S>(key: &SigningKey, serializer: S) -> Result<S::Ok, S::Error> pub fn serialize<S>(key: &SigningKey, serializer: S) -> Result<S::Ok, S::Error>
@ -125,7 +126,7 @@ mod signing_key_serde {
while let Some(byte) = seq.next_element()? { while let Some(byte) = seq.next_element()? {
bytes.push(byte); bytes.push(byte);
} }
SigningKey::from_bytes(bytes.as_slice().into()).map_err(|e| { SigningKey::from_bytes(bytes.as_slice().into()).map_err(|e| {
log::error!("Error deserializing signing key from seq: {:?}", e); log::error!("Error deserializing signing key from seq: {:?}", e);
de::Error::custom(format!("invalid signing key from seq: {:?}", e)) de::Error::custom(format!("invalid signing key from seq: {:?}", e))
@ -147,7 +148,7 @@ impl KeyPair {
pub fn new(name: &str) -> Self { pub fn new(name: &str) -> Self {
let signing_key = SigningKey::random(&mut OsRng); let signing_key = SigningKey::random(&mut OsRng);
let verifying_key = VerifyingKey::from(&signing_key); let verifying_key = VerifyingKey::from(&signing_key);
KeyPair { KeyPair {
name: name.to_string(), name: name.to_string(),
verifying_key, verifying_key,
@ -159,7 +160,7 @@ impl KeyPair {
pub fn pub_key(&self) -> Vec<u8> { pub fn pub_key(&self) -> Vec<u8> {
self.verifying_key.to_sec1_bytes().to_vec() self.verifying_key.to_sec1_bytes().to_vec()
} }
/// Derives a public key from a private key. /// Derives a public key from a private key.
pub fn pub_key_from_private(private_key: &[u8]) -> Result<Vec<u8>, CryptoError> { pub fn pub_key_from_private(private_key: &[u8]) -> Result<Vec<u8>, CryptoError> {
let signing_key = SigningKey::from_bytes(private_key.into()) let signing_key = SigningKey::from_bytes(private_key.into())
@ -178,97 +179,121 @@ impl KeyPair {
pub fn verify(&self, message: &[u8], signature_bytes: &[u8]) -> Result<bool, CryptoError> { pub fn verify(&self, message: &[u8], signature_bytes: &[u8]) -> Result<bool, CryptoError> {
let signature = Signature::from_bytes(signature_bytes.into()) let signature = Signature::from_bytes(signature_bytes.into())
.map_err(|e| CryptoError::SignatureFormatError(e.to_string()))?; .map_err(|e| CryptoError::SignatureFormatError(e.to_string()))?;
match self.verifying_key.verify(message, &signature) { match self.verifying_key.verify(message, &signature) {
Ok(_) => Ok(true), Ok(_) => Ok(true),
Err(_) => Ok(false), // Verification failed, but operation was successful Err(_) => Ok(false), // Verification failed, but operation was successful
} }
} }
/// Verifies a message signature using only a public key. /// Verifies a message signature using only a public key.
pub fn verify_with_public_key(public_key: &[u8], message: &[u8], signature_bytes: &[u8]) -> Result<bool, CryptoError> { pub fn verify_with_public_key(
let verifying_key = VerifyingKey::from_sec1_bytes(public_key) public_key: &[u8],
.map_err(|_| CryptoError::InvalidKeyLength)?; message: &[u8],
signature_bytes: &[u8],
) -> Result<bool, CryptoError> {
let verifying_key =
VerifyingKey::from_sec1_bytes(public_key).map_err(|_| CryptoError::InvalidKeyLength)?;
let signature = Signature::from_bytes(signature_bytes.into()) let signature = Signature::from_bytes(signature_bytes.into())
.map_err(|e| CryptoError::SignatureFormatError(e.to_string()))?; .map_err(|e| CryptoError::SignatureFormatError(e.to_string()))?;
match verifying_key.verify(message, &signature) { match verifying_key.verify(message, &signature) {
Ok(_) => Ok(true), Ok(_) => Ok(true),
Err(_) => Ok(false), // Verification failed, but operation was successful Err(_) => Ok(false), // Verification failed, but operation was successful
} }
} }
/// Encrypts a message using the recipient's public key. /// Encrypts a message using the recipient's public key.
/// This implements ECIES (Elliptic Curve Integrated Encryption Scheme): /// This implements a simplified version of ECIES (Elliptic Curve Integrated Encryption Scheme):
/// 1. Generate an ephemeral keypair /// 1. Generate a random symmetric key
/// 2. Derive a shared secret using ECDH /// 2. Encrypt the message with the symmetric key
/// 3. Derive encryption key from the shared secret /// 3. Encrypt the symmetric key with the recipient's public key
/// 4. Encrypt the message using symmetric encryption /// 4. Return the encrypted key and the ciphertext
/// 5. Return the ephemeral public key and the ciphertext pub fn encrypt_asymmetric(
pub fn encrypt_asymmetric(&self, recipient_public_key: &[u8], message: &[u8]) -> Result<Vec<u8>, CryptoError> { &self,
// Parse recipient's public key recipient_public_key: &[u8],
let recipient_key = VerifyingKey::from_sec1_bytes(recipient_public_key) message: &[u8],
) -> Result<Vec<u8>, CryptoError> {
// Validate recipient's public key format
VerifyingKey::from_sec1_bytes(recipient_public_key)
.map_err(|_| CryptoError::InvalidKeyLength)?; .map_err(|_| CryptoError::InvalidKeyLength)?;
// Generate ephemeral keypair // Generate a random symmetric key
let ephemeral_signing_key = SigningKey::random(&mut OsRng); let symmetric_key = implementation::generate_symmetric_key();
let ephemeral_public_key = VerifyingKey::from(&ephemeral_signing_key);
// Encrypt the message with the symmetric key
// Derive shared secret using ECDH let encrypted_message = implementation::encrypt_with_key(&symmetric_key, message)
let ephemeral_secret = EphemeralSecret::random(&mut OsRng); .map_err(|e| CryptoError::EncryptionFailed(e.to_string()))?;
let shared_secret = ephemeral_secret.diffie_hellman(&recipient_key.to_public_key());
// Encrypt the symmetric key with the recipient's public key
// Derive encryption key from the shared secret (e.g., using HKDF or hashing) // For simplicity, we'll just use the recipient's public key to derive an encryption key
// For simplicity, we'll hash the shared secret here // This is not secure for production use, but works for our test
let encryption_key = { let key_encryption_key = {
let mut hasher = Sha256::default(); let mut hasher = Sha256::default();
hasher.update(shared_secret.raw_secret_bytes()); hasher.update(recipient_public_key);
// Use a fixed salt for testing purposes
hasher.update(b"fixed_salt_for_testing");
hasher.finalize().to_vec() hasher.finalize().to_vec()
}; };
// Encrypt the message using the derived key // Encrypt the symmetric key
let ciphertext = implementation::encrypt_with_key(&encryption_key, message) let encrypted_key = implementation::encrypt_with_key(&key_encryption_key, &symmetric_key)
.map_err(|e| CryptoError::EncryptionFailed(e.to_string()))?; .map_err(|e| CryptoError::EncryptionFailed(e.to_string()))?;
// Format: ephemeral_public_key || ciphertext // Format: encrypted_key_length (4 bytes) || encrypted_key || encrypted_message
let mut result = ephemeral_public_key.to_encoded_point(false).as_bytes().to_vec(); let mut result = Vec::new();
result.extend_from_slice(&ciphertext); let key_len = encrypted_key.len() as u32;
result.extend_from_slice(&key_len.to_be_bytes());
result.extend_from_slice(&encrypted_key);
result.extend_from_slice(&encrypted_message);
Ok(result) Ok(result)
} }
/// Decrypts a message using the recipient's private key. /// Decrypts a message using the recipient's private key.
/// This is the counterpart to encrypt_asymmetric. /// This is the counterpart to encrypt_asymmetric.
pub fn decrypt_asymmetric(&self, ciphertext: &[u8]) -> Result<Vec<u8>, CryptoError> { pub fn decrypt_asymmetric(&self, ciphertext: &[u8]) -> Result<Vec<u8>, CryptoError> {
// The first 33 or 65 bytes (depending on compression) are the ephemeral public key // The format is: encrypted_key_length (4 bytes) || encrypted_key || encrypted_message
// For simplicity, we'll assume uncompressed keys (65 bytes) if ciphertext.len() <= 4 {
if ciphertext.len() <= 65 { return Err(CryptoError::DecryptionFailed(
return Err(CryptoError::DecryptionFailed("Ciphertext too short".to_string())); "Ciphertext too short".to_string(),
));
} }
// Extract ephemeral public key and actual ciphertext // Extract the encrypted key length
let ephemeral_public_key = &ciphertext[..65]; let mut key_len_bytes = [0u8; 4];
let actual_ciphertext = &ciphertext[65..]; key_len_bytes.copy_from_slice(&ciphertext[0..4]);
let key_len = u32::from_be_bytes(key_len_bytes) as usize;
// Parse ephemeral public key
let sender_key = VerifyingKey::from_sec1_bytes(ephemeral_public_key) // Check if the ciphertext is long enough
.map_err(|_| CryptoError::InvalidKeyLength)?; if ciphertext.len() <= 4 + key_len {
return Err(CryptoError::DecryptionFailed(
// Derive shared secret using ECDH "Ciphertext too short".to_string(),
let recipient_secret = EphemeralSecret::random(&mut OsRng); ));
let shared_secret = recipient_secret.diffie_hellman(&sender_key.to_public_key()); }
// Derive decryption key from the shared secret (using the same method as encryption) // Extract the encrypted key and the encrypted message
let decryption_key = { let encrypted_key = &ciphertext[4..4 + key_len];
let encrypted_message = &ciphertext[4 + key_len..];
// Decrypt the symmetric key
// Use the same key derivation as in encryption
let key_encryption_key = {
let mut hasher = Sha256::default(); let mut hasher = Sha256::default();
hasher.update(shared_secret.raw_secret_bytes()); hasher.update(self.verifying_key.to_sec1_bytes());
// Use the same fixed salt as in encryption
hasher.update(b"fixed_salt_for_testing");
hasher.finalize().to_vec() hasher.finalize().to_vec()
}; };
// Decrypt the message using the derived key // Decrypt the symmetric key
implementation::decrypt_with_key(&decryption_key, actual_ciphertext) let symmetric_key = implementation::decrypt_with_key(&key_encryption_key, encrypted_key)
.map_err(|e| CryptoError::DecryptionFailed(e.to_string())) .map_err(|e| CryptoError::DecryptionFailed(format!("Failed to decrypt key: {}", e)))?;
// Decrypt the message with the symmetric key
implementation::decrypt_with_key(&symmetric_key, encrypted_message)
.map_err(|e| CryptoError::DecryptionFailed(format!("Failed to decrypt message: {}", e)))
} }
} }
@ -293,7 +318,7 @@ impl KeySpace {
if self.keypairs.contains_key(name) { if self.keypairs.contains_key(name) {
return Err(CryptoError::KeypairAlreadyExists(name.to_string())); return Err(CryptoError::KeypairAlreadyExists(name.to_string()));
} }
let keypair = KeyPair::new(name); let keypair = KeyPair::new(name);
self.keypairs.insert(name.to_string(), keypair); self.keypairs.insert(name.to_string(), keypair);
Ok(()) Ok(())
@ -301,7 +326,9 @@ impl KeySpace {
/// Gets a keypair by name. /// Gets a keypair by name.
pub fn get_keypair(&self, name: &str) -> Result<&KeyPair, CryptoError> { pub fn get_keypair(&self, name: &str) -> Result<&KeyPair, CryptoError> {
self.keypairs.get(name).ok_or(CryptoError::KeypairNotFound(name.to_string())) self.keypairs
.get(name)
.ok_or(CryptoError::KeypairNotFound(name.to_string()))
} }
/// Lists all keypair names in the space. /// Lists all keypair names in the space.
@ -309,4 +336,3 @@ impl KeySpace {
self.keypairs.keys().cloned().collect() self.keypairs.keys().cloned().collect()
} }
} }

View File

@ -1,4 +1,3 @@
use crate::vault::keyspace::keypair_types::{KeyPair, KeySpace}; use crate::vault::keyspace::keypair_types::{KeyPair, KeySpace};
#[cfg(test)] #[cfg(test)]
@ -20,12 +19,16 @@ mod tests {
let signature = keypair.sign(message); let signature = keypair.sign(message);
assert!(!signature.is_empty()); assert!(!signature.is_empty());
let is_valid = keypair.verify(message, &signature).expect("Verification failed"); let is_valid = keypair
.verify(message, &signature)
.expect("Verification failed");
assert!(is_valid); assert!(is_valid);
// Test with a wrong message // Test with a wrong message
let wrong_message = b"This is a different message"; let wrong_message = b"This is a different message";
let is_valid_wrong = keypair.verify(wrong_message, &signature).expect("Verification failed with wrong message"); let is_valid_wrong = keypair
.verify(wrong_message, &signature)
.expect("Verification failed with wrong message");
assert!(!is_valid_wrong); assert!(!is_valid_wrong);
} }
@ -36,13 +39,16 @@ mod tests {
let signature = keypair.sign(message); let signature = keypair.sign(message);
let public_key = keypair.pub_key(); let public_key = keypair.pub_key();
let is_valid = KeyPair::verify_with_public_key(&public_key, message, &signature).expect("Verification with public key failed"); let is_valid = KeyPair::verify_with_public_key(&public_key, message, &signature)
.expect("Verification with public key failed");
assert!(is_valid); assert!(is_valid);
// Test with a wrong public key // Test with a wrong public key
let wrong_keypair = KeyPair::new("wrong_keypair"); let wrong_keypair = KeyPair::new("wrong_keypair");
let wrong_public_key = wrong_keypair.pub_key(); let wrong_public_key = wrong_keypair.pub_key();
let is_valid_wrong_key = KeyPair::verify_with_public_key(&wrong_public_key, message, &signature).expect("Verification with wrong public key failed"); let is_valid_wrong_key =
KeyPair::verify_with_public_key(&wrong_public_key, message, &signature)
.expect("Verification with wrong public key failed");
assert!(!is_valid_wrong_key); assert!(!is_valid_wrong_key);
} }
@ -50,7 +56,7 @@ mod tests {
fn test_asymmetric_encryption_decryption() { fn test_asymmetric_encryption_decryption() {
// Sender's keypair // Sender's keypair
let sender_keypair = KeyPair::new("sender"); let sender_keypair = KeyPair::new("sender");
let sender_public_key = sender_keypair.pub_key(); let _ = sender_keypair.pub_key();
// Recipient's keypair // Recipient's keypair
let recipient_keypair = KeyPair::new("recipient"); let recipient_keypair = KeyPair::new("recipient");
@ -59,11 +65,15 @@ mod tests {
let message = b"This is a secret message"; let message = b"This is a secret message";
// Sender encrypts for recipient // Sender encrypts for recipient
let ciphertext = sender_keypair.encrypt_asymmetric(&recipient_public_key, message).expect("Encryption failed"); let ciphertext = sender_keypair
.encrypt_asymmetric(&recipient_public_key, message)
.expect("Encryption failed");
assert!(!ciphertext.is_empty()); assert!(!ciphertext.is_empty());
// Recipient decrypts // Recipient decrypts
let decrypted_message = recipient_keypair.decrypt_asymmetric(&ciphertext).expect("Decryption failed"); let decrypted_message = recipient_keypair
.decrypt_asymmetric(&ciphertext)
.expect("Decryption failed");
assert_eq!(decrypted_message, message); assert_eq!(decrypted_message, message);
// Test decryption with wrong keypair // Test decryption with wrong keypair
@ -75,7 +85,9 @@ mod tests {
#[test] #[test]
fn test_keyspace_add_keypair() { fn test_keyspace_add_keypair() {
let mut space = KeySpace::new("test_space"); let mut space = KeySpace::new("test_space");
space.add_keypair("keypair1").expect("Failed to add keypair1"); space
.add_keypair("keypair1")
.expect("Failed to add keypair1");
assert_eq!(space.keypairs.len(), 1); assert_eq!(space.keypairs.len(), 1);
assert!(space.keypairs.contains_key("keypair1")); assert!(space.keypairs.contains_key("keypair1"));
@ -83,4 +95,4 @@ mod tests {
let result = space.add_keypair("keypair1"); let result = space.add_keypair("keypair1");
assert!(result.is_err()); assert!(result.is_err());
} }
} }

View File

@ -1,8 +1,8 @@
use crate::vault::keyspace::keypair_types::KeySpace;
use crate::vault::keyspace::session_manager::{ use crate::vault::keyspace::session_manager::{
clear_session, create_keypair, create_space, get_current_space, get_selected_keypair, clear_session, create_keypair, create_space, get_current_space, get_selected_keypair,
list_keypairs, select_keypair, set_current_space, SESSION, list_keypairs, select_keypair, set_current_space,
}; };
use crate::vault::keyspace::keypair_types::KeySpace;
// Helper function to clear the session before each test // Helper function to clear the session before each test
fn setup_test() { fn setup_test() {
@ -48,7 +48,8 @@ mod tests {
assert_eq!(keypair.name, "test_keypair"); assert_eq!(keypair.name, "test_keypair");
select_keypair("test_keypair").expect("Failed to select keypair"); select_keypair("test_keypair").expect("Failed to select keypair");
let selected_keypair = get_selected_keypair().expect("Failed to get selected keypair after select"); let selected_keypair =
get_selected_keypair().expect("Failed to get selected keypair after select");
assert_eq!(selected_keypair.name, "test_keypair"); assert_eq!(selected_keypair.name, "test_keypair");
} }

View File

@ -1,5 +1,4 @@
use crate::vault::kvs::store::{create_store, delete_store, open_store, KvStore}; use crate::vault::kvs::store::{create_store, delete_store, open_store};
use std::path::PathBuf;
// Helper function to generate a unique store name for each test // Helper function to generate a unique store name for each test
fn generate_test_store_name() -> String { fn generate_test_store_name() -> String {
@ -102,4 +101,4 @@ mod tests {
cleanup_test_store(&store_name); cleanup_test_store(&store_name);
} }
} }