sbd_e2e_crypto_client/
protocol.rs1pub const T_NEW_STREAM: u8 = 0x10;
34
35pub const T_MESSAGE: u8 = 0x11;
37
38pub const T_REQ_NEW_STREAM: u8 = 0x12;
40
41#[derive(PartialEq)]
49pub enum Protocol {
50 NewStream {
53 #[allow(missing_docs)]
54 full: bytes::Bytes,
55 #[allow(missing_docs)]
56 pub_key: bytes::Bytes,
57 #[allow(missing_docs)]
58 base_msg: bytes::Bytes,
59 #[allow(missing_docs)]
60 header: bytes::Bytes,
61 },
62
63 Message {
65 #[allow(missing_docs)]
66 full: bytes::Bytes,
67 #[allow(missing_docs)]
68 pub_key: bytes::Bytes,
69 #[allow(missing_docs)]
70 base_msg: bytes::Bytes,
71 #[allow(missing_docs)]
72 message: bytes::Bytes,
73 },
74
75 RequestNewStream {
77 #[allow(missing_docs)]
78 full: bytes::Bytes,
79 #[allow(missing_docs)]
80 pub_key: bytes::Bytes,
81 #[allow(missing_docs)]
82 base_msg: bytes::Bytes,
83 },
84}
85
86impl std::fmt::Debug for Protocol {
87 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88 match self {
89 Self::NewStream { .. } => {
90 f.debug_struct("Protocol::NewStream").finish()
91 }
92 Self::Message { .. } => {
93 f.debug_struct("Protocol::Message").finish()
94 }
95 Self::RequestNewStream { .. } => {
96 f.debug_struct("Protocol::RequestNewStream").finish()
97 }
98 }
99 }
100}
101
102impl Protocol {
103 pub fn from_full(full: bytes::Bytes) -> Option<Self> {
106 if full.len() < 33 {
107 return None;
108 }
109 let pub_key = full.slice(..32);
110 let base_msg = full.slice(32..);
111 Some(match full[32] {
112 T_NEW_STREAM => {
113 if base_msg.len() != 25 {
114 return None;
115 }
116 let header = full.slice(33..);
117 Self::NewStream {
118 full,
119 pub_key,
120 base_msg,
121 header,
122 }
123 }
124 T_MESSAGE => {
125 let message = full.slice(33..);
126 Self::Message {
127 full,
128 pub_key,
129 base_msg,
130 message,
131 }
132 }
133 T_REQ_NEW_STREAM => {
134 if base_msg.len() != 1 {
135 return None;
136 }
137 Self::RequestNewStream {
138 full,
139 pub_key,
140 base_msg,
141 }
142 }
143 _ => return None,
144 })
145 }
146
147 pub fn new_stream(pub_key: &[u8], header: &[u8]) -> Self {
152 let mut out = bytes::BytesMut::with_capacity(32 + 1 + 24);
153 out.extend_from_slice(&pub_key[..32]);
154 out.extend_from_slice(&[T_NEW_STREAM]);
155 out.extend_from_slice(&header[..24]);
156 Self::from_full(out.freeze()).unwrap()
158 }
159
160 pub fn message(pub_key: &[u8], message: &[u8]) -> Self {
165 let mut out = bytes::BytesMut::with_capacity(32 + 1 + message.len());
166 out.extend_from_slice(&pub_key[..32]);
167 out.extend_from_slice(&[T_MESSAGE]);
168 out.extend_from_slice(message);
169 Self::from_full(out.freeze()).unwrap()
171 }
172
173 pub fn request_new_stream(pub_key: &[u8]) -> Self {
178 let mut out = bytes::BytesMut::with_capacity(32 + 1);
179 out.extend_from_slice(&pub_key[..32]);
180 out.extend_from_slice(&[T_REQ_NEW_STREAM]);
181 Self::from_full(out.freeze()).unwrap()
183 }
184
185 pub fn full(&self) -> &bytes::Bytes {
187 match self {
188 Self::NewStream { full, .. } => full,
189 Self::Message { full, .. } => full,
190 Self::RequestNewStream { full, .. } => full,
191 }
192 }
193
194 pub fn pub_key(&self) -> &bytes::Bytes {
196 match self {
197 Self::NewStream { pub_key, .. } => pub_key,
198 Self::Message { pub_key, .. } => pub_key,
199 Self::RequestNewStream { pub_key, .. } => pub_key,
200 }
201 }
202
203 pub fn base_msg(&self) -> &bytes::Bytes {
205 match self {
206 Self::NewStream { base_msg, .. } => base_msg,
207 Self::Message { base_msg, .. } => base_msg,
208 Self::RequestNewStream { base_msg, .. } => base_msg,
209 }
210 }
211}
212
213#[cfg(test)]
214mod test {
215 use super::*;
216
217 const PUB_KEY: &[u8] = &[4; 32];
218 const HEADER: &[u8] = &[5; 24];
219
220 #[inline(always)]
221 fn valid_roundtrip(orig: &Protocol) {
222 let new = Protocol::from_full(orig.full().clone()).unwrap();
223 assert_eq!(orig, &new);
224 assert_eq!(orig.full(), new.full());
225 }
226
227 #[test]
228 #[should_panic]
229 fn bad_pk_size() {
230 Protocol::request_new_stream(&[4; 31]);
231 }
232
233 #[test]
234 #[should_panic]
235 fn bad_hdr_size() {
236 Protocol::new_stream(PUB_KEY, &[5; 23]);
237 }
238
239 #[test]
240 fn invalid_type() {
241 let mut exp_other = bytes::BytesMut::new();
242 exp_other.extend_from_slice(PUB_KEY);
243 exp_other.extend_from_slice(&[0x42]);
244 exp_other.extend_from_slice(b"not a thing");
245 let exp_other = exp_other.freeze();
246 assert!(Protocol::from_full(exp_other.clone()).is_none());
247 }
248
249 #[test]
250 fn new_stream() {
251 let ns = Protocol::new_stream(PUB_KEY, HEADER);
252 valid_roundtrip(&ns);
253
254 let mut exp_base_msg = Vec::new();
255 exp_base_msg.push(T_NEW_STREAM);
256 exp_base_msg.extend_from_slice(HEADER);
257
258 assert!(matches!(ns, Protocol::NewStream {
259 pub_key,
260 base_msg,
261 header,
262 ..
263 } if pub_key.as_ref() == PUB_KEY
264 && base_msg.as_ref() == exp_base_msg
265 && header.as_ref() == HEADER
266 ));
267 }
268
269 #[test]
270 fn message() {
271 let ns = Protocol::message(PUB_KEY, b"hello");
272 valid_roundtrip(&ns);
273
274 let mut exp_base_msg = Vec::new();
275 exp_base_msg.push(T_MESSAGE);
276 exp_base_msg.extend_from_slice(b"hello");
277
278 assert!(matches!(ns, Protocol::Message {
279 pub_key,
280 base_msg,
281 message,
282 ..
283 } if pub_key.as_ref() == PUB_KEY
284 && base_msg.as_ref() == exp_base_msg
285 && message.as_ref() == b"hello"
286 ));
287 }
288
289 #[test]
290 fn req_new_stream() {
291 let ns = Protocol::request_new_stream(PUB_KEY);
292 valid_roundtrip(&ns);
293
294 assert!(matches!(ns, Protocol::RequestNewStream {
295 pub_key,
296 base_msg,
297 ..
298 } if pub_key.as_ref() == PUB_KEY && base_msg.as_ref() == [0x12]));
299 }
300}