ComSec作业二: AES
1、描述AES中S-Box的生成过程。
(1)初始化s-box。用两个十六进制数表示为xy,x为行数,y为列数(从第0行第0列开始)
(2)将s-box中的值映射成其乘法逆元。
(3)R(b_i) = b_i ⊕ b_[(i+4) mod 8] ⊕ b_[(i+5) mod 8] ⊕ b_[(i+6) mod 8] ⊕ b_[(i+7) mod 8] ⊕ c_i
其中c_i为固定字节{63}的第i位。
2、证明公式6.9与公式6.4等价。
由6.9式:s0,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)]
=2·s0,j+3·s1,j⊕s2,j’⊕s3,j’
其它行道理亦然。
3、写一个GF(28) 的乘法函数Mul,输入GF(28)的两个元素a、b,输出a * b 。提示:回忆CINTA的Simple Multiplication。
#include<iostream>
using namespace std;
//乘2
unsigned char cheng2(unsigned char x)
{
bool maxWei = false;;//最高位是否为1
if (x >> 7)maxWei = true;
x = x << 1;
if (maxWei)
x = x ^ 0x1b;
return x;
}
unsigned char mutiply(unsigned char a, unsigned char b)
{
unsigned char c = 0x0,temp=int(a);
//cout <<"temp:"<< int(temp) << endl;
//a不变,拆b
for (int i = 0; i < 8; i++)
{
//查看该位上是否是1,如果是一,经过该变换,if语句为true,否则为false
int num = int(((b >> i) << 7));
while (num >= 256)num -= 256;
if (unsigned char(num))//
c =c^ temp;
temp = cheng2(temp);
}
return c;
}
原理比较简单,对于a*b,将b的二进制诸位拆分分别与a相乘(即左移),如果有溢出(最高位位 1),则还要异或0x1b,最后将结果相加即可
4、写一个程序,生成AES算法中的S-Box。
#include<iostream>
#include<iomanip>
#include<bitset>
using namespace std;
unsigned char sBox[16][16];
//乘2
unsigned char cheng2(unsigned char x)
{
bool maxWei = false;;//最高位是否为1
if (x >> 7)maxWei = true;
x = x << 1;
if (maxWei)
x = x ^ 0x1b;
return x;
}
unsigned char mutiply(unsigned char a, unsigned char b)
{
unsigned char c = 0x0, temp = int(a);
//cout <<"temp:"<< int(temp) << endl;
//a不变,拆b
for (int i = 0; i < 8; i++)
{
//查看该位上是否是1,如果是一,经过该变换,if语句为true,否则为false
int num = int(((b >> i) << 7));
while (num >= 256)num -= 256;
if (unsigned char(num))//
c = c ^ temp;
temp = cheng2(temp);
}
return c;
}
//初始化s-box,使其第i行第j列为ij
void initialize()
{
unsigned char i = 0;
for (i=0; i <= 0x0f; i++)
{
for (unsigned char j=0; j<= 0x0f; j++)
{
sBox[i][j] = (i << 4) + j;
}
}
}
void showSBox()
{
cout << endl;
for (int i = 0; i < 16; i++)
{
for (int j = 0; j < 16; j++)
{
cout << setw(5) <<hex<< int(sBox[i][j]);//
}
cout << endl;
}
}
//用egcd算法求a mod b 的逆元,b=0x11b
//a mod b, b > a,a,b 互素
//w1 = 1 w2 = 0 b
//q1 = 0 q2 = 1 a k = b / a
//temp1=w1 - kq1 temp2=w2 - kq2 temp3=b - ka (== 1)out, 取w2 - kq2
int egcd(int a,int b=283)
{
int c = b;
if (a == 0)return 0;
if (a == 1)return 1;
int w1 = 1, w2 = 0;
int q1 = 0, q2 = 1;
while (true)
{
int k = int(b / a);
int temp1 = w1 - k * q1, temp2 = w2 - k * q2, temp3 = b - k * a;
if (temp3 == 1)
{
if (temp2 > 0)return temp2;
else return int( temp2+c );
}
w1 = q1; w2 = q2; b = a;
q1 = temp1; q2 = temp2; a = temp3;
}
}
//B'=X*B xor {63}
void initialize2()
{
for (int i = 0; i < 16; i++)
{
for (int j = 0; j < 16; j++)
{
int temp = egcd(int(sBox[i][j]));
unsigned char ch = temp;
sBox[i][j] = ch;
}
}
}
unsigned char chengJuZhen(unsigned char a)//乘一个矩阵
{
//R(b_i) = b_i ⊕ b_[(i + 4) mod 8] ⊕ b_[(i + 5) mod 8] ⊕ b_[(i + 6) mod 8] ⊕ b_[(i + 7) mod 8] ⊕ c_i
bitset<8> bi(a);
bitset<8> r(a);
bitset<8> c("01100011");
for (int i = 0; i < 8; i++)
{
r[i] = bi[(i + 4) % 8] ^ bi[(i + 5) % 8] ^ bi[(i + 6) % 8] ^ bi[(i + 7) % 8] ^ c[i];
}
unsigned char rech = r.to_ulong();
return rech;
}
void initialize3()
{
for (int i = 0; i < 16; i++)
{
for (int j = 0; j < 16; j++)
{
sBox[i][j] = chengJuZhen(sBox[i][j]);
}
}
}
求s-box的第一步和第三步比较好实现,直接套公式就行了,主要是第二部求逆元,这就要想到之前学习的内容了,经判断,这是一个求mod m(x)的逆元的问题,m(x)=x8+x4+x3+x+1,运用到拓展欧几里得即可解出