diff --git a/Cargo.toml b/Cargo.toml index 900d74004..a7fdf3546 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -158,7 +158,7 @@ required-features = ["internals"] harness = false [[bench]] -name = "encrypt_decrypt" +name = "benchmark_decrypting" required-features = ["internals"] harness = false diff --git a/benches/encrypt_decrypt.rs b/benches/benchmark_decrypting.rs similarity index 50% rename from benches/encrypt_decrypt.rs rename to benches/benchmark_decrypting.rs index 7fb1052b4..47162e52a 100644 --- a/benches/encrypt_decrypt.rs +++ b/benches/benchmark_decrypting.rs @@ -1,14 +1,20 @@ -use std::hint::black_box; use std::path::PathBuf; +use std::{hint::black_box, io::Write}; use criterion::{Criterion, criterion_group, criterion_main}; +use deltachat::benchmark_internals::save_broadcast_shared_secret; use deltachat::{ Events, + benchmark_internals::key_from_asc, + benchmark_internals::parse_and_get_text, + benchmark_internals::store_self_keypair, + chat::ChatId, config::Config, context::Context, imex::{ImexMode, imex}, - pgp::{create_dummy_keypair, decrypt, encrypt_for_broadcast, pk_encrypt}, - receive_imf::receive_imf, + key, + pgp::{KeyPair, create_dummy_keypair, decrypt, encrypt_for_broadcast, pk_encrypt}, + receive_imf, stock_str::StockStrings, tools::create_broadcast_shared_secret_pub, }; @@ -17,6 +23,29 @@ use tempfile::tempdir; const NUM_SECRETS: usize = 500; +async fn create_context() -> Context { + let dir = tempdir().unwrap(); + let dbfile = dir.path().join("db.sqlite"); + let context = Context::new(dbfile.as_path(), 100, Events::new(), StockStrings::new()) + .await + .unwrap(); + + context + .set_config(Config::ConfiguredAddr, Some("bob@example.net")) + .await + .unwrap(); + let secret = key_from_asc(include_str!("../test-data/key/bob-secret.asc")) + .unwrap() + .0; + let public = secret.signed_public_key(); + let key_pair = KeyPair { public, secret }; + store_self_keypair(&context, &key_pair) + .await + .expect("Failed to save key"); + + context +} + fn criterion_benchmark(c: &mut Criterion) { let mut group = c.benchmark_group("Decrypt"); group.sample_size(10); @@ -28,7 +57,7 @@ fn criterion_benchmark(c: &mut Criterion) { 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 secret = secrets[NUM_SECRETS / 2].clone(); let encrypted = encrypt_for_broadcast( plain.clone(), black_box(&secret), @@ -83,6 +112,53 @@ fn criterion_benchmark(c: &mut Criterion) { assert_eq!(black_box(decrypted), plain); }); }); + + let rt = tokio::runtime::Runtime::new().unwrap(); + let mut secrets: Vec = (0..NUM_SECRETS) + .map(|_| create_broadcast_shared_secret_pub()) + .collect(); + + // "secret" is the symmetric secret that was used to encrypt text_symmetrically_encrypted.eml: + secrets[NUM_SECRETS / 2] = "secret".to_string(); + + let context = rt.block_on(async { + let context = create_context().await; + for (i, secret) in secrets.iter().enumerate() { + save_broadcast_shared_secret(&context, ChatId::new(10 + i as u32), &secret) + .await + .unwrap(); + } + context + }); + + group.bench_function("Receive a public-key encrypted message", |b| { + b.to_async(&rt).iter(|| { + let ctx = context.clone(); + async move { + let text = parse_and_get_text( + &ctx, + include_bytes!("../test-data/message/text_from_alice_encrypted.eml"), + ) + .await + .unwrap(); + assert_eq!(text, "hi"); + } + }); + }); + group.bench_function("Receive a symmetrically encrypted message", |b| { + b.to_async(&rt).iter(|| { + let ctx = context.clone(); + async move { + let text = parse_and_get_text( + &ctx, + include_bytes!("../test-data/message/text_symmetrically_encrypted.eml"), + ) + .await + .unwrap(); + assert_eq!(text, "Symmetrically encrypted message"); + } + }); + }); group.finish(); } diff --git a/src/benchmark_internals.rs b/src/benchmark_internals.rs new file mode 100644 index 000000000..423e0882e --- /dev/null +++ b/src/benchmark_internals.rs @@ -0,0 +1,34 @@ +//! Re-exports of internal functions needed for benchmarks. + +use anyhow::Result; +use std::collections::BTreeMap; + +use crate::chat::ChatId; +use crate::context::Context; +use crate::key; +use crate::key::DcKey; +use crate::mimeparser::MimeMessage; +pub use crate::pgp; + +use self::pgp::KeyPair; + +pub fn key_from_asc(data: &str) -> Result<(key::SignedSecretKey, BTreeMap)> { + key::SignedSecretKey::from_asc(data) +} + +pub async fn store_self_keypair(context: &Context, keypair: &KeyPair) -> Result<()> { + crate::key::store_self_keypair(context, keypair).await +} + +pub async fn parse_and_get_text(context: &Context, imf_raw: &[u8]) -> Result { + let mime_parser = MimeMessage::from_bytes(context, imf_raw, None).await?; + Ok(mime_parser.parts.into_iter().next().unwrap().msg) +} + +pub async fn save_broadcast_shared_secret( + context: &Context, + chat_id: ChatId, + secret: &str, +) -> Result<()> { + crate::chat::save_broadcast_shared_secret(context, chat_id, secret).await +} diff --git a/src/lib.rs b/src/lib.rs index dd1e1bad0..72237eabd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -112,6 +112,9 @@ pub mod accounts; pub mod peer_channels; pub mod reaction; +#[cfg(feature = "internals")] +pub mod benchmark_internals; + /// If set IMAP/incoming and SMTP/outgoing MIME messages will be printed. pub const DCC_MIME_DEBUG: &str = "DCC_MIME_DEBUG"; diff --git a/test-data/message/text_from_alice_encrypted.eml b/test-data/message/text_from_alice_encrypted.eml new file mode 100644 index 000000000..6e7952e91 --- /dev/null +++ b/test-data/message/text_from_alice_encrypted.eml @@ -0,0 +1,87 @@ +Content-Type: multipart/encrypted; protocol="application/pgp-encrypted"; + boundary="1858da4ad2d3c8a9_43c3a6383df12469_9f050814a95fd805" +MIME-Version: 1.0 +From: +To: +Subject: [...] +Date: Tue, 5 Aug 2025 11:07:50 +0000 +References: <0e547a9e-0785-421b-a867-ee204695fecc@localhost> +Chat-Version: 1.0 +Autocrypt: addr=alice@example.org; prefer-encrypt=mutual; keydata=mDMEXlh13RYJKwYBBAHaRw8BAQdAzfVIAleCXMJrq8VeLlEVof6ITCviMktKjmcBKAu4m5 + C0GUFsaWNlIDxhbGljZUBleGFtcGxlLm9yZz7CkgQQFggAOgUCaJHmBRYhBC5vossjtTLXKGNLWGSw + j2Gp7ZRDAhsDAh4BBQsJCAcCBhUKCQgLAgQWAgMBAScCGQEACgkQZLCPYantlENwpwEAq3zTDP9K1u + pV6yNLz6F+ylJ9U0WFIglz/CRWEu8Ma6YBAOZxBxIEJ3QFcoYaZwNUQ7lKffFiyb0cgA7hQM2cokMN + uDgEXlh13RIKKwYBBAGXVQEFAQEHQAbtyNbLZIUBTwqeW2W5tVbrusWLJ+nTUmtF7perLbYdAwEIB8 + J4BBgWCAAgBQJokeYFAhsMFiEELm+iyyO1MtcoY0tYZLCPYantlEMACgkQZLCPYantlENQgQD8CTIi + nPoPpFmnGuLXMOBH8PEDxTL+RQJgUms3dpkj2MUA/iB3L8TEtOC4A2eu5XAHttLrF3GYo7dlTq4LfO + oJtmIC + + +--1858da4ad2d3c8a9_43c3a6383df12469_9f050814a95fd805 +Content-Type: application/pgp-encrypted; charset="utf-8" +Content-Description: PGP/MIME version identification +Content-Transfer-Encoding: 7bit + +Version: 1 + +--1858da4ad2d3c8a9_43c3a6383df12469_9f050814a95fd805 +Content-Type: application/octet-stream; name="encrypted.asc"; + charset="utf-8" +Content-Description: OpenPGP encrypted message +Content-Disposition: inline; filename="encrypted.asc"; +Content-Transfer-Encoding: 7bit + +-----BEGIN PGP MESSAGE----- + +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 +=indJ +-----END PGP MESSAGE----- + + +--1858da4ad2d3c8a9_43c3a6383df12469_9f050814a95fd805-- + diff --git a/test-data/message/text_symmetrically_encrypted.eml b/test-data/message/text_symmetrically_encrypted.eml new file mode 100644 index 000000000..44406e7d4 --- /dev/null +++ b/test-data/message/text_symmetrically_encrypted.eml @@ -0,0 +1,56 @@ +Content-Type: multipart/encrypted; protocol="application/pgp-encrypted"; + boundary="1858db5a667e9817_308656fa7edcc46c_c8ec5a6c260b51bc" +MIME-Version: 1.0 +From: +To: "hidden-recipients": ; +Subject: [...] +Date: Tue, 5 Aug 2025 11:27:17 +0000 +Message-ID: <5f9a3e21-fbbd-43aa-9638-1927da98b772@localhost> +References: <5f9a3e21-fbbd-43aa-9638-1927da98b772@localhost> +Chat-Version: 1.0 +Autocrypt: addr=alice@example.org; prefer-encrypt=mutual; keydata=mDMEXlh13RYJKwYBBAHaRw8BAQdAzfVIAleCXMJrq8VeLlEVof6ITCviMktKjmcBKAu4m5 + C0GUFsaWNlIDxhbGljZUBleGFtcGxlLm9yZz7CkgQQFggAOgUCaJHqlBYhBC5vossjtTLXKGNLWGSw + j2Gp7ZRDAhsDAh4BBQsJCAcCBhUKCQgLAgQWAgMBAScCGQEACgkQZLCPYantlEM55QD9H8bPo4J8Yz + TlMuMQms7o7rW89FYX+WH//0IDbfgWysAA/2lDEwfcP0ufyJPvUMGUi62JcFS9LBwS0riKGpC6hiMM + uDgEXlh13RIKKwYBBAGXVQEFAQEHQAbtyNbLZIUBTwqeW2W5tVbrusWLJ+nTUmtF7perLbYdAwEIB8 + J4BBgWCAAgBQJokeqUAhsMFiEELm+iyyO1MtcoY0tYZLCPYantlEMACgkQZLCPYantlEPdsAEA8cjS + XsAtWnQtW6m7Yn53j5Wk+jl5b3plydWhh8kk8uAA/2gx7wuDYDW9V32NdacJFV2H7UtItsTjN3qp8f + l00TQB + + +--1858db5a667e9817_308656fa7edcc46c_c8ec5a6c260b51bc +Content-Type: application/pgp-encrypted; charset="utf-8" +Content-Description: PGP/MIME version identification +Content-Transfer-Encoding: 7bit + +Version: 1 + +--1858db5a667e9817_308656fa7edcc46c_c8ec5a6c260b51bc +Content-Type: application/octet-stream; name="encrypted.asc"; + charset="utf-8" +Content-Description: OpenPGP encrypted message +Content-Disposition: inline; filename="encrypted.asc"; +Content-Transfer-Encoding: 7bit + +-----BEGIN PGP MESSAGE----- + +wz4GHAcCCgEI44vuKOnsZubFQrI4MW7LbfmxKq5N2VIQ8c2CIRIAnvAa3AMV3Deq +P69ilwwDCf2NRy8Xg42Dc9LBkAIHAgdRy6G2xao09tPMEBBhY9dF01x21w+MyWd4 +Hm8Qz/No8BPkvxJO8WqFmbO/U0EHMEXGpADzNjU82I1bamslr0xjohgkL7goDkKl +ZbHMV1XTrG4No57fpXZSlWKRK+cJaY9S5pdwAboHuzdxhbWf+lAT2mqntkXLAtdT +tYv0piXH5+czWFsFpJRH4egYknhO+V9kpE4QX4wnwSwDinsBqAeMawcU93V4Eso+ +JYacb9Rd6Sv3ApjB12vAQTlc5KAxSFdCRGQBFIWNAMf6X04dSrURgh/gy2AnnO4q +ViU2+o5yITN+6KXxQrfmtL+xcPY1vKiATH/n5HYo/MgkwkwCSqvC5eajuMmKqncX +4877OzvCq7ohAnZVuaQFHLJlavKNzS76Hx4AGKX8MojCzhpUfmLwcjBtmteohAJd +COxhIS6hQDrgipscFmPW7fHIlHPvz0B4G/oorMzg9sN/vu+IerCoP8DCIbVIN3eK +Nt8XZtY2bNnzzQyh6XP5E5dhHWMGFlJFA1rdnAZ6O36Vdmm5++E4oFhluOTXNKRd +XapcxtXwwHfm+294pi9P8TWpADXwH6Mt2gwhHh9BE68SstjdM29hSA89q4Kn4y8p +EEsplNl2A4ZeD2Xz868PwoLnRa1f2b5nzdeZhUtj4K2JFGbAJ6alJ5sjRZaZIxnE +rQVvpwRVgaBp9scIsKVT14czCVAYW3n4RMYB3zwTkSIoW0prWZAGlzMAjzlaspnU +zxXzeY7woy+vjRPCFJCxWRrZ20cDQzs5pnrjapxS8j72ByQ= +=SwRI +-----END PGP MESSAGE----- + + +--1858db5a667e9817_308656fa7edcc46c_c8ec5a6c260b51bc-- +