AES加解密实现

AES加解密实现

代码如下,输入例子为《密码编码学与网络安全——原理与实践(第七版)》中的示例
明文:0123456789abcdeffedcba9876543210
密钥:0f 15 71 c9 47 d9 e8 59 0c b7 ad d6 af 7f 67 98
密文:ff0b844a0853bf7c6934ab4364148fb9

//S盒步骤:初始化,求在有限域中的逆,字节变换
//逆S盒步骤:初始化,字节变换,求在有限域中的逆 
//AES加密步骤:对明文进行第0轮轮密钥加,进行9轮(字节代替、行变换、列混淆、轮密钥加),再进行字节代替、行变换、第10轮的轮密钥加
//AES揭秘步骤 :对密文进行第10轮轮密钥加以及逆向行变换、逆向字节代替,进行9轮( 轮密钥加、逆向列混淆、逆向行变换、逆向字节代替),最后进行第0轮的轮密钥加 
//密钥太难输入了,直接把密钥保存在了程序里,
#include<cstdio>

int i,j;
unsigned char S[16][16],IS[16][16];  //盒子S
unsigned char w[4][44];
unsigned char ExEuclid(unsigned char b); 
unsigned char RC[10] = {
   0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1B,0x36};
unsigned char l[4][4]={
   0x02,0x03,0x01,0x01,
0x01,0x02,0x03,0x01,
0x01,0x01,0x02,0x03,
0x03,0x01,0x01,0x02};   //列混淆变换正向矩阵 
unsigned char Il[4][4]={
   0x0E,0x0B,0x0D,0x09,
0x09,0x0E,0x0B,0x0D,
0x0D,0x09,0x0E,0x0B,
0x0B,0x0D,0x09,0x0E};    //列混淆变换逆向矩阵 
unsigned char M[4][4];
unsigned char mc[4][4];
unsigned char Imc[4][4];


void initialize()  //初始化盒子S
{
   
	for(i=0;i<=0xF;i++)
	{
   
		for(j=0;j<=0xF;j++)
		{
   
			S[i][j]=((i << 4) + j);
			//printf("%02X ",S[i][j]);
			S[i][j]=ExEuclid(S[i][j]);
		}
		//printf("\n");
	}
 } 
 

unsigned char msb(unsigned short num) //求出非0最高位 
{
   
    unsigned char i;
    for(i = 0; i <= 8; i++)
    {
   
        if(!(num >> (i + 1)))
        {
   
            return i;
        }
    }
}


 unsigned char multiply(unsigned char a, unsigned char b)    //乘法实现 
{
   
	unsigned char hex=0x00;
	int d[16], s[32];
	int n = b, cnt = 0;
	while (n)///转化为二进制
	{
   
		s[cnt++] = n % 2;
		n /= 2;
	}
	if (cnt < 8)
	{
   
		for (;cnt < 8;cnt++)
			s[cnt] = 0;
	}//防止出现后面的位数为0的情况 
	d[0] = a;

	for (int i = 0; i <= 7; i++)
	{
   
		if (d[i] & 0x80)///如果最高为为1就对不可约多项式取模,否则直接左移
			d[i + 1] = ((d[i] << 1) ^ 0x1B);
		else
			d[i + 1] = d[i] << 1;
		d[i] &= 0xFF;

		if (s[i] == 1)///当二进制的这一位为1的时候才能异或
			hex ^= d[i];
	}
    return hex;
}

unsigned char divide(unsigned short a, unsigned char b, unsigned char &r,unsigned char q)  //除法实现 
{
   
    unsigned char a_msb = msb(a);  //求出非0的最高位 ,a为0x11B,b为要求逆元的字段 
    unsigned char b_msb = msb(b);
    if(a < b)  //重复步骤知道被除数a小于除数b,除法运算结束 
    {
   
        r = a;  //此时的a为余数,记录下来便于以后的运算 
        return q;
    }
    unsigned char bit = a_msb - b_msb;
    unsigned short temp = b;
    temp = temp << bit; 
    a = a ^ temp;   //将b左移也就是乘上bit后两者最高位相同,a^temp也就是a减去temp,最终能够得到a除以b的余数 
    q = q ^ (1 << bit);   //将移位记录下来得到除法运算中的积 
    return divide(a, b, r,q);
}


unsigned char ExEuclid(unsigned char b)   //求逆元 
{
   
    if(b == 0)
        return 0;

    short r0 = 0x11B;
    unsigned char r1 = b, r2, q = 0x00;  //r1为需要求逆元的字节 
    unsigned char w0 = 0, w1 = 1, w2;
    q=divide(r0, r1 , r2,q);
    w2 = w0 ^ multiply(q, w1); //w2=w0-q2*w1 扩展的欧几里得算法 
    while(1)
    {
   
	    if(r2 == 0)  //余数不为0,进行循环 
            break;
    	q = 0x00;
        r0 = r1;   
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值