diff options
author | Nora Widdecke <nora@sequoia-pgp.org> | 2021-04-08 15:27:29 +0200 |
---|---|---|
committer | Nora Widdecke <nora@sequoia-pgp.org> | 2021-04-13 12:38:16 +0200 |
commit | a931158a9810d1ab37a48640c38da779eca6113f (patch) | |
tree | c63683e7d7111ee1dc981c07c0f47c90313cc720 | |
parent | 2418df3723a18e791ebe5efc551e4825be679b76 (diff) |
bench: Add verify benchmark.
-rw-r--r-- | openpgp/Cargo.toml | 4 | ||||
-rw-r--r-- | openpgp/benches/common/decrypt.rs | 44 | ||||
-rw-r--r-- | openpgp/benches/verify_message.rs | 48 |
3 files changed, 88 insertions, 8 deletions
diff --git a/openpgp/Cargo.toml b/openpgp/Cargo.toml index 6f93aff9..258f5b2e 100644 --- a/openpgp/Cargo.toml +++ b/openpgp/Cargo.toml @@ -112,3 +112,7 @@ harness = false [[bench]] name = "sign_message" harness = false + +[[bench]] +name = "verify_message" +harness = false diff --git a/openpgp/benches/common/decrypt.rs b/openpgp/benches/common/decrypt.rs index 536581af..48186ac1 100644 --- a/openpgp/benches/common/decrypt.rs +++ b/openpgp/benches/common/decrypt.rs @@ -5,7 +5,7 @@ use openpgp::packet::prelude::*; use openpgp::packet::{PKESK, SKESK}; use openpgp::parse::stream::{ DecryptionHelper, DecryptorBuilder, MessageLayer, MessageStructure, - VerificationError, VerificationHelper, + VerificationHelper, VerifierBuilder, }; use openpgp::parse::Parse; use openpgp::policy::StandardPolicy; @@ -85,7 +85,7 @@ pub fn decrypt_with_password( // openpgp::parse::stream::Decryptor struct CertHelper<'a> { sender: Option<&'a Cert>, - recipient: &'a Cert, + recipient: Option<&'a Cert>, } impl VerificationHelper for CertHelper<'_> { @@ -104,9 +104,9 @@ impl VerificationHelper for CertHelper<'_> { for (i, layer) in structure.into_iter().enumerate() { match layer { MessageLayer::Encryption { .. } if i == 0 => (), - MessageLayer::Compression { .. } if i == 1 => (), + MessageLayer::Compression { .. } if i == 0 || i == 1 => (), MessageLayer::SignatureGroup { ref results } - if i == 1 || i == 2 => + if i == 0 || i == 1 || i == 2 => { if !results.iter().any(|r| r.is_ok()) { for result in results { @@ -118,8 +118,9 @@ impl VerificationHelper for CertHelper<'_> { } _ => { return Err(anyhow::anyhow!( - "Unexpected message structure {:?}", - layer + "Unexpected message structure {:?} at level {}", + layer, + i )) } } @@ -143,6 +144,7 @@ impl DecryptionHelper for CertHelper<'_> { let cand_secret_keys: Vec<Key<key::SecretParts, key::UnspecifiedRole>> = self.recipient + .expect("Cannot decrypt without recipient's cert.") .keys() .with_policy(p, None) .for_transport_encryption() @@ -190,7 +192,7 @@ pub fn decrypt_with_cert( // Make a helper that that feeds the password to the decryptor. let helper = CertHelper { sender: None, - recipient: cert, + recipient: Some(cert), }; // Now, create a decryptor with a helper using the given Certs. @@ -217,7 +219,7 @@ pub fn decrypt_and_verify( // Make a helper that that feeds the password to the decryptor. let helper = CertHelper { sender: Some(sender), - recipient, + recipient: Some(recipient), }; // Now, create a decryptor with a helper using the given Certs. @@ -230,3 +232,29 @@ pub fn decrypt_and_verify( Ok(()) } + +// This is marked as dead_code. Seems that using a function only from within +// a benchmark loop hides it from the compiler. +#[allow(dead_code)] +// Verifies the given message using the given sender's cert. +pub fn verify( + sink: &mut dyn Write, + ciphertext: &[u8], + sender: &Cert, +) -> openpgp::Result<()> { + // Make a helper that that feeds the sender's cert to the verifier. + let helper = CertHelper { + sender: Some(sender), + recipient: None, + }; + + // Now, create a verifier with a helper using the given Certs. + let p = &StandardPolicy::new(); + let mut verifier = VerifierBuilder::from_bytes(ciphertext)? + .with_policy(p, None, helper)?; + + // Verify the data. + std::io::copy(&mut verifier, sink)?; + + Ok(()) +} diff --git a/openpgp/benches/verify_message.rs b/openpgp/benches/verify_message.rs new file mode 100644 index 00000000..1fbf15c2 --- /dev/null +++ b/openpgp/benches/verify_message.rs @@ -0,0 +1,48 @@ +use criterion::{ + criterion_group, criterion_main, BenchmarkId, Criterion, Throughput, +}; + +use sequoia_openpgp as openpgp; +use openpgp::cert::Cert; +use openpgp::parse::Parse; + +mod common; +use common::{decrypt, encrypt}; + +lazy_static::lazy_static! { + static ref SENDER: Cert = + Cert::from_bytes(&include_bytes!("../tests/data/keys/sender.pgp")[..]) + .unwrap(); + static ref ZEROS_1_MB: Vec<u8> = vec![0; 1 * 1024 * 1024]; + static ref ZEROS_10_MB: Vec<u8> = vec![0; 10 * 1024 * 1024]; +} + +fn verify(bytes: &[u8], sender: &Cert) { + let mut sink = Vec::new(); + decrypt::verify(&mut sink, &bytes, sender).unwrap(); +} + +fn bench_verify(c: &mut Criterion) { + let mut group = c.benchmark_group("verify message"); + + // Sign a very short, medium and very long message, + // and then benchmark verification. + let messages = &[b"Hello world.", &ZEROS_1_MB[..]]; + + messages + .iter() + .for_each(|m| { + let signed = encrypt::sign(m, &SENDER).unwrap(); + group.throughput(Throughput::Bytes(signed.len() as u64)); + group.bench_with_input( + BenchmarkId::new("verify", m.len()), + &signed, + |b, s| b.iter(|| verify(&s, &SENDER)), + ); + }); + + group.finish(); +} + +criterion_group!(benches, bench_verify); +criterion_main!(benches); |