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