1use std::ops::BitXor;
19use std::mem;
20use cryptoutil::copy_memory;
21
22use cryptoutil::{read_u32_be, write_u32_be};
23use mac::{Mac, MacResult};
24use simd;
25
26#[derive(Clone, Copy)]
29struct Gf128 { d: simd::u32x4 }
30
31impl Gf128 {
32 fn new(a: u32, b: u32, c: u32, d: u32) -> Gf128 {
33 Gf128 { d: simd::u32x4(a, b, c, d) }
34 }
35
36 fn from_bytes(bytes: &[u8]) -> Gf128 {
37 assert!(bytes.len() == 16);
38 let d = read_u32_be(&bytes[0..4]);
39 let c = read_u32_be(&bytes[4..8]);
40 let b = read_u32_be(&bytes[8..12]);
41 let a = read_u32_be(&bytes[12..16]);
42 Gf128::new(a, b, c, d)
43 }
44
45 fn to_bytes(&self) -> [u8; 16] {
46 let simd::u32x4(a, b, c, d) = self.d;
47 let mut result: [u8; 16] = unsafe { mem::uninitialized() };
48
49 write_u32_be(&mut result[0..4], d);
50 write_u32_be(&mut result[4..8], c);
51 write_u32_be(&mut result[8..12], b);
52 write_u32_be(&mut result[12..16], a);
53
54 result
55 }
56
57 fn times_x(self) -> Gf128 {
60 let simd::u32x4(a, b, c, d) = self.d;
61 Gf128::new(a >> 1 | b << 31, b >> 1 | c << 31, c >> 1 | d << 31, d >> 1)
62 }
63
64 fn times_x_reduce(self) -> Gf128 {
68 let r = Gf128::new(0, 0, 0, 0b1110_0001 << 24);
69 self.cond_xor(r, self.times_x())
70 }
71
72 fn add_and_mul(&mut self, y: Gf128, hs: &[Gf128; 128]) {
74 *self = *self ^ y;
75 let mut x = mem::replace(self, Gf128::new(0, 0, 0, 0));
76
77 for &y in hs.iter().rev() {
78 *self = x.cond_xor(y, *self);
79 x = x.times_x();
80 }
81 }
82
83 fn cond_xor(self, x: Gf128, y: Gf128) -> Gf128 {
85 use simd::SimdExt;
86 let lsb = simd::u32x4(1, 0, 0, 0);
87 let simd::u32x4(m, _, _, _) = (self.d & lsb).simd_eq(lsb);
88 let mask = simd::u32x4(m, m, m, m);
89 Gf128 { d: (x.d & mask) ^ y.d }
90 }
91}
92
93impl BitXor for Gf128 {
94 type Output = Gf128;
95
96 fn bitxor(self, rhs: Gf128) -> Gf128 {
97 Gf128 { d: self.d ^ rhs.d }
98 }
99}
100
101#[derive(Copy)]
103pub struct Ghash {
104 hs: [Gf128; 128],
105 state: Gf128,
106 a_len: usize,
107 rest: Option<[u8; 16]>,
108 finished: bool
109}
110
111impl Clone for Ghash { fn clone(&self) -> Ghash { *self } }
112
113#[derive(Copy)]
115pub struct GhashWithC {
116 hs: [Gf128; 128],
117 state: Gf128,
118 a_len: usize,
119 c_len: usize,
120 rest: Option<[u8; 16]>
121}
122
123impl Clone for GhashWithC { fn clone(&self) -> GhashWithC { *self } }
124
125fn update(state: &mut Gf128, len: &mut usize, data: &[u8], srest: &mut Option<[u8; 16]>,
126 hs: &[Gf128; 128]) {
127 let rest_len = *len % 16;
128 let data_len = data.len();
129 *len += data_len;
130
131 let data = match srest.take() {
132 None => data,
133 Some(mut rest) => {
134 if 16 - rest_len > data_len {
135 copy_memory(data, &mut rest[rest_len..]);
136 *srest = Some(rest);
137 return;
138 }
139
140 let (fill, data) = data.split_at(16 - rest_len);
141 copy_memory(fill, &mut rest[rest_len..]);
142 state.add_and_mul(Gf128::from_bytes(&rest), hs);
143 data
144 }
145 };
146
147 let (data, rest) = data.split_at(data_len - data_len % 16);
148
149 for chunk in data.chunks(16) {
150 let x = Gf128::from_bytes(chunk);
151 state.add_and_mul(x, hs);
152 }
153
154 if rest.len() != 0 {
155 let mut tmp = [0; 16];
156 copy_memory(rest, &mut tmp);
157 *srest = Some(tmp);
158 }
159}
160
161impl Ghash {
162 #[inline]
164 pub fn new(h: &[u8]) -> Ghash {
165 assert!(h.len() == 16);
166 let mut table: [Gf128; 128] = unsafe { mem::uninitialized() };
167
168 let mut h = Gf128::from_bytes(h);
170 for poly in table.iter_mut() {
171 *poly = h;
172 h = h.times_x_reduce();
173 }
174
175 Ghash {
176 hs: table,
177 state: Gf128::new(0, 0, 0, 0),
178 a_len: 0,
179 rest: None,
180 finished: false
181 }
182 }
183
184 fn flush(&mut self) {
185 for rest in self.rest.take().iter() {
186 self.state.add_and_mul(Gf128::from_bytes(rest), &self.hs);
187 }
188 }
189
190 #[inline]
192 pub fn input_a(mut self, a: &[u8]) -> Ghash {
193 assert!(!self.finished);
194 update(&mut self.state, &mut self.a_len, a, &mut self.rest, &self.hs);
195 self
196 }
197
198 #[inline]
200 pub fn input_c(mut self, c: &[u8]) -> GhashWithC {
201 assert!(!self.finished);
202 self.flush();
203
204 let mut c_len = 0;
205 update(&mut self.state, &mut c_len, c, &mut self.rest, &self.hs);
206
207 let Ghash { hs, state, a_len, rest, .. } = self;
208 GhashWithC {
209 hs: hs,
210 state: state,
211 a_len: a_len,
212 c_len: c_len,
213 rest: rest
214 }
215 }
216
217 #[inline]
219 pub fn result(mut self) -> [u8; 16] {
220 if !self.finished {
221 self.flush();
222
223 let a_len = self.a_len as u64 * 8;
224 let lens = Gf128::new(0, 0, a_len as u32, (a_len >> 32) as u32);
225 self.state.add_and_mul(lens, &self.hs);
226
227 self.finished = true;
228 }
229
230 self.state.to_bytes()
231 }
232}
233
234impl GhashWithC {
235 #[inline]
237 pub fn input_c(mut self, c: &[u8]) -> GhashWithC {
238 update(&mut self.state, &mut self.c_len, c, &mut self.rest, &self.hs);
239 self
240 }
241
242 #[inline]
244 pub fn result(mut self) -> [u8; 16] {
245 for rest in self.rest.take().iter() {
246 self.state.add_and_mul(Gf128::from_bytes(rest), &self.hs);
247 }
248
249 let a_len = self.a_len as u64 * 8;
250 let c_len = self.c_len as u64 * 8;
251 let lens = Gf128::new(c_len as u32, (c_len >> 32) as u32,
252 a_len as u32, (a_len >> 32) as u32);
253 self.state.add_and_mul(lens, &self.hs);
254
255 self.state.to_bytes()
256 }
257}
258
259impl Mac for Ghash {
260 fn input(&mut self, data: &[u8]) {
261 assert!(!self.finished);
262 update(&mut self.state, &mut self.a_len, data, &mut self.rest, &self.hs);
263 }
264
265 fn reset(&mut self) {
266 self.state = Gf128::new(0, 0, 0, 0);
267 self.a_len = 0;
268 self.rest = None;
269 self.finished = false;
270 }
271
272 fn result(&mut self) -> MacResult {
273 let mut mac = [0u8; 16];
274 self.raw_result(&mut mac[..]);
275 MacResult::new(&mac[..])
276 }
277
278 fn raw_result(&mut self, output: &mut [u8]) {
279 assert!(output.len() >= 16);
280 if !self.finished {
281 self.flush();
282
283 let a_len = self.a_len as u64 * 8;
284 let lens = Gf128::new(0, 0, a_len as u32, (a_len >> 32) as u32);
285 self.state.add_and_mul(lens, &self.hs);
286
287 self.finished = true;
288 }
289
290 copy_memory(&self.state.to_bytes(), output);
291 }
292
293 fn output_bytes(&self) -> usize { 16 }
294}
295
296#[cfg(test)]
297mod test {
298 use ghash::Ghash;
299
300 static CASES: &'static [(&'static [u8], &'static [u8], &'static [u8], &'static [u8])] = &[
303 (&[0x66, 0xe9, 0x4b, 0xd4, 0xef, 0x8a, 0x2c, 0x3b,
307 0x88, 0x4c, 0xfa, 0x59, 0xca, 0x34, 0x2b, 0x2e],
308 &[],
309 &[],
310 &[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
311 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]),
312
313 (&[0x66, 0xe9, 0x4b, 0xd4, 0xef, 0x8a, 0x2c, 0x3b,
315 0x88, 0x4c, 0xfa, 0x59, 0xca, 0x34, 0x2b, 0x2e],
316 &[],
317 &[0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
318 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78],
319 &[0xf3, 0x8c, 0xbb, 0x1a, 0xd6, 0x92, 0x23, 0xdc,
320 0xc3, 0x45, 0x7a, 0xe5, 0xb6, 0xb0, 0xf8, 0x85]),
321
322 (&[0xb8, 0x3b, 0x53, 0x37, 0x08, 0xbf, 0x53, 0x5d,
324 0x0a, 0xa6, 0xe5, 0x29, 0x80, 0xd5, 0x3b, 0x78],
325 &[],
326 &[0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0,
327 0xd4, 0x9c, 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, 0x35, 0xc1, 0x7e, 0x23,
328 0x29, 0xac, 0xa1, 0x2e, 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, 0x7d, 0x8f,
329 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
330 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85],
331 &[0x7f, 0x1b, 0x32, 0xb8, 0x1b, 0x82, 0x0d, 0x02,
332 0x61, 0x4f, 0x88, 0x95, 0xac, 0x1d, 0x4e, 0xac]),
333
334 (&[0xb8, 0x3b, 0x53, 0x37, 0x08, 0xbf, 0x53, 0x5d,
336 0x0a, 0xa6, 0xe5, 0x29, 0x80, 0xd5, 0x3b, 0x78],
337 &[0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed,
338 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2],
339 &[0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0,
340 0xd4, 0x9c, 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, 0x35, 0xc1, 0x7e, 0x23,
341 0x29, 0xac, 0xa1, 0x2e, 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, 0x7d, 0x8f,
342 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
343 0x3d, 0x58, 0xe0, 0x91],
344 &[0x69, 0x8e, 0x57, 0xf7, 0x0e, 0x6e, 0xcc, 0x7f,
345 0xd9, 0x46, 0x3b, 0x72, 0x60, 0xa9, 0xae, 0x5f]),
346
347 (&[0xb8, 0x3b, 0x53, 0x37, 0x08, 0xbf, 0x53, 0x5d,
349 0x0a, 0xa6, 0xe5, 0x29, 0x80, 0xd5, 0x3b, 0x78],
350 &[0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed,
351 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2],
352 &[0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a, 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a,
353 0x47, 0x55, 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8, 0x37, 0x66, 0xe5, 0xf9,
354 0x7b, 0x6c, 0x74, 0x23, 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2, 0x2b, 0x09,
355 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42, 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
356 0xc2, 0x3f, 0x45, 0x98],
357 &[0xdf, 0x58, 0x6b, 0xb4, 0xc2, 0x49, 0xb9, 0x2c,
358 0xb6, 0x92, 0x28, 0x77, 0xe4, 0x44, 0xd3, 0x7b]),
359
360 (&[0xb8, 0x3b, 0x53, 0x37, 0x08, 0xbf, 0x53, 0x5d,
362 0x0a, 0xa6, 0xe5, 0x29, 0x80, 0xd5, 0x3b, 0x78],
363 &[0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed,
364 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2],
365 &[0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6, 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f,
366 0xb8, 0x94, 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8, 0xba, 0x26, 0x2a, 0x3c,
367 0xca, 0x7e, 0x2c, 0xa7, 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90, 0xcc, 0xdc,
368 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f, 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
369 0x4c, 0x34, 0xae, 0xe5],
370 &[0x1c, 0x5a, 0xfe, 0x97, 0x60, 0xd3, 0x93, 0x2f,
371 0x3c, 0x9a, 0x87, 0x8a, 0xac, 0x3d, 0xc3, 0xde]),
372
373 (&[0xaa, 0xe0, 0x69, 0x92, 0xac, 0xbf, 0x52, 0xa3,
375 0xe8, 0xf4, 0xa9, 0x6e, 0xc9, 0x30, 0x0b, 0xd7],
376 &[],
377 &[],
378 &[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
379 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]),
380
381 (&[0xaa, 0xe0, 0x69, 0x92, 0xac, 0xbf, 0x52, 0xa3,
383 0xe8, 0xf4, 0xa9, 0x6e, 0xc9, 0x30, 0x0b, 0xd7],
384 &[],
385 &[0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
386 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00],
387 &[0xe2, 0xc6, 0x3f, 0x0a, 0xc4, 0x4a, 0xd0, 0xe0,
388 0x2e, 0xfa, 0x05, 0xab, 0x67, 0x43, 0xd4, 0xce]),
389
390 (&[0x46, 0x69, 0x23, 0xec, 0x9a, 0xe6, 0x82, 0x21,
392 0x4f, 0x2c, 0x08, 0x2b, 0xad, 0xb3, 0x92, 0x49],
393 &[],
394 &[0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a,
395 0x27, 0x57, 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, 0x62, 0x85, 0x93, 0xb4,
396 0x0c, 0xa1, 0xe1, 0x9c, 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, 0xac, 0x61,
397 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
398 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56],
399 &[0x51, 0x11, 0x0d, 0x40, 0xf6, 0xc8, 0xff, 0xf0,
400 0xeb, 0x1a, 0xe3, 0x34, 0x45, 0xa8, 0x89, 0xf0]),
401
402 (&[0x46, 0x69, 0x23, 0xec, 0x9a, 0xe6, 0x82, 0x21,
404 0x4f, 0x2c, 0x08, 0x2b, 0xad, 0xb3, 0x92, 0x49],
405 &[0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed,
406 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2],
407 &[0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a,
408 0x27, 0x57, 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, 0x62, 0x85, 0x93, 0xb4,
409 0x0c, 0xa1, 0xe1, 0x9c, 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, 0xac, 0x61,
410 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
411 0xcc, 0xda, 0x27, 0x10],
412 &[0xed, 0x2c, 0xe3, 0x06, 0x2e, 0x4a, 0x8e, 0xc0,
413 0x6d, 0xb8, 0xb4, 0xc4, 0x90, 0xe8, 0xa2, 0x68]),
414
415 (&[0x46, 0x69, 0x23, 0xec, 0x9a, 0xe6, 0x82, 0x21,
417 0x4f, 0x2c, 0x08, 0x2b, 0xad, 0xb3, 0x92, 0x49],
418 &[0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed,
419 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2],
420 &[0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54, 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32,
421 0x4d, 0xb8, 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f, 0x83, 0x47, 0x28, 0x0f,
422 0xc4, 0x50, 0x70, 0x57, 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75, 0xc6, 0x65,
423 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9, 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
424 0xa0, 0xf0, 0x62, 0xf7],
425 &[0x1e, 0x6a, 0x13, 0x38, 0x06, 0x60, 0x78, 0x58,
426 0xee, 0x80, 0xea, 0xf2, 0x37, 0x06, 0x40, 0x89]),
427
428 (&[0x46, 0x69, 0x23, 0xec, 0x9a, 0xe6, 0x82, 0x21,
430 0x4f, 0x2c, 0x08, 0x2b, 0xad, 0xb3, 0x92, 0x49],
431 &[0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed,
432 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2],
433 &[0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c, 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc,
434 0xf9, 0xff, 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef, 0x6e, 0xf7, 0xb7, 0x98,
435 0x28, 0x66, 0x6e, 0x45, 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9, 0xe2, 0xf0,
436 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3, 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
437 0xe9, 0xb7, 0x37, 0x3b],
438 &[0x82, 0x56, 0x7f, 0xb0, 0xb4, 0xcc, 0x37, 0x18,
439 0x01, 0xea, 0xde, 0xc0, 0x05, 0x96, 0x8e, 0x94]),
440
441 (&[0xdc, 0x95, 0xc0, 0x78, 0xa2, 0x40, 0x89, 0x89,
443 0xad, 0x48, 0xa2, 0x14, 0x92, 0x84, 0x20, 0x87],
444 &[],
445 &[],
446 &[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
447 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]),
448
449 (&[0xdc, 0x95, 0xc0, 0x78, 0xa2, 0x40, 0x89, 0x89,
451 0xad, 0x48, 0xa2, 0x14, 0x92, 0x84, 0x20, 0x87],
452 &[],
453 &[0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
454 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18],
455 &[0x83, 0xde, 0x42, 0x5c, 0x5e, 0xdc, 0x5d, 0x49,
456 0x8f, 0x38, 0x2c, 0x44, 0x10, 0x41, 0xca, 0x92]),
457
458 (&[0xac, 0xbe, 0xf2, 0x05, 0x79, 0xb4, 0xb8, 0xeb,
460 0xce, 0x88, 0x9b, 0xac, 0x87, 0x32, 0xda, 0xd7],
461 &[],
462 &[0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84,
463 0x42, 0x7d, 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, 0x75, 0x98, 0xa2, 0xbd,
464 0x25, 0x55, 0xd1, 0xaa, 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, 0xa7, 0xb0,
465 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
466 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad],
467 &[0x4d, 0xb8, 0x70, 0xd3, 0x7c, 0xb7, 0x5f, 0xcb,
468 0x46, 0x09, 0x7c, 0x36, 0x23, 0x0d, 0x16, 0x12]),
469
470 (&[0xac, 0xbe, 0xf2, 0x05, 0x79, 0xb4, 0xb8, 0xeb,
472 0xce, 0x88, 0x9b, 0xac, 0x87, 0x32, 0xda, 0xd7],
473 &[0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed,
474 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2],
475 &[0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84,
476 0x42, 0x7d, 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, 0x75, 0x98, 0xa2, 0xbd,
477 0x25, 0x55, 0xd1, 0xaa, 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, 0xa7, 0xb0,
478 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
479 0xbc, 0xc9, 0xf6, 0x62],
480 &[0x8b, 0xd0, 0xc4, 0xd8, 0xaa, 0xcd, 0x39, 0x1e,
481 0x67, 0xcc, 0xa4, 0x47, 0xe8, 0xc3, 0x8f, 0x65]),
482
483 (&[0xac, 0xbe, 0xf2, 0x05, 0x79, 0xb4, 0xb8, 0xeb,
485 0xce, 0x88, 0x9b, 0xac, 0x87, 0x32, 0xda, 0xd7],
486 &[0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed,
487 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2],
488 &[0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32, 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98,
489 0x44, 0xcb, 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa, 0xc5, 0x2f, 0xf7, 0xd7,
490 0x9b, 0xba, 0x9d, 0xe0, 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0, 0x95, 0x4c,
491 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78, 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
492 0xf4, 0x7c, 0x9b, 0x1f],
493 &[0x75, 0xa3, 0x42, 0x88, 0xb8, 0xc6, 0x8f, 0x81,
494 0x1c, 0x52, 0xb2, 0xe9, 0xa2, 0xf9, 0x7f, 0x63]),
495
496 (&[0xac, 0xbe, 0xf2, 0x05, 0x79, 0xb4, 0xb8, 0xeb,
498 0xce, 0x88, 0x9b, 0xac, 0x87, 0x32, 0xda, 0xd7],
499 &[0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed,
500 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2],
501 &[0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1, 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e,
502 0x2a, 0x20, 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19, 0xa0, 0x58, 0xab, 0x4f,
503 0x6f, 0x74, 0x6b, 0xf4, 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45, 0x2d, 0xa3,
504 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde, 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
505 0x44, 0xae, 0x7e, 0x3f],
506 &[0xd5, 0xff, 0xcf, 0x6f, 0xc5, 0xac, 0x4d, 0x69,
507 0x72, 0x21, 0x87, 0x42, 0x1a, 0x7f, 0x17, 0x0b])
508 ];
509
510 #[test]
511 fn hash() {
512 for &(h, a, c, g) in CASES.iter() {
513 let ghash = Ghash::new(h);
514 assert_eq!(&ghash.input_a(a).input_c(c).result()[..], g);
515 }
516 }
517
518 #[test]
519 fn split_input() {
520 for &(h, a, c, g) in CASES.iter() {
521 let ghash = Ghash::new(h);
522 let (a1, a2) = a.split_at(a.len() / 2);
523 let (c1, c2) = c.split_at(c.len() / 2);
524 assert_eq!(&ghash.input_a(a1)
525 .input_a(a2)
526 .input_c(c1)
527 .input_c(c2)
528 .result()[..], g);
529 }
530 }
531}
532
533#[cfg(all(test, feature = "with-bench"))]
534mod bench {
535 use test::Bencher;
536 use mac::Mac;
537 use ghash::Ghash;
538
539 #[bench]
540 pub fn ghash_10(bh: & mut Bencher) {
541 let mut mac = [0u8; 16];
542 let key = [0u8; 16];
543 let bytes = [1u8; 10];
544 bh.iter( || {
545 let mut ghash = Ghash::new(&key);
546 ghash.input(&bytes);
547 ghash.raw_result(&mut mac);
548 });
549 bh.bytes = bytes.len() as u64;
550 }
551
552 #[bench]
553 pub fn ghash_1k(bh: & mut Bencher) {
554 let mut mac = [0u8; 16];
555 let key = [0u8; 16];
556 let bytes = [1u8; 1024];
557 bh.iter( || {
558 let mut ghash = Ghash::new(&key);
559 ghash.input(&bytes);
560 ghash.raw_result(&mut mac);
561 });
562 bh.bytes = bytes.len() as u64;
563 }
564
565 #[bench]
566 pub fn ghash_64k(bh: & mut Bencher) {
567 let mut mac = [0u8; 16];
568 let key = [0u8; 16];
569 let bytes = [1u8; 65536];
570 bh.iter( || {
571 let mut ghash = Ghash::new(&key);
572 ghash.input(&bytes);
573 ghash.raw_result(&mut mac);
574 });
575 bh.bytes = bytes.len() as u64;
576 }
577}