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