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