Skip to main content

vcl_protocol/
packet.rs

1use sha2::{Sha256, Digest};
2use ed25519_dalek::{SigningKey, VerifyingKey, Signature, Signer, Verifier};
3use serde::{Serialize, Deserialize};
4
5#[derive(Serialize, Deserialize, Clone, Debug)]
6pub struct VCLPacket {
7    pub version: u8,
8    pub sequence: u64,
9    pub prev_hash: Vec<u8>,
10    pub nonce: [u8; 24],
11    pub payload: Vec<u8>,
12    pub signature: Vec<u8>,
13}
14
15impl VCLPacket {
16    pub fn new(sequence: u64, prev_hash: Vec<u8>, payload: Vec<u8>, nonce: [u8; 24]) -> Self {
17        VCLPacket {
18            version: 1,
19            sequence,
20            prev_hash,
21            nonce,
22            payload,
23            signature: Vec::new(),
24        }
25    }
26
27    pub fn compute_hash(&self) -> Vec<u8> {
28        let mut hasher = Sha256::new();
29        hasher.update(self.version.to_be_bytes());
30        hasher.update(self.sequence.to_be_bytes());
31        hasher.update(&self.prev_hash);
32        hasher.update(&self.nonce);
33        hasher.update(&self.payload);
34        hasher.finalize().to_vec()
35    }
36
37    pub fn sign(&mut self, private_key: &[u8]) {
38        let key_bytes: &[u8; 32] = private_key.try_into().unwrap();
39        let signing_key = SigningKey::from_bytes(key_bytes);
40        let hash = self.compute_hash();
41        let signature: Signature = signing_key.sign(&hash);
42        self.signature = signature.to_bytes().to_vec();
43    }
44
45    pub fn verify(&self, public_key: &[u8]) -> bool {
46        if self.signature.len() != 64 {
47            return false;
48        }
49        let key_bytes: &[u8; 32] = public_key.try_into().unwrap();
50        let verifying_key = VerifyingKey::from_bytes(key_bytes).unwrap();
51        let sig_bytes: &[u8; 64] = self.signature.as_slice().try_into().unwrap();
52        let signature = Signature::from_bytes(sig_bytes);
53        let hash = self.compute_hash();
54        verifying_key.verify(&hash, &signature).is_ok()
55    }
56
57    pub fn validate_chain(&self, expected_prev_hash: &[u8]) -> bool {
58        self.prev_hash == expected_prev_hash
59    }
60
61    pub fn serialize(&self) -> Vec<u8> {
62        bincode::serialize(self).unwrap()
63    }
64
65    pub fn deserialize(data: &[u8]) -> Result<Self, String> {
66        bincode::deserialize(data).map_err(|e| e.to_string())
67    }
68}
69
70#[cfg(test)]
71mod tests {
72    use crate::crypto::KeyPair;
73    use super::*;
74
75    fn test_keypair() -> KeyPair {
76        KeyPair::generate()
77    }
78
79    #[test]
80    fn test_packet_new() {
81        let packet = VCLPacket::new(1, vec![0; 32], b"test".to_vec(), [0; 24]);
82        assert_eq!(packet.version, 1);
83        assert_eq!(packet.sequence, 1);
84        assert_eq!(packet.payload, b"test");
85    }
86
87    #[test]
88    fn test_compute_hash() {
89        let p1 = VCLPacket::new(1, vec![0; 32], b"A".to_vec(), [0; 24]);
90        let p2 = VCLPacket::new(1, vec![0; 32], b"B".to_vec(), [0; 24]);
91        assert_ne!(p1.compute_hash(), p2.compute_hash());
92    }
93
94    #[test]
95    fn test_sign_verify() {
96        let kp = test_keypair();
97        let mut packet = VCLPacket::new(1, vec![0; 32], b"test".to_vec(), [0; 24]);
98        packet.sign(&kp.private_key);
99        assert!(packet.verify(&kp.public_key));
100    }
101
102    #[test]
103    fn test_verify_wrong_key_fails() {
104        let kp1 = test_keypair();
105        let kp2 = test_keypair();
106        let mut packet = VCLPacket::new(1, vec![0; 32], b"test".to_vec(), [0; 24]);
107        packet.sign(&kp1.private_key);
108        assert!(!packet.verify(&kp2.public_key));
109    }
110
111    #[test]
112    fn test_validate_chain() {
113        let prev = vec![1, 2, 3];
114        let packet = VCLPacket::new(1, prev.clone(), b"test".to_vec(), [0; 24]);
115        assert!(packet.validate_chain(&prev));
116        assert!(!packet.validate_chain(&[4, 5, 6]));
117    }
118
119    #[test]
120    fn test_serialize_deserialize() {
121        let original = VCLPacket::new(42, vec![9; 32], b"payload".to_vec(), [7; 24]);
122        let bytes = original.serialize();
123        let restored = VCLPacket::deserialize(&bytes).unwrap();
124        assert_eq!(original.sequence, restored.sequence);
125        assert_eq!(original.payload, restored.payload);
126        assert_eq!(original.nonce, restored.nonce);
127    }
128}