From 80f518ae04d84fa4f1609e8d945f749931e5a249 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 26 Mar 2019 10:44:17 -0700 Subject: [PATCH 1/2] Add UseDigestTo* marker trait and blanket Sign/Verify impls This commit makes the digest for `SignDigest` and `VerifyDigest` an associated type rather than a generic, and also adds two marker traits: - `UseDigestToSign`: opt into blanket impl of `Sign` for `SignDigest` - `UseDigestToVerify`: opt into blanket impl of `Verify` for `VerifyDigest` The reason for requiring a marker trait is there are cases where the same keys can be used with an IUF mode of an algorithm which is distinct from the non-IUF form, e.g. Ed25519 vs Ed25519ph. In this case, the underlying keys are the same, but the signature algorithm when using the IUF mode is distinct. --- signature-crate/src/lib.rs | 2 +- signature-crate/src/sign/digest.rs | 25 +++++++++++++++++++++---- signature-crate/src/sign/mod.rs | 2 +- signature-crate/src/verify/digest.rs | 28 ++++++++++++++++++++++++---- signature-crate/src/verify/mod.rs | 2 +- 5 files changed, 48 insertions(+), 11 deletions(-) diff --git a/signature-crate/src/lib.rs b/signature-crate/src/lib.rs index 14d15ddf..2354231b 100644 --- a/signature-crate/src/lib.rs +++ b/signature-crate/src/lib.rs @@ -27,4 +27,4 @@ pub mod sign; mod signature; pub mod verify; -pub use crate::{error::Error, sign::Sign, signature::Signature, verify::Verify}; +pub use crate::{error::Error, sign::*, signature::*, verify::*}; diff --git a/signature-crate/src/sign/digest.rs b/signature-crate/src/sign/digest.rs index e4f21c2b..b2897842 100644 --- a/signature-crate/src/sign/digest.rs +++ b/signature-crate/src/sign/digest.rs @@ -4,15 +4,32 @@ //! For use signature algorithms that support an Initialize-Update-Finalize //! (IUF) API, such as ECDSA or Ed25519ph. -use crate::{error::Error, Signature}; +use super::Sign; +use crate::{Error, Signature}; use digest::Digest; /// Sign the given prehashed message `Digest` using `Self`. -pub trait SignDigest: Send + Sync +pub trait SignDigest: Send + Sync where - D: Digest, S: Signature, { + /// Digest type to use when computing a signature + type Digest: Digest; + /// Sign the given prehashed message `Digest`, returning a signature. - fn sign(&self, digest: D) -> Result; + fn sign_digest(&self, digest: Self::Digest) -> Result; +} + +/// Marker trait for digest verifiers who wish to use a blanket impl of the +/// `Sign` trait which works with any type that implements `SignDigest` +pub trait UseDigestToSign {} + +impl Sign for T +where + S: Signature, + T: SignDigest + UseDigestToSign, +{ + fn sign(&self, msg: &[u8]) -> Result { + self.sign_digest(>::Digest::new().chain(msg)) + } } diff --git a/signature-crate/src/sign/mod.rs b/signature-crate/src/sign/mod.rs index 1acc7c84..2ec1d44a 100644 --- a/signature-crate/src/sign/mod.rs +++ b/signature-crate/src/sign/mod.rs @@ -1,7 +1,7 @@ //! Traits for generating digital signatures #[cfg(feature = "digest")] -pub(crate) mod digest; +mod digest; #[cfg(feature = "digest")] pub use self::digest::SignDigest; diff --git a/signature-crate/src/verify/digest.rs b/signature-crate/src/verify/digest.rs index c577e700..7ef03744 100644 --- a/signature-crate/src/verify/digest.rs +++ b/signature-crate/src/verify/digest.rs @@ -4,16 +4,36 @@ //! For use signature algorithms that support an Initialize-Update-Finalize //! (IUF) API, such as ECDSA or Ed25519ph. -use crate::{error::Error, Signature}; +use super::Verify; +use crate::{Error, Signature}; use digest::Digest; /// Verify the provided signature for the given prehashed message `Digest` /// is authentic. -pub trait VerifyDigest: Send + Sync +pub trait VerifyDigest: Send + Sync where - D: Digest, S: Signature, { + /// Digest type to use when verifying a signature + type Digest: Digest; + /// Verify the signature against the given `Digest` - fn verify(&self, digest: D, signature: &S) -> Result<(), Error>; + fn verify_digest(&self, digest: Self::Digest, signature: &S) -> Result<(), Error>; +} + +/// Marker trait for digest verifiers who wish to use a blanket impl of the +/// `Verify` trait which works with any type that implements `VerifyDigest` +pub trait UseDigestToVerify {} + +impl Verify for T +where + S: Signature, + T: VerifyDigest + UseDigestToVerify, +{ + fn verify(&self, msg: &[u8], signature: &S) -> Result<(), Error> { + self.verify_digest( + >::Digest::new().chain(msg), + signature, + ) + } } diff --git a/signature-crate/src/verify/mod.rs b/signature-crate/src/verify/mod.rs index d8c4b0e2..a6902cd5 100644 --- a/signature-crate/src/verify/mod.rs +++ b/signature-crate/src/verify/mod.rs @@ -1,7 +1,7 @@ //! Trait for verifying digital signatures #[cfg(feature = "digest")] -pub(crate) mod digest; +mod digest; #[cfg(feature = "digest")] pub use self::digest::VerifyDigest; From 0232b07defaf8cb387bef303b4ba183d98632fe4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 26 Mar 2019 10:57:56 -0700 Subject: [PATCH 2/2] Move associated Digest to UseDigestTo* marker traits This allows the `SignDigest` and `VerifyDigest` traits to remain object safe with the same general shape as `Sign` and `Verify`. --- signature-crate/src/sign/digest.rs | 17 +++++++++-------- signature-crate/src/verify/digest.rs | 17 +++++++++-------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/signature-crate/src/sign/digest.rs b/signature-crate/src/sign/digest.rs index b2897842..005ec5ea 100644 --- a/signature-crate/src/sign/digest.rs +++ b/signature-crate/src/sign/digest.rs @@ -9,27 +9,28 @@ use crate::{Error, Signature}; use digest::Digest; /// Sign the given prehashed message `Digest` using `Self`. -pub trait SignDigest: Send + Sync +pub trait SignDigest: Send + Sync where + D: Digest, S: Signature, { - /// Digest type to use when computing a signature - type Digest: Digest; - /// Sign the given prehashed message `Digest`, returning a signature. - fn sign_digest(&self, digest: Self::Digest) -> Result; + fn sign_digest(&self, digest: D) -> Result; } /// Marker trait for digest verifiers who wish to use a blanket impl of the /// `Sign` trait which works with any type that implements `SignDigest` -pub trait UseDigestToSign {} +pub trait UseDigestToSign { + /// Digest type to use when computing a signature + type Digest: Digest; +} impl Sign for T where S: Signature, - T: SignDigest + UseDigestToSign, + T: UseDigestToSign + SignDigest<::Digest, S>, { fn sign(&self, msg: &[u8]) -> Result { - self.sign_digest(>::Digest::new().chain(msg)) + self.sign_digest(::Digest::new().chain(msg)) } } diff --git a/signature-crate/src/verify/digest.rs b/signature-crate/src/verify/digest.rs index 7ef03744..a940a77f 100644 --- a/signature-crate/src/verify/digest.rs +++ b/signature-crate/src/verify/digest.rs @@ -10,29 +10,30 @@ use digest::Digest; /// Verify the provided signature for the given prehashed message `Digest` /// is authentic. -pub trait VerifyDigest: Send + Sync +pub trait VerifyDigest: Send + Sync where + D: Digest, S: Signature, { - /// Digest type to use when verifying a signature - type Digest: Digest; - /// Verify the signature against the given `Digest` - fn verify_digest(&self, digest: Self::Digest, signature: &S) -> Result<(), Error>; + fn verify_digest(&self, digest: D, signature: &S) -> Result<(), Error>; } /// Marker trait for digest verifiers who wish to use a blanket impl of the /// `Verify` trait which works with any type that implements `VerifyDigest` -pub trait UseDigestToVerify {} +pub trait UseDigestToVerify { + /// Digest type to use when verifying a signature + type Digest: Digest; +} impl Verify for T where S: Signature, - T: VerifyDigest + UseDigestToVerify, + T: UseDigestToVerify + VerifyDigest<::Digest, S>, { fn verify(&self, msg: &[u8], signature: &S) -> Result<(), Error> { self.verify_digest( - >::Digest::new().chain(msg), + ::Digest::new().chain(msg), signature, ) }