summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2023-03-21 17:29:43 +0100
committerJustus Winter <justus@sequoia-pgp.org>2023-03-21 17:29:43 +0100
commit4819abcb29a655ef285d3fc13a1f186d50375018 (patch)
treeb2c3a1019c356596542a66c8da122c1f35d40157
parent5bc6ab7e9d9c34ab6393472219a53547106b2b5a (diff)
openpgp: Cache fingerprint calculations.
- Fixes #645.
-rw-r--r--Cargo.lock1
-rw-r--r--openpgp/Cargo.toml1
-rw-r--r--openpgp/src/packet/key.rs18
3 files changed, 15 insertions, 5 deletions
diff --git a/Cargo.lock b/Cargo.lock
index b53442c8..781eb5a5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2367,6 +2367,7 @@ dependencies = [
"memsec",
"nettle",
"num-bigint-dig",
+ "once_cell",
"openssl",
"openssl-sys",
"p256",
diff --git a/openpgp/Cargo.toml b/openpgp/Cargo.toml
index d35048ab..a734a1cf 100644
--- a/openpgp/Cargo.toml
+++ b/openpgp/Cargo.toml
@@ -39,6 +39,7 @@ lazy_static = "1.4.0"
libc = "0.2.66"
memsec = { version = ">=0.5", default-features = false }
nettle = { version = "7.2.2", optional = true }
+once_cell = "1"
regex = "1"
regex-syntax = "0.6"
sha1collisiondetection = { version = "0.2.3", default-features = false, features = ["std"] }
diff --git a/openpgp/src/packet/key.rs b/openpgp/src/packet/key.rs
index c9b433a0..9479caec 100644
--- a/openpgp/src/packet/key.rs
+++ b/openpgp/src/packet/key.rs
@@ -775,6 +775,8 @@ pub struct Key4<P, R>
/// Optional secret part of the key.
secret: Option<SecretKeyMaterial>,
+ fingerprint: once_cell::sync::OnceCell<Fingerprint>,
+
p: std::marker::PhantomData<P>,
r: std::marker::PhantomData<R>,
}
@@ -930,6 +932,7 @@ where
pk_algo,
mpis,
secret,
+ fingerprint: Default::default(),
p: std::marker::PhantomData,
r: std::marker::PhantomData,
})
@@ -951,6 +954,7 @@ impl<R> Key4<key::PublicParts, R>
pk_algo,
mpis,
secret: None,
+ fingerprint: Default::default(),
p: std::marker::PhantomData,
r: std::marker::PhantomData,
})
@@ -1044,6 +1048,7 @@ impl<R> Key4<SecretParts, R>
pk_algo,
mpis,
secret: Some(secret),
+ fingerprint: Default::default(),
p: std::marker::PhantomData,
r: std::marker::PhantomData,
})
@@ -1153,13 +1158,15 @@ impl<P, R> Key4<P, R>
///
/// [Section 12.2 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-12.2
pub fn fingerprint(&self) -> Fingerprint {
- let mut h = HashAlgorithm::SHA1.context().unwrap();
+ self.fingerprint.get_or_init(|| {
+ let mut h = HashAlgorithm::SHA1.context().unwrap();
- self.hash(&mut h);
+ self.hash(&mut h);
- let mut digest = vec![0u8; h.digest_size()];
- let _ = h.digest(&mut digest);
- Fingerprint::from_bytes(digest.as_slice())
+ let mut digest = vec![0u8; h.digest_size()];
+ let _ = h.digest(&mut digest);
+ Fingerprint::from_bytes(digest.as_slice())
+ }).clone()
}
/// Computes and returns the `Key`'s `Key ID`.
@@ -1683,6 +1690,7 @@ impl Arbitrary for Key4<PublicParts, UnspecifiedRole> {
.expect("mpi::PublicKey::arbitrary only uses known algos"),
mpis,
secret: None,
+ fingerprint: Default::default(),
p: std::marker::PhantomData,
r: std::marker::PhantomData,
}