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