From 82fc9daecd4ad9a7c1f5bfef1a5125b1463040fa Mon Sep 17 00:00:00 2001 From: Trevor Arjeski Date: Tue, 20 Jul 2021 18:48:07 +0300 Subject: [PATCH] Added v2 host function for ecdsa_verify --- primitives/core/src/ecdsa.rs | 41 ++++++++++++++++++++++++++++++------ primitives/io/src/lib.rs | 12 +++++++++++ 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/primitives/core/src/ecdsa.rs b/primitives/core/src/ecdsa.rs index e77576e40b2ee..0c3ce081457cc 100644 --- a/primitives/core/src/ecdsa.rs +++ b/primitives/core/src/ecdsa.rs @@ -382,10 +382,7 @@ impl From<(libsecp256k1::Signature, libsecp256k1::RecoveryId)> for Signature { impl<'a> TryFrom<&'a Signature> for (libsecp256k1::Signature, libsecp256k1::RecoveryId) { type Error = (); fn try_from(x: &'a Signature) -> Result<(libsecp256k1::Signature, libsecp256k1::RecoveryId), Self::Error> { - Ok(( - libsecp256k1::Signature::parse_overflowing_slice(&x.0[0..64]).expect("hardcoded to 64 bytes; qed"), - libsecp256k1::RecoveryId::parse(x.0[64]).map_err(|_| ())?, - )) + parse_signature(&x.0).map_err(|_| ()) } } @@ -511,8 +508,10 @@ impl TraitPair for Pair { fn verify_weak, M: AsRef<[u8]>>(sig: &[u8], message: M, pubkey: P) -> bool { let message = libsecp256k1::Message::parse(&blake2_256(message.as_ref())); if sig.len() != 65 { return false } - let ri = match libsecp256k1::RecoveryId::parse(sig[64]) { Ok(x) => x, _ => return false }; - let sig = match libsecp256k1::Signature::parse_overflowing_slice(&sig[0..64]) { Ok(x) => x, _ => return false }; + let (sig, ri) = match parse_signature(&sig) { + Ok(sigri) => sigri, + _ => return false, + }; match libsecp256k1::recover(&message, &sig, &ri) { Ok(actual) => pubkey.as_ref() == &actual.serialize()[1..], _ => false, @@ -565,6 +564,36 @@ impl Pair { _ => false, } } + + /// Verify a signature on a message. Returns true if the signature is good. + /// Parses Signature using parse_overflowing_slice + pub fn verify_deprecated>(sig: &Signature, message: M, pubkey: &Public) -> bool { + let message = libsecp256k1::Message::parse(&blake2_256(message.as_ref())); + let (sig, ri) = match parse_signature_deprecated(&sig.0) { + Ok(sigri) => sigri, + _ => return false + }; + match libsecp256k1::recover(&message, &sig, &ri) { + Ok(actual) => pubkey.0[..] == actual.serialize_compressed()[..], + _ => false, + } + } +} + +fn parse_signature( + x: &[u8], +) -> Result<(libsecp256k1::Signature, libsecp256k1::RecoveryId), libsecp256k1::Error> { + let sig = libsecp256k1::Signature::parse_standard_slice(&x[0..64])?; + let ri = libsecp256k1::RecoveryId::parse(x[64])?; + Ok((sig, ri)) +} + +fn parse_signature_deprecated( + x: &[u8], +) -> Result<(libsecp256k1::Signature, libsecp256k1::RecoveryId), libsecp256k1::Error> { + let sig = libsecp256k1::Signature::parse_overflowing_slice(&x[0..64])?; + let ri = libsecp256k1::RecoveryId::parse(x[64])?; + Ok((sig, ri)) } impl CryptoType for Public { diff --git a/primitives/io/src/lib.rs b/primitives/io/src/lib.rs index 6fb25df3d02a5..92c0ddb5a92c0 100644 --- a/primitives/io/src/lib.rs +++ b/primitives/io/src/lib.rs @@ -740,6 +740,18 @@ pub trait Crypto { /// Verify `ecdsa` signature. /// /// Returns `true` when the verification was successful. + fn ecdsa_verify( + sig: &ecdsa::Signature, + msg: &[u8], + pub_key: &ecdsa::Public, + ) -> bool { + ecdsa::Pair::verify_deprecated(sig, msg, pub_key) + } + + /// Verify `ecdsa` signature. + /// + /// Returns `true` when the verification was successful. + #[version(2)] fn ecdsa_verify( sig: &ecdsa::Signature, msg: &[u8],