Skip to content

Commit

Permalink
[refactor] hyperledger-iroha#2573: Use a more efficient representatio…
Browse files Browse the repository at this point in the history
…n for bytes values that are not changing

Signed-off-by: Nikita Strygin <dcnick3@users.noreply.github.com>
  • Loading branch information
DCNick3 committed Sep 4, 2023
1 parent 8d38945 commit 948c789
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 46 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

71 changes: 39 additions & 32 deletions crypto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use error::{Error, NoSuchAlgorithm};
use getset::{CopyGetters, Getters};
pub use hash::*;
use iroha_macro::ffi_impl_opaque;
use iroha_primitives::const_bytes::ConstBytes;
use iroha_schema::IntoSchema;
pub use merkle::MerkleTree;
#[cfg(not(feature = "ffi_import"))]
Expand Down Expand Up @@ -138,7 +139,7 @@ impl TryFrom<KeyGenOption> for UrsaKeyGenOption {

match algorithm {
Algorithm::Ed25519 | Algorithm::Secp256k1 => {
Ok(Self::FromSecretKey(UrsaPrivateKey(key.payload)))
Ok(Self::FromSecretKey(UrsaPrivateKey(key.payload.into_vec())))
}
_ => Err(Self::Error {}),
}
Expand Down Expand Up @@ -265,11 +266,11 @@ impl KeyPair {
Ok(Self {
public_key: PublicKey {
digest_function: configuration.algorithm,
payload: core::mem::take(&mut public_key.0),
payload: ConstBytes::new(core::mem::take(&mut public_key.0)),
},
private_key: PrivateKey {
digest_function: configuration.algorithm,
payload: core::mem::take(&mut private_key.0),
payload: ConstBytes::new(core::mem::take(&mut private_key.0)),
},
})
}
Expand Down Expand Up @@ -314,7 +315,7 @@ ffi::ffi_item! {
#[getset(get_copy = "pub")]
digest_function: Algorithm,
/// Key payload
payload: Vec<u8>,
payload: ConstBytes,
}
}

