Skip to content

Commit 1a8fe9f

Browse files
hizanibrndnmtthws
andauthored
Add beforenm compatible function to dryocbox (#82)
* Add shared secret calculation function * Add shared secret key precalculation module * Add shared secret key precalculation for KeyPair * Add precalc interface for dryocbox * Shorten precalc names * Additional tests, docs, run `cargo fmt` * Add a few more tests --------- Co-authored-by: Brenden Matthews <[email protected]>
1 parent ab10bfe commit 1a8fe9f

File tree

7 files changed

+548
-33
lines changed

7 files changed

+548
-33
lines changed

src/argon2.rs

+23-14
Original file line numberDiff line numberDiff line change
@@ -696,11 +696,14 @@ mod tests {
696696
)
697697
.expect("argon2_hash failed");
698698

699-
assert_eq!(hash, [
700-
0xc8, 0x14, 0xd9, 0xd1, 0xdc, 0x7f, 0x37, 0xaa, 0x13, 0xf0, 0xd7, 0x7f, 0x24, 0x94,
701-
0xbd, 0xa1, 0xc8, 0xde, 0x6b, 0x01, 0x6d, 0xd3, 0x88, 0xd2, 0x99, 0x52, 0xa4, 0xc4,
702-
0x67, 0x2b, 0x6c, 0xe8,
703-
]);
699+
assert_eq!(
700+
hash,
701+
[
702+
0xc8, 0x14, 0xd9, 0xd1, 0xdc, 0x7f, 0x37, 0xaa, 0x13, 0xf0, 0xd7, 0x7f, 0x24, 0x94,
703+
0xbd, 0xa1, 0xc8, 0xde, 0x6b, 0x01, 0x6d, 0xd3, 0x88, 0xd2, 0x99, 0x52, 0xa4, 0xc4,
704+
0x67, 0x2b, 0x6c, 0xe8,
705+
]
706+
);
704707
}
705708

706709
extern "C" {
@@ -742,11 +745,14 @@ mod tests {
742745
)
743746
.expect("argon2_hash failed");
744747

745-
assert_eq!(hash, [
746-
0x0d, 0x64, 0x0d, 0xf5, 0x8d, 0x78, 0x76, 0x6c, 0x08, 0xc0, 0x37, 0xa3, 0x4a, 0x8b,
747-
0x53, 0xc9, 0xd0, 0x1e, 0xf0, 0x45, 0x2d, 0x75, 0xb6, 0x5e, 0xb5, 0x25, 0x20, 0xe9,
748-
0x6b, 0x01, 0xe6, 0x59,
749-
]);
748+
assert_eq!(
749+
hash,
750+
[
751+
0x0d, 0x64, 0x0d, 0xf5, 0x8d, 0x78, 0x76, 0x6c, 0x08, 0xc0, 0x37, 0xa3, 0x4a, 0x8b,
752+
0x53, 0xc9, 0xd0, 0x1e, 0xf0, 0x45, 0x2d, 0x75, 0xb6, 0x5e, 0xb5, 0x25, 0x20, 0xe9,
753+
0x6b, 0x01, 0xe6, 0x59,
754+
]
755+
);
750756
}
751757

752758
#[test]
@@ -789,9 +795,12 @@ mod tests {
789795

790796
assert_eq!(hash, so_hash);
791797

792-
assert_eq!(hash, [
793-
3, 170, 185, 101, 193, 32, 1, 201, 215, 208, 210, 222, 51, 25, 44, 4, 148, 182, 132,
794-
187, 20, 129, 150, 215, 60, 29, 241, 172, 175, 109, 12, 46
795-
]);
798+
assert_eq!(
799+
hash,
800+
[
801+
3, 170, 185, 101, 193, 32, 1, 201, 215, 208, 210, 222, 51, 25, 44, 4, 148, 182,
802+
132, 187, 20, 129, 150, 215, 60, 29, 241, 172, 175, 109, 12, 46
803+
]
804+
);
796805
}
797806
}

src/dryocbox.rs

+193-2
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,11 @@ use subtle::ConstantTimeEq;
9898
use zeroize::Zeroize;
9999

100100
use crate::constants::{
101-
CRYPTO_BOX_MACBYTES, CRYPTO_BOX_NONCEBYTES, CRYPTO_BOX_PUBLICKEYBYTES, CRYPTO_BOX_SEALBYTES,
102-
CRYPTO_BOX_SECRETKEYBYTES,
101+
CRYPTO_BOX_BEFORENMBYTES, CRYPTO_BOX_MACBYTES, CRYPTO_BOX_NONCEBYTES,
102+
CRYPTO_BOX_PUBLICKEYBYTES, CRYPTO_BOX_SEALBYTES, CRYPTO_BOX_SECRETKEYBYTES,
103103
};
104104
use crate::error::*;
105+
use crate::precalc::PrecalcSecretKey;
105106
pub use crate::types::*;
106107

107108
/// Stack-allocated public key for authenticated public-key boxes.
@@ -250,6 +251,38 @@ impl<
250251

