mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 18:07:58 +00:00
Add ecdsa::Pair::verify_prehashed() (#8996)
* Add ecdsa::Pair::verify_prehashed() * turn verify_prehashed() into an associated function * add Signature::recover_prehashed()
This commit is contained in:
@@ -354,6 +354,18 @@ impl Signature {
|
||||
.ok()
|
||||
.map(|recovered| Public(recovered.serialize_compressed()))
|
||||
}
|
||||
|
||||
/// Recover the public key from this signature and a pre-hashed message.
|
||||
#[cfg(feature = "full_crypto")]
|
||||
pub fn recover_prehashed(&self, message: &[u8; 32]) -> Option<Public> {
|
||||
let message = secp256k1::Message::parse(message);
|
||||
|
||||
let sig: (_, _) = self.try_into().ok()?;
|
||||
|
||||
secp256k1::recover(&message, &sig.0, &sig.1)
|
||||
.ok()
|
||||
.map(|key| Public(key.serialize_compressed()))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "full_crypto")]
|
||||
@@ -537,6 +549,22 @@ impl Pair {
|
||||
let message = secp256k1::Message::parse(message);
|
||||
secp256k1::sign(&message, &self.secret).into()
|
||||
}
|
||||
|
||||
/// Verify a signature on a pre-hashed message. Return `true` if the signature is valid
|
||||
/// and thus matches the given `public` key.
|
||||
pub fn verify_prehashed(sig: &Signature, message: &[u8; 32], public: &Public) -> bool {
|
||||
let message = secp256k1::Message::parse(message);
|
||||
|
||||
let sig: (_, _) = match sig.try_into() {
|
||||
Ok(x) => x,
|
||||
_ => return false,
|
||||
};
|
||||
|
||||
match secp256k1::recover(&message, &sig.0, &sig.1) {
|
||||
Ok(actual) => public.0[..] == actual.serialize_compressed()[..],
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CryptoType for Public {
|
||||
@@ -791,4 +819,37 @@ mod test {
|
||||
|
||||
assert_eq!(sig1, sig2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn verify_prehashed_works() {
|
||||
let (pair, _, _) = Pair::generate_with_phrase(Some("password"));
|
||||
|
||||
// `msg` and `sig` match
|
||||
let msg = keccak_256(b"this should be hashed");
|
||||
let sig = pair.sign_prehashed(&msg);
|
||||
assert!(Pair::verify_prehashed(&sig, &msg, &pair.public()));
|
||||
|
||||
// `msg` and `sig` don't match
|
||||
let msg = keccak_256(b"this is a different message");
|
||||
assert!(!Pair::verify_prehashed(&sig, &msg, &pair.public()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn recover_prehashed_works() {
|
||||
let (pair, _, _) = Pair::generate_with_phrase(Some("password"));
|
||||
|
||||
// recovered key matches signing key
|
||||
let msg = keccak_256(b"this should be hashed");
|
||||
let sig = pair.sign_prehashed(&msg);
|
||||
let key = sig.recover_prehashed(&msg).unwrap();
|
||||
assert_eq!(pair.public(), key);
|
||||
|
||||
// recovered key is useable
|
||||
assert!(Pair::verify_prehashed(&sig, &msg, &key));
|
||||
|
||||
// recovered key and signing key don't match
|
||||
let msg = keccak_256(b"this is a different message");
|
||||
let key = sig.recover_prehashed(&msg).unwrap();
|
||||
assert_ne!(pair.public(), key);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user