// 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 ();
}
转载于:https://www.cnblogs.com/shangdawei/p/4581944.html
相关资源:Intel® Advanced Encryption Standard (AES) New Instructions Set.pdf