ab_core_primitives/
ed25519.rs

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