Skip to main content

tempo_primitives/
ed25519.rs

1use alloy_primitives::B256;
2use alloy_rlp::{Decodable, Encodable};
3use ed25519_consensus::{VerificationKey, VerificationKeyBytes};
4
5#[derive(Debug)]
6pub struct InvalidPublicKey;
7
8impl core::fmt::Display for InvalidPublicKey {
9    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10        f.write_str("invalid ed25519 public key")
11    }
12}
13
14#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
15#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
16#[cfg_attr(feature = "serde", serde(into = "B256", try_from = "B256"))]
17#[cfg_attr(test, reth_codecs::add_arbitrary_tests(compact))]
18pub struct PublicKey(VerificationKey);
19
20impl PublicKey {
21    pub fn get(&self) -> VerificationKey {
22        self.0
23    }
24
25    #[cfg(any(test, feature = "arbitrary"))]
26    pub fn from_seed(seed: [u8; 32]) -> Self {
27        ed25519_consensus::SigningKey::from(seed)
28            .verification_key()
29            .into()
30    }
31}
32
33impl Encodable for PublicKey {
34    fn encode(&self, out: &mut dyn alloy_rlp::BufMut) {
35        self.0.as_bytes().encode(out)
36    }
37
38    fn length(&self) -> usize {
39        self.0.as_bytes().length()
40    }
41}
42
43impl Decodable for PublicKey {
44    fn decode(buf: &mut &[u8]) -> alloy_rlp::Result<Self> {
45        let inner = <[u8; 32]>::decode(buf)?;
46        let key = VerificationKey::try_from(inner)
47            .map_err(|_| alloy_rlp::Error::Custom("malformed ed25519 public key"))?;
48        Ok(Self(key))
49    }
50}
51
52impl From<ed25519_consensus::VerificationKey> for PublicKey {
53    fn from(value: ed25519_consensus::VerificationKey) -> Self {
54        Self(value)
55    }
56}
57
58impl From<PublicKey> for B256 {
59    fn from(value: PublicKey) -> Self {
60        <[u8; 32]>::from(VerificationKeyBytes::from(value.0)).into()
61    }
62}
63
64impl<'a> From<&'a PublicKey> for B256 {
65    fn from(value: &'a PublicKey) -> Self {
66        <[u8; 32]>::from(VerificationKeyBytes::from(value.0)).into()
67    }
68}
69
70impl TryFrom<B256> for PublicKey {
71    type Error = InvalidPublicKey;
72
73    fn try_from(value: B256) -> Result<Self, Self::Error> {
74        let inner = VerificationKeyBytes::from(<[u8; 32]>::from(value))
75            .try_into()
76            .map_err(|_| InvalidPublicKey)?;
77        Ok(Self(inner))
78    }
79}
80
81#[cfg(any(test, feature = "arbitrary"))]
82impl<'a> arbitrary::Arbitrary<'a> for PublicKey {
83    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
84        Ok(Self::from_seed(u.arbitrary()?))
85    }
86}