use serde::{Deserialize, Serialize};
use crate::Group;
#[derive(PartialEq, Eq, Clone)]
pub struct PublicKey<G: Group> {
pub(crate) p: G::P,
}
impl<G: Group> PublicKey<G> {
#[inline]
pub fn element(&self) -> &G::P {
&self.p
}
}
impl<G: Group> Serialize for PublicKey<G> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
Vec::<u8>::from(self).serialize(serializer)
}
}
impl<'de, G: Group> Deserialize<'de> for PublicKey<G> {
fn deserialize<D>(deserializer: D) -> Result<PublicKey<G>, D::Error>
where
D: serde::Deserializer<'de>,
{
let bytes: Vec<u8> = Deserialize::deserialize(deserializer)?;
PublicKey::try_from(bytes.as_slice())
.map_err(|_| serde::de::Error::custom("Invalid public key"))
}
}
impl<G: Group> From<&PublicKey<G>> for Vec<u8> {
fn from(public_key: &PublicKey<G>) -> Self {
G::serialize_point(&public_key.p)
}
}
impl<G: Group> TryFrom<&[u8]> for PublicKey<G> {
type Error = ();
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
let p = G::deserialize_point(value).map_err(|_| ())?;
Ok(PublicKey { p })
}
}
#[test]
fn test_public_key_serialization() {
let rng = &mut rand::thread_rng();
let group = crate::group::p256::SchnorrP256Group;
let pk = PublicKey::<crate::group::p256::SchnorrP256Group> {
p: group.random_element(rng),
};
let serialized = bincode::serde::encode_to_vec(&pk, bincode::config::legacy()).unwrap();
let (deserialized, _): (PublicKey<crate::group::p256::SchnorrP256Group>, _) =
bincode::serde::decode_from_slice(&serialized, bincode::config::legacy()).unwrap();
assert_eq!(pk.p, deserialized.p);
let pk_bytes: Vec<u8> = (&pk).into();
let deserialized_from_bytes: PublicKey<crate::group::p256::SchnorrP256Group> =
PublicKey::try_from(pk_bytes.as_slice()).unwrap();
assert!(pk == deserialized_from_bytes);
}