Skip to main content

sui_sdk_types/crypto/
mldsa65.rs

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