ab_core_primitives/
ed25519.rs1use 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 = "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#[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
29impl From<VerificationKey> for Ed25519PublicKey {
30 #[inline(always)]
31 fn from(verification_key: VerificationKey) -> Self {
32 Ed25519PublicKey(verification_key.into())
33 }
34}
35
36impl fmt::Debug for Ed25519PublicKey {
37 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38 for byte in self.0 {
39 write!(f, "{byte:02x}")?;
40 }
41 Ok(())
42 }
43}
44
45#[cfg(feature = "serde")]
46#[derive(Serialize, Deserialize)]
47#[serde(transparent)]
48struct Ed25519PublicKeyBinary([u8; Ed25519PublicKey::SIZE]);
49
50#[cfg(feature = "serde")]
51#[derive(Serialize, Deserialize)]
52#[serde(transparent)]
53struct Ed25519PublicKeyHex(#[serde(with = "hex")] [u8; Ed25519PublicKey::SIZE]);
54
55#[cfg(feature = "serde")]
56impl Serialize for Ed25519PublicKey {
57 #[inline]
58 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
59 where
60 S: Serializer,
61 {
62 if serializer.is_human_readable() {
63 Ed25519PublicKeyHex(self.0).serialize(serializer)
64 } else {
65 Ed25519PublicKeyBinary(self.0).serialize(serializer)
66 }
67 }
68}
69
70#[cfg(feature = "serde")]
71impl<'de> Deserialize<'de> for Ed25519PublicKey {
72 #[inline]
73 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
74 where
75 D: Deserializer<'de>,
76 {
77 Ok(Self(if deserializer.is_human_readable() {
78 Ed25519PublicKeyHex::deserialize(deserializer)?.0
79 } else {
80 Ed25519PublicKeyBinary::deserialize(deserializer)?.0
81 }))
82 }
83}
84
85impl fmt::Display for Ed25519PublicKey {
86 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
87 for byte in self.0 {
88 write!(f, "{byte:02x}")?;
89 }
90 Ok(())
91 }
92}
93
94impl AsRef<[u8]> for Ed25519PublicKey {
95 #[inline]
96 fn as_ref(&self) -> &[u8] {
97 &self.0
98 }
99}
100
101impl Ed25519PublicKey {
102 pub const SIZE: usize = 32;
104
105 pub fn hash(&self) -> Blake3Hash {
107 Blake3Hash::new(
108 single_block_hash(&self.0).expect("Less than a single block worth of bytes; qed"),
109 )
110 }
111
112 #[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#[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
128impl From<Signature> for Ed25519Signature {
129 #[inline(always)]
130 fn from(signature: Signature) -> Self {
131 Ed25519Signature::from(signature.to_bytes())
132 }
133}
134
135impl Default for Ed25519Signature {
136 fn default() -> Self {
137 Self([0; Self::SIZE])
138 }
139}
140
141impl fmt::Debug for Ed25519Signature {
142 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
143 for byte in self.0 {
144 write!(f, "{byte:02x}")?;
145 }
146 Ok(())
147 }
148}
149
150#[cfg(feature = "serde")]
151#[derive(Serialize, Deserialize)]
152#[serde(transparent)]
153struct Ed25519SignatureBinary(#[serde(with = "BigArray")] [u8; Ed25519Signature::SIZE]);
154
155#[cfg(feature = "serde")]
156#[derive(Serialize, Deserialize)]
157#[serde(transparent)]
158struct Ed25519SignatureHex(#[serde(with = "hex")] [u8; Ed25519Signature::SIZE]);
159
160#[cfg(feature = "serde")]
161impl Serialize for Ed25519Signature {
162 #[inline]
163 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
164 where
165 S: Serializer,
166 {
167 if serializer.is_human_readable() {
168 Ed25519SignatureHex(self.0).serialize(serializer)
169 } else {
170 Ed25519SignatureBinary(self.0).serialize(serializer)
171 }
172 }
173}
174
175#[cfg(feature = "serde")]
176impl<'de> Deserialize<'de> for Ed25519Signature {
177 #[inline]
178 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
179 where
180 D: Deserializer<'de>,
181 {
182 Ok(Self(if deserializer.is_human_readable() {
183 Ed25519SignatureHex::deserialize(deserializer)?.0
184 } else {
185 Ed25519SignatureBinary::deserialize(deserializer)?.0
186 }))
187 }
188}
189
190impl fmt::Display for Ed25519Signature {
191 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
192 for byte in self.0 {
193 write!(f, "{byte:02x}")?;
194 }
195 Ok(())
196 }
197}
198
199impl AsRef<[u8]> for Ed25519Signature {
200 #[inline]
201 fn as_ref(&self) -> &[u8] {
202 &self.0
203 }
204}
205
206impl Ed25519Signature {
207 pub const SIZE: usize = 64;
209}