diff --git a/signature/src/signer.rs b/signature/src/signer.rs index 02ffe0f9..b9eec6ea 100644 --- a/signature/src/signer.rs +++ b/signature/src/signer.rs @@ -24,6 +24,20 @@ pub trait Signer { fn try_sign(&self, msg: &[u8]) -> Result; } +/// Equivalent of [`Signer`] but the message is provided in non-contiguous byte slices. +pub trait MultipartSigner { + /// Equivalent of [`Signer::sign()`] but the message + /// is provided in non-contiguous byte slices. + fn multipart_sign(&self, msg: &[&[u8]]) -> S { + self.try_multipart_sign(msg) + .expect("signature operation failed") + } + + /// Equivalent of [`Signer::try_sign()`] but the + /// message is provided in non-contiguous byte slices. + fn try_multipart_sign(&self, msg: &[&[u8]]) -> Result; +} + /// Sign the provided message bytestring using `&mut Self` (e.g. an evolving /// cryptographic key such as a stateful hash-based signature), returning a /// digital signature. @@ -103,6 +117,25 @@ pub trait RandomizedSigner { ) -> Result; } +/// Equivalent of [`RandomizedSigner`] but the message is provided in non-contiguous byte slices. +#[cfg(feature = "rand_core")] +pub trait RandomizedMultipartSigner { + /// Equivalent of [`RandomizedSigner::sign_with_rng()`] but + /// the message is provided in non-contiguous byte slices. + fn multipart_sign_with_rng(&self, rng: &mut R, msg: &[&[u8]]) -> S { + self.try_multipart_sign_with_rng(rng, msg) + .expect("signature operation failed") + } + + /// Equivalent of [`RandomizedSigner::try_sign_with_rng()`] but + /// the message is provided in non-contiguous byte slices. + fn try_multipart_sign_with_rng( + &self, + rng: &mut R, + msg: &[&[u8]], + ) -> Result; +} + /// Combination of [`DigestSigner`] and [`RandomizedSigner`] with support for /// computing a signature over a digest which requires entropy from an RNG. #[cfg(all(feature = "digest", feature = "rand_core"))] @@ -147,6 +180,25 @@ pub trait RandomizedSignerMut { ) -> Result; } +/// Equivalent of [`RandomizedSignerMut`] but the message is provided in non-contiguous byte slices. +#[cfg(feature = "rand_core")] +pub trait RandomizedMultipartSignerMut { + /// Equivalent of [`RandomizedSignerMut::sign_with_rng()`] but + /// the message is provided in non-contiguous byte slices. + fn multipart_sign_with_rng(&mut self, rng: &mut R, msg: &[&[u8]]) -> S { + self.try_multipart_sign_with_rng(rng, msg) + .expect("signature operation failed") + } + + /// Equivalent of [`RandomizedSignerMut::try_sign_with_rng()`] + /// but the message is provided in non-contiguous byte slices. + fn try_multipart_sign_with_rng( + &mut self, + rng: &mut R, + msg: &[&[u8]], + ) -> Result; +} + /// Blanket impl of [`RandomizedSignerMut`] for all [`RandomizedSigner`] types. #[cfg(feature = "rand_core")] impl> RandomizedSignerMut for T { diff --git a/signature/src/verifier.rs b/signature/src/verifier.rs index 65409a92..7c824f72 100644 --- a/signature/src/verifier.rs +++ b/signature/src/verifier.rs @@ -14,6 +14,13 @@ pub trait Verifier { fn verify(&self, msg: &[u8], signature: &S) -> Result<(), Error>; } +/// Equivalent of [`Verifier`] but the message is provided in non-contiguous byte slices. +pub trait MultipartVerifier { + /// Equivalent of [`Verifier::verify()`] but the + /// message is provided in non-contiguous byte slices. + fn multipart_verify(&self, msg: &[&[u8]], signature: &S) -> Result<(), Error>; +} + /// Verify the provided signature for the given prehashed message [`Digest`] /// is authentic. ///