fuel_crypto/secp256/
public.rs

1use crate::{
2    hasher::Hasher,
3    secp256::SecretKey,
4    Error,
5};
6use core::{
7    fmt,
8    ops::Deref,
9};
10
11use k256::ecdsa::VerifyingKey;
12
13use core::str;
14
15use fuel_types::{
16    Bytes32,
17    Bytes64,
18};
19use k256::elliptic_curve::sec1::ToEncodedPoint;
20
21/// Asymmetric secp256k1 public key, i.e. verifying key, in uncompressed form.
22/// <https://github.com/FuelLabs/fuel-specs/blob/master/src/protocol/cryptographic-primitives.md#ecdsa-public-key-cryptography>
23#[derive(Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
24#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
25#[repr(transparent)]
26pub struct PublicKey(Bytes64);
27
28impl PublicKey {
29    /// Memory length of the type in bytes.
30    pub const LEN: usize = Bytes64::LEN;
31
32    /// Cryptographic hash of the public key.
33    pub fn hash(&self) -> Bytes32 {
34        Hasher::hash(self.as_ref())
35    }
36}
37
38impl Deref for PublicKey {
39    type Target = [u8; PublicKey::LEN];
40
41    fn deref(&self) -> &[u8; PublicKey::LEN] {
42        self.0.deref()
43    }
44}
45
46impl AsRef<[u8]> for PublicKey {
47    fn as_ref(&self) -> &[u8] {
48        self.0.as_ref()
49    }
50}
51
52impl AsMut<[u8]> for PublicKey {
53    fn as_mut(&mut self) -> &mut [u8] {
54        self.0.as_mut()
55    }
56}
57
58impl From<PublicKey> for [u8; PublicKey::LEN] {
59    fn from(pk: PublicKey) -> [u8; PublicKey::LEN] {
60        pk.0.into()
61    }
62}
63
64impl fmt::LowerHex for PublicKey {
65    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66        self.0.fmt(f)
67    }
68}
69
70impl fmt::UpperHex for PublicKey {
71    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72        self.0.fmt(f)
73    }
74}
75
76impl fmt::Debug for PublicKey {
77    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
78        self.0.fmt(f)
79    }
80}
81
82impl fmt::Display for PublicKey {
83    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
84        self.0.fmt(f)
85    }
86}
87
88impl From<k256::PublicKey> for PublicKey {
89    fn from(key: k256::PublicKey) -> Self {
90        let point = key.to_encoded_point(false);
91        let mut raw = Bytes64::zeroed();
92        raw[..32].copy_from_slice(point.x().unwrap());
93        raw[32..].copy_from_slice(point.y().unwrap());
94        Self(raw)
95    }
96}
97
98impl From<&ecdsa::VerifyingKey<k256::Secp256k1>> for PublicKey {
99    fn from(vk: &ecdsa::VerifyingKey<k256::Secp256k1>) -> Self {
100        let vk: k256::PublicKey = vk.into();
101        vk.into()
102    }
103}
104
105#[cfg(feature = "std")]
106impl From<secp256k1::PublicKey> for PublicKey {
107    fn from(key: secp256k1::PublicKey) -> Self {
108        let key_bytes = key.serialize_uncompressed();
109        let mut raw = Bytes64::zeroed();
110        // Remove leading identifier byte
111        raw.copy_from_slice(&key_bytes[1..]);
112        Self(raw)
113    }
114}
115
116impl TryFrom<Bytes64> for PublicKey {
117    type Error = Error;
118
119    fn try_from(b: Bytes64) -> Result<Self, Self::Error> {
120        match VerifyingKey::from_sec1_bytes(&*b) {
121            Ok(_) => Ok(Self(b)),
122            Err(_) => Err(Error::InvalidPublicKey),
123        }
124    }
125}
126
127impl TryFrom<&[u8]> for PublicKey {
128    type Error = Error;
129
130    fn try_from(slice: &[u8]) -> Result<Self, Self::Error> {
131        Bytes64::try_from(slice)
132            .map_err(|_| Error::InvalidPublicKey)
133            .and_then(PublicKey::try_from)
134    }
135}
136
137impl From<&SecretKey> for PublicKey {
138    fn from(s: &SecretKey) -> PublicKey {
139        s.public_key()
140    }
141}
142
143impl str::FromStr for PublicKey {
144    type Err = Error;
145
146    fn from_str(s: &str) -> Result<Self, Self::Err> {
147        Bytes64::from_str(s)
148            .map_err(|_| Error::InvalidPublicKey)
149            .and_then(PublicKey::try_from)
150    }
151}