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