Skip to content

Commit

Permalink
Add UseDigestTo* marker trait and blanket Sign/Verify impls
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
tarcieri committed Mar 26, 2019
1 parent 502c507 commit 80f518a
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 11 deletions.
2 changes: 1 addition & 1 deletion signature-crate/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*};
25 changes: 21 additions & 4 deletions signature-crate/src/sign/digest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<D, S>: Send + Sync
pub trait SignDigest<S>: 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<S, Error>;
fn sign_digest(&self, digest: Self::Digest) -> Result<S, Error>;
}

/// 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<S, T> Sign<S> for T
where
S: Signature,
T: SignDigest<S> + UseDigestToSign,
{
fn sign(&self, msg: &[u8]) -> Result<S, Error> {
self.sign_digest(<Self as SignDigest<S>>::Digest::new().chain(msg))
}
}
2 changes: 1 addition & 1 deletion signature-crate/src/sign/mod.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
28 changes: 24 additions & 4 deletions signature-crate/src/verify/digest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<D, S>: Send + Sync
pub trait VerifyDigest<S>: 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<S, T> Verify<S> for T
where
S: Signature,
T: VerifyDigest<S> + UseDigestToVerify,
{
fn verify(&self, msg: &[u8], signature: &S) -> Result<(), Error> {
self.verify_digest(
<Self as VerifyDigest<S>>::Digest::new().chain(msg),
signature,
)
}
}
2 changes: 1 addition & 1 deletion signature-crate/src/verify/mod.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down

0 comments on commit 80f518a

Please sign in to comment.