1use crate::util::subarray_copy;
2
3pub(crate) const AES_BLOCK_SIZE: usize = 16;
4
5const ROUND_KEY_SIZE: usize = 16;
7
8const NUM_AES_ROUND_KEYS: usize = 10;
13
14pub(crate) const CN_AES_KEY_SIZE: usize = 32;
17
18#[rustfmt::skip]
19const AES_SBOX: [[u8; 16]; 16] = [
20 [0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76],
21 [0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0],
22 [0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15],
23 [0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75],
24 [0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84],
25 [0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf],
26 [0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8],
27 [0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2],
28 [0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73],
29 [0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb],
30 [0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79],
31 [0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08],
32 [0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a],
33 [0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e],
34 [0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf],
35 [0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16]
36];
37
38#[rustfmt::skip]
43const CRYPTONIGHT_SBOX: [u32; 1024] = [
44 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591,
45 0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56, 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec,
46 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb,
47 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b,
48 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83,
49 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a,
50 0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f,
51 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea,
52 0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b,
53 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413,
54 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6,
55 0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85,
56 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511,
57 0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe, 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b,
58 0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1,
59 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf,
60 0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e,
61 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6,
62 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b,
63 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad,
64 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, 0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8,
65 0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2,
66 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949,
67 0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810,
68 0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697,
69 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f,
70 0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c,
71 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27,
72 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433,
73 0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5,
74 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0,
75 0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c,
76 0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, 0xf2f2ff0d, 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154,
77 0x30306050, 0x01010203, 0x6767cea9, 0x2b2b567d, 0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a,
78 0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87, 0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b,
79 0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, 0x9c9c23bf, 0xa4a453f7, 0x7272e496, 0xc0c09b5b,
80 0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a, 0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f,
81 0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908, 0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f,
82 0x0404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e, 0x18183028, 0x969637a1, 0x05050a0f, 0x9a9a2fb5,
83 0x07070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d, 0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f,
84 0x0909121b, 0x83831d9e, 0x2c2c5874, 0x1a1a342e, 0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb,
85 0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce, 0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397,
86 0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c, 0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed,
87 0x6a6ad4be, 0xcbcb8d46, 0xbebe67d9, 0x3939724b, 0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a,
88 0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16, 0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194,
89 0x45458acf, 0xf9f9e910, 0x02020406, 0x7f7ffe81, 0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3,
90 0x5151a2f3, 0xa3a35dfe, 0x404080c0, 0x8f8f058a, 0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104,
91 0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263, 0x10102030, 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d,
92 0xcdcd814c, 0x0c0c1814, 0x13132635, 0xececc32f, 0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39,
93 0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47, 0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695,
94 0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f, 0x22224466, 0x2a2a547e, 0x90903bab, 0x88880b83,
95 0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c, 0xdedea779, 0x5e5ebce2, 0x0b0b161d, 0xdbdbad76,
96 0xe0e0db3b, 0x32326456, 0x3a3a744e, 0x0a0a141e, 0x494992db, 0x06060c0a, 0x2424486c, 0x5c5cb8e4,
97 0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6, 0x919139a8, 0x959531a4, 0xe4e4d337, 0x7979f28b,
98 0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7, 0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0,
99 0x6c6cd8b4, 0x5656acfa, 0xf4f4f307, 0xeaeacf25, 0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x08081018,
100 0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72, 0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751,
101 0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21, 0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85,
102 0x7070e090, 0x3e3e7c42, 0xb5b571c4, 0x6666ccaa, 0x484890d8, 0x03030605, 0xf6f6f701, 0x0e0e1c12,
103 0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0, 0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9,
104 0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233, 0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7,
105 0x9b9b2db6, 0x1e1e3c22, 0x87871592, 0xe9e9c920, 0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a,
106 0x8c8c038f, 0xa1a159f8, 0x89890980, 0x0d0d1a17, 0xbfbf65da, 0xe6e6d731, 0x424284c6, 0x6868d0b8,
107 0x414182c3, 0x999929b0, 0x2d2d5a77, 0x0f0f1e11, 0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a,
108 0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, 0xf2ff0df2, 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5,
109 0x30605030, 0x01020301, 0x67cea967, 0x2b567d2b, 0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76,
110 0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d, 0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0,
111 0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, 0x9c23bf9c, 0xa453f7a4, 0x72e49672, 0xc09b5bc0,
112 0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26, 0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc,
113 0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1, 0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15,
114 0x04080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3, 0x18302818, 0x9637a196, 0x050a0f05, 0x9a2fb59a,
115 0x070e0907, 0x12243612, 0x801b9b80, 0xe2df3de2, 0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75,
116 0x09121b09, 0x831d9e83, 0x2c58742c, 0x1a342e1a, 0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0,
117 0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3, 0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784,
118 0x53a6f553, 0xd1b968d1, 0x00000000, 0xedc12ced, 0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b,
119 0x6ad4be6a, 0xcb8d46cb, 0xbe67d9be, 0x39724b39, 0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf,
120 0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb, 0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485,
121 0x458acf45, 0xf9e910f9, 0x02040602, 0x7ffe817f, 0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8,
122 0x51a2f351, 0xa35dfea3, 0x4080c040, 0x8f058a8f, 0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5,
123 0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321, 0x10203010, 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2,
124 0xcd814ccd, 0x0c18140c, 0x13263513, 0xecc32fec, 0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917,
125 0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d, 0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573,
126 0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc, 0x22446622, 0x2a547e2a, 0x903bab90, 0x880b8388,
127 0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14, 0xdea779de, 0x5ebce25e, 0x0b161d0b, 0xdbad76db,
128 0xe0db3be0, 0x32645632, 0x3a744e3a, 0x0a141e0a, 0x4992db49, 0x060c0a06, 0x24486c24, 0x5cb8e45c,
129 0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662, 0x9139a891, 0x9531a495, 0xe4d337e4, 0x79f28b79,
130 0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d, 0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9,
131 0x6cd8b46c, 0x56acfa56, 0xf4f307f4, 0xeacf25ea, 0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x08101808,
132 0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e, 0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6,
133 0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f, 0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a,
134 0x70e09070, 0x3e7c423e, 0xb571c4b5, 0x66ccaa66, 0x4890d848, 0x03060503, 0xf6f701f6, 0x0e1c120e,
135 0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9, 0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e,
136 0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311, 0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794,
137 0x9b2db69b, 0x1e3c221e, 0x87159287, 0xe9c920e9, 0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf,
138 0x8c038f8c, 0xa159f8a1, 0x89098089, 0x0d1a170d, 0xbf65dabf, 0xe6d731e6, 0x4284c642, 0x68d0b868,
139 0x4182c341, 0x9929b099, 0x2d5a772d, 0x0f1e110f, 0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16,
140 0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, 0xff0df2f2, 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5,
141 0x60503030, 0x02030101, 0xcea96767, 0x567d2b2b, 0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676,
142 0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d, 0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0,
143 0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, 0x23bf9c9c, 0x53f7a4a4, 0xe4967272, 0x9b5bc0c0,
144 0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626, 0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc,
145 0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1, 0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515,
146 0x080c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3, 0x30281818, 0x37a19696, 0x0a0f0505, 0x2fb59a9a,
147 0x0e090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2, 0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575,
148 0x121b0909, 0x1d9e8383, 0x58742c2c, 0x342e1a1a, 0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0,
149 0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3, 0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484,
150 0xa6f55353, 0xb968d1d1, 0x00000000, 0xc12ceded, 0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b,
151 0xd4be6a6a, 0x8d46cbcb, 0x67d9bebe, 0x724b3939, 0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf,
152 0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb, 0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585,
153 0x8acf4545, 0xe910f9f9, 0x04060202, 0xfe817f7f, 0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8,
154 0xa2f35151, 0x5dfea3a3, 0x80c04040, 0x058a8f8f, 0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5,
155 0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121, 0x20301010, 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2,
156 0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec, 0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717,
157 0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d, 0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373,
158 0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc, 0x44662222, 0x547e2a2a, 0x3bab9090, 0x0b838888,
159 0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414, 0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb,
160 0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a, 0x92db4949, 0x0c0a0606, 0x486c2424, 0xb8e45c5c,
161 0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262, 0x39a89191, 0x31a49595, 0xd337e4e4, 0xf28b7979,
162 0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d, 0x018c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9,
163 0xd8b46c6c, 0xacfa5656, 0xf307f4f4, 0xcf25eaea, 0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808,
164 0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e, 0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6,
165 0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f, 0x96dd4b4b, 0x61dcbdbd, 0x0d868b8b, 0x0f858a8a,
166 0xe0907070, 0x7c423e3e, 0x71c4b5b5, 0xccaa6666, 0x90d84848, 0x06050303, 0xf701f6f6, 0x1c120e0e,
167 0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9, 0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e,
168 0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111, 0xd2bb6969, 0xa970d9d9, 0x07898e8e, 0x33a79494,
169 0x2db69b9b, 0x3c221e1e, 0x15928787, 0xc920e9e9, 0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf,
170 0x038f8c8c, 0x59f8a1a1, 0x09808989, 0x1a170d0d, 0x65dabfbf, 0xd731e6e6, 0x84c64242, 0xd0b86868,
171 0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f, 0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616,
172];
173
174const fn substitute_word(word: u32) -> u32 {
175 let wb: [u8; 4] = word.to_le_bytes();
176 u32::from_le_bytes([
177 AES_SBOX[(wb[0] >> 4) as usize][(wb[0] & 0x0F) as usize],
178 AES_SBOX[(wb[1] >> 4) as usize][(wb[1] & 0x0F) as usize],
179 AES_SBOX[(wb[2] >> 4) as usize][(wb[2] & 0x0F) as usize],
180 AES_SBOX[(wb[3] >> 4) as usize][(wb[3] & 0x0F) as usize],
181 ])
182}
183
184#[expect(clippy::cast_possible_truncation)]
188pub(crate) fn key_extend(key_bytes: &[u8; CN_AES_KEY_SIZE]) -> [u128; NUM_AES_ROUND_KEYS] {
189 const NK: usize = 8;
192 let mut expanded_key = [0_u128; NUM_AES_ROUND_KEYS];
193
194 expanded_key[0] = u128::from_le_bytes(subarray_copy(key_bytes, 0));
197 expanded_key[1] = u128::from_le_bytes(subarray_copy(key_bytes, ROUND_KEY_SIZE));
198
199 const ROUND_CONSTS: [u8; 11] = [
202 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36,
203 ];
204
205 let mut w0_prev = (expanded_key[1] >> 96) as u32;
207
208 for i in 2..NUM_AES_ROUND_KEYS {
210 let word_num = i * 4;
211
212 let mut w0 = if i & 1 == 0 {
215 substitute_word(w0_prev.rotate_right(8)) ^ u32::from(ROUND_CONSTS[word_num / NK])
216 } else {
217 substitute_word(w0_prev)
218 };
219
220 let pprev_key = expanded_key[i - 2];
221
222 w0 ^= pprev_key as u32;
223 let w1 = w0 ^ ((pprev_key >> 32) as u32);
224 let w2 = w1 ^ ((pprev_key >> 64) as u32);
225 let w3 = w2 ^ ((pprev_key >> 96) as u32);
226
227 expanded_key[i] = u128::from(w0)
228 | (u128::from(w1) << 32)
229 | (u128::from(w2) << 64)
230 | (u128::from(w3) << 96);
231
232 w0_prev = w3;
233 }
234
235 expanded_key
236}
237
238#[expect(clippy::cast_possible_truncation)]
239pub(crate) fn round_fwd(state: u128, key: u128) -> u128 {
240 let mut r1 = CRYPTONIGHT_SBOX[usize::from(state as u8)];
241 r1 ^= CRYPTONIGHT_SBOX[256 + usize::from((state >> 40) as u8)];
242 r1 ^= CRYPTONIGHT_SBOX[512 + usize::from((state >> 80) as u8)];
243 r1 ^= CRYPTONIGHT_SBOX[768 + usize::from((state >> 120) as u8)];
244
245 let mut r2 = CRYPTONIGHT_SBOX[usize::from((state >> 32) as u8)];
246 r2 ^= CRYPTONIGHT_SBOX[256 + usize::from((state >> 72) as u8)];
247 r2 ^= CRYPTONIGHT_SBOX[512 + usize::from((state >> 112) as u8)];
248 r2 ^= CRYPTONIGHT_SBOX[768 + usize::from((state >> 24) as u8)];
249
250 let mut r3 = CRYPTONIGHT_SBOX[usize::from((state >> 64) as u8)];
251 r3 ^= CRYPTONIGHT_SBOX[256 + usize::from((state >> 104) as u8)];
252 r3 ^= CRYPTONIGHT_SBOX[512 + usize::from((state >> 16) as u8)];
253 r3 ^= CRYPTONIGHT_SBOX[768 + usize::from((state >> 56) as u8)];
254
255 let mut r4 = CRYPTONIGHT_SBOX[usize::from((state >> 96) as u8)];
256 r4 ^= CRYPTONIGHT_SBOX[256 + usize::from((state >> 8) as u8)];
257 r4 ^= CRYPTONIGHT_SBOX[512 + usize::from((state >> 48) as u8)];
258 r4 ^= CRYPTONIGHT_SBOX[768 + usize::from((state >> 88) as u8)];
259
260 let mut new_state =
261 (u128::from(r4) << 96) | (u128::from(r3) << 64) | (u128::from(r2) << 32) | u128::from(r1);
262 new_state ^= key;
263 new_state
264}
265
266pub(crate) fn aesb_pseudo_round(block: u128, expanded_key: &[u128; NUM_AES_ROUND_KEYS]) -> u128 {
267 let mut block = block;
268 for round_key in expanded_key {
269 block = round_fwd(block, *round_key);
270 }
271
272 block
273}
274
275pub(crate) fn aesb_single_round(block: &mut u128, round_key: u128) {
276 *block = round_fwd(*block, round_key);
277}
278
279#[cfg(test)]
280mod tests {
281 use super::*;
282 use crate::util::hex_to_array;
283
284 #[test]
285 fn test_substitute_word() {
286 assert_eq!(substitute_word(0x12345678), 3373838780);
287 assert_eq!(substitute_word(0x00000000), 1667457891);
288 assert_eq!(substitute_word(0xFFFFFFFF), 370546198);
289 assert_eq!(substitute_word(0xAAAAAAAA), 2896997548);
290 assert_eq!(substitute_word(0x55555555), 4244438268);
291 }
292
293 #[test]
294 fn test_key_schedule() {
295 fn test(key_hex: &str, expected_out: &str) {
296 let key = hex_to_array(key_hex);
297 let expanded_key = key_extend(&key);
298 let expanded_key_hex = expanded_key
299 .iter()
300 .map(|value| hex::encode(value.to_le_bytes()))
301 .collect::<String>();
302 assert_eq!(expected_out[..64], expanded_key_hex[..64]);
303 assert_eq!(expected_out[64..], expanded_key_hex[64..]);
304 }
305
306 test(
307 "ac156e17cdabc0b92e3e724a06ef21e5317eb71fbc7f1587403b30ae6962a21a",
308 "ac156e17cdabc0b92e3e724a06ef21e5317eb71fbc7f1587403b30ae6962a21a072fcceeca840c57e4ba7e1de2555ff8a982785e15fd6dd955c65d773ca4ff6d4c39f00586bdfc526207824f8052ddb76482b9f7717fd42e24b98959181d7634ec01e8a86abc14fa08bb96b588e94b02a09c0a80d1e3deaef55a57f7ed4721c344fcc6fd2e40d20726fb44b2ae120fb044557c6795b6a2c960ecf53e8dabd4fd",
309 );
310 test(
311 "688dcc56a1c9b8c9cd9e378a98a1388f17a2c05a698a37232ecd4a567dccdf79",
312 "688dcc56a1c9b8c9cd9e378a98a1388f17a2c05a698a37232ecd4a567dccdf7922137aa983dac2604e44f5ead6e5cd65e17b7d1788f14a34a63c0062dbf0df1bac8dd5102f5717706113e29ab7f62fff48396801c0c8223566f42257bd04fd4c5ad9fc6a758eeb1a149d0980a36b267f42469fd3828ebde6e47a9fb1597e62fda173a8a1d4fd43bbc0604a3b630b6c44b96dcfc83be3722edf99ed9f86e78f62",
313 );
314 test(
315 "a6116fc295f15ff03d538581a560a9c1fdaa1e7f5745d8e6125d6eb092c71b15",
316 "a6116fc295f15ff03d538581a560a9c1fdaa1e7f5745d8e6125d6eb092c71b1561be368df44f697dc91cecfc6c7c453dadba7058faffa8bee8a2c60e7a65dd1b2e7f9957da30f02a132c1cd67f5059eb7fe9bbb18516130f6db4d50117d1081a144f3ba7ce7fcb8ddd53d75ba2038eb04592a256c084b159ad306458bae16c42e41f17532a60dcdef7330b8555308535b99635c079128499d422e0c16ec38c83",
317 );
318 test(
319 "80784e1c1d3730e6f422aae6b10596ab16b190e41eea452af9aeedc97aee4b74",
320 "80784e1c1d3730e6f422aae6b10596ab16b190e41eea452af9aeedc97aee4b74a9cbdcc6b4fcec2040de46c6f1dbd06db708e0d8a9e2a5f2504c483b2aa2034f91b05823254cb4036592f2c5944922a89533731a3cd1d6e86c9d9ed3463f9d9ce0ee8679c5a2327aa030c0bf3479e2178d85ebeab1543d02ddc9a3d19bf63e4daa5c656d6ffe5717cfce97a8fbb775bf822c76e233784be0eeb1e8317547d67c",
321 );
322 test(
323 "cc08712809fd4c0f0b63dc21657f22b3752fba8f2ed5882e7d75e65906bb3399",
324 "cc08712809fd4c0f0b63dc21657f22b3752fba8f2ed5882e7d75e65906bb339927cb9f472e36d34825550f69402a2dda7cca62d8521feaf62f6a0caf29d13f361bbe9ae2358849aa10dd46c350f76b192fa21d0c7dbdf7fa52d7fb557b06c46370a261c3452a286955f76eaa050005b344c17661397c819b6bab7ace10adbeaded0cf409a826dc60fdd1b2caf8d1b77905ffdfd73c835e4c5728248247859a2f",
325 );
326 }
327
328 #[test]
329 fn test_aesb_pseudo_round() {
330 fn test(key_hex: &str, input_hex: &str, expected_out: &str) {
331 let key: [u8; 32] = hex_to_array(key_hex);
332 let extended_key = key_extend(&key);
333 let mut block = u128::from_le_bytes(hex_to_array(input_hex));
334
335 block = aesb_pseudo_round(block, &extended_key);
336 assert_eq!(expected_out, hex::encode(block.to_le_bytes()));
337 }
338
339 test(
340 "1d0b47a047340e32cbe890ca0d61720a09bcfb39e01b7541d1100d1ef91f955f",
341 "274fe9eeb2d1e4c71f0f0244a80e93a1",
342 "be98612d6b05a6cd72df39326180066a",
343 );
344 test(
345 "0093d86fe74698f7b02774e6d4f67e9e29eb71d1754804a19b77d986b8141434",
346 "110f2e5d81f73a512ec95aa5b8e0d7be",
347 "1f1750d997704943b828df66661f7cbf",
348 );
349 test(
350 "d5044939d15af565447ef76445405cd899f81c6f41f4493a5a1323712f815e53",
351 "6022f491b67e27909f74d0e71becebaa",
352 "9f75d250681954d60e418b4333d247a5",
353 );
354 test(
355 "256670ed9eba1db67e6ddec5dfb78f6bfbf55d0f74e2a46d06f2e3592a208014",
356 "4de6ecad6a885ac88f09f9b2be4145fb",
357 "cb286e70825609cb97b7c7ae72548fa9",
358 );
359 test(
360 "e1077c3566d1e8bfeb2e8e48540ed76fb61e973f4951a821c3e8bb918facc03d",
361 "2a2ff0dd38c79ab13fb6b06751824e93",
362 "82f65ba66f8fc6d8e1f4e1f41976eed8",
363 );
364 test(
365 "dee818b6a894121e5e967e2218bb8772b9486bec2241377fdcfed7db75f3b724",
366 "eebc705f33d00fdf7c8add2481c62767",
367 "bee070b25e969ea87578daa1c7831651",
368 );
369 test(
370 "c9b653644f3d3adc3498c029a1373b63f548e853deadc48e559b1a0a05e5c543",
371 "bef0968fc6adb8ce96bfa99642481624",
372 "859fc5f637ee1ee835b6f9a3f16a41f8",
373 );
374 test(
375 "8e65798ebbae347c969ef9778e04e06649e3765aa58f5cd776b6ee58afde98ff",
376 "629f87e95b67e7bd5a3af528379cbef7",
377 "04a697b4fb82466950e9c0668e8c3eb9",
378 );
379 test(
380 "4c0f6a402316b3a73e2a778f20ca3f8335e7a7bb5aecdaf9db91664604b74d62",
381 "3c9ab665451100d8d21029f96edf85f3",
382 "de5e23b1ba21a16ac01098937b26f3a9",
383 );
384 test(
385 "a0b2cb30088b6145d9651ed019b0d051e4e6bf6cc0c8165dc76e3aa9fa9849f0",
386 "6a007f218c3f8b97c8489fe56433c99a",
387 "1885d448a81b0a048cc241275b9d7dce",
388 );
389 }
390
391 #[test]
392 fn test_aesb_single_round() {
393 let test = |key_hex: &str, input_hex: &str, expected_out: &str| {
394 let round_key = u128::from_ne_bytes(hex_to_array(key_hex));
396 let mut block = u128::from_ne_bytes(hex_to_array(input_hex));
397
398 aesb_single_round(&mut block, round_key);
399 assert_eq!(expected_out, hex::encode(block.to_ne_bytes()));
400 };
401
402 test(
403 "9af7bd044f96bba5251ebd8065f4c757",
404 "8844d7f6f6aa2df5706ef0e7b26a3410",
405 "a03593fc2b9b906069bfc3a86a12e7fe",
406 );
407 test(
408 "9749a59d1ee692c3b70b9c38a0c88369",
409 "f96b5a1984f7c57b92d7b2e82dd0ce46",
410 "6b03d4c6edf7a914265ca765b784c5ee",
411 );
412 test(
413 "20959275e137a08267e35afe66f9adeb",
414 "3fce6f546d8fbc15bd9c6ac7d533eae4",
415 "34692b49471e37df3cbe43a9459ebe97",
416 );
417 test(
418 "5c429524d022dc5dd48f7cd529fdf4f2",
419 "3edae93308c9aab4dfb6bfcd8e4012af",
420 "2e3061ce680d75177bac5b7af3182543",
421 );
422 test(
423 "e76c56ca69a7309866a730e8976da086",
424 "39d8ee732a115b6b21f89ca181bd9ddc",
425 "069ef0b7aaada2b65ea9665827dae9ae",
426 );
427 test(
428 "afd540af324c4fcda6246c657424a3ce",
429 "a5a01d75141522ff1ea717083abc5b5e",
430 "e0320cbc9dd8279c5f7d121ef7e1ae46",
431 );
432 test(
433 "dfe9ba9468ccf1ac20a305730d1bdcb7",
434 "7be56ce9d924bf2fc4b574e225676f3c",
435 "bee2b49ed0b578b2c94b03a8930d990c",
436 );
437 test(
438 "381e788a8d3389f27fe9aff054a0b407",
439 "b8d2600f71b0e9535d17c00ba90246f6",
440 "2a305ae7f7f3f44a43cd0342180b9394",
441 );
442 test(
443 "16a94460158a5512052626f6cb080d6d",
444 "5ea0c238c05b8f3a913c1b36102eabeb",
445 "ab8040d7395cc940ea2a47610989ceb1",
446 );
447 test(
448 "7e584682efb38bf2adfc6f1958fe08ff",
449 "80c78bb6ca2f114cbcb49fbaadaee9d1",
450 "25f7717cdbaa9c614424ef3d4e9543ec",
451 );
452 }
453}