1
1
//! Traits for generating digital signatures
2
2
3
+ use core:: iter;
4
+
3
5
use crate :: error:: Error ;
4
6
5
7
#[ cfg( feature = "digest" ) ]
@@ -12,39 +14,61 @@ use crate::rand_core::{CryptoRng, TryCryptoRng};
12
14
/// or connection to an HSM), returning a digital signature.
13
15
pub trait Signer < S > {
14
16
/// Sign the given message and return a digital signature
15
- fn sign ( & self , msg : & [ & [ u8 ] ] ) -> S {
17
+ fn sign ( & self , msg : & [ u8 ] ) -> S {
16
18
self . try_sign ( msg) . expect ( "signature operation failed" )
17
19
}
18
20
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
+
19
27
/// Attempt to sign the given message, returning a digital signature on
20
28
/// success, or an error if something went wrong.
21
29
///
22
30
/// The main intended use case for signing errors is when communicating
23
31
/// 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 > ;
25
38
}
26
39
27
40
/// Sign the provided message bytestring using `&mut Self` (e.g. an evolving
28
41
/// cryptographic key such as a stateful hash-based signature), returning a
29
42
/// digital signature.
30
43
pub trait SignerMut < S > {
31
44
/// 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 {
33
46
self . try_sign ( msg) . expect ( "signature operation failed" )
34
47
}
35
48
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
+
36
55
/// Attempt to sign the given message, updating the state, and returning a
37
56
/// digital signature on success, or an error if something went wrong.
38
57
///
39
58
/// Signing can fail, e.g., if the number of time periods allowed by the
40
59
/// 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 > ;
42
66
}
43
67
44
68
/// Blanket impl of [`SignerMut`] for all [`Signer`] types.
45
69
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)
48
72
}
49
73
}
50
74
@@ -86,11 +110,21 @@ pub trait DigestSigner<D: Digest, S> {
86
110
#[ cfg( feature = "rand_core" ) ]
87
111
pub trait RandomizedSigner < S > {
88
112
/// 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 {
90
114
self . try_sign_with_rng ( rng, msg)
91
115
. expect ( "signature operation failed" )
92
116
}
93
117
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
+
94
128
/// Attempt to sign the given message, returning a digital signature on
95
129
/// success, or an error if something went wrong.
96
130
///
@@ -99,8 +133,16 @@ pub trait RandomizedSigner<S> {
99
133
fn try_sign_with_rng < R : TryCryptoRng + ?Sized > (
100
134
& self ,
101
135
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 ] > > ;
104
146
}
105
147
106
148
/// Combination of [`DigestSigner`] and [`RandomizedSigner`] with support for
@@ -130,11 +172,21 @@ pub trait RandomizedDigestSigner<D: Digest, S> {
130
172
#[ cfg( feature = "rand_core" ) ]
131
173
pub trait RandomizedSignerMut < S > {
132
174
/// 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 {
134
176
self . try_sign_with_rng ( rng, msg)
135
177
. expect ( "signature operation failed" )
136
178
}
137
179
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
+
138
190
/// Attempt to sign the given message, updating the state, and returning a
139
191
/// digital signature on success, or an error if something went wrong.
140
192
///
@@ -143,19 +195,27 @@ pub trait RandomizedSignerMut<S> {
143
195
fn try_sign_with_rng < R : TryCryptoRng + ?Sized > (
144
196
& mut self ,
145
197
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 ] > > ;
148
208
}
149
209
150
210
/// Blanket impl of [`RandomizedSignerMut`] for all [`RandomizedSigner`] types.
151
211
#[ cfg( feature = "rand_core" ) ]
152
212
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)
159
219
}
160
220
}
161
221
@@ -169,15 +229,24 @@ pub trait AsyncSigner<S> {
169
229
///
170
230
/// The main intended use case for signing errors is when communicating
171
231
/// 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 > ;
173
239
}
174
240
175
241
impl < S , T > AsyncSigner < S > for T
176
242
where
177
243
T : Signer < S > ,
178
244
{
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)
181
250
}
182
251
}
183
252
@@ -198,12 +267,23 @@ where
198
267
#[ cfg( feature = "rand_core" ) ]
199
268
pub trait AsyncRandomizedSigner < S > {
200
269
/// 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 {
202
271
self . try_sign_with_rng_async ( rng, msg)
203
272
. await
204
273
. expect ( "signature operation failed" )
205
274
}
206
275
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
+
207
287
/// Attempt to sign the given message, returning a digital signature on
208
288
/// success, or an error if something went wrong.
209
289
///
@@ -212,20 +292,29 @@ pub trait AsyncRandomizedSigner<S> {
212
292
async fn try_sign_with_rng_async < R : TryCryptoRng + ?Sized > (
213
293
& self ,
214
294
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 ] > > ;
217
306
}
218
307
219
308
#[ cfg( feature = "rand_core" ) ]
220
309
impl < S , T > AsyncRandomizedSigner < S > for T
221
310
where
222
311
T : RandomizedSigner < S > ,
223
312
{
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)
230
319
}
231
320
}
0 commit comments