aes192.lua 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. local Array = require("lockbox.util.array");
  2. local Bit = require("lockbox.util.bit");
  3. local XOR = Bit.bxor;
  4. local SBOX = {
  5. [0] = 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
  6. 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
  7. 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
  8. 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
  9. 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
  10. 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
  11. 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
  12. 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
  13. 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
  14. 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
  15. 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
  16. 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
  17. 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
  18. 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
  19. 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
  20. 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16};
  21. local ISBOX = {
  22. [0] = 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
  23. 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
  24. 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
  25. 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
  26. 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
  27. 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
  28. 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
  29. 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
  30. 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
  31. 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
  32. 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
  33. 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
  34. 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
  35. 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
  36. 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
  37. 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D};
  38. local ROW_SHIFT = { 1, 6, 11, 16, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, };
  39. local IROW_SHIFT = { 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3, 16, 13, 10, 7, 4, };
  40. local ETABLE = {
  41. [0] = 0x01, 0x03, 0x05, 0x0F, 0x11, 0x33, 0x55, 0xFF, 0x1A, 0x2E, 0x72, 0x96, 0xA1, 0xF8, 0x13, 0x35,
  42. 0x5F, 0xE1, 0x38, 0x48, 0xD8, 0x73, 0x95, 0xA4, 0xF7, 0x02, 0x06, 0x0A, 0x1E, 0x22, 0x66, 0xAA,
  43. 0xE5, 0x34, 0x5C, 0xE4, 0x37, 0x59, 0xEB, 0x26, 0x6A, 0xBE, 0xD9, 0x70, 0x90, 0xAB, 0xE6, 0x31,
  44. 0x53, 0xF5, 0x04, 0x0C, 0x14, 0x3C, 0x44, 0xCC, 0x4F, 0xD1, 0x68, 0xB8, 0xD3, 0x6E, 0xB2, 0xCD,
  45. 0x4C, 0xD4, 0x67, 0xA9, 0xE0, 0x3B, 0x4D, 0xD7, 0x62, 0xA6, 0xF1, 0x08, 0x18, 0x28, 0x78, 0x88,
  46. 0x83, 0x9E, 0xB9, 0xD0, 0x6B, 0xBD, 0xDC, 0x7F, 0x81, 0x98, 0xB3, 0xCE, 0x49, 0xDB, 0x76, 0x9A,
  47. 0xB5, 0xC4, 0x57, 0xF9, 0x10, 0x30, 0x50, 0xF0, 0x0B, 0x1D, 0x27, 0x69, 0xBB, 0xD6, 0x61, 0xA3,
  48. 0xFE, 0x19, 0x2B, 0x7D, 0x87, 0x92, 0xAD, 0xEC, 0x2F, 0x71, 0x93, 0xAE, 0xE9, 0x20, 0x60, 0xA0,
  49. 0xFB, 0x16, 0x3A, 0x4E, 0xD2, 0x6D, 0xB7, 0xC2, 0x5D, 0xE7, 0x32, 0x56, 0xFA, 0x15, 0x3F, 0x41,
  50. 0xC3, 0x5E, 0xE2, 0x3D, 0x47, 0xC9, 0x40, 0xC0, 0x5B, 0xED, 0x2C, 0x74, 0x9C, 0xBF, 0xDA, 0x75,
  51. 0x9F, 0xBA, 0xD5, 0x64, 0xAC, 0xEF, 0x2A, 0x7E, 0x82, 0x9D, 0xBC, 0xDF, 0x7A, 0x8E, 0x89, 0x80,
  52. 0x9B, 0xB6, 0xC1, 0x58, 0xE8, 0x23, 0x65, 0xAF, 0xEA, 0x25, 0x6F, 0xB1, 0xC8, 0x43, 0xC5, 0x54,
  53. 0xFC, 0x1F, 0x21, 0x63, 0xA5, 0xF4, 0x07, 0x09, 0x1B, 0x2D, 0x77, 0x99, 0xB0, 0xCB, 0x46, 0xCA,
  54. 0x45, 0xCF, 0x4A, 0xDE, 0x79, 0x8B, 0x86, 0x91, 0xA8, 0xE3, 0x3E, 0x42, 0xC6, 0x51, 0xF3, 0x0E,
  55. 0x12, 0x36, 0x5A, 0xEE, 0x29, 0x7B, 0x8D, 0x8C, 0x8F, 0x8A, 0x85, 0x94, 0xA7, 0xF2, 0x0D, 0x17,
  56. 0x39, 0x4B, 0xDD, 0x7C, 0x84, 0x97, 0xA2, 0xFD, 0x1C, 0x24, 0x6C, 0xB4, 0xC7, 0x52, 0xF6, 0x01};
  57. local LTABLE = {
  58. [0] = 0x00, 0x00, 0x19, 0x01, 0x32, 0x02, 0x1A, 0xC6, 0x4B, 0xC7, 0x1B, 0x68, 0x33, 0xEE, 0xDF, 0x03,
  59. 0x64, 0x04, 0xE0, 0x0E, 0x34, 0x8D, 0x81, 0xEF, 0x4C, 0x71, 0x08, 0xC8, 0xF8, 0x69, 0x1C, 0xC1,
  60. 0x7D, 0xC2, 0x1D, 0xB5, 0xF9, 0xB9, 0x27, 0x6A, 0x4D, 0xE4, 0xA6, 0x72, 0x9A, 0xC9, 0x09, 0x78,
  61. 0x65, 0x2F, 0x8A, 0x05, 0x21, 0x0F, 0xE1, 0x24, 0x12, 0xF0, 0x82, 0x45, 0x35, 0x93, 0xDA, 0x8E,
  62. 0x96, 0x8F, 0xDB, 0xBD, 0x36, 0xD0, 0xCE, 0x94, 0x13, 0x5C, 0xD2, 0xF1, 0x40, 0x46, 0x83, 0x38,
  63. 0x66, 0xDD, 0xFD, 0x30, 0xBF, 0x06, 0x8B, 0x62, 0xB3, 0x25, 0xE2, 0x98, 0x22, 0x88, 0x91, 0x10,
  64. 0x7E, 0x6E, 0x48, 0xC3, 0xA3, 0xB6, 0x1E, 0x42, 0x3A, 0x6B, 0x28, 0x54, 0xFA, 0x85, 0x3D, 0xBA,
  65. 0x2B, 0x79, 0x0A, 0x15, 0x9B, 0x9F, 0x5E, 0xCA, 0x4E, 0xD4, 0xAC, 0xE5, 0xF3, 0x73, 0xA7, 0x57,
  66. 0xAF, 0x58, 0xA8, 0x50, 0xF4, 0xEA, 0xD6, 0x74, 0x4F, 0xAE, 0xE9, 0xD5, 0xE7, 0xE6, 0xAD, 0xE8,
  67. 0x2C, 0xD7, 0x75, 0x7A, 0xEB, 0x16, 0x0B, 0xF5, 0x59, 0xCB, 0x5F, 0xB0, 0x9C, 0xA9, 0x51, 0xA0,
  68. 0x7F, 0x0C, 0xF6, 0x6F, 0x17, 0xC4, 0x49, 0xEC, 0xD8, 0x43, 0x1F, 0x2D, 0xA4, 0x76, 0x7B, 0xB7,
  69. 0xCC, 0xBB, 0x3E, 0x5A, 0xFB, 0x60, 0xB1, 0x86, 0x3B, 0x52, 0xA1, 0x6C, 0xAA, 0x55, 0x29, 0x9D,
  70. 0x97, 0xB2, 0x87, 0x90, 0x61, 0xBE, 0xDC, 0xFC, 0xBC, 0x95, 0xCF, 0xCD, 0x37, 0x3F, 0x5B, 0xD1,
  71. 0x53, 0x39, 0x84, 0x3C, 0x41, 0xA2, 0x6D, 0x47, 0x14, 0x2A, 0x9E, 0x5D, 0x56, 0xF2, 0xD3, 0xAB,
  72. 0x44, 0x11, 0x92, 0xD9, 0x23, 0x20, 0x2E, 0x89, 0xB4, 0x7C, 0xB8, 0x26, 0x77, 0x99, 0xE3, 0xA5,
  73. 0x67, 0x4A, 0xED, 0xDE, 0xC5, 0x31, 0xFE, 0x18, 0x0D, 0x63, 0x8C, 0x80, 0xC0, 0xF7, 0x70, 0x07};
  74. local MIXTABLE = {
  75. 0x02, 0x03, 0x01, 0x01,
  76. 0x01, 0x02, 0x03, 0x01,
  77. 0x01, 0x01, 0x02, 0x03,
  78. 0x03, 0x01, 0x01, 0x02};
  79. local IMIXTABLE = {
  80. 0x0E, 0x0B, 0x0D, 0x09,
  81. 0x09, 0x0E, 0x0B, 0x0D,
  82. 0x0D, 0x09, 0x0E, 0x0B,
  83. 0x0B, 0x0D, 0x09, 0x0E};
  84. local RCON = {
  85. [0] = 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
  86. 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
  87. 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
  88. 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
  89. 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
  90. 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
  91. 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
  92. 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
  93. 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
  94. 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
  95. 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
  96. 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
  97. 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
  98. 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
  99. 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
  100. 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d};
  101. local GMUL = function(A, B)
  102. if(A == 0x01) then return B; end
  103. if(B == 0x01) then return A; end
  104. if(A == 0x00) then return 0; end
  105. if(B == 0x00) then return 0; end
  106. local LA = LTABLE[A];
  107. local LB = LTABLE[B];
  108. local sum = LA + LB;
  109. if (sum > 0xFF) then sum = sum - 0xFF; end
  110. return ETABLE[sum];
  111. end
  112. local byteSub = Array.substitute;
  113. local shiftRow = Array.permute;
  114. local mixCol = function(i, mix)
  115. local out = {};
  116. local a, b, c, d;
  117. a = GMUL(i[ 1], mix[ 1]);
  118. b = GMUL(i[ 2], mix[ 2]);
  119. c = GMUL(i[ 3], mix[ 3]);
  120. d = GMUL(i[ 4], mix[ 4]);
  121. out[ 1] = XOR(XOR(a, b), XOR(c, d));
  122. a = GMUL(i[ 1], mix[ 5]);
  123. b = GMUL(i[ 2], mix[ 6]);
  124. c = GMUL(i[ 3], mix[ 7]);
  125. d = GMUL(i[ 4], mix[ 8]);
  126. out[ 2] = XOR(XOR(a, b), XOR(c, d));
  127. a = GMUL(i[ 1], mix[ 9]);
  128. b = GMUL(i[ 2], mix[10]);
  129. c = GMUL(i[ 3], mix[11]);
  130. d = GMUL(i[ 4], mix[12]);
  131. out[ 3] = XOR(XOR(a, b), XOR(c, d));
  132. a = GMUL(i[ 1], mix[13]);
  133. b = GMUL(i[ 2], mix[14]);
  134. c = GMUL(i[ 3], mix[15]);
  135. d = GMUL(i[ 4], mix[16]);
  136. out[ 4] = XOR(XOR(a, b), XOR(c, d));
  137. a = GMUL(i[ 5], mix[ 1]);
  138. b = GMUL(i[ 6], mix[ 2]);
  139. c = GMUL(i[ 7], mix[ 3]);
  140. d = GMUL(i[ 8], mix[ 4]);
  141. out[ 5] = XOR(XOR(a, b), XOR(c, d));
  142. a = GMUL(i[ 5], mix[ 5]);
  143. b = GMUL(i[ 6], mix[ 6]);
  144. c = GMUL(i[ 7], mix[ 7]);
  145. d = GMUL(i[ 8], mix[ 8]);
  146. out[ 6] = XOR(XOR(a, b), XOR(c, d));
  147. a = GMUL(i[ 5], mix[ 9]);
  148. b = GMUL(i[ 6], mix[10]);
  149. c = GMUL(i[ 7], mix[11]);
  150. d = GMUL(i[ 8], mix[12]);
  151. out[ 7] = XOR(XOR(a, b), XOR(c, d));
  152. a = GMUL(i[ 5], mix[13]);
  153. b = GMUL(i[ 6], mix[14]);
  154. c = GMUL(i[ 7], mix[15]);
  155. d = GMUL(i[ 8], mix[16]);
  156. out[ 8] = XOR(XOR(a, b), XOR(c, d));
  157. a = GMUL(i[ 9], mix[ 1]);
  158. b = GMUL(i[10], mix[ 2]);
  159. c = GMUL(i[11], mix[ 3]);
  160. d = GMUL(i[12], mix[ 4]);
  161. out[ 9] = XOR(XOR(a, b), XOR(c, d));
  162. a = GMUL(i[ 9], mix[ 5]);
  163. b = GMUL(i[10], mix[ 6]);
  164. c = GMUL(i[11], mix[ 7]);
  165. d = GMUL(i[12], mix[ 8]);
  166. out[10] = XOR(XOR(a, b), XOR(c, d));
  167. a = GMUL(i[ 9], mix[ 9]);
  168. b = GMUL(i[10], mix[10]);
  169. c = GMUL(i[11], mix[11]);
  170. d = GMUL(i[12], mix[12]);
  171. out[11] = XOR(XOR(a, b), XOR(c, d));
  172. a = GMUL(i[ 9], mix[13]);
  173. b = GMUL(i[10], mix[14]);
  174. c = GMUL(i[11], mix[15]);
  175. d = GMUL(i[12], mix[16]);
  176. out[12] = XOR(XOR(a, b), XOR(c, d));
  177. a = GMUL(i[13], mix[ 1]);
  178. b = GMUL(i[14], mix[ 2]);
  179. c = GMUL(i[15], mix[ 3]);
  180. d = GMUL(i[16], mix[ 4]);
  181. out[13] = XOR(XOR(a, b), XOR(c, d));
  182. a = GMUL(i[13], mix[ 5]);
  183. b = GMUL(i[14], mix[ 6]);
  184. c = GMUL(i[15], mix[ 7]);
  185. d = GMUL(i[16], mix[ 8]);
  186. out[14] = XOR(XOR(a, b), XOR(c, d));
  187. a = GMUL(i[13], mix[ 9]);
  188. b = GMUL(i[14], mix[10]);
  189. c = GMUL(i[15], mix[11]);
  190. d = GMUL(i[16], mix[12]);
  191. out[15] = XOR(XOR(a, b), XOR(c, d));
  192. a = GMUL(i[13], mix[13]);
  193. b = GMUL(i[14], mix[14]);
  194. c = GMUL(i[15], mix[15]);
  195. d = GMUL(i[16], mix[16]);
  196. out[16] = XOR(XOR(a, b), XOR(c, d));
  197. return out;
  198. end
  199. local keyRound = function(key, round)
  200. local i = (round - 1) * 24;
  201. local out = key;
  202. out[25 + i] = XOR(key[ 1 + i], XOR(SBOX[key[22 + i]], RCON[round]));
  203. out[26 + i] = XOR(key[ 2 + i], SBOX[key[23 + i]]);
  204. out[27 + i] = XOR(key[ 3 + i], SBOX[key[24 + i]]);
  205. out[28 + i] = XOR(key[ 4 + i], SBOX[key[21 + i]]);
  206. out[29 + i] = XOR(out[25 + i], key[ 5 + i]);
  207. out[30 + i] = XOR(out[26 + i], key[ 6 + i]);
  208. out[31 + i] = XOR(out[27 + i], key[ 7 + i]);
  209. out[32 + i] = XOR(out[28 + i], key[ 8 + i]);
  210. out[33 + i] = XOR(out[29 + i], key[ 9 + i]);
  211. out[34 + i] = XOR(out[30 + i], key[10 + i]);
  212. out[35 + i] = XOR(out[31 + i], key[11 + i]);
  213. out[36 + i] = XOR(out[32 + i], key[12 + i]);
  214. out[37 + i] = XOR(out[33 + i], key[13 + i]);
  215. out[38 + i] = XOR(out[34 + i], key[14 + i]);
  216. out[39 + i] = XOR(out[35 + i], key[15 + i]);
  217. out[40 + i] = XOR(out[36 + i], key[16 + i]);
  218. out[41 + i] = XOR(out[37 + i], key[17 + i]);
  219. out[42 + i] = XOR(out[38 + i], key[18 + i]);
  220. out[43 + i] = XOR(out[39 + i], key[19 + i]);
  221. out[44 + i] = XOR(out[40 + i], key[20 + i]);
  222. out[45 + i] = XOR(out[41 + i], key[21 + i]);
  223. out[46 + i] = XOR(out[42 + i], key[22 + i]);
  224. out[47 + i] = XOR(out[43 + i], key[23 + i]);
  225. out[48 + i] = XOR(out[44 + i], key[24 + i]);
  226. return out;
  227. end
  228. local keyExpand = function(key)
  229. local bytes = Array.copy(key);
  230. for i = 1, 8 do
  231. keyRound(bytes, i);
  232. end
  233. local keys = {};
  234. keys[ 1] = Array.slice(bytes, 1, 16);
  235. keys[ 2] = Array.slice(bytes, 17, 32);
  236. keys[ 3] = Array.slice(bytes, 33, 48);
  237. keys[ 4] = Array.slice(bytes, 49, 64);
  238. keys[ 5] = Array.slice(bytes, 65, 80);
  239. keys[ 6] = Array.slice(bytes, 81, 96);
  240. keys[ 7] = Array.slice(bytes, 97, 112);
  241. keys[ 8] = Array.slice(bytes, 113, 128);
  242. keys[ 9] = Array.slice(bytes, 129, 144);
  243. keys[10] = Array.slice(bytes, 145, 160);
  244. keys[11] = Array.slice(bytes, 161, 176);
  245. keys[12] = Array.slice(bytes, 177, 192);
  246. keys[13] = Array.slice(bytes, 193, 208);
  247. return keys;
  248. end
  249. local addKey = Array.XOR;
  250. local AES = {};
  251. AES.blockSize = 16;
  252. AES.encrypt = function(key, block)
  253. local keySchedule = keyExpand(key);
  254. --round 0
  255. block = addKey(block, keySchedule[1]);
  256. --round 1
  257. block = byteSub(block, SBOX);
  258. block = shiftRow(block, ROW_SHIFT);
  259. block = mixCol(block, MIXTABLE);
  260. block = addKey(block, keySchedule[2]);
  261. --round 2
  262. block = byteSub(block, SBOX);
  263. block = shiftRow(block, ROW_SHIFT);
  264. block = mixCol(block, MIXTABLE);
  265. block = addKey(block, keySchedule[3]);
  266. --round 3
  267. block = byteSub(block, SBOX);
  268. block = shiftRow(block, ROW_SHIFT);
  269. block = mixCol(block, MIXTABLE);
  270. block = addKey(block, keySchedule[4]);
  271. --round 4
  272. block = byteSub(block, SBOX);
  273. block = shiftRow(block, ROW_SHIFT);
  274. block = mixCol(block, MIXTABLE);
  275. block = addKey(block, keySchedule[5]);
  276. --round 5
  277. block = byteSub(block, SBOX);
  278. block = shiftRow(block, ROW_SHIFT);
  279. block = mixCol(block, MIXTABLE);
  280. block = addKey(block, keySchedule[6]);
  281. --round 6
  282. block = byteSub(block, SBOX);
  283. block = shiftRow(block, ROW_SHIFT);
  284. block = mixCol(block, MIXTABLE);
  285. block = addKey(block, keySchedule[7]);
  286. --round 7
  287. block = byteSub(block, SBOX);
  288. block = shiftRow(block, ROW_SHIFT);
  289. block = mixCol(block, MIXTABLE);
  290. block = addKey(block, keySchedule[8]);
  291. --round 8
  292. block = byteSub(block, SBOX);
  293. block = shiftRow(block, ROW_SHIFT);
  294. block = mixCol(block, MIXTABLE);
  295. block = addKey(block, keySchedule[9]);
  296. --round 9
  297. block = byteSub(block, SBOX);
  298. block = shiftRow(block, ROW_SHIFT);
  299. block = mixCol(block, MIXTABLE);
  300. block = addKey(block, keySchedule[10]);
  301. --round 10
  302. block = byteSub(block, SBOX);
  303. block = shiftRow(block, ROW_SHIFT);
  304. block = mixCol(block, MIXTABLE);
  305. block = addKey(block, keySchedule[11]);
  306. --round 11
  307. block = byteSub(block, SBOX);
  308. block = shiftRow(block, ROW_SHIFT);
  309. block = mixCol(block, MIXTABLE);
  310. block = addKey(block, keySchedule[12]);
  311. --round 12
  312. block = byteSub(block, SBOX);
  313. block = shiftRow(block, ROW_SHIFT);
  314. block = addKey(block, keySchedule[13]);
  315. return block;
  316. end
  317. AES.decrypt = function(key, block)
  318. local keySchedule = keyExpand(key);
  319. --round 0
  320. block = addKey(block, keySchedule[13]);
  321. --round 1
  322. block = shiftRow(block, IROW_SHIFT);
  323. block = byteSub(block, ISBOX);
  324. block = addKey(block, keySchedule[12]);
  325. block = mixCol(block, IMIXTABLE);
  326. --round 2
  327. block = shiftRow(block, IROW_SHIFT);
  328. block = byteSub(block, ISBOX);
  329. block = addKey(block, keySchedule[11]);
  330. block = mixCol(block, IMIXTABLE);
  331. --round 3
  332. block = shiftRow(block, IROW_SHIFT);
  333. block = byteSub(block, ISBOX);
  334. block = addKey(block, keySchedule[10]);
  335. block = mixCol(block, IMIXTABLE);
  336. --round 4
  337. block = shiftRow(block, IROW_SHIFT);
  338. block = byteSub(block, ISBOX);
  339. block = addKey(block, keySchedule[9]);
  340. block = mixCol(block, IMIXTABLE);
  341. --round 5
  342. block = shiftRow(block, IROW_SHIFT);
  343. block = byteSub(block, ISBOX);
  344. block = addKey(block, keySchedule[8]);
  345. block = mixCol(block, IMIXTABLE);
  346. --round 6
  347. block = shiftRow(block, IROW_SHIFT);
  348. block = byteSub(block, ISBOX);
  349. block = addKey(block, keySchedule[7]);
  350. block = mixCol(block, IMIXTABLE);
  351. --round 7
  352. block = shiftRow(block, IROW_SHIFT);
  353. block = byteSub(block, ISBOX);
  354. block = addKey(block, keySchedule[6]);
  355. block = mixCol(block, IMIXTABLE);
  356. --round 8
  357. block = shiftRow(block, IROW_SHIFT);
  358. block = byteSub(block, ISBOX);
  359. block = addKey(block, keySchedule[5]);
  360. block = mixCol(block, IMIXTABLE);
  361. --round 9
  362. block = shiftRow(block, IROW_SHIFT);
  363. block = byteSub(block, ISBOX);
  364. block = addKey(block, keySchedule[4]);
  365. block = mixCol(block, IMIXTABLE);
  366. --round 10
  367. block = shiftRow(block, IROW_SHIFT);
  368. block = byteSub(block, ISBOX);
  369. block = addKey(block, keySchedule[3]);
  370. block = mixCol(block, IMIXTABLE);
  371. --round 11
  372. block = shiftRow(block, IROW_SHIFT);
  373. block = byteSub(block, ISBOX);
  374. block = addKey(block, keySchedule[2]);
  375. block = mixCol(block, IMIXTABLE);
  376. --round 12
  377. block = shiftRow(block, IROW_SHIFT);
  378. block = byteSub(block, ISBOX);
  379. block = addKey(block, keySchedule[1]);
  380. return block;
  381. end
  382. return AES;