cardano_serialization_lib/chain_crypto/
key.rs1use crate::chain_crypto::bech32::{self, Bech32};
2use hex::FromHexError;
3use rand_os::rand_core::{CryptoRng, RngCore};
4use std::fmt;
5use std::hash::Hash;
6use std::str::FromStr;
7
8#[derive(Debug, Copy, Clone, PartialEq, Eq)]
9pub enum SecretKeyError {
10 SizeInvalid,
11 StructureInvalid,
12}
13
14#[derive(Debug, Copy, Clone, PartialEq, Eq)]
15pub enum PublicKeyError {
16 SizeInvalid,
17 StructureInvalid,
18}
19
20#[derive(Debug, Clone, PartialEq)]
21pub enum PublicKeyFromStrError {
22 HexMalformed(FromHexError),
23 KeyInvalid(PublicKeyError),
24}
25
26pub trait AsymmetricPublicKey {
27 type Public: AsRef<[u8]> + Clone + PartialEq + Eq + Hash;
28 const PUBLIC_BECH32_HRP: &'static str;
29 const PUBLIC_KEY_SIZE: usize;
30
31 fn public_from_binary(data: &[u8]) -> Result<Self::Public, PublicKeyError>;
32}
33
34pub trait AsymmetricKey {
35 type PubAlg: AsymmetricPublicKey;
38
39 type Secret: AsRef<[u8]> + Clone;
41
42 const SECRET_BECH32_HRP: &'static str;
43
44 fn generate<T: RngCore + CryptoRng>(rng: T) -> Self::Secret;
45 fn compute_public(secret: &Self::Secret) -> <Self::PubAlg as AsymmetricPublicKey>::Public;
46 fn secret_from_binary(data: &[u8]) -> Result<Self::Secret, SecretKeyError>;
47}
48
49pub trait SecretKeySizeStatic: AsymmetricKey {
50 const SECRET_KEY_SIZE: usize;
51}
52
53pub struct SecretKey<A: AsymmetricKey>(pub(crate) A::Secret);
54
55pub struct PublicKey<A: AsymmetricPublicKey>(pub(crate) A::Public);
56
57pub struct KeyPair<A: AsymmetricKey>(SecretKey<A>, PublicKey<A::PubAlg>);
58
59impl<A: AsymmetricKey> KeyPair<A> {
60 pub fn private_key(&self) -> &SecretKey<A> {
61 &self.0
62 }
63 pub fn public_key(&self) -> &PublicKey<A::PubAlg> {
64 &self.1
65 }
66 pub fn into_keys(self) -> (SecretKey<A>, PublicKey<A::PubAlg>) {
67 (self.0, self.1)
68 }
69 pub fn generate<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
70 let sk = A::generate(rng);
71 let pk = A::compute_public(&sk);
72 KeyPair(SecretKey(sk), PublicKey(pk))
73 }
74}
75impl<A: AsymmetricKey> std::fmt::Debug for KeyPair<A> {
76 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
77 write!(f, "KeyPair(<secret key>, {:?})", self.public_key())
78 }
79}
80impl<A: AsymmetricKey> std::fmt::Display for KeyPair<A> {
81 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
82 write!(f, "KeyPair(<secret key>, {})", self.public_key())
83 }
84}
85
86impl<A: AsymmetricPublicKey> fmt::Debug for PublicKey<A> {
87 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
88 write!(f, "{}", hex::encode(self.0.as_ref()))
89 }
90}
91impl<A: AsymmetricPublicKey> fmt::Display for PublicKey<A> {
92 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
93 write!(f, "{}", hex::encode(self.0.as_ref()))
94 }
95}
96
97impl<A: AsymmetricPublicKey> FromStr for PublicKey<A> {
98 type Err = PublicKeyFromStrError;
99
100 fn from_str(hex: &str) -> Result<Self, Self::Err> {
101 let bytes = hex::decode(hex).map_err(PublicKeyFromStrError::HexMalformed)?;
102 Self::from_binary(&bytes).map_err(PublicKeyFromStrError::KeyInvalid)
103 }
104}
105
106impl fmt::Display for SecretKeyError {
107 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
108 match self {
109 SecretKeyError::SizeInvalid => write!(f, "Invalid Secret Key size"),
110 SecretKeyError::StructureInvalid => write!(f, "Invalid Secret Key structure"),
111 }
112 }
113}
114
115impl fmt::Display for PublicKeyError {
116 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
117 match self {
118 PublicKeyError::SizeInvalid => write!(f, "Invalid Public Key size"),
119 PublicKeyError::StructureInvalid => write!(f, "Invalid Public Key structure"),
120 }
121 }
122}
123
124impl fmt::Display for PublicKeyFromStrError {
125 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
126 match self {
127 PublicKeyFromStrError::HexMalformed(_) => "hex encoding malformed",
128 PublicKeyFromStrError::KeyInvalid(_) => "invalid public key data",
129 }
130 .fmt(f)
131 }
132}
133
134impl std::error::Error for SecretKeyError {}
135
136impl std::error::Error for PublicKeyError {}
137
138impl std::error::Error for PublicKeyFromStrError {
139 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
140 match self {
141 PublicKeyFromStrError::HexMalformed(e) => Some(e),
142 PublicKeyFromStrError::KeyInvalid(e) => Some(e),
143 }
144 }
145}
146
147impl<A: AsymmetricPublicKey> AsRef<[u8]> for PublicKey<A> {
148 fn as_ref(&self) -> &[u8] {
149 self.0.as_ref()
150 }
151}
152
153impl<A: AsymmetricKey> AsRef<[u8]> for SecretKey<A> {
154 fn as_ref(&self) -> &[u8] {
155 self.0.as_ref()
156 }
157}
158
159impl<A: AsymmetricKey> From<SecretKey<A>> for KeyPair<A> {
160 fn from(secret_key: SecretKey<A>) -> Self {
161 let public_key = secret_key.to_public();
162 KeyPair(secret_key, public_key)
163 }
164}
165
166impl<A: AsymmetricKey> SecretKey<A> {
167 pub fn generate<T: RngCore + CryptoRng>(rng: T) -> Self {
168 SecretKey(A::generate(rng))
169 }
170 pub fn to_public(&self) -> PublicKey<A::PubAlg> {
171 PublicKey(<A as AsymmetricKey>::compute_public(&self.0))
172 }
173 pub fn from_binary(data: &[u8]) -> Result<Self, SecretKeyError> {
174 Ok(SecretKey(<A as AsymmetricKey>::secret_from_binary(data)?))
175 }
176}
177
178impl<A: AsymmetricPublicKey> PublicKey<A> {
179 pub fn from_binary(data: &[u8]) -> Result<Self, PublicKeyError> {
180 Ok(PublicKey(<A as AsymmetricPublicKey>::public_from_binary(
181 data,
182 )?))
183 }
184}
185
186impl<A: AsymmetricKey> Clone for SecretKey<A> {
187 fn clone(&self) -> Self {
188 SecretKey(self.0.clone())
189 }
190}
191impl<A: AsymmetricPublicKey> Clone for PublicKey<A> {
192 fn clone(&self) -> Self {
193 PublicKey(self.0.clone())
194 }
195}
196impl<A: AsymmetricKey> Clone for KeyPair<A> {
197 fn clone(&self) -> Self {
198 KeyPair(self.0.clone(), self.1.clone())
199 }
200}
201
202impl<A: AsymmetricPublicKey> std::cmp::PartialEq<Self> for PublicKey<A> {
203 fn eq(&self, other: &Self) -> bool {
204 self.0.as_ref().eq(other.0.as_ref())
205 }
206}
207
208impl<A: AsymmetricPublicKey> std::cmp::Eq for PublicKey<A> {}
209
210impl<A: AsymmetricPublicKey> std::cmp::PartialOrd<Self> for PublicKey<A> {
211 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
212 self.0.as_ref().partial_cmp(other.0.as_ref())
213 }
214}
215
216impl<A: AsymmetricPublicKey> std::cmp::Ord for PublicKey<A> {
217 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
218 self.0.as_ref().cmp(other.0.as_ref())
219 }
220}
221
222impl<A: AsymmetricPublicKey> Hash for PublicKey<A> {
223 fn hash<H>(&self, state: &mut H)
224 where
225 H: std::hash::Hasher,
226 {
227 self.0.as_ref().hash(state)
228 }
229}
230
231impl<A: AsymmetricPublicKey> Bech32 for PublicKey<A> {
232 const BECH32_HRP: &'static str = A::PUBLIC_BECH32_HRP;
233
234 fn try_from_bech32_str(bech32_str: &str) -> Result<Self, bech32::Error> {
235 let bytes = bech32::try_from_bech32_to_bytes::<Self>(bech32_str)?;
236 Self::from_binary(&bytes).map_err(bech32::Error::data_invalid)
237 }
238
239 fn to_bech32_str(&self) -> String {
240 bech32::to_bech32_from_bytes::<Self>(self.as_ref())
241 }
242}
243
244impl<A: AsymmetricKey> Bech32 for SecretKey<A> {
245 const BECH32_HRP: &'static str = A::SECRET_BECH32_HRP;
246
247 fn try_from_bech32_str(bech32_str: &str) -> Result<Self, bech32::Error> {
248 let bytes = bech32::try_from_bech32_to_bytes::<Self>(bech32_str)?;
249 Self::from_binary(&bytes).map_err(bech32::Error::data_invalid)
250 }
251
252 fn to_bech32_str(&self) -> String {
253 bech32::to_bech32_from_bytes::<Self>(self.0.as_ref())
254 }
255}
256
257#[cfg(test)]
258mod test {
259 use super::*;
260
261 impl<A> std::fmt::Debug for SecretKey<A>
263 where
264 A: AsymmetricKey,
265 {
266 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
267 write!(f, "SecretKey ({:?})", self.0.as_ref())
268 }
269 }
270}