portal_lib/protocol/
exchange.rs

1use core::convert::{TryFrom, TryInto};
2use core::fmt;
3use core::marker::PhantomData;
4use serde::de::{Deserializer, Error, SeqAccess, Visitor};
5use serde::ser::{SerializeTuple, Serializer};
6use serde::{Deserialize, Serialize};
7
8/// A data format exchanged by each peer to derive
9/// the shared session key
10#[derive(PartialEq, Eq, Debug, Copy, Clone)]
11pub struct PortalKeyExchange([u8; 33]);
12
13/// A data format exchanged by each peer to confirm
14/// that they have each derived the same key
15#[derive(PartialEq, Eq, Debug, Copy, Clone)]
16pub struct PortalConfirmation(pub [u8; 42]);
17
18/// Provide a serde visitor to serialize/deserialize larger arrays
19struct ArrayVisitor<T> {
20    element: PhantomData<T>,
21}
22
23impl<'de, T, const N: usize> Visitor<'de> for ArrayVisitor<[T; N]>
24where
25    T: Default + Copy + Deserialize<'de>,
26{
27    type Value = [T; N];
28
29    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
30        write!(formatter, "an array of length {}", N)
31    }
32
33    fn visit_seq<A>(self, mut seq: A) -> Result<[T; N], A::Error>
34    where
35        A: SeqAccess<'de>,
36    {
37        let mut arr = [T::default(); N];
38        for (i, item) in arr.iter_mut().enumerate().take(N) {
39            *item = seq
40                .next_element()?
41                .ok_or_else(|| Error::invalid_length(i, &self))?;
42        }
43        Ok(arr)
44    }
45}
46
47impl<'de> Deserialize<'de> for PortalKeyExchange {
48    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
49    where
50        D: Deserializer<'de>,
51    {
52        let visitor = ArrayVisitor {
53            element: PhantomData,
54        };
55        let res =
56            deserializer.deserialize_tuple(std::mem::size_of::<PortalKeyExchange>(), visitor)?;
57
58        Ok(Self(res))
59    }
60}
61
62impl Serialize for PortalKeyExchange {
63    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
64    where
65        S: Serializer,
66    {
67        let mut seq = serializer.serialize_tuple(self.0.len())?;
68        for elem in &self.0[..] {
69            seq.serialize_element(elem)?;
70        }
71        seq.end()
72    }
73}
74
75#[allow(clippy::from_over_into)]
76impl<'a> Into<&'a [u8]> for &'a PortalKeyExchange {
77    fn into(self) -> &'a [u8] {
78        &self.0
79    }
80}
81
82impl TryFrom<Vec<u8>> for PortalKeyExchange {
83    type Error = &'static str;
84    fn try_from(v: Vec<u8>) -> Result<Self, Self::Error> {
85        Ok(Self(
86            v.try_into()
87                .or(Err("Cannot convert into PortalKeyExchange"))?,
88        ))
89    }
90}
91
92impl<'de> Deserialize<'de> for PortalConfirmation {
93    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
94    where
95        D: Deserializer<'de>,
96    {
97        let visitor = ArrayVisitor {
98            element: PhantomData,
99        };
100        let res =
101            deserializer.deserialize_tuple(std::mem::size_of::<PortalConfirmation>(), visitor)?;
102
103        Ok(Self(res))
104    }
105}
106
107impl Serialize for PortalConfirmation {
108    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
109    where
110        S: Serializer,
111    {
112        let mut seq = serializer.serialize_tuple(self.0.len())?;
113        for elem in &self.0[..] {
114            seq.serialize_element(elem)?;
115        }
116        seq.end()
117    }
118}