1use crate::{Components, Signature, VerifyingKey, OID};
6use core::{
7 cmp::min,
8 fmt::{self, Debug},
9};
10use digest::{core_api::BlockSizeUser, Digest, FixedOutputReset};
11use num_bigint::BigUint;
12use num_traits::Zero;
13use pkcs8::{
14 der::{asn1::UintRef, AnyRef, Decode, Encode},
15 AlgorithmIdentifierRef, EncodePrivateKey, PrivateKeyInfo, SecretDocument,
16};
17use signature::{
18 hazmat::{PrehashSigner, RandomizedPrehashSigner},
19 rand_core::CryptoRngCore,
20 DigestSigner, RandomizedDigestSigner, Signer,
21};
22use zeroize::{Zeroize, Zeroizing};
23
24#[derive(Clone, PartialEq)]
29#[must_use]
30pub struct SigningKey {
31 verifying_key: VerifyingKey,
33
34 x: Zeroizing<BigUint>,
36}
37
38impl SigningKey {
39 pub fn from_components(verifying_key: VerifyingKey, x: BigUint) -> signature::Result<Self> {
41 if x.is_zero() || x > *verifying_key.components().q() {
42 return Err(signature::Error::new());
43 }
44
45 Ok(Self {
46 verifying_key,
47 x: Zeroizing::new(x),
48 })
49 }
50
51 #[inline]
53 pub fn generate(rng: &mut impl CryptoRngCore, components: Components) -> SigningKey {
54 crate::generate::keypair(rng, components)
55 }
56
57 pub const fn verifying_key(&self) -> &VerifyingKey {
59 &self.verifying_key
60 }
61
62 #[must_use]
66 pub fn x(&self) -> &BigUint {
67 &self.x
68 }
69
70 pub fn sign_prehashed_rfc6979<D>(&self, prehash: &[u8]) -> Result<Signature, signature::Error>
75 where
76 D: Digest + BlockSizeUser + FixedOutputReset,
77 {
78 let k_kinv = crate::generate::secret_number_rfc6979::<D>(self, prehash);
79 self.sign_prehashed(k_kinv, prehash)
80 }
81
82 fn sign_prehashed(
84 &self,
85 (k, inv_k): (BigUint, BigUint),
86 hash: &[u8],
87 ) -> signature::Result<Signature> {
88 let components = self.verifying_key().components();
89 let (p, q, g) = (components.p(), components.q(), components.g());
90 let x = self.x();
91
92 let r = g.modpow(&k, p) % q;
93
94 let n = q.bits() / 8;
95 let block_size = hash.len(); let z_len = min(n, block_size);
98 let z = BigUint::from_bytes_be(&hash[..z_len]);
99
100 let s = (inv_k * (z + x * &r)) % q;
101
102 let signature = Signature::from_components(r, s)?;
103
104 if signature.r() < q && signature.s() < q {
105 Ok(signature)
106 } else {
107 Err(signature::Error::new())
108 }
109 }
110}
111
112impl Signer<Signature> for SigningKey {
113 fn try_sign(&self, msg: &[u8]) -> Result<Signature, signature::Error> {
114 let digest = sha2::Sha256::new_with_prefix(msg);
115 self.try_sign_digest(digest)
116 }
117}
118
119impl PrehashSigner<Signature> for SigningKey {
120 fn sign_prehash(&self, prehash: &[u8]) -> Result<Signature, signature::Error> {
122 let k_kinv = crate::generate::secret_number_rfc6979::<sha2::Sha256>(self, prehash);
123 self.sign_prehashed(k_kinv, prehash)
124 }
125}
126
127impl RandomizedPrehashSigner<Signature> for SigningKey {
128 fn sign_prehash_with_rng(
129 &self,
130 mut rng: &mut impl CryptoRngCore,
131 prehash: &[u8],
132 ) -> Result<Signature, signature::Error> {
133 let components = self.verifying_key.components();
134
135 if let Some(k_kinv) = crate::generate::secret_number(&mut rng, components) {
136 self.sign_prehashed(k_kinv, prehash)
137 } else {
138 Err(signature::Error::new())
139 }
140 }
141}
142
143impl<D> DigestSigner<D, Signature> for SigningKey
144where
145 D: Digest + BlockSizeUser + FixedOutputReset,
146{
147 fn try_sign_digest(&self, digest: D) -> Result<Signature, signature::Error> {
148 let hash = digest.finalize_fixed();
149 let ks = crate::generate::secret_number_rfc6979::<D>(self, &hash);
150
151 self.sign_prehashed(ks, &hash)
152 }
153}
154
155impl<D> RandomizedDigestSigner<D, Signature> for SigningKey
156where
157 D: Digest,
158{
159 fn try_sign_digest_with_rng(
160 &self,
161 mut rng: &mut impl CryptoRngCore,
162 digest: D,
163 ) -> Result<Signature, signature::Error> {
164 let ks = crate::generate::secret_number(&mut rng, self.verifying_key().components())
165 .ok_or_else(signature::Error::new)?;
166 let hash = digest.finalize();
167
168 self.sign_prehashed(ks, &hash)
169 }
170}
171
172impl EncodePrivateKey for SigningKey {
173 fn to_pkcs8_der(&self) -> pkcs8::Result<SecretDocument> {
174 let parameters = self.verifying_key().components().to_der()?;
175 let parameters = AnyRef::from_der(¶meters)?;
176 let algorithm = AlgorithmIdentifierRef {
177 oid: OID,
178 parameters: Some(parameters),
179 };
180
181 let mut x_bytes = self.x().to_bytes_be();
182 let x = UintRef::new(&x_bytes)?;
183 let mut signing_key = x.to_der()?;
184
185 let signing_key_info = PrivateKeyInfo::new(algorithm, &signing_key);
186 let secret_document = signing_key_info.try_into()?;
187
188 signing_key.zeroize();
189 x_bytes.zeroize();
190
191 Ok(secret_document)
192 }
193}
194
195impl<'a> TryFrom<PrivateKeyInfo<'a>> for SigningKey {
196 type Error = pkcs8::Error;
197
198 fn try_from(value: PrivateKeyInfo<'a>) -> Result<Self, Self::Error> {
199 value.algorithm.assert_algorithm_oid(OID)?;
200
201 let parameters = value.algorithm.parameters_any()?;
202 let components = parameters.decode_as::<Components>()?;
203
204 let x = UintRef::from_der(value.private_key)?;
205 let x = BigUint::from_bytes_be(x.as_bytes());
206
207 let y = if let Some(y_bytes) = value.public_key {
208 let y = UintRef::from_der(y_bytes)?;
209 BigUint::from_bytes_be(y.as_bytes())
210 } else {
211 crate::generate::public_component(&components, &x)
212 };
213
214 let verifying_key =
215 VerifyingKey::from_components(components, y).map_err(|_| pkcs8::Error::KeyMalformed)?;
216
217 SigningKey::from_components(verifying_key, x).map_err(|_| pkcs8::Error::KeyMalformed)
218 }
219}
220
221impl Debug for SigningKey {
222 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
223 f.debug_struct("SigningKey")
224 .field("verifying_key", &self.verifying_key)
225 .finish_non_exhaustive()
226 }
227}