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