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`.
This commit is contained in:
Tobin C. Harding 2022-11-07 12:23:43 +11:00
parent 497654ea23
commit 5ccf0c8db7
1 changed files with 20 additions and 2 deletions

View File

@ -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<H: core::hash::Hasher>(&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