ecaps2.rs

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