1use crate::{Error, PrivateKey, Signature};
2use derive_more::{AsMut, AsRef, Deref, Display, From, FromStr, Into};
3pub use secp256k1::XOnlyPublicKey;
4use secp256k1::SECP256K1;
5use serde::de::{Deserializer, Visitor};
6use serde::ser::Serializer;
7use serde::{Deserialize, Serialize};
8#[cfg(feature = "speedy")]
9use speedy::{Context, Readable, Reader, Writable, Writer};
10use std::fmt;
11
12#[derive(AsMut, AsRef, Copy, Clone, Debug, Deref, Eq, From, Into, PartialEq, PartialOrd, Ord)]
14pub struct PublicKey([u8; 32]);
15
16impl PublicKey {
17 pub fn as_hex_string(&self) -> String {
21 hex::encode(self.0)
22 }
23
24 pub fn try_from_hex_string(v: &str, verify: bool) -> Result<PublicKey, Error> {
29 let vec: Vec<u8> = hex::decode(v)?;
30 if vec.len() != 32 {
32 Err(Error::InvalidPublicKey)
33 } else {
34 if verify {
35 let _ = XOnlyPublicKey::from_slice(&vec)?;
36 }
37 Ok(PublicKey(vec.try_into().unwrap()))
38 }
39 }
40
41 pub fn as_bech32_string(&self) -> String {
43 bech32::encode::<bech32::Bech32>(*crate::HRP_NPUB, self.0.as_slice()).unwrap()
44 }
45
46 pub fn as_xonly_public_key(&self) -> XOnlyPublicKey {
48 XOnlyPublicKey::from_slice(&self.0).unwrap()
49 }
50
51 pub fn try_from_bech32_string(s: &str, verify: bool) -> Result<PublicKey, Error> {
56 let data = bech32::decode(s)?;
57 if data.0 != *crate::HRP_NPUB {
58 Err(Error::WrongBech32(
59 crate::HRP_NPUB.to_lowercase(),
60 data.0.to_lowercase(),
61 ))
62 } else if data.1.len() != 32 {
63 Err(Error::InvalidPublicKey)
64 } else {
65 if verify {
66 let _ = XOnlyPublicKey::from_slice(&data.1)?;
67 }
68 Ok(PublicKey(data.1.try_into().unwrap()))
69 }
70 }
71
72 pub fn from_bytes(bytes: &[u8], verify: bool) -> Result<PublicKey, Error> {
74 if bytes.len() != 32 {
75 Err(Error::InvalidPublicKey)
76 } else {
77 if verify {
78 let _ = XOnlyPublicKey::from_slice(bytes)?;
79 }
80 Ok(PublicKey(bytes.try_into().unwrap()))
81 }
82 }
83
84 #[inline]
86 pub fn as_bytes(&self) -> &[u8] {
87 self.0.as_slice()
88 }
89
90 #[inline]
92 pub fn to_bytes(&self) -> Vec<u8> {
93 self.0.as_slice().to_vec()
94 }
95
96 pub fn verify(&self, message: &[u8], signature: &Signature) -> Result<(), Error> {
98 use secp256k1::hashes::{sha256, Hash};
99 let pk = XOnlyPublicKey::from_slice(self.0.as_slice())?;
100 let hash = sha256::Hash::hash(message).to_byte_array();
101 let message = secp256k1::Message::from_digest(hash);
102 Ok(SECP256K1.verify_schnorr(&signature.0, &message, &pk)?)
103 }
104
105 pub fn hyperloglog_hash32(&self, offset: usize) -> u32 {
108 if offset + 3 >= 32 {
109 panic!("hyperloglog_hash32 offset cannot be greater than 28");
110 }
111 u32::from_ne_bytes(self.0[offset..offset + 3].try_into().unwrap())
112 }
113
114 pub fn hyperloglog_hash64(&self, offset: usize) -> u64 {
117 if offset + 7 >= 32 {
118 panic!("hyperloglog_hash64 offset cannot be greater than 24");
119 }
120 u64::from_ne_bytes(self.0[offset..offset + 7].try_into().unwrap())
121 }
122
123 #[allow(dead_code)]
125 pub(crate) fn mock() -> PublicKey {
126 PrivateKey::generate().public_key()
127 }
128
129 #[allow(dead_code)]
130 pub(crate) fn mock_deterministic() -> PublicKey {
131 PublicKey::try_from_hex_string(
132 "ee11a5dff40c19a555f41fe42b48f00e618c91225622ae37b6c2bb67b76c4e49",
133 true,
134 )
135 .unwrap()
136 }
137}
138
139impl Serialize for PublicKey {
140 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
141 where
142 S: Serializer,
143 {
144 serializer.serialize_str(&self.as_hex_string())
145 }
146}
147
148impl<'de> Deserialize<'de> for PublicKey {
149 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
150 where
151 D: Deserializer<'de>,
152 {
153 deserializer.deserialize_str(PublicKeyVisitor)
154 }
155}
156
157struct PublicKeyVisitor;
158
159impl Visitor<'_> for PublicKeyVisitor {
160 type Value = PublicKey;
161
162 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
163 write!(f, "a lowercase hexadecimal string representing 32 bytes")
164 }
165
166 fn visit_str<E>(self, v: &str) -> Result<PublicKey, E>
167 where
168 E: serde::de::Error,
169 {
170 let vec: Vec<u8> = hex::decode(v).map_err(|e| serde::de::Error::custom(format!("{e}")))?;
171
172 if vec.len() != 32 {
173 return Err(serde::de::Error::custom("Public key is not 32 bytes long"));
174 }
175
176 Ok(PublicKey(vec.try_into().unwrap()))
177 }
178}
179
180impl std::hash::Hash for PublicKey {
181 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
182 self.as_hex_string().hash(state);
183 }
184}
185
186#[cfg(feature = "speedy")]
187impl<'a, C: Context> Readable<'a, C> for PublicKey {
188 #[inline]
189 fn read_from<R: Reader<'a, C>>(reader: &mut R) -> Result<Self, C::Error> {
190 let bytes: Vec<u8> = reader.read_vec(32)?;
191 Ok(PublicKey(bytes.try_into().unwrap()))
192 }
193
194 #[inline]
195 fn minimum_bytes_needed() -> usize {
196 32
197 }
198}
199
200#[cfg(feature = "speedy")]
201impl<C: Context> Writable<C> for PublicKey {
202 #[inline]
203 fn write_to<T: ?Sized + Writer<C>>(&self, writer: &mut T) -> Result<(), C::Error> {
204 writer.write_bytes(self.as_slice())
205 }
206
207 #[inline]
208 fn bytes_needed(&self) -> Result<usize, C::Error> {
209 Ok(32)
210 }
211}
212
213#[derive(
217 AsMut,
218 AsRef,
219 Clone,
220 Debug,
221 Deref,
222 Display,
223 Eq,
224 From,
225 FromStr,
226 Hash,
227 Into,
228 PartialEq,
229 PartialOrd,
230 Ord,
231)]
232#[cfg_attr(feature = "speedy", derive(Readable, Writable))]
233pub struct PublicKeyHex(String);
234
235impl PublicKeyHex {
236 #[allow(dead_code)]
238 pub(crate) fn mock() -> PublicKeyHex {
239 From::from(PublicKey::mock())
240 }
241
242 #[allow(dead_code)]
244 pub(crate) fn mock_deterministic() -> PublicKeyHex {
245 PublicKey::mock_deterministic().into()
246 }
247
248 pub fn as_bech32_string(&self) -> String {
250 let vec: Vec<u8> = hex::decode(&self.0).unwrap();
251 bech32::encode::<bech32::Bech32>(*crate::HRP_NPUB, &vec).unwrap()
252 }
253
254 pub fn try_from_str(s: &str) -> Result<PublicKeyHex, Error> {
256 Self::try_from_string(s.to_owned())
257 }
258
259 pub fn try_from_string(s: String) -> Result<PublicKeyHex, Error> {
261 if s.len() != 64 {
262 return Err(Error::InvalidPublicKey);
263 }
264 let vec: Vec<u8> = hex::decode(&s)?;
265 if vec.len() != 32 {
266 return Err(Error::InvalidPublicKey);
267 }
268 Ok(PublicKeyHex(s))
269 }
270
271 pub fn as_str(&self) -> &str {
273 &self.0
274 }
275
276 pub fn into_string(self) -> String {
278 self.0
279 }
280}
281
282impl TryFrom<&str> for PublicKeyHex {
283 type Error = Error;
284
285 fn try_from(s: &str) -> Result<PublicKeyHex, Error> {
286 PublicKeyHex::try_from_str(s)
287 }
288}
289
290impl From<&PublicKey> for PublicKeyHex {
291 fn from(pk: &PublicKey) -> PublicKeyHex {
292 PublicKeyHex(pk.as_hex_string())
293 }
294}
295
296impl From<PublicKey> for PublicKeyHex {
297 fn from(pk: PublicKey) -> PublicKeyHex {
298 PublicKeyHex(pk.as_hex_string())
299 }
300}
301
302impl TryFrom<&PublicKeyHex> for PublicKey {
303 type Error = Error;
304
305 fn try_from(pkh: &PublicKeyHex) -> Result<PublicKey, Error> {
306 PublicKey::try_from_hex_string(&pkh.0, true)
307 }
308}
309
310impl TryFrom<PublicKeyHex> for PublicKey {
311 type Error = Error;
312
313 fn try_from(pkh: PublicKeyHex) -> Result<PublicKey, Error> {
314 PublicKey::try_from_hex_string(&pkh.0, true)
315 }
316}
317
318impl Serialize for PublicKeyHex {
319 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
320 where
321 S: Serializer,
322 {
323 serializer.serialize_str(&self.0)
324 }
325}
326
327impl<'de> Deserialize<'de> for PublicKeyHex {
328 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
329 where
330 D: Deserializer<'de>,
331 {
332 deserializer.deserialize_str(PublicKeyHexVisitor)
333 }
334}
335
336struct PublicKeyHexVisitor;
337
338impl Visitor<'_> for PublicKeyHexVisitor {
339 type Value = PublicKeyHex;
340
341 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
342 write!(f, "a lowercase hexadecimal string representing 32 bytes")
343 }
344
345 fn visit_str<E>(self, v: &str) -> Result<PublicKeyHex, E>
346 where
347 E: serde::de::Error,
348 {
349 if v.len() != 64 {
350 return Err(serde::de::Error::custom(
351 "PublicKeyHex is not 64 characters long",
352 ));
353 }
354
355 let vec: Vec<u8> = hex::decode(v).map_err(|e| serde::de::Error::custom(format!("{e}")))?;
356 if vec.len() != 32 {
357 return Err(serde::de::Error::custom("Invalid PublicKeyHex"));
358 }
359
360 Ok(PublicKeyHex(v.to_owned()))
361 }
362}
363
364#[cfg(test)]
365mod test {
366 use super::*;
367
368 test_serde! {PublicKey, test_public_key_serde}
369 test_serde! {PublicKeyHex, test_public_key_hex_serde}
370
371 #[test]
372 fn test_pubkey_bech32() {
373 let pk = PublicKey::mock();
374
375 let encoded = pk.as_bech32_string();
376 println!("bech32: {encoded}");
377
378 let decoded = PublicKey::try_from_bech32_string(&encoded, true).unwrap();
379
380 assert_eq!(pk, decoded);
381 }
382
383 #[cfg(feature = "speedy")]
384 #[test]
385 fn test_speedy_public_key() {
386 let pk = PublicKey::mock();
387 let bytes = pk.write_to_vec().unwrap();
388 let pk2 = PublicKey::read_from_buffer(&bytes).unwrap();
389 assert_eq!(pk, pk2);
390 }
391}