Expand All @@ -323,14 +324,14 @@ impl PublicKey {
/// Key payload
// TODO: Derive with getset once FFI impl is fixed
pub fn payload(&self) -> &[u8] {
&self.payload
self.payload.as_ref()
}

#[cfg(feature = "std")]
fn try_from_private(private_key: PrivateKey) -> Result<PublicKey, Error> {
let digest_function = private_key.digest_function();
let key_gen_option = Some(UrsaKeyGenOption::FromSecretKey(UrsaPrivateKey(
private_key.payload,
private_key.payload.into_vec(),
)));

let (mut public_key, _) = match digest_function {
Expand All @@ -342,7 +343,7 @@ impl PublicKey {

Ok(PublicKey {
digest_function: private_key.digest_function,
payload: core::mem::take(&mut public_key.0),
payload: ConstBytes::new(core::mem::take(&mut public_key.0)),
})
}
}
Expand Down Expand Up @@ -398,7 +399,7 @@ ffi::ffi_item! {
digest_function: Algorithm,
/// Key payload
#[serde(with = "hex::serde")]
payload: Vec<u8>,
payload: ConstBytes,
}
}

Expand All @@ -413,7 +414,7 @@ impl PrivateKey {
/// Key payload
// TODO: Derive with getset once FFI impl is fixed
pub fn payload(&self) -> &[u8] {
&self.payload
self.payload.as_ref()
}
}

Expand All @@ -429,7 +430,8 @@ impl PrivateKey {
) -> Result<Self, Error> {
Ok(Self {
digest_function,
payload: hex_decode(payload)?,
payload: ConstBytes::from_hex(payload)
.map_err(|err| Error::Parse(err.to_string()))?,
})
}

Expand All @@ -442,6 +444,7 @@ impl PrivateKey {
#[cfg(feature = "std")]
pub fn from_hex(digest_function: Algorithm, payload: &[u8]) -> Result<Self, Error> {
let payload = hex_decode(payload)?;
let payload = ConstBytes::new(payload);

let private_key_candidate = Self {
digest_function,
Expand Down Expand Up @@ -770,10 +773,12 @@ mod tests {
"{}",
PublicKey {
digest_function: Algorithm::Ed25519,
payload: hex_decode(
"1509A611AD6D97B01D871E58ED00C8FD7C3917B6CA61A8C2833A19E000AAC2E4"
payload: ConstBytes::new(
hex_decode(
"1509A611AD6D97B01D871E58ED00C8FD7C3917B6CA61A8C2833A19E000AAC2E4"
)
.expect("Failed to decode public key.")
)
.expect("Failed to decode public key.")
}
),
"ed01201509A611AD6D97B01D871E58ED00C8FD7C3917B6CA61A8C2833A19E000AAC2E4"
Expand All @@ -783,10 +788,12 @@ mod tests {
"{}",
PublicKey {
digest_function: Algorithm::Secp256k1,
payload: hex_decode(
"0312273E8810581E58948D3FB8F9E8AD53AAA21492EBB8703915BBB565A21B7FCC"
payload: ConstBytes::new(
hex_decode(
"0312273E8810581E58948D3FB8F9E8AD53AAA21492EBB8703915BBB565A21B7FCC"
)
.expect("Failed to decode public key.")
)
.expect("Failed to decode public key.")
}
),
"e701210312273E8810581E58948D3FB8F9E8AD53AAA21492EBB8703915BBB565A21B7FCC"
Expand All @@ -796,10 +803,9 @@ mod tests {
"{}",
PublicKey {
digest_function: Algorithm::BlsNormal,
payload: hex_decode(
payload: ConstBytes::from_hex(
"04175B1E79B15E8A2D5893BF7F8933CA7D0863105D8BAC3D6F976CB043378A0E4B885C57ED14EB85FC2FABC639ADC7DE7F0020C70C57ACC38DEE374AF2C04A6F61C11DE8DF9034B12D849C7EB90099B0881267D0E1507D4365D838D7DCC31511E7"
)
.expect("Failed to decode public key.")
).expect("Failed to decode public key.")
}
),
"ea016104175B1E79B15E8A2D5893BF7F8933CA7D0863105D8BAC3D6F976CB043378A0E4B885C57ED14EB85FC2FABC639ADC7DE7F0020C70C57ACC38DEE374AF2C04A6F61C11DE8DF9034B12D849C7EB90099B0881267D0E1507D4365D838D7DCC31511E7"
Expand All @@ -809,7 +815,7 @@ mod tests {
"{}",
PublicKey {
digest_function: Algorithm::BlsSmall,
payload: hex_decode(
payload: ConstBytes::from_hex(
"040CB3231F601E7245A6EC9A647B450936F707CA7DC347ED258586C1924941D8BC38576473A8BA3BB2C37E3E121130AB67103498A96D0D27003E3AD960493DA79209CF024E2AA2AE961300976AEEE599A31A5E1B683EAA1BCFFC47B09757D20F21123C594CF0EE0BAF5E1BDD272346B7DC98A8F12C481A6B28174076A352DA8EAE881B90911013369D7FA960716A5ABC5314307463FA2285A5BF2A5B5C6220D68C2D34101A91DBFC531C5B9BBFB2245CCC0C50051F79FC6714D16907B1FC40E0C0"
)
.expect("Failed to decode public key.")
Expand Down Expand Up @@ -839,14 +845,14 @@ mod tests {
TestJson {
public_key: PublicKey {
digest_function: Algorithm::Ed25519,
payload: hex_decode(
payload: ConstBytes::from_hex(
"1509A611AD6D97B01D871E58ED00C8FD7C3917B6CA61A8C2833A19E000AAC2E4"
)
.expect("Failed to decode public key.")
},
private_key: PrivateKey {
digest_function: Algorithm::Ed25519,
payload: hex_decode("3A7991AF1ABB77F3FD27CC148404A6AE4439D095A63591B77C788D53F708A02A1509A611AD6D97B01D871E58ED00C8FD7C3917B6CA61A8C2833A19E000AAC2E4")
payload: ConstBytes::from_hex("3A7991AF1ABB77F3FD27CC148404A6AE4439D095A63591B77C788D53F708A02A1509A611AD6D97B01D871E58ED00C8FD7C3917B6CA61A8C2833A19E000AAC2E4")
.expect("Failed to decode private key"),
}
}
Expand All @@ -867,14 +873,14 @@ mod tests {
TestJson {
public_key: PublicKey {
digest_function: Algorithm::Secp256k1,
payload: hex_decode(
payload: ConstBytes::from_hex(
"0312273E8810581E58948D3FB8F9E8AD53AAA21492EBB8703915BBB565A21B7FCC"
)
.expect("Failed to decode public key.")
},
private_key: PrivateKey {
digest_function: Algorithm::Secp256k1,
payload: hex_decode("4DF4FCA10762D4B529FE40A2188A60CA4469D2C50A825B5F33ADC2CB78C69445")
payload: ConstBytes::from_hex("4DF4FCA10762D4B529FE40A2188A60CA4469D2C50A825B5F33ADC2CB78C69445")
.expect("Failed to decode private key"),
}
}
Expand All @@ -895,14 +901,14 @@ mod tests {
TestJson {
public_key: PublicKey {
digest_function: Algorithm::BlsNormal,
payload: hex_decode(
payload: ConstBytes::from_hex(
"04175B1E79B15E8A2D5893BF7F8933CA7D0863105D8BAC3D6F976CB043378A0E4B885C57ED14EB85FC2FABC639ADC7DE7F0020C70C57ACC38DEE374AF2C04A6F61C11DE8DF9034B12D849C7EB90099B0881267D0E1507D4365D838D7DCC31511E7"
)
.expect("Failed to decode public key.")
},
private_key: PrivateKey {
digest_function: Algorithm::BlsNormal,
payload: hex_decode("000000000000000000000000000000002F57460183837EFBAC6AA6AB3B8DBB7CFFCFC59E9448B7860A206D37D470CBA3")
payload: ConstBytes::from_hex("000000000000000000000000000000002F57460183837EFBAC6AA6AB3B8DBB7CFFCFC59E9448B7860A206D37D470CBA3")
.expect("Failed to decode private key"),
}
}
Expand All @@ -918,15 +924,16 @@ mod tests {
TestJson {
public_key: PublicKey {
digest_function: Algorithm::BlsSmall,
payload: hex_decode(
"040CB3231F601E7245A6EC9A647B450936F707CA7DC347ED258586C1924941D8BC38576473A8BA3BB2C37E3E121130AB67103498A96D0D27003E3AD960493DA79209CF024E2AA2AE961300976AEEE599A31A5E1B683EAA1BCFFC47B09757D20F21123C594CF0EE0BAF5E1BDD272346B7DC98A8F12C481A6B28174076A352DA8EAE881B90911013369D7FA960716A5ABC5314307463FA2285A5BF2A5B5C6220D68C2D34101A91DBFC531C5B9BBFB2245CCC0C50051F79FC6714D16907B1FC40E0C0"
)
.expect("Failed to decode public key.")
payload: ConstBytes::from_hex(
"040CB3231F601E7245A6EC9A647B450936F707CA7DC347ED258586C1924941D8BC38576473A8BA3BB2C37E3E121130AB67103498A96D0D27003E3AD960493DA79209CF024E2AA2AE961300976AEEE599A31A5E1B683EAA1BCFFC47B09757D20F21123C594CF0EE0BAF5E1BDD272346B7DC98A8F12C481A6B28174076A352DA8EAE881B90911013369D7FA960716A5ABC5314307463FA2285A5BF2A5B5C6220D68C2D34101A91DBFC531C5B9BBFB2245CCC0C50051F79FC6714D16907B1FC40E0C0"
)
.expect("Failed to decode public key.")
},
private_key: PrivateKey {
digest_function: Algorithm::BlsSmall,
payload: hex_decode("0000000000000000000000000000000060F3C1AC9ADDBBED8DB83BC1B2EF22139FB049EECB723A557A41CA1A4B1FED63")
.expect("Failed to decode private key"),
payload: ConstBytes::from_hex(
"0000000000000000000000000000000060F3C1AC9ADDBBED8DB83BC1B2EF22139FB049EECB723A557A41CA1A4B1FED63")
.expect("Failed to decode private key"),
}
}
)
Expand Down
18 changes: 12 additions & 6 deletions crypto/src/multihash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use alloc::{
};

use derive_more::Display;
use iroha_primitives::const_bytes::ConstBytes;

use crate::{varint, Algorithm, NoSuchAlgorithm, PublicKey};

Expand Down Expand Up @@ -90,7 +91,7 @@ pub struct Multihash {
/// digest
pub digest_function: DigestFunction,
/// hash payload
pub payload: Vec<u8>,
pub payload: ConstBytes,
}

impl TryFrom<Vec<u8>> for Multihash {
Expand Down Expand Up @@ -127,6 +128,7 @@ impl TryFrom<Vec<u8>> for Multihash {
"Digest size not equal to actual length",
)));
}
let payload = ConstBytes::new(payload);

Ok(Self {
digest_function,
Expand All @@ -148,7 +150,7 @@ impl TryFrom<&Multihash> for Vec<u8> {
bytes.push(multihash.payload.len().try_into().map_err(|_e| {
MultihashConvertError::new(String::from("Digest size can't fit into u8"))
})?);
bytes.extend_from_slice(&multihash.payload);
bytes.extend_from_slice(multihash.payload.as_ref());

Ok(bytes)
}
Expand Down Expand Up @@ -222,8 +224,10 @@ mod tests {
fn multihash_to_bytes() {
let multihash = &Multihash {
digest_function: DigestFunction::Ed25519Pub,
payload: hex_decode("1509A611AD6D97B01D871E58ED00C8FD7C3917B6CA61A8C2833A19E000AAC2E4")
.expect("Failed to decode hex."),
payload: ConstBytes::new(
hex_decode("1509A611AD6D97B01D871E58ED00C8FD7C3917B6CA61A8C2833A19E000AAC2E4")
.expect("Failed to decode hex."),
),
};
let bytes: Vec<u8> = multihash.try_into().expect("Failed to serialize multihash");
assert_eq!(
Expand All @@ -237,8 +241,10 @@ mod tests {
fn multihash_from_bytes() {
let multihash = Multihash {
digest_function: DigestFunction::Ed25519Pub,
payload: hex_decode("1509A611AD6D97B01D871E58ED00C8FD7C3917B6CA61A8C2833A19E000AAC2E4")
.expect("Failed to decode hex."),
payload: ConstBytes::new(
hex_decode("1509A611AD6D97B01D871E58ED00C8FD7C3917B6CA61A8C2833A19E000AAC2E4")
.expect("Failed to decode hex."),
),
};
let bytes =
hex_decode("ed01201509A611AD6D97B01D871E58ED00C8FD7C3917B6CA61A8C2833A19E000AAC2E4")
Expand Down
16 changes: 8 additions & 8 deletions crypto/src/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use std::collections::btree_set;

use derive_more::{Deref, DerefMut};
use iroha_macro::ffi_impl_opaque;
use iroha_primitives::const_bytes::ConstBytes;
use iroha_schema::{IntoSchema, TypeId};
use parity_scale_codec::{Decode, Encode, Input};
#[cfg(not(feature = "ffi_import"))]
Expand All @@ -34,23 +35,23 @@ ffi::ffi_item! {
#[cfg_attr(not(feature="ffi_import"), derive(derive_more::DebugCustom, Hash, Decode, Encode, Deserialize, Serialize, IntoSchema))]
#[cfg_attr(not(feature="ffi_import"), debug(
fmt = "{{ pub_key: {public_key}, payload: {} }}",
"hex::encode_upper(payload.as_slice())"
"hex::encode_upper(payload)"
))]
pub struct Signature {
/// Public key that is used for verification. Payload is verified by algorithm
/// that corresponds with the public key's digest function.
#[getset(get = "pub")]
public_key: PublicKey,
/// Signature payload
payload: Vec<u8>,
payload: ConstBytes,
}
}

#[ffi_impl_opaque]
impl Signature {
/// Key payload
pub fn payload(&self) -> &[u8] {
&self.payload
self.payload.as_ref()
}

/// Creates new [`Signature`] by signing payload via [`KeyPair::private_key`].
Expand All @@ -62,18 +63,17 @@ impl Signature {
let (public_key, private_key) = key_pair.into();

let algorithm: crate::Algorithm = private_key.digest_function();
let private_key = UrsaPrivateKey(private_key.payload);
let private_key = UrsaPrivateKey(private_key.payload.into_vec());

let signature = match algorithm {
crate::Algorithm::Ed25519 => Ed25519Sha512::new().sign(payload, &private_key),
crate::Algorithm::Secp256k1 => EcdsaSecp256k1Sha256::new().sign(payload, &private_key),
crate::Algorithm::BlsSmall => BlsSmall::new().sign(payload, &private_key),
crate::Algorithm::BlsNormal => BlsNormal::new().sign(payload, &private_key),
}?;

Ok(Self {
public_key,
payload: signature,
payload: ConstBytes::new(signature),
})
}

Expand Down Expand Up @@ -111,7 +111,7 @@ impl Signature {

/// Get the encrypted payload of this signature.
pub fn signature_payload(&self) -> &[u8] {
&self.payload
self.payload.as_ref()
}
}

Expand All @@ -124,7 +124,7 @@ impl From<Signature> for (PublicKey, Vec<u8>) {
payload: signature,
}: Signature,
) -> Self {
(public_key, signature)
(public_key, signature.into_vec())
}
}

Expand Down
1 change: 1 addition & 0 deletions primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ smallvec = { version = "1.10.0", default-features = false, features = ["serde",
smallstr = { version = "0.3.0", default-features = false, features = ["serde", "union"] }
thiserror = { workspace = true, optional = true }
displaydoc = { workspace = true }
hex = { workspace = true, features = ["alloc"] }


[dev-dependencies]
Expand Down
Loading

0 comments on commit 948c789

Please sign in to comment.