use crate::{ generic_public_key::{GenericPublicKey, TPublicKey}, Error, PUBLIC_KEY_BYTES_LEN, }; use serde::de::{Deserialize, Deserializer}; use serde::ser::{Serialize, Serializer}; use serde_utils::hex::encode as hex_encode; use ssz::{Decode, Encode}; use std::convert::TryInto; use std::fmt; use std::hash::{Hash, Hasher}; use std::marker::PhantomData; use tree_hash::TreeHash; /// A wrapper around some bytes that may or may not be a `PublicKey` in compressed form. /// /// This struct is useful for two things: /// /// - Lazily verifying a serialized public key. /// - Storing some bytes that are actually invalid (required in the case of a `Deposit` message). #[derive(Clone)] pub struct GenericPublicKeyBytes { bytes: [u8; PUBLIC_KEY_BYTES_LEN], _phantom: PhantomData, } impl GenericPublicKeyBytes where Pub: TPublicKey, { /// Decompress and deserialize the bytes in `self` into an actual public key. /// /// May fail if the bytes are invalid. pub fn decompress(&self) -> Result, Error> { GenericPublicKey::deserialize(&self.bytes) } } impl GenericPublicKeyBytes { /// Instantiates `Self` with all-zeros. pub fn empty() -> Self { Self { bytes: [0; PUBLIC_KEY_BYTES_LEN], _phantom: PhantomData, } } /// Returns a slice of the bytes contained in `self`. /// /// The bytes are not verified (i.e., they may not represent a valid BLS point). pub fn as_serialized(&self) -> &[u8] { &self.bytes } /// Clones the bytes in `self`. /// /// The bytes are not verified (i.e., they may not represent a valid BLS point). pub fn serialize(&self) -> [u8; PUBLIC_KEY_BYTES_LEN] { self.bytes } /// Instantiates `Self` from bytes. /// /// The bytes are not fully verified (i.e., they may not represent a valid BLS point). Only the /// byte-length is checked. pub fn deserialize(bytes: &[u8]) -> Result { if bytes.len() == PUBLIC_KEY_BYTES_LEN { let mut pk_bytes = [0; PUBLIC_KEY_BYTES_LEN]; pk_bytes[..].copy_from_slice(bytes); Ok(Self { bytes: pk_bytes, _phantom: PhantomData, }) } else { Err(Error::InvalidByteLength { got: bytes.len(), expected: PUBLIC_KEY_BYTES_LEN, }) } } } impl Eq for GenericPublicKeyBytes {} impl PartialEq for GenericPublicKeyBytes { fn eq(&self, other: &Self) -> bool { self.bytes[..] == other.bytes[..] } } impl Hash for GenericPublicKeyBytes { fn hash(&self, state: &mut H) { self.bytes[..].hash(state); } } /// Serializes the `PublicKey` in compressed form, storing the bytes in the newly created `Self`. impl From> for GenericPublicKeyBytes where Pub: TPublicKey, { fn from(pk: GenericPublicKey) -> Self { Self::from(&pk) } } /// Serializes the `PublicKey` in compressed form, storing the bytes in the newly created `Self`. impl From<&GenericPublicKey> for GenericPublicKeyBytes where Pub: TPublicKey, { fn from(pk: &GenericPublicKey) -> Self { Self { bytes: pk.serialize(), _phantom: PhantomData, } } } /// Alias to `self.decompress()`. impl TryInto> for &GenericPublicKeyBytes where Pub: TPublicKey, { type Error = Error; fn try_into(self) -> Result, Self::Error> { self.decompress() } } impl Encode for GenericPublicKeyBytes { impl_ssz_encode!(PUBLIC_KEY_BYTES_LEN); } impl Decode for GenericPublicKeyBytes { impl_ssz_decode!(PUBLIC_KEY_BYTES_LEN); } impl TreeHash for GenericPublicKeyBytes { impl_tree_hash!(PUBLIC_KEY_BYTES_LEN); } impl fmt::Display for GenericPublicKeyBytes { impl_display!(); } impl std::str::FromStr for GenericPublicKeyBytes { impl_from_str!(); } impl Serialize for GenericPublicKeyBytes { impl_serde_serialize!(); } impl<'de, Pub> Deserialize<'de> for GenericPublicKeyBytes { impl_serde_deserialize!(); } impl fmt::Debug for GenericPublicKeyBytes { impl_debug!(); } #[cfg(feature = "arbitrary")] impl arbitrary::Arbitrary for GenericPublicKeyBytes { impl_arbitrary!(PUBLIC_KEY_BYTES_LEN); }