AES加密的C语言实现
摘自网上一种AES加密,用C语言实现通过32字节密钥对16字节长度数据进行加密。
1 #include <string.h> 2 #include <stdio.h> 3 #ifndef uint8 4 #define uint8 unsigned char 5 #endif 6 #ifndef uint32 7 #define uint32 unsigned long int 8 #endif 9 typedef struct 10 { 11 uint32 erk[64]; /* encryption round keys */ 12 uint32 drk[64]; /* decryption round keys */ 13 int nr; /* number of rounds */ 14 } 15 aes_context; 16 //#define TEST 17 18 /* uncomment the following line to use pre-computed tables */ 19 /* otherwise the tables will be generated at the first run */ 20 21 /* #define FIXED_TABLES */ 22 23 #ifndef FIXED_TABLES 24 25 /* forward S-box & tables */ 26 27 uint32 FSb[256]; 28 uint32 FT0[256]; 29 uint32 FT1[256]; 30 uint32 FT2[256]; 31 uint32 FT3[256]; 32 33 /* reverse S-box & tables */ 34 35 uint32 RSb[256]; 36 uint32 RT0[256]; 37 uint32 RT1[256]; 38 uint32 RT2[256]; 39 uint32 RT3[256]; 40 41 /* round constants */ 42 43 uint32 RCON[10]; 44 45 /* tables generation flag */ 46 47 int do_init = 1; 48 49 /* tables generation routine */ 50 51 #define ROTR8(x) ( ( ( x << 24 ) & 0xFFFFFFFF ) | \ 52 ((x & 0xFFFFFFFF) >> 8)) 53 54 #define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) ) 55 #define MUL(x,y) ( ( x && y ) ? pow[(log[x] + log[y]) % 255] : 0 ) 56 57 void aes_gen_tables(void) 58 { 59 int i; 60 uint8 x, y; 61 uint8 pow[256]; 62 uint8 log[256]; 63 64 /* compute pow and log tables over GF(2^8) */ 65 66 for (i = 0, x = 1; i < 256; i++, x ^= XTIME(x)) 67 { 68 pow[i] = x; 69 log[x] = i; 70 } 71 72 /* calculate the round constants */ 73 74 for (i = 0, x = 1; i < 10; i++, x = XTIME(x)) 75 { 76 RCON[i] = (uint32)x << 24; 77 } 78 79 /* generate the forward and reverse S-boxes */ 80 81 FSb[0x00] = 0x63; 82 RSb[0x63] = 0x00; 83 84 for (i = 1; i < 256; i++) 85 { 86 x = pow[255 - log[i]]; 87 88 y = x; y = (y << 1) | (y >> 7); 89 x ^= y; y = (y << 1) | (y >> 7); 90 x ^= y; y = (y << 1) | (y >> 7); 91 x ^= y; y = (y << 1) | (y >> 7); 92 x ^= y ^ 0x63; 93 94 FSb[i] = x; 95 RSb[x] = i; 96 } 97 98 /* generate the forward and reverse tables */ 99 100 for (i = 0; i < 256; i++) 101 { 102 x = (unsigned char)FSb[i]; y = XTIME(x); 103 104 FT0[i] = (uint32)(x ^ y) ^ 105 ((uint32)x << 8) ^ 106 ((uint32)x << 16) ^ 107 ((uint32)y << 24); 108 109 FT0[i] &= 0xFFFFFFFF; 110 111 FT1[i] = ROTR8(FT0[i]); 112 FT2[i] = ROTR8(FT1[i]); 113 FT3[i] = ROTR8(FT2[i]); 114 115 y = (unsigned char)RSb[i]; 116 117 RT0[i] = ((uint32)MUL(0x0B, y)) ^ 118 ((uint32)MUL(0x0D, y) << 8) ^ 119 ((uint32)MUL(0x09, y) << 16) ^ 120 ((uint32)MUL(0x0E, y) << 24); 121 122 RT0[i] &= 0xFFFFFFFF; 123 124 RT1[i] = ROTR8(RT0[i]); 125 RT2[i] = ROTR8(RT1[i]); 126 RT3[i] = ROTR8(RT2[i]); 127 } 128 } 129 130 #else 131 132 /* forward S-box */ 133 134 static const uint32 FSb[256] = 135 { 136 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 137 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 138 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 139 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 140 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 141 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 142 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 143 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, 144 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 145 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 146 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 147 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 148 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 149 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, 150 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 151 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 152 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 153 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, 154 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 155 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, 156 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 157 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 158 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 159 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, 160 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 161 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 162 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 163 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 164 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 165 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, 166 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 167 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 168 }; 169 170 /* forward tables */ 171 172 #define FT \ 173 \ 174 V(C6, 63, 63, A5), V(F8, 7C, 7C, 84), V(EE, 77, 77, 99), V(F6, 7B, 7B, 8D), \ 175 V(FF, F2, F2, 0D), V(D6, 6B, 6B, BD), V(DE, 6F, 6F, B1), V(91, C5, C5, 54), \ 176 V(60, 30, 30, 50), V(02, 01, 01, 03), V(CE, 67, 67, A9), V(56, 2B, 2B, 7D), \ 177 V(E7, FE, FE, 19), V(B5, D7, D7, 62), V(4D, AB, AB, E6), V(EC, 76, 76, 9A), \ 178 V(8F, CA, CA, 45), V(1F, 82, 82, 9D), V(89, C9, C9, 40), V(FA, 7D, 7D, 87), \ 179 V(EF, FA, FA, 15), V(B2, 59, 59, EB), V(8E, 47, 47, C9), V(FB, F0, F0, 0B), \ 180 V(41, AD, AD, EC), V(B3, D4, D4, 67), V(5F, A2, A2, FD), V(45, AF, AF, EA), \ 181 V(23, 9C, 9C, BF), V(53, A4, A4, F7), V(E4, 72, 72, 96), V(9B, C0, C0, 5B), \ 182 V(75, B7, B7, C2), V(E1, FD, FD, 1C), V(3D, 93, 93, AE), V(4C, 26, 26, 6A), \ 183 V(6C, 36, 36, 5A), V(7E, 3F, 3F, 41), V(F5, F7, F7, 02), V(83, CC, CC, 4F), \ 184 V(68, 34, 34, 5C), V(51, A5, A5, F4), V(D1, E5, E5, 34), V(F9, F1, F1, 08), \ 185 V(E2, 71, 71, 93), V(AB, D8, D8, 73), V(62, 31, 31, 53), V(2A, 15, 15, 3F), \ 186 V(08, 04, 04, 0C), V(95, C7, C7, 52), V(46, 23, 23, 65), V(9D, C3, C3, 5E), \ 187 V(30, 18, 18, 28), V(37, 96, 96, A1), V(0A, 05, 05, 0F), V(2F, 9A, 9A, B5), \ 188 V(0E, 07, 07, 09), V(24, 12, 12, 36), V(1B, 80, 80, 9B), V(DF, E2, E2, 3D), \ 189 V(CD, EB, EB, 26), V(4E, 27, 27, 69), V(7F, B2, B2, CD), V(EA, 75, 75, 9F), \ 190 V(12, 09, 09, 1B), V(1D, 83, 83, 9E), V(58, 2C, 2C, 74), V(34, 1A, 1A, 2E), \ 191 V(36, 1B, 1B, 2D), V(DC, 6E, 6E, B2), V(B4, 5A, 5A, EE), V(5B, A0, A0, FB), \ 192 V(A4, 52, 52, F6), V(76, 3B, 3B, 4D), V(B7, D6, D6, 61), V(7D, B3, B3, CE), \ 193 V(52, 29, 29, 7B), V(DD, E3, E3, 3E), V(5E, 2F, 2F, 71), V(13, 84, 84, 97), \ 194 V(A6, 53, 53, F5), V(B9, D1, D1, 68), V(00, 00, 00, 00), V(C1, ED, ED, 2C), \ 195 V(40, 20, 20, 60), V(E3, FC, FC, 1F), V(79, B1, B1, C8), V(B6, 5B, 5B, ED), \ 196 V(D4, 6A, 6A, BE), V(8D, CB, CB, 46), V(67, BE, BE, D9), V(72, 39, 39, 4B), \ 197 V(94, 4A, 4A, DE), V(98, 4C, 4C, D4), V(B0, 58, 58, E8), V(85, CF, CF, 4A), \ 198 V(BB, D0, D0, 6B), V(C5, EF, EF, 2A), V(4F, AA, AA, E5), V(ED, FB, FB, 16), \ 199 V(86, 43, 43, C5), V(9A, 4D, 4D, D7), V(66, 33, 33, 55), V(11, 85, 85, 94), \ 200 V(8A, 45, 45, CF), V(E9, F9, F9, 10), V(04, 02, 02, 06), V(FE, 7F, 7F, 81), \ 201 V(A0, 50, 50, F0), V(78, 3C, 3C, 44), V(25, 9F, 9F, BA), V(4B, A8, A8, E3), \ 202 V(A2, 51, 51, F3), V(5D, A3, A3, FE), V(80, 40, 40, C0), V(05, 8F, 8F, 8A), \ 203 V(3F, 92, 92, AD), V(21, 9D, 9D, BC), V(70, 38, 38, 48), V(F1, F5, F5, 04), \ 204 V(63, BC, BC, DF), V(77, B6, B6, C1), V(AF, DA, DA, 75), V(42, 21, 21, 63), \ 205 V(20, 10, 10, 30), V(E5, FF, FF, 1A), V(FD, F3, F3, 0E), V(BF, D2, D2, 6D), \ 206 V(81, CD, CD, 4C), V(18, 0C, 0C, 14), V(26, 13, 13, 35), V(C3, EC, EC, 2F), \ 207 V(BE, 5F, 5F, E1), V(35, 97, 97, A2), V(88, 44, 44, CC), V(2E, 17, 17, 39), \ 208 V(93, C4, C4, 57), V(55, A7, A7, F2), V(FC, 7E, 7E, 82), V(7A, 3D, 3D, 47), \ 209 V(C8, 64, 64, AC), V(BA, 5D, 5D, E7), V(32, 19, 19, 2B), V(E6, 73, 73, 95), \ 210 V(C0, 60, 60, A0), V(19, 81, 81, 98), V(9E, 4F, 4F, D1), V(A3, DC, DC, 7F), \ 211 V(44, 22, 22, 66), V(54, 2A, 2A, 7E), V(3B, 90, 90, AB), V(0B, 88, 88, 83), \ 212 V(8C, 46, 46, CA), V(C7, EE, EE, 29), V(6B, B8, B8, D3), V(28, 14, 14, 3C), \ 213 V(A7, DE, DE, 79), V(BC, 5E, 5E, E2), V(16, 0B, 0B, 1D), V(AD, DB, DB, 76), \ 214 V(DB, E0, E0, 3B), V(64, 32, 32, 56), V(74, 3A, 3A, 4E), V(14, 0A, 0A, 1E), \ 215 V(92, 49, 49, DB), V(0C, 06, 06, 0A), V(48, 24, 24, 6C), V(B8, 5C, 5C, E4), \ 216 V(9F, C2, C2, 5D), V(BD, D3, D3, 6E), V(43, AC, AC, EF), V(C4, 62, 62, A6), \ 217 V(39, 91, 91, A8), V(31, 95, 95, A4), V(D3, E4, E4, 37), V(F2, 79, 79, 8B), \ 218 V(D5, E7, E7, 32), V(8B, C8, C8, 43), V(6E, 37, 37, 59), V(DA, 6D, 6D, B7), \ 219 V(01, 8D, 8D, 8C), V(B1, D5, D5, 64), V(9C, 4E, 4E, D2), V(49, A9, A9, E0), \ 220 V(D8, 6C, 6C, B4), V(AC, 56, 56, FA), V(F3, F4, F4, 07), V(CF, EA, EA, 25), \ 221 V(CA, 65, 65, AF), V(F4, 7A, 7A, 8E), V(47, AE, AE, E9), V(10, 08, 08, 18), \ 222 V(6F, BA, BA, D5), V(F0, 78, 78, 88), V(4A, 25, 25, 6F), V(5C, 2E, 2E, 72), \ 223 V(38, 1C, 1C, 24), V(57, A6, A6, F1), V(73, B4, B4, C7), V(97, C6, C6, 51), \ 224 V(CB, E8, E8, 23), V(A1, DD, DD, 7C), V(E8, 74, 74, 9C), V(3E, 1F, 1F, 21), \ 225 V(96, 4B, 4B, DD), V(61, BD, BD, DC), V(0D, 8B, 8B, 86), V(0F, 8A, 8A, 85), \ 226 V(E0, 70, 70, 90), V(7C, 3E, 3E, 42), V(71, B5, B5, C4), V(CC, 66, 66, AA), \ 227 V(90, 48, 48, D8), V(06, 03, 03, 05), V(F7, F6, F6, 01), V(1C, 0E, 0E, 12), \ 228 V(C2, 61, 61, A3), V(6A, 35, 35, 5F), V(AE, 57, 57, F9), V(69, B9, B9, D0), \ 229 V(17, 86, 86, 91), V(99, C1, C1, 58), V(3A, 1D, 1D, 27), V(27, 9E, 9E, B9), \ 230 V(D9, E1, E1, 38), V(EB, F8, F8, 13), V(2B, 98, 98, B3), V(22, 11, 11, 33), \ 231 V(D2, 69, 69, BB), V(A9, D9, D9, 70), V(07, 8E, 8E, 89), V(33, 94, 94, A7), \ 232 V(2D, 9B, 9B, B6), V(3C, 1E, 1E, 22), V(15, 87, 87, 92), V(C9, E9, E9, 20), \ 233 V(87, CE, CE, 49), V(AA, 55, 55, FF), V(50, 28, 28, 78), V(A5, DF, DF, 7A), \ 234 V(03, 8C, 8C, 8F), V(59, A1, A1, F8), V(09, 89, 89, 80), V(1A, 0D, 0D, 17), \ 235 V(65, BF, BF, DA), V(D7, E6, E6, 31), V(84, 42, 42, C6), V(D0, 68, 68, B8), \ 236 V(82, 41, 41, C3), V(29, 99, 99, B0), V(5A, 2D, 2D, 77), V(1E, 0F, 0F, 11), \ 237 V(7B, B0, B0, CB), V(A8, 54, 54, FC), V(6D, BB, BB, D6), V(2C, 16, 16, 3A) 238 239 #define V(a,b,c,d) 0x##a##b##c##d 240 static const uint32 FT0[256] = { FT }; 241 #undef V 242 243 #define V(a,b,c,d) 0x##d##a##b##c 244 static const uint32 FT1[256] = { FT }; 245 #undef V 246 247 #define V(a,b,c,d) 0x##c##d##a##b 248 static const uint32 FT2[256] = { FT }; 249 #undef V 250 251 #define V(a,b,c,d) 0x##b##c##d##a 252 static const uint32 FT3[256] = { FT }; 253 #undef V 254 255 #undef FT 256 257 /* reverse S-box */ 258 259 static const uint32 RSb[256] = 260 { 261 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 262 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, 263 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 264 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 265 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 266 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, 267 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 268 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, 269 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 270 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 271 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 272 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, 273 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 274 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, 275 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 276 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 277 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 278 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, 279 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 280 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, 281 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 282 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 283 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 284 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, 285 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 286 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, 287 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 288 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 289 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 290 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, 291 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 292 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D 293 }; 294 295 /* reverse tables */ 296 297 #define RT \ 298 \ 299 V(51, F4, A7, 50), V(7E, 41, 65, 53), V(1A, 17, A4, C3), V(3A, 27, 5E, 96), \ 300 V(3B, AB, 6B, CB), V(1F, 9D, 45, F1), V(AC, FA, 58, AB), V(4B, E3, 03, 93), \ 301 V(20, 30, FA, 55), V(AD, 76, 6D, F6), V(88, CC, 76, 91), V(F5, 02, 4C, 25), \ 302 V(4F, E5, D7, FC), V(C5, 2A, CB, D7), V(26, 35, 44, 80), V(B5, 62, A3, 8F), \ 303 V(DE, B1, 5A, 49), V(25, BA, 1B, 67), V(45, EA, 0E, 98), V(5D, FE, C0, E1), \ 304 V(C3, 2F, 75, 02), V(81, 4C, F0, 12), V(8D, 46, 97, A3), V(6B, D3, F9, C6), \ 305 V(03, 8F, 5F, E7), V(15, 92, 9C, 95), V(BF, 6D, 7A, EB), V(95, 52, 59, DA), \ 306 V(D4, BE, 83, 2D), V(58, 74, 21, D3), V(49, E0, 69, 29), V(8E, C9, C8, 44), \ 307 V(75, C2, 89, 6A), V(F4, 8E, 79, 78), V(99, 58, 3E, 6B), V(27, B9, 71, DD), \ 308 V(BE, E1, 4F, B6), V(F0, 88, AD, 17), V(C9, 20, AC, 66), V(7D, CE, 3A, B4), \ 309 V(63, DF, 4A, 18), V(E5, 1A, 31, 82), V(97, 51, 33, 60), V(62, 53, 7F, 45), \ 310 V(B1, 64, 77, E0), V(BB, 6B, AE, 84), V(FE, 81, A0, 1C), V(F9, 08, 2B, 94), \ 311 V(70, 48, 68, 58), V(8F, 45, FD, 19), V(94, DE, 6C, 87), V(52, 7B, F8, B7), \ 312 V(AB, 73, D3, 23), V(72, 4B, 02, E2), V(E3, 1F, 8F, 57), V(66, 55, AB, 2A), \ 313 V(B2, EB, 28, 07), V(2F, B5, C2, 03), V(86, C5, 7B, 9A), V(D3, 37, 08, A5), \ 314 V(30, 28, 87, F2), V(23, BF, A5, B2), V(02, 03, 6A, BA), V(ED, 16, 82, 5C), \ 315 V(8A, CF, 1C, 2B), V(A7, 79, B4, 92), V(F3, 07, F2, F0), V(4E, 69, E2, A1), \ 316 V(65, DA, F4, CD), V(06, 05, BE, D5), V(D1, 34, 62, 1F), V(C4, A6, FE, 8A), \ 317 V(34, 2E, 53, 9D), V(A2, F3, 55, A0), V(05, 8A, E1, 32), V(A4, F6, EB, 75), \ 318 V(0B, 83, EC, 39), V(40, 60, EF, AA), V(5E, 71, 9F, 06), V(BD, 6E, 10, 51), \ 319 V(3E, 21, 8A, F9), V(96, DD, 06, 3D), V(DD, 3E, 05, AE), V(4D, E6, BD, 46), \ 320 V(91, 54, 8D, B5), V(71, C4, 5D, 05), V(04, 06, D4, 6F), V(60, 50, 15, FF), \ 321 V(19, 98, FB, 24), V(D6, BD, E9, 97), V(89, 40, 43, CC), V(67, D9, 9E, 77), \ 322 V(B0, E8, 42, BD), V(07, 89, 8B, 88), V(E7, 19, 5B, 38), V(79, C8, EE, DB), \ 323 V(A1, 7C, 0A, 47), V(7C, 42, 0F, E9), V(F8, 84, 1E, C9), V(00, 00, 00, 00), \ 324 V(09, 80, 86, 83), V(32, 2B, ED, 48), V(1E, 11, 70, AC), V(6C, 5A, 72, 4E), \ 325 V(FD, 0E, FF, FB), V(0F, 85, 38, 56), V(3D, AE, D5, 1E), V(36, 2D, 39, 27), \ 326 V(0A, 0F, D9, 64), V(68, 5C, A6, 21), V(9B, 5B, 54, D1), V(24, 36, 2E, 3A), \ 327 V(0C, 0A, 67, B1), V(93, 57, E7, 0F), V(B4, EE, 96, D2), V(1B, 9B, 91, 9E), \ 328 V(80, C0, C5, 4F), V(61, DC, 20, A2), V(5A, 77, 4B, 69), V(1C, 12, 1A, 16), \ 329 V(E2, 93, BA, 0A), V(C0, A0, 2A, E5), V(3C, 22, E0, 43), V(12, 1B, 17, 1D), \ 330 V(0E, 09, 0D, 0B), V(F2, 8B, C7, AD), V(2D, B6, A8, B9), V(14, 1E, A9, C8), \ 331 V(57, F1, 19, 85), V(AF, 75, 07, 4C), V(EE, 99, DD, BB), V(A3, 7F, 60, FD), \ 332 V(F7, 01, 26, 9F), V(5C, 72, F5, BC), V(44, 66, 3B, C5), V(5B, FB, 7E, 34), \ 333 V(8B, 43, 29, 76), V(CB, 23, C6, DC), V(B6, ED, FC, 68), V(B8, E4, F1, 63), \ 334 V(D7, 31, DC, CA), V(42, 63, 85, 10), V(13, 97, 22, 40), V(84, C6, 11, 20), \ 335 V(85, 4A, 24, 7D), V(D2, BB, 3D, F8), V(AE, F9, 32, 11), V(C7, 29, A1, 6D), \ 336 V(1D, 9E, 2F, 4B), V(DC, B2, 30, F3), V(0D, 86, 52, EC), V(77, C1, E3, D0), \ 337 V(2B, B3, 16, 6C), V(A9, 70, B9, 99), V(11, 94, 48, FA), V(47, E9, 64, 22), \ 338 V(A8, FC, 8C, C4), V(A0, F0, 3F, 1A), V(56, 7D, 2C, D8), V(22, 33, 90, EF), \ 339 V(87, 49, 4E, C7), V(D9, 38, D1, C1), V(8C, CA, A2, FE), V(98, D4, 0B, 36), \ 340 V(A6, F5, 81, CF), V(A5, 7A, DE, 28), V(DA, B7, 8E, 26), V(3F, AD, BF, A4), \ 341 V(2C, 3A, 9D, E4), V(50, 78, 92, 0D), V(6A, 5F, CC, 9B), V(54, 7E, 46, 62), \ 342 V(F6, 8D, 13, C2), V(90, D8, B8, E8), V(2E, 39, F7, 5E), V(82, C3, AF, F5), \ 343 V(9F, 5D, 80, BE), V(69, D0, 93, 7C), V(6F, D5, 2D, A9), V(CF, 25, 12, B3), \ 344 V(C8, AC, 99, 3B), V(10, 18, 7D, A7), V(E8, 9C, 63, 6E), V(DB, 3B, BB, 7B), \ 345 V(CD, 26, 78, 09), V(6E, 59, 18, F4), V(EC, 9A, B7, 01), V(83, 4F, 9A, A8), \ 346 V(E6, 95, 6E, 65), V(AA, FF, E6, 7E), V(21, BC, CF, 08), V(EF, 15, E8, E6), \ 347 V(BA, E7, 9B, D9), V(4A, 6F, 36, CE), V(EA, 9F, 09, D4), V(29, B0, 7C, D6), \ 348 V(31, A4, B2, AF), V(2A, 3F, 23, 31), V(C6, A5, 94, 30), V(35, A2, 66, C0), \ 349 V(74, 4E, BC, 37), V(FC, 82, CA, A6), V(E0, 90, D0, B0), V(33, A7, D8, 15), \ 350 V(F1, 04, 98, 4A), V(41, EC, DA, F7), V(7F, CD, 50, 0E), V(17, 91, F6, 2F), \ 351 V(76, 4D, D6, 8D), V(43, EF, B0, 4D), V(CC, AA, 4D, 54), V(E4, 96, 04, DF), \ 352 V(9E, D1, B5, E3), V(4C, 6A, 88, 1B), V(C1, 2C, 1F, B8), V(46, 65, 51, 7F), \ 353 V(9D, 5E, EA, 04), V(01, 8C, 35, 5D), V(FA, 87, 74, 73), V(FB, 0B, 41, 2E), \ 354 V(B3, 67, 1D, 5A), V(92, DB, D2, 52), V(E9, 10, 56, 33), V(6D, D6, 47, 13), \ 355 V(9A, D7, 61, 8C), V(37, A1, 0C, 7A), V(59, F8, 14, 8E), V(EB, 13, 3C, 89), \ 356 V(CE, A9, 27, EE), V(B7, 61, C9, 35), V(E1, 1C, E5, ED), V(7A, 47, B1, 3C), \ 357 V(9C, D2, DF, 59), V(55, F2, 73, 3F), V(18, 14, CE, 79), V(73, C7, 37, BF), \ 358 V(53, F7, CD, EA), V(5F, FD, AA, 5B), V(DF, 3D, 6F, 14), V(78, 44, DB, 86), \ 359 V(CA, AF, F3, 81), V(B9, 68, C4, 3E), V(38, 24, 34, 2C), V(C2, A3, 40, 5F), \ 360 V(16, 1D, C3, 72), V(BC, E2, 25, 0C), V(28, 3C, 49, 8B), V(FF, 0D, 95, 41), \ 361 V(39, A8, 01, 71), V(08, 0C, B3, DE), V(D8, B4, E4, 9C), V(64, 56, C1, 90), \ 362 V(7B, CB, 84, 61), V(D5, 32, B6, 70), V(48, 6C, 5C, 74), V(D0, B8, 57, 42) 363 364 #define V(a,b,c,d) 0x##a##b##c##d 365 static const uint32 RT0[256] = { RT }; 366 #undef V 367 368 #define V(a,b,c,d) 0x##d##a##b##c 369 static const uint32 RT1[256] = { RT }; 370 #undef V 371 372 #define V(a,b,c,d) 0x##c##d##a##b 373 static const uint32 RT2[256] = { RT }; 374 #undef V 375 376 #define V(a,b,c,d) 0x##b##c##d##a 377 static const uint32 RT3[256] = { RT }; 378 #undef V 379 380 #undef RT 381 382 /* round constants */ 383 384 static const uint32 RCON[10] = 385 { 386 0x01000000, 0x02000000, 0x04000000, 0x08000000, 387 0x10000000, 0x20000000, 0x40000000, 0x80000000, 388 0x1B000000, 0x36000000 389 }; 390 391 int do_init = 0; 392 393 void aes_gen_tables(void) 394 { 395 } 396 397 #endif 398 399 /* platform-independant 32-bit integer manipulation macros */ 400 401 #define GET_UINT32(n,b,i) \ 402 { \ 403 (n) = ((uint32)(b)[(i)] << 24) \ 404 | ((uint32)(b)[(i)+1] << 16) \ 405 | ((uint32)(b)[(i)+2] << 8) \ 406 | ((uint32)(b)[(i)+3]); \ 407 } 408 409 #define PUT_UINT32(n,b,i) \ 410 { \ 411 (b)[(i)] = (uint8)((n) >> 24); \ 412 (b)[(i)+1] = (uint8)((n) >> 16); \ 413 (b)[(i)+2] = (uint8)((n) >> 8); \ 414 (b)[(i)+3] = (uint8)((n)); \ 415 } 416 417 /* decryption key schedule tables */ 418 419 int KT_init = 1; 420 421 uint32 KT0[256]; 422 uint32 KT1[256]; 423 uint32 KT2[256]; 424 uint32 KT3[256]; 425 426 /* AES key scheduling routine */ 427 428 int aes_set_key(aes_context *ctx, uint8 *key) 429 { 430 int i; 431 uint32 *RK, *SK; 432 433 if (do_init) 434 { 435 aes_gen_tables(); 436 437 do_init = 0; 438 } 439 ctx->nr = 14; 440 /*switch( nbits ) 441 { 442 case 128: ctx->nr = 10; break; 443 case 192: ctx->nr = 12; break; 444 case 256: ctx->nr = 14; break; 445 default : return( 1 ); 446 }*/ 447 448 RK = ctx->erk; 449 450 for (i = 0; i < 8; i++) 451 { 452 GET_UINT32(RK[i], key, i * 4); 453 } 454 for (i = 0; i < 7; i++, RK += 8) 455 { 456 RK[8] = RK[0] ^ RCON[i] ^ 457 (FSb[(uint8)(RK[7] >> 16)] << 24) ^ 458 (FSb[(uint8)(RK[7] >> 8)] << 16) ^ 459 (FSb[(uint8)(RK[7])] << 8) ^ 460 (FSb[(uint8)(RK[7] >> 24)]); 461 462 RK[9] = RK[1] ^ RK[8]; 463 RK[10] = RK[2] ^ RK[9]; 464 RK[11] = RK[3] ^ RK[10]; 465 466 RK[12] = RK[4] ^ 467 (FSb[(uint8)(RK[11] >> 24)] << 24) ^ 468 (FSb[(uint8)(RK[11] >> 16)] << 16) ^ 469 (FSb[(uint8)(RK[11] >> 8)] << 8) ^ 470 (FSb[(uint8)(RK[11])]); 471 472 RK[13] = RK[5] ^ RK[12]; 473 RK[14] = RK[6] ^ RK[13]; 474 RK[15] = RK[7] ^ RK[14]; 475 } 476 477 /* setup decryption round keys */ 478 479 if (KT_init) 480 { 481 for (i = 0; i < 256; i++) 482 { 483 KT0[i] = RT0[FSb[i]]; 484 KT1[i] = RT1[FSb[i]]; 485 KT2[i] = RT2[FSb[i]]; 486 KT3[i] = RT3[FSb[i]]; 487 } 488 489 KT_init = 0; 490 } 491 492 SK = ctx->drk; 493 494 *SK++ = *RK++; 495 *SK++ = *RK++; 496 *SK++ = *RK++; 497 *SK++ = *RK++; 498 499 for (i = 1; i < 14; i++) 500 { 501 RK -= 8; 502 503 *SK++ = KT0[(uint8)(*RK >> 24)] ^ 504 KT1[(uint8)(*RK >> 16)] ^ 505 KT2[(uint8)(*RK >> 8)] ^ 506 KT3[(uint8)(*RK)]; RK++; 507 508 *SK++ = KT0[(uint8)(*RK >> 24)] ^ 509 KT1[(uint8)(*RK >> 16)] ^ 510 KT2[(uint8)(*RK >> 8)] ^ 511 KT3[(uint8)(*RK)]; RK++; 512 513 *SK++ = KT0[(uint8)(*RK >> 24)] ^ 514 KT1[(uint8)(*RK >> 16)] ^ 515 KT2[(uint8)(*RK >> 8)] ^ 516 KT3[(uint8)(*RK)]; RK++; 517 518 *SK++ = KT0[(uint8)(*RK >> 24)] ^ 519 KT1[(uint8)(*RK >> 16)] ^ 520 KT2[(uint8)(*RK >> 8)] ^ 521 KT3[(uint8)(*RK)]; RK++; 522 } 523 524 RK -= 8; 525 526 *SK++ = *RK++; 527 *SK++ = *RK++; 528 *SK++ = *RK++; 529 *SK++ = *RK++; 530 531 return(0); 532 } 533 534 /* AES 256-bit block encryption routine */ 535 536 void aes_encrypt(aes_context *ctx, uint8 input[16], uint8 output[16]) 537 { 538 uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; 539 540 RK = ctx->erk; 541 542 GET_UINT32(X0, input, 0); X0 ^= RK[0]; 543 GET_UINT32(X1, input, 4); X1 ^= RK[1]; 544 GET_UINT32(X2, input, 8); X2 ^= RK[2]; 545 GET_UINT32(X3, input, 12); X3 ^= RK[3]; 546 547 #define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ 548 { \ 549 RK += 4; \ 550 \ 551 X0 = RK[0] ^ FT0[(uint8)(Y0 >> 24)] ^ \ 552 FT1[(uint8)(Y1 >> 16)] ^ \ 553 FT2[(uint8)(Y2 >> 8)] ^ \ 554 FT3[(uint8)(Y3)]; \ 555 \ 556 X1 = RK[1] ^ FT0[(uint8)(Y1 >> 24)] ^ \ 557 FT1[(uint8)(Y2 >> 16)] ^ \ 558 FT2[(uint8)(Y3 >> 8)] ^ \ 559 FT3[(uint8)(Y0)]; \ 560 \ 561 X2 = RK[2] ^ FT0[(uint8)(Y2 >> 24)] ^ \ 562 FT1[(uint8)(Y3 >> 16)] ^ \ 563 FT2[(uint8)(Y0 >> 8)] ^ \ 564 FT3[(uint8)(Y1)]; \ 565 \ 566 X3 = RK[3] ^ FT0[(uint8)(Y3 >> 24)] ^ \ 567 FT1[(uint8)(Y0 >> 16)] ^ \ 568 FT2[(uint8)(Y1 >> 8)] ^ \ 569 FT3[(uint8)(Y2)]; \ 570 } 571 572 AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 1 */ 573 AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 2 */ 574 AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 3 */ 575 AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 4 */ 576 AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 5 */ 577 AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 6 */ 578 AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 7 */ 579 AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 8 */ 580 AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 9 */ 581 582 // if( ctx->nr > 10 ) 583 //{ 584 AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 10 */ 585 AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 11 */ 586 //} 587 AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 12 */ 588 AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 13 */ 589 590 591 /* last round */ 592 593 RK += 4; 594 595 X0 = RK[0] ^ (FSb[(uint8)(Y0 >> 24)] << 24) ^ 596 (FSb[(uint8)(Y1 >> 16)] << 16) ^ 597 (FSb[(uint8)(Y2 >> 8)] << 8) ^ 598 (FSb[(uint8)(Y3)]); 599 600 X1 = RK[1] ^ (FSb[(uint8)(Y1 >> 24)] << 24) ^ 601 (FSb[(uint8)(Y2 >> 16)] << 16) ^ 602 (FSb[(uint8)(Y3 >> 8)] << 8) ^ 603 (FSb[(uint8)(Y0)]); 604 605 X2 = RK[2] ^ (FSb[(uint8)(Y2 >> 24)] << 24) ^ 606 (FSb[(uint8)(Y3 >> 16)] << 16) ^ 607 (FSb[(uint8)(Y0 >> 8)] << 8) ^ 608 (FSb[(uint8)(Y1)]); 609 610 X3 = RK[3] ^ (FSb[(uint8)(Y3 >> 24)] << 24) ^ 611 (FSb[(uint8)(Y0 >> 16)] << 16) ^ 612 (FSb[(uint8)(Y1 >> 8)] << 8) ^ 613 (FSb[(uint8)(Y2)]); 614 615 PUT_UINT32(X0, output, 0); 616 PUT_UINT32(X1, output, 4); 617 PUT_UINT32(X2, output, 8); 618 PUT_UINT32(X3, output, 12); 619 } 620 621 /* AES 256-bit block decryption routine */ 622 623 void aes_decrypt(aes_context *ctx, uint8 input[16], uint8 output[16]) 624 { 625 uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; 626 627 RK = ctx->drk; 628 629 GET_UINT32(X0, input, 0); X0 ^= RK[0]; 630 GET_UINT32(X1, input, 4); X1 ^= RK[1]; 631 GET_UINT32(X2, input, 8); X2 ^= RK[2]; 632 GET_UINT32(X3, input, 12); X3 ^= RK[3]; 633 634 #define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ 635 { \ 636 RK += 4; \ 637 \ 638 X0 = RK[0] ^ RT0[(uint8)(Y0 >> 24)] ^ \ 639 RT1[(uint8)(Y3 >> 16)] ^ \ 640 RT2[(uint8)(Y2 >> 8)] ^ \ 641 RT3[(uint8)(Y1)]; \ 642 \ 643 X1 = RK[1] ^ RT0[(uint8)(Y1 >> 24)] ^ \ 644 RT1[(uint8)(Y0 >> 16)] ^ \ 645 RT2[(uint8)(Y3 >> 8)] ^ \ 646 RT3[(uint8)(Y2)]; \ 647 \ 648 X2 = RK[2] ^ RT0[(uint8)(Y2 >> 24)] ^ \ 649 RT1[(uint8)(Y1 >> 16)] ^ \ 650 RT2[(uint8)(Y0 >> 8)] ^ \ 651 RT3[(uint8)(Y3)]; \ 652 \ 653 X3 = RK[3] ^ RT0[(uint8)(Y3 >> 24)] ^ \ 654 RT1[(uint8)(Y2 >> 16)] ^ \ 655 RT2[(uint8)(Y1 >> 8)] ^ \ 656 RT3[(uint8)(Y0)]; \ 657 } 658 659 AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 1 */ 660 AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 2 */ 661 AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 3 */ 662 AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 4 */ 663 AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 5 */ 664 AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 6 */ 665 AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 7 */ 666 AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 8 */ 667 AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 9 */ 668 669 // if( ctx->nr > 10 ) 670 //{ 671 AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 10 */ 672 AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 11 */ 673 //} 674 AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 12 */ 675 AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 13 */ 676 677 678 /* last round */ 679 680 RK += 4; 681 682 X0 = RK[0] ^ (RSb[(uint8)(Y0 >> 24)] << 24) ^ 683 (RSb[(uint8)(Y3 >> 16)] << 16) ^ 684 (RSb[(uint8)(Y2 >> 8)] << 8) ^ 685 (RSb[(uint8)(Y1)]); 686 687 X1 = RK[1] ^ (RSb[(uint8)(Y1 >> 24)] << 24) ^ 688 (RSb[(uint8)(Y0 >> 16)] << 16) ^ 689 (RSb[(uint8)(Y3 >> 8)] << 8) ^ 690 (RSb[(uint8)(Y2)]); 691 692 X2 = RK[2] ^ (RSb[(uint8)(Y2 >> 24)] << 24) ^ 693 (RSb[(uint8)(Y1 >> 16)] << 16) ^ 694 (RSb[(uint8)(Y0 >> 8)] << 8) ^ 695 (RSb[(uint8)(Y3)]); 696 697 X3 = RK[3] ^ (RSb[(uint8)(Y3 >> 24)] << 24) ^ 698 (RSb[(uint8)(Y2 >> 16)] << 16) ^ 699 (RSb[(uint8)(Y1 >> 8)] << 8) ^ 700 (RSb[(uint8)(Y0)]); 701 702 PUT_UINT32(X0, output, 0); 703 PUT_UINT32(X1, output, 4); 704 PUT_UINT32(X2, output, 8); 705 PUT_UINT32(X3, output, 12); 706 } 707 /* 708 传进参数:密钥;加密字符串;密文存储文件 709 密钥会被自动填充或者截取为32字节 710 */ 711 void AES(unsigned char *key, unsigned char *buf, FILE *fp) 712 { 713 aes_context ctx; 714 char *keytemp; 715 //密钥拓展成32字节 716 for (int i=0,j=0; i<32; i++) 717 { 718 if (key[i] != 0) 719 { 720 keytemp[i] = key[i]; 721 j++; 722 } 723 else{ 724 keytemp[i] = key[i%j]; 725 } 726 } 727 printf("拓展后的密钥:", keytemp); 728 aes_set_key(&ctx, keytemp); 729 for (int k = 1; buf != '\0'; k++) 730 { 731 if (k%8==0) 732 aes_encrypt(&ctx, buf, buf); 733 } 734 } 735 int main(void) 736 { 737 //int m, n, i, j; 738 int i; 739 //char c; 740 aes_context ctx; 741 unsigned char buf[16]; 742 unsigned char key[32] = { 'f', 'e', 'f', '2', 'f', 'e', 'g', 'h', 'b', 'v', 'c', 'x', 'z', 'q', 'e', 'w', 'f', 'e', 'f', '2', 'f', 'e', 'g', 'h', 'f', 'e', 'f', '2', 'f', 'e', 'g', 'h' }; 743 printf("输入32个字符作为秘钥\n"); 744 scanf("%s",key); 745 printf(key); 746 printf("输入加密数据\n"); 747 scanf("%s", buf); 748 aes_set_key(&ctx, key); 749 /* for (i = 0; i<16; i++) 750 { 751 buf[i] = 'd'; 752 }*/ 753 printf("the data to encrypt:\n"); 754 for (i = 0; i<16; i++) 755 { 756 printf("%02x ", buf[i]); 757 } 758 printf("\n"); 759 760 getchar(); 761 aes_encrypt(&ctx, buf, buf); 762 printf("The encrypted data is:\n"); 763 for (i = 0; i<16; i++) 764 { 765 printf("%02x ", buf[i]); 766 } 767 printf("\n"); 768 printf("\n"); 769 770 771 // aes_set_key( &ctx, key, 128 + n * 64 ); 772 aes_decrypt(&ctx, buf, buf); 773 printf("The decrypted data is:\n"); 774 for (i = 0; i<16; i++) 775 { 776 printf("%02x ", buf[i]); 777 } 778 printf("\n"); 779 getchar(); 780 return 0; 781 782 } 783 784 //#endif