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 digest::VariableOutput;
 18use base64;
 19
 20#[derive(Debug, Clone)]
 21pub struct ECaps2 {
 22    hashes: Vec<Hash>,
 23}
 24
 25pub fn parse_ecaps2(root: &Element) -> Result<ECaps2, Error> {
 26    if !root.is("c", ns::ECAPS2) {
 27        return Err(Error::ParseError("This is not an ecaps2 element."));
 28    }
 29    let mut hashes = vec!();
 30    for child in root.children() {
 31        if child.is("hash", ns::HASHES) {
 32            let hash = parse_hash(child)?;
 33            hashes.push(hash);
 34        } else {
 35            return Err(Error::ParseError("Unknown child in ecaps2 element."));
 36        }
 37    }
 38    Ok(ECaps2 {
 39        hashes: hashes,
 40    })
 41}
 42
 43pub fn serialise(ecaps2: &ECaps2) -> Element {
 44    let mut c = Element::builder("c")
 45                        .ns(ns::ECAPS2)
 46                        .build();
 47    for hash in ecaps2.hashes.clone() {
 48        let hash_elem = hashes::serialise(&hash);
 49        c.append_child(hash_elem);
 50    }
 51    c
 52}
 53
 54fn compute_item(field: &str) -> Vec<u8> {
 55    let mut bytes = field.as_bytes().to_vec();
 56    bytes.push(0x1f);
 57    bytes
 58}
 59
 60fn compute_items<T, F: Fn(&T) -> Vec<u8>>(things: &[T], separator: u8, encode: F) -> Vec<u8> {
 61    let mut string: Vec<u8> = vec!();
 62    let mut accumulator: Vec<Vec<u8>> = vec!();
 63    for thing in things {
 64        let bytes = encode(thing);
 65        accumulator.push(bytes);
 66    }
 67    // This works using the expected i;octet collation.
 68    accumulator.sort();
 69    for mut bytes in accumulator {
 70        string.append(&mut bytes);
 71    }
 72    string.push(separator);
 73    string
 74}
 75
 76fn compute_features(features: &[Feature]) -> Vec<u8> {
 77    compute_items(features, 0x1c, |feature| compute_item(&feature.var))
 78}
 79
 80fn compute_identities(identities: &[Identity]) -> Vec<u8> {
 81    compute_items(identities, 0x1c, |identity| {
 82        let mut bytes = compute_item(&identity.category);
 83        bytes.append(&mut compute_item(&identity.type_));
 84        bytes.append(&mut compute_item(&identity.xml_lang));
 85        bytes.append(&mut compute_item(&identity.name.clone().unwrap_or_default()));
 86        bytes.push(0x1e);
 87        bytes
 88    })
 89}
 90
 91fn compute_extensions(extensions: &[DataForm]) -> Vec<u8> {
 92    compute_items(extensions, 0x1c, |extension| {
 93        compute_items(&extension.fields, 0x1d, |field| {
 94            let mut bytes = compute_item(&field.var);
 95            bytes.append(&mut compute_items(&field.values, 0x1e,
 96                                            |value| compute_item(value)));
 97            bytes
 98        })
 99    })
100}
101
102pub fn compute_disco(disco: &Disco) -> Vec<u8> {
103    let features_string = compute_features(&disco.features);
104    let identities_string = compute_identities(&disco.identities);
105    let extensions_string = compute_extensions(&disco.extensions);
106
107    let mut final_string = vec!();
108    final_string.extend(features_string);
109    final_string.extend(identities_string);
110    final_string.extend(extensions_string);
111    final_string
112}
113
114// TODO: make algo into an enum.
115pub fn hash_ecaps2(data: &[u8], algo: &str) -> String {
116    match algo {
117        "sha-256" => {
118            let mut hasher = Sha256::default();
119            hasher.input(data);
120            let hash = hasher.result();
121            base64::encode(&hash)
122        },
123        "sha-512" => {
124            let mut hasher = Sha512::default();
125            hasher.input(data);
126            let hash = hasher.result();
127            base64::encode(&hash)
128        },
129        "sha3-256" => {
130            let mut hasher = Sha3_256::default();
131            hasher.input(data);
132            let hash = hasher.result();
133            base64::encode(&hash)
134        },
135        "sha3-512" => {
136            let mut hasher = Sha3_512::default();
137            hasher.input(data);
138            let hash = hasher.result();
139            base64::encode(&hash)
140        },
141        "blake2b-256" => {
142            let mut hasher = Blake2b::default();
143            hasher.input(data);
144            let mut buf: [u8; 32] = [0; 32];
145            let hash = hasher.variable_result(&mut buf).unwrap();
146            base64::encode(&hash)
147        },
148        "blake2b-512" => {
149            let mut hasher = Blake2b::default();
150            hasher.input(data);
151            let mut buf: [u8; 64] = [0; 64];
152            let hash = hasher.variable_result(&mut buf).unwrap();
153            base64::encode(&hash)
154        },
155        _ => panic!(),
156    }
157}
158
159#[cfg(test)]
160mod tests {
161    use minidom::Element;
162    use error::Error;
163    use disco;
164    use ecaps2;
165    use base64;
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
438    #[test]
439    fn test_blake2b_512() {
440        let hash = ecaps2::hash_ecaps2("abc".as_bytes(), "blake2b-512");
441        let known_hash: [u8; 64] = [
442            0xBA, 0x80, 0xA5, 0x3F, 0x98, 0x1C, 0x4D, 0x0D, 0x6A, 0x27, 0x97, 0xB6, 0x9F, 0x12, 0xF6, 0xE9,
443            0x4C, 0x21, 0x2F, 0x14, 0x68, 0x5A, 0xC4, 0xB7, 0x4B, 0x12, 0xBB, 0x6F, 0xDB, 0xFF, 0xA2, 0xD1,
444            0x7D, 0x87, 0xC5, 0x39, 0x2A, 0xAB, 0x79, 0x2D, 0xC2, 0x52, 0xD5, 0xDE, 0x45, 0x33, 0xCC, 0x95,
445            0x18, 0xD3, 0x8A, 0xA8, 0xDB, 0xF1, 0x92, 0x5A, 0xB9, 0x23, 0x86, 0xED, 0xD4, 0x00, 0x99, 0x23,
446        ];
447        let known_hash = base64::encode(&known_hash);
448        assert_eq!(hash, known_hash);
449    }
450}