pubky_messenger/
message.rs1use anyhow::{anyhow, Result};
2use blake3::Hasher;
3use ed25519_dalek::Signature;
4use pkarr::{Keypair, PublicKey};
5use pubky_common::crypto::{decrypt, encrypt};
6use serde::{Deserialize, Serialize};
7use std::time::{SystemTime, UNIX_EPOCH};
8use uuid::Uuid;
9
10use crate::crypto::generate_shared_secret;
11
12#[derive(Serialize, Deserialize, Debug, Clone)]
14pub struct PrivateMessage {
15 pub timestamp: u64,
16 pub encrypted_sender: Vec<u8>,
17 pub encrypted_content: Vec<u8>,
18 pub signature_bytes: Vec<u8>,
19}
20
21impl PrivateMessage {
22 pub fn new(sender_keypair: &Keypair, recipient_pk: &PublicKey, content: &str) -> Result<Self> {
24 let content_bytes = content.as_bytes();
25 let timestamp = SystemTime::now()
26 .duration_since(UNIX_EPOCH)
27 .unwrap()
28 .as_secs();
29
30 let mut hasher = Hasher::new();
32 hasher.update(content_bytes);
33 hasher.update(sender_keypair.public_key().as_bytes());
34 hasher.update(×tamp.to_be_bytes());
35 let message_digest = hasher.finalize();
36
37 let signature = sender_keypair.sign(message_digest.as_bytes());
39 let signature_bytes = signature.to_bytes().to_vec();
40
41 let shared_secret = generate_shared_secret(sender_keypair, recipient_pk)?;
43 let shared_secret_bytes = hex::decode(&shared_secret)?;
44
45 let mut encryption_key = [0u8; 32];
46 encryption_key.copy_from_slice(&shared_secret_bytes);
47
48 let encrypted_content = encrypt(content_bytes, &encryption_key);
50 let sender_string = sender_keypair.public_key().to_string();
51 let encrypted_sender = encrypt(sender_string.as_bytes(), &encryption_key);
52
53 Ok(Self {
54 timestamp,
55 encrypted_sender,
56 encrypted_content,
57 signature_bytes,
58 })
59 }
60
61 pub fn decrypt_content(
63 &self,
64 receiver_keypair: &Keypair,
65 other_participant: &PublicKey,
66 ) -> Result<String> {
67 let shared_secret = generate_shared_secret(receiver_keypair, other_participant)?;
68 let shared_secret_bytes = hex::decode(&shared_secret)?;
69
70 let mut encryption_key = [0u8; 32];
71 encryption_key.copy_from_slice(&shared_secret_bytes);
72
73 let decrypted = decrypt(&self.encrypted_content, &encryption_key)?;
74 Ok(String::from_utf8(decrypted)?)
75 }
76
77 pub fn decrypt_sender(
79 &self,
80 receiver_keypair: &Keypair,
81 other_participant: &PublicKey,
82 ) -> Result<String> {
83 let shared_secret = generate_shared_secret(receiver_keypair, other_participant)?;
84 let shared_secret_bytes = hex::decode(&shared_secret)?;
85
86 let mut encryption_key = [0u8; 32];
87 encryption_key.copy_from_slice(&shared_secret_bytes);
88
89 let decrypted = decrypt(&self.encrypted_sender, &encryption_key)?;
90 Ok(String::from_utf8(decrypted)?)
91 }
92
93 pub fn verify_signature(
95 &self,
96 decrypted_content: &str,
97 decrypted_sender: &str,
98 ) -> Result<bool> {
99 let sender_pk = PublicKey::try_from(decrypted_sender)?;
100
101 let mut hasher = Hasher::new();
102 hasher.update(decrypted_content.as_bytes());
103 hasher.update(sender_pk.as_bytes());
104 hasher.update(&self.timestamp.to_be_bytes());
105 let message_digest = hasher.finalize();
106
107 if self.signature_bytes.len() != 64 {
108 return Err(anyhow!("Invalid signature length"));
109 }
110
111 let mut sig_bytes = [0u8; 64];
112 sig_bytes.copy_from_slice(&self.signature_bytes);
113 let signature = Signature::from_bytes(&sig_bytes);
114
115 match sender_pk.verify(message_digest.as_bytes(), &signature) {
116 Ok(()) => Ok(true),
117 Err(_) => Ok(false),
118 }
119 }
120
121 pub fn generate_id() -> String {
123 Uuid::new_v4().to_string()
124 }
125}
126
127#[derive(Debug, Clone, Serialize, Deserialize)]
129pub struct DecryptedMessage {
130 pub sender: String,
131 pub content: String,
132 pub timestamp: u64,
133 pub verified: bool,
134}