use crate::Error;
use base64::Engine;
use base64::engine::general_purpose;
use serde::Serialize;
use std::fmt;
use std::ops::Deref;
use std::str::FromStr;
use nym_crypto::asymmetric::x25519;
use x25519_dalek::PublicKey;
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub struct PeerPublicKey(PublicKey);
impl From<x25519::PublicKey> for PeerPublicKey {
fn from(pk: x25519::PublicKey) -> Self {
PeerPublicKey(pk.into())
}
}
impl From<&x25519::PublicKey> for PeerPublicKey {
fn from(pk: &x25519::PublicKey) -> Self {
(*pk).into()
}
}
impl PeerPublicKey {
pub fn new(key: PublicKey) -> Self {
PeerPublicKey(key)
}
pub fn as_bytes(&self) -> &[u8] {
self.0.as_bytes()
}
pub fn inner(&self) -> PublicKey {
self.0
}
}
impl From<PublicKey> for PeerPublicKey {
fn from(key: PublicKey) -> Self {
PeerPublicKey::new(key)
}
}
impl fmt::Display for PeerPublicKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", general_purpose::STANDARD.encode(self.0.as_bytes()))
}
}
impl Deref for PeerPublicKey {
type Target = PublicKey;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl FromStr for PeerPublicKey {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let key_bytes: Vec<u8> = general_purpose::STANDARD.decode(s).map_err(|source| {
Error::MalformedPeerPublicKeyEncoding {
pub_key: s.to_string(),
source,
}
})?;
let decoded_length = key_bytes.len();
let Ok(key_arr): Result<[u8; 32], _> = key_bytes.try_into() else {
return Err(Error::InvalidPeerPublicKeyLength {
pub_key: s.to_string(),
decoded_length,
})?;
};
Ok(PeerPublicKey(PublicKey::from(key_arr)))
}
}
impl Serialize for PeerPublicKey {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let encoded_key = general_purpose::STANDARD.encode(self.0.as_bytes());
serializer.serialize_str(&encoded_key)
}
}
impl<'de> serde::Deserialize<'de> for PeerPublicKey {
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let encoded_key = String::deserialize(deserializer)?;
Ok(PeerPublicKey::from_str(&encoded_key).map_err(serde::de::Error::custom))?
}
}