ComSec 作业二 AES
欢迎
①描述AES中S-Box的生成过程
AES中的S-Box是用来对明文分组或加密过程中产生的分组进行字节代替的16✖16字节的方阵工具,其大致生成过程如下:
-
生成一个16行×16列,共256块的方阵,每一块以字节为单位,第x行第y列的块其取值为十六进制{xy};
-
S-box中的每一个块(字节)映射为其在GF(2^8)中对应的乘法逆元;
-
利用公式对每个块的位进行变换:
每个字节块记为 [b7,b6,b5,b4,b3,b2,b1,b0]
变换后记为 [b7’,b6’,b5’,b4’,b3’,b2’,b1’,b0’]
公式:
bi’ = bi ⊕ bi+4(mod8)⊕bi+5(mod8)⊕bi+6(mod8)⊕bi+7(mod8)⊕Ci
其中 Ci 为十六进制{63} 的第i位
自此AES的S-box即生成。
②证明公式6.9与公式6.4等价
6.9公式
6.4公式
证明:
异或运算符合交换律和分配律
s’0,j = s0,j⊕Tmp⊕[2(s0,j⊕s1,j)]
=s0,j⊕s0,j⊕s1,j⊕s2,j⊕s3,j⊕[2(s0,j⊕s1,j)]
=s1,j⊕s2,j⊕s3,j⊕[2(s0,j⊕s1,j)]
=2s0,j⊕3s1,j⊕s2,j⊕s3,j
s’1,j = s1,j⊕Tmp⊕[2(s1,j⊕s2,j)]
=s1,j⊕s0,j⊕s1,j⊕s2,j⊕s3,j⊕[2(s1,j⊕s2,j)]
=s0,j⊕s2,j⊕s3,j⊕[2(s1,j⊕s2,j)]
=s0,j⊕2s1,j⊕3s2,j⊕s3,j
s’2,j = s2,j⊕Tmp⊕[2(s2,j⊕s3,j)]
=s2,j⊕s0,j⊕s1,j⊕s2,j⊕s3,j⊕[2(s2,j⊕s3,j)]
=s0,j⊕s1,j⊕s3,j⊕[2(s2,j⊕s3,j)]
=s0,j⊕s1,j⊕2s2,j⊕3s3,j
s’3,j = s3,j⊕Tmp⊕[2(s3,j⊕s0,j)]
=s3,j⊕s0,j⊕s1,j⊕s2,j⊕s3,j⊕[2(s3,j⊕s0,j)]
=s0,j⊕s1,j⊕s2,j⊕[2(s3,j⊕s0,j)]
=3s0,j⊕s1,j⊕s2,j⊕2s3,j
得证俩公式等价。
③写一个GF(28)的乘法函数Mul,输入GF(28)的两个元素a、b,输出a * b 。提示:回忆CINTA的Simple Multiplication。
#include<iostream>
#include<string>
#include<vector>
class GFTool{
public:
GFTool(){};
static std::string mul(std::string,std::string);
static std::string add(std::string,std::string);
static bool* string2bool(std::string);
static std::string bool2string(bool*,int);
protected:
static const std::string toolPolynomial;
};
const std::string GFTool::toolPolynomial = "100011011";
std::string GFTool::mul(std::string GFA,std::string GFB){
std::string result="0000000000000000";
bool* gfa;
bool* gfb;
bool tool[8][16]={0};
std::string toolstr[8];
int toolNum=0;
bool* gfc;
bool* polynomial = string2bool(toolPolynomial);
gfa = string2bool(GFA);
gfb = string2bool(GFB);
for(int i=0;i<8;i++){
if(GFB[i]=='1'){
for(int j=0;j<8;j++){
tool[toolNum][j+7-i]=gfa[j];
}
toolstr[toolNum] = bool2string(tool[toolNum],16);
toolNum++;
}
}
for(int i=0;i<toolNum;i++){
result = add(result,toolstr[i]);
}
int pc=0;
int x=0;
while(true){
for(int z=0;z<16;z++)
tool[0][z]=0;
gfc = string2bool(result);
for(pc=15;pc>=0;pc--)
if(gfc[pc]==1) break;
if(pc<8) break;
else{
x = pc-8;
for(int j=0;j<=8;j++){
tool[0][j+x]=polynomial[j];
}
toolstr[0] = bool2string(tool[0],16);
result = add(result,toolstr[0]);
}
};
delete []gfa;
delete []gfb;
result = result.substr(8,15);
return result;
}
测试结果:
完整代码见:
https://github.com/LimMiayong/ResourcePool
④写一个程序,生成AES算法中的S-Box。
#include<iostream>
#include<cmath>
struct block_byte{
block_byte(){
for(int i=0;i<8;i++)
eight[i]=0;
X=0;Y=0;
}
bool eight[8];
int X,Y;
// 0123 4567
// 0000 0000
// Y X
//XY = {20} --> 0010 0000 --> eight: 0000 0100
void XY2eight(int x,int y){
X=x;Y=y;
for(int i=7;i>=0;i--){
if(i>=4){
if(x>=pow(2,i-4)){
eight[i]=1;
x-=pow(2,i-4);
}
}
else{
if(y>=pow(2,i)){
eight[i]=1;
y-=pow(2,i);
}
}
}
}
void eight2XY(){
X=0;Y=0;
for(int i=7;i>3;i--)
X+= eight[i]*pow(2,i-4);
for(int i=3;i>=0;i--)
Y+= eight[i]*pow(2,i);
}
};
class S_box{
public:
S_box(){
C.XY2eight(6,3);
build();
}
void build();
void display();
protected:
block_byte box[16][16];
block_byte C; //used by S_box.build()'s step3
};
void S_box::build(){
//firststep
for(int i=0;i<16;i++)
for(int j=0;j<16;j++)
box[i][j].XY2eight(i,j);
std::cout<<"After first step:\n";
display();
//secondstep //the author is lazy and this part not finished yet
// get inverse
bool *here=NULL;
for(int i=0;i<16;i++)
for(int j=0;j<16;j++){
here = box[i][j].eight;
//getInverse(here);
}
//std::cout<<"After second step:\n";
//display();
//thirdstep
for(int i=0;i<16;i++)
for(int j=0;j<16;j++){
here = box[i][j].eight;
for(int z=0;z<8;z++){
here[z]=(here[z]+here[(z+4)%8]+here[(z+6)%8]+here[(z+7)%8]+C.eight[z])%2;
}
}
// change by bit
std::cout<<"After third step:\n";
display();
}
void S_box::display(){
for(int i=0;i<16;i++){
for(int j=0;j<16;j++){
box[i][j].eight2XY();
std::cout<<box[i][j].X<<","<<box[i][j].Y<<" ";
}
std::cout<<std::endl;
}
}