ecaps2.rs

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