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