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