什么是AES?
AES 是一个对称分组密码算法,又称高级加密标准。
AES是一个区块加密标准,用于替代原本的DES,其已然成为对称密钥加密中最流行的算法之一。
这里主要实现AES算法中最基本的S盒。
S盒构造:
- 初始化:
在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位。
按照上面的步骤来实现代码:
全局变量和一些函数
int SBox[16][16];
// 将输入的整数的16进制对应字符返回,输入的整数在0~15之间
char dec2Hex(int n){
if(n >= 0 && n <= 9)return 48 + n;
switch(n){
case 10:return 'A';break;
case 11:return 'B';break;
case 12:return 'C';break;
case 13:return 'D';break;
case 14:return 'E';break;
case 15:return 'F';break;
}
return ' ';
}
初始化
void init(){
// SBox初始化
for(int i = 0 ; i < 16 ; i++){
if(i != 0)SBox[i][0] = SBox[i-1][15] + 1;
for(int j = 1 ; j < 16 ; j++){
SBox[i][j] = SBox[i][j-1] + 1;
}
}
printf("初始化:\n");
for(int i = 0 ; i < 16 ; i++){
for(int j = 0 ; j < 16 ; j++){
printf("%c%c ",dec2Hex(SBox[i][j] / 16) ,dec2Hex(SBox[i][j] % 16));
}
printf("\n");
}
printf("\n");
}
求逆元
void exgcd(){
printf("求逆元:\n");
for(int i = 0 ; i < 16 ; i++){
for(int j = 0 ; j < 16 ; j++){
// 重要的就是Ext_Euclid算法,是拓展欧几里得算法,用于求整数在域上的逆元,参考的网上前辈的代码,感谢。
SBox[i][j] = Ext_Euclid(SBox[i][j],283);
// dec2Hex:将整数转为16进制
printf("%c%c ",dec2Hex(SBox[i][j] / 16) ,dec2Hex(SBox[i][j] % 16));
}
printf("\n");
}
}
//计算一个十进制数的二进制表示时的位数有多大
//直接计算右移了多少位就可
int numb_bits(int v)
{
int count=0;
while(v>0)
{
v=v>>1;
count++;
}
return count;
}
//多项式除法
int polydivide(int a,int b,int *remainder )
{
int tmp;
int c=numb_bits(a)-numb_bits(b);
int value=0;
while(c>=0)
{
value=(1<>7) //b7为1,就要与00011011相与
value=(value<<1) & 0xff ^27;
else
value=(value<<1) & 0xff;
if(r) //位为1的结果就参加异或运算
result=result ^ value;
}
return result;
}
//扩展的欧几里德算法
int Ext_Euclid(int a,int b)
{
int tmp;
if(a
位变换
void transforms(){
for(int i = 0 , j = 0 ; i < 16 ; i++){
for(j = 0 ; j < 16 ; j++){
SBox[i][j] = transform(SBox[i][j]);
}
}
}
int transform(int num){
int n[8];
int b[8];
// int c[8] = {0,1,1,0,0,0,1,1};
int c[8] = {1,1,0,0,0,1,1,0};
int i = 0;
for(i = 0 ; i < 8 ; i++){
n[i] = num % 2;
num /= 2;
}
int j = 1;
for(i = 0 , num = 0 ; i < 8 ; i++){
// 使用二进制移位来做更好,偷懒就不做了。
b[i] = n[i] ^ n[(i+4)%8]
^ n[(i+5)%8]
^ n[(i+6)%8]
^ n[(i+7)%8]
^ c[i];
num += b[i] * j;
j *= 2;
}
return num;
}
以上部分就是生成AES中的S盒的过程。