From d431f2ebd345d49fb3ccaa990af961a502b9da27 Mon Sep 17 00:00:00 2001 From: Hocuri Date: Mon, 4 Aug 2025 20:59:18 +0200 Subject: [PATCH] Add benchmark for message decryption --- Cargo.toml | 5 +++ benches/encrypt_decrypt.rs | 90 ++++++++++++++++++++++++++++++++++++++ src/lib.rs | 3 ++ src/pgp.rs | 5 +++ src/tools.rs | 5 +++ 5 files changed, 108 insertions(+) create mode 100644 benches/encrypt_decrypt.rs diff --git a/Cargo.toml b/Cargo.toml index 55c2c6dc3..900d74004 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -157,6 +157,11 @@ name = "receive_emails" required-features = ["internals"] harness = false +[[bench]] +name = "encrypt_decrypt" +required-features = ["internals"] +harness = false + [[bench]] name = "get_chat_msgs" harness = false diff --git a/benches/encrypt_decrypt.rs b/benches/encrypt_decrypt.rs new file mode 100644 index 000000000..7fb1052b4 --- /dev/null +++ b/benches/encrypt_decrypt.rs @@ -0,0 +1,90 @@ +use std::hint::black_box; +use std::path::PathBuf; + +use criterion::{Criterion, criterion_group, criterion_main}; +use deltachat::{ + Events, + config::Config, + context::Context, + imex::{ImexMode, imex}, + pgp::{create_dummy_keypair, decrypt, encrypt_for_broadcast, pk_encrypt}, + receive_imf::receive_imf, + stock_str::StockStrings, + tools::create_broadcast_shared_secret_pub, +}; +use rand::{Rng, thread_rng}; +use tempfile::tempdir; + +const NUM_SECRETS: usize = 500; + +fn criterion_benchmark(c: &mut Criterion) { + let mut group = c.benchmark_group("Decrypt"); + group.sample_size(10); + group.bench_function("Decrypt symmetrically encrypted", |b| { + let rt = tokio::runtime::Runtime::new().unwrap(); + let mut plain: Vec = vec![0; 500]; + thread_rng().fill(&mut plain[..]); + let (secrets, encrypted) = rt.block_on(async { + let secrets: Vec = (0..NUM_SECRETS) + .map(|_| create_broadcast_shared_secret_pub()) + .collect(); + let secret = secrets[thread_rng().gen_range::(0..NUM_SECRETS)].clone(); + let encrypted = encrypt_for_broadcast( + plain.clone(), + black_box(&secret), + create_dummy_keypair("alice@example.org").unwrap().secret, + true, + ) + .await + .unwrap(); + + (secrets, encrypted) + }); + + b.iter(|| { + let mut msg = + decrypt(encrypted.clone().into_bytes(), &[], black_box(&secrets)).unwrap(); + let decrypted = msg.as_data_vec().unwrap(); + + assert_eq!(black_box(decrypted), plain); + }); + }); + group.bench_function("Decrypt pk encrypted", |b| { + // TODO code duplication with previous benchmark + let rt = tokio::runtime::Runtime::new().unwrap(); + let mut plain: Vec = vec![0; 500]; + thread_rng().fill(&mut plain[..]); + let key_pair = create_dummy_keypair("alice@example.org").unwrap(); + let (secrets, encrypted) = rt.block_on(async { + let secrets: Vec = (0..NUM_SECRETS) + .map(|_| create_broadcast_shared_secret_pub()) + .collect(); + let encrypted = pk_encrypt( + plain.clone(), + vec![black_box(key_pair.public.clone())], + Some(key_pair.secret.clone()), + true, + ) + .await + .unwrap(); + + (secrets, encrypted) + }); + + b.iter(|| { + let mut msg = decrypt( + encrypted.clone().into_bytes(), + &[key_pair.secret.clone()], + black_box(&secrets), + ) + .unwrap(); + let decrypted = msg.as_data_vec().unwrap(); + + assert_eq!(black_box(decrypted), plain); + }); + }); + group.finish(); +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/src/lib.rs b/src/lib.rs index 6a33b23c9..dd1e1bad0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -75,7 +75,10 @@ mod mimefactory; pub mod mimeparser; pub mod oauth2; mod param; +#[cfg(not(feature = "internals"))] mod pgp; +#[cfg(feature = "internals")] +pub mod pgp; pub mod provider; pub mod qr; pub mod qr_code_generator; diff --git a/src/pgp.rs b/src/pgp.rs index 5048a1053..b59c2de0b 100644 --- a/src/pgp.rs +++ b/src/pgp.rs @@ -149,6 +149,11 @@ pub(crate) fn create_keypair(addr: EmailAddress) -> Result { Ok(key_pair) } +#[cfg(feature = "internals")] +pub fn create_dummy_keypair(addr: &str) -> Result { + create_keypair(EmailAddress::new(addr)?) +} + /// Selects a subkey of the public key to use for encryption. /// /// Returns `None` if the public key cannot be used for encryption. diff --git a/src/tools.rs b/src/tools.rs index 0acd7cf61..b4cce6ee6 100644 --- a/src/tools.rs +++ b/src/tools.rs @@ -319,6 +319,11 @@ pub(crate) fn create_broadcast_shared_secret() -> String { res } +#[cfg(feature = "internals")] +pub fn create_broadcast_shared_secret_pub() -> String { + create_broadcast_shared_secret() +} + /// Returns true if given string is a valid ID. /// /// All IDs generated with `create_id()` should be considered valid.