Merge branch 'development_lee'

This commit is contained in:
timurgordon
2025-05-23 21:14:31 +03:00
17 changed files with 1197 additions and 84 deletions

View File

@@ -11,8 +11,8 @@ use std::str::FromStr;
use std::sync::Mutex;
use tokio::runtime::Runtime;
use crate::vault::ethereum;
use crate::vault::keyspace::session_manager as keypair;
use crate::vault::ethereum::contract_utils::{convert_token_to_rhai, prepare_function_arguments};
use crate::vault::{ethereum, keyspace};
use crate::vault::symmetric::implementation as symmetric_impl;
// Global Tokio runtime for blocking async operations
@@ -73,7 +73,7 @@ fn load_key_space(name: &str, password: &str) -> bool {
};
// Set as current space
match keypair::set_current_space(space) {
match keyspace::set_current_space(space) {
Ok(_) => true,
Err(e) => {
log::error!("Error setting current space: {}", e);
@@ -83,10 +83,10 @@ fn load_key_space(name: &str, password: &str) -> bool {
}
fn create_key_space(name: &str, password: &str) -> bool {
match keypair::create_space(name) {
match keyspace::session_manager::create_space(name) {
Ok(_) => {
// Get the current space
match keypair::get_current_space() {
match keyspace::get_current_space() {
Ok(space) => {
// Encrypt the key space
let encrypted_space = match symmetric_impl::encrypt_key_space(&space, password)
@@ -151,7 +151,7 @@ fn create_key_space(name: &str, password: &str) -> bool {
// Auto-save function for internal use
fn auto_save_key_space(password: &str) -> bool {
match keypair::get_current_space() {
match keyspace::get_current_space() {
Ok(space) => {
// Encrypt the key space
let encrypted_space = match symmetric_impl::encrypt_key_space(&space, password) {
@@ -207,7 +207,7 @@ fn auto_save_key_space(password: &str) -> bool {
}
fn encrypt_key_space(password: &str) -> String {
match keypair::get_current_space() {
match keyspace::get_current_space() {
Ok(space) => match symmetric_impl::encrypt_key_space(&space, password) {
Ok(encrypted_space) => match serde_json::to_string(&encrypted_space) {
Ok(json) => json,
@@ -232,7 +232,7 @@ fn decrypt_key_space(encrypted: &str, password: &str) -> bool {
match serde_json::from_str(encrypted) {
Ok(encrypted_space) => {
match symmetric_impl::decrypt_key_space(&encrypted_space, password) {
Ok(space) => match keypair::set_current_space(space) {
Ok(space) => match keyspace::set_current_space(space) {
Ok(_) => true,
Err(e) => {
log::error!("Error setting current space: {}", e);
@@ -252,35 +252,35 @@ fn decrypt_key_space(encrypted: &str, password: &str) -> bool {
}
}
// Keypair management functions
fn create_keypair(name: &str, password: &str) -> bool {
match keypair::create_keypair(name) {
// keyspace management functions
fn create_keyspace(name: &str, password: &str) -> bool {
match keyspace::create_keypair(name) {
Ok(_) => {
// Auto-save the key space after creating a keypair
// Auto-save the key space after creating a keyspace
auto_save_key_space(password)
}
Err(e) => {
log::error!("Error creating keypair: {}", e);
log::error!("Error creating keyspace: {}", e);
false
}
}
}
fn select_keypair(name: &str) -> bool {
match keypair::select_keypair(name) {
fn select_keyspace(name: &str) -> bool {
match keyspace::select_keypair(name) {
Ok(_) => true,
Err(e) => {
log::error!("Error selecting keypair: {}", e);
log::error!("Error selecting keyspace: {}", e);
false
}
}
}
fn list_keypairs() -> Vec<String> {
match keypair::list_keypairs() {
Ok(keypairs) => keypairs,
fn list_keyspaces() -> Vec<String> {
match keyspace::list_keypairs() {
Ok(keyspaces) => keyspaces,
Err(e) => {
log::error!("Error listing keypairs: {}", e);
log::error!("Error listing keyspaces: {}", e);
Vec::new()
}
}
@@ -289,7 +289,7 @@ fn list_keypairs() -> Vec<String> {
// Cryptographic operations
fn sign(message: &str) -> String {
let message_bytes = message.as_bytes();
match keypair::keypair_sign(message_bytes) {
match keyspace::keypair_sign(message_bytes) {
Ok(signature) => BASE64.encode(signature),
Err(e) => {
log::error!("Error signing message: {}", e);
@@ -301,7 +301,7 @@ fn sign(message: &str) -> String {
fn verify(message: &str, signature: &str) -> bool {
let message_bytes = message.as_bytes();
match BASE64.decode(signature) {
Ok(signature_bytes) => match keypair::keypair_verify(message_bytes, &signature_bytes) {
Ok(signature_bytes) => match keyspace::keypair_verify(message_bytes, &signature_bytes) {
Ok(is_valid) => is_valid,
Err(e) => {
log::error!("Error verifying signature: {}", e);
@@ -881,10 +881,10 @@ pub fn register_crypto_module(engine: &mut Engine) -> Result<(), Box<EvalAltResu
engine.register_fn("encrypt_key_space", encrypt_key_space);
engine.register_fn("decrypt_key_space", decrypt_key_space);
// Register keypair functions
engine.register_fn("create_keypair", create_keypair);
engine.register_fn("select_keypair", select_keypair);
engine.register_fn("list_keypairs", list_keypairs);
// Register keyspace functions
engine.register_fn("create_keyspace", create_keyspace);
engine.register_fn("select_keyspace", select_keyspace);
engine.register_fn("list_keyspaces", list_keyspaces);
// Register signing/verification functions
engine.register_fn("sign", sign);

View File

@@ -8,8 +8,8 @@ use sha2::{Digest, Sha256};
use std::str::FromStr;
use super::networks::NetworkConfig;
use crate::vault;
use crate::vault::error::CryptoError;
use crate::vault::keyspace::KeyPair;
/// An Ethereum wallet derived from a keypair.
#[derive(Debug, Clone)]
@@ -49,7 +49,7 @@ impl EthereumWallet {
/// 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: &vault::keyspace::keypair_types::KeyPair,
keypair: &KeyPair,
network: NetworkConfig,
) -> Result<Self, CryptoError> {
// Get the private key bytes from the keypair

View File

@@ -1,3 +1,4 @@
use k256::ecdh::EphemeralSecret;
/// Implementation of keypair functionality.
use k256::ecdsa::{
signature::{Signer, Verifier},
@@ -205,31 +206,32 @@ impl KeyPair {
}
/// Encrypts a message using the recipient's public key.
/// This implements a simplified version of ECIES (Elliptic Curve Integrated Encryption Scheme):
/// 1. Generate a random symmetric key
/// 2. Encrypt the message with the symmetric key
/// 3. Encrypt the symmetric key with the recipient's public key
/// 4. Return the encrypted key and the ciphertext
/// This implements ECIES (Elliptic Curve Integrated Encryption Scheme):
/// 1. Generate an ephemeral keypair
/// 2. Derive a shared secret using ECDH
/// 3. Derive encryption key from the shared secret
/// 4. Encrypt the message using symmetric encryption
/// 5. Return the ephemeral public key and the ciphertext
pub fn encrypt_asymmetric(
&self,
recipient_public_key: &[u8],
message: &[u8],
) -> Result<Vec<u8>, CryptoError> {
// Validate recipient's public key format
VerifyingKey::from_sec1_bytes(recipient_public_key)
// Parse recipient's public key
let recipient_key = VerifyingKey::from_sec1_bytes(recipient_public_key)
.map_err(|_| CryptoError::InvalidKeyLength)?;
// Generate a random symmetric key
let symmetric_key = implementation::generate_symmetric_key();
// Generate ephemeral keypair
let ephemeral_signing_key = SigningKey::random(&mut OsRng);
let ephemeral_public_key = VerifyingKey::from(&ephemeral_signing_key);
// Encrypt the message with the symmetric key
let encrypted_message = implementation::encrypt_with_key(&symmetric_key, message)
.map_err(|e| CryptoError::EncryptionFailed(e.to_string()))?;
// Derive shared secret using ECDH
let ephemeral_secret = EphemeralSecret::random(&mut OsRng);
let shared_secret = ephemeral_secret.diffie_hellman(&recipient_key.into());
// Encrypt the symmetric key with the recipient's public key
// For simplicity, we'll just use the recipient's public key to derive an encryption key
// This is not secure for production use, but works for our test
let key_encryption_key = {
// Derive encryption key from the shared secret (e.g., using HKDF or hashing)
// For simplicity, we'll hash the shared secret here
let encryption_key = {
let mut hasher = Sha256::default();
hasher.update(recipient_public_key);
// Use a fixed salt for testing purposes
@@ -237,16 +239,16 @@ impl KeyPair {
hasher.finalize().to_vec()
};
// Encrypt the symmetric key
let encrypted_key = implementation::encrypt_with_key(&key_encryption_key, &symmetric_key)
// Encrypt the message using the derived key
let ciphertext = implementation::encrypt_with_key(&encryption_key, message)
.map_err(|e| CryptoError::EncryptionFailed(e.to_string()))?;
// Format: encrypted_key_length (4 bytes) || encrypted_key || encrypted_message
let mut result = Vec::new();
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);
// Format: ephemeral_public_key || ciphertext
let mut result = ephemeral_public_key
.to_encoded_point(false)
.as_bytes()
.to_vec();
result.extend_from_slice(&ciphertext);
Ok(result)
}
@@ -254,32 +256,28 @@ impl KeyPair {
/// Decrypts a message using the recipient's private key.
/// This is the counterpart to encrypt_asymmetric.
pub fn decrypt_asymmetric(&self, ciphertext: &[u8]) -> Result<Vec<u8>, CryptoError> {
// The format is: encrypted_key_length (4 bytes) || encrypted_key || encrypted_message
if ciphertext.len() <= 4 {
// The first 33 or 65 bytes (depending on compression) are the ephemeral public key
// For simplicity, we'll assume uncompressed keys (65 bytes)
if ciphertext.len() <= 65 {
return Err(CryptoError::DecryptionFailed(
"Ciphertext too short".to_string(),
));
}
// Extract the encrypted key length
let mut key_len_bytes = [0u8; 4];
key_len_bytes.copy_from_slice(&ciphertext[0..4]);
let key_len = u32::from_be_bytes(key_len_bytes) as usize;
// Extract ephemeral public key and actual ciphertext
let ephemeral_public_key = &ciphertext[..65];
let actual_ciphertext = &ciphertext[65..];
// Check if the ciphertext is long enough
if ciphertext.len() <= 4 + key_len {
return Err(CryptoError::DecryptionFailed(
"Ciphertext too short".to_string(),
));
}
// Parse ephemeral public key
let sender_key = VerifyingKey::from_sec1_bytes(ephemeral_public_key)
.map_err(|_| CryptoError::InvalidKeyLength)?;
// Extract the encrypted key and the encrypted message
let encrypted_key = &ciphertext[4..4 + key_len];
let encrypted_message = &ciphertext[4 + key_len..];
// Derive shared secret using ECDH
let recipient_secret = EphemeralSecret::random(&mut OsRng);
let shared_secret = recipient_secret.diffie_hellman(&sender_key.into());
// Decrypt the symmetric key
// Use the same key derivation as in encryption
let key_encryption_key = {
// Derive decryption key from the shared secret (using the same method as encryption)
let decryption_key = {
let mut hasher = Sha256::default();
hasher.update(self.verifying_key.to_sec1_bytes());
// Use the same fixed salt as in encryption
@@ -287,13 +285,9 @@ impl KeyPair {
hasher.finalize().to_vec()
};
// Decrypt the symmetric key
let symmetric_key = implementation::decrypt_with_key(&key_encryption_key, encrypted_key)
.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)))
// Decrypt the message using the derived key
implementation::decrypt_with_key(&decryption_key, actual_ciphertext)
.map_err(|e| CryptoError::DecryptionFailed(e.to_string()))
}
}

View File

@@ -355,7 +355,7 @@ impl KvStore {
// Save to disk
self.save()?;
Ok(())
Ok(())
}
/// Gets the name of the store.