sui_sdk_types/crypto/
bls12381.rs

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