From 29be808ee9054871b2b476190325c4bc261270bd Mon Sep 17 00:00:00 2001 From: Shanin Roman Date: Fri, 3 Mar 2023 13:30:02 +0300 Subject: [PATCH] [fix] #2123: Return `PublicKey` de/serialization from multihash Signed-off-by: Shanin Roman --- Cargo.lock | 1 + config/iroha_test_config.json | 32 ++---- configs/client_cli/config.json | 5 +- configs/peer/genesis.json | 15 +-- core/src/sumeragi/main_loop.rs | 1 - crypto/Cargo.toml | 1 + crypto/src/lib.rs | 189 +++++++++------------------------ 7 files changed, 66 insertions(+), 178 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f0709941d58..e57dcd6fa63 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2051,6 +2051,7 @@ dependencies = [ "parity-scale-codec", "serde", "serde_json", + "serde_with", "ursa", ] diff --git a/config/iroha_test_config.json b/config/iroha_test_config.json index d84472afe69..055995bbe67 100644 --- a/config/iroha_test_config.json +++ b/config/iroha_test_config.json @@ -1,8 +1,5 @@ { - "PUBLIC_KEY": { - "digest_function": "ed25519", - "payload": "1c61faf8fe94e253b93114240394f79a607b7fa55f9e5a41ebec74b88055768b" - }, + "PUBLIC_KEY": "ed01201c61faf8fe94e253b93114240394f79a607b7fa55f9e5a41ebec74b88055768b", "PRIVATE_KEY": { "digest_function": "ed25519", "payload": "282ed9f3cf92811c3818dbc4ae594ed59dc1a2f78e4241e31924e101d6b1fb831c61faf8fe94e253b93114240394f79a607b7fa55f9e5a41ebec74b88055768b" @@ -20,31 +17,19 @@ "TRUSTED_PEERS": [ { "address": "127.0.0.1:1337", - "public_key": { - "digest_function": "ed25519", - "payload": "1c61faf8fe94e253b93114240394f79a607b7fa55f9e5a41ebec74b88055768b" - } + "public_key": "ed01201c61faf8fe94e253b93114240394f79a607b7fa55f9e5a41ebec74b88055768b" }, { "address": "127.0.0.1:1338", - "public_key": { - "digest_function": "secp256k1", - "payload": "cc25624d62896d3a0bfd8940f928dc2abf27cc57cefeb442aa96d9081aae58a1" - } + "public_key": "ed0120cc25624d62896d3a0bfd8940f928dc2abf27cc57cefeb442aa96d9081aae58a1" }, { "address": "127.0.0.1:1339", - "public_key": { - "digest_function": "bls_normal", - "payload": "faca9e8aa83225cb4d16d67f27dd4f93fc30ffa11adc1f5c88fd5495ecc91020" - } + "public_key": "ed0120faca9e8aa83225cb4d16d67f27dd4f93fc30ffa11adc1f5c88fd5495ecc91020" }, { "address": "127.0.0.1:1340", - "public_key": { - "digest_function": "bls_small", - "payload": "8e351a70b6a603ed285d666b8d689b680865913ba03ce29fb7d13a166c4e7f1f" - } + "public_key": "ed01208e351a70b6a603ed285d666b8d689b680865913ba03ce29fb7d13a166c4e7f1f" } ], "COMMIT_TIME_LIMIT_MS": 2000, @@ -85,10 +70,7 @@ "TERMINAL_COLORS": true }, "GENESIS": { - "ACCOUNT_PUBLIC_KEY": { - "digest_function": "ed25519", - "payload": "4cffd0ee429b1bdd36b3910ec570852b8bb63f18750341772fb46bc856c5caaf" - }, + "ACCOUNT_PUBLIC_KEY": "ed01204cffd0ee429b1bdd36b3910ec570852b8bb63f18750341772fb46bc856c5caaf", "ACCOUNT_PRIVATE_KEY": { "digest_function": "ed25519", "payload": "d748e18ce60cb30dea3e73c9019b7af45a8d465e3d71bcc9a5ef99a008205e534cffd0ee429b1bdd36b3910ec570852b8bb63f18750341772fb46bc856c5caaf" @@ -133,4 +115,4 @@ "MAX_RETRY_DELAY_EXPONENT": 4, "FILE": null } -} \ No newline at end of file +} diff --git a/configs/client_cli/config.json b/configs/client_cli/config.json index 37e819b4059..426f229af38 100644 --- a/configs/client_cli/config.json +++ b/configs/client_cli/config.json @@ -1,8 +1,5 @@ { - "PUBLIC_KEY": { - "digest_function": "ed25519", - "payload": "7233bfc89dcbd68c19fde6ce6158225298ec1131b6a130d1aeb454c1ab5183c0" - }, + "PUBLIC_KEY": "ed01207233bfc89dcbd68c19fde6ce6158225298ec1131b6a130d1aeb454c1ab5183c0", "PRIVATE_KEY": { "digest_function": "ed25519", "payload": "9ac47abf59b356e0bd7dcbbbb4dec080e302156a48ca907e47cb6aea1d32719e7233bfc89dcbd68c19fde6ce6158225298ec1131b6a130d1aeb454c1ab5183c0" diff --git a/configs/peer/genesis.json b/configs/peer/genesis.json index 2b0024643fa..7c73f0d86d1 100644 --- a/configs/peer/genesis.json +++ b/configs/peer/genesis.json @@ -20,10 +20,7 @@ "NewAccount": { "id": "alice@wonderland", "signatories": [ - { - "digest_function": "ed25519", - "payload": "7233bfc89dcbd68c19fde6ce6158225298ec1131b6a130d1aeb454c1ab5183c0" - } + "ed01207233bfc89dcbd68c19fde6ce6158225298ec1131b6a130d1aeb454c1ab5183c0" ], "metadata": { "key": { @@ -38,10 +35,7 @@ "NewAccount": { "id": "bob@wonderland", "signatories": [ - { - "digest_function": "ed25519", - "payload": "7233bfc89dcbd68c19fde6ce6158225298ec1131b6a130d1aeb454c1ab5183c0" - } + "ed01207233bfc89dcbd68c19fde6ce6158225298ec1131b6a130d1aeb454c1ab5183c0" ], "metadata": { "key": { @@ -75,10 +69,7 @@ "NewAccount": { "id": "carpenter@garden_of_live_flowers", "signatories": [ - { - "digest_function": "ed25519", - "payload": "7233bfc89dcbd68c19fde6ce6158225298ec1131b6a130d1aeb454c1ab5183c0" - } + "ed01207233bfc89dcbd68c19fde6ce6158225298ec1131b6a130d1aeb454c1ab5183c0" ], "metadata": {} } diff --git a/core/src/sumeragi/main_loop.rs b/core/src/sumeragi/main_loop.rs index 839fb45ba5a..82dd4933375 100644 --- a/core/src/sumeragi/main_loop.rs +++ b/core/src/sumeragi/main_loop.rs @@ -1159,4 +1159,3 @@ fn early_return( Err(TryRecvError::Empty) => Ok(()), } } - diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 403a75bf1b8..1ccac81e157 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -27,6 +27,7 @@ iroha_schema = { path = "../schema" } derive_more = { version = "0.99.17", default-features = false, features = ["deref", "deref_mut", "display"] } parity-scale-codec = { version = "3.2.1", default-features = false, features = ["derive", "full"] } serde = { version = "1.0.151", default-features = false, features = ["derive"] } +serde_with = {version = "2.1.0", default-features = false, features = ["macros"]} hex = { version = "0.4.3", default-features = false, features = ["alloc", "serde"] } openssl-sys = { version = "0.9.80", features = ["vendored"], optional = true } ursa = { version = "0.3.7", optional = true } diff --git a/crypto/src/lib.rs b/crypto/src/lib.rs index 6f0f7b756bc..3cdc42acfc4 100755 --- a/crypto/src/lib.rs +++ b/crypto/src/lib.rs @@ -30,8 +30,9 @@ use iroha_ffi::FfiType; use iroha_schema::IntoSchema; pub use merkle::MerkleTree; use multihash::{DigestFunction as MultihashDigestFunction, Multihash}; -use parity_scale_codec::{Decode, Encode, Error as ScaleError}; +use parity_scale_codec::{Decode, Encode}; use serde::{Deserialize, Serialize}; +use serde_with::{DeserializeFromStr, SerializeDisplay}; pub use signature::*; #[cfg(feature = "std")] pub use ursa; @@ -71,101 +72,25 @@ impl std::error::Error for NoSuchAlgorithm {} ffi::ffi_item! { /// Algorithm for hashing - #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, FfiType, IntoSchema)] + #[derive(Debug, Display, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, FfiType, IntoSchema, SerializeDisplay, DeserializeFromStr, Encode, Decode, Default)] #[repr(u8)] pub enum Algorithm { - //#[codec(index = 101)] /// Ed25519 + #[display(fmt = "{ED_25519}")] + #[default] Ed25519, /// Secp256k1 + #[display(fmt = "{SECP_256_K1}")] Secp256k1, /// BlsNormal + #[display(fmt = "{BLS_NORMAL}")] BlsNormal, /// BlsSmall + #[display(fmt = "{BLS_SMALL}")] BlsSmall, } } -impl fmt::Display for Algorithm { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - let str = match self { - Algorithm::Ed25519 => ED_25519, - Algorithm::Secp256k1 => SECP_256_K1, - Algorithm::BlsNormal => BLS_NORMAL, - Algorithm::BlsSmall => BLS_SMALL, - }; - - write!(fmt, "{str}") - } -} - -impl From for String { - fn from(a: Algorithm) -> Self { - format!("{a}") - } -} - -impl Encode for Algorithm { - fn encode(&self) -> Vec { - let mut ovec: Vec = vec![]; - - let ostr = self.to_string(); - - let ol = ostr.len().try_into().expect("Failed try"); //Just 256 symbols now - - ovec.push(ol); - ovec.append(&mut self.to_string().as_bytes().to_vec()); - - ovec - } -} - -impl Decode for Algorithm { - fn decode(input: &mut I) -> Result { - let mut buf: Vec = vec![0]; //len - - input.read(&mut buf[..])?; - - let lin = buf[0]; - let mut buf: Vec = vec![0; lin as usize]; //data - - input.read(&mut buf[..])?; - - Algorithm::from_str(&String::from_utf8(buf).unwrap()) - .map_err(|_: _| ScaleError::from("Algorithm not supported")) - } -} - -impl serde::Serialize for Algorithm { - fn serialize(&self, serializer: E) -> Result - where - E: serde::Serializer, - { - serializer.serialize_str(&format!("{self}")) - } -} - -impl<'de> serde::Deserialize<'de> for Algorithm { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - use serde::de::Error as _; - - let ast = String::deserialize(deserializer)?; - - //let public_key_str = >::deserialize(deserializer)?; - - Algorithm::from_str(&ast).map_err(D::Error::custom) - } -} - -impl Default for Algorithm { - fn default() -> Self { - Algorithm::Ed25519 - } -} - impl FromStr for Algorithm { type Err = NoSuchAlgorithm; @@ -244,7 +169,7 @@ impl KeyGenConfiguration { ffi::ffi_item! { /// Pair of Public and Private keys. - #[derive(Debug, Clone, PartialEq, Eq, Getters, Serialize, Deserialize, FfiType)] + #[derive(Debug, Clone, PartialEq, Eq, Getters, Serialize, FfiType)] #[getset(get = "pub")] pub struct KeyPair { /// Public Key. @@ -267,7 +192,7 @@ pub enum Error { #[display(fmt = "Signing failed. {_0}")] Signing(String), /// Returned when an error occurs during key generation - #[display(fmt = "Key generation failed. {_0} sss")] + #[display(fmt = "Key generation failed. {_0}")] KeyGen(String), /// Returned when an error occurs during digest generation #[display(fmt = "Digest generation failed. {_0}")] @@ -355,7 +280,7 @@ impl KeyPair { SignatureOf::new(key_pair.clone(), &dummy_payload)? .verify(&dummy_payload) - .map_err(|_err| Error::KeyGen(String::from("Key pair mismatch sss")))?; + .map_err(|_err| Error::KeyGen(String::from("Key pair mismatch")))?; Ok(key_pair) } @@ -403,6 +328,25 @@ impl KeyPair { } } +#[cfg(feature = "std")] +impl<'de> Deserialize<'de> for KeyPair { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + use serde::de::Error as _; + + #[derive(Deserialize)] + struct KeyPair { + public_key: PublicKey, + private_key: PrivateKey, + } + + let key_pair = KeyPair::deserialize(deserializer)?; + Self::new(key_pair.public_key, key_pair.private_key).map_err(D::Error::custom) + } +} + impl From for (PublicKey, PrivateKey) { fn from(key_pair: KeyPair) -> Self { (key_pair.public_key, key_pair.private_key) @@ -426,7 +370,7 @@ impl std::error::Error for KeyParseError {} ffi::ffi_item! { /// Public Key used in signatures. - #[derive(DebugCustom, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Encode, FfiType, IntoSchema, Serialize, Deserialize, Decode)] + #[derive(DebugCustom, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Encode, FfiType, IntoSchema, SerializeDisplay, DeserializeFromStr, Decode)] #[debug( fmt = "{{ digest: {digest_function}, payload: {} }}", "hex::encode_upper(payload.as_slice())" @@ -434,7 +378,6 @@ ffi::ffi_item! { pub struct PublicKey { /// Digest function digest_function: Algorithm, - #[serde(with = "hex::serde")] /// Key payload payload: Vec, } @@ -700,23 +643,15 @@ mod tests { Algorithm::BlsNormal, Algorithm::BlsSmall, ] { - let ee = algorithm.encode(); + let encoded_algorithm = algorithm.encode(); - let mut a: &[u8] = ⅇ - - let _s = match std::str::from_utf8(a) { - Ok(v) => v, - Err(e) => panic!("Invalid UTF-8 sequence: {e}"), - }; - - let uu = Algorithm::decode(&mut a); - - let s = match uu { - Ok(v) => v, - Err(e) => panic!("Incorrect param: {e}"), - }; - - assert_eq!(algorithm, s, "Failed to decode encoded {:?}", &algorithm) + let decoded_algorithm = + Algorithm::decode(&mut encoded_algorithm.as_slice()).expect("Failed to decode"); + assert_eq!( + algorithm, decoded_algorithm, + "Failed to decode encoded {:?}", + &algorithm + ) } } @@ -751,22 +686,16 @@ mod tests { KeyGenConfiguration::default().with_algorithm(algorithm), ) .expect("Failed to generate key pair"); + let (public_key, _) = key_pair.into(); - let ee = key_pair.public_key.encode(); - - let mut a: &[u8] = ⅇ - - let uu = PublicKey::decode(&mut a); - - let s = match uu { - Ok(v) => v, - Err(e) => panic!("Incorrect param: {e}"), - }; + let encoded_public_key = public_key.encode(); + let decoded_public_key = + PublicKey::decode(&mut encoded_public_key.as_slice()).expect("Failed to decode"); assert_eq!( - key_pair.public_key, s, + public_key, decoded_public_key, "Failed to decode encoded Public Key{:?}", - &key_pair.public_key + &public_key ) } } @@ -853,13 +782,10 @@ mod tests { } #[test] - fn deserialize_keys_1() { + fn deserialize_keys_ed25519() { assert_eq!( - serde_json::from_str::("{ - \"public_key\": { - \"digest_function\": \"ed25519\", - \"payload\": \"1509a611ad6d97b01d871e58ed00c8fd7c3917b6ca61a8c2833a19e000aac2e4\" - }, + serde_json::from_str::<'_, TestJson>("{ + \"public_key\": \"ed01201509a611ad6d97b01d871e58ed00c8fd7c3917b6ca61a8c2833a19e000aac2e4\", \"private_key\": { \"digest_function\": \"ed25519\", \"payload\": \"3a7991af1abb77f3fd27cc148404a6ae4439d095a63591b77c788d53f708a02a1509a611ad6d97b01d871e58ed00c8fd7c3917b6ca61a8c2833a19e000aac2e4\" @@ -883,13 +809,10 @@ mod tests { } #[test] - fn deserialize_keys_2() { + fn deserialize_keys_secp256k1() { assert_eq!( serde_json::from_str::<'_, TestJson>("{ - \"public_key\": { - \"digest_function\": \"secp256k1\", - \"payload\": \"0312273e8810581e58948d3fb8f9e8ad53aaa21492ebb8703915bbb565a21b7fcc\" - }, + \"public_key\": \"e701210312273e8810581e58948d3fb8f9e8ad53aaa21492ebb8703915bbb565a21b7fcc\", \"private_key\": { \"digest_function\": \"secp256k1\", \"payload\": \"4df4fca10762d4b529fe40a2188a60ca4469d2c50a825b5f33adc2cb78c69445\" @@ -913,13 +836,10 @@ mod tests { } #[test] - fn deserialize_keys_3() { + fn deserialize_keys_bls() { assert_eq!( serde_json::from_str::<'_, TestJson>("{ - \"public_key\": { - \"digest_function\": \"bls_normal\", - \"payload\": \"04175b1e79b15e8a2d5893bf7f8933ca7d0863105d8bac3d6f976cb043378a0e4b885c57ed14eb85fc2fabc639adc7de7f0020c70c57acc38dee374af2c04a6f61c11de8df9034b12d849c7eb90099b0881267d0e1507d4365d838d7dcc31511e7\" - }, + \"public_key\": \"ea016104175b1e79b15e8a2d5893bf7f8933ca7d0863105d8bac3d6f976cb043378a0e4b885c57ed14eb85fc2fabc639adc7de7f0020c70c57acc38dee374af2c04a6f61c11de8df9034b12d849c7eb90099b0881267d0e1507d4365d838d7dcc31511e7\", \"private_key\": { \"digest_function\": \"bls_normal\", \"payload\": \"000000000000000000000000000000002f57460183837efbac6aa6ab3b8dbb7cffcfc59e9448b7860a206d37d470cba3\" @@ -942,10 +862,7 @@ mod tests { ); assert_eq!( serde_json::from_str::<'_, TestJson>("{ - \"public_key\": { - \"digest_function\": \"bls_small\", - \"payload\": \"040cb3231f601e7245a6ec9a647b450936f707ca7dc347ed258586c1924941d8bc38576473a8ba3bb2c37e3e121130ab67103498a96d0d27003e3ad960493da79209cf024e2aa2ae961300976aeee599a31a5e1b683eaa1bcffc47b09757d20f21123c594cf0ee0baf5e1bdd272346b7dc98a8f12c481a6b28174076a352da8eae881b90911013369d7fa960716a5abc5314307463fa2285a5bf2a5b5c6220d68c2d34101a91dbfc531c5b9bbfb2245ccc0c50051f79fc6714d16907b1fc40e0c0\" - }, + \"public_key\": \"eb01c1040cb3231f601e7245a6ec9a647b450936f707ca7dc347ed258586c1924941d8bc38576473a8ba3bb2c37e3e121130ab67103498a96d0d27003e3ad960493da79209cf024e2aa2ae961300976aeee599a31a5e1b683eaa1bcffc47b09757d20f21123c594cf0ee0baf5e1bdd272346b7dc98a8f12c481a6b28174076a352da8eae881b90911013369d7fa960716a5abc5314307463fa2285a5bf2a5b5c6220d68c2d34101a91dbfc531c5b9bbfb2245ccc0c50051f79fc6714d16907b1fc40e0c0\", \"private_key\": { \"digest_function\": \"bls_small\", \"payload\": \"0000000000000000000000000000000060f3c1ac9addbbed8db83bc1b2ef22139fb049eecb723a557a41ca1a4b1fed63\"