tentacle_secio/handshake/
handshake_struct.rs

1use crate::handshake::handshake_mol;
2use molecule::prelude::{Builder, Entity, Reader};
3
4use crate::peer_id::PeerId;
5
6use bytes::Bytes;
7use std::fmt;
8
9#[derive(Clone, Default, PartialEq, Ord, PartialOrd, Eq, Debug)]
10pub struct Propose {
11    pub(crate) rand: Vec<u8>,
12    /// flatbuffer public key bytes
13    pub(crate) pubkey: Bytes,
14    pub(crate) exchange: String,
15    pub(crate) ciphers: String,
16    pub(crate) hashes: String,
17}
18
19impl Propose {
20    pub fn new() -> Self {
21        Default::default()
22    }
23
24    /// Encode with molecule
25    pub fn encode(self) -> Bytes {
26        let rand = handshake_mol::Bytes::new_builder()
27            .set(self.rand.into_iter().map(Into::into).collect())
28            .build();
29        let pubkey = handshake_mol::Bytes::new_builder()
30            .set(self.pubkey.iter().copied().map(Into::into).collect())
31            .build();
32        let exchange = handshake_mol::String::new_builder()
33            .set(
34                self.exchange
35                    .into_bytes()
36                    .into_iter()
37                    .map(Into::into)
38                    .collect(),
39            )
40            .build();
41        let ciphers = handshake_mol::String::new_builder()
42            .set(
43                self.ciphers
44                    .into_bytes()
45                    .into_iter()
46                    .map(Into::into)
47                    .collect(),
48            )
49            .build();
50        let hashes = handshake_mol::String::new_builder()
51            .set(
52                self.hashes
53                    .into_bytes()
54                    .into_iter()
55                    .map(Into::into)
56                    .collect(),
57            )
58            .build();
59
60        handshake_mol::Propose::new_builder()
61            .rand(rand)
62            .pubkey(pubkey)
63            .exchanges(exchange)
64            .ciphers(ciphers)
65            .hashes(hashes)
66            .build()
67            .as_bytes()
68    }
69
70    /// Decode with molecule
71    pub fn decode(data: &[u8]) -> Option<Self> {
72        let reader = handshake_mol::ProposeReader::from_compatible_slice(data).ok()?;
73        Some(Propose {
74            rand: reader.rand().raw_data().to_owned(),
75            pubkey: Bytes::from(reader.pubkey().raw_data().to_owned()),
76            exchange: String::from_utf8(reader.exchanges().raw_data().to_owned()).ok()?,
77            ciphers: String::from_utf8(reader.ciphers().raw_data().to_owned()).ok()?,
78            hashes: String::from_utf8(reader.hashes().raw_data().to_owned()).ok()?,
79        })
80    }
81}
82
83#[derive(Clone, Default, PartialEq, Ord, PartialOrd, Eq, Debug)]
84pub struct Exchange {
85    pub(crate) epubkey: Vec<u8>,
86    pub(crate) signature: Vec<u8>,
87}
88
89impl Exchange {
90    pub fn new() -> Self {
91        Default::default()
92    }
93
94    /// Encode with molecule
95    pub fn encode(self) -> Bytes {
96        let epubkey = handshake_mol::Bytes::new_builder()
97            .set(self.epubkey.into_iter().map(Into::into).collect())
98            .build();
99        let signature = handshake_mol::Bytes::new_builder()
100            .set(self.signature.into_iter().map(Into::into).collect())
101            .build();
102
103        handshake_mol::Exchange::new_builder()
104            .epubkey(epubkey)
105            .signature(signature)
106            .build()
107            .as_bytes()
108    }
109
110    /// Decode with molecule
111    pub fn decode(data: &[u8]) -> Option<Self> {
112        let reader = handshake_mol::ExchangeReader::from_compatible_slice(data).ok()?;
113        Some(Exchange {
114            epubkey: reader.epubkey().raw_data().to_owned(),
115            signature: reader.signature().raw_data().to_owned(),
116        })
117    }
118}
119
120/// Public Key
121#[derive(Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
122pub struct PublicKey {
123    pub(crate) key: Vec<u8>,
124}
125
126impl PublicKey {
127    /// Get inner data
128    pub fn inner_ref(&self) -> &[u8] {
129        &self.key
130    }
131
132    /// Get inner data
133    pub fn inner(self) -> Vec<u8> {
134        self.key
135    }
136
137    /// from raw pubkey
138    pub fn from_raw_key(pubkey: Vec<u8>) -> Self {
139        PublicKey { key: pubkey }
140    }
141
142    /// Encode with molecule
143    pub fn encode(self) -> Bytes {
144        let secp256k1 = handshake_mol::Secp256k1::new_builder()
145            .set(self.inner().into_iter().map(Into::into).collect())
146            .build();
147        let pubkey = handshake_mol::PublicKey::new_builder()
148            .set(secp256k1)
149            .build();
150        pubkey.as_bytes()
151    }
152
153    /// Decode with molecule
154    pub fn decode(data: &[u8]) -> Option<Self> {
155        let reader = handshake_mol::PublicKeyReader::from_compatible_slice(data).ok()?;
156        let union = reader.to_enum();
157
158        match union {
159            handshake_mol::PublicKeyUnionReader::Secp256k1(reader) => Some(PublicKey {
160                key: reader.raw_data().to_owned(),
161            }),
162        }
163    }
164
165    /// Generate Peer id
166    pub fn peer_id(&self) -> PeerId {
167        PeerId::from_public_key(self)
168    }
169}
170
171impl fmt::Debug for PublicKey {
172    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
173        write!(f, "0x")?;
174        for byte in self.inner_ref() {
175            write!(f, "{:02x}", byte)?;
176        }
177        Ok(())
178    }
179}
180
181#[cfg(test)]
182mod tests {
183    use super::{Exchange, Propose, PublicKey};
184    use crate::SecioKeyPair;
185    use bytes::Bytes;
186
187    #[test]
188    fn decode_encode_pubkey() {
189        let raw = SecioKeyPair::secp256k1_generated().public_key();
190        let byte = raw.clone();
191
192        assert_eq!(raw, PublicKey::decode(&byte.encode()).unwrap())
193    }
194
195    #[test]
196    fn decode_encode_propose() {
197        let nonce: [u8; 16] = rand::random();
198        let mut raw = Propose::new();
199        raw.rand = nonce.to_vec();
200        raw.pubkey = Bytes::from(vec![25u8; 256]);
201
202        let byte = raw.clone();
203
204        assert_eq!(raw, Propose::decode(&byte.encode()).unwrap())
205    }
206
207    #[test]
208    fn decode_encode_exchange() {
209        let mut raw = Exchange::new();
210        raw.signature = vec![1u8; 256];
211        raw.epubkey = vec![9u8; 256];
212
213        let byte = raw.clone();
214
215        assert_eq!(raw, Exchange::decode(&byte.encode()).unwrap())
216    }
217}