use crate::{
hasher::Hasher,
secp256::SecretKey,
Error,
};
use core::{
fmt,
ops::Deref,
};
use k256::ecdsa::VerifyingKey;
use core::str;
use fuel_types::{
Bytes32,
Bytes64,
};
use k256::elliptic_curve::sec1::ToEncodedPoint;
#[derive(Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(transparent)]
pub struct PublicKey(Bytes64);
impl PublicKey {
pub const LEN: usize = Bytes64::LEN;
pub fn hash(&self) -> Bytes32 {
Hasher::hash(self.as_ref())
}
}
impl Deref for PublicKey {
type Target = [u8; PublicKey::LEN];
fn deref(&self) -> &[u8; PublicKey::LEN] {
self.0.deref()
}
}
impl AsRef<[u8]> for PublicKey {
fn as_ref(&self) -> &[u8] {
self.0.as_ref()
}
}
impl AsMut<[u8]> for PublicKey {
fn as_mut(&mut self) -> &mut [u8] {
self.0.as_mut()
}
}
impl From<PublicKey> for [u8; PublicKey::LEN] {
fn from(pk: PublicKey) -> [u8; PublicKey::LEN] {
pk.0.into()
}
}
impl fmt::LowerHex for PublicKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
impl fmt::UpperHex for PublicKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
impl fmt::Debug for PublicKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
}
}
impl fmt::Display for PublicKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
}
}
impl From<k256::PublicKey> for PublicKey {
fn from(key: k256::PublicKey) -> Self {
let point = key.to_encoded_point(false);
let mut raw = Bytes64::zeroed();
raw[..32].copy_from_slice(point.x().unwrap());
raw[32..].copy_from_slice(point.y().unwrap());
Self(raw)
}
}
impl From<&ecdsa::VerifyingKey<k256::Secp256k1>> for PublicKey {
fn from(vk: &ecdsa::VerifyingKey<k256::Secp256k1>) -> Self {
let vk: k256::PublicKey = vk.into();
vk.into()
}
}
#[cfg(feature = "std")]
impl From<secp256k1::PublicKey> for PublicKey {
fn from(key: secp256k1::PublicKey) -> Self {
let key_bytes = key.serialize_uncompressed();
let mut raw = Bytes64::zeroed();
raw.copy_from_slice(&key_bytes[1..]);
Self(raw)
}
}
impl TryFrom<Bytes64> for PublicKey {
type Error = Error;
fn try_from(b: Bytes64) -> Result<Self, Self::Error> {
match VerifyingKey::from_sec1_bytes(&*b) {
Ok(_) => Ok(Self(b)),
Err(_) => Err(Error::InvalidPublicKey),
}
}
}
impl TryFrom<&[u8]> for PublicKey {
type Error = Error;
fn try_from(slice: &[u8]) -> Result<Self, Self::Error> {
Bytes64::try_from(slice)
.map_err(|_| Error::InvalidPublicKey)
.and_then(PublicKey::try_from)
}
}
impl From<&SecretKey> for PublicKey {
fn from(s: &SecretKey) -> PublicKey {
s.public_key()
}
}
impl str::FromStr for PublicKey {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Bytes64::from_str(s)
.map_err(|_| Error::InvalidPublicKey)
.and_then(PublicKey::try_from)
}
}