ring_compat/signature/ecdsa/
signing_key.rs1use 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
18pub struct SigningKey<C>
20where
21 C: CurveAlg,
22 SignatureSize<C>: ArrayLength<u8>,
23{
24 keypair: EcdsaKeyPair,
26
27 csrng: SystemRandom,
29
30 curve: PhantomData<C>,
32}
33
34impl<C> SigningKey<C>
35where
36 C: CurveAlg,
37 SignatureSize<C>: ArrayLength<u8>,
38{
39 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 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}