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