diff --git a/ecdsa/src/recovery.rs b/ecdsa/src/recovery.rs index 1194c158..4b68f028 100644 --- a/ecdsa/src/recovery.rs +++ b/ecdsa/src/recovery.rs @@ -71,6 +71,78 @@ impl RecoveryId { } } +#[cfg(feature = "verify")] +#[cfg_attr(docsrs, doc(cfg(feature = "verify")))] +impl RecoveryId { + /// Given a public key, message, and signature, use trial recovery + /// to determine if a suitable recovery ID exists, or return an error + /// otherwise. + pub fn trial_recovery_from_msg( + verifying_key: &VerifyingKey, + msg: &[u8], + signature: &Signature, + ) -> Result + where + C: DigestPrimitive + PrimeCurve + ProjectiveArithmetic, + AffinePoint: + DecompressPoint + FromEncodedPoint + ToEncodedPoint + VerifyPrimitive, + FieldSize: sec1::ModulusSize, + Scalar: Reduce, + SignatureSize: ArrayLength, + { + Self::trial_recovery_from_digest(verifying_key, C::Digest::new_with_prefix(msg), signature) + } + + /// Given a public key, message digest, and signature, use trial recovery + /// to determine if a suitable recovery ID exists, or return an error + /// otherwise. + pub fn trial_recovery_from_digest( + verifying_key: &VerifyingKey, + digest: D, + signature: &Signature, + ) -> Result + where + C: PrimeCurve + ProjectiveArithmetic, + D: Digest, + AffinePoint: + DecompressPoint + FromEncodedPoint + ToEncodedPoint + VerifyPrimitive, + FieldSize: sec1::ModulusSize, + Scalar: Reduce, + SignatureSize: ArrayLength, + { + Self::trial_recovery_from_prehash(verifying_key, &digest.finalize(), signature) + } + + /// Given a public key, message digest, and signature, use trial recovery + /// to determine if a suitable recovery ID exists, or return an error + /// otherwise. + pub fn trial_recovery_from_prehash( + verifying_key: &VerifyingKey, + prehash: &[u8], + signature: &Signature, + ) -> Result + where + C: PrimeCurve + ProjectiveArithmetic, + AffinePoint: + DecompressPoint + FromEncodedPoint + ToEncodedPoint + VerifyPrimitive, + FieldSize: sec1::ModulusSize, + Scalar: Reduce, + SignatureSize: ArrayLength, + { + for id in 0..=Self::MAX { + let recovery_id = RecoveryId(id); + + if let Ok(vk) = VerifyingKey::recover_from_prehash(prehash, signature, recovery_id) { + if verifying_key == &vk { + return Ok(recovery_id); + } + } + } + + Err(Error::new()) + } +} + impl TryFrom for RecoveryId { type Error = Error; @@ -89,7 +161,7 @@ impl From for u8 { #[cfg_attr(docsrs, doc(cfg(feature = "verify")))] impl VerifyingKey where - C: PrimeCurve + ProjectiveArithmetic + DigestPrimitive, + C: PrimeCurve + ProjectiveArithmetic, AffinePoint: DecompressPoint + FromEncodedPoint + ToEncodedPoint + VerifyPrimitive, FieldSize: sec1::ModulusSize, @@ -100,11 +172,14 @@ where /// [`RecoveryId`]. /// /// The message is first hashed using this curve's [`DigestPrimitive`]. - pub fn recover_from_message( + pub fn recover_from_msg( msg: &[u8], signature: &Signature, recovery_id: RecoveryId, - ) -> Result { + ) -> Result + where + C: DigestPrimitive, + { Self::recover_from_digest(C::Digest::new_with_prefix(msg), signature, recovery_id) } diff --git a/ecdsa/src/sign.rs b/ecdsa/src/sign.rs index 2962b56e..3a7eb5ce 100644 --- a/ecdsa/src/sign.rs +++ b/ecdsa/src/sign.rs @@ -200,7 +200,7 @@ where impl PrehashSigner> for SigningKey where C: PrimeCurve + ProjectiveArithmetic + DigestPrimitive, - C::Digest: BlockSizeUser + FixedOutput> + FixedOutputReset, + C::Digest: FixedOutput>, C::UInt: for<'a> From<&'a Scalar>, Scalar: Invert>> + Reduce + SignPrimitive, SignatureSize: ArrayLength, diff --git a/ecdsa/src/verify.rs b/ecdsa/src/verify.rs index bb3f435c..b36fa165 100644 --- a/ecdsa/src/verify.rs +++ b/ecdsa/src/verify.rs @@ -116,7 +116,7 @@ where impl PrehashVerifier> for VerifyingKey where - C: PrimeCurve + ProjectiveArithmetic + DigestPrimitive, + C: PrimeCurve + ProjectiveArithmetic, AffinePoint: VerifyPrimitive, Scalar: Reduce, SignatureSize: ArrayLength,