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
28pub fn parse_ecaps2(root: &Element) -> Result<ECaps2, Error> {
29 if !root.is("c", ns::ECAPS2) {
30 return Err(Error::ParseError("This is not an ecaps2 element."));
31 }
32 let mut hashes = vec!();
33 for child in root.children() {
34 if child.is("hash", ns::HASHES) {
35 let hash = Hash::try_from(child)?;
36 hashes.push(hash);
37 } else {
38 return Err(Error::ParseError("Unknown child in ecaps2 element."));
39 }
40 }
41 Ok(ECaps2 {
42 hashes: hashes,
43 })
44}
45
46pub fn serialise(ecaps2: &ECaps2) -> Element {
47 let mut c = Element::builder("c")
48 .ns(ns::ECAPS2)
49 .build();
50 for hash in ecaps2.hashes.clone() {
51 let hash_elem = (&hash).into();
52 c.append_child(hash_elem);
53 }
54 c
55}
56
57fn compute_item(field: &str) -> Vec<u8> {
58 let mut bytes = field.as_bytes().to_vec();
59 bytes.push(0x1f);
60 bytes
61}
62
63fn compute_items<T, F: Fn(&T) -> Vec<u8>>(things: &[T], separator: u8, encode: F) -> Vec<u8> {
64 let mut string: Vec<u8> = vec!();
65 let mut accumulator: Vec<Vec<u8>> = vec!();
66 for thing in things {
67 let bytes = encode(thing);
68 accumulator.push(bytes);
69 }
70 // This works using the expected i;octet collation.
71 accumulator.sort();
72 for mut bytes in accumulator {
73 string.append(&mut bytes);
74 }
75 string.push(separator);
76 string
77}
78
79fn compute_features(features: &[Feature]) -> Vec<u8> {
80 compute_items(features, 0x1c, |feature| compute_item(&feature.var))
81}
82
83fn compute_identities(identities: &[Identity]) -> Vec<u8> {
84 compute_items(identities, 0x1c, |identity| {
85 let mut bytes = compute_item(&identity.category);
86 bytes.append(&mut compute_item(&identity.type_));
87 bytes.append(&mut compute_item(&identity.xml_lang));
88 bytes.append(&mut compute_item(&identity.name.clone().unwrap_or_default()));
89 bytes.push(0x1e);
90 bytes
91 })
92}
93
94fn compute_extensions(extensions: &[DataForm]) -> Vec<u8> {
95 compute_items(extensions, 0x1c, |extension| {
96 compute_items(&extension.fields, 0x1d, |field| {
97 let mut bytes = compute_item(&field.var);
98 bytes.append(&mut compute_items(&field.values, 0x1e,
99 |value| compute_item(value)));
100 bytes
101 })
102 })
103}
104
105pub fn compute_disco(disco: &Disco) -> Vec<u8> {
106 let features_string = compute_features(&disco.features);
107 let identities_string = compute_identities(&disco.identities);
108 let extensions_string = compute_extensions(&disco.extensions);
109
110 let mut final_string = vec!();
111 final_string.extend(features_string);
112 final_string.extend(identities_string);
113 final_string.extend(extensions_string);
114 final_string
115}
116
117// TODO: make algo into an enum.
118pub fn hash_ecaps2(data: &[u8], algo: &str) -> String {
119 match algo {
120 "sha-256" => {
121 let mut hasher = Sha256::default();
122 hasher.input(data);
123 let hash = hasher.result();
124 base64::encode(&hash.as_slice())
125 },
126 "sha-512" => {
127 let mut hasher = Sha512::default();
128 hasher.input(data);
129 let hash = hasher.result();
130 base64::encode(&hash.as_slice())
131 },
132 "sha3-256" => {
133 let mut hasher = Sha3_256::default();
134 hasher.input(data);
135 let hash = hasher.result();
136 base64::encode(&hash.as_slice())
137 },
138 "sha3-512" => {
139 let mut hasher = Sha3_512::default();
140 hasher.input(data);
141 let hash = hasher.result();
142 base64::encode(&hash.as_slice())
143 },
144 "blake2b-256" => {
145 let mut hasher = Blake2b::default();
146 hasher.input(data);
147 let mut buf: [u8; 32] = [0; 32];
148 let hash = hasher.variable_result(&mut buf).unwrap();
149 base64::encode(hash)
150 },
151 "blake2b-512" => {
152 let mut hasher = Blake2b::default();
153 hasher.input(data);
154 let mut buf: [u8; 64] = [0; 64];
155 let hash = hasher.variable_result(&mut buf).unwrap();
156 base64::encode(hash)
157 },
158 _ => panic!(),
159 }
160}
161
162#[cfg(test)]
163mod tests {
164 use minidom::Element;
165 use error::Error;
166 use disco;
167 use ecaps2;
168 use base64;
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::parse_ecaps2(&elem).unwrap();
174 assert_eq!(ecaps2.hashes.len(), 2);
175 assert_eq!(ecaps2.hashes[0].algo, "sha-256");
176 assert_eq!(ecaps2.hashes[0].hash, "K1Njy3HZBThlo4moOD5gBGhn0U0oK7/CbfLlIUDi6o4=");
177 assert_eq!(ecaps2.hashes[1].algo, "sha3-256");
178 assert_eq!(ecaps2.hashes[1].hash, "+sDTQqBmX6iG/X3zjt06fjZMBBqL/723knFIyRf0sg8=");
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::parse_ecaps2(&elem).unwrap_err();
185 let message = match error {
186 Error::ParseError(string) => string,
187 _ => panic!(),
188 };
189 assert_eq!(message, "Unknown child in ecaps2 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 = disco::parse_disco(&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 = disco::parse_disco(&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, "sha-256");
264 assert_eq!(sha_256, "kzBZbkqJ3ADrj7v08reD1qcWUwNGHaidNUgD7nHpiw8=");
265 let sha3_256 = ecaps2::hash_ecaps2(&ecaps2, "sha3-256");
266 assert_eq!(sha3_256, "79mdYAfU9rEdTOcWDO7UEAt6E56SUzk/g6TnqUeuD9Q=");
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 = disco::parse_disco(&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, "sha-256");
436 assert_eq!(sha_256, "u79ZroNJbdSWhdSp311mddz44oHHPsEBntQ5b1jqBSY=");
437 let sha3_256 = ecaps2::hash_ecaps2(&ecaps2, "sha3-256");
438 assert_eq!(sha3_256, "XpUJzLAc93258sMECZ3FJpebkzuyNXDzRNwQog8eycg=");
439 }
440
441 #[test]
442 fn test_blake2b_512() {
443 let hash = ecaps2::hash_ecaps2("abc".as_bytes(), "blake2b-512");
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 let known_hash = base64::encode(&known_hash);
451 assert_eq!(hash, known_hash);
452 }
453}