use crate::dsnp::dsnp_configs::{PublicKeyType, SecretKeyType};
use dryoc::{
classic::crypto_box::{crypto_box_seal, crypto_box_seal_open},
constants::CRYPTO_BOX_SEALBYTES,
dryocbox::ByteArray,
};
use dsnp_graph_config::errors::{DsnpGraphError, DsnpGraphResult};
use log::Level;
use log_result_proc_macro::log_result_err;
pub trait EncryptionBehavior {
fn encrypt(&self, plain_data: &[u8], input: &PublicKeyType) -> DsnpGraphResult<Vec<u8>>;
fn decrypt(&self, encrypted_data: &[u8], input: &SecretKeyType) -> DsnpGraphResult<Vec<u8>>;
}
#[derive(Clone, Debug, Eq, PartialEq, Default, Hash)]
pub struct SealBox;
impl EncryptionBehavior for SealBox {
#[log_result_err(Level::Info)]
fn encrypt(&self, plain_data: &[u8], input: &PublicKeyType) -> DsnpGraphResult<Vec<u8>> {
match input {
PublicKeyType::Version1_0(key) => {
let mut encrypted =
vec![0u8; plain_data.len().saturating_add(CRYPTO_BOX_SEALBYTES)];
crypto_box_seal(&mut encrypted, plain_data, key.as_array())
.map_err(|e| DsnpGraphError::EncryptionError(e.to_string()))?;
Ok(encrypted)
},
}
}
#[log_result_err(Level::Info)]
fn decrypt(&self, encrypted_data: &[u8], input: &SecretKeyType) -> DsnpGraphResult<Vec<u8>> {
match input {
SecretKeyType::Version1_0(key) => {
let mut plain =
vec![0u8; encrypted_data.len().saturating_sub(CRYPTO_BOX_SEALBYTES)];
crypto_box_seal_open(
plain.as_mut_slice(),
encrypted_data,
key.public_key.as_array(),
key.secret_key.as_array(),
)
.map_err(|e| DsnpGraphError::DecryptionError(e.to_string()))?;
Ok(plain)
},
}
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::dsnp::dsnp_configs::KeyPairType;
use dryoc::keypair::StackKeyPair;
#[test]
fn sealbox_should_encrypt_and_decrypt_successfully() {
let plain_data = vec![
23, 23, 109, 198, 111, 70, 2, 89, 2u8, 1, 0, 23, 5, 82, 100, 56, 1, 120, 200, 250, 140,
83, 98, 0, 10, 234, 88, 23, 54, 23, 23, 109, 198, 111, 70, 2, 89,
];
let key_pair = KeyPairType::Version1_0(StackKeyPair::gen());
let encrypted = SealBox.encrypt(&plain_data, &(&key_pair).into()).unwrap();
let decrypted = SealBox.decrypt(&encrypted, &key_pair.into()).unwrap();
assert_eq!(decrypted, plain_data);
}
#[test]
fn sealbox_decrypting_corrupted_data_should_fail() {
let plain_data = vec![83, 98, 0, 10, 234, 88, 23, 54, 23, 23, 109, 198, 111, 70, 2, 89];
let key_pair = KeyPairType::Version1_0(StackKeyPair::from_seed(&[0, 1, 2, 3, 4]));
let mut encrypted = SealBox.encrypt(&plain_data, &(&key_pair).into()).unwrap();
encrypted[1] = !encrypted[1]; let decrypted = SealBox.decrypt(&encrypted, &key_pair.into());
assert!(decrypted.is_err());
}
}