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