Skip to content

Commit

Permalink
Replace libsecp256k1 with k256 in FRAME related code (paritytech#10883)
Browse files Browse the repository at this point in the history
* Replace libsecp256k1 with k256 in beefy-mmr

* Port of FRAME `contracts` benchmarking from `libsecp256k1` to `k256`

* Newtype to allow `Pcg32` rng usage with `k256` in contracts benchmarks

* Use `sp-io::crypto` to generate dummy keys in `contracts` bechmarks

* More compact code

* Cargo fmt

* Build `sp-keystore` only for dev profile

* Move public key generation back to the `map`
  • Loading branch information
davxy authored and ark0f committed Feb 27, 2023
1 parent 26aa615 commit f2f2ede
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 34 deletions.
146 changes: 142 additions & 4 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ hash-db = { opt-level = 3 }
hmac = { opt-level = 3 }
httparse = { opt-level = 3 }
integer-sqrt = { opt-level = 3 }
k256 = { opt-level = 3 }
keccak = { opt-level = 3 }
libm = { opt-level = 3 }
librocksdb-sys = { opt-level = 3 }
Expand Down
4 changes: 2 additions & 2 deletions frame/beefy-mmr/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ repository = "https://github.com/paritytech/substrate"
[dependencies]
hex = { version = "0.4", optional = true }
codec = { version = "2.2.0", package = "parity-scale-codec", default-features = false, features = ["derive"] }
libsecp256k1 = { version = "0.7.0", default-features = false }
k256 = { version = "0.10.2", default-features = false, features = ["arithmetic"] }
log = { version = "0.4.13", default-features = false }
scale-info = { version = "1.0", default-features = false, features = ["derive"] }
serde = { version = "1.0.136", optional = true }
Expand Down Expand Up @@ -43,7 +43,7 @@ std = [
"frame-support/std",
"frame-system/std",
"hex",
"libsecp256k1/std",
"k256/std",
"log/std",
"pallet-beefy/std",
"pallet-mmr-primitives/std",
Expand Down
27 changes: 13 additions & 14 deletions frame/beefy-mmr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,21 +72,20 @@ where
pub struct BeefyEcdsaToEthereum;
impl Convert<beefy_primitives::crypto::AuthorityId, Vec<u8>> for BeefyEcdsaToEthereum {
fn convert(a: beefy_primitives::crypto::AuthorityId) -> Vec<u8> {
use k256::{elliptic_curve::sec1::ToEncodedPoint, PublicKey};
use sp_core::crypto::ByteArray;
let compressed_key = a.as_slice();

libsecp256k1::PublicKey::parse_slice(
compressed_key,
Some(libsecp256k1::PublicKeyFormat::Compressed),
)
// uncompress the key
.map(|pub_key| pub_key.serialize().to_vec())
// now convert to ETH address
.map(|uncompressed| sp_io::hashing::keccak_256(&uncompressed[1..])[12..].to_vec())
.map_err(|_| {
log::error!(target: "runtime::beefy", "Invalid BEEFY PublicKey format!");
})
.unwrap_or_default()

PublicKey::from_sec1_bytes(a.as_slice())
.map(|pub_key| {
// uncompress the key
let uncompressed = pub_key.to_encoded_point(false);
// convert to ETH address
sp_io::hashing::keccak_256(&uncompressed.as_bytes()[1..])[12..].to_vec()
})
.map_err(|_| {
log::error!(target: "runtime::beefy", "Invalid BEEFY PublicKey format!");
})
.unwrap_or_default()
}
}

Expand Down
4 changes: 1 addition & 3 deletions frame/contracts/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ smallvec = { version = "1", default-features = false, features = [
wasmi-validation = { version = "0.4", default-features = false }

# Only used in benchmarking to generate random contract code
libsecp256k1 = { version = "0.7", optional = true, default-features = false, features = ["hmac", "static-context"] }
rand = { version = "0.8", optional = true, default-features = false }
rand_pcg = { version = "0.3", optional = true }

Expand Down Expand Up @@ -56,6 +55,7 @@ pallet-balances = { version = "4.0.0-dev", path = "../balances" }
pallet-timestamp = { version = "4.0.0-dev", path = "../timestamp" }
pallet-randomness-collective-flip = { version = "4.0.0-dev", path = "../randomness-collective-flip" }
pallet-utility = { version = "4.0.0-dev", path = "../utility" }
sp-keystore = { version = "0.11.0", path = "../../primitives/keystore" }

[features]
default = ["std"]
Expand All @@ -77,11 +77,9 @@ std = [
"pallet-contracts-proc-macro/full",
"log/std",
"rand/std",
"libsecp256k1/std",
]
runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
"libsecp256k1",
"rand",
"rand_pcg",
"unstable-interface",
Expand Down
14 changes: 4 additions & 10 deletions frame/contracts/src/benchmarking/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1866,20 +1866,14 @@ benchmarks! {
// It generates different private keys and signatures for the message "Hello world".
seal_ecdsa_recover {
let r in 0 .. API_BENCHMARK_BATCHES;
use rand::SeedableRng;
let mut rng = rand_pcg::Pcg32::seed_from_u64(123456);

let message_hash = sp_io::hashing::blake2_256("Hello world".as_bytes());
let key_type = sp_core::crypto::KeyTypeId(*b"code");
let signatures = (0..r * API_BENCHMARK_BATCH_SIZE)
.map(|i| {
use libsecp256k1::{SecretKey, Message, sign};

let private_key = SecretKey::random(&mut rng);
let (signature, recovery_id) = sign(&Message::parse(&message_hash), &private_key);
let mut full_signature = [0; 65];
full_signature[..64].copy_from_slice(&signature.serialize());
full_signature[64] = recovery_id.serialize();
full_signature
let pub_key = sp_io::crypto::ecdsa_generate(key_type, None);
let sig = sp_io::crypto::ecdsa_sign_prehashed(key_type, &pub_key, &message_hash).expect("Generates signature");
AsRef::<[u8; 65]>::as_ref(&sig).to_vec()
})
.collect::<Vec<_>>();
let signatures = signatures.iter().flatten().cloned().collect::<Vec<_>>();
Expand Down
Loading

0 comments on commit f2f2ede

Please sign in to comment.