iota_sdk_types/crypto/
ed25519.rs1use crate::crypto::{PublicKeyExt, SignatureScheme};
8
9#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
19#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
20#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
21#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
22pub struct Ed25519PublicKey(
23 #[cfg_attr(
24 feature = "serde",
25 serde(with = "::serde_with::As::<::serde_with::IfIsHumanReadable<super::Base64Array32>>")
26 )]
27 #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::Base64"))]
28 [u8; Self::LENGTH],
29);
30
31impl Ed25519PublicKey {
32 pub const LENGTH: usize = 32;
34
35 pub const fn new(bytes: [u8; Self::LENGTH]) -> Self {
36 Self(bytes)
37 }
38
39 #[cfg(feature = "rand")]
40 #[cfg_attr(doc_cfg, doc(cfg(feature = "rand")))]
41 pub fn generate<R>(mut rng: R) -> Self
42 where
43 R: rand_core::RngCore + rand_core::CryptoRng,
44 {
45 let mut buf: [u8; Self::LENGTH] = [0; Self::LENGTH];
46 rng.fill_bytes(&mut buf);
47 Self::new(buf)
48 }
49
50 pub const fn into_inner(self) -> [u8; Self::LENGTH] {
52 self.0
53 }
54
55 pub const fn inner(&self) -> &[u8; Self::LENGTH] {
56 &self.0
57 }
58}
59
60impl PublicKeyExt for Ed25519PublicKey {
61 type FromBytesErr = std::array::TryFromSliceError;
62
63 fn as_bytes(&self) -> &[u8] {
65 &self.0
66 }
67
68 fn from_bytes<T: AsRef<[u8]>>(bytes: T) -> Result<Self, Self::FromBytesErr> {
70 <[u8; Self::LENGTH]>::try_from(bytes.as_ref()).map(Self)
71 }
72
73 fn scheme(&self) -> SignatureScheme {
75 SignatureScheme::Ed25519
76 }
77}
78
79impl std::str::FromStr for Ed25519PublicKey {
80 type Err = base64ct::Error;
81
82 fn from_str(s: &str) -> Result<Self, Self::Err> {
83 super::Base64FromStr32::from_str(s).map(|a| Self::new(a.0))
84 }
85}
86
87impl AsRef<[u8]> for Ed25519PublicKey {
88 fn as_ref(&self) -> &[u8] {
89 &self.0
90 }
91}
92
93impl AsRef<[u8; Self::LENGTH]> for Ed25519PublicKey {
94 fn as_ref(&self) -> &[u8; Self::LENGTH] {
95 &self.0
96 }
97}
98
99impl From<Ed25519PublicKey> for [u8; Ed25519PublicKey::LENGTH] {
100 fn from(public_key: Ed25519PublicKey) -> Self {
101 public_key.into_inner()
102 }
103}
104
105impl From<[u8; Self::LENGTH]> for Ed25519PublicKey {
106 fn from(public_key: [u8; Self::LENGTH]) -> Self {
107 Self::new(public_key)
108 }
109}
110
111impl std::fmt::Display for Ed25519PublicKey {
112 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
113 std::fmt::Display::fmt(&super::Base64Display32(&self.0), f)
114 }
115}
116
117impl std::fmt::Debug for Ed25519PublicKey {
118 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
119 f.debug_tuple("Ed25519PublicKey")
120 .field(&format_args!("\"{self}\""))
121 .finish()
122 }
123}
124
125#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
135#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
136#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
137#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
138pub struct Ed25519Signature(
139 #[cfg_attr(
140 feature = "serde",
141 serde(
142 with = "::serde_with::As::<::serde_with::IfIsHumanReadable<super::Base64Array64, [::serde_with::Same; 64]>>"
143 )
144 )]
145 #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::Base64"))]
146 [u8; Self::LENGTH],
147);
148
149impl Ed25519Signature {
150 pub const LENGTH: usize = 64;
152
153 pub const fn new(bytes: [u8; Self::LENGTH]) -> Self {
154 Self(bytes)
155 }
156
157 #[cfg(feature = "rand")]
158 #[cfg_attr(doc_cfg, doc(cfg(feature = "rand")))]
159 pub fn generate<R>(mut rng: R) -> Self
160 where
161 R: rand_core::RngCore + rand_core::CryptoRng,
162 {
163 let mut buf: [u8; Self::LENGTH] = [0; Self::LENGTH];
164 rng.fill_bytes(&mut buf);
165 Self::new(buf)
166 }
167
168 pub const fn into_inner(self) -> [u8; Self::LENGTH] {
170 self.0
171 }
172
173 pub const fn inner(&self) -> &[u8; Self::LENGTH] {
174 &self.0
175 }
176
177 pub const fn as_bytes(&self) -> &[u8] {
178 &self.0
179 }
180
181 pub fn from_bytes<T: AsRef<[u8]>>(bytes: T) -> Result<Self, std::array::TryFromSliceError> {
182 <[u8; Self::LENGTH]>::try_from(bytes.as_ref()).map(Self)
183 }
184}
185
186impl std::str::FromStr for Ed25519Signature {
187 type Err = base64ct::Error;
188
189 fn from_str(s: &str) -> Result<Self, Self::Err> {
190 super::Base64FromStr64::from_str(s).map(|a| Self::new(a.0))
191 }
192}
193
194impl AsRef<[u8]> for Ed25519Signature {
195 fn as_ref(&self) -> &[u8] {
196 &self.0
197 }
198}
199
200impl AsRef<[u8; Self::LENGTH]> for Ed25519Signature {
201 fn as_ref(&self) -> &[u8; Self::LENGTH] {
202 &self.0
203 }
204}
205
206impl From<Ed25519Signature> for [u8; Ed25519Signature::LENGTH] {
207 fn from(signature: Ed25519Signature) -> Self {
208 signature.into_inner()
209 }
210}
211
212impl From<[u8; Self::LENGTH]> for Ed25519Signature {
213 fn from(signature: [u8; Self::LENGTH]) -> Self {
214 Self::new(signature)
215 }
216}
217
218impl std::fmt::Display for Ed25519Signature {
219 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
220 std::fmt::Display::fmt(&super::Base64Display64(&self.0), f)
221 }
222}
223
224impl std::fmt::Debug for Ed25519Signature {
225 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
226 f.debug_tuple("Ed25519Signature")
227 .field(&format_args!("\"{self}\""))
228 .finish()
229 }
230}