1use crate::{Error, Mpint, Result, public::DsaPublicKey};
4use core::fmt;
5use encoding::{CheckedSum, Decode, Encode, Reader, Writer};
6use subtle::{Choice, ConstantTimeEq};
7use zeroize::Zeroize;
8
9#[cfg(feature = "dsa")]
10use encoding::Uint;
11
12#[cfg(all(feature = "dsa", feature = "rand_core"))]
13use rand_core::CryptoRng;
14
15#[derive(Clone)]
22pub struct DsaPrivateKey {
23 inner: Mpint,
25}
26
27impl DsaPrivateKey {
28 pub fn new(x: Mpint) -> Result<Self> {
30 if x.is_positive() {
31 Ok(Self { inner: x })
32 } else {
33 Err(Error::FormatEncoding)
34 }
35 }
36
37 pub fn as_bytes(&self) -> &[u8] {
39 self.inner.as_bytes()
40 }
41
42 pub fn as_mpint(&self) -> &Mpint {
44 &self.inner
45 }
46}
47
48impl AsRef<[u8]> for DsaPrivateKey {
49 fn as_ref(&self) -> &[u8] {
50 self.as_bytes()
51 }
52}
53
54impl ConstantTimeEq for DsaPrivateKey {
55 fn ct_eq(&self, other: &Self) -> Choice {
56 self.inner.ct_eq(&other.inner)
57 }
58}
59
60impl Eq for DsaPrivateKey {}
61
62impl PartialEq for DsaPrivateKey {
63 fn eq(&self, other: &Self) -> bool {
64 self.ct_eq(other).into()
65 }
66}
67
68impl TryFrom<Mpint> for DsaPrivateKey {
69 type Error = Error;
70
71 fn try_from(x: Mpint) -> Result<Self> {
72 Self::new(x)
73 }
74}
75
76impl Decode for DsaPrivateKey {
77 type Error = Error;
78
79 fn decode(reader: &mut impl Reader) -> Result<Self> {
80 Self::new(Mpint::decode(reader)?)
81 }
82}
83
84impl Encode for DsaPrivateKey {
85 fn encoded_len(&self) -> encoding::Result<usize> {
86 self.inner.encoded_len()
87 }
88
89 fn encode(&self, writer: &mut impl Writer) -> encoding::Result<()> {
90 self.inner.encode(writer)
91 }
92}
93
94impl fmt::Debug for DsaPrivateKey {
95 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96 f.debug_struct("DsaPrivateKey").finish_non_exhaustive()
97 }
98}
99
100impl Drop for DsaPrivateKey {
101 fn drop(&mut self) {
102 self.inner.zeroize();
103 }
104}
105
106#[cfg(feature = "dsa")]
107impl TryFrom<DsaPrivateKey> for Uint {
108 type Error = Error;
109
110 fn try_from(key: DsaPrivateKey) -> Result<Uint> {
111 Ok(Uint::try_from(&key.inner)?)
112 }
113}
114
115#[cfg(feature = "dsa")]
116impl TryFrom<&DsaPrivateKey> for Uint {
117 type Error = Error;
118
119 fn try_from(key: &DsaPrivateKey) -> Result<Uint> {
120 Ok(Uint::try_from(&key.inner)?)
121 }
122}
123
124#[cfg(feature = "dsa")]
125impl TryFrom<dsa::SigningKey> for DsaPrivateKey {
126 type Error = Error;
127
128 fn try_from(key: dsa::SigningKey) -> Result<DsaPrivateKey> {
129 DsaPrivateKey::try_from(&key)
130 }
131}
132
133#[cfg(feature = "dsa")]
134impl TryFrom<&dsa::SigningKey> for DsaPrivateKey {
135 type Error = Error;
136
137 fn try_from(key: &dsa::SigningKey) -> Result<DsaPrivateKey> {
138 Ok(DsaPrivateKey {
139 inner: key.x().as_ref().try_into()?,
140 })
141 }
142}
143
144#[derive(Clone)]
146pub struct DsaKeypair {
147 public: DsaPublicKey,
149
150 private: DsaPrivateKey,
152}
153
154impl DsaKeypair {
155 #[cfg(all(feature = "dsa", feature = "rand_core"))]
157 #[allow(deprecated)]
158 pub(crate) const KEY_SIZE: dsa::KeySize = dsa::KeySize::DSA_1024_160;
159
160 #[cfg(all(feature = "dsa", feature = "rand_core"))]
162 pub fn random<R: CryptoRng + ?Sized>(rng: &mut R) -> Result<Self> {
163 let components = dsa::Components::generate(rng, Self::KEY_SIZE);
164 dsa::SigningKey::generate(rng, components).try_into()
165 }
166
167 pub fn new(public: DsaPublicKey, private: DsaPrivateKey) -> Result<Self> {
169 Ok(Self { public, private })
171 }
172
173 pub fn public(&self) -> &DsaPublicKey {
175 &self.public
176 }
177
178 pub fn private(&self) -> &DsaPrivateKey {
180 &self.private
181 }
182}
183
184impl ConstantTimeEq for DsaKeypair {
185 fn ct_eq(&self, other: &Self) -> Choice {
186 Choice::from((self.public == other.public) as u8) & self.private.ct_eq(&other.private)
187 }
188}
189
190impl PartialEq for DsaKeypair {
191 fn eq(&self, other: &Self) -> bool {
192 self.ct_eq(other).into()
193 }
194}
195
196impl Eq for DsaKeypair {}
197
198impl Decode for DsaKeypair {
199 type Error = Error;
200
201 fn decode(reader: &mut impl Reader) -> Result<Self> {
202 let public = DsaPublicKey::decode(reader)?;
203 let private = DsaPrivateKey::decode(reader)?;
204 DsaKeypair::new(public, private)
205 }
206}
207
208impl Encode for DsaKeypair {
209 fn encoded_len(&self) -> encoding::Result<usize> {
210 [self.public.encoded_len()?, self.private.encoded_len()?].checked_sum()
211 }
212
213 fn encode(&self, writer: &mut impl Writer) -> encoding::Result<()> {
214 self.public.encode(writer)?;
215 self.private.encode(writer)
216 }
217}
218
219impl From<DsaKeypair> for DsaPublicKey {
220 fn from(keypair: DsaKeypair) -> DsaPublicKey {
221 keypair.public
222 }
223}
224
225impl From<&DsaKeypair> for DsaPublicKey {
226 fn from(keypair: &DsaKeypair) -> DsaPublicKey {
227 keypair.public.clone()
228 }
229}
230
231impl fmt::Debug for DsaKeypair {
232 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
233 f.debug_struct("DsaKeypair")
234 .field("public", &self.public)
235 .finish_non_exhaustive()
236 }
237}
238
239#[cfg(feature = "dsa")]
240impl TryFrom<DsaKeypair> for dsa::SigningKey {
241 type Error = Error;
242
243 fn try_from(key: DsaKeypair) -> Result<dsa::SigningKey> {
244 dsa::SigningKey::try_from(&key)
245 }
246}
247
248#[cfg(feature = "dsa")]
249impl TryFrom<&DsaKeypair> for dsa::SigningKey {
250 type Error = Error;
251
252 fn try_from(key: &DsaKeypair) -> Result<dsa::SigningKey> {
253 Ok(dsa::SigningKey::from_components(
254 dsa::VerifyingKey::try_from(&key.public)?,
255 key.private.as_mpint().try_into()?,
256 )?)
257 }
258}
259
260#[cfg(feature = "dsa")]
261impl TryFrom<dsa::SigningKey> for DsaKeypair {
262 type Error = Error;
263
264 fn try_from(key: dsa::SigningKey) -> Result<DsaKeypair> {
265 DsaKeypair::try_from(&key)
266 }
267}
268
269#[cfg(feature = "dsa")]
270impl TryFrom<&dsa::SigningKey> for DsaKeypair {
271 type Error = Error;
272
273 fn try_from(key: &dsa::SigningKey) -> Result<DsaKeypair> {
274 Ok(DsaKeypair {
275 private: key.try_into()?,
276 public: key.verifying_key().try_into()?,
277 })
278 }
279}