rejson/crypto/
encryptor.rs1use anyhow::Result;
2use nacl::{public_box, secret_box};
3
4use super::{
5 keys::{Key, KeyPair, Nonce},
6 message::Message,
7};
8
9pub struct Encryptor {
12 keys: KeyPair,
14 shared_key: Key,
16}
17
18impl Encryptor {
19 pub fn new(keys: KeyPair, shared_key: Key) -> Self {
21 Self { keys, shared_key }
22 }
23
24 pub fn create(keys: KeyPair, peer_public: Key) -> Result<Self> {
27 let shared_key = Key(public_box::calc_dhshared_key(&peer_public.0, &keys.private.0)
28 .map_err(|e| anyhow::anyhow!(e.message))?
29 .as_slice()
30 .try_into()?);
31
32 Ok(Self { keys, shared_key })
33 }
34
35 pub fn encrypt<S: Into<String>>(&self, plaintext: S) -> Result<String> {
37 let nonce = Nonce::random();
38 let value = secret_box::pack(plaintext.into().as_bytes(), &nonce.0, &self.shared_key.0)
39 .map_err(|e| anyhow::anyhow!(e.message))?;
40
41 Ok(Message {
43 version: 1,
44 key: self.keys.public.clone(),
45 nonce,
46 value,
47 }
48 .to_string())
49 }
50}
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55
56 #[test]
57 fn create() {
58 let keys = KeyPair::generate().unwrap();
59 let peer_key = Key::random();
60 let encryptor = Encryptor::create(keys.clone(), peer_key.clone()).unwrap();
61
62 assert_eq!(keys, encryptor.keys);
63 assert_ne!(Key::default(), encryptor.shared_key);
64 }
65
66 #[test]
67 fn encrypt() {
68 let encryptor = Encryptor::create(KeyPair::generate().unwrap(), Key::random()).unwrap();
69 assert!(Message::is_valid(&encryptor.encrypt("ssshhhhh").unwrap()));
70 }
71}