use crate::aes;
use crate::aes::BLOCK_SIZE;
use std::convert::TryInto;
const R: u128 = 0xe1000000000000000000000000000000;
pub const TABLE_R: [u16; 256] = calculate_table_r();
const P: u128 = 2u128.reverse_bits();
const ONE_REVERSED: u128 = 1u128.reverse_bits();
pub type GcmBlockMulFn = dyn Fn(u128) -> u128;
pub enum GcmBlockMulEnhancement {
None,
M0TableAndRTable,
M4BitTables,
MTables,
}
impl GcmBlockMulEnhancement {
pub fn to_mul_fn(&self, cipher_key: &[u8]) -> Box<GcmBlockMulFn> {
let h = u128::from_be_bytes(aes::encrypt(&[0u8; BLOCK_SIZE], cipher_key));
match self {
GcmBlockMulEnhancement::None => Box::new(move |x| block_mul(x, h)),
GcmBlockMulEnhancement::M0TableAndRTable => {
let m0 = calculate_table_m(h, 0);
Box::new(move |x| block_mul_with_m0_r(&m0, x))
}
GcmBlockMulEnhancement::M4BitTables => {
let mut m = [[0u128; 16]; BLOCK_SIZE << 1];
for i in 0..m.len() {
m[i] = calculate_4bit_table_m(h, i);
}
Box::new(move |x| block_mul_with_4bit_tables(&m, x))
}
GcmBlockMulEnhancement::MTables => {
let mut m = [[0u128; 256]; BLOCK_SIZE];
for i in 0..BLOCK_SIZE {
m[i] = calculate_table_m(h, i);
}
Box::new(move |x| block_mul_with_tables(&m, x))
}
}
}
}
pub fn gcm_aes_encrypt(
key: &[u8],
iv: &[u8],
plain_text: &[u8],
aad: &[u8],
mul_fn: &GcmBlockMulFn,
) -> (Vec<u8>, [u8; 16]) {
let mut counter_block = iv2pre_counter_block(&iv, mul_fn);
let encrypted_block = aes::encrypt(&counter_block, key);
increment_32_least_bits(&mut counter_block);
let cipher_text = gctr(&mut counter_block, plain_text, key);
let s = define_block_s(&cipher_text, aad, mul_fn);
let tag = xor_full_blocks(&s, &encrypted_block);
(cipher_text, tag)
}
pub fn gcm_aes_decrypt(
key: &[u8],
iv: &[u8],
cipher_text: &[u8],
aad: &[u8],
mul_fn: &GcmBlockMulFn,
) -> (Vec<u8>, [u8; 16]) {
let mut counter_block = iv2pre_counter_block(&iv, mul_fn);
let encrypted_block = aes::encrypt(&counter_block, key);
increment_32_least_bits(&mut counter_block);
let plain_text = gctr(&mut counter_block, cipher_text, key);
let s = define_block_s(&cipher_text, aad, mul_fn);
let tag = xor_full_blocks(&s, &encrypted_block);
(plain_text, tag)
}
fn to_multiple_128_minus_itself_bits(value: usize) -> usize {
const ZERO_7: usize = !0x7fusize;
if value & 0x7f > 0 {
(value & ZERO_7) + 0x80 - value
} else {
0
}
}
pub const fn block_mul(x: u128, y: u128) -> u128 {
let mut z = 0u128;
let mut v = x;
let mut y_bit = ONE_REVERSED;
let mut i = 0usize;
while i < 128 {
if y & y_bit > 0 {
z ^= v;
}
v = if v & 1 > 0 { (v >> 1) ^ R } else { v >> 1 };
y_bit >>= 1;
i += 1;
}
z
}
fn ghash(bytes: &[u8], mul_fn: &GcmBlockMulFn) -> [u8; BLOCK_SIZE] {
let mut y = 0u128;
let mut start = 0usize;
let mut end = start + BLOCK_SIZE;
while start < bytes.len() {
y ^= u128::from_be_bytes(bytes[start..end].try_into().unwrap());
y = mul_fn(y);
start = end;
end = start + BLOCK_SIZE;
}
y.to_be_bytes()
}
pub fn iv2pre_counter_block(iv: &[u8], mul_fn: &GcmBlockMulFn) -> [u8; BLOCK_SIZE] {
if iv.len() == 12 {
let mut result = [0u8; BLOCK_SIZE];
result[..12].copy_from_slice(iv);
result[12..].copy_from_slice(&[0, 0, 0, 1]);
result
} else {
let iv_len_bit_len = iv.len() << 3;
let s = to_multiple_128_minus_itself_bits(iv_len_bit_len);
let len = iv.len() + ((s + 64) >> 3) + 8;
let mut bytes = vec![0u8; len];
bytes[..iv.len()].copy_from_slice(iv);
bytes[len - 8..].copy_from_slice(&(iv_len_bit_len as u64).to_be_bytes());
ghash(&bytes, mul_fn)
}
}
pub fn increment_32_least_bits(value: &mut [u8; BLOCK_SIZE]) {
let least_4_bytes: [u8; 4] = value[12..].try_into().unwrap();
value[12..].copy_from_slice(
&u32::from_be_bytes(least_4_bytes)
.wrapping_add(1)
.to_be_bytes(),
);
}
pub fn gctr(counter_block: &mut [u8; BLOCK_SIZE], bytes: &[u8], key: &[u8]) -> Vec<u8> {
if bytes.len() == 0 {
return vec![];
}
let full_blocks_len = bytes.len() & !0x0f;
let mut result = Vec::with_capacity(bytes.len());
let mut start = 0usize;
while start < full_blocks_len {
let encrypted_block = aes::encrypt(counter_block, key);
result.extend_from_slice(&xor_full_blocks(
&bytes[start..start + BLOCK_SIZE],
&encrypted_block,
));
start += BLOCK_SIZE;
increment_32_least_bits(counter_block);
}
let partial_block_len = bytes.len() - full_blocks_len;
if partial_block_len > 0 {
let encrypted_block = aes::encrypt(counter_block, key);
result.extend_from_slice(&xor_partial_blocks(
&bytes[start..start + partial_block_len],
&encrypted_block[..partial_block_len],
));
}
result
}
fn xor_partial_blocks(a: &[u8], b: &[u8]) -> Vec<u8> {
let mut result = Vec::with_capacity(a.len());
for i in 0..a.len() {
result.push(a[i] ^ b[i]);
}
result
}
pub fn xor_full_blocks(a: &[u8], b: &[u8]) -> [u8; 16] {
let a = u128::from_be_bytes(a.try_into().unwrap());
let b = u128::from_be_bytes(b.try_into().unwrap());
(a ^ b).to_be_bytes()
}
pub fn define_block_s(cipher_text: &[u8], aad: &[u8], mul_fn: &GcmBlockMulFn) -> [u8; BLOCK_SIZE] {
let aad_len_bit_len = aad.len() << 3;
let cipher_text_bit_len = cipher_text.len() << 3;
let u = to_multiple_128_minus_itself_bits(cipher_text_bit_len) >> 3;
let v = to_multiple_128_minus_itself_bits(aad_len_bit_len) >> 3;
let len = aad.len() + cipher_text.len() + u + v + 16;
let mut bytes = vec![0u8; len];
bytes[..aad.len()].copy_from_slice(aad);
let mut start = aad.len() + v;
bytes[start..start + cipher_text.len()].copy_from_slice(cipher_text);
start = len - 16;
bytes[start..start + 8].copy_from_slice(&(aad_len_bit_len as u64).to_be_bytes());
start += 8;
bytes[start..].copy_from_slice(&(cipher_text_bit_len as u64).to_be_bytes());
ghash(&bytes, mul_fn)
}
pub const fn calculate_table_m(h: u128, byte_index: usize) -> [u128; 256] {
let mut m = [0u128; 256];
let mut i = 64usize;
m[128] = block_mul(h, ONE_REVERSED >> (byte_index << 3));
while i > 0 {
m[i] = block_mul(m[i << 1], P);
i >>= 1;
}
i = 2;
while i < 256 {
let mut j = 1;
while j < i {
m[i + j] = m[i] ^ m[j];
j += 1;
}
i <<= 1;
}
m
}
pub const fn calculate_4bit_table_m(h: u128, four_bit_index: usize) -> [u128; 16] {
let mut m = [0u128; 16];
let mut i = 4usize;
m[8] = block_mul(h, ONE_REVERSED >> (four_bit_index << 2));
while i > 0 {
m[i] = block_mul(m[i << 1], P);
i >>= 1;
}
i = 2;
while i < 16 {
let mut j = 1;
while j < i {
m[i + j] = m[i] ^ m[j];
j += 1;
}
i <<= 1;
}
m
}
pub fn block_mul_with_tables(m: &[[u128; 256]; BLOCK_SIZE], x: u128) -> u128 {
let mut result = 0u128;
const MASK: u128 = 0xffu128.reverse_bits();
let mut mask = MASK;
for i in 0..BLOCK_SIZE {
let index = (x & mask) >> ((15 - i) << 3);
result ^= m[i][index as usize];
mask >>= 8;
}
result
}
pub fn block_mul_with_4bit_tables(m: &[[u128; 16]; BLOCK_SIZE << 1], x: u128) -> u128 {
let mut result = 0u128;
const MASK: u128 = 0x0fu128.reverse_bits();
let mut mask = MASK;
for i in 0..BLOCK_SIZE << 1 {
let index = (x & mask) >> ((31 - i) << 2);
result ^= m[i][index as usize];
mask >>= 4;
}
result
}
pub const fn calculate_table_r() -> [u16; 256] {
let mut m = [0u128; 256];
let mut i = 64usize;
m[128] = R;
while i > 0 {
m[i] = block_mul(m[i << 1], P);
i >>= 1;
}
i = 2;
while i < 256 {
let mut j = 1;
while j < i {
m[i + j] = m[i] ^ m[j];
j += 1;
}
i <<= 1;
}
let mut result = [0u16; 256];
i = 0;
while i < 256 {
result[i] = (m[i] >> 112) as u16;
i += 1;
}
result
}
pub fn block_mul_with_m0_r(m0: &[u128; 256], x: u128) -> u128 {
let mut z = 0u128;
let mut i = 15;
let mut a;
while i > 0 {
let index = (x >> ((15 - i) << 3)) as u8;
z = z ^ m0[index as usize];
a = z as u8;
z >>= 8;
z ^= (TABLE_R[a as usize] as u128) << 112;
i -= 1;
}
let index = (x >> 120) as u8;
z ^ m0[index as usize]
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_gcm_to_multiple_128_minus_itself() {
assert_eq!(to_multiple_128_minus_itself_bits(128), 0);
assert_eq!(to_multiple_128_minus_itself_bits(148), 108);
assert_eq!(to_multiple_128_minus_itself_bits(129), 127);
assert_eq!(to_multiple_128_minus_itself_bits(888888), 72);
}
#[test]
fn test_gcm_increment_32_least_bits_a() {
let mut bytes = [
0x10u8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
];
increment_32_least_bits(&mut bytes);
assert_eq!(
bytes,
[
0x10u8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01
]
);
let mut bytes = [
0x10u8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0xff,
];
increment_32_least_bits(&mut bytes);
assert_eq!(
bytes,
[
0x10u8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00
]
);
}
#[test]
fn test_gcm_aes_128_encrypt() {
let cipher_key = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
];
let iv = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
];
let p = "".as_bytes();
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let (cipher_text, tag) = gcm_aes_encrypt(&cipher_key, &iv, &p, &"".as_bytes(), &mul_fn);
assert_eq!(&cipher_text, &[]);
assert_eq!(
&tag,
&[
0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7,
0x45, 0x5a
]
);
let p = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let (cipher_text, tag) = gcm_aes_encrypt(&cipher_key, &iv, &p, &"".as_bytes(), &mul_fn);
assert_eq!(
&cipher_text,
&[
0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2,
0xfe, 0x78
]
);
assert_eq!(
&tag,
&[
0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57,
0xbd, 0xdf
]
);
let cipher_key = [
0xAD, 0x7A, 0x2B, 0xD0, 0x3E, 0xAC, 0x83, 0x5A, 0x6F, 0x62, 0x0F, 0xDC, 0xB5, 0x06,
0xB3, 0x45,
];
let iv = [
0x12, 0x15, 0x35, 0x24, 0xC0, 0x89, 0x5E, 0x81, 0xB2, 0xC2, 0x84, 0x65,
];
let p = [
0x08, 0x00, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
0x37, 0x38, 0x39, 0x3A, 0x00, 0x02,
];
let aad = [
0xD6, 0x09, 0xB1, 0xF0, 0x56, 0x63, 0x7A, 0x0D, 0x46, 0xDF, 0x99, 0x8D, 0x88, 0xE5,
0x2E, 0x00, 0xB2, 0xC2, 0x84, 0x65, 0x12, 0x15, 0x35, 0x24, 0xC0, 0x89, 0x5E, 0x81,
];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let (cipher_text, tag) = gcm_aes_encrypt(&cipher_key, &iv, &p, &aad, &mul_fn);
assert_eq!(
&cipher_text,
&[
0x70, 0x1A, 0xFA, 0x1C, 0xC0, 0x39, 0xC0, 0xD7, 0x65, 0x12, 0x8A, 0x66, 0x5D, 0xAB,
0x69, 0x24, 0x38, 0x99, 0xBF, 0x73, 0x18, 0xCC, 0xDC, 0x81, 0xC9, 0x93, 0x1D, 0xA1,
0x7F, 0xBE, 0x8E, 0xDD, 0x7D, 0x17, 0xCB, 0x8B, 0x4C, 0x26, 0xFC, 0x81, 0xE3, 0x28,
0x4F, 0x2B, 0x7F, 0xBA, 0x71, 0x3D
]
);
assert_eq!(
&tag,
&[
0x4F, 0x8D, 0x55, 0xE7, 0xD3, 0xF0, 0x6F, 0xD5, 0xA1, 0x3C, 0x0C, 0x29, 0xB9, 0xD5,
0xB8, 0x80
]
);
let cipher_key = [
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30,
0x83, 0x08,
];
let iv = [
0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88,
];
let p = [
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5,
0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d,
0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf,
0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55,
];
let aad = [];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let (cipher_text, tag) = gcm_aes_encrypt(&cipher_key, &iv, &p, &aad, &mul_fn);
assert_eq!(
&cipher_text,
&[
0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0,
0xd4, 0x9c, 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, 0x35, 0xc1, 0x7e, 0x23,
0x29, 0xac, 0xa1, 0x2e, 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, 0x7d, 0x8f,
0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85
]
);
assert_eq!(
&tag,
&[
0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6,
0xfa, 0xb4
]
);
let cipher_key = [
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30,
0x83, 0x08,
];
let iv = [
0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88,
];
let p = [
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5,
0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d,
0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf,
0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
0xba, 0x63, 0x7b, 0x39,
];
let aad = [
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad,
0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2,
];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let (cipher_text, tag) = gcm_aes_encrypt(&cipher_key, &iv, &p, &aad, &mul_fn);
assert_eq!(
&cipher_text,
&[
0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0,
0xd4, 0x9c, 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, 0x35, 0xc1, 0x7e, 0x23,
0x29, 0xac, 0xa1, 0x2e, 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, 0x7d, 0x8f,
0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
0x3d, 0x58, 0xe0, 0x91
]
);
assert_eq!(
&tag,
&[
0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb, 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12,
0x1a, 0x47
]
);
let cipher_key = [
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30,
0x83, 0x08,
];
let iv = [0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad];
let p = [
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5,
0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d,
0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf,
0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
0xba, 0x63, 0x7b, 0x39,
];
let aad = [
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad,
0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2,
];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let (cipher_text, tag) = gcm_aes_encrypt(&cipher_key, &iv, &p, &aad, &mul_fn);
assert_eq!(
&cipher_text,
&[
0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a, 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a,
0x47, 0x55, 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8, 0x37, 0x66, 0xe5, 0xf9,
0x7b, 0x6c, 0x74, 0x23, 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2, 0x2b, 0x09,
0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42, 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
0xc2, 0x3f, 0x45, 0x98
]
);
assert_eq!(
&tag,
&[
0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85, 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2,
0xfc, 0xcb
]
);
let cipher_key = [
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30,
0x83, 0x08,
];
let iv = [
0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52,
0x69, 0xaa, 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, 0xe4, 0xc3, 0x03, 0xd2,
0xa3, 0x18, 0xa7, 0x28, 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, 0xfc, 0xf0,
0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
0xa6, 0x37, 0xb3, 0x9b,
];
let p = [
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5,
0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d,
0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf,
0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
0xba, 0x63, 0x7b, 0x39,
];
let aad = [
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad,
0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2,
];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let (cipher_text, tag) = gcm_aes_encrypt(&cipher_key, &iv, &p, &aad, &mul_fn);
assert_eq!(
&cipher_text,
&[
0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6, 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f,
0xb8, 0x94, 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8, 0xba, 0x26, 0x2a, 0x3c,
0xca, 0x7e, 0x2c, 0xa7, 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90, 0xcc, 0xdc,
0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f, 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
0x4c, 0x34, 0xae, 0xe5
]
);
assert_eq!(
&tag,
&[
0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa, 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99,
0xd0, 0x50
]
);
}
#[test]
fn test_gcm_aes_192_encrypt() {
let cipher_key = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
];
let iv = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
];
let p = [];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let (cipher_text, tag) = gcm_aes_encrypt(&cipher_key, &iv, &p, &"".as_bytes(), &mul_fn);
assert_eq!(&cipher_text, &[]);
assert_eq!(
&tag,
&[
0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b, 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57,
0x24, 0x35
]
);
let cipher_key = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
];
let iv = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
];
let p = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let (cipher_text, tag) = gcm_aes_encrypt(&cipher_key, &iv, &p, &"".as_bytes(), &mul_fn);
assert_eq!(
&cipher_text,
&[
0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41, 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0,
0xf6, 0x00
]
);
assert_eq!(
&tag,
&[
0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab, 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14,
0xf0, 0xfb
]
);
let cipher_key = [
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30,
0x83, 0x08, 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
];
let iv = [
0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88,
];
let p = [
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5,
0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d,
0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf,
0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55,
];
let aad = [];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let (cipher_text, tag) = gcm_aes_encrypt(&cipher_key, &iv, &p, &aad, &mul_fn);
assert_eq!(
&cipher_text,
&[
0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a,
0x27, 0x57, 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, 0x62, 0x85, 0x93, 0xb4,
0x0c, 0xa1, 0xe1, 0x9c, 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, 0xac, 0x61,
0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56
]
);
assert_eq!(
&tag,
&[
0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf, 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67,
0x4a, 0x14
]
);
let cipher_key = [
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30,
0x83, 0x08, 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
];
let iv = [
0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88,
];
let p = [
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5,
0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d,
0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf,
0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
0xba, 0x63, 0x7b, 0x39,
];
let aad = [
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad,
0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2,
];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let (cipher_text, tag) = gcm_aes_encrypt(&cipher_key, &iv, &p, &aad, &mul_fn);
assert_eq!(
&cipher_text,
&[
0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a,
0x27, 0x57, 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, 0x62, 0x85, 0x93, 0xb4,
0x0c, 0xa1, 0xe1, 0x9c, 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, 0xac, 0x61,
0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
0xcc, 0xda, 0x27, 0x10
]
);
assert_eq!(
&tag,
&[
0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f, 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27,
0x61, 0x8c
]
);
let cipher_key = [
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30,
0x83, 0x08, 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
];
let iv = [0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad];
let p = [
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5,
0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d,
0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf,
0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
0xba, 0x63, 0x7b, 0x39,
];
let aad = [
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad,
0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2,
];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let (cipher_text, tag) = gcm_aes_encrypt(&cipher_key, &iv, &p, &aad, &mul_fn);
assert_eq!(
&cipher_text,
&[
0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54, 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32,
0x4d, 0xb8, 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f, 0x83, 0x47, 0x28, 0x0f,
0xc4, 0x50, 0x70, 0x57, 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75, 0xc6, 0x65,
0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9, 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
0xa0, 0xf0, 0x62, 0xf7
]
);
assert_eq!(
&tag,
&[
0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24, 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35,
0x33, 0xf8
]
);
let cipher_key = [
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30,
0x83, 0x08, 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
];
let iv = [
0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52,
0x69, 0xaa, 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, 0xe4, 0xc3, 0x03, 0xd2,
0xa3, 0x18, 0xa7, 0x28, 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, 0xfc, 0xf0,
0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
0xa6, 0x37, 0xb3, 0x9b,
];
let p = [
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5,
0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d,
0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf,
0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
0xba, 0x63, 0x7b, 0x39,
];
let aad = [
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad,
0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2,
];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let (cipher_text, tag) = gcm_aes_encrypt(&cipher_key, &iv, &p, &aad, &mul_fn);
assert_eq!(
&cipher_text,
&[
0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c, 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc,
0xf9, 0xff, 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef, 0x6e, 0xf7, 0xb7, 0x98,
0x28, 0x66, 0x6e, 0x45, 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9, 0xe2, 0xf0,
0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3, 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
0xe9, 0xb7, 0x37, 0x3b
]
);
assert_eq!(
&tag,
&[
0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb, 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76,
0xa6, 0xd9
]
);
}
#[test]
fn test_gcm_aes_256_encrypt() {
let cipher_key = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let iv = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
];
let p = [];
let (cipher_text, tag) = gcm_aes_encrypt(&cipher_key, &iv, &p, &"".as_bytes(), &mul_fn);
assert_eq!(&cipher_text, &[]);
assert_eq!(
&tag,
&[
0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb,
0x73, 0x8b
]
);
let cipher_key = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
];
let iv = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
];
let p = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let (cipher_text, tag) = gcm_aes_encrypt(&cipher_key, &iv, &p, &"".as_bytes(), &mul_fn);
assert_eq!(
&cipher_text,
&[
0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e, 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3,
0x9d, 0x18
]
);
assert_eq!(
&tag,
&[
0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0, 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a,
0xb9, 0x19
]
);
let cipher_key = [
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30,
0x83, 0x08, 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94,
0x67, 0x30, 0x83, 0x08,
];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let iv = [
0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88,
];
let p = [
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5,
0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d,
0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf,
0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55,
];
let aad = [];
let (cipher_text, tag) = gcm_aes_encrypt(&cipher_key, &iv, &p, &aad, &mul_fn);
assert_eq!(
&cipher_text,
&[
0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84,
0x42, 0x7d, 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, 0x75, 0x98, 0xa2, 0xbd,
0x25, 0x55, 0xd1, 0xaa, 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, 0xa7, 0xb0,
0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad
]
);
assert_eq!(
&tag,
&[
0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd, 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3,
0xcc, 0x6c
]
);
let cipher_key = [
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30,
0x83, 0x08, 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94,
0x67, 0x30, 0x83, 0x08,
];
let iv = [
0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88,
];
let p = [
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5,
0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d,
0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf,
0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
0xba, 0x63, 0x7b, 0x39,
];
let aad = [
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad,
0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2,
];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let (cipher_text, tag) = gcm_aes_encrypt(&cipher_key, &iv, &p, &aad, &mul_fn);
assert_eq!(
&cipher_text,
&[
0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84,
0x42, 0x7d, 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, 0x75, 0x98, 0xa2, 0xbd,
0x25, 0x55, 0xd1, 0xaa, 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, 0xa7, 0xb0,
0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
0xbc, 0xc9, 0xf6, 0x62
]
);
assert_eq!(
&tag,
&[
0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68, 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d,
0x55, 0x1b
]
);
let cipher_key = [
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30,
0x83, 0x08, 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94,
0x67, 0x30, 0x83, 0x08,
];
let iv = [0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad];
let p = [
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5,
0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d,
0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf,
0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
0xba, 0x63, 0x7b, 0x39,
];
let aad = [
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad,
0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2,
];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let (cipher_text, tag) = gcm_aes_encrypt(&cipher_key, &iv, &p, &aad, &mul_fn);
assert_eq!(
&cipher_text,
&[
0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32, 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98,
0x44, 0xcb, 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa, 0xc5, 0x2f, 0xf7, 0xd7,
0x9b, 0xba, 0x9d, 0xe0, 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0, 0x95, 0x4c,
0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78, 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
0xf4, 0x7c, 0x9b, 0x1f
]
);
assert_eq!(
&tag,
&[
0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4, 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e,
0xa8, 0xf2
]
);
let cipher_key = [
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30,
0x83, 0x08, 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94,
0x67, 0x30, 0x83, 0x08,
];
let iv = [
0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52,
0x69, 0xaa, 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, 0xe4, 0xc3, 0x03, 0xd2,
0xa3, 0x18, 0xa7, 0x28, 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, 0xfc, 0xf0,
0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
0xa6, 0x37, 0xb3, 0x9b,
];
let p = [
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5,
0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d,
0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf,
0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
0xba, 0x63, 0x7b, 0x39,
];
let aad = [
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad,
0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2,
];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let (cipher_text, tag) = gcm_aes_encrypt(&cipher_key, &iv, &p, &aad, &mul_fn);
assert_eq!(
&cipher_text,
&[
0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1, 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e,
0x2a, 0x20, 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19, 0xa0, 0x58, 0xab, 0x4f,
0x6f, 0x74, 0x6b, 0xf4, 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45, 0x2d, 0xa3,
0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde, 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
0x44, 0xae, 0x7e, 0x3f
]
);
assert_eq!(
&tag,
&[
0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0, 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9,
0xf1, 0x9a
]
);
}
#[test]
fn test_calculate_m() {
let cipher_key = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
];
let h_block = aes::encrypt(&[0u8; BLOCK_SIZE], &cipher_key);
let h = u128::from_be_bytes(h_block);
let m0 = calculate_table_m(h, 0);
assert_eq!(
block_mul(h, 254u128.reverse_bits()),
m0[254u8.reverse_bits() as usize]
);
assert_eq!(
block_mul(h, 1u128.reverse_bits()),
m0[1u8.reverse_bits() as usize]
);
assert_eq!(
block_mul(h, 0u128.reverse_bits()),
m0[0u8.reverse_bits() as usize]
);
assert_eq!(
block_mul(h, 2u128.reverse_bits()),
m0[2u8.reverse_bits() as usize]
);
assert_eq!(
block_mul(h, 4u128.reverse_bits()),
m0[4u8.reverse_bits() as usize]
);
assert_eq!(
block_mul(h, 37u128.reverse_bits()),
m0[37u8.reverse_bits() as usize]
);
let m1 = calculate_table_m(h, 1);
assert_eq!(block_mul(m0[254], 1u128.reverse_bits() >> 8), m1[254]);
assert_eq!(block_mul(m0[1], 1u128.reverse_bits() >> 8), m1[1]);
assert_eq!(block_mul(m0[4], 1u128.reverse_bits() >> 8), m1[4]);
assert_eq!(block_mul(m0[0], 1u128.reverse_bits() >> 8), m1[0]);
assert_eq!(block_mul(m0[2], 1u128.reverse_bits() >> 8), m1[2]);
assert_eq!(block_mul(m0[37], 1u128.reverse_bits() >> 8), m1[37]);
let m2 = calculate_table_m(h, 2);
assert_eq!(block_mul(m1[254], 1u128.reverse_bits() >> 8), m2[254]);
assert_eq!(block_mul(m1[1], 1u128.reverse_bits() >> 8), m2[1]);
assert_eq!(block_mul(m1[4], 1u128.reverse_bits() >> 8), m2[4]);
assert_eq!(block_mul(m1[0], 1u128.reverse_bits() >> 8), m2[0]);
assert_eq!(block_mul(m1[2], 1u128.reverse_bits() >> 8), m2[2]);
assert_eq!(block_mul(m1[37], 1u128.reverse_bits() >> 8), m2[37]);
assert_eq!(block_mul(m0[37], 1u128.reverse_bits() >> 16), m2[37]);
let m3 = calculate_table_m(h, 3);
assert_eq!(block_mul(m2[255], 1u128.reverse_bits() >> 8), m3[255]);
assert_eq!(block_mul(m2[11], 1u128.reverse_bits() >> 8), m3[11]);
assert_eq!(block_mul(m2[8], 1u128.reverse_bits() >> 8), m3[8]);
assert_eq!(block_mul(m2[15], 1u128.reverse_bits() >> 8), m3[15]);
assert_eq!(block_mul(m2[3], 1u128.reverse_bits() >> 8), m3[3]);
assert_eq!(block_mul(m2[33], 1u128.reverse_bits() >> 8), m3[33]);
assert_eq!(block_mul(m0[77], 1u128.reverse_bits() >> 24), m3[77]);
let m4 = calculate_table_m(h, 4);
assert_eq!(block_mul(m3[64], 1u128.reverse_bits() >> 8), m4[64]);
assert_eq!(block_mul(m3[32], 1u128.reverse_bits() >> 8), m4[32]);
assert_eq!(block_mul(m3[192], 1u128.reverse_bits() >> 8), m4[192]);
assert_eq!(block_mul(m3[12], 1u128.reverse_bits() >> 8), m4[12]);
assert_eq!(block_mul(m3[128], 1u128.reverse_bits() >> 8), m4[128]);
assert_eq!(block_mul(m3[129], 1u128.reverse_bits() >> 8), m4[129]);
assert_eq!(block_mul(m0[211], 1u128.reverse_bits() >> 32), m4[211]);
let m5 = calculate_table_m(h, 5);
assert_eq!(block_mul(m0[12], 1u128.reverse_bits() >> 40), m5[12]);
assert_eq!(block_mul(m1[15], 1u128.reverse_bits() >> 32), m5[15]);
assert_eq!(block_mul(m2[16], 1u128.reverse_bits() >> 24), m5[16]);
assert_eq!(block_mul(m3[128], 1u128.reverse_bits() >> 16), m5[128]);
let m6 = calculate_table_m(h, 6);
let m7 = calculate_table_m(h, 7);
let m8 = calculate_table_m(h, 8);
let m9 = calculate_table_m(h, 9);
let m10 = calculate_table_m(h, 10);
let m11 = calculate_table_m(h, 11);
let m12 = calculate_table_m(h, 12);
let m13 = calculate_table_m(h, 13);
let m14 = calculate_table_m(h, 14);
let m15 = calculate_table_m(h, 15);
assert_eq!(block_mul(m0[2], 1u128.reverse_bits() >> 120), m15[2]);
assert_eq!(block_mul(m1[3], 1u128.reverse_bits() >> 112), m15[3]);
assert_eq!(block_mul(m2[4], 1u128.reverse_bits() >> 104), m15[4]);
assert_eq!(block_mul(m3[5], 1u128.reverse_bits() >> 96), m15[5]);
assert_eq!(block_mul(m4[6], 1u128.reverse_bits() >> 88), m15[6]);
assert_eq!(block_mul(m5[7], 1u128.reverse_bits() >> 80), m15[7]);
assert_eq!(block_mul(m6[8], 1u128.reverse_bits() >> 72), m15[8]);
assert_eq!(block_mul(m7[9], 1u128.reverse_bits() >> 64), m15[9]);
assert_eq!(block_mul(m8[1], 1u128.reverse_bits() >> 56), m15[1]);
assert_eq!(block_mul(m9[255], 1u128.reverse_bits() >> 48), m15[255]);
assert_eq!(block_mul(m10[232], 1u128.reverse_bits() >> 40), m15[232]);
assert_eq!(block_mul(m11[192], 1u128.reverse_bits() >> 32), m15[192]);
assert_eq!(block_mul(m12[64], 1u128.reverse_bits() >> 24), m15[64]);
assert_eq!(block_mul(m13[17], 1u128.reverse_bits() >> 16), m15[17]);
assert_eq!(block_mul(m14[93], 1u128.reverse_bits() >> 8), m15[93]);
}
#[test]
fn test_gcm_aes_block_mul_with_tables() {
let cipher_key = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
];
let h_block = aes::encrypt(&[0u8; BLOCK_SIZE], &cipher_key);
let h = u128::from_be_bytes(h_block);
let mut m = [[0u128; 256]; BLOCK_SIZE];
for i in 0..BLOCK_SIZE {
m[i] = calculate_table_m(h, i);
}
let x_block = [
0x2fu8, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab, 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14,
0xf0, 0xfb,
];
let x = u128::from_be_bytes(x_block);
let r1 = block_mul_with_tables(&m, x);
let r2 = block_mul(x, h);
assert_eq!(r1, r2);
let cipher_key = [
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30,
0x83, 0x08,
];
let iv = [
0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88,
];
let p = [
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5,
0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d,
0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf,
0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55,
];
let aad = [];
let mul_fn = GcmBlockMulEnhancement::MTables.to_mul_fn(&cipher_key);
let (cipher_text, tag) = gcm_aes_encrypt(&cipher_key, &iv, &p, &aad, &mul_fn);
assert_eq!(
&cipher_text,
&[
0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0,
0xd4, 0x9c, 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, 0x35, 0xc1, 0x7e, 0x23,
0x29, 0xac, 0xa1, 0x2e, 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, 0x7d, 0x8f,
0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85
]
);
assert_eq!(
&tag,
&[
0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6,
0xfa, 0xb4
]
);
}
#[test]
fn test_gcm_aes_block_mul_with_4bit_tables() {
let cipher_key = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
];
let h_block = aes::encrypt(&[0u8; BLOCK_SIZE], &cipher_key);
let h = u128::from_be_bytes(h_block);
let mut m = [[0u128; 16]; BLOCK_SIZE << 1];
for i in 0..m.len() {
m[i] = calculate_4bit_table_m(h, i);
}
let x_block = [
0x2fu8, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab, 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14,
0xf0, 0xfb,
];
let x = u128::from_be_bytes(x_block);
let r1 = block_mul_with_4bit_tables(&m, x);
let r2 = block_mul(x, h);
assert_eq!(r1, r2);
let cipher_key = [
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30,
0x83, 0x08,
];
let iv = [
0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88,
];
let p = [
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5,
0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d,
0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf,
0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55,
];
let aad = [];
let mul_fn = GcmBlockMulEnhancement::M4BitTables.to_mul_fn(&cipher_key);
let (cipher_text, tag) = gcm_aes_encrypt(&cipher_key, &iv, &p, &aad, &mul_fn);
assert_eq!(
&cipher_text,
&[
0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0,
0xd4, 0x9c, 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, 0x35, 0xc1, 0x7e, 0x23,
0x29, 0xac, 0xa1, 0x2e, 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, 0x7d, 0x8f,
0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85
]
);
assert_eq!(
&tag,
&[
0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6,
0xfa, 0xb4
]
);
}
#[test]
fn test_gcm_aes_calculate_r_table() {
assert_eq!(TABLE_R[0x80], 0xe100);
}
#[test]
fn test_gcm_aes_block_mul_with_m0_r() {
let cipher_key = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
];
let h_block = aes::encrypt(&[0u8; BLOCK_SIZE], &cipher_key);
let h = u128::from_be_bytes(h_block);
let m0 = calculate_table_m(h, 0);
let x_block = [
0x2fu8, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab, 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14,
0xf0, 0xfb,
];
let x = u128::from_be_bytes(x_block);
let r1 = block_mul_with_m0_r(&m0, x);
let r2 = block_mul(h, x);
assert_eq!(r1, r2);
let cipher_key = [
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30,
0x83, 0x08,
];
let iv = [
0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88,
];
let p = [
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5,
0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d,
0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf,
0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55,
];
let aad = [];
let mul_fn = GcmBlockMulEnhancement::M0TableAndRTable.to_mul_fn(&cipher_key);
let (cipher_text, tag) = gcm_aes_encrypt(&cipher_key, &iv, &p, &aad, &mul_fn);
assert_eq!(
&cipher_text,
&[
0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0,
0xd4, 0x9c, 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, 0x35, 0xc1, 0x7e, 0x23,
0x29, 0xac, 0xa1, 0x2e, 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, 0x7d, 0x8f,
0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85
]
);
assert_eq!(
&tag,
&[
0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6,
0xfa, 0xb4
]
);
}
#[test]
fn test_gcm_aes_128_decrypt() {
let cipher_key = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
];
let iv = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
];
let cipher_text = [];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let (p, tag) = gcm_aes_decrypt(&cipher_key, &iv, &cipher_text, &[], &mul_fn);
assert_eq!(&p, &[]);
assert_eq!(
&tag,
&[
0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7,
0x45, 0x5a
]
);
let cipher_text = [
0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2,
0xfe, 0x78,
];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let (p, tag) = gcm_aes_decrypt(&cipher_key, &iv, &cipher_text, &[], &mul_fn);
assert_eq!(
&p,
&[
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00
]
);
assert_eq!(
&tag,
&[
0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57,
0xbd, 0xdf
]
);
let cipher_key = [
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30,
0x83, 0x08,
];
let iv = [
0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88,
];
let cipher_text = [
0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0,
0xd4, 0x9c, 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, 0x35, 0xc1, 0x7e, 0x23,
0x29, 0xac, 0xa1, 0x2e, 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, 0x7d, 0x8f,
0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85,
];
let aad = [];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let (p, tag) = gcm_aes_decrypt(&cipher_key, &iv, &cipher_text, &aad, &mul_fn);
assert_eq!(
&p,
&[
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5,
0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d,
0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf,
0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55
]
);
assert_eq!(
&tag,
&[
0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6,
0xfa, 0xb4
]
);
let cipher_key = [
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30,
0x83, 0x08,
];
let iv = [
0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88,
];
let cipher_text = [
0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0,
0xd4, 0x9c, 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, 0x35, 0xc1, 0x7e, 0x23,
0x29, 0xac, 0xa1, 0x2e, 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, 0x7d, 0x8f,
0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
0x3d, 0x58, 0xe0, 0x91,
];
let aad = [
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad,
0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2,
];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let (p, tag) = gcm_aes_decrypt(&cipher_key, &iv, &cipher_text, &aad, &mul_fn);
assert_eq!(
&p,
&[
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5,
0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d,
0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf,
0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
0xba, 0x63, 0x7b, 0x39
]
);
assert_eq!(
&tag,
&[
0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb, 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12,
0x1a, 0x47
]
);
let cipher_key = [
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30,
0x83, 0x08,
];
let iv = [0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad];
let cipher_text = [
0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a, 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a,
0x47, 0x55, 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8, 0x37, 0x66, 0xe5, 0xf9,
0x7b, 0x6c, 0x74, 0x23, 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2, 0x2b, 0x09,
0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42, 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
0xc2, 0x3f, 0x45, 0x98,
];
let aad = [
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad,
0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2,
];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let (p, tag) = gcm_aes_decrypt(&cipher_key, &iv, &cipher_text, &aad, &mul_fn);
assert_eq!(
&p,
&[
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5,
0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d,
0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf,
0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
0xba, 0x63, 0x7b, 0x39
]
);
assert_eq!(
&tag,
&[
0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85, 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2,
0xfc, 0xcb
]
);
let cipher_key = [
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30,
0x83, 0x08,
];
let iv = [
0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52,
0x69, 0xaa, 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, 0xe4, 0xc3, 0x03, 0xd2,
0xa3, 0x18, 0xa7, 0x28, 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, 0xfc, 0xf0,
0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
0xa6, 0x37, 0xb3, 0x9b,
];
let cipher_text = [
0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6, 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f,
0xb8, 0x94, 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8, 0xba, 0x26, 0x2a, 0x3c,
0xca, 0x7e, 0x2c, 0xa7, 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90, 0xcc, 0xdc,
0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f, 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
0x4c, 0x34, 0xae, 0xe5,
];
let aad = [
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad,
0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2,
];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let (p, tag) = gcm_aes_decrypt(&cipher_key, &iv, &cipher_text, &aad, &mul_fn);
assert_eq!(
&p,
&[
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5,
0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d,
0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf,
0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
0xba, 0x63, 0x7b, 0x39
]
);
assert_eq!(
&tag,
&[
0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa, 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99,
0xd0, 0x50
]
);
}
#[test]
fn test_gcm_aes_256_decrypt() {
let cipher_key = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let iv = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
];
let cipher_text = [];
let (p, tag) = gcm_aes_decrypt(&cipher_key, &iv, &cipher_text, &[], &mul_fn);
assert_eq!(&p, &[]);
assert_eq!(
&tag,
&[
0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb,
0x73, 0x8b
]
);
let cipher_key = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
];
let iv = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
];
let cipher_text = [
0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e, 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3,
0x9d, 0x18,
];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let (p, tag) = gcm_aes_decrypt(&cipher_key, &iv, &cipher_text, &"".as_bytes(), &mul_fn);
assert_eq!(
&p,
&[
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00
]
);
assert_eq!(
&tag,
&[
0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0, 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a,
0xb9, 0x19
]
);
let cipher_key = [
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30,
0x83, 0x08, 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94,
0x67, 0x30, 0x83, 0x08,
];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let iv = [
0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88,
];
let cipher_text = [
0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84,
0x42, 0x7d, 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, 0x75, 0x98, 0xa2, 0xbd,
0x25, 0x55, 0xd1, 0xaa, 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, 0xa7, 0xb0,
0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad,
];
let aad = [];
let (p, tag) = gcm_aes_decrypt(&cipher_key, &iv, &cipher_text, &aad, &mul_fn);
assert_eq!(
&p,
&[
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5,
0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d,
0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf,
0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55
]
);
assert_eq!(
&tag,
&[
0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd, 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3,
0xcc, 0x6c
]
);
let cipher_key = [
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30,
0x83, 0x08, 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94,
0x67, 0x30, 0x83, 0x08,
];
let iv = [
0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88,
];
let cipher_text = [
0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84,
0x42, 0x7d, 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, 0x75, 0x98, 0xa2, 0xbd,
0x25, 0x55, 0xd1, 0xaa, 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, 0xa7, 0xb0,
0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
0xbc, 0xc9, 0xf6, 0x62,
];
let aad = [
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad,
0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2,
];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let (p, tag) = gcm_aes_decrypt(&cipher_key, &iv, &cipher_text, &aad, &mul_fn);
assert_eq!(
&p,
&[
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5,
0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d,
0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf,
0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
0xba, 0x63, 0x7b, 0x39
]
);
assert_eq!(
&tag,
&[
0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68, 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d,
0x55, 0x1b
]
);
let cipher_key = [
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30,
0x83, 0x08, 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94,
0x67, 0x30, 0x83, 0x08,
];
let iv = [0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad];
let cipher_text = [
0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32, 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98,
0x44, 0xcb, 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa, 0xc5, 0x2f, 0xf7, 0xd7,
0x9b, 0xba, 0x9d, 0xe0, 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0, 0x95, 0x4c,
0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78, 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
0xf4, 0x7c, 0x9b, 0x1f,
];
let aad = [
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad,
0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2,
];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let (p, tag) = gcm_aes_decrypt(&cipher_key, &iv, &cipher_text, &aad, &mul_fn);
assert_eq!(
&p,
&[
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5,
0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d,
0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf,
0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
0xba, 0x63, 0x7b, 0x39
]
);
assert_eq!(
&tag,
&[
0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4, 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e,
0xa8, 0xf2
]
);
let cipher_key = [
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30,
0x83, 0x08, 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94,
0x67, 0x30, 0x83, 0x08,
];
let iv = [
0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52,
0x69, 0xaa, 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, 0xe4, 0xc3, 0x03, 0xd2,
0xa3, 0x18, 0xa7, 0x28, 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, 0xfc, 0xf0,
0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
0xa6, 0x37, 0xb3, 0x9b,
];
let cipher_text = [
0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1, 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e,
0x2a, 0x20, 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19, 0xa0, 0x58, 0xab, 0x4f,
0x6f, 0x74, 0x6b, 0xf4, 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45, 0x2d, 0xa3,
0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde, 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
0x44, 0xae, 0x7e, 0x3f,
];
let aad = [
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad,
0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2,
];
let mul_fn = GcmBlockMulEnhancement::None.to_mul_fn(&cipher_key);
let (p, tag) = gcm_aes_decrypt(&cipher_key, &iv, &cipher_text, &aad, &mul_fn);
assert_eq!(
&p,
&[
0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5,
0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d,
0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf,
0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
0xba, 0x63, 0x7b, 0x39
]
);
assert_eq!(
&tag,
&[
0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0, 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9,
0xf1, 0x9a
]
);
}
}