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