Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tweaks to eth signer #1526

Merged
merged 6 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ jobs:
cargo check -p subxt-signer
cargo check -p subxt-signer --no-default-features --features sr25519
cargo check -p subxt-signer --no-default-features --features ecdsa
cargo check -p subxt-signer --no-default-features --features unstable-eth

# We can't enable web features here, so no cargo hack.
- name: Cargo check subxt-lightclient
Expand Down
16 changes: 13 additions & 3 deletions signer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,26 @@ description = "Sign extrinsics to be submitted by Subxt"
keywords = ["parity", "subxt", "extrinsic", "signer"]

[features]
default = ["sr25519", "ecdsa", "eth", "subxt", "std"]
std = ["regex/std", "sp-crypto-hashing/std", "pbkdf2/std", "sha2/std", "hmac/std", "bip39/std", "schnorrkel/std", "secp256k1/std", "sp-core/std"]
default = ["sr25519", "ecdsa", "subxt", "std"]
std = [
"regex/std",
"sp-crypto-hashing/std",
"pbkdf2/std",
"sha2/std",
"hmac/std",
"bip39/std",
"schnorrkel/std",
"secp256k1/std",
"sp-core/std"
]

# Pick the signer implementation(s) you need by enabling the
# corresponding features. Note: I had more difficulties getting
# ecdsa compiling to WASM on my mac; following this comment helped:
# https://github.com/rust-bitcoin/rust-bitcoin/issues/930#issuecomment-1215538699
sr25519 = ["schnorrkel"]
ecdsa = ["secp256k1"]
eth = ["keccak-hash", "secp256k1", "bip32"]
unstable-eth = ["keccak-hash", "ecdsa", "secp256k1", "bip32"]
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We pull in the ecdsa::Keypair/sign/verify for instance, so need to ensure this stuff exists too :)


# Make the keypair algorithms here compatible with Subxt's Signer trait,
# so that they can be used to sign transactions for compatible chains.
Expand Down
18 changes: 9 additions & 9 deletions signer/src/ecdsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ use hex::FromHex;
use secp256k1::{ecdsa::RecoverableSignature, Message, Secp256k1, SecretKey};
use secrecy::ExposeSecret;

const SEED_LENGTH: usize = 32;
const SECRET_KEY_LENGTH: usize = 32;

/// Seed bytes used to generate a key pair.
pub type Seed = [u8; SEED_LENGTH];
pub type SecretKeyBytes = [u8; SECRET_KEY_LENGTH];

/// A signature generated by [`Keypair::sign()`]. These bytes are equivalent
/// to a Substrate `MultiSignature::Ecdsa(bytes)`.
Expand Down Expand Up @@ -67,8 +67,8 @@ impl Keypair {
// Else, parse the phrase string taking the password into account. This is
// the same approach taken in sp_core::crypto::Pair::from_string_with_seed.
let key = if let Some(hex_str) = phrase.expose_secret().strip_prefix("0x") {
let seed = Seed::from_hex(hex_str)?;
Self::from_seed(seed)?
let seed = SecretKeyBytes::from_hex(hex_str)?;
Self::from_secret_key(seed)?
} else {
let phrase = bip39::Mnemonic::from_str(phrase.expose_secret().as_str())?;
let pass_str = password.as_ref().map(|p| p.expose_secret().as_str());
Expand Down Expand Up @@ -97,20 +97,20 @@ impl Keypair {
let big_seed =
seed_from_entropy(&arr[0..len], password.unwrap_or("")).ok_or(Error::InvalidSeed)?;

let seed: Seed = big_seed[..SEED_LENGTH]
let secret_key_bytes: SecretKeyBytes = big_seed[..SECRET_KEY_LENGTH]
.try_into()
.expect("should be valid Seed");

Self::from_seed(seed)
Self::from_secret_key(secret_key_bytes)
}

/// Turn a 32 byte seed into a keypair.
///
/// # Warning
///
/// This will only be secure if the seed is secure!
pub fn from_seed(seed: Seed) -> Result<Self, Error> {
let secret = SecretKey::from_slice(&seed).map_err(|_| Error::InvalidSeed)?;
pub fn from_secret_key(secret_key: SecretKeyBytes) -> Result<Self, Error> {
let secret = SecretKey::from_slice(&secret_key).map_err(|_| Error::InvalidSeed)?;
Ok(Self(secp256k1::Keypair::from_secret_key(
&Secp256k1::signing_only(),
&secret,
Expand Down Expand Up @@ -148,7 +148,7 @@ impl Keypair {
}
}
}
Self::from_seed(acc)
Self::from_secret_key(acc)
}

/// Obtain the [`PublicKey`] part of this key pair, which can be used in calls to [`verify()`].
Expand Down
Loading