use std::fmt::{self, Display};
use sha2::{digest::Digest, Sha256};
use tendermint::{error::Error, node};
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum PublicKey {
Ed25519(ed25519_consensus::VerificationKey),
}
impl PublicKey {
pub fn from_raw_ed25519(bytes: &[u8]) -> Result<Self, Error> {
ed25519_consensus::VerificationKey::try_from(bytes)
.map(Self::Ed25519)
.map_err(|_| Error::signature())
}
#[must_use]
pub const fn ed25519(self) -> Option<ed25519_consensus::VerificationKey> {
match self {
Self::Ed25519(pk) => Some(pk),
}
}
#[must_use]
pub fn peer_id(self) -> node::Id {
match self {
Self::Ed25519(pk) => {
let digest = Sha256::digest(pk.as_bytes());
let mut bytes = [0_u8; 20];
bytes.copy_from_slice(&digest[..20]);
node::Id::new(bytes)
},
}
}
}
impl Display for PublicKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.peer_id())
}
}
impl From<&ed25519_consensus::SigningKey> for PublicKey {
fn from(sk: &ed25519_consensus::SigningKey) -> Self {
Self::Ed25519(sk.verification_key())
}
}
impl From<ed25519_consensus::VerificationKey> for PublicKey {
fn from(pk: ed25519_consensus::VerificationKey) -> Self {
Self::Ed25519(pk)
}
}