/rust/registry/src/index.crates.io-1949cf8c6b5b557f/signature-3.0.0/src/signer.rs
Line | Count | Source |
1 | | //! Traits for generating digital signatures. |
2 | | |
3 | | use crate::error::Error; |
4 | | |
5 | | #[cfg(feature = "digest")] |
6 | | use crate::digest::Update; |
7 | | |
8 | | #[cfg(feature = "rand_core")] |
9 | | use crate::rand_core::{CryptoRng, TryCryptoRng}; |
10 | | |
11 | | /// Sign the provided message bytestring using `Self` (e.g. a cryptographic key or connection to an |
12 | | /// HSM), returning a digital signature. |
13 | | pub trait Signer<S> { |
14 | | /// Sign the given message and return a digital signature. |
15 | 2.16k | fn sign(&self, msg: &[u8]) -> S { |
16 | 2.16k | self.try_sign(msg).expect("signature operation failed") |
17 | 2.16k | } <ecdsa::signing::SigningKey<p256::NistP256> as signature::signer::Signer<ecdsa::Signature<p256::NistP256>>>::sign Line | Count | Source | 15 | 2.16k | fn sign(&self, msg: &[u8]) -> S { | 16 | 2.16k | self.try_sign(msg).expect("signature operation failed") | 17 | 2.16k | } |
Unexecuted instantiation: <_ as signature::signer::Signer<_>>::sign |
18 | | |
19 | | /// Attempt to sign the given message, returning a digital signature on success, or an error if |
20 | | /// something went wrong. |
21 | | /// |
22 | | /// The main intended use case for signing errors is when communicating with external signers, |
23 | | /// e.g. cloud KMS, HSMs, or other hardware tokens. |
24 | | /// |
25 | | /// # Errors |
26 | | /// Returns implementation-specific errors in the event signing failed (e.g. KMS or HSM |
27 | | /// communication error). |
28 | | fn try_sign(&self, msg: &[u8]) -> Result<S, Error>; |
29 | | } |
30 | | |
31 | | /// Equivalent of [`Signer`] but the message is provided in non-contiguous byte slices. |
32 | | pub trait MultipartSigner<S> { |
33 | | /// Equivalent of [`Signer::sign()`] but the message is provided in non-contiguous byte slices. |
34 | 0 | fn multipart_sign(&self, msg: &[&[u8]]) -> S { |
35 | 0 | self.try_multipart_sign(msg) |
36 | 0 | .expect("signature operation failed") |
37 | 0 | } |
38 | | |
39 | | /// Equivalent of [`Signer::try_sign()`] but the message is provided in non-contiguous byte |
40 | | /// slices. |
41 | | /// |
42 | | /// # Errors |
43 | | /// Returns implementation-specific errors in the event signing failed (e.g. KMS or HSM |
44 | | /// communication error). |
45 | | fn try_multipart_sign(&self, msg: &[&[u8]]) -> Result<S, Error>; |
46 | | } |
47 | | |
48 | | /// Sign the provided message bytestring using `&mut Self` (e.g. an evolving cryptographic key such |
49 | | /// as a stateful hash-based signature), returning a digital signature. |
50 | | pub trait SignerMut<S> { |
51 | | /// Sign the given message, update the state, and return a digital signature. |
52 | | /// |
53 | | /// # Panics |
54 | | /// In the event of a signing error. |
55 | 0 | fn sign(&mut self, msg: &[u8]) -> S { |
56 | 0 | self.try_sign(msg).expect("signature operation failed") |
57 | 0 | } |
58 | | |
59 | | /// Attempt to sign the given message, updating the state, and returning a digital signature on |
60 | | /// success, or an error if something went wrong. |
61 | | /// |
62 | | /// # Errors |
63 | | /// Signing can fail, e.g. if the number of time periods allowed by the current key is exceeded. |
64 | | fn try_sign(&mut self, msg: &[u8]) -> Result<S, Error>; |
65 | | } |
66 | | |
67 | | /// Sign the given prehashed message `Digest` using `Self`. |
68 | | /// |
69 | | /// ## Notes |
70 | | /// |
71 | | /// This trait is primarily intended for signature algorithms based on the [Fiat-Shamir heuristic], |
72 | | /// a method for converting an interactive challenge/response-based proof-of-knowledge protocol into |
73 | | /// an offline digital signature through the use of a random oracle, i.e. a digest function. |
74 | | /// |
75 | | /// The security of such protocols critically rests upon the inability of an attacker to solve for |
76 | | /// the output of the random oracle, as generally otherwise such signature algorithms are a system |
77 | | /// of linear equations and therefore doing so would allow the attacker to trivially forge |
78 | | /// signatures. |
79 | | /// |
80 | | /// To prevent misuse which would potentially allow this to be possible, this API accepts a `Digest` |
81 | | /// instance, rather than a raw digest value. |
82 | | /// |
83 | | /// [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic |
84 | | #[cfg(feature = "digest")] |
85 | | pub trait DigestSigner<D: Update, S> { |
86 | | /// Sign a message by updating the received `Digest` with it, returning a signature. |
87 | | /// |
88 | | /// The given function can be invoked multiple times. It is expected that in each invocation the |
89 | | /// `Digest` is updated with the entire equal message. |
90 | | /// |
91 | | /// # Panics |
92 | | /// In the event of a signing error. |
93 | 0 | fn sign_digest<F: Fn(&mut D)>(&self, f: F) -> S { |
94 | 0 | self.try_sign_digest(|digest| { |
95 | 0 | f(digest); |
96 | 0 | Ok(()) |
97 | 0 | }) |
98 | 0 | .expect("signature operation failed") |
99 | 0 | } |
100 | | |
101 | | /// Attempt to sign a message by updating the received `Digest` with it, returning a digital |
102 | | /// signature on success, or an error if something went wrong. |
103 | | /// |
104 | | /// The given function can be invoked multiple times. It is expected that in each invocation the |
105 | | /// `Digest` is updated with the entire equal message. |
106 | | /// |
107 | | /// # Errors |
108 | | /// Returns implementation-specific errors in the event signing failed (e.g. KMS or HSM |
109 | | /// communication error). |
110 | | fn try_sign_digest<F: Fn(&mut D) -> Result<(), Error>>(&self, f: F) -> Result<S, Error>; |
111 | | } |
112 | | |
113 | | /// Sign the given message using the provided external randomness source. |
114 | | #[cfg(feature = "rand_core")] |
115 | | pub trait RandomizedSigner<S> { |
116 | | /// Sign the given message and return a digital signature |
117 | 0 | fn sign_with_rng<R: CryptoRng + ?Sized>(&self, rng: &mut R, msg: &[u8]) -> S { |
118 | 0 | self.try_sign_with_rng(rng, msg) |
119 | 0 | .expect("signature operation failed") |
120 | 0 | } |
121 | | |
122 | | /// Attempt to sign the given message, returning a digital signature on success, or an error if |
123 | | /// something went wrong. |
124 | | /// |
125 | | /// The main intended use case for signing errors is when communicating with external signers, |
126 | | /// e.g. cloud KMS, HSMs, or other hardware tokens. |
127 | | /// |
128 | | /// # Errors |
129 | | /// Returns implementation-specific errors in the event signing failed (e.g. KMS or HSM |
130 | | /// communication error), or if the provided `rng` experiences an internal failure. |
131 | | fn try_sign_with_rng<R: TryCryptoRng + ?Sized>( |
132 | | &self, |
133 | | rng: &mut R, |
134 | | msg: &[u8], |
135 | | ) -> Result<S, Error>; |
136 | | } |
137 | | |
138 | | /// Equivalent of [`RandomizedSigner`] but the message is provided in non-contiguous byte slices. |
139 | | #[cfg(feature = "rand_core")] |
140 | | pub trait RandomizedMultipartSigner<S> { |
141 | | /// Equivalent of [`RandomizedSigner::sign_with_rng()`] but the message is provided in |
142 | | /// non-contiguous byte slices. |
143 | 0 | fn multipart_sign_with_rng<R: CryptoRng + ?Sized>(&self, rng: &mut R, msg: &[&[u8]]) -> S { |
144 | 0 | self.try_multipart_sign_with_rng(rng, msg) |
145 | 0 | .expect("signature operation failed") |
146 | 0 | } |
147 | | |
148 | | /// Equivalent of [`RandomizedSigner::try_sign_with_rng()`] but the message is provided in |
149 | | /// non-contiguous byte slices. |
150 | | /// |
151 | | /// # Errors |
152 | | /// Returns implementation-specific errors in the event signing failed (e.g. KMS or HSM |
153 | | /// communication error), or if the provided `rng` experiences an internal failure. |
154 | | fn try_multipart_sign_with_rng<R: TryCryptoRng + ?Sized>( |
155 | | &self, |
156 | | rng: &mut R, |
157 | | msg: &[&[u8]], |
158 | | ) -> Result<S, Error>; |
159 | | } |
160 | | |
161 | | /// Combination of [`DigestSigner`] and [`RandomizedSigner`] with support for computing a signature |
162 | | /// over a digest which requires entropy from an RNG. |
163 | | #[cfg(all(feature = "digest", feature = "rand_core"))] |
164 | | pub trait RandomizedDigestSigner<D: Update, S> { |
165 | | /// Sign a message by updating the received `Digest` with it, returning a signature. |
166 | | /// |
167 | | /// The given function can be invoked multiple times. It is expected that in each invocation the |
168 | | /// `Digest` is updated with the entire equal message. |
169 | | /// |
170 | | /// # Panics |
171 | | /// In the event of a signing error. |
172 | 0 | fn sign_digest_with_rng<R: CryptoRng + ?Sized, F: Fn(&mut D)>(&self, rng: &mut R, f: F) -> S { |
173 | 0 | self.try_sign_digest_with_rng(rng, |digest| { |
174 | 0 | f(digest); |
175 | 0 | Ok(()) |
176 | 0 | }) |
177 | 0 | .expect("signature operation failed") |
178 | 0 | } |
179 | | |
180 | | /// Attempt to sign a message by updating the received `Digest` with it, returning a digital |
181 | | /// signature on success, or an error if something went wrong. |
182 | | /// |
183 | | /// The given function can be invoked multiple times. It is expected that in each invocation the |
184 | | /// `Digest` is updated with the entire equal message. |
185 | | /// |
186 | | /// # Errors |
187 | | /// Returns implementation-specific errors in the event signing failed (e.g. KMS or HSM |
188 | | /// communication error), or if the provided `rng` experiences an internal failure. |
189 | | fn try_sign_digest_with_rng<R: TryCryptoRng + ?Sized, F: Fn(&mut D) -> Result<(), Error>>( |
190 | | &self, |
191 | | rng: &mut R, |
192 | | f: F, |
193 | | ) -> Result<S, Error>; |
194 | | } |
195 | | |
196 | | /// Sign the provided message bytestring using `&mut Self` (e.g. an evolving cryptographic key such |
197 | | /// as a stateful hash-based signature), and a per-signature randomizer, returning a digital |
198 | | /// signature. |
199 | | #[cfg(feature = "rand_core")] |
200 | | pub trait RandomizedSignerMut<S> { |
201 | | /// Sign the given message, update the state, and return a digital signature. |
202 | | /// |
203 | | /// # Panics |
204 | | /// In the event of a signing error. |
205 | 0 | fn sign_with_rng<R: CryptoRng + ?Sized>(&mut self, rng: &mut R, msg: &[u8]) -> S { |
206 | 0 | self.try_sign_with_rng(rng, msg) |
207 | 0 | .expect("signature operation failed") |
208 | 0 | } |
209 | | |
210 | | /// Attempt to sign the given message, updating the state, and returning a digital signature on |
211 | | /// success, or an error if something went wrong. |
212 | | /// |
213 | | /// # Errors |
214 | | /// Signing can fail, e.g. if the number of time periods allowed by the current key is exceeded, |
215 | | /// or if the provided `rng` experiences an internal failure. |
216 | | fn try_sign_with_rng<R: TryCryptoRng + ?Sized>( |
217 | | &mut self, |
218 | | rng: &mut R, |
219 | | msg: &[u8], |
220 | | ) -> Result<S, Error>; |
221 | | } |
222 | | |
223 | | /// Equivalent of [`RandomizedSignerMut`] but the message is provided in non-contiguous byte slices. |
224 | | #[cfg(feature = "rand_core")] |
225 | | pub trait RandomizedMultipartSignerMut<S> { |
226 | | /// Equivalent of [`RandomizedSignerMut::sign_with_rng()`] but the message is provided in |
227 | | /// non-contiguous byte slices. |
228 | | /// |
229 | | /// # Panics |
230 | | /// In the event of a signing error. |
231 | 0 | fn multipart_sign_with_rng<R: CryptoRng + ?Sized>(&mut self, rng: &mut R, msg: &[&[u8]]) -> S { |
232 | 0 | self.try_multipart_sign_with_rng(rng, msg) |
233 | 0 | .expect("signature operation failed") |
234 | 0 | } |
235 | | |
236 | | /// Equivalent of [`RandomizedSignerMut::try_sign_with_rng()`] but the message is provided in |
237 | | /// non-contiguous byte slices. |
238 | | /// |
239 | | /// # Errors |
240 | | /// Signing can fail, e.g. if the number of time periods allowed by the current key is exceeded, |
241 | | /// or if the provided `rng` experiences an internal failure. |
242 | | fn try_multipart_sign_with_rng<R: TryCryptoRng + ?Sized>( |
243 | | &mut self, |
244 | | rng: &mut R, |
245 | | msg: &[&[u8]], |
246 | | ) -> Result<S, Error>; |
247 | | } |
248 | | |
249 | | /// Blanket impl of [`RandomizedSignerMut`] for all [`RandomizedSigner`] types. |
250 | | #[cfg(feature = "rand_core")] |
251 | | impl<S, T: RandomizedSigner<S>> RandomizedSignerMut<S> for T { |
252 | 0 | fn try_sign_with_rng<R: TryCryptoRng + ?Sized>( |
253 | 0 | &mut self, |
254 | 0 | rng: &mut R, |
255 | 0 | msg: &[u8], |
256 | 0 | ) -> Result<S, Error> { |
257 | 0 | T::try_sign_with_rng(self, rng, msg) |
258 | 0 | } |
259 | | } |
260 | | |
261 | | /// Asynchronously sign the provided message bytestring using `Self` (e.g. client for a Cloud KMS or |
262 | | /// HSM), returning a digital signature. |
263 | | /// |
264 | | /// This trait is an async equivalent of the [`Signer`] trait. |
265 | | pub trait AsyncSigner<S> { |
266 | | /// Attempt to sign the given message, returning a digital signature on success, or an error if |
267 | | /// something went wrong. |
268 | | /// |
269 | | /// The main intended use case for signing errors is when communicating with external signers, |
270 | | /// e.g. cloud KMS, HSMs, or other hardware tokens. |
271 | | /// |
272 | | /// # Errors |
273 | | /// Returns implementation-specific errors in the event signing failed (e.g. KMS or HSM |
274 | | /// communication error). |
275 | | async fn sign_async(&self, msg: &[u8]) -> Result<S, Error>; |
276 | | } |
277 | | |
278 | | impl<S, T> AsyncSigner<S> for T |
279 | | where |
280 | | T: Signer<S>, |
281 | | { |
282 | 0 | async fn sign_async(&self, msg: &[u8]) -> Result<S, Error> { |
283 | 0 | self.try_sign(msg) |
284 | 0 | } |
285 | | } |
286 | | |
287 | | /// Asynchronously sign the given prehashed message `Digest` using `Self`. |
288 | | /// |
289 | | /// This trait is an async equivalent of the [`DigestSigner`] trait. |
290 | | #[cfg(feature = "digest")] |
291 | | pub trait AsyncDigestSigner<D, S> |
292 | | where |
293 | | D: Update, |
294 | | { |
295 | | /// Attempt to sign a message by updating the received `Digest` with it, returning a digital |
296 | | /// signature on success, or an error if something went wrong. |
297 | | /// |
298 | | /// The given function can be invoked multiple times. It is expected that in each invocation the |
299 | | /// `Digest` is updated with the entire equal message. |
300 | | /// |
301 | | /// # Errors |
302 | | /// Returns implementation-specific errors in the event signing failed (e.g. KMS or HSM |
303 | | /// communication error). |
304 | | async fn sign_digest_async<F: AsyncFn(&mut D) -> Result<(), Error>>( |
305 | | &self, |
306 | | f: F, |
307 | | ) -> Result<S, Error>; |
308 | | } |
309 | | |
310 | | /// Sign the given message using the provided external randomness source. |
311 | | #[cfg(feature = "rand_core")] |
312 | | pub trait AsyncRandomizedSigner<S> { |
313 | | /// Sign the given message and return a digital signature. |
314 | | /// |
315 | | /// # Panics |
316 | | /// In the event of a signing error. |
317 | 0 | async fn sign_with_rng_async<R: CryptoRng + ?Sized>(&self, rng: &mut R, msg: &[u8]) -> S { |
318 | 0 | self.try_sign_with_rng_async(rng, msg) |
319 | 0 | .await |
320 | 0 | .expect("signature operation failed") |
321 | 0 | } |
322 | | |
323 | | /// Attempt to sign the given message, returning a digital signature on success, or an error if |
324 | | /// something went wrong. |
325 | | /// |
326 | | /// The main intended use case for signing errors is when communicating with external signers, |
327 | | /// e.g. cloud KMS, HSMs, or other hardware tokens. |
328 | | /// |
329 | | /// # Errors |
330 | | /// Returns implementation-specific errors in the event signing failed (e.g. KMS or HSM |
331 | | /// communication error), or if the provided `rng` experiences an internal failure. |
332 | | async fn try_sign_with_rng_async<R: TryCryptoRng + ?Sized>( |
333 | | &self, |
334 | | rng: &mut R, |
335 | | msg: &[u8], |
336 | | ) -> Result<S, Error>; |
337 | | } |
338 | | |
339 | | #[cfg(feature = "rand_core")] |
340 | | impl<S, T> AsyncRandomizedSigner<S> for T |
341 | | where |
342 | | T: RandomizedSigner<S>, |
343 | | { |
344 | 0 | async fn try_sign_with_rng_async<R: TryCryptoRng + ?Sized>( |
345 | 0 | &self, |
346 | 0 | rng: &mut R, |
347 | 0 | msg: &[u8], |
348 | 0 | ) -> Result<S, Error> { |
349 | 0 | self.try_sign_with_rng(rng, msg) |
350 | 0 | } |
351 | | } |