1use ed25519_dalek::SigningKey;
13use rand::rngs::OsRng;
14use rand::RngCore;
15use chacha20poly1305::{XChaCha20Poly1305, KeyInit, AeadCore};
16use chacha20poly1305::aead::Aead;
17use chacha20poly1305::XNonce;
18use crate::error::VCLError;
19
20#[derive(Clone, Debug)]
24pub struct KeyPair {
25 pub public_key: Vec<u8>,
27 pub private_key: Vec<u8>,
29}
30
31impl KeyPair {
32 pub fn generate() -> Self {
34 let mut secret_bytes = [0u8; 32];
35 OsRng.fill_bytes(&mut secret_bytes);
36 let signing_key = SigningKey::from_bytes(&secret_bytes);
37 let verifying_key = signing_key.verifying_key();
38 KeyPair {
39 public_key: verifying_key.to_bytes().to_vec(),
40 private_key: signing_key.to_bytes().to_vec(),
41 }
42 }
43}
44
45pub fn encrypt_payload(data: &[u8], key: &[u8; 32]) -> Result<(Vec<u8>, [u8; 24]), VCLError> {
56 let cipher = XChaCha20Poly1305::new_from_slice(key)
57 .map_err(|e| VCLError::InvalidKey(format!("Invalid key length: {}", e)))?;
58
59 let nonce = XChaCha20Poly1305::generate_nonce(&mut OsRng);
60 let mut nonce_bytes = [0u8; 24];
61 nonce_bytes.copy_from_slice(nonce.as_slice());
62
63 let ciphertext = cipher
64 .encrypt(&nonce, data)
65 .map_err(|e| VCLError::CryptoError(format!("Encryption failed: {}", e)))?;
66
67 Ok((ciphertext, nonce_bytes))
68}
69
70pub fn decrypt_payload(ciphertext: &[u8], key: &[u8; 32], nonce: &[u8; 24]) -> Result<Vec<u8>, VCLError> {
77 let cipher = XChaCha20Poly1305::new_from_slice(key)
78 .map_err(|e| VCLError::InvalidKey(format!("Invalid key length: {}", e)))?;
79
80 let nonce = XNonce::from_slice(nonce);
81
82 cipher
83 .decrypt(nonce, ciphertext)
84 .map_err(|e| VCLError::CryptoError(format!("Decryption failed: {}", e)))
85}
86
87#[allow(dead_code)]
89pub fn hash_data(data: &[u8]) -> Vec<u8> {
90 use sha2::{Sha256, Digest};
91 Sha256::new().chain_update(data).finalize().to_vec()
92}
93
94#[cfg(test)]
95mod tests {
96 use super::*;
97
98 #[test]
99 fn test_keypair_generate() {
100 let kp1 = KeyPair::generate();
101 let kp2 = KeyPair::generate();
102 assert_eq!(kp1.public_key.len(), 32);
103 assert_eq!(kp1.private_key.len(), 32);
104 assert_ne!(kp1.public_key, kp2.public_key);
105 }
106
107 #[test]
108 fn test_encrypt_decrypt() {
109 let key = [1u8; 32];
110 let data = b"Hello, VCL!";
111 let (ciphertext, nonce) = encrypt_payload(data, &key).unwrap();
112 let decrypted = decrypt_payload(&ciphertext, &key, &nonce).unwrap();
113 assert_eq!(data, decrypted.as_slice());
114 }
115
116 #[test]
117 fn test_decrypt_wrong_key_fails() {
118 let key1 = [1u8; 32];
119 let key2 = [2u8; 32];
120 let data = b"Secret message";
121 let (ciphertext, nonce) = encrypt_payload(data, &key1).unwrap();
122 let result = decrypt_payload(&ciphertext, &key2, &nonce);
123 assert!(result.is_err());
124 }
125
126 #[test]
127 fn test_hash_data() {
128 let h1 = hash_data(b"test");
129 let h2 = hash_data(b"test");
130 let h3 = hash_data(b"Test");
131 assert_eq!(h1, h2);
132 assert_ne!(h1, h3);
133 assert_eq!(h1.len(), 32);
134 }
135}