sui_sdk_types/crypto/
ed25519.rs

1//! Implementation of ed25519 public-key cryptogrophy.
2
3/// An ed25519 public key.
4///
5/// # BCS
6///
7/// The BCS serialized form for this type is defined by the following ABNF:
8///
9/// ```text
10/// ed25519-public-key = 32OCTECT
11/// ```
12#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
13#[cfg_attr(
14    feature = "serde",
15    derive(serde_derive::Serialize, serde_derive::Deserialize)
16)]
17#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
18pub struct Ed25519PublicKey(
19    #[cfg_attr(
20        feature = "serde",
21        serde(with = "::serde_with::As::<::serde_with::IfIsHumanReadable<super::Base64Array32>>")
22    )]
23    [u8; Self::LENGTH],
24);
25
26impl Ed25519PublicKey {
27    /// The length of an ed25519 public key in bytes.
28    pub const LENGTH: usize = 32;
29
30    pub const fn new(bytes: [u8; Self::LENGTH]) -> Self {
31        Self(bytes)
32    }
33
34    #[cfg(feature = "rand")]
35    #[cfg_attr(doc_cfg, doc(cfg(feature = "rand")))]
36    pub fn generate<R>(mut rng: R) -> Self
37    where
38        R: rand_core::RngCore + rand_core::CryptoRng,
39    {
40        let mut buf: [u8; Self::LENGTH] = [0; Self::LENGTH];
41        rng.fill_bytes(&mut buf);
42        Self::new(buf)
43    }
44
45    /// Return the underlying byte array of an Ed25519PublicKey.
46    pub const fn into_inner(self) -> [u8; Self::LENGTH] {
47        self.0
48    }
49
50    pub const fn inner(&self) -> &[u8; Self::LENGTH] {
51        &self.0
52    }
53
54    pub const fn as_bytes(&self) -> &[u8] {
55        &self.0
56    }
57
58    pub fn from_bytes<T: AsRef<[u8]>>(bytes: T) -> Result<Self, std::array::TryFromSliceError> {
59        <[u8; Self::LENGTH]>::try_from(bytes.as_ref()).map(Self)
60    }
61}
62
63impl std::str::FromStr for Ed25519PublicKey {
64    type Err = base64ct::Error;
65
66    fn from_str(s: &str) -> Result<Self, Self::Err> {
67        super::Base64FromStr32::from_str(s).map(|a| Self::new(a.0))
68    }
69}
70
71impl AsRef<[u8]> for Ed25519PublicKey {
72    fn as_ref(&self) -> &[u8] {
73        &self.0
74    }
75}
76
77impl AsRef<[u8; Self::LENGTH]> for Ed25519PublicKey {
78    fn as_ref(&self) -> &[u8; Self::LENGTH] {
79        &self.0
80    }
81}
82
83impl From<Ed25519PublicKey> for [u8; Ed25519PublicKey::LENGTH] {
84    fn from(public_key: Ed25519PublicKey) -> Self {
85        public_key.into_inner()
86    }
87}
88
89impl From<[u8; Self::LENGTH]> for Ed25519PublicKey {
90    fn from(public_key: [u8; Self::LENGTH]) -> Self {
91        Self::new(public_key)
92    }
93}
94
95impl std::fmt::Display for Ed25519PublicKey {
96    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
97        std::fmt::Display::fmt(&super::Base64Display32(&self.0), f)
98    }
99}
100
101impl std::fmt::Debug for Ed25519PublicKey {
102    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
103        f.debug_tuple("Ed25519PublicKey")
104            .field(&format_args!("\"{}\"", self))
105            .finish()
106    }
107}
108
109/// An ed25519 signature.
110///
111/// # BCS
112///
113/// The BCS serialized form for this type is defined by the following ABNF:
114///
115/// ```text
116/// ed25519-signature = 64OCTECT
117/// ```
118#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
119#[cfg_attr(
120    feature = "serde",
121    derive(serde_derive::Serialize, serde_derive::Deserialize)
122)]
123#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
124pub struct Ed25519Signature(
125    #[cfg_attr(
126        feature = "serde",
127        serde(
128            with = "::serde_with::As::<::serde_with::IfIsHumanReadable<super::Base64Array64, [::serde_with::Same; 64]>>"
129        )
130    )]
131    [u8; Self::LENGTH],
132);
133
134impl Ed25519Signature {
135    /// The length of an ed25519 signature key in bytes.
136    pub const LENGTH: usize = 64;
137
138    pub const fn new(bytes: [u8; Self::LENGTH]) -> Self {
139        Self(bytes)
140    }
141
142    #[cfg(feature = "rand")]
143    #[cfg_attr(doc_cfg, doc(cfg(feature = "rand")))]
144    pub fn generate<R>(mut rng: R) -> Self
145    where
146        R: rand_core::RngCore + rand_core::CryptoRng,
147    {
148        let mut buf: [u8; Self::LENGTH] = [0; Self::LENGTH];
149        rng.fill_bytes(&mut buf);
150        Self::new(buf)
151    }
152
153    /// Return the underlying byte array of an Ed25519Signature.
154    pub const fn into_inner(self) -> [u8; Self::LENGTH] {
155        self.0
156    }
157
158    pub const fn inner(&self) -> &[u8; Self::LENGTH] {
159        &self.0
160    }
161
162    pub const fn as_bytes(&self) -> &[u8] {
163        &self.0
164    }
165
166    pub fn from_bytes<T: AsRef<[u8]>>(bytes: T) -> Result<Self, std::array::TryFromSliceError> {
167        <[u8; Self::LENGTH]>::try_from(bytes.as_ref()).map(Self)
168    }
169}
170
171impl std::str::FromStr for Ed25519Signature {
172    type Err = base64ct::Error;
173
174    fn from_str(s: &str) -> Result<Self, Self::Err> {
175        super::Base64FromStr64::from_str(s).map(|a| Self::new(a.0))
176    }
177}
178
179impl AsRef<[u8]> for Ed25519Signature {
180    fn as_ref(&self) -> &[u8] {
181        &self.0
182    }
183}
184
185impl AsRef<[u8; Self::LENGTH]> for Ed25519Signature {
186    fn as_ref(&self) -> &[u8; Self::LENGTH] {
187        &self.0
188    }
189}
190
191impl From<Ed25519Signature> for [u8; Ed25519Signature::LENGTH] {
192    fn from(signature: Ed25519Signature) -> Self {
193        signature.into_inner()
194    }
195}
196
197impl From<[u8; Self::LENGTH]> for Ed25519Signature {
198    fn from(signature: [u8; Self::LENGTH]) -> Self {
199        Self::new(signature)
200    }
201}
202
203impl std::fmt::Display for Ed25519Signature {
204    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
205        std::fmt::Display::fmt(&super::Base64Display64(&self.0), f)
206    }
207}
208
209impl std::fmt::Debug for Ed25519Signature {
210    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
211        f.debug_tuple("Ed25519Signature")
212            .field(&format_args!("\"{}\"", self))
213            .finish()
214    }
215}