use crate::secure_stream::crypto::error::DecryptionError;
use crate::secure_stream::crypto::shared::SharedSecretKey;
use crate::secure_stream::crypto::PublicEncryptKey;
use crate::secure_stream::serialize::deserialize;
use serde::de::DeserializeOwned;
use serde::Serialize;
use sodiumoxide::crypto::box_::{SecretKey, SECRETKEYBYTES};
use sodiumoxide::crypto::{box_, sealedbox};
use std::sync::Arc;
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct SecretEncryptKey {
pub(super) inner: Arc<SecretEncryptKeyInner>,
}
#[derive(Debug, PartialEq, Eq)]
pub(super) struct SecretEncryptKeyInner {
pub(super) encrypt: SecretKey,
}
impl SecretEncryptKey {
pub fn from_bytes(secret_key: [u8; SECRETKEYBYTES]) -> Self {
Self {
inner: Arc::new(SecretEncryptKeyInner {
encrypt: SecretKey(secret_key),
}),
}
}
pub fn shared_secret(&self, their_pk: &PublicEncryptKey) -> SharedSecretKey {
let precomputed = Arc::new(box_::precompute(&their_pk.inner, &self.inner.encrypt));
SharedSecretKey { precomputed }
}
pub fn into_bytes(self) -> [u8; SECRETKEYBYTES] {
self.inner.encrypt.0
}
pub fn anonymously_decrypt<T>(
&self,
ciphertext: &[u8],
my_pk: &PublicEncryptKey,
) -> Result<T, DecryptionError>
where
T: Serialize + DeserializeOwned,
{
Ok(deserialize(
&self.anonymously_decrypt_bytes(ciphertext, my_pk)?,
)?)
}
pub fn anonymously_decrypt_bytes(
&self,
ciphertext: &[u8],
my_pk: &PublicEncryptKey,
) -> Result<Vec<u8>, DecryptionError> {
sealedbox::open(ciphertext, &my_pk.inner, &self.inner.encrypt)
.map_err(DecryptionError::GenericDecryptionError)
}
}