distant_net/common/
key.rs1use std::fmt;
2use std::str::FromStr;
3
4use derive_more::{Display, Error};
5use rand::rngs::OsRng;
6use rand::RngCore;
7
8#[derive(Debug, Display, Error)]
9pub struct SecretKeyError;
10
11impl From<SecretKeyError> for std::io::Error {
12 fn from(_: SecretKeyError) -> Self {
13 std::io::Error::new(
14 std::io::ErrorKind::InvalidData,
15 "not valid secret key format",
16 )
17 }
18}
19
20pub type SecretKey16 = SecretKey<16>;
22
23pub type SecretKey24 = SecretKey<24>;
25
26pub type SecretKey32 = SecretKey<32>;
28
29#[derive(Clone, PartialEq, Eq)]
31pub struct SecretKey<const N: usize>([u8; N]);
32
33impl<const N: usize> fmt::Debug for SecretKey<N> {
34 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35 f.debug_tuple("SecretKey")
36 .field(&"**OMITTED**".to_string())
37 .finish()
38 }
39}
40
41impl<const N: usize> Default for SecretKey<N> {
42 fn default() -> Self {
48 Self::generate().unwrap()
49 }
50}
51
52impl<const N: usize> SecretKey<N> {
53 pub fn unprotected_as_bytes(&self) -> &[u8] {
55 &self.0
56 }
57
58 pub fn unprotected_as_byte_array(&self) -> &[u8; N] {
60 &self.0
61 }
62
63 pub fn unprotected_into_byte_array(self) -> [u8; N] {
65 self.0
66 }
67
68 pub fn into_heap_secret_key(self) -> HeapSecretKey {
70 HeapSecretKey(self.0.to_vec())
71 }
72
73 #[allow(clippy::len_without_is_empty)]
75 pub fn len(&self) -> usize {
76 N
77 }
78
79 pub fn generate() -> Result<Self, SecretKeyError> {
82 if N < 1 || N > (isize::MAX as usize) {
84 return Err(SecretKeyError);
85 }
86
87 let mut key = [0; N];
88 OsRng.fill_bytes(&mut key);
89
90 Ok(Self(key))
91 }
92
93 pub fn from_slice(slice: &[u8]) -> Result<Self, SecretKeyError> {
96 if slice.len() != N {
97 return Err(SecretKeyError);
98 }
99
100 let mut value = [0u8; N];
101 value[..N].copy_from_slice(slice);
102
103 Ok(Self(value))
104 }
105}
106
107impl<const N: usize> From<[u8; N]> for SecretKey<N> {
108 fn from(arr: [u8; N]) -> Self {
109 Self(arr)
110 }
111}
112
113impl<const N: usize> FromStr for SecretKey<N> {
114 type Err = SecretKeyError;
115
116 fn from_str(s: &str) -> Result<Self, Self::Err> {
118 let bytes = hex::decode(s).map_err(|_| SecretKeyError)?;
119 Self::from_slice(&bytes)
120 }
121}
122
123impl<const N: usize> fmt::Display for SecretKey<N> {
124 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
126 write!(f, "{}", hex::encode(self.unprotected_as_bytes()))
127 }
128}
129
130#[derive(Clone, PartialEq, Eq)]
133pub struct HeapSecretKey(Vec<u8>);
134
135impl fmt::Debug for HeapSecretKey {
136 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
137 f.debug_tuple("HeapSecretKey")
138 .field(&"**OMITTED**".to_string())
139 .finish()
140 }
141}
142
143impl HeapSecretKey {
144 pub fn unprotected_as_bytes(&self) -> &[u8] {
146 &self.0
147 }
148
149 pub fn unprotected_into_bytes(self) -> Vec<u8> {
151 self.0.to_vec()
152 }
153
154 #[allow(clippy::len_without_is_empty)]
156 pub fn len(&self) -> usize {
157 self.0.len()
158 }
159
160 pub fn generate(n: usize) -> Result<Self, SecretKeyError> {
166 if n < 1 || n > (isize::MAX as usize) {
168 return Err(SecretKeyError);
169 }
170
171 let mut key = Vec::new();
172 let mut buf = [0; 32];
173
174 while key.len() < n {
177 OsRng.fill_bytes(&mut buf);
178 key.extend_from_slice(&buf[..std::cmp::min(n - key.len(), 32)]);
179 }
180
181 Ok(Self(key))
182 }
183}
184
185impl From<Vec<u8>> for HeapSecretKey {
186 fn from(bytes: Vec<u8>) -> Self {
187 Self(bytes)
188 }
189}
190
191impl<const N: usize> From<[u8; N]> for HeapSecretKey {
192 fn from(arr: [u8; N]) -> Self {
193 Self::from(arr.to_vec())
194 }
195}
196
197impl<const N: usize> From<SecretKey<N>> for HeapSecretKey {
198 fn from(key: SecretKey<N>) -> Self {
199 key.into_heap_secret_key()
200 }
201}
202
203impl FromStr for HeapSecretKey {
204 type Err = SecretKeyError;
205
206 fn from_str(s: &str) -> Result<Self, Self::Err> {
208 Ok(Self(hex::decode(s).map_err(|_| SecretKeyError)?))
209 }
210}
211
212impl fmt::Display for HeapSecretKey {
213 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
215 write!(f, "{}", hex::encode(self.unprotected_as_bytes()))
216 }
217}
218
219impl<const N: usize> PartialEq<[u8; N]> for HeapSecretKey {
220 fn eq(&self, other: &[u8; N]) -> bool {
221 self.0.eq(other)
222 }
223}
224
225impl<const N: usize> PartialEq<HeapSecretKey> for [u8; N] {
226 fn eq(&self, other: &HeapSecretKey) -> bool {
227 other.eq(self)
228 }
229}
230
231impl<const N: usize> PartialEq<HeapSecretKey> for &[u8; N] {
232 fn eq(&self, other: &HeapSecretKey) -> bool {
233 other.eq(*self)
234 }
235}
236
237impl PartialEq<[u8]> for HeapSecretKey {
238 fn eq(&self, other: &[u8]) -> bool {
239 self.0.eq(other)
240 }
241}
242
243impl PartialEq<HeapSecretKey> for [u8] {
244 fn eq(&self, other: &HeapSecretKey) -> bool {
245 other.eq(self)
246 }
247}
248
249impl PartialEq<HeapSecretKey> for &[u8] {
250 fn eq(&self, other: &HeapSecretKey) -> bool {
251 other.eq(*self)
252 }
253}
254
255impl PartialEq<String> for HeapSecretKey {
256 fn eq(&self, other: &String) -> bool {
257 self.0.eq(other.as_bytes())
258 }
259}
260
261impl PartialEq<HeapSecretKey> for String {
262 fn eq(&self, other: &HeapSecretKey) -> bool {
263 other.eq(self)
264 }
265}
266
267impl PartialEq<HeapSecretKey> for &String {
268 fn eq(&self, other: &HeapSecretKey) -> bool {
269 other.eq(*self)
270 }
271}
272
273impl PartialEq<str> for HeapSecretKey {
274 fn eq(&self, other: &str) -> bool {
275 self.0.eq(other.as_bytes())
276 }
277}
278
279impl PartialEq<HeapSecretKey> for str {
280 fn eq(&self, other: &HeapSecretKey) -> bool {
281 other.eq(self)
282 }
283}
284
285impl PartialEq<HeapSecretKey> for &str {
286 fn eq(&self, other: &HeapSecretKey) -> bool {
287 other.eq(*self)
288 }
289}
290
291#[cfg(test)]
292mod tests {
293 use test_log::test;
294
295 use super::*;
296
297 #[test]
298 fn secret_key_should_be_able_to_be_generated() {
299 SecretKey::<0>::generate().unwrap_err();
300
301 let key = SecretKey::<1>::generate().unwrap();
302 assert_eq!(key.len(), 1);
303
304 let key = SecretKey::<100>::generate().unwrap();
307 assert_eq!(key.len(), 100);
308 }
309
310 #[test]
311 fn heap_secret_key_should_be_able_to_be_generated() {
312 HeapSecretKey::generate(0).unwrap_err();
313
314 let key = HeapSecretKey::generate(1).unwrap();
315 assert_eq!(key.len(), 1);
316
317 let key = HeapSecretKey::generate(100).unwrap();
320 assert_eq!(key.len(), 100);
321 }
322}