1.SBOX的生成过程
初始化:
在S盒中按字节的升序逐行初始化S盒。即从第一行:{00},{01},{02},…,{0f}进行初始化,第二行是{10},{11},{12},…,{1F}。
求逆元:
将S盒中的每个元素转化为该元素在域GF(28)上的逆元。
位变换:
将S盒中的每个字节的位记为{b7,b6,b5,b4,b3,b2,b1,b0}。对S盒的每个字节的每个位做如下变换:
bi’ = bi⊕b(i+4)mod8⊕b(i+5)mod8⊕b(i+6)mod8⊕b(i+7)mod8⊕ci
ci指的是值{63}的字节的第i位。
2.证明公式6.9与公式6.4等价
公式6.4
公式6.9
证明如下:
3.GF(2^8)中的乘法与加法
#include <cstdio>
#include<iostream>
#include <iomanip>
using namespace std;
unsigned char GF_add(unsigned char a,unsigned char b){
return a^b;
}
unsigned char GF_multi(unsigned char a,unsigned char b){
if(a==0)return 0;
else if(a==1)return b;
else if(a==2){
if((b&0x80)>0)return GF_add(b<<1,0x1b);
else return b<<1;
}
else{
if(a&1)return GF_add(GF_multi(a&0xfe,b),b);//第一位是1
else return GF_multi(a>>1,GF_multi(2,b));//第一位是0
}
}
4.SBOX的生成程序
#include <cstdio>
#include<iostream>
using namespace std;
unsigned char S_box[16][16];
//获取最高位
unsigned char getH(unsigned short Number)
{
int i = 0;
while (Number)
{
i++;
Number = Number >> 1;
}
return i;
}
//GF(2^8)多项式除法
unsigned char divide(unsigned short a, unsigned char b, unsigned char& r)
{
unsigned char a_getH = getH(a);
unsigned char b_getH = getH(b);
if (a < b)
{
r = a;
return 0;
}
unsigned char bit = a_getH - b_getH;
unsigned short tmp = b;
tmp = tmp << bit;
a = a ^ tmp;
return (1 << bit) | divide(a, b, r);
}
//GF(2^8)多项式除法
unsigned char Mul(unsigned char a, unsigned char b) {
unsigned char res = 0; //运算结果
while (a)
{
if (a & 0x01) //若a的最低位为1,则异或b
{
res ^= b;
}
a = a >> 1; //a左移一位
if (b & 0x80) //若b的最高位为1,则异或不可约多项式,防止溢出
{
b ^= 0x1b;
}
else //否则b左移一位
{
b = b << 1;
}
}
return res;
}
//EEA为GF(2)上的egcd算法,即求输入数据b的乘法逆元
unsigned char EEA(unsigned char b)
{
if (b == 0)
return 0;
short r0 = 0x11B;
unsigned char r1 = b, r2, q;
unsigned char w0 = 0, w1 = 1, w2;
q = divide(r0, r1, r2);
w2 = w0 ^ Mul(q, w1);
while (1)
{
if (r2 == 0)
break;
r0 = r1;
r1 = r2;
q = divide(r0, r1, r2);
w0 = w1;
w1 = w2;
w2 = w0 ^ Mul(q, w1);
}
return w1;
}
//得到S_Box
unsigned char getBox(unsigned char a)
{
unsigned char c = 0x63;
unsigned char res = 0x0;
unsigned char temp = 0x0;
unsigned char 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;
}
int main()
{
unsigned char i, j;
for (i = 0; i <= 0xF; i++)
{
for (j = 0; j <= 0xF; j++)
{
S_box[i][j] = EEA(i*16 + j); //使第i行第j列的元素为{xj}
}
}//初始化矩阵
for (i = 0; i <= 0xF; i++)
{
if (i != 0)printf("\n");
for (j = 0; j <= 0xF; j++)
{
S_box[i][j] = getBox(S_box[i][j]);
printf("%02X ", S_box[i][j]);
}
}
return 0;
}