1#![cfg_attr(feature = "simd", feature(portable_simd))]
2use constant_time_eq::constant_time_eq;
106
107mod accessor;
108mod aesround;
109mod block;
110
111#[cfg(test)]
112mod testvectors;
113
114use accessor::BlockAccessor;
115use aesround::AesRound;
116use block::Block;
117type Key = [u8; 48];
118type Tweak<'a> = &'a [&'a [u8]];
119
120static ZEROES: [u8; 1024] = [0; 1024];
121
122#[derive(Clone, Copy, PartialEq, Eq)]
123enum Mode {
124 Encipher,
125 Decipher,
126}
127
128pub struct Aez {
130 key_i: Block,
131 key_j: Block,
132 key_l: Block,
133 key_l_multiples: [Block; 8],
134 aes: aesround::AesImpl,
135}
136
137impl Aez {
138 pub fn new(key: &[u8]) -> Self {
145 let key = extract(key);
146 let (key_i, key_j, key_l) = split_key(&key);
147 let aes = aesround::AesImpl::new(key_i, key_j, key_l);
148 let key_l_multiples = [
149 key_l * 0,
150 key_l * 1,
151 key_l * 2,
152 key_l * 3,
153 key_l * 4,
154 key_l * 5,
155 key_l * 6,
156 key_l * 7,
157 ];
158 Aez {
159 key_i,
160 key_j,
161 key_l,
162 key_l_multiples,
163 aes,
164 }
165 }
166
167 pub fn encrypt(
188 &self,
189 nonce: &[u8],
190 associated_data: &[&[u8]],
191 tau: u32,
192 data: &[u8],
193 ) -> Vec<u8> {
194 let mut buffer = Vec::from(data);
195 self.encrypt_vec(nonce, associated_data, tau, &mut buffer);
196 buffer
197 }
198
199 pub fn encrypt_vec(
208 &self,
209 nonce: &[u8],
210 associated_data: &[&[u8]],
211 tau: u32,
212 data: &mut Vec<u8>,
213 ) {
214 data.resize(data.len() + tau as usize, 0);
215 encrypt(&self, nonce, associated_data, tau, data);
216 }
217
218 pub fn encrypt_inplace(
225 &self,
226 nonce: &[u8],
227 associated_data: &[&[u8]],
228 tau: u32,
229 buffer: &mut [u8],
230 ) {
231 assert!(buffer.len() >= tau as usize);
232 let data_len = buffer.len() - tau as usize;
233 append_auth(data_len, buffer);
234 encrypt(&self, nonce, associated_data, tau as u32, buffer);
235 }
236
237 pub fn encrypt_buffer(
244 &self,
245 nonce: &[u8],
246 associated_data: &[&[u8]],
247 input: &[u8],
248 output: &mut [u8],
249 ) {
250 assert!(output.len() >= input.len());
251 let tau = output.len() - input.len();
252 output[..input.len()].copy_from_slice(input);
253 append_auth(input.len(), output);
254 encrypt(&self, nonce, associated_data, tau as u32, output);
255 }
256
257 pub fn decrypt(
270 &self,
271 nonce: &[u8],
272 associated_data: &[&[u8]],
273 tau: u32,
274 data: &[u8],
275 ) -> Option<Vec<u8>> {
276 let mut buffer = Vec::from(data);
277 let len = match decrypt(&self, nonce, associated_data, tau, &mut buffer) {
278 None => return None,
279 Some(m) => m.len(),
280 };
281 buffer.truncate(len);
282 Some(buffer)
283 }
284
285 pub fn decrypt_inplace<'a>(
291 &self,
292 nonce: &[u8],
293 associated_data: &[&[u8]],
294 tau: u32,
295 data: &'a mut [u8],
296 ) -> Option<&'a [u8]> {
297 decrypt(&self, nonce, associated_data, tau, data)
298 }
299}
300
301fn extract(key: &[u8]) -> [u8; 48] {
302 if key.len() == 48 {
303 key.try_into().unwrap()
304 } else {
305 use blake2::Digest;
306 type Blake2b384 = blake2::Blake2b<blake2::digest::consts::U48>;
307 let mut hasher = Blake2b384::new();
308 hasher.update(key);
309 hasher.finalize().into()
310 }
311}
312
313fn append_auth(data_len: usize, buffer: &mut [u8]) {
314 let mut total_len = data_len;
315 while total_len < buffer.len() {
316 let block_size = ZEROES.len().min(buffer.len() - total_len);
317 buffer[total_len..total_len + block_size].copy_from_slice(&ZEROES[..block_size]);
318 total_len += block_size;
319 }
320}
321
322fn encrypt(aez: &Aez, nonce: &[u8], ad: &[&[u8]], tau: u32, buffer: &mut [u8]) {
323 let tau_block = Block::from_int(tau as u128 * 8);
325 let tau_bytes = tau_block.bytes();
326 let mut tweaks_vec;
327 let tweaks = match ad.len() {
331 0 => &[&tau_bytes, nonce] as &[&[u8]],
332 1 => &[&tau_bytes, nonce, ad[0]],
333 _ => {
334 tweaks_vec = vec![&tau_bytes, nonce];
335 tweaks_vec.extend(ad);
336 &tweaks_vec
337 }
338 };
339 assert!(buffer.len() >= tau as usize);
340 if buffer.len() == tau as usize {
341 buffer.fill(0);
343 aez_prf(aez, &tweaks, buffer);
344 } else {
345 encipher(aez, &tweaks, buffer);
346 }
347}
348
349fn decrypt<'a>(
350 aez: &Aez,
351 nonce: &[u8],
352 ad: &[&[u8]],
353 tau: u32,
354 ciphertext: &'a mut [u8],
355) -> Option<&'a [u8]> {
356 if ciphertext.len() < tau as usize {
357 return None;
358 }
359
360 let tau_block = Block::from_int(tau * 8);
361 let tau_bytes = tau_block.bytes();
362 let mut tweaks = vec![&tau_bytes, nonce];
363 tweaks.extend(ad);
364
365 if ciphertext.len() == tau as usize {
366 aez_prf(aez, &tweaks, ciphertext);
367 if is_zeroes(&ciphertext) {
368 return Some(&[]);
369 } else {
370 return None;
371 }
372 }
373
374 decipher(aez, &tweaks, ciphertext);
375 let (m, auth) = ciphertext.split_at(ciphertext.len() - tau as usize);
376 assert!(auth.len() == tau as usize);
377
378 if is_zeroes(&auth) { Some(m) } else { None }
379}
380
381fn is_zeroes(data: &[u8]) -> bool {
382 let comparator = if data.len() <= ZEROES.len() {
383 &ZEROES[..data.len()]
384 } else {
385 &vec![0; data.len()]
388 };
389 constant_time_eq(data, comparator)
390}
391
392fn encipher(aez: &Aez, tweaks: Tweak, message: &mut [u8]) {
393 if message.len() < 256 / 8 {
394 cipher_aez_tiny(Mode::Encipher, aez, tweaks, message)
395 } else {
396 cipher_aez_core(Mode::Encipher, aez, tweaks, message)
397 }
398}
399
400fn decipher(aez: &Aez, tweaks: Tweak, buffer: &mut [u8]) {
401 if buffer.len() < 256 / 8 {
402 cipher_aez_tiny(Mode::Decipher, aez, tweaks, buffer);
403 } else {
404 cipher_aez_core(Mode::Decipher, aez, tweaks, buffer);
405 }
406}
407
408fn cipher_aez_tiny(mode: Mode, aez: &Aez, tweaks: Tweak, message: &mut [u8]) {
409 let mu = message.len() * 8;
410 assert!(mu < 256);
411 let n = mu / 2;
412 let delta = aez_hash(aez, tweaks);
413 let round_count = match mu {
414 8 => 24u32,
415 16 => 16,
416 _ if mu < 128 => 10,
417 _ => 8,
418 };
419
420 if mode == Mode::Decipher && mu < 128 {
421 let mut c = Block::from_slice(message);
422 c = c ^ (e(0, 3, aez, delta ^ (c | Block::one())) & Block::one());
423 message.copy_from_slice(&c.bytes()[..mu / 8]);
424 }
425
426 let (mut left, mut right);
427 if n % 8 == 0 {
429 left = Block::from_slice(&message[..n / 8]);
430 right = Block::from_slice(&message[n / 8..]);
431 } else {
432 assert!(n % 8 == 4);
433 left = Block::from_slice(&message[..n / 8 + 1]).clip(n);
434 right = Block::from_slice(&message[n / 8..]) << 4;
435 };
436
437 let i = if mu >= 128 { 6 } else { 7 };
438
439 if mode == Mode::Encipher {
440 for j in 0..round_count {
441 let right_ = (left ^ e(0, i, aez, delta ^ right.pad(n) ^ Block::from_int(j))).clip(n);
442 (left, right) = (right, right_);
443 }
444 } else {
445 for j in (0..round_count).rev() {
446 let right_ = (left ^ e(0, i, aez, delta ^ right.pad(n) ^ Block::from_int(j))).clip(n);
447 (left, right) = (right, right_);
448 }
449 }
450
451 if n % 8 == 0 {
452 message[..n / 8].copy_from_slice(&right.bytes()[..n / 8]);
453 message[n / 8..].copy_from_slice(&left.bytes()[..n / 8]);
454 } else {
455 let mut index = n / 8;
456 message[..index + 1].copy_from_slice(&right.bytes()[..index + 1]);
457 for byte in &left.bytes()[..n / 8 + 1] {
458 message[index] |= byte >> 4;
459 if index < message.len() - 1 {
460 message[index + 1] = (byte & 0x0f) << 4;
461 }
462 index += 1;
463 }
464 }
465
466 if mode == Mode::Encipher && mu < 128 {
467 let mut c = Block::from_slice(&message);
468 c = c ^ (e(0, 3, aez, delta ^ (c | Block::one())) & Block::one());
469 message.copy_from_slice(&c.bytes()[..mu / 8]);
470 }
471}
472
473fn cipher_aez_core(mode: Mode, aez: &Aez, tweaks: Tweak, message: &mut [u8]) {
474 assert!(message.len() >= 32);
475 let delta = aez_hash(aez, tweaks);
476 let mut blocks = BlockAccessor::new(message);
477 let (m_u, m_v, m_x, m_y, d) = (
478 blocks.m_u(),
479 blocks.m_v(),
480 blocks.m_x(),
481 blocks.m_y(),
482 blocks.m_uv_len(),
483 );
484 let len_v = d.saturating_sub(128);
485
486 let mut x = Block::null();
487 let mut e1_eval = E::new(1, 0, aez);
488 let e0_eval = E::new(0, 0, aez);
489
490 for (raw_mi, raw_mi_) in blocks.pairs_mut() {
491 e1_eval.advance();
492 let mi = Block::from(*raw_mi);
493 let mi_ = Block::from(*raw_mi_);
494 let wi = mi ^ e1_eval.eval(mi_);
495 let xi = mi_ ^ e0_eval.eval(wi);
496
497 wi.write_to(raw_mi);
498 xi.write_to(raw_mi_);
499
500 x = x ^ xi;
501 }
502
503 match d {
504 0 => (),
505 _ if d <= 127 => {
506 x = x ^ e(0, 4, aez, m_u.pad(d.into()));
507 }
508 _ => {
509 x = x ^ e(0, 4, aez, m_u);
510 x = x ^ e(0, 5, aez, m_v.pad(len_v.into()));
511 }
512 }
513
514 let (s_x, s_y);
515 match mode {
516 Mode::Encipher => {
517 s_x = m_x ^ delta ^ x ^ e(0, 1, aez, m_y);
518 s_y = m_y ^ e(-1, 1, aez, s_x);
519 }
520 Mode::Decipher => {
521 s_x = m_x ^ delta ^ x ^ e(0, 2, aez, m_y);
522 s_y = m_y ^ e(-1, 2, aez, s_x);
523 }
524 }
525 let s = s_x ^ s_y;
526
527 let mut y = Block::null();
528 let mut e2_eval = E::new(2, 0, aez);
529 let mut e1_eval = E::new(1, 0, aez);
530 for (raw_wi, raw_xi) in blocks.pairs_mut() {
531 e2_eval.advance();
532 e1_eval.advance();
533 let wi = Block::from(*raw_wi);
534 let xi = Block::from(*raw_xi);
535 let s_ = e2_eval.eval(s);
536 let yi = wi ^ s_;
537 let zi = xi ^ s_;
538 let ci_ = yi ^ e0_eval.eval(zi);
539 let ci = zi ^ e1_eval.eval(ci_);
540
541 ci.write_to(raw_wi);
542 ci_.write_to(raw_xi);
543
544 y = y ^ yi;
545 }
546
547 let mut c_u = Block::default();
548 let mut c_v = Block::default();
549
550 match d {
551 0 => (),
552 _ if d <= 127 => {
553 c_u = (m_u ^ e(-1, 4, aez, s)).clip(d.into());
554 y = y ^ e(0, 4, aez, c_u.pad(d.into()));
555 }
556 _ => {
557 c_u = m_u ^ e(-1, 4, aez, s);
558 c_v = (m_v ^ e(-1, 5, aez, s)).clip(len_v.into());
559 y = y ^ e(0, 4, aez, c_u);
560 y = y ^ e(0, 5, aez, c_v.pad(len_v.into()));
561 }
562 }
563
564 let (c_x, c_y);
565 match mode {
566 Mode::Encipher => {
567 c_y = s_x ^ e(-1, 2, aez, s_y);
568 c_x = s_y ^ delta ^ y ^ e(0, 2, aez, c_y);
569 }
570 Mode::Decipher => {
571 c_y = s_x ^ e(-1, 1, aez, s_y);
572 c_x = s_y ^ delta ^ y ^ e(0, 1, aez, c_y);
573 }
574 }
575
576 blocks.set_m_u(c_u);
577 blocks.set_m_v(c_v);
578 blocks.set_m_x(c_x);
579 blocks.set_m_y(c_y);
580}
581
582fn pad_to_blocks(value: &[u8]) -> Vec<Block> {
583 let mut blocks = Vec::new();
584 for chunk in value.chunks(16) {
585 if chunk.len() == 16 {
586 blocks.push(Block::from_slice(chunk));
587 } else {
588 blocks.push(Block::from_slice(chunk).pad(chunk.len() * 8));
589 }
590 }
591 blocks
592}
593
594fn aez_hash(aez: &Aez, tweaks: Tweak) -> Block {
595 let mut hash = Block::null();
596 for (i, tweak) in tweaks.iter().enumerate() {
597 let j = i + 2 + 1;
599 let mut ej = E::new(j.try_into().unwrap(), 0, aez);
600 if tweak.is_empty() {
604 hash = hash ^ ej.eval(Block::one());
605 } else if tweak.len() % 16 == 0 {
606 for chunk in tweak.chunks(16) {
607 ej.advance();
608 hash = hash ^ ej.eval(Block::from_slice(chunk));
609 }
610 } else {
611 let blocks = pad_to_blocks(tweak);
612 for (l, chunk) in blocks.iter().enumerate() {
613 ej.advance();
614 if l == blocks.len() - 1 {
615 hash = hash ^ e(j.try_into().unwrap(), 0, aez, *chunk);
616 } else {
617 hash = hash ^ ej.eval(*chunk);
618 }
619 }
620 }
621 }
622 hash
623}
624
625fn aez_prf(aez: &Aez, tweaks: Tweak, buffer: &mut [u8]) {
627 let mut index = 0u128;
628 let delta = aez_hash(aez, tweaks);
629 for chunk in buffer.chunks_exact_mut(16) {
630 let chunk: &mut [u8; 16] = chunk.try_into().unwrap();
631 let block = e(-1, 3, aez, delta ^ Block::from_int(index));
632 (block ^ Block::from(*chunk)).write_to(chunk);
633 index += 1;
634 }
635 let suffix_start = buffer.len() - buffer.len() % 16;
636 let chunk = &mut buffer[suffix_start..];
637 let block = e(-1, 3, aez, delta ^ Block::from_int(index));
638 for (a, b) in chunk.iter_mut().zip(block.bytes().iter()) {
639 *a ^= *b;
640 }
641}
642
643struct E<'a> {
648 aez: &'a Aez,
649 i: u32,
650 kj_t_j: Block,
651 ki_p_i: Block,
652}
653
654impl<'a> E<'a> {
655 fn new(j: i32, i: u32, aez: &'a Aez) -> Self {
657 assert!(j >= 0);
658 let j: u32 = j.try_into().expect("j was negative");
659 let exponent = if i % 8 == 0 { i / 8 } else { i / 8 + 1 };
660 E {
661 aez,
662 i,
663 kj_t_j: aez.key_j * j,
664 ki_p_i: aez.key_i.exp(exponent),
665 }
666 }
667
668 fn eval(&self, block: Block) -> Block {
670 let delta = self.kj_t_j ^ self.ki_p_i ^ self.aez.key_l_multiples[self.i as usize % 8];
671 self.aez.aes.aes4(block ^ delta)
672 }
673
674 fn advance(&mut self) {
678 if self.i % 8 == 0 {
682 self.ki_p_i = self.ki_p_i * 2
683 };
684 self.i += 1;
685 }
686}
687
688fn e(j: i32, i: u32, aez: &Aez, block: Block) -> Block {
690 if j == -1 {
691 let delta = if i < 8 {
692 aez.key_l_multiples[i as usize]
693 } else {
694 aez.key_l * i
695 };
696 aez.aes.aes10(block ^ delta)
697 } else {
698 E::new(j, i, aez).eval(block)
699 }
700}
701
702fn split_key(key: &Key) -> (Block, Block, Block) {
703 (
704 Block::from_slice(&key[..16]),
705 Block::from_slice(&key[16..32]),
706 Block::from_slice(&key[32..]),
707 )
708}
709
710#[cfg(test)]
711mod test {
712 use super::*;
713
714 static PLAIN: &[u8] = include_bytes!("payload.txt");
715
716 #[test]
717 fn test_extract() {
718 for (a, b) in testvectors::EXTRACT_VECTORS {
719 let a = hex::decode(a).unwrap();
720 let b = hex::decode(b).unwrap();
721 assert_eq!(extract(&a), b.as_slice());
722 }
723 }
724
725 #[test]
726 fn test_e() {
727 for (k, j, i, a, b) in testvectors::E_VECTORS {
728 let name = format!("e({j}, {i}, {k}, {a})");
729 let k = hex::decode(k).unwrap();
730 let aez = Aez::new(k.as_slice());
731 let a = hex::decode(a).unwrap();
732 let a = Block::from_slice(&a);
733 let b = hex::decode(b).unwrap();
734 assert_eq!(&e(*j, *i, &aez, a).bytes(), b.as_slice(), "{name}");
735 }
736 }
737
738 #[test]
739 fn test_aez_hash() {
740 for (k, tau, tw, v) in testvectors::HASH_VECTORS {
741 let name = format!("aez_hash({k}, {tau}, {tw:?})");
742 let k = hex::decode(k).unwrap();
743 let aez = Aez::new(k.as_slice());
744 let v = hex::decode(v).unwrap();
745
746 let mut tweaks = vec![Vec::from(Block::from_int(*tau).bytes())];
747 for t in *tw {
748 tweaks.push(hex::decode(t).unwrap());
749 }
750 let tweaks = tweaks.iter().map(Vec::as_slice).collect::<Vec<_>>();
751
752 assert_eq!(&aez_hash(&aez, &tweaks).bytes(), v.as_slice(), "{name}");
753 }
754 }
755
756 fn vec_encrypt(key: &Key, nonce: &[u8], ad: &[&[u8]], tau: u32, message: &[u8]) -> Vec<u8> {
757 let aez = Aez::new(key);
758 let mut v = vec![0; message.len() + tau as usize];
759 v[..message.len()].copy_from_slice(message);
760 encrypt(&aez, nonce, ad, tau, &mut v);
761 v
762 }
763
764 fn vec_decrypt(
765 key: &Key,
766 nonce: &[u8],
767 ad: &[&[u8]],
768 tau: u32,
769 ciphertext: &[u8],
770 ) -> Option<Vec<u8>> {
771 let aez = Aez::new(key);
772 let mut v = Vec::from(ciphertext);
773 let len = match decrypt(&aez, nonce, ad, tau, &mut v) {
774 None => return None,
775 Some(m) => m.len(),
776 };
777 v.truncate(len);
778 Some(v)
779 }
780
781 #[test]
782 fn test_encrypt() {
783 let mut failed = 0;
784 let mut succ = 0;
785 for (k, n, ads, tau, m, c) in testvectors::ENCRYPT_VECTORS {
786 let name = format!("encrypt({k}, {n}, {ads:?}, {tau}, {m})");
787 let k = hex::decode(k).unwrap();
788 let k = k.as_slice().try_into().unwrap();
789 let n = hex::decode(n).unwrap();
790
791 let mut ad = Vec::new();
792 for i in *ads {
793 ad.push(hex::decode(i).unwrap());
794 }
795 let ad = ad.iter().map(Vec::as_slice).collect::<Vec<_>>();
796
797 let m = hex::decode(m).unwrap();
798 let c = hex::decode(c).unwrap();
799
800 if &vec_encrypt(&k, &n, &ad, *tau, &m) == &c {
801 println!("+ {name}");
802 succ += 1;
803 } else {
804 println!("- {name}");
805 failed += 1;
806 }
807 }
808 println!("{succ} succeeded, {failed} failed");
809 assert_eq!(failed, 0);
810 }
811
812 #[test]
813 fn test_decrypt() {
814 let mut failed = 0;
815 let mut succ = 0;
816 for (k, n, ads, tau, m, c) in testvectors::ENCRYPT_VECTORS {
817 let name = format!("decrypt({k}, {n}, {ads:?}, {tau}, {c})");
818 let k = hex::decode(k).unwrap();
819 let k = k.as_slice().try_into().unwrap();
820 let n = hex::decode(n).unwrap();
821
822 let mut ad = Vec::new();
823 for i in *ads {
824 ad.push(hex::decode(i).unwrap());
825 }
826 let ad = ad.iter().map(Vec::as_slice).collect::<Vec<_>>();
827
828 let m = hex::decode(m).unwrap();
829 let c = hex::decode(c).unwrap();
830
831 if vec_decrypt(&k, &n, &ad, *tau, &c) == Some(m) {
832 println!("+ {name}");
833 succ += 1;
834 } else {
835 println!("- {name}");
836 failed += 1;
837 }
838 }
839 println!("{succ} succeeded, {failed} failed");
840 assert_eq!(failed, 0);
841 }
842
843 #[test]
844 fn test_encrypt_decrypt() {
845 let aez = Aez::new(b"foobar");
846 let cipher = aez.encrypt(&[0], &[b"foobar"], 16, b"hi");
847 let plain = aez.decrypt(&[0], &[b"foobar"], 16, &cipher).unwrap();
848 assert_eq!(plain, b"hi");
849 }
850
851 #[test]
852 fn test_encrypt_decrypt_inplace() {
853 let mut buffer = Vec::from(PLAIN);
854 let aez = Aez::new(b"foobar");
855 aez.encrypt_inplace(&[0], &[], 16, &mut buffer);
856 let plain = aez.decrypt_inplace(&[0], &[], 16, &mut buffer).unwrap();
857 assert_eq!(plain, &PLAIN[..PLAIN.len() - 16]);
858 }
859
860 #[test]
861 fn test_encrypt_decrypt_buffer() {
862 let mut output = vec![0; PLAIN.len() + 16];
863 let aez = Aez::new(b"foobar");
864 aez.encrypt_buffer(&[0], &[], PLAIN, &mut output);
865 let plain = aez.decrypt_inplace(&[0], &[], 16, &mut output).unwrap();
866 assert_eq!(plain, PLAIN);
867 }
868
869 #[test]
870 fn test_encrypt_decrypt_long() {
871 let message = b"ene mene miste es rappelt in der kiste ene mene meck und du bist weg";
872 let aez = Aez::new(b"foobar");
873 let cipher = aez.encrypt(&[0], &[b"foobar"], 16, message);
874 let plain = aez.decrypt(&[0], &[b"foobar"], 16, &cipher).unwrap();
875 assert_eq!(plain, message);
876 }
877
878 #[test]
879 fn test_encrypt_decrypt_empty() {
880 let aez = Aez::new(b"jimbo");
881 let hash = aez.encrypt(&[0], &[b"foobar"], 16, b"");
882
883 assert!(aez.decrypt(&[0], &[b"foobar"], 16, &hash).is_some());
884 assert!(aez.decrypt(&[0], &[b"boofar"], 16, &hash).is_none());
885 }
886
887 #[test]
888 fn test_fuzzed_1() {
889 let aez = Aez::new(b"");
890 aez.encrypt(b"", &[], 2220241, &[0]);
891 }
892
893 #[test]
894 fn test_fuzzed_2() {
895 let aez = Aez::new(b"");
896 aez.encrypt(b"", &[], 673261693, &[]);
897 }
898
899 #[test]
900 fn test_fuzzed_3() {
901 let aez = Aez::new(&[0, 110, 109, 0]);
903 let value = aez.encrypt(&[0], &[], 0, &[]);
904 assert_eq!(&value, &[]);
905 }
906}