Skip to main content

vcl_protocol/
crypto.rs

1use ed25519_dalek::SigningKey;
2use rand::rngs::OsRng;
3use rand::RngCore;
4use chacha20poly1305::{XChaCha20Poly1305, KeyInit, AeadCore};
5use chacha20poly1305::aead::Aead;
6use chacha20poly1305::XNonce;
7
8#[derive(Clone, Debug)]
9pub struct KeyPair {
10    pub public_key: Vec<u8>,
11    pub private_key: Vec<u8>,
12}
13
14impl KeyPair {
15    pub fn generate() -> Self {
16        let mut secret_bytes = [0u8; 32];
17        OsRng.fill_bytes(&mut secret_bytes);
18        let signing_key = SigningKey::from_bytes(&secret_bytes);
19        let verifying_key = signing_key.verifying_key();
20        
21        KeyPair {
22            public_key: verifying_key.to_bytes().to_vec(),
23            private_key: signing_key.to_bytes().to_vec(),
24        }
25    }
26}
27
28pub fn encrypt_payload(data: &[u8], key: &[u8; 32]) -> (Vec<u8>, [u8; 24]) {
29    let cipher = XChaCha20Poly1305::new_from_slice(key).unwrap();
30    let nonce = XChaCha20Poly1305::generate_nonce(&mut OsRng);
31    let mut nonce_bytes = [0u8; 24];
32    nonce_bytes.copy_from_slice(nonce.as_slice());
33    
34    let ciphertext = cipher.encrypt(&nonce, data).unwrap();
35    
36    (ciphertext, nonce_bytes)
37}
38
39pub fn decrypt_payload(ciphertext: &[u8], key: &[u8; 32], nonce: &[u8; 24]) -> Result<Vec<u8>, String> {
40    let cipher = XChaCha20Poly1305::new_from_slice(key).unwrap();
41    let nonce = XNonce::from_slice(nonce);
42    
43    let plaintext = cipher.decrypt(nonce, ciphertext)
44        .map_err(|e| format!("Decryption failed: {}", e))?;
45    
46    Ok(plaintext)
47}
48
49pub fn hash_data(data: &[u8]) -> Vec<u8> {
50    use sha2::{Sha256, Digest};
51    Sha256::new().chain_update(data).finalize().to_vec()
52}
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57
58    #[test]
59    fn test_keypair_generate() {
60        let kp1 = KeyPair::generate();
61        let kp2 = KeyPair::generate();
62        assert_eq!(kp1.public_key.len(), 32);
63        assert_eq!(kp1.private_key.len(), 32);
64        assert_ne!(kp1.public_key, kp2.public_key);
65    }
66
67    #[test]
68    fn test_encrypt_decrypt() {
69        let key = [1u8; 32];
70        let data = b"Hello, VCL!";
71        
72        let (ciphertext, nonce) = encrypt_payload(data, &key);
73        let decrypted = decrypt_payload(&ciphertext, &key, &nonce).unwrap();
74        
75        assert_eq!(data, decrypted.as_slice());
76    }
77
78    #[test]
79    fn test_decrypt_wrong_key_fails() {
80        let key1 = [1u8; 32];
81        let key2 = [2u8; 32];
82        let data = b"Secret message";
83        
84        let (ciphertext, nonce) = encrypt_payload(data, &key1);
85        let result = decrypt_payload(&ciphertext, &key2, &nonce);
86        
87        assert!(result.is_err());
88    }
89
90    #[test]
91    fn test_hash_data() {
92        let h1 = hash_data(b"test");
93        let h2 = hash_data(b"test");
94        let h3 = hash_data(b"Test");
95        
96        assert_eq!(h1, h2);
97        assert_ne!(h1, h3);
98        assert_eq!(h1.len(), 32);
99    }
100}