rsa/traits/keys.rs
1//! Traits related to the key components
2
3#[cfg(feature = "alloc")]
4use alloc::boxed::Box;
5
6use crate::traits::{modular::ModulusParams, NonZero, UnsignedModularInt};
7
8/// Marker trait gating the raw `(public_key, d)` constructor
9/// [`crate::key::GenericRsaPrivateKey::from_public_and_d`]. Backends opt
10/// in to building private keys without `primes` or CRT precompute — the
11/// heapless path, where the caller already holds validated `(n, e, d)`.
12///
13/// **Not impl'd for [`BoxedUint`]**: alloc callers must use the validated
14/// `RsaPrivateKey::from_components` / `from_p_q` / `from_primes` paths, so
15/// empty `primes` can't leak into CRT-aware APIs as a `primes[0]` panic.
16pub trait RawPrivateKeyConstructible: UnsignedModularInt {}
17
18// Heapless build: `FixedWidthUnsignedInt + PartialOrd` matches the
19// `UnsignedModularInt` blanket and gets the marker for free. `BoxedUint`
20// isn't `Copy`, so it can't satisfy `FixedWidthUnsignedInt`.
21#[cfg(not(feature = "alloc"))]
22impl<T> RawPrivateKeyConstructible for T where
23 T: crate::traits::modular::FixedWidthUnsignedInt + PartialOrd
24{
25}
26
27/// Components of an RSA public key.
28pub trait PublicKeyParts<T: UnsignedModularInt> {
29 /// Montgomery parameter type matching this modulus type.
30 type MontyParams: ModulusParams<Modulus = T>;
31
32 /// Returns the modulus of the key.
33 fn n(&self) -> &NonZero<T>;
34
35 /// Returns the public exponent of the key.
36 fn e(&self) -> &T;
37
38 /// Returns the modulus size in bytes. Raw signatures and ciphertexts for
39 /// or by this public key will have the same size.
40 fn size(&self) -> usize {
41 (self.n().bits() as usize).div_ceil(8)
42 }
43
44 /// Returns the parameters for montgomery operations.
45 fn n_params(&self) -> &Self::MontyParams;
46
47 /// Returns precision (in bits) of `n`.
48 fn n_bits_precision(&self) -> u32 {
49 self.n().bits_precision()
50 }
51
52 /// Returns the big endian serialization of the modulus of the key
53 #[cfg(feature = "alloc")]
54 fn n_bytes(&self) -> Box<[u8]> {
55 self.n().to_be_bytes_trimmed_vartime()
56 }
57
58 /// Returns the big endian serialization of the public exponent of the key
59 #[cfg(feature = "alloc")]
60 fn e_bytes(&self) -> Box<[u8]> {
61 self.e().to_be_bytes_trimmed_vartime()
62 }
63}
64
65/// Components of an RSA private key — generic over the integer /
66/// Montgomery-parameter backend.
67///
68/// The base surface is `d()`; the CRT accessors (`dp`/`dq`/`qinv`/
69/// `p_params`/`q_params`) are `alloc`-gated and default to `None`, so a
70/// key without CRT precompute satisfies the trait with just `d()`.
71pub trait PrivateKeyParts<T>: PublicKeyParts<T>
72where
73 T: UnsignedModularInt,
74{
75 /// Returns the private exponent of the key.
76 fn d(&self) -> &T;
77
78 /// Returns the prime factors of the modulus. Returns `&[]` for keys
79 /// that don't store factors.
80 #[cfg(feature = "alloc")]
81 fn primes(&self) -> &[T] {
82 &[]
83 }
84
85 /// Returns the precomputed `dp = d mod (p - 1)` value, if available.
86 /// `None` for keys that didn't precompute CRT.
87 #[cfg(feature = "alloc")]
88 fn dp(&self) -> Option<&T> {
89 None
90 }
91
92 /// Returns the precomputed `dq = d mod (q - 1)` value, if available.
93 #[cfg(feature = "alloc")]
94 fn dq(&self) -> Option<&T> {
95 None
96 }
97
98 /// Returns the precomputed `qinv = q^-1 mod p` value, if available.
99 #[cfg(feature = "alloc")]
100 fn qinv(&self) -> Option<&<Self::MontyParams as ModulusParams>::MontgomeryForm> {
101 None
102 }
103
104 /// Returns the Montgomery parameters for `p`, if available.
105 #[cfg(feature = "alloc")]
106 fn p_params(&self) -> Option<&Self::MontyParams> {
107 None
108 }
109
110 /// Returns the Montgomery parameters for `q`, if available.
111 #[cfg(feature = "alloc")]
112 fn q_params(&self) -> Option<&Self::MontyParams> {
113 None
114 }
115}