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}