#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use subtle::ConstantTimeEq;
use zeroize::Zeroize;
use crate::constants::{
CRYPTO_BOX_BEFORENMBYTES, CRYPTO_BOX_MACBYTES, CRYPTO_BOX_NONCEBYTES,
CRYPTO_BOX_PUBLICKEYBYTES, CRYPTO_BOX_SEALBYTES, CRYPTO_BOX_SECRETKEYBYTES,
};
use crate::error::*;
pub use crate::types::*;
pub type PublicKey = StackByteArray<CRYPTO_BOX_PUBLICKEYBYTES>;
pub type SecretKey = StackByteArray<CRYPTO_BOX_SECRETKEYBYTES>;
pub type Nonce = StackByteArray<CRYPTO_BOX_NONCEBYTES>;
pub type Mac = StackByteArray<CRYPTO_BOX_MACBYTES>;
pub type KeyPair = crate::keypair::KeyPair<PublicKey, SecretKey>;
#[cfg(any(feature = "nightly", all(doc, not(doctest))))]
#[cfg_attr(all(feature = "nightly", doc), doc(cfg(feature = "nightly")))]
pub mod protected {
use super::*;
pub use crate::protected::*;
pub type PublicKey = HeapByteArray<CRYPTO_BOX_PUBLICKEYBYTES>;
pub type SecretKey = HeapByteArray<CRYPTO_BOX_SECRETKEYBYTES>;
pub type Nonce = HeapByteArray<CRYPTO_BOX_NONCEBYTES>;
pub type Mac = HeapByteArray<CRYPTO_BOX_MACBYTES>;
pub type LockedKeyPair = crate::keypair::KeyPair<Locked<PublicKey>, Locked<SecretKey>>;
pub type LockedROKeyPair = crate::keypair::KeyPair<LockedRO<PublicKey>, LockedRO<SecretKey>>;
pub type LockedBox = DryocBox<Locked<PublicKey>, Locked<Mac>, LockedBytes>;
}
#[cfg_attr(
feature = "serde",
derive(Zeroize, Clone, Debug, Serialize, Deserialize)
)]
#[cfg_attr(not(feature = "serde"), derive(Zeroize, Clone, Debug))]
pub struct DryocBox<
EphemeralPublicKey: ByteArray<CRYPTO_BOX_PUBLICKEYBYTES> + Zeroize,
Mac: ByteArray<CRYPTO_BOX_MACBYTES> + Zeroize,
Data: Bytes + Zeroize,
> {
ephemeral_pk: Option<EphemeralPublicKey>,
tag: Mac,
data: Data,
}
pub type VecBox = DryocBox<PublicKey, Mac, Vec<u8>>;
impl<
EphemeralPublicKey: ByteArray<CRYPTO_BOX_PUBLICKEYBYTES> + Zeroize,
Mac: NewByteArray<CRYPTO_BOX_MACBYTES> + Zeroize,
Data: NewBytes + ResizableBytes + Zeroize,
> DryocBox<EphemeralPublicKey, Mac, Data>
{
pub fn encrypt<
Message: Bytes + ?Sized,
Nonce: ByteArray<CRYPTO_BOX_NONCEBYTES>,
RecipientPublicKey: ByteArray<CRYPTO_BOX_PUBLICKEYBYTES>,
SenderSecretKey: ByteArray<CRYPTO_BOX_SECRETKEYBYTES>,
>(
message: &Message,
nonce: &Nonce,
recipient_public_key: &RecipientPublicKey,
sender_secret_key: &SenderSecretKey,
) -> Result<Self, Error> {
use crate::classic::crypto_box::crypto_box_detached;
let mut dryocbox = Self {
ephemeral_pk: None,
tag: Mac::new_byte_array(),
data: Data::new_bytes(),
};
dryocbox.data.resize(message.as_slice().len(), 0);
crypto_box_detached(
dryocbox.data.as_mut_slice(),
dryocbox.tag.as_mut_array(),
message.as_slice(),
nonce.as_array(),
recipient_public_key.as_array(),
sender_secret_key.as_array(),
);
Ok(dryocbox)
}
pub fn precalc_encrypt<
PrecalcSecretKey: ByteArray<CRYPTO_BOX_BEFORENMBYTES> + Zeroize,
Message: Bytes + ?Sized,
Nonce: ByteArray<CRYPTO_BOX_NONCEBYTES>,
>(
message: &Message,
nonce: &Nonce,
precalc_secret_key: &PrecalcSecretKey,
) -> Result<Self, Error> {
use crate::classic::crypto_box::crypto_box_detached_afternm;
let mut dryocbox = Self {
ephemeral_pk: None,
tag: Mac::new_byte_array(),
data: Data::new_bytes(),
};
dryocbox.data.resize(message.as_slice().len(), 0);
crypto_box_detached_afternm(
dryocbox.data.as_mut_slice(),
dryocbox.tag.as_mut_array(),
message.as_slice(),
nonce.as_array(),
precalc_secret_key.as_array(),
);
Ok(dryocbox)
}
}
impl<
EphemeralPublicKey: NewByteArray<CRYPTO_BOX_PUBLICKEYBYTES> + Zeroize,
Mac: NewByteArray<CRYPTO_BOX_MACBYTES> + Zeroize,
Data: NewBytes + ResizableBytes + Zeroize,
> DryocBox<EphemeralPublicKey, Mac, Data>
{
pub fn seal<
Message: Bytes + ?Sized,
RecipientPublicKey: ByteArray<CRYPTO_BOX_PUBLICKEYBYTES>,
>(
message: &Message,
recipient_public_key: &RecipientPublicKey,
) -> Result<Self, Error> {
use crate::classic::crypto_box::{
crypto_box_detached, crypto_box_keypair, crypto_box_seal_nonce,
};
let mut nonce = Nonce::new_byte_array();
let (epk, esk) = crypto_box_keypair();
crypto_box_seal_nonce(nonce.as_mut_array(), &epk, recipient_public_key.as_array());
let mut pk = EphemeralPublicKey::new_byte_array();
pk.copy_from_slice(&epk);
let mut dryocbox = Self {
ephemeral_pk: Some(pk),
tag: Mac::new_byte_array(),
data: Data::new_bytes(),
};
dryocbox.data.resize(message.as_slice().len(), 0);
crypto_box_detached(
dryocbox.data.as_mut_slice(),
dryocbox.tag.as_mut_array(),
message.as_slice(),
nonce.as_array(),
recipient_public_key.as_array(),
&esk,
);
Ok(dryocbox)
}
}
impl<
'a,
EphemeralPublicKey: ByteArray<CRYPTO_BOX_PUBLICKEYBYTES> + std::convert::TryFrom<&'a [u8]> + Zeroize,
Mac: ByteArray<CRYPTO_BOX_MACBYTES> + std::convert::TryFrom<&'a [u8]> + Zeroize,
Data: Bytes + From<&'a [u8]> + Zeroize,
> DryocBox<EphemeralPublicKey, Mac, Data>
{
pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, Error> {
if bytes.len() < CRYPTO_BOX_MACBYTES {
Err(dryoc_error!(format!(
"bytes of len {} less than expected minimum of {}",
bytes.len(),
CRYPTO_BOX_MACBYTES
)))
} else {
let (tag, data) = bytes.split_at(CRYPTO_BOX_MACBYTES);
Ok(Self {
ephemeral_pk: None,
tag: Mac::try_from(tag).map_err(|_e| dryoc_error!("invalid tag"))?,
data: Data::from(data),
})
}
}
pub fn from_sealed_bytes(bytes: &'a [u8]) -> Result<Self, Error> {
if bytes.len() < CRYPTO_BOX_SEALBYTES {
Err(dryoc_error!(format!(
"bytes of len {} less than expected minimum of {}",
bytes.len(),
CRYPTO_BOX_SEALBYTES
)))
} else {
let (seal, data) = bytes.split_at(CRYPTO_BOX_SEALBYTES);
let (epk, tag) = seal.split_at(CRYPTO_BOX_PUBLICKEYBYTES);
Ok(Self {
ephemeral_pk: Some(
EphemeralPublicKey::try_from(epk)
.map_err(|_e| dryoc_error!("invalid ephemeral public key"))?,
),
tag: Mac::try_from(tag).map_err(|_e| dryoc_error!("invalid tag"))?,
data: Data::from(data),
})
}
}
}
impl<
EphemeralPublicKey: ByteArray<CRYPTO_BOX_PUBLICKEYBYTES> + Zeroize,
Mac: ByteArray<CRYPTO_BOX_MACBYTES> + Zeroize,
Data: Bytes + Zeroize,
> DryocBox<EphemeralPublicKey, Mac, Data>
{
pub fn from_parts(tag: Mac, data: Data, ephemeral_pk: Option<EphemeralPublicKey>) -> Self {
Self {
ephemeral_pk,
tag,
data,
}
}
pub fn to_vec(&self) -> Vec<u8> {
self.to_bytes()
}
pub fn into_parts(self) -> (Mac, Data, Option<EphemeralPublicKey>) {
(self.tag, self.data, self.ephemeral_pk)
}
pub fn decrypt<
Nonce: ByteArray<CRYPTO_BOX_NONCEBYTES>,
SenderPublicKey: ByteArray<CRYPTO_BOX_PUBLICKEYBYTES>,
RecipientSecretKey: ByteArray<CRYPTO_BOX_SECRETKEYBYTES>,
Output: ResizableBytes + NewBytes,
>(
&self,
nonce: &Nonce,
sender_public_key: &SenderPublicKey,
recipient_secret_key: &RecipientSecretKey,
) -> Result<Output, Error> {
use crate::classic::crypto_box::*;
let mut message = Output::new_bytes();
message.resize(self.data.as_slice().len(), 0);
crypto_box_open_detached(
message.as_mut_slice(),
self.tag.as_array(),
self.data.as_slice(),
nonce.as_array(),
sender_public_key.as_array(),
recipient_secret_key.as_array(),
)?;
Ok(message)
}
pub fn precalc_decrypt<
PrecalcSecretKey: ByteArray<CRYPTO_BOX_BEFORENMBYTES> + Zeroize,
Nonce: ByteArray<CRYPTO_BOX_NONCEBYTES>,
Output: ResizableBytes + NewBytes,
>(
&self,
nonce: &Nonce,
precalc_secret_key: &PrecalcSecretKey,
) -> Result<Output, Error> {
use crate::classic::crypto_box::crypto_box_open_detached_afternm;
let mut message = Output::new_bytes();
message.resize(self.data.as_slice().len(), 0);
crypto_box_open_detached_afternm(
message.as_mut_slice(),
self.tag.as_array(),
self.data.as_slice(),
nonce.as_array(),
precalc_secret_key.as_array(),
)?;
Ok(message)
}
pub fn unseal<
RecipientPublicKey: ByteArray<CRYPTO_BOX_PUBLICKEYBYTES> + Zeroize,
RecipientSecretKey: ByteArray<CRYPTO_BOX_SECRETKEYBYTES> + Zeroize,
Output: ResizableBytes + NewBytes + Zeroize,
>(
&self,
recipient_keypair: &crate::keypair::KeyPair<RecipientPublicKey, RecipientSecretKey>,
) -> Result<Output, Error> {
use crate::classic::crypto_box::*;
match &self.ephemeral_pk {
Some(epk) => {
let mut nonce = Nonce::new_byte_array();
crypto_box_seal_nonce(
nonce.as_mut_array(),
epk.as_array(),
recipient_keypair.public_key.as_array(),
);
let mut message = Output::new_bytes();
message.resize(self.data.as_slice().len(), 0);
crypto_box_open_detached(
message.as_mut_slice(),
self.tag.as_array(),
self.data.as_slice(),
nonce.as_array(),
epk.as_array(),
recipient_keypair.secret_key.as_array(),
)?;
Ok(message)
}
None => Err(dryoc_error!(
"ephemeral public key is missing, cannot unseal"
)),
}
}
pub fn to_bytes<Bytes: NewBytes + ResizableBytes>(&self) -> Bytes {
let mut data = Bytes::new_bytes();
match &self.ephemeral_pk {
Some(epk) => {
data.resize(epk.len() + self.tag.len() + self.data.len(), 0);
let s = data.as_mut_slice();
s[..CRYPTO_BOX_PUBLICKEYBYTES].copy_from_slice(epk.as_slice());
s[CRYPTO_BOX_PUBLICKEYBYTES..CRYPTO_BOX_SEALBYTES]
.copy_from_slice(self.tag.as_slice());
s[CRYPTO_BOX_SEALBYTES..].copy_from_slice(self.data.as_slice());
}
None => {
data.resize(self.tag.len() + self.data.len(), 0);
let s = data.as_mut_slice();
s[..CRYPTO_BOX_MACBYTES].copy_from_slice(self.tag.as_slice());
s[CRYPTO_BOX_MACBYTES..].copy_from_slice(self.data.as_slice());
}
}
data
}
}
impl DryocBox<PublicKey, Mac, Vec<u8>> {
pub fn encrypt_to_vecbox<
Message: Bytes + ?Sized,
SecretKey: ByteArray<CRYPTO_BOX_SECRETKEYBYTES>,
>(
message: &Message,
nonce: &Nonce,
recipient_public_key: &PublicKey,
sender_secret_key: &SecretKey,
) -> Result<Self, Error> {
Self::encrypt(message, nonce, recipient_public_key, sender_secret_key)
}
pub fn precalc_encrypt_to_vecbox<
Message: Bytes + ?Sized,
PrecalcSecretKey: ByteArray<CRYPTO_BOX_BEFORENMBYTES> + Zeroize,
>(
message: &Message,
nonce: &Nonce,
precalc_secret_key: &PrecalcSecretKey,
) -> Result<Self, Error> {
Self::precalc_encrypt(message, nonce, precalc_secret_key)
}
pub fn seal_to_vecbox<Message: Bytes + ?Sized>(
message: &Message,
recipient_public_key: &PublicKey,
) -> Result<Self, Error> {
Self::seal(message, recipient_public_key)
}
pub fn decrypt_to_vec<SecretKey: ByteArray<CRYPTO_BOX_SECRETKEYBYTES>>(
&self,
nonce: &Nonce,
sender_public_key: &PublicKey,
recipient_secret_key: &SecretKey,
) -> Result<Vec<u8>, Error> {
self.decrypt(nonce, sender_public_key, recipient_secret_key)
}
pub fn precalc_decrypt_to_vec<
PrecalcSecretKey: ByteArray<CRYPTO_BOX_BEFORENMBYTES> + Zeroize,
>(
&self,
nonce: &Nonce,
precalc_secret_key: &PrecalcSecretKey,
) -> Result<Vec<u8>, Error> {
self.precalc_decrypt(nonce, precalc_secret_key)
}
pub fn unseal_to_vec<
RecipientPublicKey: ByteArray<CRYPTO_BOX_PUBLICKEYBYTES> + Zeroize,
RecipientSecretKey: ByteArray<CRYPTO_BOX_SECRETKEYBYTES> + Zeroize,
>(
&self,
recipient_keypair: &crate::keypair::KeyPair<RecipientPublicKey, RecipientSecretKey>,
) -> Result<Vec<u8>, Error> {
self.unseal(recipient_keypair)
}
}
impl<
'a,
EphemeralPublicKey: ByteArray<CRYPTO_BOX_PUBLICKEYBYTES> + Zeroize,
Mac: ByteArray<CRYPTO_BOX_MACBYTES> + Zeroize,
Data: Bytes + ResizableBytes + From<&'a [u8]> + Zeroize,
> DryocBox<EphemeralPublicKey, Mac, Data>
{
pub fn new_with_data_and_mac(tag: Mac, input: &'a [u8]) -> Self {
Self {
ephemeral_pk: None,
tag,
data: input.into(),
}
}
pub fn new_with_epk_data_and_mac(
ephemeral_pk: EphemeralPublicKey,
tag: Mac,
input: &'a [u8],
) -> Self {
Self {
ephemeral_pk: Some(ephemeral_pk),
tag,
data: input.into(),
}
}
}
impl<
EphemeralPublicKey: ByteArray<CRYPTO_BOX_PUBLICKEYBYTES> + Zeroize,
Mac: ByteArray<CRYPTO_BOX_MACBYTES> + Zeroize,
Data: Bytes + Zeroize,
> PartialEq<DryocBox<EphemeralPublicKey, Mac, Data>> for DryocBox<EphemeralPublicKey, Mac, Data>
{
fn eq(&self, other: &Self) -> bool {
if let Some(our_epk) = &self.ephemeral_pk {
if let Some(their_epk) = &other.ephemeral_pk {
self.tag.as_slice().ct_eq(other.tag.as_slice()).unwrap_u8() == 1
&& self
.data
.as_slice()
.ct_eq(other.data.as_slice())
.unwrap_u8()
== 1
&& our_epk.as_slice().ct_eq(their_epk.as_slice()).unwrap_u8() == 1
} else {
false
}
} else if other.ephemeral_pk.is_none() {
self.tag.as_slice().ct_eq(other.tag.as_slice()).unwrap_u8() == 1
&& self
.data
.as_slice()
.ct_eq(other.data.as_slice())
.unwrap_u8()
== 1
} else {
false
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::precalc::PrecalcSecretKey;
#[test]
fn test_dryocbox_vecbox() {
for i in 0..20 {
use base64::Engine as _;
use base64::engine::general_purpose;
use sodiumoxide::crypto::box_;
use sodiumoxide::crypto::box_::{Nonce as SONonce, PublicKey, SecretKey};
let keypair_sender = KeyPair::gen();
let keypair_recipient = KeyPair::gen();
let keypair_sender_copy = keypair_sender.clone();
let keypair_recipient_copy = keypair_recipient.clone();
let nonce = Nonce::gen();
let words = vec!["hello1".to_string(); i];
let message = words.join(" :D ");
let message_copy = message.clone();
let dryocbox = DryocBox::encrypt_to_vecbox(
message.as_bytes(),
&nonce,
&keypair_recipient.public_key,
&keypair_sender.secret_key,
)
.unwrap();
let ciphertext = dryocbox.to_vec();
let so_ciphertext = box_::seal(
message_copy.as_bytes(),
&SONonce::from_slice(&nonce).unwrap(),
&PublicKey::from_slice(&keypair_recipient_copy.public_key).unwrap(),
&SecretKey::from_slice(&keypair_sender_copy.secret_key).unwrap(),
);
assert_eq!(
general_purpose::STANDARD.encode(&ciphertext),
general_purpose::STANDARD.encode(&so_ciphertext)
);
let keypair_sender = keypair_sender_copy.clone();
let keypair_recipient = keypair_recipient_copy.clone();
let m = dryocbox
.decrypt_to_vec(
&nonce,
&keypair_sender.public_key,
&keypair_recipient.secret_key,
)
.expect("hmm");
let so_m = box_::open(
&ciphertext,
&SONonce::from_slice(&nonce).unwrap(),
&PublicKey::from_slice(&keypair_recipient_copy.public_key).unwrap(),
&SecretKey::from_slice(&keypair_sender_copy.secret_key).unwrap(),
)
.expect("HMMM");
assert_eq!(m, message_copy.as_bytes());
assert_eq!(m, so_m);
}
}
#[test]
fn test_decrypt_failure() {
for i in 0..20 {
use base64::Engine as _;
use base64::engine::general_purpose;
use sodiumoxide::crypto::box_;
use sodiumoxide::crypto::box_::{
Nonce as SONonce, PublicKey as SOPublicKey, SecretKey as SOSecretKey,
};
let keypair_sender = KeyPair::gen();
let keypair_recipient = KeyPair::gen();
let keypair_sender_copy = keypair_sender.clone();
let keypair_recipient_copy = keypair_recipient.clone();
let nonce = Nonce::gen();
let words = vec!["hello1".to_string(); i];
let message = words.join(" :D ");
let message_copy = message.clone();
let dryocbox = DryocBox::encrypt_to_vecbox(
message.as_bytes(),
&nonce,
&keypair_recipient.public_key,
&keypair_sender.secret_key,
)
.unwrap();
let ciphertext = dryocbox.to_vec();
let so_ciphertext = box_::seal(
message_copy.as_bytes(),
&SONonce::from_slice(&nonce).unwrap(),
&SOPublicKey::from_slice(&keypair_recipient_copy.public_key).unwrap(),
&SOSecretKey::from_slice(&keypair_sender_copy.secret_key).unwrap(),
);
assert_eq!(
general_purpose::STANDARD.encode(&ciphertext),
general_purpose::STANDARD.encode(&so_ciphertext)
);
let invalid_key = KeyPair::gen();
let invalid_key_copy_1 = invalid_key.clone();
let invalid_key_copy_2 = invalid_key.clone();
DryocBox::decrypt::<Nonce, PublicKey, SecretKey, Vec<u8>>(
&dryocbox,
&nonce,
&invalid_key_copy_1.public_key,
&invalid_key_copy_2.secret_key,
)
.expect_err("hmm");
box_::open(
&ciphertext,
&SONonce::from_slice(&nonce).unwrap(),
&SOPublicKey::from_slice(&invalid_key.public_key).unwrap(),
&SOSecretKey::from_slice(&invalid_key.secret_key).unwrap(),
)
.expect_err("HMMM");
}
}
#[test]
fn test_decrypt_failure_empty() {
for _ in 0..20 {
use crate::keypair::*;
let invalid_key = KeyPair::gen();
let invalid_key_copy_1 = invalid_key.clone();
let invalid_key_copy_2 = invalid_key.clone();
let nonce = Nonce::gen();
let dryocbox: VecBox =
DryocBox::from_bytes(b"trollolllololololollollolololololol").expect("ok");
DryocBox::decrypt::<
Nonce,
crate::classic::crypto_box::PublicKey,
crate::classic::crypto_box::SecretKey,
Vec<u8>,
>(
&dryocbox,
&nonce,
&invalid_key_copy_1.public_key,
&invalid_key_copy_2.secret_key,
)
.expect_err("hmm");
}
}
#[test]
fn test_copy() {
for _ in 0..20 {
use std::convert::TryFrom;
use crate::rng::*;
let mut data1: Vec<u8> = vec![0u8; 1024];
copy_randombytes(data1.as_mut_slice());
let data1_copy = data1.clone();
let dryocbox: VecBox = DryocBox::from_bytes(&data1).expect("ok");
assert_eq!(dryocbox.data.as_slice(), &data1_copy[CRYPTO_BOX_MACBYTES..]);
assert_eq!(dryocbox.tag.as_slice(), &data1_copy[..CRYPTO_BOX_MACBYTES]);
let data1 = data1_copy.clone();
let (tag, data) = data1.split_at(CRYPTO_BOX_MACBYTES);
let dryocbox: VecBox =
DryocBox::new_with_data_and_mac(Mac::try_from(tag).expect("mac"), data);
assert_eq!(dryocbox.data.as_slice(), &data1_copy[CRYPTO_BOX_MACBYTES..]);
assert_eq!(dryocbox.tag.as_array(), &data1_copy[..CRYPTO_BOX_MACBYTES]);
}
}
#[test]
fn test_dryocbox_seal_vecbox() {
for i in 0..20 {
use sodiumoxide::crypto::box_::{PublicKey as SOPublicKey, SecretKey as SOSecretKey};
use sodiumoxide::crypto::sealedbox::curve25519blake2bxsalsa20poly1305;
let keypair_recipient = KeyPair::gen();
let words = vec!["hello1".to_string(); i];
let message = words.join(" :D ");
let message_copy = message.clone();
let dryocbox =
DryocBox::seal_to_vecbox(message.as_bytes(), &keypair_recipient.public_key)
.unwrap();
let ciphertext = dryocbox.to_vec();
let m = dryocbox.unseal_to_vec(&keypair_recipient).expect("hmm");
let so_m = curve25519blake2bxsalsa20poly1305::open(
ciphertext.as_slice(),
&SOPublicKey::from_slice(keypair_recipient.public_key.as_slice()).unwrap(),
&SOSecretKey::from_slice(keypair_recipient.secret_key.as_slice()).unwrap(),
)
.unwrap();
assert_eq!(m, message_copy.as_bytes());
assert_eq!(m, so_m);
}
}
#[test]
fn test_dryocbox_unseal_vecbox() {
for i in 0..20 {
use sodiumoxide::crypto::box_::PublicKey as SOPublicKey;
use sodiumoxide::crypto::sealedbox::curve25519blake2bxsalsa20poly1305;
let keypair_recipient = KeyPair::gen();
let words = vec!["hello1".to_string(); i];
let message = words.join(" :D ");
let ciphertext = curve25519blake2bxsalsa20poly1305::seal(
message.as_bytes(),
&SOPublicKey::from_slice(keypair_recipient.public_key.as_slice()).unwrap(),
);
let dryocbox =
DryocBox::from_sealed_bytes(&ciphertext).expect("from sealed bytes failed");
let m = dryocbox.unseal_to_vec(&keypair_recipient).expect("hmm");
assert_eq!(m, message.as_bytes());
}
}
#[test]
fn test_precalc_encrypt_decrypt() {
let keypair_sender = KeyPair::gen();
let keypair_recipient = KeyPair::gen();
let nonce = Nonce::gen();
let message = b"To be, or not to be, that is the question:";
let precalc_secret_key = PrecalcSecretKey::precalculate(
&keypair_sender.secret_key,
&keypair_recipient.public_key,
);
let dryocbox: VecBox = DryocBox::precalc_encrypt(message, &nonce, &precalc_secret_key)
.expect("unable to encrypt");
let decrypted: Vec<u8> = dryocbox
.precalc_decrypt(&nonce, &precalc_secret_key)
.expect("unable to decrypt");
assert_eq!(message, decrypted.as_slice());
}
#[test]
fn test_precalc_encrypt_to_vecbox_decrypt_to_vecbox() {
let keypair_sender = KeyPair::gen();
let keypair_recipient = KeyPair::gen();
let nonce = Nonce::gen();
let message = b"All the world's a stage, and all the men and women merely players:";
let precalc_secret_key = PrecalcSecretKey::precalculate(
&keypair_sender.secret_key,
&keypair_recipient.public_key,
);
let dryocbox = DryocBox::precalc_encrypt_to_vecbox(message, &nonce, &precalc_secret_key)
.expect("unable to encrypt");
let decrypted = dryocbox
.precalc_decrypt_to_vec(&nonce, &precalc_secret_key)
.expect("unable to decrypt");
assert_eq!(message, decrypted.as_slice());
}
#[test]
fn test_precalc_encrypt_decrypt_with_different_messages() {
let keypair_sender = KeyPair::gen();
let keypair_recipient = KeyPair::gen();
let nonce = Nonce::gen();
let messages: Vec<&[u8]> = vec![
b"Now is the winter of our discontent, made glorious summer by this sun of York;",
b"Friends, Romans, countrymen, lend me your ears; I come to bury Caesar, not to praise him.",
b"A horse! a horse! my kingdom for a horse!",
b"Good night, good night! parting is such sweet sorrow, that I shall say good night till it be morrow.",
];
let precalc_secret_key = PrecalcSecretKey::precalculate(
&keypair_sender.secret_key,
&keypair_recipient.public_key,
);
for message in &messages {
let dryocbox: VecBox = DryocBox::precalc_encrypt(message, &nonce, &precalc_secret_key)
.expect("unable to encrypt");
let decrypted: Vec<u8> = dryocbox
.precalc_decrypt(&nonce, &precalc_secret_key)
.expect("unable to decrypt");
assert_eq!(*message, decrypted.as_slice());
}
}
#[test]
fn test_precalc_encrypt_to_vecbox_decrypt_to_vecbox_with_different_messages() {
let keypair_sender = KeyPair::gen();
let keypair_recipient = KeyPair::gen();
let nonce = Nonce::gen();
let messages: Vec<&[u8]> = vec![
b"Out, out brief candle! Life's but a walking shadow, a poor player that struts and frets his hour upon the stage and then is heard no more.",
b"Some are born great, some achieve greatness, and some have greatness thrust upon them.",
b"The lady doth protest too much, methinks.",
b"What's in a name? That which we call a rose by any other name would smell as sweet.",
];
let precalc_secret_key = PrecalcSecretKey::precalculate(
&keypair_sender.secret_key,
&keypair_recipient.public_key,
);
for message in &messages {
let dryocbox =
DryocBox::precalc_encrypt_to_vecbox(message, &nonce, &precalc_secret_key)
.expect("unable to encrypt");
let decrypted = dryocbox
.precalc_decrypt_to_vec(&nonce, &precalc_secret_key)
.expect("unable to decrypt");
assert_eq!(*message, decrypted.as_slice());
}
}
}