1、描述AES中S-Box的生成过程。
2、证明公式6.9与公式6.4等价。
3、写一个GF(2^8)的乘法函数Mul,输入GF(2^8)的两个元素a、b,输出a * b 。提示:回忆CINTA的Simple Multiplication。
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
using namespace std;
unsigned char XTIME(unsigned char x) ; //求一个数x与0x02的乘积
unsigned char Mul(unsigned char a, unsigned char b) ; //GF(2^8)的乘法函数
unsigned char XTIME(unsigned char x) {
return ((x << 1) ^ ((x & 0x80) ? 0x1b : 0x00));
}
unsigned char Mul(unsigned char a, unsigned char b) {
unsigned char temp[8] = { a };
unsigned char tempmultiply = 0x00;
int i = 0;
for (i = 1; i < 8; i++) {
temp[i] = XTIME(temp[i - 1]); //生成0x01,0x02等 8个数
}
tempmultiply = (b & 0x01) * a;
for (i = 1; i <= 7; i++) {
tempmultiply ^= (((b >> i) & 0x01) * temp[i]);
}
return tempmultiply;
}
int main()
{
int a,b;
cout<<"输入 a 和 b 的值"<<endl;
scanf("%x", &a);
scanf("%x", &b);
//cin>>a>>b;
cout <<"a*b = ";
printf("%#X", Mul(a, b));
cout<<endl;
return 0;
}
4、写一个程序,生成AES算法中的S-Box。
#include<iostream>
#include <cstdio>
using namespace std;
typedef unsigned char uc;
uc sbox[16][16];
//初始化 sbox[i][j] <- {ij}
void initialize();
//找到非零最高位并返回
uc msb(unsigned short num);
//一个字节的多项式除法,返回商(a/b)
uc divide(unsigned short a, uc b, uc &r);
//GF(2^8)乘法,返回a * b
uc multiply(uc a, uc b);
//扩展欧几里得算法求b在GF(2^8)的乘法逆元
uc inverse(uc b);
//映射
uc map(uc a);
int main()
{
initialize();
uc i, j;
for(i = 0; i <= 0xF; i++)
{
printf("\n");
for(j = 0; j <= 0xF; j++)
{
sbox[i][j] = map(sbox[i][j]);
printf("%02X ",sbox[i][j]);
}
}
return 0;
}
void initialize()
{
uc i, j;
for(i = 0; i <= 0xF; i++)
{
for(j = 0; j <= 0xF; j++)
{
sbox[i][j] = inverse((i << 4) + j);
}
}
}
uc msb(unsigned short num)
{
uc i;
for(i = 0; i <= 8; i++)
{
if(!(num >> (i + 1)))
{
return i;
}
}
}
uc divide(unsigned short a, uc b, uc &r)
{
uc a_msb = msb(a);
uc b_msb = msb(b);
if(a < b)
{
r = a;
return 0;
}
uc bit = a_msb - b_msb;
unsigned short temp = b;
temp = temp << bit;
a = a ^ temp;
return (1 << bit) | divide(a, b, r);
}
uc multiply(uc a, uc b)
{
uc res = 0;
if(b & 0x01)
{
res = a;
}
for (uc i = 1; i < 8; i++)
{
if(b & (0x01 << i))
{
uc temp = a;
for(uc j = 0; j < i; j++)
{
if(!(temp & 0x80))
{
temp <<= 1;
}
else
{
temp <<= 1;
temp = temp ^ 0x1B;
}
}
res = res ^ temp;
}
}
return res;
}
uc inverse(uc b)
{
if(b == 0)
return 0;
short r0 = 0x11B;
uc r1 = b, r2, q;
uc w0 = 0, w1 = 1, w2;
q = divide(r0, r1 , r2);
w2 = w0 ^ multiply(q, w1);
while(1)
{
if(r2 == 0)
break;
r0 = r1;
r1 = r2;
q = divide(r0, r1, r2);
w0 = w1;
w1 = w2;
w2 = w0 ^ multiply(q, w1);
}
return w1;
}
uc map(uc a)
{
uc c = 0x63;
uc res = 0x0;
uc temp = 0x0;
uc i;
for(i = 0; i < 8; i++)
{
temp = temp ^ ((a >> i) & 0x1) ^ ((a >> ((i + 4) % 8)) & 0x1);//优先级>> 高于 &
temp = temp ^ ((a >> ((i + 5) % 8)) & 0x1) ^ ((a >> ((i + 6) % 8)) & 0x1);
temp = temp ^ ((a >> ((i + 7) % 8)) & 0x1) ^ ((c >> i) & 0x1);
res = res | (temp << i);
temp = 0x0;
}
return res;
}