0


S-AES加密实现

S-AES加密实现

S-AES是AES的简化版本,其只使用了16位的明文和16位的密钥进行加密。以下介绍S-AES的加密步骤。

测试数据:使用密钥

1010 0111 0011 1011

加密二进制明文

0110 1111 0110 1011

,得出二进制密文

0000 0111 0011 1000

总体加密思路

简化版的AES和原本AES的步骤差不多,只是在轮数和一些运算的字节数上有不同。

S-AES加密的整体步骤示意图如下

在这里插入图片描述

接下来从扩展密钥到明文加密开始进行步骤阐述。

密钥扩展

由于只需要加密两轮,因此只需要扩展出两个密钥即可,包括原始密钥总共6个字节。扩展密钥步骤的示意图如下

在这里插入图片描述

将16位密钥分为左右两部分,每一部分各8位。记原始密钥为第0个密钥。

在计算第

i

个密钥时,首先将第

i-1

个密钥的右半部分(8位)进行左循环移位,即将第

i-1

个密钥的右半部分的左右4位进行交换,再将左循环移位后的第

i-1

个密钥的右半部分(8位)进行S盒置换,S-AES的S盒定义如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3QD1YPZN-1665906607044)(C:\Users\YYYYYKN\AppData\Roaming\Typora\typora-user-images\image-20221016153622241.png)]

进行S盒置换后需要与轮常数进行异或,S-AES的轮常数定义为:第一轮加密的轮常数是【1000 0000】,第二轮加密的轮常数是【0011 0000】。

上述步骤就是示意图中函数

g

的步骤,将第

i-1

个密钥的右半部分(8位)执行完上述步骤后得到

g(第i-1个密钥的右半部分)

,将其与第

i-1

个密钥的左半部分(8位)进行异或得到第

i

个密钥的左半部分。

i

个密钥的右半部分由第

i

个密钥的左半部分与第

i-1

个密钥的右半部分进行异或得到。

计算出的两个扩展密钥是:

key1:0001 1100 0010 0111 
key2:0111 0110 0101 0001

明文加密

第0轮加密

只有将明文进行轮密钥加操作,即把明文按位与第0个密钥(原始输入密钥)进行异或。以下统称每一步骤处理完的都为明文。

第1轮加密

半字节代替

使用S盒将明文进行半字节的代替,就是一个简单的查表。具体步骤为:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Eqgzqjub-1665906607045)(C:\Users\YYYYYKN\AppData\Roaming\Typora\typora-user-images\image-20221016154406870.png)]

行位移

将一个字节排列成两行一列,即一行有四位,第二个字节按照这种方式形成第二列。第一行不进行移位,第二行循环左移位,一次移动

4

位。示例如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jzkSRINX-1665906607046)(C:\Users\YYYYYKN\AppData\Roaming\Typora\typora-user-images\image-20221016154521276.png)]

其中60是一个字节,4C是一个字节。

列混淆

简单来说列混淆就是乘上一个矩阵,运算定义在

    G
   
   
    F
   
   
    (
   
   
    
     2
    
    
     4
    
   
   
    )
   
  
  
   GF(2^4)
  
 
GF(24) 上。列混淆矩阵是:

在这里插入图片描述

则与明文进行运算示意图为:

其中等式左边的右侧矩阵为明文,

     S
    
    
     
      0
     
     
      ,
     
     
      0
     
    
   
  
  
   S_{0,0}
  
 
S0,0​ 和 

 
  
   
    
     S
    
    
     
      1
     
     
      ,
     
     
      0
     
    
   
  
  
   S_{1,0}
  
 
S1,0​ 是一个字节,各为4位。

 
  
   
    
     S
    
    
     
      0
     
     
      ,
     
     
      1
     
    
   
  
  
   S_{0,1}
  
 
S0,1​ 和 

 
  
   
    
     S
    
    
     
      1
     
     
      ,
     
     
      1
     
    
   
  
  
   S_{1,1}
  
 
S1,1​ 是一个字节,各为4位。执行乘法后可得到:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sArVGzXx-1665906607050)(C:\Users\YYYYYKN\AppData\Roaming\Typora\typora-user-images\image-20221016154711311.png)]

