1#[cfg(feature = "serde")]
96use serde::{Deserialize, Serialize};
97use subtle::ConstantTimeEq;
98use zeroize::Zeroize;
99
100use crate::constants::{
101 CRYPTO_BOX_BEFORENMBYTES, CRYPTO_BOX_MACBYTES, CRYPTO_BOX_NONCEBYTES,
102 CRYPTO_BOX_PUBLICKEYBYTES, CRYPTO_BOX_SEALBYTES, CRYPTO_BOX_SECRETKEYBYTES,
103};
104use crate::error::*;
105pub use crate::types::*;
106
107pub type PublicKey = StackByteArray<CRYPTO_BOX_PUBLICKEYBYTES>;
109pub type SecretKey = StackByteArray<CRYPTO_BOX_SECRETKEYBYTES>;
111pub type Nonce = StackByteArray<CRYPTO_BOX_NONCEBYTES>;
113pub type Mac = StackByteArray<CRYPTO_BOX_MACBYTES>;
116pub type KeyPair = crate::keypair::KeyPair<PublicKey, SecretKey>;
119
120#[cfg(any(feature = "nightly", all(doc, not(doctest))))]
121#[cfg_attr(all(feature = "nightly", doc), doc(cfg(feature = "nightly")))]
122pub mod protected {
123 use super::*;
167 pub use crate::protected::*;
168
169 pub type PublicKey = HeapByteArray<CRYPTO_BOX_PUBLICKEYBYTES>;
172 pub type SecretKey = HeapByteArray<CRYPTO_BOX_SECRETKEYBYTES>;
175 pub type Nonce = HeapByteArray<CRYPTO_BOX_NONCEBYTES>;
178 pub type Mac = HeapByteArray<CRYPTO_BOX_MACBYTES>;
181
182 pub type LockedKeyPair = crate::keypair::KeyPair<Locked<PublicKey>, Locked<SecretKey>>;
185 pub type LockedROKeyPair = crate::keypair::KeyPair<LockedRO<PublicKey>, LockedRO<SecretKey>>;
188 pub type LockedBox = DryocBox<Locked<PublicKey>, Locked<Mac>, LockedBytes>;
190}
191
192#[cfg_attr(
193 feature = "serde",
194 derive(Zeroize, Clone, Debug, Serialize, Deserialize)
195)]
196#[cfg_attr(not(feature = "serde"), derive(Zeroize, Clone, Debug))]
197pub struct DryocBox<
201 EphemeralPublicKey: ByteArray<CRYPTO_BOX_PUBLICKEYBYTES> + Zeroize,
202 Mac: ByteArray<CRYPTO_BOX_MACBYTES> + Zeroize,
203 Data: Bytes + Zeroize,
204> {
205 ephemeral_pk: Option<EphemeralPublicKey>,
206 tag: Mac,
207 data: Data,
208}
209
210pub type VecBox = DryocBox<PublicKey, Mac, Vec<u8>>;
212
213impl<
214 EphemeralPublicKey: ByteArray<CRYPTO_BOX_PUBLICKEYBYTES> + Zeroize,
215 Mac: NewByteArray<CRYPTO_BOX_MACBYTES> + Zeroize,
216 Data: NewBytes + ResizableBytes + Zeroize,
217> DryocBox<EphemeralPublicKey, Mac, Data>
218{
219 pub fn encrypt<
222 Message: Bytes + ?Sized,
223 Nonce: ByteArray<CRYPTO_BOX_NONCEBYTES>,
224 RecipientPublicKey: ByteArray<CRYPTO_BOX_PUBLICKEYBYTES>,
225 SenderSecretKey: ByteArray<CRYPTO_BOX_SECRETKEYBYTES>,
226 >(
227 message: &Message,
228 nonce: &Nonce,
229 recipient_public_key: &RecipientPublicKey,
230 sender_secret_key: &SenderSecretKey,
231 ) -> Result<Self, Error> {
232 use crate::classic::crypto_box::crypto_box_detached;
233
234 let mut dryocbox = Self {
235 ephemeral_pk: None,
236 tag: Mac::new_byte_array(),
237 data: Data::new_bytes(),
238 };
239
240 dryocbox.data.resize(message.as_slice().len(), 0);
241
242 crypto_box_detached(
243 dryocbox.data.as_mut_slice(),
244 dryocbox.tag.as_mut_array(),
245 message.as_slice(),
246 nonce.as_array(),
247 recipient_public_key.as_array(),
248 sender_secret_key.as_array(),
249 );
250
251 Ok(dryocbox)
252 }
253
254 pub fn precalc_encrypt<
257 PrecalcSecretKey: ByteArray<CRYPTO_BOX_BEFORENMBYTES> + Zeroize,
258 Message: Bytes + ?Sized,
259 Nonce: ByteArray<CRYPTO_BOX_NONCEBYTES>,
260 >(
261 message: &Message,
262 nonce: &Nonce,
263 precalc_secret_key: &PrecalcSecretKey,
264 ) -> Result<Self, Error> {
265 use crate::classic::crypto_box::crypto_box_detached_afternm;
266
267 let mut dryocbox = Self {
268 ephemeral_pk: None,
269 tag: Mac::new_byte_array(),
270 data: Data::new_bytes(),
271 };
272
273 dryocbox.data.resize(message.as_slice().len(), 0);
274
275 crypto_box_detached_afternm(
276 dryocbox.data.as_mut_slice(),
277 dryocbox.tag.as_mut_array(),
278 message.as_slice(),
279 nonce.as_array(),
280 precalc_secret_key.as_array(),
281 );
282
283 Ok(dryocbox)
284 }
285}
286
287impl<
288 EphemeralPublicKey: NewByteArray<CRYPTO_BOX_PUBLICKEYBYTES> + Zeroize,
289 Mac: NewByteArray<CRYPTO_BOX_MACBYTES> + Zeroize,
290 Data: NewBytes + ResizableBytes + Zeroize,
291> DryocBox<EphemeralPublicKey, Mac, Data>
292{
293 pub fn seal<
297 Message: Bytes + ?Sized,
298 RecipientPublicKey: ByteArray<CRYPTO_BOX_PUBLICKEYBYTES>,
299 >(
300 message: &Message,
301 recipient_public_key: &RecipientPublicKey,
302 ) -> Result<Self, Error> {
303 use crate::classic::crypto_box::{
304 crypto_box_detached, crypto_box_keypair, crypto_box_seal_nonce,
305 };
306
307 let mut nonce = Nonce::new_byte_array();
308 let (epk, esk) = crypto_box_keypair();
309 crypto_box_seal_nonce(nonce.as_mut_array(), &epk, recipient_public_key.as_array());
310
311 let mut pk = EphemeralPublicKey::new_byte_array();
312 pk.copy_from_slice(&epk);
313
314 let mut dryocbox = Self {
315 ephemeral_pk: Some(pk),
316 tag: Mac::new_byte_array(),
317 data: Data::new_bytes(),
318 };
319
320 dryocbox.data.resize(message.as_slice().len(), 0);
321
322 crypto_box_detached(
323 dryocbox.data.as_mut_slice(),
324 dryocbox.tag.as_mut_array(),
325 message.as_slice(),
326 nonce.as_array(),
327 recipient_public_key.as_array(),
328 &esk,
329 );
330
331 Ok(dryocbox)
332 }
333}
334
335impl<
336 'a,
337 EphemeralPublicKey: ByteArray<CRYPTO_BOX_PUBLICKEYBYTES> + std::convert::TryFrom<&'a [u8]> + Zeroize,
338 Mac: ByteArray<CRYPTO_BOX_MACBYTES> + std::convert::TryFrom<&'a [u8]> + Zeroize,
339 Data: Bytes + From<&'a [u8]> + Zeroize,
340> DryocBox<EphemeralPublicKey, Mac, Data>
341{
342 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, Error> {
346 if bytes.len() < CRYPTO_BOX_MACBYTES {
347 Err(dryoc_error!(format!(
348 "bytes of len {} less than expected minimum of {}",
349 bytes.len(),
350 CRYPTO_BOX_MACBYTES
351 )))
352 } else {
353 let (tag, data) = bytes.split_at(CRYPTO_BOX_MACBYTES);
354 Ok(Self {
355 ephemeral_pk: None,
356 tag: Mac::try_from(tag).map_err(|_e| dryoc_error!("invalid tag"))?,
357 data: Data::from(data),
358 })
359 }
360 }
361
362 pub fn from_sealed_bytes(bytes: &'a [u8]) -> Result<Self, Error> {
367 if bytes.len() < CRYPTO_BOX_SEALBYTES {
368 Err(dryoc_error!(format!(
369 "bytes of len {} less than expected minimum of {}",
370 bytes.len(),
371 CRYPTO_BOX_SEALBYTES
372 )))
373 } else {
374 let (seal, data) = bytes.split_at(CRYPTO_BOX_SEALBYTES);
375 let (epk, tag) = seal.split_at(CRYPTO_BOX_PUBLICKEYBYTES);
376 Ok(Self {
377 ephemeral_pk: Some(
378 EphemeralPublicKey::try_from(epk)
379 .map_err(|_e| dryoc_error!("invalid ephemeral public key"))?,
380 ),
381 tag: Mac::try_from(tag).map_err(|_e| dryoc_error!("invalid tag"))?,
382 data: Data::from(data),
383 })
384 }
385 }
386}
387
388impl<
389 EphemeralPublicKey: ByteArray<CRYPTO_BOX_PUBLICKEYBYTES> + Zeroize,
390 Mac: ByteArray<CRYPTO_BOX_MACBYTES> + Zeroize,
391 Data: Bytes + Zeroize,
392> DryocBox<EphemeralPublicKey, Mac, Data>
393{
394 pub fn from_parts(tag: Mac, data: Data, ephemeral_pk: Option<EphemeralPublicKey>) -> Self {
397 Self {
398 ephemeral_pk,
399 tag,
400 data,
401 }
402 }
403
404 pub fn to_vec(&self) -> Vec<u8> {
406 self.to_bytes()
407 }
408
409 pub fn into_parts(self) -> (Mac, Data, Option<EphemeralPublicKey>) {
412 (self.tag, self.data, self.ephemeral_pk)
413 }
414
415 pub fn decrypt<
418 Nonce: ByteArray<CRYPTO_BOX_NONCEBYTES>,
419 SenderPublicKey: ByteArray<CRYPTO_BOX_PUBLICKEYBYTES>,
420 RecipientSecretKey: ByteArray<CRYPTO_BOX_SECRETKEYBYTES>,
421 Output: ResizableBytes + NewBytes,
422 >(
423 &self,
424 nonce: &Nonce,
425 sender_public_key: &SenderPublicKey,
426 recipient_secret_key: &RecipientSecretKey,
427 ) -> Result<Output, Error> {
428 use crate::classic::crypto_box::*;
429
430 let mut message = Output::new_bytes();
431 message.resize(self.data.as_slice().len(), 0);
432
433 crypto_box_open_detached(
434 message.as_mut_slice(),
435 self.tag.as_array(),
436 self.data.as_slice(),
437 nonce.as_array(),
438 sender_public_key.as_array(),
439 recipient_secret_key.as_array(),
440 )?;
441
442 Ok(message)
443 }
444
445 pub fn precalc_decrypt<
448 PrecalcSecretKey: ByteArray<CRYPTO_BOX_BEFORENMBYTES> + Zeroize,
449 Nonce: ByteArray<CRYPTO_BOX_NONCEBYTES>,
450 Output: ResizableBytes + NewBytes,
451 >(
452 &self,
453 nonce: &Nonce,
454 precalc_secret_key: &PrecalcSecretKey,
455 ) -> Result<Output, Error> {
456 use crate::classic::crypto_box::crypto_box_open_detached_afternm;
457
458 let mut message = Output::new_bytes();
459 message.resize(self.data.as_slice().len(), 0);
460
461 crypto_box_open_detached_afternm(
462 message.as_mut_slice(),
463 self.tag.as_array(),
464 self.data.as_slice(),
465 nonce.as_array(),
466 precalc_secret_key.as_array(),
467 )?;
468
469 Ok(message)
470 }
471
472 pub fn unseal<
475 RecipientPublicKey: ByteArray<CRYPTO_BOX_PUBLICKEYBYTES> + Zeroize,
476 RecipientSecretKey: ByteArray<CRYPTO_BOX_SECRETKEYBYTES> + Zeroize,
477 Output: ResizableBytes + NewBytes + Zeroize,
478 >(
479 &self,
480 recipient_keypair: &crate::keypair::KeyPair<RecipientPublicKey, RecipientSecretKey>,
481 ) -> Result<Output, Error> {
482 use crate::classic::crypto_box::*;
483
484 match &self.ephemeral_pk {
485 Some(epk) => {
486 let mut nonce = Nonce::new_byte_array();
487 crypto_box_seal_nonce(
488 nonce.as_mut_array(),
489 epk.as_array(),
490 recipient_keypair.public_key.as_array(),
491 );
492
493 let mut message = Output::new_bytes();
494 message.resize(self.data.as_slice().len(), 0);
495
496 crypto_box_open_detached(
497 message.as_mut_slice(),
498 self.tag.as_array(),
499 self.data.as_slice(),
500 nonce.as_array(),
501 epk.as_array(),
502 recipient_keypair.secret_key.as_array(),
503 )?;
504
505 Ok(message)
506 }
507 None => Err(dryoc_error!(
508 "ephemeral public key is missing, cannot unseal"
509 )),
510 }
511 }
512
513 pub fn to_bytes<Bytes: NewBytes + ResizableBytes>(&self) -> Bytes {
515 let mut data = Bytes::new_bytes();
516 match &self.ephemeral_pk {
517 Some(epk) => {
518 data.resize(epk.len() + self.tag.len() + self.data.len(), 0);
519 let s = data.as_mut_slice();
520 s[..CRYPTO_BOX_PUBLICKEYBYTES].copy_from_slice(epk.as_slice());
521 s[CRYPTO_BOX_PUBLICKEYBYTES..CRYPTO_BOX_SEALBYTES]
522 .copy_from_slice(self.tag.as_slice());
523 s[CRYPTO_BOX_SEALBYTES..].copy_from_slice(self.data.as_slice());
524 }
525 None => {
526 data.resize(self.tag.len() + self.data.len(), 0);
527 let s = data.as_mut_slice();
528 s[..CRYPTO_BOX_MACBYTES].copy_from_slice(self.tag.as_slice());
529 s[CRYPTO_BOX_MACBYTES..].copy_from_slice(self.data.as_slice());
530 }
531 }
532 data
533 }
534}
535
536impl DryocBox<PublicKey, Mac, Vec<u8>> {
537 pub fn encrypt_to_vecbox<
540 Message: Bytes + ?Sized,
541 SecretKey: ByteArray<CRYPTO_BOX_SECRETKEYBYTES>,
542 >(
543 message: &Message,
544 nonce: &Nonce,
545 recipient_public_key: &PublicKey,
546 sender_secret_key: &SecretKey,
547 ) -> Result<Self, Error> {
548 Self::encrypt(message, nonce, recipient_public_key, sender_secret_key)
549 }
550
551 pub fn precalc_encrypt_to_vecbox<
554 Message: Bytes + ?Sized,
555 PrecalcSecretKey: ByteArray<CRYPTO_BOX_BEFORENMBYTES> + Zeroize,
556 >(
557 message: &Message,
558 nonce: &Nonce,
559 precalc_secret_key: &PrecalcSecretKey,
560 ) -> Result<Self, Error> {
561 Self::precalc_encrypt(message, nonce, precalc_secret_key)
562 }
563
564 pub fn seal_to_vecbox<Message: Bytes + ?Sized>(
568 message: &Message,
569 recipient_public_key: &PublicKey,
570 ) -> Result<Self, Error> {
571 Self::seal(message, recipient_public_key)
572 }
573
574 pub fn decrypt_to_vec<SecretKey: ByteArray<CRYPTO_BOX_SECRETKEYBYTES>>(
577 &self,
578 nonce: &Nonce,
579 sender_public_key: &PublicKey,
580 recipient_secret_key: &SecretKey,
581 ) -> Result<Vec<u8>, Error> {
582 self.decrypt(nonce, sender_public_key, recipient_secret_key)
583 }
584
585 pub fn precalc_decrypt_to_vec<
589 PrecalcSecretKey: ByteArray<CRYPTO_BOX_BEFORENMBYTES> + Zeroize,
590 >(
591 &self,
592 nonce: &Nonce,
593 precalc_secret_key: &PrecalcSecretKey,
594 ) -> Result<Vec<u8>, Error> {
595 self.precalc_decrypt(nonce, precalc_secret_key)
596 }
597
598 pub fn unseal_to_vec<
601 RecipientPublicKey: ByteArray<CRYPTO_BOX_PUBLICKEYBYTES> + Zeroize,
602 RecipientSecretKey: ByteArray<CRYPTO_BOX_SECRETKEYBYTES> + Zeroize,
603 >(
604 &self,
605 recipient_keypair: &crate::keypair::KeyPair<RecipientPublicKey, RecipientSecretKey>,
606 ) -> Result<Vec<u8>, Error> {
607 self.unseal(recipient_keypair)
608 }
609}
610
611impl<
612 'a,
613 EphemeralPublicKey: ByteArray<CRYPTO_BOX_PUBLICKEYBYTES> + Zeroize,
614 Mac: ByteArray<CRYPTO_BOX_MACBYTES> + Zeroize,
615 Data: Bytes + ResizableBytes + From<&'a [u8]> + Zeroize,
616> DryocBox<EphemeralPublicKey, Mac, Data>
617{
618 pub fn new_with_data_and_mac(tag: Mac, input: &'a [u8]) -> Self {
622 Self {
623 ephemeral_pk: None,
624 tag,
625 data: input.into(),
626 }
627 }
628
629 pub fn new_with_epk_data_and_mac(
632 ephemeral_pk: EphemeralPublicKey,
633 tag: Mac,
634 input: &'a [u8],
635 ) -> Self {
636 Self {
637 ephemeral_pk: Some(ephemeral_pk),
638 tag,
639 data: input.into(),
640 }
641 }
642}
643
644impl<
645 EphemeralPublicKey: ByteArray<CRYPTO_BOX_PUBLICKEYBYTES> + Zeroize,
646 Mac: ByteArray<CRYPTO_BOX_MACBYTES> + Zeroize,
647 Data: Bytes + Zeroize,
648> PartialEq<DryocBox<EphemeralPublicKey, Mac, Data>> for DryocBox<EphemeralPublicKey, Mac, Data>
649{
650 fn eq(&self, other: &Self) -> bool {
651 if let Some(our_epk) = &self.ephemeral_pk {
652 if let Some(their_epk) = &other.ephemeral_pk {
653 self.tag.as_slice().ct_eq(other.tag.as_slice()).unwrap_u8() == 1
654 && self
655 .data
656 .as_slice()
657 .ct_eq(other.data.as_slice())
658 .unwrap_u8()
659 == 1
660 && our_epk.as_slice().ct_eq(their_epk.as_slice()).unwrap_u8() == 1
661 } else {
662 false
663 }
664 } else if other.ephemeral_pk.is_none() {
665 self.tag.as_slice().ct_eq(other.tag.as_slice()).unwrap_u8() == 1
666 && self
667 .data
668 .as_slice()
669 .ct_eq(other.data.as_slice())
670 .unwrap_u8()
671 == 1
672 } else {
673 false
674 }
675 }
676}
677
678#[cfg(test)]
679mod tests {
680 use super::*;
681 use crate::precalc::PrecalcSecretKey;
682
683 #[test]
684 fn test_dryocbox_vecbox() {
685 for i in 0..20 {
686 use base64::Engine as _;
687 use base64::engine::general_purpose;
688 use sodiumoxide::crypto::box_;
689 use sodiumoxide::crypto::box_::{Nonce as SONonce, PublicKey, SecretKey};
690
691 let keypair_sender = KeyPair::gen();
692 let keypair_recipient = KeyPair::gen();
693 let keypair_sender_copy = keypair_sender.clone();
694 let keypair_recipient_copy = keypair_recipient.clone();
695 let nonce = Nonce::gen();
696 let words = vec!["hello1".to_string(); i];
697 let message = words.join(" :D ");
698 let message_copy = message.clone();
699 let dryocbox = DryocBox::encrypt_to_vecbox(
700 message.as_bytes(),
701 &nonce,
702 &keypair_recipient.public_key,
703 &keypair_sender.secret_key,
704 )
705 .unwrap();
706
707 let ciphertext = dryocbox.to_vec();
708
709 let so_ciphertext = box_::seal(
710 message_copy.as_bytes(),
711 &SONonce::from_slice(&nonce).unwrap(),
712 &PublicKey::from_slice(&keypair_recipient_copy.public_key).unwrap(),
713 &SecretKey::from_slice(&keypair_sender_copy.secret_key).unwrap(),
714 );
715
716 assert_eq!(
717 general_purpose::STANDARD.encode(&ciphertext),
718 general_purpose::STANDARD.encode(&so_ciphertext)
719 );
720
721 let keypair_sender = keypair_sender_copy.clone();
722 let keypair_recipient = keypair_recipient_copy.clone();
723
724 let m = dryocbox
725 .decrypt_to_vec(
726 &nonce,
727 &keypair_sender.public_key,
728 &keypair_recipient.secret_key,
729 )
730 .expect("hmm");
731 let so_m = box_::open(
732 &ciphertext,
733 &SONonce::from_slice(&nonce).unwrap(),
734 &PublicKey::from_slice(&keypair_recipient_copy.public_key).unwrap(),
735 &SecretKey::from_slice(&keypair_sender_copy.secret_key).unwrap(),
736 )
737 .expect("HMMM");
738
739 assert_eq!(m, message_copy.as_bytes());
740 assert_eq!(m, so_m);
741 }
742 }
743
744 #[test]
745 fn test_decrypt_failure() {
746 for i in 0..20 {
747 use base64::Engine as _;
748 use base64::engine::general_purpose;
749 use sodiumoxide::crypto::box_;
750 use sodiumoxide::crypto::box_::{
751 Nonce as SONonce, PublicKey as SOPublicKey, SecretKey as SOSecretKey,
752 };
753
754 let keypair_sender = KeyPair::gen();
755 let keypair_recipient = KeyPair::gen();
756 let keypair_sender_copy = keypair_sender.clone();
757 let keypair_recipient_copy = keypair_recipient.clone();
758 let nonce = Nonce::gen();
759 let words = vec!["hello1".to_string(); i];
760 let message = words.join(" :D ");
761 let message_copy = message.clone();
762 let dryocbox = DryocBox::encrypt_to_vecbox(
763 message.as_bytes(),
764 &nonce,
765 &keypair_recipient.public_key,
766 &keypair_sender.secret_key,
767 )
768 .unwrap();
769
770 let ciphertext = dryocbox.to_vec();
771
772 let so_ciphertext = box_::seal(
773 message_copy.as_bytes(),
774 &SONonce::from_slice(&nonce).unwrap(),
775 &SOPublicKey::from_slice(&keypair_recipient_copy.public_key).unwrap(),
776 &SOSecretKey::from_slice(&keypair_sender_copy.secret_key).unwrap(),
777 );
778
779 assert_eq!(
780 general_purpose::STANDARD.encode(&ciphertext),
781 general_purpose::STANDARD.encode(&so_ciphertext)
782 );
783
784 let invalid_key = KeyPair::gen();
785 let invalid_key_copy_1 = invalid_key.clone();
786 let invalid_key_copy_2 = invalid_key.clone();
787
788 DryocBox::decrypt::<Nonce, PublicKey, SecretKey, Vec<u8>>(
789 &dryocbox,
790 &nonce,
791 &invalid_key_copy_1.public_key,
792 &invalid_key_copy_2.secret_key,
793 )
794 .expect_err("hmm");
795 box_::open(
796 &ciphertext,
797 &SONonce::from_slice(&nonce).unwrap(),
798 &SOPublicKey::from_slice(&invalid_key.public_key).unwrap(),
799 &SOSecretKey::from_slice(&invalid_key.secret_key).unwrap(),
800 )
801 .expect_err("HMMM");
802 }
803 }
804
805 #[test]
806 fn test_decrypt_failure_empty() {
807 for _ in 0..20 {
808 use crate::keypair::*;
809
810 let invalid_key = KeyPair::gen();
811 let invalid_key_copy_1 = invalid_key.clone();
812 let invalid_key_copy_2 = invalid_key.clone();
813 let nonce = Nonce::gen();
814
815 let dryocbox: VecBox =
816 DryocBox::from_bytes(b"trollolllololololollollolololololol").expect("ok");
817 DryocBox::decrypt::<
818 Nonce,
819 crate::classic::crypto_box::PublicKey,
820 crate::classic::crypto_box::SecretKey,
821 Vec<u8>,
822 >(
823 &dryocbox,
824 &nonce,
825 &invalid_key_copy_1.public_key,
826 &invalid_key_copy_2.secret_key,
827 )
828 .expect_err("hmm");
829 }
830 }
831
832 #[test]
833 fn test_copy() {
834 for _ in 0..20 {
835 use std::convert::TryFrom;
836
837 use crate::rng::*;
838
839 let mut data1: Vec<u8> = vec![0u8; 1024];
840 copy_randombytes(data1.as_mut_slice());
841 let data1_copy = data1.clone();
842
843 let dryocbox: VecBox = DryocBox::from_bytes(&data1).expect("ok");
844 assert_eq!(dryocbox.data.as_slice(), &data1_copy[CRYPTO_BOX_MACBYTES..]);
845 assert_eq!(dryocbox.tag.as_slice(), &data1_copy[..CRYPTO_BOX_MACBYTES]);
846
847 let data1 = data1_copy.clone();
848 let (tag, data) = data1.split_at(CRYPTO_BOX_MACBYTES);
849 let dryocbox: VecBox =
850 DryocBox::new_with_data_and_mac(Mac::try_from(tag).expect("mac"), data);
851 assert_eq!(dryocbox.data.as_slice(), &data1_copy[CRYPTO_BOX_MACBYTES..]);
852 assert_eq!(dryocbox.tag.as_array(), &data1_copy[..CRYPTO_BOX_MACBYTES]);
853 }
854 }
855
856 #[test]
857 fn test_dryocbox_seal_vecbox() {
858 for i in 0..20 {
859 use sodiumoxide::crypto::box_::{PublicKey as SOPublicKey, SecretKey as SOSecretKey};
860 use sodiumoxide::crypto::sealedbox::curve25519blake2bxsalsa20poly1305;
861
862 let keypair_recipient = KeyPair::gen();
863 let words = vec!["hello1".to_string(); i];
864 let message = words.join(" :D ");
865 let message_copy = message.clone();
866 let dryocbox =
867 DryocBox::seal_to_vecbox(message.as_bytes(), &keypair_recipient.public_key)
868 .unwrap();
869
870 let ciphertext = dryocbox.to_vec();
871
872 let m = dryocbox.unseal_to_vec(&keypair_recipient).expect("hmm");
873 let so_m = curve25519blake2bxsalsa20poly1305::open(
874 ciphertext.as_slice(),
875 &SOPublicKey::from_slice(keypair_recipient.public_key.as_slice()).unwrap(),
876 &SOSecretKey::from_slice(keypair_recipient.secret_key.as_slice()).unwrap(),
877 )
878 .unwrap();
879
880 assert_eq!(m, message_copy.as_bytes());
881 assert_eq!(m, so_m);
882 }
883 }
884
885 #[test]
886 fn test_dryocbox_unseal_vecbox() {
887 for i in 0..20 {
888 use sodiumoxide::crypto::box_::PublicKey as SOPublicKey;
889 use sodiumoxide::crypto::sealedbox::curve25519blake2bxsalsa20poly1305;
890
891 let keypair_recipient = KeyPair::gen();
892 let words = vec!["hello1".to_string(); i];
893 let message = words.join(" :D ");
894
895 let ciphertext = curve25519blake2bxsalsa20poly1305::seal(
896 message.as_bytes(),
897 &SOPublicKey::from_slice(keypair_recipient.public_key.as_slice()).unwrap(),
898 );
899
900 let dryocbox =
901 DryocBox::from_sealed_bytes(&ciphertext).expect("from sealed bytes failed");
902
903 let m = dryocbox.unseal_to_vec(&keypair_recipient).expect("hmm");
904
905 assert_eq!(m, message.as_bytes());
906 }
907 }
908
909 #[test]
910 fn test_precalc_encrypt_decrypt() {
911 let keypair_sender = KeyPair::gen();
912 let keypair_recipient = KeyPair::gen();
913 let nonce = Nonce::gen();
914
915 let message = b"To be, or not to be, that is the question:";
916 let precalc_secret_key = PrecalcSecretKey::precalculate(
917 &keypair_sender.secret_key,
918 &keypair_recipient.public_key,
919 );
920
921 let dryocbox: VecBox = DryocBox::precalc_encrypt(message, &nonce, &precalc_secret_key)
922 .expect("unable to encrypt");
923
924 let decrypted: Vec<u8> = dryocbox
925 .precalc_decrypt(&nonce, &precalc_secret_key)
926 .expect("unable to decrypt");
927
928 assert_eq!(message, decrypted.as_slice());
929 }
930
931 #[test]
932 fn test_precalc_encrypt_to_vecbox_decrypt_to_vecbox() {
933 let keypair_sender = KeyPair::gen();
934 let keypair_recipient = KeyPair::gen();
935 let nonce = Nonce::gen();
936
937 let message = b"All the world's a stage, and all the men and women merely players:";
938 let precalc_secret_key = PrecalcSecretKey::precalculate(
939 &keypair_sender.secret_key,
940 &keypair_recipient.public_key,
941 );
942
943 let dryocbox = DryocBox::precalc_encrypt_to_vecbox(message, &nonce, &precalc_secret_key)
944 .expect("unable to encrypt");
945
946 let decrypted = dryocbox
947 .precalc_decrypt_to_vec(&nonce, &precalc_secret_key)
948 .expect("unable to decrypt");
949
950 assert_eq!(message, decrypted.as_slice());
951 }
952
953 #[test]
954 fn test_precalc_encrypt_decrypt_with_different_messages() {
955 let keypair_sender = KeyPair::gen();
956 let keypair_recipient = KeyPair::gen();
957 let nonce = Nonce::gen();
958
959 let messages: Vec<&[u8]> = vec![
960 b"Now is the winter of our discontent, made glorious summer by this sun of York;",
961 b"Friends, Romans, countrymen, lend me your ears; I come to bury Caesar, not to praise him.",
962 b"A horse! a horse! my kingdom for a horse!",
963 b"Good night, good night! parting is such sweet sorrow, that I shall say good night till it be morrow.",
964 ];
965
966 let precalc_secret_key = PrecalcSecretKey::precalculate(
967 &keypair_sender.secret_key,
968 &keypair_recipient.public_key,
969 );
970
971 for message in &messages {
972 let dryocbox: VecBox = DryocBox::precalc_encrypt(message, &nonce, &precalc_secret_key)
973 .expect("unable to encrypt");
974
975 let decrypted: Vec<u8> = dryocbox
976 .precalc_decrypt(&nonce, &precalc_secret_key)
977 .expect("unable to decrypt");
978
979 assert_eq!(*message, decrypted.as_slice());
980 }
981 }
982
983 #[test]
984 fn test_precalc_encrypt_to_vecbox_decrypt_to_vecbox_with_different_messages() {
985 let keypair_sender = KeyPair::gen();
986 let keypair_recipient = KeyPair::gen();
987 let nonce = Nonce::gen();
988
989 let messages: Vec<&[u8]> = vec![
990 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.",
991 b"Some are born great, some achieve greatness, and some have greatness thrust upon them.",
992 b"The lady doth protest too much, methinks.",
993 b"What's in a name? That which we call a rose by any other name would smell as sweet.",
994 ];
995
996 let precalc_secret_key = PrecalcSecretKey::precalculate(
997 &keypair_sender.secret_key,
998 &keypair_recipient.public_key,
999 );
1000
1001 for message in &messages {
1002 let dryocbox =
1003 DryocBox::precalc_encrypt_to_vecbox(message, &nonce, &precalc_secret_key)
1004 .expect("unable to encrypt");
1005
1006 let decrypted = dryocbox
1007 .precalc_decrypt_to_vec(&nonce, &precalc_secret_key)
1008 .expect("unable to decrypt");
1009
1010 assert_eq!(*message, decrypted.as_slice());
1011 }
1012 }
1013}