1#[cfg(not(feature = "std"))]
2use alloc::vec::Vec;
3#[cfg(feature = "std")]
4use std::vec::Vec;
5
6use crate::{
7 errors::LllvError,
8 header::{CapsuleFlags, CapsuleHeader},
9 version::HEADER_LEN,
10};
11use blake3::hash;
12use ed25519_dalek::{Signature, Signer, SigningKey, VerifyingKey};
13
14#[derive(Clone, Debug)]
15pub struct Capsule {
16 pub header: CapsuleHeader,
17 pub payload: Vec<u8>,
18}
19
20impl Capsule {
21 pub fn create(
22 dim: u16,
23 payload: &[u8],
24 flags: CapsuleFlags,
25 sk: &SigningKey,
26 ) -> Result<Self, LllvError> {
27 let cid = *hash(payload).as_bytes();
28 #[cfg(feature = "std")]
29 let ts_ms = (std::time::SystemTime::now()
30 .duration_since(std::time::UNIX_EPOCH)
31 .unwrap()
32 .as_millis()) as u64;
33 #[cfg(not(feature = "std"))]
34 let ts_ms = 0u64; let len = u32::try_from(payload.len()).map_err(|_| LllvError::MismatchedLengths)?;
36 let mut header = CapsuleHeader::empty(dim, flags, cid, len, ts_ms);
37
38 let mut to_sign = Vec::with_capacity(HEADER_LEN - 64 + payload.len());
40 to_sign.extend_from_slice(&header.to_bytes_wo_sig());
41 to_sign.extend_from_slice(payload);
42
43 let sig: Signature = sk.sign(&to_sign);
44 header.sig.copy_from_slice(&sig.to_bytes());
45
46 Ok(Self {
47 header,
48 payload: payload.to_vec(),
49 })
50 }
51
52 pub fn to_bytes(&self) -> Vec<u8> {
53 let mut v = Vec::with_capacity(HEADER_LEN + self.payload.len());
54 v.extend_from_slice(&self.header.to_bytes());
55 v.extend_from_slice(&self.payload);
56 v
57 }
58
59 pub fn from_bytes(raw: &[u8]) -> Result<Self, LllvError> {
60 let header = CapsuleHeader::from_bytes(raw)?;
61 let payload = raw[HEADER_LEN..].to_vec();
62 if payload.len() != header.len as usize {
63 return Err(LllvError::MismatchedLengths);
64 }
65 Ok(Self { header, payload })
66 }
67
68 pub fn verify_cid(&self) -> Result<(), LllvError> {
70 let cid_now = *hash(&self.payload).as_bytes();
71 if cid_now != self.header.cid {
72 return Err(LllvError::BadSignature);
73 }
74 Ok(())
75 }
76
77 pub fn verify_with(&self, pk: &VerifyingKey) -> Result<(), LllvError> {
79 self.verify_cid()?;
80 let mut to_verify = Vec::with_capacity(HEADER_LEN - 64 + self.payload.len());
81 to_verify.extend_from_slice(&self.header.to_bytes_wo_sig());
82 to_verify.extend_from_slice(&self.payload);
83
84 let sig = ed25519_dalek::Signature::from_bytes(&self.header.sig);
85 pk.verify_strict(&to_verify, &sig)
86 .map_err(|_| LllvError::BadSignature)
87 }
88
89 #[deprecated(
90 since = "0.1.0",
91 note = "use verify_with(&pk) para autenticidade ou verify_cid() para integridade"
92 )]
93 pub fn verify(&self) -> Result<(), LllvError> {
94 self.verify_cid()
95 }
96}