use crate::{ NameString, crypto::{Keystore, PrivateKey, PublicKey, SharedSecret}, }; use bytes::Bytes; use tinyvec::ArrayVec; #[derive(PartialEq, Clone, Debug)] pub struct Identity { pub private_key: PrivateKey, pub hash_prefix: u32, pub secrets: ArrayVec<[(u32, SharedSecret); 10]>, } impl Default for Identity { fn default() -> Self { let private_key = PrivateKey::default(); let hash_prefix = private_key.hash_prefix(); Self { private_key, hash_prefix, secrets: Default::default(), } } } #[derive(PartialEq, Clone, Debug)] pub struct StaticKeystore { pub identities: ArrayVec<[Identity; 10]>, pub groups: ArrayVec<[SharedSecret; 10]>, } impl Keystore for StaticKeystore { fn decrypt_and_id_p2p( &self, _source: u8, _dest: u8, mac: u16, data: &Bytes, ) -> Option<(Bytes, u32, u32)> { // Just brute-force all the secrets until one matches... for identity in self.identities.iter() { for (peer_prefix, secret) in identity.secrets.iter() { let result = secret.mac_then_decrypt(mac, data); if let Some(result) = result { return Some((result, identity.hash_prefix, *peer_prefix)); } } } None } fn decrypt_and_id_group( &self, _group_hash_prefix: u8, mac: u16, data: &Bytes, ) -> Option<(Bytes, Option)> { for group in self.groups.iter() { let result = group.mac_then_decrypt(mac, data); if let Some(result) = result { return Some((result, None)); } } None } fn decrypt_anon( &self, _dest: u8, pub_key: &PublicKey, mac: u16, data: &Bytes, ) -> Option<(Bytes, u32)> { // For each identity, create a shared secret against the provided public key and check it. for identity in self.identities.iter() { let secret = identity.private_key.create_secret(pub_key); let result = secret.mac_then_decrypt(mac, data); if let Some(result) = result { return Some((result, identity.hash_prefix)); } } None } } #[derive(PartialEq, Debug, Clone)] pub struct StaticKeystoreInput { pub identities: ArrayVec<[PrivateKey; 10]>, pub contacts: ArrayVec<[PublicKey; 10]>, pub groups: ArrayVec<[SharedSecret; 10]>, } impl StaticKeystoreInput { pub fn compile(self) -> StaticKeystore { let mut retval = StaticKeystore { identities: ArrayVec::new(), groups: ArrayVec::new(), }; for identity_in in self.identities { let mut identity = Identity::default(); identity.private_key = identity_in; identity.hash_prefix = PublicKey::from(&identity.private_key).hash_prefix(); for contact_in in self.contacts.iter() { identity.secrets.push(( contact_in.hash_prefix(), identity.private_key.create_secret(&contact_in), )); } retval.identities.push(identity); } for group in self.groups.iter() { retval.groups.push(group.clone()); } retval } } #[cfg(test)] mod tests { #[test] fn test_compile() {} }