1// Copyright (c) 2017 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7use try_from::TryFrom;
8
9use disco::{Feature, Identity, DiscoInfoResult, DiscoInfoQuery};
10use data_forms::DataForm;
11use hashes::{Hash, Algo};
12
13use minidom::Element;
14use error::Error;
15use ns;
16use base64;
17
18use sha2::{Sha256, Sha512};
19use sha3::{Sha3_256, Sha3_512};
20use blake2::Blake2b;
21use digest::{Digest, VariableOutput};
22
23#[derive(Debug, Clone)]
24pub struct ECaps2 {
25 hashes: Vec<Hash>,
26}
27
28impl TryFrom<Element> for ECaps2 {
29 type Err = Error;
30
31 fn try_from(elem: Element) -> Result<ECaps2, Error> {
32 if !elem.is("c", ns::ECAPS2) {
33 return Err(Error::ParseError("This is not an ecaps2 element."));
34 }
35 let mut hashes = vec!();
36 for child in elem.children() {
37 if child.is("hash", ns::HASHES) {
38 let hash = Hash::try_from(child.clone())?;
39 hashes.push(hash);
40 } else {
41 return Err(Error::ParseError("Unknown child in ecaps2 element."));
42 }
43 }
44 Ok(ECaps2 {
45 hashes: hashes,
46 })
47 }
48}
49
50impl From<ECaps2> for Element {
51 fn from(mut ecaps2: ECaps2) -> Element {
52 Element::builder("c")
53 .ns(ns::ECAPS2)
54 .append(ecaps2.hashes.drain(..)
55 .map(Element::from)
56 .collect::<Vec<_>>())
57 .build()
58 }
59}
60
61fn compute_item(field: &str) -> Vec<u8> {
62 let mut bytes = field.as_bytes().to_vec();
63 bytes.push(0x1f);
64 bytes
65}
66
67fn compute_items<T, F: Fn(&T) -> Vec<u8>>(things: &[T], separator: u8, encode: F) -> Vec<u8> {
68 let mut string: Vec<u8> = vec!();
69 let mut accumulator: Vec<Vec<u8>> = vec!();
70 for thing in things {
71 let bytes = encode(thing);
72 accumulator.push(bytes);
73 }
74 // This works using the expected i;octet collation.
75 accumulator.sort();
76 for mut bytes in accumulator {
77 string.append(&mut bytes);
78 }
79 string.push(separator);
80 string
81}
82
83fn compute_features(features: &[Feature]) -> Vec<u8> {
84 compute_items(features, 0x1c, |feature| compute_item(&feature.var))
85}
86
87fn compute_identities(identities: &[Identity]) -> Vec<u8> {
88 compute_items(identities, 0x1c, |identity| {
89 let mut bytes = compute_item(&identity.category);
90 bytes.append(&mut compute_item(&identity.type_));
91 bytes.append(&mut compute_item(&identity.lang.clone().unwrap_or_default()));
92 bytes.append(&mut compute_item(&identity.name.clone().unwrap_or_default()));
93 bytes.push(0x1e);
94 bytes
95 })
96}
97
98fn compute_extensions(extensions: &[DataForm]) -> Vec<u8> {
99 compute_items(extensions, 0x1c, |extension| {
100 compute_items(&extension.fields, 0x1d, |field| {
101 let mut bytes = compute_item(&field.var);
102 bytes.append(&mut compute_items(&field.values, 0x1e,
103 |value| compute_item(value)));
104 bytes
105 })
106 })
107}
108
109pub fn compute_disco(disco: &DiscoInfoResult) -> Vec<u8> {
110 let features_string = compute_features(&disco.features);
111 let identities_string = compute_identities(&disco.identities);
112 let extensions_string = compute_extensions(&disco.extensions);
113
114 let mut final_string = vec!();
115 final_string.extend(features_string);
116 final_string.extend(identities_string);
117 final_string.extend(extensions_string);
118 final_string
119}
120
121fn get_hash_vec(hash: &[u8]) -> Vec<u8> {
122 let mut vec = Vec::with_capacity(hash.len());
123 vec.extend_from_slice(hash);
124 vec
125}
126
127pub fn hash_ecaps2(data: &[u8], algo: Algo) -> Result<Hash, String> {
128 Ok(Hash {
129 hash: match algo {
130 Algo::Sha_256 => {
131 let mut hasher = Sha256::default();
132 hasher.input(data);
133 let hash = hasher.result();
134 get_hash_vec(hash.as_slice())
135 },
136 Algo::Sha_512 => {
137 let mut hasher = Sha512::default();
138 hasher.input(data);
139 let hash = hasher.result();
140 get_hash_vec(hash.as_slice())
141 },
142 Algo::Sha3_256 => {
143 let mut hasher = Sha3_256::default();
144 hasher.input(data);
145 let hash = hasher.result();
146 get_hash_vec(hash.as_slice())
147 },
148 Algo::Sha3_512 => {
149 let mut hasher = Sha3_512::default();
150 hasher.input(data);
151 let hash = hasher.result();
152 get_hash_vec(hash.as_slice())
153 },
154 Algo::Blake2b_256 => {
155 let mut hasher = Blake2b::default();
156 hasher.input(data);
157 let mut buf: [u8; 32] = [0; 32];
158 let hash = hasher.variable_result(&mut buf).unwrap();
159 get_hash_vec(hash)
160 },
161 Algo::Blake2b_512 => {
162 let mut hasher = Blake2b::default();
163 hasher.input(data);
164 let mut buf: [u8; 64] = [0; 64];
165 let hash = hasher.variable_result(&mut buf).unwrap();
166 get_hash_vec(hash)
167 },
168 Algo::Sha_1 => return Err(String::from("Disabled algorithm sha-1: unsafe.")),
169 Algo::Unknown(algo) => return Err(format!("Unknown algorithm: {}.", algo)),
170 },
171 algo: algo,
172 })
173}
174
175pub fn query_ecaps2(hash: Hash) -> DiscoInfoQuery {
176 DiscoInfoQuery {
177 node: Some(format!("{}#{}.{}", ns::ECAPS2, String::from(hash.algo), base64::encode(&hash.hash))),
178 }
179}
180
181#[cfg(test)]
182mod tests {
183 use super::*;
184 use ecaps2;
185
186 #[test]
187 fn test_parse() {
188 let elem: Element = "<c xmlns='urn:xmpp:caps'><hash xmlns='urn:xmpp:hashes:2' algo='sha-256'>K1Njy3HZBThlo4moOD5gBGhn0U0oK7/CbfLlIUDi6o4=</hash><hash xmlns='urn:xmpp:hashes:2' algo='sha3-256'>+sDTQqBmX6iG/X3zjt06fjZMBBqL/723knFIyRf0sg8=</hash></c>".parse().unwrap();
189 let ecaps2 = ECaps2::try_from(elem).unwrap();
190 assert_eq!(ecaps2.hashes.len(), 2);
191 assert_eq!(ecaps2.hashes[0].algo, Algo::Sha_256);
192 assert_eq!(ecaps2.hashes[0].hash, base64::decode("K1Njy3HZBThlo4moOD5gBGhn0U0oK7/CbfLlIUDi6o4=").unwrap());
193 assert_eq!(ecaps2.hashes[1].algo, Algo::Sha3_256);
194 assert_eq!(ecaps2.hashes[1].hash, base64::decode("+sDTQqBmX6iG/X3zjt06fjZMBBqL/723knFIyRf0sg8=").unwrap());
195 }
196
197 #[test]
198 fn test_invalid_child() {
199 let elem: Element = "<c xmlns='urn:xmpp:caps'><hash xmlns='urn:xmpp:hashes:2' algo='sha-256'>K1Njy3HZBThlo4moOD5gBGhn0U0oK7/CbfLlIUDi6o4=</hash><hash xmlns='urn:xmpp:hashes:1' algo='sha3-256'>+sDTQqBmX6iG/X3zjt06fjZMBBqL/723knFIyRf0sg8=</hash></c>".parse().unwrap();
200 let error = ECaps2::try_from(elem).unwrap_err();
201 let message = match error {
202 Error::ParseError(string) => string,
203 _ => panic!(),
204 };
205 assert_eq!(message, "Unknown child in ecaps2 element.");
206 }
207
208 #[test]
209 fn test_simple() {
210 let elem: Element = "<query xmlns='http://jabber.org/protocol/disco#info'><identity category='client' type='pc'/><feature var='http://jabber.org/protocol/disco#info'/></query>".parse().unwrap();
211 let disco = DiscoInfoResult::try_from(elem).unwrap();
212 let ecaps2 = ecaps2::compute_disco(&disco);
213 assert_eq!(ecaps2.len(), 54);
214 }
215
216 #[test]
217 fn test_xep_ex1() {
218 let elem: Element = r#"
219<query xmlns="http://jabber.org/protocol/disco#info">
220 <identity category="client" name="BombusMod" type="mobile"/>
221 <feature var="http://jabber.org/protocol/si"/>
222 <feature var="http://jabber.org/protocol/bytestreams"/>
223 <feature var="http://jabber.org/protocol/chatstates"/>
224 <feature var="http://jabber.org/protocol/disco#info"/>
225 <feature var="http://jabber.org/protocol/disco#items"/>
226 <feature var="urn:xmpp:ping"/>
227 <feature var="jabber:iq:time"/>
228 <feature var="jabber:iq:privacy"/>
229 <feature var="jabber:iq:version"/>
230 <feature var="http://jabber.org/protocol/rosterx"/>
231 <feature var="urn:xmpp:time"/>
232 <feature var="jabber:x:oob"/>
233 <feature var="http://jabber.org/protocol/ibb"/>
234 <feature var="http://jabber.org/protocol/si/profile/file-transfer"/>
235 <feature var="urn:xmpp:receipts"/>
236 <feature var="jabber:iq:roster"/>
237 <feature var="jabber:iq:last"/>
238</query>
239"#.parse().unwrap();
240 let expected = vec![104, 116, 116, 112, 58, 47, 47, 106, 97, 98, 98,
241 101, 114, 46, 111, 114, 103, 47, 112, 114, 111, 116, 111, 99, 111,
242 108, 47, 98, 121, 116, 101, 115, 116, 114, 101, 97, 109, 115, 31,
243 104, 116, 116, 112, 58, 47, 47, 106, 97, 98, 98, 101, 114, 46, 111,
244 114, 103, 47, 112, 114, 111, 116, 111, 99, 111, 108, 47, 99, 104,
245 97, 116, 115, 116, 97, 116, 101, 115, 31, 104, 116, 116, 112, 58,
246 47, 47, 106, 97, 98, 98, 101, 114, 46, 111, 114, 103, 47, 112, 114,
247 111, 116, 111, 99, 111, 108, 47, 100, 105, 115, 99, 111, 35, 105,
248 110, 102, 111, 31, 104, 116, 116, 112, 58, 47, 47, 106, 97, 98, 98,
249 101, 114, 46, 111, 114, 103, 47, 112, 114, 111, 116, 111, 99, 111,
250 108, 47, 100, 105, 115, 99, 111, 35, 105, 116, 101, 109, 115, 31,
251 104, 116, 116, 112, 58, 47, 47, 106, 97, 98, 98, 101, 114, 46, 111,
252 114, 103, 47, 112, 114, 111, 116, 111, 99, 111, 108, 47, 105, 98,
253 98, 31, 104, 116, 116, 112, 58, 47, 47, 106, 97, 98, 98, 101, 114,
254 46, 111, 114, 103, 47, 112, 114, 111, 116, 111, 99, 111, 108, 47,
255 114, 111, 115, 116, 101, 114, 120, 31, 104, 116, 116, 112, 58, 47,
256 47, 106, 97, 98, 98, 101, 114, 46, 111, 114, 103, 47, 112, 114,
257 111, 116, 111, 99, 111, 108, 47, 115, 105, 31, 104, 116, 116, 112,
258 58, 47, 47, 106, 97, 98, 98, 101, 114, 46, 111, 114, 103, 47, 112,
259 114, 111, 116, 111, 99, 111, 108, 47, 115, 105, 47, 112, 114, 111,
260 102, 105, 108, 101, 47, 102, 105, 108, 101, 45, 116, 114, 97, 110,
261 115, 102, 101, 114, 31, 106, 97, 98, 98, 101, 114, 58, 105, 113,
262 58, 108, 97, 115, 116, 31, 106, 97, 98, 98, 101, 114, 58, 105, 113,
263 58, 112, 114, 105, 118, 97, 99, 121, 31, 106, 97, 98, 98, 101, 114,
264 58, 105, 113, 58, 114, 111, 115, 116, 101, 114, 31, 106, 97, 98,
265 98, 101, 114, 58, 105, 113, 58, 116, 105, 109, 101, 31, 106, 97,
266 98, 98, 101, 114, 58, 105, 113, 58, 118, 101, 114, 115, 105, 111,
267 110, 31, 106, 97, 98, 98, 101, 114, 58, 120, 58, 111, 111, 98, 31,
268 117, 114, 110, 58, 120, 109, 112, 112, 58, 112, 105, 110, 103, 31,
269 117, 114, 110, 58, 120, 109, 112, 112, 58, 114, 101, 99, 101, 105,
270 112, 116, 115, 31, 117, 114, 110, 58, 120, 109, 112, 112, 58, 116,
271 105, 109, 101, 31, 28, 99, 108, 105, 101, 110, 116, 31, 109, 111,
272 98, 105, 108, 101, 31, 31, 66, 111, 109, 98, 117, 115, 77, 111,
273 100, 31, 30, 28, 28];
274 let disco = DiscoInfoResult::try_from(elem).unwrap();
275 let ecaps2 = ecaps2::compute_disco(&disco);
276 assert_eq!(ecaps2.len(), 0x1d9);
277 assert_eq!(ecaps2, expected);
278
279 let sha_256 = ecaps2::hash_ecaps2(&ecaps2, Algo::Sha_256).unwrap();
280 assert_eq!(sha_256.hash, base64::decode("kzBZbkqJ3ADrj7v08reD1qcWUwNGHaidNUgD7nHpiw8=").unwrap());
281 let sha3_256 = ecaps2::hash_ecaps2(&ecaps2, Algo::Sha3_256).unwrap();
282 assert_eq!(sha3_256.hash, base64::decode("79mdYAfU9rEdTOcWDO7UEAt6E56SUzk/g6TnqUeuD9Q=").unwrap());
283 }
284
285 #[test]
286 fn test_xep_ex2() {
287 let elem: Element = r#"
288<query xmlns="http://jabber.org/protocol/disco#info">
289 <identity category="client" name="Tkabber" type="pc" xml:lang="en"/>
290 <identity category="client" name="Ткаббер" type="pc" xml:lang="ru"/>
291 <feature var="games:board"/>
292 <feature var="http://jabber.org/protocol/activity"/>
293 <feature var="http://jabber.org/protocol/activity+notify"/>
294 <feature var="http://jabber.org/protocol/bytestreams"/>
295 <feature var="http://jabber.org/protocol/chatstates"/>
296 <feature var="http://jabber.org/protocol/commands"/>
297 <feature var="http://jabber.org/protocol/disco#info"/>
298 <feature var="http://jabber.org/protocol/disco#items"/>
299 <feature var="http://jabber.org/protocol/evil"/>
300 <feature var="http://jabber.org/protocol/feature-neg"/>
301 <feature var="http://jabber.org/protocol/geoloc"/>
302 <feature var="http://jabber.org/protocol/geoloc+notify"/>
303 <feature var="http://jabber.org/protocol/ibb"/>
304 <feature var="http://jabber.org/protocol/iqibb"/>
305 <feature var="http://jabber.org/protocol/mood"/>
306 <feature var="http://jabber.org/protocol/mood+notify"/>
307 <feature var="http://jabber.org/protocol/rosterx"/>
308 <feature var="http://jabber.org/protocol/si"/>
309 <feature var="http://jabber.org/protocol/si/profile/file-transfer"/>
310 <feature var="http://jabber.org/protocol/tune"/>
311 <feature var="http://www.facebook.com/xmpp/messages"/>
312 <feature var="http://www.xmpp.org/extensions/xep-0084.html#ns-metadata+notify"/>
313 <feature var="jabber:iq:avatar"/>
314 <feature var="jabber:iq:browse"/>
315 <feature var="jabber:iq:dtcp"/>
316 <feature var="jabber:iq:filexfer"/>
317 <feature var="jabber:iq:ibb"/>
318 <feature var="jabber:iq:inband"/>
319 <feature var="jabber:iq:jidlink"/>
320 <feature var="jabber:iq:last"/>
321 <feature var="jabber:iq:oob"/>
322 <feature var="jabber:iq:privacy"/>
323 <feature var="jabber:iq:roster"/>
324 <feature var="jabber:iq:time"/>
325 <feature var="jabber:iq:version"/>
326 <feature var="jabber:x:data"/>
327 <feature var="jabber:x:event"/>
328 <feature var="jabber:x:oob"/>
329 <feature var="urn:xmpp:avatar:metadata+notify"/>
330 <feature var="urn:xmpp:ping"/>
331 <feature var="urn:xmpp:receipts"/>
332 <feature var="urn:xmpp:time"/>
333 <x xmlns="jabber:x:data" type="result">
334 <field type="hidden" var="FORM_TYPE">
335 <value>urn:xmpp:dataforms:softwareinfo</value>
336 </field>
337 <field var="software">
338 <value>Tkabber</value>
339 </field>
340 <field var="software_version">
341 <value>0.11.1-svn-20111216-mod (Tcl/Tk 8.6b2)</value>
342 </field>
343 <field var="os">
344 <value>Windows</value>
345 </field>
346 <field var="os_version">
347 <value>XP</value>
348 </field>
349 </x>
350</query>
351"#.parse().unwrap();
352 let expected = vec![103, 97, 109, 101, 115, 58, 98, 111, 97, 114, 100,
353 31, 104, 116, 116, 112, 58, 47, 47, 106, 97, 98, 98, 101, 114, 46,
354 111, 114, 103, 47, 112, 114, 111, 116, 111, 99, 111, 108, 47, 97,
355 99, 116, 105, 118, 105, 116, 121, 31, 104, 116, 116, 112, 58, 47,
356 47, 106, 97, 98, 98, 101, 114, 46, 111, 114, 103, 47, 112, 114,
357 111, 116, 111, 99, 111, 108, 47, 97, 99, 116, 105, 118, 105, 116,
358 121, 43, 110, 111, 116, 105, 102, 121, 31, 104, 116, 116, 112, 58,
359 47, 47, 106, 97, 98, 98, 101, 114, 46, 111, 114, 103, 47, 112, 114,
360 111, 116, 111, 99, 111, 108, 47, 98, 121, 116, 101, 115, 116, 114,
361 101, 97, 109, 115, 31, 104, 116, 116, 112, 58,47, 47, 106, 97, 98,
362 98, 101, 114, 46, 111, 114, 103, 47, 112, 114, 111, 116, 111, 99,
363 111, 108, 47, 99, 104, 97, 116, 115, 116, 97, 116, 101, 115, 31,
364 104, 116, 116, 112, 58, 47, 47, 106, 97, 98, 98, 101, 114, 46, 111,
365 114, 103, 47, 112, 114, 111, 116, 111, 99, 111, 108, 47, 99, 111,
366 109, 109, 97, 110, 100, 115, 31,104,116, 116, 112, 58, 47, 47, 106,
367 97, 98, 98, 101, 114, 46, 111, 114, 103, 47, 112, 114, 111, 116,
368 111, 99, 111, 108, 47, 100, 105, 115, 99, 111, 35, 105, 110, 102,
369 111, 31, 104, 116, 116, 112, 58, 47, 47, 106, 97, 98, 98, 101, 114,
370 46, 111, 114, 103, 47, 112, 114, 111, 116, 111, 99, 111, 108, 47,
371 100, 105, 115, 99, 111, 35, 105, 116, 101, 109, 115, 31, 104, 116,
372 116, 112, 58, 47, 47, 106, 97, 98, 98, 101, 114, 46, 111, 114, 103,
373 47, 112, 114, 111, 116, 111, 99, 111, 108, 47, 101, 118, 105, 108,
374 31, 104, 116, 116, 112, 58, 47, 47, 106, 97, 98, 98, 101, 114, 46,
375 111, 114, 103, 47, 112, 114, 111, 116, 111, 99, 111, 108, 47, 102,
376 101, 97, 116, 117, 114, 101, 45, 110, 101, 103, 31, 104, 116, 116,
377 112, 58, 47, 47, 106, 97, 98, 98, 101, 114, 46, 111, 114, 103, 47,
378 112, 114, 111, 116, 111, 99, 111, 108, 47, 103, 101, 111, 108, 111,
379 99, 31, 104, 116, 116, 112, 58, 47, 47, 106, 97, 98, 98, 101, 114,
380 46, 111, 114, 103, 47, 112, 114, 111, 116, 111, 99,111, 108, 47,
381 103, 101, 111, 108, 111, 99, 43, 110, 111, 116, 105, 102, 121, 31,
382 104, 116, 116, 112, 58, 47, 47, 106, 97, 98, 98, 101, 114, 46, 111,
383 114, 103,47, 112, 114, 111, 116, 111, 99, 111, 108, 47, 105, 98,
384 98, 31, 104, 116, 116, 112, 58, 47, 47, 106, 97, 98, 98, 101, 114,
385 46, 111, 114, 103, 47, 112, 114, 111,116, 111, 99, 111, 108, 47,
386 105, 113, 105, 98, 98, 31, 104, 116, 116, 112, 58, 47, 47, 106, 97,
387 98, 98, 101, 114, 46, 111, 114, 103, 47, 112, 114, 111, 116,111,
388 99, 111, 108, 47, 109, 111, 111, 100, 31, 104, 116, 116, 112, 58,
389 47, 47, 106, 97, 98, 98, 101, 114, 46, 111, 114, 103, 47, 112, 114,
390 111, 116, 111, 99, 111,108, 47, 109, 111, 111, 100, 43, 110, 111,
391 116, 105, 102, 121, 31, 104, 116, 116, 112, 58, 47, 47, 106, 97,
392 98, 98, 101, 114, 46, 111, 114, 103, 47, 112, 114, 111, 116, 111,
393 99, 111, 108, 47, 114, 111, 115, 116, 101, 114, 120, 31, 104, 116,
394 116, 112, 58, 47, 47, 106, 97, 98, 98, 101, 114, 46, 111, 114, 103,
395 47, 112, 114, 111, 116, 111, 99, 111, 108, 47, 115, 105, 31, 104,
396 116, 116, 112, 58, 47, 47, 106, 97, 98, 98, 101, 114, 46, 111, 114,
397 103, 47, 112, 114, 111, 116, 111, 99, 111, 108, 47, 115, 105, 47,
398 112, 114, 111, 102, 105, 108, 101, 47, 102, 105, 108, 101, 45, 116,
399 114, 97, 110, 115, 102, 101, 114, 31, 104, 116, 116, 112, 58, 47,
400 47, 106, 97, 98, 98, 101, 114, 46, 111, 114, 103, 47, 112, 114,
401 111, 116, 111, 99, 111, 108, 47, 116, 117, 110, 101, 31, 104, 116,
402 116, 112, 58, 47, 47, 119, 119, 119, 46, 102, 97, 99, 101, 98, 111,
403 111, 107, 46, 99, 111, 109, 47, 120, 109, 112, 112, 47, 109, 101,
404 115, 115, 97, 103, 101, 115, 31, 104, 116, 116, 112, 58, 47, 47,
405 119, 119, 119, 46, 120, 109, 112, 112, 46, 111, 114, 103, 47, 101,
406 120, 116, 101, 110, 115, 105, 111, 110, 115, 47, 120, 101, 112, 45,
407 48, 48, 56, 52, 46, 104, 116, 109, 108, 35, 110, 115, 45, 109, 101,
408 116, 97, 100, 97, 116, 97, 43, 110, 111, 116, 105, 102, 121, 31,
409 106, 97, 98, 98, 101, 114,58, 105,113, 58, 97, 118, 97, 116, 97,
410 114, 31, 106, 97, 98, 98, 101, 114, 58, 105, 113, 58, 98, 114, 111,
411 119, 115, 101, 31, 106, 97, 98, 98, 101, 114, 58, 105, 113, 58,
412 100, 116, 99, 112, 31, 106, 97, 98, 98, 101, 114, 58, 105, 113, 58,
413 102, 105, 108, 101, 120, 102, 101, 114, 31, 106, 97, 98, 98, 101,
414 114, 58, 105, 113, 58, 105, 98, 98, 31, 106, 97, 98, 98, 101, 114,
415 58, 105, 113, 58, 105, 110, 98, 97, 110, 100, 31, 106, 97, 98, 98,
416 101, 114, 58, 105, 113, 58, 106, 105, 100, 108, 105, 110, 107, 31,
417 106, 97, 98, 98, 101, 114, 58, 105, 113, 58, 108, 97, 115, 116, 31,
418 106, 97, 98, 98, 101, 114, 58, 105, 113, 58, 111, 111, 98, 31, 106,
419 97,98, 98, 101, 114, 58, 105, 113, 58, 112, 114, 105, 118, 97, 99,
420 121, 31, 106, 97, 98, 98, 101, 114, 58, 105, 113, 58, 114, 111,
421 115, 116, 101, 114,31, 106, 97, 98, 98, 101, 114, 58, 105, 113, 58,
422 116, 105, 109, 101, 31, 106, 97, 98, 98, 101, 114, 58, 105, 113,
423 58, 118, 101, 114, 115, 105, 111, 110, 31, 106, 97, 98, 98, 101,
424 114, 58, 120, 58, 100, 97, 116, 97, 31, 106, 97, 98, 98, 101, 114,
425 58, 120, 58, 101, 118, 101, 110, 116, 31, 106, 97, 98, 98, 101,
426 114, 58, 120, 58, 111, 111, 98, 31, 117, 114, 110, 58, 120, 109,
427 112, 112, 58, 97, 118, 97, 116, 97, 114, 58, 109, 101, 116, 97,
428 100, 97, 116, 97, 43, 110, 111, 116, 105, 102, 121,31, 117, 114,
429 110, 58, 120, 109, 112, 112, 58, 112, 105, 110, 103, 31, 117, 114,
430 110, 58, 120, 109, 112, 112, 58, 114, 101, 99, 101, 105, 112, 116,
431 115, 31, 117, 114, 110, 58, 120, 109, 112, 112, 58, 116, 105, 109,
432 101, 31, 28, 99, 108, 105, 101, 110, 116, 31, 112, 99, 31, 101,
433 110, 31, 84, 107, 97, 98, 98, 101, 114,31, 30, 99, 108, 105, 101,
434 110, 116, 31, 112, 99, 31, 114, 117, 31, 208, 162, 208, 186, 208,
435 176, 208, 177, 208, 177, 208, 181, 209, 128, 31, 30, 28, 70, 79,
436 82, 77, 95, 84, 89, 80, 69, 31, 117, 114, 110, 58, 120, 109, 112,
437 112, 58, 100, 97, 116, 97, 102, 111, 114, 109, 115, 58, 115, 111,
438 102, 116, 119, 97, 114, 101,105, 110, 102, 111, 31, 30, 111, 115,
439 31, 87, 105, 110, 100, 111, 119, 115, 31, 30, 111, 115, 95, 118,
440 101, 114, 115, 105, 111, 110, 31, 88, 80, 31, 30, 115, 111, 102,
441 116, 119, 97, 114, 101, 31, 84, 107, 97, 98, 98, 101, 114, 31, 30,
442 115, 111, 102, 116, 119, 97, 114, 101, 95, 118, 101, 114, 115, 105,
443 111, 110, 31, 48, 46, 49, 49, 46, 49, 45, 115, 118, 110, 45, 50,
444 48, 49, 49, 49, 50, 49, 54, 45, 109, 111, 100, 32, 40, 84, 99, 108,
445 47, 84, 107, 32, 56, 46,54, 98, 50, 41, 31, 30, 29, 28];
446 let disco = DiscoInfoResult::try_from(elem).unwrap();
447 let ecaps2 = ecaps2::compute_disco(&disco);
448 assert_eq!(ecaps2.len(), 0x543);
449 assert_eq!(ecaps2, expected);
450
451 let sha_256 = ecaps2::hash_ecaps2(&ecaps2, Algo::Sha_256).unwrap();
452 assert_eq!(sha_256.hash, base64::decode("u79ZroNJbdSWhdSp311mddz44oHHPsEBntQ5b1jqBSY=").unwrap());
453 let sha3_256 = ecaps2::hash_ecaps2(&ecaps2, Algo::Sha3_256).unwrap();
454 assert_eq!(sha3_256.hash, base64::decode("XpUJzLAc93258sMECZ3FJpebkzuyNXDzRNwQog8eycg=").unwrap());
455 }
456
457 #[test]
458 fn test_blake2b_512() {
459 let hash = ecaps2::hash_ecaps2("abc".as_bytes(), Algo::Blake2b_512).unwrap();
460 let known_hash: Vec<u8> = vec!(
461 0xBA, 0x80, 0xA5, 0x3F, 0x98, 0x1C, 0x4D, 0x0D, 0x6A, 0x27, 0x97, 0xB6, 0x9F, 0x12, 0xF6, 0xE9,
462 0x4C, 0x21, 0x2F, 0x14, 0x68, 0x5A, 0xC4, 0xB7, 0x4B, 0x12, 0xBB, 0x6F, 0xDB, 0xFF, 0xA2, 0xD1,
463 0x7D, 0x87, 0xC5, 0x39, 0x2A, 0xAB, 0x79, 0x2D, 0xC2, 0x52, 0xD5, 0xDE, 0x45, 0x33, 0xCC, 0x95,
464 0x18, 0xD3, 0x8A, 0xA8, 0xDB, 0xF1, 0x92, 0x5A, 0xB9, 0x23, 0x86, 0xED, 0xD4, 0x00, 0x99, 0x23,
465 );
466 assert_eq!(hash.hash, known_hash);
467 }
468}