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