1#[cfg(feature = "alloc")]
11use super::pkcs1v15_generate_prefix;
12#[cfg(not(feature = "alloc"))]
13use super::{pkcs1v15_generate_prefix_helper, Prefix};
14use super::{sign_into, sign_with_rng_into, GenericVerifyingKey};
15use crate::{
16 errors::Result,
17 key::GenericRsaPrivateKey,
18 traits::{
19 modular::{ModulusParams, Pow, PowBoundedExp},
20 PublicKeyParts, UnsignedModularInt,
21 },
22};
23use const_oid::AssociatedOid;
24use core::fmt;
25use core::marker::PhantomData;
26use digest::Digest;
27use zeroize::Zeroize;
28
29pub struct GenericSigningKey<D, T, M>
35where
36 D: Digest,
37 T: UnsignedModularInt + Zeroize,
38 M: ModulusParams<Modulus = T>,
39{
40 pub(super) inner: GenericRsaPrivateKey<T, M>,
41 #[cfg(feature = "alloc")]
42 pub(super) prefix: alloc::vec::Vec<u8>,
43 #[cfg(not(feature = "alloc"))]
44 pub(super) prefix: Prefix,
45 pub(super) phantom: PhantomData<D>,
46}
47
48impl<D, T, M> fmt::Debug for GenericSigningKey<D, T, M>
51where
52 D: Digest,
53 T: UnsignedModularInt + Zeroize,
54 M: ModulusParams<Modulus = T>,
55 GenericRsaPrivateKey<T, M>: fmt::Debug,
56{
57 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58 f.debug_struct("GenericSigningKey")
59 .field("inner", &self.inner)
60 .field("prefix", &self.prefix)
61 .finish()
62 }
63}
64
65#[cfg(feature = "alloc")]
70impl<D, T, M> Clone for GenericSigningKey<D, T, M>
71where
72 D: Digest,
73 T: UnsignedModularInt + Zeroize + Clone,
74 M: ModulusParams<Modulus = T> + Clone,
75 M::MontgomeryForm: Clone,
76{
77 fn clone(&self) -> Self {
78 Self {
79 inner: self.inner.clone(),
80 prefix: self.prefix.clone(),
81 phantom: PhantomData,
82 }
83 }
84}
85
86#[cfg(not(feature = "alloc"))]
87impl<D, T, M> Clone for GenericSigningKey<D, T, M>
88where
89 D: Digest,
90 T: UnsignedModularInt + Zeroize + Clone,
91 M: ModulusParams<Modulus = T> + Clone,
92{
93 fn clone(&self) -> Self {
94 Self {
95 inner: self.inner.clone(),
96 prefix: self.prefix.clone(),
97 phantom: PhantomData,
98 }
99 }
100}
101
102impl<D, T, M> GenericSigningKey<D, T, M>
103where
104 D: Digest + AssociatedOid,
105 T: UnsignedModularInt + Zeroize,
106 M: ModulusParams<Modulus = T>,
107{
108 pub fn new(key: GenericRsaPrivateKey<T, M>) -> Self {
110 Self {
111 inner: key,
112 #[cfg(feature = "alloc")]
113 prefix: pkcs1v15_generate_prefix::<D>(),
114 #[cfg(not(feature = "alloc"))]
115 prefix: pkcs1v15_generate_prefix_helper::<D>(),
116 phantom: PhantomData,
117 }
118 }
119}
120
121impl<D, T, M> GenericSigningKey<D, T, M>
122where
123 D: Digest,
124 T: UnsignedModularInt + Zeroize,
125 M: ModulusParams<Modulus = T>,
126{
127 pub fn new_unprefixed(key: GenericRsaPrivateKey<T, M>) -> Self {
130 Self {
131 inner: key,
132 #[cfg(feature = "alloc")]
133 prefix: alloc::vec::Vec::new(),
134 #[cfg(not(feature = "alloc"))]
135 prefix: Prefix::new(),
136 phantom: PhantomData,
137 }
138 }
139}
140
141impl<D, T, M> AsRef<GenericRsaPrivateKey<T, M>> for GenericSigningKey<D, T, M>
144where
145 D: Digest,
146 T: UnsignedModularInt + Zeroize,
147 M: ModulusParams<Modulus = T>,
148{
149 fn as_ref(&self) -> &GenericRsaPrivateKey<T, M> {
150 &self.inner
151 }
152}
153
154impl<D, T, M> GenericSigningKey<D, T, M>
155where
156 D: Digest,
157 T: UnsignedModularInt + Zeroize,
158 T::Bytes: Zeroize,
159 M: ModulusParams<Modulus = T> + crate::traits::modular::CtModulusParams,
160 M::MontgomeryForm: Pow<M> + PowBoundedExp<M>,
161{
162 pub fn try_sign_into<'sig>(
171 &self,
172 msg: &[u8],
173 em_storage: &mut [u8],
174 sig_storage: &'sig mut [u8],
175 ) -> Result<&'sig [u8]> {
176 let digest = D::digest(msg);
177 let k = self.inner.size();
178 sign_into(
179 self.inner.n_params(),
180 crate::traits::keys::PrivateKeyParts::d(&self.inner),
181 self.inner.e(),
182 self.prefix.as_ref(),
183 digest.as_ref(),
184 k,
185 em_storage,
186 sig_storage,
187 )
188 }
189
190 pub fn try_sign_prehash_into<'sig>(
198 &self,
199 prehash: &[u8],
200 em_storage: &mut [u8],
201 sig_storage: &'sig mut [u8],
202 ) -> Result<&'sig [u8]> {
203 if prehash.len() != <D as Digest>::output_size() {
204 return Err(crate::errors::Error::InputNotHashed);
205 }
206 let k = self.inner.size();
207 sign_into(
208 self.inner.n_params(),
209 crate::traits::keys::PrivateKeyParts::d(&self.inner),
210 self.inner.e(),
211 self.prefix.as_ref(),
212 prehash,
213 k,
214 em_storage,
215 sig_storage,
216 )
217 }
218}
219
220impl<D, T, M> GenericSigningKey<D, T, M>
227where
228 D: Digest,
229 T: UnsignedModularInt + Zeroize + crate::traits::modular::TryRandomMod,
230 T::Bytes: Zeroize,
231 M: ModulusParams<Modulus = T> + crate::traits::modular::CtModulusParams,
232 M::MontgomeryForm: Pow<M>
233 + PowBoundedExp<M>
234 + crate::traits::modular::InvertCt<M>
235 + crate::traits::modular::MulCt<M>,
236{
237 pub fn try_sign_with_rng_into<'sig, R: rand_core::TryCryptoRng + ?Sized>(
240 &self,
241 rng: &mut R,
242 msg: &[u8],
243 em_storage: &mut [u8],
244 sig_storage: &'sig mut [u8],
245 ) -> Result<&'sig [u8]> {
246 let digest = D::digest(msg);
247 let k = self.inner.size();
248 sign_with_rng_into(
249 rng,
250 self.inner.n_params(),
251 crate::traits::keys::PrivateKeyParts::d(&self.inner),
252 self.inner.e(),
253 self.prefix.as_ref(),
254 digest.as_ref(),
255 k,
256 em_storage,
257 sig_storage,
258 )
259 }
260
261 pub fn try_sign_prehash_with_rng_into<'sig, R: rand_core::TryCryptoRng + ?Sized>(
263 &self,
264 rng: &mut R,
265 prehash: &[u8],
266 em_storage: &mut [u8],
267 sig_storage: &'sig mut [u8],
268 ) -> Result<&'sig [u8]> {
269 if prehash.len() != <D as Digest>::output_size() {
270 return Err(crate::errors::Error::InputNotHashed);
271 }
272 let k = self.inner.size();
273 sign_with_rng_into(
274 rng,
275 self.inner.n_params(),
276 crate::traits::keys::PrivateKeyParts::d(&self.inner),
277 self.inner.e(),
278 self.prefix.as_ref(),
279 prehash,
280 k,
281 em_storage,
282 sig_storage,
283 )
284 }
285}
286
287impl<D, T, M> Zeroize for GenericSigningKey<D, T, M>
291where
292 D: Digest,
293 T: UnsignedModularInt + Zeroize,
294 M: ModulusParams<Modulus = T>,
295{
296 fn zeroize(&mut self) {
297 self.inner.zeroize();
298 }
299}
300
301impl<D, T, M> GenericSigningKey<D, T, M>
302where
303 D: Digest,
304 T: UnsignedModularInt + Zeroize,
305 M: ModulusParams<Modulus = T>,
306{
307 pub fn to_verifying_key(&self) -> GenericVerifyingKey<D, T, M>
314 where
315 crate::key::GenericRsaPublicKey<T, M>: Clone,
316 {
317 GenericVerifyingKey {
318 inner: self.inner.as_public().clone(),
319 prefix: self.prefix.clone(),
320 phantom: PhantomData,
321 }
322 }
323}