antelope/chain/
private_key.rs

1use std::fmt::{Debug, Display, Formatter};
2
3use serde::{Deserialize, Serialize};
4
5use crate::{
6    base58::{decode_key, encode_check, encode_ripemd160_check},
7    chain::{
8        checksum::Checksum512, key_type::KeyType, public_key::PublicKey, signature::Signature,
9    },
10    crypto::{
11        generate::generate, get_public::get_public, shared_secrets::shared_secret, sign::sign,
12    },
13};
14
15#[derive(Default, Clone, Serialize, Deserialize)]
16pub struct PrivateKey {
17    pub key_type: KeyType,
18    value: Vec<u8>,
19}
20
21impl PrivateKey {
22    // TODO: should this be done via the ToString trait?
23    //   If so, should other structs also do that?
24    //   Also if so, should from on this and other structs use the From trait?
25    pub fn as_string(&self) -> String {
26        let type_str = self.key_type.to_string();
27        let encoded = encode_ripemd160_check(
28            self.value.to_vec(),
29            Option::from(self.key_type.to_string().as_str()),
30        );
31        format!("PVT_{type_str}_{encoded}")
32    }
33
34    pub fn to_bytes(&self) -> Vec<u8> {
35        self.value.to_vec()
36    }
37
38    pub fn to_hex(&self) -> String {
39        hex::encode(&self.value)
40    }
41
42    pub fn to_wif(&self) -> Result<String, String> {
43        if !matches!(self.key_type, KeyType::K1) {
44            return Err(String::from("Unable to generate WIF for non-k1 key"));
45        }
46        let mut to_encode = Vec::new();
47        to_encode.push(0x80);
48        to_encode.append(&mut self.value.to_vec());
49
50        Ok(encode_check(to_encode))
51    }
52
53    pub fn to_public(&self) -> PublicKey {
54        let compressed = get_public(self.value.to_vec(), self.key_type).unwrap();
55        PublicKey::from_bytes(compressed, self.key_type)
56    }
57
58    pub fn from_bytes(bytes: Vec<u8>, key_type: KeyType) -> Self {
59        PrivateKey {
60            key_type,
61            value: bytes,
62        }
63    }
64
65    pub fn from_str(key: &str, ignore_checksum: bool) -> Result<Self, String> {
66        let decode_result = decode_key(key, ignore_checksum);
67        if decode_result.is_err() {
68            let err_message = decode_result.err().unwrap_or(String::from("Unknown error"));
69            return Err(format!("Failed to decode private key: {err_message}"));
70        }
71
72        let decoded = decode_result.unwrap();
73        Ok(PrivateKey {
74            key_type: decoded.0,
75            value: decoded.1,
76        })
77    }
78
79    pub fn sign_message(&self, message: &Vec<u8>) -> Signature {
80        sign(self.value.to_vec(), message, self.key_type).unwrap()
81    }
82
83    pub fn shared_secret(&self, their_pub: &PublicKey) -> Checksum512 {
84        Checksum512::hash(shared_secret(&self.to_bytes(), &their_pub.value, self.key_type).unwrap())
85    }
86
87    pub fn random(key_type: KeyType) -> Result<Self, String> {
88        let secret_bytes = generate(key_type);
89        Ok(Self::from_bytes(secret_bytes.unwrap(), key_type))
90    }
91}
92
93impl Display for PrivateKey {
94    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
95        write!(f, "{}", self.as_string())
96    }
97}
98
99impl Debug for PrivateKey {
100    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
101        write!(f, "{}", self.as_string())
102    }
103}