From 0ed928c3e1ce027c160aef1c1296fd8f693d94a9 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 29 Mar 2019 12:19:19 -0700 Subject: [PATCH 1/4] Digestable signatures: signature::digest::Signature Adds a marker trait for `Signature` types computable as `S(H(m))` where: - `S`: signature algorithm - `H`: hash (a.k.a. digest) function - `m`: message For signature types that implement this trait, a blanket impl of `Signer` will be provided for all types that `impl signature::digest::Signer`. --- signature-crate/src/digest/mod.rs | 3 ++- signature-crate/src/digest/signature.rs | 13 +++++++++++++ signature-crate/src/digest/signer.rs | 12 +++++++++++- signature-crate/src/digest/verifier.rs | 12 +++++++++++- 4 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 signature-crate/src/digest/signature.rs diff --git a/signature-crate/src/digest/mod.rs b/signature-crate/src/digest/mod.rs index 406623be..ab0eb08e 100644 --- a/signature-crate/src/digest/mod.rs +++ b/signature-crate/src/digest/mod.rs @@ -1,6 +1,7 @@ //! Support for using hash functions that impl the `Digest` trait in order //! to hash the input message in order to compute a signature. +mod signature; mod signer; mod verifier; @@ -8,4 +9,4 @@ mod verifier; /// trait this module depends on. pub use ::digest::Digest; -pub use self::{signer::Signer, verifier::Verifier}; +pub use self::{signature::Signature, signer::Signer, verifier::Verifier}; diff --git a/signature-crate/src/digest/signature.rs b/signature-crate/src/digest/signature.rs new file mode 100644 index 00000000..a54c7cc8 --- /dev/null +++ b/signature-crate/src/digest/signature.rs @@ -0,0 +1,13 @@ +use super::Digest; + +/// Marker trait for `Signature` types computable as `S(H(m))` where: +/// +/// - `S`: signature algorithm +/// - `H`: hash (a.k.a. digest) function +/// - `m`: message +/// +/// For signature types that implement this trait, a blanket impl of +/// `Signer` will be provided for all types that `impl digest::Signer`. +pub trait Signature: crate::signature::Signature { + type Digest: Digest; +} diff --git a/signature-crate/src/digest/signer.rs b/signature-crate/src/digest/signer.rs index 008493f9..325c2887 100644 --- a/signature-crate/src/digest/signer.rs +++ b/signature-crate/src/digest/signer.rs @@ -13,5 +13,15 @@ where S: Signature, { /// Sign the given prehashed message `Digest`, returning a signature. - fn sign(&self, digest: D) -> Result; + fn sign_digest(&self, digest: D) -> Result; +} + +impl crate::Signer for T +where + S: crate::digest::Signature, + T: Signer, +{ + fn sign(&self, msg: &[u8]) -> Result { + self.sign_digest(S::Digest::new().chain(msg)) + } } diff --git a/signature-crate/src/digest/verifier.rs b/signature-crate/src/digest/verifier.rs index 865b422b..28dcca5f 100644 --- a/signature-crate/src/digest/verifier.rs +++ b/signature-crate/src/digest/verifier.rs @@ -14,5 +14,15 @@ where S: Signature, { /// Verify the signature against the given `Digest` - fn verify(&self, digest: D, signature: &S) -> Result<(), Error>; + fn verify_digest(&self, digest: D, signature: &S) -> Result<(), Error>; +} + +impl crate::Verifier for T +where + S: crate::digest::Signature, + T: Verifier, +{ + fn verify(&self, msg: &[u8], signature: &S) -> Result<(), Error> { + self.verify_digest(S::Digest::new().chain(msg), signature) + } } From 5082a5139fb286f2b7fe097d05ea285faa05ce51 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 29 Mar 2019 12:32:17 -0700 Subject: [PATCH 2/4] Rename digest::Signature to 'Digestable' Re-exported as `signature::Digestable`, and acts as a marker trait for cases where signatures can be computed using `Digest`. --- signature-crate/src/digest/{signature.rs => digestable.rs} | 5 +++-- signature-crate/src/digest/mod.rs | 4 ++-- signature-crate/src/digest/signer.rs | 7 ++++--- signature-crate/src/digest/verifier.rs | 7 ++++--- signature-crate/src/lib.rs | 3 +++ 5 files changed, 16 insertions(+), 10 deletions(-) rename signature-crate/src/digest/{signature.rs => digestable.rs} (67%) diff --git a/signature-crate/src/digest/signature.rs b/signature-crate/src/digest/digestable.rs similarity index 67% rename from signature-crate/src/digest/signature.rs rename to signature-crate/src/digest/digestable.rs index a54c7cc8..02f852fc 100644 --- a/signature-crate/src/digest/signature.rs +++ b/signature-crate/src/digest/digestable.rs @@ -1,4 +1,4 @@ -use super::Digest; +use crate::{digest::Digest, signature::Signature}; /// Marker trait for `Signature` types computable as `S(H(m))` where: /// @@ -8,6 +8,7 @@ use super::Digest; /// /// For signature types that implement this trait, a blanket impl of /// `Signer` will be provided for all types that `impl digest::Signer`. -pub trait Signature: crate::signature::Signature { +pub trait Digestable: Signature { + /// Preferred `Digest` algorithm to use when computing this signature type. type Digest: Digest; } diff --git a/signature-crate/src/digest/mod.rs b/signature-crate/src/digest/mod.rs index ab0eb08e..3973d610 100644 --- a/signature-crate/src/digest/mod.rs +++ b/signature-crate/src/digest/mod.rs @@ -1,7 +1,7 @@ //! Support for using hash functions that impl the `Digest` trait in order //! to hash the input message in order to compute a signature. -mod signature; +mod digestable; mod signer; mod verifier; @@ -9,4 +9,4 @@ mod verifier; /// trait this module depends on. pub use ::digest::Digest; -pub use self::{signature::Signature, signer::Signer, verifier::Verifier}; +pub use self::{digestable::Digestable, signer::Signer, verifier::Verifier}; diff --git a/signature-crate/src/digest/signer.rs b/signature-crate/src/digest/signer.rs index 325c2887..d67e3763 100644 --- a/signature-crate/src/digest/signer.rs +++ b/signature-crate/src/digest/signer.rs @@ -4,7 +4,8 @@ //! For use signature algorithms that support an Initialize-Update-Finalize //! (IUF) API, such as ECDSA or Ed25519ph. -use crate::{digest::Digest, error::Error, Signature}; +use super::{Digest, Digestable}; +use crate::{error::Error, signature::Signature}; /// Sign the given prehashed message `Digest` using `Self`. pub trait Signer @@ -16,9 +17,9 @@ where fn sign_digest(&self, digest: D) -> Result; } -impl crate::Signer for T +impl crate::signer::Signer for T where - S: crate::digest::Signature, + S: Digestable + Signature, T: Signer, { fn sign(&self, msg: &[u8]) -> Result { diff --git a/signature-crate/src/digest/verifier.rs b/signature-crate/src/digest/verifier.rs index 28dcca5f..73804c9e 100644 --- a/signature-crate/src/digest/verifier.rs +++ b/signature-crate/src/digest/verifier.rs @@ -4,7 +4,8 @@ //! For use signature algorithms that support an Initialize-Update-Finalize //! (IUF) API, such as ECDSA or Ed25519ph. -use crate::{digest::Digest, error::Error, Signature}; +use super::{Digest, Digestable}; +use crate::{error::Error, signature::Signature}; /// Verify the provided signature for the given prehashed message `Digest` /// is authentic. @@ -17,9 +18,9 @@ where fn verify_digest(&self, digest: D, signature: &S) -> Result<(), Error>; } -impl crate::Verifier for T +impl crate::verifier::Verifier for T where - S: crate::digest::Signature, + S: Digestable + Signature, T: Verifier, { fn verify(&self, msg: &[u8], signature: &S) -> Result<(), Error> { diff --git a/signature-crate/src/lib.rs b/signature-crate/src/lib.rs index 03c3e8e6..05f1802e 100644 --- a/signature-crate/src/lib.rs +++ b/signature-crate/src/lib.rs @@ -27,3 +27,6 @@ pub mod signer; pub mod verifier; pub use crate::{error::Error, signature::Signature, signer::Signer, verifier::Verifier}; + +#[cfg(feature = "digest")] +pub use crate::digest::Digestable; From a1b59a16b42d9dad64ab87e6f081b9456ea7cd68 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 29 Mar 2019 12:44:44 -0700 Subject: [PATCH 3/4] Move blanket impls into 'digestable' module The `Digestable` trait is used to constrain blanket impls of `Signer` and `Verifier` for `digest::Signer` and `digest::Verifier` respectively. Since that's what it's used for, it makes sense to put the blanket impls in the same module. --- signature-crate/src/digest/digestable.rs | 28 +++++++++++++++++++++++- signature-crate/src/digest/signer.rs | 12 +--------- signature-crate/src/digest/verifier.rs | 12 +--------- 3 files changed, 29 insertions(+), 23 deletions(-) diff --git a/signature-crate/src/digest/digestable.rs b/signature-crate/src/digest/digestable.rs index 02f852fc..2fbed70d 100644 --- a/signature-crate/src/digest/digestable.rs +++ b/signature-crate/src/digest/digestable.rs @@ -1,4 +1,10 @@ -use crate::{digest::Digest, signature::Signature}; +use crate::{ + digest::{self, Digest}, + error::Error, + signature::Signature, + signer::Signer, + verifier::Verifier, +}; /// Marker trait for `Signature` types computable as `S(H(m))` where: /// @@ -12,3 +18,23 @@ pub trait Digestable: Signature { /// Preferred `Digest` algorithm to use when computing this signature type. type Digest: Digest; } + +impl Signer for T +where + S: Digestable + Signature, + T: digest::Signer, +{ + fn sign(&self, msg: &[u8]) -> Result { + self.sign_digest(S::Digest::new().chain(msg)) + } +} + +impl Verifier for T +where + S: Digestable + Signature, + T: digest::Verifier, +{ + fn verify(&self, msg: &[u8], signature: &S) -> Result<(), Error> { + self.verify_digest(S::Digest::new().chain(msg), signature) + } +} diff --git a/signature-crate/src/digest/signer.rs b/signature-crate/src/digest/signer.rs index d67e3763..0f915b4f 100644 --- a/signature-crate/src/digest/signer.rs +++ b/signature-crate/src/digest/signer.rs @@ -4,7 +4,7 @@ //! For use signature algorithms that support an Initialize-Update-Finalize //! (IUF) API, such as ECDSA or Ed25519ph. -use super::{Digest, Digestable}; +use super::Digest; use crate::{error::Error, signature::Signature}; /// Sign the given prehashed message `Digest` using `Self`. @@ -16,13 +16,3 @@ where /// Sign the given prehashed message `Digest`, returning a signature. fn sign_digest(&self, digest: D) -> Result; } - -impl crate::signer::Signer for T -where - S: Digestable + Signature, - T: Signer, -{ - fn sign(&self, msg: &[u8]) -> Result { - self.sign_digest(S::Digest::new().chain(msg)) - } -} diff --git a/signature-crate/src/digest/verifier.rs b/signature-crate/src/digest/verifier.rs index 73804c9e..32c00118 100644 --- a/signature-crate/src/digest/verifier.rs +++ b/signature-crate/src/digest/verifier.rs @@ -4,7 +4,7 @@ //! For use signature algorithms that support an Initialize-Update-Finalize //! (IUF) API, such as ECDSA or Ed25519ph. -use super::{Digest, Digestable}; +use super::Digest; use crate::{error::Error, signature::Signature}; /// Verify the provided signature for the given prehashed message `Digest` @@ -17,13 +17,3 @@ where /// Verify the signature against the given `Digest` fn verify_digest(&self, digest: D, signature: &S) -> Result<(), Error>; } - -impl crate::verifier::Verifier for T -where - S: Digestable + Signature, - T: Verifier, -{ - fn verify(&self, msg: &[u8], signature: &S) -> Result<(), Error> { - self.verify_digest(S::Digest::new().chain(msg), signature) - } -} From 564a42c5a549b5557284f8a94e2dfa196fd14034 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 1 Apr 2019 07:01:34 -0700 Subject: [PATCH 4/4] Have digest Signer/Verifier take digest output as an argument --- signature-crate/src/digest/digestable.rs | 4 ++-- signature-crate/src/digest/signer.rs | 3 ++- signature-crate/src/digest/verifier.rs | 7 ++++++- signature-crate/src/lib.rs | 6 +++--- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/signature-crate/src/digest/digestable.rs b/signature-crate/src/digest/digestable.rs index 2fbed70d..0eff397e 100644 --- a/signature-crate/src/digest/digestable.rs +++ b/signature-crate/src/digest/digestable.rs @@ -25,7 +25,7 @@ where T: digest::Signer, { fn sign(&self, msg: &[u8]) -> Result { - self.sign_digest(S::Digest::new().chain(msg)) + self.sign_digest(S::Digest::digest(msg)) } } @@ -35,6 +35,6 @@ where T: digest::Verifier, { fn verify(&self, msg: &[u8], signature: &S) -> Result<(), Error> { - self.verify_digest(S::Digest::new().chain(msg), signature) + self.verify_digest(S::Digest::digest(msg), signature) } } diff --git a/signature-crate/src/digest/signer.rs b/signature-crate/src/digest/signer.rs index 0f915b4f..65043b0a 100644 --- a/signature-crate/src/digest/signer.rs +++ b/signature-crate/src/digest/signer.rs @@ -6,6 +6,7 @@ use super::Digest; use crate::{error::Error, signature::Signature}; +use digest::generic_array::GenericArray; /// Sign the given prehashed message `Digest` using `Self`. pub trait Signer @@ -14,5 +15,5 @@ where S: Signature, { /// Sign the given prehashed message `Digest`, returning a signature. - fn sign_digest(&self, digest: D) -> Result; + fn sign_digest(&self, digest: GenericArray) -> Result; } diff --git a/signature-crate/src/digest/verifier.rs b/signature-crate/src/digest/verifier.rs index 32c00118..72d5f017 100644 --- a/signature-crate/src/digest/verifier.rs +++ b/signature-crate/src/digest/verifier.rs @@ -6,6 +6,7 @@ use super::Digest; use crate::{error::Error, signature::Signature}; +use digest::generic_array::GenericArray; /// Verify the provided signature for the given prehashed message `Digest` /// is authentic. @@ -15,5 +16,9 @@ where S: Signature, { /// Verify the signature against the given `Digest` - fn verify_digest(&self, digest: D, signature: &S) -> Result<(), Error>; + fn verify_digest( + &self, + digest: GenericArray, + signature: &S, + ) -> Result<(), Error>; } diff --git a/signature-crate/src/lib.rs b/signature-crate/src/lib.rs index 05f1802e..688258fd 100644 --- a/signature-crate/src/lib.rs +++ b/signature-crate/src/lib.rs @@ -19,12 +19,12 @@ extern crate std; #[cfg(feature = "digest")] -mod digest; +pub mod digest; mod error; mod prelude; mod signature; -pub mod signer; -pub mod verifier; +mod signer; +mod verifier; pub use crate::{error::Error, signature::Signature, signer::Signer, verifier::Verifier};