vector_core/community/
cipher.rs1use nostr_sdk::nips::nip44::v2::{decrypt_to_bytes, encrypt_to_bytes, ConversationKey};
7
8pub fn seal(key: &[u8; 32], plaintext: &[u8]) -> Result<String, String> {
10 let ck = ConversationKey::new(*key);
11 let ciphertext = encrypt_to_bytes(&ck, plaintext).map_err(|e| e.to_string())?;
12 Ok(base64_simd::STANDARD.encode_to_string(&ciphertext))
13}
14
15pub fn open(key: &[u8; 32], content_b64: &str) -> Result<Vec<u8>, String> {
18 let ciphertext = base64_simd::STANDARD
19 .decode_to_vec(content_b64.as_bytes())
20 .map_err(|e| e.to_string())?;
21 let ck = ConversationKey::new(*key);
22 decrypt_to_bytes(&ck, &ciphertext).map_err(|e| e.to_string())
23}
24
25#[cfg(test)]
26mod tests {
27 use super::*;
28
29 #[test]
30 fn round_trip() {
31 let key = [0x5au8; 32];
32 let sealed = seal(&key, b"hello community").unwrap();
33 assert_eq!(open(&key, &sealed).unwrap(), b"hello community");
34 }
35
36 #[test]
37 fn wrong_key_fails() {
38 let sealed = seal(&[1u8; 32], b"secret").unwrap();
39 assert!(open(&[2u8; 32], &sealed).is_err());
40 }
41
42 #[test]
43 fn distinct_ciphertext_per_call() {
44 let key = [9u8; 32];
45 assert_ne!(seal(&key, b"x").unwrap(), seal(&key, b"x").unwrap());
46 }
47}