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