diff --git a/Cargo.lock b/Cargo.lock index 854a9b37d..e2544b3bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -100,6 +100,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64" version = "0.13.1" @@ -112,6 +118,12 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f1e31e207a6b8fb791a38ea3105e6cb541f55e4d029902d3039a4ad07cc4105" +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + [[package]] name = "bitflags" version = "1.3.2" @@ -127,6 +139,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + [[package]] name = "bumpalo" version = "3.13.0" @@ -208,6 +229,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "const-oid" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" + [[package]] name = "core-foundation-sys" version = "0.8.4" @@ -234,15 +261,37 @@ dependencies = [ "serde_json", ] +[[package]] +name = "crypto-bigint" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4c2f4e1afd912bc40bfd6fed5d9dc1f288e0ba01bfcc835cc5bc3eb13efe15" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + [[package]] name = "curve25519-dalek" -version = "3.2.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" dependencies = [ "byteorder", - "digest", - "rand_core", + "digest 0.9.0", + "rand_core 0.5.1", "subtle", "zeroize", ] @@ -282,6 +331,16 @@ dependencies = [ "syn 2.0.16", ] +[[package]] +name = "der" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56acb310e15652100da43d130af8d97b509e95af61aab1c5a7939ef24337ee17" +dependencies = [ + "const-oid", + "zeroize", +] + [[package]] name = "derive_arbitrary" version = "1.3.0" @@ -302,6 +361,18 @@ 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 0.10.4", + "const-oid", + "crypto-common", + "subtle", +] + [[package]] name = "dissimilar" version = "1.0.6" @@ -324,13 +395,27 @@ dependencies = [ "fnv", ] +[[package]] +name = "ecdsa" +version = "0.16.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0997c976637b606099b9985693efa3581e84e41f5c11ba5255f88711058ad428" +dependencies = [ + "der", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "signature 2.1.0", + "spki", +] + [[package]] name = "ed25519" version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" dependencies = [ - "signature", + "signature 1.6.4", ] [[package]] @@ -343,7 +428,7 @@ dependencies = [ "ed25519", "rand", "serde", - "sha2", + "sha2 0.9.9", "zeroize", ] @@ -353,6 +438,25 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +[[package]] +name = "elliptic-curve" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest 0.10.7", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + [[package]] name = "env_logger" version = "0.9.3" @@ -382,6 +486,16 @@ dependencies = [ "once_cell", ] +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "fnv" version = "1.0.7" @@ -405,6 +519,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -415,7 +530,18 @@ checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", ] [[package]] @@ -424,6 +550,17 @@ version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -457,6 +594,15 @@ dependencies = [ "serde", ] +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + [[package]] name = "humantime" version = "2.1.0" @@ -570,6 +716,29 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "k256" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2 0.10.6", + "signature 2.1.0", +] + +[[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" @@ -805,6 +974,16 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -869,10 +1048,10 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ - "getrandom", + "getrandom 0.1.16", "libc", "rand_chacha", - "rand_core", + "rand_core 0.5.1", "rand_hc", ] @@ -883,7 +1062,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.5.1", ] [[package]] @@ -892,7 +1071,16 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "getrandom", + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.10", ] [[package]] @@ -901,7 +1089,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ - "rand_core", + "rand_core 0.5.1", ] [[package]] @@ -927,6 +1115,16 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + [[package]] name = "rgb" version = "0.8.36" @@ -957,6 +1155,20 @@ dependencies = [ "bytemuck", ] +[[package]] +name = "sec1" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0aec48e813d6b90b15f0b8948af3c63483992dee44c03e9930b3eebdabe046e" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + [[package]] name = "serde" version = "1.0.163" @@ -1022,19 +1234,50 @@ version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ - "block-buffer", + "block-buffer 0.9.0", "cfg-if", "cpufeatures", - "digest", + "digest 0.9.0", "opaque-debug", ] +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[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 = "signature" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + [[package]] name = "simba" version = "0.8.1" @@ -1089,6 +1332,7 @@ dependencies = [ "expect-test", "hex", "itertools", + "k256", "linregress", "log", "more-asserts", @@ -1098,7 +1342,8 @@ dependencies = [ "perf-event", "rand", "rand_chacha", - "sha2", + "sha2 0.9.9", + "sha3", "soroban-env-common", "soroban-native-sdk-macros", "soroban-synth-wasm", @@ -1181,6 +1426,16 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "spki" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "static_assertions" version = "1.1.0" @@ -1190,7 +1445,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "stellar-xdr" version = "0.0.16" -source = "git+https://github.com/stellar/rs-stellar-xdr?rev=3429ea634df58aadf836790de8bbea21b7e82651#3429ea634df58aadf836790de8bbea21b7e82651" +source = "git+https://github.com/stellar/rs-stellar-xdr?rev=eafa8b74e3814d738e2bd948b556f8f3c8a76659#eafa8b74e3814d738e2bd948b556f8f3c8a76659" dependencies = [ "arbitrary", "base64 0.13.1", @@ -1502,6 +1757,12 @@ 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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "wasm-bindgen" version = "0.2.86" @@ -1717,9 +1978,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.3.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" dependencies = [ "zeroize_derive", ] diff --git a/Cargo.toml b/Cargo.toml index 60ece3a13..03e74701d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ soroban-native-sdk-macros = { version = "0.0.16", path = "soroban-native-sdk-mac [workspace.dependencies.stellar-xdr] version = "0.0.16" git = "https://github.com/stellar/rs-stellar-xdr" -rev = "3429ea634df58aadf836790de8bbea21b7e82651" +rev = "eafa8b74e3814d738e2bd948b556f8f3c8a76659" default-features = false [workspace.dependencies.wasmi] diff --git a/soroban-env-common/env.json b/soroban-env-common/env.json index 19a609161..b2c63b3ff 100644 --- a/soroban-env-common/env.json +++ b/soroban-env-common/env.json @@ -1548,6 +1548,58 @@ } ], "return": "Void" + }, + { + "export": "1", + "name": "compute_hash_keccak256", + "args": [ + { + "name": "x", + "type": "BytesObject" + } + ], + "return": "BytesObject", + "docs": "Returns the keccak256 hash of given input bytes." + }, + { + "export": "2", + "name": "verify_sig_ecdsa_secp256k1", + "args": [ + { + "name": "public_key", + "type": "BytesObject" + }, + { + "name": "message", + "type": "BytesObject" + }, + { + "name": "signature", + "type": "BytesObject" + } + ], + "return": "Void", + "docs": "Verifies that a given SEC-1-encoded ECDSA secp256k1 public key, signing a given message, produced a given 64-byte signature." + }, + { + "export": "3", + "name": "recover_key_ecdsa_secp256k1", + "args": [ + { + "name": "msg_digest", + "type": "BytesObject" + }, + { + "name": "signature", + "type": "BytesObject" + }, + { + "name": "recovery_id", + "type": "U32Val" + } + ], + "return": "BytesObject", + "docs": "Recovers the SEC-1-encoded ECDSA secp256k1 public key that produced a given 64-byte signature over a given 32-byte message digest, for a given recovery_id byte." } ] }, diff --git a/soroban-env-common/src/meta.rs b/soroban-env-common/src/meta.rs index c71acf2b4..a8940bb0e 100644 --- a/soroban-env-common/src/meta.rs +++ b/soroban-env-common/src/meta.rs @@ -42,7 +42,7 @@ pub const ENV_META_V0_SECTION_NAME: &str = "contractenvmetav0"; soroban_env_macros::generate_env_meta_consts!( ledger_protocol_version: 20, - pre_release_version: 43, + pre_release_version: 44, ); pub fn get_ledger_protocol_version(interface_version: u64) -> u32 { diff --git a/soroban-env-host/Cargo.toml b/soroban-env-host/Cargo.toml index dd845dcca..e53fe70f3 100644 --- a/soroban-env-host/Cargo.toml +++ b/soroban-env-host/Cargo.toml @@ -29,6 +29,8 @@ num-integer = "0.1.45" num-derive = "0.3.3" log = "0.4.17" backtrace = "0.3" +k256 = {version = "0.13.1", features=["ecdsa", "arithmetic"]} +sha3 = "0.10.8" [dev-dependencies] env_logger = "0.9.0" diff --git a/soroban-env-host/benches/common/cost_types/compute_ecdsa_secp256k1_pubkey.rs b/soroban-env-host/benches/common/cost_types/compute_ecdsa_secp256k1_pubkey.rs new file mode 100644 index 000000000..2264791a2 --- /dev/null +++ b/soroban-env-host/benches/common/cost_types/compute_ecdsa_secp256k1_pubkey.rs @@ -0,0 +1,26 @@ +use crate::common::HostCostMeasurement; +use k256::{PublicKey, SecretKey}; +use rand::rngs::StdRng; +use soroban_env_host::{cost_runner::ComputeEcdsaSecp256k1PubKeyRun, Host}; + +// This measures the costs to turn one byte buffer into an EcdsaSecp256k1 +// pubkey, which should be constant time. The input value is ignored. +pub(crate) struct ComputeEcdsaSecp256k1PubKeyMeasure { + key: Vec, +} + +impl HostCostMeasurement for ComputeEcdsaSecp256k1PubKeyMeasure { + type Runner = ComputeEcdsaSecp256k1PubKeyRun; + + fn new_random_case(_host: &Host, _rng: &mut StdRng, _input: u64) -> Vec { + // Very awkward: the 'rand' crate has two copies linked in due to + // divergence between the requirements of k256 and ed25519. The StdRng + // we're getting here is not the one k256 wants. So we use an OsRng + // here, from the package k256 wants (and re-exports). + let mut rng = k256::elliptic_curve::rand_core::OsRng; + + let secret = SecretKey::random(&mut rng); + let public: PublicKey = secret.public_key(); + public.to_sec1_bytes().into_vec() + } +} diff --git a/soroban-env-host/benches/common/cost_types/compute_ecdsa_secp256k1_sig.rs b/soroban-env-host/benches/common/cost_types/compute_ecdsa_secp256k1_sig.rs new file mode 100644 index 000000000..171c67087 --- /dev/null +++ b/soroban-env-host/benches/common/cost_types/compute_ecdsa_secp256k1_sig.rs @@ -0,0 +1,32 @@ +use crate::common::HostCostMeasurement; +use k256::{ + ecdsa::{signature::Signer, Signature, SigningKey}, + SecretKey, +}; +use rand::rngs::StdRng; +use soroban_env_host::{cost_runner::ComputeEcdsaSecp256k1SigRun, Host}; + +// This measures the costs to turn one byte buffer into an EcdsaSecp256k1 +// signature, which should be constant time. The input value is ignored. +pub(crate) struct ComputeEcdsaSecp256k1SigMeasure { + sig: Vec, +} + +impl HostCostMeasurement for ComputeEcdsaSecp256k1SigMeasure { + type Runner = ComputeEcdsaSecp256k1SigRun; + + fn new_random_case(_host: &Host, _rng: &mut StdRng, input: u64) -> Vec { + let size = 1 + input * Self::STEP_SIZE; + + // Very awkward: the 'rand' crate has two copies linked in due to + // divergence between the requirements of k256 and ed25519. The StdRng + // we're getting here is not the one k256 wants. So we use an OsRng + // here, from the package k256 wants (and re-exports). + let mut rng = k256::elliptic_curve::rand_core::OsRng; + + let sec: SecretKey = SecretKey::random(&mut rng); + let msg: Vec = (0..size).map(|x| x as u8).collect(); + let sig: Signature = SigningKey::from(sec).try_sign(msg.as_slice()).unwrap(); + sig.to_bytes().to_vec() + } +} diff --git a/soroban-env-host/benches/common/cost_types/compute_keccak256_hash.rs b/soroban-env-host/benches/common/cost_types/compute_keccak256_hash.rs new file mode 100644 index 000000000..e76f3d219 --- /dev/null +++ b/soroban-env-host/benches/common/cost_types/compute_keccak256_hash.rs @@ -0,0 +1,19 @@ +use crate::common::HostCostMeasurement; +use rand::rngs::StdRng; +use soroban_env_host::{cost_runner::ComputeKeccak256HashRun, Host}; + +// This measures the costs of performing a keccak256 hash on a variable-sized +// byte buffer. The input value is the size of the buffer. It should be +// linear time. +pub(crate) struct ComputeKeccak256HashMeasure; + +impl HostCostMeasurement for ComputeKeccak256HashMeasure { + type Runner = ComputeKeccak256HashRun; + + const STEP_SIZE: u64 = 100; + + fn new_random_case(_host: &Host, _rng: &mut StdRng, input: u64) -> Vec { + let size = 1 + input * Self::STEP_SIZE; + (0..size).map(|n| n as u8).collect() + } +} diff --git a/soroban-env-host/benches/common/cost_types/mod.rs b/soroban-env-host/benches/common/cost_types/mod.rs index 2738ff899..26bec45d8 100644 --- a/soroban-env-host/benches/common/cost_types/mod.rs +++ b/soroban-env-host/benches/common/cost_types/mod.rs @@ -1,5 +1,8 @@ mod charge_budget; +mod compute_ecdsa_secp256k1_pubkey; +mod compute_ecdsa_secp256k1_sig; mod compute_ed25519_pubkey; +mod compute_keccak256_hash; mod compute_sha256_hash; mod guard_frame; mod host_mem_alloc; @@ -7,17 +10,22 @@ mod host_mem_cmp; mod host_mem_cpy; mod invoke; mod map_ops; +mod recover_ecdsa_secp256k1_key; mod val_deser; mod val_ser; mod val_xdr_conv; mod vec_ops; +mod verify_ecdsa_secp256k1_sig; mod verify_ed25519_sig; mod visit_object; mod vm_ops; mod wasm_insn_exec; pub(crate) use charge_budget::*; +pub(crate) use compute_ecdsa_secp256k1_pubkey::*; +pub(crate) use compute_ecdsa_secp256k1_sig::*; pub(crate) use compute_ed25519_pubkey::*; +pub(crate) use compute_keccak256_hash::*; pub(crate) use compute_sha256_hash::*; pub(crate) use guard_frame::*; pub(crate) use host_mem_alloc::*; @@ -25,10 +33,12 @@ pub(crate) use host_mem_cmp::*; pub(crate) use host_mem_cpy::*; pub(crate) use invoke::*; pub(crate) use map_ops::*; +pub(crate) use recover_ecdsa_secp256k1_key::*; pub(crate) use val_deser::*; pub(crate) use val_ser::*; pub(crate) use val_xdr_conv::*; pub(crate) use vec_ops::*; +pub(crate) use verify_ecdsa_secp256k1_sig::*; pub(crate) use verify_ed25519_sig::*; pub(crate) use visit_object::*; pub(crate) use vm_ops::*; diff --git a/soroban-env-host/benches/common/cost_types/recover_ecdsa_secp256k1_key.rs b/soroban-env-host/benches/common/cost_types/recover_ecdsa_secp256k1_key.rs new file mode 100644 index 000000000..3d390be69 --- /dev/null +++ b/soroban-env-host/benches/common/cost_types/recover_ecdsa_secp256k1_key.rs @@ -0,0 +1,41 @@ +use crate::common::HostCostMeasurement; +use k256::{ecdsa::SigningKey, SecretKey}; +use rand::rngs::StdRng; +use sha3::{Digest, Keccak256}; +use soroban_env_host::{ + cost_runner::{RecoverEcdsaSecp256k1KeyRun, RecoverEcdsaSecp256k1KeySample}, + xdr::Hash, + Host, +}; + +pub(crate) struct RecoverEcdsaSecp256k1KeyMeasure; + +// This measures the cost of verifying an EcdsaSecp256k1 signature of varying-length +// messages. The input value is the length of the signed message. It should cost +// linear CPU (for hashing) and zero heap memory. +impl HostCostMeasurement for RecoverEcdsaSecp256k1KeyMeasure { + type Runner = RecoverEcdsaSecp256k1KeyRun; + + const STEP_SIZE: u64 = 1000; + + fn new_random_case( + _host: &Host, + _rng: &mut StdRng, + input: u64, + ) -> RecoverEcdsaSecp256k1KeySample { + // Very awkward: the 'rand' crate has two copies linked in due to + // divergence between the requirements of k256 and ed25519. The StdRng + // we're getting here is not the one k256 wants. So we use an OsRng + // here, from the package k256 wants (and re-exports). + let mut rng = k256::elliptic_curve::rand_core::OsRng; + + let size = 1 + input * Self::STEP_SIZE; + let sec: SecretKey = SecretKey::random(&mut rng); + let msg: Vec = (0..size).map(|x| x as u8).collect(); + let hash: Hash = Hash(Keccak256::digest(msg).into()); + let (sig, rid) = SigningKey::from(sec) + .sign_prehash_recoverable(hash.as_slice()) + .unwrap(); + RecoverEcdsaSecp256k1KeySample { hash, sig, rid } + } +} diff --git a/soroban-env-host/benches/common/cost_types/verify_ecdsa_secp256k1_sig.rs b/soroban-env-host/benches/common/cost_types/verify_ecdsa_secp256k1_sig.rs new file mode 100644 index 000000000..146967209 --- /dev/null +++ b/soroban-env-host/benches/common/cost_types/verify_ecdsa_secp256k1_sig.rs @@ -0,0 +1,41 @@ +use crate::common::HostCostMeasurement; +use k256::{ + ecdsa::{signature::Signer, Signature, SigningKey}, + PublicKey, SecretKey, +}; +use rand::rngs::StdRng; +use soroban_env_host::{ + cost_runner::{VerifyEcdsaSecp256k1SigRun, VerifyEcdsaSecp256k1SigSample}, + Host, +}; + +pub(crate) struct VerifyEcdsaSecp256k1SigMeasure; + +// This measures the cost of verifying an EcdsaSecp256k1 signature of varying-length +// messages. The input value is the length of the signed message. It should cost +// linear CPU (for hashing) and zero heap memory. +impl HostCostMeasurement for VerifyEcdsaSecp256k1SigMeasure { + type Runner = VerifyEcdsaSecp256k1SigRun; + + const STEP_SIZE: u64 = 1000; + + fn new_random_case( + _host: &Host, + _rng: &mut StdRng, + input: u64, + ) -> VerifyEcdsaSecp256k1SigSample { + let size = 1 + input * Self::STEP_SIZE; + + // Very awkward: the 'rand' crate has two copies linked in due to + // divergence between the requirements of k256 and ed25519. The StdRng + // we're getting here is not the one k256 wants. So we use an OsRng + // here, from the package k256 wants (and re-exports). + let mut rng = k256::elliptic_curve::rand_core::OsRng; + + let sec: SecretKey = SecretKey::random(&mut rng); + let key: PublicKey = sec.public_key(); + let msg: Vec = (0..size).map(|x| x as u8).collect(); + let sig: Signature = SigningKey::from(sec).try_sign(msg.as_slice()).unwrap(); + VerifyEcdsaSecp256k1SigSample { key, msg, sig } + } +} diff --git a/soroban-env-host/benches/common/mod.rs b/soroban-env-host/benches/common/mod.rs index abe741e2e..ebe60b937 100644 --- a/soroban-env-host/benches/common/mod.rs +++ b/soroban-env-host/benches/common/mod.rs @@ -62,8 +62,13 @@ pub(crate) fn for_each_host_cost_measurement( ) -> std::io::Result> { let mut params: BTreeMap = BTreeMap::new(); + call_bench::(&mut params)?; + call_bench::(&mut params)?; call_bench::(&mut params)?; + call_bench::(&mut params)?; call_bench::(&mut params)?; + call_bench::(&mut params)?; + call_bench::(&mut params)?; call_bench::(&mut params)?; call_bench::(&mut params)?; call_bench::(&mut params)?; diff --git a/soroban-env-host/src/budget.rs b/soroban-env-host/src/budget.rs index 3c8bd3285..43fad2b3c 100644 --- a/soroban-env-host/src/budget.rs +++ b/soroban-env-host/src/budget.rs @@ -304,12 +304,17 @@ impl BudgetImpl { ContractCostType::MapEntry => (), ContractCostType::VecEntry => (), ContractCostType::GuardFrame => (), - ContractCostType::VerifyEd25519Sig => self.tracker[i].1 = Some(0), // length of the signature buffer + ContractCostType::VerifyEd25519Sig => self.tracker[i].1 = Some(0), // length of the signed message ContractCostType::VmMemRead => self.tracker[i].1 = Some(0), // number of bytes in the linear memory to read ContractCostType::VmMemWrite => self.tracker[i].1 = Some(0), // number of bytes in the linear memory to write ContractCostType::VmInstantiation => self.tracker[i].1 = Some(0), // length of the wasm bytes, ContractCostType::InvokeVmFunction => (), ContractCostType::ChargeBudget => (), + ContractCostType::ComputeKeccak256Hash => self.tracker[i].1 = Some(0), // number of bytes in the buffer + ContractCostType::ComputeEcdsaSecp256k1Key => (), + ContractCostType::ComputeEcdsaSecp256k1Sig => (), + ContractCostType::VerifyEcdsaSecp256k1Sig => self.tracker[i].1 = Some(0), // length of the signed message + ContractCostType::RecoverEcdsaSecp256k1Key => (), } } } @@ -804,6 +809,26 @@ impl Default for BudgetImpl { cpu.const_term = 130; cpu.linear_term = 0; } + ContractCostType::ComputeKeccak256Hash => { + cpu.const_term = 3322; + cpu.linear_term = 46; + } + ContractCostType::ComputeEcdsaSecp256k1Key => { + cpu.const_term = 56525; + cpu.linear_term = 0; + } + ContractCostType::ComputeEcdsaSecp256k1Sig => { + cpu.const_term = 250; + cpu.linear_term = 0; + } + ContractCostType::VerifyEcdsaSecp256k1Sig => { + cpu.const_term = 1109918; + cpu.linear_term = 53; + } + ContractCostType::RecoverEcdsaSecp256k1Key => { + cpu.const_term = 2319640; + cpu.linear_term = 0; + } } // define the memory cost model parameters @@ -897,6 +922,26 @@ impl Default for BudgetImpl { mem.const_term = 0; mem.linear_term = 0; } + ContractCostType::ComputeKeccak256Hash => { + mem.const_term = 40; + mem.linear_term = 0; + } + ContractCostType::ComputeEcdsaSecp256k1Key => { + mem.const_term = 0; + mem.linear_term = 0; + } + ContractCostType::ComputeEcdsaSecp256k1Sig => { + mem.const_term = 0; + mem.linear_term = 0; + } + ContractCostType::VerifyEcdsaSecp256k1Sig => { + mem.const_term = 0; + mem.linear_term = 0; + } + ContractCostType::RecoverEcdsaSecp256k1Key => { + mem.const_term = 181; + mem.linear_term = 0; + } } b.init_tracker(); diff --git a/soroban-env-host/src/cost_runner/cost_types/compute_ecdsa_secp256k1_pubkey.rs b/soroban-env-host/src/cost_runner/cost_types/compute_ecdsa_secp256k1_pubkey.rs new file mode 100644 index 000000000..77347048b --- /dev/null +++ b/soroban-env-host/src/cost_runner/cost_types/compute_ecdsa_secp256k1_pubkey.rs @@ -0,0 +1,32 @@ +use std::hint::black_box; + +use k256::PublicKey; + +use crate::{cost_runner::CostRunner, xdr::ContractCostType}; + +pub struct ComputeEcdsaSecp256k1PubKeyRun; + +impl CostRunner for ComputeEcdsaSecp256k1PubKeyRun { + const COST_TYPE: ContractCostType = ContractCostType::ComputeEcdsaSecp256k1Key; + + type SampleType = Vec; + + type RecycledType = (Option, Vec); + + fn run_iter(host: &crate::Host, _iter: u64, sample: Self::SampleType) -> Self::RecycledType { + let pk = black_box( + host.secp256k1_pub_key_from_bytes(sample.as_slice()) + .expect("ecdsa secp256k1 publickey"), + ); + (Some(pk), sample) + } + + fn run_baseline_iter( + host: &crate::Host, + _iter: u64, + sample: Self::SampleType, + ) -> Self::RecycledType { + black_box(host.charge_budget(Self::COST_TYPE, None).unwrap()); + black_box((None, sample)) + } +} diff --git a/soroban-env-host/src/cost_runner/cost_types/compute_ecdsa_secp256k1_sig.rs b/soroban-env-host/src/cost_runner/cost_types/compute_ecdsa_secp256k1_sig.rs new file mode 100644 index 000000000..246afacbb --- /dev/null +++ b/soroban-env-host/src/cost_runner/cost_types/compute_ecdsa_secp256k1_sig.rs @@ -0,0 +1,32 @@ +use std::hint::black_box; + +use k256::ecdsa::Signature; + +use crate::{cost_runner::CostRunner, xdr::ContractCostType}; + +pub struct ComputeEcdsaSecp256k1SigRun; + +impl CostRunner for ComputeEcdsaSecp256k1SigRun { + const COST_TYPE: ContractCostType = ContractCostType::ComputeEcdsaSecp256k1Sig; + + type SampleType = Vec; + + type RecycledType = (Option, Vec); + + fn run_iter(host: &crate::Host, _iter: u64, sample: Self::SampleType) -> Self::RecycledType { + let pk = black_box( + host.secp256k1_signature_from_bytes(sample.as_slice()) + .expect("ecdsa secp256k1 signature"), + ); + (Some(pk), sample) + } + + fn run_baseline_iter( + host: &crate::Host, + _iter: u64, + sample: Self::SampleType, + ) -> Self::RecycledType { + black_box(host.charge_budget(Self::COST_TYPE, None).unwrap()); + black_box((None, sample)) + } +} diff --git a/soroban-env-host/src/cost_runner/cost_types/compute_ed25519_pubkey.rs b/soroban-env-host/src/cost_runner/cost_types/compute_ed25519_pubkey.rs index 9a8837166..135f9642c 100644 --- a/soroban-env-host/src/cost_runner/cost_types/compute_ed25519_pubkey.rs +++ b/soroban-env-host/src/cost_runner/cost_types/compute_ed25519_pubkey.rs @@ -16,7 +16,7 @@ impl CostRunner for ComputeEd25519PubKeyRun { fn run_iter(host: &crate::Host, _iter: u64, sample: Self::SampleType) -> Self::RecycledType { let pk = black_box( host.ed25519_pub_key_from_bytes(sample.as_slice()) - .expect("publickey"), + .expect("ed25519 publickey"), ); (Some(pk), sample) } diff --git a/soroban-env-host/src/cost_runner/cost_types/compute_keccak256_hash.rs b/soroban-env-host/src/cost_runner/cost_types/compute_keccak256_hash.rs new file mode 100644 index 000000000..991d95b5c --- /dev/null +++ b/soroban-env-host/src/cost_runner/cost_types/compute_keccak256_hash.rs @@ -0,0 +1,30 @@ +use std::hint::black_box; + +use crate::{cost_runner::CostRunner, xdr::ContractCostType}; + +pub struct ComputeKeccak256HashRun; + +impl CostRunner for ComputeKeccak256HashRun { + const COST_TYPE: ContractCostType = ContractCostType::ComputeKeccak256Hash; + + type SampleType = Vec; + + type RecycledType = (Option>, Vec); + + fn run_iter(host: &crate::Host, _iter: u64, sample: Self::SampleType) -> Self::RecycledType { + let hash = black_box( + host.keccak256_hash_from_bytes(sample.as_slice()) + .expect("keccak256"), + ); + (Some(hash), sample) + } + + fn run_baseline_iter( + host: &crate::Host, + _iter: u64, + sample: Self::SampleType, + ) -> Self::RecycledType { + black_box(host.charge_budget(Self::COST_TYPE, Some(0)).unwrap()); + black_box((None, sample)) + } +} diff --git a/soroban-env-host/src/cost_runner/cost_types/mod.rs b/soroban-env-host/src/cost_runner/cost_types/mod.rs index b5321d524..d90d8d936 100644 --- a/soroban-env-host/src/cost_runner/cost_types/mod.rs +++ b/soroban-env-host/src/cost_runner/cost_types/mod.rs @@ -1,5 +1,8 @@ mod charge_budget; +mod compute_ecdsa_secp256k1_pubkey; +mod compute_ecdsa_secp256k1_sig; mod compute_ed25519_pubkey; +mod compute_keccak256_hash; mod compute_sha256_hash; mod guard_frame; mod host_mem_alloc; @@ -7,17 +10,22 @@ mod host_mem_cmp; mod host_mem_cpy; mod invoke; mod map_ops; +mod recover_ecdsa_secp256k1_key; mod val_deser; mod val_ser; mod val_xdr_conv; mod vec_ops; +mod verify_ecdsa_secp256k1_sig; mod verify_ed25519_sig; mod visit_object; mod vm_ops; mod wasm_insn_exec; pub use charge_budget::*; +pub use compute_ecdsa_secp256k1_pubkey::*; +pub use compute_ecdsa_secp256k1_sig::*; pub use compute_ed25519_pubkey::*; +pub use compute_keccak256_hash::*; pub use compute_sha256_hash::*; pub use guard_frame::*; pub use host_mem_alloc::*; @@ -25,10 +33,12 @@ pub use host_mem_cmp::*; pub use host_mem_cpy::*; pub use invoke::*; pub use map_ops::*; +pub use recover_ecdsa_secp256k1_key::*; pub use val_deser::*; pub use val_ser::*; pub use val_xdr_conv::*; pub use vec_ops::*; +pub use verify_ecdsa_secp256k1_sig::*; pub use verify_ed25519_sig::*; pub use visit_object::*; pub use vm_ops::*; diff --git a/soroban-env-host/src/cost_runner/cost_types/recover_ecdsa_secp256k1_key.rs b/soroban-env-host/src/cost_runner/cost_types/recover_ecdsa_secp256k1_key.rs new file mode 100644 index 000000000..6a821e828 --- /dev/null +++ b/soroban-env-host/src/cost_runner/cost_types/recover_ecdsa_secp256k1_key.rs @@ -0,0 +1,41 @@ +use std::hint::black_box; + +use crate::{ + cost_runner::CostRunner, + xdr::{ContractCostType, Hash}, +}; +use k256::ecdsa::{RecoveryId, Signature}; + +pub struct RecoverEcdsaSecp256k1KeyRun; + +#[derive(Clone)] +pub struct RecoverEcdsaSecp256k1KeySample { + pub hash: Hash, + pub sig: Signature, + pub rid: RecoveryId, +} + +impl CostRunner for RecoverEcdsaSecp256k1KeyRun { + const COST_TYPE: ContractCostType = ContractCostType::RecoverEcdsaSecp256k1Key; + + type SampleType = RecoverEcdsaSecp256k1KeySample; + + type RecycledType = Self::SampleType; + + fn run_iter(host: &crate::Host, _iter: u64, sample: Self::SampleType) -> Self::RecycledType { + black_box( + host.recover_key_ecdsa_secp256k1_internal(&sample.hash, &sample.sig, sample.rid) + .expect("recover ecdsa secp256k1 key"), + ); + sample + } + + fn run_baseline_iter( + host: &crate::Host, + _iter: u64, + sample: Self::SampleType, + ) -> Self::RecycledType { + black_box(host.charge_budget(Self::COST_TYPE, None).unwrap()); + black_box(sample) + } +} diff --git a/soroban-env-host/src/cost_runner/cost_types/verify_ecdsa_secp256k1_sig.rs b/soroban-env-host/src/cost_runner/cost_types/verify_ecdsa_secp256k1_sig.rs new file mode 100644 index 000000000..bf95b0b8b --- /dev/null +++ b/soroban-env-host/src/cost_runner/cost_types/verify_ecdsa_secp256k1_sig.rs @@ -0,0 +1,42 @@ +use std::hint::black_box; + +use crate::{cost_runner::CostRunner, xdr::ContractCostType}; +use k256::{ecdsa::Signature, PublicKey}; + +pub struct VerifyEcdsaSecp256k1SigRun; + +#[derive(Clone)] +pub struct VerifyEcdsaSecp256k1SigSample { + pub key: PublicKey, + pub msg: Vec, + pub sig: Signature, +} + +impl CostRunner for VerifyEcdsaSecp256k1SigRun { + const COST_TYPE: ContractCostType = ContractCostType::VerifyEcdsaSecp256k1Sig; + + type SampleType = VerifyEcdsaSecp256k1SigSample; + + type RecycledType = Self::SampleType; + + fn run_iter(host: &crate::Host, _iter: u64, sample: Self::SampleType) -> Self::RecycledType { + black_box( + host.verify_sig_ecdsa_secp256k1_internal( + sample.msg.as_slice(), + &sample.key, + &sample.sig, + ) + .expect("verify sig ecdsa secp256k1"), + ); + sample + } + + fn run_baseline_iter( + host: &crate::Host, + _iter: u64, + sample: Self::SampleType, + ) -> Self::RecycledType { + black_box(host.charge_budget(Self::COST_TYPE, Some(0)).unwrap()); + black_box(sample) + } +} diff --git a/soroban-env-host/src/host.rs b/soroban-env-host/src/host.rs index dda5cc1eb..5f3fbadc5 100644 --- a/soroban-env-host/src/host.rs +++ b/soroban-env-host/src/host.rs @@ -29,6 +29,7 @@ use crate::{EnvBase, Object, RawVal, Symbol}; pub(crate) mod comparison; mod conversion; +mod crypto; mod data_helper; pub(crate) mod declared_size; pub(crate) mod error; @@ -569,27 +570,6 @@ impl Host { Ok(hash_obj) } - pub(crate) fn verify_sig_ed25519_internal( - &self, - payload: &[u8], - public_key: &ed25519_dalek::PublicKey, - sig: &ed25519_dalek::Signature, - ) -> Result<(), HostError> { - use ed25519_dalek::Verifier; - self.charge_budget( - ContractCostType::VerifyEd25519Sig, - Some(payload.len() as u64), - )?; - public_key.verify(payload, sig).map_err(|_| { - self.err( - ScErrorType::Crypto, - ScErrorCode::InvalidInput, - "failed ED25519 verification", - &[], - ) - }) - } - // Returns the recorded per-address authorization payloads that would cover the // top-level contract function invocation in the enforcing mode. // This should only be called in the recording authorization mode, i.e. only @@ -1861,7 +1841,7 @@ impl VmCallerEnv for Host { address: self.visit_obj(deployer, |addr: &ScAddress| { addr.metered_clone(self.budget_ref()) })?, - salt: self.uint256_from_bytesobj_input("contract_id_salt", salt)?, + salt: self.u256_from_bytesobj_input("contract_id_salt", salt)?, }); let executable = ScContractExecutable::WasmRef(self.hash_from_bytesobj_input("wasm_hash", wasm_hash)?); @@ -2395,6 +2375,16 @@ impl VmCallerEnv for Host { self.add_host_object(self.scbytes_from_vec(hash)?) } + // Notes on metering: covered by components. + fn compute_hash_keccak256( + &self, + _vmcaller: &mut VmCaller, + x: BytesObject, + ) -> Result { + let hash = self.keccak256_hash_from_bytesobj_input(x)?; + self.add_host_object(self.scbytes_from_vec(hash)?) + } + // Notes on metering: covered by components. fn verify_sig_ed25519( &self, @@ -2404,13 +2394,42 @@ impl VmCallerEnv for Host { s: BytesObject, ) -> Result { let public_key = self.ed25519_pub_key_from_bytesobj_input(k)?; - let sig = self.signature_from_bytesobj_input("sig", s)?; + let sig = self.ed25519_signature_from_bytesobj_input("sig", s)?; let res = self.visit_obj(x, |payload: &ScBytes| { self.verify_sig_ed25519_internal(payload.as_slice(), &public_key, &sig) }); Ok(res?.into()) } + // Notes on metering: covered by components. + fn verify_sig_ecdsa_secp256k1( + &self, + _vmcaller: &mut VmCaller, + public_key: BytesObject, + message: BytesObject, + signature: BytesObject, + ) -> Result { + let public_key = self.secp256k1_pub_key_from_bytesobj_input(public_key)?; + let sig = self.secp256k1_signature_from_bytesobj_input(signature)?; + let res = self.visit_obj(message, |payload: &ScBytes| { + self.verify_sig_ecdsa_secp256k1_internal(payload.as_slice(), &public_key, &sig) + }); + Ok(res?.into()) + } + + fn recover_key_ecdsa_secp256k1( + &self, + _vmcaller: &mut VmCaller, + msg_digest: BytesObject, + signature: BytesObject, + recovery_id: U32Val, + ) -> Result { + let sig = self.secp256k1_signature_from_bytesobj_input(signature)?; + let rid = self.secp256k1_recovery_id_from_u32val(recovery_id)?; + let hash = self.hash_from_bytesobj_input("msg_digest", msg_digest)?; + self.recover_key_ecdsa_secp256k1_internal(&hash, &sig, rid) + } + fn get_ledger_version(&self, _vmcaller: &mut VmCaller) -> Result { self.with_ledger_info(|li| Ok(li.protocol_version.into())) } diff --git a/soroban-env-host/src/host/conversion.rs b/soroban-env-host/src/host/conversion.rs index f54c9a72a..03ec07ba9 100644 --- a/soroban-env-host/src/host/conversion.rs +++ b/soroban-env-host/src/host/conversion.rs @@ -6,8 +6,6 @@ use crate::err; use crate::host_object::{HostMap, HostObject, HostVec}; use crate::xdr::{Hash, LedgerKey, LedgerKeyContractData, ScVal, ScVec, Uint256}; use crate::{xdr::ContractCostType, Host, HostError, RawVal}; -use ed25519_dalek::{PublicKey, Signature, SIGNATURE_LENGTH}; -use sha2::{Digest, Sha256}; use soroban_env_common::num::{ i256_from_pieces, i256_into_pieces, u256_from_pieces, u256_into_pieces, }; @@ -66,10 +64,7 @@ impl Host { } } - pub(crate) fn to_u256_from_account( - &self, - account_id: &AccountId, - ) -> Result { + pub(crate) fn u256_from_account(&self, account_id: &AccountId) -> Result { let crate::xdr::PublicKey::PublicKeyTypeEd25519(ed25519) = account_id.metered_clone(&self.0.budget)?.0; Ok(ed25519) @@ -101,7 +96,7 @@ impl Host { self.fixed_length_bytes_from_bytesobj_input::(name, hash) } - pub(crate) fn uint256_from_bytesobj_input( + pub(crate) fn u256_from_bytesobj_input( &self, name: &'static str, u256: BytesObject, @@ -109,23 +104,7 @@ impl Host { self.fixed_length_bytes_from_bytesobj_input::(name, u256) } - pub(crate) fn signature_from_bytes( - &self, - name: &'static str, - bytes: &[u8], - ) -> Result { - self.fixed_length_bytes_from_slice::(name, bytes) - } - - pub(crate) fn signature_from_bytesobj_input( - &self, - name: &'static str, - sig: BytesObject, - ) -> Result { - self.fixed_length_bytes_from_bytesobj_input::(name, sig) - } - - fn fixed_length_bytes_from_slice( + pub(crate) fn fixed_length_bytes_from_slice( &self, name: &'static str, bytes_arr: &[u8], @@ -149,7 +128,7 @@ impl Host { } } - fn fixed_length_bytes_from_bytesobj_input( + pub(crate) fn fixed_length_bytes_from_bytesobj_input( &self, name: &'static str, obj: BytesObject, @@ -162,27 +141,6 @@ impl Host { }) } - pub(crate) fn ed25519_pub_key_from_bytes(&self, bytes: &[u8]) -> Result { - self.charge_budget(ContractCostType::ComputeEd25519PubKey, None)?; - PublicKey::from_bytes(bytes).map_err(|_| { - err!( - self, - (ScErrorType::Crypto, ScErrorCode::InvalidInput), - "invalid ed25519 public key", - bytes - ) - }) - } - - pub fn ed25519_pub_key_from_bytesobj_input( - &self, - k: BytesObject, - ) -> Result { - self.visit_obj(k, |bytes: &ScBytes| { - self.ed25519_pub_key_from_bytes(bytes.as_slice()) - }) - } - pub(crate) fn account_id_from_bytesobj(&self, k: BytesObject) -> Result { self.visit_obj(k, |bytes: &ScBytes| { Ok(AccountId(xdr::PublicKey::PublicKeyTypeEd25519( @@ -191,29 +149,6 @@ impl Host { }) } - pub(crate) fn sha256_hash_from_bytes(&self, bytes: &[u8]) -> Result, HostError> { - self.charge_budget( - ContractCostType::ComputeSha256Hash, - Some(bytes.len() as u64), - )?; - Ok(Sha256::digest(bytes).as_slice().to_vec()) - } - - pub fn sha256_hash_from_bytesobj_input(&self, x: BytesObject) -> Result, HostError> { - self.visit_obj(x, |bytes: &ScBytes| { - let hash = self.sha256_hash_from_bytes(bytes.as_slice())?; - if hash.len() != 32 { - return Err(err!( - self, - (ScErrorType::Object, ScErrorCode::UnexpectedSize), - "expected 32-byte BytesObject for hash, got different size", - hash.len() - )); - } - Ok(hash) - }) - } - /// Converts a [`RawVal`] to an [`ScVal`] and combines it with the currently-executing /// [`ContractID`] to produce a [`Key`], that can be used to access ledger [`Storage`]. // Notes on metering: covered by components. diff --git a/soroban-env-host/src/host/crypto.rs b/soroban-env-host/src/host/crypto.rs new file mode 100644 index 000000000..c23ccee41 --- /dev/null +++ b/soroban-env-host/src/host/crypto.rs @@ -0,0 +1,260 @@ +use crate::{ + err, + xdr::{ContractCostType, Hash, ScBytes, ScErrorCode, ScErrorType}, + BytesObject, Host, HostError, U32Val, +}; +use sha2::Sha256; +use sha3::Keccak256; + +impl Host { + // Ed25519 functions + + pub(crate) fn ed25519_signature_from_bytes( + &self, + name: &'static str, + bytes: &[u8], + ) -> Result { + self.fixed_length_bytes_from_slice::(name, bytes) + } + + pub(crate) fn ed25519_signature_from_bytesobj_input( + &self, + name: &'static str, + sig: BytesObject, + ) -> Result { + self.fixed_length_bytes_from_bytesobj_input::(name, sig) + } + + pub(crate) fn ed25519_pub_key_from_bytes( + &self, + bytes: &[u8], + ) -> Result { + self.charge_budget(ContractCostType::ComputeEd25519PubKey, None)?; + ed25519_dalek::PublicKey::from_bytes(bytes).map_err(|_| { + err!( + self, + (ScErrorType::Crypto, ScErrorCode::InvalidInput), + "invalid ed25519 public key", + bytes + ) + }) + } + + pub fn ed25519_pub_key_from_bytesobj_input( + &self, + k: BytesObject, + ) -> Result { + self.visit_obj(k, |bytes: &ScBytes| { + self.ed25519_pub_key_from_bytes(bytes.as_slice()) + }) + } + + pub(crate) fn verify_sig_ed25519_internal( + &self, + payload: &[u8], + public_key: &ed25519_dalek::PublicKey, + sig: &ed25519_dalek::Signature, + ) -> Result<(), HostError> { + use ed25519_dalek::Verifier; + self.charge_budget( + ContractCostType::VerifyEd25519Sig, + Some(payload.len() as u64), + )?; + public_key.verify(payload, sig).map_err(|_| { + self.err( + ScErrorType::Crypto, + ScErrorCode::InvalidInput, + "failed ED25519 verification", + &[], + ) + }) + } + + // ECDSA secp256k1 functions + + pub(crate) fn secp256k1_pub_key_from_bytes( + &self, + bytes: &[u8], + ) -> Result { + self.charge_budget(ContractCostType::ComputeEcdsaSecp256k1Key, None)?; + k256::PublicKey::from_sec1_bytes(bytes).map_err(|_| { + self.err( + ScErrorType::Crypto, + ScErrorCode::InvalidInput, + "invalid ECDSA-secp256k1 public key", + &[], + ) + }) + } + + pub(crate) fn secp256k1_pub_key_from_bytesobj_input( + &self, + k: BytesObject, + ) -> Result { + self.visit_obj(k, |bytes: &ScBytes| { + self.secp256k1_pub_key_from_bytes(bytes.as_slice()) + }) + } + + pub(crate) fn secp256k1_signature_from_bytes( + &self, + bytes: &[u8], + ) -> Result { + use k256::elliptic_curve::scalar::IsHigh; + self.charge_budget(ContractCostType::ComputeEcdsaSecp256k1Sig, None)?; + let sig: k256::ecdsa::Signature = + k256::ecdsa::Signature::try_from(bytes).map_err(|_| { + self.err( + ScErrorType::Crypto, + ScErrorCode::InvalidInput, + "invalid ECDSA-secp256k1 signature", + &[], + ) + })?; + if sig.s().is_high().into() { + Err(self.err( + ScErrorType::Crypto, + ScErrorCode::InvalidInput, + "ECDSA-secp256k1 signature 's' part is not normalized to low form", + &[], + )) + } else { + Ok(sig) + } + } + + pub(crate) fn secp256k1_signature_from_bytesobj_input( + &self, + k: BytesObject, + ) -> Result { + self.visit_obj(k, |bytes: &ScBytes| { + self.secp256k1_signature_from_bytes(bytes.as_slice()) + }) + } + + // NB: not metered as it's a trivial constant cost, just converting a byte to a byte, + // and always done exactly once as part of the secp256k1 recovery path. + pub(crate) fn secp256k1_recovery_id_from_u32val( + &self, + recovery_id: U32Val, + ) -> Result { + let rid32: u32 = u32::from(recovery_id); + if rid32 > k256::ecdsa::RecoveryId::MAX as u32 { + return Err(self.err( + ScErrorType::Crypto, + ScErrorCode::InvalidInput, + "invalid ECDSA-secp256k1 recovery ID", + &[recovery_id.to_raw()], + )); + } + k256::ecdsa::RecoveryId::try_from(rid32 as u8).map_err(|_| { + self.err( + ScErrorType::Crypto, + ScErrorCode::InvalidInput, + "invalid ECDSA-secp256k1 recovery ID", + &[recovery_id.to_raw()], + ) + }) + } + + pub(crate) fn verify_sig_ecdsa_secp256k1_internal( + &self, + payload: &[u8], + public_key: &k256::PublicKey, + sig: &k256::ecdsa::Signature, + ) -> Result<(), HostError> { + use k256::ecdsa::{signature::Verifier, VerifyingKey}; + self.charge_budget( + ContractCostType::VerifyEcdsaSecp256k1Sig, + Some(payload.len() as u64), + )?; + let verifier: VerifyingKey = public_key.into(); + verifier.verify(payload, sig).map_err(|_| { + self.err( + ScErrorType::Crypto, + ScErrorCode::InvalidInput, + "failed ecdsa verification", + &[], + ) + }) + } + + pub(crate) fn recover_key_ecdsa_secp256k1_internal( + &self, + hash: &Hash, + sig: &k256::ecdsa::Signature, + rid: k256::ecdsa::RecoveryId, + ) -> Result { + self.charge_budget(ContractCostType::RecoverEcdsaSecp256k1Key, None)?; + let recovered_key = + k256::ecdsa::VerifyingKey::recover_from_prehash(hash.as_slice(), &sig, rid).map_err( + |_| { + self.err( + ScErrorType::Crypto, + ScErrorCode::InvalidInput, + "ECDSA-secp256k1 signature recovery failed", + &[], + ) + }, + )?; + let rk = ScBytes::from(crate::xdr::BytesM::try_from( + recovered_key.to_encoded_point(false).as_bytes(), + )?); + self.add_host_object(rk) + } + + // SHA256 functions + + pub(crate) fn sha256_hash_from_bytes(&self, bytes: &[u8]) -> Result, HostError> { + self.charge_budget( + ContractCostType::ComputeSha256Hash, + Some(bytes.len() as u64), + )?; + Ok(::digest(bytes).as_slice().to_vec()) + } + + pub fn sha256_hash_from_bytesobj_input(&self, x: BytesObject) -> Result, HostError> { + self.visit_obj(x, |bytes: &ScBytes| { + let hash = self.sha256_hash_from_bytes(bytes.as_slice())?; + if hash.len() != 32 { + return Err(err!( + self, + (ScErrorType::Object, ScErrorCode::UnexpectedSize), + "expected 32-byte BytesObject for hash, got different size", + hash.len() + )); + } + Ok(hash) + }) + } + + // Keccak256/SHA3 functions + + pub(crate) fn keccak256_hash_from_bytes(&self, bytes: &[u8]) -> Result, HostError> { + self.charge_budget( + ContractCostType::ComputeKeccak256Hash, + Some(bytes.len() as u64), + )?; + Ok(::digest(bytes) + .as_slice() + .to_vec()) + } + + pub(crate) fn keccak256_hash_from_bytesobj_input( + &self, + x: BytesObject, + ) -> Result, HostError> { + self.visit_obj(x, |bytes: &ScBytes| { + let hash = self.keccak256_hash_from_bytes(bytes.as_slice())?; + if hash.len() != 32 { + return Err(err!( + self, + (ScErrorType::Object, ScErrorCode::UnexpectedSize), + "expected 32-byte BytesObject for hash, got different size", + hash.len() + )); + } + Ok(hash) + }) + } +} diff --git a/soroban-env-host/src/native_contract/invoker_contract_auth.rs b/soroban-env-host/src/native_contract/invoker_contract_auth.rs index 67a9ce42f..5f6dbc6d0 100644 --- a/soroban-env-host/src/native_contract/invoker_contract_auth.rs +++ b/soroban-env-host/src/native_contract/invoker_contract_auth.rs @@ -73,7 +73,7 @@ impl InvokerContractAuthEntry { contract_id_preimage: ContractIdPreimage::Address( ContractIdPreimageFromAddress { address: invoker_contract_addr.metered_clone(host.budget_ref())?, - salt: host.uint256_from_bytesobj_input( + salt: host.u256_from_bytesobj_input( "salt", create_contract_fn.salt.as_object(), )?, diff --git a/soroban-env-host/src/native_contract/token/contract.rs b/soroban-env-host/src/native_contract/token/contract.rs index ffe6f95db..c6f9733ba 100644 --- a/soroban-env-host/src/native_contract/token/contract.rs +++ b/soroban-env-host/src/native_contract/token/contract.rs @@ -149,7 +149,7 @@ impl TokenTrait for Token { )?, issuer: BytesN::<32>::try_from_val( e, - &e.bytes_new_from_slice(&e.to_u256_from_account(&asset4.issuer)?.0)?, + &e.bytes_new_from_slice(&e.u256_from_account(&asset4.issuer)?.0)?, )?, }), )?; @@ -165,7 +165,7 @@ impl TokenTrait for Token { )?, issuer: BytesN::<32>::try_from_val( e, - &e.bytes_new_from_slice(&e.to_u256_from_account(&asset12.issuer)?.0)?, + &e.bytes_new_from_slice(&e.u256_from_account(&asset12.issuer)?.0)?, )?, }), )?; diff --git a/soroban-env-host/src/test/budget_metering.rs b/soroban-env-host/src/test/budget_metering.rs index 0bd5c8b62..58ef1e479 100644 --- a/soroban-env-host/src/test/budget_metering.rs +++ b/soroban-env-host/src/test/budget_metering.rs @@ -247,6 +247,11 @@ fn total_amount_charged_from_random_inputs() -> Result<(), HostError> { (1, Some(147)), (47, None), (263, None), + (1, Some(1)), + (1, None), + (1, None), + (1, Some(1)), + (1, None), ]; for ty in ContractCostType::variants() { @@ -255,8 +260,8 @@ fn total_amount_charged_from_random_inputs() -> Result<(), HostError> { let actual = format!("{:?}", host.as_budget()); expect![[r#" ===================================================================================================================================================================== - Cpu limit: 40000000; used: 7964683 - Mem limit: 52428800; used: 218984 + Cpu limit: 40000000; used: 11455087 + Mem limit: 52428800; used: 219205 ===================================================================================================================================================================== CostType iterations input cpu_insns mem_bytes const_term_cpu lin_term_cpu const_term_mem lin_term_mem WasmInsnExec 246 None 1722 0 7 0 0 0 @@ -279,7 +284,12 @@ fn total_amount_charged_from_random_inputs() -> Result<(), HostError> { VmMemWrite 1 Some(160) 124 0 124 0 0 0 VmInstantiation 1 Some(147) 671595 123751 600447 484 117871 40 InvokeVmFunction 47 None 278522 22842 5926 0 486 0 - ChargeBudget 284 None 36920 0 130 0 0 0 + ChargeBudget 289 None 37570 0 130 0 0 0 + ComputeKeccak256Hash 1 Some(1) 3368 40 3322 46 40 0 + ComputeEcdsaSecp256k1Key 1 None 56525 0 56525 0 0 0 + ComputeEcdsaSecp256k1Sig 1 None 250 0 250 0 0 0 + VerifyEcdsaSecp256k1Sig 1 Some(1) 1109971 0 1109918 53 0 0 + RecoverEcdsaSecp256k1Key 1 None 2319640 181 2319640 0 181 0 ===================================================================================================================================================================== "#]] diff --git a/soroban-env-host/src/test/crypto.rs b/soroban-env-host/src/test/crypto.rs index efa58fb28..1f6636fc8 100644 --- a/soroban-env-host/src/test/crypto.rs +++ b/soroban-env-host/src/test/crypto.rs @@ -1,5 +1,6 @@ use crate::{xdr::ScVal, Env, Host, HostError}; use hex::FromHex; +use soroban_env_common::{EnvBase, U32Val}; /// crypto tests #[test] @@ -25,6 +26,26 @@ fn sha256_test() -> Result<(), HostError> { Ok(()) } +#[test] +fn keccak256_test() -> Result<(), HostError> { + // From https://paulmillr.com/noble/ + + let host = Host::default(); + let obj0 = host.test_bin_obj(b"test vector for soroban")?; + let hash_obj = host.compute_hash_keccak256(obj0)?; + + let v = host.from_host_val(hash_obj.to_raw())?; + let ScVal::Bytes(bytes) = v else { + panic!("Wrong type") + }; + + let exp: Vec = + FromHex::from_hex(b"352fe2eaddf44eb02eb3eab1f8d6ff4ba426df4f1734b1e3f210d621ee8853d9") + .unwrap(); + assert_eq!(bytes.as_vec().clone(), exp); + Ok(()) +} + #[test] fn ed25519_verify_test() -> Result<(), HostError> { let host = Host::default(); @@ -61,3 +82,54 @@ fn ed25519_verify_test() -> Result<(), HostError> { }; Ok(()) } + +#[test] +fn recover_ecdsa_secp256k1_key_test() -> Result<(), HostError> { + let host = Host::default(); + + // From ethereum: https://github.com/ethereum/go-ethereum/blob/master/crypto/secp256k1/secp256_test.go + + let msg_digest: Vec = + FromHex::from_hex(b"ce0677bb30baa8cf067c88db9811f4333d131bf8bcf12fe7065d211dce971008") + .unwrap(); + let sig: Vec = FromHex::from_hex(b"90f27b8b488db00b00606796d2987f6a5f59ae62ea05effe84fef5b8b0e549984a691139ad57a3f0b906637673aa2f63d1f55cb1a69199d4009eea23ceaddc93").unwrap(); + let pk: Vec = FromHex::from_hex(b"04e32df42865e97135acfb65f3bae71bdc86f4d49150ad6a440b6f15878109880a0a2b2667f7e725ceea70c673093bf67663e0312623c8e091b13cf2c0f11ef652").unwrap(); + let msg_digest_obj = host.test_bin_obj(msg_digest.as_slice())?; + let sig_obj = host.test_bin_obj(sig.as_slice())?; + let pk_obj = host.test_bin_obj(pk.as_slice())?; + let pk_obj_2 = host.recover_key_ecdsa_secp256k1(msg_digest_obj, sig_obj, U32Val::from(1))?; + let mut buf = [0u8; 65]; + assert_eq!(u32::from(host.bytes_len(pk_obj_2)?), 65); + host.bytes_copy_to_slice(pk_obj_2, U32Val::from(0), &mut buf)?; + assert_eq!(pk.as_slice(), buf.as_slice()); + assert_eq!(host.obj_cmp(pk_obj.to_raw(), pk_obj_2.to_raw())?, 0); + Ok(()) +} + +#[test] +fn verify_ecdsa_secp256k1_sig_test() -> Result<(), HostError> { + // From https://paulmillr.com/noble/ + + let host = Host::default(); + let _privkey: Vec = + FromHex::from_hex(b"11c2e68923f734df5ee9f3c76e90a66a732a88a5e4b73e7d893a20b0e7e03ce2") + .unwrap(); + let pubkey: Vec = FromHex::from_hex(b"04c5f87053270105b96561e76690d063f9d959f214f76580ecff0771b406bade54d856ce9f07c59b0c3f6bdc9e9abedbe0f7d79005f8601d0ccb3f92c0255f4a0a").unwrap(); + let msg = b"test vector for soroban"; + let msg_bad = b"test vector for sorobun"; + let sig: Vec = FromHex::from_hex(b"a39f868318230b07d1ce26fb847d733cd6e224b2938371f5e4f2e11381251da32ce33743a6340ac7f50db7885687e86bc079e8bc072538a2274a4fa268caaff9").unwrap(); + let pubkey_obj = host.test_bin_obj(pubkey.as_slice())?; + let msg_obj = host.test_bin_obj(msg.as_slice())?; + let msg_obj_bad = host.test_bin_obj(msg_bad.as_slice())?; + let sig_obj = host.test_bin_obj(sig.as_slice())?; + + // Verify OK + host.verify_sig_ecdsa_secp256k1(pubkey_obj, msg_obj, sig_obj)?; + + // Verify failure + assert!(host + .verify_sig_ecdsa_secp256k1(pubkey_obj, msg_obj_bad, sig_obj) + .is_err()); + + Ok(()) +} diff --git a/soroban-env-host/src/test/token.rs b/soroban-env-host/src/test/token.rs index 7a083a613..12333fe53 100644 --- a/soroban-env-host/src/test/token.rs +++ b/soroban-env-host/src/test/token.rs @@ -2332,7 +2332,7 @@ fn test_wrapped_asset_classic_balance_boundaries( Asset::CreditAlphanum12(AlphaNum12 { asset_code: AssetCode12([255; 12]), issuer: AccountId(PublicKey::PublicKeyTypeEd25519( - test.host.to_u256_from_account(&issuer_id).unwrap(), + test.host.u256_from_account(&issuer_id).unwrap(), )), }), ); @@ -2489,7 +2489,7 @@ fn test_classic_transfers_not_possible_for_unauthorized_asset() { Asset::CreditAlphanum4(AlphaNum4 { asset_code: AssetCode4([255; 4]), issuer: AccountId(PublicKey::PublicKeyTypeEd25519( - test.host.to_u256_from_account(&issuer_id).unwrap(), + test.host.u256_from_account(&issuer_id).unwrap(), )), }), ); diff --git a/soroban-test-wasms/wasm-workspace/Cargo.lock b/soroban-test-wasms/wasm-workspace/Cargo.lock index 7860e37c5..66b468544 100644 --- a/soroban-test-wasms/wasm-workspace/Cargo.lock +++ b/soroban-test-wasms/wasm-workspace/Cargo.lock @@ -17,6 +17,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -63,6 +69,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base32" version = "0.4.0" @@ -77,9 +89,15 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.1" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" + +[[package]] +name = "base64ct" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f1e31e207a6b8fb791a38ea3105e6cb541f55e4d029902d3039a4ad07cc4105" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "block-buffer" @@ -90,6 +108,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + [[package]] name = "bumpalo" version = "3.13.0" @@ -111,7 +138,7 @@ dependencies = [ "num-bigint", "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.18", ] [[package]] @@ -128,17 +155,23 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.24" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" +checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" dependencies = [ + "android-tzdata", "iana-time-zone", - "num-integer", "num-traits", "serde", "winapi", ] +[[package]] +name = "const-oid" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" + [[package]] name = "core-foundation-sys" version = "0.8.4" @@ -165,15 +198,37 @@ dependencies = [ "serde_json", ] +[[package]] +name = "crypto-bigint" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4c2f4e1afd912bc40bfd6fed5d9dc1f288e0ba01bfcc835cc5bc3eb13efe15" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + [[package]] name = "curve25519-dalek" -version = "3.2.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" dependencies = [ "byteorder", - "digest", - "rand_core", + "digest 0.9.0", + "rand_core 0.5.1", "subtle", "zeroize", ] @@ -199,7 +254,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.16", + "syn 2.0.18", ] [[package]] @@ -210,18 +265,28 @@ checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" dependencies = [ "darling_core", "quote", - "syn 2.0.16", + "syn 2.0.18", +] + +[[package]] +name = "der" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56acb310e15652100da43d130af8d97b509e95af61aab1c5a7939ef24337ee17" +dependencies = [ + "const-oid", + "zeroize", ] [[package]] name = "derive_arbitrary" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cdeb9ec472d588e539a818b2dee436825730da08ad0017c4b1a17676bdc8b7" +checksum = "53e0efad4403bfc52dc201159c4b842a246a14b98c64b55dfd0f2d89729dfeb8" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.18", ] [[package]] @@ -233,19 +298,45 @@ 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 0.10.4", + "const-oid", + "crypto-common", + "subtle", +] + [[package]] name = "downcast-rs" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" +[[package]] +name = "ecdsa" +version = "0.16.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0997c976637b606099b9985693efa3581e84e41f5c11ba5255f88711058ad428" +dependencies = [ + "der", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "signature 2.1.0", + "spki", +] + [[package]] name = "ed25519" version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" dependencies = [ - "signature", + "signature 1.6.4", ] [[package]] @@ -258,7 +349,7 @@ dependencies = [ "ed25519", "rand", "serde", - "sha2", + "sha2 0.9.9", "zeroize", ] @@ -268,6 +359,25 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +[[package]] +name = "elliptic-curve" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest 0.10.7", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + [[package]] name = "ethnum" version = "1.3.2" @@ -365,6 +475,16 @@ dependencies = [ "soroban-sdk", ] +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "fnv" version = "1.0.7" @@ -379,6 +499,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -389,7 +510,18 @@ checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", ] [[package]] @@ -398,6 +530,17 @@ version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -413,11 +556,20 @@ dependencies = [ "serde", ] +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + [[package]] name = "iana-time-zone" -version = "0.1.56" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c" +checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -482,18 +634,41 @@ checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "js-sys" -version = "0.3.63" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ "wasm-bindgen", ] +[[package]] +name = "k256" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2 0.10.6", + "signature 2.1.0", +] + +[[package]] +name = "keccak" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] + [[package]] name = "libc" -version = "0.2.144" +version = "0.2.146" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" +checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" [[package]] name = "libm" @@ -503,12 +678,9 @@ checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" [[package]] name = "log" -version = "0.4.17" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] name = "memchr" @@ -568,18 +740,18 @@ dependencies = [ [[package]] name = "object" -version = "0.30.3" +version = "0.30.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439" +checksum = "03b4680b86d9cfafba8fc491dc9b6df26b68cf40e9e6cd73909194759a63c385" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.17.1" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "opaque-debug" @@ -593,6 +765,16 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -606,23 +788,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b69d39aab54d069e7f2fe8cb970493e7834601ca2d8c65fd7bbd183578080d1" dependencies = [ "proc-macro2", - "syn 2.0.16", + "syn 2.0.18", ] [[package]] name = "proc-macro2" -version = "1.0.58" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa1fb82fc0c281dd9671101b66b771ebbe1eaf967b96ac8740dcba4b70005ca8" +checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" dependencies = [ "proc-macro2", ] @@ -633,10 +815,10 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ - "getrandom", + "getrandom 0.1.16", "libc", "rand_chacha", - "rand_core", + "rand_core 0.5.1", "rand_hc", ] @@ -647,7 +829,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.5.1", ] [[package]] @@ -656,7 +838,16 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "getrandom", + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.10", ] [[package]] @@ -665,7 +856,17 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ - "rand_core", + "rand_core 0.5.1", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", ] [[package]] @@ -680,24 +881,38 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +[[package]] +name = "sec1" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0aec48e813d6b90b15f0b8948af3c63483992dee44c03e9930b3eebdabe046e" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + [[package]] name = "serde" -version = "1.0.163" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" +checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.163" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" +checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.18", ] [[package]] @@ -717,7 +932,7 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f02d8aa6e3c385bf084924f660ce2a3a6bd333ba55b35e8590b321f35d88513" dependencies = [ - "base64 0.21.1", + "base64 0.21.2", "chrono", "hex", "indexmap", @@ -736,7 +951,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.18", ] [[package]] @@ -745,19 +960,50 @@ version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ - "block-buffer", + "block-buffer 0.9.0", "cfg-if", "cpufeatures", - "digest", + "digest 0.9.0", "opaque-debug", ] +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[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 = "signature" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + [[package]] name = "smallvec" version = "1.10.0" @@ -775,7 +1021,7 @@ dependencies = [ "soroban-env-macros", "soroban-wasmi", "static_assertions", - "stellar-xdr 0.0.16 (git+https://github.com/stellar/rs-stellar-xdr?rev=3429ea634df58aadf836790de8bbea21b7e82651)", + "stellar-xdr 0.0.16 (git+https://github.com/stellar/rs-stellar-xdr?rev=eafa8b74e3814d738e2bd948b556f8f3c8a76659)", ] [[package]] @@ -794,13 +1040,15 @@ dependencies = [ "curve25519-dalek", "ed25519-dalek", "hex", + "k256", "log", "num-derive", "num-integer", "num-traits", "rand", "rand_chacha", - "sha2", + "sha2 0.9.9", + "sha3", "soroban-env-common", "soroban-native-sdk-macros", "soroban-wasmi", @@ -816,8 +1064,8 @@ dependencies = [ "quote", "serde", "serde_json", - "stellar-xdr 0.0.16 (git+https://github.com/stellar/rs-stellar-xdr?rev=3429ea634df58aadf836790de8bbea21b7e82651)", - "syn 2.0.16", + "stellar-xdr 0.0.16 (git+https://github.com/stellar/rs-stellar-xdr?rev=eafa8b74e3814d738e2bd948b556f8f3c8a76659)", + "syn 2.0.18", "thiserror", ] @@ -839,7 +1087,7 @@ dependencies = [ "itertools", "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.18", ] [[package]] @@ -864,11 +1112,12 @@ dependencies = [ "itertools", "proc-macro2", "quote", - "sha2", + "sha2 0.9.9", "soroban-env-common", "soroban-spec", + "soroban-spec-rust", "stellar-xdr 0.0.16 (git+https://github.com/stellar/rs-stellar-xdr?rev=ba1ff9231ae81793d470db93815ead664eb21fb2)", - "syn 2.0.16", + "syn 2.0.18", ] [[package]] @@ -876,19 +1125,23 @@ name = "soroban-spec" version = "0.8.4" dependencies = [ "base64 0.13.1", - "darling", - "itertools", + "stellar-xdr 0.0.16 (git+https://github.com/stellar/rs-stellar-xdr?rev=ba1ff9231ae81793d470db93815ead664eb21fb2)", + "thiserror", + "wasmparser", +] + +[[package]] +name = "soroban-spec-rust" +version = "0.8.4" +dependencies = [ "prettyplease", "proc-macro2", "quote", - "serde", - "serde_derive", - "serde_json", - "sha2", + "sha2 0.9.9", + "soroban-spec", "stellar-xdr 0.0.16 (git+https://github.com/stellar/rs-stellar-xdr?rev=ba1ff9231ae81793d470db93815ead664eb21fb2)", - "syn 2.0.16", + "syn 2.0.18", "thiserror", - "wasmparser", ] [[package]] @@ -921,6 +1174,16 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "spki" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "static_assertions" version = "1.1.0" @@ -939,10 +1202,8 @@ dependencies = [ [[package]] name = "stellar-xdr" version = "0.0.16" -source = "git+https://github.com/stellar/rs-stellar-xdr?rev=3429ea634df58aadf836790de8bbea21b7e82651#3429ea634df58aadf836790de8bbea21b7e82651" +source = "git+https://github.com/stellar/rs-stellar-xdr?rev=ba1ff9231ae81793d470db93815ead664eb21fb2#ba1ff9231ae81793d470db93815ead664eb21fb2" dependencies = [ - "arbitrary", - "base64 0.13.1", "crate-git-revision", "hex", "serde", @@ -952,8 +1213,10 @@ dependencies = [ [[package]] name = "stellar-xdr" version = "0.0.16" -source = "git+https://github.com/stellar/rs-stellar-xdr?rev=ba1ff9231ae81793d470db93815ead664eb21fb2#ba1ff9231ae81793d470db93815ead664eb21fb2" +source = "git+https://github.com/stellar/rs-stellar-xdr?rev=eafa8b74e3814d738e2bd948b556f8f3c8a76659#eafa8b74e3814d738e2bd948b556f8f3c8a76659" dependencies = [ + "arbitrary", + "base64 0.13.1", "crate-git-revision", "hex", "serde", @@ -985,9 +1248,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.16" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6f671d4b5ffdb8eadec19c0ae67fe2639df8684bd7bc4b83d986b8db549cf01" +checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" dependencies = [ "proc-macro2", "quote", @@ -1011,14 +1274,14 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.18", ] [[package]] name = "time" -version = "0.3.21" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3403384eaacbca9923fa06940178ac13e4edb725486d70e8e15881d0c836cc" +checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" dependencies = [ "itoa", "serde", @@ -1049,9 +1312,9 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "unicode-ident" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" [[package]] name = "version_check" @@ -1065,11 +1328,17 @@ 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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "wasm-bindgen" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1077,24 +1346,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.18", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1102,22 +1371,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.18", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "wasmi_arena" @@ -1232,9 +1501,9 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "zeroize" -version = "1.3.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" dependencies = [ "zeroize_derive", ] @@ -1247,5 +1516,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.18", ] diff --git a/soroban-test-wasms/wasm-workspace/auth/src/lib.rs b/soroban-test-wasms/wasm-workspace/auth/src/lib.rs index 99bf54b20..e4cfe5ca2 100644 --- a/soroban-test-wasms/wasm-workspace/auth/src/lib.rs +++ b/soroban-test-wasms/wasm-workspace/auth/src/lib.rs @@ -1,15 +1,12 @@ #![no_std] -use soroban_sdk::{ - auth::{ContractContext, InvokerContractAuthEntry, SubContractInvocation}, - contractimpl, contracttype, vec, Address, Env, IntoVal, Symbol, Vec, -}; +use soroban_sdk::{contractimpl, contracttype, vec, Address, Env, IntoVal, Symbol, Vec}; struct AuthContract; #[derive(Clone)] #[contracttype] pub struct TreeNode { - pub contract: Address, + pub addr: Address, pub need_auth: Vec, pub children: Vec, } @@ -33,7 +30,7 @@ impl AuthContract { for child in tree.children.iter() { let child = child.unwrap(); env.invoke_contract::<()>( - &child.contract.clone(), + &child.addr.clone(), &Symbol::short("tree_fn"), (addresses.clone(), child).into_val(&env), ); @@ -52,37 +49,4 @@ impl AuthContract { pub fn do_auth(_env: Env, addr: Address, _val: u32) { addr.require_auth(); } - - pub fn invoker_auth_fn(env: Env, tree: TreeNode) { - // Build auth entries from children - tree root auth works - // automatically. - let mut auth_entries = vec![&env]; - for child in tree.children.iter() { - auth_entries.push_back(tree_to_invoker_contract_auth(&env, &child.unwrap())); - } - env.authorize_as_curr_contract(auth_entries); - let curr_address = env.current_contract_address(); - env.invoke_contract::<()>( - &tree.contract, - &Symbol::short("tree_fn"), - (vec![&env, curr_address], tree.clone()).into_val(&env), - ); - } -} - -// Converts the whole provided tree to invoker auth entries, ignoring -// `need_auth` (for covering non-matching tree scenarios). -fn tree_to_invoker_contract_auth(env: &Env, tree: &TreeNode) -> InvokerContractAuthEntry { - let mut sub_invocations = vec![env]; - for c in tree.children.iter() { - sub_invocations.push_back(tree_to_invoker_contract_auth(env, &c.unwrap())); - } - InvokerContractAuthEntry::Contract(SubContractInvocation { - context: ContractContext { - contract: tree.contract.clone(), - fn_name: Symbol::short("tree_fn"), - args: vec![&env], - }, - sub_invocations, - }) } diff --git a/soroban-test-wasms/wasm-workspace/create_contract/src/lib.rs b/soroban-test-wasms/wasm-workspace/create_contract/src/lib.rs index 4f8fbed48..ab31daeac 100644 --- a/soroban-test-wasms/wasm-workspace/create_contract/src/lib.rs +++ b/soroban-test-wasms/wasm-workspace/create_contract/src/lib.rs @@ -8,8 +8,6 @@ impl Contract { // Note that anyone can create a contract here with any salt, so a users call to // this could be frontrun and the same salt taken. pub fn create(e: Env, wasm_hash: BytesN<32>, salt: BytesN<32>) { - e.deployer() - .with_current_contract() - .deploy(&salt, &wasm_hash); + e.deployer().with_current_contract(&salt).deploy(&wasm_hash); } } diff --git a/soroban-test-wasms/wasm-workspace/opt/auth_test_contract.wasm b/soroban-test-wasms/wasm-workspace/opt/auth_test_contract.wasm index 83161809f..912f86384 100644 Binary files a/soroban-test-wasms/wasm-workspace/opt/auth_test_contract.wasm and b/soroban-test-wasms/wasm-workspace/opt/auth_test_contract.wasm differ diff --git a/soroban-test-wasms/wasm-workspace/opt/example_add_f32.wasm b/soroban-test-wasms/wasm-workspace/opt/example_add_f32.wasm index a408545d2..e9c8f0a32 100644 Binary files a/soroban-test-wasms/wasm-workspace/opt/example_add_f32.wasm and b/soroban-test-wasms/wasm-workspace/opt/example_add_f32.wasm differ diff --git a/soroban-test-wasms/wasm-workspace/opt/example_add_i32.wasm b/soroban-test-wasms/wasm-workspace/opt/example_add_i32.wasm index ed3c9a12b..aee044cb6 100644 Binary files a/soroban-test-wasms/wasm-workspace/opt/example_add_i32.wasm and b/soroban-test-wasms/wasm-workspace/opt/example_add_i32.wasm differ diff --git a/soroban-test-wasms/wasm-workspace/opt/example_complex.wasm b/soroban-test-wasms/wasm-workspace/opt/example_complex.wasm index 50ae16804..a91881eae 100644 Binary files a/soroban-test-wasms/wasm-workspace/opt/example_complex.wasm and b/soroban-test-wasms/wasm-workspace/opt/example_complex.wasm differ diff --git a/soroban-test-wasms/wasm-workspace/opt/example_contract_data.wasm b/soroban-test-wasms/wasm-workspace/opt/example_contract_data.wasm index d2ef0e28c..3e3732050 100644 Binary files a/soroban-test-wasms/wasm-workspace/opt/example_contract_data.wasm and b/soroban-test-wasms/wasm-workspace/opt/example_contract_data.wasm differ diff --git a/soroban-test-wasms/wasm-workspace/opt/example_create_contract.wasm b/soroban-test-wasms/wasm-workspace/opt/example_create_contract.wasm index ac5e015d7..c5c8bcbc6 100644 Binary files a/soroban-test-wasms/wasm-workspace/opt/example_create_contract.wasm and b/soroban-test-wasms/wasm-workspace/opt/example_create_contract.wasm differ diff --git a/soroban-test-wasms/wasm-workspace/opt/example_fannkuch.wasm b/soroban-test-wasms/wasm-workspace/opt/example_fannkuch.wasm index e17cfc756..2d0a49606 100644 Binary files a/soroban-test-wasms/wasm-workspace/opt/example_fannkuch.wasm and b/soroban-test-wasms/wasm-workspace/opt/example_fannkuch.wasm differ diff --git a/soroban-test-wasms/wasm-workspace/opt/example_fib.wasm b/soroban-test-wasms/wasm-workspace/opt/example_fib.wasm index 3d6add835..e738e8d37 100644 Binary files a/soroban-test-wasms/wasm-workspace/opt/example_fib.wasm and b/soroban-test-wasms/wasm-workspace/opt/example_fib.wasm differ diff --git a/soroban-test-wasms/wasm-workspace/opt/example_hostile.wasm b/soroban-test-wasms/wasm-workspace/opt/example_hostile.wasm index fc23f946f..00674bf42 100644 Binary files a/soroban-test-wasms/wasm-workspace/opt/example_hostile.wasm and b/soroban-test-wasms/wasm-workspace/opt/example_hostile.wasm differ diff --git a/soroban-test-wasms/wasm-workspace/opt/example_invoke_contract.wasm b/soroban-test-wasms/wasm-workspace/opt/example_invoke_contract.wasm index e514e5d5a..790d5fde9 100644 Binary files a/soroban-test-wasms/wasm-workspace/opt/example_invoke_contract.wasm and b/soroban-test-wasms/wasm-workspace/opt/example_invoke_contract.wasm differ diff --git a/soroban-test-wasms/wasm-workspace/opt/example_linear_memory.wasm b/soroban-test-wasms/wasm-workspace/opt/example_linear_memory.wasm index e71718905..88950ea6d 100644 Binary files a/soroban-test-wasms/wasm-workspace/opt/example_linear_memory.wasm and b/soroban-test-wasms/wasm-workspace/opt/example_linear_memory.wasm differ diff --git a/soroban-test-wasms/wasm-workspace/opt/example_simple_account.wasm b/soroban-test-wasms/wasm-workspace/opt/example_simple_account.wasm index 13d2d9c03..8a6a37a45 100644 Binary files a/soroban-test-wasms/wasm-workspace/opt/example_simple_account.wasm and b/soroban-test-wasms/wasm-workspace/opt/example_simple_account.wasm differ diff --git a/soroban-test-wasms/wasm-workspace/opt/example_updateable_contract.wasm b/soroban-test-wasms/wasm-workspace/opt/example_updateable_contract.wasm index c8ea05d98..98a55295e 100644 Binary files a/soroban-test-wasms/wasm-workspace/opt/example_updateable_contract.wasm and b/soroban-test-wasms/wasm-workspace/opt/example_updateable_contract.wasm differ diff --git a/soroban-test-wasms/wasm-workspace/opt/example_vec.wasm b/soroban-test-wasms/wasm-workspace/opt/example_vec.wasm index de13f3576..e036474e0 100644 Binary files a/soroban-test-wasms/wasm-workspace/opt/example_vec.wasm and b/soroban-test-wasms/wasm-workspace/opt/example_vec.wasm differ