diff --git a/signature/CHANGELOG.md b/signature/CHANGELOG.md index 3f9d8cd08..554e0f5fd 100644 --- a/signature/CHANGELOG.md +++ b/signature/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased +### Added +- `RandomizedSignerMut` trait + +[#1448](https://github.com/RustCrypto/traits/pull/1448) + ## 2.2.0 (2023-11-12) ### Changed - MSRV 1.60 ([#1387]) diff --git a/signature/src/signer.rs b/signature/src/signer.rs index b339ddf59..488f7da67 100644 --- a/signature/src/signer.rs +++ b/signature/src/signer.rs @@ -116,3 +116,30 @@ pub trait RandomizedDigestSigner { fn try_sign_digest_with_rng(&self, rng: &mut impl CryptoRngCore, digest: D) -> Result; } + +/// Sign the provided message bytestring using `&mut Self` (e.g. an evolving +/// cryptographic key such as a stateful hash-based signature), and a per-signature +/// randomizer, returning a digital signature. +#[cfg(feature = "rand_core")] +pub trait RandomizedSignerMut { + /// Sign the given message, update the state, and return a digital signature. + fn sign_with_rng(&mut self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> S { + self.try_sign_with_rng(rng, msg) + .expect("signature operation failed") + } + + /// Attempt to sign the given message, updating the state, and returning a + /// digital signature on success, or an error if something went wrong. + /// + /// Signing can fail, e.g., if the number of time periods allowed by the + /// current key is exceeded. + fn try_sign_with_rng(&mut self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> Result; +} + +/// Blanket impl of [`RandomizedSignerMut`] for all [`RandomizedSigner`] types. +#[cfg(feature = "rand_core")] +impl> RandomizedSignerMut for T { + fn try_sign_with_rng(&mut self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> Result { + T::try_sign_with_rng(self, rng, msg) + } +}