radix_common/crypto/secp256k1/
public_key.rs

1use crate::internal_prelude::*;
2
3/// Represents an uncompressed ECDSA Secp256k1 public key.
4#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
5#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Sbor)]
6#[sbor(transparent)]
7pub struct Secp256k1UncompressedPublicKey(
8    #[cfg_attr(feature = "serde", serde(with = "hex::serde"))] pub [u8; Self::LENGTH],
9);
10
11impl Secp256k1UncompressedPublicKey {
12    pub const LENGTH: usize = 65;
13}
14
15/// Represents a compressed ECDSA Secp256k1 public key, which is the default format used in the Radix stack.
16#[cfg_attr(feature = "fuzzing", derive(::arbitrary::Arbitrary))]
17#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
18#[derive(
19    Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Categorize, Encode, Decode, BasicDescribe,
20)]
21#[sbor(transparent)]
22pub struct Secp256k1PublicKey(
23    #[cfg_attr(feature = "serde", serde(with = "hex::serde"))] pub [u8; Self::LENGTH],
24);
25
26impl Describe<ScryptoCustomTypeKind> for Secp256k1PublicKey {
27    const TYPE_ID: RustTypeId =
28        RustTypeId::WellKnown(well_known_scrypto_custom_types::SECP256K1_PUBLIC_KEY_TYPE);
29
30    fn type_data() -> ScryptoTypeData<RustTypeId> {
31        well_known_scrypto_custom_types::secp256k1_public_key_type_data()
32    }
33}
34
35impl Secp256k1PublicKey {
36    pub const LENGTH: usize = 33;
37
38    pub fn to_vec(&self) -> Vec<u8> {
39        self.0.to_vec()
40    }
41
42    pub fn to_hash(&self) -> Secp256k1PublicKeyHash {
43        Secp256k1PublicKeyHash::new_from_public_key(self)
44    }
45}
46
47impl TryFrom<&[u8]> for Secp256k1PublicKey {
48    type Error = ParseSecp256k1PublicKeyError;
49
50    fn try_from(slice: &[u8]) -> Result<Self, Self::Error> {
51        if slice.len() != Secp256k1PublicKey::LENGTH {
52            return Err(ParseSecp256k1PublicKeyError::InvalidLength(slice.len()));
53        }
54
55        Ok(Secp256k1PublicKey(copy_u8_array(slice)))
56    }
57}
58
59impl AsRef<Self> for Secp256k1PublicKey {
60    fn as_ref(&self) -> &Self {
61        self
62    }
63}
64
65impl AsRef<[u8]> for Secp256k1PublicKey {
66    fn as_ref(&self) -> &[u8] {
67        &self.0
68    }
69}
70
71//======
72// hash
73//======
74
75#[cfg_attr(feature = "fuzzing", derive(::arbitrary::Arbitrary))]
76#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Categorize, Encode, Decode, BasicDescribe)]
77#[sbor(transparent)]
78pub struct Secp256k1PublicKeyHash(pub [u8; Self::LENGTH]);
79
80impl Describe<ScryptoCustomTypeKind> for Secp256k1PublicKeyHash {
81    const TYPE_ID: RustTypeId =
82        RustTypeId::WellKnown(well_known_scrypto_custom_types::SECP256K1_PUBLIC_KEY_HASH_TYPE);
83
84    fn type_data() -> ScryptoTypeData<RustTypeId> {
85        well_known_scrypto_custom_types::secp256k1_public_key_hash_type_data()
86    }
87}
88
89impl Secp256k1PublicKeyHash {
90    pub const LENGTH: usize = NodeId::RID_LENGTH;
91
92    pub fn new_from_public_key(public_key: &Secp256k1PublicKey) -> Self {
93        Self(hash_public_key_bytes(public_key.0))
94    }
95}
96
97impl HasPublicKeyHash for Secp256k1PublicKey {
98    type TypedPublicKeyHash = Secp256k1PublicKeyHash;
99
100    fn get_hash(&self) -> Self::TypedPublicKeyHash {
101        Self::TypedPublicKeyHash::new_from_public_key(self)
102    }
103}
104
105impl IsPublicKeyHash for Secp256k1PublicKeyHash {
106    fn get_hash_bytes(&self) -> &[u8; Self::LENGTH] {
107        &self.0
108    }
109
110    fn into_enum(self) -> PublicKeyHash {
111        PublicKeyHash::Secp256k1(self)
112    }
113}
114
115impl HasPublicKeyHash for Secp256k1PublicKeyHash {
116    type TypedPublicKeyHash = Self;
117
118    fn get_hash(&self) -> Self::TypedPublicKeyHash {
119        *self
120    }
121}
122
123//======
124// error
125//======
126
127/// Represents an error when parsing ED25519 public key from hex.
128#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
129pub enum ParseSecp256k1PublicKeyError {
130    InvalidHex(String),
131    InvalidLength(usize),
132}
133
134#[cfg(not(feature = "alloc"))]
135impl std::error::Error for ParseSecp256k1PublicKeyError {}
136
137#[cfg(not(feature = "alloc"))]
138impl fmt::Display for ParseSecp256k1PublicKeyError {
139    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
140        write!(f, "{:?}", self)
141    }
142}
143
144//======
145// text
146//======
147
148impl FromStr for Secp256k1PublicKey {
149    type Err = ParseSecp256k1PublicKeyError;
150
151    fn from_str(s: &str) -> Result<Self, Self::Err> {
152        let bytes =
153            hex::decode(s).map_err(|_| ParseSecp256k1PublicKeyError::InvalidHex(s.to_owned()))?;
154        Self::try_from(bytes.as_slice())
155    }
156}
157
158impl fmt::Display for Secp256k1PublicKey {
159    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
160        write!(f, "{}", hex::encode(self.to_vec()))
161    }
162}
163
164impl fmt::Debug for Secp256k1PublicKey {
165    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
166        write!(f, "{}", self)
167    }
168}