use crate::BlockCipher::BlockCipherTrait;
static RoundConstant: [u8; 11] = [ 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 ];
static SBox: [u8; 256] =
[
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
];
static InvertSBox: [u8; 256] =
[
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
];
static X1LookupTable: [u8; 256] =
[
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 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, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
];
static X2LookupTable: [u8; 256] =
[
0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05,
0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25,
0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45,
0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65,
0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85,
0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5,
0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5
];
static X3LookupTable: [u8; 256] =
[
0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11,
0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21,
0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41,
0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1,
0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1,
0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1,
0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81,
0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a,
0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba,
0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea,
0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda,
0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a,
0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a,
0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a,
0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a
];
static X9LookupTable: [u8; 256] =
[
0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7,
0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8, 0xc7, 0xce, 0xd5, 0xdc,
0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49, 0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01,
0xe6, 0xef, 0xf4, 0xfd, 0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91,
0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e, 0x21, 0x28, 0x33, 0x3a,
0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2, 0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa,
0xec, 0xe5, 0xfe, 0xf7, 0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b,
0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f, 0x10, 0x19, 0x02, 0x0b,
0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8, 0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0,
0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30,
0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed,
0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35, 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d,
0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6,
0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46
];
static X11LookupTable: [u8; 256] =
[
0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69,
0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9,
0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12,
0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, 0x85, 0x8e, 0xbf, 0xb4, 0xa9, 0xa2,
0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7, 0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f,
0x46, 0x4d, 0x50, 0x5b, 0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f,
0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8, 0xf9, 0xf2, 0xef, 0xe4,
0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c, 0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54,
0xf7, 0xfc, 0xe1, 0xea, 0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e,
0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2e,
0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd, 0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5,
0x3c, 0x37, 0x2a, 0x21, 0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55,
0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68,
0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80, 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8,
0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13,
0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3
];
static X13LookupTable: [u8; 256] =
[
0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b,
0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b,
0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0,
0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14, 0x37, 0x3a, 0x2d, 0x20,
0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e, 0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26,
0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6,
0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9, 0x8a, 0x87, 0x90, 0x9d,
0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25, 0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d,
0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91,
0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41,
0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42, 0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a,
0xb1, 0xbc, 0xab, 0xa6, 0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa,
0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc,
0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44, 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c,
0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47,
0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97
];
static X14LookupTable: [u8; 256] =
[
0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a,
0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba,
0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81,
0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59, 0x73, 0x7d, 0x6f, 0x61,
0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87, 0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7,
0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17,
0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14, 0x3e, 0x30, 0x22, 0x2c,
0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc, 0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc,
0x41, 0x4f, 0x5d, 0x53, 0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b,
0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3, 0xe9, 0xe7, 0xf5, 0xfb,
0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0, 0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0,
0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20,
0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6,
0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56,
0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d,
0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d
];
fn AddRoundKey (state: &mut [[u8; 4]; 4], roundKey: &[[u8; 4]; 4])
{
for i in 0..4
{
for j in 0..4
{
state[i][j] = state[i][j] ^ roundKey[i][j];
}
}
}
fn SubBytes (state: &mut [[u8; 4]; 4])
{
for i in 0..4
{
for j in 0..4
{
state[i][j] = SBox[state[i][j] as usize];
}
}
}
fn ShiftRows (state: &mut [[u8; 4]; 4])
{
let tmp = state[1][0];
state[1][0] = state[1][1];
state[1][1] = state[1][2];
state[1][2] = state[1][3];
state[1][3] = tmp;
let tmp = state[2][0];
state[2][0] = state[2][2];
state[2][2] = tmp;
let tmp = state[2][1];
state[2][1] = state[2][3];
state[2][3] = tmp;
let tmp = state[3][3];
state[3][3] = state[3][2];
state[3][2] = state[3][1];
state[3][1] = state[3][0];
state[3][0] = tmp;
}
fn MixColumns (state: &mut [[u8; 4]; 4])
{
for j in 0..4
{
let mut tmp = [0; 4];
tmp[0] = X2LookupTable[state[0][j] as usize] ^ X3LookupTable[state[1][j] as usize] ^ X1LookupTable[state[2][j] as usize] ^ X1LookupTable[state[3][j] as usize];
tmp[1] = X1LookupTable[state[0][j] as usize] ^ X2LookupTable[state[1][j] as usize] ^ X3LookupTable[state[2][j] as usize] ^ X1LookupTable[state[3][j] as usize];
tmp[2] = X1LookupTable[state[0][j] as usize] ^ X1LookupTable[state[1][j] as usize] ^ X2LookupTable[state[2][j] as usize] ^ X3LookupTable[state[3][j] as usize];
tmp[3] = X3LookupTable[state[0][j] as usize] ^ X1LookupTable[state[1][j] as usize] ^ X1LookupTable[state[2][j] as usize] ^ X2LookupTable[state[3][j] as usize];
for i in 0..4
{
state[i][j] = tmp[i];
}
}
}
fn InvertSubBytes (state: &mut [[u8; 4]; 4])
{
for i in 0..4
{
for j in 0..4
{
state[i][j] = InvertSBox[state[i][j] as usize];
}
}
}
fn InvertShiftRows (state: &mut [[u8; 4]; 4])
{
let tmp = state[1][3];
state[1][3] = state[1][2];
state[1][2] = state[1][1];
state[1][1] = state[1][0];
state[1][0] = tmp;
let tmp = state[2][2];
state[2][2] = state[2][0];
state[2][0] = tmp;
let tmp = state[2][3];
state[2][3] = state[2][1];
state[2][1] = tmp;
let tmp = state[3][0];
state[3][0] = state[3][1];
state[3][1] = state[3][2];
state[3][2] = state[3][3];
state[3][3] = tmp;
}
fn InvertMixColumns (state: &mut [[u8; 4]; 4])
{
for j in 0..4
{
let mut tmp = [0; 4];
tmp[0] = X14LookupTable[state[0][j] as usize] ^ X11LookupTable[state[1][j] as usize] ^ X13LookupTable[state[2][j] as usize] ^ X9LookupTable[state[3][j] as usize];
tmp[1] = X9LookupTable[state[0][j] as usize] ^ X14LookupTable[state[1][j] as usize] ^ X11LookupTable[state[2][j] as usize] ^ X13LookupTable[state[3][j] as usize];
tmp[2] = X13LookupTable[state[0][j] as usize] ^ X9LookupTable[state[1][j] as usize] ^ X14LookupTable[state[2][j] as usize] ^ X11LookupTable[state[3][j] as usize];
tmp[3] = X11LookupTable[state[0][j] as usize] ^ X13LookupTable[state[1][j] as usize] ^ X9LookupTable[state[2][j] as usize] ^ X14LookupTable[state[3][j] as usize];
for i in 0..4
{
state[i][j] = tmp[i];
}
}
}
#[derive(Debug, Clone)]
pub struct Aes128CipherKey([u8; Aes128Cipher::KEY_LEN]);
impl Aes128CipherKey
{
pub fn New (key: &[u8; Aes128Cipher::KEY_LEN]) -> Self { Self(key.clone ()) }
}
#[derive(Debug, Clone)]
pub struct Aes128Cipher
{
key: Aes128CipherKey,
roundKeys: [[[u8; 4]; 4]; Self::ROUND_NUMBER + 1],
}
impl Aes128Cipher
{
const KEY_WORD_LEN: usize = 4;
const ROUND_NUMBER: usize = 10;
const KEY_LEN: usize = Self::KEY_WORD_LEN*4;
const EXPANDED_KEY_WORD_LEN: usize = 4*(Self::ROUND_NUMBER + 1);
pub fn New (key: &Aes128CipherKey) -> Self
{
let mut result = Self
{
key: key.clone (),
roundKeys: [[[0u8; 4]; 4]; Self::ROUND_NUMBER + 1],
};
result.CreateRoundKeys ();
result
}
fn CreateRoundKeys (&mut self)
{
let mut expandedKey = [[0; 4]; Self::EXPANDED_KEY_WORD_LEN];
for i in 0..Self::EXPANDED_KEY_WORD_LEN
{
if i < Self::KEY_WORD_LEN
{
expandedKey[i][0] = self.key.0[i*4 + 0];
expandedKey[i][1] = self.key.0[i*4 + 1];
expandedKey[i][2] = self.key.0[i*4 + 2];
expandedKey[i][3] = self.key.0[i*4 + 3];
}
else if i % Self::KEY_WORD_LEN == 0
{
let mut tmpWord = expandedKey[i - 1];
let tmp = tmpWord[0];
tmpWord[0] = tmpWord[1];
tmpWord[1] = tmpWord[2];
tmpWord[2] = tmpWord[3];
tmpWord[3] = tmp;
tmpWord[0] = SBox[tmpWord[0] as usize];
tmpWord[1] = SBox[tmpWord[1] as usize];
tmpWord[2] = SBox[tmpWord[2] as usize];
tmpWord[3] = SBox[tmpWord[3] as usize];
tmpWord[0] = tmpWord[0] ^ RoundConstant[i/Self::KEY_WORD_LEN];
expandedKey[i][0] = expandedKey[i - Self::KEY_WORD_LEN][0] ^ tmpWord[0];
expandedKey[i][1] = expandedKey[i - Self::KEY_WORD_LEN][1] ^ tmpWord[1];
expandedKey[i][2] = expandedKey[i - Self::KEY_WORD_LEN][2] ^ tmpWord[2];
expandedKey[i][3] = expandedKey[i - Self::KEY_WORD_LEN][3] ^ tmpWord[3];
}
else if Self::KEY_WORD_LEN > 6 && (i % Self::KEY_WORD_LEN) == 4
{
let mut tmpWord = expandedKey[i - 1];
tmpWord[0] = SBox[tmpWord[0] as usize];
tmpWord[1] = SBox[tmpWord[1] as usize];
tmpWord[2] = SBox[tmpWord[2] as usize];
tmpWord[3] = SBox[tmpWord[3] as usize];
expandedKey[i][0] = expandedKey[i - Self::KEY_WORD_LEN][0] ^ tmpWord[0];
expandedKey[i][1] = expandedKey[i - Self::KEY_WORD_LEN][1] ^ tmpWord[1];
expandedKey[i][2] = expandedKey[i - Self::KEY_WORD_LEN][2] ^ tmpWord[2];
expandedKey[i][3] = expandedKey[i - Self::KEY_WORD_LEN][3] ^ tmpWord[3];
}
else
{
expandedKey[i][0] = expandedKey[i - Self::KEY_WORD_LEN][0] ^ expandedKey[i - 1][0];
expandedKey[i][1] = expandedKey[i - Self::KEY_WORD_LEN][1] ^ expandedKey[i - 1][1];
expandedKey[i][2] = expandedKey[i - Self::KEY_WORD_LEN][2] ^ expandedKey[i - 1][2];
expandedKey[i][3] = expandedKey[i - Self::KEY_WORD_LEN][3] ^ expandedKey[i - 1][3];
}
}
for i in 0..Self::ROUND_NUMBER + 1
{
for j in 0..4
{
self.roundKeys[i][0][j] = expandedKey[i*4 + j][0];
self.roundKeys[i][1][j] = expandedKey[i*4 + j][1];
self.roundKeys[i][2][j] = expandedKey[i*4 + j][2];
self.roundKeys[i][3][j] = expandedKey[i*4 + j][3];
}
}
}
pub fn Encrypt (&self, input: &[u8; Self::BLOCK_SIZE]) -> [u8; Self::BLOCK_SIZE]
{
let mut output = [0; Self::BLOCK_SIZE];
self.EncryptInplace (input, &mut output);
output
}
pub fn Decrypt (&self, input: &[u8; Self::BLOCK_SIZE]) -> [u8; Self::BLOCK_SIZE]
{
let mut output = [0; Self::BLOCK_SIZE];
self.DecryptInplace (input, &mut output);
output
}
pub fn EncryptInplace (&self, input: &[u8; Self::BLOCK_SIZE], output: &mut [u8; Self::BLOCK_SIZE])
{
let mut state = [[0; 4]; 4];
for i in 0..4
{
for j in 0..4
{
state[j][i] = input[i*4 + j];
}
}
AddRoundKey (&mut state, &self.roundKeys[0]);
for i in 1..Self::ROUND_NUMBER
{
SubBytes (&mut state);
ShiftRows (&mut state);
MixColumns (&mut state);
AddRoundKey (&mut state, &self.roundKeys[i]);
}
SubBytes (&mut state);
ShiftRows (&mut state);
AddRoundKey (&mut state, &self.roundKeys[Self::ROUND_NUMBER]);
for i in 0..4
{
for j in 0..4
{
output[i*4 + j] = state[j][i];
}
}
}
pub fn DecryptInplace (&self, input: &[u8; Self::BLOCK_SIZE], output: &mut [u8; Self::BLOCK_SIZE])
{
let mut state = [[0; 4]; 4];
for i in 0..4
{
for j in 0..4
{
state[j][i] = input[i*4 + j];
}
}
AddRoundKey (&mut state, &self.roundKeys[Self::ROUND_NUMBER]);
InvertShiftRows (&mut state);
InvertSubBytes (&mut state);
for i in (1..Self::ROUND_NUMBER).rev ()
{
AddRoundKey (&mut state, &self.roundKeys[i]);
InvertMixColumns (&mut state);
InvertShiftRows (&mut state);
InvertSubBytes (&mut state);
}
AddRoundKey (&mut state, &self.roundKeys[0]);
for i in 0..4
{
for j in 0..4
{
output[i*4 + j] = state[j][i];
}
}
}
}
impl BlockCipherTrait for Aes128Cipher
{
const BLOCK_SIZE: usize = 16;
fn EncryptBlock (&self, input: &[u8; Self::BLOCK_SIZE]) -> [u8; Self::BLOCK_SIZE]
{
self.Encrypt (input)
}
fn DecryptBlock (&self, input: &[u8; Self::BLOCK_SIZE]) -> [u8; Self::BLOCK_SIZE]
{
self.Decrypt (input)
}
fn EncryptBlockInplace (&self, input: &[u8; Self::BLOCK_SIZE], output: &mut [u8; Self::BLOCK_SIZE])
{
self.EncryptInplace (input, output);
}
fn DecryptBlockInplace (&self, input: &[u8; Self::BLOCK_SIZE], output: &mut [u8; Self::BLOCK_SIZE])
{
self.DecryptInplace (input, output);
}
}
#[derive(Debug, Clone)]
pub struct Aes192CipherKey([u8; Aes192Cipher::KEY_LEN]);
impl Aes192CipherKey
{
pub fn New (key: &[u8; Aes192Cipher::KEY_LEN]) -> Self { Self(key.clone ()) }
}
#[derive(Debug, Clone)]
pub struct Aes192Cipher
{
key: Aes192CipherKey,
roundKeys: [[[u8; 4]; 4]; Self::ROUND_NUMBER + 1],
}
impl Aes192Cipher
{
const KEY_WORD_LEN: usize = 6;
const ROUND_NUMBER: usize = 12;
const KEY_LEN: usize = Self::KEY_WORD_LEN*4;
const EXPANDED_KEY_WORD_LEN: usize = 4*(Self::ROUND_NUMBER + 1);
pub fn New (key: &Aes192CipherKey) -> Self
{
let mut result = Self
{
key: key.clone (),
roundKeys: [[[0u8; 4]; 4]; Self::ROUND_NUMBER + 1],
};
result.CreateRoundKeys ();
result
}
fn CreateRoundKeys (&mut self)
{
let mut expandedKey = [[0; 4]; Self::EXPANDED_KEY_WORD_LEN];
for i in 0..Self::EXPANDED_KEY_WORD_LEN
{
if i < Self::KEY_WORD_LEN
{
expandedKey[i][0] = self.key.0[i*4 + 0];
expandedKey[i][1] = self.key.0[i*4 + 1];
expandedKey[i][2] = self.key.0[i*4 + 2];
expandedKey[i][3] = self.key.0[i*4 + 3];
}
else if i % Self::KEY_WORD_LEN == 0
{
let mut tmpWord = expandedKey[i - 1];
let tmp = tmpWord[0];
tmpWord[0] = tmpWord[1];
tmpWord[1] = tmpWord[2];
tmpWord[2] = tmpWord[3];
tmpWord[3] = tmp;
tmpWord[0] = SBox[tmpWord[0] as usize];
tmpWord[1] = SBox[tmpWord[1] as usize];
tmpWord[2] = SBox[tmpWord[2] as usize];
tmpWord[3] = SBox[tmpWord[3] as usize];
tmpWord[0] = tmpWord[0] ^ RoundConstant[i/Self::KEY_WORD_LEN];
expandedKey[i][0] = expandedKey[i - Self::KEY_WORD_LEN][0] ^ tmpWord[0];
expandedKey[i][1] = expandedKey[i - Self::KEY_WORD_LEN][1] ^ tmpWord[1];
expandedKey[i][2] = expandedKey[i - Self::KEY_WORD_LEN][2] ^ tmpWord[2];
expandedKey[i][3] = expandedKey[i - Self::KEY_WORD_LEN][3] ^ tmpWord[3];
}
else if Self::KEY_WORD_LEN > 6 && (i % Self::KEY_WORD_LEN) == 4
{
let mut tmpWord = expandedKey[i - 1];
tmpWord[0] = SBox[tmpWord[0] as usize];
tmpWord[1] = SBox[tmpWord[1] as usize];
tmpWord[2] = SBox[tmpWord[2] as usize];
tmpWord[3] = SBox[tmpWord[3] as usize];
expandedKey[i][0] = expandedKey[i - Self::KEY_WORD_LEN][0] ^ tmpWord[0];
expandedKey[i][1] = expandedKey[i - Self::KEY_WORD_LEN][1] ^ tmpWord[1];
expandedKey[i][2] = expandedKey[i - Self::KEY_WORD_LEN][2] ^ tmpWord[2];
expandedKey[i][3] = expandedKey[i - Self::KEY_WORD_LEN][3] ^ tmpWord[3];
}
else
{
expandedKey[i][0] = expandedKey[i - Self::KEY_WORD_LEN][0] ^ expandedKey[i - 1][0];
expandedKey[i][1] = expandedKey[i - Self::KEY_WORD_LEN][1] ^ expandedKey[i - 1][1];
expandedKey[i][2] = expandedKey[i - Self::KEY_WORD_LEN][2] ^ expandedKey[i - 1][2];
expandedKey[i][3] = expandedKey[i - Self::KEY_WORD_LEN][3] ^ expandedKey[i - 1][3];
}
}
for i in 0..Self::ROUND_NUMBER + 1
{
for j in 0..4
{
self.roundKeys[i][0][j] = expandedKey[i*4 + j][0];
self.roundKeys[i][1][j] = expandedKey[i*4 + j][1];
self.roundKeys[i][2][j] = expandedKey[i*4 + j][2];
self.roundKeys[i][3][j] = expandedKey[i*4 + j][3];
}
}
}
pub fn Encrypt (&self, input: &[u8; Self::BLOCK_SIZE]) -> [u8; Self::BLOCK_SIZE]
{
let mut output = [0; Self::BLOCK_SIZE];
self.EncryptInplace (input, &mut output);
output
}
pub fn Decrypt (&self, input: &[u8; Self::BLOCK_SIZE]) -> [u8; Self::BLOCK_SIZE]
{
let mut output = [0; Self::BLOCK_SIZE];
self.DecryptInplace (input, &mut output);
output
}
pub fn EncryptInplace (&self, input: &[u8; Self::BLOCK_SIZE], output: &mut [u8; Self::BLOCK_SIZE])
{
let mut state = [[0; 4]; 4];
for i in 0..4
{
for j in 0..4
{
state[j][i] = input[i*4 + j];
}
}
AddRoundKey (&mut state, &self.roundKeys[0]);
for i in 1..Self::ROUND_NUMBER
{
SubBytes (&mut state);
ShiftRows (&mut state);
MixColumns (&mut state);
AddRoundKey (&mut state, &self.roundKeys[i]);
}
SubBytes (&mut state);
ShiftRows (&mut state);
AddRoundKey (&mut state, &self.roundKeys[Self::ROUND_NUMBER]);
for i in 0..4
{
for j in 0..4
{
output[i*4 + j] = state[j][i];
}
}
}
pub fn DecryptInplace (&self, input: &[u8; Self::BLOCK_SIZE], output: &mut [u8; Self::BLOCK_SIZE])
{
let mut state = [[0; 4]; 4];
for i in 0..4
{
for j in 0..4
{
state[j][i] = input[i*4 + j];
}
}
AddRoundKey (&mut state, &self.roundKeys[Self::ROUND_NUMBER]);
InvertShiftRows (&mut state);
InvertSubBytes (&mut state);
for i in (1..Self::ROUND_NUMBER).rev ()
{
AddRoundKey (&mut state, &self.roundKeys[i]);
InvertMixColumns (&mut state);
InvertShiftRows (&mut state);
InvertSubBytes (&mut state);
}
AddRoundKey (&mut state, &self.roundKeys[0]);
for i in 0..4
{
for j in 0..4
{
output[i*4 + j] = state[j][i];
}
}
}
}
impl BlockCipherTrait for Aes192Cipher
{
const BLOCK_SIZE: usize = 16;
fn EncryptBlock (&self, input: &[u8; Self::BLOCK_SIZE]) -> [u8; Self::BLOCK_SIZE]
{
self.Encrypt (input)
}
fn DecryptBlock (&self, input: &[u8; Self::BLOCK_SIZE]) -> [u8; Self::BLOCK_SIZE]
{
self.Decrypt (input)
}
fn EncryptBlockInplace (&self, input: &[u8; Self::BLOCK_SIZE], output: &mut [u8; Self::BLOCK_SIZE])
{
self.EncryptInplace (input, output);
}
fn DecryptBlockInplace (&self, input: &[u8; Self::BLOCK_SIZE], output: &mut [u8; Self::BLOCK_SIZE])
{
self.DecryptInplace (input, output);
}
}
#[derive(Debug, Clone)]
pub struct Aes256CipherKey([u8; Aes256Cipher::KEY_LEN]);
impl Aes256CipherKey
{
pub fn New (key: &[u8; Aes256Cipher::KEY_LEN]) -> Self { Self(key.clone ()) }
}
#[derive(Debug, Clone)]
pub struct Aes256Cipher
{
key: Aes256CipherKey,
roundKeys: [[[u8; 4]; 4]; Self::ROUND_NUMBER + 1],
}
impl Aes256Cipher
{
const KEY_WORD_LEN: usize = 8;
const ROUND_NUMBER: usize = 14;
const KEY_LEN: usize = Self::KEY_WORD_LEN*4;
const EXPANDED_KEY_WORD_LEN: usize = 4*(Self::ROUND_NUMBER + 1);
pub fn New (key: &Aes256CipherKey) -> Self
{
let mut result = Self
{
key: key.clone (),
roundKeys: [[[0u8; 4]; 4]; Self::ROUND_NUMBER + 1],
};
result.CreateRoundKeys ();
result
}
fn CreateRoundKeys (&mut self)
{
let mut expandedKey = [[0; 4]; Self::EXPANDED_KEY_WORD_LEN];
for i in 0..Self::EXPANDED_KEY_WORD_LEN
{
if i < Self::KEY_WORD_LEN
{
expandedKey[i][0] = self.key.0[i*4 + 0];
expandedKey[i][1] = self.key.0[i*4 + 1];
expandedKey[i][2] = self.key.0[i*4 + 2];
expandedKey[i][3] = self.key.0[i*4 + 3];
}
else if i % Self::KEY_WORD_LEN == 0
{
let mut tmpWord = expandedKey[i - 1];
let tmp = tmpWord[0];
tmpWord[0] = tmpWord[1];
tmpWord[1] = tmpWord[2];
tmpWord[2] = tmpWord[3];
tmpWord[3] = tmp;
tmpWord[0] = SBox[tmpWord[0] as usize];
tmpWord[1] = SBox[tmpWord[1] as usize];
tmpWord[2] = SBox[tmpWord[2] as usize];
tmpWord[3] = SBox[tmpWord[3] as usize];
tmpWord[0] = tmpWord[0] ^ RoundConstant[i/Self::KEY_WORD_LEN];
expandedKey[i][0] = expandedKey[i - Self::KEY_WORD_LEN][0] ^ tmpWord[0];
expandedKey[i][1] = expandedKey[i - Self::KEY_WORD_LEN][1] ^ tmpWord[1];
expandedKey[i][2] = expandedKey[i - Self::KEY_WORD_LEN][2] ^ tmpWord[2];
expandedKey[i][3] = expandedKey[i - Self::KEY_WORD_LEN][3] ^ tmpWord[3];
}
else if Self::KEY_WORD_LEN > 6 && (i % Self::KEY_WORD_LEN) == 4
{
let mut tmpWord = expandedKey[i - 1];
tmpWord[0] = SBox[tmpWord[0] as usize];
tmpWord[1] = SBox[tmpWord[1] as usize];
tmpWord[2] = SBox[tmpWord[2] as usize];
tmpWord[3] = SBox[tmpWord[3] as usize];
expandedKey[i][0] = expandedKey[i - Self::KEY_WORD_LEN][0] ^ tmpWord[0];
expandedKey[i][1] = expandedKey[i - Self::KEY_WORD_LEN][1] ^ tmpWord[1];
expandedKey[i][2] = expandedKey[i - Self::KEY_WORD_LEN][2] ^ tmpWord[2];
expandedKey[i][3] = expandedKey[i - Self::KEY_WORD_LEN][3] ^ tmpWord[3];
}
else
{
expandedKey[i][0] = expandedKey[i - Self::KEY_WORD_LEN][0] ^ expandedKey[i - 1][0];
expandedKey[i][1] = expandedKey[i - Self::KEY_WORD_LEN][1] ^ expandedKey[i - 1][1];
expandedKey[i][2] = expandedKey[i - Self::KEY_WORD_LEN][2] ^ expandedKey[i - 1][2];
expandedKey[i][3] = expandedKey[i - Self::KEY_WORD_LEN][3] ^ expandedKey[i - 1][3];
}
}
for i in 0..Self::ROUND_NUMBER + 1
{
for j in 0..4
{
self.roundKeys[i][0][j] = expandedKey[i*4 + j][0];
self.roundKeys[i][1][j] = expandedKey[i*4 + j][1];
self.roundKeys[i][2][j] = expandedKey[i*4 + j][2];
self.roundKeys[i][3][j] = expandedKey[i*4 + j][3];
}
}
}
pub fn Encrypt (&self, input: &[u8; Self::BLOCK_SIZE]) -> [u8; Self::BLOCK_SIZE]
{
let mut output = [0; Self::BLOCK_SIZE];
self.EncryptInplace (input, &mut output);
output
}
pub fn Decrypt (&self, input: &[u8; Self::BLOCK_SIZE]) -> [u8; Self::BLOCK_SIZE]
{
let mut output = [0; Self::BLOCK_SIZE];
self.DecryptInplace (input, &mut output);
output
}
pub fn EncryptInplace (&self, input: &[u8; Self::BLOCK_SIZE], output: &mut [u8; Self::BLOCK_SIZE])
{
let mut state = [[0; 4]; 4];
for i in 0..4
{
for j in 0..4
{
state[j][i] = input[i*4 + j];
}
}
AddRoundKey (&mut state, &self.roundKeys[0]);
for i in 1..Self::ROUND_NUMBER
{
SubBytes (&mut state);
ShiftRows (&mut state);
MixColumns (&mut state);
AddRoundKey (&mut state, &self.roundKeys[i]);
}
SubBytes (&mut state);
ShiftRows (&mut state);
AddRoundKey (&mut state, &self.roundKeys[Self::ROUND_NUMBER]);
for i in 0..4
{
for j in 0..4
{
output[i*4 + j] = state[j][i];
}
}
}
pub fn DecryptInplace (&self, input: &[u8; Self::BLOCK_SIZE], output: &mut [u8; Self::BLOCK_SIZE])
{
let mut state = [[0; 4]; 4];
for i in 0..4
{
for j in 0..4
{
state[j][i] = input[i*4 + j];
}
}
AddRoundKey (&mut state, &self.roundKeys[Self::ROUND_NUMBER]);
InvertShiftRows (&mut state);
InvertSubBytes (&mut state);
for i in (1..Self::ROUND_NUMBER).rev ()
{
AddRoundKey (&mut state, &self.roundKeys[i]);
InvertMixColumns (&mut state);
InvertShiftRows (&mut state);
InvertSubBytes (&mut state);
}
AddRoundKey (&mut state, &self.roundKeys[0]);
for i in 0..4
{
for j in 0..4
{
output[i*4 + j] = state[j][i];
}
}
}
}
impl BlockCipherTrait for Aes256Cipher
{
const BLOCK_SIZE: usize = 16;
fn EncryptBlock (&self, input: &[u8; Self::BLOCK_SIZE]) -> [u8; Self::BLOCK_SIZE]
{
self.Encrypt (input)
}
fn DecryptBlock (&self, input: &[u8; Self::BLOCK_SIZE]) -> [u8; Self::BLOCK_SIZE]
{
self.Decrypt (input)
}
fn EncryptBlockInplace (&self, input: &[u8; Self::BLOCK_SIZE], output: &mut [u8; Self::BLOCK_SIZE])
{
self.EncryptInplace (input, output);
}
fn DecryptBlockInplace (&self, input: &[u8; Self::BLOCK_SIZE], output: &mut [u8; Self::BLOCK_SIZE])
{
self.DecryptInplace (input, output);
}
}
#[cfg(test)]
mod tests
{
use super::*;
use hex;
#[test]
fn Aes128Encrypt ()
{
let key = hex::decode ("00000000000000000000000000000000").unwrap ();
let aes128Cipher = Aes128Cipher::New (&Aes128CipherKey::New (&key.try_into ().unwrap ()));
let plainText1: [u8; 16] = hex::decode ("f34481ec3cc627bacd5dc3fb08f273e6").unwrap ().try_into ().unwrap ();
let plainText2: [u8; 16] = hex::decode ("9798c4640bad75c7c3227db910174e72").unwrap ().try_into ().unwrap ();
let plainText3: [u8; 16] = hex::decode ("96ab5c2ff612d9dfaae8c31f30c42168").unwrap ().try_into ().unwrap ();
let plainText4: [u8; 16] = hex::decode ("6a118a874519e64e9963798a503f1d35").unwrap ().try_into ().unwrap ();
let plainText5: [u8; 16] = hex::decode ("cb9fceec81286ca3e989bd979b0cb284").unwrap ().try_into ().unwrap ();
let plainText6: [u8; 16] = hex::decode ("b26aeb1874e47ca8358ff22378f09144").unwrap ().try_into ().unwrap ();
let plainText7: [u8; 16] = hex::decode ("58c8e00b2631686d54eab84b91f0aca1").unwrap ().try_into ().unwrap ();
let expected1: [u8; 16] = hex::decode ("0336763e966d92595a567cc9ce537f5e").unwrap ().try_into ().unwrap ();
let expected2: [u8; 16] = hex::decode ("a9a1631bf4996954ebc093957b234589").unwrap ().try_into ().unwrap ();
let expected3: [u8; 16] = hex::decode ("ff4f8391a6a40ca5b25d23bedd44a597").unwrap ().try_into ().unwrap ();
let expected4: [u8; 16] = hex::decode ("dc43be40be0e53712f7e2bf5ca707209").unwrap ().try_into ().unwrap ();
let expected5: [u8; 16] = hex::decode ("92beedab1895a94faa69b632e5cc47ce").unwrap ().try_into ().unwrap ();
let expected6: [u8; 16] = hex::decode ("459264f4798f6a78bacb89c15ed3d601").unwrap ().try_into ().unwrap ();
let expected7: [u8; 16] = hex::decode ("08a4e2efec8a8e3312ca7460b9040bbf").unwrap ().try_into ().unwrap ();
let cipherText1 = aes128Cipher.EncryptBlock (&plainText1);
let cipherText2 = aes128Cipher.EncryptBlock (&plainText2);
let cipherText3 = aes128Cipher.EncryptBlock (&plainText3);
let cipherText4 = aes128Cipher.EncryptBlock (&plainText4);
let cipherText5 = aes128Cipher.EncryptBlock (&plainText5);
let cipherText6 = aes128Cipher.EncryptBlock (&plainText6);
let cipherText7 = aes128Cipher.EncryptBlock (&plainText7);
assert! (cipherText1 == expected1);
assert! (cipherText2 == expected2);
assert! (cipherText3 == expected3);
assert! (cipherText4 == expected4);
assert! (cipherText5 == expected5);
assert! (cipherText6 == expected6);
assert! (cipherText7 == expected7);
}
#[test]
fn Aes192Encrypt ()
{
let key = hex::decode ("000000000000000000000000000000000000000000000000").unwrap ();
let aes192Cipher = Aes192Cipher::New (&Aes192CipherKey::New (&key.try_into ().unwrap ()));
let plainText1: [u8; 16] = hex::decode ("1b077a6af4b7f98229de786d7516b639").unwrap ().try_into ().unwrap ();
let plainText2: [u8; 16] = hex::decode ("9c2d8842e5f48f57648205d39a239af1").unwrap ().try_into ().unwrap ();
let plainText3: [u8; 16] = hex::decode ("bff52510095f518ecca60af4205444bb").unwrap ().try_into ().unwrap ();
let plainText4: [u8; 16] = hex::decode ("51719783d3185a535bd75adc65071ce1").unwrap ().try_into ().unwrap ();
let plainText5: [u8; 16] = hex::decode ("26aa49dcfe7629a8901a69a9914e6dfd").unwrap ().try_into ().unwrap ();
let plainText6: [u8; 16] = hex::decode ("941a4773058224e1ef66d10e0a6ee782").unwrap ().try_into ().unwrap ();
let expected1: [u8; 16] = hex::decode ("275cfc0413d8ccb70513c3859b1d0f72").unwrap ().try_into ().unwrap ();
let expected2: [u8; 16] = hex::decode ("c9b8135ff1b5adc413dfd053b21bd96d").unwrap ().try_into ().unwrap ();
let expected3: [u8; 16] = hex::decode ("4a3650c3371ce2eb35e389a171427440").unwrap ().try_into ().unwrap ();
let expected4: [u8; 16] = hex::decode ("4f354592ff7c8847d2d0870ca9481b7c").unwrap ().try_into ().unwrap ();
let expected5: [u8; 16] = hex::decode ("d5e08bf9a182e857cf40b3a36ee248cc").unwrap ().try_into ().unwrap ();
let expected6: [u8; 16] = hex::decode ("067cd9d3749207791841562507fa9626").unwrap ().try_into ().unwrap ();
let cipherText1 = aes192Cipher.EncryptBlock (&plainText1);
let cipherText2 = aes192Cipher.EncryptBlock (&plainText2);
let cipherText3 = aes192Cipher.EncryptBlock (&plainText3);
let cipherText4 = aes192Cipher.EncryptBlock (&plainText4);
let cipherText5 = aes192Cipher.EncryptBlock (&plainText5);
let cipherText6 = aes192Cipher.EncryptBlock (&plainText6);
assert! (cipherText1 == expected1);
assert! (cipherText2 == expected2);
assert! (cipherText3 == expected3);
assert! (cipherText4 == expected4);
assert! (cipherText5 == expected5);
assert! (cipherText6 == expected6);
}
#[test]
fn Aes256Encrypt ()
{
let key = hex::decode ("0000000000000000000000000000000000000000000000000000000000000000").unwrap ();
let aes256Cipher = Aes256Cipher::New (&Aes256CipherKey::New (&key.try_into ().unwrap ()));
let plainText1: [u8; 16] = hex::decode ("014730f80ac625fe84f026c60bfd547d").unwrap ().try_into ().unwrap ();
let plainText2: [u8; 16] = hex::decode ("0b24af36193ce4665f2825d7b4749c98").unwrap ().try_into ().unwrap ();
let plainText3: [u8; 16] = hex::decode ("761c1fe41a18acf20d241650611d90f1").unwrap ().try_into ().unwrap ();
let plainText4: [u8; 16] = hex::decode ("8a560769d605868ad80d819bdba03771").unwrap ().try_into ().unwrap ();
let plainText5: [u8; 16] = hex::decode ("91fbef2d15a97816060bee1feaa49afe").unwrap ().try_into ().unwrap ();
let expected1: [u8; 16] = hex::decode ("5c9d844ed46f9885085e5d6a4f94c7d7").unwrap ().try_into ().unwrap ();
let expected2: [u8; 16] = hex::decode ("a9ff75bd7cf6613d3731c77c3b6d0c04").unwrap ().try_into ().unwrap ();
let expected3: [u8; 16] = hex::decode ("623a52fcea5d443e48d9181ab32c7421").unwrap ().try_into ().unwrap ();
let expected4: [u8; 16] = hex::decode ("38f2c7ae10612415d27ca190d27da8b4").unwrap ().try_into ().unwrap ();
let expected5: [u8; 16] = hex::decode ("1bc704f1bce135ceb810341b216d7abe").unwrap ().try_into ().unwrap ();
let cipherText1 = aes256Cipher.EncryptBlock (&plainText1);
let cipherText2 = aes256Cipher.EncryptBlock (&plainText2);
let cipherText3 = aes256Cipher.EncryptBlock (&plainText3);
let cipherText4 = aes256Cipher.EncryptBlock (&plainText4);
let cipherText5 = aes256Cipher.EncryptBlock (&plainText5);
assert! (cipherText1 == expected1);
assert! (cipherText2 == expected2);
assert! (cipherText3 == expected3);
assert! (cipherText4 == expected4);
assert! (cipherText5 == expected5);
}
#[test]
fn Aes128Decrypt ()
{
let key = hex::decode ("00000000000000000000000000000000").unwrap ();
let aes128Cipher = Aes128Cipher::New (&Aes128CipherKey::New (&key.try_into ().unwrap ()));
let cipherText1: [u8; 16] = hex::decode ("0336763e966d92595a567cc9ce537f5e").unwrap ().try_into ().unwrap ();
let cipherText2: [u8; 16] = hex::decode ("a9a1631bf4996954ebc093957b234589").unwrap ().try_into ().unwrap ();
let cipherText3: [u8; 16] = hex::decode ("ff4f8391a6a40ca5b25d23bedd44a597").unwrap ().try_into ().unwrap ();
let cipherText4: [u8; 16] = hex::decode ("dc43be40be0e53712f7e2bf5ca707209").unwrap ().try_into ().unwrap ();
let cipherText5: [u8; 16] = hex::decode ("92beedab1895a94faa69b632e5cc47ce").unwrap ().try_into ().unwrap ();
let cipherText6: [u8; 16] = hex::decode ("459264f4798f6a78bacb89c15ed3d601").unwrap ().try_into ().unwrap ();
let cipherText7: [u8; 16] = hex::decode ("08a4e2efec8a8e3312ca7460b9040bbf").unwrap ().try_into ().unwrap ();
let expected1: [u8; 16] = hex::decode ("f34481ec3cc627bacd5dc3fb08f273e6").unwrap ().try_into ().unwrap ();
let expected2: [u8; 16] = hex::decode ("9798c4640bad75c7c3227db910174e72").unwrap ().try_into ().unwrap ();
let expected3: [u8; 16] = hex::decode ("96ab5c2ff612d9dfaae8c31f30c42168").unwrap ().try_into ().unwrap ();
let expected4: [u8; 16] = hex::decode ("6a118a874519e64e9963798a503f1d35").unwrap ().try_into ().unwrap ();
let expected5: [u8; 16] = hex::decode ("cb9fceec81286ca3e989bd979b0cb284").unwrap ().try_into ().unwrap ();
let expected6: [u8; 16] = hex::decode ("b26aeb1874e47ca8358ff22378f09144").unwrap ().try_into ().unwrap ();
let expected7: [u8; 16] = hex::decode ("58c8e00b2631686d54eab84b91f0aca1").unwrap ().try_into ().unwrap ();
let plainText1 = aes128Cipher.DecryptBlock (&cipherText1);
let plainText2 = aes128Cipher.DecryptBlock (&cipherText2);
let plainText3 = aes128Cipher.DecryptBlock (&cipherText3);
let plainText4 = aes128Cipher.DecryptBlock (&cipherText4);
let plainText5 = aes128Cipher.DecryptBlock (&cipherText5);
let plainText6 = aes128Cipher.DecryptBlock (&cipherText6);
let plainText7 = aes128Cipher.DecryptBlock (&cipherText7);
assert! (plainText1 == expected1);
assert! (plainText2 == expected2);
assert! (plainText3 == expected3);
assert! (plainText4 == expected4);
assert! (plainText5 == expected5);
assert! (plainText6 == expected6);
assert! (plainText7 == expected7);
}
#[test]
fn Aes192Decrypt ()
{
let key = hex::decode ("000000000000000000000000000000000000000000000000").unwrap ();
let aes192Cipher = Aes192Cipher::New (&Aes192CipherKey::New (&key.try_into ().unwrap ()));
let cipherText1: [u8; 16] = hex::decode ("275cfc0413d8ccb70513c3859b1d0f72").unwrap ().try_into ().unwrap ();
let cipherText2: [u8; 16] = hex::decode ("c9b8135ff1b5adc413dfd053b21bd96d").unwrap ().try_into ().unwrap ();
let cipherText3: [u8; 16] = hex::decode ("4a3650c3371ce2eb35e389a171427440").unwrap ().try_into ().unwrap ();
let cipherText4: [u8; 16] = hex::decode ("4f354592ff7c8847d2d0870ca9481b7c").unwrap ().try_into ().unwrap ();
let cipherText5: [u8; 16] = hex::decode ("d5e08bf9a182e857cf40b3a36ee248cc").unwrap ().try_into ().unwrap ();
let cipherText6: [u8; 16] = hex::decode ("067cd9d3749207791841562507fa9626").unwrap ().try_into ().unwrap ();
let expected1: [u8; 16] = hex::decode ("1b077a6af4b7f98229de786d7516b639").unwrap ().try_into ().unwrap ();
let expected2: [u8; 16] = hex::decode ("9c2d8842e5f48f57648205d39a239af1").unwrap ().try_into ().unwrap ();
let expected3: [u8; 16] = hex::decode ("bff52510095f518ecca60af4205444bb").unwrap ().try_into ().unwrap ();
let expected4: [u8; 16] = hex::decode ("51719783d3185a535bd75adc65071ce1").unwrap ().try_into ().unwrap ();
let expected5: [u8; 16] = hex::decode ("26aa49dcfe7629a8901a69a9914e6dfd").unwrap ().try_into ().unwrap ();
let expected6: [u8; 16] = hex::decode ("941a4773058224e1ef66d10e0a6ee782").unwrap ().try_into ().unwrap ();
let plainText1 = aes192Cipher.DecryptBlock (&cipherText1);
let plainText2 = aes192Cipher.DecryptBlock (&cipherText2);
let plainText3 = aes192Cipher.DecryptBlock (&cipherText3);
let plainText4 = aes192Cipher.DecryptBlock (&cipherText4);
let plainText5 = aes192Cipher.DecryptBlock (&cipherText5);
let plainText6 = aes192Cipher.DecryptBlock (&cipherText6);
assert! (plainText1 == expected1);
assert! (plainText2 == expected2);
assert! (plainText3 == expected3);
assert! (plainText4 == expected4);
assert! (plainText5 == expected5);
assert! (plainText6 == expected6);
}
#[test]
fn Aes256Decrypt ()
{
let key = hex::decode ("0000000000000000000000000000000000000000000000000000000000000000").unwrap ();
let aes256Cipher = Aes256Cipher::New (&Aes256CipherKey::New (&key.try_into ().unwrap ()));
let cipherText1: [u8; 16] = hex::decode ("5c9d844ed46f9885085e5d6a4f94c7d7").unwrap ().try_into ().unwrap ();
let cipherText2: [u8; 16] = hex::decode ("a9ff75bd7cf6613d3731c77c3b6d0c04").unwrap ().try_into ().unwrap ();
let cipherText3: [u8; 16] = hex::decode ("623a52fcea5d443e48d9181ab32c7421").unwrap ().try_into ().unwrap ();
let cipherText4: [u8; 16] = hex::decode ("38f2c7ae10612415d27ca190d27da8b4").unwrap ().try_into ().unwrap ();
let cipherText5: [u8; 16] = hex::decode ("1bc704f1bce135ceb810341b216d7abe").unwrap ().try_into ().unwrap ();
let expected1: [u8; 16] = hex::decode ("014730f80ac625fe84f026c60bfd547d").unwrap ().try_into ().unwrap ();
let expected2: [u8; 16] = hex::decode ("0b24af36193ce4665f2825d7b4749c98").unwrap ().try_into ().unwrap ();
let expected3: [u8; 16] = hex::decode ("761c1fe41a18acf20d241650611d90f1").unwrap ().try_into ().unwrap ();
let expected4: [u8; 16] = hex::decode ("8a560769d605868ad80d819bdba03771").unwrap ().try_into ().unwrap ();
let expected5: [u8; 16] = hex::decode ("91fbef2d15a97816060bee1feaa49afe").unwrap ().try_into ().unwrap ();
let plainText1 = aes256Cipher.DecryptBlock (&cipherText1);
let plainText2 = aes256Cipher.DecryptBlock (&cipherText2);
let plainText3 = aes256Cipher.DecryptBlock (&cipherText3);
let plainText4 = aes256Cipher.DecryptBlock (&cipherText4);
let plainText5 = aes256Cipher.DecryptBlock (&cipherText5);
assert! (plainText1 == expected1);
assert! (plainText2 == expected2);
assert! (plainText3 == expected3);
assert! (plainText4 == expected4);
assert! (plainText5 == expected5);
}
}