Skip to content
Snippets Groups Projects
Commit ccb4e6a5 authored by Andreas Doerr's avatar Andreas Doerr Committed by GitHub
Browse files

Add ecdsa::Pair::verify_prehashed() (#8996)

* Add ecdsa::Pair::verify_prehashed()

* turn verify_prehashed() into an associated function

* add Signature::recover_prehashed()
parent 7ec6ebb6
Branches
No related merge requests found
......@@ -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);
}
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment