Here is my code
#include <iostream>
using namespace std;
/**/ unsigned char sBox[256] =
{ 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 };
/**/unsigned char lookUpTableFor02[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 };
unsigned char rcon[11] =
{
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36,
};
void RotWord(unsigned char* arr)
{
unsigned char temp = arr[0];
arr[0] = arr[1];
arr[1] = arr[2];
arr[2] = arr[3];
arr[3] = temp;
}
void SubWord(unsigned char* arr)
{
arr[0] = sBox[arr[0]];
arr[1] = sBox[arr[1]];
arr[2] = sBox[arr[2]];
arr[3] = sBox[arr[3]];
}
void RCon(unsigned char* arr, unsigned char i)
{
arr[0] ^= rcon[i];
}
void KeyExpansionRoutine(unsigned char* arr, unsigned char i)
{
RotWord(arr);
SubWord(arr);
RCon(arr, i);
}
void KeyExpansion(unsigned char inputKey[16], unsigned char expandedKeys[176])
{
for (int i = 0; i < 16; i++)
{
expandedKeys[i] = inputKey[i];
}
int generatedNumberOfBytes = 16;
int rConCounter = 1;
unsigned char temp[4];
while (generatedNumberOfBytes < 176)
{
for (int i = 0; i < 4; i++)
temp[i] = expandedKeys[i + generatedNumberOfBytes - 4];
if (generatedNumberOfBytes % 16 == 0)
KeyExpansionRoutine(temp, rConCounter++);
for (unsigned char j = 0; j < 4; j++)
{
expandedKeys[generatedNumberOfBytes/*16,17,18,19 means w4*/] = expandedKeys[generatedNumberOfBytes - 16/*wO*/] ^ temp[j];
generatedNumberOfBytes++;
}
}
}
void SubBytes(unsigned char* state)
{
for (int i = 0; i < 16; i++)
{
state[i] = sBox[state[i]];
}
}
void ShiftRows(unsigned char* state)
{
unsigned char tempState[16];
int counter = 0;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
tempState[counter] = state[(counter + (j * 4)) % 16];
counter++;
}
}
for (int i = 0; i < 16; i++)
{
state[i] = tempState[i];
}
}
void MixColumns(unsigned char* state)
{
unsigned char tempState[16];
int cnt = 0;
for (int cnt = 0; cnt <16; cnt+=4)
{
tempState[cnt] = (unsigned char)(lookUpTableFor02[state[cnt]] ^ lookUpTableFor02[state[cnt + 1]] ^ state[cnt + 1] ^ state[cnt + 2] ^ state[cnt + 3]);
tempState[cnt + 1] = (unsigned char)(state[cnt] ^ lookUpTableFor02[state[cnt + 1]] ^ lookUpTableFor02[state[cnt + 2]] ^ state[cnt + 2] ^ state[cnt + 3]);
tempState[cnt + 2] = (unsigned char)(state[cnt] ^ state[cnt + 1] ^ lookUpTableFor02[state[cnt + 2]] ^ lookUpTableFor02[state[cnt + 3]] ^ state[cnt + 3]);
tempState[cnt + 3] = (unsigned char)(lookUpTableFor02[state[cnt]] ^ state[cnt] ^ state[cnt + 1] ^ state[cnt + 2] ^ lookUpTableFor02[state[cnt + 3]]);
}
for (int i = 0; i < 16; i++)
{
state[i] = tempState[i];
}
}
void AddRoundKey(unsigned char* state, unsigned char* roundKey)
{
for (int i = 0; i < 16; i++)
{
state[i] = state[i] ^ roundKey[i];
}
}
void Encrypt(unsigned char* plaintext, unsigned char* key) {
unsigned char state[16];
const int numberOfRounds = 10;
const int numberOfColumns = 4;
unsigned char expandedKeys[176];
KeyExpansion(key, expandedKeys);
AddRoundKey(state, key);
for (int i = 0; i < numberOfRounds - 1; i++)
{
SubBytes(state);
ShiftRows(state);
MixColumns(state);
AddRoundKey(state, expandedKeys + (16 * (i + 1)));
}
SubBytes(state);
ShiftRows(state);
AddRoundKey(state, expandedKeys + 160);
for (int i = 0; i < 16; i++)
{
plaintext[i] = state[i];
}
}
void HexadecimalCout(unsigned char i)
{
if (i / 16 < 10) cout << (char)((i / 16) + '0');
if (i / 16 >= 10) cout << (char)((i / 16 - 10) + 'A');
if (i % 16 < 10) cout << (char)((i % 16) + '0');
if (i % 16 >= 10) cout << (char)((i % 16 - 10) + 'A');
}
int main() {
unsigned char plaintext[] = "this";
unsigned char key[16] =
{
1,2,3,4,
5,6,7,8,
9,10,11,12,
13,14,15,16 };
int lengthofPlainText = strlen((const char*)plaintext);
int lengthofSeperatedPT = lengthofPlainText;
if (lengthofSeperatedPT % 16 != 0)
lengthofSeperatedPT = (lengthofSeperatedPT / 16 + 1) * 16;
unsigned char* seperatedPT = new unsigned char[lengthofSeperatedPT];
for (int i = 0; i < lengthofSeperatedPT; i++)
{
if (i >= lengthofPlainText) seperatedPT[i] = 0;
else seperatedPT[i] = plaintext[i];
}
for (int i = 0; i < lengthofSeperatedPT; i += 16)
Encrypt(seperatedPT+i, key);
cout << "Encrypted message is:" << endl;
for (int i = 0; i < lengthofSeperatedPT; i++)
{
HexadecimalCout(seperatedPT[i]);
cout << " ";
}
return 0;
}
Encrypt
doesn't use the original values in plaintext
in any way. The only place plaintext
ever appears is on the left hand side of an assignment.