diff --git a/src/util/key.rs b/src/util/key.rs index 52cc97c84f..c28d675fe7 100644 --- a/src/util/key.rs +++ b/src/util/key.rs @@ -17,7 +17,7 @@ //! use std::fmt::{self, Write}; -use std::{io, ops, error}; +use std::{cmp, io, ops, error}; use std::str::FromStr; use secp256k1::{self, Secp256k1}; @@ -69,7 +69,7 @@ impl From for Error { } /// A Bitcoin ECDSA public key -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct PublicKey { /// Whether this public key should be serialized as compressed pub compressed: bool, @@ -77,6 +77,28 @@ pub struct PublicKey { pub key: secp256k1::PublicKey, } +impl Ord for PublicKey{ + + // implement lexical partial ord for PublicKey as per BIP 67 if both keys are + // compressed/uncompressed. Since, compressed Pk's start with 0x02 and 0x03 + // they are always less than the 0x04 uncompressed keys + fn cmp(&self, other: &PublicKey) -> cmp::Ordering { + match (self.compressed, other.compressed){ + (true, false) => cmp::Ordering::Less, + (false, true) => cmp::Ordering::Greater, + (true, true) => self.key.serialize().cmp(&other.key.serialize()), + (false, false) => self.key.serialize_uncompressed().cmp(&other.key.serialize_uncompressed()), + } + } +} + +impl PartialOrd for PublicKey{ + + fn partial_cmp(&self, other: &PublicKey) -> Option { + Some(self.cmp(other)) + } +} + impl PublicKey { /// Returns bitcoin 160-bit hash of the public key pub fn pubkey_hash(&self) -> PubkeyHash {