diff --git a/CHANGELOG.md b/CHANGELOG.md index 01e044f4..9d53f78b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,8 @@ # 0.49.0 - [unreleased] +- Update to [`libp2p-core` `v0.36.1`](core/CHANGELOG.md#0361). + - Update to [`libp2p-tcp` `v0.37.0`](transports/tcp/CHANGELOG.md#0370). - Update individual crates. - Update to [`libp2p-ping` `v0.39.1`](protocols/ping/CHANGELOG.md#0391). diff --git a/Cargo.toml b/Cargo.toml index 0a4344d1..e3e2283b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -81,7 +81,7 @@ instant = "0.1.11" # Explicit dependency to be used in `wasm-bindgen` feature lazy_static = "1.2" libp2p-autonat = { version = "0.7.0", path = "protocols/autonat", optional = true } -libp2p-core = { version = "0.36.0", path = "core", default-features = false } +libp2p-core = { version = "0.36.1", path = "core", default-features = false } libp2p-dcutr = { version = "0.6.0", path = "protocols/dcutr", optional = true } libp2p-floodsub = { version = "0.39.1", path = "protocols/floodsub", optional = true } libp2p-identify = { version = "0.39.0", path = "protocols/identify", optional = true } diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md index 4a5e07f1..deb921e9 100644 --- a/core/CHANGELOG.md +++ b/core/CHANGELOG.md @@ -1,3 +1,9 @@ +# 0.36.1 - [unreleased] + +- Implement `Hash` and `Ord` for `PublicKey`. See [PR 2915]. + +[PR 2915]: https://github.com/libp2p/rust-libp2p/pull/2915 + # 0.36.0 - Make RSA keypair support optional. To enable RSA support, `rsa` feature should be enabled. diff --git a/core/Cargo.toml b/core/Cargo.toml index 8390c758..201f5220 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -3,7 +3,7 @@ name = "libp2p-core" edition = "2021" rust-version = "1.56.1" description = "Core traits and structs of libp2p" -version = "0.36.0" +version = "0.36.1" authors = ["Parity Technologies "] license = "MIT" repository = "https://github.com/libp2p/rust-libp2p" diff --git a/core/src/identity.rs b/core/src/identity.rs index 73be1c78..af5dceb6 100644 --- a/core/src/identity.rs +++ b/core/src/identity.rs @@ -214,7 +214,7 @@ impl zeroize::Zeroize for keys_proto::PrivateKey { } /// The public key of a node's identity keypair. -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] pub enum PublicKey { /// A public Ed25519 key. Ed25519(ed25519::PublicKey), @@ -379,4 +379,22 @@ mod tests { assert_eq!(expected_peer_id, peer_id); } + + #[test] + fn public_key_implements_hash() { + use std::hash::Hash; + + fn assert_implements_hash() {} + + assert_implements_hash::(); + } + + #[test] + fn public_key_implements_ord() { + use std::cmp::Ord; + + fn assert_implements_ord() {} + + assert_implements_ord::(); + } } diff --git a/core/src/identity/ecdsa.rs b/core/src/identity/ecdsa.rs index 81dfec4b..88411b23 100644 --- a/core/src/identity/ecdsa.rs +++ b/core/src/identity/ecdsa.rs @@ -21,7 +21,9 @@ //! ECDSA keys with secp256r1 curve support. use super::error::DecodingError; +use core::cmp; use core::fmt; +use core::hash; use p256::{ ecdsa::{ signature::{Signer, Verifier}, @@ -117,7 +119,7 @@ impl fmt::Debug for SecretKey { } /// An ECDSA public key. -#[derive(Clone, PartialEq, Eq)] +#[derive(Clone, Eq, PartialOrd, Ord)] pub struct PublicKey(VerifyingKey); impl PublicKey { @@ -222,6 +224,18 @@ impl fmt::Debug for PublicKey { } } +impl cmp::PartialEq for PublicKey { + fn eq(&self, other: &Self) -> bool { + self.to_bytes().eq(&other.to_bytes()) + } +} + +impl hash::Hash for PublicKey { + fn hash(&self, state: &mut H) { + self.to_bytes().hash(state); + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/core/src/identity/ed25519.rs b/core/src/identity/ed25519.rs index 5782ac78..eef934d4 100644 --- a/core/src/identity/ed25519.rs +++ b/core/src/identity/ed25519.rs @@ -21,7 +21,9 @@ //! Ed25519 keys. use super::error::DecodingError; +use core::cmp; use core::fmt; +use core::hash; use ed25519_dalek::{self as ed25519, Signer as _, Verifier as _}; use rand::RngCore; use std::convert::TryFrom; @@ -113,7 +115,7 @@ impl From for Keypair { } /// An Ed25519 public key. -#[derive(PartialEq, Eq, Clone)] +#[derive(Eq, Clone)] pub struct PublicKey(ed25519::PublicKey); impl fmt::Debug for PublicKey { @@ -126,6 +128,30 @@ impl fmt::Debug for PublicKey { } } +impl cmp::PartialEq for PublicKey { + fn eq(&self, other: &Self) -> bool { + self.0.as_bytes().eq(other.0.as_bytes()) + } +} + +impl hash::Hash for PublicKey { + fn hash(&self, state: &mut H) { + self.0.as_bytes().hash(state); + } +} + +impl cmp::PartialOrd for PublicKey { + fn partial_cmp(&self, other: &Self) -> Option { + self.0.as_bytes().partial_cmp(other.0.as_bytes()) + } +} + +impl cmp::Ord for PublicKey { + fn cmp(&self, other: &Self) -> cmp::Ordering { + self.0.as_bytes().cmp(other.0.as_bytes()) + } +} + impl PublicKey { /// Verify the Ed25519 signature on a message using the public key. pub fn verify(&self, msg: &[u8], sig: &[u8]) -> bool { diff --git a/core/src/identity/rsa.rs b/core/src/identity/rsa.rs index 1d20f00a..497dca40 100644 --- a/core/src/identity/rsa.rs +++ b/core/src/identity/rsa.rs @@ -70,7 +70,7 @@ impl Keypair { } /// An RSA public key. -#[derive(Clone, PartialEq, Eq)] +#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct PublicKey(Vec); impl PublicKey { @@ -306,21 +306,14 @@ impl DerDecodable<'_> for Asn1SubjectPublicKeyInfo { mod tests { use super::*; use quickcheck::*; - use std::fmt; const KEY1: &'static [u8] = include_bytes!("test/rsa-2048.pk8"); const KEY2: &'static [u8] = include_bytes!("test/rsa-3072.pk8"); const KEY3: &'static [u8] = include_bytes!("test/rsa-4096.pk8"); - #[derive(Clone)] + #[derive(Clone, Debug)] struct SomeKeypair(Keypair); - impl fmt::Debug for SomeKeypair { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "SomeKeypair") - } - } - impl Arbitrary for SomeKeypair { fn arbitrary(g: &mut Gen) -> SomeKeypair { let mut key = g.choose(&[KEY1, KEY2, KEY3]).unwrap().to_vec(); diff --git a/core/src/identity/secp256k1.rs b/core/src/identity/secp256k1.rs index 2c3aaf89..bfecc33e 100644 --- a/core/src/identity/secp256k1.rs +++ b/core/src/identity/secp256k1.rs @@ -22,7 +22,9 @@ use super::error::{DecodingError, SigningError}; use asn1_der::typed::{DerDecodable, Sequence}; +use core::cmp; use core::fmt; +use core::hash; use libsecp256k1::{Message, Signature}; use sha2::{Digest as ShaDigestTrait, Sha256}; use zeroize::Zeroize; @@ -150,7 +152,7 @@ impl SecretKey { } /// A Secp256k1 public key. -#[derive(PartialEq, Eq, Clone)] +#[derive(Eq, Clone)] pub struct PublicKey(libsecp256k1::PublicKey); impl fmt::Debug for PublicKey { @@ -163,6 +165,30 @@ impl fmt::Debug for PublicKey { } } +impl cmp::PartialEq for PublicKey { + fn eq(&self, other: &Self) -> bool { + self.encode().eq(&other.encode()) + } +} + +impl hash::Hash for PublicKey { + fn hash(&self, state: &mut H) { + self.encode().hash(state); + } +} + +impl cmp::PartialOrd for PublicKey { + fn partial_cmp(&self, other: &Self) -> Option { + self.encode().partial_cmp(&other.encode()) + } +} + +impl cmp::Ord for PublicKey { + fn cmp(&self, other: &Self) -> cmp::Ordering { + self.encode().cmp(&other.encode()) + } +} + impl PublicKey { /// Verify the Secp256k1 signature on a message using the public key. pub fn verify(&self, msg: &[u8], sig: &[u8]) -> bool {