ecaps2.rs

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