From dd8943b0383a00b31e36df090e10403dfb861236 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Wed, 29 Nov 2023 13:07:33 +0100 Subject: [PATCH 01/82] Add BlsPublicKey definition --- radix-engine-common/src/crypto/mod.rs | 2 + .../src/crypto/public_key_bls.rs | 90 +++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 radix-engine-common/src/crypto/public_key_bls.rs diff --git a/radix-engine-common/src/crypto/mod.rs b/radix-engine-common/src/crypto/mod.rs index b0fbe7825f4..ccf61122d32 100644 --- a/radix-engine-common/src/crypto/mod.rs +++ b/radix-engine-common/src/crypto/mod.rs @@ -2,6 +2,7 @@ mod blake2b; mod hash; mod hash_accumulator; mod public_key; +mod public_key_bls; mod public_key_ed25519; mod public_key_hash; mod public_key_secp256k1; @@ -10,6 +11,7 @@ pub use self::blake2b::*; pub use self::hash::*; pub use self::hash_accumulator::*; pub use self::public_key::*; +pub use self::public_key_bls::*; pub use self::public_key_ed25519::*; pub use self::public_key_hash::*; pub use self::public_key_secp256k1::*; diff --git a/radix-engine-common/src/crypto/public_key_bls.rs b/radix-engine-common/src/crypto/public_key_bls.rs new file mode 100644 index 00000000000..a099e367e3d --- /dev/null +++ b/radix-engine-common/src/crypto/public_key_bls.rs @@ -0,0 +1,90 @@ +use super::*; +use crate::internal_prelude::*; +#[cfg(feature = "radix_engine_fuzzing")] +use arbitrary::Arbitrary; + +/// Represents a BLS public key. +#[cfg_attr(feature = "radix_engine_fuzzing", derive(Arbitrary))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive( + Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Categorize, Encode, Decode, BasicDescribe, +)] +#[sbor(transparent)] +pub struct BlsPublicKey( + #[cfg_attr(feature = "serde", serde(with = "hex::serde"))] pub [u8; Self::LENGTH], +); +/* +impl Describe for BlsPublicKey { + const TYPE_ID: RustTypeId = + RustTypeId::WellKnown(well_known_scrypto_custom_types::BLS_PUBLIC_KEY_TYPE); + + fn type_data() -> ScryptoTypeData { + well_known_scrypto_custom_types::secp256k1_public_key_type_data() + } +} +*/ +impl BlsPublicKey { + pub const LENGTH: usize = 48; + + pub fn to_vec(&self) -> Vec { + self.0.to_vec() + } +} + +impl TryFrom<&[u8]> for BlsPublicKey { + type Error = ParseBlsPublicKeyError; + + fn try_from(slice: &[u8]) -> Result { + if slice.len() != BlsPublicKey::LENGTH { + return Err(ParseBlsPublicKeyError::InvalidLength(slice.len())); + } + + Ok(BlsPublicKey(copy_u8_array(slice))) + } +} + +//====== +// error +//====== + +/// Represents an error when parsing ED25519 public key from hex. +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum ParseBlsPublicKeyError { + InvalidHex(String), + InvalidLength(usize), +} + +#[cfg(not(feature = "alloc"))] +impl std::error::Error for ParseBlsPublicKeyError {} + +#[cfg(not(feature = "alloc"))] +impl fmt::Display for ParseBlsPublicKeyError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}", self) + } +} + +//====== +// text +//====== + +impl FromStr for BlsPublicKey { + type Err = ParseBlsPublicKeyError; + + fn from_str(s: &str) -> Result { + let bytes = hex::decode(s).map_err(|_| ParseBlsPublicKeyError::InvalidHex(s.to_owned()))?; + Self::try_from(bytes.as_slice()) + } +} + +impl fmt::Display for BlsPublicKey { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + write!(f, "{}", hex::encode(self.to_vec())) + } +} + +impl fmt::Debug for BlsPublicKey { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + write!(f, "{}", self) + } +} From 45aabaa8a9a4ab7ee93c9dec2873c158bf11b7ad Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Wed, 29 Nov 2023 15:13:11 +0100 Subject: [PATCH 02/82] Add BLS signature sign/verify support --- transaction/Cargo.toml | 1 + transaction/src/lib.rs | 1 + transaction/src/signing/bls/mod.rs | 5 ++ transaction/src/signing/bls/private_key.rs | 60 ++++++++++++++ transaction/src/signing/bls/signature.rs | 82 +++++++++++++++++++ transaction/src/signing/mod.rs | 1 + .../src/validation/signature_validator.rs | 15 ++++ 7 files changed, 165 insertions(+) create mode 100644 transaction/src/signing/bls/mod.rs create mode 100644 transaction/src/signing/bls/private_key.rs create mode 100644 transaction/src/signing/bls/signature.rs diff --git a/transaction/Cargo.toml b/transaction/Cargo.toml index 478cd679f4a..131d951bc72 100644 --- a/transaction/Cargo.toml +++ b/transaction/Cargo.toml @@ -12,6 +12,7 @@ radix-engine-common = { path = "../radix-engine-common", default-features = fals hex = { version = "0.4.3", default-features = false } ed25519-dalek = { version = "1.0.1", default-features = false, features = ["u64_backend"]} secp256k1 = { version = "0.24.0", default-features = false, features = ["global-context", "recovery"]} +blst = { version = "0.3.11", default-features = false } serde = { version = "1.0.144", default-features = false, optional = true } lazy_static = "1.4.0" strum = { version = "0.24", default-features = false, features = ["derive"] } diff --git a/transaction/src/lib.rs b/transaction/src/lib.rs index e2f9f7a6a48..dc60bce4923 100644 --- a/transaction/src/lib.rs +++ b/transaction/src/lib.rs @@ -19,6 +19,7 @@ pub mod prelude { // Exports from this crate pub use crate::builder::*; pub use crate::model::*; + pub use crate::signing::bls::*; pub use crate::signing::ed25519::*; pub use crate::signing::secp256k1::*; pub use crate::signing::{PrivateKey, Signer}; diff --git a/transaction/src/signing/bls/mod.rs b/transaction/src/signing/bls/mod.rs new file mode 100644 index 00000000000..83d7a82178e --- /dev/null +++ b/transaction/src/signing/bls/mod.rs @@ -0,0 +1,5 @@ +mod private_key; +mod signature; + +pub use private_key::*; +pub use signature::*; diff --git a/transaction/src/signing/bls/private_key.rs b/transaction/src/signing/bls/private_key.rs new file mode 100644 index 00000000000..a482fa225c6 --- /dev/null +++ b/transaction/src/signing/bls/private_key.rs @@ -0,0 +1,60 @@ +use super::BlsSignature; +use crate::internal_prelude::*; +use blst::min_pk::SecretKey; + +pub struct BlsPrivateKey(SecretKey); + +impl BlsPrivateKey { + pub const LENGTH: usize = 32; + + pub fn public_key(&self) -> BlsPublicKey { + BlsPublicKey(self.0.sk_to_pk().to_bytes()) + } + + pub fn sign(&self, msg_hash: &impl IsHash) -> BlsSignature { + let signature = self.0.sign(msg_hash.as_ref(), BLS_SCHEME, &[]).to_bytes(); + BlsSignature(signature) + } + + pub fn to_bytes(&self) -> Vec { + self.0.to_bytes().to_vec() + } + + pub fn from_bytes(slice: &[u8]) -> Result { + if slice.len() != BlsPrivateKey::LENGTH { + return Err(()); + } + Ok(Self(SecretKey::from_bytes(slice).map_err(|_| ())?)) + } + + pub fn from_u64(n: u64) -> Result { + let mut bytes = [0u8; BlsPrivateKey::LENGTH]; + (&mut bytes[BlsPrivateKey::LENGTH - 8..BlsPrivateKey::LENGTH]) + .copy_from_slice(&n.to_be_bytes()); + + Ok(Self(SecretKey::from_bytes(&bytes).map_err(|_| ())?)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::validation::verify_bls; + use radix_engine_interface::crypto::hash; + use sbor::rust::str::FromStr; + + #[test] + fn sign_and_verify() { + let test_sk = "408157791befddd702672dcfcfc99da3512f9c0ea818890fcb6ab749580ef2cf"; + let test_pk = "93b1aa7542a5423e21d8e84b4472c31664412cc604a666e9fdf03baf3c758e728c7a11576ebb01110ac39a0df95636e2"; + let test_message_hash = hash("Test"); + let test_signature = "a2ba96a1fc1e698b7688e077f171fbd7fe99c6bbf240b1421a08e3faa5d6b55523a18b8c77fba5830181dfec716edc3d18a8657bcadd0a83e3cafdad33998d10417f767c536b26b98df41d67ab416c761ad55438f23132a136fc82eb7b290571"; + let sk = BlsPrivateKey::from_bytes(&hex::decode(test_sk).unwrap()).unwrap(); + let pk = BlsPublicKey::from_str(test_pk).unwrap(); + let sig = BlsSignature::from_str(test_signature).unwrap(); + + assert_eq!(sk.public_key(), pk); + assert_eq!(sk.sign(&test_message_hash), sig); + assert!(verify_bls(&test_message_hash, &pk, &sig)); + } +} diff --git a/transaction/src/signing/bls/signature.rs b/transaction/src/signing/bls/signature.rs new file mode 100644 index 00000000000..ce8c86fdb1e --- /dev/null +++ b/transaction/src/signing/bls/signature.rs @@ -0,0 +1,82 @@ +use sbor::rust::borrow::ToOwned; +use sbor::rust::fmt; +use sbor::rust::str::FromStr; +use sbor::rust::string::String; +use sbor::rust::vec::Vec; +use sbor::*; +use utils::copy_u8_array; + +pub const BLS_SCHEME: &[u8] = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_"; + +/// Represents a BLS signature (variant with 96-byte signature and 48-byte public key) +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Sbor)] +pub struct BlsSignature( + #[cfg_attr(feature = "serde", serde(with = "hex::serde"))] pub [u8; Self::LENGTH], +); + +impl BlsSignature { + pub const LENGTH: usize = 96; + + pub fn to_vec(&self) -> Vec { + self.0.to_vec() + } +} + +impl TryFrom<&[u8]> for BlsSignature { + type Error = ParseBlsSignatureError; + + fn try_from(slice: &[u8]) -> Result { + if slice.len() != BlsSignature::LENGTH { + return Err(ParseBlsSignatureError::InvalidLength(slice.len())); + } + + Ok(BlsSignature(copy_u8_array(slice))) + } +} + +//====== +// error +//====== + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum ParseBlsSignatureError { + InvalidHex(String), + InvalidLength(usize), +} + +/// Represents an error when parsing ED25519 signature from hex. +#[cfg(not(feature = "alloc"))] +impl std::error::Error for ParseBlsSignatureError {} + +#[cfg(not(feature = "alloc"))] +impl fmt::Display for ParseBlsSignatureError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}", self) + } +} + +//====== +// text +//====== + +impl FromStr for BlsSignature { + type Err = ParseBlsSignatureError; + + fn from_str(s: &str) -> Result { + let bytes = hex::decode(s).map_err(|_| ParseBlsSignatureError::InvalidHex(s.to_owned()))?; + Self::try_from(bytes.as_slice()) + } +} + +impl fmt::Display for BlsSignature { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + write!(f, "{}", hex::encode(self.to_vec())) + } +} + +impl fmt::Debug for BlsSignature { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + write!(f, "{}", self) + } +} diff --git a/transaction/src/signing/mod.rs b/transaction/src/signing/mod.rs index ea46c9ebe4a..bb384380a2d 100644 --- a/transaction/src/signing/mod.rs +++ b/transaction/src/signing/mod.rs @@ -1,3 +1,4 @@ +pub mod bls; pub mod ed25519; pub mod secp256k1; mod signer; diff --git a/transaction/src/validation/signature_validator.rs b/transaction/src/validation/signature_validator.rs index 54f4490e096..c86a7f0e340 100644 --- a/transaction/src/validation/signature_validator.rs +++ b/transaction/src/validation/signature_validator.rs @@ -73,3 +73,18 @@ pub fn verify_ed25519( false } + +pub fn verify_bls(signed_hash: &Hash, public_key: &BlsPublicKey, signature: &BlsSignature) -> bool { + if let Ok(sig) = blst::min_pk::Signature::from_bytes(&signature.0) { + if let Ok(pk) = blst::min_pk::PublicKey::from_bytes(&public_key.0) { + let result = sig.verify(true, &signed_hash.0, BLS_SCHEME, &[], &pk, true); + + match result { + blst::BLST_ERROR::BLST_SUCCESS => return true, + _ => return false, + } + } + } + + false +} From 797929fd32936b3d2427cf6cbd6364dc7ec343ac Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Wed, 29 Nov 2023 15:29:20 +0100 Subject: [PATCH 03/82] Add BLS signature verify bench --- .../benches/transaction_validation.rs | 14 ++++++++++++++ transaction/src/signing/bls/signature.rs | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/radix-engine-tests/benches/transaction_validation.rs b/radix-engine-tests/benches/transaction_validation.rs index 067eca59a09..db912b484d5 100644 --- a/radix-engine-tests/benches/transaction_validation.rs +++ b/radix-engine-tests/benches/transaction_validation.rs @@ -31,6 +31,19 @@ fn bench_ed25519_validation(c: &mut Criterion) { }); } +fn bench_bls_validation(c: &mut Criterion) { + let message_hash = hash("This is a long message".repeat(100)); + let signer = BlsPrivateKey::from_u64(123123123123).unwrap(); + let public_key = signer.public_key(); + let signature = signer.sign(&message_hash); + + c.bench_function("transaction_validation::verify_bls", |b| { + b.iter(|| { + verify_bls(&message_hash, &public_key, &signature); + }) + }); +} + fn bench_transaction_validation(c: &mut Criterion) { let address_bech32_decoder: AddressBech32Decoder = AddressBech32Decoder::new(&NetworkDefinition::simulator()); @@ -85,6 +98,7 @@ criterion_group!( validation, bench_secp256k1_validation, bench_ed25519_validation, + bench_bls_validation, bench_transaction_validation, ); criterion_main!(validation); diff --git a/transaction/src/signing/bls/signature.rs b/transaction/src/signing/bls/signature.rs index ce8c86fdb1e..94e3b4376f5 100644 --- a/transaction/src/signing/bls/signature.rs +++ b/transaction/src/signing/bls/signature.rs @@ -45,7 +45,7 @@ pub enum ParseBlsSignatureError { InvalidLength(usize), } -/// Represents an error when parsing ED25519 signature from hex. +/// Represents an error when parsing BLS signature from hex. #[cfg(not(feature = "alloc"))] impl std::error::Error for ParseBlsSignatureError {} From 0aad1e3c612e354c3de70d025363512855bc09e1 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Wed, 29 Nov 2023 16:24:26 +0100 Subject: [PATCH 04/82] Add BLS key to custom well known types --- .../src/data/scrypto/custom_well_known_types.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/radix-engine-common/src/data/scrypto/custom_well_known_types.rs b/radix-engine-common/src/data/scrypto/custom_well_known_types.rs index 8068ca36fc4..9ceea940a51 100644 --- a/radix-engine-common/src/data/scrypto/custom_well_known_types.rs +++ b/radix-engine-common/src/data/scrypto/custom_well_known_types.rs @@ -407,6 +407,14 @@ create_well_known_lookup!( bytes_fixed_length_type_data(Ed25519PublicKey::LENGTH), ) ), + ( + BLS_PUBLIC_KEY, + KEY_TYPES_START + 3, + named_transparent( + "BlsPublicKey", + bytes_fixed_length_type_data(BlsPublicKey::LENGTH), + ) + ), ( PUBLIC_KEY_HASH, KEY_TYPES_START + 8, From 4bf4de3def8bb9c5babd66e17e7d229fe6386f19 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Wed, 29 Nov 2023 16:25:54 +0100 Subject: [PATCH 05/82] Implement Describe for BLS types --- radix-engine-common/src/crypto/public_key_bls.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/radix-engine-common/src/crypto/public_key_bls.rs b/radix-engine-common/src/crypto/public_key_bls.rs index a099e367e3d..4fe200e34ac 100644 --- a/radix-engine-common/src/crypto/public_key_bls.rs +++ b/radix-engine-common/src/crypto/public_key_bls.rs @@ -13,16 +13,16 @@ use arbitrary::Arbitrary; pub struct BlsPublicKey( #[cfg_attr(feature = "serde", serde(with = "hex::serde"))] pub [u8; Self::LENGTH], ); -/* + impl Describe for BlsPublicKey { const TYPE_ID: RustTypeId = RustTypeId::WellKnown(well_known_scrypto_custom_types::BLS_PUBLIC_KEY_TYPE); fn type_data() -> ScryptoTypeData { - well_known_scrypto_custom_types::secp256k1_public_key_type_data() + well_known_scrypto_custom_types::bls_public_key_type_data() } } -*/ + impl BlsPublicKey { pub const LENGTH: usize = 48; From d96dc4523b91b9fa062f691fac5c99093044e8ac Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Wed, 29 Nov 2023 17:19:51 +0100 Subject: [PATCH 06/82] Add tests for BLS custom types --- radix-engine-common/src/data/scrypto/custom_well_known_types.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/radix-engine-common/src/data/scrypto/custom_well_known_types.rs b/radix-engine-common/src/data/scrypto/custom_well_known_types.rs index 9ceea940a51..c9698cf7d63 100644 --- a/radix-engine-common/src/data/scrypto/custom_well_known_types.rs +++ b/radix-engine-common/src/data/scrypto/custom_well_known_types.rs @@ -628,6 +628,7 @@ mod tests { SECP256K1_PUBLIC_KEY_TYPE, Secp256k1PublicKey([0; Secp256k1PublicKey::LENGTH]), ); + test_equivalence(BLS_PUBLIC_KEY_TYPE, BlsPublicKey([0; BlsPublicKey::LENGTH])); test_equivalence( PUBLIC_KEY_HASH_TYPE, PublicKeyHash::Ed25519(Ed25519PublicKeyHash([0; Ed25519PublicKeyHash::LENGTH])), From 08db1a77430de39c43698fbc70a26a637ddce3d7 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Fri, 1 Dec 2023 13:32:58 +0100 Subject: [PATCH 07/82] Move crypto primitives to radix-engine-common Hashes, keys, signing, verification moved to 'radix-engine-common'. In 'transaction' above primitives are wrapped with RE specifics such as: - IntentSignature, - NotarySignature - etc. --- radix-engine-common/Cargo.toml | 5 +- .../src/crypto/bls12381}/mod.rs | 2 + .../src/crypto/bls12381}/private_key.rs | 2 - .../public_key.rs} | 1 - .../src/crypto/bls12381}/signature.rs | 0 .../src/crypto/ed25519}/mod.rs | 2 + .../src/crypto}/ed25519/private_key.rs | 2 - .../public_key.rs} | 1 - .../src/crypto}/ed25519/signature.rs | 0 radix-engine-common/src/crypto/mod.rs | 20 ++++-- radix-engine-common/src/crypto/private_key.rs | 27 ++++++++ .../src/crypto/secp256k1}/mod.rs | 2 + .../src/crypto}/secp256k1/private_key.rs | 2 - .../public_key.rs} | 1 - .../src/crypto}/secp256k1/signature.rs | 0 radix-engine-common/src/crypto/signature.rs | 67 +++++++++++++++++++ .../src/crypto}/signature_validator.rs | 0 .../src/crypto}/signer.rs | 26 ------- .../src/crypto}/signing/mod.rs | 0 scrypto-unit/src/test_runner.rs | 1 - transaction/Cargo.toml | 7 +- .../src/builder/transaction_builder.rs | 3 +- transaction/src/lib.rs | 5 -- transaction/src/manifest/e2e.rs | 1 - transaction/src/manifest/generator.rs | 2 +- transaction/src/model/v1/intent_signatures.rs | 41 ------------ transaction/src/model/v1/notary_signature.rs | 24 ------- transaction/src/model/versioned.rs | 1 - transaction/src/validation/mod.rs | 2 - .../src/validation/transaction_validator.rs | 6 +- 30 files changed, 123 insertions(+), 130 deletions(-) rename {transaction/src/signing/ed25519 => radix-engine-common/src/crypto/bls12381}/mod.rs (66%) rename {transaction/src/signing/bls => radix-engine-common/src/crypto/bls12381}/private_key.rs (96%) rename radix-engine-common/src/crypto/{public_key_bls.rs => bls12381/public_key.rs} (99%) rename {transaction/src/signing/bls => radix-engine-common/src/crypto/bls12381}/signature.rs (100%) rename {transaction/src/signing/secp256k1 => radix-engine-common/src/crypto/ed25519}/mod.rs (66%) rename {transaction/src/signing => radix-engine-common/src/crypto}/ed25519/private_key.rs (96%) rename radix-engine-common/src/crypto/{public_key_ed25519.rs => ed25519/public_key.rs} (99%) rename {transaction/src/signing => radix-engine-common/src/crypto}/ed25519/signature.rs (100%) create mode 100644 radix-engine-common/src/crypto/private_key.rs rename {transaction/src/signing/bls => radix-engine-common/src/crypto/secp256k1}/mod.rs (66%) rename {transaction/src/signing => radix-engine-common/src/crypto}/secp256k1/private_key.rs (96%) rename radix-engine-common/src/crypto/{public_key_secp256k1.rs => secp256k1/public_key.rs} (99%) rename {transaction/src/signing => radix-engine-common/src/crypto}/secp256k1/signature.rs (100%) create mode 100644 radix-engine-common/src/crypto/signature.rs rename {transaction/src/validation => radix-engine-common/src/crypto}/signature_validator.rs (100%) rename {transaction/src/signing => radix-engine-common/src/crypto}/signer.rs (74%) rename {transaction/src => radix-engine-common/src/crypto}/signing/mod.rs (100%) diff --git a/radix-engine-common/Cargo.toml b/radix-engine-common/Cargo.toml index 203f26860e8..5f8d95c287c 100644 --- a/radix-engine-common/Cargo.toml +++ b/radix-engine-common/Cargo.toml @@ -24,6 +24,9 @@ arbitrary = { version = "1.3.0", features = ["derive"], optional = true } # Fast alternative to bigint but unfortunately not cross-compiled to WASM rug = { version = "1.18", optional = true } ethnum = {version = "1.3.2", default-features = false, optional = true } +ed25519-dalek = { version = "1.0.1", default-features = false, features = ["u64_backend"]} +secp256k1 = { version = "0.24.0", default-features = false, features = ["global-context", "recovery"]} +blst = { version = "0.3.11", default-features = false } [dev-dependencies] serde_json = { version = "1.0.81", default-features = false } @@ -42,7 +45,7 @@ harness = false default = ["std"] serde = ["dep:serde", "utils/serde", "sbor/serde", "hex/serde"] std = ["hex/std", "sbor/std", "utils/std", "radix-engine-derive/std", "serde_json/std", "blake2/std"] -alloc = ["hex/alloc", "sbor/alloc", "utils/alloc", "radix-engine-derive/alloc", "serde_json/alloc", "lazy_static/spin_no_std"] +alloc = ["hex/alloc", "sbor/alloc", "utils/alloc", "radix-engine-derive/alloc", "serde_json/alloc", "ed25519-dalek/alloc", "secp256k1/alloc", "lazy_static/spin_no_std"] # This flag is set by fuzz-tests framework and it is used to disable/enable some optional features # to let fuzzing work diff --git a/transaction/src/signing/ed25519/mod.rs b/radix-engine-common/src/crypto/bls12381/mod.rs similarity index 66% rename from transaction/src/signing/ed25519/mod.rs rename to radix-engine-common/src/crypto/bls12381/mod.rs index 83d7a82178e..d83eaa9db8e 100644 --- a/transaction/src/signing/ed25519/mod.rs +++ b/radix-engine-common/src/crypto/bls12381/mod.rs @@ -1,5 +1,7 @@ mod private_key; +mod public_key; mod signature; pub use private_key::*; +pub use public_key::*; pub use signature::*; diff --git a/transaction/src/signing/bls/private_key.rs b/radix-engine-common/src/crypto/bls12381/private_key.rs similarity index 96% rename from transaction/src/signing/bls/private_key.rs rename to radix-engine-common/src/crypto/bls12381/private_key.rs index a482fa225c6..0c896ac4611 100644 --- a/transaction/src/signing/bls/private_key.rs +++ b/radix-engine-common/src/crypto/bls12381/private_key.rs @@ -39,8 +39,6 @@ impl BlsPrivateKey { #[cfg(test)] mod tests { use super::*; - use crate::validation::verify_bls; - use radix_engine_interface::crypto::hash; use sbor::rust::str::FromStr; #[test] diff --git a/radix-engine-common/src/crypto/public_key_bls.rs b/radix-engine-common/src/crypto/bls12381/public_key.rs similarity index 99% rename from radix-engine-common/src/crypto/public_key_bls.rs rename to radix-engine-common/src/crypto/bls12381/public_key.rs index 4fe200e34ac..79134f55d8b 100644 --- a/radix-engine-common/src/crypto/public_key_bls.rs +++ b/radix-engine-common/src/crypto/bls12381/public_key.rs @@ -1,4 +1,3 @@ -use super::*; use crate::internal_prelude::*; #[cfg(feature = "radix_engine_fuzzing")] use arbitrary::Arbitrary; diff --git a/transaction/src/signing/bls/signature.rs b/radix-engine-common/src/crypto/bls12381/signature.rs similarity index 100% rename from transaction/src/signing/bls/signature.rs rename to radix-engine-common/src/crypto/bls12381/signature.rs diff --git a/transaction/src/signing/secp256k1/mod.rs b/radix-engine-common/src/crypto/ed25519/mod.rs similarity index 66% rename from transaction/src/signing/secp256k1/mod.rs rename to radix-engine-common/src/crypto/ed25519/mod.rs index 83d7a82178e..d83eaa9db8e 100644 --- a/transaction/src/signing/secp256k1/mod.rs +++ b/radix-engine-common/src/crypto/ed25519/mod.rs @@ -1,5 +1,7 @@ mod private_key; +mod public_key; mod signature; pub use private_key::*; +pub use public_key::*; pub use signature::*; diff --git a/transaction/src/signing/ed25519/private_key.rs b/radix-engine-common/src/crypto/ed25519/private_key.rs similarity index 96% rename from transaction/src/signing/ed25519/private_key.rs rename to radix-engine-common/src/crypto/ed25519/private_key.rs index 30abd27438c..5ac75758719 100644 --- a/transaction/src/signing/ed25519/private_key.rs +++ b/radix-engine-common/src/crypto/ed25519/private_key.rs @@ -45,8 +45,6 @@ impl Ed25519PrivateKey { #[cfg(test)] mod tests { use super::*; - use crate::validation::verify_ed25519; - use radix_engine_interface::crypto::hash; use sbor::rust::str::FromStr; #[test] diff --git a/radix-engine-common/src/crypto/public_key_ed25519.rs b/radix-engine-common/src/crypto/ed25519/public_key.rs similarity index 99% rename from radix-engine-common/src/crypto/public_key_ed25519.rs rename to radix-engine-common/src/crypto/ed25519/public_key.rs index 147af2af93e..35ba3d5e93f 100644 --- a/radix-engine-common/src/crypto/public_key_ed25519.rs +++ b/radix-engine-common/src/crypto/ed25519/public_key.rs @@ -1,4 +1,3 @@ -use super::*; use crate::internal_prelude::*; #[cfg(feature = "radix_engine_fuzzing")] use arbitrary::Arbitrary; diff --git a/transaction/src/signing/ed25519/signature.rs b/radix-engine-common/src/crypto/ed25519/signature.rs similarity index 100% rename from transaction/src/signing/ed25519/signature.rs rename to radix-engine-common/src/crypto/ed25519/signature.rs diff --git a/radix-engine-common/src/crypto/mod.rs b/radix-engine-common/src/crypto/mod.rs index ccf61122d32..16127526e7b 100644 --- a/radix-engine-common/src/crypto/mod.rs +++ b/radix-engine-common/src/crypto/mod.rs @@ -1,17 +1,25 @@ mod blake2b; +mod bls12381; +mod ed25519; mod hash; mod hash_accumulator; +mod private_key; mod public_key; -mod public_key_bls; -mod public_key_ed25519; mod public_key_hash; -mod public_key_secp256k1; +mod secp256k1; +mod signature; +mod signature_validator; +mod signer; pub use self::blake2b::*; +pub use self::bls12381::*; +pub use self::ed25519::*; pub use self::hash::*; pub use self::hash_accumulator::*; +pub use self::private_key::*; pub use self::public_key::*; -pub use self::public_key_bls::*; -pub use self::public_key_ed25519::*; pub use self::public_key_hash::*; -pub use self::public_key_secp256k1::*; +pub use self::secp256k1::*; +pub use self::signature::*; +pub use self::signature_validator::*; +pub use self::signer::*; diff --git a/radix-engine-common/src/crypto/private_key.rs b/radix-engine-common/src/crypto/private_key.rs new file mode 100644 index 00000000000..3aac81fb919 --- /dev/null +++ b/radix-engine-common/src/crypto/private_key.rs @@ -0,0 +1,27 @@ +use crate::internal_prelude::*; + +pub enum PrivateKey { + Secp256k1(Secp256k1PrivateKey), + Ed25519(Ed25519PrivateKey), +} + +impl PrivateKey { + pub fn public_key(&self) -> PublicKey { + match self { + PrivateKey::Secp256k1(key) => key.public_key().into(), + PrivateKey::Ed25519(key) => key.public_key().into(), + } + } +} + +impl From for PrivateKey { + fn from(public_key: Secp256k1PrivateKey) -> Self { + Self::Secp256k1(public_key) + } +} + +impl From for PrivateKey { + fn from(public_key: Ed25519PrivateKey) -> Self { + Self::Ed25519(public_key) + } +} diff --git a/transaction/src/signing/bls/mod.rs b/radix-engine-common/src/crypto/secp256k1/mod.rs similarity index 66% rename from transaction/src/signing/bls/mod.rs rename to radix-engine-common/src/crypto/secp256k1/mod.rs index 83d7a82178e..d83eaa9db8e 100644 --- a/transaction/src/signing/bls/mod.rs +++ b/radix-engine-common/src/crypto/secp256k1/mod.rs @@ -1,5 +1,7 @@ mod private_key; +mod public_key; mod signature; pub use private_key::*; +pub use public_key::*; pub use signature::*; diff --git a/transaction/src/signing/secp256k1/private_key.rs b/radix-engine-common/src/crypto/secp256k1/private_key.rs similarity index 96% rename from transaction/src/signing/secp256k1/private_key.rs rename to radix-engine-common/src/crypto/secp256k1/private_key.rs index 2466afd7d13..3446c9b13cc 100644 --- a/transaction/src/signing/secp256k1/private_key.rs +++ b/radix-engine-common/src/crypto/secp256k1/private_key.rs @@ -56,8 +56,6 @@ impl Secp256k1PrivateKey { #[cfg(test)] mod tests { use super::*; - use crate::validation::verify_secp256k1; - use radix_engine_interface::crypto::hash; use sbor::rust::str::FromStr; #[test] diff --git a/radix-engine-common/src/crypto/public_key_secp256k1.rs b/radix-engine-common/src/crypto/secp256k1/public_key.rs similarity index 99% rename from radix-engine-common/src/crypto/public_key_secp256k1.rs rename to radix-engine-common/src/crypto/secp256k1/public_key.rs index db9dbd860e8..e6a62de71f4 100644 --- a/radix-engine-common/src/crypto/public_key_secp256k1.rs +++ b/radix-engine-common/src/crypto/secp256k1/public_key.rs @@ -1,4 +1,3 @@ -use super::*; use crate::internal_prelude::*; #[cfg(feature = "radix_engine_fuzzing")] use arbitrary::Arbitrary; diff --git a/transaction/src/signing/secp256k1/signature.rs b/radix-engine-common/src/crypto/secp256k1/signature.rs similarity index 100% rename from transaction/src/signing/secp256k1/signature.rs rename to radix-engine-common/src/crypto/secp256k1/signature.rs diff --git a/radix-engine-common/src/crypto/signature.rs b/radix-engine-common/src/crypto/signature.rs new file mode 100644 index 00000000000..f75d5a981f1 --- /dev/null +++ b/radix-engine-common/src/crypto/signature.rs @@ -0,0 +1,67 @@ +use super::*; +use crate::internal_prelude::*; + +/// Represents any natively supported signature. +#[cfg_attr( + feature = "serde", + derive(serde::Serialize, serde::Deserialize), + serde(tag = "type", content = "signature") +)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Sbor)] +pub enum SignatureV1 { + Secp256k1(Secp256k1Signature), + Ed25519(Ed25519Signature), +} + +impl From for SignatureV1 { + fn from(signature: Secp256k1Signature) -> Self { + Self::Secp256k1(signature) + } +} + +impl From for SignatureV1 { + fn from(signature: Ed25519Signature) -> Self { + Self::Ed25519(signature) + } +} + +/// Represents any natively supported signature, including public key. +#[cfg_attr( + feature = "serde", + derive(serde::Serialize, serde::Deserialize), + serde(tag = "type") +)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, ManifestSbor, ScryptoSbor)] +pub enum SignatureWithPublicKeyV1 { + Secp256k1 { + signature: Secp256k1Signature, + }, + Ed25519 { + public_key: Ed25519PublicKey, + signature: Ed25519Signature, + }, +} + +impl SignatureWithPublicKeyV1 { + pub fn signature(&self) -> SignatureV1 { + match &self { + Self::Secp256k1 { signature } => signature.clone().into(), + Self::Ed25519 { signature, .. } => signature.clone().into(), + } + } +} + +impl From for SignatureWithPublicKeyV1 { + fn from(signature: Secp256k1Signature) -> Self { + Self::Secp256k1 { signature } + } +} + +impl From<(Ed25519PublicKey, Ed25519Signature)> for SignatureWithPublicKeyV1 { + fn from((public_key, signature): (Ed25519PublicKey, Ed25519Signature)) -> Self { + Self::Ed25519 { + public_key, + signature, + } + } +} diff --git a/transaction/src/validation/signature_validator.rs b/radix-engine-common/src/crypto/signature_validator.rs similarity index 100% rename from transaction/src/validation/signature_validator.rs rename to radix-engine-common/src/crypto/signature_validator.rs diff --git a/transaction/src/signing/signer.rs b/radix-engine-common/src/crypto/signer.rs similarity index 74% rename from transaction/src/signing/signer.rs rename to radix-engine-common/src/crypto/signer.rs index 2d5a9731c6f..4bfa1b38277 100644 --- a/transaction/src/signing/signer.rs +++ b/radix-engine-common/src/crypto/signer.rs @@ -1,32 +1,6 @@ use crate::internal_prelude::*; use radix_engine_common::prelude::IsHash; -pub enum PrivateKey { - Secp256k1(Secp256k1PrivateKey), - Ed25519(Ed25519PrivateKey), -} - -impl PrivateKey { - pub fn public_key(&self) -> PublicKey { - match self { - PrivateKey::Secp256k1(key) => key.public_key().into(), - PrivateKey::Ed25519(key) => key.public_key().into(), - } - } -} - -impl From for PrivateKey { - fn from(public_key: Secp256k1PrivateKey) -> Self { - Self::Secp256k1(public_key) - } -} - -impl From for PrivateKey { - fn from(public_key: Ed25519PrivateKey) -> Self { - Self::Ed25519(public_key) - } -} - pub trait Signer { fn public_key(&self) -> PublicKey; fn sign_without_public_key(&self, message_hash: &impl IsHash) -> SignatureV1; diff --git a/transaction/src/signing/mod.rs b/radix-engine-common/src/crypto/signing/mod.rs similarity index 100% rename from transaction/src/signing/mod.rs rename to radix-engine-common/src/crypto/signing/mod.rs diff --git a/scrypto-unit/src/test_runner.rs b/scrypto-unit/src/test_runner.rs index 867b53c8562..1a38fd6a445 100644 --- a/scrypto-unit/src/test_runner.rs +++ b/scrypto-unit/src/test_runner.rs @@ -57,7 +57,6 @@ use radix_engine_stores::hash_tree_support::HashTreeUpdatingDatabase; use radix_engine_stores::memory_db::InMemorySubstateDatabase; use scrypto::prelude::*; use transaction::prelude::*; -use transaction::signing::secp256k1::Secp256k1PrivateKey; use transaction::validation::{ NotarizedTransactionValidator, TransactionValidator, ValidationConfig, }; diff --git a/transaction/Cargo.toml b/transaction/Cargo.toml index 131d951bc72..6add10ae61f 100644 --- a/transaction/Cargo.toml +++ b/transaction/Cargo.toml @@ -10,9 +10,6 @@ radix-engine-interface = { path = "../radix-engine-interface", default-features radix-engine-common = { path = "../radix-engine-common", default-features = false } hex = { version = "0.4.3", default-features = false } -ed25519-dalek = { version = "1.0.1", default-features = false, features = ["u64_backend"]} -secp256k1 = { version = "0.24.0", default-features = false, features = ["global-context", "recovery"]} -blst = { version = "0.3.11", default-features = false } serde = { version = "1.0.144", default-features = false, optional = true } lazy_static = "1.4.0" strum = { version = "0.24", default-features = false, features = ["derive"] } @@ -25,8 +22,8 @@ scrypto-derive = { path = "../scrypto-derive" } [features] # You should enable either `std` or `alloc` default = ["std"] -std = ["sbor/std", "utils/std", "radix-engine-interface/std", "radix-engine-common/std", "hex/std", "ed25519-dalek/std", "secp256k1/std"] -alloc = ["sbor/alloc", "utils/alloc", "radix-engine-interface/alloc", "radix-engine-common/alloc", "hex/alloc", "ed25519-dalek/alloc", "secp256k1/alloc", "lazy_static/spin_no_std"] +std = ["sbor/std", "utils/std", "radix-engine-interface/std", "radix-engine-common/std", "hex/std"] +alloc = ["sbor/alloc", "utils/alloc", "radix-engine-interface/alloc", "radix-engine-common/alloc", "hex/alloc", "lazy_static/spin_no_std"] serde = ["serde/derive"] dump_manifest_to_file = [] diff --git a/transaction/src/builder/transaction_builder.rs b/transaction/src/builder/transaction_builder.rs index e16f10d8049..13b8dd2f08a 100644 --- a/transaction/src/builder/transaction_builder.rs +++ b/transaction/src/builder/transaction_builder.rs @@ -1,5 +1,5 @@ +use crate::internal_prelude::*; use crate::model::*; -use crate::signing::Signer; pub struct TransactionBuilder { manifest: Option, @@ -122,7 +122,6 @@ mod tests { use super::*; use crate::builder::*; - use crate::signing::secp256k1::Secp256k1PrivateKey; #[test] fn notary_as_signatory() { diff --git a/transaction/src/lib.rs b/transaction/src/lib.rs index dc60bce4923..4e024de413a 100644 --- a/transaction/src/lib.rs +++ b/transaction/src/lib.rs @@ -3,7 +3,6 @@ pub mod data; pub mod errors; pub mod manifest; pub mod model; -pub mod signing; pub mod validation; /// Each module should have its own prelude, which: @@ -19,10 +18,6 @@ pub mod prelude { // Exports from this crate pub use crate::builder::*; pub use crate::model::*; - pub use crate::signing::bls::*; - pub use crate::signing::ed25519::*; - pub use crate::signing::secp256k1::*; - pub use crate::signing::{PrivateKey, Signer}; } // Extra things which this crate wants which upstream crates likely don't diff --git a/transaction/src/manifest/e2e.rs b/transaction/src/manifest/e2e.rs index 94f6ec49bfd..347444a68f1 100644 --- a/transaction/src/manifest/e2e.rs +++ b/transaction/src/manifest/e2e.rs @@ -6,7 +6,6 @@ pub mod tests { use super::*; use crate::internal_prelude::*; use crate::manifest::*; - use crate::signing::ed25519::Ed25519PrivateKey; use radix_engine_interface::api::node_modules::ModuleConfig; use radix_engine_interface::blueprints::resource::RoleAssignmentInit; use radix_engine_interface::blueprints::resource::{NonFungibleResourceRoles, OwnerRole}; diff --git a/transaction/src/manifest/generator.rs b/transaction/src/manifest/generator.rs index c84d25dcc9a..928cee4e8bb 100644 --- a/transaction/src/manifest/generator.rs +++ b/transaction/src/manifest/generator.rs @@ -1486,7 +1486,6 @@ mod tests { use super::*; use crate::manifest::lexer::tokenize; use crate::manifest::parser::{Parser, ParserError, PARSER_MAX_DEPTH}; - use crate::signing::secp256k1::Secp256k1PrivateKey; use radix_engine_common::constants::CONSENSUS_MANAGER; use radix_engine_common::manifest_args; use radix_engine_common::types::{ComponentAddress, PackageAddress}; @@ -1498,6 +1497,7 @@ mod tests { NonFungibleDataSchema, NonFungibleResourceManagerMintManifestInput, NonFungibleResourceManagerMintRuidManifestInput, }; + use radix_engine_interface::crypto::Secp256k1PrivateKey; use radix_engine_interface::network::NetworkDefinition; use radix_engine_interface::schema::BlueprintStateSchemaInit; use radix_engine_interface::types::{NonFungibleData, PackageRoyaltyConfig}; diff --git a/transaction/src/model/v1/intent_signatures.rs b/transaction/src/model/v1/intent_signatures.rs index 1d7fdb3b3b5..82b41d4a70b 100644 --- a/transaction/src/model/v1/intent_signatures.rs +++ b/transaction/src/model/v1/intent_signatures.rs @@ -1,47 +1,6 @@ use super::*; use crate::internal_prelude::*; -/// Represents any natively supported signature, including public key. -#[cfg_attr( - feature = "serde", - derive(serde::Serialize, serde::Deserialize), - serde(tag = "type") -)] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, ManifestSbor, ScryptoSbor)] -pub enum SignatureWithPublicKeyV1 { - Secp256k1 { - signature: Secp256k1Signature, - }, - Ed25519 { - public_key: Ed25519PublicKey, - signature: Ed25519Signature, - }, -} - -impl SignatureWithPublicKeyV1 { - pub fn signature(&self) -> SignatureV1 { - match &self { - Self::Secp256k1 { signature } => signature.clone().into(), - Self::Ed25519 { signature, .. } => signature.clone().into(), - } - } -} - -impl From for SignatureWithPublicKeyV1 { - fn from(signature: Secp256k1Signature) -> Self { - Self::Secp256k1 { signature } - } -} - -impl From<(Ed25519PublicKey, Ed25519Signature)> for SignatureWithPublicKeyV1 { - fn from((public_key, signature): (Ed25519PublicKey, Ed25519Signature)) -> Self { - Self::Ed25519 { - public_key, - signature, - } - } -} - #[derive(Debug, Clone, Eq, PartialEq, ManifestSbor)] #[sbor(transparent)] pub struct IntentSignatureV1(pub SignatureWithPublicKeyV1); diff --git a/transaction/src/model/v1/notary_signature.rs b/transaction/src/model/v1/notary_signature.rs index 20136055c5f..ce48343a908 100644 --- a/transaction/src/model/v1/notary_signature.rs +++ b/transaction/src/model/v1/notary_signature.rs @@ -1,30 +1,6 @@ use super::*; use crate::internal_prelude::*; -/// Represents any natively supported signature. -#[cfg_attr( - feature = "serde", - derive(serde::Serialize, serde::Deserialize), - serde(tag = "type", content = "signature") -)] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Sbor)] -pub enum SignatureV1 { - Secp256k1(Secp256k1Signature), - Ed25519(Ed25519Signature), -} - -impl From for SignatureV1 { - fn from(signature: Secp256k1Signature) -> Self { - Self::Secp256k1(signature) - } -} - -impl From for SignatureV1 { - fn from(signature: Ed25519Signature) -> Self { - Self::Ed25519(signature) - } -} - #[derive(Debug, Clone, Eq, PartialEq, ManifestSbor)] #[sbor(transparent)] pub struct NotarySignatureV1(pub SignatureV1); diff --git a/transaction/src/model/versioned.rs b/transaction/src/model/versioned.rs index c65e18edc66..14a40dd67f0 100644 --- a/transaction/src/model/versioned.rs +++ b/transaction/src/model/versioned.rs @@ -67,7 +67,6 @@ mod tests { use super::*; use crate::manifest::e2e::tests::print_blob; use crate::model::*; - use crate::{signing::ed25519::Ed25519PrivateKey, signing::secp256k1::Secp256k1PrivateKey}; fn hash_manifest_encoded_without_prefix_byte(value: T) -> Hash { hash(&manifest_encode(&value).unwrap()[1..]) diff --git a/transaction/src/validation/mod.rs b/transaction/src/validation/mod.rs index 02c4dd852af..2aa324c3c0f 100644 --- a/transaction/src/validation/mod.rs +++ b/transaction/src/validation/mod.rs @@ -1,9 +1,7 @@ mod id_allocator; mod id_validator; -mod signature_validator; mod transaction_validator; pub use id_allocator::*; pub use id_validator::*; -pub use signature_validator::*; pub use transaction_validator::*; diff --git a/transaction/src/validation/transaction_validator.rs b/transaction/src/validation/transaction_validator.rs index 4c0ac989fd1..041aa385ccb 100644 --- a/transaction/src/validation/transaction_validator.rs +++ b/transaction/src/validation/transaction_validator.rs @@ -1,5 +1,4 @@ use crate::internal_prelude::*; -use crate::validation::*; pub trait TransactionValidator { type Validated; @@ -440,10 +439,7 @@ mod tests { use radix_engine_interface::network::NetworkDefinition; use super::*; - use crate::{ - builder::ManifestBuilder, builder::TransactionBuilder, - signing::secp256k1::Secp256k1PrivateKey, - }; + use crate::{builder::ManifestBuilder, builder::TransactionBuilder}; macro_rules! assert_invalid_tx { ($result: expr, ($start_epoch: expr, $end_epoch: expr, $nonce: expr, $signers: expr, $notary: expr)) => {{ From 57e9710c1caa912ca4218859bbcbef6df6fe8bcb Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Fri, 1 Dec 2023 13:49:02 +0100 Subject: [PATCH 08/82] Fix compilation issues in radix-engine-tests --- radix-engine-tests/benches/resources_usage.rs | 1 - radix-engine-tests/benches/transaction_processing.rs | 1 - radix-engine-tests/benches/transfer.rs | 1 - radix-engine-tests/tests/application/common_transactions.rs | 1 - radix-engine-tests/tests/application/fuzz_transactions.rs | 1 - radix-engine-tests/tests/blueprints/account_deposit_modes.rs | 1 - .../tests/blueprints/native_blueprint_call_validator.rs | 5 +---- .../tests/kernel/transaction_multi_threaded.rs | 1 - radix-engine-tests/tests/system/bootstrap.rs | 1 - radix-engine-tests/tests/system/events.rs | 1 - radix-engine-tests/tests/system/metadata_identity.rs | 1 - radix-engine-tests/tests/system/typed_substate_layout.rs | 1 - 12 files changed, 1 insertion(+), 15 deletions(-) diff --git a/radix-engine-tests/benches/resources_usage.rs b/radix-engine-tests/benches/resources_usage.rs index d2a95140db9..b6b179fc07f 100644 --- a/radix-engine-tests/benches/resources_usage.rs +++ b/radix-engine-tests/benches/resources_usage.rs @@ -11,7 +11,6 @@ use radix_engine_interface::dec; use radix_engine_interface::rule; use transaction::builder::ManifestBuilder; use transaction::model::TestTransaction; -use transaction::signing::secp256k1::Secp256k1PrivateKey; #[derive(Eq, PartialEq, Hash, Clone, Copy)] struct Bytes(usize); diff --git a/radix-engine-tests/benches/transaction_processing.rs b/radix-engine-tests/benches/transaction_processing.rs index 5c0cfc6a22b..22cf5cd049f 100644 --- a/radix-engine-tests/benches/transaction_processing.rs +++ b/radix-engine-tests/benches/transaction_processing.rs @@ -16,7 +16,6 @@ use transaction::model::{ TransactionPayloadPreparable, }; use transaction::prelude::*; -use transaction::signing::secp256k1::Secp256k1PrivateKey; fn decompile_notarized_intent_benchmarks(c: &mut Criterion) { let compiled_transaction = compiled_notarized_transaction(); diff --git a/radix-engine-tests/benches/transfer.rs b/radix-engine-tests/benches/transfer.rs index 3abe4ea25d5..1d61c980098 100644 --- a/radix-engine-tests/benches/transfer.rs +++ b/radix-engine-tests/benches/transfer.rs @@ -11,7 +11,6 @@ use radix_engine_interface::rule; use radix_engine_stores::memory_db::InMemorySubstateDatabase; use transaction::model::TestTransaction; use transaction::prelude::*; -use transaction::signing::secp256k1::Secp256k1PrivateKey; fn bench_transfer(c: &mut Criterion) { // Set up environment. diff --git a/radix-engine-tests/tests/application/common_transactions.rs b/radix-engine-tests/tests/application/common_transactions.rs index c784d2df4e1..bc6937732ee 100644 --- a/radix-engine-tests/tests/application/common_transactions.rs +++ b/radix-engine-tests/tests/application/common_transactions.rs @@ -10,7 +10,6 @@ use scrypto::NonFungibleData; use scrypto_unit::TestRunnerBuilder; use transaction::manifest::{compile, BlobProvider}; use transaction::prelude::*; -use transaction::signing::secp256k1::Secp256k1PrivateKey; use utils::ContextualDisplay; macro_rules! replace_variables { diff --git a/radix-engine-tests/tests/application/fuzz_transactions.rs b/radix-engine-tests/tests/application/fuzz_transactions.rs index f2b58bab90c..c7b2d76707b 100644 --- a/radix-engine-tests/tests/application/fuzz_transactions.rs +++ b/radix-engine-tests/tests/application/fuzz_transactions.rs @@ -13,7 +13,6 @@ use rand_chacha::rand_core::SeedableRng; use rand_chacha::ChaCha8Rng; use transaction::model::{NotarizedTransactionV1, TransactionHeaderV1, TransactionPayload}; use transaction::prelude::*; -use transaction::signing::secp256k1::Secp256k1PrivateKey; use transaction::validation::{ NotarizedTransactionValidator, TransactionValidator, ValidationConfig, }; diff --git a/radix-engine-tests/tests/blueprints/account_deposit_modes.rs b/radix-engine-tests/tests/blueprints/account_deposit_modes.rs index 8a3d788467a..d1c2471cb1a 100644 --- a/radix-engine-tests/tests/blueprints/account_deposit_modes.rs +++ b/radix-engine-tests/tests/blueprints/account_deposit_modes.rs @@ -6,7 +6,6 @@ use radix_engine_interface::blueprints::account::*; use radix_engine_queries::typed_substate_layout::AccountError; use scrypto_unit::{DefaultTestRunner, TestRunnerBuilder}; use transaction::prelude::*; -use transaction::signing::secp256k1::Secp256k1PrivateKey; #[test] fn account_deposit_method_is_callable_with_owner_signature() { diff --git a/radix-engine-tests/tests/blueprints/native_blueprint_call_validator.rs b/radix-engine-tests/tests/blueprints/native_blueprint_call_validator.rs index e70d5780791..7a5f4f098b1 100644 --- a/radix-engine-tests/tests/blueprints/native_blueprint_call_validator.rs +++ b/radix-engine-tests/tests/blueprints/native_blueprint_call_validator.rs @@ -5,11 +5,8 @@ use radix_engine::utils::{ }; use radix_engine_common::prelude::NetworkDefinition; use scrypto::prelude::*; +use transaction::manifest::{compile, MockBlobProvider}; use transaction::prelude::*; -use transaction::{ - manifest::{compile, MockBlobProvider}, - signing::secp256k1::Secp256k1PrivateKey, -}; use walkdir::WalkDir; use transaction::manifest::e2e::apply_address_replacements; diff --git a/radix-engine-tests/tests/kernel/transaction_multi_threaded.rs b/radix-engine-tests/tests/kernel/transaction_multi_threaded.rs index d10f4ee8921..622fd224977 100644 --- a/radix-engine-tests/tests/kernel/transaction_multi_threaded.rs +++ b/radix-engine-tests/tests/kernel/transaction_multi_threaded.rs @@ -11,7 +11,6 @@ mod multi_threaded_test { use radix_engine_stores::memory_db::InMemorySubstateDatabase; use transaction::model::TestTransaction; use transaction::prelude::*; - use transaction::signing::secp256k1::Secp256k1PrivateKey; // using crossbeam for its scoped thread feature, which allows non-static lifetimes for data being // passed to the thread (see https://docs.rs/crossbeam/0.8.2/crossbeam/thread/struct.Scope.html) extern crate crossbeam; diff --git a/radix-engine-tests/tests/system/bootstrap.rs b/radix-engine-tests/tests/system/bootstrap.rs index af497f5b75f..9a6aa91b05b 100644 --- a/radix-engine-tests/tests/system/bootstrap.rs +++ b/radix-engine-tests/tests/system/bootstrap.rs @@ -17,7 +17,6 @@ use radix_engine_stores::memory_db::InMemorySubstateDatabase; use scrypto_test::prelude::KeyValueEntrySubstate; use scrypto_unit::{CustomGenesis, SubtreeVaults, TestRunnerBuilder}; use transaction::prelude::*; -use transaction::signing::secp256k1::Secp256k1PrivateKey; #[test] fn test_bootstrap_receipt_should_match_constants() { diff --git a/radix-engine-tests/tests/system/events.rs b/radix-engine-tests/tests/system/events.rs index 11b2e6ae114..ad5ab936c51 100644 --- a/radix-engine-tests/tests/system/events.rs +++ b/radix-engine-tests/tests/system/events.rs @@ -27,7 +27,6 @@ use scrypto::NonFungibleData; use scrypto_unit::*; use transaction::model::InstructionV1; use transaction::prelude::*; -use transaction::signing::secp256k1::Secp256k1PrivateKey; #[test] fn test_events_of_commit_failure() { diff --git a/radix-engine-tests/tests/system/metadata_identity.rs b/radix-engine-tests/tests/system/metadata_identity.rs index 5c93f18d76d..0cbe394ef8b 100644 --- a/radix-engine-tests/tests/system/metadata_identity.rs +++ b/radix-engine-tests/tests/system/metadata_identity.rs @@ -4,7 +4,6 @@ use radix_engine::types::*; use radix_engine_interface::api::node_modules::metadata::MetadataValue; use scrypto_unit::*; use transaction::prelude::*; -use transaction::signing::secp256k1::Secp256k1PrivateKey; fn can_set_identity_metadata_with_owner(is_virtual: bool) { // Arrange diff --git a/radix-engine-tests/tests/system/typed_substate_layout.rs b/radix-engine-tests/tests/system/typed_substate_layout.rs index 1e58aad1f47..7d3025079ce 100644 --- a/radix-engine-tests/tests/system/typed_substate_layout.rs +++ b/radix-engine-tests/tests/system/typed_substate_layout.rs @@ -11,7 +11,6 @@ use radix_engine_queries::typed_native_events::TypedNativeEvent; use radix_engine_stores::memory_db::InMemorySubstateDatabase; use sbor::rust::ops::Deref; use scrypto_unit::*; -use transaction::signing::secp256k1::Secp256k1PrivateKey; use transaction_scenarios::scenario::{NextAction, ScenarioCore}; use transaction_scenarios::scenarios::get_builder_for_every_scenario; From 205d90525fd51761d93a2c431b22e5a26b9eebad Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Mon, 4 Dec 2023 16:14:32 +0100 Subject: [PATCH 09/82] Add CryptoUtils API to ClientAPI --- .../src/crypto/bls12381/public_key.rs | 4 +- .../src/crypto/bls12381/signature.rs | 3 +- radix-engine-common/src/crypto/hash.rs | 3 +- radix-engine-interface/src/api/mod.rs | 2 + .../api/system_modules/crypto_utils_api.rs | 12 +++ .../src/api/system_modules/mod.rs | 1 + radix-engine/src/system/system.rs | 25 ++++++ radix-engine/src/vm/wasm/constants.rs | 6 ++ radix-engine/src/vm/wasm/errors.rs | 4 + radix-engine/src/vm/wasm/prepare.rs | 37 +++++++++ radix-engine/src/vm/wasm/traits.rs | 12 +++ radix-engine/src/vm/wasm/wasmi.rs | 83 ++++++++++++++++++- .../src/vm/wasm_runtime/no_op_runtime.rs | 16 ++++ .../src/vm/wasm_runtime/scrypto_runtime.rs | 25 ++++++ scrypto-test/src/environment/client_api.rs | 6 +- scrypto/src/engine/scrypto_env.rs | 26 ++++++ scrypto/src/engine/wasm_api.rs | 19 +++++ 17 files changed, 278 insertions(+), 6 deletions(-) create mode 100644 radix-engine-interface/src/api/system_modules/crypto_utils_api.rs diff --git a/radix-engine-common/src/crypto/bls12381/public_key.rs b/radix-engine-common/src/crypto/bls12381/public_key.rs index 79134f55d8b..c27403c7211 100644 --- a/radix-engine-common/src/crypto/bls12381/public_key.rs +++ b/radix-engine-common/src/crypto/bls12381/public_key.rs @@ -46,8 +46,8 @@ impl TryFrom<&[u8]> for BlsPublicKey { // error //====== -/// Represents an error when parsing ED25519 public key from hex. -#[derive(Debug, Clone, PartialEq, Eq)] +/// Represents an error when parsing BLS public key from hex. +#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)] pub enum ParseBlsPublicKeyError { InvalidHex(String), InvalidLength(usize), diff --git a/radix-engine-common/src/crypto/bls12381/signature.rs b/radix-engine-common/src/crypto/bls12381/signature.rs index 94e3b4376f5..e4c3050b602 100644 --- a/radix-engine-common/src/crypto/bls12381/signature.rs +++ b/radix-engine-common/src/crypto/bls12381/signature.rs @@ -1,3 +1,4 @@ +use crate::ScryptoSbor; use sbor::rust::borrow::ToOwned; use sbor::rust::fmt; use sbor::rust::str::FromStr; @@ -39,7 +40,7 @@ impl TryFrom<&[u8]> for BlsSignature { // error //====== -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)] pub enum ParseBlsSignatureError { InvalidHex(String), InvalidLength(usize), diff --git a/radix-engine-common/src/crypto/hash.rs b/radix-engine-common/src/crypto/hash.rs index 0a74906a8c5..d56450d8a0e 100644 --- a/radix-engine-common/src/crypto/hash.rs +++ b/radix-engine-common/src/crypto/hash.rs @@ -1,4 +1,5 @@ use crate::crypto::blake2b_256_hash; +use crate::ScryptoSbor; use sbor::rust::borrow::ToOwned; use sbor::rust::convert::TryFrom; use sbor::rust::fmt; @@ -75,7 +76,7 @@ pub fn hash>(data: T) -> Hash { //======== /// Represents an error when parsing hash. -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)] pub enum ParseHashError { InvalidHex(String), InvalidLength(usize), diff --git a/radix-engine-interface/src/api/mod.rs b/radix-engine-interface/src/api/mod.rs index ab0fa5cb759..34da852b30d 100644 --- a/radix-engine-interface/src/api/mod.rs +++ b/radix-engine-interface/src/api/mod.rs @@ -21,6 +21,7 @@ pub use key_value_entry_api::*; pub use key_value_store_api::*; pub use object_api::*; pub use system_modules::costing_api::ClientCostingApi; +pub use system_modules::crypto_utils_api::ClientCryptoUtilsApi; pub use system_modules::execution_trace_api::ClientExecutionTraceApi; pub use system_modules::transaction_runtime_api::ClientTransactionRuntimeApi; @@ -55,6 +56,7 @@ pub trait ClientApi: + ClientCostingApi + ClientTransactionRuntimeApi + ClientExecutionTraceApi + + ClientCryptoUtilsApi { } diff --git a/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs b/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs new file mode 100644 index 00000000000..01bdb518467 --- /dev/null +++ b/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs @@ -0,0 +1,12 @@ +use crate::crypto::*; + +pub trait ClientCryptoUtilsApi { + fn bls_verify( + &mut self, + msg_hash: Hash, + public_key: BlsPublicKey, + signature: BlsSignature, + ) -> Result; + + fn keccak_hash(&mut self, data: Vec) -> Result; +} diff --git a/radix-engine-interface/src/api/system_modules/mod.rs b/radix-engine-interface/src/api/system_modules/mod.rs index 155b74e7a92..bafd97b58f7 100644 --- a/radix-engine-interface/src/api/system_modules/mod.rs +++ b/radix-engine-interface/src/api/system_modules/mod.rs @@ -1,3 +1,4 @@ pub mod costing_api; +pub mod crypto_utils_api; pub mod execution_trace_api; pub mod transaction_runtime_api; diff --git a/radix-engine/src/system/system.rs b/radix-engine/src/system/system.rs index b537562573e..b6a5f9d97a3 100644 --- a/radix-engine/src/system/system.rs +++ b/radix-engine/src/system/system.rs @@ -2849,6 +2849,31 @@ where } } +#[cfg_attr( + feature = "std", + catch_unwind(crate::utils::catch_unwind_system_panic_transformer) +)] +impl<'a, Y, V> ClientCryptoUtilsApi for SystemService<'a, Y, V> +where + Y: KernelApi>, + V: SystemCallbackObject, +{ + #[trace_resources] + fn bls_verify( + &mut self, + msg_hash: Hash, + public_key: BlsPublicKey, + signature: BlsSignature, + ) -> Result { + Ok(verify_bls(&msg_hash, &public_key, &signature) as u32) + } + + #[trace_resources] + fn keccak_hash(&mut self, data: Vec) -> Result { + Ok(blake2b_256_hash(&data)) + } +} + #[cfg_attr( feature = "std", catch_unwind(crate::utils::catch_unwind_system_panic_transformer) diff --git a/radix-engine/src/vm/wasm/constants.rs b/radix-engine/src/vm/wasm/constants.rs index ee986a36e56..752bbbbdfd4 100644 --- a/radix-engine/src/vm/wasm/constants.rs +++ b/radix-engine/src/vm/wasm/constants.rs @@ -77,6 +77,12 @@ pub const SYS_GET_TRANSACTION_HASH_FUNCTION_NAME: &str = "sys_get_transaction_ha pub const SYS_GENERATE_RUID_FUNCTION_NAME: &str = "sys_generate_ruid"; pub const SYS_PANIC_FUNCTION_NAME: &str = "sys_panic"; +//================= +// Crypto Utils +//================= +pub const CRYPTO_UTILS_BLS_VERIFY_FUNCTION_NAME: &str = "crypto_utils_bls_verify"; +pub const CRYPTO_UTILS_KECCAK_HASH_FUNCTION_NAME: &str = "crypto_utils_keccak_hash"; + //================= // WASM Shim //================= diff --git a/radix-engine/src/vm/wasm/errors.rs b/radix-engine/src/vm/wasm/errors.rs index d030bfb8781..40e12f6dfb3 100644 --- a/radix-engine/src/vm/wasm/errors.rs +++ b/radix-engine/src/vm/wasm/errors.rs @@ -153,6 +153,10 @@ pub enum WasmRuntimeError { InvalidPackageAddress, TooManyBuffers, + + InvalidBlsPublicKey(ParseBlsPublicKeyError), + InvalidBlsSignature(ParseBlsSignatureError), + InvalidHash(ParseHashError), } impl SelfError for WasmRuntimeError { diff --git a/radix-engine/src/vm/wasm/prepare.rs b/radix-engine/src/vm/wasm/prepare.rs index b10036aa1bc..cd1b4732ff8 100644 --- a/radix-engine/src/vm/wasm/prepare.rs +++ b/radix-engine/src/vm/wasm/prepare.rs @@ -733,6 +733,43 @@ impl WasmModule { )); } } + CRYPTO_UTILS_BLS_VERIFY_FUNCTION_NAME => { + if let TypeRef::Func(type_index) = entry.ty { + if Self::function_type_matches( + &self.module, + type_index, + vec![ + ValType::I32, + ValType::I32, + ValType::I32, + ValType::I32, + ValType::I32, + ValType::I32, + ], + vec![ValType::I32], + ) { + continue; + } + return Err(PrepareError::InvalidImport( + InvalidImport::InvalidFunctionType(entry.name.to_string()), + )); + } + } + CRYPTO_UTILS_KECCAK_HASH_FUNCTION_NAME => { + if let TypeRef::Func(type_index) = entry.ty { + if Self::function_type_matches( + &self.module, + type_index, + vec![ValType::I32, ValType::I32], + vec![ValType::I64], + ) { + continue; + } + return Err(PrepareError::InvalidImport( + InvalidImport::InvalidFunctionType(entry.name.to_string()), + )); + } + } _ => {} }; } diff --git a/radix-engine/src/vm/wasm/traits.rs b/radix-engine/src/vm/wasm/traits.rs index 59e3dbfd806..de09941550b 100644 --- a/radix-engine/src/vm/wasm/traits.rs +++ b/radix-engine/src/vm/wasm/traits.rs @@ -200,6 +200,18 @@ pub trait WasmRuntime { fn sys_generate_ruid(&mut self) -> Result>; fn sys_panic(&mut self, message: Vec) -> Result<(), InvokeError>; + + fn crypto_utils_bls_verify( + &mut self, + msg_hash: Vec, + public_key: Vec, + signature: Vec, + ) -> Result>; + + fn crypto_utils_keccak_hash( + &mut self, + data: Vec, + ) -> Result>; } /// Represents an instantiated, invocable Scrypto module. diff --git a/radix-engine/src/vm/wasm/wasmi.rs b/radix-engine/src/vm/wasm/wasmi.rs index 5d2805ed4d3..950147c9729 100644 --- a/radix-engine/src/vm/wasm/wasmi.rs +++ b/radix-engine/src/vm/wasm/wasmi.rs @@ -663,6 +663,48 @@ fn panic( runtime.sys_panic(message) } +fn bls_verify( + mut caller: Caller<'_, HostState>, + msg_hash_ptr: u32, + msg_hash_len: u32, + public_key_ptr: u32, + public_key_len: u32, + signature_ptr: u32, + signature_len: u32, +) -> Result> { + let (memory, runtime) = grab_runtime!(caller); + + let msg_hash = read_memory(caller.as_context_mut(), memory, msg_hash_ptr, msg_hash_len)?; + let public_key = read_memory( + caller.as_context_mut(), + memory, + public_key_ptr, + public_key_len, + )?; + let signature = read_memory( + caller.as_context_mut(), + memory, + signature_ptr, + signature_len, + )?; + + runtime.crypto_utils_bls_verify(msg_hash, public_key, signature) +} + +fn keccak_hash( + mut caller: Caller<'_, HostState>, + data_ptr: u32, + data_len: u32, +) -> Result> { + let (memory, runtime) = grab_runtime!(caller); + + let data = read_memory(caller.as_context_mut(), memory, data_ptr, data_len)?; + + runtime + .crypto_utils_keccak_hash(data) + .map(|buffer| buffer.0) +} + #[cfg(feature = "radix_engine_tests")] fn test_host_read_memory( mut caller: Caller<'_, HostState>, @@ -1226,6 +1268,36 @@ impl WasmiModule { }, ); + let host_bls_verify = Func::wrap( + store.as_context_mut(), + |caller: Caller<'_, HostState>, + msg_hash_ptr: u32, + msg_hash_len: u32, + public_key_ptr: u32, + public_key_len: u32, + signature_ptr: u32, + signature_len: u32| + -> Result { + bls_verify( + caller, + msg_hash_ptr, + msg_hash_len, + public_key_ptr, + public_key_len, + signature_ptr, + signature_len, + ) + .map_err(|e| e.into()) + }, + ); + + let host_keccak_hash = Func::wrap( + store.as_context_mut(), + |caller: Caller<'_, HostState>, data_ptr: u32, data_len: u32| -> Result { + keccak_hash(caller, data_ptr, data_len).map_err(|e| e.into()) + }, + ); + let mut linker = >::new(); linker_define!(linker, BUFFER_CONSUME_FUNCTION_NAME, host_consume_buffer); @@ -1382,8 +1454,17 @@ impl WasmiModule { SYS_BECH32_ENCODE_ADDRESS_FUNCTION_NAME, host_bech32_encode_address ); - linker_define!(linker, SYS_GENERATE_RUID_FUNCTION_NAME, host_generate_ruid); + linker_define!( + linker, + CRYPTO_UTILS_BLS_VERIFY_FUNCTION_NAME, + host_bls_verify + ); + linker_define!( + linker, + CRYPTO_UTILS_KECCAK_HASH_FUNCTION_NAME, + host_keccak_hash + ); #[cfg(feature = "radix_engine_tests")] { diff --git a/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs b/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs index 860a1d56107..cdc0bc04138 100644 --- a/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs +++ b/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs @@ -305,4 +305,20 @@ impl<'a> WasmRuntime for NoOpWasmRuntime<'a> { fn costing_get_fee_balance(&mut self) -> Result> { Err(InvokeError::SelfError(WasmRuntimeError::NotImplemented)) } + + fn crypto_utils_bls_verify( + &mut self, + msg_hash: Vec, + public_key: Vec, + signature: Vec, + ) -> Result> { + Err(InvokeError::SelfError(WasmRuntimeError::NotImplemented)) + } + + fn crypto_utils_keccak_hash( + &mut self, + data: Vec, + ) -> Result> { + Err(InvokeError::SelfError(WasmRuntimeError::NotImplemented)) + } } diff --git a/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs b/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs index 00658ba32f4..eab22da2926 100644 --- a/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs +++ b/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs @@ -560,4 +560,29 @@ where self.allocate_buffer(scrypto_encode(&fee_balance).expect("Failed to encode fee_balance")) } + + fn crypto_utils_bls_verify( + &mut self, + msg_hash: Vec, + public_key: Vec, + signature: Vec, + ) -> Result> { + let msg_hash = + Hash::try_from(msg_hash.as_slice()).map_err(WasmRuntimeError::InvalidHash)?; + let public_key = BlsPublicKey::try_from(public_key.as_slice()) + .map_err(WasmRuntimeError::InvalidBlsPublicKey)?; + let signature = BlsSignature::try_from(signature.as_slice()) + .map_err(WasmRuntimeError::InvalidBlsSignature)?; + let result = self.api.bls_verify(msg_hash, public_key, signature)?; + Ok(result) + } + + fn crypto_utils_keccak_hash( + &mut self, + data: Vec, + ) -> Result> { + let hash = self.api.keccak_hash(data)?; + + self.allocate_buffer(hash.to_vec()) + } } diff --git a/scrypto-test/src/environment/client_api.rs b/scrypto-test/src/environment/client_api.rs index 3d0bcd7472c..c3677321888 100644 --- a/scrypto-test/src/environment/client_api.rs +++ b/scrypto-test/src/environment/client_api.rs @@ -274,5 +274,9 @@ implement_client_api! { max_per_function_royalty_in_xrd: (&mut self) -> Result, tip_percentage: (&mut self) -> Result, fee_balance: (&mut self) -> Result, - } + }, + ClientCryptoUtilsApi: { + bls_verify: (&mut self, msg_hash: Hash, public_key: BlsPublicKey, signature: BlsSignature) -> Result, + keccak_hash: (&mut self, data: Vec) -> Result, + }, } diff --git a/scrypto/src/engine/scrypto_env.rs b/scrypto/src/engine/scrypto_env.rs index 2dcc25be46e..82d1465aa98 100644 --- a/scrypto/src/engine/scrypto_env.rs +++ b/scrypto/src/engine/scrypto_env.rs @@ -1,5 +1,6 @@ use crate::engine::wasm_api::*; use radix_engine_common::math::Decimal; +use radix_engine_common::prelude::{BlsPublicKey, BlsSignature, IsHash}; use radix_engine_common::types::GlobalAddressReservation; use radix_engine_interface::api::actor_api::EventFlags; use radix_engine_interface::api::key_value_entry_api::KeyValueEntryHandle; @@ -320,4 +321,29 @@ impl ScryptoVmV1Api { system::sys_panic(message.as_ptr(), message.len()); }; } + + pub fn crypto_utils_bls_verify( + msg_hash: Hash, + public_key: BlsPublicKey, + signature: BlsSignature, + ) -> u32 { + unsafe { + crypto_utils::crypto_utils_bls_verify( + msg_hash.0.as_ptr(), + msg_hash.0.len(), + public_key.0.as_ptr(), + public_key.0.len(), + signature.0.as_ptr(), + signature.0.len(), + ) + } + } + + pub fn crypto_utils_keccak_hash(data: Vec) -> Hash { + let hash = copy_buffer(unsafe { + crypto_utils::crypto_utils_keccak_hash(data.as_ptr(), data.len()) + }); + + Hash(hash.try_into().unwrap()) + } } diff --git a/scrypto/src/engine/wasm_api.rs b/scrypto/src/engine/wasm_api.rs index 4a87174e10a..84add98b85c 100644 --- a/scrypto/src/engine/wasm_api.rs +++ b/scrypto/src/engine/wasm_api.rs @@ -284,6 +284,25 @@ pub mod system { } } +/// Various environment-based API calls +pub mod crypto_utils { + pub use radix_engine_interface::types::{Buffer, BufferId, Slice}; + + super::wasm_extern_c! { + pub fn crypto_utils_bls_verify( + hash_ptr: *const u8, + hash_len: usize, + public_key_ptr: *const u8, + public_key_len: usize, + signature_ptr: *const u8, + signature_len: usize) -> u32; + + pub fn crypto_utils_keccak_hash( + message_ptr: *const u8, + message_len: usize) -> Buffer; + } +} + pub mod buffer { pub use radix_engine_interface::types::{Buffer, BufferId, Slice}; From e98f9439344361b999a1f2e87d7de0bc56114951 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Mon, 4 Dec 2023 17:18:57 +0100 Subject: [PATCH 10/82] Test CryptoUtils API with CryptoScrypto blueprint --- .../assets/blueprints/Cargo.toml | 3 +- .../blueprints/crypto_scrypto/Cargo.toml | 15 ++ .../blueprints/crypto_scrypto/src/lib.rs | 18 +++ .../tests/system/crypto_utils.rs | 138 ++++++++++++++++++ 4 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 radix-engine-tests/assets/blueprints/crypto_scrypto/Cargo.toml create mode 100644 radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs create mode 100644 radix-engine-tests/tests/system/crypto_utils.rs diff --git a/radix-engine-tests/assets/blueprints/Cargo.toml b/radix-engine-tests/assets/blueprints/Cargo.toml index dd6a686930e..b56ef1690b5 100644 --- a/radix-engine-tests/assets/blueprints/Cargo.toml +++ b/radix-engine-tests/assets/blueprints/Cargo.toml @@ -65,7 +65,8 @@ members = [ "royalty-edge-cases", "system_wasm_buffers", "event-replacement", - "decimal" + "decimal", + "crypto_scrypto" ] [profile.release] diff --git a/radix-engine-tests/assets/blueprints/crypto_scrypto/Cargo.toml b/radix-engine-tests/assets/blueprints/crypto_scrypto/Cargo.toml new file mode 100644 index 00000000000..e429f6f0c0d --- /dev/null +++ b/radix-engine-tests/assets/blueprints/crypto_scrypto/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "crypto_scrypto" +version = "1.0.2-dev" +edition = "2021" + +[dependencies] +sbor = { path = "../../../../sbor" } +scrypto = { path = "../../../../scrypto" } + +[dev-dependencies] +radix-engine = { path = "../../../../radix-engine" } + +[lib] +doctest = false +crate-type = ["cdylib", "lib"] diff --git a/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs b/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs new file mode 100644 index 00000000000..aaa18d454d3 --- /dev/null +++ b/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs @@ -0,0 +1,18 @@ +use scrypto::prelude::*; + +#[blueprint] +mod component_module { + struct CryptoScrypto {} + + impl CryptoScrypto { + pub fn bls_verify(msg_hash: Hash, pub_key: BlsPublicKey, signature: BlsSignature) -> bool { + let rtn = ScryptoVmV1Api::crypto_utils_bls_verify(msg_hash, pub_key, signature) != 0; + rtn + } + + pub fn keccak_hash(data: Vec) -> Hash { + let hash = ScryptoVmV1Api::crypto_utils_keccak_hash(data); + hash + } + } +} diff --git a/radix-engine-tests/tests/system/crypto_utils.rs b/radix-engine-tests/tests/system/crypto_utils.rs new file mode 100644 index 00000000000..6d478a812ed --- /dev/null +++ b/radix-engine-tests/tests/system/crypto_utils.rs @@ -0,0 +1,138 @@ +use radix_engine::types::*; +use radix_engine::vm::NoExtension; +use radix_engine_stores::memory_db::InMemorySubstateDatabase; +use radix_engine_tests::common::*; +use scrypto_unit::*; +use transaction::builder::ManifestBuilder; + +#[cfg(test)] +fn crypto_scrypto_bls_verify( + runner: &mut TestRunner, + package_address: PackageAddress, + msg_hash: &str, + pk: &str, + sig: &str, +) -> bool { + let msg_hash = Hash::from_str(msg_hash).unwrap(); + let pub_key = BlsPublicKey::from_str(pk).unwrap(); + let signature = BlsSignature::from_str(sig).unwrap(); + + let receipt = runner.execute_manifest( + ManifestBuilder::new() + .lock_fee(runner.faucet_component(), 500u32) + .call_function( + package_address, + "CryptoScrypto", + "bls_verify", + manifest_args!(msg_hash, pub_key, signature), + ) + .build(), + vec![], + ); + let result = receipt.expect_commit_success(); + result.output(1) +} + +#[cfg(test)] +fn crypto_scrypto_keccak_hash( + runner: &mut TestRunner, + package_address: PackageAddress, + data: &str, +) -> Hash { + let data = data.as_bytes().to_vec(); + + let receipt = runner.execute_manifest( + ManifestBuilder::new() + .lock_fee(runner.faucet_component(), 500u32) + .call_function( + package_address, + "CryptoScrypto", + "keccak_hash", + manifest_args!(data), + ) + .build(), + vec![], + ); + let result = receipt.expect_commit_success(); + result.output(1) +} + +#[test] +fn test_crypto_scrypto_bls_verify() { + // Arrange + let mut test_runner = TestRunnerBuilder::new().build(); + + let package_address = test_runner.publish_package_simple(PackageLoader::get("crypto_scrypto")); + + let msg1 = hash("Test").to_string(); + let msg2 = hash("ExpectFailureTest").to_string(); + let pk = "93b1aa7542a5423e21d8e84b4472c31664412cc604a666e9fdf03baf3c758e728c7a11576ebb01110ac39a0df95636e2"; + let msg1_signature = "a2ba96a1fc1e698b7688e077f171fbd7fe99c6bbf240b1421a08e3faa5d6b55523a18b8c77fba5830181dfec716edc3d18a8657bcadd0a83e3cafdad33998d10417f767c536b26b98df41d67ab416c761ad55438f23132a136fc82eb7b290571"; + + // Act + let msg1_verify = + crypto_scrypto_bls_verify(&mut test_runner, package_address, &msg1, pk, msg1_signature); + let msg2_verify = + crypto_scrypto_bls_verify(&mut test_runner, package_address, &msg2, pk, msg1_signature); + + // Assert + assert!(msg1_verify); + assert!(!msg2_verify); +} + +#[test] +fn test_crypto_scrypto_keccak_hash() { + // Arrange + let mut test_runner = TestRunnerBuilder::new().build(); + + let package_address = test_runner.publish_package_simple(PackageLoader::get("crypto_scrypto")); + + let data1 = "Hello Radix"; + let data2 = "xidaR olleH"; + + // Act + let data1_hash = crypto_scrypto_keccak_hash(&mut test_runner, package_address, data1); + let data2_hash = crypto_scrypto_keccak_hash(&mut test_runner, package_address, data2); + + // Assert + assert_eq!( + data1_hash, + Hash::from_str("48f1bd08444b5e713db9e14caac2faae71836786ac94d645b00679728202a935").unwrap() + ); + assert_ne!( + data2_hash, + Hash::from_str("48f1bd08444b5e713db9e14caac2faae71836786ac94d645b00679728202a935").unwrap() + ); +} + +#[test] +fn test_crypto_scrypto_flow() { + // Arrange + let mut test_runner = TestRunnerBuilder::new().build(); + + let package_address = test_runner.publish_package_simple(PackageLoader::get("crypto_scrypto")); + + let msg = "Important message"; + + // Act + // Get the hash of the message using CryptoScrypto package + let msg_hash = crypto_scrypto_keccak_hash(&mut test_runner, package_address, msg); + + let secret_key = BlsPrivateKey::from_u64(1).unwrap(); + let public_key = secret_key.public_key(); + + // Sign the message hash using BLS + let msg_signature = secret_key.sign(&msg_hash); + + // Verify the BLS signature using CryptoScrypto package + let result = crypto_scrypto_bls_verify( + &mut test_runner, + package_address, + &msg_hash.to_string(), + &public_key.to_string(), + &msg_signature.to_string(), + ); + + // Assert + assert!(result); +} From ae69bd10b2133459f4337cfde784531db1967255 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Mon, 4 Dec 2023 17:49:15 +0100 Subject: [PATCH 11/82] Install clang in CI --- .github/actions/setup-env/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/setup-env/action.yml b/.github/actions/setup-env/action.yml index 0c9aeb3bb51..be40cbf5436 100644 --- a/.github/actions/setup-env/action.yml +++ b/.github/actions/setup-env/action.yml @@ -29,6 +29,6 @@ runs: cmake-version: '3.27.9' - name: Install libclang-dev if: runner.os == 'Linux' - run: sudo apt-get install libclang-dev -y -f + run: sudo apt-get -y update && sudo apt-get install clang libclang-dev -y -f shell: bash From 03568e4f8ff0726e95c9a3ec98ffcf8ecf0ffafe Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Mon, 4 Dec 2023 17:54:49 +0100 Subject: [PATCH 12/82] Fix no_std --- .../src/api/system_modules/crypto_utils_api.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs b/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs index 01bdb518467..26235e2fb80 100644 --- a/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs +++ b/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs @@ -1,4 +1,5 @@ use crate::crypto::*; +use crate::internal_prelude::Vec; pub trait ClientCryptoUtilsApi { fn bls_verify( From bc73b065bd7166384705930742a094dda6174d56 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Mon, 4 Dec 2023 17:55:42 +0100 Subject: [PATCH 13/82] Fix compilation issues in radix-engine-tests --- radix-engine-tests/benches/costing.rs | 6 ++---- radix-engine-tests/benches/transaction_validation.rs | 1 + 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/radix-engine-tests/benches/costing.rs b/radix-engine-tests/benches/costing.rs index 81879f00f7b..2a3d3e8764c 100644 --- a/radix-engine-tests/benches/costing.rs +++ b/radix-engine-tests/benches/costing.rs @@ -12,14 +12,12 @@ use radix_engine::{ wasm_runtime::NoOpWasmRuntime, }, }; +use radix_engine_common::crypto::{recover_secp256k1, verify_secp256k1}; use radix_engine_queries::typed_substate_layout::{CodeHash, PackageDefinition}; use radix_engine_tests::common::*; use sbor::rust::iter; use scrypto_unit::TestRunnerBuilder; -use transaction::{ - prelude::{Secp256k1PrivateKey, TransactionCostingParameters}, - validation::{recover_secp256k1, verify_secp256k1}, -}; +use transaction::prelude::TransactionCostingParameters; use wabt::wat2wasm; fn bench_decode_sbor(c: &mut Criterion) { diff --git a/radix-engine-tests/benches/transaction_validation.rs b/radix-engine-tests/benches/transaction_validation.rs index db912b484d5..f5d0c2ebebb 100644 --- a/radix-engine-tests/benches/transaction_validation.rs +++ b/radix-engine-tests/benches/transaction_validation.rs @@ -2,6 +2,7 @@ use std::hint::black_box; use criterion::{criterion_group, criterion_main, Criterion}; use radix_engine::types::*; +use radix_engine_common::crypto::{recover_secp256k1, verify_secp256k1}; use transaction::prelude::*; use transaction::validation::*; From 17c06aa8369442d3317034c63ecab76474b9e654 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Mon, 4 Dec 2023 17:55:59 +0100 Subject: [PATCH 14/82] Remove warning --- scrypto/src/engine/scrypto_env.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scrypto/src/engine/scrypto_env.rs b/scrypto/src/engine/scrypto_env.rs index 82d1465aa98..8766e7f119c 100644 --- a/scrypto/src/engine/scrypto_env.rs +++ b/scrypto/src/engine/scrypto_env.rs @@ -1,6 +1,6 @@ use crate::engine::wasm_api::*; use radix_engine_common::math::Decimal; -use radix_engine_common::prelude::{BlsPublicKey, BlsSignature, IsHash}; +use radix_engine_common::prelude::{BlsPublicKey, BlsSignature}; use radix_engine_common::types::GlobalAddressReservation; use radix_engine_interface::api::actor_api::EventFlags; use radix_engine_interface::api::key_value_entry_api::KeyValueEntryHandle; From 5e346777d4377c1c15d44706ab9a0c0e0234cd19 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Mon, 4 Dec 2023 17:56:19 +0100 Subject: [PATCH 15/82] Add TODO note --- radix-engine/src/system/system.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/radix-engine/src/system/system.rs b/radix-engine/src/system/system.rs index b6a5f9d97a3..90cd0df4bd1 100644 --- a/radix-engine/src/system/system.rs +++ b/radix-engine/src/system/system.rs @@ -2865,11 +2865,13 @@ where public_key: BlsPublicKey, signature: BlsSignature, ) -> Result { + // TODO: apply execution costs Ok(verify_bls(&msg_hash, &public_key, &signature) as u32) } #[trace_resources] fn keccak_hash(&mut self, data: Vec) -> Result { + // TODO: apply execution costs Ok(blake2b_256_hash(&data)) } } From 1ba5467fbd85f91c1562b92c056baad96a38bfff Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Mon, 4 Dec 2023 17:57:19 +0100 Subject: [PATCH 16/82] Fix simulator --- simulator/Cargo.lock | 94 +++++++++++++------------------------- simulator/src/resim/mod.rs | 3 +- 2 files changed, 32 insertions(+), 65 deletions(-) diff --git a/simulator/Cargo.lock b/simulator/Cargo.lock index d2128151114..42fb93439fd 100644 --- a/simulator/Cargo.lock +++ b/simulator/Cargo.lock @@ -106,6 +106,18 @@ dependencies = [ "generic-array", ] +[[package]] +name = "blst" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c94087b935a822949d3291a9989ad2b2051ea141eda0fd4e478a75f6aa3e604b" +dependencies = [ + "cc", + "glob", + "threadpool", + "zeroize", +] + [[package]] name = "bnum" version = "0.7.0" @@ -468,8 +480,6 @@ checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" dependencies = [ "curve25519-dalek", "ed25519", - "rand 0.7.3", - "serde", "sha2", "zeroize", ] @@ -584,17 +594,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - [[package]] name = "getrandom" version = "0.2.10" @@ -604,7 +603,7 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "wasm-bindgen", ] @@ -903,7 +902,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" dependencies = [ - "getrandom 0.2.10", + "getrandom", ] [[package]] @@ -1130,7 +1129,9 @@ version = "1.0.2-dev" dependencies = [ "bech32", "blake2", + "blst", "bnum", + "ed25519-dalek", "hex", "lazy_static", "num-bigint", @@ -1139,6 +1140,7 @@ dependencies = [ "paste", "radix-engine-derive", "sbor", + "secp256k1", "strum", "utils", ] @@ -1234,19 +1236,6 @@ dependencies = [ "utils", ] -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc", -] - [[package]] name = "rand" version = "0.8.5" @@ -1254,20 +1243,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha 0.3.1", + "rand_chacha", "rand_core 0.6.4", ] -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", -] - [[package]] name = "rand_chacha" version = "0.3.1" @@ -1283,9 +1262,6 @@ name = "rand_core" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] [[package]] name = "rand_core" @@ -1293,16 +1269,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.10", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", + "getrandom", ] [[package]] @@ -1329,7 +1296,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ - "getrandom 0.2.10", + "getrandom", "redox_syscall 0.2.16", "thiserror", ] @@ -1598,7 +1565,7 @@ dependencies = [ "radix-engine-queries", "radix-engine-store-interface", "radix-engine-stores", - "rand 0.8.5", + "rand", "regex", "rocksdb", "sbor", @@ -1784,6 +1751,15 @@ dependencies = [ "syn 2.0.29", ] +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + [[package]] name = "toml" version = "0.5.11" @@ -1798,13 +1774,11 @@ name = "transaction" version = "1.0.2-dev" dependencies = [ "bech32", - "ed25519-dalek", "hex", "lazy_static", "radix-engine-common", "radix-engine-interface", "sbor", - "secp256k1", "strum", "utils", ] @@ -1861,7 +1835,7 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" dependencies = [ - "getrandom 0.2.10", + "getrandom", ] [[package]] @@ -1886,12 +1860,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/simulator/src/resim/mod.rs b/simulator/src/resim/mod.rs index 5ba031498f3..f4e9b32819c 100644 --- a/simulator/src/resim/mod.rs +++ b/simulator/src/resim/mod.rs @@ -77,7 +77,7 @@ use radix_engine_interface::blueprints::package::{ BlueprintDefinition, BlueprintInterface, BlueprintPayloadDef, BlueprintVersionKey, }; use radix_engine_interface::blueprints::resource::FromPublicKey; -use radix_engine_interface::crypto::hash; +use radix_engine_interface::crypto::{hash, Secp256k1PrivateKey}; use radix_engine_interface::network::NetworkDefinition; use radix_engine_queries::typed_substate_layout::*; use radix_engine_store_interface::interface::SubstateDatabase; @@ -90,7 +90,6 @@ use transaction::model::TestTransaction; use transaction::model::{BlobV1, BlobsV1, InstructionV1, InstructionsV1}; use transaction::model::{SystemTransactionV1, TransactionPayload}; use transaction::prelude::*; -use transaction::signing::secp256k1::Secp256k1PrivateKey; use utils::ContextualDisplay; /// Build fast, reward everyone, and scale without friction From a0a0fbdf672020e0a1518b24adbe1463f249ef2c Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Tue, 5 Dec 2023 09:29:40 +0100 Subject: [PATCH 17/82] Disable 'global-context' for secp2561 as it enforces 'std' --- radix-engine-common/Cargo.toml | 4 ++-- .../src/crypto/secp256k1/private_key.rs | 10 +++++++--- radix-engine-common/src/crypto/signature_validator.rs | 5 +++-- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/radix-engine-common/Cargo.toml b/radix-engine-common/Cargo.toml index 5f8d95c287c..4f5abddeb8c 100644 --- a/radix-engine-common/Cargo.toml +++ b/radix-engine-common/Cargo.toml @@ -25,7 +25,7 @@ arbitrary = { version = "1.3.0", features = ["derive"], optional = true } rug = { version = "1.18", optional = true } ethnum = {version = "1.3.2", default-features = false, optional = true } ed25519-dalek = { version = "1.0.1", default-features = false, features = ["u64_backend"]} -secp256k1 = { version = "0.24.0", default-features = false, features = ["global-context", "recovery"]} +secp256k1 = { version = "0.24.0", default-features = false, features = ["recovery"]} blst = { version = "0.3.11", default-features = false } [dev-dependencies] @@ -44,7 +44,7 @@ harness = false # You should enable either `std` or `alloc` default = ["std"] serde = ["dep:serde", "utils/serde", "sbor/serde", "hex/serde"] -std = ["hex/std", "sbor/std", "utils/std", "radix-engine-derive/std", "serde_json/std", "blake2/std"] +std = ["hex/std", "sbor/std", "utils/std", "radix-engine-derive/std", "serde_json/std", "ed25519-dalek/std", "secp256k1/std", "blake2/std"] alloc = ["hex/alloc", "sbor/alloc", "utils/alloc", "radix-engine-derive/alloc", "serde_json/alloc", "ed25519-dalek/alloc", "secp256k1/alloc", "lazy_static/spin_no_std"] # This flag is set by fuzz-tests framework and it is used to disable/enable some optional features diff --git a/radix-engine-common/src/crypto/secp256k1/private_key.rs b/radix-engine-common/src/crypto/secp256k1/private_key.rs index 3446c9b13cc..fe0458c5b3c 100644 --- a/radix-engine-common/src/crypto/secp256k1/private_key.rs +++ b/radix-engine-common/src/crypto/secp256k1/private_key.rs @@ -1,20 +1,24 @@ use crate::internal_prelude::*; -use ::secp256k1::{Message, PublicKey, SecretKey, SECP256K1}; +use ::secp256k1::{All, Message, PublicKey, Secp256k1, SecretKey}; use super::Secp256k1Signature; +lazy_static::lazy_static! { + pub static ref SECP256K1_CTX: Secp256k1 = secp256k1::Secp256k1::new(); +} + pub struct Secp256k1PrivateKey(SecretKey); impl Secp256k1PrivateKey { pub const LENGTH: usize = 32; pub fn public_key(&self) -> Secp256k1PublicKey { - Secp256k1PublicKey(PublicKey::from_secret_key_global(&self.0).serialize()) + Secp256k1PublicKey(PublicKey::from_secret_key(&SECP256K1_CTX, &self.0).serialize()) } pub fn sign(&self, msg_hash: &impl IsHash) -> Secp256k1Signature { let m = Message::from_slice(msg_hash.as_ref()).expect("Hash is always a valid message"); - let signature = SECP256K1.sign_ecdsa_recoverable(&m, &self.0); + let signature = SECP256K1_CTX.sign_ecdsa_recoverable(&m, &self.0); let (recovery_id, signature_data) = signature.serialize_compact(); let mut buf = [0u8; 65]; diff --git a/radix-engine-common/src/crypto/signature_validator.rs b/radix-engine-common/src/crypto/signature_validator.rs index c86a7f0e340..eaa61b8e479 100644 --- a/radix-engine-common/src/crypto/signature_validator.rs +++ b/radix-engine-common/src/crypto/signature_validator.rs @@ -20,7 +20,8 @@ pub fn recover_secp256k1( { let msg = ::secp256k1::Message::from_slice(&signed_hash.0) .expect("Hash is always a valid message"); - if let Ok(pk) = sig.recover(&msg) { + + if let Ok(pk) = SECP256K1_CTX.recover_ecdsa(&msg, &sig) { return Some(Secp256k1PublicKey(pk.serialize())); } } @@ -52,7 +53,7 @@ pub fn verify_secp256k1( if let Ok(pk) = ::secp256k1::PublicKey::from_slice(&public_key.0) { let msg = ::secp256k1::Message::from_slice(&signed_hash.0) .expect("Hash is always a valid message"); - return sig.verify(&msg, &pk).is_ok(); + return SECP256K1_CTX.verify_ecdsa(&msg, &sig, &pk).is_ok(); } } } From be6baa831f0a6454cf95657331cdded60c5cb322 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Tue, 5 Dec 2023 09:42:59 +0100 Subject: [PATCH 18/82] Use setup-env action in Benchmark PR GH action --- .github/workflows/bench.yml | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index 4cff1ae6651..d2f8b41a3c9 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -14,15 +14,8 @@ jobs: runs-on: gh-runner-scrypto-ubuntu-jammy-16-cores steps: - uses: actions/checkout@v3 - - name: Setup cmake - uses: RDXWorks-actions/actions-setup-cmake@master - with: - cmake-version: '3.27.9' - - uses: RDXWorks-actions/toolchain@master - with: - toolchain: stable - - name: Add wasm target - run: rustup target add wasm32-unknown-unknown + - name: Setup environment + uses: ./.github/actions/setup-env - uses: radixdlt/criterion-compare-action@update-same-commit with: branchName: ${{ github.base_ref }} From 8e5f93ea85ad41e616b560620d8bd91d3926e71d Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Tue, 5 Dec 2023 09:44:39 +0100 Subject: [PATCH 19/82] Fix tests when 'compile-blueprints-at-build-time' enabled --- radix-engine-tests/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radix-engine-tests/Cargo.toml b/radix-engine-tests/Cargo.toml index 43cf3fb67a8..e725caf21d0 100644 --- a/radix-engine-tests/Cargo.toml +++ b/radix-engine-tests/Cargo.toml @@ -20,6 +20,7 @@ radix-engine-profiling = { path = "../radix-engine-profiling", optional = true, resources-tracker-macro = { path = "../radix-engine-profiling/resources-tracker-macro" } scrypto-test = { path = "../scrypto-test", default-features = false } scrypto-unit = { path = "../scrypto-unit", default-features = false } +lazy_static = { version = "1.4.0" } [dev-dependencies] transaction = { path = "../transaction", default-features = false } @@ -35,7 +36,6 @@ serde_json = { version = "1.0.81", default-features = false } crossbeam = { version = "0.8.2" } walkdir = { version = "2.3.3" } paste = { version = "1.0.13" } -lazy_static = { version = "1.4.0" } hex = { version = "0.4.3", default-features = false } trybuild = { version = "1.0.85" } automod = "1.0.13" From a37e6f6764ca74371c23967845a3ecc30f89979d Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Tue, 5 Dec 2023 09:55:24 +0100 Subject: [PATCH 20/82] Add bls_verify() and keccak_hash() to wasmer --- radix-engine/src/vm/wasm/wasmer.rs | 36 ++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/radix-engine/src/vm/wasm/wasmer.rs b/radix-engine/src/vm/wasm/wasmer.rs index 17d65db8d78..edff94698e3 100644 --- a/radix-engine/src/vm/wasm/wasmer.rs +++ b/radix-engine/src/vm/wasm/wasmer.rs @@ -676,6 +676,39 @@ impl WasmerModule { runtime.sys_generate_ruid().map(|buffer| buffer.0) } + pub fn bls_verify( + env: &WasmerInstanceEnv, + msg_hash_ptr: u32, + msg_hash_len: u32, + public_key_ptr: u32, + public_key_len: u32, + signature_ptr: u32, + signature_len: u32, + ) -> Result> { + let (instance, runtime) = grab_runtime!(env); + + let msg_hash = read_memory(&instance, msg_hash_ptr, msg_hash_len)?; + + let public_key = read_memory(&instance, public_key_ptr, public_key_len)?; + let signature = read_memory(instance, signature_ptr, signature_len)?; + + runtime.crypto_utils_bls_verify(msg_hash, public_key, signature) + } + + pub fn keccak_hash( + env: &WasmerInstanceEnv, + data_ptr: u32, + data_len: u32, + ) -> Result> { + let (instance, runtime) = grab_runtime!(env); + + let data = read_memory(instance, data_ptr, data_len)?; + + runtime + .crypto_utils_keccak_hash(data) + .map(|buffer| buffer.0) + } + #[cfg(feature = "radix_engine_tests")] pub fn host_read_memory( env: &WasmerInstanceEnv, @@ -779,6 +812,9 @@ impl WasmerModule { SYS_GET_TRANSACTION_HASH_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), sys_get_transaction_hash), SYS_GENERATE_RUID_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), sys_generate_ruid), BUFFER_CONSUME_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), buffer_consume), + CRYPTO_UTILS_BLS_VERIFY_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), bls_verify), + CRYPTO_UTILS_KECCAK_HASH_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), keccak_hash), + #[cfg(feature = "radix_engine_tests")] "test_host_read_memory" => Function::new_native_with_env(self.module.store(), env.clone(), host_read_memory), #[cfg(feature = "radix_engine_tests")] From 0262df0329831b72d00ce952f9e1d9721e8bd194 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Tue, 5 Dec 2023 12:55:39 +0100 Subject: [PATCH 21/82] Get rid of crypto-related dependencies for WASM target ATM it is not required in WASM in Scrypto. Partial support (BLS verification, Keccak hash) is implemented natively via Client API. --- radix-engine-common/Cargo.toml | 3 +++ radix-engine-common/src/crypto/bls12381/mod.rs | 2 ++ radix-engine-common/src/crypto/ed25519/mod.rs | 2 ++ radix-engine-common/src/crypto/mod.rs | 6 ++++++ radix-engine-common/src/crypto/secp256k1/mod.rs | 2 ++ 5 files changed, 15 insertions(+) diff --git a/radix-engine-common/Cargo.toml b/radix-engine-common/Cargo.toml index 4f5abddeb8c..3c4a692a5f2 100644 --- a/radix-engine-common/Cargo.toml +++ b/radix-engine-common/Cargo.toml @@ -24,6 +24,9 @@ arbitrary = { version = "1.3.0", features = ["derive"], optional = true } # Fast alternative to bigint but unfortunately not cross-compiled to WASM rug = { version = "1.18", optional = true } ethnum = {version = "1.3.2", default-features = false, optional = true } + +# Do not include crypto-related dependencies when building for WASM. +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] ed25519-dalek = { version = "1.0.1", default-features = false, features = ["u64_backend"]} secp256k1 = { version = "0.24.0", default-features = false, features = ["recovery"]} blst = { version = "0.3.11", default-features = false } diff --git a/radix-engine-common/src/crypto/bls12381/mod.rs b/radix-engine-common/src/crypto/bls12381/mod.rs index d83eaa9db8e..c45b976b438 100644 --- a/radix-engine-common/src/crypto/bls12381/mod.rs +++ b/radix-engine-common/src/crypto/bls12381/mod.rs @@ -1,7 +1,9 @@ +#[cfg(not(target_arch = "wasm32"))] mod private_key; mod public_key; mod signature; +#[cfg(not(target_arch = "wasm32"))] pub use private_key::*; pub use public_key::*; pub use signature::*; diff --git a/radix-engine-common/src/crypto/ed25519/mod.rs b/radix-engine-common/src/crypto/ed25519/mod.rs index d83eaa9db8e..c45b976b438 100644 --- a/radix-engine-common/src/crypto/ed25519/mod.rs +++ b/radix-engine-common/src/crypto/ed25519/mod.rs @@ -1,7 +1,9 @@ +#[cfg(not(target_arch = "wasm32"))] mod private_key; mod public_key; mod signature; +#[cfg(not(target_arch = "wasm32"))] pub use private_key::*; pub use public_key::*; pub use signature::*; diff --git a/radix-engine-common/src/crypto/mod.rs b/radix-engine-common/src/crypto/mod.rs index 16127526e7b..f7f1780e4d8 100644 --- a/radix-engine-common/src/crypto/mod.rs +++ b/radix-engine-common/src/crypto/mod.rs @@ -3,12 +3,15 @@ mod bls12381; mod ed25519; mod hash; mod hash_accumulator; +#[cfg(not(target_arch = "wasm32"))] mod private_key; mod public_key; mod public_key_hash; mod secp256k1; mod signature; +#[cfg(not(target_arch = "wasm32"))] mod signature_validator; +#[cfg(not(target_arch = "wasm32"))] mod signer; pub use self::blake2b::*; @@ -16,10 +19,13 @@ pub use self::bls12381::*; pub use self::ed25519::*; pub use self::hash::*; pub use self::hash_accumulator::*; +#[cfg(not(target_arch = "wasm32"))] pub use self::private_key::*; pub use self::public_key::*; pub use self::public_key_hash::*; pub use self::secp256k1::*; pub use self::signature::*; +#[cfg(not(target_arch = "wasm32"))] pub use self::signature_validator::*; +#[cfg(not(target_arch = "wasm32"))] pub use self::signer::*; diff --git a/radix-engine-common/src/crypto/secp256k1/mod.rs b/radix-engine-common/src/crypto/secp256k1/mod.rs index d83eaa9db8e..c45b976b438 100644 --- a/radix-engine-common/src/crypto/secp256k1/mod.rs +++ b/radix-engine-common/src/crypto/secp256k1/mod.rs @@ -1,7 +1,9 @@ +#[cfg(not(target_arch = "wasm32"))] mod private_key; mod public_key; mod signature; +#[cfg(not(target_arch = "wasm32"))] pub use private_key::*; pub use public_key::*; pub use signature::*; From 10f2f7737a806a6e0f11755c9f76697af26879ef Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Tue, 5 Dec 2023 13:27:21 +0100 Subject: [PATCH 22/82] Add support for Keccak256 hash --- radix-engine-common/Cargo.toml | 3 ++- radix-engine-common/src/crypto/keccak256.rs | 26 +++++++++++++++++++++ radix-engine-common/src/crypto/mod.rs | 4 ++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 radix-engine-common/src/crypto/keccak256.rs diff --git a/radix-engine-common/Cargo.toml b/radix-engine-common/Cargo.toml index 3c4a692a5f2..b9c737d4cad 100644 --- a/radix-engine-common/Cargo.toml +++ b/radix-engine-common/Cargo.toml @@ -30,6 +30,7 @@ ethnum = {version = "1.3.2", default-features = false, optional = true } ed25519-dalek = { version = "1.0.1", default-features = false, features = ["u64_backend"]} secp256k1 = { version = "0.24.0", default-features = false, features = ["recovery"]} blst = { version = "0.3.11", default-features = false } +sha3 = { version = "0.10.8", default-features = false } [dev-dependencies] serde_json = { version = "1.0.81", default-features = false } @@ -47,7 +48,7 @@ harness = false # You should enable either `std` or `alloc` default = ["std"] serde = ["dep:serde", "utils/serde", "sbor/serde", "hex/serde"] -std = ["hex/std", "sbor/std", "utils/std", "radix-engine-derive/std", "serde_json/std", "ed25519-dalek/std", "secp256k1/std", "blake2/std"] +std = ["hex/std", "sbor/std", "utils/std", "radix-engine-derive/std", "serde_json/std", "ed25519-dalek/std", "secp256k1/std", "blake2/std", "sha3/std" ] alloc = ["hex/alloc", "sbor/alloc", "utils/alloc", "radix-engine-derive/alloc", "serde_json/alloc", "ed25519-dalek/alloc", "secp256k1/alloc", "lazy_static/spin_no_std"] # This flag is set by fuzz-tests framework and it is used to disable/enable some optional features diff --git a/radix-engine-common/src/crypto/keccak256.rs b/radix-engine-common/src/crypto/keccak256.rs new file mode 100644 index 00000000000..ded9000efd5 --- /dev/null +++ b/radix-engine-common/src/crypto/keccak256.rs @@ -0,0 +1,26 @@ +use crate::crypto::*; +use sha3::{Digest, Keccak256}; + +pub fn keccak_256_hash>(data: T) -> Hash { + let mut hasher = Keccak256::new(); + hasher.update(data); + let hash = hasher.finalize(); + Hash(hash.into()) +} + +#[cfg(test)] +mod tests { + use super::*; + use sbor::rust::str::FromStr; + + #[test] + fn test_keccak_256_hash() { + let data = "Hello Radix"; + let hash = keccak_256_hash(data); + assert_eq!( + hash, + Hash::from_str("415942230ddb029416a4612818536de230d827cbac9646a0b26d9855a4c45587") + .unwrap() + ); + } +} diff --git a/radix-engine-common/src/crypto/mod.rs b/radix-engine-common/src/crypto/mod.rs index f7f1780e4d8..4ec0a2eca29 100644 --- a/radix-engine-common/src/crypto/mod.rs +++ b/radix-engine-common/src/crypto/mod.rs @@ -4,6 +4,8 @@ mod ed25519; mod hash; mod hash_accumulator; #[cfg(not(target_arch = "wasm32"))] +mod keccak256; +#[cfg(not(target_arch = "wasm32"))] mod private_key; mod public_key; mod public_key_hash; @@ -20,6 +22,8 @@ pub use self::ed25519::*; pub use self::hash::*; pub use self::hash_accumulator::*; #[cfg(not(target_arch = "wasm32"))] +pub use self::keccak256::*; +#[cfg(not(target_arch = "wasm32"))] pub use self::private_key::*; pub use self::public_key::*; pub use self::public_key_hash::*; From 89a9aca2f7100becc6dbeeeeaa396961c109d1aa Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Tue, 5 Dec 2023 13:28:17 +0100 Subject: [PATCH 23/82] Switch keccak_hash() to real Keccak256 hash --- radix-engine-tests/tests/system/crypto_utils.rs | 4 ++-- radix-engine/src/system/system.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/radix-engine-tests/tests/system/crypto_utils.rs b/radix-engine-tests/tests/system/crypto_utils.rs index 6d478a812ed..05c358e4455 100644 --- a/radix-engine-tests/tests/system/crypto_utils.rs +++ b/radix-engine-tests/tests/system/crypto_utils.rs @@ -97,11 +97,11 @@ fn test_crypto_scrypto_keccak_hash() { // Assert assert_eq!( data1_hash, - Hash::from_str("48f1bd08444b5e713db9e14caac2faae71836786ac94d645b00679728202a935").unwrap() + Hash::from_str("415942230ddb029416a4612818536de230d827cbac9646a0b26d9855a4c45587").unwrap() ); assert_ne!( data2_hash, - Hash::from_str("48f1bd08444b5e713db9e14caac2faae71836786ac94d645b00679728202a935").unwrap() + Hash::from_str("415942230ddb029416a4612818536de230d827cbac9646a0b26d9855a4c45587").unwrap() ); } diff --git a/radix-engine/src/system/system.rs b/radix-engine/src/system/system.rs index 90cd0df4bd1..faa42632b93 100644 --- a/radix-engine/src/system/system.rs +++ b/radix-engine/src/system/system.rs @@ -2872,7 +2872,7 @@ where #[trace_resources] fn keccak_hash(&mut self, data: Vec) -> Result { // TODO: apply execution costs - Ok(blake2b_256_hash(&data)) + Ok(keccak_256_hash(&data)) } } From 5321cfe4eff454dfac4829681580bfdf9783edb8 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Tue, 5 Dec 2023 16:14:15 +0100 Subject: [PATCH 24/82] Fix return type of crypto_utils_bls_verify --- .../assets/blueprints/crypto_scrypto/src/lib.rs | 3 +-- scrypto/src/engine/scrypto_env.rs | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs b/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs index aaa18d454d3..8f14de128d4 100644 --- a/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs +++ b/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs @@ -6,8 +6,7 @@ mod component_module { impl CryptoScrypto { pub fn bls_verify(msg_hash: Hash, pub_key: BlsPublicKey, signature: BlsSignature) -> bool { - let rtn = ScryptoVmV1Api::crypto_utils_bls_verify(msg_hash, pub_key, signature) != 0; - rtn + ScryptoVmV1Api::crypto_utils_bls_verify(msg_hash, pub_key, signature) } pub fn keccak_hash(data: Vec) -> Hash { diff --git a/scrypto/src/engine/scrypto_env.rs b/scrypto/src/engine/scrypto_env.rs index 8766e7f119c..a9dc5d85dc8 100644 --- a/scrypto/src/engine/scrypto_env.rs +++ b/scrypto/src/engine/scrypto_env.rs @@ -326,7 +326,7 @@ impl ScryptoVmV1Api { msg_hash: Hash, public_key: BlsPublicKey, signature: BlsSignature, - ) -> u32 { + ) -> bool { unsafe { crypto_utils::crypto_utils_bls_verify( msg_hash.0.as_ptr(), @@ -335,7 +335,7 @@ impl ScryptoVmV1Api { public_key.0.len(), signature.0.as_ptr(), signature.0.len(), - ) + ) != 0 } } From 27f3e8d28b6bb9c1b498a0ccddf8a38c82e6541f Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Wed, 6 Dec 2023 08:36:13 +0100 Subject: [PATCH 25/82] Add BlsSignature to well known types --- .../src/crypto/bls12381/signature.rs | 14 ++++++-- .../data/scrypto/custom_well_known_types.rs | 34 +++++++++++++------ 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/radix-engine-common/src/crypto/bls12381/signature.rs b/radix-engine-common/src/crypto/bls12381/signature.rs index e4c3050b602..f9f6f4f9167 100644 --- a/radix-engine-common/src/crypto/bls12381/signature.rs +++ b/radix-engine-common/src/crypto/bls12381/signature.rs @@ -1,4 +1,4 @@ -use crate::ScryptoSbor; +use crate::internal_prelude::*; use sbor::rust::borrow::ToOwned; use sbor::rust::fmt; use sbor::rust::str::FromStr; @@ -11,11 +11,21 @@ pub const BLS_SCHEME: &[u8] = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_"; /// Represents a BLS signature (variant with 96-byte signature and 48-byte public key) #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, Copy, PartialEq, Eq, Hash, Sbor)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Categorize, Encode, Decode, BasicDescribe)] +#[sbor(transparent)] pub struct BlsSignature( #[cfg_attr(feature = "serde", serde(with = "hex::serde"))] pub [u8; Self::LENGTH], ); +impl Describe for BlsSignature { + const TYPE_ID: RustTypeId = + RustTypeId::WellKnown(well_known_scrypto_custom_types::BLS_SIGNATURE_TYPE); + + fn type_data() -> ScryptoTypeData { + well_known_scrypto_custom_types::bls_signature_type_data() + } +} + impl BlsSignature { pub const LENGTH: usize = 96; diff --git a/radix-engine-common/src/data/scrypto/custom_well_known_types.rs b/radix-engine-common/src/data/scrypto/custom_well_known_types.rs index c9698cf7d63..6f5ff981fe5 100644 --- a/radix-engine-common/src/data/scrypto/custom_well_known_types.rs +++ b/radix-engine-common/src/data/scrypto/custom_well_known_types.rs @@ -92,7 +92,7 @@ fn bytes_fixed_length_type_data(length: usize) -> ScryptoType const REFERENCES_START: u8 = 0x80; const OWNED_ENTITIES_START: u8 = 0xa0; const MISC_TYPES_START: u8 = 0xc0; -const KEY_TYPES_START: u8 = 0xd0; +const CRYPTO_TYPES_START: u8 = 0xd0; const ROLE_ASSIGNMENT_TYPES_START: u8 = 0xe0; const OTHER_MODULE_TYPES_START: u8 = 0xf0; @@ -379,10 +379,15 @@ create_well_known_lookup!( MISC_TYPES_START + 7, named_transparent("Origin", string_type_data(),) ), - // Public key-related types from KEY_TYPES_START + ( + HASH, + MISC_TYPES_START + 8, + named_transparent("Hash", bytes_fixed_length_type_data(Hash::LENGTH),) + ), + // Crypto-related types from CRYPTO_TYPES_START ( PUBLIC_KEY, - KEY_TYPES_START + 0, + CRYPTO_TYPES_START + 0, named_enum( "PublicKey", [ @@ -393,7 +398,7 @@ create_well_known_lookup!( ), ( SECP256K1_PUBLIC_KEY, - KEY_TYPES_START + 1, + CRYPTO_TYPES_START + 1, named_transparent( "Secp256k1PublicKey", bytes_fixed_length_type_data(Secp256k1PublicKey::LENGTH), @@ -401,7 +406,7 @@ create_well_known_lookup!( ), ( ED25519_PUBLIC_KEY, - KEY_TYPES_START + 2, + CRYPTO_TYPES_START + 2, named_transparent( "Ed25519PublicKey", bytes_fixed_length_type_data(Ed25519PublicKey::LENGTH), @@ -409,7 +414,7 @@ create_well_known_lookup!( ), ( BLS_PUBLIC_KEY, - KEY_TYPES_START + 3, + CRYPTO_TYPES_START + 3, named_transparent( "BlsPublicKey", bytes_fixed_length_type_data(BlsPublicKey::LENGTH), @@ -417,7 +422,7 @@ create_well_known_lookup!( ), ( PUBLIC_KEY_HASH, - KEY_TYPES_START + 8, + CRYPTO_TYPES_START + 8, named_enum( "PublicKeyHash", [ @@ -431,7 +436,7 @@ create_well_known_lookup!( ), ( SECP256K1_PUBLIC_KEY_HASH, - KEY_TYPES_START + 9, + CRYPTO_TYPES_START + 9, named_transparent( "Secp256k1PublicKeyHash", bytes_fixed_length_type_data(Secp256k1PublicKeyHash::LENGTH), @@ -439,12 +444,20 @@ create_well_known_lookup!( ), ( ED25519_PUBLIC_KEY_HASH, - KEY_TYPES_START + 10, + CRYPTO_TYPES_START + 10, named_transparent( "Ed25519PublicKeyHash", bytes_fixed_length_type_data(Ed25519PublicKeyHash::LENGTH), ) ), + ( + BLS_SIGNATURE, + CRYPTO_TYPES_START + 12, + named_transparent( + "BlsSignature", + bytes_fixed_length_type_data(BlsSignature::LENGTH), + ) + ), // ROLE ASSIGNMENT TYPES ( ACCESS_RULE, @@ -611,7 +624,7 @@ mod tests { // URL - tested in interface crate // Origin - tested in interface crate - // KEY-RELATED + // CRYPTO-RELATED test_equivalence( PUBLIC_KEY_TYPE, PublicKey::Ed25519(Ed25519PublicKey([0; Ed25519PublicKey::LENGTH])), @@ -645,6 +658,7 @@ mod tests { SECP256K1_PUBLIC_KEY_HASH_TYPE, Secp256k1PublicKeyHash([0; Secp256k1PublicKeyHash::LENGTH]), ); + test_equivalence(BLS_SIGNATURE_TYPE, BlsSignature([0; BlsSignature::LENGTH])); } fn test_equivalence(id: WellKnownTypeId, value: T) { From 26852a44c01e3fbd3af2ff75159fce10f30d7ec2 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Wed, 6 Dec 2023 12:44:59 +0100 Subject: [PATCH 26/82] Moved some general abstraction objects back to 'transaction' Included: - PrivateKey - SignatureV1 - SignatureWithPublicKeyV1 --- radix-engine-common/src/crypto/mod.rs | 11 --- radix-engine-common/src/crypto/private_key.rs | 27 -------- radix-engine-common/src/crypto/signature.rs | 67 ------------------- .../src/crypto/signature_validator.rs | 21 ------ .../src/builder/transaction_builder.rs | 3 +- transaction/src/lib.rs | 2 + transaction/src/model/v1/intent_signatures.rs | 41 ++++++++++++ transaction/src/model/v1/notary_signature.rs | 24 +++++++ transaction/src/signing/mod.rs | 3 + .../src/signing}/signer.rs | 26 +++++++ transaction/src/validation/mod.rs | 2 + .../src/validation/signature_validator.rs | 22 ++++++ 12 files changed, 122 insertions(+), 127 deletions(-) delete mode 100644 radix-engine-common/src/crypto/private_key.rs delete mode 100644 radix-engine-common/src/crypto/signature.rs create mode 100644 transaction/src/signing/mod.rs rename {radix-engine-common/src/crypto => transaction/src/signing}/signer.rs (74%) create mode 100644 transaction/src/validation/signature_validator.rs diff --git a/radix-engine-common/src/crypto/mod.rs b/radix-engine-common/src/crypto/mod.rs index 4ec0a2eca29..52ca87c9302 100644 --- a/radix-engine-common/src/crypto/mod.rs +++ b/radix-engine-common/src/crypto/mod.rs @@ -5,17 +5,11 @@ mod hash; mod hash_accumulator; #[cfg(not(target_arch = "wasm32"))] mod keccak256; -#[cfg(not(target_arch = "wasm32"))] -mod private_key; mod public_key; mod public_key_hash; mod secp256k1; -mod signature; #[cfg(not(target_arch = "wasm32"))] mod signature_validator; -#[cfg(not(target_arch = "wasm32"))] -mod signer; - pub use self::blake2b::*; pub use self::bls12381::*; pub use self::ed25519::*; @@ -23,13 +17,8 @@ pub use self::hash::*; pub use self::hash_accumulator::*; #[cfg(not(target_arch = "wasm32"))] pub use self::keccak256::*; -#[cfg(not(target_arch = "wasm32"))] -pub use self::private_key::*; pub use self::public_key::*; pub use self::public_key_hash::*; pub use self::secp256k1::*; -pub use self::signature::*; #[cfg(not(target_arch = "wasm32"))] pub use self::signature_validator::*; -#[cfg(not(target_arch = "wasm32"))] -pub use self::signer::*; diff --git a/radix-engine-common/src/crypto/private_key.rs b/radix-engine-common/src/crypto/private_key.rs deleted file mode 100644 index 3aac81fb919..00000000000 --- a/radix-engine-common/src/crypto/private_key.rs +++ /dev/null @@ -1,27 +0,0 @@ -use crate::internal_prelude::*; - -pub enum PrivateKey { - Secp256k1(Secp256k1PrivateKey), - Ed25519(Ed25519PrivateKey), -} - -impl PrivateKey { - pub fn public_key(&self) -> PublicKey { - match self { - PrivateKey::Secp256k1(key) => key.public_key().into(), - PrivateKey::Ed25519(key) => key.public_key().into(), - } - } -} - -impl From for PrivateKey { - fn from(public_key: Secp256k1PrivateKey) -> Self { - Self::Secp256k1(public_key) - } -} - -impl From for PrivateKey { - fn from(public_key: Ed25519PrivateKey) -> Self { - Self::Ed25519(public_key) - } -} diff --git a/radix-engine-common/src/crypto/signature.rs b/radix-engine-common/src/crypto/signature.rs deleted file mode 100644 index f75d5a981f1..00000000000 --- a/radix-engine-common/src/crypto/signature.rs +++ /dev/null @@ -1,67 +0,0 @@ -use super::*; -use crate::internal_prelude::*; - -/// Represents any natively supported signature. -#[cfg_attr( - feature = "serde", - derive(serde::Serialize, serde::Deserialize), - serde(tag = "type", content = "signature") -)] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Sbor)] -pub enum SignatureV1 { - Secp256k1(Secp256k1Signature), - Ed25519(Ed25519Signature), -} - -impl From for SignatureV1 { - fn from(signature: Secp256k1Signature) -> Self { - Self::Secp256k1(signature) - } -} - -impl From for SignatureV1 { - fn from(signature: Ed25519Signature) -> Self { - Self::Ed25519(signature) - } -} - -/// Represents any natively supported signature, including public key. -#[cfg_attr( - feature = "serde", - derive(serde::Serialize, serde::Deserialize), - serde(tag = "type") -)] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, ManifestSbor, ScryptoSbor)] -pub enum SignatureWithPublicKeyV1 { - Secp256k1 { - signature: Secp256k1Signature, - }, - Ed25519 { - public_key: Ed25519PublicKey, - signature: Ed25519Signature, - }, -} - -impl SignatureWithPublicKeyV1 { - pub fn signature(&self) -> SignatureV1 { - match &self { - Self::Secp256k1 { signature } => signature.clone().into(), - Self::Ed25519 { signature, .. } => signature.clone().into(), - } - } -} - -impl From for SignatureWithPublicKeyV1 { - fn from(signature: Secp256k1Signature) -> Self { - Self::Secp256k1 { signature } - } -} - -impl From<(Ed25519PublicKey, Ed25519Signature)> for SignatureWithPublicKeyV1 { - fn from((public_key, signature): (Ed25519PublicKey, Ed25519Signature)) -> Self { - Self::Ed25519 { - public_key, - signature, - } - } -} diff --git a/radix-engine-common/src/crypto/signature_validator.rs b/radix-engine-common/src/crypto/signature_validator.rs index eaa61b8e479..a758fdcf553 100644 --- a/radix-engine-common/src/crypto/signature_validator.rs +++ b/radix-engine-common/src/crypto/signature_validator.rs @@ -1,14 +1,5 @@ use crate::internal_prelude::*; -pub fn recover(signed_hash: &Hash, signature: &SignatureWithPublicKeyV1) -> Option { - match signature { - SignatureWithPublicKeyV1::Secp256k1 { signature } => { - recover_secp256k1(signed_hash, signature).map(Into::into) - } - SignatureWithPublicKeyV1::Ed25519 { public_key, .. } => Some(public_key.clone().into()), - } -} - pub fn recover_secp256k1( signed_hash: &Hash, signature: &Secp256k1Signature, @@ -29,18 +20,6 @@ pub fn recover_secp256k1( None } -pub fn verify(signed_hash: &Hash, public_key: &PublicKey, signature: &SignatureV1) -> bool { - match (public_key, signature) { - (PublicKey::Secp256k1(pk), SignatureV1::Secp256k1(sig)) => { - verify_secp256k1(&signed_hash, pk, sig) - } - (PublicKey::Ed25519(pk), SignatureV1::Ed25519(sig)) => { - verify_ed25519(&signed_hash, pk, sig) - } - _ => false, - } -} - pub fn verify_secp256k1( signed_hash: &Hash, public_key: &Secp256k1PublicKey, diff --git a/transaction/src/builder/transaction_builder.rs b/transaction/src/builder/transaction_builder.rs index 13b8dd2f08a..cd71c470d93 100644 --- a/transaction/src/builder/transaction_builder.rs +++ b/transaction/src/builder/transaction_builder.rs @@ -1,5 +1,5 @@ -use crate::internal_prelude::*; use crate::model::*; +use crate::signing::Signer; pub struct TransactionBuilder { manifest: Option, @@ -122,6 +122,7 @@ mod tests { use super::*; use crate::builder::*; + use crate::internal_prelude::Secp256k1PrivateKey; #[test] fn notary_as_signatory() { diff --git a/transaction/src/lib.rs b/transaction/src/lib.rs index 4e024de413a..35aabc2dae2 100644 --- a/transaction/src/lib.rs +++ b/transaction/src/lib.rs @@ -3,6 +3,7 @@ pub mod data; pub mod errors; pub mod manifest; pub mod model; +pub mod signing; pub mod validation; /// Each module should have its own prelude, which: @@ -18,6 +19,7 @@ pub mod prelude { // Exports from this crate pub use crate::builder::*; pub use crate::model::*; + pub use crate::signing::{PrivateKey, Signer}; } // Extra things which this crate wants which upstream crates likely don't diff --git a/transaction/src/model/v1/intent_signatures.rs b/transaction/src/model/v1/intent_signatures.rs index 82b41d4a70b..1d7fdb3b3b5 100644 --- a/transaction/src/model/v1/intent_signatures.rs +++ b/transaction/src/model/v1/intent_signatures.rs @@ -1,6 +1,47 @@ use super::*; use crate::internal_prelude::*; +/// Represents any natively supported signature, including public key. +#[cfg_attr( + feature = "serde", + derive(serde::Serialize, serde::Deserialize), + serde(tag = "type") +)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, ManifestSbor, ScryptoSbor)] +pub enum SignatureWithPublicKeyV1 { + Secp256k1 { + signature: Secp256k1Signature, + }, + Ed25519 { + public_key: Ed25519PublicKey, + signature: Ed25519Signature, + }, +} + +impl SignatureWithPublicKeyV1 { + pub fn signature(&self) -> SignatureV1 { + match &self { + Self::Secp256k1 { signature } => signature.clone().into(), + Self::Ed25519 { signature, .. } => signature.clone().into(), + } + } +} + +impl From for SignatureWithPublicKeyV1 { + fn from(signature: Secp256k1Signature) -> Self { + Self::Secp256k1 { signature } + } +} + +impl From<(Ed25519PublicKey, Ed25519Signature)> for SignatureWithPublicKeyV1 { + fn from((public_key, signature): (Ed25519PublicKey, Ed25519Signature)) -> Self { + Self::Ed25519 { + public_key, + signature, + } + } +} + #[derive(Debug, Clone, Eq, PartialEq, ManifestSbor)] #[sbor(transparent)] pub struct IntentSignatureV1(pub SignatureWithPublicKeyV1); diff --git a/transaction/src/model/v1/notary_signature.rs b/transaction/src/model/v1/notary_signature.rs index ce48343a908..20136055c5f 100644 --- a/transaction/src/model/v1/notary_signature.rs +++ b/transaction/src/model/v1/notary_signature.rs @@ -1,6 +1,30 @@ use super::*; use crate::internal_prelude::*; +/// Represents any natively supported signature. +#[cfg_attr( + feature = "serde", + derive(serde::Serialize, serde::Deserialize), + serde(tag = "type", content = "signature") +)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Sbor)] +pub enum SignatureV1 { + Secp256k1(Secp256k1Signature), + Ed25519(Ed25519Signature), +} + +impl From for SignatureV1 { + fn from(signature: Secp256k1Signature) -> Self { + Self::Secp256k1(signature) + } +} + +impl From for SignatureV1 { + fn from(signature: Ed25519Signature) -> Self { + Self::Ed25519(signature) + } +} + #[derive(Debug, Clone, Eq, PartialEq, ManifestSbor)] #[sbor(transparent)] pub struct NotarySignatureV1(pub SignatureV1); diff --git a/transaction/src/signing/mod.rs b/transaction/src/signing/mod.rs new file mode 100644 index 00000000000..64b048b7036 --- /dev/null +++ b/transaction/src/signing/mod.rs @@ -0,0 +1,3 @@ +mod signer; + +pub use signer::*; diff --git a/radix-engine-common/src/crypto/signer.rs b/transaction/src/signing/signer.rs similarity index 74% rename from radix-engine-common/src/crypto/signer.rs rename to transaction/src/signing/signer.rs index 4bfa1b38277..2d5a9731c6f 100644 --- a/radix-engine-common/src/crypto/signer.rs +++ b/transaction/src/signing/signer.rs @@ -1,6 +1,32 @@ use crate::internal_prelude::*; use radix_engine_common::prelude::IsHash; +pub enum PrivateKey { + Secp256k1(Secp256k1PrivateKey), + Ed25519(Ed25519PrivateKey), +} + +impl PrivateKey { + pub fn public_key(&self) -> PublicKey { + match self { + PrivateKey::Secp256k1(key) => key.public_key().into(), + PrivateKey::Ed25519(key) => key.public_key().into(), + } + } +} + +impl From for PrivateKey { + fn from(public_key: Secp256k1PrivateKey) -> Self { + Self::Secp256k1(public_key) + } +} + +impl From for PrivateKey { + fn from(public_key: Ed25519PrivateKey) -> Self { + Self::Ed25519(public_key) + } +} + pub trait Signer { fn public_key(&self) -> PublicKey; fn sign_without_public_key(&self, message_hash: &impl IsHash) -> SignatureV1; diff --git a/transaction/src/validation/mod.rs b/transaction/src/validation/mod.rs index 2aa324c3c0f..02c4dd852af 100644 --- a/transaction/src/validation/mod.rs +++ b/transaction/src/validation/mod.rs @@ -1,7 +1,9 @@ mod id_allocator; mod id_validator; +mod signature_validator; mod transaction_validator; pub use id_allocator::*; pub use id_validator::*; +pub use signature_validator::*; pub use transaction_validator::*; diff --git a/transaction/src/validation/signature_validator.rs b/transaction/src/validation/signature_validator.rs new file mode 100644 index 00000000000..db5d6ff8cee --- /dev/null +++ b/transaction/src/validation/signature_validator.rs @@ -0,0 +1,22 @@ +use crate::internal_prelude::*; + +pub fn recover(signed_hash: &Hash, signature: &SignatureWithPublicKeyV1) -> Option { + match signature { + SignatureWithPublicKeyV1::Secp256k1 { signature } => { + recover_secp256k1(signed_hash, signature).map(Into::into) + } + SignatureWithPublicKeyV1::Ed25519 { public_key, .. } => Some(public_key.clone().into()), + } +} + +pub fn verify(signed_hash: &Hash, public_key: &PublicKey, signature: &SignatureV1) -> bool { + match (public_key, signature) { + (PublicKey::Secp256k1(pk), SignatureV1::Secp256k1(sig)) => { + verify_secp256k1(&signed_hash, pk, sig) + } + (PublicKey::Ed25519(pk), SignatureV1::Ed25519(sig)) => { + verify_ed25519(&signed_hash, pk, sig) + } + _ => false, + } +} From d5b87cdb6e5ec6b707aeed51d1fd3d1c950b9860 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Wed, 6 Dec 2023 13:06:03 +0100 Subject: [PATCH 27/82] Move crypto methods to the separated 'CryptoUtils' struct in Scrypto API --- .../blueprints/crypto_scrypto/src/lib.rs | 4 +-- scrypto/src/crypto_utils/crypto_utils.rs | 29 +++++++++++++++++++ scrypto/src/crypto_utils/mod.rs | 3 ++ scrypto/src/engine/scrypto_env.rs | 26 ----------------- scrypto/src/lib.rs | 2 ++ scrypto/src/prelude/mod.rs | 1 + 6 files changed, 37 insertions(+), 28 deletions(-) create mode 100644 scrypto/src/crypto_utils/crypto_utils.rs create mode 100644 scrypto/src/crypto_utils/mod.rs diff --git a/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs b/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs index 8f14de128d4..85ca05fe939 100644 --- a/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs +++ b/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs @@ -6,11 +6,11 @@ mod component_module { impl CryptoScrypto { pub fn bls_verify(msg_hash: Hash, pub_key: BlsPublicKey, signature: BlsSignature) -> bool { - ScryptoVmV1Api::crypto_utils_bls_verify(msg_hash, pub_key, signature) + CryptoUtils::bls_verify(msg_hash, pub_key, signature) } pub fn keccak_hash(data: Vec) -> Hash { - let hash = ScryptoVmV1Api::crypto_utils_keccak_hash(data); + let hash = CryptoUtils::keccak_hash(data); hash } } diff --git a/scrypto/src/crypto_utils/crypto_utils.rs b/scrypto/src/crypto_utils/crypto_utils.rs new file mode 100644 index 00000000000..762f96c8cf5 --- /dev/null +++ b/scrypto/src/crypto_utils/crypto_utils.rs @@ -0,0 +1,29 @@ +use crate::engine::wasm_api::{copy_buffer, crypto_utils}; +use radix_engine_common::prelude::{BlsPublicKey, BlsSignature, Hash}; + +/// Crypto utilities. +#[derive(Debug)] +pub struct CryptoUtils {} + +impl CryptoUtils { + pub fn bls_verify(msg_hash: Hash, public_key: BlsPublicKey, signature: BlsSignature) -> bool { + unsafe { + crypto_utils::crypto_utils_bls_verify( + msg_hash.0.as_ptr(), + msg_hash.0.len(), + public_key.0.as_ptr(), + public_key.0.len(), + signature.0.as_ptr(), + signature.0.len(), + ) != 0 + } + } + + pub fn keccak_hash(data: Vec) -> Hash { + let hash = copy_buffer(unsafe { + crypto_utils::crypto_utils_keccak_hash(data.as_ptr(), data.len()) + }); + + Hash(hash.try_into().unwrap()) + } +} diff --git a/scrypto/src/crypto_utils/mod.rs b/scrypto/src/crypto_utils/mod.rs new file mode 100644 index 00000000000..1afc813c591 --- /dev/null +++ b/scrypto/src/crypto_utils/mod.rs @@ -0,0 +1,3 @@ +mod crypto_utils; + +pub use crypto_utils::*; diff --git a/scrypto/src/engine/scrypto_env.rs b/scrypto/src/engine/scrypto_env.rs index a9dc5d85dc8..2dcc25be46e 100644 --- a/scrypto/src/engine/scrypto_env.rs +++ b/scrypto/src/engine/scrypto_env.rs @@ -1,6 +1,5 @@ use crate::engine::wasm_api::*; use radix_engine_common::math::Decimal; -use radix_engine_common::prelude::{BlsPublicKey, BlsSignature}; use radix_engine_common::types::GlobalAddressReservation; use radix_engine_interface::api::actor_api::EventFlags; use radix_engine_interface::api::key_value_entry_api::KeyValueEntryHandle; @@ -321,29 +320,4 @@ impl ScryptoVmV1Api { system::sys_panic(message.as_ptr(), message.len()); }; } - - pub fn crypto_utils_bls_verify( - msg_hash: Hash, - public_key: BlsPublicKey, - signature: BlsSignature, - ) -> bool { - unsafe { - crypto_utils::crypto_utils_bls_verify( - msg_hash.0.as_ptr(), - msg_hash.0.len(), - public_key.0.as_ptr(), - public_key.0.len(), - signature.0.as_ptr(), - signature.0.len(), - ) != 0 - } - } - - pub fn crypto_utils_keccak_hash(data: Vec) -> Hash { - let hash = copy_buffer(unsafe { - crypto_utils::crypto_utils_keccak_hash(data.as_ptr(), data.len()) - }); - - Hash(hash.try_into().unwrap()) - } } diff --git a/scrypto/src/lib.rs b/scrypto/src/lib.rs index 18d46305c13..f39a1a0fcaa 100644 --- a/scrypto/src/lib.rs +++ b/scrypto/src/lib.rs @@ -18,6 +18,8 @@ compile_error!("Feature `std` and `alloc` can't be enabled at the same time."); /// Scrypto component abstraction. pub mod component; +/// Scrypto crypto utilities abstraction. +pub mod crypto_utils; /// Scrypto engine abstraction. pub mod engine; /// Scrypto module abstraction. diff --git a/scrypto/src/prelude/mod.rs b/scrypto/src/prelude/mod.rs index 1f14980b22c..86c877fdd6e 100644 --- a/scrypto/src/prelude/mod.rs +++ b/scrypto/src/prelude/mod.rs @@ -3,6 +3,7 @@ //============= pub use crate::component::*; +pub use crate::crypto_utils::*; pub use crate::engine::scrypto_env::ScryptoVmV1Api; pub use crate::engine::*; pub use crate::modules::*; From dfb5c6ac18e88ff204a80af0add0f5764ae38497 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Wed, 6 Dec 2023 14:28:34 +0100 Subject: [PATCH 28/82] Let BLS verify accept messages of arbitrary length --- .../src/crypto/bls12381/private_key.rs | 6 ++--- .../src/crypto/signature_validator.rs | 4 +-- .../api/system_modules/crypto_utils_api.rs | 2 +- .../blueprints/crypto_scrypto/src/lib.rs | 8 ++++-- .../benches/transaction_validation.rs | 27 ++++++++++++++----- .../tests/system/crypto_utils.rs | 8 +++--- radix-engine/src/system/system.rs | 4 +-- radix-engine/src/vm/wasm/errors.rs | 1 - radix-engine/src/vm/wasm/traits.rs | 2 +- radix-engine/src/vm/wasm/wasmer.rs | 8 +++--- radix-engine/src/vm/wasm/wasmi.rs | 16 +++++------ .../src/vm/wasm_runtime/no_op_runtime.rs | 2 +- .../src/vm/wasm_runtime/scrypto_runtime.rs | 6 ++--- scrypto-test/src/environment/client_api.rs | 2 +- scrypto/src/crypto_utils/crypto_utils.rs | 6 ++--- scrypto/src/engine/wasm_api.rs | 4 +-- 16 files changed, 61 insertions(+), 45 deletions(-) diff --git a/radix-engine-common/src/crypto/bls12381/private_key.rs b/radix-engine-common/src/crypto/bls12381/private_key.rs index 0c896ac4611..625bb496705 100644 --- a/radix-engine-common/src/crypto/bls12381/private_key.rs +++ b/radix-engine-common/src/crypto/bls12381/private_key.rs @@ -11,8 +11,8 @@ impl BlsPrivateKey { BlsPublicKey(self.0.sk_to_pk().to_bytes()) } - pub fn sign(&self, msg_hash: &impl IsHash) -> BlsSignature { - let signature = self.0.sign(msg_hash.as_ref(), BLS_SCHEME, &[]).to_bytes(); + pub fn sign(&self, message: &[u8]) -> BlsSignature { + let signature = self.0.sign(message, BLS_SCHEME, &[]).to_bytes(); BlsSignature(signature) } @@ -45,7 +45,7 @@ mod tests { fn sign_and_verify() { let test_sk = "408157791befddd702672dcfcfc99da3512f9c0ea818890fcb6ab749580ef2cf"; let test_pk = "93b1aa7542a5423e21d8e84b4472c31664412cc604a666e9fdf03baf3c758e728c7a11576ebb01110ac39a0df95636e2"; - let test_message_hash = hash("Test"); + let test_message_hash = hash("Test").as_bytes().to_vec(); let test_signature = "a2ba96a1fc1e698b7688e077f171fbd7fe99c6bbf240b1421a08e3faa5d6b55523a18b8c77fba5830181dfec716edc3d18a8657bcadd0a83e3cafdad33998d10417f767c536b26b98df41d67ab416c761ad55438f23132a136fc82eb7b290571"; let sk = BlsPrivateKey::from_bytes(&hex::decode(test_sk).unwrap()).unwrap(); let pk = BlsPublicKey::from_str(test_pk).unwrap(); diff --git a/radix-engine-common/src/crypto/signature_validator.rs b/radix-engine-common/src/crypto/signature_validator.rs index a758fdcf553..1589bbbe763 100644 --- a/radix-engine-common/src/crypto/signature_validator.rs +++ b/radix-engine-common/src/crypto/signature_validator.rs @@ -54,10 +54,10 @@ pub fn verify_ed25519( false } -pub fn verify_bls(signed_hash: &Hash, public_key: &BlsPublicKey, signature: &BlsSignature) -> bool { +pub fn verify_bls(message: &[u8], public_key: &BlsPublicKey, signature: &BlsSignature) -> bool { if let Ok(sig) = blst::min_pk::Signature::from_bytes(&signature.0) { if let Ok(pk) = blst::min_pk::PublicKey::from_bytes(&public_key.0) { - let result = sig.verify(true, &signed_hash.0, BLS_SCHEME, &[], &pk, true); + let result = sig.verify(true, message, BLS_SCHEME, &[], &pk, true); match result { blst::BLST_ERROR::BLST_SUCCESS => return true, diff --git a/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs b/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs index 26235e2fb80..b598b02701e 100644 --- a/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs +++ b/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs @@ -4,7 +4,7 @@ use crate::internal_prelude::Vec; pub trait ClientCryptoUtilsApi { fn bls_verify( &mut self, - msg_hash: Hash, + message: Vec, public_key: BlsPublicKey, signature: BlsSignature, ) -> Result; diff --git a/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs b/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs index 85ca05fe939..492501a9c1a 100644 --- a/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs +++ b/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs @@ -5,8 +5,12 @@ mod component_module { struct CryptoScrypto {} impl CryptoScrypto { - pub fn bls_verify(msg_hash: Hash, pub_key: BlsPublicKey, signature: BlsSignature) -> bool { - CryptoUtils::bls_verify(msg_hash, pub_key, signature) + pub fn bls_verify( + message: Vec, + pub_key: BlsPublicKey, + signature: BlsSignature, + ) -> bool { + CryptoUtils::bls_verify(message, pub_key, signature) } pub fn keccak_hash(data: Vec) -> Hash { diff --git a/radix-engine-tests/benches/transaction_validation.rs b/radix-engine-tests/benches/transaction_validation.rs index f5d0c2ebebb..75c7e3c4f41 100644 --- a/radix-engine-tests/benches/transaction_validation.rs +++ b/radix-engine-tests/benches/transaction_validation.rs @@ -32,15 +32,29 @@ fn bench_ed25519_validation(c: &mut Criterion) { }); } -fn bench_bls_validation(c: &mut Criterion) { - let message_hash = hash("This is a long message".repeat(100)); +fn bench_bls_validation_long(c: &mut Criterion) { + let message = vec![0u8; 2048]; + println!("message len = {}", message.len()); let signer = BlsPrivateKey::from_u64(123123123123).unwrap(); let public_key = signer.public_key(); - let signature = signer.sign(&message_hash); + let signature = signer.sign(&message); + + c.bench_function("transaction_validation::verify_bls_2KB", |b| { + b.iter(|| { + verify_bls(&message, &public_key, &signature); + }) + }); +} + +fn bench_bls_validation_short(c: &mut Criterion) { + let message = vec![0u8; 32]; + let signer = BlsPrivateKey::from_u64(123123123123).unwrap(); + let public_key = signer.public_key(); + let signature = signer.sign(&message); - c.bench_function("transaction_validation::verify_bls", |b| { + c.bench_function("transaction_validation::verify_bls_32B", |b| { b.iter(|| { - verify_bls(&message_hash, &public_key, &signature); + verify_bls(&message, &public_key, &signature); }) }); } @@ -99,7 +113,8 @@ criterion_group!( validation, bench_secp256k1_validation, bench_ed25519_validation, - bench_bls_validation, + bench_bls_validation_short, + bench_bls_validation_long, bench_transaction_validation, ); criterion_main!(validation); diff --git a/radix-engine-tests/tests/system/crypto_utils.rs b/radix-engine-tests/tests/system/crypto_utils.rs index 05c358e4455..971637c2288 100644 --- a/radix-engine-tests/tests/system/crypto_utils.rs +++ b/radix-engine-tests/tests/system/crypto_utils.rs @@ -9,11 +9,11 @@ use transaction::builder::ManifestBuilder; fn crypto_scrypto_bls_verify( runner: &mut TestRunner, package_address: PackageAddress, - msg_hash: &str, + msg: &str, pk: &str, sig: &str, ) -> bool { - let msg_hash = Hash::from_str(msg_hash).unwrap(); + let msg = hex::decode(msg).unwrap(); let pub_key = BlsPublicKey::from_str(pk).unwrap(); let signature = BlsSignature::from_str(sig).unwrap(); @@ -24,7 +24,7 @@ fn crypto_scrypto_bls_verify( package_address, "CryptoScrypto", "bls_verify", - manifest_args!(msg_hash, pub_key, signature), + manifest_args!(msg, pub_key, signature), ) .build(), vec![], @@ -122,7 +122,7 @@ fn test_crypto_scrypto_flow() { let public_key = secret_key.public_key(); // Sign the message hash using BLS - let msg_signature = secret_key.sign(&msg_hash); + let msg_signature = secret_key.sign(msg_hash.as_slice()); // Verify the BLS signature using CryptoScrypto package let result = crypto_scrypto_bls_verify( diff --git a/radix-engine/src/system/system.rs b/radix-engine/src/system/system.rs index faa42632b93..9f3905963aa 100644 --- a/radix-engine/src/system/system.rs +++ b/radix-engine/src/system/system.rs @@ -2861,12 +2861,12 @@ where #[trace_resources] fn bls_verify( &mut self, - msg_hash: Hash, + message: Vec, public_key: BlsPublicKey, signature: BlsSignature, ) -> Result { // TODO: apply execution costs - Ok(verify_bls(&msg_hash, &public_key, &signature) as u32) + Ok(verify_bls(&message, &public_key, &signature) as u32) } #[trace_resources] diff --git a/radix-engine/src/vm/wasm/errors.rs b/radix-engine/src/vm/wasm/errors.rs index 40e12f6dfb3..d22d146f5ad 100644 --- a/radix-engine/src/vm/wasm/errors.rs +++ b/radix-engine/src/vm/wasm/errors.rs @@ -156,7 +156,6 @@ pub enum WasmRuntimeError { InvalidBlsPublicKey(ParseBlsPublicKeyError), InvalidBlsSignature(ParseBlsSignatureError), - InvalidHash(ParseHashError), } impl SelfError for WasmRuntimeError { diff --git a/radix-engine/src/vm/wasm/traits.rs b/radix-engine/src/vm/wasm/traits.rs index de09941550b..1c044590661 100644 --- a/radix-engine/src/vm/wasm/traits.rs +++ b/radix-engine/src/vm/wasm/traits.rs @@ -203,7 +203,7 @@ pub trait WasmRuntime { fn crypto_utils_bls_verify( &mut self, - msg_hash: Vec, + message: Vec, public_key: Vec, signature: Vec, ) -> Result>; diff --git a/radix-engine/src/vm/wasm/wasmer.rs b/radix-engine/src/vm/wasm/wasmer.rs index edff94698e3..3a9212c547e 100644 --- a/radix-engine/src/vm/wasm/wasmer.rs +++ b/radix-engine/src/vm/wasm/wasmer.rs @@ -678,8 +678,8 @@ impl WasmerModule { pub fn bls_verify( env: &WasmerInstanceEnv, - msg_hash_ptr: u32, - msg_hash_len: u32, + message_ptr: u32, + message_len: u32, public_key_ptr: u32, public_key_len: u32, signature_ptr: u32, @@ -687,12 +687,12 @@ impl WasmerModule { ) -> Result> { let (instance, runtime) = grab_runtime!(env); - let msg_hash = read_memory(&instance, msg_hash_ptr, msg_hash_len)?; + let message = read_memory(&instance, message_ptr, message_len)?; let public_key = read_memory(&instance, public_key_ptr, public_key_len)?; let signature = read_memory(instance, signature_ptr, signature_len)?; - runtime.crypto_utils_bls_verify(msg_hash, public_key, signature) + runtime.crypto_utils_bls_verify(message, public_key, signature) } pub fn keccak_hash( diff --git a/radix-engine/src/vm/wasm/wasmi.rs b/radix-engine/src/vm/wasm/wasmi.rs index 950147c9729..7f0f44cbf41 100644 --- a/radix-engine/src/vm/wasm/wasmi.rs +++ b/radix-engine/src/vm/wasm/wasmi.rs @@ -665,8 +665,8 @@ fn panic( fn bls_verify( mut caller: Caller<'_, HostState>, - msg_hash_ptr: u32, - msg_hash_len: u32, + message_ptr: u32, + message_len: u32, public_key_ptr: u32, public_key_len: u32, signature_ptr: u32, @@ -674,7 +674,7 @@ fn bls_verify( ) -> Result> { let (memory, runtime) = grab_runtime!(caller); - let msg_hash = read_memory(caller.as_context_mut(), memory, msg_hash_ptr, msg_hash_len)?; + let message = read_memory(caller.as_context_mut(), memory, message_ptr, message_len)?; let public_key = read_memory( caller.as_context_mut(), memory, @@ -688,7 +688,7 @@ fn bls_verify( signature_len, )?; - runtime.crypto_utils_bls_verify(msg_hash, public_key, signature) + runtime.crypto_utils_bls_verify(message, public_key, signature) } fn keccak_hash( @@ -1271,8 +1271,8 @@ impl WasmiModule { let host_bls_verify = Func::wrap( store.as_context_mut(), |caller: Caller<'_, HostState>, - msg_hash_ptr: u32, - msg_hash_len: u32, + message_ptr: u32, + message_len: u32, public_key_ptr: u32, public_key_len: u32, signature_ptr: u32, @@ -1280,8 +1280,8 @@ impl WasmiModule { -> Result { bls_verify( caller, - msg_hash_ptr, - msg_hash_len, + message_ptr, + message_len, public_key_ptr, public_key_len, signature_ptr, diff --git a/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs b/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs index cdc0bc04138..172d498860a 100644 --- a/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs +++ b/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs @@ -308,7 +308,7 @@ impl<'a> WasmRuntime for NoOpWasmRuntime<'a> { fn crypto_utils_bls_verify( &mut self, - msg_hash: Vec, + message: Vec, public_key: Vec, signature: Vec, ) -> Result> { diff --git a/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs b/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs index eab22da2926..f74bc8d7205 100644 --- a/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs +++ b/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs @@ -563,17 +563,15 @@ where fn crypto_utils_bls_verify( &mut self, - msg_hash: Vec, + message: Vec, public_key: Vec, signature: Vec, ) -> Result> { - let msg_hash = - Hash::try_from(msg_hash.as_slice()).map_err(WasmRuntimeError::InvalidHash)?; let public_key = BlsPublicKey::try_from(public_key.as_slice()) .map_err(WasmRuntimeError::InvalidBlsPublicKey)?; let signature = BlsSignature::try_from(signature.as_slice()) .map_err(WasmRuntimeError::InvalidBlsSignature)?; - let result = self.api.bls_verify(msg_hash, public_key, signature)?; + let result = self.api.bls_verify(message, public_key, signature)?; Ok(result) } diff --git a/scrypto-test/src/environment/client_api.rs b/scrypto-test/src/environment/client_api.rs index c3677321888..b209a371aad 100644 --- a/scrypto-test/src/environment/client_api.rs +++ b/scrypto-test/src/environment/client_api.rs @@ -276,7 +276,7 @@ implement_client_api! { fee_balance: (&mut self) -> Result, }, ClientCryptoUtilsApi: { - bls_verify: (&mut self, msg_hash: Hash, public_key: BlsPublicKey, signature: BlsSignature) -> Result, + bls_verify: (&mut self, message: Vec, public_key: BlsPublicKey, signature: BlsSignature) -> Result, keccak_hash: (&mut self, data: Vec) -> Result, }, } diff --git a/scrypto/src/crypto_utils/crypto_utils.rs b/scrypto/src/crypto_utils/crypto_utils.rs index 762f96c8cf5..6890b7179cd 100644 --- a/scrypto/src/crypto_utils/crypto_utils.rs +++ b/scrypto/src/crypto_utils/crypto_utils.rs @@ -6,11 +6,11 @@ use radix_engine_common::prelude::{BlsPublicKey, BlsSignature, Hash}; pub struct CryptoUtils {} impl CryptoUtils { - pub fn bls_verify(msg_hash: Hash, public_key: BlsPublicKey, signature: BlsSignature) -> bool { + pub fn bls_verify(message: Vec, public_key: BlsPublicKey, signature: BlsSignature) -> bool { unsafe { crypto_utils::crypto_utils_bls_verify( - msg_hash.0.as_ptr(), - msg_hash.0.len(), + message.as_ptr(), + message.len(), public_key.0.as_ptr(), public_key.0.len(), signature.0.as_ptr(), diff --git a/scrypto/src/engine/wasm_api.rs b/scrypto/src/engine/wasm_api.rs index 84add98b85c..ea4913689a0 100644 --- a/scrypto/src/engine/wasm_api.rs +++ b/scrypto/src/engine/wasm_api.rs @@ -290,8 +290,8 @@ pub mod crypto_utils { super::wasm_extern_c! { pub fn crypto_utils_bls_verify( - hash_ptr: *const u8, - hash_len: usize, + message_ptr: *const u8, + message_len: usize, public_key_ptr: *const u8, public_key_len: usize, signature_ptr: *const u8, From 31599df300f104a45d924acf116d3afcce3488e8 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Wed, 6 Dec 2023 15:20:50 +0100 Subject: [PATCH 29/82] Fix no_std --- scrypto/src/crypto_utils/crypto_utils.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/scrypto/src/crypto_utils/crypto_utils.rs b/scrypto/src/crypto_utils/crypto_utils.rs index 6890b7179cd..9518ad7849f 100644 --- a/scrypto/src/crypto_utils/crypto_utils.rs +++ b/scrypto/src/crypto_utils/crypto_utils.rs @@ -1,5 +1,6 @@ use crate::engine::wasm_api::{copy_buffer, crypto_utils}; use radix_engine_common::prelude::{BlsPublicKey, BlsSignature, Hash}; +use sbor::prelude::Vec; /// Crypto utilities. #[derive(Debug)] From d01014af0b89d3edb2278472dfc7ae5517a9ba33 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Wed, 6 Dec 2023 15:21:53 +0100 Subject: [PATCH 30/82] Fix formatting --- radix-engine-common/src/crypto/bls12381/signature.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/radix-engine-common/src/crypto/bls12381/signature.rs b/radix-engine-common/src/crypto/bls12381/signature.rs index f9f6f4f9167..73754b3903a 100644 --- a/radix-engine-common/src/crypto/bls12381/signature.rs +++ b/radix-engine-common/src/crypto/bls12381/signature.rs @@ -11,7 +11,9 @@ pub const BLS_SCHEME: &[u8] = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_"; /// Represents a BLS signature (variant with 96-byte signature and 48-byte public key) #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Categorize, Encode, Decode, BasicDescribe)] +#[derive( + Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Categorize, Encode, Decode, BasicDescribe, +)] #[sbor(transparent)] pub struct BlsSignature( #[cfg_attr(feature = "serde", serde(with = "hex::serde"))] pub [u8; Self::LENGTH], From 61f4d8887ea9f6b2cf0bcdd9343d333fb29f231b Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Thu, 7 Dec 2023 09:42:26 +0100 Subject: [PATCH 31/82] Change BLS scheme to the one used by Supra Details: - G2 - min pubkey - scheme: proof-of-possession --- .../src/crypto/bls12381/private_key.rs | 27 ++++++++++++++++++- .../src/crypto/bls12381/signature.rs | 10 ++++++- .../tests/system/crypto_utils.rs | 2 +- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/radix-engine-common/src/crypto/bls12381/private_key.rs b/radix-engine-common/src/crypto/bls12381/private_key.rs index 625bb496705..5773740d0ad 100644 --- a/radix-engine-common/src/crypto/bls12381/private_key.rs +++ b/radix-engine-common/src/crypto/bls12381/private_key.rs @@ -46,7 +46,32 @@ mod tests { let test_sk = "408157791befddd702672dcfcfc99da3512f9c0ea818890fcb6ab749580ef2cf"; let test_pk = "93b1aa7542a5423e21d8e84b4472c31664412cc604a666e9fdf03baf3c758e728c7a11576ebb01110ac39a0df95636e2"; let test_message_hash = hash("Test").as_bytes().to_vec(); - let test_signature = "a2ba96a1fc1e698b7688e077f171fbd7fe99c6bbf240b1421a08e3faa5d6b55523a18b8c77fba5830181dfec716edc3d18a8657bcadd0a83e3cafdad33998d10417f767c536b26b98df41d67ab416c761ad55438f23132a136fc82eb7b290571"; + let test_signature = "8b84ff5a1d4f8095ab8a80518ac99230ed24a7d1ec90c4105f9c719aa7137ed5d7ce1454d4a953f5f55f3959ab416f3014f4cd2c361e4d32c6b4704a70b0e2e652a908f501acb54ec4e79540be010e3fdc1fbf8e7af61625705e185a71c884f1"; + let sk = BlsPrivateKey::from_bytes(&hex::decode(test_sk).unwrap()).unwrap(); + let pk = BlsPublicKey::from_str(test_pk).unwrap(); + let sig = BlsSignature::from_str(test_signature).unwrap(); + + assert_eq!(sk.public_key(), pk); + assert_eq!(sk.sign(&test_message_hash), sig); + assert!(verify_bls(&test_message_hash, &pk, &sig)); + } + + #[test] + fn sign_and_verify_supra() { + // Supra example + let test_pk = "8a38419cb83c15a92d11243384bea0acd15cbacc24b385b9c577b17272d6ad68bb53c52dbbf79324005528d2d73c2643"; + let test_sk = "5B00CC8C7153F39EF2E6E2FADB1BB95A1F4BF21F43CC5B28EFA9E526FB788C08"; + let test_message_hash = keccak_256_hash("Hello World!"); + + assert_eq!( + test_message_hash, + Hash::from_str("3ea2f1d0abf3fc66cf29eebb70cbd4e7fe762ef8a09bcc06c8edf641230afec0") + .unwrap() + ); + let test_message_hash = test_message_hash.to_vec(); + + let test_signature = "82131f69b6699755f830e29d6ed41cbf759591a2ab598aa4e9686113341118d1db900d190436048601791121b5757c341045d4d0c94a95ec31a9ba6205f9b7504de85dadff52874375c58eec6cec28397279de87d5595101e398d31646d345bb"; + let sk = BlsPrivateKey::from_bytes(&hex::decode(test_sk).unwrap()).unwrap(); let pk = BlsPublicKey::from_str(test_pk).unwrap(); let sig = BlsSignature::from_str(test_signature).unwrap(); diff --git a/radix-engine-common/src/crypto/bls12381/signature.rs b/radix-engine-common/src/crypto/bls12381/signature.rs index 73754b3903a..edaaf487ae4 100644 --- a/radix-engine-common/src/crypto/bls12381/signature.rs +++ b/radix-engine-common/src/crypto/bls12381/signature.rs @@ -7,7 +7,15 @@ use sbor::rust::vec::Vec; use sbor::*; use utils::copy_u8_array; -pub const BLS_SCHEME: &[u8] = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_"; +// Ciphersuite for BLS12-381 +// - hash-to-curve: BLS12381G2_XMD:SHA-256_SSWU_RO +// - pairing-friendly elliptic curve: BLS12-381 +// - hash function: SHA-256 +// - signature variant: G2 minimal pubkey size +// - scheme: +// - proof-of-possession +pub const BLS_SCHEME: &[u8] = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_"; +// More details: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04 /// Represents a BLS signature (variant with 96-byte signature and 48-byte public key) #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] diff --git a/radix-engine-tests/tests/system/crypto_utils.rs b/radix-engine-tests/tests/system/crypto_utils.rs index 971637c2288..94d3b71ccef 100644 --- a/radix-engine-tests/tests/system/crypto_utils.rs +++ b/radix-engine-tests/tests/system/crypto_utils.rs @@ -67,7 +67,7 @@ fn test_crypto_scrypto_bls_verify() { let msg1 = hash("Test").to_string(); let msg2 = hash("ExpectFailureTest").to_string(); let pk = "93b1aa7542a5423e21d8e84b4472c31664412cc604a666e9fdf03baf3c758e728c7a11576ebb01110ac39a0df95636e2"; - let msg1_signature = "a2ba96a1fc1e698b7688e077f171fbd7fe99c6bbf240b1421a08e3faa5d6b55523a18b8c77fba5830181dfec716edc3d18a8657bcadd0a83e3cafdad33998d10417f767c536b26b98df41d67ab416c761ad55438f23132a136fc82eb7b290571"; + let msg1_signature = "8b84ff5a1d4f8095ab8a80518ac99230ed24a7d1ec90c4105f9c719aa7137ed5d7ce1454d4a953f5f55f3959ab416f3014f4cd2c361e4d32c6b4704a70b0e2e652a908f501acb54ec4e79540be010e3fdc1fbf8e7af61625705e185a71c884f1"; // Act let msg1_verify = From 59fc3274a13ee38c3cc91967759c4b7f6b5b1b3c Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Fri, 8 Dec 2023 09:31:38 +0100 Subject: [PATCH 32/82] Rename BLS related stuff more specifically --- .../src/crypto/bls12381/private_key.rs | 42 ++++++++--------- .../src/crypto/bls12381/public_key.rs | 24 +++++----- .../src/crypto/bls12381/signature.rs | 45 ++++++++++--------- .../src/crypto/signature_validator.rs | 10 ++++- .../data/scrypto/custom_well_known_types.rs | 22 +++++---- .../api/system_modules/crypto_utils_api.rs | 6 +-- .../blueprints/crypto_scrypto/src/lib.rs | 8 ++-- .../benches/transaction_validation.rs | 12 ++--- .../tests/system/crypto_utils.rs | 34 +++++++++----- radix-engine/src/system/system.rs | 8 ++-- radix-engine/src/vm/wasm/constants.rs | 2 +- radix-engine/src/vm/wasm/prepare.rs | 2 +- radix-engine/src/vm/wasm/traits.rs | 2 +- radix-engine/src/vm/wasm/wasmer.rs | 6 +-- radix-engine/src/vm/wasm/wasmi.rs | 12 ++--- .../src/vm/wasm_runtime/no_op_runtime.rs | 2 +- .../src/vm/wasm_runtime/scrypto_runtime.rs | 10 +++-- scrypto-test/src/environment/client_api.rs | 2 +- scrypto/src/crypto_utils/crypto_utils.rs | 10 +++-- scrypto/src/engine/wasm_api.rs | 2 +- 20 files changed, 145 insertions(+), 116 deletions(-) diff --git a/radix-engine-common/src/crypto/bls12381/private_key.rs b/radix-engine-common/src/crypto/bls12381/private_key.rs index 5773740d0ad..363508b965d 100644 --- a/radix-engine-common/src/crypto/bls12381/private_key.rs +++ b/radix-engine-common/src/crypto/bls12381/private_key.rs @@ -1,19 +1,19 @@ -use super::BlsSignature; +use super::Bls12381G2Signature; use crate::internal_prelude::*; use blst::min_pk::SecretKey; -pub struct BlsPrivateKey(SecretKey); +pub struct Bls12381G1PrivateKey(SecretKey); -impl BlsPrivateKey { +impl Bls12381G1PrivateKey { pub const LENGTH: usize = 32; - pub fn public_key(&self) -> BlsPublicKey { - BlsPublicKey(self.0.sk_to_pk().to_bytes()) + pub fn public_key(&self) -> Bls12381G1PublicKey { + Bls12381G1PublicKey(self.0.sk_to_pk().to_bytes()) } - pub fn sign(&self, message: &[u8]) -> BlsSignature { - let signature = self.0.sign(message, BLS_SCHEME, &[]).to_bytes(); - BlsSignature(signature) + pub fn sign_v1(&self, message: &[u8]) -> Bls12381G2Signature { + let signature = self.0.sign(message, BLS12381_CIPHERSITE_V1, &[]).to_bytes(); + Bls12381G2Signature(signature) } pub fn to_bytes(&self) -> Vec { @@ -21,15 +21,15 @@ impl BlsPrivateKey { } pub fn from_bytes(slice: &[u8]) -> Result { - if slice.len() != BlsPrivateKey::LENGTH { + if slice.len() != Bls12381G1PrivateKey::LENGTH { return Err(()); } Ok(Self(SecretKey::from_bytes(slice).map_err(|_| ())?)) } pub fn from_u64(n: u64) -> Result { - let mut bytes = [0u8; BlsPrivateKey::LENGTH]; - (&mut bytes[BlsPrivateKey::LENGTH - 8..BlsPrivateKey::LENGTH]) + let mut bytes = [0u8; Bls12381G1PrivateKey::LENGTH]; + (&mut bytes[Bls12381G1PrivateKey::LENGTH - 8..Bls12381G1PrivateKey::LENGTH]) .copy_from_slice(&n.to_be_bytes()); Ok(Self(SecretKey::from_bytes(&bytes).map_err(|_| ())?)) @@ -47,13 +47,13 @@ mod tests { let test_pk = "93b1aa7542a5423e21d8e84b4472c31664412cc604a666e9fdf03baf3c758e728c7a11576ebb01110ac39a0df95636e2"; let test_message_hash = hash("Test").as_bytes().to_vec(); let test_signature = "8b84ff5a1d4f8095ab8a80518ac99230ed24a7d1ec90c4105f9c719aa7137ed5d7ce1454d4a953f5f55f3959ab416f3014f4cd2c361e4d32c6b4704a70b0e2e652a908f501acb54ec4e79540be010e3fdc1fbf8e7af61625705e185a71c884f1"; - let sk = BlsPrivateKey::from_bytes(&hex::decode(test_sk).unwrap()).unwrap(); - let pk = BlsPublicKey::from_str(test_pk).unwrap(); - let sig = BlsSignature::from_str(test_signature).unwrap(); + let sk = Bls12381G1PrivateKey::from_bytes(&hex::decode(test_sk).unwrap()).unwrap(); + let pk = Bls12381G1PublicKey::from_str(test_pk).unwrap(); + let sig = Bls12381G2Signature::from_str(test_signature).unwrap(); assert_eq!(sk.public_key(), pk); - assert_eq!(sk.sign(&test_message_hash), sig); - assert!(verify_bls(&test_message_hash, &pk, &sig)); + assert_eq!(sk.sign_v1(&test_message_hash), sig); + assert!(verify_bls12381_v1(&test_message_hash, &pk, &sig)); } #[test] @@ -72,12 +72,12 @@ mod tests { let test_signature = "82131f69b6699755f830e29d6ed41cbf759591a2ab598aa4e9686113341118d1db900d190436048601791121b5757c341045d4d0c94a95ec31a9ba6205f9b7504de85dadff52874375c58eec6cec28397279de87d5595101e398d31646d345bb"; - let sk = BlsPrivateKey::from_bytes(&hex::decode(test_sk).unwrap()).unwrap(); - let pk = BlsPublicKey::from_str(test_pk).unwrap(); - let sig = BlsSignature::from_str(test_signature).unwrap(); + let sk = Bls12381G1PrivateKey::from_bytes(&hex::decode(test_sk).unwrap()).unwrap(); + let pk = Bls12381G1PublicKey::from_str(test_pk).unwrap(); + let sig = Bls12381G2Signature::from_str(test_signature).unwrap(); assert_eq!(sk.public_key(), pk); - assert_eq!(sk.sign(&test_message_hash), sig); - assert!(verify_bls(&test_message_hash, &pk, &sig)); + assert_eq!(sk.sign_v1(&test_message_hash), sig); + assert!(verify_bls12381_v1(&test_message_hash, &pk, &sig)); } } diff --git a/radix-engine-common/src/crypto/bls12381/public_key.rs b/radix-engine-common/src/crypto/bls12381/public_key.rs index c27403c7211..f96d3f895a6 100644 --- a/radix-engine-common/src/crypto/bls12381/public_key.rs +++ b/radix-engine-common/src/crypto/bls12381/public_key.rs @@ -2,27 +2,27 @@ use crate::internal_prelude::*; #[cfg(feature = "radix_engine_fuzzing")] use arbitrary::Arbitrary; -/// Represents a BLS public key. +/// Represents a BLS12-381 G1 public key. #[cfg_attr(feature = "radix_engine_fuzzing", derive(Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive( Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Categorize, Encode, Decode, BasicDescribe, )] #[sbor(transparent)] -pub struct BlsPublicKey( +pub struct Bls12381G1PublicKey( #[cfg_attr(feature = "serde", serde(with = "hex::serde"))] pub [u8; Self::LENGTH], ); -impl Describe for BlsPublicKey { +impl Describe for Bls12381G1PublicKey { const TYPE_ID: RustTypeId = - RustTypeId::WellKnown(well_known_scrypto_custom_types::BLS_PUBLIC_KEY_TYPE); + RustTypeId::WellKnown(well_known_scrypto_custom_types::BLS12381G1_PUBLIC_KEY_TYPE); fn type_data() -> ScryptoTypeData { - well_known_scrypto_custom_types::bls_public_key_type_data() + well_known_scrypto_custom_types::bls12381g1_public_key_type_data() } } -impl BlsPublicKey { +impl Bls12381G1PublicKey { pub const LENGTH: usize = 48; pub fn to_vec(&self) -> Vec { @@ -30,15 +30,15 @@ impl BlsPublicKey { } } -impl TryFrom<&[u8]> for BlsPublicKey { +impl TryFrom<&[u8]> for Bls12381G1PublicKey { type Error = ParseBlsPublicKeyError; fn try_from(slice: &[u8]) -> Result { - if slice.len() != BlsPublicKey::LENGTH { + if slice.len() != Bls12381G1PublicKey::LENGTH { return Err(ParseBlsPublicKeyError::InvalidLength(slice.len())); } - Ok(BlsPublicKey(copy_u8_array(slice))) + Ok(Bls12381G1PublicKey(copy_u8_array(slice))) } } @@ -67,7 +67,7 @@ impl fmt::Display for ParseBlsPublicKeyError { // text //====== -impl FromStr for BlsPublicKey { +impl FromStr for Bls12381G1PublicKey { type Err = ParseBlsPublicKeyError; fn from_str(s: &str) -> Result { @@ -76,13 +76,13 @@ impl FromStr for BlsPublicKey { } } -impl fmt::Display for BlsPublicKey { +impl fmt::Display for Bls12381G1PublicKey { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { write!(f, "{}", hex::encode(self.to_vec())) } } -impl fmt::Debug for BlsPublicKey { +impl fmt::Debug for Bls12381G1PublicKey { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { write!(f, "{}", self) } diff --git a/radix-engine-common/src/crypto/bls12381/signature.rs b/radix-engine-common/src/crypto/bls12381/signature.rs index edaaf487ae4..cc8d64ca076 100644 --- a/radix-engine-common/src/crypto/bls12381/signature.rs +++ b/radix-engine-common/src/crypto/bls12381/signature.rs @@ -7,36 +7,37 @@ use sbor::rust::vec::Vec; use sbor::*; use utils::copy_u8_array; -// Ciphersuite for BLS12-381 -// - hash-to-curve: BLS12381G2_XMD:SHA-256_SSWU_RO -// - pairing-friendly elliptic curve: BLS12-381 -// - hash function: SHA-256 -// - signature variant: G2 minimal pubkey size -// - scheme: -// - proof-of-possession -pub const BLS_SCHEME: &[u8] = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_"; -// More details: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04 - -/// Represents a BLS signature (variant with 96-byte signature and 48-byte public key) +/// BLS12-381 ciphersuite v1 +/// It has following parameters +/// - hash-to-curve: BLS12381G2_XMD:SHA-256_SSWU_RO +/// - pairing-friendly elliptic curve: BLS12-381 +/// - hash function: SHA-256 +/// - signature variant: G2 minimal pubkey size +/// - scheme: +/// - proof-of-possession +/// More details: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04 +pub const BLS12381_CIPHERSITE_V1: &[u8] = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_"; + +/// Represents a BLS12-381 G2 signature (variant with 96-byte signature and 48-byte public key) #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive( Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Categorize, Encode, Decode, BasicDescribe, )] #[sbor(transparent)] -pub struct BlsSignature( +pub struct Bls12381G2Signature( #[cfg_attr(feature = "serde", serde(with = "hex::serde"))] pub [u8; Self::LENGTH], ); -impl Describe for BlsSignature { +impl Describe for Bls12381G2Signature { const TYPE_ID: RustTypeId = - RustTypeId::WellKnown(well_known_scrypto_custom_types::BLS_SIGNATURE_TYPE); + RustTypeId::WellKnown(well_known_scrypto_custom_types::BLS12381G2_SIGNATURE_TYPE); fn type_data() -> ScryptoTypeData { - well_known_scrypto_custom_types::bls_signature_type_data() + well_known_scrypto_custom_types::bls12381g2_signature_type_data() } } -impl BlsSignature { +impl Bls12381G2Signature { pub const LENGTH: usize = 96; pub fn to_vec(&self) -> Vec { @@ -44,15 +45,15 @@ impl BlsSignature { } } -impl TryFrom<&[u8]> for BlsSignature { +impl TryFrom<&[u8]> for Bls12381G2Signature { type Error = ParseBlsSignatureError; fn try_from(slice: &[u8]) -> Result { - if slice.len() != BlsSignature::LENGTH { + if slice.len() != Bls12381G2Signature::LENGTH { return Err(ParseBlsSignatureError::InvalidLength(slice.len())); } - Ok(BlsSignature(copy_u8_array(slice))) + Ok(Bls12381G2Signature(copy_u8_array(slice))) } } @@ -81,7 +82,7 @@ impl fmt::Display for ParseBlsSignatureError { // text //====== -impl FromStr for BlsSignature { +impl FromStr for Bls12381G2Signature { type Err = ParseBlsSignatureError; fn from_str(s: &str) -> Result { @@ -90,13 +91,13 @@ impl FromStr for BlsSignature { } } -impl fmt::Display for BlsSignature { +impl fmt::Display for Bls12381G2Signature { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { write!(f, "{}", hex::encode(self.to_vec())) } } -impl fmt::Debug for BlsSignature { +impl fmt::Debug for Bls12381G2Signature { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { write!(f, "{}", self) } diff --git a/radix-engine-common/src/crypto/signature_validator.rs b/radix-engine-common/src/crypto/signature_validator.rs index 1589bbbe763..03c9fecd325 100644 --- a/radix-engine-common/src/crypto/signature_validator.rs +++ b/radix-engine-common/src/crypto/signature_validator.rs @@ -54,10 +54,16 @@ pub fn verify_ed25519( false } -pub fn verify_bls(message: &[u8], public_key: &BlsPublicKey, signature: &BlsSignature) -> bool { +/// Performs BLS12-381 G2 signature verification using following +/// domain specifier tag: BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_ +pub fn verify_bls12381_v1( + message: &[u8], + public_key: &Bls12381G1PublicKey, + signature: &Bls12381G2Signature, +) -> bool { if let Ok(sig) = blst::min_pk::Signature::from_bytes(&signature.0) { if let Ok(pk) = blst::min_pk::PublicKey::from_bytes(&public_key.0) { - let result = sig.verify(true, message, BLS_SCHEME, &[], &pk, true); + let result = sig.verify(true, message, BLS12381_CIPHERSITE_V1, &[], &pk, true); match result { blst::BLST_ERROR::BLST_SUCCESS => return true, diff --git a/radix-engine-common/src/data/scrypto/custom_well_known_types.rs b/radix-engine-common/src/data/scrypto/custom_well_known_types.rs index 6f5ff981fe5..e75fce11d89 100644 --- a/radix-engine-common/src/data/scrypto/custom_well_known_types.rs +++ b/radix-engine-common/src/data/scrypto/custom_well_known_types.rs @@ -413,11 +413,11 @@ create_well_known_lookup!( ) ), ( - BLS_PUBLIC_KEY, + BLS12381G1_PUBLIC_KEY, CRYPTO_TYPES_START + 3, named_transparent( - "BlsPublicKey", - bytes_fixed_length_type_data(BlsPublicKey::LENGTH), + "Bls12381G1PublicKey", + bytes_fixed_length_type_data(Bls12381G1PublicKey::LENGTH), ) ), ( @@ -451,11 +451,11 @@ create_well_known_lookup!( ) ), ( - BLS_SIGNATURE, + BLS12381G2_SIGNATURE, CRYPTO_TYPES_START + 12, named_transparent( - "BlsSignature", - bytes_fixed_length_type_data(BlsSignature::LENGTH), + "Bls12381G2Signature", + bytes_fixed_length_type_data(Bls12381G2Signature::LENGTH), ) ), // ROLE ASSIGNMENT TYPES @@ -641,7 +641,10 @@ mod tests { SECP256K1_PUBLIC_KEY_TYPE, Secp256k1PublicKey([0; Secp256k1PublicKey::LENGTH]), ); - test_equivalence(BLS_PUBLIC_KEY_TYPE, BlsPublicKey([0; BlsPublicKey::LENGTH])); + test_equivalence( + BLS12381G1_PUBLIC_KEY_TYPE, + Bls12381G1PublicKey([0; Bls12381G1PublicKey::LENGTH]), + ); test_equivalence( PUBLIC_KEY_HASH_TYPE, PublicKeyHash::Ed25519(Ed25519PublicKeyHash([0; Ed25519PublicKeyHash::LENGTH])), @@ -658,7 +661,10 @@ mod tests { SECP256K1_PUBLIC_KEY_HASH_TYPE, Secp256k1PublicKeyHash([0; Secp256k1PublicKeyHash::LENGTH]), ); - test_equivalence(BLS_SIGNATURE_TYPE, BlsSignature([0; BlsSignature::LENGTH])); + test_equivalence( + BLS12381G2_SIGNATURE_TYPE, + Bls12381G2Signature([0; Bls12381G2Signature::LENGTH]), + ); } fn test_equivalence(id: WellKnownTypeId, value: T) { diff --git a/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs b/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs index b598b02701e..6cf6ab3c2e4 100644 --- a/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs +++ b/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs @@ -2,11 +2,11 @@ use crate::crypto::*; use crate::internal_prelude::Vec; pub trait ClientCryptoUtilsApi { - fn bls_verify( + fn bls12381_v1_verify( &mut self, message: Vec, - public_key: BlsPublicKey, - signature: BlsSignature, + public_key: Bls12381G1PublicKey, + signature: Bls12381G2Signature, ) -> Result; fn keccak_hash(&mut self, data: Vec) -> Result; diff --git a/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs b/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs index 492501a9c1a..5d914592bd9 100644 --- a/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs +++ b/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs @@ -5,12 +5,12 @@ mod component_module { struct CryptoScrypto {} impl CryptoScrypto { - pub fn bls_verify( + pub fn bls12381_v1_verify( message: Vec, - pub_key: BlsPublicKey, - signature: BlsSignature, + pub_key: Bls12381G1PublicKey, + signature: Bls12381G2Signature, ) -> bool { - CryptoUtils::bls_verify(message, pub_key, signature) + CryptoUtils::bls12381_v1_verify(message, pub_key, signature) } pub fn keccak_hash(data: Vec) -> Hash { diff --git a/radix-engine-tests/benches/transaction_validation.rs b/radix-engine-tests/benches/transaction_validation.rs index 75c7e3c4f41..170782d0843 100644 --- a/radix-engine-tests/benches/transaction_validation.rs +++ b/radix-engine-tests/benches/transaction_validation.rs @@ -35,26 +35,26 @@ fn bench_ed25519_validation(c: &mut Criterion) { fn bench_bls_validation_long(c: &mut Criterion) { let message = vec![0u8; 2048]; println!("message len = {}", message.len()); - let signer = BlsPrivateKey::from_u64(123123123123).unwrap(); + let signer = Bls12381G1PrivateKey::from_u64(123123123123).unwrap(); let public_key = signer.public_key(); - let signature = signer.sign(&message); + let signature = signer.sign_v1(&message); c.bench_function("transaction_validation::verify_bls_2KB", |b| { b.iter(|| { - verify_bls(&message, &public_key, &signature); + verify_bls12381_v1(&message, &public_key, &signature); }) }); } fn bench_bls_validation_short(c: &mut Criterion) { let message = vec![0u8; 32]; - let signer = BlsPrivateKey::from_u64(123123123123).unwrap(); + let signer = Bls12381G1PrivateKey::from_u64(123123123123).unwrap(); let public_key = signer.public_key(); - let signature = signer.sign(&message); + let signature = signer.sign_v1(&message); c.bench_function("transaction_validation::verify_bls_32B", |b| { b.iter(|| { - verify_bls(&message, &public_key, &signature); + verify_bls12381_v1(&message, &public_key, &signature); }) }); } diff --git a/radix-engine-tests/tests/system/crypto_utils.rs b/radix-engine-tests/tests/system/crypto_utils.rs index 94d3b71ccef..fd80b46a10c 100644 --- a/radix-engine-tests/tests/system/crypto_utils.rs +++ b/radix-engine-tests/tests/system/crypto_utils.rs @@ -6,7 +6,7 @@ use scrypto_unit::*; use transaction::builder::ManifestBuilder; #[cfg(test)] -fn crypto_scrypto_bls_verify( +fn crypto_scrypto_bls12381_v1_verify( runner: &mut TestRunner, package_address: PackageAddress, msg: &str, @@ -14,8 +14,8 @@ fn crypto_scrypto_bls_verify( sig: &str, ) -> bool { let msg = hex::decode(msg).unwrap(); - let pub_key = BlsPublicKey::from_str(pk).unwrap(); - let signature = BlsSignature::from_str(sig).unwrap(); + let pub_key = Bls12381G1PublicKey::from_str(pk).unwrap(); + let signature = Bls12381G2Signature::from_str(sig).unwrap(); let receipt = runner.execute_manifest( ManifestBuilder::new() @@ -23,7 +23,7 @@ fn crypto_scrypto_bls_verify( .call_function( package_address, "CryptoScrypto", - "bls_verify", + "bls12381_v1_verify", manifest_args!(msg, pub_key, signature), ) .build(), @@ -58,7 +58,7 @@ fn crypto_scrypto_keccak_hash( } #[test] -fn test_crypto_scrypto_bls_verify() { +fn test_crypto_scrypto_verify_bls12381_v1() { // Arrange let mut test_runner = TestRunnerBuilder::new().build(); @@ -70,10 +70,20 @@ fn test_crypto_scrypto_bls_verify() { let msg1_signature = "8b84ff5a1d4f8095ab8a80518ac99230ed24a7d1ec90c4105f9c719aa7137ed5d7ce1454d4a953f5f55f3959ab416f3014f4cd2c361e4d32c6b4704a70b0e2e652a908f501acb54ec4e79540be010e3fdc1fbf8e7af61625705e185a71c884f1"; // Act - let msg1_verify = - crypto_scrypto_bls_verify(&mut test_runner, package_address, &msg1, pk, msg1_signature); - let msg2_verify = - crypto_scrypto_bls_verify(&mut test_runner, package_address, &msg2, pk, msg1_signature); + let msg1_verify = crypto_scrypto_bls12381_v1_verify( + &mut test_runner, + package_address, + &msg1, + pk, + msg1_signature, + ); + let msg2_verify = crypto_scrypto_bls12381_v1_verify( + &mut test_runner, + package_address, + &msg2, + pk, + msg1_signature, + ); // Assert assert!(msg1_verify); @@ -118,14 +128,14 @@ fn test_crypto_scrypto_flow() { // Get the hash of the message using CryptoScrypto package let msg_hash = crypto_scrypto_keccak_hash(&mut test_runner, package_address, msg); - let secret_key = BlsPrivateKey::from_u64(1).unwrap(); + let secret_key = Bls12381G1PrivateKey::from_u64(1).unwrap(); let public_key = secret_key.public_key(); // Sign the message hash using BLS - let msg_signature = secret_key.sign(msg_hash.as_slice()); + let msg_signature = secret_key.sign_v1(msg_hash.as_slice()); // Verify the BLS signature using CryptoScrypto package - let result = crypto_scrypto_bls_verify( + let result = crypto_scrypto_bls12381_v1_verify( &mut test_runner, package_address, &msg_hash.to_string(), diff --git a/radix-engine/src/system/system.rs b/radix-engine/src/system/system.rs index 9f3905963aa..7fe31602ffe 100644 --- a/radix-engine/src/system/system.rs +++ b/radix-engine/src/system/system.rs @@ -2859,14 +2859,14 @@ where V: SystemCallbackObject, { #[trace_resources] - fn bls_verify( + fn bls12381_v1_verify( &mut self, message: Vec, - public_key: BlsPublicKey, - signature: BlsSignature, + public_key: Bls12381G1PublicKey, + signature: Bls12381G2Signature, ) -> Result { // TODO: apply execution costs - Ok(verify_bls(&message, &public_key, &signature) as u32) + Ok(verify_bls12381_v1(&message, &public_key, &signature) as u32) } #[trace_resources] diff --git a/radix-engine/src/vm/wasm/constants.rs b/radix-engine/src/vm/wasm/constants.rs index 752bbbbdfd4..212beb1fdad 100644 --- a/radix-engine/src/vm/wasm/constants.rs +++ b/radix-engine/src/vm/wasm/constants.rs @@ -80,7 +80,7 @@ pub const SYS_PANIC_FUNCTION_NAME: &str = "sys_panic"; //================= // Crypto Utils //================= -pub const CRYPTO_UTILS_BLS_VERIFY_FUNCTION_NAME: &str = "crypto_utils_bls_verify"; +pub const CRYPTO_UTILS_BLS12381_V1_VERIFY_FUNCTION_NAME: &str = "crypto_utils_bls12381_v1_verify"; pub const CRYPTO_UTILS_KECCAK_HASH_FUNCTION_NAME: &str = "crypto_utils_keccak_hash"; //================= diff --git a/radix-engine/src/vm/wasm/prepare.rs b/radix-engine/src/vm/wasm/prepare.rs index cd1b4732ff8..31930f1b8c8 100644 --- a/radix-engine/src/vm/wasm/prepare.rs +++ b/radix-engine/src/vm/wasm/prepare.rs @@ -733,7 +733,7 @@ impl WasmModule { )); } } - CRYPTO_UTILS_BLS_VERIFY_FUNCTION_NAME => { + CRYPTO_UTILS_BLS12381_V1_VERIFY_FUNCTION_NAME => { if let TypeRef::Func(type_index) = entry.ty { if Self::function_type_matches( &self.module, diff --git a/radix-engine/src/vm/wasm/traits.rs b/radix-engine/src/vm/wasm/traits.rs index 1c044590661..b78e5ef4795 100644 --- a/radix-engine/src/vm/wasm/traits.rs +++ b/radix-engine/src/vm/wasm/traits.rs @@ -201,7 +201,7 @@ pub trait WasmRuntime { fn sys_panic(&mut self, message: Vec) -> Result<(), InvokeError>; - fn crypto_utils_bls_verify( + fn crypto_utils_bls12381_v1_verify( &mut self, message: Vec, public_key: Vec, diff --git a/radix-engine/src/vm/wasm/wasmer.rs b/radix-engine/src/vm/wasm/wasmer.rs index 3a9212c547e..3f18908146e 100644 --- a/radix-engine/src/vm/wasm/wasmer.rs +++ b/radix-engine/src/vm/wasm/wasmer.rs @@ -676,7 +676,7 @@ impl WasmerModule { runtime.sys_generate_ruid().map(|buffer| buffer.0) } - pub fn bls_verify( + pub fn bls12381_v1_verify( env: &WasmerInstanceEnv, message_ptr: u32, message_len: u32, @@ -692,7 +692,7 @@ impl WasmerModule { let public_key = read_memory(&instance, public_key_ptr, public_key_len)?; let signature = read_memory(instance, signature_ptr, signature_len)?; - runtime.crypto_utils_bls_verify(message, public_key, signature) + runtime.crypto_utils_bls12381_v1_verify(message, public_key, signature) } pub fn keccak_hash( @@ -812,7 +812,7 @@ impl WasmerModule { SYS_GET_TRANSACTION_HASH_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), sys_get_transaction_hash), SYS_GENERATE_RUID_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), sys_generate_ruid), BUFFER_CONSUME_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), buffer_consume), - CRYPTO_UTILS_BLS_VERIFY_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), bls_verify), + CRYPTO_UTILS_BLS12381_V1_VERIFY_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), bls12381_v1_verify), CRYPTO_UTILS_KECCAK_HASH_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), keccak_hash), #[cfg(feature = "radix_engine_tests")] diff --git a/radix-engine/src/vm/wasm/wasmi.rs b/radix-engine/src/vm/wasm/wasmi.rs index 7f0f44cbf41..e213a6c3fe2 100644 --- a/radix-engine/src/vm/wasm/wasmi.rs +++ b/radix-engine/src/vm/wasm/wasmi.rs @@ -663,7 +663,7 @@ fn panic( runtime.sys_panic(message) } -fn bls_verify( +fn bls12381_v1_verify( mut caller: Caller<'_, HostState>, message_ptr: u32, message_len: u32, @@ -688,7 +688,7 @@ fn bls_verify( signature_len, )?; - runtime.crypto_utils_bls_verify(message, public_key, signature) + runtime.crypto_utils_bls12381_v1_verify(message, public_key, signature) } fn keccak_hash( @@ -1268,7 +1268,7 @@ impl WasmiModule { }, ); - let host_bls_verify = Func::wrap( + let host_bls12381_v1_verify = Func::wrap( store.as_context_mut(), |caller: Caller<'_, HostState>, message_ptr: u32, @@ -1278,7 +1278,7 @@ impl WasmiModule { signature_ptr: u32, signature_len: u32| -> Result { - bls_verify( + bls12381_v1_verify( caller, message_ptr, message_len, @@ -1457,8 +1457,8 @@ impl WasmiModule { linker_define!(linker, SYS_GENERATE_RUID_FUNCTION_NAME, host_generate_ruid); linker_define!( linker, - CRYPTO_UTILS_BLS_VERIFY_FUNCTION_NAME, - host_bls_verify + CRYPTO_UTILS_BLS12381_V1_VERIFY_FUNCTION_NAME, + host_bls12381_v1_verify ); linker_define!( linker, diff --git a/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs b/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs index 172d498860a..ad22085dae0 100644 --- a/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs +++ b/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs @@ -306,7 +306,7 @@ impl<'a> WasmRuntime for NoOpWasmRuntime<'a> { Err(InvokeError::SelfError(WasmRuntimeError::NotImplemented)) } - fn crypto_utils_bls_verify( + fn crypto_utils_bls12381_v1_verify( &mut self, message: Vec, public_key: Vec, diff --git a/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs b/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs index f74bc8d7205..f46e98a43fe 100644 --- a/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs +++ b/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs @@ -561,17 +561,19 @@ where self.allocate_buffer(scrypto_encode(&fee_balance).expect("Failed to encode fee_balance")) } - fn crypto_utils_bls_verify( + fn crypto_utils_bls12381_v1_verify( &mut self, message: Vec, public_key: Vec, signature: Vec, ) -> Result> { - let public_key = BlsPublicKey::try_from(public_key.as_slice()) + let public_key = Bls12381G1PublicKey::try_from(public_key.as_slice()) .map_err(WasmRuntimeError::InvalidBlsPublicKey)?; - let signature = BlsSignature::try_from(signature.as_slice()) + let signature = Bls12381G2Signature::try_from(signature.as_slice()) .map_err(WasmRuntimeError::InvalidBlsSignature)?; - let result = self.api.bls_verify(message, public_key, signature)?; + let result = self + .api + .bls12381_v1_verify(message, public_key, signature)?; Ok(result) } diff --git a/scrypto-test/src/environment/client_api.rs b/scrypto-test/src/environment/client_api.rs index b209a371aad..d3409f72ece 100644 --- a/scrypto-test/src/environment/client_api.rs +++ b/scrypto-test/src/environment/client_api.rs @@ -276,7 +276,7 @@ implement_client_api! { fee_balance: (&mut self) -> Result, }, ClientCryptoUtilsApi: { - bls_verify: (&mut self, message: Vec, public_key: BlsPublicKey, signature: BlsSignature) -> Result, + bls12381_v1_verify: (&mut self, message: Vec, public_key: Bls12381G1PublicKey, signature: Bls12381G2Signature) -> Result, keccak_hash: (&mut self, data: Vec) -> Result, }, } diff --git a/scrypto/src/crypto_utils/crypto_utils.rs b/scrypto/src/crypto_utils/crypto_utils.rs index 9518ad7849f..91d38e579bb 100644 --- a/scrypto/src/crypto_utils/crypto_utils.rs +++ b/scrypto/src/crypto_utils/crypto_utils.rs @@ -1,5 +1,5 @@ use crate::engine::wasm_api::{copy_buffer, crypto_utils}; -use radix_engine_common::prelude::{BlsPublicKey, BlsSignature, Hash}; +use radix_engine_common::prelude::{Bls12381G1PublicKey, Bls12381G2Signature, Hash}; use sbor::prelude::Vec; /// Crypto utilities. @@ -7,9 +7,13 @@ use sbor::prelude::Vec; pub struct CryptoUtils {} impl CryptoUtils { - pub fn bls_verify(message: Vec, public_key: BlsPublicKey, signature: BlsSignature) -> bool { + pub fn bls12381_v1_verify( + message: Vec, + public_key: Bls12381G1PublicKey, + signature: Bls12381G2Signature, + ) -> bool { unsafe { - crypto_utils::crypto_utils_bls_verify( + crypto_utils::crypto_utils_bls12381_v1_verify( message.as_ptr(), message.len(), public_key.0.as_ptr(), diff --git a/scrypto/src/engine/wasm_api.rs b/scrypto/src/engine/wasm_api.rs index ea4913689a0..e836fb5c545 100644 --- a/scrypto/src/engine/wasm_api.rs +++ b/scrypto/src/engine/wasm_api.rs @@ -289,7 +289,7 @@ pub mod crypto_utils { pub use radix_engine_interface::types::{Buffer, BufferId, Slice}; super::wasm_extern_c! { - pub fn crypto_utils_bls_verify( + pub fn crypto_utils_bls12381_v1_verify( message_ptr: *const u8, message_len: usize, public_key_ptr: *const u8, From 61ae645ef9d95b483e3f03a4b4c67e674d2c3321 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Fri, 8 Dec 2023 09:40:36 +0100 Subject: [PATCH 33/82] Rename Keccak related stuff more specifically --- .../src/crypto/bls12381/private_key.rs | 2 +- radix-engine-common/src/crypto/keccak256.rs | 6 +++--- .../src/api/system_modules/crypto_utils_api.rs | 2 +- .../assets/blueprints/crypto_scrypto/src/lib.rs | 4 ++-- radix-engine-tests/tests/system/crypto_utils.rs | 12 ++++++------ radix-engine/src/system/system.rs | 4 ++-- radix-engine/src/vm/wasm/constants.rs | 2 +- radix-engine/src/vm/wasm/prepare.rs | 2 +- radix-engine/src/vm/wasm/traits.rs | 2 +- radix-engine/src/vm/wasm/wasmer.rs | 6 +++--- radix-engine/src/vm/wasm/wasmi.rs | 12 ++++++------ radix-engine/src/vm/wasm_runtime/no_op_runtime.rs | 2 +- radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs | 4 ++-- scrypto-test/src/environment/client_api.rs | 2 +- scrypto/src/crypto_utils/crypto_utils.rs | 4 ++-- scrypto/src/engine/wasm_api.rs | 2 +- 16 files changed, 34 insertions(+), 34 deletions(-) diff --git a/radix-engine-common/src/crypto/bls12381/private_key.rs b/radix-engine-common/src/crypto/bls12381/private_key.rs index 363508b965d..4d54be4dce1 100644 --- a/radix-engine-common/src/crypto/bls12381/private_key.rs +++ b/radix-engine-common/src/crypto/bls12381/private_key.rs @@ -61,7 +61,7 @@ mod tests { // Supra example let test_pk = "8a38419cb83c15a92d11243384bea0acd15cbacc24b385b9c577b17272d6ad68bb53c52dbbf79324005528d2d73c2643"; let test_sk = "5B00CC8C7153F39EF2E6E2FADB1BB95A1F4BF21F43CC5B28EFA9E526FB788C08"; - let test_message_hash = keccak_256_hash("Hello World!"); + let test_message_hash = keccak256_hash("Hello World!"); assert_eq!( test_message_hash, diff --git a/radix-engine-common/src/crypto/keccak256.rs b/radix-engine-common/src/crypto/keccak256.rs index ded9000efd5..ab22ac24b64 100644 --- a/radix-engine-common/src/crypto/keccak256.rs +++ b/radix-engine-common/src/crypto/keccak256.rs @@ -1,7 +1,7 @@ use crate::crypto::*; use sha3::{Digest, Keccak256}; -pub fn keccak_256_hash>(data: T) -> Hash { +pub fn keccak256_hash>(data: T) -> Hash { let mut hasher = Keccak256::new(); hasher.update(data); let hash = hasher.finalize(); @@ -14,9 +14,9 @@ mod tests { use sbor::rust::str::FromStr; #[test] - fn test_keccak_256_hash() { + fn test_keccak256_hash() { let data = "Hello Radix"; - let hash = keccak_256_hash(data); + let hash = keccak256_hash(data); assert_eq!( hash, Hash::from_str("415942230ddb029416a4612818536de230d827cbac9646a0b26d9855a4c45587") diff --git a/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs b/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs index 6cf6ab3c2e4..9a5e407610f 100644 --- a/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs +++ b/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs @@ -9,5 +9,5 @@ pub trait ClientCryptoUtilsApi { signature: Bls12381G2Signature, ) -> Result; - fn keccak_hash(&mut self, data: Vec) -> Result; + fn keccak256_hash(&mut self, data: Vec) -> Result; } diff --git a/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs b/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs index 5d914592bd9..ff1b3673da3 100644 --- a/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs +++ b/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs @@ -13,8 +13,8 @@ mod component_module { CryptoUtils::bls12381_v1_verify(message, pub_key, signature) } - pub fn keccak_hash(data: Vec) -> Hash { - let hash = CryptoUtils::keccak_hash(data); + pub fn keccak256_hash(data: Vec) -> Hash { + let hash = CryptoUtils::keccak256_hash(data); hash } } diff --git a/radix-engine-tests/tests/system/crypto_utils.rs b/radix-engine-tests/tests/system/crypto_utils.rs index fd80b46a10c..163a64dc2bf 100644 --- a/radix-engine-tests/tests/system/crypto_utils.rs +++ b/radix-engine-tests/tests/system/crypto_utils.rs @@ -34,7 +34,7 @@ fn crypto_scrypto_bls12381_v1_verify( } #[cfg(test)] -fn crypto_scrypto_keccak_hash( +fn crypto_scrypto_keccak256_hash( runner: &mut TestRunner, package_address: PackageAddress, data: &str, @@ -47,7 +47,7 @@ fn crypto_scrypto_keccak_hash( .call_function( package_address, "CryptoScrypto", - "keccak_hash", + "keccak256_hash", manifest_args!(data), ) .build(), @@ -91,7 +91,7 @@ fn test_crypto_scrypto_verify_bls12381_v1() { } #[test] -fn test_crypto_scrypto_keccak_hash() { +fn test_crypto_scrypto_keccak256_hash() { // Arrange let mut test_runner = TestRunnerBuilder::new().build(); @@ -101,8 +101,8 @@ fn test_crypto_scrypto_keccak_hash() { let data2 = "xidaR olleH"; // Act - let data1_hash = crypto_scrypto_keccak_hash(&mut test_runner, package_address, data1); - let data2_hash = crypto_scrypto_keccak_hash(&mut test_runner, package_address, data2); + let data1_hash = crypto_scrypto_keccak256_hash(&mut test_runner, package_address, data1); + let data2_hash = crypto_scrypto_keccak256_hash(&mut test_runner, package_address, data2); // Assert assert_eq!( @@ -126,7 +126,7 @@ fn test_crypto_scrypto_flow() { // Act // Get the hash of the message using CryptoScrypto package - let msg_hash = crypto_scrypto_keccak_hash(&mut test_runner, package_address, msg); + let msg_hash = crypto_scrypto_keccak256_hash(&mut test_runner, package_address, msg); let secret_key = Bls12381G1PrivateKey::from_u64(1).unwrap(); let public_key = secret_key.public_key(); diff --git a/radix-engine/src/system/system.rs b/radix-engine/src/system/system.rs index 7fe31602ffe..619de5db4f5 100644 --- a/radix-engine/src/system/system.rs +++ b/radix-engine/src/system/system.rs @@ -2870,9 +2870,9 @@ where } #[trace_resources] - fn keccak_hash(&mut self, data: Vec) -> Result { + fn keccak256_hash(&mut self, data: Vec) -> Result { // TODO: apply execution costs - Ok(keccak_256_hash(&data)) + Ok(keccak256_hash(&data)) } } diff --git a/radix-engine/src/vm/wasm/constants.rs b/radix-engine/src/vm/wasm/constants.rs index 212beb1fdad..c60725ce87d 100644 --- a/radix-engine/src/vm/wasm/constants.rs +++ b/radix-engine/src/vm/wasm/constants.rs @@ -81,7 +81,7 @@ pub const SYS_PANIC_FUNCTION_NAME: &str = "sys_panic"; // Crypto Utils //================= pub const CRYPTO_UTILS_BLS12381_V1_VERIFY_FUNCTION_NAME: &str = "crypto_utils_bls12381_v1_verify"; -pub const CRYPTO_UTILS_KECCAK_HASH_FUNCTION_NAME: &str = "crypto_utils_keccak_hash"; +pub const CRYPTO_UTILS_KECCAK256_HASH_FUNCTION_NAME: &str = "crypto_utils_keccak256_hash"; //================= // WASM Shim diff --git a/radix-engine/src/vm/wasm/prepare.rs b/radix-engine/src/vm/wasm/prepare.rs index 31930f1b8c8..76afd4cc16e 100644 --- a/radix-engine/src/vm/wasm/prepare.rs +++ b/radix-engine/src/vm/wasm/prepare.rs @@ -755,7 +755,7 @@ impl WasmModule { )); } } - CRYPTO_UTILS_KECCAK_HASH_FUNCTION_NAME => { + CRYPTO_UTILS_KECCAK256_HASH_FUNCTION_NAME => { if let TypeRef::Func(type_index) = entry.ty { if Self::function_type_matches( &self.module, diff --git a/radix-engine/src/vm/wasm/traits.rs b/radix-engine/src/vm/wasm/traits.rs index b78e5ef4795..17f08322374 100644 --- a/radix-engine/src/vm/wasm/traits.rs +++ b/radix-engine/src/vm/wasm/traits.rs @@ -208,7 +208,7 @@ pub trait WasmRuntime { signature: Vec, ) -> Result>; - fn crypto_utils_keccak_hash( + fn crypto_utils_keccak256_hash( &mut self, data: Vec, ) -> Result>; diff --git a/radix-engine/src/vm/wasm/wasmer.rs b/radix-engine/src/vm/wasm/wasmer.rs index 3f18908146e..38bdc413b80 100644 --- a/radix-engine/src/vm/wasm/wasmer.rs +++ b/radix-engine/src/vm/wasm/wasmer.rs @@ -695,7 +695,7 @@ impl WasmerModule { runtime.crypto_utils_bls12381_v1_verify(message, public_key, signature) } - pub fn keccak_hash( + pub fn keccak256_hash( env: &WasmerInstanceEnv, data_ptr: u32, data_len: u32, @@ -705,7 +705,7 @@ impl WasmerModule { let data = read_memory(instance, data_ptr, data_len)?; runtime - .crypto_utils_keccak_hash(data) + .crypto_utils_keccak256_hash(data) .map(|buffer| buffer.0) } @@ -813,7 +813,7 @@ impl WasmerModule { SYS_GENERATE_RUID_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), sys_generate_ruid), BUFFER_CONSUME_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), buffer_consume), CRYPTO_UTILS_BLS12381_V1_VERIFY_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), bls12381_v1_verify), - CRYPTO_UTILS_KECCAK_HASH_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), keccak_hash), + CRYPTO_UTILS_KECCAK256_HASH_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), keccak256_hash), #[cfg(feature = "radix_engine_tests")] "test_host_read_memory" => Function::new_native_with_env(self.module.store(), env.clone(), host_read_memory), diff --git a/radix-engine/src/vm/wasm/wasmi.rs b/radix-engine/src/vm/wasm/wasmi.rs index e213a6c3fe2..38a38b98fa9 100644 --- a/radix-engine/src/vm/wasm/wasmi.rs +++ b/radix-engine/src/vm/wasm/wasmi.rs @@ -691,7 +691,7 @@ fn bls12381_v1_verify( runtime.crypto_utils_bls12381_v1_verify(message, public_key, signature) } -fn keccak_hash( +fn keccak256_hash( mut caller: Caller<'_, HostState>, data_ptr: u32, data_len: u32, @@ -701,7 +701,7 @@ fn keccak_hash( let data = read_memory(caller.as_context_mut(), memory, data_ptr, data_len)?; runtime - .crypto_utils_keccak_hash(data) + .crypto_utils_keccak256_hash(data) .map(|buffer| buffer.0) } @@ -1291,10 +1291,10 @@ impl WasmiModule { }, ); - let host_keccak_hash = Func::wrap( + let host_keccak256_hash = Func::wrap( store.as_context_mut(), |caller: Caller<'_, HostState>, data_ptr: u32, data_len: u32| -> Result { - keccak_hash(caller, data_ptr, data_len).map_err(|e| e.into()) + keccak256_hash(caller, data_ptr, data_len).map_err(|e| e.into()) }, ); @@ -1462,8 +1462,8 @@ impl WasmiModule { ); linker_define!( linker, - CRYPTO_UTILS_KECCAK_HASH_FUNCTION_NAME, - host_keccak_hash + CRYPTO_UTILS_KECCAK256_HASH_FUNCTION_NAME, + host_keccak256_hash ); #[cfg(feature = "radix_engine_tests")] diff --git a/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs b/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs index ad22085dae0..3a376f45884 100644 --- a/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs +++ b/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs @@ -315,7 +315,7 @@ impl<'a> WasmRuntime for NoOpWasmRuntime<'a> { Err(InvokeError::SelfError(WasmRuntimeError::NotImplemented)) } - fn crypto_utils_keccak_hash( + fn crypto_utils_keccak256_hash( &mut self, data: Vec, ) -> Result> { diff --git a/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs b/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs index f46e98a43fe..44cb905aa76 100644 --- a/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs +++ b/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs @@ -577,11 +577,11 @@ where Ok(result) } - fn crypto_utils_keccak_hash( + fn crypto_utils_keccak256_hash( &mut self, data: Vec, ) -> Result> { - let hash = self.api.keccak_hash(data)?; + let hash = self.api.keccak256_hash(data)?; self.allocate_buffer(hash.to_vec()) } diff --git a/scrypto-test/src/environment/client_api.rs b/scrypto-test/src/environment/client_api.rs index d3409f72ece..f9c49ce0ace 100644 --- a/scrypto-test/src/environment/client_api.rs +++ b/scrypto-test/src/environment/client_api.rs @@ -277,6 +277,6 @@ implement_client_api! { }, ClientCryptoUtilsApi: { bls12381_v1_verify: (&mut self, message: Vec, public_key: Bls12381G1PublicKey, signature: Bls12381G2Signature) -> Result, - keccak_hash: (&mut self, data: Vec) -> Result, + keccak256_hash: (&mut self, data: Vec) -> Result, }, } diff --git a/scrypto/src/crypto_utils/crypto_utils.rs b/scrypto/src/crypto_utils/crypto_utils.rs index 91d38e579bb..8fde247b535 100644 --- a/scrypto/src/crypto_utils/crypto_utils.rs +++ b/scrypto/src/crypto_utils/crypto_utils.rs @@ -24,9 +24,9 @@ impl CryptoUtils { } } - pub fn keccak_hash(data: Vec) -> Hash { + pub fn keccak256_hash(data: Vec) -> Hash { let hash = copy_buffer(unsafe { - crypto_utils::crypto_utils_keccak_hash(data.as_ptr(), data.len()) + crypto_utils::crypto_utils_keccak256_hash(data.as_ptr(), data.len()) }); Hash(hash.try_into().unwrap()) diff --git a/scrypto/src/engine/wasm_api.rs b/scrypto/src/engine/wasm_api.rs index e836fb5c545..6ccba78cdb8 100644 --- a/scrypto/src/engine/wasm_api.rs +++ b/scrypto/src/engine/wasm_api.rs @@ -297,7 +297,7 @@ pub mod crypto_utils { signature_ptr: *const u8, signature_len: usize) -> u32; - pub fn crypto_utils_keccak_hash( + pub fn crypto_utils_keccak256_hash( message_ptr: *const u8, message_len: usize) -> Buffer; } From 206d65b05a98e4d2f8476dc73bb3fae9348c2fc7 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Fri, 8 Dec 2023 14:35:13 +0100 Subject: [PATCH 34/82] Add rust docs to CryptoUtils --- scrypto/src/crypto_utils/crypto_utils.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scrypto/src/crypto_utils/crypto_utils.rs b/scrypto/src/crypto_utils/crypto_utils.rs index 8fde247b535..4db7a57d5c6 100644 --- a/scrypto/src/crypto_utils/crypto_utils.rs +++ b/scrypto/src/crypto_utils/crypto_utils.rs @@ -7,6 +7,8 @@ use sbor::prelude::Vec; pub struct CryptoUtils {} impl CryptoUtils { + /// Performs BLS12-381 G2 signature verification using following + /// domain specifier tag: BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_ pub fn bls12381_v1_verify( message: Vec, public_key: Bls12381G1PublicKey, @@ -24,6 +26,7 @@ impl CryptoUtils { } } + /// Calculates Keccak-256 digest over given vector of bytes pub fn keccak256_hash(data: Vec) -> Hash { let hash = copy_buffer(unsafe { crypto_utils::crypto_utils_keccak256_hash(data.as_ptr(), data.len()) From f95d5b31e6f1bb212f549c637d593c4bcc898a19 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Tue, 9 Jan 2024 11:18:47 +0100 Subject: [PATCH 35/82] Limit SECP256K1_CTX visibility to current crate --- radix-engine-common/src/crypto/secp256k1/private_key.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radix-engine-common/src/crypto/secp256k1/private_key.rs b/radix-engine-common/src/crypto/secp256k1/private_key.rs index fe0458c5b3c..c53c5a9d36d 100644 --- a/radix-engine-common/src/crypto/secp256k1/private_key.rs +++ b/radix-engine-common/src/crypto/secp256k1/private_key.rs @@ -4,7 +4,7 @@ use ::secp256k1::{All, Message, PublicKey, Secp256k1, SecretKey}; use super::Secp256k1Signature; lazy_static::lazy_static! { - pub static ref SECP256K1_CTX: Secp256k1 = secp256k1::Secp256k1::new(); + pub(crate) static ref SECP256K1_CTX: Secp256k1 = secp256k1::Secp256k1::new(); } pub struct Secp256k1PrivateKey(SecretKey); From b212d0e1fefc47f071162b72e8150d9654265a38 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Thu, 11 Jan 2024 09:16:29 +0100 Subject: [PATCH 36/82] Remove BLS types from SBOR well-known types This is for backward compatibility reasons. We might reconsider it when SBOR is versioned. --- .../src/crypto/bls12381/public_key.rs | 13 +--------- .../src/crypto/bls12381/signature.rs | 13 +--------- .../data/scrypto/custom_well_known_types.rs | 24 ------------------- 3 files changed, 2 insertions(+), 48 deletions(-) diff --git a/radix-engine-common/src/crypto/bls12381/public_key.rs b/radix-engine-common/src/crypto/bls12381/public_key.rs index f96d3f895a6..e42c2db9779 100644 --- a/radix-engine-common/src/crypto/bls12381/public_key.rs +++ b/radix-engine-common/src/crypto/bls12381/public_key.rs @@ -5,23 +5,12 @@ use arbitrary::Arbitrary; /// Represents a BLS12-381 G1 public key. #[cfg_attr(feature = "radix_engine_fuzzing", derive(Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive( - Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Categorize, Encode, Decode, BasicDescribe, -)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Sbor)] #[sbor(transparent)] pub struct Bls12381G1PublicKey( #[cfg_attr(feature = "serde", serde(with = "hex::serde"))] pub [u8; Self::LENGTH], ); -impl Describe for Bls12381G1PublicKey { - const TYPE_ID: RustTypeId = - RustTypeId::WellKnown(well_known_scrypto_custom_types::BLS12381G1_PUBLIC_KEY_TYPE); - - fn type_data() -> ScryptoTypeData { - well_known_scrypto_custom_types::bls12381g1_public_key_type_data() - } -} - impl Bls12381G1PublicKey { pub const LENGTH: usize = 48; diff --git a/radix-engine-common/src/crypto/bls12381/signature.rs b/radix-engine-common/src/crypto/bls12381/signature.rs index cc8d64ca076..c377b5d916d 100644 --- a/radix-engine-common/src/crypto/bls12381/signature.rs +++ b/radix-engine-common/src/crypto/bls12381/signature.rs @@ -20,23 +20,12 @@ pub const BLS12381_CIPHERSITE_V1: &[u8] = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_ /// Represents a BLS12-381 G2 signature (variant with 96-byte signature and 48-byte public key) #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive( - Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Categorize, Encode, Decode, BasicDescribe, -)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Sbor)] #[sbor(transparent)] pub struct Bls12381G2Signature( #[cfg_attr(feature = "serde", serde(with = "hex::serde"))] pub [u8; Self::LENGTH], ); -impl Describe for Bls12381G2Signature { - const TYPE_ID: RustTypeId = - RustTypeId::WellKnown(well_known_scrypto_custom_types::BLS12381G2_SIGNATURE_TYPE); - - fn type_data() -> ScryptoTypeData { - well_known_scrypto_custom_types::bls12381g2_signature_type_data() - } -} - impl Bls12381G2Signature { pub const LENGTH: usize = 96; diff --git a/radix-engine-common/src/data/scrypto/custom_well_known_types.rs b/radix-engine-common/src/data/scrypto/custom_well_known_types.rs index e75fce11d89..8df5f17d99b 100644 --- a/radix-engine-common/src/data/scrypto/custom_well_known_types.rs +++ b/radix-engine-common/src/data/scrypto/custom_well_known_types.rs @@ -412,14 +412,6 @@ create_well_known_lookup!( bytes_fixed_length_type_data(Ed25519PublicKey::LENGTH), ) ), - ( - BLS12381G1_PUBLIC_KEY, - CRYPTO_TYPES_START + 3, - named_transparent( - "Bls12381G1PublicKey", - bytes_fixed_length_type_data(Bls12381G1PublicKey::LENGTH), - ) - ), ( PUBLIC_KEY_HASH, CRYPTO_TYPES_START + 8, @@ -450,14 +442,6 @@ create_well_known_lookup!( bytes_fixed_length_type_data(Ed25519PublicKeyHash::LENGTH), ) ), - ( - BLS12381G2_SIGNATURE, - CRYPTO_TYPES_START + 12, - named_transparent( - "Bls12381G2Signature", - bytes_fixed_length_type_data(Bls12381G2Signature::LENGTH), - ) - ), // ROLE ASSIGNMENT TYPES ( ACCESS_RULE, @@ -641,10 +625,6 @@ mod tests { SECP256K1_PUBLIC_KEY_TYPE, Secp256k1PublicKey([0; Secp256k1PublicKey::LENGTH]), ); - test_equivalence( - BLS12381G1_PUBLIC_KEY_TYPE, - Bls12381G1PublicKey([0; Bls12381G1PublicKey::LENGTH]), - ); test_equivalence( PUBLIC_KEY_HASH_TYPE, PublicKeyHash::Ed25519(Ed25519PublicKeyHash([0; Ed25519PublicKeyHash::LENGTH])), @@ -661,10 +641,6 @@ mod tests { SECP256K1_PUBLIC_KEY_HASH_TYPE, Secp256k1PublicKeyHash([0; Secp256k1PublicKeyHash::LENGTH]), ); - test_equivalence( - BLS12381G2_SIGNATURE_TYPE, - Bls12381G2Signature([0; Bls12381G2Signature::LENGTH]), - ); } fn test_equivalence(id: WellKnownTypeId, value: T) { From 066448d99f80eecbcfbb1636af63d84a275b3eb7 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Tue, 9 Jan 2024 13:37:47 +0100 Subject: [PATCH 37/82] Enable crypto features for wasm32 target as well --- assets/blueprints/Cargo.lock | 46 ++- examples/everything/Cargo.lock | 89 ++++-- examples/hello-world/Cargo.lock | 46 ++- examples/no-std/Cargo.lock | 281 +++++++++++++++++- radix-engine-common/Cargo.toml | 13 +- .../src/crypto/bls12381/mod.rs | 2 - radix-engine-common/src/crypto/ed25519/mod.rs | 2 - radix-engine-common/src/crypto/mod.rs | 4 - .../src/crypto/secp256k1/mod.rs | 2 - simulator/Cargo.lock | 88 +++++- 10 files changed, 507 insertions(+), 66 deletions(-) diff --git a/assets/blueprints/Cargo.lock b/assets/blueprints/Cargo.lock index bc4c91e09e2..58661d106ed 100644 --- a/assets/blueprints/Cargo.lock +++ b/assets/blueprints/Cargo.lock @@ -65,6 +65,18 @@ dependencies = [ "generic-array", ] +[[package]] +name = "blst" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c94087b935a822949d3291a9989ad2b2051ea141eda0fd4e478a75f6aa3e604b" +dependencies = [ + "cc", + "glob 0.3.1", + "threadpool", + "zeroize", +] + [[package]] name = "bnum" version = "0.7.0" @@ -514,6 +526,15 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +[[package]] +name = "keccak" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] + [[package]] name = "kv_store" version = "0.1.0" @@ -849,7 +870,9 @@ version = "1.0.2-dev" dependencies = [ "bech32", "blake2", + "blst", "bnum", + "ed25519-dalek", "hex", "lazy_static", "num-bigint", @@ -858,7 +881,9 @@ dependencies = [ "paste", "radix-engine-derive", "sbor", + "secp256k1", "serde", + "sha3", "strum", "utils", ] @@ -1280,6 +1305,16 @@ dependencies = [ "opaque-debug", ] +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + [[package]] name = "signature" version = "1.6.4" @@ -1429,18 +1464,25 @@ dependencies = [ "syn 2.0.29", ] +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + [[package]] name = "transaction" version = "1.0.2-dev" dependencies = [ "bech32", - "ed25519-dalek", "hex", "lazy_static", "radix-engine-common", "radix-engine-interface", "sbor", - "secp256k1", "strum", "utils", ] diff --git a/examples/everything/Cargo.lock b/examples/everything/Cargo.lock index ea50a716da4..c0a898d3794 100644 --- a/examples/everything/Cargo.lock +++ b/examples/everything/Cargo.lock @@ -59,6 +59,18 @@ dependencies = [ "generic-array", ] +[[package]] +name = "blst" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c94087b935a822949d3291a9989ad2b2051ea141eda0fd4e478a75f6aa3e604b" +dependencies = [ + "cc", + "glob 0.3.1", + "threadpool", + "zeroize", +] + [[package]] name = "bnum" version = "0.7.0" @@ -309,7 +321,7 @@ dependencies = [ [[package]] name = "everything" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "native-sdk", "radix-engine", @@ -475,6 +487,15 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +[[package]] +name = "keccak" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -554,7 +575,7 @@ dependencies = [ [[package]] name = "native-sdk" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "radix-engine-common", "radix-engine-derive", @@ -681,7 +702,7 @@ dependencies = [ [[package]] name = "radix-engine" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "bitflags 1.3.2", "colored", @@ -710,11 +731,13 @@ dependencies = [ [[package]] name = "radix-engine-common" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "bech32", "blake2", + "blst", "bnum", + "ed25519-dalek", "hex", "lazy_static", "num-bigint", @@ -723,14 +746,16 @@ dependencies = [ "paste", "radix-engine-derive", "sbor", + "secp256k1", "serde", + "sha3", "strum", "utils", ] [[package]] name = "radix-engine-derive" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "proc-macro2", "quote", @@ -740,7 +765,7 @@ dependencies = [ [[package]] name = "radix-engine-interface" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "bitflags 1.3.2", "const-sha1", @@ -753,6 +778,7 @@ dependencies = [ "regex", "sbor", "scrypto-schema", + "serde", "serde_json", "strum", "utils", @@ -760,7 +786,7 @@ dependencies = [ [[package]] name = "radix-engine-macros" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "paste", "proc-macro2", @@ -771,14 +797,14 @@ dependencies = [ [[package]] name = "radix-engine-profiling" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "fixedstr", ] [[package]] name = "radix-engine-queries" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "hex", "itertools", @@ -793,7 +819,7 @@ dependencies = [ [[package]] name = "radix-engine-store-interface" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "hex", "itertools", @@ -806,7 +832,7 @@ dependencies = [ [[package]] name = "radix-engine-stores" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "hex", "itertools", @@ -894,7 +920,7 @@ checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "resources-tracker-macro" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "proc-macro2", "quote", @@ -947,7 +973,7 @@ dependencies = [ [[package]] name = "sbor" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "const-sha1", "hex", @@ -960,7 +986,7 @@ dependencies = [ [[package]] name = "sbor-derive" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "proc-macro2", "sbor-derive-common", @@ -968,7 +994,7 @@ dependencies = [ [[package]] name = "sbor-derive-common" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "const-sha1", "itertools", @@ -994,7 +1020,7 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "scrypto" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "bech32", "const-sha1", @@ -1015,7 +1041,7 @@ dependencies = [ [[package]] name = "scrypto-derive" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "proc-macro2", "quote", @@ -1030,7 +1056,7 @@ dependencies = [ [[package]] name = "scrypto-schema" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "bitflags 1.3.2", "radix-engine-common", @@ -1040,7 +1066,7 @@ dependencies = [ [[package]] name = "scrypto-unit" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "radix-engine", "radix-engine-interface", @@ -1127,6 +1153,16 @@ dependencies = [ "opaque-debug", ] +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + [[package]] name = "signature" version = "1.6.4" @@ -1259,18 +1295,25 @@ dependencies = [ "syn 2.0.29", ] +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + [[package]] name = "transaction" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "bech32", - "ed25519-dalek", "hex", "lazy_static", "radix-engine-common", "radix-engine-interface", "sbor", - "secp256k1", "strum", "utils", ] @@ -1310,7 +1353,7 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "utils" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "indexmap 2.0.0-pre", "serde", diff --git a/examples/hello-world/Cargo.lock b/examples/hello-world/Cargo.lock index 2b2b089c9dc..7ef61bbfca9 100644 --- a/examples/hello-world/Cargo.lock +++ b/examples/hello-world/Cargo.lock @@ -59,6 +59,18 @@ dependencies = [ "generic-array", ] +[[package]] +name = "blst" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c94087b935a822949d3291a9989ad2b2051ea141eda0fd4e478a75f6aa3e604b" +dependencies = [ + "cc", + "glob 0.3.1", + "threadpool", + "zeroize", +] + [[package]] name = "bnum" version = "0.7.0" @@ -474,6 +486,15 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +[[package]] +name = "keccak" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -713,7 +734,9 @@ version = "1.0.2-dev" dependencies = [ "bech32", "blake2", + "blst", "bnum", + "ed25519-dalek", "hex", "lazy_static", "num-bigint", @@ -722,7 +745,9 @@ dependencies = [ "paste", "radix-engine-derive", "sbor", + "secp256k1", "serde", + "sha3", "strum", "utils", ] @@ -1127,6 +1152,16 @@ dependencies = [ "opaque-debug", ] +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + [[package]] name = "signature" version = "1.6.4" @@ -1259,18 +1294,25 @@ dependencies = [ "syn 2.0.29", ] +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + [[package]] name = "transaction" version = "1.0.2-dev" dependencies = [ "bech32", - "ed25519-dalek", "hex", "lazy_static", "radix-engine-common", "radix-engine-interface", "sbor", - "secp256k1", "strum", "utils", ] diff --git a/examples/no-std/Cargo.lock b/examples/no-std/Cargo.lock index 3144a349dd6..1fa35c12b46 100644 --- a/examples/no-std/Cargo.lock +++ b/examples/no-std/Cargo.lock @@ -37,7 +37,16 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" dependencies = [ - "digest", + "digest 0.10.7", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", ] [[package]] @@ -49,6 +58,18 @@ dependencies = [ "generic-array", ] +[[package]] +name = "blst" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c94087b935a822949d3291a9989ad2b2051ea141eda0fd4e478a75f6aa3e604b" +dependencies = [ + "cc", + "glob", + "threadpool", + "zeroize", +] + [[package]] name = "bnum" version = "0.7.0" @@ -59,6 +80,21 @@ dependencies = [ "num-traits", ] +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + [[package]] name = "cfg-if" version = "0.1.10" @@ -76,6 +112,15 @@ name = "const-sha1" version = "0.2.0" source = "git+https://github.com/radixdlt/const-sha1#5e9ae2a99e9c76e85aa67f42e4b62e7f7ce8dad4" +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -86,17 +131,61 @@ dependencies = [ "typenum", ] +[[package]] +name = "curve25519-dalek" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + [[package]] name = "digest" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", + "block-buffer 0.10.4", "crypto-common", "subtle", ] +[[package]] +name = "ed25519" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +dependencies = [ + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand", + "sha2", + "zeroize", +] + [[package]] name = "either" version = "1.9.0" @@ -113,6 +202,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + [[package]] name = "hashbrown" version = "0.13.2" @@ -128,6 +223,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + [[package]] name = "hex" version = "0.4.3" @@ -161,6 +262,15 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +[[package]] +name = "keccak" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -172,9 +282,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.147" +version = "0.2.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" [[package]] name = "memory_units" @@ -184,7 +294,7 @@ checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" [[package]] name = "no-std" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "sbor", "scrypto", @@ -221,18 +331,40 @@ dependencies = [ "autocfg", ] +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + [[package]] name = "once_cell" version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + [[package]] name = "paste" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + [[package]] name = "proc-macro2" version = "1.0.66" @@ -253,11 +385,13 @@ dependencies = [ [[package]] name = "radix-engine-common" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "bech32", "blake2", + "blst", "bnum", + "ed25519-dalek", "hex", "lazy_static", "num-bigint", @@ -266,14 +400,16 @@ dependencies = [ "paste", "radix-engine-derive", "sbor", + "secp256k1", "serde", + "sha3", "strum", "utils", ] [[package]] name = "radix-engine-derive" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "proc-macro2", "quote", @@ -283,7 +419,7 @@ dependencies = [ [[package]] name = "radix-engine-interface" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "bitflags", "const-sha1", @@ -296,6 +432,7 @@ dependencies = [ "regex", "sbor", "scrypto-schema", + "serde", "serde_json", "strum", "utils", @@ -303,7 +440,7 @@ dependencies = [ [[package]] name = "radix-engine-macros" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "paste", "proc-macro2", @@ -312,6 +449,42 @@ dependencies = [ "syn 1.0.93", ] +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core", +] + [[package]] name = "regex" version = "1.9.3" @@ -351,7 +524,7 @@ checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "sbor" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "const-sha1", "hex", @@ -364,7 +537,7 @@ dependencies = [ [[package]] name = "sbor-derive" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "proc-macro2", "sbor-derive-common", @@ -372,7 +545,7 @@ dependencies = [ [[package]] name = "sbor-derive-common" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "const-sha1", "itertools", @@ -383,7 +556,7 @@ dependencies = [ [[package]] name = "scrypto" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "bech32", "const-sha1", @@ -403,7 +576,7 @@ dependencies = [ [[package]] name = "scrypto-derive" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "proc-macro2", "quote", @@ -418,7 +591,7 @@ dependencies = [ [[package]] name = "scrypto-schema" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "bitflags", "radix-engine-common", @@ -426,6 +599,24 @@ dependencies = [ "serde", ] +[[package]] +name = "secp256k1" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62" +dependencies = [ + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83080e2c2fc1006e625be82e5d1eb6a43b7fd9578b617fcc55814daf286bba4b" +dependencies = [ + "cc", +] + [[package]] name = "serde" version = "1.0.188" @@ -457,6 +648,35 @@ dependencies = [ "serde", ] +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" + [[package]] name = "spin" version = "0.5.2" @@ -523,6 +743,15 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + [[package]] name = "typenum" version = "1.16.0" @@ -543,7 +772,7 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "utils" -version = "1.1.0-dev" +version = "1.0.2-dev" dependencies = [ "hashbrown", "indexmap", @@ -589,3 +818,23 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "zeroize" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.29", +] diff --git a/radix-engine-common/Cargo.toml b/radix-engine-common/Cargo.toml index b9c737d4cad..82d1d62f992 100644 --- a/radix-engine-common/Cargo.toml +++ b/radix-engine-common/Cargo.toml @@ -25,12 +25,10 @@ arbitrary = { version = "1.3.0", features = ["derive"], optional = true } rug = { version = "1.18", optional = true } ethnum = {version = "1.3.2", default-features = false, optional = true } -# Do not include crypto-related dependencies when building for WASM. -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] -ed25519-dalek = { version = "1.0.1", default-features = false, features = ["u64_backend"]} -secp256k1 = { version = "0.24.0", default-features = false, features = ["recovery"]} -blst = { version = "0.3.11", default-features = false } -sha3 = { version = "0.10.8", default-features = false } +ed25519-dalek = { version = "1.0.1", default-features = false, features = ["u64_backend"] } +secp256k1 = { version = "0.24.0", default-features = false, features = ["recovery"] } +blst = { version = "0.3.11", default-features = false, optional = false } +sha3 = { version = "0.10.8", default-features = false, optional = false } [dev-dependencies] serde_json = { version = "1.0.81", default-features = false } @@ -51,6 +49,9 @@ serde = ["dep:serde", "utils/serde", "sbor/serde", "hex/serde"] std = ["hex/std", "sbor/std", "utils/std", "radix-engine-derive/std", "serde_json/std", "ed25519-dalek/std", "secp256k1/std", "blake2/std", "sha3/std" ] alloc = ["hex/alloc", "sbor/alloc", "utils/alloc", "radix-engine-derive/alloc", "serde_json/alloc", "ed25519-dalek/alloc", "secp256k1/alloc", "lazy_static/spin_no_std"] +# Include crypto primitives +#crypto = ["dep:ed25519-dalek", "dep:secp256k1", "dep:blst", "dep:sha3"] + # This flag is set by fuzz-tests framework and it is used to disable/enable some optional features # to let fuzzing work radix_engine_fuzzing = ["arbitrary", "serde", "bnum/arbitrary", "bnum/serde", "sbor/radix_engine_fuzzing", "utils/radix_engine_fuzzing"] diff --git a/radix-engine-common/src/crypto/bls12381/mod.rs b/radix-engine-common/src/crypto/bls12381/mod.rs index c45b976b438..d83eaa9db8e 100644 --- a/radix-engine-common/src/crypto/bls12381/mod.rs +++ b/radix-engine-common/src/crypto/bls12381/mod.rs @@ -1,9 +1,7 @@ -#[cfg(not(target_arch = "wasm32"))] mod private_key; mod public_key; mod signature; -#[cfg(not(target_arch = "wasm32"))] pub use private_key::*; pub use public_key::*; pub use signature::*; diff --git a/radix-engine-common/src/crypto/ed25519/mod.rs b/radix-engine-common/src/crypto/ed25519/mod.rs index c45b976b438..d83eaa9db8e 100644 --- a/radix-engine-common/src/crypto/ed25519/mod.rs +++ b/radix-engine-common/src/crypto/ed25519/mod.rs @@ -1,9 +1,7 @@ -#[cfg(not(target_arch = "wasm32"))] mod private_key; mod public_key; mod signature; -#[cfg(not(target_arch = "wasm32"))] pub use private_key::*; pub use public_key::*; pub use signature::*; diff --git a/radix-engine-common/src/crypto/mod.rs b/radix-engine-common/src/crypto/mod.rs index 52ca87c9302..e22bc1ecfab 100644 --- a/radix-engine-common/src/crypto/mod.rs +++ b/radix-engine-common/src/crypto/mod.rs @@ -3,22 +3,18 @@ mod bls12381; mod ed25519; mod hash; mod hash_accumulator; -#[cfg(not(target_arch = "wasm32"))] mod keccak256; mod public_key; mod public_key_hash; mod secp256k1; -#[cfg(not(target_arch = "wasm32"))] mod signature_validator; pub use self::blake2b::*; pub use self::bls12381::*; pub use self::ed25519::*; pub use self::hash::*; pub use self::hash_accumulator::*; -#[cfg(not(target_arch = "wasm32"))] pub use self::keccak256::*; pub use self::public_key::*; pub use self::public_key_hash::*; pub use self::secp256k1::*; -#[cfg(not(target_arch = "wasm32"))] pub use self::signature_validator::*; diff --git a/radix-engine-common/src/crypto/secp256k1/mod.rs b/radix-engine-common/src/crypto/secp256k1/mod.rs index c45b976b438..d83eaa9db8e 100644 --- a/radix-engine-common/src/crypto/secp256k1/mod.rs +++ b/radix-engine-common/src/crypto/secp256k1/mod.rs @@ -1,9 +1,7 @@ -#[cfg(not(target_arch = "wasm32"))] mod private_key; mod public_key; mod signature; -#[cfg(not(target_arch = "wasm32"))] pub use private_key::*; pub use public_key::*; pub use signature::*; diff --git a/simulator/Cargo.lock b/simulator/Cargo.lock index 42fb93439fd..962e02d7198 100644 --- a/simulator/Cargo.lock +++ b/simulator/Cargo.lock @@ -480,6 +480,8 @@ checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" dependencies = [ "curve25519-dalek", "ed25519", + "rand 0.7.3", + "serde", "sha2", "zeroize", ] @@ -594,6 +596,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + [[package]] name = "getrandom" version = "0.2.10" @@ -603,7 +616,7 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "wasm-bindgen", ] @@ -736,6 +749,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "keccak" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -902,7 +924,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" dependencies = [ - "getrandom", + "getrandom 0.2.10", ] [[package]] @@ -1141,6 +1163,7 @@ dependencies = [ "radix-engine-derive", "sbor", "secp256k1", + "sha3", "strum", "utils", ] @@ -1236,6 +1259,19 @@ dependencies = [ "utils", ] +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + [[package]] name = "rand" version = "0.8.5" @@ -1243,10 +1279,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", + "rand_chacha 0.3.1", "rand_core 0.6.4", ] +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + [[package]] name = "rand_chacha" version = "0.3.1" @@ -1262,6 +1308,9 @@ name = "rand_core" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] [[package]] name = "rand_core" @@ -1269,7 +1318,16 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.10", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", ] [[package]] @@ -1296,7 +1354,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ - "getrandom", + "getrandom 0.2.10", "redox_syscall 0.2.16", "thiserror", ] @@ -1533,6 +1591,16 @@ dependencies = [ "opaque-debug", ] +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + [[package]] name = "shlex" version = "1.1.0" @@ -1565,7 +1633,7 @@ dependencies = [ "radix-engine-queries", "radix-engine-store-interface", "radix-engine-stores", - "rand", + "rand 0.8.5", "regex", "rocksdb", "sbor", @@ -1835,7 +1903,7 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" dependencies = [ - "getrandom", + "getrandom 0.2.10", ] [[package]] @@ -1860,6 +1928,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" From c9b75af3783aa541917199ccecc5551e2bc446e0 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Thu, 11 Jan 2024 13:16:18 +0100 Subject: [PATCH 38/82] Add llvm to GH path --- .github/actions/setup-env/action.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/actions/setup-env/action.yml b/.github/actions/setup-env/action.yml index be40cbf5436..7e57bc85803 100644 --- a/.github/actions/setup-env/action.yml +++ b/.github/actions/setup-env/action.yml @@ -31,4 +31,10 @@ runs: if: runner.os == 'Linux' run: sudo apt-get -y update && sudo apt-get install clang libclang-dev -y -f shell: bash + - name: Setup LLVM + if: runner.os == 'macOS' + # Switch to more recent LLVM/Clang 15.0.7 + # see: https://github.com/actions/runner-images/blob/macOS-12/20240105.3/images/macos/macos-12-Readme.md + run: echo "$(brew --prefix llvm@15)/bin" >> $GITHUB_PATH + shell: bash From 69d1642b59d01b71be7e3587cf39a3afa6bf5571 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Thu, 11 Jan 2024 13:36:46 +0100 Subject: [PATCH 39/82] Update README to install llvm for MacOS --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 69f0cacb981..ae1c4135ebf 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,11 @@ Binaries, including libraries, CLIs and docker images, are licensed under the [R ``` - macOS: - Make sure you have the xcode command line tools: `xcode-select --install`. - - Install cmake: `brew install cmake` + - Install cmake: `brew install cmake llvm`
+ Add LLVM to the system path by adding below line to the `~/.profile` + ``` + PATH="/opt/homebrew/opt/llvm/bin:$PATH" + ``` - Install the Rust compiler: ```bash curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh From 0a7b51b6205b34bb46ca9703b3ce54d9f4172184 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Tue, 19 Dec 2023 19:04:54 +0100 Subject: [PATCH 40/82] Add support for BLS aggregated signatures and public keys --- .../src/crypto/bls12381/private_key.rs | 44 +++++++++++++++++++ .../src/crypto/bls12381/public_key.rs | 32 ++++++++++++++ .../src/crypto/bls12381/signature.rs | 32 ++++++++++++++ .../src/crypto/signature_validator.rs | 43 ++++++++++++++++++ 4 files changed, 151 insertions(+) diff --git a/radix-engine-common/src/crypto/bls12381/private_key.rs b/radix-engine-common/src/crypto/bls12381/private_key.rs index 4d54be4dce1..1ab9b68699e 100644 --- a/radix-engine-common/src/crypto/bls12381/private_key.rs +++ b/radix-engine-common/src/crypto/bls12381/private_key.rs @@ -80,4 +80,48 @@ mod tests { assert_eq!(sk.sign_v1(&test_message_hash), sig); assert!(verify_bls12381_v1(&test_message_hash, &pk, &sig)); } + + #[test] + fn sign_and_verify_aggregated() { + let sks: Vec = (1..11) + .map(|i| Bls12381G1PrivateKey::from_u64(i).unwrap()) + .collect(); + + let pks: Vec = sks.iter().map(|sk| sk.public_key()).collect(); + + let msgs: Vec> = (1..11).map(|i| vec![i; 10]).collect(); + + let sigs: Vec = sks + .iter() + .zip(&msgs) + .map(|(sk, msg)| sk.sign_v1(msg)) + .collect(); + + // Aggregate the signature + let agg_sig = Bls12381G2Signature::from_aggregate(&sigs).unwrap(); + + let msgs_ref: Vec<&[u8]> = msgs.iter().map(|m| m.as_slice()).collect(); + + // Verify the messages against public keys and aggregated signature + assert!(aggregate_verify_bls12381_v1(&msgs_ref, &pks, &agg_sig)) + } + + #[test] + fn sign_and_verify_fast_aggregated() { + let sks: Vec = (1..11) + .map(|i| Bls12381G1PrivateKey::from_u64(i).unwrap()) + .collect(); + + let pks: Vec = sks.iter().map(|sk| sk.public_key()).collect(); + + let msg = "One message to sign for all".as_bytes(); + + let sigs: Vec = sks.iter().map(|sk| sk.sign_v1(msg)).collect(); + + // Aggregate the signature + let agg_sig = Bls12381G2Signature::from_aggregate(&sigs).unwrap(); + + // Verify the message against public keys and aggregated signature + assert!(fast_aggregate_verify_bls12381_v1(msg, &pks, &agg_sig)) + } } diff --git a/radix-engine-common/src/crypto/bls12381/public_key.rs b/radix-engine-common/src/crypto/bls12381/public_key.rs index e42c2db9779..d6982cb8c65 100644 --- a/radix-engine-common/src/crypto/bls12381/public_key.rs +++ b/radix-engine-common/src/crypto/bls12381/public_key.rs @@ -1,6 +1,8 @@ use crate::internal_prelude::*; #[cfg(feature = "radix_engine_fuzzing")] use arbitrary::Arbitrary; +use blst::min_pk::{AggregatePublicKey, PublicKey}; +use blst::BLST_ERROR; /// Represents a BLS12-381 G1 public key. #[cfg_attr(feature = "radix_engine_fuzzing", derive(Arbitrary))] @@ -17,6 +19,27 @@ impl Bls12381G1PublicKey { pub fn to_vec(&self) -> Vec { self.0.to_vec() } + + fn to_native_public_key(self) -> Result { + PublicKey::from_bytes(&self.0).map_err(|err| err.into()) + } + + pub fn from_aggregate( + public_keys: &[Bls12381G1PublicKey], + ) -> Result { + if !public_keys.is_empty() { + let pk_first = public_keys[0].to_native_public_key()?; + + let mut agg_pk = AggregatePublicKey::from_public_key(&pk_first); + + for pk in public_keys.iter().skip(1) { + agg_pk.add_public_key(&pk.to_native_public_key()?, true)?; + } + Ok(Bls12381G1PublicKey(agg_pk.to_public_key().to_bytes())) + } else { + Err(ParseBlsPublicKeyError::NoPublicKeysGiven) + } + } } impl TryFrom<&[u8]> for Bls12381G1PublicKey { @@ -35,11 +58,20 @@ impl TryFrom<&[u8]> for Bls12381G1PublicKey { // error //====== +impl From for ParseBlsPublicKeyError { + fn from(error: BLST_ERROR) -> Self { + let err_msg = format!("{:?}", error); + Self::BlsError(err_msg) + } +} + /// Represents an error when parsing BLS public key from hex. #[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)] pub enum ParseBlsPublicKeyError { InvalidHex(String), InvalidLength(usize), + NoPublicKeysGiven, + BlsError(String), } #[cfg(not(feature = "alloc"))] diff --git a/radix-engine-common/src/crypto/bls12381/signature.rs b/radix-engine-common/src/crypto/bls12381/signature.rs index c377b5d916d..bab431c5e7b 100644 --- a/radix-engine-common/src/crypto/bls12381/signature.rs +++ b/radix-engine-common/src/crypto/bls12381/signature.rs @@ -1,4 +1,6 @@ use crate::internal_prelude::*; +use blst::min_pk::{AggregateSignature, Signature}; +use blst::BLST_ERROR; use sbor::rust::borrow::ToOwned; use sbor::rust::fmt; use sbor::rust::str::FromStr; @@ -32,6 +34,27 @@ impl Bls12381G2Signature { pub fn to_vec(&self) -> Vec { self.0.to_vec() } + + fn to_native_signature(self) -> Result { + Signature::from_bytes(&self.0).map_err(|err| err.into()) + } + + pub fn from_aggregate( + signatures: &[Bls12381G2Signature], + ) -> Result { + if !signatures.is_empty() { + let sig_first = signatures[0].to_native_signature()?; + + let mut agg_sig = AggregateSignature::from_signature(&sig_first); + + for sig in signatures.iter().skip(1) { + agg_sig.add_signature(&sig.to_native_signature()?, true)?; + } + Ok(Bls12381G2Signature(agg_sig.to_signature().to_bytes())) + } else { + Err(ParseBlsSignatureError::NoSignatureGiven) + } + } } impl TryFrom<&[u8]> for Bls12381G2Signature { @@ -50,10 +73,19 @@ impl TryFrom<&[u8]> for Bls12381G2Signature { // error //====== +impl From for ParseBlsSignatureError { + fn from(error: BLST_ERROR) -> Self { + let err_msg = format!("{:?}", error); + Self::BlsError(err_msg) + } +} + #[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)] pub enum ParseBlsSignatureError { InvalidHex(String), InvalidLength(usize), + NoSignatureGiven, + BlsError(String), } /// Represents an error when parsing BLS signature from hex. diff --git a/radix-engine-common/src/crypto/signature_validator.rs b/radix-engine-common/src/crypto/signature_validator.rs index 03c9fecd325..49fb74a6386 100644 --- a/radix-engine-common/src/crypto/signature_validator.rs +++ b/radix-engine-common/src/crypto/signature_validator.rs @@ -74,3 +74,46 @@ pub fn verify_bls12381_v1( false } + +/// Performs BLS12-381 G2 aggregated signature verification using following +/// domain specifier tag: BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_ +pub fn aggregate_verify_bls12381_v1( + messages: &[&[u8]], + public_keys: &[Bls12381G1PublicKey], + signature: &Bls12381G2Signature, +) -> bool { + if let Ok(sig) = blst::min_pk::Signature::from_bytes(&signature.0) { + let mut pks = vec![]; + for pk in public_keys { + if let Ok(pk) = blst::min_pk::PublicKey::from_bytes(&pk.0) { + pks.push(pk); + } else { + return false; + } + } + let pks_refs: Vec<&blst::min_pk::PublicKey> = pks.iter().collect(); + + let result = sig.aggregate_verify(true, messages, BLS12381_CIPHERSITE_V1, &pks_refs, true); + + match result { + blst::BLST_ERROR::BLST_SUCCESS => return true, + _ => return false, + } + } + + false +} + +/// Performs BLS12-381 G2 aggregated signature verification using following +/// domain specifier tag: BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_ +pub fn fast_aggregate_verify_bls12381_v1( + message: &[u8], + public_keys: &[Bls12381G1PublicKey], + signature: &Bls12381G2Signature, +) -> bool { + if let Ok(agg_pk) = Bls12381G1PublicKey::from_aggregate(public_keys) { + return verify_bls12381_v1(message, &agg_pk, signature); + } + + false +} From f3fad9f86d54b7c8c3812872b3b986fe7cba9c32 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Wed, 20 Dec 2023 14:13:40 +0100 Subject: [PATCH 41/82] Fixes for WASM and cleanup --- .../src/crypto/bls12381/private_key.rs | 4 ++-- .../src/crypto/bls12381/public_key.rs | 18 ++++++++++++------ .../src/crypto/bls12381/signature.rs | 18 ++++++++++++------ .../src/crypto/signature_validator.rs | 16 +++++++++------- 4 files changed, 35 insertions(+), 21 deletions(-) diff --git a/radix-engine-common/src/crypto/bls12381/private_key.rs b/radix-engine-common/src/crypto/bls12381/private_key.rs index 1ab9b68699e..0e81e114ee5 100644 --- a/radix-engine-common/src/crypto/bls12381/private_key.rs +++ b/radix-engine-common/src/crypto/bls12381/private_key.rs @@ -98,7 +98,7 @@ mod tests { .collect(); // Aggregate the signature - let agg_sig = Bls12381G2Signature::from_aggregate(&sigs).unwrap(); + let agg_sig = Bls12381G2Signature::aggregate(&sigs).unwrap(); let msgs_ref: Vec<&[u8]> = msgs.iter().map(|m| m.as_slice()).collect(); @@ -119,7 +119,7 @@ mod tests { let sigs: Vec = sks.iter().map(|sk| sk.sign_v1(msg)).collect(); // Aggregate the signature - let agg_sig = Bls12381G2Signature::from_aggregate(&sigs).unwrap(); + let agg_sig = Bls12381G2Signature::aggregate(&sigs).unwrap(); // Verify the message against public keys and aggregated signature assert!(fast_aggregate_verify_bls12381_v1(msg, &pks, &agg_sig)) diff --git a/radix-engine-common/src/crypto/bls12381/public_key.rs b/radix-engine-common/src/crypto/bls12381/public_key.rs index d6982cb8c65..bae32255b36 100644 --- a/radix-engine-common/src/crypto/bls12381/public_key.rs +++ b/radix-engine-common/src/crypto/bls12381/public_key.rs @@ -1,8 +1,11 @@ use crate::internal_prelude::*; #[cfg(feature = "radix_engine_fuzzing")] use arbitrary::Arbitrary; -use blst::min_pk::{AggregatePublicKey, PublicKey}; -use blst::BLST_ERROR; +#[cfg(not(target_arch = "wasm32"))] +use blst::{ + min_pk::{AggregatePublicKey, PublicKey}, + BLST_ERROR, +}; /// Represents a BLS12-381 G1 public key. #[cfg_attr(feature = "radix_engine_fuzzing", derive(Arbitrary))] @@ -20,13 +23,14 @@ impl Bls12381G1PublicKey { self.0.to_vec() } + #[cfg(not(target_arch = "wasm32"))] fn to_native_public_key(self) -> Result { PublicKey::from_bytes(&self.0).map_err(|err| err.into()) } - pub fn from_aggregate( - public_keys: &[Bls12381G1PublicKey], - ) -> Result { + #[cfg(not(target_arch = "wasm32"))] + /// Aggregate multiple public keys into a single one + pub fn aggregate(public_keys: &[Bls12381G1PublicKey]) -> Result { if !public_keys.is_empty() { let pk_first = public_keys[0].to_native_public_key()?; @@ -58,6 +62,7 @@ impl TryFrom<&[u8]> for Bls12381G1PublicKey { // error //====== +#[cfg(not(target_arch = "wasm32"))] impl From for ParseBlsPublicKeyError { fn from(error: BLST_ERROR) -> Self { let err_msg = format!("{:?}", error); @@ -65,12 +70,13 @@ impl From for ParseBlsPublicKeyError { } } -/// Represents an error when parsing BLS public key from hex. +/// Represents an error when retrieving BLS public key from hex or when aggregating. #[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)] pub enum ParseBlsPublicKeyError { InvalidHex(String), InvalidLength(usize), NoPublicKeysGiven, + // Error returned by underlying BLS library BlsError(String), } diff --git a/radix-engine-common/src/crypto/bls12381/signature.rs b/radix-engine-common/src/crypto/bls12381/signature.rs index bab431c5e7b..982d669aa5e 100644 --- a/radix-engine-common/src/crypto/bls12381/signature.rs +++ b/radix-engine-common/src/crypto/bls12381/signature.rs @@ -1,6 +1,9 @@ use crate::internal_prelude::*; -use blst::min_pk::{AggregateSignature, Signature}; -use blst::BLST_ERROR; +#[cfg(not(target_arch = "wasm32"))] +use blst::{ + min_pk::{AggregateSignature, Signature}, + BLST_ERROR, +}; use sbor::rust::borrow::ToOwned; use sbor::rust::fmt; use sbor::rust::str::FromStr; @@ -35,13 +38,14 @@ impl Bls12381G2Signature { self.0.to_vec() } + #[cfg(not(target_arch = "wasm32"))] fn to_native_signature(self) -> Result { Signature::from_bytes(&self.0).map_err(|err| err.into()) } - pub fn from_aggregate( - signatures: &[Bls12381G2Signature], - ) -> Result { + #[cfg(not(target_arch = "wasm32"))] + /// Aggregate multiple signatures into a single one + pub fn aggregate(signatures: &[Bls12381G2Signature]) -> Result { if !signatures.is_empty() { let sig_first = signatures[0].to_native_signature()?; @@ -73,6 +77,7 @@ impl TryFrom<&[u8]> for Bls12381G2Signature { // error //====== +#[cfg(not(target_arch = "wasm32"))] impl From for ParseBlsSignatureError { fn from(error: BLST_ERROR) -> Self { let err_msg = format!("{:?}", error); @@ -80,15 +85,16 @@ impl From for ParseBlsSignatureError { } } +/// Represents an error when retrieving BLS signature from hex or when aggregating. #[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)] pub enum ParseBlsSignatureError { InvalidHex(String), InvalidLength(usize), NoSignatureGiven, + // Error returned by underlying BLS library BlsError(String), } -/// Represents an error when parsing BLS signature from hex. #[cfg(not(feature = "alloc"))] impl std::error::Error for ParseBlsSignatureError {} diff --git a/radix-engine-common/src/crypto/signature_validator.rs b/radix-engine-common/src/crypto/signature_validator.rs index 49fb74a6386..47a8416a929 100644 --- a/radix-engine-common/src/crypto/signature_validator.rs +++ b/radix-engine-common/src/crypto/signature_validator.rs @@ -54,8 +54,8 @@ pub fn verify_ed25519( false } -/// Performs BLS12-381 G2 signature verification using following -/// domain specifier tag: BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_ +/// Performs BLS12-381 G2 signature verification. +/// Domain specifier tag: BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_ pub fn verify_bls12381_v1( message: &[u8], public_key: &Bls12381G1PublicKey, @@ -75,8 +75,9 @@ pub fn verify_bls12381_v1( false } -/// Performs BLS12-381 G2 aggregated signature verification using following -/// domain specifier tag: BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_ +/// Performs BLS12-381 G2 aggregated signature verification of +/// multiple messages each signed with different key. +/// Domain specifier tag: BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_ pub fn aggregate_verify_bls12381_v1( messages: &[&[u8]], public_keys: &[Bls12381G1PublicKey], @@ -104,14 +105,15 @@ pub fn aggregate_verify_bls12381_v1( false } -/// Performs BLS12-381 G2 aggregated signature verification using following -/// domain specifier tag: BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_ +/// Performs BLS12-381 G2 aggregated signature verification +/// one message signed with multiple keys. +/// Domain specifier tag: BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_ pub fn fast_aggregate_verify_bls12381_v1( message: &[u8], public_keys: &[Bls12381G1PublicKey], signature: &Bls12381G2Signature, ) -> bool { - if let Ok(agg_pk) = Bls12381G1PublicKey::from_aggregate(public_keys) { + if let Ok(agg_pk) = Bls12381G1PublicKey::aggregate(public_keys) { return verify_bls12381_v1(message, &agg_pk, signature); } From 6d982d0a4998955a8418cacabb690e5e274c3269 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Tue, 19 Dec 2023 11:58:42 +0100 Subject: [PATCH 42/82] Improve resource tracing for CryptoUtils API --- radix-engine/src/system/system.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/radix-engine/src/system/system.rs b/radix-engine/src/system/system.rs index 619de5db4f5..5394340cbd0 100644 --- a/radix-engine/src/system/system.rs +++ b/radix-engine/src/system/system.rs @@ -2858,7 +2858,7 @@ where Y: KernelApi>, V: SystemCallbackObject, { - #[trace_resources] + #[trace_resources(log=message.len())] fn bls12381_v1_verify( &mut self, message: Vec, @@ -2869,7 +2869,7 @@ where Ok(verify_bls12381_v1(&message, &public_key, &signature) as u32) } - #[trace_resources] + #[trace_resources(log=data.len())] fn keccak256_hash(&mut self, data: Vec) -> Result { // TODO: apply execution costs Ok(keccak256_hash(&data)) From 453131e439cc1de460fa23d968e963d1402a7ea4 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Wed, 20 Dec 2023 15:26:08 +0100 Subject: [PATCH 43/82] Add bls12381_g2_signature_aggregate() to CryptoUtils API --- .../src/api/system_modules/crypto_utils_api.rs | 5 +++++ radix-engine/src/errors.rs | 2 ++ radix-engine/src/system/system.rs | 16 ++++++++++++++++ 3 files changed, 23 insertions(+) diff --git a/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs b/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs index 9a5e407610f..f4f5243f362 100644 --- a/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs +++ b/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs @@ -9,5 +9,10 @@ pub trait ClientCryptoUtilsApi { signature: Bls12381G2Signature, ) -> Result; + fn bls12381_g2_signature_aggregate( + &mut self, + signatures: Vec, + ) -> Result; + fn keccak256_hash(&mut self, data: Vec) -> Result; } diff --git a/radix-engine/src/errors.rs b/radix-engine/src/errors.rs index e42998a67b5..923eb4f6053 100644 --- a/radix-engine/src/errors.rs +++ b/radix-engine/src/errors.rs @@ -251,6 +251,8 @@ pub enum SystemError { BlueprintTypeNotFound(String), + BlsError(String), + /// A panic that's occurred in the system-layer or below. We're calling it system panic since /// we're treating the system as a black-box here. #[cfg(feature = "std")] diff --git a/radix-engine/src/system/system.rs b/radix-engine/src/system/system.rs index 5394340cbd0..ca03389b8f8 100644 --- a/radix-engine/src/system/system.rs +++ b/radix-engine/src/system/system.rs @@ -2869,6 +2869,22 @@ where Ok(verify_bls12381_v1(&message, &public_key, &signature) as u32) } + #[trace_resources(log=signatures.len())] + fn bls12381_g2_signature_aggregate( + &mut self, + signatures: Vec, + ) -> Result { + /* + self.api.kernel_get_system().modules.apply_execution_cost( + ExecutionCostingEntry::Bls12381V1Verify { + size: message.len(), + }, + )?; + */ + Bls12381G2Signature::aggregate(&signatures) + .map_err(|err| RuntimeError::SystemError(SystemError::BlsError(err.to_string()))) + } + #[trace_resources(log=data.len())] fn keccak256_hash(&mut self, data: Vec) -> Result { // TODO: apply execution costs From 7001c43f809c560171d5e5d290b4a3283cdc4bef Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Wed, 20 Dec 2023 15:44:05 +0100 Subject: [PATCH 44/82] Implement Display for ParseBlsSignatureError --- radix-engine-common/src/crypto/bls12381/signature.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/radix-engine-common/src/crypto/bls12381/signature.rs b/radix-engine-common/src/crypto/bls12381/signature.rs index 982d669aa5e..6b9b071ad7f 100644 --- a/radix-engine-common/src/crypto/bls12381/signature.rs +++ b/radix-engine-common/src/crypto/bls12381/signature.rs @@ -98,7 +98,6 @@ pub enum ParseBlsSignatureError { #[cfg(not(feature = "alloc"))] impl std::error::Error for ParseBlsSignatureError {} -#[cfg(not(feature = "alloc"))] impl fmt::Display for ParseBlsSignatureError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:?}", self) From dc740bd9ca8434245e7efed8f17ed8b3d122208d Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Wed, 20 Dec 2023 17:37:13 +0100 Subject: [PATCH 45/82] Finish adding bls12381_g2_signature_aggregate() to CryptoUtils API --- radix-engine/src/vm/wasm/constants.rs | 2 ++ radix-engine/src/vm/wasm/prepare.rs | 15 ++++++++ radix-engine/src/vm/wasm/traits.rs | 5 +++ radix-engine/src/vm/wasm/wasmer.rs | 15 ++++++++ radix-engine/src/vm/wasm/wasmi.rs | 36 +++++++++++++++++++ .../src/vm/wasm_runtime/no_op_runtime.rs | 7 ++++ .../src/vm/wasm_runtime/scrypto_runtime.rs | 20 +++++++++++ scrypto-test/src/environment/client_api.rs | 1 + scrypto/src/crypto_utils/crypto_utils.rs | 14 ++++++++ scrypto/src/engine/wasm_api.rs | 4 +++ 10 files changed, 119 insertions(+) diff --git a/radix-engine/src/vm/wasm/constants.rs b/radix-engine/src/vm/wasm/constants.rs index c60725ce87d..01ea98ca739 100644 --- a/radix-engine/src/vm/wasm/constants.rs +++ b/radix-engine/src/vm/wasm/constants.rs @@ -81,6 +81,8 @@ pub const SYS_PANIC_FUNCTION_NAME: &str = "sys_panic"; // Crypto Utils //================= pub const CRYPTO_UTILS_BLS12381_V1_VERIFY_FUNCTION_NAME: &str = "crypto_utils_bls12381_v1_verify"; +pub const CRYPTO_UTILS_BLS12381_G2_SIGNATURE_AGGREGATE_FUNCTION_NAME: &str = + "crypto_utils_bls12381_g2_signature_aggregate"; pub const CRYPTO_UTILS_KECCAK256_HASH_FUNCTION_NAME: &str = "crypto_utils_keccak256_hash"; //================= diff --git a/radix-engine/src/vm/wasm/prepare.rs b/radix-engine/src/vm/wasm/prepare.rs index 76afd4cc16e..ee6e61c3f8f 100644 --- a/radix-engine/src/vm/wasm/prepare.rs +++ b/radix-engine/src/vm/wasm/prepare.rs @@ -755,6 +755,21 @@ impl WasmModule { )); } } + CRYPTO_UTILS_BLS12381_G2_SIGNATURE_AGGREGATE_FUNCTION_NAME => { + if let TypeRef::Func(type_index) = entry.ty { + if Self::function_type_matches( + &self.module, + type_index, + vec![ValType::I32, ValType::I32], + vec![ValType::I64], + ) { + continue; + } + return Err(PrepareError::InvalidImport( + InvalidImport::InvalidFunctionType(entry.name.to_string()), + )); + } + } CRYPTO_UTILS_KECCAK256_HASH_FUNCTION_NAME => { if let TypeRef::Func(type_index) = entry.ty { if Self::function_type_matches( diff --git a/radix-engine/src/vm/wasm/traits.rs b/radix-engine/src/vm/wasm/traits.rs index 17f08322374..4dd9e6a25f5 100644 --- a/radix-engine/src/vm/wasm/traits.rs +++ b/radix-engine/src/vm/wasm/traits.rs @@ -208,6 +208,11 @@ pub trait WasmRuntime { signature: Vec, ) -> Result>; + fn crypto_utils_bls12381_g2_signature_aggregate( + &mut self, + signatures: Vec, + ) -> Result>; + fn crypto_utils_keccak256_hash( &mut self, data: Vec, diff --git a/radix-engine/src/vm/wasm/wasmer.rs b/radix-engine/src/vm/wasm/wasmer.rs index 38bdc413b80..82b761f8cf8 100644 --- a/radix-engine/src/vm/wasm/wasmer.rs +++ b/radix-engine/src/vm/wasm/wasmer.rs @@ -695,6 +695,20 @@ impl WasmerModule { runtime.crypto_utils_bls12381_v1_verify(message, public_key, signature) } + pub fn bls12381_g2_signature_aggregate( + env: &WasmerInstanceEnv, + signatures_ptr: u32, + signatures_len: u32, + ) -> Result> { + let (instance, runtime) = grab_runtime!(env); + + let signatures = read_memory(instance, signatures_ptr, signatures_len)?; + + runtime + .crypto_utils_bls12381_g2_signature_aggregate(signatures) + .map(|buffer| buffer.0) + } + pub fn keccak256_hash( env: &WasmerInstanceEnv, data_ptr: u32, @@ -813,6 +827,7 @@ impl WasmerModule { SYS_GENERATE_RUID_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), sys_generate_ruid), BUFFER_CONSUME_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), buffer_consume), CRYPTO_UTILS_BLS12381_V1_VERIFY_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), bls12381_v1_verify), + CRYPTO_UTILS_BLS12381_G2_SIGNATURE_AGGREGATE_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), bls12381_g2_signature_aggregate), CRYPTO_UTILS_KECCAK256_HASH_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), keccak256_hash), #[cfg(feature = "radix_engine_tests")] diff --git a/radix-engine/src/vm/wasm/wasmi.rs b/radix-engine/src/vm/wasm/wasmi.rs index 38a38b98fa9..7017e7d91e3 100644 --- a/radix-engine/src/vm/wasm/wasmi.rs +++ b/radix-engine/src/vm/wasm/wasmi.rs @@ -691,6 +691,25 @@ fn bls12381_v1_verify( runtime.crypto_utils_bls12381_v1_verify(message, public_key, signature) } +fn bls12381_g2_signature_aggregate( + mut caller: Caller<'_, HostState>, + signatures_ptr: u32, + signatures_len: u32, +) -> Result> { + let (memory, runtime) = grab_runtime!(caller); + + let signatures = read_memory( + caller.as_context_mut(), + memory, + signatures_ptr, + signatures_len, + )?; + + runtime + .crypto_utils_bls12381_g2_signature_aggregate(signatures) + .map(|buffer| buffer.0) +} + fn keccak256_hash( mut caller: Caller<'_, HostState>, data_ptr: u32, @@ -1291,6 +1310,17 @@ impl WasmiModule { }, ); + let host_bls12381_g2_signature_aggregate = Func::wrap( + store.as_context_mut(), + |caller: Caller<'_, HostState>, + signatures_ptr: u32, + signatures_len: u32| + -> Result { + bls12381_g2_signature_aggregate(caller, signatures_ptr, signatures_len) + .map_err(|e| e.into()) + }, + ); + let host_keccak256_hash = Func::wrap( store.as_context_mut(), |caller: Caller<'_, HostState>, data_ptr: u32, data_len: u32| -> Result { @@ -1460,6 +1490,12 @@ impl WasmiModule { CRYPTO_UTILS_BLS12381_V1_VERIFY_FUNCTION_NAME, host_bls12381_v1_verify ); + linker_define!( + linker, + CRYPTO_UTILS_BLS12381_G2_SIGNATURE_AGGREGATE_FUNCTION_NAME, + host_bls12381_g2_signature_aggregate + ); + linker_define!( linker, CRYPTO_UTILS_KECCAK256_HASH_FUNCTION_NAME, diff --git a/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs b/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs index 3a376f45884..6aa505e2d8e 100644 --- a/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs +++ b/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs @@ -315,6 +315,13 @@ impl<'a> WasmRuntime for NoOpWasmRuntime<'a> { Err(InvokeError::SelfError(WasmRuntimeError::NotImplemented)) } + fn crypto_utils_bls12381_g2_signature_aggregate( + &mut self, + signatures: Vec, + ) -> Result> { + Err(InvokeError::SelfError(WasmRuntimeError::NotImplemented)) + } + fn crypto_utils_keccak256_hash( &mut self, data: Vec, diff --git a/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs b/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs index 44cb905aa76..f750a592439 100644 --- a/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs +++ b/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs @@ -577,6 +577,26 @@ where Ok(result) } + fn crypto_utils_bls12381_g2_signature_aggregate( + &mut self, + signatures: Vec, + ) -> Result> { + let sigs_cnt = signatures.len() / Bls12381G2Signature::LENGTH; + let mut sigs_vec = vec![]; + + for i in 0..sigs_cnt { + let idx = i * Bls12381G2Signature::LENGTH; + let sig = + Bls12381G2Signature::try_from(&signatures[idx..idx + Bls12381G2Signature::LENGTH]) + .map_err(WasmRuntimeError::InvalidBlsSignature)?; + sigs_vec.push(sig); + } + + let agg_sig = self.api.bls12381_g2_signature_aggregate(sigs_vec)?; + + self.allocate_buffer(agg_sig.to_vec()) + } + fn crypto_utils_keccak256_hash( &mut self, data: Vec, diff --git a/scrypto-test/src/environment/client_api.rs b/scrypto-test/src/environment/client_api.rs index f9c49ce0ace..8f9798c7323 100644 --- a/scrypto-test/src/environment/client_api.rs +++ b/scrypto-test/src/environment/client_api.rs @@ -277,6 +277,7 @@ implement_client_api! { }, ClientCryptoUtilsApi: { bls12381_v1_verify: (&mut self, message: Vec, public_key: Bls12381G1PublicKey, signature: Bls12381G2Signature) -> Result, + bls12381_g2_signature_aggregate: (&mut self, signatures: Vec) -> Result, keccak256_hash: (&mut self, data: Vec) -> Result, }, } diff --git a/scrypto/src/crypto_utils/crypto_utils.rs b/scrypto/src/crypto_utils/crypto_utils.rs index 4db7a57d5c6..b366ed01c59 100644 --- a/scrypto/src/crypto_utils/crypto_utils.rs +++ b/scrypto/src/crypto_utils/crypto_utils.rs @@ -26,6 +26,20 @@ impl CryptoUtils { } } + /// Aggregate multiple BLS12-381 G2 signatures into single one + pub fn bls12381_g2_signature_aggregate( + signatures: Vec, + ) -> Bls12381G2Signature { + let agg_signature = copy_buffer(unsafe { + crypto_utils::crypto_utils_bls12381_g2_signature_aggregate( + signatures.as_ptr() as *const u8, + signatures.len() * Bls12381G2Signature::LENGTH, + ) + }); + + Bls12381G2Signature::try_from(agg_signature.as_slice()).unwrap() + } + /// Calculates Keccak-256 digest over given vector of bytes pub fn keccak256_hash(data: Vec) -> Hash { let hash = copy_buffer(unsafe { diff --git a/scrypto/src/engine/wasm_api.rs b/scrypto/src/engine/wasm_api.rs index 6ccba78cdb8..074ed735548 100644 --- a/scrypto/src/engine/wasm_api.rs +++ b/scrypto/src/engine/wasm_api.rs @@ -297,6 +297,10 @@ pub mod crypto_utils { signature_ptr: *const u8, signature_len: usize) -> u32; + pub fn crypto_utils_bls12381_g2_signature_aggregate( + signatures_ptr: *const u8, + signatures_len: usize) -> Buffer; + pub fn crypto_utils_keccak256_hash( message_ptr: *const u8, message_len: usize) -> Buffer; From 3eb85d67e5f7370da1a9006d1938faa579eaaea4 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Wed, 20 Dec 2023 17:38:37 +0100 Subject: [PATCH 46/82] Test bls12381_g2_signature_aggregate() --- .../blueprints/crypto_scrypto/src/lib.rs | 6 +++ .../tests/system/crypto_utils.rs | 48 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs b/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs index ff1b3673da3..eea6e890bf0 100644 --- a/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs +++ b/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs @@ -13,6 +13,12 @@ mod component_module { CryptoUtils::bls12381_v1_verify(message, pub_key, signature) } + pub fn bls12381_g2_signature_aggregate( + signatures: Vec, + ) -> Bls12381G2Signature { + CryptoUtils::bls12381_g2_signature_aggregate(signatures) + } + pub fn keccak256_hash(data: Vec) -> Hash { let hash = CryptoUtils::keccak256_hash(data); hash diff --git a/radix-engine-tests/tests/system/crypto_utils.rs b/radix-engine-tests/tests/system/crypto_utils.rs index 163a64dc2bf..79aade84caa 100644 --- a/radix-engine-tests/tests/system/crypto_utils.rs +++ b/radix-engine-tests/tests/system/crypto_utils.rs @@ -33,6 +33,28 @@ fn crypto_scrypto_bls12381_v1_verify( result.output(1) } +#[cfg(test)] +fn crypto_scrypto_bls12381_g2_signature_aggregate( + runner: &mut TestRunner, + package_address: PackageAddress, + signatures: Vec, +) -> Bls12381G2Signature { + let receipt = runner.execute_manifest( + ManifestBuilder::new() + .lock_fee(runner.faucet_component(), 500u32) + .call_function( + package_address, + "CryptoScrypto", + "bls12381_g2_signature_aggregate", + manifest_args!(signatures), + ) + .build(), + vec![], + ); + let result = receipt.expect_commit_success(); + result.output(1) +} + #[cfg(test)] fn crypto_scrypto_keccak256_hash( runner: &mut TestRunner, @@ -90,6 +112,32 @@ fn test_crypto_scrypto_verify_bls12381_v1() { assert!(!msg2_verify); } +#[test] +fn test_crypto_scrypto_bls12381_aggregate_verify() { + // Arrange + let mut test_runner = TestRunnerBuilder::new().build(); + + let package_address = test_runner.publish_package_simple(PackageLoader::get("crypto_scrypto")); + + let sks: Vec = (1..11) + .map(|i| Bls12381G1PrivateKey::from_u64(i).unwrap()) + .collect(); + + let msg = "One message to sign for all".as_bytes(); + + let sigs: Vec = sks.iter().map(|sk| sk.sign_v1(msg)).collect(); + + // Aggregate the signature + let agg_sig = Bls12381G2Signature::aggregate(&sigs).unwrap(); + + // Act + let agg_sig_from_scrypto = + crypto_scrypto_bls12381_g2_signature_aggregate(&mut test_runner, package_address, sigs); + + // Assert + assert_eq!(agg_sig, agg_sig_from_scrypto); +} + #[test] fn test_crypto_scrypto_keccak256_hash() { // Arrange From 7c89f7542f8ba8ced0d96fb7c608082780e39b73 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Thu, 21 Dec 2023 09:19:33 +0100 Subject: [PATCH 47/82] Add TODO costing note --- radix-engine/src/system/system.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/radix-engine/src/system/system.rs b/radix-engine/src/system/system.rs index ca03389b8f8..c77ff55fd94 100644 --- a/radix-engine/src/system/system.rs +++ b/radix-engine/src/system/system.rs @@ -2874,13 +2874,7 @@ where &mut self, signatures: Vec, ) -> Result { - /* - self.api.kernel_get_system().modules.apply_execution_cost( - ExecutionCostingEntry::Bls12381V1Verify { - size: message.len(), - }, - )?; - */ + // TODO costing Bls12381G2Signature::aggregate(&signatures) .map_err(|err| RuntimeError::SystemError(SystemError::BlsError(err.to_string()))) } From f79fadf3e7042890e5a7c678429d4cb7add56873 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Thu, 21 Dec 2023 10:17:44 +0100 Subject: [PATCH 48/82] Use references in ClientCryptoUtilsApi --- .../src/api/system_modules/crypto_utils_api.rs | 10 +++++----- radix-engine/src/system/system.rs | 18 +++++++++--------- .../src/vm/wasm_runtime/scrypto_runtime.rs | 6 +++--- scrypto-test/src/environment/client_api.rs | 6 +++--- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs b/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs index f4f5243f362..4848fca3b51 100644 --- a/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs +++ b/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs @@ -4,15 +4,15 @@ use crate::internal_prelude::Vec; pub trait ClientCryptoUtilsApi { fn bls12381_v1_verify( &mut self, - message: Vec, - public_key: Bls12381G1PublicKey, - signature: Bls12381G2Signature, + message: &[u8], + public_key: &Bls12381G1PublicKey, + signature: &Bls12381G2Signature, ) -> Result; fn bls12381_g2_signature_aggregate( &mut self, - signatures: Vec, + signatures: &[Bls12381G2Signature], ) -> Result; - fn keccak256_hash(&mut self, data: Vec) -> Result; + fn keccak256_hash(&mut self, data: &[u8]) -> Result; } diff --git a/radix-engine/src/system/system.rs b/radix-engine/src/system/system.rs index c77ff55fd94..c8965ff59cd 100644 --- a/radix-engine/src/system/system.rs +++ b/radix-engine/src/system/system.rs @@ -2861,28 +2861,28 @@ where #[trace_resources(log=message.len())] fn bls12381_v1_verify( &mut self, - message: Vec, - public_key: Bls12381G1PublicKey, - signature: Bls12381G2Signature, + message: &[u8], + public_key: &Bls12381G1PublicKey, + signature: &Bls12381G2Signature, ) -> Result { // TODO: apply execution costs - Ok(verify_bls12381_v1(&message, &public_key, &signature) as u32) + Ok(verify_bls12381_v1(message, public_key, signature) as u32) } #[trace_resources(log=signatures.len())] fn bls12381_g2_signature_aggregate( &mut self, - signatures: Vec, + signatures: &[Bls12381G2Signature], ) -> Result { - // TODO costing - Bls12381G2Signature::aggregate(&signatures) + // TODO: apply execution costs + Bls12381G2Signature::aggregate(signatures) .map_err(|err| RuntimeError::SystemError(SystemError::BlsError(err.to_string()))) } #[trace_resources(log=data.len())] - fn keccak256_hash(&mut self, data: Vec) -> Result { + fn keccak256_hash(&mut self, data: &[u8]) -> Result { // TODO: apply execution costs - Ok(keccak256_hash(&data)) + Ok(keccak256_hash(data)) } } diff --git a/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs b/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs index f750a592439..9a60944c645 100644 --- a/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs +++ b/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs @@ -573,7 +573,7 @@ where .map_err(WasmRuntimeError::InvalidBlsSignature)?; let result = self .api - .bls12381_v1_verify(message, public_key, signature)?; + .bls12381_v1_verify(&message, &public_key, &signature)?; Ok(result) } @@ -592,7 +592,7 @@ where sigs_vec.push(sig); } - let agg_sig = self.api.bls12381_g2_signature_aggregate(sigs_vec)?; + let agg_sig = self.api.bls12381_g2_signature_aggregate(&sigs_vec)?; self.allocate_buffer(agg_sig.to_vec()) } @@ -601,7 +601,7 @@ where &mut self, data: Vec, ) -> Result> { - let hash = self.api.keccak256_hash(data)?; + let hash = self.api.keccak256_hash(&data)?; self.allocate_buffer(hash.to_vec()) } diff --git a/scrypto-test/src/environment/client_api.rs b/scrypto-test/src/environment/client_api.rs index 8f9798c7323..2d43f0f4d0a 100644 --- a/scrypto-test/src/environment/client_api.rs +++ b/scrypto-test/src/environment/client_api.rs @@ -276,8 +276,8 @@ implement_client_api! { fee_balance: (&mut self) -> Result, }, ClientCryptoUtilsApi: { - bls12381_v1_verify: (&mut self, message: Vec, public_key: Bls12381G1PublicKey, signature: Bls12381G2Signature) -> Result, - bls12381_g2_signature_aggregate: (&mut self, signatures: Vec) -> Result, - keccak256_hash: (&mut self, data: Vec) -> Result, + bls12381_v1_verify: (&mut self, message: &[u8], public_key: &Bls12381G1PublicKey, signature: &Bls12381G2Signature) -> Result, + bls12381_g2_signature_aggregate: (&mut self, signatures: &[Bls12381G2Signature]) -> Result, + keccak256_hash: (&mut self, data: &[u8]) -> Result, }, } From 9c2728ae596e6d780584240b01c09fb554db84f7 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Thu, 21 Dec 2023 12:53:40 +0100 Subject: [PATCH 49/82] Add bls12381_v1_aggregate_verify() to CryptoUtils API --- .../api/system_modules/crypto_utils_api.rs | 7 +++ radix-engine/src/system/system.rs | 11 ++++ radix-engine/src/vm/wasm/constants.rs | 2 + radix-engine/src/vm/wasm/errors.rs | 1 + radix-engine/src/vm/wasm/traits.rs | 7 +++ radix-engine/src/vm/wasm/wasmer.rs | 20 +++++++ radix-engine/src/vm/wasm/wasmi.rs | 55 +++++++++++++++++++ .../src/vm/wasm_runtime/no_op_runtime.rs | 9 +++ .../src/vm/wasm_runtime/scrypto_runtime.rs | 29 ++++++++++ scrypto-test/src/environment/client_api.rs | 1 + scrypto/src/crypto_utils/crypto_utils.rs | 22 +++++++- scrypto/src/engine/wasm_api.rs | 8 +++ 12 files changed, 171 insertions(+), 1 deletion(-) diff --git a/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs b/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs index 4848fca3b51..d5a114a018c 100644 --- a/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs +++ b/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs @@ -9,6 +9,13 @@ pub trait ClientCryptoUtilsApi { signature: &Bls12381G2Signature, ) -> Result; + fn bls12381_v1_aggregate_verify( + &mut self, + messages: &[&[u8]], + public_keys: &[Bls12381G1PublicKey], + signature: &Bls12381G2Signature, + ) -> Result; + fn bls12381_g2_signature_aggregate( &mut self, signatures: &[Bls12381G2Signature], diff --git a/radix-engine/src/system/system.rs b/radix-engine/src/system/system.rs index c8965ff59cd..049135a4724 100644 --- a/radix-engine/src/system/system.rs +++ b/radix-engine/src/system/system.rs @@ -2869,6 +2869,17 @@ where Ok(verify_bls12381_v1(message, public_key, signature) as u32) } + #[trace_resources(log=messages.len())] + fn bls12381_v1_aggregate_verify( + &mut self, + messages: &[&[u8]], + public_keys: &[Bls12381G1PublicKey], + signature: &Bls12381G2Signature, + ) -> Result { + // TODO costing + Ok(aggregate_verify_bls12381_v1(messages, public_keys, signature) as u32) + } + #[trace_resources(log=signatures.len())] fn bls12381_g2_signature_aggregate( &mut self, diff --git a/radix-engine/src/vm/wasm/constants.rs b/radix-engine/src/vm/wasm/constants.rs index 01ea98ca739..3e758aed600 100644 --- a/radix-engine/src/vm/wasm/constants.rs +++ b/radix-engine/src/vm/wasm/constants.rs @@ -81,6 +81,8 @@ pub const SYS_PANIC_FUNCTION_NAME: &str = "sys_panic"; // Crypto Utils //================= pub const CRYPTO_UTILS_BLS12381_V1_VERIFY_FUNCTION_NAME: &str = "crypto_utils_bls12381_v1_verify"; +pub const CRYPTO_UTILS_BLS12381_V1_AGGREGATE_VERIFY_FUNCTION_NAME: &str = + "crypto_utils_bls12381_v1_aggregate_verify"; pub const CRYPTO_UTILS_BLS12381_G2_SIGNATURE_AGGREGATE_FUNCTION_NAME: &str = "crypto_utils_bls12381_g2_signature_aggregate"; pub const CRYPTO_UTILS_KECCAK256_HASH_FUNCTION_NAME: &str = "crypto_utils_keccak256_hash"; diff --git a/radix-engine/src/vm/wasm/errors.rs b/radix-engine/src/vm/wasm/errors.rs index d22d146f5ad..8214014e5f1 100644 --- a/radix-engine/src/vm/wasm/errors.rs +++ b/radix-engine/src/vm/wasm/errors.rs @@ -156,6 +156,7 @@ pub enum WasmRuntimeError { InvalidBlsPublicKey(ParseBlsPublicKeyError), InvalidBlsSignature(ParseBlsSignatureError), + InvalidBlsMessage(DecodeError), } impl SelfError for WasmRuntimeError { diff --git a/radix-engine/src/vm/wasm/traits.rs b/radix-engine/src/vm/wasm/traits.rs index 4dd9e6a25f5..53cb119fb86 100644 --- a/radix-engine/src/vm/wasm/traits.rs +++ b/radix-engine/src/vm/wasm/traits.rs @@ -208,6 +208,13 @@ pub trait WasmRuntime { signature: Vec, ) -> Result>; + fn crypto_utils_bls12381_v1_aggregate_verify( + &mut self, + messages: Vec, + public_keys: Vec, + signatures: Vec, + ) -> Result>; + fn crypto_utils_bls12381_g2_signature_aggregate( &mut self, signatures: Vec, diff --git a/radix-engine/src/vm/wasm/wasmer.rs b/radix-engine/src/vm/wasm/wasmer.rs index 82b761f8cf8..08842d65ec8 100644 --- a/radix-engine/src/vm/wasm/wasmer.rs +++ b/radix-engine/src/vm/wasm/wasmer.rs @@ -695,6 +695,25 @@ impl WasmerModule { runtime.crypto_utils_bls12381_v1_verify(message, public_key, signature) } + pub fn bls12381_v1_aggregate_verify( + env: &WasmerInstanceEnv, + messages_ptr: u32, + messages_len: u32, + public_keys_ptr: u32, + public_keys_len: u32, + signature_ptr: u32, + signature_len: u32, + ) -> Result> { + let (instance, runtime) = grab_runtime!(env); + + let messages = read_memory(&instance, messages_ptr, messages_len)?; + + let public_keys = read_memory(&instance, public_keys_ptr, public_keys_len)?; + let signature = read_memory(instance, signature_ptr, signature_len)?; + + runtime.crypto_utils_bls12381_v1_verify(messages, public_keys, signature) + } + pub fn bls12381_g2_signature_aggregate( env: &WasmerInstanceEnv, signatures_ptr: u32, @@ -827,6 +846,7 @@ impl WasmerModule { SYS_GENERATE_RUID_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), sys_generate_ruid), BUFFER_CONSUME_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), buffer_consume), CRYPTO_UTILS_BLS12381_V1_VERIFY_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), bls12381_v1_verify), + CRYPTO_UTILS_BLS12381_V1_AGGREGATE_VERIFY_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), bls12381_v1_aggregate_verify), CRYPTO_UTILS_BLS12381_G2_SIGNATURE_AGGREGATE_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), bls12381_g2_signature_aggregate), CRYPTO_UTILS_KECCAK256_HASH_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), keccak256_hash), diff --git a/radix-engine/src/vm/wasm/wasmi.rs b/radix-engine/src/vm/wasm/wasmi.rs index 7017e7d91e3..a93d9a160bd 100644 --- a/radix-engine/src/vm/wasm/wasmi.rs +++ b/radix-engine/src/vm/wasm/wasmi.rs @@ -691,6 +691,34 @@ fn bls12381_v1_verify( runtime.crypto_utils_bls12381_v1_verify(message, public_key, signature) } +fn bls12381_v1_aggregate_verify( + mut caller: Caller<'_, HostState>, + messages_ptr: u32, + messages_len: u32, + public_keys_ptr: u32, + public_keys_len: u32, + signature_ptr: u32, + signature_len: u32, +) -> Result> { + let (memory, runtime) = grab_runtime!(caller); + + let messages = read_memory(caller.as_context_mut(), memory, messages_ptr, messages_len)?; + let public_keys = read_memory( + caller.as_context_mut(), + memory, + public_keys_ptr, + public_keys_len, + )?; + let signature = read_memory( + caller.as_context_mut(), + memory, + signature_ptr, + signature_len, + )?; + + runtime.crypto_utils_bls12381_v1_aggregate_verify(messages, public_keys, signature) +} + fn bls12381_g2_signature_aggregate( mut caller: Caller<'_, HostState>, signatures_ptr: u32, @@ -1310,6 +1338,28 @@ impl WasmiModule { }, ); + let host_bls12381_v1_aggregate_verify = Func::wrap( + store.as_context_mut(), + |caller: Caller<'_, HostState>, + messages_ptr: u32, + messages_len: u32, + public_keys_ptr: u32, + public_keys_len: u32, + signature_ptr: u32, + signature_len: u32| + -> Result { + bls12381_v1_aggregate_verify( + caller, + messages_ptr, + messages_len, + public_keys_ptr, + public_keys_len, + signature_ptr, + signature_len, + ) + .map_err(|e| e.into()) + }, + ); let host_bls12381_g2_signature_aggregate = Func::wrap( store.as_context_mut(), |caller: Caller<'_, HostState>, @@ -1490,6 +1540,11 @@ impl WasmiModule { CRYPTO_UTILS_BLS12381_V1_VERIFY_FUNCTION_NAME, host_bls12381_v1_verify ); + linker_define!( + linker, + CRYPTO_UTILS_BLS12381_V1_AGGREGATE_VERIFY_FUNCTION_NAME, + host_bls12381_v1_aggregate_verify + ); linker_define!( linker, CRYPTO_UTILS_BLS12381_G2_SIGNATURE_AGGREGATE_FUNCTION_NAME, diff --git a/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs b/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs index 6aa505e2d8e..9fd0a8037ac 100644 --- a/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs +++ b/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs @@ -315,6 +315,15 @@ impl<'a> WasmRuntime for NoOpWasmRuntime<'a> { Err(InvokeError::SelfError(WasmRuntimeError::NotImplemented)) } + fn crypto_utils_bls12381_v1_aggregate_verify( + &mut self, + messages: Vec, + public_keys: Vec, + signature: Vec, + ) -> Result> { + Err(InvokeError::SelfError(WasmRuntimeError::NotImplemented)) + } + fn crypto_utils_bls12381_g2_signature_aggregate( &mut self, signatures: Vec, diff --git a/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs b/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs index 9a60944c645..f23c77d1c5c 100644 --- a/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs +++ b/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs @@ -577,6 +577,35 @@ where Ok(result) } + fn crypto_utils_bls12381_v1_aggregate_verify( + &mut self, + messages: Vec, + public_keys: Vec, + signature: Vec, + ) -> Result> { + let signature = Bls12381G2Signature::try_from(signature.as_slice()) + .map_err(WasmRuntimeError::InvalidBlsSignature)?; + let pks_cnt = public_keys.len() / Bls12381G1PublicKey::LENGTH; + let mut pks_vec = vec![]; + + for i in 0..pks_cnt { + let idx = i * Bls12381G1PublicKey::LENGTH; + let pk = + Bls12381G1PublicKey::try_from(&public_keys[idx..idx + Bls12381G1PublicKey::LENGTH]) + .map_err(WasmRuntimeError::InvalidBlsPublicKey)?; + pks_vec.push(pk); + } + + let messages: Vec> = + scrypto_decode(&messages).map_err(WasmRuntimeError::InvalidBlsMessage)?; + let msgs_ref: Vec<&[u8]> = messages.iter().map(|msg| msg.as_slice()).collect(); + + let result = self + .api + .bls12381_v1_aggregate_verify(&msgs_ref, &pks_vec, &signature)?; + Ok(result) + } + fn crypto_utils_bls12381_g2_signature_aggregate( &mut self, signatures: Vec, diff --git a/scrypto-test/src/environment/client_api.rs b/scrypto-test/src/environment/client_api.rs index 2d43f0f4d0a..5663a198273 100644 --- a/scrypto-test/src/environment/client_api.rs +++ b/scrypto-test/src/environment/client_api.rs @@ -277,6 +277,7 @@ implement_client_api! { }, ClientCryptoUtilsApi: { bls12381_v1_verify: (&mut self, message: &[u8], public_key: &Bls12381G1PublicKey, signature: &Bls12381G2Signature) -> Result, + bls12381_v1_aggregate_verify: (&mut self, messages: &[&[u8]], public_keys: &[Bls12381G1PublicKey], signature: &Bls12381G2Signature) -> Result, bls12381_g2_signature_aggregate: (&mut self, signatures: &[Bls12381G2Signature]) -> Result, keccak256_hash: (&mut self, data: &[u8]) -> Result, }, diff --git a/scrypto/src/crypto_utils/crypto_utils.rs b/scrypto/src/crypto_utils/crypto_utils.rs index b366ed01c59..08f2632fba4 100644 --- a/scrypto/src/crypto_utils/crypto_utils.rs +++ b/scrypto/src/crypto_utils/crypto_utils.rs @@ -1,5 +1,7 @@ use crate::engine::wasm_api::{copy_buffer, crypto_utils}; -use radix_engine_common::prelude::{Bls12381G1PublicKey, Bls12381G2Signature, Hash}; +use radix_engine_common::prelude::{ + scrypto_encode, Bls12381G1PublicKey, Bls12381G2Signature, Hash, +}; use sbor::prelude::Vec; /// Crypto utilities. @@ -26,6 +28,24 @@ impl CryptoUtils { } } + pub fn crypto_utils_bls12381_v1_aggregate_verify( + messages: Vec>, + public_keys: Vec, + signature: Bls12381G2Signature, + ) -> bool { + let messages: Vec = scrypto_encode(&messages).unwrap(); + unsafe { + crypto_utils::crypto_utils_bls12381_v1_aggregate_verify( + messages.as_ptr(), + messages.len(), + public_keys.as_ptr() as *const u8, + public_keys.len() * Bls12381G1PublicKey::LENGTH, + signature.0.as_ptr(), + signature.0.len(), + ) != 0 + } + } + /// Aggregate multiple BLS12-381 G2 signatures into single one pub fn bls12381_g2_signature_aggregate( signatures: Vec, diff --git a/scrypto/src/engine/wasm_api.rs b/scrypto/src/engine/wasm_api.rs index 074ed735548..676824f47e7 100644 --- a/scrypto/src/engine/wasm_api.rs +++ b/scrypto/src/engine/wasm_api.rs @@ -297,6 +297,14 @@ pub mod crypto_utils { signature_ptr: *const u8, signature_len: usize) -> u32; + pub fn crypto_utils_bls12381_v1_aggregate_verify( + messages_ptr: *const u8, + messages_len: usize, + public_keys_ptr: *const u8, + public_keys_len: usize, + signature_ptr: *const u8, + signature_len: usize) -> u32; + pub fn crypto_utils_bls12381_g2_signature_aggregate( signatures_ptr: *const u8, signatures_len: usize) -> Buffer; From 01ac0cad071a539d7a5f6fe80b6c4f4e46feb3ef Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Thu, 21 Dec 2023 13:00:40 +0100 Subject: [PATCH 50/82] Cleanup in crypto_utils tests --- .../tests/system/crypto_utils.rs | 40 +++++++++---------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/radix-engine-tests/tests/system/crypto_utils.rs b/radix-engine-tests/tests/system/crypto_utils.rs index 79aade84caa..415c6df6314 100644 --- a/radix-engine-tests/tests/system/crypto_utils.rs +++ b/radix-engine-tests/tests/system/crypto_utils.rs @@ -9,14 +9,10 @@ use transaction::builder::ManifestBuilder; fn crypto_scrypto_bls12381_v1_verify( runner: &mut TestRunner, package_address: PackageAddress, - msg: &str, - pk: &str, - sig: &str, + msg: Vec, + pub_key: Bls12381G1PublicKey, + signature: Bls12381G2Signature, ) -> bool { - let msg = hex::decode(msg).unwrap(); - let pub_key = Bls12381G1PublicKey::from_str(pk).unwrap(); - let signature = Bls12381G2Signature::from_str(sig).unwrap(); - let receipt = runner.execute_manifest( ManifestBuilder::new() .lock_fee(runner.faucet_component(), 500u32) @@ -59,10 +55,8 @@ fn crypto_scrypto_bls12381_g2_signature_aggregate( fn crypto_scrypto_keccak256_hash( runner: &mut TestRunner, package_address: PackageAddress, - data: &str, + data: Vec, ) -> Hash { - let data = data.as_bytes().to_vec(); - let receipt = runner.execute_manifest( ManifestBuilder::new() .lock_fee(runner.faucet_component(), 500u32) @@ -86,23 +80,25 @@ fn test_crypto_scrypto_verify_bls12381_v1() { let package_address = test_runner.publish_package_simple(PackageLoader::get("crypto_scrypto")); - let msg1 = hash("Test").to_string(); - let msg2 = hash("ExpectFailureTest").to_string(); + let msg1 = hash("Test").to_vec(); + let msg2 = hash("ExpectFailureTest").to_vec(); let pk = "93b1aa7542a5423e21d8e84b4472c31664412cc604a666e9fdf03baf3c758e728c7a11576ebb01110ac39a0df95636e2"; let msg1_signature = "8b84ff5a1d4f8095ab8a80518ac99230ed24a7d1ec90c4105f9c719aa7137ed5d7ce1454d4a953f5f55f3959ab416f3014f4cd2c361e4d32c6b4704a70b0e2e652a908f501acb54ec4e79540be010e3fdc1fbf8e7af61625705e185a71c884f1"; + let pk = Bls12381G1PublicKey::from_str(pk).unwrap(); + let msg1_signature = Bls12381G2Signature::from_str(msg1_signature).unwrap(); // Act let msg1_verify = crypto_scrypto_bls12381_v1_verify( &mut test_runner, package_address, - &msg1, + msg1, pk, msg1_signature, ); let msg2_verify = crypto_scrypto_bls12381_v1_verify( &mut test_runner, package_address, - &msg2, + msg2, pk, msg1_signature, ); @@ -145,8 +141,8 @@ fn test_crypto_scrypto_keccak256_hash() { let package_address = test_runner.publish_package_simple(PackageLoader::get("crypto_scrypto")); - let data1 = "Hello Radix"; - let data2 = "xidaR olleH"; + let data1 = b"Hello Radix".to_vec(); + let data2 = b"xidaR olleH".to_vec(); // Act let data1_hash = crypto_scrypto_keccak256_hash(&mut test_runner, package_address, data1); @@ -170,11 +166,13 @@ fn test_crypto_scrypto_flow() { let package_address = test_runner.publish_package_simple(PackageLoader::get("crypto_scrypto")); - let msg = "Important message"; + let msg = b"Important message".to_vec(); // Act // Get the hash of the message using CryptoScrypto package - let msg_hash = crypto_scrypto_keccak256_hash(&mut test_runner, package_address, msg); + let msg_hash = crypto_scrypto_keccak256_hash(&mut test_runner, package_address, msg) + .as_bytes() + .to_vec(); let secret_key = Bls12381G1PrivateKey::from_u64(1).unwrap(); let public_key = secret_key.public_key(); @@ -186,9 +184,9 @@ fn test_crypto_scrypto_flow() { let result = crypto_scrypto_bls12381_v1_verify( &mut test_runner, package_address, - &msg_hash.to_string(), - &public_key.to_string(), - &msg_signature.to_string(), + msg_hash, + public_key, + msg_signature, ); // Assert From 088307e40fe33190deed3094813d557721131e43 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Thu, 21 Dec 2023 13:11:06 +0100 Subject: [PATCH 51/82] Add bls12381_v1_aggregate_verify() to CryptoUtils API --- radix-engine/src/vm/wasm/prepare.rs | 22 ++++++++++++++++++++++ radix-engine/src/vm/wasm/wasmer.rs | 2 +- scrypto/src/crypto_utils/crypto_utils.rs | 9 ++++++--- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/radix-engine/src/vm/wasm/prepare.rs b/radix-engine/src/vm/wasm/prepare.rs index ee6e61c3f8f..769cae077dd 100644 --- a/radix-engine/src/vm/wasm/prepare.rs +++ b/radix-engine/src/vm/wasm/prepare.rs @@ -755,6 +755,28 @@ impl WasmModule { )); } } + CRYPTO_UTILS_BLS12381_V1_AGGREGATE_VERIFY_FUNCTION_NAME => { + if let TypeRef::Func(type_index) = entry.ty { + if Self::function_type_matches( + &self.module, + type_index, + vec![ + ValType::I32, + ValType::I32, + ValType::I32, + ValType::I32, + ValType::I32, + ValType::I32, + ], + vec![ValType::I32], + ) { + continue; + } + return Err(PrepareError::InvalidImport( + InvalidImport::InvalidFunctionType(entry.name.to_string()), + )); + } + } CRYPTO_UTILS_BLS12381_G2_SIGNATURE_AGGREGATE_FUNCTION_NAME => { if let TypeRef::Func(type_index) = entry.ty { if Self::function_type_matches( diff --git a/radix-engine/src/vm/wasm/wasmer.rs b/radix-engine/src/vm/wasm/wasmer.rs index 08842d65ec8..8be5f81d642 100644 --- a/radix-engine/src/vm/wasm/wasmer.rs +++ b/radix-engine/src/vm/wasm/wasmer.rs @@ -711,7 +711,7 @@ impl WasmerModule { let public_keys = read_memory(&instance, public_keys_ptr, public_keys_len)?; let signature = read_memory(instance, signature_ptr, signature_len)?; - runtime.crypto_utils_bls12381_v1_verify(messages, public_keys, signature) + runtime.crypto_utils_bls12381_v1_aggregate_verify(messages, public_keys, signature) } pub fn bls12381_g2_signature_aggregate( diff --git a/scrypto/src/crypto_utils/crypto_utils.rs b/scrypto/src/crypto_utils/crypto_utils.rs index 08f2632fba4..ed5328f72d7 100644 --- a/scrypto/src/crypto_utils/crypto_utils.rs +++ b/scrypto/src/crypto_utils/crypto_utils.rs @@ -9,8 +9,8 @@ use sbor::prelude::Vec; pub struct CryptoUtils {} impl CryptoUtils { - /// Performs BLS12-381 G2 signature verification using following - /// domain specifier tag: BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_ + /// Performs BLS12-381 G2 signature verification. + /// Domain specifier tag: BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_ pub fn bls12381_v1_verify( message: Vec, public_key: Bls12381G1PublicKey, @@ -28,7 +28,10 @@ impl CryptoUtils { } } - pub fn crypto_utils_bls12381_v1_aggregate_verify( + /// Performs BLS12-381 G2 aggregated signature verification of + /// multiple messages each signed with different key. + /// Domain specifier tag: BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_ + pub fn bls12381_v1_aggregate_verify( messages: Vec>, public_keys: Vec, signature: Bls12381G2Signature, From 6f88c1bd895f073594a459feeb1aaa3d434f1631 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Thu, 21 Dec 2023 13:12:44 +0100 Subject: [PATCH 52/82] Test bls12381_v1_aggregate_verify() --- .../blueprints/crypto_scrypto/src/lib.rs | 8 +++ .../tests/system/crypto_utils.rs | 54 +++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs b/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs index eea6e890bf0..b807b80f2a2 100644 --- a/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs +++ b/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs @@ -13,6 +13,14 @@ mod component_module { CryptoUtils::bls12381_v1_verify(message, pub_key, signature) } + pub fn bls12381_v1_aggregate_verify( + messages: Vec>, + pub_keys: Vec, + signature: Bls12381G2Signature, + ) -> bool { + CryptoUtils::bls12381_v1_aggregate_verify(messages, pub_keys, signature) + } + pub fn bls12381_g2_signature_aggregate( signatures: Vec, ) -> Bls12381G2Signature { diff --git a/radix-engine-tests/tests/system/crypto_utils.rs b/radix-engine-tests/tests/system/crypto_utils.rs index 415c6df6314..fd45f8026a8 100644 --- a/radix-engine-tests/tests/system/crypto_utils.rs +++ b/radix-engine-tests/tests/system/crypto_utils.rs @@ -29,6 +29,30 @@ fn crypto_scrypto_bls12381_v1_verify( result.output(1) } +#[cfg(test)] +fn crypto_scrypto_bls12381_v1_aggregate_verify( + runner: &mut TestRunner, + package_address: PackageAddress, + msgs: Vec>, + pub_keys: Vec, + signature: Bls12381G2Signature, +) -> bool { + let receipt = runner.execute_manifest( + ManifestBuilder::new() + .lock_fee(runner.faucet_component(), 500u32) + .call_function( + package_address, + "CryptoScrypto", + "bls12381_v1_aggregate_verify", + manifest_args!(msgs, pub_keys, signature), + ) + .build(), + vec![], + ); + let result = receipt.expect_commit_success(); + result.output(1) +} + #[cfg(test)] fn crypto_scrypto_bls12381_g2_signature_aggregate( runner: &mut TestRunner, @@ -119,6 +143,36 @@ fn test_crypto_scrypto_bls12381_aggregate_verify() { .map(|i| Bls12381G1PrivateKey::from_u64(i).unwrap()) .collect(); + //// Multiple messages + let msgs: Vec> = (1u8..11).map(|i| vec![i; 10]).collect(); + + let sigs: Vec = sks + .iter() + .zip(msgs.clone()) + .map(|(sk, msg)| sk.sign_v1(&msg)) + .collect(); + + let pks: Vec = sks.iter().map(|sk| sk.public_key()).collect(); + + // Aggregate the signature + let agg_sig = Bls12381G2Signature::aggregate(&sigs).unwrap(); + + // Act + let agg_sig_from_scrypto = + crypto_scrypto_bls12381_g2_signature_aggregate(&mut test_runner, package_address, sigs); + let agg_verify = crypto_scrypto_bls12381_v1_aggregate_verify( + &mut test_runner, + package_address, + msgs, + pks, + agg_sig, + ); + + // Assert + assert_eq!(agg_sig, agg_sig_from_scrypto); + assert!(agg_verify); + + //// Single message let msg = "One message to sign for all".as_bytes(); let sigs: Vec = sks.iter().map(|sk| sk.sign_v1(msg)).collect(); From 65621f50ce44a30712992e0feafe1a5635e672d9 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Thu, 21 Dec 2023 15:40:37 +0100 Subject: [PATCH 53/82] Fix resources tracing --- radix-engine/src/system/system.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/radix-engine/src/system/system.rs b/radix-engine/src/system/system.rs index 049135a4724..a57a473443c 100644 --- a/radix-engine/src/system/system.rs +++ b/radix-engine/src/system/system.rs @@ -2869,7 +2869,8 @@ where Ok(verify_bls12381_v1(message, public_key, signature) as u32) } - #[trace_resources(log=messages.len())] + // Trace average message length and number of public_keys + #[trace_resources(log=messages.iter().map(Vec::len).sum::()/messages.len(),log=public_keys.len())] fn bls12381_v1_aggregate_verify( &mut self, messages: &[&[u8]], From e49d3a22773387c68c19ca2373bf432dca4d6fa6 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Thu, 21 Dec 2023 16:56:10 +0100 Subject: [PATCH 54/82] Add bls12381_v1_fast_aggregate_verify() to CryptoUtils API --- .../api/system_modules/crypto_utils_api.rs | 9 ++- radix-engine/src/system/system.rs | 11 ++++ radix-engine/src/vm/wasm/constants.rs | 2 + radix-engine/src/vm/wasm/prepare.rs | 22 +++++++ radix-engine/src/vm/wasm/traits.rs | 7 +++ radix-engine/src/vm/wasm/wasmer.rs | 20 +++++++ radix-engine/src/vm/wasm/wasmi.rs | 57 +++++++++++++++++++ .../src/vm/wasm_runtime/no_op_runtime.rs | 9 +++ .../src/vm/wasm_runtime/scrypto_runtime.rs | 25 ++++++++ scrypto-test/src/environment/client_api.rs | 1 + scrypto/src/crypto_utils/crypto_utils.rs | 20 +++++++ scrypto/src/engine/wasm_api.rs | 8 +++ 12 files changed, 190 insertions(+), 1 deletion(-) diff --git a/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs b/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs index d5a114a018c..30b2ebae641 100644 --- a/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs +++ b/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs @@ -1,5 +1,5 @@ use crate::crypto::*; -use crate::internal_prelude::Vec; +use crate::internal_prelude::*; pub trait ClientCryptoUtilsApi { fn bls12381_v1_verify( @@ -16,6 +16,13 @@ pub trait ClientCryptoUtilsApi { signature: &Bls12381G2Signature, ) -> Result; + fn bls12381_v1_fast_aggregate_verify( + &mut self, + message: &[u8], + public_keys: &[Bls12381G1PublicKey], + signature: &Bls12381G2Signature, + ) -> Result; + fn bls12381_g2_signature_aggregate( &mut self, signatures: &[Bls12381G2Signature], diff --git a/radix-engine/src/system/system.rs b/radix-engine/src/system/system.rs index a57a473443c..184377360a5 100644 --- a/radix-engine/src/system/system.rs +++ b/radix-engine/src/system/system.rs @@ -2881,6 +2881,17 @@ where Ok(aggregate_verify_bls12381_v1(messages, public_keys, signature) as u32) } + #[trace_resources(log=message.len(), log=public_keys.len())] + fn bls12381_v1_fast_aggregate_verify( + &mut self, + message: &[u8], + public_keys: &[Bls12381G1PublicKey], + signature: &Bls12381G2Signature, + ) -> Result { + // TODO costing + Ok(fast_aggregate_verify_bls12381_v1(message, public_keys, signature) as u32) + } + #[trace_resources(log=signatures.len())] fn bls12381_g2_signature_aggregate( &mut self, diff --git a/radix-engine/src/vm/wasm/constants.rs b/radix-engine/src/vm/wasm/constants.rs index 3e758aed600..34ef2f84487 100644 --- a/radix-engine/src/vm/wasm/constants.rs +++ b/radix-engine/src/vm/wasm/constants.rs @@ -83,6 +83,8 @@ pub const SYS_PANIC_FUNCTION_NAME: &str = "sys_panic"; pub const CRYPTO_UTILS_BLS12381_V1_VERIFY_FUNCTION_NAME: &str = "crypto_utils_bls12381_v1_verify"; pub const CRYPTO_UTILS_BLS12381_V1_AGGREGATE_VERIFY_FUNCTION_NAME: &str = "crypto_utils_bls12381_v1_aggregate_verify"; +pub const CRYPTO_UTILS_BLS12381_V1_FAST_AGGREGATE_VERIFY_FUNCTION_NAME: &str = + "crypto_utils_bls12381_v1_fast_aggregate_verify"; pub const CRYPTO_UTILS_BLS12381_G2_SIGNATURE_AGGREGATE_FUNCTION_NAME: &str = "crypto_utils_bls12381_g2_signature_aggregate"; pub const CRYPTO_UTILS_KECCAK256_HASH_FUNCTION_NAME: &str = "crypto_utils_keccak256_hash"; diff --git a/radix-engine/src/vm/wasm/prepare.rs b/radix-engine/src/vm/wasm/prepare.rs index 769cae077dd..5285bcfa539 100644 --- a/radix-engine/src/vm/wasm/prepare.rs +++ b/radix-engine/src/vm/wasm/prepare.rs @@ -777,6 +777,28 @@ impl WasmModule { )); } } + CRYPTO_UTILS_BLS12381_V1_FAST_AGGREGATE_VERIFY_FUNCTION_NAME => { + if let TypeRef::Func(type_index) = entry.ty { + if Self::function_type_matches( + &self.module, + type_index, + vec![ + ValType::I32, + ValType::I32, + ValType::I32, + ValType::I32, + ValType::I32, + ValType::I32, + ], + vec![ValType::I32], + ) { + continue; + } + return Err(PrepareError::InvalidImport( + InvalidImport::InvalidFunctionType(entry.name.to_string()), + )); + } + } CRYPTO_UTILS_BLS12381_G2_SIGNATURE_AGGREGATE_FUNCTION_NAME => { if let TypeRef::Func(type_index) = entry.ty { if Self::function_type_matches( diff --git a/radix-engine/src/vm/wasm/traits.rs b/radix-engine/src/vm/wasm/traits.rs index 53cb119fb86..0653004f2b0 100644 --- a/radix-engine/src/vm/wasm/traits.rs +++ b/radix-engine/src/vm/wasm/traits.rs @@ -215,6 +215,13 @@ pub trait WasmRuntime { signatures: Vec, ) -> Result>; + fn crypto_utils_bls12381_v1_fast_aggregate_verify( + &mut self, + message: Vec, + public_keys: Vec, + signatures: Vec, + ) -> Result>; + fn crypto_utils_bls12381_g2_signature_aggregate( &mut self, signatures: Vec, diff --git a/radix-engine/src/vm/wasm/wasmer.rs b/radix-engine/src/vm/wasm/wasmer.rs index 8be5f81d642..9d3fe499e95 100644 --- a/radix-engine/src/vm/wasm/wasmer.rs +++ b/radix-engine/src/vm/wasm/wasmer.rs @@ -714,6 +714,25 @@ impl WasmerModule { runtime.crypto_utils_bls12381_v1_aggregate_verify(messages, public_keys, signature) } + pub fn bls12381_v1_fast_aggregate_verify( + env: &WasmerInstanceEnv, + message_ptr: u32, + message_len: u32, + public_keys_ptr: u32, + public_keys_len: u32, + signature_ptr: u32, + signature_len: u32, + ) -> Result> { + let (instance, runtime) = grab_runtime!(env); + + let message = read_memory(&instance, message_ptr, message_len)?; + + let public_keys = read_memory(&instance, public_keys_ptr, public_keys_len)?; + let signature = read_memory(instance, signature_ptr, signature_len)?; + + runtime.crypto_utils_bls12381_v1_fast_aggregate_verify(message, public_keys, signature) + } + pub fn bls12381_g2_signature_aggregate( env: &WasmerInstanceEnv, signatures_ptr: u32, @@ -847,6 +866,7 @@ impl WasmerModule { BUFFER_CONSUME_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), buffer_consume), CRYPTO_UTILS_BLS12381_V1_VERIFY_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), bls12381_v1_verify), CRYPTO_UTILS_BLS12381_V1_AGGREGATE_VERIFY_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), bls12381_v1_aggregate_verify), + CRYPTO_UTILS_BLS12381_V1_FAST_AGGREGATE_VERIFY_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), bls12381_v1_fast_aggregate_verify), CRYPTO_UTILS_BLS12381_G2_SIGNATURE_AGGREGATE_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), bls12381_g2_signature_aggregate), CRYPTO_UTILS_KECCAK256_HASH_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), keccak256_hash), diff --git a/radix-engine/src/vm/wasm/wasmi.rs b/radix-engine/src/vm/wasm/wasmi.rs index a93d9a160bd..465461dfec2 100644 --- a/radix-engine/src/vm/wasm/wasmi.rs +++ b/radix-engine/src/vm/wasm/wasmi.rs @@ -719,6 +719,34 @@ fn bls12381_v1_aggregate_verify( runtime.crypto_utils_bls12381_v1_aggregate_verify(messages, public_keys, signature) } +fn bls12381_v1_fast_aggregate_verify( + mut caller: Caller<'_, HostState>, + message_ptr: u32, + message_len: u32, + public_keys_ptr: u32, + public_keys_len: u32, + signature_ptr: u32, + signature_len: u32, +) -> Result> { + let (memory, runtime) = grab_runtime!(caller); + + let message = read_memory(caller.as_context_mut(), memory, message_ptr, message_len)?; + let public_keys = read_memory( + caller.as_context_mut(), + memory, + public_keys_ptr, + public_keys_len, + )?; + let signature = read_memory( + caller.as_context_mut(), + memory, + signature_ptr, + signature_len, + )?; + + runtime.crypto_utils_bls12381_v1_fast_aggregate_verify(message, public_keys, signature) +} + fn bls12381_g2_signature_aggregate( mut caller: Caller<'_, HostState>, signatures_ptr: u32, @@ -1360,6 +1388,30 @@ impl WasmiModule { .map_err(|e| e.into()) }, ); + + let host_bls12381_v1_fast_aggregate_verify = Func::wrap( + store.as_context_mut(), + |caller: Caller<'_, HostState>, + message_ptr: u32, + message_len: u32, + public_keys_ptr: u32, + public_keys_len: u32, + signature_ptr: u32, + signature_len: u32| + -> Result { + bls12381_v1_fast_aggregate_verify( + caller, + message_ptr, + message_len, + public_keys_ptr, + public_keys_len, + signature_ptr, + signature_len, + ) + .map_err(|e| e.into()) + }, + ); + let host_bls12381_g2_signature_aggregate = Func::wrap( store.as_context_mut(), |caller: Caller<'_, HostState>, @@ -1545,6 +1597,11 @@ impl WasmiModule { CRYPTO_UTILS_BLS12381_V1_AGGREGATE_VERIFY_FUNCTION_NAME, host_bls12381_v1_aggregate_verify ); + linker_define!( + linker, + CRYPTO_UTILS_BLS12381_V1_FAST_AGGREGATE_VERIFY_FUNCTION_NAME, + host_bls12381_v1_fast_aggregate_verify + ); linker_define!( linker, CRYPTO_UTILS_BLS12381_G2_SIGNATURE_AGGREGATE_FUNCTION_NAME, diff --git a/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs b/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs index 9fd0a8037ac..b925ae5bd54 100644 --- a/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs +++ b/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs @@ -324,6 +324,15 @@ impl<'a> WasmRuntime for NoOpWasmRuntime<'a> { Err(InvokeError::SelfError(WasmRuntimeError::NotImplemented)) } + fn crypto_utils_bls12381_v1_fast_aggregate_verify( + &mut self, + message: Vec, + public_keys: Vec, + signature: Vec, + ) -> Result> { + Err(InvokeError::SelfError(WasmRuntimeError::NotImplemented)) + } + fn crypto_utils_bls12381_g2_signature_aggregate( &mut self, signatures: Vec, diff --git a/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs b/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs index f23c77d1c5c..26a6704fc54 100644 --- a/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs +++ b/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs @@ -606,6 +606,31 @@ where Ok(result) } + fn crypto_utils_bls12381_v1_fast_aggregate_verify( + &mut self, + message: Vec, + public_keys: Vec, + signature: Vec, + ) -> Result> { + let signature = Bls12381G2Signature::try_from(signature.as_slice()) + .map_err(WasmRuntimeError::InvalidBlsSignature)?; + let pks_cnt = public_keys.len() / Bls12381G1PublicKey::LENGTH; + let mut pks_vec = vec![]; + + for i in 0..pks_cnt { + let idx = i * Bls12381G1PublicKey::LENGTH; + let pk = + Bls12381G1PublicKey::try_from(&public_keys[idx..idx + Bls12381G1PublicKey::LENGTH]) + .map_err(WasmRuntimeError::InvalidBlsPublicKey)?; + pks_vec.push(pk); + } + + let result = self + .api + .bls12381_v1_fast_aggregate_verify(&message, &pks_vec, &signature)?; + Ok(result) + } + fn crypto_utils_bls12381_g2_signature_aggregate( &mut self, signatures: Vec, diff --git a/scrypto-test/src/environment/client_api.rs b/scrypto-test/src/environment/client_api.rs index 5663a198273..e46d8b27aab 100644 --- a/scrypto-test/src/environment/client_api.rs +++ b/scrypto-test/src/environment/client_api.rs @@ -278,6 +278,7 @@ implement_client_api! { ClientCryptoUtilsApi: { bls12381_v1_verify: (&mut self, message: &[u8], public_key: &Bls12381G1PublicKey, signature: &Bls12381G2Signature) -> Result, bls12381_v1_aggregate_verify: (&mut self, messages: &[&[u8]], public_keys: &[Bls12381G1PublicKey], signature: &Bls12381G2Signature) -> Result, + bls12381_v1_fast_aggregate_verify: (&mut self, message: &[u8], public_keys: &[Bls12381G1PublicKey], signature: &Bls12381G2Signature) -> Result, bls12381_g2_signature_aggregate: (&mut self, signatures: &[Bls12381G2Signature]) -> Result, keccak256_hash: (&mut self, data: &[u8]) -> Result, }, diff --git a/scrypto/src/crypto_utils/crypto_utils.rs b/scrypto/src/crypto_utils/crypto_utils.rs index ed5328f72d7..8456ac8f175 100644 --- a/scrypto/src/crypto_utils/crypto_utils.rs +++ b/scrypto/src/crypto_utils/crypto_utils.rs @@ -49,6 +49,26 @@ impl CryptoUtils { } } + /// Performs BLS12-381 G2 aggregated signature verification of + /// multiple messages each signed with different key. + /// Domain specifier tag: BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_ + pub fn bls12381_v1_fast_aggregate_verify( + message: Vec, + public_keys: Vec, + signature: Bls12381G2Signature, + ) -> bool { + unsafe { + crypto_utils::crypto_utils_bls12381_v1_fast_aggregate_verify( + message.as_ptr(), + message.len(), + public_keys.as_ptr() as *const u8, + public_keys.len() * Bls12381G1PublicKey::LENGTH, + signature.0.as_ptr(), + signature.0.len(), + ) != 0 + } + } + /// Aggregate multiple BLS12-381 G2 signatures into single one pub fn bls12381_g2_signature_aggregate( signatures: Vec, diff --git a/scrypto/src/engine/wasm_api.rs b/scrypto/src/engine/wasm_api.rs index 676824f47e7..70e1240d0e7 100644 --- a/scrypto/src/engine/wasm_api.rs +++ b/scrypto/src/engine/wasm_api.rs @@ -305,6 +305,14 @@ pub mod crypto_utils { signature_ptr: *const u8, signature_len: usize) -> u32; + pub fn crypto_utils_bls12381_v1_fast_aggregate_verify( + messages_ptr: *const u8, + messages_len: usize, + public_keys_ptr: *const u8, + public_keys_len: usize, + signature_ptr: *const u8, + signature_len: usize) -> u32; + pub fn crypto_utils_bls12381_g2_signature_aggregate( signatures_ptr: *const u8, signatures_len: usize) -> Buffer; From 101cc14d1f51623aa51c16cae95d93c70de5b757 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Thu, 21 Dec 2023 17:22:23 +0100 Subject: [PATCH 55/82] Test bls12381_v1_fast_aggregate_verify() --- .../blueprints/crypto_scrypto/src/lib.rs | 8 ++ .../tests/system/crypto_utils.rs | 91 +++++++++++++++++-- 2 files changed, 89 insertions(+), 10 deletions(-) diff --git a/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs b/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs index b807b80f2a2..ef70670f5bb 100644 --- a/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs +++ b/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs @@ -21,6 +21,14 @@ mod component_module { CryptoUtils::bls12381_v1_aggregate_verify(messages, pub_keys, signature) } + pub fn bls12381_v1_fast_aggregate_verify( + message: Vec, + pub_keys: Vec, + signature: Bls12381G2Signature, + ) -> bool { + CryptoUtils::bls12381_v1_fast_aggregate_verify(message, pub_keys, signature) + } + pub fn bls12381_g2_signature_aggregate( signatures: Vec, ) -> Bls12381G2Signature { diff --git a/radix-engine-tests/tests/system/crypto_utils.rs b/radix-engine-tests/tests/system/crypto_utils.rs index fd45f8026a8..b9a69b4cd38 100644 --- a/radix-engine-tests/tests/system/crypto_utils.rs +++ b/radix-engine-tests/tests/system/crypto_utils.rs @@ -53,6 +53,30 @@ fn crypto_scrypto_bls12381_v1_aggregate_verify( result.output(1) } +#[cfg(test)] +fn crypto_scrypto_bls12381_v1_fast_aggregate_verify( + runner: &mut TestRunner, + package_address: PackageAddress, + msg: Vec, + pub_keys: Vec, + signature: Bls12381G2Signature, +) -> bool { + let receipt = runner.execute_manifest( + ManifestBuilder::new() + .lock_fee(runner.faucet_component(), 500u32) + .call_function( + package_address, + "CryptoScrypto", + "bls12381_v1_fast_aggregate_verify", + manifest_args!(msg, pub_keys, signature), + ) + .build(), + vec![], + ); + let result = receipt.expect_commit_success(); + result.output(1) +} + #[cfg(test)] fn crypto_scrypto_bls12381_g2_signature_aggregate( runner: &mut TestRunner, @@ -143,7 +167,7 @@ fn test_crypto_scrypto_bls12381_aggregate_verify() { .map(|i| Bls12381G1PrivateKey::from_u64(i).unwrap()) .collect(); - //// Multiple messages + // Multiple messages let msgs: Vec> = (1u8..11).map(|i| vec![i; 10]).collect(); let sigs: Vec = sks @@ -155,37 +179,84 @@ fn test_crypto_scrypto_bls12381_aggregate_verify() { let pks: Vec = sks.iter().map(|sk| sk.public_key()).collect(); // Aggregate the signature - let agg_sig = Bls12381G2Signature::aggregate(&sigs).unwrap(); + let agg_sig_multiple_msgs = Bls12381G2Signature::aggregate(&sigs).unwrap(); // Act let agg_sig_from_scrypto = crypto_scrypto_bls12381_g2_signature_aggregate(&mut test_runner, package_address, sigs); let agg_verify = crypto_scrypto_bls12381_v1_aggregate_verify( + &mut test_runner, + package_address, + msgs.clone(), + pks.clone(), + agg_sig_multiple_msgs, + ); + + let mut pks_rev = pks.clone(); + pks_rev.reverse(); + + // Attempt to verify with reversed public keys order + let agg_verify_expect_false = crypto_scrypto_bls12381_v1_aggregate_verify( &mut test_runner, package_address, msgs, - pks, - agg_sig, + pks_rev, + agg_sig_multiple_msgs, ); // Assert - assert_eq!(agg_sig, agg_sig_from_scrypto); + assert_eq!(agg_sig_multiple_msgs, agg_sig_from_scrypto); assert!(agg_verify); + assert!(!agg_verify_expect_false); +} + +#[test] +fn test_crypto_scrypto_bls12381_fast_aggregate_verify() { + // Arrange + let mut test_runner = TestRunnerBuilder::new().build(); + + let package_address = test_runner.publish_package_simple(PackageLoader::get("crypto_scrypto")); + + let sks: Vec = (1..11) + .map(|i| Bls12381G1PrivateKey::from_u64(i).unwrap()) + .collect(); - //// Single message - let msg = "One message to sign for all".as_bytes(); + // Single message + let msg = b"One message to sign for all".to_vec(); - let sigs: Vec = sks.iter().map(|sk| sk.sign_v1(msg)).collect(); + let sigs: Vec = sks.iter().map(|sk| sk.sign_v1(&msg)).collect(); + + let pks: Vec = sks.iter().map(|sk| sk.public_key()).collect(); // Aggregate the signature - let agg_sig = Bls12381G2Signature::aggregate(&sigs).unwrap(); + let agg_sig_single_msg = Bls12381G2Signature::aggregate(&sigs).unwrap(); // Act let agg_sig_from_scrypto = crypto_scrypto_bls12381_g2_signature_aggregate(&mut test_runner, package_address, sigs); + let agg_verify = crypto_scrypto_bls12381_v1_fast_aggregate_verify( + &mut test_runner, + package_address, + msg, + pks.clone(), + agg_sig_single_msg, + ); + + let msg_false = b"Some other message".to_vec(); + + // Attempt to verify non-matching signature + let agg_verify_expect_false = crypto_scrypto_bls12381_v1_fast_aggregate_verify( + &mut test_runner, + package_address, + msg_false, + pks, + agg_sig_single_msg, + ); // Assert - assert_eq!(agg_sig, agg_sig_from_scrypto); + assert_eq!(agg_sig_single_msg, agg_sig_from_scrypto); + assert!(agg_verify); + assert!(!agg_verify_expect_false); } #[test] From d3bda78bd7d19ce6fb47be2eb68676ddc8b8dadd Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Thu, 21 Dec 2023 18:08:37 +0100 Subject: [PATCH 56/82] Temporarily set dummy resources tracing for bls12381_v1_aggregate_verify --- radix-engine/src/system/system.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/radix-engine/src/system/system.rs b/radix-engine/src/system/system.rs index 184377360a5..04790eaef61 100644 --- a/radix-engine/src/system/system.rs +++ b/radix-engine/src/system/system.rs @@ -2870,7 +2870,9 @@ where } // Trace average message length and number of public_keys - #[trace_resources(log=messages.iter().map(Vec::len).sum::()/messages.len(),log=public_keys.len())] + // FIXME: Improve resource tracker, because below line causes panic in resource tracker + //#[trace_resources(log=(messages.iter().map(|m| m.len()).sum::()/messages.len()),log=public_keys.len())] + #[trace_resources(log=messages.len(),log=public_keys.len())] fn bls12381_v1_aggregate_verify( &mut self, messages: &[&[u8]], From 1dc2b4d01deab419128fae3a5c0d8e5d6cb9df7b Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Thu, 21 Dec 2023 18:24:13 +0100 Subject: [PATCH 57/82] Comment fixed --- scrypto/src/crypto_utils/crypto_utils.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scrypto/src/crypto_utils/crypto_utils.rs b/scrypto/src/crypto_utils/crypto_utils.rs index 8456ac8f175..400d86153d4 100644 --- a/scrypto/src/crypto_utils/crypto_utils.rs +++ b/scrypto/src/crypto_utils/crypto_utils.rs @@ -49,8 +49,8 @@ impl CryptoUtils { } } - /// Performs BLS12-381 G2 aggregated signature verification of - /// multiple messages each signed with different key. + /// Performs BLS12-381 G2 aggregated signature verification + /// one message signed with multiple keys. /// Domain specifier tag: BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_ pub fn bls12381_v1_fast_aggregate_verify( message: Vec, From fc270331f3df4a1416753b339b594d42a1089c0f Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Thu, 4 Jan 2024 13:27:30 +0100 Subject: [PATCH 58/82] Fix resources tracing for bls12381_v1_aggregate_verify --- radix-engine/src/system/system.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/radix-engine/src/system/system.rs b/radix-engine/src/system/system.rs index 04790eaef61..326fdb2a80e 100644 --- a/radix-engine/src/system/system.rs +++ b/radix-engine/src/system/system.rs @@ -2870,9 +2870,7 @@ where } // Trace average message length and number of public_keys - // FIXME: Improve resource tracker, because below line causes panic in resource tracker - //#[trace_resources(log=(messages.iter().map(|m| m.len()).sum::()/messages.len()),log=public_keys.len())] - #[trace_resources(log=messages.len(),log=public_keys.len())] + #[trace_resources(log={messages.iter().map(|m| m.len()).sum::()/messages.len()},log=public_keys.len())] fn bls12381_v1_aggregate_verify( &mut self, messages: &[&[u8]], From 385ea47a61d40a33fec48fc630646a1b26da4d8b Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Thu, 4 Jan 2024 14:19:14 +0100 Subject: [PATCH 59/82] Add more Keccak256 and BLS12381 tests for costing --- .../tests/system/crypto_utils.rs | 154 ++++++++++++++++++ 1 file changed, 154 insertions(+) diff --git a/radix-engine-tests/tests/system/crypto_utils.rs b/radix-engine-tests/tests/system/crypto_utils.rs index b9a69b4cd38..5ba6b710991 100644 --- a/radix-engine-tests/tests/system/crypto_utils.rs +++ b/radix-engine-tests/tests/system/crypto_utils.rs @@ -317,3 +317,157 @@ fn test_crypto_scrypto_flow() { // Assert assert!(result); } + +#[test] +fn test_crypto_scrypto_keccak256_costing() { + let mut test_runner = TestRunnerBuilder::new().build(); + + let package_address = test_runner.publish_package_simple(PackageLoader::get("crypto_scrypto")); + + for size in [ + 100usize, + 200, + 500, + 1024, + 10 * 1024, + 20 * 1024, + 50 * 1024, + 100 * 1024, + 200 * 1024, + 500 * 1024, + 900 * 1024, + ] { + let data = vec![0u8; size]; + let _hash = crypto_scrypto_keccak256_hash(&mut test_runner, package_address, data); + } +} + +#[test] +fn test_crypto_scrypto_verify_bls12381_v1_costing() { + let mut test_runner = TestRunnerBuilder::new().build(); + + let package_address = test_runner.publish_package_simple(PackageLoader::get("crypto_scrypto")); + + let secret_key = Bls12381G1PrivateKey::from_u64(1).unwrap(); + let public_key = secret_key.public_key(); + + for size in [ + 100usize, + 200, + 500, + 1024, + 10 * 1024, + 20 * 1024, + 50 * 1024, + 100 * 1024, + 200 * 1024, + 500 * 1024, + 900 * 1024, + ] { + let data = vec![0u8; size]; + let signature = secret_key.sign_v1(data.as_slice()); + let receipt = test_runner.execute_manifest( + ManifestBuilder::new() + .lock_fee(test_runner.faucet_component(), 500u32) + .call_function( + package_address, + "CryptoScrypto", + "bls12381_v1_verify", + manifest_args!(data, public_key, signature), + ) + .build(), + vec![], + ); + let _ = receipt.expect_commit_success(); + } +} + +#[test] +fn test_crypto_scrypto_bls12381_g2_signature_aggregate_costing() { + let mut test_runner = TestRunnerBuilder::new().build(); + + let package_address = test_runner.publish_package_simple(PackageLoader::get("crypto_scrypto")); + + for cnt in [1, 2, 5, 10, 20, 50, 100] { + let sks: Vec = (1..(cnt + 1)) + .map(|i| Bls12381G1PrivateKey::from_u64(i).unwrap()) + .collect(); + + // Single message + let msg = b"One message to sign for all".to_vec(); + + let sigs: Vec = sks.iter().map(|sk| sk.sign_v1(&msg)).collect(); + + // Act + let _agg_sig_from_scrypto = + crypto_scrypto_bls12381_g2_signature_aggregate(&mut test_runner, package_address, sigs); + } +} + +#[test] +fn test_crypto_scrypto_bls12381_v1_aggregate_verify_costing() { + let mut test_runner = TestRunnerBuilder::new().build(); + + let package_address = test_runner.publish_package_simple(PackageLoader::get("crypto_scrypto")); + + for msg_size in [100usize, 200, 500, 1024, 10 * 1024, 20 * 1024] { + for cnt in [1u8, 2, 5, 10, 20] { + let sks: Vec = (1..(cnt + 1)) + .map(|i| Bls12381G1PrivateKey::from_u64(i.into()).unwrap()) + .collect(); + + // Multiple messages + let msgs: Vec> = (1..(cnt + 1)).map(|i| vec![i; msg_size]).collect(); + + let sigs: Vec = sks + .iter() + .zip(msgs.clone()) + .map(|(sk, msg)| sk.sign_v1(&msg)) + .collect(); + + let pks: Vec = sks.iter().map(|sk| sk.public_key()).collect(); + + let agg_sig_multiple_msgs = Bls12381G2Signature::aggregate(&sigs).unwrap(); + + let _agg_verify = crypto_scrypto_bls12381_v1_aggregate_verify( + &mut test_runner, + package_address, + msgs, + pks, + agg_sig_multiple_msgs, + ); + } + } +} + +#[test] +fn test_crypto_scrypto_bls12381_v1_fast_aggregate_verify_costing() { + let mut test_runner = TestRunnerBuilder::new().build(); + + let package_address = test_runner.publish_package_simple(PackageLoader::get("crypto_scrypto")); + + for msg_size in [100usize, 200, 500, 1024, 10 * 1024, 20 * 1024] { + for cnt in [1u8, 2, 5, 10, 20, 50, 100] { + let sks: Vec = (1..(cnt + 1)) + .map(|i| Bls12381G1PrivateKey::from_u64(i.into()).unwrap()) + .collect(); + + // Single message + let msg: Vec = vec![cnt; msg_size]; + + let sigs: Vec = sks.iter().map(|sk| sk.sign_v1(&msg)).collect(); + + let pks: Vec = sks.iter().map(|sk| sk.public_key()).collect(); + + let agg_sig_single_msg = Bls12381G2Signature::aggregate(&sigs).unwrap(); + + let _agg_verify = crypto_scrypto_bls12381_v1_fast_aggregate_verify( + &mut test_runner, + package_address, + msg, + pks, + agg_sig_single_msg, + ); + } + } +} From d5e469aeaed73c7d839884f7ed18564179713ab2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Strug?= <114988195+mstrug-rdx@users.noreply.github.com> Date: Mon, 18 Dec 2023 16:45:10 +0100 Subject: [PATCH 60/82] Disabled cpu parameter in qemu call due to some incompatibility issues. --- .../resources-tracker-macro/scripts/run_tests.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/radix-engine-profiling/resources-tracker-macro/scripts/run_tests.sh b/radix-engine-profiling/resources-tracker-macro/scripts/run_tests.sh index b246b70c4e6..54acd5b047a 100755 --- a/radix-engine-profiling/resources-tracker-macro/scripts/run_tests.sh +++ b/radix-engine-profiling/resources-tracker-macro/scripts/run_tests.sh @@ -4,7 +4,7 @@ qemu_app=/home/ubuntu/qemu/qemu-x86_64 qemu_plugin=/home/ubuntu/qemu/libscrypto-qemu-plugin.so -qemu_cpu="Westmere-v1" +#qemu_cpu="Westmere-v1" # disabled due to some issue with missing CPU instructions in BLS implementation if [ -z "$*" ]; then echo "Provide path to folder with binaries to execute."; exit; fi @@ -18,7 +18,7 @@ for i in $list; do [ -x $i ] && list_count=$((list_count+1)); done for i in $list; do if [ -x $i ]; then echo "Running $idx/$list_count: $i" - $qemu_app -cpu $qemu_cpu -plugin $qemu_plugin -d plugin -D log.txt $i --show-output --test --test-threads 1 > out.txt + $qemu_app -plugin $qemu_plugin -d plugin -D log.txt $i --show-output --test --test-threads 1 > out.txt idx=$((idx+1)) fi done From 46407f66b2811e9c4f8a4946b46d7dd5f84ff4d2 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Mon, 18 Dec 2023 12:08:16 +0100 Subject: [PATCH 61/82] Add Keccak256 and Bls12381 costing basing on benches --- radix-engine/src/system/system.rs | 11 +++++- .../system_modules/costing/costing_entry.rs | 10 +++++ .../system_modules/costing/fee_table.rs | 39 +++++++++++++++++++ 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/radix-engine/src/system/system.rs b/radix-engine/src/system/system.rs index 326fdb2a80e..9d7a8d72c34 100644 --- a/radix-engine/src/system/system.rs +++ b/radix-engine/src/system/system.rs @@ -2865,7 +2865,11 @@ where public_key: &Bls12381G1PublicKey, signature: &Bls12381G2Signature, ) -> Result { - // TODO: apply execution costs + self.api.kernel_get_system().modules.apply_execution_cost( + ExecutionCostingEntry::Bls12381V1Verify { + size: message.len(), + }, + )?; Ok(verify_bls12381_v1(message, public_key, signature) as u32) } @@ -2904,7 +2908,10 @@ where #[trace_resources(log=data.len())] fn keccak256_hash(&mut self, data: &[u8]) -> Result { - // TODO: apply execution costs + self.api + .kernel_get_system() + .modules + .apply_execution_cost(ExecutionCostingEntry::Keccak256Hash { size: data.len() })?; Ok(keccak256_hash(data)) } } diff --git a/radix-engine/src/system/system_modules/costing/costing_entry.rs b/radix-engine/src/system/system_modules/costing/costing_entry.rs index d511bd356b2..df9da3e5b47 100644 --- a/radix-engine/src/system/system_modules/costing/costing_entry.rs +++ b/radix-engine/src/system/system_modules/costing/costing_entry.rs @@ -110,6 +110,14 @@ pub enum ExecutionCostingEntry<'a> { Panic { size: usize, }, + + /* crypto utils */ + Bls12381V1Verify { + size: usize, + }, + Keccak256Hash { + size: usize, + }, } #[derive(Debug, IntoStaticStr)] @@ -172,6 +180,8 @@ impl<'a> ExecutionCostingEntry<'a> { ExecutionCostingEntry::EmitEvent { size } => ft.emit_event_cost(*size), ExecutionCostingEntry::EmitLog { size } => ft.emit_log_cost(*size), ExecutionCostingEntry::Panic { size } => ft.panic_cost(*size), + ExecutionCostingEntry::Bls12381V1Verify { size } => ft.bls12381_v1_verify_cost(*size), + ExecutionCostingEntry::Keccak256Hash { size } => ft.keccak256_hash_cost(*size), } } } diff --git a/radix-engine/src/system/system_modules/costing/fee_table.rs b/radix-engine/src/system/system_modules/costing/fee_table.rs index 04e565bb07b..3aa6d8bb84e 100644 --- a/radix-engine/src/system/system_modules/costing/fee_table.rs +++ b/radix-engine/src/system/system_modules/costing/fee_table.rs @@ -381,6 +381,40 @@ impl FeeTable { 500 + Self::data_processing_cost(size) } + #[inline] + pub fn bls12381_v1_verify_cost(&self, size: usize) -> u32 { + // Based on benchmark `bench_bls_verify` + // The cost of validating is: + // - calculate sha256 over a message and map it to the curve (depends on the data size) + // 42 µs for 100kB + // 430 µs for 1MB + // which gives: + // 0.04 µs for 100B => 0.04 µs * 100 units/µs = 0.04 cost units for one byte + // Assume cost 4 cost units for sizes < 100B + // - validate the signature (does not depend on the data size) + // 770 µs * 100 units/µs = 77,000 cost units + let size = if size < 100 { 100 } else { cast(size) }; + + div(mul(size, 4), 100) + 77_000 + } + + #[inline] + pub fn keccak256_hash_cost(&self, size: usize) -> u32 { + // Based on benchmark `bench_keccak256_hash` + // The cost of validating is: + // - calculate sha256 over a message and map it to the curve (depends on the data size) + // 176 µs for 100kB + // 1800 µs for 1MB + // 248 ns for 32B + // which gives: + // 0.19 µs for 100B => 0.19 µs * 100 units/µs = 0.19 cost units for one byte + // For sizes lower than 500B timings are non-linear, so assume 19 * 5 = 95 cost units + // for sizes < 500B + let size = if size < 500 { 500 } else { cast(size) }; + + div(mul(size, 19), 100) + } + //====================== // Finalization costs // This is primarily to account for the additional work on the Node side @@ -431,3 +465,8 @@ fn add(a: u32, b: u32) -> u32 { fn mul(a: u32, b: u32) -> u32 { a.checked_mul(b).unwrap_or(u32::MAX) } + +#[inline] +fn div(a: u32, b: u32) -> u32 { + a.checked_div(b).unwrap_or(u32::MAX) +} From b18f6d8fb99aceea32151109a4b226116667a84a Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Thu, 4 Jan 2024 16:49:39 +0100 Subject: [PATCH 62/82] Rework Keccak256 and Bls12381 costing to rely on instruction count --- .../system_modules/costing/fee_table.rs | 48 +++++++++---------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/radix-engine/src/system/system_modules/costing/fee_table.rs b/radix-engine/src/system/system_modules/costing/fee_table.rs index 3aa6d8bb84e..4519c7086d2 100644 --- a/radix-engine/src/system/system_modules/costing/fee_table.rs +++ b/radix-engine/src/system/system_modules/costing/fee_table.rs @@ -383,36 +383,32 @@ impl FeeTable { #[inline] pub fn bls12381_v1_verify_cost(&self, size: usize) -> u32 { - // Based on benchmark `bench_bls_verify` - // The cost of validating is: - // - calculate sha256 over a message and map it to the curve (depends on the data size) - // 42 µs for 100kB - // 430 µs for 1MB - // which gives: - // 0.04 µs for 100B => 0.04 µs * 100 units/µs = 0.04 cost units for one byte - // Assume cost 4 cost units for sizes < 100B - // - validate the signature (does not depend on the data size) - // 770 µs * 100 units/µs = 77,000 cost units - let size = if size < 100 { 100 } else { cast(size) }; - - div(mul(size, 4), 100) + 77_000 + // Based on `test_crypto_scrypto_verify_bls12381_v1_costing` + // - For sizes less than 1024, instruction count remains the same. + // - For greater sizes following linear equation might be applied: + // instructions_cnt = 34.55672 * size + 10577803.13 + // Lets round: + // 34.55672 -> 35 + // 10577803.13 -> 10577804 + let size = if size < 1024 { 1024 } else { cast(size) }; + let instructions_cnt = mul(size, 35) + 10577804; + // Convert to cost units + div(instructions_cnt, CPU_INSTRUCTIONS_TO_COST_UNIT) } #[inline] pub fn keccak256_hash_cost(&self, size: usize) -> u32 { - // Based on benchmark `bench_keccak256_hash` - // The cost of validating is: - // - calculate sha256 over a message and map it to the curve (depends on the data size) - // 176 µs for 100kB - // 1800 µs for 1MB - // 248 ns for 32B - // which gives: - // 0.19 µs for 100B => 0.19 µs * 100 units/µs = 0.19 cost units for one byte - // For sizes lower than 500B timings are non-linear, so assume 19 * 5 = 95 cost units - // for sizes < 500B - let size = if size < 500 { 500 } else { cast(size) }; - - div(mul(size, 19), 100) + // Based on `test_crypto_scrypto_keccak256_costing` + // - For sizes less than 100, instruction count remains the same. + // - For greater sizes following linear equation might be applied: + // instructions_cnt = 46.41919 * size + 2641.66077 + // Lets round: + // 46.41919 -> 47 + // 2641.66077 -> 2642 + let size = if size < 100 { 100 } else { cast(size) }; + let instructions_cnt = mul(size, 47) + 2642; + // Convert to cost units + div(instructions_cnt, CPU_INSTRUCTIONS_TO_COST_UNIT) } //====================== From 35a4762937d7003cda37a0f1da28321424f21f7e Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Fri, 5 Jan 2024 10:58:30 +0100 Subject: [PATCH 63/82] Add costing for remaining Bls12381 methods --- radix-engine/src/system/system.rs | 20 +++++- .../system_modules/costing/costing_entry.rs | 20 ++++++ .../system_modules/costing/fee_table.rs | 66 ++++++++++++++++--- 3 files changed, 95 insertions(+), 11 deletions(-) diff --git a/radix-engine/src/system/system.rs b/radix-engine/src/system/system.rs index 9d7a8d72c34..e7f99e7ee6f 100644 --- a/radix-engine/src/system/system.rs +++ b/radix-engine/src/system/system.rs @@ -2881,7 +2881,12 @@ where public_keys: &[Bls12381G1PublicKey], signature: &Bls12381G2Signature, ) -> Result { - // TODO costing + self.api.kernel_get_system().modules.apply_execution_cost( + ExecutionCostingEntry::Bls12381V1AggregateVerify { + size: messages.iter().map(|m| m.len()).sum::() / messages.len(), + keys_cnt: public_keys.len(), + }, + )?; Ok(aggregate_verify_bls12381_v1(messages, public_keys, signature) as u32) } @@ -2892,7 +2897,12 @@ where public_keys: &[Bls12381G1PublicKey], signature: &Bls12381G2Signature, ) -> Result { - // TODO costing + self.api.kernel_get_system().modules.apply_execution_cost( + ExecutionCostingEntry::Bls12381V1FastAggregateVerify { + size: message.len(), + keys_cnt: public_keys.len(), + }, + )?; Ok(fast_aggregate_verify_bls12381_v1(message, public_keys, signature) as u32) } @@ -2901,7 +2911,11 @@ where &mut self, signatures: &[Bls12381G2Signature], ) -> Result { - // TODO: apply execution costs + self.api.kernel_get_system().modules.apply_execution_cost( + ExecutionCostingEntry::Bls12381G2SignatureAggregate { + signatures_cnt: signatures.len(), + }, + )?; Bls12381G2Signature::aggregate(signatures) .map_err(|err| RuntimeError::SystemError(SystemError::BlsError(err.to_string()))) } diff --git a/radix-engine/src/system/system_modules/costing/costing_entry.rs b/radix-engine/src/system/system_modules/costing/costing_entry.rs index df9da3e5b47..9b4523810ef 100644 --- a/radix-engine/src/system/system_modules/costing/costing_entry.rs +++ b/radix-engine/src/system/system_modules/costing/costing_entry.rs @@ -115,6 +115,17 @@ pub enum ExecutionCostingEntry<'a> { Bls12381V1Verify { size: usize, }, + Bls12381V1AggregateVerify { + size: usize, + keys_cnt: usize, + }, + Bls12381V1FastAggregateVerify { + size: usize, + keys_cnt: usize, + }, + Bls12381G2SignatureAggregate { + signatures_cnt: usize, + }, Keccak256Hash { size: usize, }, @@ -181,6 +192,15 @@ impl<'a> ExecutionCostingEntry<'a> { ExecutionCostingEntry::EmitLog { size } => ft.emit_log_cost(*size), ExecutionCostingEntry::Panic { size } => ft.panic_cost(*size), ExecutionCostingEntry::Bls12381V1Verify { size } => ft.bls12381_v1_verify_cost(*size), + ExecutionCostingEntry::Bls12381V1AggregateVerify { size, keys_cnt } => { + ft.bls12381_v1_aggregate_verify_cost(*size, *keys_cnt) + } + ExecutionCostingEntry::Bls12381V1FastAggregateVerify { size, keys_cnt } => { + ft.bls12381_v1_fast_aggregate_verify_cost(*size, *keys_cnt) + } + ExecutionCostingEntry::Bls12381G2SignatureAggregate { signatures_cnt } => { + ft.bls12381_g2_signature_aggregate_cost(*signatures_cnt) + } ExecutionCostingEntry::Keccak256Hash { size } => ft.keccak256_hash_cost(*size), } } diff --git a/radix-engine/src/system/system_modules/costing/fee_table.rs b/radix-engine/src/system/system_modules/costing/fee_table.rs index 4519c7086d2..d6c00613b83 100644 --- a/radix-engine/src/system/system_modules/costing/fee_table.rs +++ b/radix-engine/src/system/system_modules/costing/fee_table.rs @@ -386,14 +386,63 @@ impl FeeTable { // Based on `test_crypto_scrypto_verify_bls12381_v1_costing` // - For sizes less than 1024, instruction count remains the same. // - For greater sizes following linear equation might be applied: + // (used: https://www.socscistatistics.com/tests/regression/default.aspx) // instructions_cnt = 34.55672 * size + 10577803.13 // Lets round: // 34.55672 -> 35 // 10577803.13 -> 10577804 let size = if size < 1024 { 1024 } else { cast(size) }; - let instructions_cnt = mul(size, 35) + 10577804; + let instructions_cnt = add(mul(size, 35), 10577804); // Convert to cost units - div(instructions_cnt, CPU_INSTRUCTIONS_TO_COST_UNIT) + instructions_cnt / CPU_INSTRUCTIONS_TO_COST_UNIT + } + + #[inline] + pub fn bls12381_v1_aggregate_verify_cost(&self, size: usize, keys_cnt: usize) -> u32 { + // Based on `test_crypto_scrypto_bls12381_v1_aggregate_verify_costing` + // - For sizes less than 1024, instruction count remains the same. + // - For greater sizes following linear equation might be applied: + // instructions_cnt = 87.3416 * size + 1438527.7574 * keys_cnt + 9058827.9112 + // (used: https://www.socscistatistics.com/tests/multipleregression/default.aspx) + // Lets round: + // 87.3416 -> 88 + // 1438527.757 -> 1438528 + // 9058827.911 -> 9058828 + let size = if size < 1024 { 1024 } else { cast(size) }; + let instructions_cnt = add(add(mul(size, 88), mul(cast(keys_cnt), 1438528)), 9058828); + // Convert to cost units + instructions_cnt / CPU_INSTRUCTIONS_TO_COST_UNIT + } + + #[inline] + pub fn bls12381_v1_fast_aggregate_verify_cost(&self, size: usize, keys_cnt: usize) -> u32 { + // Based on `test_crypto_scrypto_bls12381_v1_fast_aggregate_verify_costing` + // - For sizes less than 1024, instruction count remains the same. + // - For greater sizes following linear equation might be applied: + // instructions_cnt = 32.1717 * size + 624919.5254 * keys_cnt + 9058827.9112 + // (used: https://www.socscistatistics.com/tests/multipleregression/default.aspx) + // Lets round: + // 32.1717 -> 33 + // 624919.5254 -> 624920 + // 10096964.55 -> 10096965 + let size = if size < 1024 { 1024 } else { cast(size) }; + let instructions_cnt = add(add(mul(size, 33), mul(cast(keys_cnt), 624920)), 10096965); + // Convert to cost units + instructions_cnt / CPU_INSTRUCTIONS_TO_COST_UNIT + } + + #[inline] + pub fn bls12381_g2_signature_aggregate_cost(&self, signatures_cnt: usize) -> u32 { + // Based on `test_crypto_scrypto_bls12381_g2_signature_aggregate_costing` + // Following linear equation might be applied: + // instructions_cnt = 879553.91557 * signatures_cnt - 567872.58948 + // (used: https://www.socscistatistics.com/tests/regression/default.aspx) + // Lets round: + // 879553.91557 -> 879554 + // 567872.5895 -> 567873 + let instructions_cnt = sub(mul(cast(signatures_cnt), 879554), 567873); + // Convert to cost units + instructions_cnt / CPU_INSTRUCTIONS_TO_COST_UNIT } #[inline] @@ -402,13 +451,14 @@ impl FeeTable { // - For sizes less than 100, instruction count remains the same. // - For greater sizes following linear equation might be applied: // instructions_cnt = 46.41919 * size + 2641.66077 + // (used: https://www.socscistatistics.com/tests/regression/default.aspx) // Lets round: // 46.41919 -> 47 // 2641.66077 -> 2642 let size = if size < 100 { 100 } else { cast(size) }; - let instructions_cnt = mul(size, 47) + 2642; + let instructions_cnt = add(mul(size, 47), 2642); // Convert to cost units - div(instructions_cnt, CPU_INSTRUCTIONS_TO_COST_UNIT) + instructions_cnt / CPU_INSTRUCTIONS_TO_COST_UNIT } //====================== @@ -458,11 +508,11 @@ fn add(a: u32, b: u32) -> u32 { } #[inline] -fn mul(a: u32, b: u32) -> u32 { - a.checked_mul(b).unwrap_or(u32::MAX) +fn sub(a: u32, b: u32) -> u32 { + a.checked_sub(b).unwrap_or(u32::MAX) } #[inline] -fn div(a: u32, b: u32) -> u32 { - a.checked_div(b).unwrap_or(u32::MAX) +fn mul(a: u32, b: u32) -> u32 { + a.checked_mul(b).unwrap_or(u32::MAX) } From 7cf8a5a81ee36198528c62a2b972c2659d2ee76b Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Fri, 5 Jan 2024 15:45:10 +0100 Subject: [PATCH 64/82] Check for empty input --- radix-engine/src/errors.rs | 1 + radix-engine/src/system/system.rs | 54 +++++++++++++++++++------------ 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/radix-engine/src/errors.rs b/radix-engine/src/errors.rs index 923eb4f6053..b9862c8ab74 100644 --- a/radix-engine/src/errors.rs +++ b/radix-engine/src/errors.rs @@ -252,6 +252,7 @@ pub enum SystemError { BlueprintTypeNotFound(String), BlsError(String), + InputDataEmpty, /// A panic that's occurred in the system-layer or below. We're calling it system panic since /// we're treating the system as a black-box here. diff --git a/radix-engine/src/system/system.rs b/radix-engine/src/system/system.rs index e7f99e7ee6f..fd0a049209c 100644 --- a/radix-engine/src/system/system.rs +++ b/radix-engine/src/system/system.rs @@ -2881,13 +2881,17 @@ where public_keys: &[Bls12381G1PublicKey], signature: &Bls12381G2Signature, ) -> Result { - self.api.kernel_get_system().modules.apply_execution_cost( - ExecutionCostingEntry::Bls12381V1AggregateVerify { - size: messages.iter().map(|m| m.len()).sum::() / messages.len(), - keys_cnt: public_keys.len(), - }, - )?; - Ok(aggregate_verify_bls12381_v1(messages, public_keys, signature) as u32) + if !messages.is_empty() && !public_keys.is_empty() { + self.api.kernel_get_system().modules.apply_execution_cost( + ExecutionCostingEntry::Bls12381V1AggregateVerify { + size: messages.iter().map(|m| m.len()).sum::() / messages.len(), + keys_cnt: public_keys.len(), + }, + )?; + Ok(aggregate_verify_bls12381_v1(messages, public_keys, signature) as u32) + } else { + Err(RuntimeError::SystemError(SystemError::InputDataEmpty)) + } } #[trace_resources(log=message.len(), log=public_keys.len())] @@ -2897,13 +2901,17 @@ where public_keys: &[Bls12381G1PublicKey], signature: &Bls12381G2Signature, ) -> Result { - self.api.kernel_get_system().modules.apply_execution_cost( - ExecutionCostingEntry::Bls12381V1FastAggregateVerify { - size: message.len(), - keys_cnt: public_keys.len(), - }, - )?; - Ok(fast_aggregate_verify_bls12381_v1(message, public_keys, signature) as u32) + if !public_keys.is_empty() { + self.api.kernel_get_system().modules.apply_execution_cost( + ExecutionCostingEntry::Bls12381V1FastAggregateVerify { + size: message.len(), + keys_cnt: public_keys.len(), + }, + )?; + Ok(fast_aggregate_verify_bls12381_v1(message, public_keys, signature) as u32) + } else { + Err(RuntimeError::SystemError(SystemError::InputDataEmpty)) + } } #[trace_resources(log=signatures.len())] @@ -2911,13 +2919,17 @@ where &mut self, signatures: &[Bls12381G2Signature], ) -> Result { - self.api.kernel_get_system().modules.apply_execution_cost( - ExecutionCostingEntry::Bls12381G2SignatureAggregate { - signatures_cnt: signatures.len(), - }, - )?; - Bls12381G2Signature::aggregate(signatures) - .map_err(|err| RuntimeError::SystemError(SystemError::BlsError(err.to_string()))) + if !signatures.is_empty() { + self.api.kernel_get_system().modules.apply_execution_cost( + ExecutionCostingEntry::Bls12381G2SignatureAggregate { + signatures_cnt: signatures.len(), + }, + )?; + Bls12381G2Signature::aggregate(signatures) + .map_err(|err| RuntimeError::SystemError(SystemError::BlsError(err.to_string()))) + } else { + Err(RuntimeError::SystemError(SystemError::InputDataEmpty)) + } } #[trace_resources(log=data.len())] From 24385f66640978687d8a0fdcd8dd0f77c91d08cc Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Fri, 5 Jan 2024 15:46:05 +0100 Subject: [PATCH 65/82] Tests for empty input --- .../tests/system/crypto_utils.rs | 238 +++++++++++++----- 1 file changed, 172 insertions(+), 66 deletions(-) diff --git a/radix-engine-tests/tests/system/crypto_utils.rs b/radix-engine-tests/tests/system/crypto_utils.rs index 5ba6b710991..9d1b36e1c3d 100644 --- a/radix-engine-tests/tests/system/crypto_utils.rs +++ b/radix-engine-tests/tests/system/crypto_utils.rs @@ -1,3 +1,4 @@ +use radix_engine::transaction::TransactionReceiptV1; use radix_engine::types::*; use radix_engine::vm::NoExtension; use radix_engine_stores::memory_db::InMemorySubstateDatabase; @@ -5,6 +6,24 @@ use radix_engine_tests::common::*; use scrypto_unit::*; use transaction::builder::ManifestBuilder; +macro_rules! get_output { + ($func:ident($($args:tt)*)) => { + $func($($args)*) + .expect_commit_success() + .output(1) + }; +} + +macro_rules! get_failure { + ($func:ident($($args:tt)*)) => { + $func($($args)*) + .expect_commit_failure() + .outcome + .expect_failure() + .to_string() + }; +} + #[cfg(test)] fn crypto_scrypto_bls12381_v1_verify( runner: &mut TestRunner, @@ -12,8 +31,8 @@ fn crypto_scrypto_bls12381_v1_verify( msg: Vec, pub_key: Bls12381G1PublicKey, signature: Bls12381G2Signature, -) -> bool { - let receipt = runner.execute_manifest( +) -> TransactionReceiptV1 { + runner.execute_manifest( ManifestBuilder::new() .lock_fee(runner.faucet_component(), 500u32) .call_function( @@ -24,9 +43,7 @@ fn crypto_scrypto_bls12381_v1_verify( ) .build(), vec![], - ); - let result = receipt.expect_commit_success(); - result.output(1) + ) } #[cfg(test)] @@ -36,8 +53,8 @@ fn crypto_scrypto_bls12381_v1_aggregate_verify( msgs: Vec>, pub_keys: Vec, signature: Bls12381G2Signature, -) -> bool { - let receipt = runner.execute_manifest( +) -> TransactionReceiptV1 { + runner.execute_manifest( ManifestBuilder::new() .lock_fee(runner.faucet_component(), 500u32) .call_function( @@ -48,9 +65,7 @@ fn crypto_scrypto_bls12381_v1_aggregate_verify( ) .build(), vec![], - ); - let result = receipt.expect_commit_success(); - result.output(1) + ) } #[cfg(test)] @@ -60,8 +75,8 @@ fn crypto_scrypto_bls12381_v1_fast_aggregate_verify( msg: Vec, pub_keys: Vec, signature: Bls12381G2Signature, -) -> bool { - let receipt = runner.execute_manifest( +) -> TransactionReceiptV1 { + runner.execute_manifest( ManifestBuilder::new() .lock_fee(runner.faucet_component(), 500u32) .call_function( @@ -72,9 +87,7 @@ fn crypto_scrypto_bls12381_v1_fast_aggregate_verify( ) .build(), vec![], - ); - let result = receipt.expect_commit_success(); - result.output(1) + ) } #[cfg(test)] @@ -82,8 +95,8 @@ fn crypto_scrypto_bls12381_g2_signature_aggregate( runner: &mut TestRunner, package_address: PackageAddress, signatures: Vec, -) -> Bls12381G2Signature { - let receipt = runner.execute_manifest( +) -> TransactionReceiptV1 { + runner.execute_manifest( ManifestBuilder::new() .lock_fee(runner.faucet_component(), 500u32) .call_function( @@ -94,9 +107,7 @@ fn crypto_scrypto_bls12381_g2_signature_aggregate( ) .build(), vec![], - ); - let result = receipt.expect_commit_success(); - result.output(1) + ) } #[cfg(test)] @@ -104,8 +115,8 @@ fn crypto_scrypto_keccak256_hash( runner: &mut TestRunner, package_address: PackageAddress, data: Vec, -) -> Hash { - let receipt = runner.execute_manifest( +) -> TransactionReceiptV1 { + runner.execute_manifest( ManifestBuilder::new() .lock_fee(runner.faucet_component(), 500u32) .call_function( @@ -116,9 +127,7 @@ fn crypto_scrypto_keccak256_hash( ) .build(), vec![], - ); - let result = receipt.expect_commit_success(); - result.output(1) + ) } #[test] @@ -136,26 +145,68 @@ fn test_crypto_scrypto_verify_bls12381_v1() { let pk = Bls12381G1PublicKey::from_str(pk).unwrap(); let msg1_signature = Bls12381G2Signature::from_str(msg1_signature).unwrap(); // Act - let msg1_verify = crypto_scrypto_bls12381_v1_verify( + let msg1_verify: bool = get_output!(crypto_scrypto_bls12381_v1_verify( &mut test_runner, package_address, msg1, pk, msg1_signature, - ); - let msg2_verify = crypto_scrypto_bls12381_v1_verify( + )); + let msg2_verify: bool = get_output!(crypto_scrypto_bls12381_v1_verify( &mut test_runner, package_address, msg2, pk, msg1_signature, - ); + )); // Assert assert!(msg1_verify); assert!(!msg2_verify); } +#[test] +fn test_crypto_scrypto_bls12381_g2_signature_aggregate() { + // Arrange + let mut test_runner = TestRunnerBuilder::new().build(); + + let package_address = test_runner.publish_package_simple(PackageLoader::get("crypto_scrypto")); + + let sks: Vec = (1..11) + .map(|i| Bls12381G1PrivateKey::from_u64(i).unwrap()) + .collect(); + + // Multiple messages + let msgs: Vec> = (1u8..11).map(|i| vec![i; 10]).collect(); + + let sigs: Vec = sks + .iter() + .zip(msgs.clone()) + .map(|(sk, msg)| sk.sign_v1(&msg)) + .collect(); + + // Aggregate the signature + let agg_sig_multiple_msgs = Bls12381G2Signature::aggregate(&sigs).unwrap(); + + // Act + let agg_sig_from_scrypto = + crypto_scrypto_bls12381_g2_signature_aggregate(&mut test_runner, package_address, sigs) + .expect_commit_success() + .output(1); + + // Attempt to aggregate signature from empty input + let error_message = + crypto_scrypto_bls12381_g2_signature_aggregate(&mut test_runner, package_address, vec![]) + .expect_commit_failure() + .outcome + .expect_failure() + .to_string(); + + // Assert + assert_eq!(agg_sig_multiple_msgs, agg_sig_from_scrypto); + assert!(error_message.contains("InputDataEmpty")); +} + #[test] fn test_crypto_scrypto_bls12381_aggregate_verify() { // Arrange @@ -183,31 +234,54 @@ fn test_crypto_scrypto_bls12381_aggregate_verify() { // Act let agg_sig_from_scrypto = - crypto_scrypto_bls12381_g2_signature_aggregate(&mut test_runner, package_address, sigs); - let agg_verify = crypto_scrypto_bls12381_v1_aggregate_verify( + crypto_scrypto_bls12381_g2_signature_aggregate(&mut test_runner, package_address, sigs) + .expect_commit_success() + .output(1); + + let agg_verify: bool = get_output!(crypto_scrypto_bls12381_v1_aggregate_verify( &mut test_runner, package_address, msgs.clone(), pks.clone(), agg_sig_multiple_msgs, - ); + )); let mut pks_rev = pks.clone(); pks_rev.reverse(); // Attempt to verify with reversed public keys order - let agg_verify_expect_false = crypto_scrypto_bls12381_v1_aggregate_verify( + let agg_verify_expect_false: bool = get_output!(crypto_scrypto_bls12381_v1_aggregate_verify( &mut test_runner, package_address, - msgs, + msgs.clone(), pks_rev, agg_sig_multiple_msgs, - ); + )); + + // Attempt to verify signature of empty message vector + let empty_message_error = get_failure!(crypto_scrypto_bls12381_v1_aggregate_verify( + &mut test_runner, + package_address, + vec![], + pks, + agg_sig_multiple_msgs, + )); + + // Attempt to verify signature using empty keys vector + let empty_keys_error = get_failure!(crypto_scrypto_bls12381_v1_aggregate_verify( + &mut test_runner, + package_address, + msgs, + vec![], + agg_sig_multiple_msgs, + )); // Assert assert_eq!(agg_sig_multiple_msgs, agg_sig_from_scrypto); assert!(agg_verify); assert!(!agg_verify_expect_false); + assert!(empty_message_error.contains("InputDataEmpty")); + assert!(empty_keys_error.contains("InputDataEmpty")); } #[test] @@ -232,31 +306,44 @@ fn test_crypto_scrypto_bls12381_fast_aggregate_verify() { let agg_sig_single_msg = Bls12381G2Signature::aggregate(&sigs).unwrap(); // Act - let agg_sig_from_scrypto = - crypto_scrypto_bls12381_g2_signature_aggregate(&mut test_runner, package_address, sigs); - let agg_verify = crypto_scrypto_bls12381_v1_fast_aggregate_verify( + let agg_sig_from_scrypto: Bls12381G2Signature = get_output!( + crypto_scrypto_bls12381_g2_signature_aggregate(&mut test_runner, package_address, sigs) + ); + + let agg_verify: bool = get_output!(crypto_scrypto_bls12381_v1_fast_aggregate_verify( &mut test_runner, package_address, - msg, + msg.clone(), pks.clone(), agg_sig_single_msg, - ); + )); let msg_false = b"Some other message".to_vec(); // Attempt to verify non-matching signature - let agg_verify_expect_false = crypto_scrypto_bls12381_v1_fast_aggregate_verify( + let agg_verify_expect_false: bool = + get_output!(crypto_scrypto_bls12381_v1_fast_aggregate_verify( + &mut test_runner, + package_address, + msg_false, + pks, + agg_sig_single_msg, + )); + + // Attempt to verify signature using empty keys vector + let empty_keys_error = get_failure!(crypto_scrypto_bls12381_v1_fast_aggregate_verify( &mut test_runner, package_address, - msg_false, - pks, + msg, + vec![], agg_sig_single_msg, - ); + )); // Assert assert_eq!(agg_sig_single_msg, agg_sig_from_scrypto); assert!(agg_verify); assert!(!agg_verify_expect_false); + assert!(empty_keys_error.contains("InputDataEmpty")); } #[test] @@ -268,10 +355,24 @@ fn test_crypto_scrypto_keccak256_hash() { let data1 = b"Hello Radix".to_vec(); let data2 = b"xidaR olleH".to_vec(); + let data3: Vec = vec![]; // empty data // Act - let data1_hash = crypto_scrypto_keccak256_hash(&mut test_runner, package_address, data1); - let data2_hash = crypto_scrypto_keccak256_hash(&mut test_runner, package_address, data2); + let data1_hash: Hash = get_output!(crypto_scrypto_keccak256_hash( + &mut test_runner, + package_address, + data1 + )); + let data2_hash: Hash = get_output!(crypto_scrypto_keccak256_hash( + &mut test_runner, + package_address, + data2 + )); + let data3_hash: Hash = get_output!(crypto_scrypto_keccak256_hash( + &mut test_runner, + package_address, + data3 + )); // Assert assert_eq!( @@ -282,6 +383,10 @@ fn test_crypto_scrypto_keccak256_hash() { data2_hash, Hash::from_str("415942230ddb029416a4612818536de230d827cbac9646a0b26d9855a4c45587").unwrap() ); + assert_eq!( + data3_hash, + Hash::from_str("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").unwrap() + ); } #[test] @@ -295,9 +400,16 @@ fn test_crypto_scrypto_flow() { // Act // Get the hash of the message using CryptoScrypto package - let msg_hash = crypto_scrypto_keccak256_hash(&mut test_runner, package_address, msg) - .as_bytes() - .to_vec(); + let msg_hash: Vec = { + let hash: Hash = get_output!(crypto_scrypto_keccak256_hash( + &mut test_runner, + package_address, + msg + )); + hash + } + .as_bytes() + .to_vec(); let secret_key = Bls12381G1PrivateKey::from_u64(1).unwrap(); let public_key = secret_key.public_key(); @@ -306,13 +418,13 @@ fn test_crypto_scrypto_flow() { let msg_signature = secret_key.sign_v1(msg_hash.as_slice()); // Verify the BLS signature using CryptoScrypto package - let result = crypto_scrypto_bls12381_v1_verify( + let result: bool = get_output!(crypto_scrypto_bls12381_v1_verify( &mut test_runner, package_address, msg_hash, public_key, msg_signature, - ); + )); // Assert assert!(result); @@ -366,19 +478,13 @@ fn test_crypto_scrypto_verify_bls12381_v1_costing() { ] { let data = vec![0u8; size]; let signature = secret_key.sign_v1(data.as_slice()); - let receipt = test_runner.execute_manifest( - ManifestBuilder::new() - .lock_fee(test_runner.faucet_component(), 500u32) - .call_function( - package_address, - "CryptoScrypto", - "bls12381_v1_verify", - manifest_args!(data, public_key, signature), - ) - .build(), - vec![], + let _ = crypto_scrypto_bls12381_v1_verify( + &mut test_runner, + package_address, + data, + public_key, + signature, ); - let _ = receipt.expect_commit_success(); } } @@ -399,7 +505,7 @@ fn test_crypto_scrypto_bls12381_g2_signature_aggregate_costing() { let sigs: Vec = sks.iter().map(|sk| sk.sign_v1(&msg)).collect(); // Act - let _agg_sig_from_scrypto = + let _ = crypto_scrypto_bls12381_g2_signature_aggregate(&mut test_runner, package_address, sigs); } } @@ -429,7 +535,7 @@ fn test_crypto_scrypto_bls12381_v1_aggregate_verify_costing() { let agg_sig_multiple_msgs = Bls12381G2Signature::aggregate(&sigs).unwrap(); - let _agg_verify = crypto_scrypto_bls12381_v1_aggregate_verify( + let _ = crypto_scrypto_bls12381_v1_aggregate_verify( &mut test_runner, package_address, msgs, @@ -461,7 +567,7 @@ fn test_crypto_scrypto_bls12381_v1_fast_aggregate_verify_costing() { let agg_sig_single_msg = Bls12381G2Signature::aggregate(&sigs).unwrap(); - let _agg_verify = crypto_scrypto_bls12381_v1_fast_aggregate_verify( + let _ = crypto_scrypto_bls12381_v1_fast_aggregate_verify( &mut test_runner, package_address, msg, From 1c7f32e0034cd4d090e5f98d0ce7256c962b60e7 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Tue, 9 Jan 2024 12:42:19 +0100 Subject: [PATCH 66/82] Minor improvements in crypto_utils tests --- .../tests/system/crypto_utils.rs | 69 ++++++++++++------- 1 file changed, 45 insertions(+), 24 deletions(-) diff --git a/radix-engine-tests/tests/system/crypto_utils.rs b/radix-engine-tests/tests/system/crypto_utils.rs index 9d1b36e1c3d..3c69798d41a 100644 --- a/radix-engine-tests/tests/system/crypto_utils.rs +++ b/radix-engine-tests/tests/system/crypto_utils.rs @@ -24,7 +24,6 @@ macro_rules! get_failure { }; } -#[cfg(test)] fn crypto_scrypto_bls12381_v1_verify( runner: &mut TestRunner, package_address: PackageAddress, @@ -46,7 +45,6 @@ fn crypto_scrypto_bls12381_v1_verify( ) } -#[cfg(test)] fn crypto_scrypto_bls12381_v1_aggregate_verify( runner: &mut TestRunner, package_address: PackageAddress, @@ -68,7 +66,6 @@ fn crypto_scrypto_bls12381_v1_aggregate_verify( ) } -#[cfg(test)] fn crypto_scrypto_bls12381_v1_fast_aggregate_verify( runner: &mut TestRunner, package_address: PackageAddress, @@ -90,7 +87,6 @@ fn crypto_scrypto_bls12381_v1_fast_aggregate_verify( ) } -#[cfg(test)] fn crypto_scrypto_bls12381_g2_signature_aggregate( runner: &mut TestRunner, package_address: PackageAddress, @@ -110,7 +106,6 @@ fn crypto_scrypto_bls12381_g2_signature_aggregate( ) } -#[cfg(test)] fn crypto_scrypto_keccak256_hash( runner: &mut TestRunner, package_address: PackageAddress, @@ -138,7 +133,6 @@ fn test_crypto_scrypto_verify_bls12381_v1() { let package_address = test_runner.publish_package_simple(PackageLoader::get("crypto_scrypto")); let msg1 = hash("Test").to_vec(); - let msg2 = hash("ExpectFailureTest").to_vec(); let pk = "93b1aa7542a5423e21d8e84b4472c31664412cc604a666e9fdf03baf3c758e728c7a11576ebb01110ac39a0df95636e2"; let msg1_signature = "8b84ff5a1d4f8095ab8a80518ac99230ed24a7d1ec90c4105f9c719aa7137ed5d7ce1454d4a953f5f55f3959ab416f3014f4cd2c361e4d32c6b4704a70b0e2e652a908f501acb54ec4e79540be010e3fdc1fbf8e7af61625705e185a71c884f1"; @@ -152,6 +146,14 @@ fn test_crypto_scrypto_verify_bls12381_v1() { pk, msg1_signature, )); + + // Assert + assert!(msg1_verify); + + // Arrange + let msg2 = hash("ExpectFailureTest").to_vec(); + + // Act let msg2_verify: bool = get_output!(crypto_scrypto_bls12381_v1_verify( &mut test_runner, package_address, @@ -161,7 +163,6 @@ fn test_crypto_scrypto_verify_bls12381_v1() { )); // Assert - assert!(msg1_verify); assert!(!msg2_verify); } @@ -233,11 +234,16 @@ fn test_crypto_scrypto_bls12381_aggregate_verify() { let agg_sig_multiple_msgs = Bls12381G2Signature::aggregate(&sigs).unwrap(); // Act - let agg_sig_from_scrypto = - crypto_scrypto_bls12381_g2_signature_aggregate(&mut test_runner, package_address, sigs) - .expect_commit_success() - .output(1); + let agg_sig_from_scrypto = get_output!(crypto_scrypto_bls12381_g2_signature_aggregate( + &mut test_runner, + package_address, + sigs + )); + + // Assert + assert_eq!(agg_sig_multiple_msgs, agg_sig_from_scrypto); + // Act let agg_verify: bool = get_output!(crypto_scrypto_bls12381_v1_aggregate_verify( &mut test_runner, package_address, @@ -246,9 +252,14 @@ fn test_crypto_scrypto_bls12381_aggregate_verify() { agg_sig_multiple_msgs, )); + // Assert + assert!(agg_verify); + + // Arrange let mut pks_rev = pks.clone(); pks_rev.reverse(); + // Act // Attempt to verify with reversed public keys order let agg_verify_expect_false: bool = get_output!(crypto_scrypto_bls12381_v1_aggregate_verify( &mut test_runner, @@ -277,8 +288,6 @@ fn test_crypto_scrypto_bls12381_aggregate_verify() { )); // Assert - assert_eq!(agg_sig_multiple_msgs, agg_sig_from_scrypto); - assert!(agg_verify); assert!(!agg_verify_expect_false); assert!(empty_message_error.contains("InputDataEmpty")); assert!(empty_keys_error.contains("InputDataEmpty")); @@ -310,6 +319,10 @@ fn test_crypto_scrypto_bls12381_fast_aggregate_verify() { crypto_scrypto_bls12381_g2_signature_aggregate(&mut test_runner, package_address, sigs) ); + // Assert + assert_eq!(agg_sig_single_msg, agg_sig_from_scrypto); + + // Act let agg_verify: bool = get_output!(crypto_scrypto_bls12381_v1_fast_aggregate_verify( &mut test_runner, package_address, @@ -318,8 +331,13 @@ fn test_crypto_scrypto_bls12381_fast_aggregate_verify() { agg_sig_single_msg, )); + // Assert + assert!(agg_verify); + + // Arrange let msg_false = b"Some other message".to_vec(); + // Act // Attempt to verify non-matching signature let agg_verify_expect_false: bool = get_output!(crypto_scrypto_bls12381_v1_fast_aggregate_verify( @@ -340,8 +358,6 @@ fn test_crypto_scrypto_bls12381_fast_aggregate_verify() { )); // Assert - assert_eq!(agg_sig_single_msg, agg_sig_from_scrypto); - assert!(agg_verify); assert!(!agg_verify_expect_false); assert!(empty_keys_error.contains("InputDataEmpty")); } @@ -363,26 +379,31 @@ fn test_crypto_scrypto_keccak256_hash() { package_address, data1 )); + // Assert + assert_eq!( + data1_hash, + Hash::from_str("415942230ddb029416a4612818536de230d827cbac9646a0b26d9855a4c45587").unwrap() + ); + + // Act let data2_hash: Hash = get_output!(crypto_scrypto_keccak256_hash( &mut test_runner, package_address, data2 )); + // Assert + assert_ne!( + data2_hash, + Hash::from_str("415942230ddb029416a4612818536de230d827cbac9646a0b26d9855a4c45587").unwrap() + ); + + // Act let data3_hash: Hash = get_output!(crypto_scrypto_keccak256_hash( &mut test_runner, package_address, data3 )); - // Assert - assert_eq!( - data1_hash, - Hash::from_str("415942230ddb029416a4612818536de230d827cbac9646a0b26d9855a4c45587").unwrap() - ); - assert_ne!( - data2_hash, - Hash::from_str("415942230ddb029416a4612818536de230d827cbac9646a0b26d9855a4c45587").unwrap() - ); assert_eq!( data3_hash, Hash::from_str("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").unwrap() From 8590fd36683de1012699fe9a43b0cdc7d0bde733 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Tue, 9 Jan 2024 12:43:10 +0100 Subject: [PATCH 67/82] Remove unused import --- .../src/api/system_modules/crypto_utils_api.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs b/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs index 30b2ebae641..908030a12a1 100644 --- a/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs +++ b/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs @@ -1,4 +1,3 @@ -use crate::crypto::*; use crate::internal_prelude::*; pub trait ClientCryptoUtilsApi { From 2bd981891a104f536b2b01e585c18f02c43c6bbc Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Wed, 10 Jan 2024 11:12:15 +0100 Subject: [PATCH 68/82] Refactor BLS aggregate verify API This is to make sure public key count matches message count. Take vector of tuples (public key and message) as argument. --- .../src/crypto/bls12381/private_key.rs | 5 ++-- .../src/crypto/signature_validator.rs | 9 ++++--- .../api/system_modules/crypto_utils_api.rs | 3 +-- .../blueprints/crypto_scrypto/src/lib.rs | 5 ++-- .../tests/system/crypto_utils.rs | 8 +++++- radix-engine/src/system/system.rs | 17 +++++++----- radix-engine/src/vm/wasm/errors.rs | 2 +- radix-engine/src/vm/wasm/prepare.rs | 9 +------ radix-engine/src/vm/wasm/traits.rs | 3 +-- radix-engine/src/vm/wasm/wasmi.rs | 27 +++++++------------ .../src/vm/wasm_runtime/no_op_runtime.rs | 3 +-- .../src/vm/wasm_runtime/scrypto_runtime.rs | 20 +++----------- scrypto-test/src/environment/client_api.rs | 2 +- scrypto/src/crypto_utils/crypto_utils.rs | 11 +++----- scrypto/src/engine/wasm_api.rs | 6 ++--- 15 files changed, 53 insertions(+), 77 deletions(-) diff --git a/radix-engine-common/src/crypto/bls12381/private_key.rs b/radix-engine-common/src/crypto/bls12381/private_key.rs index 0e81e114ee5..f1c9cb07c48 100644 --- a/radix-engine-common/src/crypto/bls12381/private_key.rs +++ b/radix-engine-common/src/crypto/bls12381/private_key.rs @@ -100,10 +100,11 @@ mod tests { // Aggregate the signature let agg_sig = Bls12381G2Signature::aggregate(&sigs).unwrap(); - let msgs_ref: Vec<&[u8]> = msgs.iter().map(|m| m.as_slice()).collect(); + let pub_keys_msgs: Vec<(Bls12381G1PublicKey, Vec)> = + pks.iter().zip(msgs).map(|(pk, sk)| (*pk, sk)).collect(); // Verify the messages against public keys and aggregated signature - assert!(aggregate_verify_bls12381_v1(&msgs_ref, &pks, &agg_sig)) + assert!(aggregate_verify_bls12381_v1(&pub_keys_msgs, &agg_sig)) } #[test] diff --git a/radix-engine-common/src/crypto/signature_validator.rs b/radix-engine-common/src/crypto/signature_validator.rs index 47a8416a929..cd679887113 100644 --- a/radix-engine-common/src/crypto/signature_validator.rs +++ b/radix-engine-common/src/crypto/signature_validator.rs @@ -79,22 +79,23 @@ pub fn verify_bls12381_v1( /// multiple messages each signed with different key. /// Domain specifier tag: BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_ pub fn aggregate_verify_bls12381_v1( - messages: &[&[u8]], - public_keys: &[Bls12381G1PublicKey], + pub_keys_and_msgs: &[(Bls12381G1PublicKey, Vec)], signature: &Bls12381G2Signature, ) -> bool { if let Ok(sig) = blst::min_pk::Signature::from_bytes(&signature.0) { let mut pks = vec![]; - for pk in public_keys { + let mut msg_refs = vec![]; + for (pk, msg) in pub_keys_and_msgs.iter() { if let Ok(pk) = blst::min_pk::PublicKey::from_bytes(&pk.0) { pks.push(pk); } else { return false; } + msg_refs.push(msg.as_slice()); } let pks_refs: Vec<&blst::min_pk::PublicKey> = pks.iter().collect(); - let result = sig.aggregate_verify(true, messages, BLS12381_CIPHERSITE_V1, &pks_refs, true); + let result = sig.aggregate_verify(true, &msg_refs, BLS12381_CIPHERSITE_V1, &pks_refs, true); match result { blst::BLST_ERROR::BLST_SUCCESS => return true, diff --git a/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs b/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs index 908030a12a1..74a195996f1 100644 --- a/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs +++ b/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs @@ -10,8 +10,7 @@ pub trait ClientCryptoUtilsApi { fn bls12381_v1_aggregate_verify( &mut self, - messages: &[&[u8]], - public_keys: &[Bls12381G1PublicKey], + pub_keys_and_msgs: &[(Bls12381G1PublicKey, Vec)], signature: &Bls12381G2Signature, ) -> Result; diff --git a/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs b/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs index ef70670f5bb..8e873b5366a 100644 --- a/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs +++ b/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs @@ -14,11 +14,10 @@ mod component_module { } pub fn bls12381_v1_aggregate_verify( - messages: Vec>, - pub_keys: Vec, + pub_keys_msgs: Vec<(Bls12381G1PublicKey, Vec)>, signature: Bls12381G2Signature, ) -> bool { - CryptoUtils::bls12381_v1_aggregate_verify(messages, pub_keys, signature) + CryptoUtils::bls12381_v1_aggregate_verify(pub_keys_msgs, signature) } pub fn bls12381_v1_fast_aggregate_verify( diff --git a/radix-engine-tests/tests/system/crypto_utils.rs b/radix-engine-tests/tests/system/crypto_utils.rs index 3c69798d41a..e57cbeb6d21 100644 --- a/radix-engine-tests/tests/system/crypto_utils.rs +++ b/radix-engine-tests/tests/system/crypto_utils.rs @@ -52,6 +52,12 @@ fn crypto_scrypto_bls12381_v1_aggregate_verify( pub_keys: Vec, signature: Bls12381G2Signature, ) -> TransactionReceiptV1 { + let pub_keys_msgs: Vec<(Bls12381G1PublicKey, Vec)> = pub_keys + .iter() + .zip(msgs) + .map(|(pk, sk)| (*pk, sk)) + .collect(); + runner.execute_manifest( ManifestBuilder::new() .lock_fee(runner.faucet_component(), 500u32) @@ -59,7 +65,7 @@ fn crypto_scrypto_bls12381_v1_aggregate_verify( package_address, "CryptoScrypto", "bls12381_v1_aggregate_verify", - manifest_args!(msgs, pub_keys, signature), + manifest_args!(pub_keys_msgs, signature), ) .build(), vec![], diff --git a/radix-engine/src/system/system.rs b/radix-engine/src/system/system.rs index fd0a049209c..fedbfc21c72 100644 --- a/radix-engine/src/system/system.rs +++ b/radix-engine/src/system/system.rs @@ -2874,21 +2874,24 @@ where } // Trace average message length and number of public_keys - #[trace_resources(log={messages.iter().map(|m| m.len()).sum::()/messages.len()},log=public_keys.len())] + #[trace_resources(log={pub_keys_and_msgs.iter().map(|(_, msg)| msg.len()).sum::()/pub_keys_and_msgs.len()},log=pub_keys_and_msgs.len())] fn bls12381_v1_aggregate_verify( &mut self, - messages: &[&[u8]], - public_keys: &[Bls12381G1PublicKey], + pub_keys_and_msgs: &[(Bls12381G1PublicKey, Vec)], signature: &Bls12381G2Signature, ) -> Result { - if !messages.is_empty() && !public_keys.is_empty() { + if !pub_keys_and_msgs.is_empty() { self.api.kernel_get_system().modules.apply_execution_cost( ExecutionCostingEntry::Bls12381V1AggregateVerify { - size: messages.iter().map(|m| m.len()).sum::() / messages.len(), - keys_cnt: public_keys.len(), + size: pub_keys_and_msgs + .iter() + .map(|(_, msg)| msg.len()) + .sum::() + / pub_keys_and_msgs.len(), + keys_cnt: pub_keys_and_msgs.len(), }, )?; - Ok(aggregate_verify_bls12381_v1(messages, public_keys, signature) as u32) + Ok(aggregate_verify_bls12381_v1(pub_keys_and_msgs, signature) as u32) } else { Err(RuntimeError::SystemError(SystemError::InputDataEmpty)) } diff --git a/radix-engine/src/vm/wasm/errors.rs b/radix-engine/src/vm/wasm/errors.rs index 8214014e5f1..e404857a6ab 100644 --- a/radix-engine/src/vm/wasm/errors.rs +++ b/radix-engine/src/vm/wasm/errors.rs @@ -156,7 +156,7 @@ pub enum WasmRuntimeError { InvalidBlsPublicKey(ParseBlsPublicKeyError), InvalidBlsSignature(ParseBlsSignatureError), - InvalidBlsMessage(DecodeError), + InvalidBlsInput(DecodeError), } impl SelfError for WasmRuntimeError { diff --git a/radix-engine/src/vm/wasm/prepare.rs b/radix-engine/src/vm/wasm/prepare.rs index 5285bcfa539..43d3014b363 100644 --- a/radix-engine/src/vm/wasm/prepare.rs +++ b/radix-engine/src/vm/wasm/prepare.rs @@ -760,14 +760,7 @@ impl WasmModule { if Self::function_type_matches( &self.module, type_index, - vec![ - ValType::I32, - ValType::I32, - ValType::I32, - ValType::I32, - ValType::I32, - ValType::I32, - ], + vec![ValType::I32, ValType::I32, ValType::I32, ValType::I32], vec![ValType::I32], ) { continue; diff --git a/radix-engine/src/vm/wasm/traits.rs b/radix-engine/src/vm/wasm/traits.rs index 0653004f2b0..9c887f90c18 100644 --- a/radix-engine/src/vm/wasm/traits.rs +++ b/radix-engine/src/vm/wasm/traits.rs @@ -210,8 +210,7 @@ pub trait WasmRuntime { fn crypto_utils_bls12381_v1_aggregate_verify( &mut self, - messages: Vec, - public_keys: Vec, + pub_keys_and_msgs: Vec, signatures: Vec, ) -> Result>; diff --git a/radix-engine/src/vm/wasm/wasmi.rs b/radix-engine/src/vm/wasm/wasmi.rs index 465461dfec2..4cfad067dba 100644 --- a/radix-engine/src/vm/wasm/wasmi.rs +++ b/radix-engine/src/vm/wasm/wasmi.rs @@ -693,21 +693,18 @@ fn bls12381_v1_verify( fn bls12381_v1_aggregate_verify( mut caller: Caller<'_, HostState>, - messages_ptr: u32, - messages_len: u32, - public_keys_ptr: u32, - public_keys_len: u32, + pub_keys_and_msgs_ptr: u32, + pub_keys_and_msgs_len: u32, signature_ptr: u32, signature_len: u32, ) -> Result> { let (memory, runtime) = grab_runtime!(caller); - let messages = read_memory(caller.as_context_mut(), memory, messages_ptr, messages_len)?; - let public_keys = read_memory( + let pub_keys_and_msgs = read_memory( caller.as_context_mut(), memory, - public_keys_ptr, - public_keys_len, + pub_keys_and_msgs_ptr, + pub_keys_and_msgs_len, )?; let signature = read_memory( caller.as_context_mut(), @@ -716,7 +713,7 @@ fn bls12381_v1_aggregate_verify( signature_len, )?; - runtime.crypto_utils_bls12381_v1_aggregate_verify(messages, public_keys, signature) + runtime.crypto_utils_bls12381_v1_aggregate_verify(pub_keys_and_msgs, signature) } fn bls12381_v1_fast_aggregate_verify( @@ -1369,19 +1366,15 @@ impl WasmiModule { let host_bls12381_v1_aggregate_verify = Func::wrap( store.as_context_mut(), |caller: Caller<'_, HostState>, - messages_ptr: u32, - messages_len: u32, - public_keys_ptr: u32, - public_keys_len: u32, + pub_keys_and_msgs_ptr: u32, + pub_keys_and_msgs_len: u32, signature_ptr: u32, signature_len: u32| -> Result { bls12381_v1_aggregate_verify( caller, - messages_ptr, - messages_len, - public_keys_ptr, - public_keys_len, + pub_keys_and_msgs_ptr, + pub_keys_and_msgs_len, signature_ptr, signature_len, ) diff --git a/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs b/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs index b925ae5bd54..f26a28f8d1b 100644 --- a/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs +++ b/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs @@ -317,8 +317,7 @@ impl<'a> WasmRuntime for NoOpWasmRuntime<'a> { fn crypto_utils_bls12381_v1_aggregate_verify( &mut self, - messages: Vec, - public_keys: Vec, + pub_keys_and_msgs: Vec, signature: Vec, ) -> Result> { Err(InvokeError::SelfError(WasmRuntimeError::NotImplemented)) diff --git a/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs b/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs index 26a6704fc54..b3d2d2e3ae0 100644 --- a/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs +++ b/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs @@ -579,30 +579,18 @@ where fn crypto_utils_bls12381_v1_aggregate_verify( &mut self, - messages: Vec, - public_keys: Vec, + pub_keys_and_msgs: Vec, signature: Vec, ) -> Result> { let signature = Bls12381G2Signature::try_from(signature.as_slice()) .map_err(WasmRuntimeError::InvalidBlsSignature)?; - let pks_cnt = public_keys.len() / Bls12381G1PublicKey::LENGTH; - let mut pks_vec = vec![]; - - for i in 0..pks_cnt { - let idx = i * Bls12381G1PublicKey::LENGTH; - let pk = - Bls12381G1PublicKey::try_from(&public_keys[idx..idx + Bls12381G1PublicKey::LENGTH]) - .map_err(WasmRuntimeError::InvalidBlsPublicKey)?; - pks_vec.push(pk); - } - let messages: Vec> = - scrypto_decode(&messages).map_err(WasmRuntimeError::InvalidBlsMessage)?; - let msgs_ref: Vec<&[u8]> = messages.iter().map(|msg| msg.as_slice()).collect(); + let pub_keys_and_msgs: Vec<(Bls12381G1PublicKey, Vec)> = + scrypto_decode(&pub_keys_and_msgs).map_err(WasmRuntimeError::InvalidBlsInput)?; let result = self .api - .bls12381_v1_aggregate_verify(&msgs_ref, &pks_vec, &signature)?; + .bls12381_v1_aggregate_verify(&pub_keys_and_msgs, &signature)?; Ok(result) } diff --git a/scrypto-test/src/environment/client_api.rs b/scrypto-test/src/environment/client_api.rs index e46d8b27aab..c760cff248f 100644 --- a/scrypto-test/src/environment/client_api.rs +++ b/scrypto-test/src/environment/client_api.rs @@ -277,7 +277,7 @@ implement_client_api! { }, ClientCryptoUtilsApi: { bls12381_v1_verify: (&mut self, message: &[u8], public_key: &Bls12381G1PublicKey, signature: &Bls12381G2Signature) -> Result, - bls12381_v1_aggregate_verify: (&mut self, messages: &[&[u8]], public_keys: &[Bls12381G1PublicKey], signature: &Bls12381G2Signature) -> Result, + bls12381_v1_aggregate_verify: (&mut self, pub_keys_and_msgs: &[(Bls12381G1PublicKey, Vec)], signature: &Bls12381G2Signature) -> Result, bls12381_v1_fast_aggregate_verify: (&mut self, message: &[u8], public_keys: &[Bls12381G1PublicKey], signature: &Bls12381G2Signature) -> Result, bls12381_g2_signature_aggregate: (&mut self, signatures: &[Bls12381G2Signature]) -> Result, keccak256_hash: (&mut self, data: &[u8]) -> Result, diff --git a/scrypto/src/crypto_utils/crypto_utils.rs b/scrypto/src/crypto_utils/crypto_utils.rs index 400d86153d4..014a0ec2347 100644 --- a/scrypto/src/crypto_utils/crypto_utils.rs +++ b/scrypto/src/crypto_utils/crypto_utils.rs @@ -32,17 +32,14 @@ impl CryptoUtils { /// multiple messages each signed with different key. /// Domain specifier tag: BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_ pub fn bls12381_v1_aggregate_verify( - messages: Vec>, - public_keys: Vec, + pub_keys_and_msgs: Vec<(Bls12381G1PublicKey, Vec)>, signature: Bls12381G2Signature, ) -> bool { - let messages: Vec = scrypto_encode(&messages).unwrap(); + let pub_keys_and_msgs: Vec = scrypto_encode(&pub_keys_and_msgs).unwrap(); unsafe { crypto_utils::crypto_utils_bls12381_v1_aggregate_verify( - messages.as_ptr(), - messages.len(), - public_keys.as_ptr() as *const u8, - public_keys.len() * Bls12381G1PublicKey::LENGTH, + pub_keys_and_msgs.as_ptr(), + pub_keys_and_msgs.len(), signature.0.as_ptr(), signature.0.len(), ) != 0 diff --git a/scrypto/src/engine/wasm_api.rs b/scrypto/src/engine/wasm_api.rs index 70e1240d0e7..fda3b0c7dd2 100644 --- a/scrypto/src/engine/wasm_api.rs +++ b/scrypto/src/engine/wasm_api.rs @@ -298,10 +298,8 @@ pub mod crypto_utils { signature_len: usize) -> u32; pub fn crypto_utils_bls12381_v1_aggregate_verify( - messages_ptr: *const u8, - messages_len: usize, - public_keys_ptr: *const u8, - public_keys_len: usize, + pub_keys_and_msgs_ptr: *const u8, + pub_keys_and_msgs_len: usize, signature_ptr: *const u8, signature_len: usize) -> u32; From 900e73c541e37af722d55511ec7af7e4f8f9a251 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Wed, 10 Jan 2024 13:53:13 +0100 Subject: [PATCH 69/82] Use SBOR for data carried in CryptoUtils API --- radix-engine/src/vm/wasm/errors.rs | 4 +- .../src/vm/wasm_runtime/scrypto_runtime.rs | 53 +++++++------------ scrypto/src/crypto_utils/crypto_utils.rs | 34 +++++++----- 3 files changed, 41 insertions(+), 50 deletions(-) diff --git a/radix-engine/src/vm/wasm/errors.rs b/radix-engine/src/vm/wasm/errors.rs index e404857a6ab..00ebdc6157a 100644 --- a/radix-engine/src/vm/wasm/errors.rs +++ b/radix-engine/src/vm/wasm/errors.rs @@ -154,8 +154,8 @@ pub enum WasmRuntimeError { TooManyBuffers, - InvalidBlsPublicKey(ParseBlsPublicKeyError), - InvalidBlsSignature(ParseBlsSignatureError), + InvalidBlsPublicKey(DecodeError), + InvalidBlsSignature(DecodeError), InvalidBlsInput(DecodeError), } diff --git a/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs b/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs index b3d2d2e3ae0..99c923992dc 100644 --- a/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs +++ b/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs @@ -567,10 +567,10 @@ where public_key: Vec, signature: Vec, ) -> Result> { - let public_key = Bls12381G1PublicKey::try_from(public_key.as_slice()) - .map_err(WasmRuntimeError::InvalidBlsPublicKey)?; - let signature = Bls12381G2Signature::try_from(signature.as_slice()) - .map_err(WasmRuntimeError::InvalidBlsSignature)?; + let public_key: Bls12381G1PublicKey = + scrypto_decode(&public_key).map_err(WasmRuntimeError::InvalidBlsPublicKey)?; + let signature: Bls12381G2Signature = + scrypto_decode(&signature).map_err(WasmRuntimeError::InvalidBlsSignature)?; let result = self .api .bls12381_v1_verify(&message, &public_key, &signature)?; @@ -582,9 +582,8 @@ where pub_keys_and_msgs: Vec, signature: Vec, ) -> Result> { - let signature = Bls12381G2Signature::try_from(signature.as_slice()) - .map_err(WasmRuntimeError::InvalidBlsSignature)?; - + let signature: Bls12381G2Signature = + scrypto_decode(&signature).map_err(WasmRuntimeError::InvalidBlsSignature)?; let pub_keys_and_msgs: Vec<(Bls12381G1PublicKey, Vec)> = scrypto_decode(&pub_keys_and_msgs).map_err(WasmRuntimeError::InvalidBlsInput)?; @@ -600,22 +599,14 @@ where public_keys: Vec, signature: Vec, ) -> Result> { - let signature = Bls12381G2Signature::try_from(signature.as_slice()) - .map_err(WasmRuntimeError::InvalidBlsSignature)?; - let pks_cnt = public_keys.len() / Bls12381G1PublicKey::LENGTH; - let mut pks_vec = vec![]; - - for i in 0..pks_cnt { - let idx = i * Bls12381G1PublicKey::LENGTH; - let pk = - Bls12381G1PublicKey::try_from(&public_keys[idx..idx + Bls12381G1PublicKey::LENGTH]) - .map_err(WasmRuntimeError::InvalidBlsPublicKey)?; - pks_vec.push(pk); - } + let public_keys: Vec = + scrypto_decode(&public_keys).map_err(WasmRuntimeError::InvalidBlsPublicKey)?; + let signature: Bls12381G2Signature = + scrypto_decode(&signature).map_err(WasmRuntimeError::InvalidBlsSignature)?; - let result = self - .api - .bls12381_v1_fast_aggregate_verify(&message, &pks_vec, &signature)?; + let result = + self.api + .bls12381_v1_fast_aggregate_verify(&message, &public_keys, &signature)?; Ok(result) } @@ -623,20 +614,14 @@ where &mut self, signatures: Vec, ) -> Result> { - let sigs_cnt = signatures.len() / Bls12381G2Signature::LENGTH; - let mut sigs_vec = vec![]; - - for i in 0..sigs_cnt { - let idx = i * Bls12381G2Signature::LENGTH; - let sig = - Bls12381G2Signature::try_from(&signatures[idx..idx + Bls12381G2Signature::LENGTH]) - .map_err(WasmRuntimeError::InvalidBlsSignature)?; - sigs_vec.push(sig); - } + let signatures: Vec = + scrypto_decode(&signatures).map_err(WasmRuntimeError::InvalidBlsSignature)?; - let agg_sig = self.api.bls12381_g2_signature_aggregate(&sigs_vec)?; + let agg_sig = self.api.bls12381_g2_signature_aggregate(&signatures)?; - self.allocate_buffer(agg_sig.to_vec()) + self.allocate_buffer( + scrypto_encode(&agg_sig).expect("Failed to encode Bls12381G2Signature"), + ) } fn crypto_utils_keccak256_hash( diff --git a/scrypto/src/crypto_utils/crypto_utils.rs b/scrypto/src/crypto_utils/crypto_utils.rs index 014a0ec2347..2687f1dbe6e 100644 --- a/scrypto/src/crypto_utils/crypto_utils.rs +++ b/scrypto/src/crypto_utils/crypto_utils.rs @@ -1,6 +1,6 @@ use crate::engine::wasm_api::{copy_buffer, crypto_utils}; use radix_engine_common::prelude::{ - scrypto_encode, Bls12381G1PublicKey, Bls12381G2Signature, Hash, + scrypto_decode, scrypto_encode, Bls12381G1PublicKey, Bls12381G2Signature, Hash, }; use sbor::prelude::Vec; @@ -16,14 +16,16 @@ impl CryptoUtils { public_key: Bls12381G1PublicKey, signature: Bls12381G2Signature, ) -> bool { + let public_key: Vec = scrypto_encode(&public_key).unwrap(); + let signature: Vec = scrypto_encode(&signature).unwrap(); unsafe { crypto_utils::crypto_utils_bls12381_v1_verify( message.as_ptr(), message.len(), - public_key.0.as_ptr(), - public_key.0.len(), - signature.0.as_ptr(), - signature.0.len(), + public_key.as_ptr(), + public_key.len(), + signature.as_ptr(), + signature.len(), ) != 0 } } @@ -36,12 +38,13 @@ impl CryptoUtils { signature: Bls12381G2Signature, ) -> bool { let pub_keys_and_msgs: Vec = scrypto_encode(&pub_keys_and_msgs).unwrap(); + let signature: Vec = scrypto_encode(&signature).unwrap(); unsafe { crypto_utils::crypto_utils_bls12381_v1_aggregate_verify( pub_keys_and_msgs.as_ptr(), pub_keys_and_msgs.len(), - signature.0.as_ptr(), - signature.0.len(), + signature.as_ptr(), + signature.len(), ) != 0 } } @@ -54,14 +57,16 @@ impl CryptoUtils { public_keys: Vec, signature: Bls12381G2Signature, ) -> bool { + let public_keys: Vec = scrypto_encode(&public_keys).unwrap(); + let signature: Vec = scrypto_encode(&signature).unwrap(); unsafe { crypto_utils::crypto_utils_bls12381_v1_fast_aggregate_verify( message.as_ptr(), message.len(), - public_keys.as_ptr() as *const u8, - public_keys.len() * Bls12381G1PublicKey::LENGTH, - signature.0.as_ptr(), - signature.0.len(), + public_keys.as_ptr(), + public_keys.len(), + signature.as_ptr(), + signature.len(), ) != 0 } } @@ -70,14 +75,15 @@ impl CryptoUtils { pub fn bls12381_g2_signature_aggregate( signatures: Vec, ) -> Bls12381G2Signature { + let signatures: Vec = scrypto_encode(&signatures).unwrap(); let agg_signature = copy_buffer(unsafe { crypto_utils::crypto_utils_bls12381_g2_signature_aggregate( - signatures.as_ptr() as *const u8, - signatures.len() * Bls12381G2Signature::LENGTH, + signatures.as_ptr(), + signatures.len(), ) }); - Bls12381G2Signature::try_from(agg_signature.as_slice()).unwrap() + scrypto_decode::(&agg_signature).unwrap() } /// Calculates Keccak-256 digest over given vector of bytes From 5cc3fce03f39db0aad074e176935f23bcbfa9839 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Wed, 10 Jan 2024 13:54:23 +0100 Subject: [PATCH 70/82] Rename some error --- radix-engine/src/vm/wasm/errors.rs | 2 +- radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/radix-engine/src/vm/wasm/errors.rs b/radix-engine/src/vm/wasm/errors.rs index 00ebdc6157a..f467c0e02cf 100644 --- a/radix-engine/src/vm/wasm/errors.rs +++ b/radix-engine/src/vm/wasm/errors.rs @@ -156,7 +156,7 @@ pub enum WasmRuntimeError { InvalidBlsPublicKey(DecodeError), InvalidBlsSignature(DecodeError), - InvalidBlsInput(DecodeError), + InvalidBlsPublicKeyOrMessage(DecodeError), } impl SelfError for WasmRuntimeError { diff --git a/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs b/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs index 99c923992dc..45db7867a0a 100644 --- a/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs +++ b/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs @@ -585,7 +585,8 @@ where let signature: Bls12381G2Signature = scrypto_decode(&signature).map_err(WasmRuntimeError::InvalidBlsSignature)?; let pub_keys_and_msgs: Vec<(Bls12381G1PublicKey, Vec)> = - scrypto_decode(&pub_keys_and_msgs).map_err(WasmRuntimeError::InvalidBlsInput)?; + scrypto_decode(&pub_keys_and_msgs) + .map_err(WasmRuntimeError::InvalidBlsPublicKeyOrMessage)?; let result = self .api From fbfc02d3a17f94ec7a294936cce2e28f258d6fed Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Wed, 10 Jan 2024 14:23:29 +0100 Subject: [PATCH 71/82] Tweak costing for aggregate verify --- radix-engine/src/system/system.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/radix-engine/src/system/system.rs b/radix-engine/src/system/system.rs index fedbfc21c72..505e789eb3e 100644 --- a/radix-engine/src/system/system.rs +++ b/radix-engine/src/system/system.rs @@ -2874,7 +2874,7 @@ where } // Trace average message length and number of public_keys - #[trace_resources(log={pub_keys_and_msgs.iter().map(|(_, msg)| msg.len()).sum::()/pub_keys_and_msgs.len()},log=pub_keys_and_msgs.len())] + #[trace_resources(log={pub_keys_and_msgs.iter().flat_map(|(_, msg)| msg).count()/pub_keys_and_msgs.len()},log=pub_keys_and_msgs.len())] fn bls12381_v1_aggregate_verify( &mut self, pub_keys_and_msgs: &[(Bls12381G1PublicKey, Vec)], @@ -2883,10 +2883,7 @@ where if !pub_keys_and_msgs.is_empty() { self.api.kernel_get_system().modules.apply_execution_cost( ExecutionCostingEntry::Bls12381V1AggregateVerify { - size: pub_keys_and_msgs - .iter() - .map(|(_, msg)| msg.len()) - .sum::() + size: pub_keys_and_msgs.iter().flat_map(|(_, msg)| msg).count() / pub_keys_and_msgs.len(), keys_cnt: pub_keys_and_msgs.len(), }, From c6e2f131cf65d78e47cea429af2a2ab4526274ab Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Wed, 10 Jan 2024 14:31:45 +0100 Subject: [PATCH 72/82] Update BLS aggregate verify API in wasmer --- radix-engine/src/vm/wasm/wasmer.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/radix-engine/src/vm/wasm/wasmer.rs b/radix-engine/src/vm/wasm/wasmer.rs index 9d3fe499e95..d83e6a9fe5d 100644 --- a/radix-engine/src/vm/wasm/wasmer.rs +++ b/radix-engine/src/vm/wasm/wasmer.rs @@ -697,21 +697,18 @@ impl WasmerModule { pub fn bls12381_v1_aggregate_verify( env: &WasmerInstanceEnv, - messages_ptr: u32, - messages_len: u32, - public_keys_ptr: u32, - public_keys_len: u32, + pub_keys_and_msgs_ptr: u32, + pub_keys_and_msgs_len: u32, signature_ptr: u32, signature_len: u32, ) -> Result> { let (instance, runtime) = grab_runtime!(env); - let messages = read_memory(&instance, messages_ptr, messages_len)?; - - let public_keys = read_memory(&instance, public_keys_ptr, public_keys_len)?; + let pub_keys_and_msgs = + read_memory(&instance, pub_keys_and_msgs_ptr, pub_keys_and_msgs_len)?; let signature = read_memory(instance, signature_ptr, signature_len)?; - runtime.crypto_utils_bls12381_v1_aggregate_verify(messages, public_keys, signature) + runtime.crypto_utils_bls12381_v1_aggregate_verify(pub_keys_and_msgs, signature) } pub fn bls12381_v1_fast_aggregate_verify( From 50535cd3dca94e8c8ab032e75988b729fc9d7795 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Wed, 10 Jan 2024 11:47:49 +0100 Subject: [PATCH 73/82] Add more aggregate verify costing tests --- .../tests/system/crypto_utils.rs | 140 ++++++++++++------ 1 file changed, 98 insertions(+), 42 deletions(-) diff --git a/radix-engine-tests/tests/system/crypto_utils.rs b/radix-engine-tests/tests/system/crypto_utils.rs index e57cbeb6d21..eaabea7f937 100644 --- a/radix-engine-tests/tests/system/crypto_utils.rs +++ b/radix-engine-tests/tests/system/crypto_utils.rs @@ -24,6 +24,36 @@ macro_rules! get_failure { }; } +fn get_aggregate_verify_test_data( + cnt: u32, + msg_size: usize, +) -> ( + Vec, + Vec, + Vec>, + Vec, +) { + let sks: Vec = (1..(cnt + 1)) + .map(|i| Bls12381G1PrivateKey::from_u64(i.into()).unwrap()) + .collect(); + + let msgs: Vec> = (1..(cnt + 1)) + .map(|i| { + let u: u8 = (i % u8::MAX as u32) as u8; + vec![u; msg_size] + }) + .collect(); + let sigs: Vec = sks + .iter() + .zip(msgs.clone()) + .map(|(sk, msg)| sk.sign_v1(&msg)) + .collect(); + + let pks: Vec = sks.iter().map(|sk| sk.public_key()).collect(); + + (sks, pks, msgs, sigs) +} + fn crypto_scrypto_bls12381_v1_verify( runner: &mut TestRunner, package_address: PackageAddress, @@ -179,18 +209,7 @@ fn test_crypto_scrypto_bls12381_g2_signature_aggregate() { let package_address = test_runner.publish_package_simple(PackageLoader::get("crypto_scrypto")); - let sks: Vec = (1..11) - .map(|i| Bls12381G1PrivateKey::from_u64(i).unwrap()) - .collect(); - - // Multiple messages - let msgs: Vec> = (1u8..11).map(|i| vec![i; 10]).collect(); - - let sigs: Vec = sks - .iter() - .zip(msgs.clone()) - .map(|(sk, msg)| sk.sign_v1(&msg)) - .collect(); + let (_sks, _pks, _msgs, sigs) = get_aggregate_verify_test_data(10, 10); // Aggregate the signature let agg_sig_multiple_msgs = Bls12381G2Signature::aggregate(&sigs).unwrap(); @@ -201,6 +220,9 @@ fn test_crypto_scrypto_bls12381_g2_signature_aggregate() { .expect_commit_success() .output(1); + // Assert + assert_eq!(agg_sig_multiple_msgs, agg_sig_from_scrypto); + // Attempt to aggregate signature from empty input let error_message = crypto_scrypto_bls12381_g2_signature_aggregate(&mut test_runner, package_address, vec![]) @@ -210,7 +232,6 @@ fn test_crypto_scrypto_bls12381_g2_signature_aggregate() { .to_string(); // Assert - assert_eq!(agg_sig_multiple_msgs, agg_sig_from_scrypto); assert!(error_message.contains("InputDataEmpty")); } @@ -221,20 +242,7 @@ fn test_crypto_scrypto_bls12381_aggregate_verify() { let package_address = test_runner.publish_package_simple(PackageLoader::get("crypto_scrypto")); - let sks: Vec = (1..11) - .map(|i| Bls12381G1PrivateKey::from_u64(i).unwrap()) - .collect(); - - // Multiple messages - let msgs: Vec> = (1u8..11).map(|i| vec![i; 10]).collect(); - - let sigs: Vec = sks - .iter() - .zip(msgs.clone()) - .map(|(sk, msg)| sk.sign_v1(&msg)) - .collect(); - - let pks: Vec = sks.iter().map(|sk| sk.public_key()).collect(); + let (_sks, pks, msgs, sigs) = get_aggregate_verify_test_data(10, 10); // Aggregate the signature let agg_sig_multiple_msgs = Bls12381G2Signature::aggregate(&sigs).unwrap(); @@ -544,21 +552,8 @@ fn test_crypto_scrypto_bls12381_v1_aggregate_verify_costing() { let package_address = test_runner.publish_package_simple(PackageLoader::get("crypto_scrypto")); for msg_size in [100usize, 200, 500, 1024, 10 * 1024, 20 * 1024] { - for cnt in [1u8, 2, 5, 10, 20] { - let sks: Vec = (1..(cnt + 1)) - .map(|i| Bls12381G1PrivateKey::from_u64(i.into()).unwrap()) - .collect(); - - // Multiple messages - let msgs: Vec> = (1..(cnt + 1)).map(|i| vec![i; msg_size]).collect(); - - let sigs: Vec = sks - .iter() - .zip(msgs.clone()) - .map(|(sk, msg)| sk.sign_v1(&msg)) - .collect(); - - let pks: Vec = sks.iter().map(|sk| sk.public_key()).collect(); + for cnt in [1u32, 2, 5, 10, 20] { + let (_sks, pks, msgs, sigs) = get_aggregate_verify_test_data(cnt, msg_size); let agg_sig_multiple_msgs = Bls12381G2Signature::aggregate(&sigs).unwrap(); @@ -573,6 +568,67 @@ fn test_crypto_scrypto_bls12381_v1_aggregate_verify_costing() { } } +#[test] +fn test_crypto_scrypto_bls12381_v1_aggregate_verify_costing_2() { + let mut test_runner = TestRunnerBuilder::new().build(); + + let package_address = test_runner.publish_package_simple(PackageLoader::get("crypto_scrypto")); + + for (cnt, msg_size) in [ + (1, 100 * 1024), + (2, 50 * 1024), + (5, 20 * 1024), + (10, 10 * 1024), + (100, 1024), + (1024, 100), + ] { + let (_sks, pks, msgs, sigs) = get_aggregate_verify_test_data(cnt, msg_size); + let agg_sig = Bls12381G2Signature::aggregate(&sigs).unwrap(); + + let _ = crypto_scrypto_bls12381_v1_aggregate_verify( + &mut test_runner, + package_address, + msgs, + pks, + agg_sig, + ); + } + + // 1x 99kB and 1000x1B + let (mut sks1, mut pks1, mut msgs1, mut sigs1) = get_aggregate_verify_test_data(1, 99 * 1024); + let (mut sks2, mut pks2, mut msgs2, mut sigs2) = get_aggregate_verify_test_data(1000, 1); + sks1.append(&mut sks2); + pks1.append(&mut pks2); + msgs1.append(&mut msgs2); + sigs1.append(&mut sigs2); + let agg_sig = Bls12381G2Signature::aggregate(&sigs1).unwrap(); + + let _ = crypto_scrypto_bls12381_v1_aggregate_verify( + &mut test_runner, + package_address, + msgs1, + pks1, + agg_sig, + ); + + // 1x 90kB and 10 x 1kB + let (mut sks1, mut pks1, mut msgs1, mut sigs1) = get_aggregate_verify_test_data(1, 90 * 1024); + let (mut sks2, mut pks2, mut msgs2, mut sigs2) = get_aggregate_verify_test_data(10, 1024); + sks1.append(&mut sks2); + pks1.append(&mut pks2); + msgs1.append(&mut msgs2); + sigs1.append(&mut sigs2); + let agg_sig = Bls12381G2Signature::aggregate(&sigs1).unwrap(); + + let _ = crypto_scrypto_bls12381_v1_aggregate_verify( + &mut test_runner, + package_address, + msgs1, + pks1, + agg_sig, + ); +} + #[test] fn test_crypto_scrypto_bls12381_v1_fast_aggregate_verify_costing() { let mut test_runner = TestRunnerBuilder::new().build(); From f2cc6ded030a5e7eb4f16609d71a186c05b2b6b5 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Thu, 11 Jan 2024 16:22:24 +0100 Subject: [PATCH 74/82] Update aggregated verify costs Do not take aggregation into account. Just sum up the costs per size for all messages. --- radix-engine/src/system/system.rs | 5 ++-- .../system_modules/costing/costing_entry.rs | 7 +++--- .../system_modules/costing/fee_table.rs | 25 ++++++++----------- 3 files changed, 16 insertions(+), 21 deletions(-) diff --git a/radix-engine/src/system/system.rs b/radix-engine/src/system/system.rs index 505e789eb3e..e893815eb2e 100644 --- a/radix-engine/src/system/system.rs +++ b/radix-engine/src/system/system.rs @@ -2881,11 +2881,10 @@ where signature: &Bls12381G2Signature, ) -> Result { if !pub_keys_and_msgs.is_empty() { + let sizes: Vec = pub_keys_and_msgs.iter().map(|(_, msg)| msg.len()).collect(); self.api.kernel_get_system().modules.apply_execution_cost( ExecutionCostingEntry::Bls12381V1AggregateVerify { - size: pub_keys_and_msgs.iter().flat_map(|(_, msg)| msg).count() - / pub_keys_and_msgs.len(), - keys_cnt: pub_keys_and_msgs.len(), + sizes: sizes.as_slice(), }, )?; Ok(aggregate_verify_bls12381_v1(pub_keys_and_msgs, signature) as u32) diff --git a/radix-engine/src/system/system_modules/costing/costing_entry.rs b/radix-engine/src/system/system_modules/costing/costing_entry.rs index 9b4523810ef..1730d1aad7e 100644 --- a/radix-engine/src/system/system_modules/costing/costing_entry.rs +++ b/radix-engine/src/system/system_modules/costing/costing_entry.rs @@ -116,8 +116,7 @@ pub enum ExecutionCostingEntry<'a> { size: usize, }, Bls12381V1AggregateVerify { - size: usize, - keys_cnt: usize, + sizes: &'a [usize], }, Bls12381V1FastAggregateVerify { size: usize, @@ -192,8 +191,8 @@ impl<'a> ExecutionCostingEntry<'a> { ExecutionCostingEntry::EmitLog { size } => ft.emit_log_cost(*size), ExecutionCostingEntry::Panic { size } => ft.panic_cost(*size), ExecutionCostingEntry::Bls12381V1Verify { size } => ft.bls12381_v1_verify_cost(*size), - ExecutionCostingEntry::Bls12381V1AggregateVerify { size, keys_cnt } => { - ft.bls12381_v1_aggregate_verify_cost(*size, *keys_cnt) + ExecutionCostingEntry::Bls12381V1AggregateVerify { sizes } => { + ft.bls12381_v1_aggregate_verify_cost(sizes) } ExecutionCostingEntry::Bls12381V1FastAggregateVerify { size, keys_cnt } => { ft.bls12381_v1_fast_aggregate_verify_cost(*size, *keys_cnt) diff --git a/radix-engine/src/system/system_modules/costing/fee_table.rs b/radix-engine/src/system/system_modules/costing/fee_table.rs index d6c00613b83..94e3ae9625f 100644 --- a/radix-engine/src/system/system_modules/costing/fee_table.rs +++ b/radix-engine/src/system/system_modules/costing/fee_table.rs @@ -398,20 +398,17 @@ impl FeeTable { } #[inline] - pub fn bls12381_v1_aggregate_verify_cost(&self, size: usize, keys_cnt: usize) -> u32 { - // Based on `test_crypto_scrypto_bls12381_v1_aggregate_verify_costing` - // - For sizes less than 1024, instruction count remains the same. - // - For greater sizes following linear equation might be applied: - // instructions_cnt = 87.3416 * size + 1438527.7574 * keys_cnt + 9058827.9112 - // (used: https://www.socscistatistics.com/tests/multipleregression/default.aspx) - // Lets round: - // 87.3416 -> 88 - // 1438527.757 -> 1438528 - // 9058827.911 -> 9058828 - let size = if size < 1024 { 1024 } else { cast(size) }; - let instructions_cnt = add(add(mul(size, 88), mul(cast(keys_cnt), 1438528)), 9058828); - // Convert to cost units - instructions_cnt / CPU_INSTRUCTIONS_TO_COST_UNIT + pub fn bls12381_v1_aggregate_verify_cost(&self, sizes: &[usize]) -> u32 { + // Below approach does not take aggregation into account. + // Summing costs pers size gives greater values. + // We've found somewhat difficult to find a proper and effective equation to estimate + // the instructions count collected with `test_crypto_scrypto_verify_bls12381_v1_costing` + // TODO: Find more adequate cost estimation + let mut cost: u32 = 0; + for size in sizes { + cost += self.bls12381_v1_verify_cost(*size); + } + cost } #[inline] From 7c6f79d7f4f305c4f79958576250ab701a37e695 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Thu, 11 Jan 2024 19:44:54 +0100 Subject: [PATCH 75/82] Reenable crypto features for wasm32 target as well --- radix-engine-common/src/crypto/bls12381/public_key.rs | 4 ---- radix-engine-common/src/crypto/bls12381/signature.rs | 4 ---- 2 files changed, 8 deletions(-) diff --git a/radix-engine-common/src/crypto/bls12381/public_key.rs b/radix-engine-common/src/crypto/bls12381/public_key.rs index bae32255b36..276ad8d40b1 100644 --- a/radix-engine-common/src/crypto/bls12381/public_key.rs +++ b/radix-engine-common/src/crypto/bls12381/public_key.rs @@ -1,7 +1,6 @@ use crate::internal_prelude::*; #[cfg(feature = "radix_engine_fuzzing")] use arbitrary::Arbitrary; -#[cfg(not(target_arch = "wasm32"))] use blst::{ min_pk::{AggregatePublicKey, PublicKey}, BLST_ERROR, @@ -23,12 +22,10 @@ impl Bls12381G1PublicKey { self.0.to_vec() } - #[cfg(not(target_arch = "wasm32"))] fn to_native_public_key(self) -> Result { PublicKey::from_bytes(&self.0).map_err(|err| err.into()) } - #[cfg(not(target_arch = "wasm32"))] /// Aggregate multiple public keys into a single one pub fn aggregate(public_keys: &[Bls12381G1PublicKey]) -> Result { if !public_keys.is_empty() { @@ -62,7 +59,6 @@ impl TryFrom<&[u8]> for Bls12381G1PublicKey { // error //====== -#[cfg(not(target_arch = "wasm32"))] impl From for ParseBlsPublicKeyError { fn from(error: BLST_ERROR) -> Self { let err_msg = format!("{:?}", error); diff --git a/radix-engine-common/src/crypto/bls12381/signature.rs b/radix-engine-common/src/crypto/bls12381/signature.rs index 6b9b071ad7f..17bd02efe52 100644 --- a/radix-engine-common/src/crypto/bls12381/signature.rs +++ b/radix-engine-common/src/crypto/bls12381/signature.rs @@ -1,5 +1,4 @@ use crate::internal_prelude::*; -#[cfg(not(target_arch = "wasm32"))] use blst::{ min_pk::{AggregateSignature, Signature}, BLST_ERROR, @@ -38,12 +37,10 @@ impl Bls12381G2Signature { self.0.to_vec() } - #[cfg(not(target_arch = "wasm32"))] fn to_native_signature(self) -> Result { Signature::from_bytes(&self.0).map_err(|err| err.into()) } - #[cfg(not(target_arch = "wasm32"))] /// Aggregate multiple signatures into a single one pub fn aggregate(signatures: &[Bls12381G2Signature]) -> Result { if !signatures.is_empty() { @@ -77,7 +74,6 @@ impl TryFrom<&[u8]> for Bls12381G2Signature { // error //====== -#[cfg(not(target_arch = "wasm32"))] impl From for ParseBlsSignatureError { fn from(error: BLST_ERROR) -> Self { let err_msg = format!("{:?}", error); From eca021bd4e8b2b15c78372901421516edca3efb3 Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Fri, 12 Jan 2024 00:35:56 +0100 Subject: [PATCH 76/82] Temporarily disable BLS aggregate verify It does not work for WASM and no_std --- radix-engine-common/Cargo.toml | 7 ++++--- .../src/crypto/bls12381/private_key.rs | 1 + .../src/crypto/signature_validator.rs | 1 + .../src/api/system_modules/crypto_utils_api.rs | 1 + .../assets/blueprints/crypto_scrypto/src/lib.rs | 3 +++ radix-engine-tests/tests/system/crypto_utils.rs | 4 ++++ radix-engine/src/system/system.rs | 1 + .../system/system_modules/costing/costing_entry.rs | 2 ++ .../src/system/system_modules/costing/fee_table.rs | 1 + radix-engine/src/vm/wasm/constants.rs | 1 + radix-engine/src/vm/wasm/prepare.rs | 1 + radix-engine/src/vm/wasm/traits.rs | 1 + radix-engine/src/vm/wasm/wasmer.rs | 4 +++- radix-engine/src/vm/wasm/wasmi.rs | 3 +++ radix-engine/src/vm/wasm_runtime/no_op_runtime.rs | 1 + radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs | 1 + scrypto-test/src/environment/client_api.rs | 13 +++++++++++++ scrypto/src/crypto_utils/crypto_utils.rs | 1 + scrypto/src/engine/wasm_api.rs | 1 + 19 files changed, 44 insertions(+), 4 deletions(-) diff --git a/radix-engine-common/Cargo.toml b/radix-engine-common/Cargo.toml index 82d1d62f992..27857146d9a 100644 --- a/radix-engine-common/Cargo.toml +++ b/radix-engine-common/Cargo.toml @@ -47,10 +47,11 @@ harness = false default = ["std"] serde = ["dep:serde", "utils/serde", "sbor/serde", "hex/serde"] std = ["hex/std", "sbor/std", "utils/std", "radix-engine-derive/std", "serde_json/std", "ed25519-dalek/std", "secp256k1/std", "blake2/std", "sha3/std" ] -alloc = ["hex/alloc", "sbor/alloc", "utils/alloc", "radix-engine-derive/alloc", "serde_json/alloc", "ed25519-dalek/alloc", "secp256k1/alloc", "lazy_static/spin_no_std"] +alloc = ["hex/alloc", "sbor/alloc", "utils/alloc", "radix-engine-derive/alloc", "serde_json/alloc", "ed25519-dalek/alloc", "secp256k1/alloc", "lazy_static/spin_no_std" ] -# Include crypto primitives -#crypto = ["dep:ed25519-dalek", "dep:secp256k1", "dep:blst", "dep:sha3"] +# Temporary switch to disable code related to BLS aggregate verify +# It does not work for WASM32 and no_std +enable_bls_aggregate_verify = [] # This flag is set by fuzz-tests framework and it is used to disable/enable some optional features # to let fuzzing work diff --git a/radix-engine-common/src/crypto/bls12381/private_key.rs b/radix-engine-common/src/crypto/bls12381/private_key.rs index f1c9cb07c48..2397dabd936 100644 --- a/radix-engine-common/src/crypto/bls12381/private_key.rs +++ b/radix-engine-common/src/crypto/bls12381/private_key.rs @@ -82,6 +82,7 @@ mod tests { } #[test] + #[cfg(feature = "enable_bls_aggregate_verify")] fn sign_and_verify_aggregated() { let sks: Vec = (1..11) .map(|i| Bls12381G1PrivateKey::from_u64(i).unwrap()) diff --git a/radix-engine-common/src/crypto/signature_validator.rs b/radix-engine-common/src/crypto/signature_validator.rs index cd679887113..9ba7183facc 100644 --- a/radix-engine-common/src/crypto/signature_validator.rs +++ b/radix-engine-common/src/crypto/signature_validator.rs @@ -78,6 +78,7 @@ pub fn verify_bls12381_v1( /// Performs BLS12-381 G2 aggregated signature verification of /// multiple messages each signed with different key. /// Domain specifier tag: BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_ +#[cfg(feature = "enable_bls_aggregate_verify")] pub fn aggregate_verify_bls12381_v1( pub_keys_and_msgs: &[(Bls12381G1PublicKey, Vec)], signature: &Bls12381G2Signature, diff --git a/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs b/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs index 74a195996f1..c02bd436c8d 100644 --- a/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs +++ b/radix-engine-interface/src/api/system_modules/crypto_utils_api.rs @@ -8,6 +8,7 @@ pub trait ClientCryptoUtilsApi { signature: &Bls12381G2Signature, ) -> Result; + #[cfg(feature = "enable_bls_aggregate_verify")] fn bls12381_v1_aggregate_verify( &mut self, pub_keys_and_msgs: &[(Bls12381G1PublicKey, Vec)], diff --git a/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs b/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs index 8e873b5366a..cd5b250c079 100644 --- a/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs +++ b/radix-engine-tests/assets/blueprints/crypto_scrypto/src/lib.rs @@ -13,12 +13,15 @@ mod component_module { CryptoUtils::bls12381_v1_verify(message, pub_key, signature) } + /* + * Uncomment once supported again: #[cfg(feature = "enable_bls_aggregate_verify")] pub fn bls12381_v1_aggregate_verify( pub_keys_msgs: Vec<(Bls12381G1PublicKey, Vec)>, signature: Bls12381G2Signature, ) -> bool { CryptoUtils::bls12381_v1_aggregate_verify(pub_keys_msgs, signature) } + */ pub fn bls12381_v1_fast_aggregate_verify( message: Vec, diff --git a/radix-engine-tests/tests/system/crypto_utils.rs b/radix-engine-tests/tests/system/crypto_utils.rs index eaabea7f937..b481863ca41 100644 --- a/radix-engine-tests/tests/system/crypto_utils.rs +++ b/radix-engine-tests/tests/system/crypto_utils.rs @@ -75,6 +75,7 @@ fn crypto_scrypto_bls12381_v1_verify( ) } +#[cfg(feature = "enable_bls_aggregate_verify")] fn crypto_scrypto_bls12381_v1_aggregate_verify( runner: &mut TestRunner, package_address: PackageAddress, @@ -236,6 +237,7 @@ fn test_crypto_scrypto_bls12381_g2_signature_aggregate() { } #[test] +#[cfg(feature = "enable_bls_aggregate_verify")] fn test_crypto_scrypto_bls12381_aggregate_verify() { // Arrange let mut test_runner = TestRunnerBuilder::new().build(); @@ -546,6 +548,7 @@ fn test_crypto_scrypto_bls12381_g2_signature_aggregate_costing() { } #[test] +#[cfg(feature = "enable_bls_aggregate_verify")] fn test_crypto_scrypto_bls12381_v1_aggregate_verify_costing() { let mut test_runner = TestRunnerBuilder::new().build(); @@ -569,6 +572,7 @@ fn test_crypto_scrypto_bls12381_v1_aggregate_verify_costing() { } #[test] +#[cfg(feature = "enable_bls_aggregate_verify")] fn test_crypto_scrypto_bls12381_v1_aggregate_verify_costing_2() { let mut test_runner = TestRunnerBuilder::new().build(); diff --git a/radix-engine/src/system/system.rs b/radix-engine/src/system/system.rs index e893815eb2e..95afb80ec50 100644 --- a/radix-engine/src/system/system.rs +++ b/radix-engine/src/system/system.rs @@ -2875,6 +2875,7 @@ where // Trace average message length and number of public_keys #[trace_resources(log={pub_keys_and_msgs.iter().flat_map(|(_, msg)| msg).count()/pub_keys_and_msgs.len()},log=pub_keys_and_msgs.len())] + #[cfg(feature = "enable_bls_aggregate_verify")] fn bls12381_v1_aggregate_verify( &mut self, pub_keys_and_msgs: &[(Bls12381G1PublicKey, Vec)], diff --git a/radix-engine/src/system/system_modules/costing/costing_entry.rs b/radix-engine/src/system/system_modules/costing/costing_entry.rs index 1730d1aad7e..045ff0a1997 100644 --- a/radix-engine/src/system/system_modules/costing/costing_entry.rs +++ b/radix-engine/src/system/system_modules/costing/costing_entry.rs @@ -115,6 +115,7 @@ pub enum ExecutionCostingEntry<'a> { Bls12381V1Verify { size: usize, }, + #[cfg(feature = "enable_bls_aggregate_verify")] Bls12381V1AggregateVerify { sizes: &'a [usize], }, @@ -191,6 +192,7 @@ impl<'a> ExecutionCostingEntry<'a> { ExecutionCostingEntry::EmitLog { size } => ft.emit_log_cost(*size), ExecutionCostingEntry::Panic { size } => ft.panic_cost(*size), ExecutionCostingEntry::Bls12381V1Verify { size } => ft.bls12381_v1_verify_cost(*size), + #[cfg(feature = "enable_bls_aggregate_verify")] ExecutionCostingEntry::Bls12381V1AggregateVerify { sizes } => { ft.bls12381_v1_aggregate_verify_cost(sizes) } diff --git a/radix-engine/src/system/system_modules/costing/fee_table.rs b/radix-engine/src/system/system_modules/costing/fee_table.rs index 94e3ae9625f..0768767709c 100644 --- a/radix-engine/src/system/system_modules/costing/fee_table.rs +++ b/radix-engine/src/system/system_modules/costing/fee_table.rs @@ -398,6 +398,7 @@ impl FeeTable { } #[inline] + #[cfg(feature = "enable_bls_aggregate_verify")] pub fn bls12381_v1_aggregate_verify_cost(&self, sizes: &[usize]) -> u32 { // Below approach does not take aggregation into account. // Summing costs pers size gives greater values. diff --git a/radix-engine/src/vm/wasm/constants.rs b/radix-engine/src/vm/wasm/constants.rs index 34ef2f84487..1ee2454ec0f 100644 --- a/radix-engine/src/vm/wasm/constants.rs +++ b/radix-engine/src/vm/wasm/constants.rs @@ -81,6 +81,7 @@ pub const SYS_PANIC_FUNCTION_NAME: &str = "sys_panic"; // Crypto Utils //================= pub const CRYPTO_UTILS_BLS12381_V1_VERIFY_FUNCTION_NAME: &str = "crypto_utils_bls12381_v1_verify"; +#[cfg(feature = "enable_bls_aggregate_verify")] pub const CRYPTO_UTILS_BLS12381_V1_AGGREGATE_VERIFY_FUNCTION_NAME: &str = "crypto_utils_bls12381_v1_aggregate_verify"; pub const CRYPTO_UTILS_BLS12381_V1_FAST_AGGREGATE_VERIFY_FUNCTION_NAME: &str = diff --git a/radix-engine/src/vm/wasm/prepare.rs b/radix-engine/src/vm/wasm/prepare.rs index 43d3014b363..10787ffa54c 100644 --- a/radix-engine/src/vm/wasm/prepare.rs +++ b/radix-engine/src/vm/wasm/prepare.rs @@ -755,6 +755,7 @@ impl WasmModule { )); } } + #[cfg(feature = "enable_bls_aggregate_verify")] CRYPTO_UTILS_BLS12381_V1_AGGREGATE_VERIFY_FUNCTION_NAME => { if let TypeRef::Func(type_index) = entry.ty { if Self::function_type_matches( diff --git a/radix-engine/src/vm/wasm/traits.rs b/radix-engine/src/vm/wasm/traits.rs index 9c887f90c18..92e204c1296 100644 --- a/radix-engine/src/vm/wasm/traits.rs +++ b/radix-engine/src/vm/wasm/traits.rs @@ -208,6 +208,7 @@ pub trait WasmRuntime { signature: Vec, ) -> Result>; + #[cfg(feature = "enable_bls_aggregate_verify")] fn crypto_utils_bls12381_v1_aggregate_verify( &mut self, pub_keys_and_msgs: Vec, diff --git a/radix-engine/src/vm/wasm/wasmer.rs b/radix-engine/src/vm/wasm/wasmer.rs index d83e6a9fe5d..eb5464d556f 100644 --- a/radix-engine/src/vm/wasm/wasmer.rs +++ b/radix-engine/src/vm/wasm/wasmer.rs @@ -695,6 +695,7 @@ impl WasmerModule { runtime.crypto_utils_bls12381_v1_verify(message, public_key, signature) } + #[cfg(feature = "enable_bls_aggregate_verify")] pub fn bls12381_v1_aggregate_verify( env: &WasmerInstanceEnv, pub_keys_and_msgs_ptr: u32, @@ -862,7 +863,8 @@ impl WasmerModule { SYS_GENERATE_RUID_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), sys_generate_ruid), BUFFER_CONSUME_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), buffer_consume), CRYPTO_UTILS_BLS12381_V1_VERIFY_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), bls12381_v1_verify), - CRYPTO_UTILS_BLS12381_V1_AGGREGATE_VERIFY_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), bls12381_v1_aggregate_verify), + // TODO: Uncomment once supported #[cfg(feature = "enable_bls_aggregate_verify")] + //CRYPTO_UTILS_BLS12381_V1_AGGREGATE_VERIFY_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), bls12381_v1_aggregate_verify), CRYPTO_UTILS_BLS12381_V1_FAST_AGGREGATE_VERIFY_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), bls12381_v1_fast_aggregate_verify), CRYPTO_UTILS_BLS12381_G2_SIGNATURE_AGGREGATE_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), bls12381_g2_signature_aggregate), CRYPTO_UTILS_KECCAK256_HASH_FUNCTION_NAME => Function::new_native_with_env(self.module.store(), env.clone(), keccak256_hash), diff --git a/radix-engine/src/vm/wasm/wasmi.rs b/radix-engine/src/vm/wasm/wasmi.rs index 4cfad067dba..a8bf3467949 100644 --- a/radix-engine/src/vm/wasm/wasmi.rs +++ b/radix-engine/src/vm/wasm/wasmi.rs @@ -691,6 +691,7 @@ fn bls12381_v1_verify( runtime.crypto_utils_bls12381_v1_verify(message, public_key, signature) } +#[cfg(feature = "enable_bls_aggregate_verify")] fn bls12381_v1_aggregate_verify( mut caller: Caller<'_, HostState>, pub_keys_and_msgs_ptr: u32, @@ -1363,6 +1364,7 @@ impl WasmiModule { }, ); + #[cfg(feature = "enable_bls_aggregate_verify")] let host_bls12381_v1_aggregate_verify = Func::wrap( store.as_context_mut(), |caller: Caller<'_, HostState>, @@ -1585,6 +1587,7 @@ impl WasmiModule { CRYPTO_UTILS_BLS12381_V1_VERIFY_FUNCTION_NAME, host_bls12381_v1_verify ); + #[cfg(feature = "enable_bls_aggregate_verify")] linker_define!( linker, CRYPTO_UTILS_BLS12381_V1_AGGREGATE_VERIFY_FUNCTION_NAME, diff --git a/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs b/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs index f26a28f8d1b..8bca0fe3c50 100644 --- a/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs +++ b/radix-engine/src/vm/wasm_runtime/no_op_runtime.rs @@ -315,6 +315,7 @@ impl<'a> WasmRuntime for NoOpWasmRuntime<'a> { Err(InvokeError::SelfError(WasmRuntimeError::NotImplemented)) } + #[cfg(feature = "enable_bls_aggregate_verify")] fn crypto_utils_bls12381_v1_aggregate_verify( &mut self, pub_keys_and_msgs: Vec, diff --git a/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs b/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs index 45db7867a0a..1ca91600e82 100644 --- a/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs +++ b/radix-engine/src/vm/wasm_runtime/scrypto_runtime.rs @@ -577,6 +577,7 @@ where Ok(result) } + #[cfg(feature = "enable_bls_aggregate_verify")] fn crypto_utils_bls12381_v1_aggregate_verify( &mut self, pub_keys_and_msgs: Vec, diff --git a/scrypto-test/src/environment/client_api.rs b/scrypto-test/src/environment/client_api.rs index c760cff248f..33f4bf12086 100644 --- a/scrypto-test/src/environment/client_api.rs +++ b/scrypto-test/src/environment/client_api.rs @@ -275,6 +275,19 @@ implement_client_api! { tip_percentage: (&mut self) -> Result, fee_balance: (&mut self) -> Result, }, +} + +#[cfg(not(feature = "enable_bls_aggregate_verify"))] +implement_client_api! { + ClientCryptoUtilsApi: { + bls12381_v1_verify: (&mut self, message: &[u8], public_key: &Bls12381G1PublicKey, signature: &Bls12381G2Signature) -> Result, + bls12381_v1_fast_aggregate_verify: (&mut self, message: &[u8], public_keys: &[Bls12381G1PublicKey], signature: &Bls12381G2Signature) -> Result, + bls12381_g2_signature_aggregate: (&mut self, signatures: &[Bls12381G2Signature]) -> Result, + keccak256_hash: (&mut self, data: &[u8]) -> Result, + }, +} +#[cfg(feature = "enable_bls_aggregate_verify")] +implement_client_api! { ClientCryptoUtilsApi: { bls12381_v1_verify: (&mut self, message: &[u8], public_key: &Bls12381G1PublicKey, signature: &Bls12381G2Signature) -> Result, bls12381_v1_aggregate_verify: (&mut self, pub_keys_and_msgs: &[(Bls12381G1PublicKey, Vec)], signature: &Bls12381G2Signature) -> Result, diff --git a/scrypto/src/crypto_utils/crypto_utils.rs b/scrypto/src/crypto_utils/crypto_utils.rs index 2687f1dbe6e..5a33ff43fe4 100644 --- a/scrypto/src/crypto_utils/crypto_utils.rs +++ b/scrypto/src/crypto_utils/crypto_utils.rs @@ -33,6 +33,7 @@ impl CryptoUtils { /// Performs BLS12-381 G2 aggregated signature verification of /// multiple messages each signed with different key. /// Domain specifier tag: BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_ + #[cfg(feature = "enable_bls_aggregate_verify")] pub fn bls12381_v1_aggregate_verify( pub_keys_and_msgs: Vec<(Bls12381G1PublicKey, Vec)>, signature: Bls12381G2Signature, diff --git a/scrypto/src/engine/wasm_api.rs b/scrypto/src/engine/wasm_api.rs index fda3b0c7dd2..1ca72a429a0 100644 --- a/scrypto/src/engine/wasm_api.rs +++ b/scrypto/src/engine/wasm_api.rs @@ -297,6 +297,7 @@ pub mod crypto_utils { signature_ptr: *const u8, signature_len: usize) -> u32; + #[cfg(feature = "enable_bls_aggregate_verify")] pub fn crypto_utils_bls12381_v1_aggregate_verify( pub_keys_and_msgs_ptr: *const u8, pub_keys_and_msgs_len: usize, From fd5a53043d20ec3a1b1d7ab87b1775cfbce98048 Mon Sep 17 00:00:00 2001 From: Joshua Primero Date: Thu, 11 Jan 2024 23:43:15 -0600 Subject: [PATCH 77/82] Add minor version checks for Crypto Utils --- ...estamp_seconds.rs => seconds_precision.rs} | 0 radix-engine/src/vm/wasm/prepare.rs | 36 +++++++++++++++++-- radix-engine/src/vm/wasm/wasm_validator.rs | 2 +- 3 files changed, 34 insertions(+), 4 deletions(-) rename radix-engine-tests/tests/flash/{timestamp_seconds.rs => seconds_precision.rs} (100%) diff --git a/radix-engine-tests/tests/flash/timestamp_seconds.rs b/radix-engine-tests/tests/flash/seconds_precision.rs similarity index 100% rename from radix-engine-tests/tests/flash/timestamp_seconds.rs rename to radix-engine-tests/tests/flash/seconds_precision.rs diff --git a/radix-engine/src/vm/wasm/prepare.rs b/radix-engine/src/vm/wasm/prepare.rs index 10787ffa54c..e645dc7f29d 100644 --- a/radix-engine/src/vm/wasm/prepare.rs +++ b/radix-engine/src/vm/wasm/prepare.rs @@ -59,7 +59,7 @@ impl WasmModule { } } - pub fn enforce_import_limit(self) -> Result { + pub fn enforce_import_limit(self, minor_version: u64) -> Result { // Only allow `env::radix_engine` import for entry in self .module @@ -734,6 +734,12 @@ impl WasmModule { } } CRYPTO_UTILS_BLS12381_V1_VERIFY_FUNCTION_NAME => { + if minor_version < 1 { + return Err(PrepareError::InvalidImport( + InvalidImport::ImportNotAllowed(entry.name.to_string()), + )); + } + if let TypeRef::Func(type_index) = entry.ty { if Self::function_type_matches( &self.module, @@ -757,6 +763,12 @@ impl WasmModule { } #[cfg(feature = "enable_bls_aggregate_verify")] CRYPTO_UTILS_BLS12381_V1_AGGREGATE_VERIFY_FUNCTION_NAME => { + if minor_version < 1 { + return Err(PrepareError::InvalidImport( + InvalidImport::ImportNotAllowed(entry.name.to_string()), + )); + } + if let TypeRef::Func(type_index) = entry.ty { if Self::function_type_matches( &self.module, @@ -772,6 +784,12 @@ impl WasmModule { } } CRYPTO_UTILS_BLS12381_V1_FAST_AGGREGATE_VERIFY_FUNCTION_NAME => { + if minor_version < 1 { + return Err(PrepareError::InvalidImport( + InvalidImport::ImportNotAllowed(entry.name.to_string()), + )); + } + if let TypeRef::Func(type_index) = entry.ty { if Self::function_type_matches( &self.module, @@ -794,6 +812,12 @@ impl WasmModule { } } CRYPTO_UTILS_BLS12381_G2_SIGNATURE_AGGREGATE_FUNCTION_NAME => { + if minor_version < 1 { + return Err(PrepareError::InvalidImport( + InvalidImport::ImportNotAllowed(entry.name.to_string()), + )); + } + if let TypeRef::Func(type_index) = entry.ty { if Self::function_type_matches( &self.module, @@ -809,6 +833,12 @@ impl WasmModule { } } CRYPTO_UTILS_KECCAK256_HASH_FUNCTION_NAME => { + if minor_version < 1 { + return Err(PrepareError::InvalidImport( + InvalidImport::ImportNotAllowed(entry.name.to_string()), + )); + } + if let TypeRef::Func(type_index) = entry.ty { if Self::function_type_matches( &self.module, @@ -1330,7 +1360,7 @@ mod tests { PrepareError::InvalidImport(InvalidImport::ImportNotAllowed( "name_to_replace".to_string() )), - WasmModule::enforce_import_limit + |s| WasmModule::enforce_import_limit(s, 0u64) ); for name in [ @@ -1377,7 +1407,7 @@ mod tests { assert_invalid_wasm!( wat.replace("name_to_replace", name), PrepareError::InvalidImport(InvalidImport::InvalidFunctionType(name.to_string())), - WasmModule::enforce_import_limit + |w| WasmModule::enforce_import_limit(w, 0u64) ); } } diff --git a/radix-engine/src/vm/wasm/wasm_validator.rs b/radix-engine/src/vm/wasm/wasm_validator.rs index bbb1919b75b..4fbe6442bdf 100644 --- a/radix-engine/src/vm/wasm/wasm_validator.rs +++ b/radix-engine/src/vm/wasm/wasm_validator.rs @@ -60,7 +60,7 @@ impl ScryptoV1WasmValidator { ) -> Result<(Vec, Vec), PrepareError> { WasmModule::init(code)? .enforce_no_start_function()? - .enforce_import_limit()? + .enforce_import_limit(self.minor_version)? .enforce_export_names()? .enforce_memory_limit_and_inject_max(self.max_memory_size_in_pages)? .enforce_table_limit(self.max_initial_table_size)? From a680b8f6620bc280711b0fd11083f999c4bc99fa Mon Sep 17 00:00:00 2001 From: Joshua Primero Date: Fri, 12 Jan 2024 01:15:20 -0600 Subject: [PATCH 78/82] Add StateUpdate generation for Scrypto CryptoUtils --- .../src/types/node_and_substate.rs | 4 ++++ .../tests/application/stake_reconciliation.rs | 1 + .../src/system/checkers/kernel_db_checker.rs | 2 +- .../src/system/checkers/system_db_checker.rs | 4 ++++ .../src/utils/flash_state_generator.rs | 21 ++++++++++++++++++- radix-engine/src/utils/package_extractor.rs | 2 +- radix-engine/src/vm/vm.rs | 10 +++++---- radix-engine/src/vm/wasm/wasm_validator.rs | 6 +++--- scrypto-unit/src/test_runner.rs | 18 ++++++++++++++++ 9 files changed, 58 insertions(+), 10 deletions(-) diff --git a/radix-engine-common/src/types/node_and_substate.rs b/radix-engine-common/src/types/node_and_substate.rs index b2dafc447a4..ee69fa1274c 100644 --- a/radix-engine-common/src/types/node_and_substate.rs +++ b/radix-engine-common/src/types/node_and_substate.rs @@ -55,6 +55,10 @@ impl NodeId { EntityType::from_repr(self.0[0]) } + pub const fn is_boot_loader(&self) -> bool { + self.0[0] == 0u8 + } + /// `Global` means root nodes in the store pub const fn is_global(&self) -> bool { matches!(self.entity_type(), Some(t) if t.is_global()) diff --git a/radix-engine-tests/tests/application/stake_reconciliation.rs b/radix-engine-tests/tests/application/stake_reconciliation.rs index b985f0de8bb..bd62db4d218 100644 --- a/radix-engine-tests/tests/application/stake_reconciliation.rs +++ b/radix-engine-tests/tests/application/stake_reconciliation.rs @@ -9,6 +9,7 @@ fn test_stake_reconciliation() { let pub_key = Secp256k1PrivateKey::from_u64(1u64).unwrap().public_key(); let mut test_runner = TestRunnerBuilder::new() .without_seconds_precision_update() + .without_bls_update() .build(); let (account_pk, _, account) = test_runner.new_account(false); diff --git a/radix-engine/src/system/checkers/kernel_db_checker.rs b/radix-engine/src/system/checkers/kernel_db_checker.rs index 45beb9783fa..421fa3f1c74 100644 --- a/radix-engine/src/system/checkers/kernel_db_checker.rs +++ b/radix-engine/src/system/checkers/kernel_db_checker.rs @@ -79,7 +79,7 @@ impl KernelDatabaseChecker { for (node_id, state) in internal_nodes { match state { NodeCheckerState::NoOwner(partition_count) => { - if !node_id.is_global() { + if !node_id.is_global() && !node_id.is_boot_loader() { return Err(KernelDatabaseCheckError::NoOwnerForNonGlobalNode(node_id)); } diff --git a/radix-engine/src/system/checkers/system_db_checker.rs b/radix-engine/src/system/checkers/system_db_checker.rs index 6e38e96a8d2..7af92bc7d67 100644 --- a/radix-engine/src/system/checkers/system_db_checker.rs +++ b/radix-engine/src/system/checkers/system_db_checker.rs @@ -215,6 +215,10 @@ impl SystemDatabaseChecker { let reader = SystemDatabaseReader::new(substate_db); for (node_id, partition_number) in reader.partitions_iter() { + if node_id.is_boot_loader() { + continue; + } + let new_node = match &mut current_checker_node { Some(checker_state) => { if node_id.ne(&checker_state.node_id) { diff --git a/radix-engine/src/utils/flash_state_generator.rs b/radix-engine/src/utils/flash_state_generator.rs index 7bed738e129..0c1fb93a76a 100644 --- a/radix-engine/src/utils/flash_state_generator.rs +++ b/radix-engine/src/utils/flash_state_generator.rs @@ -6,7 +6,7 @@ use crate::internal_prelude::{ }; use crate::system::system_db_reader::{ObjectCollectionKey, SystemDatabaseReader}; use crate::track::{NodeStateUpdates, PartitionStateUpdates, StateUpdates}; -use radix_engine_common::constants::CONSENSUS_MANAGER_PACKAGE; +use radix_engine_common::constants::{BOOT_LOADER_STATE, CONSENSUS_MANAGER_PACKAGE}; use radix_engine_common::crypto::hash; use radix_engine_common::prelude::ScopedTypeId; use radix_engine_common::prelude::{scrypto_encode, ScryptoCustomTypeKind}; @@ -29,6 +29,25 @@ use radix_engine_store_interface::interface::{DatabaseUpdate, SubstateDatabase}; use sbor::HasLatestVersion; use sbor::{generate_full_schema, TypeAggregator}; use utils::indexmap; +use crate::vm::{BOOT_LOADER_VM_PARTITION_NUM, BOOT_LOADER_VM_SUBSTATE_FIELD_KEY, VmBoot}; + +pub fn generate_vm_boot_scrypto_minor_version_state_updates() -> StateUpdates { + let substate = scrypto_encode(&VmBoot::V1 { scrypto_v1_minor_version: 1u64 }).unwrap(); + + StateUpdates { + by_node: indexmap!( + BOOT_LOADER_STATE => NodeStateUpdates::Delta { + by_partition: indexmap! { + BOOT_LOADER_VM_PARTITION_NUM => PartitionStateUpdates::Delta { + by_substate: indexmap! { + SubstateKey::Field(BOOT_LOADER_VM_SUBSTATE_FIELD_KEY) => DatabaseUpdate::Set(substate) + } + }, + } + } + ), + } +} /// Generates the state updates required for updating the Consensus Manager blueprint /// to use seconds precision diff --git a/radix-engine/src/utils/package_extractor.rs b/radix-engine/src/utils/package_extractor.rs index bbac59350ee..52c7fa6d8fd 100644 --- a/radix-engine/src/utils/package_extractor.rs +++ b/radix-engine/src/utils/package_extractor.rs @@ -28,7 +28,7 @@ pub fn extract_definition(code: &[u8]) -> Result { pub scrypto_vm: &'g ScryptoVm, @@ -79,8 +79,10 @@ impl<'g, W: WasmEngine + 'g, E: NativeVmExtension> SystemCallbackObject for Vm<' let vm_version = match vm_boot { VmBoot::V1 { scrypto_v1_minor_version, - } => VmVersion { - scrypto_v1_minor_version, + } => { + VmVersion { + scrypto_v1_minor_version, + } }, }; diff --git a/radix-engine/src/vm/wasm/wasm_validator.rs b/radix-engine/src/vm/wasm/wasm_validator.rs index 4fbe6442bdf..86ec4934e62 100644 --- a/radix-engine/src/vm/wasm/wasm_validator.rs +++ b/radix-engine/src/vm/wasm/wasm_validator.rs @@ -2,7 +2,7 @@ use crate::types::*; use crate::vm::wasm::*; use radix_engine_interface::blueprints::package::BlueprintDefinitionInit; -pub const SCRYPTO_V1_CURRENT_MINOR_VERSION: u64 = 0u64; +pub const SCRYPTO_V1_LATEST_MINOR_VERSION: u64 = 1u64; pub struct ScryptoV1WasmValidator { pub max_memory_size_in_pages: u32, @@ -18,7 +18,7 @@ pub struct ScryptoV1WasmValidator { impl ScryptoV1WasmValidator { pub fn new(minor_version: u64) -> Self { - if minor_version > SCRYPTO_V1_CURRENT_MINOR_VERSION { + if minor_version > SCRYPTO_V1_LATEST_MINOR_VERSION { panic!("Invalid minor version: {}", minor_version); } @@ -47,7 +47,7 @@ impl Default for ScryptoV1WasmValidator { max_number_of_function_locals: MAX_NUMBER_OF_FUNCTION_LOCALS, max_number_of_globals: MAX_NUMBER_OF_GLOBALS, instrumenter_config: WasmValidatorConfigV1::new(), - minor_version: SCRYPTO_V1_CURRENT_MINOR_VERSION, + minor_version: SCRYPTO_V1_LATEST_MINOR_VERSION, } } } diff --git a/scrypto-unit/src/test_runner.rs b/scrypto-unit/src/test_runner.rs index 38c3361640b..95d0363bc12 100644 --- a/scrypto-unit/src/test_runner.rs +++ b/scrypto-unit/src/test_runner.rs @@ -347,7 +347,10 @@ pub struct TestRunnerBuilder { custom_database: D, trace: bool, skip_receipt_check: bool, + + // The following are protocol updates on mainnet with_seconds_precision_update: bool, + with_scrypto_bls_update: bool, } impl TestRunnerBuilder { @@ -359,6 +362,7 @@ impl TestRunnerBuilder { trace: true, skip_receipt_check: false, with_seconds_precision_update: true, + with_scrypto_bls_update: true, } } } @@ -377,6 +381,7 @@ impl TestRunnerBuilder { trace: self.trace, skip_receipt_check: false, with_seconds_precision_update: self.with_seconds_precision_update, + with_scrypto_bls_update: self.with_scrypto_bls_update, } } @@ -401,6 +406,7 @@ impl TestRunnerBuilder { trace: self.trace, skip_receipt_check: self.skip_receipt_check, with_seconds_precision_update: self.with_seconds_precision_update, + with_scrypto_bls_update: self.with_scrypto_bls_update, } } @@ -412,6 +418,7 @@ impl TestRunnerBuilder { trace: self.trace, skip_receipt_check: self.skip_receipt_check, with_seconds_precision_update: self.with_seconds_precision_update, + with_scrypto_bls_update: self.with_scrypto_bls_update, } } @@ -420,6 +427,11 @@ impl TestRunnerBuilder { self } + pub fn without_bls_update(mut self) -> Self { + self.with_scrypto_bls_update = false; + self + } + pub fn build_from_snapshot( self, snapshot: TestRunnerSnapshot, @@ -515,6 +527,12 @@ impl TestRunnerBuilder { substate_db.commit(&db_updates); }; + if self.with_scrypto_bls_update { + let state_updates = generate_vm_boot_scrypto_minor_version_state_updates(); + let db_updates = state_updates.create_database_updates::(); + substate_db.commit(&db_updates); + } + let runner = TestRunner { scrypto_vm, native_vm, From 7bfa8a231f0956a05bb31d39a3206dc55a3e988d Mon Sep 17 00:00:00 2001 From: Joshua Primero Date: Fri, 12 Jan 2024 02:08:10 -0600 Subject: [PATCH 79/82] Add Crypto Utils flash test --- .../src/types/node_and_substate.rs | 6 ++- .../tests/application/stake_reconciliation.rs | 2 +- .../tests/flash/crypto_utils.rs | 51 +++++++++++++++++++ .../src/system/checkers/kernel_db_checker.rs | 10 ++++ .../src/system/checkers/system_db_checker.rs | 1 + scrypto-unit/src/test_runner.rs | 30 ++++++++--- 6 files changed, 90 insertions(+), 10 deletions(-) create mode 100644 radix-engine-tests/tests/flash/crypto_utils.rs diff --git a/radix-engine-common/src/types/node_and_substate.rs b/radix-engine-common/src/types/node_and_substate.rs index ee69fa1274c..a290de87a51 100644 --- a/radix-engine-common/src/types/node_and_substate.rs +++ b/radix-engine-common/src/types/node_and_substate.rs @@ -11,6 +11,8 @@ use utils::ContextualDisplay; // Please update REP-60 after updating types/configs defined in this file! //========================================================================= +pub const BOOT_LOADER_RESERVED_NODE_ID_FIRST_BYTE: u8 = 0u8; + /// The unique identifier of a (stored) node. #[cfg_attr( feature = "radix_engine_fuzzing", @@ -55,8 +57,10 @@ impl NodeId { EntityType::from_repr(self.0[0]) } + /// Boot Loader means the Node is part of the boot loading process and does + /// not represent any sort of entity. pub const fn is_boot_loader(&self) -> bool { - self.0[0] == 0u8 + self.0[0] == BOOT_LOADER_RESERVED_NODE_ID_FIRST_BYTE } /// `Global` means root nodes in the store diff --git a/radix-engine-tests/tests/application/stake_reconciliation.rs b/radix-engine-tests/tests/application/stake_reconciliation.rs index bd62db4d218..5959aeb48b5 100644 --- a/radix-engine-tests/tests/application/stake_reconciliation.rs +++ b/radix-engine-tests/tests/application/stake_reconciliation.rs @@ -9,7 +9,7 @@ fn test_stake_reconciliation() { let pub_key = Secp256k1PrivateKey::from_u64(1u64).unwrap().public_key(); let mut test_runner = TestRunnerBuilder::new() .without_seconds_precision_update() - .without_bls_update() + .without_crypto_utils_update() .build(); let (account_pk, _, account) = test_runner.new_account(false); diff --git a/radix-engine-tests/tests/flash/crypto_utils.rs b/radix-engine-tests/tests/flash/crypto_utils.rs new file mode 100644 index 00000000000..6dfe9931e19 --- /dev/null +++ b/radix-engine-tests/tests/flash/crypto_utils.rs @@ -0,0 +1,51 @@ +use radix_engine::errors::RuntimeError; +use radix_engine_common::prelude::{Epoch}; +use radix_engine_store_interface::db_key_mapper::SpreadPrefixKeyMapper; +use radix_engine_store_interface::interface::{CommittableSubstateDatabase}; +use radix_engine_tests::common::PackageLoader; +use scrypto_unit::{CustomGenesis, TestRunnerBuilder}; +use radix_engine::utils::generate_vm_boot_scrypto_minor_version_state_updates; +use radix_engine::types::*; +use radix_engine::errors::ApplicationError; +use radix_engine::blueprints::package::PackageError; + +#[test] +fn publishing_crypto_utils_without_state_flash_should_fail() { + run_flash_test(false, false); +} + +#[test] +fn publishing_crypto_utils_with_state_flash_should_succeed() { + run_flash_test(true, true); +} + +fn run_flash_test(flash_substates: bool, expect_success: bool) { + // Arrange + let mut test_runner = TestRunnerBuilder::new() + .without_crypto_utils_update() + .with_custom_genesis(CustomGenesis::default( + Epoch::of(1), + CustomGenesis::default_consensus_manager_config(), + )) + .build(); + if flash_substates { + let state_updates = generate_vm_boot_scrypto_minor_version_state_updates(); + let db_updates = state_updates.create_database_updates::(); + test_runner.substate_db_mut().commit(&db_updates); + } + + // Act + let receipt = test_runner.try_publish_package(PackageLoader::get("crypto_scrypto")); + + // Assert + if expect_success { + receipt.expect_commit_success(); + } else { + receipt.expect_specific_failure(|e| { + matches!( + e, + RuntimeError::ApplicationError(ApplicationError::PackageError(PackageError::InvalidWasm(..))) + ) + }); + } +} diff --git a/radix-engine/src/system/checkers/kernel_db_checker.rs b/radix-engine/src/system/checkers/kernel_db_checker.rs index 421fa3f1c74..99a540ab970 100644 --- a/radix-engine/src/system/checkers/kernel_db_checker.rs +++ b/radix-engine/src/system/checkers/kernel_db_checker.rs @@ -13,6 +13,8 @@ pub enum KernelDatabaseCheckError { NonGlobalReference(NodeId), NoOwnerForNonGlobalNode(NodeId), ZeroPartitionCount(NodeId), + CannotOwnBootLoaderNode(NodeId), + CannotReferenceBootLoaderNode(NodeId), } pub enum NodeCheckerState { @@ -52,6 +54,10 @@ impl KernelDatabaseChecker { let value = IndexedScryptoValue::from_vec(value) .map_err(KernelDatabaseCheckError::DecodeError)?; for owned in value.owned_nodes() { + if owned.is_boot_loader() { + return Err(KernelDatabaseCheckError::CannotOwnBootLoaderNode(*owned)) + } + let state = internal_nodes .entry(*owned) .or_insert(NodeCheckerState::NoOwner(0u8)); @@ -66,6 +72,10 @@ impl KernelDatabaseChecker { } for refed in value.references() { + if refed.is_boot_loader() { + return Err(KernelDatabaseCheckError::CannotReferenceBootLoaderNode(*refed)) + } + if !refed.is_global() { return Err(KernelDatabaseCheckError::NonGlobalReference(*refed)); } diff --git a/radix-engine/src/system/checkers/system_db_checker.rs b/radix-engine/src/system/checkers/system_db_checker.rs index 7af92bc7d67..756f644fb78 100644 --- a/radix-engine/src/system/checkers/system_db_checker.rs +++ b/radix-engine/src/system/checkers/system_db_checker.rs @@ -215,6 +215,7 @@ impl SystemDatabaseChecker { let reader = SystemDatabaseReader::new(substate_db); for (node_id, partition_number) in reader.partitions_iter() { + // Boot Loader is not part of the system state if node_id.is_boot_loader() { continue; } diff --git a/scrypto-unit/src/test_runner.rs b/scrypto-unit/src/test_runner.rs index 95d0363bc12..2c01e976f94 100644 --- a/scrypto-unit/src/test_runner.rs +++ b/scrypto-unit/src/test_runner.rs @@ -350,7 +350,7 @@ pub struct TestRunnerBuilder { // The following are protocol updates on mainnet with_seconds_precision_update: bool, - with_scrypto_bls_update: bool, + with_crypto_utils_update: bool, } impl TestRunnerBuilder { @@ -362,7 +362,7 @@ impl TestRunnerBuilder { trace: true, skip_receipt_check: false, with_seconds_precision_update: true, - with_scrypto_bls_update: true, + with_crypto_utils_update: true, } } } @@ -381,7 +381,7 @@ impl TestRunnerBuilder { trace: self.trace, skip_receipt_check: false, with_seconds_precision_update: self.with_seconds_precision_update, - with_scrypto_bls_update: self.with_scrypto_bls_update, + with_crypto_utils_update: self.with_crypto_utils_update, } } @@ -406,7 +406,7 @@ impl TestRunnerBuilder { trace: self.trace, skip_receipt_check: self.skip_receipt_check, with_seconds_precision_update: self.with_seconds_precision_update, - with_scrypto_bls_update: self.with_scrypto_bls_update, + with_crypto_utils_update: self.with_crypto_utils_update, } } @@ -418,7 +418,7 @@ impl TestRunnerBuilder { trace: self.trace, skip_receipt_check: self.skip_receipt_check, with_seconds_precision_update: self.with_seconds_precision_update, - with_scrypto_bls_update: self.with_scrypto_bls_update, + with_crypto_utils_update: self.with_crypto_utils_update, } } @@ -427,8 +427,8 @@ impl TestRunnerBuilder { self } - pub fn without_bls_update(mut self) -> Self { - self.with_scrypto_bls_update = false; + pub fn without_crypto_utils_update(mut self) -> Self { + self.with_crypto_utils_update = false; self } @@ -527,7 +527,7 @@ impl TestRunnerBuilder { substate_db.commit(&db_updates); }; - if self.with_scrypto_bls_update { + if self.with_crypto_utils_update { let state_updates = generate_vm_boot_scrypto_minor_version_state_updates(); let db_updates = state_updates.create_database_updates::(); substate_db.commit(&db_updates); @@ -1320,6 +1320,20 @@ impl TestRunner { receipt.expect_commit(true).new_package_addresses()[0] } + pub fn try_publish_package>( + &mut self, + source: P, + ) -> TransactionReceipt { + let (code, definition) = source.into().code_and_definition(); + let manifest = ManifestBuilder::new() + .lock_fee_from_faucet() + .publish_package_advanced(None, code, definition, BTreeMap::new(), OwnerRole::None) + .build(); + + let receipt = self.execute_manifest(manifest, vec![]); + receipt + } + pub fn publish_package_simple>( &mut self, source: P, From b1bf2a65ab143f69a5727592b83dbfc213659b46 Mon Sep 17 00:00:00 2001 From: Joshua Primero Date: Fri, 12 Jan 2024 02:09:09 -0600 Subject: [PATCH 80/82] Cleanup format --- radix-engine/src/system/checkers/kernel_db_checker.rs | 6 ++++-- radix-engine/src/utils/flash_state_generator.rs | 7 +++++-- radix-engine/src/vm/vm.rs | 6 ++---- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/radix-engine/src/system/checkers/kernel_db_checker.rs b/radix-engine/src/system/checkers/kernel_db_checker.rs index 99a540ab970..b7869c7b482 100644 --- a/radix-engine/src/system/checkers/kernel_db_checker.rs +++ b/radix-engine/src/system/checkers/kernel_db_checker.rs @@ -55,7 +55,7 @@ impl KernelDatabaseChecker { .map_err(KernelDatabaseCheckError::DecodeError)?; for owned in value.owned_nodes() { if owned.is_boot_loader() { - return Err(KernelDatabaseCheckError::CannotOwnBootLoaderNode(*owned)) + return Err(KernelDatabaseCheckError::CannotOwnBootLoaderNode(*owned)); } let state = internal_nodes @@ -73,7 +73,9 @@ impl KernelDatabaseChecker { for refed in value.references() { if refed.is_boot_loader() { - return Err(KernelDatabaseCheckError::CannotReferenceBootLoaderNode(*refed)) + return Err(KernelDatabaseCheckError::CannotReferenceBootLoaderNode( + *refed, + )); } if !refed.is_global() { diff --git a/radix-engine/src/utils/flash_state_generator.rs b/radix-engine/src/utils/flash_state_generator.rs index 0c1fb93a76a..253e89bcac3 100644 --- a/radix-engine/src/utils/flash_state_generator.rs +++ b/radix-engine/src/utils/flash_state_generator.rs @@ -6,6 +6,7 @@ use crate::internal_prelude::{ }; use crate::system::system_db_reader::{ObjectCollectionKey, SystemDatabaseReader}; use crate::track::{NodeStateUpdates, PartitionStateUpdates, StateUpdates}; +use crate::vm::{VmBoot, BOOT_LOADER_VM_PARTITION_NUM, BOOT_LOADER_VM_SUBSTATE_FIELD_KEY}; use radix_engine_common::constants::{BOOT_LOADER_STATE, CONSENSUS_MANAGER_PACKAGE}; use radix_engine_common::crypto::hash; use radix_engine_common::prelude::ScopedTypeId; @@ -29,10 +30,12 @@ use radix_engine_store_interface::interface::{DatabaseUpdate, SubstateDatabase}; use sbor::HasLatestVersion; use sbor::{generate_full_schema, TypeAggregator}; use utils::indexmap; -use crate::vm::{BOOT_LOADER_VM_PARTITION_NUM, BOOT_LOADER_VM_SUBSTATE_FIELD_KEY, VmBoot}; pub fn generate_vm_boot_scrypto_minor_version_state_updates() -> StateUpdates { - let substate = scrypto_encode(&VmBoot::V1 { scrypto_v1_minor_version: 1u64 }).unwrap(); + let substate = scrypto_encode(&VmBoot::V1 { + scrypto_v1_minor_version: 1u64, + }) + .unwrap(); StateUpdates { by_node: indexmap!( diff --git a/radix-engine/src/vm/vm.rs b/radix-engine/src/vm/vm.rs index 97bdb0f9ec6..8a8208b8f9b 100644 --- a/radix-engine/src/vm/vm.rs +++ b/radix-engine/src/vm/vm.rs @@ -79,10 +79,8 @@ impl<'g, W: WasmEngine + 'g, E: NativeVmExtension> SystemCallbackObject for Vm<' let vm_version = match vm_boot { VmBoot::V1 { scrypto_v1_minor_version, - } => { - VmVersion { - scrypto_v1_minor_version, - } + } => VmVersion { + scrypto_v1_minor_version, }, }; From 284aa4548e666fccfdc2e2b86b5e012788ee2921 Mon Sep 17 00:00:00 2001 From: Joshua Primero Date: Fri, 12 Jan 2024 15:50:06 -0600 Subject: [PATCH 81/82] Some cleanup --- radix-engine/src/vm/wasm/prepare.rs | 17 ++++++++++------- radix-engine/src/vm/wasm/wasm_validator.rs | 2 +- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/radix-engine/src/vm/wasm/prepare.rs b/radix-engine/src/vm/wasm/prepare.rs index e645dc7f29d..e6d19ad571b 100644 --- a/radix-engine/src/vm/wasm/prepare.rs +++ b/radix-engine/src/vm/wasm/prepare.rs @@ -11,6 +11,9 @@ use wasm_instrument::{ use wasmparser::{ExternalKind, FuncType, Operator, Type, TypeRef, ValType, WasmFeatures}; use super::WasmiModule; + +pub const SCRPYTO_VM_CRYPTO_UTILS_MINOR_VERSION: u64 = 1u64; + #[derive(Debug)] pub struct WasmModule { module: ModuleInfo, @@ -59,7 +62,7 @@ impl WasmModule { } } - pub fn enforce_import_limit(self, minor_version: u64) -> Result { + pub fn enforce_import_constraints(self, minor_version: u64) -> Result { // Only allow `env::radix_engine` import for entry in self .module @@ -734,7 +737,7 @@ impl WasmModule { } } CRYPTO_UTILS_BLS12381_V1_VERIFY_FUNCTION_NAME => { - if minor_version < 1 { + if minor_version < SCRPYTO_VM_CRYPTO_UTILS_MINOR_VERSION { return Err(PrepareError::InvalidImport( InvalidImport::ImportNotAllowed(entry.name.to_string()), )); @@ -784,7 +787,7 @@ impl WasmModule { } } CRYPTO_UTILS_BLS12381_V1_FAST_AGGREGATE_VERIFY_FUNCTION_NAME => { - if minor_version < 1 { + if minor_version < SCRPYTO_VM_CRYPTO_UTILS_MINOR_VERSION { return Err(PrepareError::InvalidImport( InvalidImport::ImportNotAllowed(entry.name.to_string()), )); @@ -812,7 +815,7 @@ impl WasmModule { } } CRYPTO_UTILS_BLS12381_G2_SIGNATURE_AGGREGATE_FUNCTION_NAME => { - if minor_version < 1 { + if minor_version < SCRPYTO_VM_CRYPTO_UTILS_MINOR_VERSION { return Err(PrepareError::InvalidImport( InvalidImport::ImportNotAllowed(entry.name.to_string()), )); @@ -833,7 +836,7 @@ impl WasmModule { } } CRYPTO_UTILS_KECCAK256_HASH_FUNCTION_NAME => { - if minor_version < 1 { + if minor_version < SCRPYTO_VM_CRYPTO_UTILS_MINOR_VERSION { return Err(PrepareError::InvalidImport( InvalidImport::ImportNotAllowed(entry.name.to_string()), )); @@ -1360,7 +1363,7 @@ mod tests { PrepareError::InvalidImport(InvalidImport::ImportNotAllowed( "name_to_replace".to_string() )), - |s| WasmModule::enforce_import_limit(s, 0u64) + |s| WasmModule::enforce_import_constraints(s, 0u64) ); for name in [ @@ -1407,7 +1410,7 @@ mod tests { assert_invalid_wasm!( wat.replace("name_to_replace", name), PrepareError::InvalidImport(InvalidImport::InvalidFunctionType(name.to_string())), - |w| WasmModule::enforce_import_limit(w, 0u64) + |w| WasmModule::enforce_import_constraints(w, 0u64) ); } } diff --git a/radix-engine/src/vm/wasm/wasm_validator.rs b/radix-engine/src/vm/wasm/wasm_validator.rs index 86ec4934e62..d0b81ddb4f0 100644 --- a/radix-engine/src/vm/wasm/wasm_validator.rs +++ b/radix-engine/src/vm/wasm/wasm_validator.rs @@ -60,7 +60,7 @@ impl ScryptoV1WasmValidator { ) -> Result<(Vec, Vec), PrepareError> { WasmModule::init(code)? .enforce_no_start_function()? - .enforce_import_limit(self.minor_version)? + .enforce_import_constraints(self.minor_version)? .enforce_export_names()? .enforce_memory_limit_and_inject_max(self.max_memory_size_in_pages)? .enforce_table_limit(self.max_initial_table_size)? From cee6e5222ca296d01a8fb466bfa56a95a10b3d7f Mon Sep 17 00:00:00 2001 From: Joshua Primero Date: Fri, 12 Jan 2024 17:39:29 -0600 Subject: [PATCH 82/82] Some cleanup including removal of new HASH custom well known type --- radix-engine-common/src/crypto/hash.rs | 2 +- .../src/data/scrypto/custom_well_known_types.rs | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/radix-engine-common/src/crypto/hash.rs b/radix-engine-common/src/crypto/hash.rs index d56450d8a0e..c0875bb3473 100644 --- a/radix-engine-common/src/crypto/hash.rs +++ b/radix-engine-common/src/crypto/hash.rs @@ -76,7 +76,7 @@ pub fn hash>(data: T) -> Hash { //======== /// Represents an error when parsing hash. -#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)] +#[derive(Debug, Clone, PartialEq, Eq, Sbor)] pub enum ParseHashError { InvalidHex(String), InvalidLength(usize), diff --git a/radix-engine-common/src/data/scrypto/custom_well_known_types.rs b/radix-engine-common/src/data/scrypto/custom_well_known_types.rs index 8df5f17d99b..bdef76f0a21 100644 --- a/radix-engine-common/src/data/scrypto/custom_well_known_types.rs +++ b/radix-engine-common/src/data/scrypto/custom_well_known_types.rs @@ -379,11 +379,6 @@ create_well_known_lookup!( MISC_TYPES_START + 7, named_transparent("Origin", string_type_data(),) ), - ( - HASH, - MISC_TYPES_START + 8, - named_transparent("Hash", bytes_fixed_length_type_data(Hash::LENGTH),) - ), // Crypto-related types from CRYPTO_TYPES_START ( PUBLIC_KEY,