2021SC@SDUSC
上一章大致分析了AES在高级程序语言中的实现,这里再给出c++实现AES的完整源代码,帮助理解。
#include <iostream>
#include <cstdlib>
#include <stdio.h>
using namespace std;
typedef unsigned char byte;
struct word
{
byte wordKey[4];
};
class AES
{
public:
AES(){
initRcon();
};
// ~AES();
void setCipherKey(byte key[]);
void setPlainText(byte plain[]);
//
void keyExpansion(byte key[], word w[]);
word rotWord(word w);
word subWord(word w);
word wordXOR(word w1, word w2);
//functions in encryption and decryption
void encryption();
void processEncryption();
void addRoundKey(word in[], int round);
void subByte(word in[]);
void shiftRows(word in[]);
void mixColumn(word in[]);
byte GFMultiplyByte(byte L, byte R);
void decryption();
void processDecryption();
void invShiftRows(word in[]);
void invSubByte(word in[]);
void invMixColumn(word in[]);
void initRcon();
void showWord(word w[], int len);
void showMesage();
private:
byte cipherKey[16];
word plainText[4];
word cipherText[4];
word deCipherText[4];
static const int Nb=4, Nk=4, Nr=10;
word Rcon[11];
word wordKey[44];
static const byte SBox[16][16];
static const byte invSBox[16][16];
static const byte mixColumnMatrix[4][4];
static const byte invmixColumnMatrix[4][4];
};
void AES::showWord(word w[], int len){
int i,j;
for(i=0; i<len; i++){
for(j=0; j<4; j++){
printf("%x ", w[i].wordKey[j]);
}
}
cout<<endl;
}
void AES::showMesage(){
cout<<"plainText:"<<endl;
showWord(plainText, 4);
cout<<"wordKey:"<<endl;
showWord(wordKey, Nb*(Nr+1));
cout<<"cipherText:"<<endl;
showWord(cipherText, 4);
cout<<"deCipherText:"<<endl;
showWord(deCipherText, 4);
}
// initialize the plainText--trans plaintext from vector to state_matrix
void AES::setPlainText(byte plain[]){
int i;
for(i=0; i<16; i++){
plainText[i/4].wordKey[i%4] = plain[i];
}
}
//initialize the key--from vector to state_matrix
void AES::setCipherKey(byte key[]){
int i;
for(i=0; i<16; i++){
cipherKey[i] = key[i];
}
keyExpansion(cipherKey, wordKey);
}
//initialize the Rcon
void AES::initRcon(){
int i,j;
for(i=0; i<4; i++)
for(j=0; j<4; j++){
Rcon[i].wordKey[j] = 0x0;
}
Rcon[1].wordKey[0] = 0x01;
Rcon[2].wordKey[0] = 0x02;
Rcon[3].wordKey[0] = 0x04;
Rcon[4].wordKey[0] = 0x08;
Rcon[5].wordKey[0] = 0x10;
Rcon[6].wordKey[0] = 0x20;
Rcon[7].wordKey[0] = 0x40;
Rcon[8].wordKey[0] = 0x80;
Rcon[9].wordKey[0] = 0x1b;
Rcon[10].wordKey[0] = 0x36;
}
//initialize the const of mixColumn and invMixColumn
const byte AES::mixColumnMatrix[4][4] = {
{0x02, 0x03, 0x01, 0x01},
{0x01, 0x02, 0x03, 0x01},
{0x01, 0x01, 0x02, 0x03},
{0x03, 0x01, 0x01, 0x02}
};
const byte AES::invmixColumnMatrix[4][4] = {
{0x0e, 0x0b, 0x0d, 0x09},
{0x09, 0x0e, 0x0b, 0x0d},
{0x0d, 0x09, 0x0e, 0x0b},
{0x0b, 0x0d, 0x09, 0x0e}
};
//initialize SBox
const byte AES::SBox[16][16] = {
{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, 0xc