veilid_core/crypto/types/
keypair.rs

1use super::*;
2
3#[derive(Clone, Copy, Default, PartialOrd, Ord, PartialEq, Eq, Hash)]
4#[must_use]
5pub struct KeyPair {
6    pub key: PublicKey,
7    pub secret: SecretKey,
8}
9
10cfg_if::cfg_if! {
11    if #[cfg(all(target_arch = "wasm32", target_os = "unknown"))] {
12        #[wasm_bindgen(typescript_custom_section)]
13        const KEYPAIR_TYPE: &'static str = r#"
14export type KeyPair = `${PublicKey}:${SecretKey}`;
15"#;
16    }
17}
18
19impl KeyPair {
20    pub fn new(key: PublicKey, secret: SecretKey) -> Self {
21        Self { key, secret }
22    }
23    pub fn split(&self) -> (PublicKey, SecretKey) {
24        (self.key, self.secret)
25    }
26    pub fn into_split(self) -> (PublicKey, SecretKey) {
27        (self.key, self.secret)
28    }
29}
30
31impl Encodable for KeyPair {
32    fn encode(&self) -> String {
33        format!("{}:{}", self.key.encode(), self.secret.encode())
34    }
35    fn encoded_len() -> usize {
36        PublicKey::encoded_len() + 1 + SecretKey::encoded_len()
37    }
38    fn try_decode_bytes(b: &[u8]) -> VeilidAPIResult<Self> {
39        if b.len() != Self::encoded_len() {
40            apibail_parse_error!("input has wrong encoded length", format!("len={}", b.len()));
41        }
42        let key = PublicKey::try_decode_bytes(&b[0..PublicKey::encoded_len()])?;
43        let secret = SecretKey::try_decode_bytes(&b[(PublicKey::encoded_len() + 1)..])?;
44        Ok(KeyPair { key, secret })
45    }
46}
47impl fmt::Display for KeyPair {
48    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49        write!(f, "{}", self.encode())
50    }
51}
52
53impl fmt::Debug for KeyPair {
54    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55        write!(f, "KeyPair({})", self.encode())
56    }
57}
58
59impl From<&KeyPair> for String {
60    fn from(value: &KeyPair) -> Self {
61        value.encode()
62    }
63}
64
65impl FromStr for KeyPair {
66    type Err = VeilidAPIError;
67
68    fn from_str(s: &str) -> Result<Self, Self::Err> {
69        KeyPair::try_from(s)
70    }
71}
72
73impl TryFrom<String> for KeyPair {
74    type Error = VeilidAPIError;
75    fn try_from(value: String) -> Result<Self, Self::Error> {
76        KeyPair::try_from(value.as_str())
77    }
78}
79
80impl TryFrom<&str> for KeyPair {
81    type Error = VeilidAPIError;
82    fn try_from(value: &str) -> Result<Self, Self::Error> {
83        Self::try_decode(value)
84    }
85}
86
87impl serde::Serialize for KeyPair {
88    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
89    where
90        S: serde::Serializer,
91    {
92        let s = self.encode();
93        serde::Serialize::serialize(&s, serializer)
94    }
95}
96
97impl<'de> serde::Deserialize<'de> for KeyPair {
98    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
99    where
100        D: serde::Deserializer<'de>,
101    {
102        let s = <String as serde::Deserialize>::deserialize(deserializer)?;
103        if s.is_empty() {
104            return Ok(KeyPair::default());
105        }
106        KeyPair::try_decode(s.as_str()).map_err(serde::de::Error::custom)
107    }
108}