Skip to content

Commit

Permalink
feat(signer): ethereum implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanleecode committed Mar 26, 2024
1 parent d6ae5b4 commit b394b36
Show file tree
Hide file tree
Showing 7 changed files with 425 additions and 18 deletions.
115 changes: 113 additions & 2 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 @@ -150,6 +150,7 @@ hmac = { version = "0.12.1", default-features = false }
pbkdf2 = { version = "0.12.2", default-features = false }
schnorrkel = { version = "0.11.4", default-features = false }
secp256k1 = { version = "0.28.2", default-features = false }
keccak-hash = { version = "0.10.0", default-features = false }
secrecy = "0.8.0"
sha2 = { version = "0.10.8", default-features = false }
zeroize = { version = "1", default-features = false }
Expand Down
6 changes: 4 additions & 2 deletions signer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ description = "Sign extrinsics to be submitted by Subxt"
keywords = ["parity", "subxt", "extrinsic", "signer"]

[features]
default = ["sr25519", "ecdsa", "subxt", "std", "native"]
default = ["sr25519", "ecdsa", "eth", "subxt", "std", "native"]
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
Expand All @@ -24,6 +24,7 @@ std = ["regex/std", "sp-crypto-hashing/std", "pbkdf2/std", "sha2/std", "hmac/std
# https://github.com/rust-bitcoin/rust-bitcoin/issues/930#issuecomment-1215538699
sr25519 = ["schnorrkel"]
ecdsa = ["secp256k1"]
eth = ["keccak-hash", "secp256k1"]

# Make the keypair algorithms here compatible with Subxt's Signer trait,
# so that they can be used to sign transactions for compatible chains.
Expand All @@ -50,14 +51,15 @@ bip39 = { workspace = true }
schnorrkel = { workspace = true, optional = true }
secp256k1 = { workspace = true, optional = true, features = ["alloc", "recovery"] }
secrecy = { workspace = true }

keccak-hash = { workspace = true, optional = true }

# We only pull this in to enable the JS flag for schnorrkel to use.
getrandom = { workspace = true, optional = true }

[dev-dependencies]
sp-core = { workspace = true }
sp-keyring = { workspace = true }
proptest = "1.4.0"

[package.metadata.cargo-machete]
ignored = ["getrandom"]
Expand Down
21 changes: 11 additions & 10 deletions signer/src/ecdsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,21 +160,22 @@ impl Keypair {

/// Sign some message. These bytes can be used directly in a Substrate `MultiSignature::Ecdsa(..)`.
pub fn sign(&self, message: &[u8]) -> Signature {
// From sp_core::ecdsa::sign:
let message_hash = sp_crypto_hashing::blake2_256(message);
// From sp_core::ecdsa::sign_prehashed:
let wrapped = Message::from_digest_slice(&message_hash).expect("Message is 32 bytes; qed");
let recsig: RecoverableSignature =
Secp256k1::signing_only().sign_ecdsa_recoverable(&wrapped, &self.0.secret_key());
// From sp_core::ecdsa's `impl From<RecoverableSignature> for Signature`:
let (recid, sig): (_, [u8; 64]) = recsig.serialize_compact();
let mut signature_bytes: [u8; 65] = [0; 65];
signature_bytes[..64].copy_from_slice(&sig);
signature_bytes[64] = (recid.to_i32() & 0xFF) as u8;
Signature(signature_bytes)
Signature(sign(&self.0.secret_key(), &wrapped))
}
}

pub(crate) fn sign(secret_key: &secp256k1::SecretKey, message: &Message) -> [u8; 65] {
let recsig: RecoverableSignature =
Secp256k1::signing_only().sign_ecdsa_recoverable(message, secret_key);
let (recid, sig): (_, [u8; 64]) = recsig.serialize_compact();
let mut signature_bytes: [u8; 65] = [0; 65];
signature_bytes[..64].copy_from_slice(&sig);
signature_bytes[64] = (recid.to_i32() & 0xFF) as u8;
signature_bytes
}

/// Verify that some signature for a message was created by the owner of the [`PublicKey`].
///
/// ```rust
Expand Down
Loading

0 comments on commit b394b36

Please sign in to comment.