1use super::{tagged_hash, Signature, VerifyingKey, AUX_TAG, CHALLENGE_TAG, NONCE_TAG};
4use crate::{
5 AffinePoint, FieldBytes, NonZeroScalar, ProjectivePoint, PublicKey, Scalar, SecretKey,
6};
7use elliptic_curve::{
8 bigint::U256,
9 ops::Reduce,
10 rand_core::CryptoRngCore,
11 subtle::ConditionallySelectable,
12 zeroize::{Zeroize, ZeroizeOnDrop},
13};
14use sha2::{Digest, Sha256};
15use signature::{
16 digest::{consts::U32, FixedOutput},
17 hazmat::{PrehashSigner, RandomizedPrehashSigner},
18 DigestSigner, Error, KeypairRef, RandomizedDigestSigner, RandomizedSigner, Result, Signer,
19};
20
21#[cfg(feature = "serde")]
22use serdect::serde::{de, ser, Deserialize, Serialize};
23
24#[cfg(debug_assertions)]
25use signature::hazmat::PrehashVerifier;
26
27#[derive(Clone)]
29pub struct SigningKey {
30 secret_key: NonZeroScalar,
32
33 verifying_key: VerifyingKey,
35}
36
37impl SigningKey {
38 pub fn random(rng: &mut impl CryptoRngCore) -> Self {
40 NonZeroScalar::random(rng).into()
41 }
42
43 pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
45 NonZeroScalar::try_from(bytes)
46 .map(Into::into)
47 .map_err(|_| Error::new())
48 }
49
50 pub fn to_bytes(&self) -> FieldBytes {
52 self.secret_key.to_bytes()
53 }
54
55 pub fn verifying_key(&self) -> &VerifyingKey {
57 &self.verifying_key
58 }
59
60 pub fn as_nonzero_scalar(&self) -> &NonZeroScalar {
68 &self.secret_key
69 }
70
71 pub fn sign_prehash_with_aux_rand(
80 &self,
81 msg_digest: &[u8; 32],
82 aux_rand: &[u8; 32],
83 ) -> Result<Signature> {
84 self.sign_raw(&msg_digest[..], &aux_rand)
85 }
86
87 pub fn sign_raw(&self, msg: &[u8], aux_rand: &[u8; 32]) -> Result<Signature> {
98 let mut t = tagged_hash(AUX_TAG).chain_update(aux_rand).finalize();
99
100 for (a, b) in t.iter_mut().zip(self.secret_key.to_bytes().iter()) {
101 *a ^= b
102 }
103
104 let rand = tagged_hash(NONCE_TAG)
105 .chain_update(t)
106 .chain_update(self.verifying_key.as_affine().x.to_bytes())
107 .chain_update(msg)
108 .finalize();
109
110 let k = NonZeroScalar::try_from(&*rand)
111 .map(Self::from)
112 .map_err(|_| Error::new())?;
113
114 let secret_key = k.secret_key;
115 let verifying_point = AffinePoint::from(k.verifying_key);
116 let r = verifying_point.x.normalize();
117
118 let e = <Scalar as Reduce<U256>>::reduce_bytes(
119 &tagged_hash(CHALLENGE_TAG)
120 .chain_update(r.to_bytes())
121 .chain_update(self.verifying_key.to_bytes())
122 .chain_update(msg)
123 .finalize(),
124 );
125
126 let s = *secret_key + e * *self.secret_key;
127 let s = Option::from(NonZeroScalar::new(s)).ok_or_else(Error::new)?;
128 let sig = Signature { r, s };
129
130 #[cfg(debug_assertions)]
131 self.verifying_key.verify_prehash(msg, &sig)?;
132
133 Ok(sig)
134 }
135}
136
137impl From<NonZeroScalar> for SigningKey {
138 #[inline]
139 fn from(mut secret_key: NonZeroScalar) -> SigningKey {
140 let odd = (ProjectivePoint::GENERATOR * *secret_key)
141 .to_affine()
142 .y
143 .normalize()
144 .is_odd();
145
146 secret_key.conditional_assign(&-secret_key, odd);
147
148 let verifying_key = VerifyingKey {
149 inner: PublicKey::from_secret_scalar(&secret_key),
150 };
151
152 SigningKey {
153 secret_key,
154 verifying_key,
155 }
156 }
157}
158
159impl From<SecretKey> for SigningKey {
160 #[inline]
161 fn from(secret_key: SecretKey) -> SigningKey {
162 SigningKey::from(&secret_key)
163 }
164}
165
166impl From<&SecretKey> for SigningKey {
167 fn from(secret_key: &SecretKey) -> SigningKey {
168 secret_key.to_nonzero_scalar().into()
169 }
170}
171
172impl<D> DigestSigner<D, Signature> for SigningKey
177where
178 D: Digest + FixedOutput<OutputSize = U32>,
179{
180 fn try_sign_digest(&self, digest: D) -> Result<Signature> {
181 self.sign_raw(&digest.finalize_fixed(), &Default::default())
182 }
183}
184
185impl PrehashSigner<Signature> for SigningKey {
186 fn sign_prehash(&self, prehash: &[u8]) -> Result<Signature> {
187 self.sign_raw(prehash, &Default::default())
188 }
189}
190
191impl<D> RandomizedDigestSigner<D, Signature> for SigningKey
192where
193 D: Digest + FixedOutput<OutputSize = U32>,
194{
195 fn try_sign_digest_with_rng(
196 &self,
197 rng: &mut impl CryptoRngCore,
198 digest: D,
199 ) -> Result<Signature> {
200 let mut aux_rand = [0u8; 32];
201 rng.fill_bytes(&mut aux_rand);
202 self.sign_raw(&digest.finalize_fixed(), &aux_rand)
203 }
204}
205
206impl RandomizedSigner<Signature> for SigningKey {
207 fn try_sign_with_rng(&self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> Result<Signature> {
208 self.try_sign_digest_with_rng(rng, Sha256::new_with_prefix(msg))
209 }
210}
211
212impl RandomizedPrehashSigner<Signature> for SigningKey {
213 fn sign_prehash_with_rng(
214 &self,
215 rng: &mut impl CryptoRngCore,
216 prehash: &[u8],
217 ) -> Result<Signature> {
218 let mut aux_rand = [0u8; 32];
219 rng.fill_bytes(&mut aux_rand);
220
221 self.sign_raw(prehash, &aux_rand)
222 }
223}
224
225impl Signer<Signature> for SigningKey {
226 fn try_sign(&self, msg: &[u8]) -> Result<Signature> {
227 self.try_sign_digest(Sha256::new_with_prefix(msg))
228 }
229}
230
231impl AsRef<VerifyingKey> for SigningKey {
236 fn as_ref(&self) -> &VerifyingKey {
237 &self.verifying_key
238 }
239}
240
241impl Drop for SigningKey {
242 fn drop(&mut self) {
243 self.secret_key.zeroize();
244 }
245}
246
247impl KeypairRef for SigningKey {
248 type VerifyingKey = VerifyingKey;
249}
250
251impl ZeroizeOnDrop for SigningKey {}
252
253#[cfg(feature = "serde")]
254impl Serialize for SigningKey {
255 fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
256 where
257 S: ser::Serializer,
258 {
259 self.secret_key.serialize(serializer)
260 }
261}
262
263#[cfg(feature = "serde")]
264impl<'de> Deserialize<'de> for SigningKey {
265 fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
266 where
267 D: de::Deserializer<'de>,
268 {
269 Ok(SigningKey::from(NonZeroScalar::deserialize(deserializer)?))
270 }
271}