1use crypto_secretbox::{
4 aead::{Aead, AeadCore, KeyInit, OsRng},
5 XSalsa20Poly1305,
6};
7use rand::random;
8
9pub use crate::keys::{Keypair, PublicKey};
10
11pub use ed25519_dalek::Signature;
12
13pub type Hash = blake3::Hash;
15
16pub use blake3::hash;
17
18pub use blake3::Hasher;
19
20pub fn random_hash() -> Hash {
22 Hash::from_bytes(random())
23}
24
25pub fn random_bytes<const N: usize>() -> [u8; N] {
27 let arr: [u8; N] = random();
28
29 arr
30}
31
32pub fn encrypt(plain_text: &[u8], encryption_key: &[u8; 32]) -> Vec<u8> {
34 if plain_text.is_empty() {
35 return plain_text.to_vec();
36 }
37
38 let cipher = XSalsa20Poly1305::new(encryption_key.into());
39 let nonce = XSalsa20Poly1305::generate_nonce(&mut OsRng); let ciphertext = cipher
41 .encrypt(&nonce, plain_text)
42 .expect("XSalsa20Poly1305 encrypt should be infallible");
43
44 let mut out: Vec<u8> = Vec::with_capacity(nonce.len() + ciphertext.len());
45 out.extend_from_slice(nonce.as_ref());
46 out.extend_from_slice(&ciphertext);
47
48 out
49}
50
51pub fn decrypt(bytes: &[u8], encryption_key: &[u8; 32]) -> Result<Vec<u8>, DecryptError> {
53 if bytes.is_empty() {
54 return Ok(bytes.to_vec());
55 }
56
57 let cipher = XSalsa20Poly1305::new(encryption_key.into());
58
59 if bytes.len() < 24 {
60 return Err(DecryptError::TooSmall(bytes.len()));
61 }
62
63 Ok(cipher.decrypt(bytes[..24].into(), &bytes[24..])?)
64}
65
66#[derive(thiserror::Error, Debug)]
67pub enum DecryptError {
69 #[error(transparent)]
70 Fail(#[from] crypto_secretbox::Error),
72
73 #[error("Encrypted message too small, expected at least 24 bytes nonce, received {0} bytes")]
74 TooSmall(usize),
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81
82 #[test]
83 fn encrypt_decrypt() {
84 let plain_text = "Plain text!";
85 let encryption_key = [0; 32];
86
87 let encrypted = encrypt(plain_text.as_bytes(), &encryption_key);
88 let decrypted = decrypt(&encrypted, &encryption_key).unwrap();
89
90 assert_eq!(decrypted, plain_text.as_bytes())
91 }
92}