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