251252
Ok(dryocbox)
252253
}
254+
255+
/// Encrypts a message using `precalc_secret_key`,
256+
/// and returns a new [DryocBox] with ciphertext and tag.
257+
pub fn precalc_encrypt<
258+
InnerSecretKey: ByteArray<CRYPTO_BOX_BEFORENMBYTES> + Zeroize,
259+
Message: Bytes + ?Sized,
260+
Nonce: ByteArray<CRYPTO_BOX_NONCEBYTES>,
261+
>(
262+
message: &Message,
263+
nonce: &Nonce,
264+
precalc_secret_key: &PrecalcSecretKey<InnerSecretKey>,
265+
) -> Result<Self, Error> {
266+
use crate::classic::crypto_box::crypto_box_detached_afternm;
267+
268+
let mut dryocbox = Self {
269+
ephemeral_pk: None,
270+
tag: Mac::new_byte_array(),
271+
data: Data::new_bytes(),
272+
};
273+
274+
dryocbox.data.resize(message.as_slice().len(), 0);
275+
276+
crypto_box_detached_afternm(
277+
dryocbox.data.as_mut_slice(),
278+
dryocbox.tag.as_mut_array(),
279+
message.as_slice(),
280+
nonce.as_array(),
281+
precalc_secret_key.as_array(),
282+
);
283+
284+
Ok(dryocbox)
285+
}
253286
}
254287

255288
impl<
@@ -410,6 +443,33 @@ impl<
410443
Ok(message)
411444
}
412445

446+
/// Decrypts this box using `nonce`, `precalc_secret_key`, and
447+
/// `sender_public_key`, returning the decrypted message upon success.
448+
pub fn precalc_decrypt<
449+
InnerSecretKey: ByteArray<CRYPTO_BOX_BEFORENMBYTES> + Zeroize,
450+
Nonce: ByteArray<CRYPTO_BOX_NONCEBYTES>,
451+
Output: ResizableBytes + NewBytes,
452+
>(
453+
&self,
454+
nonce: &Nonce,
455+
precalc_secret_key: &PrecalcSecretKey<InnerSecretKey>,
456+
) -> Result<Output, Error> {
457+
use crate::classic::crypto_box::crypto_box_open_detached_afternm;
458+
459+
let mut message = Output::new_bytes();
460+
message.resize(self.data.as_slice().len(), 0);
461+
462+
crypto_box_open_detached_afternm(
463+
message.as_mut_slice(),
464+
self.tag.as_array(),
465+
self.data.as_slice(),
466+
nonce.as_array(),
467+
precalc_secret_key.as_array(),
468+
)?;
469+
470+
Ok(message)
471+
}
472+
413473
/// Decrypts this sealed box using `recipient_secret_key`, and
414474
/// returning the decrypted message upon success.
415475
pub fn unseal<
@@ -489,6 +549,19 @@ impl DryocBox<PublicKey, Mac, Vec<u8>> {
489549
Self::encrypt(message, nonce, recipient_public_key, sender_secret_key)
490550
}
491551

552+
/// Encrypts a message using `precalc_secret_key`,
553+
/// and returns a new [DryocBox] with ciphertext and tag.
554+
pub fn precalc_encrypt_to_vecbox<
555+
Message: Bytes + ?Sized,
556+
InnerSecretKey: ByteArray<CRYPTO_BOX_BEFORENMBYTES> + Zeroize,
557+
>(
558+
message: &Message,
559+
nonce: &Nonce,
560+
precalc_secret_key: &PrecalcSecretKey<InnerSecretKey>,
561+
) -> Result<Self, Error> {
562+
Self::precalc_encrypt(message, nonce, precalc_secret_key)
563+
}
564+
492565
/// Encrypts a message for `recipient_public_key`, using an ephemeral secret
493566
/// key and nonce, and returns a new [DryocBox] with the ciphertext,
494567
/// ephemeral public key, and tag.
@@ -510,6 +583,19 @@ impl DryocBox<PublicKey, Mac, Vec<u8>> {
510583
self.decrypt(nonce, sender_public_key, recipient_secret_key)
511584
}
512585

586+
/// Decrypts this box using `nonce` and
587+
/// `precalc_secret_key`, returning the decrypted message upon
588+
/// success.
589+
pub fn precalc_decrypt_to_vecbox<
590+
InnerSecretKey: ByteArray<CRYPTO_BOX_BEFORENMBYTES> + Zeroize,
591+
>(
592+
&self,
593+
nonce: &Nonce,
594+
precalc_secret_key: &PrecalcSecretKey<InnerSecretKey>,
595+
) -> Result<Vec<u8>, Error> {
596+
self.precalc_decrypt(nonce, precalc_secret_key)
597+
}
598+
513599
/// Decrypts this sealed box using `recipient_secret_key`, returning the
514600
/// decrypted message upon success.
515601
pub fn unseal_to_vec<
@@ -819,4 +905,109 @@ mod tests {
819905
assert_eq!(m, message.as_bytes());
820906
}
821907
}
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_vecbox(&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_vecbox(&nonce, &precalc_secret_key)
1008+
.expect("unable to decrypt");
1009+
1010+
assert_eq!(*message, decrypted.as_slice());
1011+
}
1012+
}
8221013
}

0 commit comments

Comments
 (0)