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