1use crate::{Algorithm, EcdsaCurve, Error, Result, public::EcdsaPublicKey};
4use core::fmt;
5use ctutils::{Choice, CtEq};
6use encoding::{CheckedSum, Decode, Encode, Reader, Writer};
7use sec1::consts::{U32, U48, U66};
8use zeroize::Zeroize;
9
10#[cfg(feature = "rand_core")]
11use rand_core::CryptoRng;
12
13#[cfg(all(
14 feature = "rand_core",
15 any(feature = "p256", feature = "p384", feature = "p521")
16))]
17use cipher::cipher::common::Generate;
18
19#[derive(Clone)]
21pub struct EcdsaPrivateKey<const SIZE: usize> {
22 bytes: [u8; SIZE],
24}
25
26impl<const SIZE: usize> EcdsaPrivateKey<SIZE> {
27 #[must_use]
29 pub fn as_slice(&self) -> &[u8] {
30 self.bytes.as_ref()
31 }
32
33 #[must_use]
35 pub fn into_bytes(self) -> [u8; SIZE] {
36 self.bytes
37 }
38
39 fn needs_leading_zero(&self) -> bool {
41 self.bytes[0] >= 0x80
42 }
43}
44
45impl<const SIZE: usize> Decode for EcdsaPrivateKey<SIZE> {
46 type Error = Error;
47
48 fn decode(reader: &mut impl Reader) -> Result<Self> {
49 reader.read_prefixed(|reader| {
50 let mut len = reader.remaining_len();
51
52 if len == SIZE.checked_add(1).ok_or(encoding::Error::Length)? {
55 if u8::decode(reader)? != 0 {
57 return Err(Error::FormatEncoding);
58 }
59
60 len = SIZE;
61 }
62
63 const MIN_SIZE: usize = 32;
65 if len < MIN_SIZE || len > SIZE {
66 return Err(encoding::Error::Length.into());
67 }
68
69 let leading_zeros = SIZE.checked_sub(len).ok_or(encoding::Error::Length)?;
72
73 let mut bytes = [0u8; SIZE];
74 reader.read(&mut bytes[leading_zeros..])?;
75 Ok(Self { bytes })
76 })
77 }
78}
79
80impl<const SIZE: usize> Encode for EcdsaPrivateKey<SIZE> {
81 fn encoded_len(&self) -> encoding::Result<usize> {
82 [4, self.needs_leading_zero().into(), SIZE].checked_sum()
83 }
84
85 fn encode(&self, writer: &mut impl Writer) -> encoding::Result<()> {
86 [self.needs_leading_zero().into(), SIZE]
87 .checked_sum()?
88 .encode(writer)?;
89
90 if self.needs_leading_zero() {
91 writer.write(&[0])?;
92 }
93
94 writer.write(&self.bytes)?;
95 Ok(())
96 }
97}
98
99impl<const SIZE: usize> From<[u8; SIZE]> for EcdsaPrivateKey<SIZE> {
100 fn from(bytes: [u8; SIZE]) -> Self {
101 Self { bytes }
102 }
103}
104
105impl<const SIZE: usize> AsRef<[u8; SIZE]> for EcdsaPrivateKey<SIZE> {
106 fn as_ref(&self) -> &[u8; SIZE] {
107 &self.bytes
108 }
109}
110
111impl<const SIZE: usize> CtEq for EcdsaPrivateKey<SIZE> {
112 fn ct_eq(&self, other: &Self) -> Choice {
113 self.as_ref().ct_eq(other.as_ref())
114 }
115}
116
117impl<const SIZE: usize> PartialEq for EcdsaPrivateKey<SIZE> {
118 fn eq(&self, other: &Self) -> bool {
119 self.ct_eq(other).into()
120 }
121}
122
123impl<const SIZE: usize> Eq for EcdsaPrivateKey<SIZE> {}
124
125impl<const SIZE: usize> fmt::Debug for EcdsaPrivateKey<SIZE> {
126 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
127 f.debug_struct("EcdsaPrivateKey").finish_non_exhaustive()
128 }
129}
130
131impl<const SIZE: usize> fmt::LowerHex for EcdsaPrivateKey<SIZE> {
132 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
133 for byte in self.as_ref() {
134 write!(f, "{byte:02x}")?;
135 }
136 Ok(())
137 }
138}
139
140impl<const SIZE: usize> fmt::UpperHex for EcdsaPrivateKey<SIZE> {
141 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
142 for byte in self.as_ref() {
143 write!(f, "{byte:02X}")?;
144 }
145 Ok(())
146 }
147}
148
149impl<const SIZE: usize> Drop for EcdsaPrivateKey<SIZE> {
150 fn drop(&mut self) {
151 self.bytes.zeroize();
152 }
153}
154
155#[cfg(feature = "p256")]
156impl From<p256::SecretKey> for EcdsaPrivateKey<32> {
157 fn from(sk: p256::SecretKey) -> EcdsaPrivateKey<32> {
158 EcdsaPrivateKey {
159 bytes: sk.to_bytes().into(),
160 }
161 }
162}
163
164#[cfg(feature = "p384")]
165impl From<p384::SecretKey> for EcdsaPrivateKey<48> {
166 fn from(sk: p384::SecretKey) -> EcdsaPrivateKey<48> {
167 EcdsaPrivateKey {
168 bytes: sk.to_bytes().into(),
169 }
170 }
171}
172
173#[cfg(feature = "p521")]
174impl From<p521::SecretKey> for EcdsaPrivateKey<66> {
175 fn from(sk: p521::SecretKey) -> EcdsaPrivateKey<66> {
176 let mut bytes = [0u8; 66];
178 bytes.copy_from_slice(&sk.to_bytes());
179 EcdsaPrivateKey { bytes }
180 }
181}
182
183#[derive(Clone, Debug)]
185pub enum EcdsaKeypair {
186 NistP256 {
188 public: sec1::EncodedPoint<U32>,
190
191 private: EcdsaPrivateKey<32>,
193 },
194
195 NistP384 {
197 public: sec1::EncodedPoint<U48>,
199
200 private: EcdsaPrivateKey<48>,
202 },
203
204 NistP521 {
206 public: sec1::EncodedPoint<U66>,
208
209 private: EcdsaPrivateKey<66>,
211 },
212}
213
214impl EcdsaKeypair {
215 #[cfg(feature = "rand_core")]
221 #[allow(unused_variables)]
222 pub fn random<R: CryptoRng + ?Sized>(rng: &mut R, curve: EcdsaCurve) -> Result<Self> {
223 match curve {
224 #[cfg(feature = "p256")]
225 EcdsaCurve::NistP256 => {
226 let private = p256::SecretKey::generate_from_rng(rng);
227 let public = private.public_key();
228 Ok(EcdsaKeypair::NistP256 {
229 private: private.into(),
230 public: public.into(),
231 })
232 }
233 #[cfg(feature = "p384")]
234 EcdsaCurve::NistP384 => {
235 let private = p384::SecretKey::generate_from_rng(rng);
236 let public = private.public_key();
237 Ok(EcdsaKeypair::NistP384 {
238 private: private.into(),
239 public: public.into(),
240 })
241 }
242 #[cfg(feature = "p521")]
243 EcdsaCurve::NistP521 => {
244 let private = p521::SecretKey::generate_from_rng(rng);
245 let public = private.public_key();
246 Ok(EcdsaKeypair::NistP521 {
247 private: private.into(),
248 public: public.into(),
249 })
250 }
251 #[cfg(not(all(feature = "p256", feature = "p384", feature = "p521")))]
252 _ => Err(Error::AlgorithmUnsupported {
253 algorithm: curve.into(),
254 }),
255 }
256 }
257
258 #[must_use]
260 pub fn algorithm(&self) -> Algorithm {
261 Algorithm::Ecdsa {
262 curve: self.curve(),
263 }
264 }
265
266 #[must_use]
268 pub fn curve(&self) -> EcdsaCurve {
269 match self {
270 Self::NistP256 { .. } => EcdsaCurve::NistP256,
271 Self::NistP384 { .. } => EcdsaCurve::NistP384,
272 Self::NistP521 { .. } => EcdsaCurve::NistP521,
273 }
274 }
275
276 #[must_use]
278 pub fn public_key_bytes(&self) -> &[u8] {
279 match self {
280 Self::NistP256 { public, .. } => public.as_ref(),
281 Self::NistP384 { public, .. } => public.as_ref(),
282 Self::NistP521 { public, .. } => public.as_ref(),
283 }
284 }
285
286 #[must_use]
288 pub fn private_key_bytes(&self) -> &[u8] {
289 match self {
290 Self::NistP256 { private, .. } => private.as_ref(),
291 Self::NistP384 { private, .. } => private.as_ref(),
292 Self::NistP521 { private, .. } => private.as_ref(),
293 }
294 }
295}
296
297impl CtEq for EcdsaKeypair {
298 fn ct_eq(&self, other: &Self) -> Choice {
299 let public_eq = Choice::from(u8::from(
300 EcdsaPublicKey::from(self) == EcdsaPublicKey::from(other),
301 ));
302
303 let private_key_a = match self {
304 Self::NistP256 { private, .. } => private.as_slice(),
305 Self::NistP384 { private, .. } => private.as_slice(),
306 Self::NistP521 { private, .. } => private.as_slice(),
307 };
308
309 let private_key_b = match other {
310 Self::NistP256 { private, .. } => private.as_slice(),
311 Self::NistP384 { private, .. } => private.as_slice(),
312 Self::NistP521 { private, .. } => private.as_slice(),
313 };
314
315 public_eq & private_key_a.ct_eq(private_key_b)
316 }
317}
318
319impl Eq for EcdsaKeypair {}
320
321impl PartialEq for EcdsaKeypair {
322 fn eq(&self, other: &Self) -> bool {
323 self.ct_eq(other).into()
324 }
325}
326
327impl Decode for EcdsaKeypair {
328 type Error = Error;
329
330 fn decode(reader: &mut impl Reader) -> Result<Self> {
331 match EcdsaPublicKey::decode(reader)? {
332 EcdsaPublicKey::NistP256(public) => {
333 let private = EcdsaPrivateKey::<32>::decode(reader)?;
334 Ok(Self::NistP256 { public, private })
335 }
336 EcdsaPublicKey::NistP384(public) => {
337 let private = EcdsaPrivateKey::<48>::decode(reader)?;
338 Ok(Self::NistP384 { public, private })
339 }
340 EcdsaPublicKey::NistP521(public) => {
341 let private = EcdsaPrivateKey::<66>::decode(reader)?;
342 Ok(Self::NistP521 { public, private })
343 }
344 }
345 }
346}
347
348impl Encode for EcdsaKeypair {
349 fn encoded_len(&self) -> encoding::Result<usize> {
350 let public_len = EcdsaPublicKey::from(self).encoded_len()?;
351
352 let private_len = match self {
353 Self::NistP256 { private, .. } => private.encoded_len()?,
354 Self::NistP384 { private, .. } => private.encoded_len()?,
355 Self::NistP521 { private, .. } => private.encoded_len()?,
356 };
357
358 [public_len, private_len].checked_sum()
359 }
360
361 fn encode(&self, writer: &mut impl Writer) -> encoding::Result<()> {
362 EcdsaPublicKey::from(self).encode(writer)?;
363
364 match self {
365 Self::NistP256 { private, .. } => private.encode(writer)?,
366 Self::NistP384 { private, .. } => private.encode(writer)?,
367 Self::NistP521 { private, .. } => private.encode(writer)?,
368 }
369
370 Ok(())
371 }
372}
373
374impl From<EcdsaKeypair> for EcdsaPublicKey {
375 fn from(keypair: EcdsaKeypair) -> EcdsaPublicKey {
376 EcdsaPublicKey::from(&keypair)
377 }
378}
379
380impl From<&EcdsaKeypair> for EcdsaPublicKey {
381 fn from(keypair: &EcdsaKeypair) -> EcdsaPublicKey {
382 match keypair {
383 EcdsaKeypair::NistP256 { public, .. } => EcdsaPublicKey::NistP256(*public),
384 EcdsaKeypair::NistP384 { public, .. } => EcdsaPublicKey::NistP384(*public),
385 EcdsaKeypair::NistP521 { public, .. } => EcdsaPublicKey::NistP521(*public),
386 }
387 }
388}