chik_secp/secp256k1/
public_key.rs

1use std::fmt;
2use std::hash::{Hash, Hasher};
3
4use chik_sha2::Sha256;
5use k256::ecdsa::signature::hazmat::PrehashVerifier;
6use k256::ecdsa::{Error, VerifyingKey};
7
8use super::K1Signature;
9
10#[derive(Clone, Copy, PartialEq, Eq)]
11pub struct K1PublicKey(pub(crate) VerifyingKey);
12
13impl Hash for K1PublicKey {
14    fn hash<H: Hasher>(&self, state: &mut H) {
15        self.to_bytes().hash(state);
16    }
17}
18
19impl fmt::Debug for K1PublicKey {
20    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21        write!(f, "K1PublicKey({self})")
22    }
23}
24
25impl fmt::Display for K1PublicKey {
26    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27        write!(f, "{}", hex::encode(self.to_bytes()))
28    }
29}
30
31#[cfg(feature = "arbitrary")]
32impl<'a> arbitrary::Arbitrary<'a> for K1PublicKey {
33    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
34        Self::from_bytes(&u.arbitrary()?).map_err(|_| arbitrary::Error::IncorrectFormat)
35    }
36}
37
38impl K1PublicKey {
39    pub const SIZE: usize = 33;
40
41    pub fn to_bytes(&self) -> [u8; Self::SIZE] {
42        self.0.to_encoded_point(true).as_ref().try_into().unwrap()
43    }
44
45    pub fn from_bytes(bytes: &[u8; Self::SIZE]) -> Result<Self, Error> {
46        Ok(Self(VerifyingKey::from_sec1_bytes(bytes)?))
47    }
48
49    pub fn verify_prehashed(&self, message_hash: &[u8; 32], signature: &K1Signature) -> bool {
50        self.0.verify_prehash(message_hash, &signature.0).is_ok()
51    }
52
53    pub fn fingerprint(&self) -> u32 {
54        let mut hasher = Sha256::new();
55        hasher.update(self.to_bytes());
56        let hash = hasher.finalize();
57        u32::from_be_bytes(hash[0..4].try_into().unwrap())
58    }
59}