diff --git a/Cargo.lock b/Cargo.lock index 44aaee484..9e7cc9414 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -439,6 +439,7 @@ dependencies = [ "pbkdf2", "rand 0.8.5", "rand_chacha 0.3.1", + "rayon", "rsa", "schemars", "serde", @@ -961,6 +962,25 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.19" @@ -2578,6 +2598,26 @@ dependencies = [ "rand_core 0.5.1", ] +[[package]] +name = "rayon" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "redox_syscall" version = "0.4.1" diff --git a/crates/bitwarden-crypto/Cargo.toml b/crates/bitwarden-crypto/Cargo.toml index 295cdd38e..f0eac0d0a 100644 --- a/crates/bitwarden-crypto/Cargo.toml +++ b/crates/bitwarden-crypto/Cargo.toml @@ -32,6 +32,7 @@ num-bigint = ">=0.4, <0.5" num-traits = ">=0.2.15, <0.3" pbkdf2 = { version = ">=0.12.1, <0.13", default-features = false } rand = ">=0.8.5, <0.9" +rayon = ">=1.8.1, <2.0" rsa = ">=0.9.2, <0.10" schemars = { version = ">=0.8, <0.9", features = ["uuid1"] } serde = { version = ">=1.0, <2.0", features = ["derive"] } diff --git a/crates/bitwarden-crypto/src/encryptable.rs b/crates/bitwarden-crypto/src/encryptable.rs index 9f1256afa..a9882629f 100644 --- a/crates/bitwarden-crypto/src/encryptable.rs +++ b/crates/bitwarden-crypto/src/encryptable.rs @@ -1,10 +1,11 @@ use std::{collections::HashMap, hash::Hash}; +use rayon::prelude::*; use uuid::Uuid; use crate::{CryptoError, KeyDecryptable, KeyEncryptable, Result, SymmetricCryptoKey}; -pub trait KeyContainer { +pub trait KeyContainer: Send + Sync { fn get_key(&self, org_id: &Option) -> Option<&SymmetricCryptoKey>; } @@ -46,37 +47,48 @@ impl + LocateKey, Output> Decrypta } } -impl, Output> Encryptable> for Vec { +impl + Send + Sync, Output: Send + Sync> Encryptable> + for Vec +{ fn encrypt(self, enc: &dyn KeyContainer, org_id: &Option) -> Result> { - self.into_iter().map(|e| e.encrypt(enc, org_id)).collect() + self.into_par_iter() + .map(|e| e.encrypt(enc, org_id)) + .collect() } } -impl, Output> Decryptable> for Vec { +impl + Send + Sync, Output: Send + Sync> Decryptable> + for Vec +{ fn decrypt(&self, enc: &dyn KeyContainer, org_id: &Option) -> Result> { - self.iter().map(|e| e.decrypt(enc, org_id)).collect() + self.into_par_iter() + .map(|e| e.decrypt(enc, org_id)) + .collect() } } -impl, Output, Id: Hash + Eq> Encryptable> - for HashMap +impl + Send + Sync, Output: Send + Sync, Id: Hash + Eq + Send + Sync> + Encryptable> for HashMap { fn encrypt(self, enc: &dyn KeyContainer, org_id: &Option) -> Result> { - self.into_iter() + self.into_par_iter() .map(|(id, e)| Ok((id, e.encrypt(enc, org_id)?))) .collect() } } -impl, Output, Id: Hash + Eq + Copy> Decryptable> - for HashMap +impl< + T: Decryptable + Send + Sync, + Output: Send + Sync, + Id: Hash + Eq + Copy + Send + Sync, + > Decryptable> for HashMap { fn decrypt( &self, enc: &dyn KeyContainer, org_id: &Option, ) -> Result> { - self.iter() + self.into_par_iter() .map(|(id, e)| Ok((*id, e.decrypt(enc, org_id)?))) .collect() } diff --git a/crates/bitwarden-crypto/src/keys/key_encryptable.rs b/crates/bitwarden-crypto/src/keys/key_encryptable.rs index 852b55c62..750647ee8 100644 --- a/crates/bitwarden-crypto/src/keys/key_encryptable.rs +++ b/crates/bitwarden-crypto/src/keys/key_encryptable.rs @@ -1,5 +1,7 @@ use std::{collections::HashMap, hash::Hash}; +use rayon::prelude::*; + use crate::error::Result; pub trait CryptoKey {} @@ -44,37 +46,55 @@ impl, Key: CryptoKey, Output> KeyDecryptable, Key: CryptoKey, Output> KeyEncryptable> - for Vec +impl< + T: KeyEncryptable + Send + Sync, + Key: CryptoKey + Send + Sync, + Output: Send + Sync, + > KeyEncryptable> for Vec { fn encrypt_with_key(self, key: &Key) -> Result> { - self.into_iter().map(|e| e.encrypt_with_key(key)).collect() + self.into_par_iter() + .map(|e| e.encrypt_with_key(key)) + .collect() } } -impl, Key: CryptoKey, Output> KeyDecryptable> - for Vec +impl< + T: KeyDecryptable + Send + Sync, + Key: CryptoKey + Send + Sync, + Output: Send + Sync, + > KeyDecryptable> for Vec { fn decrypt_with_key(&self, key: &Key) -> Result> { - self.iter().map(|e| e.decrypt_with_key(key)).collect() + self.into_par_iter() + .map(|e| e.decrypt_with_key(key)) + .collect() } } -impl, Key: CryptoKey, Output, Id: Hash + Eq> - KeyEncryptable> for HashMap +impl< + T: KeyEncryptable + Send + Sync, + Key: CryptoKey + Send + Sync, + Output: Send + Sync, + Id: Hash + Eq + Send + Sync, + > KeyEncryptable> for HashMap { fn encrypt_with_key(self, key: &Key) -> Result> { - self.into_iter() + self.into_par_iter() .map(|(id, e)| Ok((id, e.encrypt_with_key(key)?))) .collect() } } -impl, Key: CryptoKey, Output, Id: Hash + Eq + Copy> - KeyDecryptable> for HashMap +impl< + T: KeyDecryptable + Send + Sync, + Key: CryptoKey + Send + Sync, + Output: Send + Sync, + Id: Hash + Eq + Copy + Send + Sync, + > KeyDecryptable> for HashMap { fn decrypt_with_key(&self, key: &Key) -> Result> { - self.iter() + self.into_par_iter() .map(|(id, e)| Ok((*id, e.decrypt_with_key(key)?))) .collect() }