From 5ccf0c8db7cd63ab80ff9388565e258d4faec4c6 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Mon, 7 Nov 2022 12:23:43 +1100 Subject: [PATCH] Manually implement PartialEq, Eq, and Hash for PublicKey `PartialEq` and `Eq` should agree with `PartialOrd` and `Ord` but we are deriving `PartialEq`/`Eq` and doing a custom implementation of `PartialOrd` and `Ord` (that calls down to ffi functions). If two keys are equal their hashes should be equal so, we should add a custom implementation of `Hash` also. In order to guarantee the digest will be the same across library versions first serialize the key before hashing it. Add custom implementation of `PartialEq`, `Eq`, and `Hash` when not fuzzing. Please note, this is for the main `PublicKey` type, the patch does not effect the `ffi::PublicKey`, nor do we call methods on the `ffi::PublicKey`. --- src/key.rs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/key.rs b/src/key.rs index ef45f2d..962d710 100644 --- a/src/key.rs +++ b/src/key.rs @@ -100,8 +100,8 @@ pub const ONE_KEY: SecretKey = SecretKey(constants::ONE); /// ``` /// [`bincode`]: https://docs.rs/bincode /// [`cbor`]: https://docs.rs/cbor -#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] -#[cfg_attr(fuzzing, derive(PartialOrd, Ord))] +#[derive(Copy, Clone, Debug)] +#[cfg_attr(fuzzing, derive(PartialOrd, Ord, PartialEq, Eq, Hash))] #[repr(transparent)] pub struct PublicKey(ffi::PublicKey); @@ -814,6 +814,24 @@ impl Ord for PublicKey { } } +#[cfg(not(fuzzing))] +impl PartialEq for PublicKey { + fn eq(&self, other: &Self) -> bool { + self.cmp(other) == core::cmp::Ordering::Equal + } +} + +#[cfg(not(fuzzing))] +impl Eq for PublicKey {} + +#[cfg(not(fuzzing))] +impl core::hash::Hash for PublicKey { + fn hash(&self, state: &mut H) { + let ser = self.serialize(); + ser.hash(state); + } +} + /// Opaque data structure that holds a keypair consisting of a secret and a public key. /// /// # Serde support