saltbox.rs
1 /* This file is part of DarkFi (https://dark.fi) 2 * 3 * Copyright (C) 2020-2025 Dyne.org foundation 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU Affero General Public License as 7 * published by the Free Software Foundation, either version 3 of the 8 * License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Affero General Public License for more details. 14 * 15 * You should have received a copy of the GNU Affero General Public License 16 * along with this program. If not, see <https://www.gnu.org/licenses/>. 17 */ 18 19 use crypto_box::{ 20 aead::{Aead, AeadCore}, 21 ChaChaBox, 22 }; 23 use rand::rngs::OsRng; 24 25 /// Encrypt given data using the given `ChaChaBox`. 26 /// Returns base58-encoded string of the ciphertext. 27 /// Panics if encryption fails. 28 /// 29 /// The encryption format we're using with `ChaChaBox` is `nonce||ciphertext`, 30 /// where nonce is 24 bytes large, and the remaining data should be the ciphertext. 31 pub fn encrypt(salt_box: &ChaChaBox, plaintext: &[u8]) -> String { 32 // Generate the nonce 33 let nonce = ChaChaBox::generate_nonce(&mut OsRng); 34 35 // Encrypt 36 let mut ciphertext = salt_box.encrypt(&nonce, plaintext).unwrap(); 37 38 // Concatenate 39 let mut concat = Vec::with_capacity(24 + ciphertext.len()); 40 concat.append(&mut nonce.as_slice().to_vec()); 41 concat.append(&mut ciphertext); 42 43 // Encode 44 bs58::encode(concat).into_string() 45 } 46 47 /// Attempt to decrypt given ciphertext using the given `ChaChaBox`. 48 /// Returns a `Vec<u8>` on success, and `None` on failure. 49 /// 50 /// The encryption format we're using with `ChaChaBox` is `nonce||ciphertext`, 51 /// where nonce is 24 bytes large, and the remaining data should be the ciphertext. 52 pub fn try_decrypt(salt_box: &ChaChaBox, ciphertext: &[u8]) -> Option<Vec<u8>> { 53 // Make sure we have enough bytes to work with 54 if ciphertext.len() < 25 { 55 return None 56 } 57 58 salt_box.decrypt((&ciphertext[0..24]).into(), &ciphertext[24..]).ok() 59 }