diff --git a/config/src/genesis.rs b/config/src/genesis.rs index b137b2298c4..b6881ac4d65 100644 --- a/config/src/genesis.rs +++ b/config/src/genesis.rs @@ -48,7 +48,7 @@ pub enum ParsedConfiguration { /// The peer is responsible for submitting the genesis block Full { /// Genesis account key pair - key_pair: Box, + key_pair: KeyPair, /// Raw genesis block raw_block: RawGenesisBlock, }, @@ -69,7 +69,7 @@ impl Configuration { .map_err(|report| ParseError::File { path, report })?; Ok(ParsedConfiguration::Full { - key_pair: Box::new(KeyPair::new(self.public_key, private_key)?), + key_pair: KeyPair::new(self.public_key, private_key)?, raw_block, }) } diff --git a/configs/peer/executor.wasm b/configs/peer/executor.wasm index dbac1ecc7cf..edbf46b4cfb 100644 Binary files a/configs/peer/executor.wasm and b/configs/peer/executor.wasm differ diff --git a/core/src/queue.rs b/core/src/queue.rs index 3da000e068d..d67abd31972 100644 --- a/core/src/queue.rs +++ b/core/src/queue.rs @@ -743,6 +743,8 @@ mod tests { #[test] async fn custom_expired_transaction_is_rejected() { + const TTL_MS: u64 = 100; + let chain_id = ChainId::new("0"); let max_txs_in_block = 2; @@ -769,10 +771,8 @@ mod tests { AccountId::from_str("alice@wonderland").expect("Valid"), ) .with_instructions(instructions); - tx.set_ttl(Duration::from_millis(10)); - let now = std::time::Instant::now(); + tx.set_ttl(Duration::from_millis(TTL_MS)); let tx = tx.sign(&alice_key); - println!("Signing time: {}ms", now.elapsed().as_millis()); let limits = TransactionLimits { max_instruction_number: 4096, max_wasm_size_bytes: 0, @@ -784,7 +784,7 @@ mod tests { .expect("Failed to push tx into queue"); let mut txs = Vec::new(); let mut expired_txs = Vec::new(); - thread::sleep(Duration::from_millis(10)); + thread::sleep(Duration::from_millis(TTL_MS)); queue.get_transactions_for_block(&wsv, max_txs_in_block, &mut txs, &mut expired_txs); assert!(txs.is_empty()); assert_eq!(expired_txs.len(), 1); diff --git a/core/src/smartcontracts/isi/account.rs b/core/src/smartcontracts/isi/account.rs index ecc3eb214fe..7c803c76b43 100644 --- a/core/src/smartcontracts/isi/account.rs +++ b/core/src/smartcontracts/isi/account.rs @@ -171,7 +171,7 @@ pub mod isi { ))); } if !account.remove_signatory(&public_key) { - return Err(FindError::PublicKey(Box::new(public_key)).into()); + return Err(FindError::PublicKey(public_key).into()); } Ok(()) })?; diff --git a/crypto/src/kex/x25519.rs b/crypto/src/kex/x25519.rs index 5e65a167753..d6c9b6e97f5 100644 --- a/crypto/src/kex/x25519.rs +++ b/crypto/src/kex/x25519.rs @@ -1,6 +1,6 @@ #[cfg(not(feature = "std"))] -use alloc::borrow::ToOwned as _; -use core::borrow::Borrow; +use alloc::{borrow::ToOwned as _, boxed::Box}; +use core::borrow::Borrow as _; use arrayref::array_ref; use iroha_primitives::const_vec::ConstVec; @@ -48,7 +48,7 @@ impl KeyExchangeScheme for X25519Sha256 { (pk, sk) } KeyGenOption::FromPrivateKey(ref s) => { - let crate::PrivateKey::Ed25519(s) = s.borrow() else { + let crate::PrivateKeyInner::Ed25519(s) = s.0.borrow() else { panic!("Wrong private key type, expected `Ed25519`, got {s:?}") }; let sk = StaticSecret::from(*array_ref!(s.as_bytes(), 0, 32)); @@ -66,12 +66,14 @@ impl KeyExchangeScheme for X25519Sha256 { let edwards_compressed = edwards.compress(); ( - PublicKey::Ed25519( + PublicKey(Box::new(crate::PublicKeyInner::Ed25519( crate::ed25519::PublicKey::from_bytes(edwards_compressed.as_bytes()).expect( "Ed25519 public key should be possible to create from X25519 public key", ), - ), - PrivateKey::Ed25519(crate::ed25519::PrivateKey::from_bytes(sk.as_bytes())), + ))), + PrivateKey(Box::new(crate::PrivateKeyInner::Ed25519( + crate::ed25519::PrivateKey::from_bytes(sk.as_bytes()), + ))), ) } @@ -80,10 +82,11 @@ impl KeyExchangeScheme for X25519Sha256 { local_private_key: &PrivateKey, remote_public_key: &PublicKey, ) -> Result { - let crate::PrivateKey::Ed25519(local_private_key) = local_private_key else { + let crate::PrivateKeyInner::Ed25519(local_private_key) = local_private_key.0.borrow() + else { panic!("Wrong private key type, expected `Ed25519`, got {local_private_key:?}") }; - let crate::PublicKey::Ed25519(remote_public_key) = remote_public_key else { + let crate::PublicKeyInner::Ed25519(remote_public_key) = remote_public_key.0.borrow() else { panic!("Wrong public key type, expected `Ed25519`, got {remote_public_key:?}") }; diff --git a/crypto/src/lib.rs b/crypto/src/lib.rs index 525d59af00a..0db94fcbb37 100755 --- a/crypto/src/lib.rs +++ b/crypto/src/lib.rs @@ -25,7 +25,7 @@ use alloc::{ vec, vec::Vec, }; -use core::{fmt, str::FromStr}; +use core::{borrow::Borrow, fmt, str::FromStr}; #[cfg(feature = "base64")] pub use base64; @@ -252,8 +252,8 @@ impl KeyPair { impl From<(ed25519::PublicKey, ed25519::PrivateKey)> for KeyPair { fn from((public_key, private_key): (ed25519::PublicKey, ed25519::PrivateKey)) -> Self { Self { - public_key: PublicKey::Ed25519(public_key), - private_key: PrivateKey::Ed25519(private_key), + public_key: PublicKey(Box::new(PublicKeyInner::Ed25519(public_key))), + private_key: PrivateKey(Box::new(PrivateKeyInner::Ed25519(private_key))), } } } @@ -261,8 +261,8 @@ impl From<(ed25519::PublicKey, ed25519::PrivateKey)> for KeyPair { impl From<(secp256k1::PublicKey, secp256k1::PrivateKey)> for KeyPair { fn from((public_key, private_key): (secp256k1::PublicKey, secp256k1::PrivateKey)) -> Self { Self { - public_key: PublicKey::Secp256k1(public_key), - private_key: PrivateKey::Secp256k1(private_key), + public_key: PublicKey(Box::new(PublicKeyInner::Secp256k1(public_key))), + private_key: PrivateKey(Box::new(PrivateKeyInner::Secp256k1(private_key))), } } } @@ -272,8 +272,8 @@ impl From<(bls::BlsNormalPublicKey, bls::BlsNormalPrivateKey)> for KeyPair { (public_key, private_key): (bls::BlsNormalPublicKey, bls::BlsNormalPrivateKey), ) -> Self { Self { - public_key: PublicKey::BlsNormal(public_key), - private_key: PrivateKey::BlsNormal(private_key), + public_key: PublicKey(Box::new(PublicKeyInner::BlsNormal(public_key))), + private_key: PrivateKey(Box::new(PrivateKeyInner::BlsNormal(private_key))), } } } @@ -281,8 +281,8 @@ impl From<(bls::BlsNormalPublicKey, bls::BlsNormalPrivateKey)> for KeyPair { impl From<(bls::BlsSmallPublicKey, bls::BlsSmallPrivateKey)> for KeyPair { fn from((public_key, private_key): (bls::BlsSmallPublicKey, bls::BlsSmallPrivateKey)) -> Self { Self { - public_key: PublicKey::BlsSmall(Box::new(public_key)), - private_key: PrivateKey::BlsSmall(private_key), + public_key: PublicKey(Box::new(PublicKeyInner::BlsSmall(public_key))), + private_key: PrivateKey(Box::new(PrivateKeyInner::BlsSmall(private_key))), } } } @@ -315,18 +315,96 @@ impl From for (PublicKey, PrivateKey) { } } +#[derive(Clone, PartialEq, Eq)] +#[cfg_attr( + not(feature = "ffi_import"), + derive(DeserializeFromStr, SerializeDisplay) +)] +#[allow(missing_docs, variant_size_differences)] +enum PublicKeyInner { + Ed25519(ed25519::PublicKey), + Secp256k1(secp256k1::PublicKey), + BlsNormal(bls::BlsNormalPublicKey), + BlsSmall(bls::BlsSmallPublicKey), +} + +#[cfg(not(feature = "ffi_import"))] +impl fmt::Debug for PublicKeyInner { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple(self.algorithm().as_static_str()) + .field(&self.normalize()) + .finish() + } +} + +#[cfg(not(feature = "ffi_import"))] +impl fmt::Display for PublicKeyInner { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(&self.normalize()) + } +} + +#[cfg(not(feature = "ffi_import"))] +impl FromStr for PublicKeyInner { + type Err = ParseError; + + fn from_str(key: &str) -> Result { + let bytes = hex_decode(key)?; + + multihash::Multihash::try_from(bytes).map(Into::into) + } +} + +#[cfg(not(feature = "ffi_import"))] +impl PublicKeyInner { + fn normalize(&self) -> String { + let multihash: &multihash::Multihash = &self.clone().into(); + let bytes = Vec::try_from(multihash).expect("Failed to convert multihash to bytes."); + + let mut bytes_iter = bytes.into_iter(); + let fn_code = hex::encode(bytes_iter.by_ref().take(2).collect::>()); + let dig_size = hex::encode(bytes_iter.by_ref().take(1).collect::>()); + let key = hex::encode_upper(bytes_iter.by_ref().collect::>()); + + format!("{fn_code}{dig_size}{key}") + } +} + +impl PublicKeyInner { + fn to_raw(&self) -> (Algorithm, Vec) { + (self.algorithm(), self.payload()) + } + + /// Key payload + fn payload(&self) -> Vec { + use w3f_bls::SerializableToBytes as _; + + match self { + Self::Ed25519(key) => key.as_bytes().to_vec(), + Self::Secp256k1(key) => key.to_sec1_bytes().to_vec(), + Self::BlsNormal(key) => key.to_bytes(), + Self::BlsSmall(key) => key.to_bytes(), + } + } + + fn algorithm(&self) -> Algorithm { + match self { + Self::Ed25519(_) => Algorithm::Ed25519, + Self::Secp256k1(_) => Algorithm::Secp256k1, + Self::BlsNormal(_) => Algorithm::BlsNormal, + Self::BlsSmall(_) => Algorithm::BlsSmall, + } + } +} + ffi::ffi_item! { /// Public Key used in signatures. - #[derive(Clone, PartialEq, Eq, TypeId)] - #[cfg_attr(not(feature="ffi_import"), derive(DeserializeFromStr, SerializeDisplay))] + #[derive(Debug, Clone, PartialEq, Eq, TypeId)] + #[cfg_attr(not(feature="ffi_import"), derive(Deserialize, Serialize, derive_more::Display))] + #[cfg_attr(not(feature="ffi_import"), display(fmt = "{_0}"))] #[cfg_attr(all(feature = "ffi_export", not(feature = "ffi_import")), ffi_type(opaque))] #[allow(missing_docs)] - pub enum PublicKey { - Ed25519(ed25519::PublicKey), - Secp256k1(secp256k1::PublicKey), - BlsNormal(bls::BlsNormalPublicKey), - BlsSmall(Box), - } + pub struct PublicKey(Box); } #[ffi_impl_opaque] @@ -339,16 +417,19 @@ impl PublicKey { pub fn from_raw(algorithm: Algorithm, payload: &[u8]) -> Result { match algorithm { Algorithm::Ed25519 => { - ed25519::Ed25519Sha512::parse_public_key(payload).map(Self::Ed25519) + ed25519::Ed25519Sha512::parse_public_key(payload).map(PublicKeyInner::Ed25519) } - Algorithm::Secp256k1 => { - secp256k1::EcdsaSecp256k1Sha256::parse_public_key(payload).map(Self::Secp256k1) + Algorithm::Secp256k1 => secp256k1::EcdsaSecp256k1Sha256::parse_public_key(payload) + .map(PublicKeyInner::Secp256k1), + Algorithm::BlsNormal => { + bls::BlsNormal::parse_public_key(payload).map(PublicKeyInner::BlsNormal) + } + Algorithm::BlsSmall => { + bls::BlsSmall::parse_public_key(payload).map(PublicKeyInner::BlsSmall) } - Algorithm::BlsNormal => bls::BlsNormal::parse_public_key(payload).map(Self::BlsNormal), - Algorithm::BlsSmall => bls::BlsSmall::parse_public_key(payload) - .map(Box::new) - .map(Self::BlsSmall), } + .map(Box::new) + .map(PublicKey) } /// Extracts the raw bytes from public key, copying the payload. @@ -356,19 +437,7 @@ impl PublicKey { /// `into_raw()` without copying is not provided because underlying crypto /// libraries do not provide move functionality. pub fn to_raw(&self) -> (Algorithm, Vec) { - (self.algorithm(), self.payload()) - } - - /// Key payload - fn payload(&self) -> Vec { - use w3f_bls::SerializableToBytes as _; - - match self { - PublicKey::Ed25519(key) => key.as_bytes().to_vec(), - PublicKey::Secp256k1(key) => key.to_sec1_bytes().to_vec(), - PublicKey::BlsNormal(key) => key.to_bytes(), - PublicKey::BlsSmall(key) => key.to_bytes(), - } + self.0.to_raw() } /// Construct [`PublicKey`] from hex encoded string @@ -384,35 +453,14 @@ impl PublicKey { /// Get the digital signature algorithm of the public key pub fn algorithm(&self) -> Algorithm { - match self { - Self::Ed25519(_) => Algorithm::Ed25519, - Self::Secp256k1(_) => Algorithm::Secp256k1, - Self::BlsNormal(_) => Algorithm::BlsNormal, - Self::BlsSmall(_) => Algorithm::BlsSmall, - } - } -} - -#[cfg(not(feature = "ffi_import"))] -impl fmt::Debug for PublicKey { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple(self.algorithm().as_static_str()) - .field(&self.normalize()) - .finish() - } -} - -#[cfg(not(feature = "ffi_import"))] -impl fmt::Display for PublicKey { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(&self.normalize()) + self.0.algorithm() } } #[cfg(not(feature = "ffi_import"))] impl core::hash::Hash for PublicKey { fn hash(&self, state: &mut H) { - (self.algorithm(), self.payload()).hash(state) + (self.to_raw()).hash(state) } } @@ -424,19 +472,18 @@ impl PartialOrd for PublicKey { impl Ord for PublicKey { fn cmp(&self, other: &Self) -> core::cmp::Ordering { - (self.algorithm(), self.payload()).cmp(&(other.algorithm(), other.payload())) + self.to_raw().cmp(&other.to_raw()) } } #[cfg(not(feature = "ffi_import"))] impl Encode for PublicKey { fn size_hint(&self) -> usize { - self.algorithm().size_hint() + self.payload().size_hint() + self.to_raw().size_hint() } fn encode_to(&self, dest: &mut W) { - self.algorithm().encode_to(dest); - self.payload().encode_to(dest); + self.to_raw().encode_to(dest); } } @@ -490,24 +537,7 @@ impl FromStr for PublicKey { type Err = ParseError; fn from_str(key: &str) -> Result { - let bytes = hex_decode(key)?; - - multihash::Multihash::try_from(bytes).map(Into::into) - } -} - -#[cfg(not(feature = "ffi_import"))] -impl PublicKey { - fn normalize(&self) -> String { - let multihash: &multihash::Multihash = &self.clone().into(); - let bytes = Vec::try_from(multihash).expect("Failed to convert multihash to bytes."); - - let mut bytes_iter = bytes.into_iter(); - let fn_code = hex::encode(bytes_iter.by_ref().take(2).collect::>()); - let dig_size = hex::encode(bytes_iter.by_ref().take(1).collect::>()); - let key = hex::encode_upper(bytes_iter.by_ref().collect::>()); - - format!("{fn_code}{dig_size}{key}") + PublicKeyInner::from_str(key).map(Box::new).map(Self) } } @@ -515,44 +545,55 @@ impl PublicKey { #[cfg(not(feature = "ffi_import"))] impl From for PublicKey { fn from(private_key: PrivateKey) -> Self { - let digest_function = private_key.algorithm(); + let algorithm = private_key.algorithm(); let key_gen_option = KeyGenOption::FromPrivateKey(Box::new(private_key)); - match digest_function { + let inner = match algorithm { Algorithm::Ed25519 => { - PublicKey::Ed25519(ed25519::Ed25519Sha512::keypair(key_gen_option).0) + PublicKeyInner::Ed25519(ed25519::Ed25519Sha512::keypair(key_gen_option).0) } - Algorithm::Secp256k1 => { - PublicKey::Secp256k1(secp256k1::EcdsaSecp256k1Sha256::keypair(key_gen_option).0) + Algorithm::Secp256k1 => PublicKeyInner::Secp256k1( + secp256k1::EcdsaSecp256k1Sha256::keypair(key_gen_option).0, + ), + Algorithm::BlsNormal => { + PublicKeyInner::BlsNormal(bls::BlsNormal::keypair(key_gen_option).0) } - Algorithm::BlsNormal => PublicKey::BlsNormal(bls::BlsNormal::keypair(key_gen_option).0), Algorithm::BlsSmall => { - PublicKey::BlsSmall(Box::new(bls::BlsSmall::keypair(key_gen_option).0)) + PublicKeyInner::BlsSmall(bls::BlsSmall::keypair(key_gen_option).0) } - } + }; + PublicKey(Box::new(inner)) } } +#[derive(Clone)] +#[allow(missing_docs, variant_size_differences)] +enum PrivateKeyInner { + Ed25519(ed25519::PrivateKey), + Secp256k1(secp256k1::PrivateKey), + BlsNormal(bls::BlsNormalPrivateKey), + BlsSmall(bls::BlsSmallPrivateKey), +} + ffi::ffi_item! { /// Private Key used in signatures. #[derive(Clone)] #[cfg_attr(all(feature = "ffi_export", not(feature = "ffi_import")), ffi_type(opaque))] #[allow(missing_docs, variant_size_differences)] - pub enum PrivateKey { - Ed25519(ed25519::PrivateKey), - Secp256k1(secp256k1::PrivateKey), - BlsNormal(bls::BlsNormalPrivateKey), - BlsSmall(bls::BlsSmallPrivateKey), - } + pub struct PrivateKey(Box); } impl PartialEq for PrivateKey { fn eq(&self, other: &Self) -> bool { - match (self, other) { - (Self::Ed25519(l), Self::Ed25519(r)) => l == r, - (Self::Secp256k1(l), Self::Secp256k1(r)) => l == r, - (Self::BlsNormal(l), Self::BlsNormal(r)) => l.to_bytes() == r.to_bytes(), - (Self::BlsSmall(l), Self::BlsSmall(r)) => l.to_bytes() == r.to_bytes(), + match (self.0.borrow(), other.0.borrow()) { + (PrivateKeyInner::Ed25519(l), PrivateKeyInner::Ed25519(r)) => l == r, + (PrivateKeyInner::Secp256k1(l), PrivateKeyInner::Secp256k1(r)) => l == r, + (PrivateKeyInner::BlsNormal(l), PrivateKeyInner::BlsNormal(r)) => { + l.to_bytes() == r.to_bytes() + } + (PrivateKeyInner::BlsSmall(l), PrivateKeyInner::BlsSmall(r)) => { + l.to_bytes() == r.to_bytes() + } _ => false, } } @@ -569,14 +610,19 @@ impl PrivateKey { pub fn from_raw(algorithm: Algorithm, payload: &[u8]) -> Result { match algorithm { Algorithm::Ed25519 => { - ed25519::Ed25519Sha512::parse_private_key(payload).map(Self::Ed25519) + ed25519::Ed25519Sha512::parse_private_key(payload).map(PrivateKeyInner::Ed25519) } - Algorithm::Secp256k1 => { - secp256k1::EcdsaSecp256k1Sha256::parse_private_key(payload).map(Self::Secp256k1) + Algorithm::Secp256k1 => secp256k1::EcdsaSecp256k1Sha256::parse_private_key(payload) + .map(PrivateKeyInner::Secp256k1), + Algorithm::BlsNormal => { + bls::BlsNormal::parse_private_key(payload).map(PrivateKeyInner::BlsNormal) + } + Algorithm::BlsSmall => { + bls::BlsSmall::parse_private_key(payload).map(PrivateKeyInner::BlsSmall) } - Algorithm::BlsNormal => bls::BlsNormal::parse_private_key(payload).map(Self::BlsNormal), - Algorithm::BlsSmall => bls::BlsSmall::parse_private_key(payload).map(Self::BlsSmall), } + .map(Box::new) + .map(PrivateKey) } /// Construct [`PrivateKey`] from hex encoded string @@ -593,21 +639,21 @@ impl PrivateKey { /// Get the digital signature algorithm of the private key pub fn algorithm(&self) -> Algorithm { - match self { - Self::Ed25519(_) => Algorithm::Ed25519, - Self::Secp256k1(_) => Algorithm::Secp256k1, - Self::BlsNormal(_) => Algorithm::BlsNormal, - Self::BlsSmall(_) => Algorithm::BlsSmall, + match self.0.borrow() { + PrivateKeyInner::Ed25519(_) => Algorithm::Ed25519, + PrivateKeyInner::Secp256k1(_) => Algorithm::Secp256k1, + PrivateKeyInner::BlsNormal(_) => Algorithm::BlsNormal, + PrivateKeyInner::BlsSmall(_) => Algorithm::BlsSmall, } } /// Key payload fn payload(&self) -> Vec { - match self { - Self::Ed25519(key) => key.to_keypair_bytes().to_vec(), - Self::Secp256k1(key) => key.to_bytes().to_vec(), - Self::BlsNormal(key) => key.to_bytes(), - Self::BlsSmall(key) => key.to_bytes(), + match self.0.borrow() { + PrivateKeyInner::Ed25519(key) => key.to_keypair_bytes().to_vec(), + PrivateKeyInner::Secp256k1(key) => key.to_bytes().to_vec(), + PrivateKeyInner::BlsNormal(key) => key.to_bytes(), + PrivateKeyInner::BlsSmall(key) => key.to_bytes(), } } } diff --git a/crypto/src/multihash.rs b/crypto/src/multihash.rs index 248731dfcb9..a2c8281b134 100644 --- a/crypto/src/multihash.rs +++ b/crypto/src/multihash.rs @@ -10,7 +10,7 @@ use alloc::{ use derive_more::Display; use iroha_primitives::const_vec::ConstVec; -use crate::{varint, Algorithm, NoSuchAlgorithm, ParseError, PublicKey}; +use crate::{varint, Algorithm, NoSuchAlgorithm, ParseError, PublicKey, PublicKeyInner}; /// ed25519 public string pub const ED_25519_PUB_STR: &str = "ed25519-pub"; @@ -111,7 +111,7 @@ impl From for u64 { /// Offers a middleware representation of [`PublicKey`] which can be converted /// to/from bytes or string. #[derive(Debug, PartialEq, Eq)] -pub struct Multihash(PublicKey); +pub struct Multihash(PublicKeyInner); impl TryFrom> for Multihash { type Error = ParseError; @@ -151,7 +151,7 @@ impl TryFrom> for Multihash { } let payload = ConstVec::new(payload); - Ok(PublicKey::from_raw(algorithm, &payload)?.into()) + Ok(Self::from(*PublicKey::from_raw(algorithm, &payload)?.0)) } } @@ -176,16 +176,16 @@ impl TryFrom<&Multihash> for Vec { } } -impl From for PublicKey { +impl From for PublicKeyInner { #[inline] fn from(multihash: Multihash) -> Self { multihash.0 } } -impl From for Multihash { +impl From for Multihash { #[inline] - fn from(public_key: PublicKey) -> Self { + fn from(public_key: PublicKeyInner) -> Self { Self(public_key) } } @@ -221,12 +221,13 @@ mod tests { #[test] fn multihash_to_bytes() { let multihash = Multihash( - PublicKey::from_raw( + *PublicKey::from_raw( Algorithm::Ed25519, &hex_decode("1509A611AD6D97B01D871E58ED00C8FD7C3917B6CA61A8C2833A19E000AAC2E4") .unwrap(), ) - .unwrap(), + .unwrap() + .0, ); let bytes = Vec::try_from(&multihash).expect("Failed to serialize multihash"); assert_eq!( @@ -239,12 +240,13 @@ mod tests { #[test] fn multihash_from_bytes() { let multihash = Multihash( - PublicKey::from_raw( + *PublicKey::from_raw( Algorithm::Ed25519, &hex_decode("1509A611AD6D97B01D871E58ED00C8FD7C3917B6CA61A8C2833A19E000AAC2E4") .unwrap(), ) - .unwrap(), + .unwrap() + .0, ); let bytes = hex_decode("ed01201509A611AD6D97B01D871E58ED00C8FD7C3917B6CA61A8C2833A19E000AAC2E4") diff --git a/crypto/src/signature/bls/mod.rs b/crypto/src/signature/bls/mod.rs index 28325e9346b..8a69a3dd7a5 100644 --- a/crypto/src/signature/bls/mod.rs +++ b/crypto/src/signature/bls/mod.rs @@ -14,6 +14,8 @@ mod implementation; /// with the public key group in G1 and signature group in G2. /// 192 byte signatures and 97 byte public keys mod normal { + use core::borrow::Borrow as _; + use super::{implementation, implementation::BlsConfiguration}; use crate::Algorithm; @@ -26,7 +28,7 @@ mod normal { type Engine = w3f_bls::ZBLS; fn extract_private_key(private_key: &crate::PrivateKey) -> Option<&NormalPrivateKey> { - if let crate::PrivateKey::BlsNormal(key) = private_key { + if let crate::PrivateKeyInner::BlsNormal(key) = private_key.0.borrow() { Some(key) } else { None @@ -46,6 +48,8 @@ mod normal { /// /// This is good for situations where space is a consideration and verification is infrequent. mod small { + use core::borrow::Borrow as _; + use super::implementation::{self, BlsConfiguration}; use crate::Algorithm; @@ -57,7 +61,7 @@ mod small { type Engine = w3f_bls::TinyBLS381; fn extract_private_key(private_key: &crate::PrivateKey) -> Option<&SmallPrivateKey> { - if let crate::PrivateKey::BlsSmall(key) = private_key { + if let crate::PrivateKeyInner::BlsSmall(key) = private_key.0.borrow() { Some(key) } else { None diff --git a/crypto/src/signature/ed25519.rs b/crypto/src/signature/ed25519.rs index 1276d49cf08..d7b4715d5ce 100644 --- a/crypto/src/signature/ed25519.rs +++ b/crypto/src/signature/ed25519.rs @@ -33,7 +33,7 @@ impl Ed25519Sha512 { PrivateKey::generate(&mut rng) } KeyGenOption::FromPrivateKey(ref s) => { - let crate::PrivateKey::Ed25519(s) = s.borrow() else { + let crate::PrivateKeyInner::Ed25519(s) = s.0.borrow() else { panic!("Wrong private key type, expected `Ed25519`, got {s:?}") }; PrivateKey::clone(s) @@ -96,11 +96,11 @@ mod test { let (p1, s1) = Ed25519Sha512::keypair(KeyGenOption::FromPrivateKey(Box::new(secret))); assert_eq!( - PrivateKey::Ed25519(s1), + PrivateKey(Box::new(crate::PrivateKeyInner::Ed25519(s1))), PrivateKey::from_hex(Algorithm::Ed25519, PRIVATE_KEY).unwrap() ); assert_eq!( - PublicKey::Ed25519(p1), + PublicKey(Box::new(crate::PublicKeyInner::Ed25519(p1))), PublicKey::from_hex(Algorithm::Ed25519, PUBLIC_KEY).unwrap() ); } diff --git a/crypto/src/signature/mod.rs b/crypto/src/signature/mod.rs index acdf50d12f8..1317403f8b8 100644 --- a/crypto/src/signature/mod.rs +++ b/crypto/src/signature/mod.rs @@ -15,7 +15,7 @@ use alloc::{ boxed::Box, collections::btree_set, format, string::String, string::ToString as _, vec, vec::Vec, }; -use core::marker::PhantomData; +use core::{borrow::Borrow as _, marker::PhantomData}; #[cfg(feature = "std")] use std::collections::btree_set; @@ -57,11 +57,13 @@ impl Signature { /// # Errors /// Fails if signing fails pub fn new(key_pair: &KeyPair, payload: &[u8]) -> Self { - let signature = match &key_pair.private_key { - crate::PrivateKey::Ed25519(sk) => ed25519::Ed25519Sha512::sign(payload, sk), - crate::PrivateKey::Secp256k1(sk) => secp256k1::EcdsaSecp256k1Sha256::sign(payload, sk), - crate::PrivateKey::BlsSmall(sk) => bls::BlsSmall::sign(payload, sk), - crate::PrivateKey::BlsNormal(sk) => bls::BlsNormal::sign(payload, sk), + let signature = match key_pair.private_key.0.borrow() { + crate::PrivateKeyInner::Ed25519(sk) => ed25519::Ed25519Sha512::sign(payload, sk), + crate::PrivateKeyInner::Secp256k1(sk) => { + secp256k1::EcdsaSecp256k1Sha256::sign(payload, sk) + } + crate::PrivateKeyInner::BlsSmall(sk) => bls::BlsSmall::sign(payload, sk), + crate::PrivateKeyInner::BlsNormal(sk) => bls::BlsNormal::sign(payload, sk), }; Self { public_key: key_pair.public_key.clone(), @@ -74,15 +76,19 @@ impl Signature { /// # Errors /// Fails if message didn't pass verification pub fn verify(&self, payload: &[u8]) -> Result<(), Error> { - match &self.public_key { - crate::PublicKey::Ed25519(pk) => { + match self.public_key.0.borrow() { + crate::PublicKeyInner::Ed25519(pk) => { ed25519::Ed25519Sha512::verify(payload, self.payload(), pk) } - crate::PublicKey::Secp256k1(pk) => { + crate::PublicKeyInner::Secp256k1(pk) => { secp256k1::EcdsaSecp256k1Sha256::verify(payload, self.payload(), pk) } - crate::PublicKey::BlsSmall(pk) => bls::BlsSmall::verify(payload, self.payload(), pk), - crate::PublicKey::BlsNormal(pk) => bls::BlsNormal::verify(payload, self.payload(), pk), + crate::PublicKeyInner::BlsSmall(pk) => { + bls::BlsSmall::verify(payload, self.payload(), pk) + } + crate::PublicKeyInner::BlsNormal(pk) => { + bls::BlsNormal::verify(payload, self.payload(), pk) + } }?; Ok(()) diff --git a/crypto/src/signature/secp256k1.rs b/crypto/src/signature/secp256k1.rs index 5fab149484f..b0b50d7f878 100644 --- a/crypto/src/signature/secp256k1.rs +++ b/crypto/src/signature/secp256k1.rs @@ -69,7 +69,7 @@ mod ecdsa_secp256k1 { .expect("Creating private key from seed should always succeed") } KeyGenOption::FromPrivateKey(ref s) => { - let crate::PrivateKey::Secp256k1(s) = s.borrow() else { + let crate::PrivateKeyInner::Secp256k1(s) = s.0.borrow() else { panic!("Wrong private key type, expected `Secp256k1`, got {s:?}") }; s.clone() @@ -155,7 +155,7 @@ mod test { fn secp256k1_compatibility() { let secret = private_key(); let (p, s) = EcdsaSecp256k1Sha256::keypair(KeyGenOption::FromPrivateKey(Box::new( - crate::PrivateKey::Secp256k1(secret), + crate::PrivateKey(Box::new(crate::PrivateKeyInner::Secp256k1(secret))), ))); let _sk = secp256k1::SecretKey::from_slice(&s.to_bytes()).unwrap(); @@ -207,7 +207,7 @@ mod test { fn secp256k1_sign() { let secret = private_key(); let (pk, sk) = EcdsaSecp256k1Sha256::keypair(KeyGenOption::FromPrivateKey(Box::new( - crate::PrivateKey::Secp256k1(secret), + crate::PrivateKey(Box::new(crate::PrivateKeyInner::Secp256k1(secret))), ))); let sig = EcdsaSecp256k1Sha256::sign(MESSAGE_1, &sk); diff --git a/data_model/src/block.rs b/data_model/src/block.rs index 24d8a470e6e..3ad6900d32d 100644 --- a/data_model/src/block.rs +++ b/data_model/src/block.rs @@ -194,10 +194,6 @@ impl SignedBlock { } /// Add additional signatures to this block - /// - /// # Errors - /// - /// If given signature doesn't match block hash #[cfg(feature = "std")] #[cfg(feature = "transparent_api")] #[must_use] diff --git a/data_model/src/peer.rs b/data_model/src/peer.rs index 80894c26ad6..f5da00a8bb5 100644 --- a/data_model/src/peer.rs +++ b/data_model/src/peer.rs @@ -20,21 +20,26 @@ use crate::{Identifiable, PublicKey, Registered, Value}; #[model] pub mod model { + use getset::Getters; + use super::*; /// Peer's identification. /// /// Equality is tested by `public_key` field only. /// Each peer should have a unique public key. - #[derive(Debug, Display, Clone, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema)] + #[derive( + Debug, Display, Clone, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema, Getters, + )] #[display(fmt = "{public_key}@@{address}")] + #[getset(get = "pub")] #[ffi_type] pub struct PeerId { /// Address of the [`Peer`]'s entrypoint. // TODO: Derive with getset once FFI impl is fixed pub address: SocketAddr, /// Public Key of the [`Peer`]. - pub public_key: Box, + pub public_key: PublicKey, } /// Representation of other Iroha Peer instances running in separate processes. @@ -58,15 +63,9 @@ impl PeerId { pub fn new(address: SocketAddr, public_key: PublicKey) -> Self { Self { address, - public_key: Box::new(public_key), + public_key, } } - - /// Get public key of the peer. - #[inline] - pub fn public_key(&self) -> &PublicKey { - &self.public_key - } } impl Peer { diff --git a/data_model/src/query/mod.rs b/data_model/src/query/mod.rs index a28e2c59a20..46100020b12 100644 --- a/data_model/src/query/mod.rs +++ b/data_model/src/query/mod.rs @@ -1231,6 +1231,7 @@ pub mod http { /// # Errors /// Fails if signature creation fails. #[inline] + #[must_use] pub fn sign(self, key_pair: &iroha_crypto::KeyPair) -> SignedQuery { SignedQueryV1 { signature: SignatureOf::new(key_pair, &self.payload), @@ -1348,7 +1349,7 @@ pub mod error { /// Parameter with id `{0}` not found Parameter(ParameterId), /// Failed to find public key: `{0}` - PublicKey(Box), + PublicKey(PublicKey), } } } diff --git a/data_model/src/transaction.rs b/data_model/src/transaction.rs index 649fb9838b4..59eacb1c9e5 100644 --- a/data_model/src/transaction.rs +++ b/data_model/src/transaction.rs @@ -279,10 +279,6 @@ impl SignedTransaction { } /// Sign transaction with provided key pair. - /// - /// # Errors - /// - /// Fails if signature creation fails #[cfg(feature = "std")] #[must_use] pub fn sign(self, key_pair: &iroha_crypto::KeyPair) -> SignedTransaction { @@ -743,11 +739,8 @@ mod http { } /// Sign transaction with provided key pair. - /// - /// # Errors - /// - /// Fails if signature creation fails #[cfg(feature = "std")] + #[must_use] pub fn sign(self, key_pair: &iroha_crypto::KeyPair) -> SignedTransaction { let signatures = SignaturesOf::new(key_pair, &self.payload); diff --git a/genesis/src/lib.rs b/genesis/src/lib.rs index e4861426467..b0d9a1cef9a 100644 --- a/genesis/src/lib.rs +++ b/genesis/src/lib.rs @@ -182,9 +182,7 @@ pub struct GenesisTransactionBuilder { impl GenesisTransactionBuilder { /// Convert [`GenesisTransactionBuilder`] into [`SignedTransaction`] with signature. - /// - /// # Errors - /// Fails if signing or accepting fails. + #[must_use] fn sign(self, chain_id: ChainId, genesis_key_pair: &KeyPair) -> SignedTransaction { TransactionBuilder::new(chain_id, GENESIS_ACCOUNT_ID.clone()) .with_instructions(self.isi)