Contains the source code from the course work throughout my undergraduate Computer Engineering degree at Brigham Young University. There is a mixture of Go, Python, C, C++, Java, VHDL, Verilog, Matlab, Bash, Assembly, etc..
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

aes.go 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  1. package aes
  2. import (
  3. "encoding/hex"
  4. "fmt"
  5. "log"
  6. "strconv"
  7. )
  8. var sbox = [][]byte{
  9. {0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76},
  10. {0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0},
  11. {0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15},
  12. {0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75},
  13. {0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84},
  14. {0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf},
  15. {0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8},
  16. {0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2},
  17. {0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73},
  18. {0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb},
  19. {0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79},
  20. {0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08},
  21. {0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a},
  22. {0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e},
  23. {0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf},
  24. {0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16},
  25. }
  26. var invSbox = [][]byte{
  27. {0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb},
  28. {0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb},
  29. {0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e},
  30. {0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25},
  31. {0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92},
  32. {0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84},
  33. {0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06},
  34. {0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b},
  35. {0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73},
  36. {0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e},
  37. {0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b},
  38. {0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4},
  39. {0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f},
  40. {0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef},
  41. {0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61},
  42. {0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d},
  43. }
  44. var mm = []byte{
  45. 2, 3, 1, 1,
  46. 1, 2, 3, 1,
  47. 1, 1, 2, 3,
  48. 3, 1, 1, 2,
  49. }
  50. var iMM = []byte{
  51. 14, 11, 13, 9,
  52. 9, 14, 11, 13,
  53. 13, 9, 14, 11,
  54. 11, 13, 9, 14,
  55. }
  56. var rcon = []byte{0x00, // rcon[] is 1-based, so the first entry is just a place holder
  57. 0x01, 0x02, 0x04, 0x08,
  58. 0x10, 0x20, 0x40, 0x80,
  59. 0x1B, 0x36, 0x6C, 0xD8,
  60. 0xAB, 0x4D, 0x9A, 0x2F,
  61. 0x5E, 0xBC, 0x63, 0xC6,
  62. 0x97, 0x35, 0x6A, 0xD4,
  63. 0xB3, 0x7D, 0xFA, 0xEF,
  64. 0xC5, 0x91, 0x39, 0x72,
  65. 0xE4, 0xD3, 0xBD, 0x61,
  66. 0xC2, 0x9F, 0x25, 0x4A,
  67. 0x94, 0x33, 0x66, 0xCC,
  68. 0x83, 0x1D, 0x3A, 0x74,
  69. 0xE8, 0xCB, 0x8D,
  70. }
  71. //Block renamed []byte type for simplicity
  72. type Block []byte
  73. var keyexpanded []Block
  74. var key Block
  75. //ToString writes []Block to a string in ascii form
  76. func ToString(all []Block, keysize int, k Block, decrypt bool) string {
  77. final := ""
  78. for _, bl := range all {
  79. result := Block{}
  80. if decrypt {
  81. result = InvCipher(bl, keysize, k)
  82. } else {
  83. result = Cipher(bl, keysize, k)
  84. }
  85. final += string(result)
  86. }
  87. return final
  88. }
  89. //ToHex writes []Block to a string in hex form
  90. func ToHex(all []Block, keysize int, k Block, decrypt bool) string {
  91. final := ""
  92. for _, bl := range all {
  93. result := Block{}
  94. if decrypt {
  95. result = InvCipher(bl, keysize, k)
  96. } else {
  97. result = Cipher(bl, keysize, k)
  98. }
  99. for i := 0; i < 16; i++ {
  100. final += fmt.Sprintf("0x%x ", result[i])
  101. }
  102. }
  103. return final
  104. }
  105. //BlockGen helps create []Block from incoming string
  106. func BlockGen(arg string) []Block {
  107. all := []Block{}
  108. b := Block{}
  109. for i, char := range arg {
  110. value, err := strconv.ParseUint(
  111. hex.EncodeToString(
  112. []byte(string(char))),
  113. 16,
  114. 32,
  115. )
  116. if err != nil {
  117. log.Fatal(err)
  118. }
  119. if i%16 == 0 && i > 0 {
  120. all = append(all, b)
  121. b = b[:0]
  122. }
  123. b = append(b, byte(value))
  124. if i == len(arg)-1 {
  125. all = append(all, b)
  126. }
  127. }
  128. return all
  129. }
  130. //Cipher performs AES cipher
  131. func Cipher(cur Block, bit int, incomingKey Block) Block {
  132. if len(cur) != 16 {
  133. missing := 16 - len(cur)
  134. for i := 0; i < missing; i++ {
  135. cur = append(cur, 0x00)
  136. }
  137. }
  138. key = Block{}
  139. keyexpanded = []Block{}
  140. assignKey(incomingKey)
  141. if bit == 128 {
  142. keyExpansionBase(128)
  143. cur = addRoundKey(cur, 0)
  144. for i := 0; i < 9; i++ {
  145. cur = subBytes(cur)
  146. cur = shiftRows(cur)
  147. cur = mixColumns(cur)
  148. cur = addRoundKey(cur, i+1)
  149. }
  150. cur = subBytes(cur)
  151. cur = shiftRows(cur)
  152. cur = addRoundKey(cur, 10)
  153. return cur
  154. }
  155. if bit == 192 {
  156. keyExpansionBase(192)
  157. cur = addRoundKey(cur, 0)
  158. for i := 0; i < 11; i++ {
  159. cur = subBytes(cur)
  160. cur = shiftRows(cur)
  161. cur = mixColumns(cur)
  162. cur = addRoundKey(cur, i+1)
  163. if i == 0 {
  164. }
  165. }
  166. cur = subBytes(cur)
  167. cur = shiftRows(cur)
  168. cur = addRoundKey(cur, 12)
  169. return cur
  170. }
  171. if bit == 256 {
  172. keyExpansionBase(256)
  173. cur = addRoundKey(cur, 0)
  174. for i := 0; i < 13; i++ {
  175. cur = subBytes(cur)
  176. cur = shiftRows(cur)
  177. cur = mixColumns(cur)
  178. cur = addRoundKey(cur, i+1)
  179. if i == 0 {
  180. }
  181. }
  182. cur = subBytes(cur)
  183. cur = shiftRows(cur)
  184. cur = addRoundKey(cur, 14)
  185. return cur
  186. }
  187. return cur
  188. }
  189. //InvCipher inverse AES cipher
  190. func InvCipher(cur Block, bit int, incomingKey Block) Block {
  191. if len(cur) != 16 {
  192. missing := 16 - len(cur)
  193. for i := 0; i < missing; i++ {
  194. cur = append(cur, 0x00)
  195. }
  196. }
  197. key = Block{}
  198. keyexpanded = []Block{}
  199. assignKey(incomingKey)
  200. if bit == 128 {
  201. keyExpansionBase(128)
  202. cur = addRoundKey(cur, 10)
  203. for i := 9; i > 0; i-- {
  204. cur = invShiftRows(cur)
  205. cur = invSubBytes(cur)
  206. cur = addRoundKey(cur, i)
  207. cur = invMixColumns(cur)
  208. }
  209. cur = invSubBytes(cur)
  210. cur = invShiftRows(cur)
  211. cur = addRoundKey(cur, 0)
  212. return cur
  213. }
  214. if bit == 192 {
  215. keyExpansionBase(192)
  216. cur = addRoundKey(cur, 12)
  217. for i := 11; i > 0; i-- {
  218. cur = invShiftRows(cur)
  219. cur = invSubBytes(cur)
  220. cur = addRoundKey(cur, i)
  221. cur = invMixColumns(cur)
  222. }
  223. cur = invSubBytes(cur)
  224. cur = invShiftRows(cur)
  225. cur = addRoundKey(cur, 0)
  226. return cur
  227. }
  228. if bit == 256 {
  229. keyExpansionBase(256)
  230. cur = addRoundKey(cur, 14)
  231. for i := 13; i > 0; i-- {
  232. cur = invShiftRows(cur)
  233. cur = invSubBytes(cur)
  234. cur = addRoundKey(cur, i)
  235. cur = invMixColumns(cur)
  236. }
  237. cur = invSubBytes(cur)
  238. cur = invShiftRows(cur)
  239. cur = addRoundKey(cur, 0)
  240. return cur
  241. }
  242. return cur
  243. }
  244. func addRoundKey(cur Block, iteration int) Block {
  245. for i := 0; i < 16; i++ {
  246. cur[i] = cur[i] ^ keyexpanded[iteration][i]
  247. }
  248. return cur
  249. }
  250. func assignKey(cur Block) {
  251. key = cur
  252. }
  253. func keyExpansionBase(keysize int) {
  254. if keysize == 128 {
  255. keyexpanded = append(keyexpanded, key)
  256. for i := 0; i < 10; i++ {
  257. keyExpansion(keyexpanded[i], i+1)
  258. }
  259. } else if keysize == 192 {
  260. keyexpanded = append(keyexpanded, key)
  261. for i := 0; i < 8; i++ {
  262. keyExpansion192(keyexpanded[i], i+1)
  263. }
  264. temp := keyexpanded
  265. keyexpanded = []Block{}
  266. for i := 0; i < 9; i++ {
  267. if i == 8 {
  268. a := Block{
  269. temp[i][0], temp[i][1], temp[i][2], temp[i][3],
  270. temp[i][6], temp[i][7], temp[i][8], temp[i][9],
  271. temp[i][12], temp[i][13], temp[i][14], temp[i][15],
  272. temp[i][18], temp[i][19], temp[i][20], temp[i][21],
  273. }
  274. b := Block{
  275. temp[i][4], temp[i][5], 0, 0,
  276. temp[i][10], temp[i][11], 0, 0,
  277. temp[i][16], temp[i][17], 0, 0,
  278. temp[i][22], temp[i][23], 0, 0,
  279. }
  280. keyexpanded = append(keyexpanded, a)
  281. keyexpanded = append(keyexpanded, b)
  282. } else {
  283. a := Block{
  284. temp[i][0], temp[i][1], temp[i][2], temp[i][3],
  285. temp[i][6], temp[i][7], temp[i][8], temp[i][9],
  286. temp[i][12], temp[i][13], temp[i][14], temp[i][15],
  287. temp[i][18], temp[i][19], temp[i][20], temp[i][21],
  288. }
  289. b := Block{
  290. temp[i][4], temp[i][5], temp[i+1][0], temp[i+1][1],
  291. temp[i][10], temp[i][11], temp[i+1][6], temp[i+1][7],
  292. temp[i][16], temp[i][17], temp[i+1][12], temp[i+1][13],
  293. temp[i][22], temp[i][23], temp[i+1][18], temp[i+1][19],
  294. }
  295. c := Block{
  296. temp[i+1][2], temp[i+1][3], temp[i+1][4], temp[i+1][5],
  297. temp[i+1][8], temp[i+1][9], temp[i+1][10], temp[i+1][11],
  298. temp[i+1][14], temp[i+1][15], temp[i+1][16], temp[i+1][17],
  299. temp[i+1][20], temp[i+1][21], temp[i+1][22], temp[i+1][23],
  300. }
  301. keyexpanded = append(keyexpanded, a)
  302. keyexpanded = append(keyexpanded, b)
  303. keyexpanded = append(keyexpanded, c)
  304. }
  305. i++
  306. }
  307. } else if keysize == 256 {
  308. keyexpanded = append(keyexpanded, key)
  309. for i := 0; i < 8; i++ {
  310. keyExpansion256(keyexpanded[i], i+1)
  311. }
  312. temp := keyexpanded
  313. keyexpanded = []Block{}
  314. for i := 0; i < 9; i++ {
  315. a := Block{
  316. temp[i][0], temp[i][1], temp[i][2], temp[i][3],
  317. temp[i][8], temp[i][9], temp[i][10], temp[i][11],
  318. temp[i][16], temp[i][17], temp[i][18], temp[i][19],
  319. temp[i][24], temp[i][25], temp[i][26], temp[i][27],
  320. }
  321. b := Block{
  322. temp[i][4], temp[i][5], temp[i][6], temp[i][7],
  323. temp[i][12], temp[i][13], temp[i][14], temp[i][15],
  324. temp[i][20], temp[i][21], temp[i][22], temp[i][23],
  325. temp[i][28], temp[i][29], temp[i][30], temp[i][31],
  326. }
  327. keyexpanded = append(keyexpanded, a)
  328. keyexpanded = append(keyexpanded, b)
  329. }
  330. }
  331. }
  332. func keyExpansion(cur Block, iteration int) Block {
  333. var nb = Block{ //nb = nextBlock
  334. 0x00, 0x00, 0x00, 0x00,
  335. 0x00, 0x00, 0x00, 0x00,
  336. 0x00, 0x00, 0x00, 0x00,
  337. 0x00, 0x00, 0x00, 0x00,
  338. }
  339. rotword := []byte{cur[7], cur[11], cur[15], cur[3]}
  340. for i := 0; i < 4; i++ {
  341. upper, lower := splitBytes(rotword[i])
  342. rotword[i] = sbox[upper][lower]
  343. }
  344. rotword[0] = rotword[0] ^ cur[0] ^ rcon[iteration]
  345. rotword[1] = rotword[1] ^ cur[4]
  346. rotword[2] = rotword[2] ^ cur[8]
  347. rotword[3] = rotword[3] ^ cur[12]
  348. nb[0], nb[4], nb[8], nb[12] = rotword[0], rotword[1], rotword[2], rotword[3]
  349. nb[1], nb[5], nb[9], nb[13] = nb[0]^cur[1], nb[4]^cur[5], nb[8]^cur[9], nb[12]^cur[13]
  350. nb[2], nb[6], nb[10], nb[14] = nb[1]^cur[2], nb[5]^cur[6], nb[9]^cur[10], nb[13]^cur[14]
  351. nb[3], nb[7], nb[11], nb[15] = nb[2]^cur[3], nb[6]^cur[7], nb[10]^cur[11], nb[14]^cur[15]
  352. keyexpanded = append(keyexpanded, nb)
  353. return nb
  354. }
  355. func keyExpansion192(cur Block, iteration int) Block {
  356. var nb = Block{ //nb = nextBlock
  357. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  358. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  359. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  360. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  361. }
  362. rotword := []byte{cur[11], cur[17], cur[23], cur[5]}
  363. for i := 0; i < 4; i++ {
  364. upper, lower := splitBytes(rotword[i])
  365. rotword[i] = sbox[upper][lower]
  366. }
  367. rotword[0] = rotword[0] ^ cur[0] ^ rcon[iteration]
  368. rotword[1] = rotword[1] ^ cur[6]
  369. rotword[2] = rotword[2] ^ cur[12]
  370. rotword[3] = rotword[3] ^ cur[18]
  371. nb[0], nb[6], nb[12], nb[18] = rotword[0], rotword[1], rotword[2], rotword[3]
  372. nb[1], nb[7], nb[13], nb[19] = nb[0]^cur[1], nb[6]^cur[7], nb[12]^cur[13], nb[18]^cur[19]
  373. nb[2], nb[8], nb[14], nb[20] = nb[1]^cur[2], nb[7]^cur[8], nb[13]^cur[14], nb[19]^cur[20]
  374. nb[3], nb[9], nb[15], nb[21] = nb[2]^cur[3], nb[8]^cur[9], nb[14]^cur[15], nb[20]^cur[21]
  375. nb[4], nb[10], nb[16], nb[22] = nb[3]^cur[4], nb[9]^cur[10], nb[15]^cur[16], nb[21]^cur[22]
  376. nb[5], nb[11], nb[17], nb[23] = nb[4]^cur[5], nb[10]^cur[11], nb[16]^cur[17], nb[22]^cur[23]
  377. keyexpanded = append(keyexpanded, nb)
  378. return nb
  379. }
  380. func keyExpansion256(cur Block, iteration int) Block {
  381. var nb = Block{ //nb = nextBlock
  382. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  383. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  384. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  385. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  386. }
  387. rotword := []byte{cur[15], cur[23], cur[31], cur[7]}
  388. for i := 0; i < 4; i++ {
  389. upper, lower := splitBytes(rotword[i])
  390. rotword[i] = sbox[upper][lower]
  391. }
  392. rotword[0] = rotword[0] ^ cur[0] ^ rcon[iteration]
  393. rotword[1] = rotword[1] ^ cur[8]
  394. rotword[2] = rotword[2] ^ cur[16]
  395. rotword[3] = rotword[3] ^ cur[24]
  396. nb[0], nb[8], nb[16], nb[24] = rotword[0], rotword[1], rotword[2], rotword[3]
  397. nb[1], nb[9], nb[17], nb[25] = nb[0]^cur[1], nb[8]^cur[9], nb[16]^cur[17], nb[24]^cur[25]
  398. nb[2], nb[10], nb[18], nb[26] = nb[1]^cur[2], nb[9]^cur[10], nb[17]^cur[18], nb[25]^cur[26]
  399. nb[3], nb[11], nb[19], nb[27] = nb[2]^cur[3], nb[10]^cur[11], nb[18]^cur[19], nb[26]^cur[27]
  400. sw := []byte{nb[3], nb[11], nb[19], nb[27]} //sw = subword
  401. for i := 0; i < 4; i++ {
  402. upper, lower := splitBytes(sw[i])
  403. sw[i] = sbox[upper][lower]
  404. }
  405. nb[4], nb[12], nb[20], nb[28] = sw[0]^cur[4], sw[1]^cur[12], sw[2]^cur[20], sw[3]^cur[28]
  406. nb[5], nb[13], nb[21], nb[29] = nb[4]^cur[5], nb[12]^cur[13], nb[20]^cur[21], nb[28]^cur[29]
  407. nb[6], nb[14], nb[22], nb[30] = nb[5]^cur[6], nb[13]^cur[14], nb[21]^cur[22], nb[29]^cur[30]
  408. nb[7], nb[15], nb[23], nb[31] = nb[6]^cur[7], nb[14]^cur[15], nb[22]^cur[23], nb[30]^cur[31]
  409. keyexpanded = append(keyexpanded, nb)
  410. return nb
  411. }
  412. func splitBytes(b byte) (byte, byte) {
  413. return b >> 4, b & 0x0f
  414. }
  415. func subBytes(cur Block) Block {
  416. for i := 0; i < 16; i++ {
  417. upper, lower := splitBytes(cur[i])
  418. cur[i] = sbox[upper][lower]
  419. }
  420. return cur
  421. }
  422. func invSubBytes(cur Block) Block {
  423. for i := 0; i < 16; i++ {
  424. upper, lower := splitBytes(cur[i])
  425. cur[i] = invSbox[upper][lower]
  426. }
  427. return cur
  428. }
  429. func xtime(cur byte) []byte {
  430. var bytes []byte
  431. bytes = append(bytes, cur)
  432. for i := 1; i < 8; i++ { // first iteration done outside of for-loop
  433. if (cur >> 7) == 1 {
  434. cur = cur << 1
  435. cur = cur ^ 0x1b
  436. } else {
  437. cur = cur << 1
  438. }
  439. bytes = append(bytes, cur)
  440. }
  441. return bytes
  442. }
  443. func ffmult(cur []byte, multiplier byte) byte {
  444. if multiplier == 1 {
  445. return cur[0]
  446. } else if multiplier == 2 {
  447. return cur[1]
  448. } else if multiplier == 3 {
  449. return cur[0] ^ cur[1]
  450. } else if multiplier == 9 {
  451. return cur[0] ^ cur[3]
  452. } else if multiplier == 11 {
  453. return cur[0] ^ cur[1] ^ cur[3]
  454. } else if multiplier == 13 {
  455. return cur[0] ^ cur[2] ^ cur[3]
  456. } else if multiplier == 14 {
  457. return cur[1] ^ cur[2] ^ cur[3]
  458. }
  459. return 0
  460. }
  461. func mixColumnsAssist(cur []byte) []byte {
  462. a1 := ffmult(xtime(cur[0]), mm[0]) ^ ffmult(xtime(cur[1]), mm[1]) ^ ffmult(xtime(cur[2]), mm[2]) ^ ffmult(xtime(cur[3]), mm[3])
  463. a2 := ffmult(xtime(cur[0]), mm[4]) ^ ffmult(xtime(cur[1]), mm[5]) ^ ffmult(xtime(cur[2]), mm[6]) ^ ffmult(xtime(cur[3]), mm[7])
  464. a3 := ffmult(xtime(cur[0]), mm[8]) ^ ffmult(xtime(cur[1]), mm[9]) ^ ffmult(xtime(cur[2]), mm[10]) ^ ffmult(xtime(cur[3]), mm[11])
  465. a4 := ffmult(xtime(cur[0]), mm[12]) ^ ffmult(xtime(cur[1]), mm[13]) ^ ffmult(xtime(cur[2]), mm[14]) ^ ffmult(xtime(cur[3]), mm[15])
  466. return []byte{a1, a2, a3, a4}
  467. }
  468. func mixColumns(cur Block) Block {
  469. col1 := []byte{cur[0], cur[4], cur[8], cur[12]}
  470. col2 := []byte{cur[1], cur[5], cur[9], cur[13]}
  471. col3 := []byte{cur[2], cur[6], cur[10], cur[14]}
  472. col4 := []byte{cur[3], cur[7], cur[11], cur[15]}
  473. col1 = mixColumnsAssist(col1)
  474. col2 = mixColumnsAssist(col2)
  475. col3 = mixColumnsAssist(col3)
  476. col4 = mixColumnsAssist(col4)
  477. cur = Block{
  478. col1[0], col2[0], col3[0], col4[0],
  479. col1[1], col2[1], col3[1], col4[1],
  480. col1[2], col2[2], col3[2], col4[2],
  481. col1[3], col2[3], col3[3], col4[3],
  482. }
  483. return cur
  484. }
  485. func invMixColumns(cur Block) Block {
  486. col1 := []byte{cur[0], cur[4], cur[8], cur[12]}
  487. col2 := []byte{cur[1], cur[5], cur[9], cur[13]}
  488. col3 := []byte{cur[2], cur[6], cur[10], cur[14]}
  489. col4 := []byte{cur[3], cur[7], cur[11], cur[15]}
  490. col1 = invMixColumnsAssist(col1)
  491. col2 = invMixColumnsAssist(col2)
  492. col3 = invMixColumnsAssist(col3)
  493. col4 = invMixColumnsAssist(col4)
  494. cur = Block{
  495. col1[0], col2[0], col3[0], col4[0],
  496. col1[1], col2[1], col3[1], col4[1],
  497. col1[2], col2[2], col3[2], col4[2],
  498. col1[3], col2[3], col3[3], col4[3],
  499. }
  500. return cur
  501. }
  502. func invMixColumnsAssist(cur []byte) []byte {
  503. a1 := ffmult(xtime(cur[0]), iMM[0]) ^ ffmult(xtime(cur[1]), iMM[1]) ^ ffmult(xtime(cur[2]), iMM[2]) ^ ffmult(xtime(cur[3]), iMM[3])
  504. a2 := ffmult(xtime(cur[0]), iMM[4]) ^ ffmult(xtime(cur[1]), iMM[5]) ^ ffmult(xtime(cur[2]), iMM[6]) ^ ffmult(xtime(cur[3]), iMM[7])
  505. a3 := ffmult(xtime(cur[0]), iMM[8]) ^ ffmult(xtime(cur[1]), iMM[9]) ^ ffmult(xtime(cur[2]), iMM[10]) ^ ffmult(xtime(cur[3]), iMM[11])
  506. a4 := ffmult(xtime(cur[0]), iMM[12]) ^ ffmult(xtime(cur[1]), iMM[13]) ^ ffmult(xtime(cur[2]), iMM[14]) ^ ffmult(xtime(cur[3]), iMM[15])
  507. return []byte{a1, a2, a3, a4}
  508. }
  509. func shiftRows(cur Block) Block {
  510. cur[4], cur[5], cur[6], cur[7] = cur[5], cur[6], cur[7], cur[4]
  511. cur[8], cur[9], cur[10], cur[11] = cur[10], cur[11], cur[8], cur[9]
  512. cur[12], cur[13], cur[14], cur[15] = cur[15], cur[12], cur[13], cur[14]
  513. return cur
  514. }
  515. func invShiftRows(cur Block) Block {
  516. cur[4], cur[5], cur[6], cur[7] = cur[7], cur[4], cur[5], cur[6]
  517. cur[8], cur[9], cur[10], cur[11] = cur[10], cur[11], cur[8], cur[9]
  518. cur[12], cur[13], cur[14], cur[15] = cur[13], cur[14], cur[15], cur[12]
  519. return cur
  520. }