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