ring_compat/signature/ecdsa/
signing_key.rs

1//! ECDSA signing key
2
3use super::{CurveAlg, Signature, VerifyingKey};
4use crate::signature::{Error, Keypair, Signer};
5use core::marker::PhantomData;
6use ecdsa::{
7    elliptic_curve::{sec1, FieldBytesSize},
8    SignatureSize,
9};
10use generic_array::ArrayLength;
11use pkcs8::DecodePrivateKey;
12use ring::{
13    self,
14    rand::SystemRandom,
15    signature::{EcdsaKeyPair, KeyPair as _},
16};
17
18/// ECDSA signing key. Generic over elliptic curves.
19pub struct SigningKey<C>
20where
21    C: CurveAlg,
22    SignatureSize<C>: ArrayLength<u8>,
23{
24    /// *ring* ECDSA keypair
25    keypair: EcdsaKeyPair,
26
27    /// Cryptographically secure random number generator
28    csrng: SystemRandom,
29
30    /// Elliptic curve type
31    curve: PhantomData<C>,
32}
33
34impl<C> SigningKey<C>
35where
36    C: CurveAlg,
37    SignatureSize<C>: ArrayLength<u8>,
38{
39    /// Initialize a [`SigningKey`] from a raw keypair
40    pub fn from_keypair_bytes(signing_key: &[u8], verifying_key: &[u8]) -> Result<Self, Error> {
41        let csrng = SystemRandom::new();
42
43        let keypair = EcdsaKeyPair::from_private_key_and_public_key(
44            C::signing_alg(),
45            signing_key,
46            verifying_key,
47            &csrng,
48        )
49        .map_err(|_| Error::new())?;
50
51        Ok(Self {
52            keypair,
53            csrng,
54            curve: PhantomData,
55        })
56    }
57
58    /// Get the [`VerifyingKey`] for this [`SigningKey`]
59    pub fn verifying_key(&self) -> VerifyingKey<C>
60    where
61        FieldBytesSize<C>: sec1::ModulusSize,
62    {
63        VerifyingKey::new(self.keypair.public_key().as_ref()).unwrap()
64    }
65}
66
67impl<C> DecodePrivateKey for SigningKey<C>
68where
69    C: CurveAlg,
70    SignatureSize<C>: ArrayLength<u8>,
71{
72    fn from_pkcs8_der(pkcs8_bytes: &[u8]) -> Result<Self, pkcs8::Error> {
73        let csrng = SystemRandom::new();
74
75        let keypair = EcdsaKeyPair::from_pkcs8(C::signing_alg(), pkcs8_bytes, &csrng)
76            .map_err(|_| pkcs8::Error::KeyMalformed)?;
77
78        Ok(Self {
79            keypair,
80            csrng,
81            curve: PhantomData,
82        })
83    }
84}
85
86impl<C> Keypair for SigningKey<C>
87where
88    C: CurveAlg,
89    FieldBytesSize<C>: sec1::ModulusSize,
90    SignatureSize<C>: ArrayLength<u8>,
91{
92    type VerifyingKey = VerifyingKey<C>;
93
94    fn verifying_key(&self) -> VerifyingKey<C> {
95        self.verifying_key()
96    }
97}
98
99impl<C> Signer<Signature<C>> for SigningKey<C>
100where
101    C: CurveAlg,
102    SignatureSize<C>: ArrayLength<u8>,
103{
104    fn try_sign(&self, msg: &[u8]) -> Result<Signature<C>, Error> {
105        self.keypair
106            .sign(&self.csrng, msg)
107            .map_err(|_| Error::new())
108            .and_then(|sig| Signature::try_from(sig.as_ref()))
109    }
110}