AES advanced encryption standard
// advanced encryption standard // author: karl malbrain, malbrain@yahoo.com typedef unsigned char uchar; #include <string.h> #include <memory.h> // AES only supports Nb=4 #define Nb 4 // number of columns in the state & expanded key #define Nk 4 // number of columns in a key #define Nr 10 // number of rounds in encryption uchar Sbox[256] = { // forward s-box 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16}; uchar InvSbox[256] = { // inverse s-box 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d}; // combined Xtimes2[Sbox[]] uchar Xtime2Sbox[256] = { 0xc6, 0xf8, 0xee, 0xf6, 0xff, 0xd6, 0xde, 0x91, 0x60, 0x02, 0xce, 0x56, 0xe7, 0xb5, 0x4d, 0xec, 0x8f, 0x1f, 0x89, 0xfa, 0xef, 0xb2, 0x8e, 0xfb, 0x41, 0xb3, 0x5f, 0x45, 0x23, 0x53, 0xe4, 0x9b, 0x75, 0xe1, 0x3d, 0x4c, 0x6c, 0x7e, 0xf5, 0x83, 0x68, 0x51, 0xd1, 0xf9, 0xe2, 0xab, 0x62, 0x2a, 0x08, 0x95, 0x46, 0x9d, 0x30, 0x37, 0x0a, 0x2f, 0x0e, 0x24, 0x1b, 0xdf, 0xcd, 0x4e, 0x7f, 0xea, 0x12, 0x1d, 0x58, 0x34, 0x36, 0xdc, 0xb4, 0x5b, 0xa4, 0x76, 0xb7, 0x7d, 0x52, 0xdd, 0x5e, 0x13, 0xa6, 0xb9, 0x00, 0xc1, 0x40, 0xe3, 0x79, 0xb6, 0xd4, 0x8d, 0x67, 0x72, 0x94, 0x98, 0xb0, 0x85, 0xbb, 0xc5, 0x4f, 0xed, 0x86, 0x9a, 0x66, 0x11, 0x8a, 0xe9, 0x04, 0xfe, 0xa0, 0x78, 0x25, 0x4b, 0xa2, 0x5d, 0x80, 0x05, 0x3f, 0x21, 0x70, 0xf1, 0x63, 0x77, 0xaf, 0x42, 0x20, 0xe5, 0xfd, 0xbf, 0x81, 0x18, 0x26, 0xc3, 0xbe, 0x35, 0x88, 0x2e, 0x93, 0x55, 0xfc, 0x7a, 0xc8, 0xba, 0x32, 0xe6, 0xc0, 0x19, 0x9e, 0xa3, 0x44, 0x54, 0x3b, 0x0b, 0x8c, 0xc7, 0x6b, 0x28, 0xa7, 0xbc, 0x16, 0xad, 0xdb, 0x64, 0x74, 0x14, 0x92, 0x0c, 0x48, 0xb8, 0x9f, 0xbd, 0x43, 0xc4, 0x39, 0x31, 0xd3, 0xf2, 0xd5, 0x8b, 0x6e, 0xda, 0x01, 0xb1, 0x9c, 0x49, 0xd8, 0xac, 0xf3, 0xcf, 0xca, 0xf4, 0x47, 0x10, 0x6f, 0xf0, 0x4a, 0x5c, 0x38, 0x57, 0x73, 0x97, 0xcb, 0xa1, 0xe8, 0x3e, 0x96, 0x61, 0x0d, 0x0f, 0xe0, 0x7c, 0x71, 0xcc, 0x90, 0x06, 0xf7, 0x1c, 0xc2, 0x6a, 0xae, 0x69, 0x17, 0x99, 0x3a, 0x27, 0xd9, 0xeb, 0x2b, 0x22, 0xd2, 0xa9, 0x07, 0x33, 0x2d, 0x3c, 0x15, 0xc9, 0x87, 0xaa, 0x50, 0xa5, 0x03, 0x59, 0x09, 0x1a, 0x65, 0xd7, 0x84, 0xd0, 0x82, 0x29, 0x5a, 0x1e, 0x7b, 0xa8, 0x6d, 0x2c }; // combined Xtimes3[Sbox[]] uchar Xtime3Sbox[256] = { 0xa5, 0x84, 0x99, 0x8d, 0x0d, 0xbd, 0xb1, 0x54, 0x50, 0x03, 0xa9, 0x7d, 0x19, 0x62, 0xe6, 0x9a, 0x45, 0x9d, 0x40, 0x87, 0x15, 0xeb, 0xc9, 0x0b, 0xec, 0x67, 0xfd, 0xea, 0xbf, 0xf7, 0x96, 0x5b, 0xc2, 0x1c, 0xae, 0x6a, 0x5a, 0x41, 0x02, 0x4f, 0x5c, 0xf4, 0x34, 0x08, 0x93, 0x73, 0x53, 0x3f, 0x0c, 0x52, 0x65, 0x5e, 0x28, 0xa1, 0x0f, 0xb5, 0x09, 0x36, 0x9b, 0x3d, 0x26, 0x69, 0xcd, 0x9f, 0x1b, 0x9e, 0x74, 0x2e, 0x2d, 0xb2, 0xee, 0xfb, 0xf6, 0x4d, 0x61, 0xce, 0x7b, 0x3e, 0x71, 0x97, 0xf5, 0x68, 0x00, 0x2c, 0x60, 0x1f, 0xc8, 0xed, 0xbe, 0x46, 0xd9, 0x4b, 0xde, 0xd4, 0xe8, 0x4a, 0x6b, 0x2a, 0xe5, 0x16, 0xc5, 0xd7, 0x55, 0x94, 0xcf, 0x10, 0x06, 0x81, 0xf0, 0x44, 0xba, 0xe3, 0xf3, 0xfe, 0xc0, 0x8a, 0xad, 0xbc, 0x48, 0x04, 0xdf, 0xc1, 0x75, 0x63, 0x30, 0x1a, 0x0e, 0x6d, 0x4c, 0x14, 0x35, 0x2f, 0xe1, 0xa2, 0xcc, 0x39, 0x57, 0xf2, 0x82, 0x47, 0xac, 0xe7, 0x2b, 0x95, 0xa0, 0x98, 0xd1, 0x7f, 0x66, 0x7e, 0xab, 0x83, 0xca, 0x29, 0xd3, 0x3c, 0x79, 0xe2, 0x1d, 0x76, 0x3b, 0x56, 0x4e, 0x1e, 0xdb, 0x0a, 0x6c, 0xe4, 0x5d, 0x6e, 0xef, 0xa6, 0xa8, 0xa4, 0x37, 0x8b, 0x32, 0x43, 0x59, 0xb7, 0x8c, 0x64, 0xd2, 0xe0, 0xb4, 0xfa, 0x07, 0x25, 0xaf, 0x8e, 0xe9, 0x18, 0xd5, 0x88, 0x6f, 0x72, 0x24, 0xf1, 0xc7, 0x51, 0x23, 0x7c, 0x9c, 0x21, 0xdd, 0xdc, 0x86, 0x85, 0x90, 0x42, 0xc4, 0xaa, 0xd8, 0x05, 0x01, 0x12, 0xa3, 0x5f, 0xf9, 0xd0, 0x91, 0x58, 0x27, 0xb9, 0x38, 0x13, 0xb3, 0x33, 0xbb, 0x70, 0x89, 0xa7, 0xb6, 0x22, 0x92, 0x20, 0x49, 0xff, 0x78, 0x7a, 0x8f, 0xf8, 0x80, 0x17, 0xda, 0x31, 0xc6, 0xb8, 0xc3, 0xb0, 0x77, 0x11, 0xcb, 0xfc, 0xd6, 0x3a }; // modular multiplication tables // based on: // Xtime2[x] = (x & 0x80 ? 0x1b : 0) ^ (x + x) // Xtime3[x] = x^Xtime2[x]; uchar Xtime2[256] = { 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e, 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, 0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05, 0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25, 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45, 0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65, 0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85, 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5, 0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5, 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5}; uchar Xtime9[256] = { 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77, 0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7, 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c, 0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8, 0xc7, 0xce, 0xd5, 0xdc, 0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49, 0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01, 0xe6, 0xef, 0xf4, 0xfd, 0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91, 0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e, 0x21, 0x28, 0x33, 0x3a, 0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2, 0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa, 0xec, 0xe5, 0xfe, 0xf7, 0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b, 0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f, 0x10, 0x19, 0x02, 0x0b, 0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8, 0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0, 0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30, 0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed, 0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35, 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d, 0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6, 0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46}; uchar XtimeB[256] = { 0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69, 0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9, 0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12, 0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, 0x85, 0x8e, 0xbf, 0xb4, 0xa9, 0xa2, 0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7, 0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f, 0x46, 0x4d, 0x50, 0x5b, 0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f, 0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8, 0xf9, 0xf2, 0xef, 0xe4, 0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c, 0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54, 0xf7, 0xfc, 0xe1, 0xea, 0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e, 0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2e, 0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd, 0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5, 0x3c, 0x37, 0x2a, 0x21, 0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55, 0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68, 0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80, 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8, 0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13, 0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3}; uchar XtimeD[256] = { 0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b, 0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b, 0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0, 0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14, 0x37, 0x3a, 0x2d, 0x20, 0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e, 0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26, 0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6, 0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9, 0x8a, 0x87, 0x90, 0x9d, 0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25, 0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d, 0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91, 0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41, 0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42, 0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a, 0xb1, 0xbc, 0xab, 0xa6, 0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa, 0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc, 0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44, 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c, 0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47, 0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97}; uchar XtimeE[256] = { 0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a, 0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba, 0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81, 0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59, 0x73, 0x7d, 0x6f, 0x61, 0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87, 0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7, 0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17, 0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14, 0x3e, 0x30, 0x22, 0x2c, 0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc, 0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc, 0x41, 0x4f, 0x5d, 0x53, 0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b, 0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3, 0xe9, 0xe7, 0xf5, 0xfb, 0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0, 0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0, 0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20, 0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6, 0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56, 0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d, 0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d}; // exchanges columns in each of 4 rows // row0 - unchanged, row1- shifted left 1, // row2 - shifted left 2 and row3 - shifted left 3 void ShiftRows (uchar *state, uchar *out) { // just substitute row 0 out[0] = Sbox[state[0]], out[4] = Sbox[state[4]]; out[8] = Sbox[state[8]], out[12] = Sbox[state[12]]; // rotate row 1 out[1] = Sbox[state[5]], out[5] = Sbox[state[9]]; out[9] = Sbox[state[13]], out[13] = Sbox[state[1]]; // rotate row 2 out[2] = Sbox[state[10]], out[10] = Sbox[state[2]]; out[6] = Sbox[state[14]], out[14] = Sbox[state[6]]; // rotate row 3 out[15] = Sbox[state[11]], out[11] = Sbox[state[7]]; out[7] = Sbox[state[3]], out[3] = Sbox[state[15]]; } // restores columns in each of 4 rows // row0 - unchanged, row1- shifted right 1, // row2 - shifted right 2 and row3 - shifted right 3 void InvShiftRows (uchar *state, uchar *out) { // restore row 0 out[0] = InvSbox[state[0]], out[4] = InvSbox[state[4]]; out[8] = InvSbox[state[8]], out[12] = InvSbox[state[12]]; // restore row 1 out[13] = InvSbox[state[9]], out[9] = InvSbox[state[5]]; out[5] = InvSbox[state[1]], out[1] = InvSbox[state[13]]; // restore row 2 out[2] = InvSbox[state[10]], out[10] = InvSbox[state[2]]; out[6] = InvSbox[state[14]], out[14] = InvSbox[state[6]]; // restore row 3 out[3] = InvSbox[state[7]], out[7] = InvSbox[state[11]]; out[11] = InvSbox[state[15]], out[15] = InvSbox[state[3]]; } uchar Rcon[11] = { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36}; // produce Nb bytes for each round void ExpandKey (uchar *key, uchar *expkey) { uchar tmp0, tmp1, tmp2, tmp3, tmp4; int idx; memcpy (expkey, key, Nk * 4); for( idx = Nk; idx < Nb * (Nr + 1); idx++ ) { tmp0 = expkey[4*idx - 4]; tmp1 = expkey[4*idx - 3]; tmp2 = expkey[4*idx - 2]; tmp3 = expkey[4*idx - 1]; if( !(idx % Nk) ) { tmp4 = tmp3; tmp3 = Sbox[tmp0]; tmp0 = Sbox[tmp1] ^ Rcon[idx/Nk]; tmp1 = Sbox[tmp2]; tmp2 = Sbox[tmp4]; } else if( Nk > 6 && idx % Nk == 4 ) { tmp0 = Sbox[tmp0]; tmp1 = Sbox[tmp1]; tmp2 = Sbox[tmp2]; tmp3 = Sbox[tmp3]; } expkey[4*idx+0] = expkey[4*idx - 4*Nk + 0] ^ tmp0; expkey[4*idx+1] = expkey[4*idx - 4*Nk + 1] ^ tmp1; expkey[4*idx+2] = expkey[4*idx - 4*Nk + 2] ^ tmp2; expkey[4*idx+3] = expkey[4*idx - 4*Nk + 3] ^ tmp3; } } // encrypt/decrypt columns of the key #define AddRoundKey(state, key, out)\ do {\ out[0] = state[0] ^ key[0];\ out[1] = state[1] ^ key[1];\ out[2] = state[2] ^ key[2];\ out[3] = state[3] ^ key[3];\ out[4] = state[4] ^ key[4];\ out[5] = state[5] ^ key[5];\ out[6] = state[6] ^ key[6];\ out[7] = state[7] ^ key[7];\ out[8] = state[8] ^ key[8];\ out[9] = state[9] ^ key[9];\ out[10] = state[10] ^ key[10];\ out[11] = state[11] ^ key[11];\ out[12] = state[12] ^ key[12];\ out[13] = state[13] ^ key[13];\ out[14] = state[14] ^ key[14];\ out[15] = state[15] ^ key[15];\ } while(0) // recombine and mix each row in a column #define MixSubColumns(state, out, key)\ do {\ /* mixing column 0*/\ out[0] = Xtime2Sbox[state[0]] ^ Xtime3Sbox[state[5]] ^ Sbox[state[10]] ^ Sbox[state[15]] ^ key[0];\ out[1] = Sbox[state[0]] ^ Xtime2Sbox[state[5]] ^ Xtime3Sbox[state[10]] ^ Sbox[state[15]] ^ key[1];\ out[2] = Sbox[state[0]] ^ Sbox[state[5]] ^ Xtime2Sbox[state[10]] ^ Xtime3Sbox[state[15]] ^ key[2];\ out[3] = Xtime3Sbox[state[0]] ^ Sbox[state[5]] ^ Sbox[state[10]] ^ Xtime2Sbox[state[15]] ^ key[3];\ \ /* mixing column 1*/\ out[4] = Xtime2Sbox[state[4]] ^ Xtime3Sbox[state[9]] ^ Sbox[state[14]] ^ Sbox[state[3]] ^ key[4];\ out[5] = Sbox[state[4]] ^ Xtime2Sbox[state[9]] ^ Xtime3Sbox[state[14]] ^ Sbox[state[3]] ^ key[5];\ out[6] = Sbox[state[4]] ^ Sbox[state[9]] ^ Xtime2Sbox[state[14]] ^ Xtime3Sbox[state[3]] ^ key[6];\ out[7] = Xtime3Sbox[state[4]] ^ Sbox[state[9]] ^ Sbox[state[14]] ^ Xtime2Sbox[state[3]] ^ key[7];\ \ /* mixing column 2*/\ out[8] = Xtime2Sbox[state[8]] ^ Xtime3Sbox[state[13]] ^ Sbox[state[2]] ^ Sbox[state[7]] ^ key[8];\ out[9] = Sbox[state[8]] ^ Xtime2Sbox[state[13]] ^ Xtime3Sbox[state[2]] ^ Sbox[state[7]] ^ key[9];\ out[10] = Sbox[state[8]] ^ Sbox[state[13]] ^ Xtime2Sbox[state[2]] ^ Xtime3Sbox[state[7]] ^ key[10];\ out[11] = Xtime3Sbox[state[8]] ^ Sbox[state[13]] ^ Sbox[state[2]] ^ Xtime2Sbox[state[7]] ^ key[11];\ \ /* mixing column 3*/\ out[12] = Xtime2Sbox[state[12]] ^ Xtime3Sbox[state[1]] ^ Sbox[state[6]] ^ Sbox[state[11]] ^ key[12];\ out[13] = Sbox[state[12]] ^ Xtime2Sbox[state[1]] ^ Xtime3Sbox[state[6]] ^ Sbox[state[11]] ^ key[13];\ out[14] = Sbox[state[12]] ^ Sbox[state[1]] ^ Xtime2Sbox[state[6]] ^ Xtime3Sbox[state[11]] ^ key[14];\ out[15] = Xtime3Sbox[state[12]] ^ Sbox[state[1]] ^ Sbox[state[6]] ^ Xtime2Sbox[state[11]] ^ key[15];\ } while(0) // encrypt one 128 bit block void Encrypt (uchar *in, uchar *expkey, uchar *out) { uchar state[Nb * 4], tmp[Nb * 4]; AddRoundKey (in, expkey, state); expkey += Nb * 4; MixSubColumns (state, tmp, expkey); expkey += Nb * 4; MixSubColumns (tmp, state, expkey); expkey += Nb * 4; MixSubColumns (state, tmp, expkey); expkey += Nb * 4; MixSubColumns (tmp, state, expkey); expkey += Nb * 4; MixSubColumns (state, tmp, expkey); expkey += Nb * 4; MixSubColumns (tmp, state, expkey); expkey += Nb * 4; MixSubColumns (state, tmp, expkey); expkey += Nb * 4; MixSubColumns (tmp, state, expkey); expkey += Nb * 4; MixSubColumns (state, tmp, expkey); expkey += Nb * 4; #if (Nr > 10) MixSubColumns (tmp, state, expkey); expkey += Nb * 4; MixSubColumns (state, tmp, expkey); expkey += Nb * 4; #endif #if (Nr > 12) MixSubColumns (tmp, state, expkey); expkey += Nb * 4; MixSubColumns (state, tmp, expkey); expkey += Nb * 4; #endif ShiftRows (tmp, state); AddRoundKey (state, expkey, out); } // restore and un-mix each row in a column #define InvMixSubColumns(state, out, key)\ do {\ /* restore column 0*/\ t0 = state[0] ^ key[0];\ t1 = state[1] ^ key[1];\ t2 = state[2] ^ key[2];\ t3 = state[3] ^ key[3];\ out[0] = InvSbox[XtimeE[t0] ^ XtimeB[t1] ^ XtimeD[t2] ^ Xtime9[t3]];\ out[5] = InvSbox[Xtime9[t0] ^ XtimeE[t1] ^ XtimeB[t2] ^ XtimeD[t3]];\ out[10] = InvSbox[XtimeD[t0] ^ Xtime9[t1] ^ XtimeE[t2] ^ XtimeB[t3]];\ out[15] = InvSbox[XtimeB[t0] ^ XtimeD[t1] ^ Xtime9[t2] ^ XtimeE[t3]];\ \ /* restore column 1*/\ t0 = state[4] ^ key[4];\ t1 = state[5] ^ key[5];\ t2 = state[6] ^ key[6];\ t3 = state[7] ^ key[7];\ out[4] = InvSbox[XtimeE[t0] ^ XtimeB[t1] ^ XtimeD[t2] ^ Xtime9[t3]];\ out[9] = InvSbox[Xtime9[t0] ^ XtimeE[t1] ^ XtimeB[t2] ^ XtimeD[t3]];\ out[14] = InvSbox[XtimeD[t0] ^ Xtime9[t1] ^ XtimeE[t2] ^ XtimeB[t3]];\ out[3] = InvSbox[XtimeB[t0] ^ XtimeD[t1] ^ Xtime9[t2] ^ XtimeE[t3]];\ \ /* restore column 2*/\ t0 = state[8] ^ key[8];\ t1 = state[9] ^ key[9];\ t2 = state[10] ^ key[10];\ t3 = state[11] ^ key[11];\ out[8] = InvSbox[XtimeE[t0] ^ XtimeB[t1] ^ XtimeD[t2] ^ Xtime9[t3]];\ out[13] = InvSbox[Xtime9[t0] ^ XtimeE[t1] ^ XtimeB[t2] ^ XtimeD[t3]];\ out[2] = InvSbox[XtimeD[t0] ^ Xtime9[t1] ^ XtimeE[t2] ^ XtimeB[t3]];\ out[7] = InvSbox[XtimeB[t0] ^ XtimeD[t1] ^ Xtime9[t2] ^ XtimeE[t3]];\ \ /* restore column 3*/\ t0 = state[12] ^ key[12];\ t1 = state[13] ^ key[13];\ t2 = state[14] ^ key[14];\ t3 = state[15] ^ key[15];\ out[12] = InvSbox[XtimeE[t0] ^ XtimeB[t1] ^ XtimeD[t2] ^ Xtime9[t3]];\ out[1] = InvSbox[Xtime9[t0] ^ XtimeE[t1] ^ XtimeB[t2] ^ XtimeD[t3]];\ out[6] = InvSbox[XtimeD[t0] ^ Xtime9[t1] ^ XtimeE[t2] ^ XtimeB[t3]];\ out[11] = InvSbox[XtimeB[t0] ^ XtimeD[t1] ^ Xtime9[t2] ^ XtimeE[t3]];\ } while(0) void Decrypt (uchar *in, uchar *expkey, uchar *out) { uchar state[Nb * 4], tmp[Nb * 4]; uchar t0, t1, t2, t3; expkey += Nr * Nb * 4; AddRoundKey (in, expkey, tmp); InvShiftRows(tmp, state); expkey -= Nb * 4; InvMixSubColumns (state, tmp, expkey); expkey -= Nb * 4; InvMixSubColumns (tmp, state, expkey); expkey -= Nb * 4; InvMixSubColumns (state, tmp, expkey); expkey -= Nb * 4; InvMixSubColumns (tmp, state, expkey); expkey -= Nb * 4; InvMixSubColumns (state, tmp, expkey); expkey -= Nb * 4; InvMixSubColumns (tmp, state, expkey); expkey -= Nb * 4; InvMixSubColumns (state, tmp, expkey); expkey -= Nb * 4; InvMixSubColumns (tmp, state, expkey); expkey -= Nb * 4; InvMixSubColumns (state, tmp, expkey); #if (Nr > 10) expkey -= Nb * 4; InvMixSubColumns (tmp, state, expkey); expkey -= Nb * 4; InvMixSubColumns (state, tmp, expkey); #endif #if (Nr > 12) expkey -= Nb * 4; InvMixSubColumns (tmp, state, expkey); expkey -= Nb * 4; InvMixSubColumns (state, tmp, expkey); #endif expkey -= Nb * 4; AddRoundKey (tmp, expkey, out); } #include <stdio.h> #include <fcntl.h> uchar in[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}; uchar key[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f}; uchar out[16]; #ifndef unix void rd_clock (__int64 *ans) { unsigned dwLow, dwHigh; __asm { rdtsc mov dwLow, eax mov dwHigh, edx } *ans = (__int64)dwHigh << 32 | (__int64)dwLow; } #else typedef long long __int64; void rd_clock (__int64 *ans) { unsigned long long dwBoth; __asm__ volatile(".byte 0x0f, 0x31" : "=A"(dwBoth)); *ans = dwBoth; } #endif uchar samplekey[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}; uchar samplein[] = {0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34}; void sample () { uchar expkey[4 * Nb * (Nr + 1)]; int idx, diff; __int64 start, stop; ExpandKey (samplekey, expkey); Encrypt (samplein, expkey, out); rd_clock(&start); Encrypt (samplein, expkey, out); rd_clock(&stop); diff = stop - start; printf ("encrypt time: %d, %d cycles per byte\n", diff, diff/16); for( idx = 0; idx < 16; idx++ ) printf ("%.2x ", out[idx]); printf ("\n"); Decrypt (out, expkey, in); rd_clock(&start); Decrypt (out, expkey, in); rd_clock(&stop); diff = stop - start; printf ("decrypt time: %d, %d cycles per byte\n", diff, diff/16); for( idx = 0; idx < 16; idx++ ) printf ("%.2x ", in[idx]); printf ("\n"); } void certify () { uchar expkey[4 * Nb * (Nr + 1)]; int idx, diff; __int64 start, stop; ExpandKey (key, expkey); Encrypt (in, expkey, out); rd_clock(&start); Encrypt (in, expkey, out); rd_clock(&stop); diff = stop - start; printf ("encrypt time: %d, %d cycles per byte\n", diff, diff/16); for( idx = 0; idx < 16; idx++ ) printf ("%.2x ", out[idx]); printf ("\n"); Decrypt (out, expkey, in); rd_clock(&start); Decrypt (out, expkey, in); rd_clock(&stop); diff = stop - start; printf ("decrypt time: %d, %d cycles per byte\n", diff, diff/16); for( idx = 0; idx < 16; idx++ ) printf ("%.2x ", in[idx]); printf ("\n"); } void decrypt (char *mykey, char *name) { uchar expkey[4 * Nb * (Nr + 1)]; FILE *fd = fopen (name, "rb"); int ch, idx = 0; strncpy (key, mykey, sizeof(key)); ExpandKey (key, expkey); while( ch = getc(fd), ch != EOF ) { in[idx++] = ch; if( idx % 16 ) continue; Decrypt (in, expkey, out); for( idx = 0; idx < 16; idx++ ) putchar (out[idx]); idx = 0; } } void encrypt (char *mykey, char *name) { uchar expkey[4 * Nb * (Nr + 1)]; FILE *fd = fopen (name, "rb"); int ch, idx = 0; strncpy (key, mykey, sizeof(key)); ExpandKey (key, expkey); while( ch = getc(fd), ch != EOF ) { in[idx++] = ch; if( idx % 16 ) continue; Encrypt (in, expkey, out); for( idx = 0; idx < 16; idx++ ) putchar (out[idx]); idx = 0; } if( idx ) while( idx % 16 ) in[idx++] = 0; else return; Encrypt (in, expkey, out); for( idx = 0; idx < 16; idx++ ) putchar (out[idx]); } uchar expkey[4 * Nb * (Nr + 1)]; void mrandom (int, char *); unsigned xrandom (void); int aescycles () { __int64 start, end; int t; do { rd_clock(&start); Encrypt (in, expkey, out); rd_clock (&end); t = end - start; } while( t<= 0 || t>= 4000); return t; } int bestx (int b, int loops) { int bestx = 0, bestxt = 0; int x, xt, i, j; for( x = 0; x < 256; x++ ) { xt = 0; for( i = 0; i < loops; i++ ) { for( j = 0; j < 16; j++ ) in[j] = xrandom() >> 16; in[b] = x; xt += aescycles(); xt += aescycles(); xt += aescycles(); xt += aescycles(); xt += aescycles(); } if( xt > bestxt ) bestx = x, bestxt = xt; } return bestx; } void bernstein (char *seed) { int loops, b, j, k; mrandom (strlen(seed), seed); for( loops = 4; loops <= 65536; loops *= 16) { for( b = 0; b < 16; b++ ) { printf ("%.2d, %.5d loops:", b, loops); for( k = 0; k < 10; k++ ) { for( j = 0; j < 16; j++ ) key[j] = xrandom() >> 16; ExpandKey (key, expkey); printf (" %.2x", bestx (b, loops) ^ key[b]); fflush (stdout); } printf ("\n"); } } } void tables() { int i; for( i = 0; i < 256; i++) { printf("0x%.2x, ", Sbox[i] ^ Xtime2[Sbox[i]]); if( !((i+1) % 16) ) printf("\n"); } printf("\n"); for( i = 0; i < 256; i++) { printf("0x%.2x, ", Xtime2[Sbox[i]]); if ( !((i+1) % 16) ) printf("\n"); } } int main (int argc, char *argv[]) { #ifndef unix extern int __cdecl _setmode (int, int); _setmode (_fileno(stdout), _O_BINARY); #endif switch( argv[1][0] ) { case 'c': certify(); break; case 'e': encrypt(argv[2], argv[3]); break; case 'd': decrypt(argv[2], argv[3]); break; case 'b': bernstein(argv[2]); break; case 's': sample(); break; case 't': tables(); break; } } /* * The package generates far better random numbers than a linear * congruential generator. The random number generation technique * is a linear feedback shift register approach. In this approach, * the least significant bit of all the numbers in the RandTbl table * will act as a linear feedback shift register, and will have period * of approximately 2^96 - 1. * */ #define RAND_order (7 * sizeof(unsigned)) #define RAND_size (96 * sizeof(unsigned)) uchar RandTbl[RAND_size + RAND_order]; int RandHead = 0; /* * random: x**96 + x**7 + x**6 + x**4 + x**3 + x**2 + 1 * * The basic operation is to add to the number at the head index * the XOR sum of the lower order terms in the polynomial. * Then the index is advanced to the next location cyclically * in the table. The value returned is the sum generated. * */ unsigned xrandom () { register unsigned fact; if( (RandHead -= sizeof(unsigned)) < 0 ) { RandHead = RAND_size - sizeof(unsigned); memcpy (RandTbl + RAND_size, RandTbl, RAND_order); } fact = *(unsigned *)(RandTbl + RandHead + 7 * sizeof(unsigned)); fact ^= *(unsigned *)(RandTbl + RandHead + 6 * sizeof(unsigned)); fact ^= *(unsigned *)(RandTbl + RandHead + 4 * sizeof(unsigned)); fact ^= *(unsigned *)(RandTbl + RandHead + 3 * sizeof(unsigned)); fact ^= *(unsigned *)(RandTbl + RandHead + 2 * sizeof(unsigned)); return *(unsigned *)(RandTbl + RandHead) += fact; } /* * mrandom: * Initialize the random number generator based on the given seed. * */ void mrandom (int len, char *ptr) { unsigned short rand = *ptr; int idx, bit = len * 4; memset (RandTbl, 0, sizeof(RandTbl)); RandHead = 0; while( rand *= 20077, rand += 11, bit-- ) if( ptr[bit >> 2] & (1 << (bit & 3)) ) for (idx = 0; idx < 5; idx++) { rand *= 20077, rand += 11; RandTbl[rand % 96 << 2] ^= 1; } for( idx = 0; idx < 96 * 63; idx++ ) xrandom (); }
分类:
ALGO
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
2013-06-16 A SCSI command code -- SIMPLIFIED DIRECT-ACCESS DEVICE (RBC)
2013-06-16 How to match between physical usb device and its drive letter?
2013-06-16 A SCSI command code quick reference
2013-06-16 Inprove the speed of the "Mass storage" as u disk