From cebf321c32f9a2f4af82f902dc16ce84747f33a9 Mon Sep 17 00:00:00 2001 From: futpib Date: Mon, 19 Sep 2022 14:45:05 +0400 Subject: [PATCH 1/9] Implement `Hash` for `PublicKey` --- core/src/identity.rs | 28 +++++++++++++++++++++++++++- core/src/identity/ecdsa.rs | 7 +++++++ core/src/identity/ed25519.rs | 9 +++++++++ core/src/identity/secp256k1.rs | 7 +++++++ 4 files changed, 50 insertions(+), 1 deletion(-) diff --git a/core/src/identity.rs b/core/src/identity.rs index 73be1c78b57..f6af245f6ea 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)] pub enum PublicKey { /// A public Ed25519 key. Ed25519(ed25519::PublicKey), @@ -379,4 +379,30 @@ mod tests { assert_eq!(expected_peer_id, peer_id); } + + #[test] + fn public_key_hash() { + use std::collections::*; + + let mut keypairs = Vec::new(); + + for _ in 0..8 { + keypairs.push(Keypair::generate_ed25519()); + keypairs.push(Keypair::generate_secp256k1()); + keypairs.push(Keypair::generate_ecdsa()); + } + + let public_keys: Vec<_> = keypairs + .iter() + .map(|k| k.public()) + .collect(); + + let public_keys_hash_set: HashSet = HashSet::from_iter( + public_keys + .iter() + .map(|p| p.clone()) + ); + + assert_eq!(public_keys_hash_set.len(), public_keys.len()); + } } diff --git a/core/src/identity/ecdsa.rs b/core/src/identity/ecdsa.rs index 81dfec4b4e0..c0816f4cedb 100644 --- a/core/src/identity/ecdsa.rs +++ b/core/src/identity/ecdsa.rs @@ -22,6 +22,7 @@ use super::error::DecodingError; use core::fmt; +use core::hash; use p256::{ ecdsa::{ signature::{Signer, Verifier}, @@ -222,6 +223,12 @@ impl fmt::Debug for PublicKey { } } +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 5782ac788cb..c289ce85c70 100644 --- a/core/src/identity/ed25519.rs +++ b/core/src/identity/ed25519.rs @@ -22,6 +22,7 @@ use super::error::DecodingError; use core::fmt; +use core::hash; use ed25519_dalek::{self as ed25519, Signer as _, Verifier as _}; use rand::RngCore; use std::convert::TryFrom; @@ -126,6 +127,14 @@ impl fmt::Debug for PublicKey { } } +// Remove (derive instead) when this PR is merged: +// https://github.com/dalek-cryptography/ed25519-dalek/pull/176 +impl hash::Hash for PublicKey { + fn hash(&self, state: &mut H) { + self.0.as_bytes().hash(state); + } +} + 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/secp256k1.rs b/core/src/identity/secp256k1.rs index 2c3aaf89a51..4da19154650 100644 --- a/core/src/identity/secp256k1.rs +++ b/core/src/identity/secp256k1.rs @@ -23,6 +23,7 @@ use super::error::{DecodingError, SigningError}; use asn1_der::typed::{DerDecodable, Sequence}; use core::fmt; +use core::hash; use libsecp256k1::{Message, Signature}; use sha2::{Digest as ShaDigestTrait, Sha256}; use zeroize::Zeroize; @@ -163,6 +164,12 @@ impl fmt::Debug for PublicKey { } } +impl hash::Hash for PublicKey { + fn hash(&self, state: &mut H) { + self.encode().hash(state); + } +} + impl PublicKey { /// Verify the Secp256k1 signature on a message using the public key. pub fn verify(&self, msg: &[u8], sig: &[u8]) -> bool { From 801166afe52ae8d9ec965805fd9773149b5ac794 Mon Sep 17 00:00:00 2001 From: futpib Date: Mon, 19 Sep 2022 14:55:30 +0400 Subject: [PATCH 2/9] Implement `Ord` for `PublicKey` --- core/src/identity.rs | 28 +++++++++++++++++++++++++++- core/src/identity/ecdsa.rs | 2 +- core/src/identity/ed25519.rs | 13 +++++++++++++ core/src/identity/secp256k1.rs | 13 +++++++++++++ 4 files changed, 54 insertions(+), 2 deletions(-) diff --git a/core/src/identity.rs b/core/src/identity.rs index f6af245f6ea..91a7c3a0dc5 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, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] pub enum PublicKey { /// A public Ed25519 key. Ed25519(ed25519::PublicKey), @@ -405,4 +405,30 @@ mod tests { assert_eq!(public_keys_hash_set.len(), public_keys.len()); } + + #[test] + fn public_key_ord() { + use std::collections::*; + + let mut keypairs = Vec::new(); + + for _ in 0..8 { + keypairs.push(Keypair::generate_ed25519()); + keypairs.push(Keypair::generate_secp256k1()); + keypairs.push(Keypair::generate_ecdsa()); + } + + let public_keys: Vec<_> = keypairs + .iter() + .map(|k| k.public()) + .collect(); + + let public_keys_b_tree_set: BTreeSet = BTreeSet::from_iter( + public_keys + .iter() + .map(|p| p.clone()) + ); + + assert_eq!(public_keys_b_tree_set.len(), public_keys.len()); + } } diff --git a/core/src/identity/ecdsa.rs b/core/src/identity/ecdsa.rs index c0816f4cedb..c4ddde65937 100644 --- a/core/src/identity/ecdsa.rs +++ b/core/src/identity/ecdsa.rs @@ -118,7 +118,7 @@ impl fmt::Debug for SecretKey { } /// An ECDSA public key. -#[derive(Clone, PartialEq, Eq)] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct PublicKey(VerifyingKey); impl PublicKey { diff --git a/core/src/identity/ed25519.rs b/core/src/identity/ed25519.rs index c289ce85c70..c1dd4db7a62 100644 --- a/core/src/identity/ed25519.rs +++ b/core/src/identity/ed25519.rs @@ -23,6 +23,7 @@ use super::error::DecodingError; use core::fmt; use core::hash; +use core::cmp; use ed25519_dalek::{self as ed25519, Signer as _, Verifier as _}; use rand::RngCore; use std::convert::TryFrom; @@ -135,6 +136,18 @@ impl hash::Hash for PublicKey { } } +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/secp256k1.rs b/core/src/identity/secp256k1.rs index 4da19154650..ca6b4bbcd48 100644 --- a/core/src/identity/secp256k1.rs +++ b/core/src/identity/secp256k1.rs @@ -24,6 +24,7 @@ use super::error::{DecodingError, SigningError}; use asn1_der::typed::{DerDecodable, Sequence}; use core::fmt; use core::hash; +use core::cmp; use libsecp256k1::{Message, Signature}; use sha2::{Digest as ShaDigestTrait, Sha256}; use zeroize::Zeroize; @@ -170,6 +171,18 @@ impl hash::Hash for PublicKey { } } +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 { From e0263ddfdf7eb238684efb0a516393c6ebd80c9a Mon Sep 17 00:00:00 2001 From: futpib Date: Mon, 19 Sep 2022 15:02:46 +0400 Subject: [PATCH 3/9] core/CHANGELOG: Add entry for PublicKey Hash + Ord --- core/CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md index 4a5e07f14f8..32ef9c536c2 100644 --- a/core/CHANGELOG.md +++ b/core/CHANGELOG.md @@ -1,3 +1,9 @@ +# 0.36.1 - [unreleased] + +- Added `Hash` and `Ord` instances 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. From 0e58af1b0e94892f8935e448ee7b3bf9aff889b3 Mon Sep 17 00:00:00 2001 From: futpib Date: Mon, 19 Sep 2022 21:46:33 +0000 Subject: [PATCH 4/9] Update core/CHANGELOG.md Co-authored-by: Thomas Eizinger --- core/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md index 32ef9c536c2..deb921e9d25 100644 --- a/core/CHANGELOG.md +++ b/core/CHANGELOG.md @@ -1,6 +1,6 @@ # 0.36.1 - [unreleased] -- Added `Hash` and `Ord` instances for `PublicKey`. See [PR 2915]. +- Implement `Hash` and `Ord` for `PublicKey`. See [PR 2915]. [PR 2915]: https://github.com/libp2p/rust-libp2p/pull/2915 From 8292a786be7c92b1f2b84d7a073359d694d79116 Mon Sep 17 00:00:00 2001 From: futpib Date: Tue, 20 Sep 2022 02:56:22 +0400 Subject: [PATCH 5/9] Test for Hash trait properties with quickcheck --- core/src/identity.rs | 50 ++++++---------------------------- core/src/identity/ecdsa.rs | 28 +++++++++++++++++++ core/src/identity/ed25519.rs | 27 ++++++++++++++++++ core/src/identity/rsa.rs | 30 ++++++++++++++------ core/src/identity/secp256k1.rs | 39 ++++++++++++++++++++++++++ core/src/lib.rs | 3 ++ core/src/test.rs | 8 ++++++ 7 files changed, 134 insertions(+), 51 deletions(-) create mode 100644 core/src/test.rs diff --git a/core/src/identity.rs b/core/src/identity.rs index 91a7c3a0dc5..af5dceb69ee 100644 --- a/core/src/identity.rs +++ b/core/src/identity.rs @@ -381,54 +381,20 @@ mod tests { } #[test] - fn public_key_hash() { - use std::collections::*; + fn public_key_implements_hash() { + use std::hash::Hash; - let mut keypairs = Vec::new(); + fn assert_implements_hash() {} - for _ in 0..8 { - keypairs.push(Keypair::generate_ed25519()); - keypairs.push(Keypair::generate_secp256k1()); - keypairs.push(Keypair::generate_ecdsa()); - } - - let public_keys: Vec<_> = keypairs - .iter() - .map(|k| k.public()) - .collect(); - - let public_keys_hash_set: HashSet = HashSet::from_iter( - public_keys - .iter() - .map(|p| p.clone()) - ); - - assert_eq!(public_keys_hash_set.len(), public_keys.len()); + assert_implements_hash::(); } #[test] - fn public_key_ord() { - use std::collections::*; - - let mut keypairs = Vec::new(); - - for _ in 0..8 { - keypairs.push(Keypair::generate_ed25519()); - keypairs.push(Keypair::generate_secp256k1()); - keypairs.push(Keypair::generate_ecdsa()); - } - - let public_keys: Vec<_> = keypairs - .iter() - .map(|k| k.public()) - .collect(); + fn public_key_implements_ord() { + use std::cmp::Ord; - let public_keys_b_tree_set: BTreeSet = BTreeSet::from_iter( - public_keys - .iter() - .map(|p| p.clone()) - ); + fn assert_implements_ord() {} - assert_eq!(public_keys_b_tree_set.len(), public_keys.len()); + assert_implements_ord::(); } } diff --git a/core/src/identity/ecdsa.rs b/core/src/identity/ecdsa.rs index c4ddde65937..70048844807 100644 --- a/core/src/identity/ecdsa.rs +++ b/core/src/identity/ecdsa.rs @@ -223,6 +223,7 @@ impl fmt::Debug for PublicKey { } } +#[allow(clippy::derive_hash_xor_eq)] impl hash::Hash for PublicKey { fn hash(&self, state: &mut H) { self.to_bytes().hash(state); @@ -232,6 +233,24 @@ impl hash::Hash for PublicKey { #[cfg(test)] mod tests { use super::*; + use crate::test::*; + use quickcheck::*; + + #[derive(Clone, Debug)] + struct SomePublicKey(PublicKey); + + impl Arbitrary for SomePublicKey { + fn arbitrary(g: &mut G) -> SomePublicKey { + loop { + let mut bytes = Vec::::arbitrary(g); + bytes.resize(33, 0); + let public_key = PublicKey::from_bytes(&bytes); + if let Ok(public_key) = public_key { + return SomePublicKey(public_key); + } + } + } + } #[test] fn sign_verify() { @@ -249,4 +268,13 @@ mod tests { let invalid_msg = "h3ll0 w0rld".as_bytes(); assert!(!pk.verify(invalid_msg, &sig)); } + + #[test] + fn ecdsa_public_key_eq_implies_hash() { + fn prop(SomePublicKey(pub1): SomePublicKey, SomePublicKey(pub2): SomePublicKey) -> bool { + pub1 != pub2 || hash(&pub1) == hash(&pub2) + } + QuickCheck::new() + .quickcheck(prop as fn(_, _) -> _); + } } diff --git a/core/src/identity/ed25519.rs b/core/src/identity/ed25519.rs index c1dd4db7a62..8e73ec598e2 100644 --- a/core/src/identity/ed25519.rs +++ b/core/src/identity/ed25519.rs @@ -130,6 +130,7 @@ impl fmt::Debug for PublicKey { // Remove (derive instead) when this PR is merged: // https://github.com/dalek-cryptography/ed25519-dalek/pull/176 +#[allow(clippy::derive_hash_xor_eq)] impl hash::Hash for PublicKey { fn hash(&self, state: &mut H) { self.0.as_bytes().hash(state); @@ -220,8 +221,25 @@ impl SecretKey { #[cfg(test)] mod tests { use super::*; + use crate::test::*; use quickcheck::*; + #[derive(Clone, Debug)] + struct SomePublicKey(PublicKey); + + impl Arbitrary for SomePublicKey { + fn arbitrary(g: &mut G) -> SomePublicKey { + loop { + let mut bytes = Vec::::arbitrary(g); + bytes.resize(32, 0); + let public_key = PublicKey::decode(&mut bytes); + if let Ok(public_key) = public_key { + return SomePublicKey(public_key); + } + } + } + } + fn eq_keypairs(kp1: &Keypair, kp2: &Keypair) -> bool { kp1.public() == kp2.public() && kp1.0.secret.as_bytes() == kp2.0.secret.as_bytes() } @@ -264,4 +282,13 @@ mod tests { let invalid_msg = "h3ll0 w0rld".as_bytes(); assert!(!pk.verify(invalid_msg, &sig)); } + + #[test] + fn ecdsa_public_key_eq_implies_hash() { + fn prop(SomePublicKey(pub1): SomePublicKey, SomePublicKey(pub2): SomePublicKey) -> bool { + pub1 != pub2 || hash(&pub1) == hash(&pub2) + } + QuickCheck::new() + .quickcheck(prop as fn(_, _) -> _); + } } diff --git a/core/src/identity/rsa.rs b/core/src/identity/rsa.rs index 40a7ea6f144..fc204e3a1f8 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 { @@ -305,23 +305,17 @@ impl DerDecodable<'_> for Asn1SubjectPublicKeyInfo { #[cfg(test)] mod tests { use super::*; + use crate::test::*; use quickcheck::*; use rand07::seq::SliceRandom; - 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 G) -> SomeKeypair { let mut key = [KEY1, KEY2, KEY3].choose(g).unwrap().to_vec(); @@ -329,6 +323,15 @@ mod tests { } } + #[derive(Clone, Debug)] + struct SomePublicKey(PublicKey); + + impl Arbitrary for SomePublicKey { + fn arbitrary(g: &mut G) -> SomePublicKey { + SomePublicKey(SomeKeypair::arbitrary(g).0.public()) + } + } + #[test] fn rsa_from_pkcs8() { assert!(Keypair::from_pkcs8(&mut KEY1.to_vec()).is_ok()); @@ -356,4 +359,13 @@ mod tests { .tests(10) .quickcheck(prop as fn(_, _) -> _); } + + #[test] + fn rsa_public_key_eq_implies_hash() { + fn prop(SomePublicKey(pub1): SomePublicKey, SomePublicKey(pub2): SomePublicKey) -> bool { + pub1 != pub2 || hash(&pub1) == hash(&pub2) + } + QuickCheck::new() + .quickcheck(prop as fn(_, _) -> _); + } } diff --git a/core/src/identity/secp256k1.rs b/core/src/identity/secp256k1.rs index ca6b4bbcd48..9cddd810fec 100644 --- a/core/src/identity/secp256k1.rs +++ b/core/src/identity/secp256k1.rs @@ -165,6 +165,7 @@ impl fmt::Debug for PublicKey { } } +#[allow(clippy::derive_hash_xor_eq)] impl hash::Hash for PublicKey { fn hash(&self, state: &mut H) { self.encode().hash(state); @@ -219,6 +220,35 @@ impl PublicKey { #[cfg(test)] mod tests { use super::*; + use crate::test::*; + use quickcheck::*; + + #[derive(Clone, Debug)] + struct SomeSecretKey(SecretKey); + + impl Arbitrary for SomeSecretKey { + fn arbitrary(g: &mut G) -> SomeSecretKey { + loop { + let mut bytes = Vec::::arbitrary(g); + bytes.resize(32, 0); + let secret_key = SecretKey::from_bytes(&mut bytes); + if let Ok(secret_key) = secret_key { + return SomeSecretKey(secret_key); + } + } + } + } + + #[derive(Clone, Debug)] + struct SomePublicKey(PublicKey); + + impl Arbitrary for SomePublicKey { + fn arbitrary(g: &mut G) -> SomePublicKey { + let secret_key = SomeSecretKey::arbitrary(g).0; + let keypair: Keypair = secret_key.into(); + SomePublicKey(keypair.public().clone()) + } + } #[test] fn secp256k1_secret_from_bytes() { @@ -229,4 +259,13 @@ mod tests { assert_eq!(sk1.0.serialize(), sk2.0.serialize()); assert_eq!(sk_bytes, [0; 32]); } + + #[test] + fn ecdsa_public_key_eq_implies_hash() { + fn prop(SomePublicKey(pub1): SomePublicKey, SomePublicKey(pub2): SomePublicKey) -> bool { + pub1 != pub2 || hash(&pub1) == hash(&pub2) + } + QuickCheck::new() + .quickcheck(prop as fn(_, _) -> _); + } } diff --git a/core/src/lib.rs b/core/src/lib.rs index ac55537eb0b..98bdb29d0a2 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -77,6 +77,9 @@ pub use translation::address_translation; pub use transport::Transport; pub use upgrade::{InboundUpgrade, OutboundUpgrade, ProtocolName, UpgradeError, UpgradeInfo}; +#[cfg(test)] +mod test; + use std::{future::Future, pin::Pin}; /// Implemented on objects that can run a `Future` in the background. diff --git a/core/src/test.rs b/core/src/test.rs new file mode 100644 index 00000000000..90839625a0a --- /dev/null +++ b/core/src/test.rs @@ -0,0 +1,8 @@ +use std::hash::{Hash, Hasher}; +use std::collections::hash_map::DefaultHasher; + +pub fn hash(t: &T) -> u64 { + let mut s = DefaultHasher::new(); + t.hash(&mut s); + s.finish() +} From 902b6840eb96794c13875fa38ae3ba033b140f83 Mon Sep 17 00:00:00 2001 From: futpib Date: Tue, 20 Sep 2022 19:24:10 +0400 Subject: [PATCH 6/9] Remove hash property tests, implement PartialEq manually where Hash is implemented manually. --- core/src/identity/ecdsa.rs | 37 ++++++-------------------- core/src/identity/ed25519.rs | 37 +++++--------------------- core/src/identity/rsa.rs | 10 -------- core/src/identity/secp256k1.rs | 47 +++++----------------------------- core/src/lib.rs | 3 --- core/src/test.rs | 8 ------ 6 files changed, 22 insertions(+), 120 deletions(-) delete mode 100644 core/src/test.rs diff --git a/core/src/identity/ecdsa.rs b/core/src/identity/ecdsa.rs index 70048844807..80c1dea80c5 100644 --- a/core/src/identity/ecdsa.rs +++ b/core/src/identity/ecdsa.rs @@ -22,6 +22,7 @@ use super::error::DecodingError; use core::fmt; +use core::cmp; use core::hash; use p256::{ ecdsa::{ @@ -118,7 +119,7 @@ impl fmt::Debug for SecretKey { } /// An ECDSA public key. -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Clone, Eq, PartialOrd, Ord)] pub struct PublicKey(VerifyingKey); impl PublicKey { @@ -223,7 +224,12 @@ impl fmt::Debug for PublicKey { } } -#[allow(clippy::derive_hash_xor_eq)] +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); @@ -233,24 +239,6 @@ impl hash::Hash for PublicKey { #[cfg(test)] mod tests { use super::*; - use crate::test::*; - use quickcheck::*; - - #[derive(Clone, Debug)] - struct SomePublicKey(PublicKey); - - impl Arbitrary for SomePublicKey { - fn arbitrary(g: &mut G) -> SomePublicKey { - loop { - let mut bytes = Vec::::arbitrary(g); - bytes.resize(33, 0); - let public_key = PublicKey::from_bytes(&bytes); - if let Ok(public_key) = public_key { - return SomePublicKey(public_key); - } - } - } - } #[test] fn sign_verify() { @@ -268,13 +256,4 @@ mod tests { let invalid_msg = "h3ll0 w0rld".as_bytes(); assert!(!pk.verify(invalid_msg, &sig)); } - - #[test] - fn ecdsa_public_key_eq_implies_hash() { - fn prop(SomePublicKey(pub1): SomePublicKey, SomePublicKey(pub2): SomePublicKey) -> bool { - pub1 != pub2 || hash(&pub1) == hash(&pub2) - } - QuickCheck::new() - .quickcheck(prop as fn(_, _) -> _); - } } diff --git a/core/src/identity/ed25519.rs b/core/src/identity/ed25519.rs index 8e73ec598e2..62c13708216 100644 --- a/core/src/identity/ed25519.rs +++ b/core/src/identity/ed25519.rs @@ -115,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 { @@ -128,9 +128,12 @@ impl fmt::Debug for PublicKey { } } -// Remove (derive instead) when this PR is merged: -// https://github.com/dalek-cryptography/ed25519-dalek/pull/176 -#[allow(clippy::derive_hash_xor_eq)] +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); @@ -221,25 +224,8 @@ impl SecretKey { #[cfg(test)] mod tests { use super::*; - use crate::test::*; use quickcheck::*; - #[derive(Clone, Debug)] - struct SomePublicKey(PublicKey); - - impl Arbitrary for SomePublicKey { - fn arbitrary(g: &mut G) -> SomePublicKey { - loop { - let mut bytes = Vec::::arbitrary(g); - bytes.resize(32, 0); - let public_key = PublicKey::decode(&mut bytes); - if let Ok(public_key) = public_key { - return SomePublicKey(public_key); - } - } - } - } - fn eq_keypairs(kp1: &Keypair, kp2: &Keypair) -> bool { kp1.public() == kp2.public() && kp1.0.secret.as_bytes() == kp2.0.secret.as_bytes() } @@ -282,13 +268,4 @@ mod tests { let invalid_msg = "h3ll0 w0rld".as_bytes(); assert!(!pk.verify(invalid_msg, &sig)); } - - #[test] - fn ecdsa_public_key_eq_implies_hash() { - fn prop(SomePublicKey(pub1): SomePublicKey, SomePublicKey(pub2): SomePublicKey) -> bool { - pub1 != pub2 || hash(&pub1) == hash(&pub2) - } - QuickCheck::new() - .quickcheck(prop as fn(_, _) -> _); - } } diff --git a/core/src/identity/rsa.rs b/core/src/identity/rsa.rs index fc204e3a1f8..7bfef330402 100644 --- a/core/src/identity/rsa.rs +++ b/core/src/identity/rsa.rs @@ -305,7 +305,6 @@ impl DerDecodable<'_> for Asn1SubjectPublicKeyInfo { #[cfg(test)] mod tests { use super::*; - use crate::test::*; use quickcheck::*; use rand07::seq::SliceRandom; @@ -359,13 +358,4 @@ mod tests { .tests(10) .quickcheck(prop as fn(_, _) -> _); } - - #[test] - fn rsa_public_key_eq_implies_hash() { - fn prop(SomePublicKey(pub1): SomePublicKey, SomePublicKey(pub2): SomePublicKey) -> bool { - pub1 != pub2 || hash(&pub1) == hash(&pub2) - } - QuickCheck::new() - .quickcheck(prop as fn(_, _) -> _); - } } diff --git a/core/src/identity/secp256k1.rs b/core/src/identity/secp256k1.rs index 9cddd810fec..779f44dcb10 100644 --- a/core/src/identity/secp256k1.rs +++ b/core/src/identity/secp256k1.rs @@ -152,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 { @@ -165,7 +165,12 @@ impl fmt::Debug for PublicKey { } } -#[allow(clippy::derive_hash_xor_eq)] +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); @@ -220,35 +225,6 @@ impl PublicKey { #[cfg(test)] mod tests { use super::*; - use crate::test::*; - use quickcheck::*; - - #[derive(Clone, Debug)] - struct SomeSecretKey(SecretKey); - - impl Arbitrary for SomeSecretKey { - fn arbitrary(g: &mut G) -> SomeSecretKey { - loop { - let mut bytes = Vec::::arbitrary(g); - bytes.resize(32, 0); - let secret_key = SecretKey::from_bytes(&mut bytes); - if let Ok(secret_key) = secret_key { - return SomeSecretKey(secret_key); - } - } - } - } - - #[derive(Clone, Debug)] - struct SomePublicKey(PublicKey); - - impl Arbitrary for SomePublicKey { - fn arbitrary(g: &mut G) -> SomePublicKey { - let secret_key = SomeSecretKey::arbitrary(g).0; - let keypair: Keypair = secret_key.into(); - SomePublicKey(keypair.public().clone()) - } - } #[test] fn secp256k1_secret_from_bytes() { @@ -259,13 +235,4 @@ mod tests { assert_eq!(sk1.0.serialize(), sk2.0.serialize()); assert_eq!(sk_bytes, [0; 32]); } - - #[test] - fn ecdsa_public_key_eq_implies_hash() { - fn prop(SomePublicKey(pub1): SomePublicKey, SomePublicKey(pub2): SomePublicKey) -> bool { - pub1 != pub2 || hash(&pub1) == hash(&pub2) - } - QuickCheck::new() - .quickcheck(prop as fn(_, _) -> _); - } } diff --git a/core/src/lib.rs b/core/src/lib.rs index 98bdb29d0a2..ac55537eb0b 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -77,9 +77,6 @@ pub use translation::address_translation; pub use transport::Transport; pub use upgrade::{InboundUpgrade, OutboundUpgrade, ProtocolName, UpgradeError, UpgradeInfo}; -#[cfg(test)] -mod test; - use std::{future::Future, pin::Pin}; /// Implemented on objects that can run a `Future` in the background. diff --git a/core/src/test.rs b/core/src/test.rs deleted file mode 100644 index 90839625a0a..00000000000 --- a/core/src/test.rs +++ /dev/null @@ -1,8 +0,0 @@ -use std::hash::{Hash, Hasher}; -use std::collections::hash_map::DefaultHasher; - -pub fn hash(t: &T) -> u64 { - let mut s = DefaultHasher::new(); - t.hash(&mut s); - s.finish() -} From bcedf1221d30d670931c8a894cbbee6d01c82e47 Mon Sep 17 00:00:00 2001 From: futpib Date: Wed, 21 Sep 2022 10:41:43 +0000 Subject: [PATCH 7/9] Update core/src/identity/rsa.rs Co-authored-by: Thomas Eizinger --- core/src/identity/rsa.rs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/core/src/identity/rsa.rs b/core/src/identity/rsa.rs index 7bfef330402..5d43f06d720 100644 --- a/core/src/identity/rsa.rs +++ b/core/src/identity/rsa.rs @@ -322,15 +322,6 @@ mod tests { } } - #[derive(Clone, Debug)] - struct SomePublicKey(PublicKey); - - impl Arbitrary for SomePublicKey { - fn arbitrary(g: &mut G) -> SomePublicKey { - SomePublicKey(SomeKeypair::arbitrary(g).0.public()) - } - } - #[test] fn rsa_from_pkcs8() { assert!(Keypair::from_pkcs8(&mut KEY1.to_vec()).is_ok()); From 8c0099720f4bb492ce52fbfbb053fb335cd94e85 Mon Sep 17 00:00:00 2001 From: futpib Date: Wed, 21 Sep 2022 14:42:35 +0400 Subject: [PATCH 8/9] cargo fmt --- core/src/identity/ecdsa.rs | 2 +- core/src/identity/ed25519.rs | 2 +- core/src/identity/secp256k1.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/identity/ecdsa.rs b/core/src/identity/ecdsa.rs index 80c1dea80c5..88411b23655 100644 --- a/core/src/identity/ecdsa.rs +++ b/core/src/identity/ecdsa.rs @@ -21,8 +21,8 @@ //! ECDSA keys with secp256r1 curve support. use super::error::DecodingError; -use core::fmt; use core::cmp; +use core::fmt; use core::hash; use p256::{ ecdsa::{ diff --git a/core/src/identity/ed25519.rs b/core/src/identity/ed25519.rs index 62c13708216..eef934d4d91 100644 --- a/core/src/identity/ed25519.rs +++ b/core/src/identity/ed25519.rs @@ -21,9 +21,9 @@ //! Ed25519 keys. use super::error::DecodingError; +use core::cmp; use core::fmt; use core::hash; -use core::cmp; use ed25519_dalek::{self as ed25519, Signer as _, Verifier as _}; use rand::RngCore; use std::convert::TryFrom; diff --git a/core/src/identity/secp256k1.rs b/core/src/identity/secp256k1.rs index 779f44dcb10..bfecc33ed2f 100644 --- a/core/src/identity/secp256k1.rs +++ b/core/src/identity/secp256k1.rs @@ -22,9 +22,9 @@ use super::error::{DecodingError, SigningError}; use asn1_der::typed::{DerDecodable, Sequence}; +use core::cmp; use core::fmt; use core::hash; -use core::cmp; use libsecp256k1::{Message, Signature}; use sha2::{Digest as ShaDigestTrait, Sha256}; use zeroize::Zeroize; From 51421e61e3214cbb87bb50dda281fd9890dcca34 Mon Sep 17 00:00:00 2001 From: futpib Date: Wed, 21 Sep 2022 23:30:39 +0400 Subject: [PATCH 9/9] Bump libp2p-core to 0.36.1 --- CHANGELOG.md | 2 ++ Cargo.toml | 2 +- core/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1eca5375c41..4bbd5b6036f 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 to [`libp2p-noise` `v0.39.1`](transports/noise/CHANGELOG.md#0391). diff --git a/Cargo.toml b/Cargo.toml index a14405eff6b..3fad1ee96be 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.0", path = "protocols/floodsub", optional = true } libp2p-identify = { version = "0.39.0", path = "protocols/identify", optional = true } diff --git a/core/Cargo.toml b/core/Cargo.toml index 0505ccd970d..8c1e20b9527 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"