ComSec_HW2 AES

欢迎

①描述AES中S-Box的生成过程

AES中的S-Box是用来对明文分组或加密过程中产生的分组进行字节代替的16✖16字节的方阵工具,其大致生成过程如下:

  1. 生成一个16行×16列,共256块的方阵,每一块以字节为单位,第x行第y列的块其取值为十六进制{xy};
    在这里插入图片描述

  2. S-box中的每一个块(字节)映射为其在GF(2^8)中对应的乘法逆元;

  3. 利用公式对每个块的位进行变换:

    每个字节块记为 [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.9 公式
6.4公式
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;
    }

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值