ab_core_primitives/
ed25519.rs

1//! Primitives related to Ed25519
2
3use crate::hashes::Blake3Hash;
4use ab_io_type::trivial_type::TrivialType;
5use core::fmt;
6use derive_more::{Deref, From, Into};
7#[cfg(feature = "ed25519-verify")]
8use ed25519_zebra::{Error, Signature, VerificationKey};
9#[cfg(feature = "scale-codec")]
10use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
11#[cfg(feature = "scale-codec")]
12use scale_info::TypeInfo;
13#[cfg(feature = "serde")]
14use serde::{Deserialize, Deserializer, Serialize, Serializer};
15#[cfg(feature = "serde")]
16use serde_big_array::BigArray;
17
18/// Ed25519 public key
19#[derive(
20    Default, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash, Deref, From, Into, TrivialType,
21)]
22#[cfg_attr(
23    feature = "scale-codec",
24    derive(Encode, Decode, TypeInfo, MaxEncodedLen)
25)]
26#[repr(C)]
27pub struct Ed25519PublicKey([u8; Ed25519PublicKey::SIZE]);
28
29#[cfg(feature = "ed25519-verify")]
30impl From<VerificationKey> for Ed25519PublicKey {
31    #[inline(always)]
32    fn from(verification_key: VerificationKey) -> Self {
33        Ed25519PublicKey(verification_key.into())
34    }
35}
36
37impl fmt::Debug for Ed25519PublicKey {
38    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39        for byte in self.0 {
40            write!(f, "{byte:02x}")?;
41        }
42        Ok(())
43    }
44}
45
46#[cfg(feature = "serde")]
47#[derive(Serialize, Deserialize)]
48#[serde(transparent)]
49struct Ed25519PublicKeyBinary([u8; Ed25519PublicKey::SIZE]);
50
51#[cfg(feature = "serde")]
52#[derive(Serialize, Deserialize)]
53#[serde(transparent)]
54struct Ed25519PublicKeyHex(#[serde(with = "hex")] [u8; Ed25519PublicKey::SIZE]);
55
56#[cfg(feature = "serde")]
57impl Serialize for Ed25519PublicKey {
58    #[inline]
59    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
60    where
61        S: Serializer,
62    {
63        if serializer.is_human_readable() {
64            Ed25519PublicKeyHex(self.0).serialize(serializer)
65        } else {
66            Ed25519PublicKeyBinary(self.0).serialize(serializer)
67        }
68    }
69}
70
71#[cfg(feature = "serde")]
72impl<'de> Deserialize<'de> for Ed25519PublicKey {
73    #[inline]
74    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
75    where
76        D: Deserializer<'de>,
77    {
78        Ok(Self(if deserializer.is_human_readable() {
79            Ed25519PublicKeyHex::deserialize(deserializer)?.0
80        } else {
81            Ed25519PublicKeyBinary::deserialize(deserializer)?.0
82        }))
83    }
84}
85
86impl fmt::Display for Ed25519PublicKey {
87    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88        for byte in self.0 {
89            write!(f, "{byte:02x}")?;
90        }
91        Ok(())
92    }
93}
94
95impl AsRef<[u8]> for Ed25519PublicKey {
96    #[inline]
97    fn as_ref(&self) -> &[u8] {
98        &self.0
99    }
100}
101
102impl Ed25519PublicKey {
103    /// Public key size in bytes
104    pub const SIZE: usize = 32;
105
106    /// Public key hash.
107    pub fn hash(&self) -> Blake3Hash {
108        Blake3Hash::new(blake3::hash(&self.0).into())
109    }
110
111    /// Verify Ed25519 signature
112    #[cfg(feature = "ed25519-verify")]
113    #[inline]
114    pub fn verify(&self, signature: &Ed25519Signature, msg: &[u8]) -> Result<(), Error> {
115        VerificationKey::try_from(self.0)?.verify(&Signature::from_bytes(signature), msg)
116    }
117}
118
119/// Ed25519 signature
120#[derive(Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash, Deref, From, Into, TrivialType)]
121#[cfg_attr(
122    feature = "scale-codec",
123    derive(Encode, Decode, TypeInfo, MaxEncodedLen)
124)]
125#[repr(C)]
126pub struct Ed25519Signature([u8; Ed25519Signature::SIZE]);
127
128#[cfg(feature = "ed25519-verify")]
129impl From<Signature> for Ed25519Signature {
130    #[inline(always)]
131    fn from(signature: Signature) -> Self {
132        Ed25519Signature::from(signature.to_bytes())
133    }
134}
135
136impl Default for Ed25519Signature {
137    fn default() -> Self {
138        Self([0; Self::SIZE])
139    }
140}
141
142impl fmt::Debug for Ed25519Signature {
143    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
144        for byte in self.0 {
145            write!(f, "{byte:02x}")?;
146        }
147        Ok(())
148    }
149}
150
151#[cfg(feature = "serde")]
152#[derive(Serialize, Deserialize)]
153#[serde(transparent)]
154struct Ed25519SignatureBinary(#[serde(with = "BigArray")] [u8; Ed25519Signature::SIZE]);
155
156#[cfg(feature = "serde")]
157#[derive(Serialize, Deserialize)]
158#[serde(transparent)]
159struct Ed25519SignatureHex(#[serde(with = "hex")] [u8; Ed25519Signature::SIZE]);
160
161#[cfg(feature = "serde")]
162impl Serialize for Ed25519Signature {
163    #[inline]
164    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
165    where
166        S: Serializer,
167    {
168        if serializer.is_human_readable() {
169            Ed25519SignatureHex(self.0).serialize(serializer)
170        } else {
171            Ed25519SignatureBinary(self.0).serialize(serializer)
172        }
173    }
174}
175
176#[cfg(feature = "serde")]
177impl<'de> Deserialize<'de> for Ed25519Signature {
178    #[inline]
179    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
180    where
181        D: Deserializer<'de>,
182    {
183        Ok(Self(if deserializer.is_human_readable() {
184            Ed25519SignatureHex::deserialize(deserializer)?.0
185        } else {
186            Ed25519SignatureBinary::deserialize(deserializer)?.0
187        }))
188    }
189}
190
191impl fmt::Display for Ed25519Signature {
192    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
193        for byte in self.0 {
194            write!(f, "{byte:02x}")?;
195        }
196        Ok(())
197    }
198}
199
200impl AsRef<[u8]> for Ed25519Signature {
201    #[inline]
202    fn as_ref(&self) -> &[u8] {
203        &self.0
204    }
205}
206
207impl Ed25519Signature {
208    /// Signature size in bytes
209    pub const SIZE: usize = 64;
210}