示意图右边即为列混淆后的结果。

第2轮加密

进行第二轮加密时,只有半字节代替,行移位和轮密钥加三个步骤,具体过程和第一轮一样,轮密钥加使用的是扩展密钥2即

key2

经过上述步骤之后的结果就是密文了。

程序实现(C++)

#include<bits/stdc++.h>usingnamespace std;// TODO 实现x^nfx的函数voidx_de_n_fang_cheng_fx(int xfx[4],int a[4])//* xfx是结果,a是上一步的结果{//! 注意要取模//! 既约多项式是 x^4 + x + 1//* 保存四次乘法的系数if(a[0]==0){for(int i =0; i <3; i++)
            xfx[i]= a[i +1];}else{//! 如果乘数首项不为1就需要将 b1x^2+b0x 与 x+1 进行异或
        xfx[1]= a[2];
        xfx[2]= a[3]==1?0:1;
        xfx[3]=1;}}// TODO 乘法int*chengfa(int a[4],int b[4]){//* 储存结果的系数int*result =newint[4];for(int i =0; i <4; i++)
        result[i]=0;//* 记录下x^nfxint xfx[4]={0};x_de_n_fang_cheng_fx(xfx, a);int x2fx[4]={0};x_de_n_fang_cheng_fx(x2fx, xfx);int x3fx[4]={0};x_de_n_fang_cheng_fx(x3fx, x2fx);//* 现在需要根据多项式a和b开始异或if(b[0]==1)for(int i =0; i <4; i++)
            result[i]^= x3fx[i];if(b[1]==1)for(int i =0; i <4; i++)
            result[i]^= x2fx[i];if(b[2]==1)for(int i =0; i <4; i++)
            result[i]^= xfx[i];if(b[3]==1)for(int i =0; i <4; i++)
            result[i]^= a[i];return result;}constint s[4][4]={{9,4,10,11},{13,1,8,5},{6,2,0,3},{12,14,15,7}};constint tihuanwei[16][4]={{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1},{0,1,0,0},{0,1,0,1},{0,1,1,0},{0,1,1,1},{1,0,0,0},{1,0,0,1},{1,0,1,0},{1,0,1,1},{1,1,0,0},{1,1,0,1},{1,1,1,0},{1,1,1,1}};// const int tihuanwei[4][4][4] = {//     {{1, 0, 0, 1},{0, 1, 0, 0},{1, 0, 1, 0},{1, 0, 1, 1}},//     {{1, 1, 0, 1},{0, 0, 0, 1},{1,0,0,0},{0,1,0,1}},//     {{0,1,1,0},{0,0,1,0},{0,0,0,0},{0,0,1,1}},//     {{1,1,0,0},{1,1,1,0},{1,1,1,1},{0,1,1,1}}};//* 定义轮常数int rcon1[8]={1,0,0,0,0,0,0,0};int rcon2[8]={0,0,1,1,0,0,0,0};int*yihuo8(int*a,int*b)//8位的异或{int*t =newint[8];for(int i =0; i <8; i++)
        t[i]= a[i]^ b[i];return t;}int*yihuo4(int*a,int*b)//4位的异或{int*t =newint[4];for(int i =0; i <4; i++)
        t[i]= a[i]^ b[i];return t;}voids_he_tihuan(int*temp)//使用s盒替换的函数,8位换{int t1 =2* temp[0]+ temp[1];int t2 =2* temp[2]+ temp[3];int t3 =2* temp[4]+ temp[5];int t4 =2* temp[6]+ temp[7];int tihuan1 = s[t1][t2];//记录替换后的数字int tihuan2 = s[t3][t4];//* 四位四位进行替换for(int i =0; i <4; i++)
        temp[i]= tihuanwei[tihuan1][i];for(int i =0; i <4; i++)
        temp[i +4]= tihuanwei[tihuan2][i];}voidzuoyi(int**temp)//循环左移{//! 掉大坑!!!!注意半字节排列的方式,这里应该是第一字节的右半部分和第二字节的右半部分进行替换for(int i =4;i <8;i ++){int t = temp[0][i];
        temp[0][i]= temp[1][i];
        temp[1][i]= t;}}int*g(int*temp,int*rcon)// temp是一个八位的数组,rcon是轮常数{//! 注意这个temp是密钥,不能改动,要复制一个新的进行计算int*t =newint[8];for(int i =0; i <8; i++)
        t[i]= temp[i];//* 循环左移for(int i =0; i <4; i++){int tt = t[i +4];
        t[i +4]= t[i];
        t[i]= tt;}//* 进行s盒替换s_he_tihuan(t);//* 进行轮常数异或returnyihuo8(t, rcon);}voidliehunxiao(int**mingwen){int si_de2jinzhi[4]={0,1,0,0};int*m00 =newint[4];int*m10 =newint[4];int*m01 =newint[4];int*m11 =newint[4];for(int i =0; i <4; i++){
        m00[i]= mingwen[0][i];
        m10[i]= mingwen[0][i +4];
        m01[i]= mingwen[1][i];
        m11[i]= mingwen[1][i +4];}int*n00 =newint[4];int*n10 =newint[4];int*n01 =newint[4];int*n11 =newint[4];
    n00 =yihuo4(m00,chengfa(si_de2jinzhi, m10));//乘法结果是1011
    n10 =yihuo4(chengfa(si_de2jinzhi, m00), m10);//0101
    n01 =yihuo4(m01,chengfa(si_de2jinzhi, m11));//0100
    n11 =yihuo4(chengfa(si_de2jinzhi, m01), m11);//0010for(int i =0; i <4; i++){
        mingwen[0][i]= n00[i];
        mingwen[0][i +4]= n10[i];
        mingwen[1][i]= n01[i];
        mingwen[1][i +4]= n11[i];}}voidlunmiyaojia(int**mingwen,int**key){for(int i =0; i <2; i++)for(int j =0; j <8; j++)
            mingwen[i][j]^= key[i][j];}//用于输出voidshuchu(int**a){for(int i =0; i <2; i++)for(int j =0; j <8; j++)
            cout << a[i][j]<<' ';
    cout << endl;}intmain(){//* 输入明文和密钥int**mingwen =newint*[2];for(int i =0; i <2; i++)
        mingwen[i]=newint[8];int**key =newint*[2];for(int i =0; i <2; i++)
        key[i]=newint[8];for(int i =0; i <2; i++)for(int j =0; j <8; j++)
            cin >> mingwen[i][j];for(int i =0; i <2; i++)for(int j =0; j <8; j++)
            cin >> key[i][j];//* 密钥扩展算法,由于只有三轮加密,第一轮还只使用了原始keyint**key1 =newint*[2];for(int i =0; i <2; i++)
        key1[i]=newint[8];int**key2 =newint*[2];for(int i =0; i <2; i++)
        key2[i]=newint[8];

    key1[0]=yihuo8(key[0],g(key[1], rcon1));
    key1[1]=yihuo8(key1[0], key[1]);
    key2[0]=yihuo8(key1[0],g(key1[1], rcon2));
    key2[1]=yihuo8(key2[0], key1[1]);//* 第0轮的轮密钥加lunmiyaojia(mingwen, key);//*第一轮//* 明文半字节代替s_he_tihuan(mingwen[0]);s_he_tihuan(mingwen[1]);//* 明文的行移位zuoyi(mingwen);//* 明文的列混淆liehunxiao(mingwen);//* 明文的轮密钥加lunmiyaojia(mingwen, key1);//*第二轮//* 明文半字节代替s_he_tihuan(mingwen[0]);s_he_tihuan(mingwen[1]);//* 明文的行移位zuoyi(mingwen);//* 明文的轮密钥加lunmiyaojia(mingwen, key2);//* 现在的明文其实是密文了shuchu(mingwen);return0;}/*
0 1 1 0 1 1 1 1 0 1 1 0 1 0 1 1
1 0 1 0 0 1 1 1 0 0 1 1 1 0 1 1
*/
标签: 安全

本文转载自: https://blog.csdn.net/ykn37/article/details/127348735
版权归原作者 角度洗 所有, 如有侵权,请联系我们删除。

“S-AES加密实现”的评论:

还没有评论