mirror of
https://github.com/MikaylaFischler/cc-mek-scada.git
synced 2024-08-30 18:22:34 +00:00
463 lines
17 KiB
Lua
463 lines
17 KiB
Lua
|
|
local Array = require("lockbox.util.array");
|
|
local Bit = require("lockbox.util.bit");
|
|
|
|
local XOR = Bit.bxor;
|
|
|
|
local SBOX = {
|
|
[0] = 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};
|
|
|
|
local ISBOX = {
|
|
[0] = 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};
|
|
|
|
local ROW_SHIFT = { 1, 6, 11, 16, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, };
|
|
local IROW_SHIFT = { 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3, 16, 13, 10, 7, 4, };
|
|
|
|
local ETABLE = {
|
|
[0] = 0x01, 0x03, 0x05, 0x0F, 0x11, 0x33, 0x55, 0xFF, 0x1A, 0x2E, 0x72, 0x96, 0xA1, 0xF8, 0x13, 0x35,
|
|
0x5F, 0xE1, 0x38, 0x48, 0xD8, 0x73, 0x95, 0xA4, 0xF7, 0x02, 0x06, 0x0A, 0x1E, 0x22, 0x66, 0xAA,
|
|
0xE5, 0x34, 0x5C, 0xE4, 0x37, 0x59, 0xEB, 0x26, 0x6A, 0xBE, 0xD9, 0x70, 0x90, 0xAB, 0xE6, 0x31,
|
|
0x53, 0xF5, 0x04, 0x0C, 0x14, 0x3C, 0x44, 0xCC, 0x4F, 0xD1, 0x68, 0xB8, 0xD3, 0x6E, 0xB2, 0xCD,
|
|
0x4C, 0xD4, 0x67, 0xA9, 0xE0, 0x3B, 0x4D, 0xD7, 0x62, 0xA6, 0xF1, 0x08, 0x18, 0x28, 0x78, 0x88,
|
|
0x83, 0x9E, 0xB9, 0xD0, 0x6B, 0xBD, 0xDC, 0x7F, 0x81, 0x98, 0xB3, 0xCE, 0x49, 0xDB, 0x76, 0x9A,
|
|
0xB5, 0xC4, 0x57, 0xF9, 0x10, 0x30, 0x50, 0xF0, 0x0B, 0x1D, 0x27, 0x69, 0xBB, 0xD6, 0x61, 0xA3,
|
|
0xFE, 0x19, 0x2B, 0x7D, 0x87, 0x92, 0xAD, 0xEC, 0x2F, 0x71, 0x93, 0xAE, 0xE9, 0x20, 0x60, 0xA0,
|
|
0xFB, 0x16, 0x3A, 0x4E, 0xD2, 0x6D, 0xB7, 0xC2, 0x5D, 0xE7, 0x32, 0x56, 0xFA, 0x15, 0x3F, 0x41,
|
|
0xC3, 0x5E, 0xE2, 0x3D, 0x47, 0xC9, 0x40, 0xC0, 0x5B, 0xED, 0x2C, 0x74, 0x9C, 0xBF, 0xDA, 0x75,
|
|
0x9F, 0xBA, 0xD5, 0x64, 0xAC, 0xEF, 0x2A, 0x7E, 0x82, 0x9D, 0xBC, 0xDF, 0x7A, 0x8E, 0x89, 0x80,
|
|
0x9B, 0xB6, 0xC1, 0x58, 0xE8, 0x23, 0x65, 0xAF, 0xEA, 0x25, 0x6F, 0xB1, 0xC8, 0x43, 0xC5, 0x54,
|
|
0xFC, 0x1F, 0x21, 0x63, 0xA5, 0xF4, 0x07, 0x09, 0x1B, 0x2D, 0x77, 0x99, 0xB0, 0xCB, 0x46, 0xCA,
|
|
0x45, 0xCF, 0x4A, 0xDE, 0x79, 0x8B, 0x86, 0x91, 0xA8, 0xE3, 0x3E, 0x42, 0xC6, 0x51, 0xF3, 0x0E,
|
|
0x12, 0x36, 0x5A, 0xEE, 0x29, 0x7B, 0x8D, 0x8C, 0x8F, 0x8A, 0x85, 0x94, 0xA7, 0xF2, 0x0D, 0x17,
|
|
0x39, 0x4B, 0xDD, 0x7C, 0x84, 0x97, 0xA2, 0xFD, 0x1C, 0x24, 0x6C, 0xB4, 0xC7, 0x52, 0xF6, 0x01};
|
|
|
|
local LTABLE = {
|
|
[0] = 0x00, 0x00, 0x19, 0x01, 0x32, 0x02, 0x1A, 0xC6, 0x4B, 0xC7, 0x1B, 0x68, 0x33, 0xEE, 0xDF, 0x03,
|
|
0x64, 0x04, 0xE0, 0x0E, 0x34, 0x8D, 0x81, 0xEF, 0x4C, 0x71, 0x08, 0xC8, 0xF8, 0x69, 0x1C, 0xC1,
|
|
0x7D, 0xC2, 0x1D, 0xB5, 0xF9, 0xB9, 0x27, 0x6A, 0x4D, 0xE4, 0xA6, 0x72, 0x9A, 0xC9, 0x09, 0x78,
|
|
0x65, 0x2F, 0x8A, 0x05, 0x21, 0x0F, 0xE1, 0x24, 0x12, 0xF0, 0x82, 0x45, 0x35, 0x93, 0xDA, 0x8E,
|
|
0x96, 0x8F, 0xDB, 0xBD, 0x36, 0xD0, 0xCE, 0x94, 0x13, 0x5C, 0xD2, 0xF1, 0x40, 0x46, 0x83, 0x38,
|
|
0x66, 0xDD, 0xFD, 0x30, 0xBF, 0x06, 0x8B, 0x62, 0xB3, 0x25, 0xE2, 0x98, 0x22, 0x88, 0x91, 0x10,
|
|
0x7E, 0x6E, 0x48, 0xC3, 0xA3, 0xB6, 0x1E, 0x42, 0x3A, 0x6B, 0x28, 0x54, 0xFA, 0x85, 0x3D, 0xBA,
|
|
0x2B, 0x79, 0x0A, 0x15, 0x9B, 0x9F, 0x5E, 0xCA, 0x4E, 0xD4, 0xAC, 0xE5, 0xF3, 0x73, 0xA7, 0x57,
|
|
0xAF, 0x58, 0xA8, 0x50, 0xF4, 0xEA, 0xD6, 0x74, 0x4F, 0xAE, 0xE9, 0xD5, 0xE7, 0xE6, 0xAD, 0xE8,
|
|
0x2C, 0xD7, 0x75, 0x7A, 0xEB, 0x16, 0x0B, 0xF5, 0x59, 0xCB, 0x5F, 0xB0, 0x9C, 0xA9, 0x51, 0xA0,
|
|
0x7F, 0x0C, 0xF6, 0x6F, 0x17, 0xC4, 0x49, 0xEC, 0xD8, 0x43, 0x1F, 0x2D, 0xA4, 0x76, 0x7B, 0xB7,
|
|
0xCC, 0xBB, 0x3E, 0x5A, 0xFB, 0x60, 0xB1, 0x86, 0x3B, 0x52, 0xA1, 0x6C, 0xAA, 0x55, 0x29, 0x9D,
|
|
0x97, 0xB2, 0x87, 0x90, 0x61, 0xBE, 0xDC, 0xFC, 0xBC, 0x95, 0xCF, 0xCD, 0x37, 0x3F, 0x5B, 0xD1,
|
|
0x53, 0x39, 0x84, 0x3C, 0x41, 0xA2, 0x6D, 0x47, 0x14, 0x2A, 0x9E, 0x5D, 0x56, 0xF2, 0xD3, 0xAB,
|
|
0x44, 0x11, 0x92, 0xD9, 0x23, 0x20, 0x2E, 0x89, 0xB4, 0x7C, 0xB8, 0x26, 0x77, 0x99, 0xE3, 0xA5,
|
|
0x67, 0x4A, 0xED, 0xDE, 0xC5, 0x31, 0xFE, 0x18, 0x0D, 0x63, 0x8C, 0x80, 0xC0, 0xF7, 0x70, 0x07};
|
|
|
|
local MIXTABLE = {
|
|
0x02, 0x03, 0x01, 0x01,
|
|
0x01, 0x02, 0x03, 0x01,
|
|
0x01, 0x01, 0x02, 0x03,
|
|
0x03, 0x01, 0x01, 0x02};
|
|
|
|
local IMIXTABLE = {
|
|
0x0E, 0x0B, 0x0D, 0x09,
|
|
0x09, 0x0E, 0x0B, 0x0D,
|
|
0x0D, 0x09, 0x0E, 0x0B,
|
|
0x0B, 0x0D, 0x09, 0x0E};
|
|
|
|
local RCON = {
|
|
[0] = 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
|
|
0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
|
|
0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
|
|
0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
|
|
0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
|
|
0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
|
|
0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
|
|
0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
|
|
0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
|
|
0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
|
|
0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
|
|
0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
|
|
0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
|
|
0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
|
|
0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
|
|
0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d};
|
|
|
|
|
|
local GMUL = function(A, B)
|
|
if(A == 0x01) then return B; end
|
|
if(B == 0x01) then return A; end
|
|
if(A == 0x00) then return 0; end
|
|
if(B == 0x00) then return 0; end
|
|
|
|
local LA = LTABLE[A];
|
|
local LB = LTABLE[B];
|
|
|
|
local sum = LA + LB;
|
|
if (sum > 0xFF) then sum = sum - 0xFF; end
|
|
|
|
return ETABLE[sum];
|
|
end
|
|
|
|
local byteSub = Array.substitute;
|
|
|
|
local shiftRow = Array.permute;
|
|
|
|
local mixCol = function(i, mix)
|
|
local out = {};
|
|
|
|
local a, b, c, d;
|
|
|
|
a = GMUL(i[ 1], mix[ 1]);
|
|
b = GMUL(i[ 2], mix[ 2]);
|
|
c = GMUL(i[ 3], mix[ 3]);
|
|
d = GMUL(i[ 4], mix[ 4]);
|
|
out[ 1] = XOR(XOR(a, b), XOR(c, d));
|
|
a = GMUL(i[ 1], mix[ 5]);
|
|
b = GMUL(i[ 2], mix[ 6]);
|
|
c = GMUL(i[ 3], mix[ 7]);
|
|
d = GMUL(i[ 4], mix[ 8]);
|
|
out[ 2] = XOR(XOR(a, b), XOR(c, d));
|
|
a = GMUL(i[ 1], mix[ 9]);
|
|
b = GMUL(i[ 2], mix[10]);
|
|
c = GMUL(i[ 3], mix[11]);
|
|
d = GMUL(i[ 4], mix[12]);
|
|
out[ 3] = XOR(XOR(a, b), XOR(c, d));
|
|
a = GMUL(i[ 1], mix[13]);
|
|
b = GMUL(i[ 2], mix[14]);
|
|
c = GMUL(i[ 3], mix[15]);
|
|
d = GMUL(i[ 4], mix[16]);
|
|
out[ 4] = XOR(XOR(a, b), XOR(c, d));
|
|
|
|
|
|
a = GMUL(i[ 5], mix[ 1]);
|
|
b = GMUL(i[ 6], mix[ 2]);
|
|
c = GMUL(i[ 7], mix[ 3]);
|
|
d = GMUL(i[ 8], mix[ 4]);
|
|
out[ 5] = XOR(XOR(a, b), XOR(c, d));
|
|
a = GMUL(i[ 5], mix[ 5]);
|
|
b = GMUL(i[ 6], mix[ 6]);
|
|
c = GMUL(i[ 7], mix[ 7]);
|
|
d = GMUL(i[ 8], mix[ 8]);
|
|
out[ 6] = XOR(XOR(a, b), XOR(c, d));
|
|
a = GMUL(i[ 5], mix[ 9]);
|
|
b = GMUL(i[ 6], mix[10]);
|
|
c = GMUL(i[ 7], mix[11]);
|
|
d = GMUL(i[ 8], mix[12]);
|
|
out[ 7] = XOR(XOR(a, b), XOR(c, d));
|
|
a = GMUL(i[ 5], mix[13]);
|
|
b = GMUL(i[ 6], mix[14]);
|
|
c = GMUL(i[ 7], mix[15]);
|
|
d = GMUL(i[ 8], mix[16]);
|
|
out[ 8] = XOR(XOR(a, b), XOR(c, d));
|
|
|
|
|
|
a = GMUL(i[ 9], mix[ 1]);
|
|
b = GMUL(i[10], mix[ 2]);
|
|
c = GMUL(i[11], mix[ 3]);
|
|
d = GMUL(i[12], mix[ 4]);
|
|
out[ 9] = XOR(XOR(a, b), XOR(c, d));
|
|
a = GMUL(i[ 9], mix[ 5]);
|
|
b = GMUL(i[10], mix[ 6]);
|
|
c = GMUL(i[11], mix[ 7]);
|
|
d = GMUL(i[12], mix[ 8]);
|
|
out[10] = XOR(XOR(a, b), XOR(c, d));
|
|
a = GMUL(i[ 9], mix[ 9]);
|
|
b = GMUL(i[10], mix[10]);
|
|
c = GMUL(i[11], mix[11]);
|
|
d = GMUL(i[12], mix[12]);
|
|
out[11] = XOR(XOR(a, b), XOR(c, d));
|
|
a = GMUL(i[ 9], mix[13]);
|
|
b = GMUL(i[10], mix[14]);
|
|
c = GMUL(i[11], mix[15]);
|
|
d = GMUL(i[12], mix[16]);
|
|
out[12] = XOR(XOR(a, b), XOR(c, d));
|
|
|
|
|
|
a = GMUL(i[13], mix[ 1]);
|
|
b = GMUL(i[14], mix[ 2]);
|
|
c = GMUL(i[15], mix[ 3]);
|
|
d = GMUL(i[16], mix[ 4]);
|
|
out[13] = XOR(XOR(a, b), XOR(c, d));
|
|
a = GMUL(i[13], mix[ 5]);
|
|
b = GMUL(i[14], mix[ 6]);
|
|
c = GMUL(i[15], mix[ 7]);
|
|
d = GMUL(i[16], mix[ 8]);
|
|
out[14] = XOR(XOR(a, b), XOR(c, d));
|
|
a = GMUL(i[13], mix[ 9]);
|
|
b = GMUL(i[14], mix[10]);
|
|
c = GMUL(i[15], mix[11]);
|
|
d = GMUL(i[16], mix[12]);
|
|
out[15] = XOR(XOR(a, b), XOR(c, d));
|
|
a = GMUL(i[13], mix[13]);
|
|
b = GMUL(i[14], mix[14]);
|
|
c = GMUL(i[15], mix[15]);
|
|
d = GMUL(i[16], mix[16]);
|
|
out[16] = XOR(XOR(a, b), XOR(c, d));
|
|
|
|
return out;
|
|
end
|
|
|
|
local keyRound = function(key, round)
|
|
local i = (round - 1) * 24;
|
|
local out = key;
|
|
|
|
out[25 + i] = XOR(key[ 1 + i], XOR(SBOX[key[22 + i]], RCON[round]));
|
|
out[26 + i] = XOR(key[ 2 + i], SBOX[key[23 + i]]);
|
|
out[27 + i] = XOR(key[ 3 + i], SBOX[key[24 + i]]);
|
|
out[28 + i] = XOR(key[ 4 + i], SBOX[key[21 + i]]);
|
|
|
|
out[29 + i] = XOR(out[25 + i], key[ 5 + i]);
|
|
out[30 + i] = XOR(out[26 + i], key[ 6 + i]);
|
|
out[31 + i] = XOR(out[27 + i], key[ 7 + i]);
|
|
out[32 + i] = XOR(out[28 + i], key[ 8 + i]);
|
|
|
|
out[33 + i] = XOR(out[29 + i], key[ 9 + i]);
|
|
out[34 + i] = XOR(out[30 + i], key[10 + i]);
|
|
out[35 + i] = XOR(out[31 + i], key[11 + i]);
|
|
out[36 + i] = XOR(out[32 + i], key[12 + i]);
|
|
|
|
out[37 + i] = XOR(out[33 + i], key[13 + i]);
|
|
out[38 + i] = XOR(out[34 + i], key[14 + i]);
|
|
out[39 + i] = XOR(out[35 + i], key[15 + i]);
|
|
out[40 + i] = XOR(out[36 + i], key[16 + i]);
|
|
|
|
out[41 + i] = XOR(out[37 + i], key[17 + i]);
|
|
out[42 + i] = XOR(out[38 + i], key[18 + i]);
|
|
out[43 + i] = XOR(out[39 + i], key[19 + i]);
|
|
out[44 + i] = XOR(out[40 + i], key[20 + i]);
|
|
|
|
out[45 + i] = XOR(out[41 + i], key[21 + i]);
|
|
out[46 + i] = XOR(out[42 + i], key[22 + i]);
|
|
out[47 + i] = XOR(out[43 + i], key[23 + i]);
|
|
out[48 + i] = XOR(out[44 + i], key[24 + i]);
|
|
|
|
return out;
|
|
end
|
|
|
|
local keyExpand = function(key)
|
|
local bytes = Array.copy(key);
|
|
|
|
for i = 1, 8 do
|
|
keyRound(bytes, i);
|
|
end
|
|
|
|
local keys = {};
|
|
|
|
keys[ 1] = Array.slice(bytes, 1, 16);
|
|
keys[ 2] = Array.slice(bytes, 17, 32);
|
|
keys[ 3] = Array.slice(bytes, 33, 48);
|
|
keys[ 4] = Array.slice(bytes, 49, 64);
|
|
keys[ 5] = Array.slice(bytes, 65, 80);
|
|
keys[ 6] = Array.slice(bytes, 81, 96);
|
|
keys[ 7] = Array.slice(bytes, 97, 112);
|
|
keys[ 8] = Array.slice(bytes, 113, 128);
|
|
keys[ 9] = Array.slice(bytes, 129, 144);
|
|
keys[10] = Array.slice(bytes, 145, 160);
|
|
keys[11] = Array.slice(bytes, 161, 176);
|
|
keys[12] = Array.slice(bytes, 177, 192);
|
|
keys[13] = Array.slice(bytes, 193, 208);
|
|
|
|
return keys;
|
|
|
|
end
|
|
|
|
local addKey = Array.XOR;
|
|
|
|
|
|
|
|
local AES = {};
|
|
|
|
AES.blockSize = 16;
|
|
|
|
AES.encrypt = function(_key, block)
|
|
|
|
local key = keyExpand(_key);
|
|
|
|
--round 0
|
|
block = addKey(block, key[1]);
|
|
|
|
--round 1
|
|
block = byteSub(block, SBOX);
|
|
block = shiftRow(block, ROW_SHIFT);
|
|
block = mixCol(block, MIXTABLE);
|
|
block = addKey(block, key[2]);
|
|
|
|
--round 2
|
|
block = byteSub(block, SBOX);
|
|
block = shiftRow(block, ROW_SHIFT);
|
|
block = mixCol(block, MIXTABLE);
|
|
block = addKey(block, key[3]);
|
|
|
|
--round 3
|
|
block = byteSub(block, SBOX);
|
|
block = shiftRow(block, ROW_SHIFT);
|
|
block = mixCol(block, MIXTABLE);
|
|
block = addKey(block, key[4]);
|
|
|
|
--round 4
|
|
block = byteSub(block, SBOX);
|
|
block = shiftRow(block, ROW_SHIFT);
|
|
block = mixCol(block, MIXTABLE);
|
|
block = addKey(block, key[5]);
|
|
|
|
--round 5
|
|
block = byteSub(block, SBOX);
|
|
block = shiftRow(block, ROW_SHIFT);
|
|
block = mixCol(block, MIXTABLE);
|
|
block = addKey(block, key[6]);
|
|
|
|
--round 6
|
|
block = byteSub(block, SBOX);
|
|
block = shiftRow(block, ROW_SHIFT);
|
|
block = mixCol(block, MIXTABLE);
|
|
block = addKey(block, key[7]);
|
|
|
|
--round 7
|
|
block = byteSub(block, SBOX);
|
|
block = shiftRow(block, ROW_SHIFT);
|
|
block = mixCol(block, MIXTABLE);
|
|
block = addKey(block, key[8]);
|
|
|
|
--round 8
|
|
block = byteSub(block, SBOX);
|
|
block = shiftRow(block, ROW_SHIFT);
|
|
block = mixCol(block, MIXTABLE);
|
|
block = addKey(block, key[9]);
|
|
|
|
--round 9
|
|
block = byteSub(block, SBOX);
|
|
block = shiftRow(block, ROW_SHIFT);
|
|
block = mixCol(block, MIXTABLE);
|
|
block = addKey(block, key[10]);
|
|
|
|
--round 10
|
|
block = byteSub(block, SBOX);
|
|
block = shiftRow(block, ROW_SHIFT);
|
|
block = mixCol(block, MIXTABLE);
|
|
block = addKey(block, key[11]);
|
|
|
|
--round 11
|
|
block = byteSub(block, SBOX);
|
|
block = shiftRow(block, ROW_SHIFT);
|
|
block = mixCol(block, MIXTABLE);
|
|
block = addKey(block, key[12]);
|
|
|
|
--round 12
|
|
block = byteSub(block, SBOX);
|
|
block = shiftRow(block, ROW_SHIFT);
|
|
block = addKey(block, key[13]);
|
|
|
|
return block;
|
|
|
|
end
|
|
|
|
AES.decrypt = function(_key, block)
|
|
|
|
local key = keyExpand(_key);
|
|
|
|
--round 0
|
|
block = addKey(block, key[13]);
|
|
|
|
--round 1
|
|
block = shiftRow(block, IROW_SHIFT);
|
|
block = byteSub(block, ISBOX);
|
|
block = addKey(block, key[12]);
|
|
block = mixCol(block, IMIXTABLE);
|
|
|
|
--round 2
|
|
block = shiftRow(block, IROW_SHIFT);
|
|
block = byteSub(block, ISBOX);
|
|
block = addKey(block, key[11]);
|
|
block = mixCol(block, IMIXTABLE);
|
|
|
|
--round 3
|
|
block = shiftRow(block, IROW_SHIFT);
|
|
block = byteSub(block, ISBOX);
|
|
block = addKey(block, key[10]);
|
|
block = mixCol(block, IMIXTABLE);
|
|
|
|
--round 4
|
|
block = shiftRow(block, IROW_SHIFT);
|
|
block = byteSub(block, ISBOX);
|
|
block = addKey(block, key[9]);
|
|
block = mixCol(block, IMIXTABLE);
|
|
|
|
--round 5
|
|
block = shiftRow(block, IROW_SHIFT);
|
|
block = byteSub(block, ISBOX);
|
|
block = addKey(block, key[8]);
|
|
block = mixCol(block, IMIXTABLE);
|
|
|
|
--round 6
|
|
block = shiftRow(block, IROW_SHIFT);
|
|
block = byteSub(block, ISBOX);
|
|
block = addKey(block, key[7]);
|
|
block = mixCol(block, IMIXTABLE);
|
|
|
|
--round 7
|
|
block = shiftRow(block, IROW_SHIFT);
|
|
block = byteSub(block, ISBOX);
|
|
block = addKey(block, key[6]);
|
|
block = mixCol(block, IMIXTABLE);
|
|
|
|
--round 8
|
|
block = shiftRow(block, IROW_SHIFT);
|
|
block = byteSub(block, ISBOX);
|
|
block = addKey(block, key[5]);
|
|
block = mixCol(block, IMIXTABLE);
|
|
|
|
--round 9
|
|
block = shiftRow(block, IROW_SHIFT);
|
|
block = byteSub(block, ISBOX);
|
|
block = addKey(block, key[4]);
|
|
block = mixCol(block, IMIXTABLE);
|
|
|
|
--round 10
|
|
block = shiftRow(block, IROW_SHIFT);
|
|
block = byteSub(block, ISBOX);
|
|
block = addKey(block, key[3]);
|
|
block = mixCol(block, IMIXTABLE);
|
|
|
|
--round 11
|
|
block = shiftRow(block, IROW_SHIFT);
|
|
block = byteSub(block, ISBOX);
|
|
block = addKey(block, key[2]);
|
|
block = mixCol(block, IMIXTABLE);
|
|
|
|
--round 12
|
|
block = shiftRow(block, IROW_SHIFT);
|
|
block = byteSub(block, ISBOX);
|
|
block = addKey(block, key[1]);
|
|
|
|
return block;
|
|
end
|
|
|
|
return AES;
|