use std::fmt;
use std::fmt::Debug;
use anyhow::Result;
#[cfg(feature = "serde")]
use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[cfg(feature = "serde")]
use serde::de::Error as SerdeError;
#[cfg(feature = "serde")]
use serde_bytes::{ByteBuf as SerdeByteBuf, Bytes as SerdeBytes};
use crate::{KeyPairSchema, PrivateKey, KEYPAIR_LENGTH, KEY_BYTES_SIZE, Signature, PublicKey, BlockCipher};
#[derive(Debug, Clone, Copy, PartialEq, Hash)]
pub struct Keypair<Kp: KeyPairSchema>(pub Kp);
impl<Kp: KeyPairSchema> Keypair<Kp> {
pub fn random() -> Self {
Self(<Kp>::random())
}
pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
let kp = <Kp>::from_bytes(bytes)?;
Ok(Self(kp))
}
pub fn from_hex_private_key<S: AsRef<str>>(hex: S) -> Result<Self> {
let kp = <Kp>::from_hex_private_key(hex)?;
Ok(Self(kp))
}
pub fn from_private_key(private_key: PrivateKey) -> Self {
let kp = <Kp>::from_private_key(private_key);
Self(kp)
}
pub fn to_bytes(&self) -> [u8; KEYPAIR_LENGTH] {
let mut bytes: [u8; KEYPAIR_LENGTH] = [0u8; KEYPAIR_LENGTH];
bytes[..KEY_BYTES_SIZE].copy_from_slice(self.0.private_key().as_bytes());
bytes[KEY_BYTES_SIZE..].copy_from_slice(self.0.public_key().as_bytes());
bytes
}
pub fn sign(&self, data: &[u8]) -> Signature {
self.0.sign(data)
}
pub fn verify(&self, data: &[u8], signature: Signature) -> Result<()> {
self.0.verify(data, signature)
}
pub fn private_key(&self) -> PrivateKey {
self.0.private_key()
}
pub fn public_key(&self) -> PublicKey {
self.0.public_key()
}
pub fn encrypt_message(
&self,
receiver_pk: &[u8; KEY_BYTES_SIZE],
msg: &[u8],
) -> Result<Vec<u8>> {
<Kp>::Crypto::encrypt_message(self.private_key().as_fixed_bytes(), receiver_pk, msg)
}
pub fn decrypt_message(
&self,
signer_pk: &[u8; KEY_BYTES_SIZE],
enc_msg: &[u8],
) -> Result<Vec<u8>> {
<Kp>::Crypto::decrypt_message(self.private_key().as_fixed_bytes(), signer_pk, enc_msg)
}
}
impl<C: KeyPairSchema> fmt::Display for Keypair<C> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{{public_key: {:x}}}", self.public_key())
}
}
#[cfg(feature = "serde")]
impl<C: KeyPairSchema> Serialize for Keypair<C> {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
{
let bytes = &self.to_bytes()[..];
SerdeBytes::new(bytes).serialize(serializer)
}
}
#[cfg(feature = "serde")]
impl<'d, C: KeyPairSchema> Deserialize<'d> for Keypair<C> {
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: Deserializer<'d>,
{
let bytes = <SerdeByteBuf>::deserialize(deserializer)?;
Keypair::from_bytes(bytes.as_ref()).map_err(SerdeError::custom)
}
}
impl<C: KeyPairSchema> AsRef<C> for Keypair<C> {
fn as_ref(&self) -> &C {
&self.0
}
}