Skip to content

Commit 50e2d17

Browse files
committed
Split into separate method
1 parent 9e3f5ec commit 50e2d17

File tree

2 files changed

+131
-31
lines changed

2 files changed

+131
-31
lines changed

signature/src/signer.rs

Lines changed: 119 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! Traits for generating digital signatures
22
3+
use core::iter;
4+
35
use crate::error::Error;
46

57
#[cfg(feature = "digest")]
@@ -12,39 +14,61 @@ use crate::rand_core::{CryptoRng, TryCryptoRng};
1214
/// or connection to an HSM), returning a digital signature.
1315
pub trait Signer<S> {
1416
/// Sign the given message and return a digital signature
15-
fn sign(&self, msg: &[&[u8]]) -> S {
17+
fn sign(&self, msg: &[u8]) -> S {
1618
self.try_sign(msg).expect("signature operation failed")
1719
}
1820

21+
/// Equivalent of [`sign()`](Self::sign) but the message is passed in segments.
22+
fn sign_segments<I: Iterator<Item: AsRef<[u8]>>>(&self, msg: I) -> S {
23+
self.try_sign_segments(msg)
24+
.expect("signature operation failed")
25+
}
26+
1927
/// Attempt to sign the given message, returning a digital signature on
2028
/// success, or an error if something went wrong.
2129
///
2230
/// The main intended use case for signing errors is when communicating
2331
/// with external signers, e.g. cloud KMS, HSMs, or other hardware tokens.
24-
fn try_sign(&self, msg: &[&[u8]]) -> Result<S, Error>;
32+
fn try_sign(&self, msg: &[u8]) -> Result<S, Error> {
33+
self.try_sign_segments(iter::once(msg))
34+
}
35+
36+
/// Equivalent of [`try_sign()`](Self::try_sign) but the message is passed in segments.
37+
fn try_sign_segments<I: Iterator<Item: AsRef<[u8]>>>(&self, msg: I) -> Result<S, Error>;
2538
}
2639

2740
/// Sign the provided message bytestring using `&mut Self` (e.g. an evolving
2841
/// cryptographic key such as a stateful hash-based signature), returning a
2942
/// digital signature.
3043
pub trait SignerMut<S> {
3144
/// Sign the given message, update the state, and return a digital signature.
32-
fn sign(&mut self, msg: &[&[u8]]) -> S {
45+
fn sign(&mut self, msg: &[u8]) -> S {
3346
self.try_sign(msg).expect("signature operation failed")
3447
}
3548

49+
/// Equivalent of [`sign()`](Self::sign) but the message is passed in segments.
50+
fn sign_segments<I: Iterator<Item: AsRef<[u8]>>>(&mut self, msg: I) -> S {
51+
self.try_sign_segments(msg)
52+
.expect("signature operation failed")
53+
}
54+
3655
/// Attempt to sign the given message, updating the state, and returning a
3756
/// digital signature on success, or an error if something went wrong.
3857
///
3958
/// Signing can fail, e.g., if the number of time periods allowed by the
4059
/// current key is exceeded.
41-
fn try_sign(&mut self, msg: &[&[u8]]) -> Result<S, Error>;
60+
fn try_sign(&mut self, msg: &[u8]) -> Result<S, Error> {
61+
self.try_sign_segments(iter::once(msg))
62+
}
63+
64+
/// Equivalent of [`try_sign()`](Self::try_sign) but the message is passed in segments.
65+
fn try_sign_segments<I: Iterator<Item: AsRef<[u8]>>>(&mut self, msg: I) -> Result<S, Error>;
4266
}
4367

4468
/// Blanket impl of [`SignerMut`] for all [`Signer`] types.
4569
impl<S, T: Signer<S>> SignerMut<S> for T {
46-
fn try_sign(&mut self, msg: &[&[u8]]) -> Result<S, Error> {
47-
T::try_sign(self, msg)
70+
fn try_sign_segments<I: Iterator<Item: AsRef<[u8]>>>(&mut self, msg: I) -> Result<S, Error> {
71+
T::try_sign_segments(self, msg)
4872
}
4973
}
5074

@@ -86,11 +110,21 @@ pub trait DigestSigner<D: Digest, S> {
86110
#[cfg(feature = "rand_core")]
87111
pub trait RandomizedSigner<S> {
88112
/// Sign the given message and return a digital signature
89-
fn sign_with_rng<R: CryptoRng + ?Sized>(&self, rng: &mut R, msg: &[&[u8]]) -> S {
113+
fn sign_with_rng<R: CryptoRng + ?Sized>(&self, rng: &mut R, msg: &[u8]) -> S {
90114
self.try_sign_with_rng(rng, msg)
91115
.expect("signature operation failed")
92116
}
93117

118+
/// Equivalent of [`sign_with_rng()`](Self::sign_with_rng) but the message is passed in segments.
119+
fn sign_segments_with_rng<R, I>(&self, rng: &mut R, msg: I) -> S
120+
where
121+
R: CryptoRng + ?Sized,
122+
I: Iterator<Item: AsRef<[u8]>>,
123+
{
124+
self.try_sign_segments_with_rng(rng, msg)
125+
.expect("signature operation failed")
126+
}
127+
94128
/// Attempt to sign the given message, returning a digital signature on
95129
/// success, or an error if something went wrong.
96130
///
@@ -99,8 +133,16 @@ pub trait RandomizedSigner<S> {
99133
fn try_sign_with_rng<R: TryCryptoRng + ?Sized>(
100134
&self,
101135
rng: &mut R,
102-
msg: &[&[u8]],
103-
) -> Result<S, Error>;
136+
msg: &[u8],
137+
) -> Result<S, Error> {
138+
self.try_sign_segments_with_rng(rng, iter::once(msg))
139+
}
140+
141+
/// Equivalent of [`try_sign_with_rng()`](Self::try_sign_with_rng) but the message is passed in segments.
142+
fn try_sign_segments_with_rng<R, I>(&self, rng: &mut R, msg: I) -> Result<S, Error>
143+
where
144+
R: TryCryptoRng + ?Sized,
145+
I: Iterator<Item: AsRef<[u8]>>;
104146
}
105147

106148
/// Combination of [`DigestSigner`] and [`RandomizedSigner`] with support for
@@ -130,11 +172,21 @@ pub trait RandomizedDigestSigner<D: Digest, S> {
130172
#[cfg(feature = "rand_core")]
131173
pub trait RandomizedSignerMut<S> {
132174
/// Sign the given message, update the state, and return a digital signature.
133-
fn sign_with_rng<R: CryptoRng + ?Sized>(&mut self, rng: &mut R, msg: &[&[u8]]) -> S {
175+
fn sign_with_rng<R: CryptoRng + ?Sized>(&mut self, rng: &mut R, msg: &[u8]) -> S {
134176
self.try_sign_with_rng(rng, msg)
135177
.expect("signature operation failed")
136178
}
137179

180+
/// Equivalent of [`sign_with_rng()`](Self::sign_with_rng) but the message is passed in segments.
181+
fn sign_segments_with_rng<R, I>(&self, rng: &mut R, msg: I) -> S
182+
where
183+
R: CryptoRng + ?Sized,
184+
I: Iterator<Item: AsRef<[u8]>>,
185+
{
186+
self.try_sign_segments_with_rng(rng, msg)
187+
.expect("signature operation failed")
188+
}
189+
138190
/// Attempt to sign the given message, updating the state, and returning a
139191
/// digital signature on success, or an error if something went wrong.
140192
///
@@ -143,19 +195,27 @@ pub trait RandomizedSignerMut<S> {
143195
fn try_sign_with_rng<R: TryCryptoRng + ?Sized>(
144196
&mut self,
145197
rng: &mut R,
146-
msg: &[&[u8]],
147-
) -> Result<S, Error>;
198+
msg: &[u8],
199+
) -> Result<S, Error> {
200+
self.try_sign_segments_with_rng(rng, iter::once(msg))
201+
}
202+
203+
/// Equivalent of [`try_sign_with_rng()`](Self::try_sign_with_rng) but the message is passed in segments.
204+
fn try_sign_segments_with_rng<R, I>(&self, rng: &mut R, msg: I) -> Result<S, Error>
205+
where
206+
R: TryCryptoRng + ?Sized,
207+
I: Iterator<Item: AsRef<[u8]>>;
148208
}
149209

150210
/// Blanket impl of [`RandomizedSignerMut`] for all [`RandomizedSigner`] types.
151211
#[cfg(feature = "rand_core")]
152212
impl<S, T: RandomizedSigner<S>> RandomizedSignerMut<S> for T {
153-
fn try_sign_with_rng<R: TryCryptoRng + ?Sized>(
154-
&mut self,
155-
rng: &mut R,
156-
msg: &[&[u8]],
157-
) -> Result<S, Error> {
158-
T::try_sign_with_rng(self, rng, msg)
213+
fn try_sign_segments_with_rng<R, I>(&self, rng: &mut R, msg: I) -> Result<S, Error>
214+
where
215+
R: TryCryptoRng + ?Sized,
216+
I: Iterator<Item: AsRef<[u8]>>,
217+
{
218+
self.try_sign_segments_with_rng(rng, msg)
159219
}
160220
}
161221

@@ -169,15 +229,24 @@ pub trait AsyncSigner<S> {
169229
///
170230
/// The main intended use case for signing errors is when communicating
171231
/// with external signers, e.g. cloud KMS, HSMs, or other hardware tokens.
172-
async fn sign_async(&self, msg: &[&[u8]]) -> Result<S, Error>;
232+
async fn sign_async(&self, msg: &[u8]) -> Result<S, Error> {
233+
self.sign_segments_async(iter::once(msg)).await
234+
}
235+
236+
/// Equivalent of [`sign_async()`](Self::sign_async) but the message is passed in segments.
237+
async fn sign_segments_async<I: Iterator<Item: AsRef<[u8]>>>(&self, msg: I)
238+
-> Result<S, Error>;
173239
}
174240

175241
impl<S, T> AsyncSigner<S> for T
176242
where
177243
T: Signer<S>,
178244
{
179-
async fn sign_async(&self, msg: &[&[u8]]) -> Result<S, Error> {
180-
self.try_sign(msg)
245+
async fn sign_segments_async<I: Iterator<Item: AsRef<[u8]>>>(
246+
&self,
247+
msg: I,
248+
) -> Result<S, Error> {
249+
self.try_sign_segments(msg)
181250
}
182251
}
183252

@@ -198,12 +267,23 @@ where
198267
#[cfg(feature = "rand_core")]
199268
pub trait AsyncRandomizedSigner<S> {
200269
/// Sign the given message and return a digital signature
201-
async fn sign_with_rng_async<R: CryptoRng + ?Sized>(&self, rng: &mut R, msg: &[&[u8]]) -> S {
270+
async fn sign_with_rng_async<R: CryptoRng + ?Sized>(&self, rng: &mut R, msg: &[u8]) -> S {
202271
self.try_sign_with_rng_async(rng, msg)
203272
.await
204273
.expect("signature operation failed")
205274
}
206275

276+
/// Equivalent of [`sign_with_rng_async()`](Self::sign_with_rng_async) but the message is passed in segments.
277+
async fn sign_segments_with_rng_async<R, I>(&self, rng: &mut R, msg: I) -> S
278+
where
279+
R: CryptoRng + ?Sized,
280+
I: Iterator<Item: AsRef<[u8]>>,
281+
{
282+
self.try_sign_segments_with_rng_async(rng, msg)
283+
.await
284+
.expect("signature operation failed")
285+
}
286+
207287
/// Attempt to sign the given message, returning a digital signature on
208288
/// success, or an error if something went wrong.
209289
///
@@ -212,20 +292,29 @@ pub trait AsyncRandomizedSigner<S> {
212292
async fn try_sign_with_rng_async<R: TryCryptoRng + ?Sized>(
213293
&self,
214294
rng: &mut R,
215-
msg: &[&[u8]],
216-
) -> Result<S, Error>;
295+
msg: &[u8],
296+
) -> Result<S, Error> {
297+
self.try_sign_segments_with_rng_async(rng, iter::once(msg))
298+
.await
299+
}
300+
301+
/// Equivalent of [`try_sign_with_rng_async()`](Self::try_sign_with_rng_async) but the message is passed in segments.
302+
async fn try_sign_segments_with_rng_async<R, I>(&self, rng: &mut R, msg: I) -> Result<S, Error>
303+
where
304+
R: TryCryptoRng + ?Sized,
305+
I: Iterator<Item: AsRef<[u8]>>;
217306
}
218307

219308
#[cfg(feature = "rand_core")]
220309
impl<S, T> AsyncRandomizedSigner<S> for T
221310
where
222311
T: RandomizedSigner<S>,
223312
{
224-
async fn try_sign_with_rng_async<R: TryCryptoRng + ?Sized>(
225-
&self,
226-
rng: &mut R,
227-
msg: &[&[u8]],
228-
) -> Result<S, Error> {
229-
self.try_sign_with_rng(rng, msg)
313+
async fn try_sign_segments_with_rng_async<R, I>(&self, rng: &mut R, msg: I) -> Result<S, Error>
314+
where
315+
R: TryCryptoRng + ?Sized,
316+
I: Iterator<Item: AsRef<[u8]>>,
317+
{
318+
self.try_sign_segments_with_rng(rng, msg)
230319
}
231320
}

signature/src/verifier.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! Trait for verifying digital signatures
22
3+
use core::iter;
4+
35
use crate::error::Error;
46

57
#[cfg(feature = "digest")]
@@ -11,7 +13,16 @@ pub trait Verifier<S> {
1113
/// bytestring is authentic.
1214
///
1315
/// Returns `Error` if it is inauthentic, or otherwise returns `()`.
14-
fn verify(&self, msg: &[&[u8]], signature: &S) -> Result<(), Error>;
16+
fn verify(&self, msg: &[u8], signature: &S) -> Result<(), Error> {
17+
self.verify_segments(iter::once(msg), signature)
18+
}
19+
20+
/// Equivalent of [`verify()`](Self::verify) but the message is passed in segments.
21+
fn verify_segments<I: Iterator<Item: AsRef<[u8]>>>(
22+
&self,
23+
msg: I,
24+
signature: &S,
25+
) -> Result<(), Error>;
1526
}
1627

1728
/// Verify the provided signature for the given prehashed message [`Digest`]

0 commit comments

Comments
 (0)