distant_net/common/transport/framed/exchange/
salt.rs1use std::convert::{TryFrom, TryInto};
2use std::ops::BitXor;
3use std::str::FromStr;
4use std::{fmt, io};
5
6use rand::rngs::OsRng;
7use rand::RngCore;
8use serde::{Deserialize, Deserializer, Serialize, Serializer};
9
10#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
12#[serde(into = "Vec<u8>", try_from = "Vec<u8>")]
13pub struct Salt([u8; 32]);
14
15impl Salt {
16 pub fn random() -> Self {
18 let mut salt = [0u8; 32];
19 OsRng.fill_bytes(&mut salt);
20 Self(salt)
21 }
22}
23
24impl fmt::Display for Salt {
25 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26 write!(f, "{}", hex::encode(self.0))
27 }
28}
29
30impl serde_bytes::Serialize for Salt {
31 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
32 where
33 S: Serializer,
34 {
35 serializer.serialize_bytes(self.as_ref())
36 }
37}
38
39impl<'de> serde_bytes::Deserialize<'de> for Salt {
40 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
41 where
42 D: Deserializer<'de>,
43 {
44 let bytes = Deserialize::deserialize(deserializer).map(serde_bytes::ByteBuf::into_vec)?;
45 let bytes_len = bytes.len();
46 Salt::try_from(bytes)
47 .map_err(|_| serde::de::Error::invalid_length(bytes_len, &"expected 32-byte length"))
48 }
49}
50
51impl From<Salt> for String {
52 fn from(salt: Salt) -> Self {
53 salt.to_string()
54 }
55}
56
57impl FromStr for Salt {
58 type Err = io::Error;
59
60 fn from_str(s: &str) -> Result<Self, Self::Err> {
61 let bytes = hex::decode(s).map_err(|x| io::Error::new(io::ErrorKind::InvalidData, x))?;
62 Self::try_from(bytes)
63 }
64}
65
66impl TryFrom<String> for Salt {
67 type Error = io::Error;
68
69 fn try_from(s: String) -> Result<Self, Self::Error> {
70 s.parse()
71 }
72}
73
74impl TryFrom<Vec<u8>> for Salt {
75 type Error = io::Error;
76
77 fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
78 Ok(Self(bytes.try_into().map_err(|x: Vec<u8>| {
79 io::Error::new(
80 io::ErrorKind::InvalidData,
81 format!("Vec<u8> len of {} != 32", x.len()),
82 )
83 })?))
84 }
85}
86
87impl From<Salt> for Vec<u8> {
88 fn from(salt: Salt) -> Self {
89 salt.0.to_vec()
90 }
91}
92
93impl AsRef<[u8]> for Salt {
94 fn as_ref(&self) -> &[u8] {
95 self.0.as_ref()
96 }
97}
98
99impl BitXor for Salt {
100 type Output = Self;
101
102 fn bitxor(self, rhs: Self) -> Self::Output {
103 let shared_salt = self
104 .0
105 .iter()
106 .zip(rhs.0.iter())
107 .map(|(x, y)| x ^ y)
108 .collect::<Vec<u8>>();
109 Self::try_from(shared_salt).unwrap()
110 }
111}