1use crate::{Error, Frame, Recipient};
4use identity::Identity;
5use {
6 std::hash::{BuildHasher, Hasher},
7 twox_hash::{RandomXxHashBuilder64 as RXHash64, XxHash64},
8};
9
10pub type SeqId = Identity;
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
15pub struct XxSignature {
16 sig: u64,
17 seed: u64,
18}
19
20impl XxSignature {
21 fn new(data: &Vec<u8>) -> Self {
22 let mut hasher = RXHash64::default().build_hasher();
23 hasher.write(data);
24 Self {
25 sig: hasher.finish(),
26 seed: hasher.seed(),
27 }
28 }
29
30 fn verify(&self, data: &Vec<u8>) -> bool {
31 let mut hasher = XxHash64::with_seed(self.seed);
32 hasher.write(data);
33 hasher.finish() == self.sig
34 }
35}
36
37#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
47pub struct SeqData {
48 pub num: u32,
50 pub sig: XxSignature,
52 pub seqid: SeqId,
54 pub next: Option<u64>,
56}
57
58pub struct SeqBuilder {
64 #[doc(hidden)]
65 pub seqid: SeqId,
66 #[doc(hidden)]
67 pub sender: Identity,
68 #[doc(hidden)]
69 pub recp: Recipient,
70 #[doc(hidden)]
71 pub data: Vec<Vec<u8>>,
72}
73
74impl SeqBuilder {
75 pub fn new(sender: Identity, recp: Recipient, seqid: SeqId) -> Self {
77 Self {
78 sender,
79 recp,
80 seqid,
81 data: vec![],
82 }
83 }
84
85 pub fn add(mut self, data: Vec<u8>) -> Self {
87 self.data.push(data);
88 self
89 }
90
91 pub fn build(self) -> Vec<Frame> {
93 let seqid = self.seqid;
94 let sender = self.sender;
95 let recipient = self.recp;
96 let signed = self
97 .data
98 .into_iter()
99 .map(|d| (XxSignature::new(&d), d))
100 .collect::<Vec<_>>();
101
102 (0..signed.len())
103 .enumerate()
104 .map(|(num, i)| match (signed.get(i), signed.get(i + 1)) {
105 (
106 Some((ref sig, data)),
107 Some((
108 XxSignature {
109 sig: ref next,
110 seed: _,
111 },
112 _,
113 )),
114 ) => (
115 SeqData {
116 num: num as u32,
117 seqid,
118 sig: *sig,
119 next: Some(*next),
120 },
121 data,
122 ),
123 (Some((ref sig, data)), None) => (
124 SeqData {
125 num: num as u32,
126 seqid,
127 sig: *sig,
128 next: None,
129 },
130 data,
131 ),
132 _ => unreachable!(),
133 })
134 .map(|(seq, data)| Frame {
135 sender,
136 recipient,
137 seq,
138 payload: data.to_vec(),
139 })
140 .collect()
141 }
142
143 pub fn restore(buf: &mut Vec<Frame>) -> Vec<u8> {
148 let fake = if buf.len() == 1 {
157 buf.push(buf.get(0).unwrap().clone());
158 true
159 } else {
160 false
161 };
162
163 let wins = buf.windows(2);
164 let len = wins.len();
165
166 let r: Result<Vec<u8>, Error> = wins.enumerate().into_iter().fold(
167 Ok(Vec::with_capacity(buf.len())),
168 |mut res, (i, win)| {
169 let last = i == (len - 1);
170 let a = &win[0];
171 let seqa = &a.seq;
172 let b = &win[1];
173 let seqb = &b.seq;
174
175 if !seqa.sig.verify(&a.payload) {
176 res = Err(Error::DesequenceFault);
177 }
178
179 if last && !seqb.sig.verify(&b.payload) {
180 res = Err(Error::DesequenceFault);
181 }
182
183 fn append(vec: &mut Vec<u8>, other: &Vec<u8>) {
184 let mut f = other.clone();
185 vec.append(&mut f);
186 }
187
188 match (res, last) {
189 (Ok(mut vec), false) => {
190 append(&mut vec, &a.payload);
191 Ok(vec)
192 }
193 (Ok(mut vec), true) => {
194 append(&mut vec, &a.payload);
195
196 if !fake {
197 append(&mut vec, &b.payload);
198 }
199 Ok(vec)
200 }
201 _ => Err(Error::DesequenceFault),
202 }
203 },
204 );
205
206 r.expect("SeqBuilder::restore failed with invalid inputs!")
207 }
208
209 pub fn seqid(&self) -> &SeqId {
211 &self.seqid
212 }
213
214 pub fn sender(&self) -> Identity {
216 self.sender
217 }
218
219 pub fn recp(&self) -> Recipient {
221 self.recp
222 }
223
224 pub fn data(&self) -> Vec<u8> {
226 self.data.get(0).unwrap().clone()
227 }
228}
229
230#[cfg(test)]
231fn setup() -> Vec<Frame> {
232 let sender = Identity::with_digest(&vec![1]);
233 let recp = Identity::with_digest(&vec![2]);
234 SeqBuilder::new(sender, Recipient::User(recp), Identity::random())
235 .add(vec![42])
236 .add(vec![13, 12])
237 .add(vec![13, 37])
238 .build()
239}
240
241#[test]
242fn simple() {
243 let seq = setup();
244 assert!(seq.len() == 3);
245 assert!(seq.get(0).unwrap().seq.next == Some(seq.get(1).unwrap().seq.sig.sig));
246}
247
248#[test]
250fn seq_num() {
251 let seq = setup();
252 assert_eq!(seq[0].seq.num, 0);
253 assert_eq!(seq[1].seq.num, 1);
254 assert_eq!(seq[2].seq.num, 2);
255}
256
257#[test]
259fn hash_seq() {
260 let seq = setup();
261 assert_eq!(seq[0].seq.next, Some(seq[1].seq.sig.sig));
262 assert_eq!(seq[1].seq.next, Some(seq[2].seq.sig.sig));
263 assert_eq!(seq[2].seq.next, None);
264}