From d04120bacf802a7e1127f4955b7391b0a4353128 Mon Sep 17 00:00:00 2001 From: Nick Date: Thu, 29 Jun 2023 19:21:14 +0300 Subject: [PATCH] feat: update libp2p identity (#109) --- Cargo.lock | 121 +++++++++++--------------------------- Cargo.toml | 2 +- keypair/Cargo.toml | 2 +- keypair/src/key_pair.rs | 83 ++++++++++++++++---------- keypair/src/public_key.rs | 69 ++++++++++++++-------- keypair/src/secp256k1.rs | 17 ++++++ 6 files changed, 148 insertions(+), 146 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7aed6a3..069eb28 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -153,12 +153,6 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "base-x" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" - [[package]] name = "base64" version = "0.13.1" @@ -239,6 +233,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" +[[package]] +name = "bs58" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" +dependencies = [ + "tinyvec", +] + [[package]] name = "built" version = "0.5.2" @@ -674,32 +677,6 @@ dependencies = [ "syn 2.0.18", ] -[[package]] -name = "data-encoding" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" - -[[package]] -name = "data-encoding-macro" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c904b33cc60130e1aeea4956ab803d08a3f4a0ca82d64ed757afac3891f2bb99" -dependencies = [ - "data-encoding", - "data-encoding-macro-internal", -] - -[[package]] -name = "data-encoding-macro-internal" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fdf3fce3ce863539ec1d7fd1b6dcc3c645663376b43ed376bbf887733e4f772" -dependencies = [ - "data-encoding", - "syn 1.0.109", -] - [[package]] name = "derivative" version = "2.2.0" @@ -947,7 +924,7 @@ name = "fluence-keypair" version = "0.10.1" dependencies = [ "asn1_der 0.6.3", - "bs58", + "bs58 0.5.0", "ed25519-dalek", "eyre", "lazy_static", @@ -959,7 +936,7 @@ dependencies = [ "ring", "serde", "serde_bytes", - "sha2 0.10.6", + "sha2 0.10.7", "thiserror", "zeroize", ] @@ -1373,21 +1350,20 @@ checksum = "fc86cde3ff845662b8f4ef6cb50ea0e20c524eb3d29ae048287e06a1b3fa6a81" [[package]] name = "libp2p-identity" -version = "0.1.2" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e2d584751cecb2aabaa56106be6be91338a60a0f4e420cf2af639204f596fc1" +checksum = "d2874d9c6575f1d7a151022af5c42bb0ffdcdfbafe0a6fd039de870b384835a2" dependencies = [ "asn1_der 0.7.6", - "bs58", + "bs58 0.5.0", "ed25519-dalek", "libsecp256k1", "log", - "multiaddr", - "multihash 0.17.0", + "multihash 0.19.0", "quick-protobuf", "rand 0.8.5", "ring", - "sha2 0.10.6", + "sha2 0.10.7", "thiserror", "zeroize", ] @@ -1852,47 +1828,6 @@ dependencies = [ "adler", ] -[[package]] -name = "multiaddr" -version = "0.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b36f567c7099511fa8612bbbb52dda2419ce0bdbacf31714e3a5ffdb766d3bd" -dependencies = [ - "arrayref", - "byteorder", - "data-encoding", - "log", - "multibase", - "multihash 0.17.0", - "percent-encoding", - "serde", - "static_assertions", - "unsigned-varint", - "url", -] - -[[package]] -name = "multibase" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b3539ec3c1f04ac9748a260728e855f261b4977f5c3406612c884564f329404" -dependencies = [ - "base-x", - "data-encoding", - "data-encoding-macro", -] - -[[package]] -name = "multihash" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "835d6ff01d610179fbce3de1694d007e500bf33a7f29689838941d6bf783ae40" -dependencies = [ - "core2", - "multihash-derive", - "unsigned-varint", -] - [[package]] name = "multihash" version = "0.18.1" @@ -1905,11 +1840,21 @@ dependencies = [ "core2", "digest 0.10.7", "multihash-derive", - "sha2 0.10.6", + "sha2 0.10.7", "sha3", "unsigned-varint", ] +[[package]] +name = "multihash" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd59dcc2bbe70baabeac52cd22ae52c55eefe6c38ff11a9439f16a350a939f2" +dependencies = [ + "core2", + "unsigned-varint", +] + [[package]] name = "multihash-derive" version = "0.8.1" @@ -2505,9 +2450,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" dependencies = [ "cfg-if", "cpufeatures", @@ -2765,7 +2710,7 @@ dependencies = [ name = "trust-graph" version = "0.4.5" dependencies = [ - "bs58", + "bs58 0.4.0", "derivative", "failure", "fluence-keypair", @@ -2774,7 +2719,7 @@ dependencies = [ "rand 0.8.5", "ref-cast", "serde", - "sha2 0.10.6", + "sha2 0.10.7", "thiserror", ] @@ -2795,7 +2740,7 @@ version = "0.4.5" dependencies = [ "anyhow", "bincode", - "bs58", + "bs58 0.4.0", "fluence-keypair", "libp2p-identity", "log", @@ -3158,7 +3103,7 @@ dependencies = [ "log", "rustix 0.36.14", "serde", - "sha2 0.10.6", + "sha2 0.10.7", "toml", "windows-sys 0.42.0", "zstd", diff --git a/Cargo.toml b/Cargo.toml index 0b690eb..ed7d8a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,4 +7,4 @@ members = [ ] [workspace.dependencies] -libp2p-identity = { version = "0.1.2", default-features = false } +libp2p-identity = { version = "0.2.1", default-features = false } diff --git a/keypair/Cargo.toml b/keypair/Cargo.toml index 7b14dc3..2f2d1b7 100644 --- a/keypair/Cargo.toml +++ b/keypair/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/fluencelabs/trust-graph" [dependencies] serde = { version = "1.0.118", features = ["derive"] } -bs58 = "0.4.0" +bs58 = "0.5.0" ed25519-dalek = { version = "1.0.1", features = ["serde", "std"] } rand = "0.8.5" thiserror = "1.0.23" diff --git a/keypair/src/key_pair.rs b/keypair/src/key_pair.rs index 2238e54..3c14da7 100644 --- a/keypair/src/key_pair.rs +++ b/keypair/src/key_pair.rs @@ -26,7 +26,7 @@ use crate::public_key::PublicKey; use crate::rsa; use crate::secp256k1; use crate::signature::Signature; -use libp2p_identity::PeerId; +use libp2p_identity::{KeyType, Keypair, PeerId}; use std::convert::TryFrom; use std::str::FromStr; @@ -47,7 +47,6 @@ use std::str::FromStr; /// let keypair = Keypair::rsa_from_pkcs8(&mut bytes); /// ``` /// - #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum KeyFormat { Ed25519, @@ -106,6 +105,7 @@ impl From for String { } } } + #[derive(Clone)] pub enum KeyPair { /// An Ed25519 keypair. @@ -250,42 +250,61 @@ impl KeyPair { impl From for KeyPair { fn from(key: libp2p_identity::Keypair) -> Self { - use libp2p_identity::Keypair::*; - - #[allow(deprecated)] //TODO: fix it later - match key { - Ed25519(kp) => KeyPair::Ed25519(ed25519::Keypair::decode(&mut kp.encode()).unwrap()), - #[cfg(not(target_arch = "wasm32"))] - // safety: these Keypair structures are identical - Rsa(kp) => KeyPair::Rsa(unsafe { - std::mem::transmute::(kp) - }), - Secp256k1(kp) => KeyPair::Secp256k1(secp256k1::Keypair::from( - secp256k1::SecretKey::from_bytes(kp.secret().to_bytes()).unwrap(), - )), + fn convert_keypair(key: Keypair) -> eyre::Result { + match key.key_type() { + KeyType::Ed25519 => { + let kp = key.try_into_ed25519()?; + let raw_kp = ed25519::Keypair::decode(&mut kp.to_bytes())?; + Ok(KeyPair::Ed25519(raw_kp)) + } + #[cfg(not(target_arch = "wasm32"))] + KeyType::RSA => { + let kp = key.try_into_rsa()?; + let raw_kp = unsafe { + std::mem::transmute::(kp) + }; + Ok(KeyPair::Rsa(raw_kp)) + } + KeyType::Secp256k1 => { + let kp = key.try_into_secp256k1()?; + let raw_kp = secp256k1::SecretKey::from_bytes(kp.secret().to_bytes())?; + Ok(KeyPair::Secp256k1(secp256k1::Keypair::from(raw_kp))) + } + _ => unreachable!(), + } } + + convert_keypair(key).expect("Could not convert keypair") } } impl From for libp2p_identity::Keypair { fn from(key: KeyPair) -> Self { - use libp2p_identity::Keypair; - use KeyPair::*; - - #[allow(deprecated)] //TODO: fix it later - match key { - Ed25519(kp) => Keypair::Ed25519( - libp2p_identity::ed25519::Keypair::decode(kp.encode().to_vec().as_mut_slice()) - .unwrap(), - ), - #[cfg(not(target_arch = "wasm32"))] - // safety: these Keypair structures are identical - Rsa(kp) => Keypair::Rsa(unsafe { - std::mem::transmute::(kp) - }), - Secp256k1(kp) => Keypair::Secp256k1(libp2p_identity::secp256k1::Keypair::from( - libp2p_identity::secp256k1::SecretKey::from_bytes(kp.secret().to_bytes()).unwrap(), - )), + fn convert_keypair(key: KeyPair) -> eyre::Result { + match key { + KeyPair::Ed25519(kp) => { + let kp = Keypair::ed25519_from_bytes(kp.encode().to_vec().as_mut_slice())?; + Ok(kp) + } + #[cfg(not(target_arch = "wasm32"))] + // safety: these Keypair structures are identical + KeyPair::Rsa(kp) => { + let kp = unsafe { + std::mem::transmute::(kp) + }; + let kp = Keypair::from(kp); + Ok(kp) + } + KeyPair::Secp256k1(kp) => { + let sk = libp2p_identity::secp256k1::SecretKey::try_from_bytes( + kp.secret().to_bytes(), + )?; + let kp = libp2p_identity::secp256k1::Keypair::from(sk); + let kp = Keypair::from(kp); + Ok(kp) + } + } } + convert_keypair(key).expect("Could not convert key pair") } } diff --git a/keypair/src/public_key.rs b/keypair/src/public_key.rs index 1dabd93..483b06b 100644 --- a/keypair/src/public_key.rs +++ b/keypair/src/public_key.rs @@ -21,7 +21,7 @@ use crate::secp256k1; use crate::signature::Signature; use crate::key_pair::KeyFormat; -use libp2p_identity::PeerId; +use libp2p_identity::{KeyType, PeerId}; use serde::{Deserialize, Serialize}; use std::convert::TryFrom; @@ -126,37 +126,58 @@ impl PublicKey { impl From for PublicKey { fn from(key: libp2p_identity::PublicKey) -> Self { - use libp2p_identity::PublicKey::*; - - #[allow(deprecated)] //TODO: fix it later - match key { - Ed25519(key) => { - PublicKey::Ed25519(ed25519::PublicKey::decode(&key.encode()[..]).unwrap()) - } - #[cfg(not(target_arch = "wasm32"))] - Rsa(key) => PublicKey::Rsa(rsa::PublicKey::from_pkcs1(key.encode_pkcs1()).unwrap()), - Secp256k1(key) => { - PublicKey::Secp256k1(secp256k1::PublicKey::decode(&key.encode()[..]).unwrap()) + fn convert_key(key: libp2p_identity::PublicKey) -> eyre::Result { + match key.key_type() { + KeyType::Ed25519 => { + let pk = key.try_into_ed25519()?; + let raw_pk = ed25519::PublicKey::decode(&pk.to_bytes())?; + Ok(PublicKey::Ed25519(raw_pk)) + } + #[cfg(not(target_arch = "wasm32"))] + KeyType::RSA => { + let pk = key.try_into_rsa()?; + let raw_pk = rsa::PublicKey::from_pkcs1(pk.encode_pkcs1())?; + Ok(PublicKey::Rsa(raw_pk)) + } + KeyType::Secp256k1 => { + let pk = key.try_into_secp256k1()?; + let raw_pk = secp256k1::PublicKey::decode(&pk.to_bytes())?; + Ok(PublicKey::Secp256k1(raw_pk)) + } + _ => unreachable!(), } } + + convert_key(key).expect("Could not convert public key") } } impl From for libp2p_identity::PublicKey { fn from(key: PublicKey) -> Self { - #[allow(deprecated)] //TODO: fix it later - match key { - PublicKey::Ed25519(key) => libp2p_identity::PublicKey::Ed25519( - libp2p_identity::ed25519::PublicKey::decode(&key.encode()[..]).unwrap(), - ), - #[cfg(not(target_arch = "wasm32"))] - PublicKey::Rsa(key) => libp2p_identity::PublicKey::Rsa( - libp2p_identity::rsa::PublicKey::decode_x509(&key.encode_x509()).unwrap(), - ), - PublicKey::Secp256k1(key) => libp2p_identity::PublicKey::Secp256k1( - libp2p_identity::secp256k1::PublicKey::decode(&key.encode()[..]).unwrap(), - ), + fn convert_key(key: PublicKey) -> eyre::Result { + match key { + PublicKey::Ed25519(key) => { + let raw_pk = + libp2p_identity::ed25519::PublicKey::try_from_bytes(&key.encode())?; + let pk = libp2p_identity::PublicKey::from(raw_pk); + Ok(pk) + } + #[cfg(not(target_arch = "wasm32"))] + PublicKey::Rsa(key) => { + let raw_pk = + libp2p_identity::rsa::PublicKey::try_decode_x509(&key.encode_x509())?; + let pk = libp2p_identity::PublicKey::from(raw_pk); + Ok(pk) + } + PublicKey::Secp256k1(key) => { + let raw_pk = + libp2p_identity::secp256k1::PublicKey::try_from_bytes(&key.encode())?; + let pk = libp2p_identity::PublicKey::from(raw_pk); + Ok(pk) + } + } } + convert_key(key).expect("Could not convert key") } } diff --git a/keypair/src/secp256k1.rs b/keypair/src/secp256k1.rs index e72c431..64c4a85 100644 --- a/keypair/src/secp256k1.rs +++ b/keypair/src/secp256k1.rs @@ -229,6 +229,12 @@ pub struct Signature(pub Vec); #[cfg(test)] mod tests { use super::*; + use crate::{key_pair, KeyFormat}; + use quickcheck::QuickCheck; + + fn eq_keypairs(kp1: key_pair::KeyPair, kp2: key_pair::KeyPair) -> bool { + kp1.public() == kp2.public() && kp1.secret().unwrap() == kp2.secret().unwrap() + } #[test] fn secp256k1_secret_from_bytes() { @@ -239,4 +245,15 @@ mod tests { assert_eq!(sk1.0.serialize(), sk2.0.serialize()); assert_eq!(sk_bytes, [0; 32]); } + + #[test] + fn secp256k1_keypair_encode_decode() { + fn prop() -> bool { + let kp1 = key_pair::KeyPair::generate(KeyFormat::Secp256k1); + let kp1_enc = libp2p_identity::Keypair::from(kp1.clone()); + let kp2 = key_pair::KeyPair::from(kp1_enc); + eq_keypairs(kp1, kp2) + } + QuickCheck::new().tests(10).quickcheck(prop as fn() -> _); + } }