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