From 766d04335d1825b9cc555c081839fb7583880665 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Tue, 19 Oct 2021 12:49:10 +0200 Subject: [PATCH 01/20] =?UTF-8?q?Upgrade=20`libsecp256k1`=20from=20`0.3.5`?= =?UTF-8?q?=20=E2=9E=94=20`0.7.0`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/engine/Cargo.toml | 2 +- crates/engine/src/ext.rs | 4 ++-- crates/env/Cargo.toml | 2 +- crates/env/src/engine/experimental_off_chain/impls.rs | 4 ++-- crates/env/src/engine/off_chain/impls.rs | 4 ++-- crates/eth_compatibility/Cargo.toml | 2 +- crates/eth_compatibility/src/lib.rs | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/crates/engine/Cargo.toml b/crates/engine/Cargo.toml index 4f700af06ec..85f26e05d70 100644 --- a/crates/engine/Cargo.toml +++ b/crates/engine/Cargo.toml @@ -23,7 +23,7 @@ sha3 = { version = "0.9" } blake2 = { version = "0.9" } # ECDSA for the off-chain environment. -libsecp256k1 = { version = "0.3.5", default-features = false } +libsecp256k1 = { version = "0.7.0", default-features = false, features = ["static-context"] } [features] default = ["std"] diff --git a/crates/engine/src/ext.rs b/crates/engine/src/ext.rs index a302df6390a..a28957954cc 100644 --- a/crates/engine/src/ext.rs +++ b/crates/engine/src/ext.rs @@ -428,7 +428,7 @@ impl Engine { message_hash: &[u8; 32], output: &mut [u8; 33], ) -> Result { - use secp256k1::{ + use libsecp256k1::{ recover, Message, RecoveryId, @@ -443,7 +443,7 @@ impl Engine { signature[64] }; let message = Message::parse(message_hash); - let signature = Signature::parse_slice(&signature[0..64]) + let signature = Signature::parse_standard_slice(&signature[0..64]) .unwrap_or_else(|error| panic!("Unable to parse the signature: {}", error)); let recovery_id = RecoveryId::parse(recovery_byte) diff --git a/crates/env/Cargo.toml b/crates/env/Cargo.toml index 69bd6cd40ee..ff146457cfd 100644 --- a/crates/env/Cargo.toml +++ b/crates/env/Cargo.toml @@ -36,7 +36,7 @@ sha3 = { version = "0.9", optional = true } blake2 = { version = "0.9", optional = true } # ECDSA for the off-chain environment. -libsecp256k1 = { version = "0.3.5", default-features = false } +libsecp256k1 = { version = "0.7.0", default-features = false, features = ["static-context"] } # Only used in the off-chain environment. # diff --git a/crates/env/src/engine/experimental_off_chain/impls.rs b/crates/env/src/engine/experimental_off_chain/impls.rs index 375f85ab650..75a2a879318 100644 --- a/crates/env/src/engine/experimental_off_chain/impls.rs +++ b/crates/env/src/engine/experimental_off_chain/impls.rs @@ -255,7 +255,7 @@ impl EnvBackend for EnvInstance { message_hash: &[u8; 32], output: &mut [u8; 33], ) -> Result<()> { - use secp256k1::{ + use libsecp256k1::{ recover, Message, RecoveryId, @@ -270,7 +270,7 @@ impl EnvBackend for EnvInstance { signature[64] }; let message = Message::parse(message_hash); - let signature = Signature::parse_slice(&signature[0..64]) + let signature = Signature::parse_standard_slice(&signature[0..64]) .unwrap_or_else(|error| panic!("Unable to parse the signature: {}", error)); let recovery_id = RecoveryId::parse(recovery_byte) diff --git a/crates/env/src/engine/off_chain/impls.rs b/crates/env/src/engine/off_chain/impls.rs index b86631242b3..4e8deda5489 100644 --- a/crates/env/src/engine/off_chain/impls.rs +++ b/crates/env/src/engine/off_chain/impls.rs @@ -201,7 +201,7 @@ impl EnvBackend for EnvInstance { message_hash: &[u8; 32], output: &mut [u8; 33], ) -> Result<()> { - use secp256k1::{ + use libsecp256k1::{ recover, Message, RecoveryId, @@ -216,7 +216,7 @@ impl EnvBackend for EnvInstance { signature[64] }; let message = Message::parse(message_hash); - let signature = Signature::parse_slice(&signature[0..64]) + let signature = Signature::parse_standard_slice(&signature[0..64]) .unwrap_or_else(|error| panic!("Unable to parse the signature: {}", error)); let recovery_id = RecoveryId::parse(recovery_byte) diff --git a/crates/eth_compatibility/Cargo.toml b/crates/eth_compatibility/Cargo.toml index fa63f9f4db4..d6325d0c8b2 100644 --- a/crates/eth_compatibility/Cargo.toml +++ b/crates/eth_compatibility/Cargo.toml @@ -16,7 +16,7 @@ include = ["Cargo.toml", "src/**/*.rs", "/README.md", "/LICENSE"] [dependencies] ink_env = { version = "3.0.0-rc6", path = "../env", default-features = false } -libsecp256k1 = { version = "0.3.5", default-features = false } +libsecp256k1 = { version = "0.7.0", default-features = false, features = ["static-context"] } [features] default = ["std"] diff --git a/crates/eth_compatibility/src/lib.rs b/crates/eth_compatibility/src/lib.rs index 4c27cad1ef3..b7144ea7411 100644 --- a/crates/eth_compatibility/src/lib.rs +++ b/crates/eth_compatibility/src/lib.rs @@ -92,7 +92,7 @@ impl ECDSAPublicKey { /// ``` pub fn to_eth_address(&self) -> EthereumAddress { use ink_env::hash; - use secp256k1::PublicKey; + use libsecp256k1::PublicKey; // Transform compressed public key into uncompressed. let pub_key = PublicKey::parse_compressed(&self.0) From 9610d3a1cb7cc2d633f2c06851013ddba54b3836 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Tue, 19 Oct 2021 13:36:06 +0200 Subject: [PATCH 02/20] Include off-chain dependencies only when necessary --- crates/env/Cargo.toml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/crates/env/Cargo.toml b/crates/env/Cargo.toml index ff146457cfd..f3c6853d4d1 100644 --- a/crates/env/Cargo.toml +++ b/crates/env/Cargo.toml @@ -30,6 +30,7 @@ arrayref = "0.3" static_assertions = "1.1" sp-arithmetic = { version = "3.0", default-features = false } +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] # Hashes for the off-chain environment. sha2 = { version = "0.9", optional = true } sha3 = { version = "0.9", optional = true } @@ -39,9 +40,6 @@ blake2 = { version = "0.9", optional = true } libsecp256k1 = { version = "0.7.0", default-features = false, features = ["static-context"] } # Only used in the off-chain environment. -# -# Sadly couldn't be marked as dev-dependency. -# Never use this crate outside the off-chain environment! rand = { version = "0.8", default-features = false, features = ["alloc"], optional = true } scale-info = { version = "1.0", default-features = false, features = ["derive"], optional = true } From a32ce167ad7c0751fc2670abe954bb9699e65b7b Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Tue, 19 Oct 2021 13:37:19 +0200 Subject: [PATCH 03/20] Include off-chain dependency only when necessary --- crates/storage/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/storage/Cargo.toml b/crates/storage/Cargo.toml index 4e7fb5ba3fc..2fb7b8238e0 100644 --- a/crates/storage/Cargo.toml +++ b/crates/storage/Cargo.toml @@ -27,6 +27,7 @@ scale-info = { version = "1.0", default-features = false, features = ["derive"], cfg-if = "1.0" array-init = { version = "2.0", default-features = false } +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] # Workaround: we actually just need criterion as a dev-dependency, but # there is an issue with a doubly included std lib when executing # `cargo check --no-default-features --target wasm32-unknown-unknown`. From f4d895910e9bea629b1c40ed852341bd7231d62f Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Tue, 19 Oct 2021 13:42:57 +0200 Subject: [PATCH 04/20] Include off-chain dependency only when necessary --- crates/eth_compatibility/Cargo.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/eth_compatibility/Cargo.toml b/crates/eth_compatibility/Cargo.toml index d6325d0c8b2..c744d921e32 100644 --- a/crates/eth_compatibility/Cargo.toml +++ b/crates/eth_compatibility/Cargo.toml @@ -16,6 +16,8 @@ include = ["Cargo.toml", "src/**/*.rs", "/README.md", "/LICENSE"] [dependencies] ink_env = { version = "3.0.0-rc6", path = "../env", default-features = false } + +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] libsecp256k1 = { version = "0.7.0", default-features = false, features = ["static-context"] } [features] From f339fdf74a1cb2b7281547aaec56d1a8cbd316fc Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Tue, 19 Oct 2021 16:21:04 +0200 Subject: [PATCH 05/20] Switch to `secp256k1` for `eth_compatibility` crate --- crates/eth_compatibility/Cargo.toml | 4 ++-- crates/eth_compatibility/src/lib.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/eth_compatibility/Cargo.toml b/crates/eth_compatibility/Cargo.toml index c744d921e32..cebc5bf4e90 100644 --- a/crates/eth_compatibility/Cargo.toml +++ b/crates/eth_compatibility/Cargo.toml @@ -17,8 +17,8 @@ include = ["Cargo.toml", "src/**/*.rs", "/README.md", "/LICENSE"] [dependencies] ink_env = { version = "3.0.0-rc6", path = "../env", default-features = false } -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] -libsecp256k1 = { version = "0.7.0", default-features = false, features = ["static-context"] } +[target.'cfg(target_arch = "wasm32")'.dependencies] +secp256k1 = { version = "0.20.3", default-features = false } [features] default = ["std"] diff --git a/crates/eth_compatibility/src/lib.rs b/crates/eth_compatibility/src/lib.rs index b7144ea7411..b6676c92aeb 100644 --- a/crates/eth_compatibility/src/lib.rs +++ b/crates/eth_compatibility/src/lib.rs @@ -92,10 +92,10 @@ impl ECDSAPublicKey { /// ``` pub fn to_eth_address(&self) -> EthereumAddress { use ink_env::hash; - use libsecp256k1::PublicKey; + use secp256k1::PublicKey; // Transform compressed public key into uncompressed. - let pub_key = PublicKey::parse_compressed(&self.0) + let pub_key = PublicKey::from_slice(&self.0) .expect("Unable to parse the compressed ECDSA public key"); let uncompressed = pub_key.serialize(); From 1d4ff6dd9e89075265b646fc654ffc50cec0e76c Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Tue, 19 Oct 2021 19:37:51 +0200 Subject: [PATCH 06/20] Remove conditional dependency --- crates/eth_compatibility/Cargo.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/eth_compatibility/Cargo.toml b/crates/eth_compatibility/Cargo.toml index cebc5bf4e90..b93c2416109 100644 --- a/crates/eth_compatibility/Cargo.toml +++ b/crates/eth_compatibility/Cargo.toml @@ -16,8 +16,6 @@ include = ["Cargo.toml", "src/**/*.rs", "/README.md", "/LICENSE"] [dependencies] ink_env = { version = "3.0.0-rc6", path = "../env", default-features = false } - -[target.'cfg(target_arch = "wasm32")'.dependencies] secp256k1 = { version = "0.20.3", default-features = false } [features] From bf40498cd98b1ba99a5323e981bf6c551c91bb45 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Wed, 20 Oct 2021 07:41:33 +0200 Subject: [PATCH 07/20] Fix serialize --- crates/eth_compatibility/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/eth_compatibility/src/lib.rs b/crates/eth_compatibility/src/lib.rs index b6676c92aeb..3e853b8ea1a 100644 --- a/crates/eth_compatibility/src/lib.rs +++ b/crates/eth_compatibility/src/lib.rs @@ -97,7 +97,7 @@ impl ECDSAPublicKey { // Transform compressed public key into uncompressed. let pub_key = PublicKey::from_slice(&self.0) .expect("Unable to parse the compressed ECDSA public key"); - let uncompressed = pub_key.serialize(); + let uncompressed = pub_key.serialize_uncompressed(); // Hash the uncompressed public key by Keccak256 algorithm. let mut hash = ::Type::default(); From d22c6dafcfb80d50ca6f8557466ce00238b1be88 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Wed, 20 Oct 2021 08:31:16 +0200 Subject: [PATCH 08/20] Switch to `secp256k1` crate everywhere --- crates/engine/Cargo.toml | 2 +- crates/engine/src/ext.rs | 31 ++++++++------ crates/engine/src/tests.rs | 82 ++++++++++++++++++++++++++++++++++++++ crates/env/Cargo.toml | 4 +- 4 files changed, 104 insertions(+), 15 deletions(-) diff --git a/crates/engine/Cargo.toml b/crates/engine/Cargo.toml index 85f26e05d70..073d2c22a36 100644 --- a/crates/engine/Cargo.toml +++ b/crates/engine/Cargo.toml @@ -23,7 +23,7 @@ sha3 = { version = "0.9" } blake2 = { version = "0.9" } # ECDSA for the off-chain environment. -libsecp256k1 = { version = "0.7.0", default-features = false, features = ["static-context"] } +secp256k1 = { version = "0.20.3", features = ["recovery"] } [features] default = ["std"] diff --git a/crates/engine/src/ext.rs b/crates/engine/src/ext.rs index a28957954cc..1d01f2d9a08 100644 --- a/crates/engine/src/ext.rs +++ b/crates/engine/src/ext.rs @@ -428,11 +428,13 @@ impl Engine { message_hash: &[u8; 32], output: &mut [u8; 33], ) -> Result { - use libsecp256k1::{ - recover, + use secp256k1::{ + recovery::{ + RecoverableSignature, + RecoveryId, + }, Message, - RecoveryId, - Signature, + Secp256k1, }; // In most implementations, the v is just 0 or 1 internally, but 27 was added @@ -442,17 +444,22 @@ impl Engine { } else { signature[64] }; - let message = Message::parse(message_hash); - let signature = Signature::parse_standard_slice(&signature[0..64]) - .unwrap_or_else(|error| panic!("Unable to parse the signature: {}", error)); - - let recovery_id = RecoveryId::parse(recovery_byte) + let recovery_id = RecoveryId::from_i32(recovery_byte as i32) .unwrap_or_else(|error| panic!("Unable to parse the recovery id: {}", error)); - - let pub_key = recover(&message, &signature, &recovery_id); + let message = Message::from_slice(message_hash).unwrap_or_else(|error| { + panic!("Unable to create the message from hash: {}", error) + }); + let signature = + RecoverableSignature::from_compact(&signature[0..64], recovery_id) + .unwrap_or_else(|error| { + panic!("Unable to parse the signature: {}", error) + }); + + let secp = Secp256k1::new(); + let pub_key = secp.recover(&message, &signature); match pub_key { Ok(pub_key) => { - *output = pub_key.serialize_compressed(); + *output = pub_key.serialize(); Ok(()) } Err(_) => Err(Error::EcdsaRecoverFailed), diff --git a/crates/engine/src/tests.rs b/crates/engine/src/tests.rs index 798f5287de7..97ffa823b71 100644 --- a/crates/engine/src/tests.rs +++ b/crates/engine/src/tests.rs @@ -16,6 +16,14 @@ use crate::ext::{ Engine, Error, }; +use secp256k1::{ + recovery::RecoverableSignature, + Message, + PublicKey, + Secp256k1, + SecretKey, +}; +use std::convert::TryInto; /// The public methods of the `contracts` pallet write their result into an /// `output` buffer instead of returning them. Since we aim to emulate this @@ -192,3 +200,77 @@ fn must_panic_when_buffer_too_small() { // then unreachable!("`get_storage` must already have panicked"); } + +#[test] +fn ecdsa_recovery_test_from_contracts_pallet() { + // given + let mut engine = Engine::new(); + #[rustfmt::skip] + let signature: [u8; 65] = [ + 161, 234, 203, 74, 147, 96, 51, 212, 5, 174, 231, 9, 142, 48, 137, 201, + 162, 118, 192, 67, 239, 16, 71, 216, 125, 86, 167, 139, 70, 7, 86, 241, + 33, 87, 154, 251, 81, 29, 160, 4, 176, 239, 88, 211, 244, 232, 232, 52, + 211, 234, 100, 115, 230, 47, 80, 44, 152, 166, 62, 50, 8, 13, 86, 175, + 28, + ]; + #[rustfmt::skip] + let message_hash: [u8; 32] = [ + 162, 28, 244, 179, 96, 76, 244, 178, 188, 83, 230, 248, 143, 106, 77, 117, + 239, 95, 244, 171, 65, 95, 62, 153, 174, 166, 182, 28, 130, 73, 196, 208 + ]; + + // when + let mut output = [0; 33]; + engine + .ecdsa_recover(&signature, &message_hash, &mut output) + .expect("must work"); + + // then + #[rustfmt::skip] + const EXPECTED_COMPRESSED_PUBLIC_KEY: [u8; 33] = [ + 2, 121, 190, 102, 126, 249, 220, 187, 172, 85, 160, 98, 149, 206, 135, 11, + 7, 2, 155, 252, 219, 45, 206, 40, 217, 89, 242, 129, 91, 22, 248, 23, + 152, + ]; + assert_eq!(output, EXPECTED_COMPRESSED_PUBLIC_KEY); +} + +#[test] +fn ecdsa_recovery_with_secp256k1_crate() { + // given + let mut engine = Engine::new(); + let secp = Secp256k1::new(); + let seckey = [ + 59, 148, 11, 85, 134, 130, 61, 253, 2, 174, 59, 70, 27, 180, 51, 107, 94, 203, + 174, 253, 102, 39, 170, 146, 46, 252, 4, 143, 236, 12, 136, 28, + ]; + let pubkey = PublicKey::from_slice(&[ + 2, 29, 21, 35, 7, 198, 183, 43, 14, 208, 65, 139, 14, 112, 205, 128, 231, 245, + 41, 91, 141, 134, 245, 114, 45, 63, 82, 19, 251, 210, 57, 79, 54, + ]) + .expect("pubkey creation failed"); + + let mut msg_hash = [0; 32]; + crate::hashing::sha2_256(b"Some message", &mut msg_hash); + + let msg = Message::from_slice(&msg_hash).expect("message creation failed"); + let seckey = SecretKey::from_slice(&seckey).expect("secret key creation failed"); + let recoverable_signature: RecoverableSignature = + secp.sign_recoverable(&msg, &seckey); + + let recovery_id = recoverable_signature.serialize_compact().0.to_i32() as u8; + let mut signature = recoverable_signature.serialize_compact().1.to_vec(); + signature.push(recovery_id); + let signature_with_recovery_id: [u8; 65] = signature + .try_into() + .expect("unable to create signature with recovery id"); + + // when + let mut output = [0; 33]; + engine + .ecdsa_recover(&signature_with_recovery_id, &msg.as_ref(), &mut output) + .expect("ecdsa recovery failed"); + + // then + assert_eq!(output, pubkey.serialize()); +} diff --git a/crates/env/Cargo.toml b/crates/env/Cargo.toml index f3c6853d4d1..3edcde5393a 100644 --- a/crates/env/Cargo.toml +++ b/crates/env/Cargo.toml @@ -15,7 +15,6 @@ categories = ["no-std", "embedded"] include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE"] [dependencies] -ink_engine = { version = "3.0.0-rc6", path = "../engine/", default-features = false, optional = true } ink_metadata = { version = "3.0.0-rc6", path = "../metadata/", default-features = false, features = ["derive"], optional = true } ink_allocator = { version = "3.0.0-rc6", path = "../allocator/", default-features = false } ink_primitives = { version = "3.0.0-rc6", path = "../primitives/", default-features = false } @@ -31,13 +30,14 @@ static_assertions = "1.1" sp-arithmetic = { version = "3.0", default-features = false } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] +ink_engine = { version = "3.0.0-rc6", path = "../engine/", default-features = false, optional = true } # Hashes for the off-chain environment. sha2 = { version = "0.9", optional = true } sha3 = { version = "0.9", optional = true } blake2 = { version = "0.9", optional = true } # ECDSA for the off-chain environment. -libsecp256k1 = { version = "0.7.0", default-features = false, features = ["static-context"] } +secp256k1 = { version = "0.20.3", features = ["recovery"] } # Only used in the off-chain environment. rand = { version = "0.8", default-features = false, features = ["alloc"], optional = true } From 92d0577184a08dfaf753989847480d46e40e3699 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Thu, 21 Oct 2021 12:34:00 +0200 Subject: [PATCH 09/20] Switch to `secp256k1` crate everywhere --- .../engine/experimental_off_chain/impls.rs | 31 ++++++++++------- crates/env/src/engine/off_chain/impls.rs | 33 +++++++++++-------- 2 files changed, 39 insertions(+), 25 deletions(-) diff --git a/crates/env/src/engine/experimental_off_chain/impls.rs b/crates/env/src/engine/experimental_off_chain/impls.rs index 75a2a879318..dea1c6d0139 100644 --- a/crates/env/src/engine/experimental_off_chain/impls.rs +++ b/crates/env/src/engine/experimental_off_chain/impls.rs @@ -255,11 +255,13 @@ impl EnvBackend for EnvInstance { message_hash: &[u8; 32], output: &mut [u8; 33], ) -> Result<()> { - use libsecp256k1::{ - recover, + use secp256k1::{ + recovery::{ + RecoverableSignature, + RecoveryId, + }, Message, - RecoveryId, - Signature, + Secp256k1, }; // In most implementations, the v is just 0 or 1 internally, but 27 was added @@ -269,17 +271,22 @@ impl EnvBackend for EnvInstance { } else { signature[64] }; - let message = Message::parse(message_hash); - let signature = Signature::parse_standard_slice(&signature[0..64]) - .unwrap_or_else(|error| panic!("Unable to parse the signature: {}", error)); - - let recovery_id = RecoveryId::parse(recovery_byte) + let recovery_id = RecoveryId::from_i32(recovery_byte as i32) .unwrap_or_else(|error| panic!("Unable to parse the recovery id: {}", error)); - - let pub_key = recover(&message, &signature, &recovery_id); + let message = Message::from_slice(message_hash).unwrap_or_else(|error| { + panic!("Unable to create the message from hash: {}", error) + }); + let signature = + RecoverableSignature::from_compact(&signature[0..64], recovery_id) + .unwrap_or_else(|error| { + panic!("Unable to parse the signature: {}", error) + }); + + let secp = Secp256k1::new(); + let pub_key = secp.recover(&message, &signature); match pub_key { Ok(pub_key) => { - *output = pub_key.serialize_compressed(); + *output = pub_key.serialize(); Ok(()) } Err(_) => Err(crate::Error::EcdsaRecoverFailed), diff --git a/crates/env/src/engine/off_chain/impls.rs b/crates/env/src/engine/off_chain/impls.rs index 4e8deda5489..27ba2bb05de 100644 --- a/crates/env/src/engine/off_chain/impls.rs +++ b/crates/env/src/engine/off_chain/impls.rs @@ -201,11 +201,13 @@ impl EnvBackend for EnvInstance { message_hash: &[u8; 32], output: &mut [u8; 33], ) -> Result<()> { - use libsecp256k1::{ - recover, + use secp256k1::{ + recovery::{ + RecoverableSignature, + RecoveryId, + }, Message, - RecoveryId, - Signature, + Secp256k1, }; // In most implementations, the v is just 0 or 1 internally, but 27 was added @@ -215,20 +217,25 @@ impl EnvBackend for EnvInstance { } else { signature[64] }; - let message = Message::parse(message_hash); - let signature = Signature::parse_standard_slice(&signature[0..64]) - .unwrap_or_else(|error| panic!("Unable to parse the signature: {}", error)); - - let recovery_id = RecoveryId::parse(recovery_byte) + let recovery_id = RecoveryId::from_i32(recovery_byte as i32) .unwrap_or_else(|error| panic!("Unable to parse the recovery id: {}", error)); - - let pub_key = recover(&message, &signature, &recovery_id); + let message = Message::from_slice(message_hash).unwrap_or_else(|error| { + panic!("Unable to create the message from hash: {}", error) + }); + let signature = + RecoverableSignature::from_compact(&signature[0..64], recovery_id) + .unwrap_or_else(|error| { + panic!("Unable to parse the signature: {}", error) + }); + + let secp = Secp256k1::new(); + let pub_key = secp.recover(&message, &signature); match pub_key { Ok(pub_key) => { - *output = pub_key.serialize_compressed(); + *output = pub_key.serialize(); Ok(()) } - Err(_) => Err(Error::EcdsaRecoverFailed), + Err(_) => Err(crate::Error::EcdsaRecoverFailed), } } From 6f4e16e96adfa60f693cca64499ad1e9603325af Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Thu, 21 Oct 2021 13:15:31 +0200 Subject: [PATCH 10/20] Fix compilation for `wasm32` target --- crates/env/Cargo.toml | 3 ++- crates/eth_compatibility/src/lib.rs | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/env/Cargo.toml b/crates/env/Cargo.toml index 3edcde5393a..68b5255736c 100644 --- a/crates/env/Cargo.toml +++ b/crates/env/Cargo.toml @@ -31,13 +31,14 @@ sp-arithmetic = { version = "3.0", default-features = false } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] ink_engine = { version = "3.0.0-rc6", path = "../engine/", default-features = false, optional = true } + # Hashes for the off-chain environment. sha2 = { version = "0.9", optional = true } sha3 = { version = "0.9", optional = true } blake2 = { version = "0.9", optional = true } # ECDSA for the off-chain environment. -secp256k1 = { version = "0.20.3", features = ["recovery"] } +secp256k1 = { version = "0.20.3", default-features = false, features = ["recovery"] } # Only used in the off-chain environment. rand = { version = "0.8", default-features = false, features = ["alloc"], optional = true } diff --git a/crates/eth_compatibility/src/lib.rs b/crates/eth_compatibility/src/lib.rs index 3e853b8ea1a..1439f8f3098 100644 --- a/crates/eth_compatibility/src/lib.rs +++ b/crates/eth_compatibility/src/lib.rs @@ -13,6 +13,7 @@ // limitations under the License. #![no_std] + use ink_env::{ DefaultEnvironment, Environment, From a30a790d557025a4e4ab88c90e11b7c08a5a2105 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Thu, 21 Oct 2021 13:44:17 +0200 Subject: [PATCH 11/20] Ensure enabled features are not merged for targets --- Cargo.toml | 1 + crates/env/Cargo.toml | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 554092d4a5e..48f592ff034 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,5 @@ [workspace] +resolver = "2" members = [ "crates/metadata", "crates/allocator", diff --git a/crates/env/Cargo.toml b/crates/env/Cargo.toml index 68b5255736c..a517358c8db 100644 --- a/crates/env/Cargo.toml +++ b/crates/env/Cargo.toml @@ -29,6 +29,9 @@ arrayref = "0.3" static_assertions = "1.1" sp-arithmetic = { version = "3.0", default-features = false } +[target.'cfg(target_arch = "wasm32")'.dependencies] +secp256k1 = { version = "0.20.3", default-features = false } + [target.'cfg(not(target_arch = "wasm32"))'.dependencies] ink_engine = { version = "3.0.0-rc6", path = "../engine/", default-features = false, optional = true } @@ -38,7 +41,7 @@ sha3 = { version = "0.9", optional = true } blake2 = { version = "0.9", optional = true } # ECDSA for the off-chain environment. -secp256k1 = { version = "0.20.3", default-features = false, features = ["recovery"] } +secp256k1 = { version = "0.20.3", features = ["recovery"] } # Only used in the off-chain environment. rand = { version = "0.8", default-features = false, features = ["alloc"], optional = true } From 17369999a02867ab0d270dc428488f8e1ccf9148 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Thu, 21 Oct 2021 13:53:50 +0200 Subject: [PATCH 12/20] Make clippy happy --- crates/engine/src/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/engine/src/tests.rs b/crates/engine/src/tests.rs index 97ffa823b71..f687ad3d136 100644 --- a/crates/engine/src/tests.rs +++ b/crates/engine/src/tests.rs @@ -268,7 +268,7 @@ fn ecdsa_recovery_with_secp256k1_crate() { // when let mut output = [0; 33]; engine - .ecdsa_recover(&signature_with_recovery_id, &msg.as_ref(), &mut output) + .ecdsa_recover(&signature_with_recovery_id, msg.as_ref(), &mut output) .expect("ecdsa recovery failed"); // then From f12e024d01554f0d62ceb97bdae117c4848f03b7 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Thu, 21 Oct 2021 14:24:42 +0200 Subject: [PATCH 13/20] Use resolver `2` in all examples --- examples/contract-terminate/Cargo.toml | 1 + examples/contract-transfer/Cargo.toml | 1 + examples/delegator/Cargo.toml | 1 + examples/delegator/accumulator/Cargo.toml | 1 + examples/delegator/adder/Cargo.toml | 1 + examples/delegator/subber/Cargo.toml | 1 + examples/dns/Cargo.toml | 1 + examples/erc1155/Cargo.toml | 1 + examples/erc20/Cargo.toml | 1 + examples/erc721/Cargo.toml | 1 + examples/flipper/Cargo.toml | 1 + examples/incrementer/Cargo.toml | 1 + examples/multisig/Cargo.toml | 1 + examples/rand-extension/Cargo.toml | 1 + examples/trait-erc20/Cargo.toml | 1 + examples/trait-flipper/Cargo.toml | 1 + examples/trait-incrementer/Cargo.toml | 1 + 17 files changed, 17 insertions(+) diff --git a/examples/contract-terminate/Cargo.toml b/examples/contract-terminate/Cargo.toml index 39d89d74061..4f4feb74df4 100644 --- a/examples/contract-terminate/Cargo.toml +++ b/examples/contract-terminate/Cargo.toml @@ -3,6 +3,7 @@ name = "contract_terminate" version = "3.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" +resolver = "2" [dependencies] ink_primitives = { version = "3.0.0-rc6", path = "../../crates/primitives", default-features = false } diff --git a/examples/contract-transfer/Cargo.toml b/examples/contract-transfer/Cargo.toml index 3d6a2cc0cfc..d7ef695a187 100644 --- a/examples/contract-transfer/Cargo.toml +++ b/examples/contract-transfer/Cargo.toml @@ -3,6 +3,7 @@ name = "contract_transfer" version = "3.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" +resolver = "2" [dependencies] ink_primitives = { version = "3.0.0-rc6", path = "../../crates/primitives", default-features = false } diff --git a/examples/delegator/Cargo.toml b/examples/delegator/Cargo.toml index 087684226cf..1899b35750e 100644 --- a/examples/delegator/Cargo.toml +++ b/examples/delegator/Cargo.toml @@ -3,6 +3,7 @@ name = "delegator" version = "3.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" +resolver = "2" [dependencies] ink_primitives = { version = "3.0.0-rc6", path = "../../crates/primitives", default-features = false } diff --git a/examples/delegator/accumulator/Cargo.toml b/examples/delegator/accumulator/Cargo.toml index 03ce8203287..cee48a893a5 100644 --- a/examples/delegator/accumulator/Cargo.toml +++ b/examples/delegator/accumulator/Cargo.toml @@ -3,6 +3,7 @@ name = "accumulator" version = "3.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" +resolver = "2" [dependencies] ink_primitives = { version = "3.0.0-rc6", path = "../../../crates/primitives", default-features = false } diff --git a/examples/delegator/adder/Cargo.toml b/examples/delegator/adder/Cargo.toml index 043d9808013..5778bb5c65e 100644 --- a/examples/delegator/adder/Cargo.toml +++ b/examples/delegator/adder/Cargo.toml @@ -3,6 +3,7 @@ name = "adder" version = "3.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" +resolver = "2" [dependencies] ink_primitives = { version = "3.0.0-rc6", path = "../../../crates/primitives", default-features = false } diff --git a/examples/delegator/subber/Cargo.toml b/examples/delegator/subber/Cargo.toml index 3470808961a..a068e3758c4 100644 --- a/examples/delegator/subber/Cargo.toml +++ b/examples/delegator/subber/Cargo.toml @@ -3,6 +3,7 @@ name = "subber" version = "3.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" +resolver = "2" [dependencies] ink_primitives = { version = "3.0.0-rc6", path = "../../../crates/primitives", default-features = false } diff --git a/examples/dns/Cargo.toml b/examples/dns/Cargo.toml index 438690c768d..bb433e83345 100644 --- a/examples/dns/Cargo.toml +++ b/examples/dns/Cargo.toml @@ -3,6 +3,7 @@ name = "dns" version = "3.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" +resolver = "2" [dependencies] ink_primitives = { version = "3.0.0-rc6", path = "../../crates/primitives", default-features = false } diff --git a/examples/erc1155/Cargo.toml b/examples/erc1155/Cargo.toml index 957e8409921..9bf2c452f2f 100644 --- a/examples/erc1155/Cargo.toml +++ b/examples/erc1155/Cargo.toml @@ -3,6 +3,7 @@ name = "erc1155" version = "3.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" +resolver = "2" [dependencies] ink_primitives = { version = "3.0.0-rc6", path = "../../crates/primitives", default-features = false } diff --git a/examples/erc20/Cargo.toml b/examples/erc20/Cargo.toml index 8430850f5d9..2e5663c508d 100644 --- a/examples/erc20/Cargo.toml +++ b/examples/erc20/Cargo.toml @@ -3,6 +3,7 @@ name = "erc20" version = "3.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" +resolver = "2" [dependencies] ink_primitives = { version = "3.0.0-rc6", path = "../../crates/primitives", default-features = false } diff --git a/examples/erc721/Cargo.toml b/examples/erc721/Cargo.toml index 068e9d81013..58e04f0197a 100644 --- a/examples/erc721/Cargo.toml +++ b/examples/erc721/Cargo.toml @@ -3,6 +3,7 @@ name = "erc721" version = "3.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" +resolver = "2" [dependencies] ink_primitives = { version = "3.0.0-rc6", path = "../../crates/primitives", default-features = false } diff --git a/examples/flipper/Cargo.toml b/examples/flipper/Cargo.toml index 22fb07ef367..3047165a5e4 100644 --- a/examples/flipper/Cargo.toml +++ b/examples/flipper/Cargo.toml @@ -3,6 +3,7 @@ name = "flipper" version = "3.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" +resolver = "2" [dependencies] ink_primitives = { version = "3.0.0-rc6", path = "../../crates/primitives", default-features = false } diff --git a/examples/incrementer/Cargo.toml b/examples/incrementer/Cargo.toml index 3f834cc9e89..a3756e22336 100644 --- a/examples/incrementer/Cargo.toml +++ b/examples/incrementer/Cargo.toml @@ -3,6 +3,7 @@ name = "incrementer" version = "3.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" +resolver = "2" [dependencies] ink_primitives = { version = "3.0.0-rc6", path = "../../crates/primitives", default-features = false } diff --git a/examples/multisig/Cargo.toml b/examples/multisig/Cargo.toml index f324ce3782d..3458a958502 100755 --- a/examples/multisig/Cargo.toml +++ b/examples/multisig/Cargo.toml @@ -3,6 +3,7 @@ name = "multisig" version = "3.0.0-rc5" authors = ["Parity Technologies "] edition = "2018" +resolver = "2" [dependencies] ink_primitives = { version = "3.0.0-rc6", path = "../../crates/primitives", default-features = false } diff --git a/examples/rand-extension/Cargo.toml b/examples/rand-extension/Cargo.toml index d17f4f985b8..3872c400e4d 100755 --- a/examples/rand-extension/Cargo.toml +++ b/examples/rand-extension/Cargo.toml @@ -3,6 +3,7 @@ name = "rand_extension" version = "3.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" +resolver = "2" [dependencies] ink_primitives = { version = "3.0.0-rc6", path = "../../crates/primitives", default-features = false } diff --git a/examples/trait-erc20/Cargo.toml b/examples/trait-erc20/Cargo.toml index 85200db8a7a..0b4efc6f67a 100644 --- a/examples/trait-erc20/Cargo.toml +++ b/examples/trait-erc20/Cargo.toml @@ -3,6 +3,7 @@ name = "trait_erc20" version = "3.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" +resolver = "2" [dependencies] ink_primitives = { version = "3.0.0-rc6", path = "../../crates/primitives", default-features = false } diff --git a/examples/trait-flipper/Cargo.toml b/examples/trait-flipper/Cargo.toml index 60563b6e504..ed049aaf45b 100644 --- a/examples/trait-flipper/Cargo.toml +++ b/examples/trait-flipper/Cargo.toml @@ -3,6 +3,7 @@ name = "trait_flipper" version = "3.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" +resolver = "2" [dependencies] ink_primitives = { version = "3.0.0-rc6", path = "../../crates/primitives", default-features = false } diff --git a/examples/trait-incrementer/Cargo.toml b/examples/trait-incrementer/Cargo.toml index 3e54410fe05..f92aa54e422 100644 --- a/examples/trait-incrementer/Cargo.toml +++ b/examples/trait-incrementer/Cargo.toml @@ -3,6 +3,7 @@ name = "trait-incrementer" version = "3.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" +resolver = "2" [dependencies] ink_primitives = { version = "3.0.0-rc6", path = "../../crates/primitives", default-features = false } From f3c5161fde3aa9bee915641519e7b3260ad54c82 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Thu, 21 Oct 2021 16:43:55 +0200 Subject: [PATCH 14/20] Switch to `libsecp256k1` 0.7.0 --- crates/engine/Cargo.toml | 2 +- crates/engine/src/ext.rs | 30 +++++++---------- crates/engine/src/tests.rs | 23 +++++-------- crates/env/Cargo.toml | 4 +-- .../engine/experimental_off_chain/impls.rs | 33 ++++++++----------- crates/env/src/engine/off_chain/impls.rs | 32 +++++++----------- crates/eth_compatibility/Cargo.toml | 2 +- crates/eth_compatibility/src/lib.rs | 6 ++-- 8 files changed, 52 insertions(+), 80 deletions(-) diff --git a/crates/engine/Cargo.toml b/crates/engine/Cargo.toml index 073d2c22a36..95cd6e4fa64 100644 --- a/crates/engine/Cargo.toml +++ b/crates/engine/Cargo.toml @@ -23,7 +23,7 @@ sha3 = { version = "0.9" } blake2 = { version = "0.9" } # ECDSA for the off-chain environment. -secp256k1 = { version = "0.20.3", features = ["recovery"] } +libsecp256k1 = { version = "0.7.0", features = ["lazy-static-context"] } [features] default = ["std"] diff --git a/crates/engine/src/ext.rs b/crates/engine/src/ext.rs index 1d01f2d9a08..73e4a1c26e9 100644 --- a/crates/engine/src/ext.rs +++ b/crates/engine/src/ext.rs @@ -428,13 +428,11 @@ impl Engine { message_hash: &[u8; 32], output: &mut [u8; 33], ) -> Result { - use secp256k1::{ - recovery::{ - RecoverableSignature, - RecoveryId, - }, + use libsecp256k1::{ + recover, Message, - Secp256k1, + RecoveryId, + Signature, }; // In most implementations, the v is just 0 or 1 internally, but 27 was added @@ -444,22 +442,16 @@ impl Engine { } else { signature[64] }; - let recovery_id = RecoveryId::from_i32(recovery_byte as i32) + let recovery_id = RecoveryId::parse(recovery_byte) .unwrap_or_else(|error| panic!("Unable to parse the recovery id: {}", error)); - let message = Message::from_slice(message_hash).unwrap_or_else(|error| { - panic!("Unable to create the message from hash: {}", error) - }); - let signature = - RecoverableSignature::from_compact(&signature[0..64], recovery_id) - .unwrap_or_else(|error| { - panic!("Unable to parse the signature: {}", error) - }); - - let secp = Secp256k1::new(); - let pub_key = secp.recover(&message, &signature); + let message = Message::parse(message_hash); + let signature = Signature::parse_standard_slice(&signature[0..64]) + .unwrap_or_else(|error| panic!("Unable to parse the signature: {}", error)); + + let pub_key = recover(&message, &signature, &recovery_id); match pub_key { Ok(pub_key) => { - *output = pub_key.serialize(); + *output = pub_key.serialize_compressed(); Ok(()) } Err(_) => Err(Error::EcdsaRecoverFailed), diff --git a/crates/engine/src/tests.rs b/crates/engine/src/tests.rs index f687ad3d136..524468685a2 100644 --- a/crates/engine/src/tests.rs +++ b/crates/engine/src/tests.rs @@ -16,11 +16,9 @@ use crate::ext::{ Engine, Error, }; -use secp256k1::{ - recovery::RecoverableSignature, +use libsecp256k1::{ Message, PublicKey, - Secp256k1, SecretKey, }; use std::convert::TryInto; @@ -239,12 +237,11 @@ fn ecdsa_recovery_test_from_contracts_pallet() { fn ecdsa_recovery_with_secp256k1_crate() { // given let mut engine = Engine::new(); - let secp = Secp256k1::new(); let seckey = [ 59, 148, 11, 85, 134, 130, 61, 253, 2, 174, 59, 70, 27, 180, 51, 107, 94, 203, 174, 253, 102, 39, 170, 146, 46, 252, 4, 143, 236, 12, 136, 28, ]; - let pubkey = PublicKey::from_slice(&[ + let pubkey = PublicKey::parse_compressed(&[ 2, 29, 21, 35, 7, 198, 183, 43, 14, 208, 65, 139, 14, 112, 205, 128, 231, 245, 41, 91, 141, 134, 245, 114, 45, 63, 82, 19, 251, 210, 57, 79, 54, ]) @@ -253,14 +250,12 @@ fn ecdsa_recovery_with_secp256k1_crate() { let mut msg_hash = [0; 32]; crate::hashing::sha2_256(b"Some message", &mut msg_hash); - let msg = Message::from_slice(&msg_hash).expect("message creation failed"); - let seckey = SecretKey::from_slice(&seckey).expect("secret key creation failed"); - let recoverable_signature: RecoverableSignature = - secp.sign_recoverable(&msg, &seckey); + let msg = Message::parse(&msg_hash); + let seckey = SecretKey::parse(&seckey).expect("secret key creation failed"); + let (signature, recovery_id) = libsecp256k1::sign(&msg, &seckey); - let recovery_id = recoverable_signature.serialize_compact().0.to_i32() as u8; - let mut signature = recoverable_signature.serialize_compact().1.to_vec(); - signature.push(recovery_id); + let mut signature = signature.serialize().to_vec(); + signature.push(recovery_id.serialize()); let signature_with_recovery_id: [u8; 65] = signature .try_into() .expect("unable to create signature with recovery id"); @@ -268,9 +263,9 @@ fn ecdsa_recovery_with_secp256k1_crate() { // when let mut output = [0; 33]; engine - .ecdsa_recover(&signature_with_recovery_id, msg.as_ref(), &mut output) + .ecdsa_recover(&signature_with_recovery_id, &msg.serialize(), &mut output) .expect("ecdsa recovery failed"); // then - assert_eq!(output, pubkey.serialize()); + assert_eq!(output, pubkey.serialize_compressed()); } diff --git a/crates/env/Cargo.toml b/crates/env/Cargo.toml index a517358c8db..cf21d59331a 100644 --- a/crates/env/Cargo.toml +++ b/crates/env/Cargo.toml @@ -30,7 +30,7 @@ static_assertions = "1.1" sp-arithmetic = { version = "3.0", default-features = false } [target.'cfg(target_arch = "wasm32")'.dependencies] -secp256k1 = { version = "0.20.3", default-features = false } +libsecp256k1 = { version = "0.7.0", default-features = false } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] ink_engine = { version = "3.0.0-rc6", path = "../engine/", default-features = false, optional = true } @@ -41,7 +41,7 @@ sha3 = { version = "0.9", optional = true } blake2 = { version = "0.9", optional = true } # ECDSA for the off-chain environment. -secp256k1 = { version = "0.20.3", features = ["recovery"] } +libsecp256k1 = { version = "0.7.0", features = ["lazy-static-context"] } # Only used in the off-chain environment. rand = { version = "0.8", default-features = false, features = ["alloc"], optional = true } diff --git a/crates/env/src/engine/experimental_off_chain/impls.rs b/crates/env/src/engine/experimental_off_chain/impls.rs index dea1c6d0139..9eac160dadf 100644 --- a/crates/env/src/engine/experimental_off_chain/impls.rs +++ b/crates/env/src/engine/experimental_off_chain/impls.rs @@ -34,6 +34,7 @@ use crate::{ Clear, EnvBackend, Environment, + Error, RentParams, RentStatus, Result, @@ -255,13 +256,11 @@ impl EnvBackend for EnvInstance { message_hash: &[u8; 32], output: &mut [u8; 33], ) -> Result<()> { - use secp256k1::{ - recovery::{ - RecoverableSignature, - RecoveryId, - }, + use libsecp256k1::{ + recover, Message, - Secp256k1, + RecoveryId, + Signature, }; // In most implementations, the v is just 0 or 1 internally, but 27 was added @@ -271,25 +270,19 @@ impl EnvBackend for EnvInstance { } else { signature[64] }; - let recovery_id = RecoveryId::from_i32(recovery_byte as i32) + let recovery_id = RecoveryId::parse(recovery_byte) .unwrap_or_else(|error| panic!("Unable to parse the recovery id: {}", error)); - let message = Message::from_slice(message_hash).unwrap_or_else(|error| { - panic!("Unable to create the message from hash: {}", error) - }); - let signature = - RecoverableSignature::from_compact(&signature[0..64], recovery_id) - .unwrap_or_else(|error| { - panic!("Unable to parse the signature: {}", error) - }); - - let secp = Secp256k1::new(); - let pub_key = secp.recover(&message, &signature); + let message = Message::parse(message_hash); + let signature = Signature::parse_standard_slice(&signature[0..64]) + .unwrap_or_else(|error| panic!("Unable to parse the signature: {}", error)); + + let pub_key = recover(&message, &signature, &recovery_id); match pub_key { Ok(pub_key) => { - *output = pub_key.serialize(); + *output = pub_key.serialize_compressed(); Ok(()) } - Err(_) => Err(crate::Error::EcdsaRecoverFailed), + Err(_) => Err(Error::EcdsaRecoverFailed), } } diff --git a/crates/env/src/engine/off_chain/impls.rs b/crates/env/src/engine/off_chain/impls.rs index 27ba2bb05de..529cf1baa57 100644 --- a/crates/env/src/engine/off_chain/impls.rs +++ b/crates/env/src/engine/off_chain/impls.rs @@ -201,13 +201,11 @@ impl EnvBackend for EnvInstance { message_hash: &[u8; 32], output: &mut [u8; 33], ) -> Result<()> { - use secp256k1::{ - recovery::{ - RecoverableSignature, - RecoveryId, - }, + use libsecp256k1::{ + recover, Message, - Secp256k1, + RecoveryId, + Signature, }; // In most implementations, the v is just 0 or 1 internally, but 27 was added @@ -217,25 +215,19 @@ impl EnvBackend for EnvInstance { } else { signature[64] }; - let recovery_id = RecoveryId::from_i32(recovery_byte as i32) + let recovery_id = RecoveryId::parse(recovery_byte) .unwrap_or_else(|error| panic!("Unable to parse the recovery id: {}", error)); - let message = Message::from_slice(message_hash).unwrap_or_else(|error| { - panic!("Unable to create the message from hash: {}", error) - }); - let signature = - RecoverableSignature::from_compact(&signature[0..64], recovery_id) - .unwrap_or_else(|error| { - panic!("Unable to parse the signature: {}", error) - }); - - let secp = Secp256k1::new(); - let pub_key = secp.recover(&message, &signature); + let message = Message::parse(message_hash); + let signature = Signature::parse_standard_slice(&signature[0..64]) + .unwrap_or_else(|error| panic!("Unable to parse the signature: {}", error)); + + let pub_key = recover(&message, &signature, &recovery_id); match pub_key { Ok(pub_key) => { - *output = pub_key.serialize(); + *output = pub_key.serialize_compressed(); Ok(()) } - Err(_) => Err(crate::Error::EcdsaRecoverFailed), + Err(_) => Err(Error::EcdsaRecoverFailed), } } diff --git a/crates/eth_compatibility/Cargo.toml b/crates/eth_compatibility/Cargo.toml index b93c2416109..85359c81567 100644 --- a/crates/eth_compatibility/Cargo.toml +++ b/crates/eth_compatibility/Cargo.toml @@ -16,7 +16,7 @@ include = ["Cargo.toml", "src/**/*.rs", "/README.md", "/LICENSE"] [dependencies] ink_env = { version = "3.0.0-rc6", path = "../env", default-features = false } -secp256k1 = { version = "0.20.3", default-features = false } +libsecp256k1 = { version = "0.7.0", default-features = false } [features] default = ["std"] diff --git a/crates/eth_compatibility/src/lib.rs b/crates/eth_compatibility/src/lib.rs index 1439f8f3098..827384ed3b2 100644 --- a/crates/eth_compatibility/src/lib.rs +++ b/crates/eth_compatibility/src/lib.rs @@ -93,12 +93,12 @@ impl ECDSAPublicKey { /// ``` pub fn to_eth_address(&self) -> EthereumAddress { use ink_env::hash; - use secp256k1::PublicKey; + use libsecp256k1::PublicKey; // Transform compressed public key into uncompressed. - let pub_key = PublicKey::from_slice(&self.0) + let pub_key = PublicKey::parse_compressed(&self.0) .expect("Unable to parse the compressed ECDSA public key"); - let uncompressed = pub_key.serialize_uncompressed(); + let uncompressed = pub_key.serialize(); // Hash the uncompressed public key by Keccak256 algorithm. let mut hash = ::Type::default(); From c68fcbe9de8837c4ffaf5b22c3ca8568f4c9a56a Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Thu, 21 Oct 2021 17:53:35 +0200 Subject: [PATCH 15/20] Use default features --- crates/engine/Cargo.toml | 2 +- crates/env/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/engine/Cargo.toml b/crates/engine/Cargo.toml index 95cd6e4fa64..ffbdfd290ed 100644 --- a/crates/engine/Cargo.toml +++ b/crates/engine/Cargo.toml @@ -23,7 +23,7 @@ sha3 = { version = "0.9" } blake2 = { version = "0.9" } # ECDSA for the off-chain environment. -libsecp256k1 = { version = "0.7.0", features = ["lazy-static-context"] } +libsecp256k1 = { version = "0.7.0" } [features] default = ["std"] diff --git a/crates/env/Cargo.toml b/crates/env/Cargo.toml index cf21d59331a..cb4666e694b 100644 --- a/crates/env/Cargo.toml +++ b/crates/env/Cargo.toml @@ -41,7 +41,7 @@ sha3 = { version = "0.9", optional = true } blake2 = { version = "0.9", optional = true } # ECDSA for the off-chain environment. -libsecp256k1 = { version = "0.7.0", features = ["lazy-static-context"] } +libsecp256k1 = { version = "0.7.0" } # Only used in the off-chain environment. rand = { version = "0.8", default-features = false, features = ["alloc"], optional = true } From b5ee0914d4828556ba032e7b93e960fa4bc30a89 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Thu, 21 Oct 2021 17:55:15 +0200 Subject: [PATCH 16/20] Bring comment back --- crates/env/Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/env/Cargo.toml b/crates/env/Cargo.toml index cb4666e694b..2d1cbaabee9 100644 --- a/crates/env/Cargo.toml +++ b/crates/env/Cargo.toml @@ -44,6 +44,9 @@ blake2 = { version = "0.9", optional = true } libsecp256k1 = { version = "0.7.0" } # Only used in the off-chain environment. +# +# Sadly couldn't be marked as dev-dependency. +# Never use this crate outside the off-chain environment! rand = { version = "0.8", default-features = false, features = ["alloc"], optional = true } scale-info = { version = "1.0", default-features = false, features = ["derive"], optional = true } From 2186ceb7cd9e6fb136edcb2c47e46fc1343655a1 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Thu, 21 Oct 2021 18:04:50 +0200 Subject: [PATCH 17/20] Reduce diff --- crates/engine/src/ext.rs | 5 +++-- crates/env/src/engine/experimental_off_chain/impls.rs | 5 +++-- crates/env/src/engine/off_chain/impls.rs | 5 +++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/crates/engine/src/ext.rs b/crates/engine/src/ext.rs index 73e4a1c26e9..a28957954cc 100644 --- a/crates/engine/src/ext.rs +++ b/crates/engine/src/ext.rs @@ -442,12 +442,13 @@ impl Engine { } else { signature[64] }; - let recovery_id = RecoveryId::parse(recovery_byte) - .unwrap_or_else(|error| panic!("Unable to parse the recovery id: {}", error)); let message = Message::parse(message_hash); let signature = Signature::parse_standard_slice(&signature[0..64]) .unwrap_or_else(|error| panic!("Unable to parse the signature: {}", error)); + let recovery_id = RecoveryId::parse(recovery_byte) + .unwrap_or_else(|error| panic!("Unable to parse the recovery id: {}", error)); + let pub_key = recover(&message, &signature, &recovery_id); match pub_key { Ok(pub_key) => { diff --git a/crates/env/src/engine/experimental_off_chain/impls.rs b/crates/env/src/engine/experimental_off_chain/impls.rs index 9eac160dadf..3cdc5979e76 100644 --- a/crates/env/src/engine/experimental_off_chain/impls.rs +++ b/crates/env/src/engine/experimental_off_chain/impls.rs @@ -270,12 +270,13 @@ impl EnvBackend for EnvInstance { } else { signature[64] }; - let recovery_id = RecoveryId::parse(recovery_byte) - .unwrap_or_else(|error| panic!("Unable to parse the recovery id: {}", error)); let message = Message::parse(message_hash); let signature = Signature::parse_standard_slice(&signature[0..64]) .unwrap_or_else(|error| panic!("Unable to parse the signature: {}", error)); + let recovery_id = RecoveryId::parse(recovery_byte) + .unwrap_or_else(|error| panic!("Unable to parse the recovery id: {}", error)); + let pub_key = recover(&message, &signature, &recovery_id); match pub_key { Ok(pub_key) => { diff --git a/crates/env/src/engine/off_chain/impls.rs b/crates/env/src/engine/off_chain/impls.rs index 529cf1baa57..4e8deda5489 100644 --- a/crates/env/src/engine/off_chain/impls.rs +++ b/crates/env/src/engine/off_chain/impls.rs @@ -215,12 +215,13 @@ impl EnvBackend for EnvInstance { } else { signature[64] }; - let recovery_id = RecoveryId::parse(recovery_byte) - .unwrap_or_else(|error| panic!("Unable to parse the recovery id: {}", error)); let message = Message::parse(message_hash); let signature = Signature::parse_standard_slice(&signature[0..64]) .unwrap_or_else(|error| panic!("Unable to parse the signature: {}", error)); + let recovery_id = RecoveryId::parse(recovery_byte) + .unwrap_or_else(|error| panic!("Unable to parse the recovery id: {}", error)); + let pub_key = recover(&message, &signature, &recovery_id); match pub_key { Ok(pub_key) => { From da18644d5903730043bbf052fea7ad0102584ef8 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Thu, 21 Oct 2021 19:11:54 +0200 Subject: [PATCH 18/20] Remove unnecessary import --- crates/engine/src/tests.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/engine/src/tests.rs b/crates/engine/src/tests.rs index 524468685a2..b8fd7179d50 100644 --- a/crates/engine/src/tests.rs +++ b/crates/engine/src/tests.rs @@ -21,7 +21,6 @@ use libsecp256k1::{ PublicKey, SecretKey, }; -use std::convert::TryInto; /// The public methods of the `contracts` pallet write their result into an /// `output` buffer instead of returning them. Since we aim to emulate this From f9f4b78a2d421e3d08bdb971b225c5439e4e14dc Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Thu, 21 Oct 2021 20:28:35 +0200 Subject: [PATCH 19/20] Update rustfmt config to edition 2018 --- .rustfmt.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.rustfmt.toml b/.rustfmt.toml index 0e0e77b53ca..422da2beabf 100644 --- a/.rustfmt.toml +++ b/.rustfmt.toml @@ -43,7 +43,7 @@ trailing_comma = "Vertical" match_block_trailing_comma = false blank_lines_upper_bound = 1 blank_lines_lower_bound = 0 -edition = "2018" # changed +edition = "2021" # changed version = "One" merge_derives = true use_try_shorthand = true # changed From ffbb1e8d98d5de39806dfb7c975d19e43237a689 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Thu, 21 Oct 2021 20:28:48 +0200 Subject: [PATCH 20/20] Use resolver `2` for workspace --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 554092d4a5e..48f592ff034 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,5 @@ [workspace] +resolver = "2" members = [ "crates/metadata", "crates/allocator",