📚关于AES

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

📚实验目的

  • 实现 S-AES加密。
  • 测试数据:使用密钥 1010 0111 0011 1011 加密二进制明文 0110 1111 0110 1011,得出二进制密文 0000 0111 0011 1000。

📚流程梳理

  • S-AES 是 AES 加解密方法的缩减版。AES 的明文包括 128 位、256 位等处理,而 S-AES 只是对 16 位二进制明文进行处理;
  • AES 需要进行 0+10 轮加密,而S-AES 只进行 0+2 轮加密
    • 第0轮只进行轮密钥加
    • 第一轮进行字节替换行变换列混淆轮密钥加
    • 第二轮只进行字节替换行变换轮密钥加

🐇Step1:密钥扩展算法

  • 密钥的左半部分key1[0] = OR_8(key[0], g(key[1], rcon1));

    • g函数:g(key[1], rcon1)
      • 将第i-1个密钥的右半部分(8位)进行左循环移位,即将第i-1个密钥的右半部分的左右4位进行交换
      • 再将左循环移位后的第i-1个密钥的右半部分(8位)进行字节替换
      • 进行字节替换后需要与轮常数进行异或
    • OR_8(key[0], g(key[1], rcon1))
      • 将第i-1个密钥的右半部分(8位)执行完g函数后得到g(第i-1个密钥的右半部分)
      • 将其与第i-1个密钥的左半部分(8位)进行异或得到第i个密钥的左半部分。
  • 密钥的右半部分key1[1] = OR_8(key1[0], key[1]);。第i个密钥的右半部分由第i个密钥的左半部分与第i-1个密钥的右半部分进行异或得到。

    //密钥扩展算法,需要扩展出两个密钥key1和key2 
    int **key1 = new int *[2];
    for (int i = 0; i < 2; i++)
        key1[i] = new int[8];
    int **key2 = new int *[2];
    for (int i = 0; i < 2; i++)
        key2[i] = new int[8];
    
    //key1生成 
    key1[0] = OR_8(key[0], g(key[1], rcon1));
    key1[1] = OR_8(key1[0], key[1]);
    //key2生成 
    key2[0] = OR_8(key1[0], g(key1[1], rcon2));
    key2[1] = OR_8(key2[0], key1[1]);
    

🔥8位的异或

  • 对两个8位数组进行异或操作(4位异或也是同理)。
    //8位的异或
    int *OR_8(int *a, int *b)
    {
        int *result = new int[8];
        for (int i = 0; i < 8; i++)
            result[i] = a[i] ^ b[i];
        return result;
    }
    

🔥字节替换

  • 使用 S 盒进行不同位置的内容的替换。
    在这里插入图片描述

  • 具体而言,对 16 位二进制明文,8 位一组,每组中包含两个 16 进制的二进制表达,也就是 4 位为一个单位进行字节替代。前两位求其十进制得到行号,后两位求其十进制得到列号。

  • 然后到 S 盒中找到替换的那几组数据替换上,每次调用函数替换一组,共换 4 个单位的数据。

    //字节替换 
    void SubBytes(int *temp)
    {
    	//将8位二进制分组为4个2位的数字,这里的×2使得t的范围为0~3,可在表中对应位置检索
        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];
        
        //在S盒中找到替换后的值
        int num1 = s[t1][t2]; 
        int num2 = s[t3][t4];
        
        //分别进行四位四位的替换
        for (int i = 0; i < 4; i++)
            temp[i] = Replace[num1][i];
        for (int i = 0; i < 4; i++)
            temp[i + 4] = Replace[num2][i];
    }
    

🔥g函数

  • 将第i-1个密钥的右半部分(8位)进行左循环移位,即将第i-1个密钥的右半部分的左右4位进行交换
  • 再将左循环移位后的第i-1个密钥的右半部分(8位)进行字节替换
  • 进行字节替换后需要与轮常数进行异或
    //g函数
    int *g(int *temp, int *rcon) 
    {
        //这个temp是密钥的右半部分,不能改动,要复制一个新的进行计算
        int *t = new int[8];
        for (int i = 0; i < 8; i++)
            t[i] = temp[i];
        //循环左移,即左右4位进行交换 
        for (int i = 0; i < 4; i++)
        {
            int tt = t[i + 4];
            t[i + 4] = t[i];
            t[i] = tt;
        }
        //移位后的右半部分进行字节替换 
        SubBytes(t);
        //与轮常数异或
        return OR_8(t, rcon);
    } 
    

🐇Step2:第0轮

  • 只进行轮密钥加,即AddRoundKey(plaintext, key);

🔥轮密钥加

  • 轮密钥加就是每组与密钥的每组分别异或。

  • 第0轮中使用的是初始密钥

  • 第一轮用到的是密钥拓展后的第一个 8 位密钥,即key1

  • 第二轮用到的是密钥拓展后的第二个 8 位密钥,即key2

    //轮秘钥加 
    void AddRoundKey(int **mingwen, int **key)
    {
        for (int i = 0; i < 2; i++)
            for (int j = 0; j < 8; j++)
                mingwen[i][j] ^= key[i][j];
    }
    

🐇Step3:第一轮

  • 第一轮进行字节替换行变换列混淆轮密钥加
    // 第一轮
    // 明文半字节代替
    SubBytes(plaintext[0]);
    SubBytes(plaintext[1]);
    
    // 明文的行变换 
    ShiftRows(plaintext);
    
    // 明文的列混淆
    MixColumns(plaintext);
    
    // 明文的轮密钥加
    AddRoundKey(plaintext, key1);
    

🔥行变换

  • 行变换的规则:第一行不变,第二行左移 1 位,依次类推。
    在这里插入图片描述

    在这里插入图片描述


关注60是一个字节,4C是一个字节!所以从咱们数组上看,就是第一字节的右半部分和第二字节的右半部分进行替换

//行变换 
void ShiftRows(int **temp) 
{
    //第一字节的右半部分和第二字节的右半部分进行替换
    for(int i = 4;i < 8;i ++)
    {
        int t = temp[0][i];
        temp[0][i] = temp[1][i];
        temp[1][i] = t;
    }
}

🔥列混淆

【AES加密算法】| AES加密过程详解】16分07秒

  • 列混淆本质上就是乘上一个矩阵,运算定义在 G F ( 2 4 ) GF(2^4) GF(24),所以乘上矩阵[[1,4],[4,1]],于是我们可以得出运算公式:
    在这里插入图片描述

  • 其中 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位。得到:
    在这里插入图片描述

  • “加”实际上是异或。

  • “乘”
    在这里插入图片描述


  1. x_fx函数用于计算 x*f(x),即将多项式 f(x) 进行左移,并根据最高次数是否为 1 进行取模操作(原理类似下图)。
    在这里插入图片描述

  2. multiply函数用于进行多项式乘法操作,在有限域 GF(2^8) 上进行。

    • 乘法 a(x)*b(x)可以拆成多个 a(x)*x^n 的异或操作。
    • 首先根据输入多项式 a,使用 x_fx 函数计算 a ∗ ( x 1 ) a*(x^1) a(x1) a ∗ ( x 2 ) a*(x^2) a(x2) a ∗ ( x 3 ) a*(x^3) a(x3) 分别得到 x1fx、x2fx 和 x3fx。
    • 根据输入多项式 b 的系数,分别使用异或操作符对 x3fx、x2fx、x1fx 和 a 进行运算,得到结果数组 result。
  3. MixColumns函数用于进行列混淆操作,输入为明文矩阵 mingwen。

    • 定义固定的二进制数 rule = {0, 1, 0, 0}(就是4),用于进行乘法计算。

    • 将 mingwen 第一行和第二行的元素分别存储到 m00、m10、m01 和 m11 数组中。

    • 使用 multiply 函数分别计算结果,得到 n00、n10、n01 和 n11。
      在这里插入图片描述

    • 更新 mingwen 矩阵,将 n00、n10、n01 和 n11 的元素分别放回 mingwen 中对应的位置。

  4. 最终得到经过列混淆操作后的明文矩阵。

    //实现x*f(x)的函数
    void x_fx(int last[4], int res[4]) 
    {
    	//res是结果,last是上一步的结果
        if (last[0] == 0)
        {
    		//最高次为0 
            for (int i = 0; i < 3; i++)
            	//低三项分别升幂次 
                res[i] = last[i + 1];
        }
        else
        {
        	//最高次为1
            res[1] = last[2];
            res[2] = last[3] == 1 ? 0 : 1;
            res[3] = 1;
        }
    }
    
    //乘法
    int *multiply(int a[4], int b[4])
    {
        //储存结果的系数
        int *result = new int[4];
        for (int i = 0; i < 4; i++) result[i] = 0;
    
        //记录下a*(x^n) 
        int x1fx[4] = {0};
        x_fx(a, x1fx);//a*(x^1)=a*{0,0,1,0}=a*b3 
        int x2fx[4] = {0};
        x_fx(x1fx, x2fx);//a*(x^2)=a*{0,1,0,0}=a*b2
        int x3fx[4] = {0};
        x_fx(x2fx, x3fx);//a*(x^3)=a*{1,0,0,0}=a*b1
    
        //现在需要根据多项式a和b开始异或
        if (b[0] == 1)//b1=={1,0,0,0}
            for (int i = 0; i < 4; i++)
                result[i] ^= x3fx[i];
        if (b[1] == 1)//b2=={0,1,0,0}
            for (int i = 0; i < 4; i++)
                result[i] ^= x2fx[i];
        if (b[2] == 1)//b3=={0,0,1,0}
            for (int i = 0; i < 4; i++)
                result[i] ^= x1fx[i];
        if (b[3] == 1)//b4=={0,0,0,1}
            for (int i = 0; i < 4; i++)
                result[i] ^= a[i];
        return result;
    }
    
    //列混淆 
    void MixColumns(int **mingwen)
    {
        int rule[4] = {0, 1, 0, 0};
        int *m00 = new int[4]; // 第一行的前4个元素
        int *m10 = new int[4]; // 第一行的后4个元素
        int *m01 = new int[4]; // 第二行的前4个元素
        int *m11 = new int[4]; // 第二行的后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 = new int[4];
        int *n10 = new int[4];
        int *n01 = new int[4];
        int *n11 = new int[4];
        n00 = OR_4(m00, multiply(rule, m10));
        n10 = OR_4(multiply(rule, m00), m10);
        n01 = OR_4(m01, multiply(rule, m11));
        n11 = OR_4(multiply(rule, m01), m11);
        for (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];
        }
    }
    

🐇Step4:第二轮

  • 第二轮只进行字节替换行变换轮密钥加

    // 第二轮
    // 明文半字节代替
    SubBytes(plaintext[0]);
    SubBytes(plaintext[1]);
    
    // 明文的行移位
    ShiftRows(plaintext);
    
    // 明文的轮密钥加
    AddRoundKey(plaintext, key2);
    

📚实验结果

🐇C++

#include <bits/stdc++.h>
using namespace std;

//S盒 
const int s[4][4] = {
    {9, 4, 10, 11},
    {13, 1, 8, 5},
    {6, 2, 0, 3},
    {12, 14, 15, 7}};

//替换表 
const int Replace[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}};

//轮常数
int rcon1[8] = {1, 0, 0, 0, 0, 0, 0, 0};
int rcon2[8] = {0, 0, 1, 1, 0, 0, 0, 0};

//8位的异或
int *OR_8(int *a, int *b)
{
    int *result = new int[8];
    for (int i = 0; i < 8; i++)
        result[i] = a[i] ^ b[i];
    return result;
}

//字节替换 
void SubBytes(int *temp)
{
	//将8位二进制分组为4个2位的数字
    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];
    
    //在S盒中找到替换后的值
    int num1 = s[t1][t2]; 
    int num2 = s[t3][t4];
    
    //分别进行四位四位的替换
    for (int i = 0; i < 4; i++)
        temp[i] = Replace[num1][i];
    for (int i = 0; i < 4; i++)
        temp[i + 4] = Replace[num2][i];
}

//g函数
int *g(int *temp, int *rcon) 
{
    //这个temp是密钥的右半部分,不能改动,要复制一个新的进行计算
    int *t = new int[8];
    for (int i = 0; i < 8; i++)
        t[i] = temp[i];
    //循环左移,即左右4位进行交换 
    for (int i = 0; i < 4; i++)
    {
        int tt = t[i + 4];
        t[i + 4] = t[i];
        t[i] = tt;
    }
    //移位后的右半部分进行字节替换 
    SubBytes(t);
    //与轮常数异或
    return OR_8(t, rcon);
} 

//轮秘钥加 
void AddRoundKey(int **mingwen, int **key)
{
    for (int i = 0; i < 2; i++)
        for (int j = 0; j < 8; j++)
            mingwen[i][j] ^= key[i][j];
}

//行变换 
void ShiftRows(int **temp) 
{
    //第一字节的右半部分和第二字节的右半部分进行替换
    for(int i = 4;i < 8;i ++)
    {
        int t = temp[0][i];
        temp[0][i] = temp[1][i];
        temp[1][i] = t;
    }
}

//4位的异或
int *OR_4(int *a, int *b)
{
    int *t = new int[4];
    for (int i = 0; i < 4; i++)
        t[i] = a[i] ^ b[i];
    return t;
}

//实现x*f(x)的函数
void x_fx(int last[4], int res[4]) 
{
	//res是结果,last是上一步的结果
    if (last[0] == 0)
    {
		//最高次为0 
        for (int i = 0; i < 3; i++)
        	//低三项分别升幂次 
            res[i] = last[i + 1];
    }
    else
    {
    	//最高次为1
        res[1] = last[2];
        res[2] = last[3] == 1 ? 0 : 1;
        res[3] = 1;
    }
}

//乘法
int *multiply(int a[4], int b[4])
{
    //储存结果的系数
    int *result = new int[4];
    for (int i = 0; i < 4; i++) result[i] = 0;

    //记录下a*(x^n) 
    int x1fx[4] = {0};
    x_fx(a, x1fx);//a*(x^1)=a*{0,0,1,0}=a*b3 
    int x2fx[4] = {0};
    x_fx(x1fx, x2fx);//a*(x^2)=a*{0,1,0,0}=a*b2
    int x3fx[4] = {0};
    x_fx(x2fx, x3fx);//a*(x^3)=a*{1,0,0,0}=a*b1

    //现在需要根据多项式a和b开始异或
    if (b[0] == 1)//b1=={1,0,0,0}
        for (int i = 0; i < 4; i++)
            result[i] ^= x3fx[i];
    if (b[1] == 1)//b2=={0,1,0,0}
        for (int i = 0; i < 4; i++)
            result[i] ^= x2fx[i];
    if (b[2] == 1)//b3=={0,0,1,0}
        for (int i = 0; i < 4; i++)
            result[i] ^= x1fx[i];
    if (b[3] == 1)//b4=={0,0,0,1}
        for (int i = 0; i < 4; i++)
            result[i] ^= a[i];
    return result;
}

//列混淆 
void MixColumns(int **mingwen)
{
    int rule[4] = {0, 1, 0, 0};
    int *m00 = new int[4]; // 第一行的前4个元素
    int *m10 = new int[4]; // 第一行的后4个元素
    int *m01 = new int[4]; // 第二行的前4个元素
    int *m11 = new int[4]; // 第二行的后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 = new int[4];
    int *n10 = new int[4];
    int *n01 = new int[4];
    int *n11 = new int[4];
    n00 = OR_4(m00, multiply(rule, m10));
    n10 = OR_4(multiply(rule, m00), m10);
    n01 = OR_4(m01, multiply(rule, m11));
    n11 = OR_4(multiply(rule, m01), m11);
    for (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];
    }
}

int main()
{
    //输入明文和密钥,存储在两个2x8的二维数组中,方便后续的密钥扩展(右半部分即key[1])
    cout << "请输入明文(用空格分隔的16个数字):" << endl;
    int **plaintext = new int *[2];
    for (int i = 0; i < 2; i++)
    {
    	plaintext[i] = new int[8];
        for (int j = 0; j < 8; j++)
        {
            cin >> plaintext[i][j];
        }
    }
    cout << "请输入密钥(用空格分隔的16个数字):" << endl;
    int **key = new int *[2];
    for (int i = 0; i < 2; i++)
    {
    	key[i] = new int[8];
        for (int j = 0; j < 8; j++)
        {
            cin >> key[i][j];
        }
    }

    //密钥扩展算法,需要扩展出两个密钥key1和key2 
    int **key1 = new int *[2];
    for (int i = 0; i < 2; i++)
        key1[i] = new int[8];

    int **key2 = new int *[2];
    for (int i = 0; i < 2; i++)
        key2[i] = new int[8];
        
	//key1生成 
    key1[0] = OR_8(key[0], g(key[1], rcon1));
    key1[1] = OR_8(key1[0], key[1]);
    //key2生成 
    key2[0] = OR_8(key1[0], g(key1[1], rcon2));
    key2[1] = OR_8(key2[0], key1[1]);

    //第0轮的轮密钥加
    AddRoundKey(plaintext, key);

    // 第一轮
    // 明文半字节代替
    SubBytes(plaintext[0]);
    SubBytes(plaintext[1]);

    // 明文的行变换 
    ShiftRows(plaintext);

    // 明文的列混淆
    MixColumns(plaintext);

    // 明文的轮密钥加
    AddRoundKey(plaintext, key1);

    // 第二轮
    // 明文半字节代替
    SubBytes(plaintext[0]);
    SubBytes(plaintext[1]);

    // 明文的行移位
    ShiftRows(plaintext);

    // 明文的轮密钥加
    AddRoundKey(plaintext, key2);

    cout << "最后的密文是:" << endl;
	for (int i = 0; i < 2; i++)
        for (int j = 0; j < 8; j++)
            cout << plaintext[i][j] << ' ';
    cout << endl;
    return 0;
}

在这里插入图片描述

🐇python

# S盒
s = [[9, 4, 10, 11],
     [13, 1, 8, 5],
     [6, 2, 0, 3],
     [12, 14, 15, 7]]

# 替换表
Replace = [[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]]

# 轮常数
rcon1 = [1, 0, 0, 0, 0, 0, 0, 0]
rcon2 = [0, 0, 1, 1, 0, 0, 0, 0]

def XR_8(a, b):
    # a、b 分别是两个长度为 8 的数组,返回一个长度也为 8 的数组
    t = [0] * 8  # 结果数组
    for i in range(8):
        t[i] = a[i] ^ b[i]
    return t

# 字节替换
def SubBytes(temp):
    # temp 是一个长度为8的数组,进行S盒替换
    # 先计算出需要进行S盒替换的四位二进制数
    t1 = 2 * temp[0] + temp[1]
    t2 = 2 * temp[2] + temp[3]
    t3 = 2 * temp[4] + temp[5]
    t4 = 2 * temp[6] + temp[7]
    # 进行 S 盒替换
    num1 = s[t1][t2]
    num2 = s[t3][t4]
    # 将替换后的结果按四位四位赋值给temp
    for i in range(4):
        temp[i] = Replace[num1][i]
    for i in range(4):
        temp[i + 4] = Replace[num2][i]

# g函数
def g(temp, rcon):
    # temp 是一个长度为8的数组,rcon是轮常数
    t = temp.copy()  # temp是密钥,不能改动,复制一个新的
    # 进行循环左移
    for i in range(4):
        tt = t[i + 4]
        t[i + 4] = t[i]
        t[i] = tt
    # 进行 S 盒替换
    SubBytes(t)
    # 进行轮常数异或
    return XR_8(t, rcon)

# 轮密钥加
def AddRoundKey(mingwen, key):
    for i in range(2):
        for j in range(8):
            mingwen[i][j] ^= key[i][j]

# 行变换
def ShiftRows(temp):
    # 第一字节的右半部分和第二字节的右半部分进行替换
    for i in range(4, 8):
        t = temp[0][i]
        temp[0][i] = temp[1][i]
        temp[1][i] = t

# 4位的异或
def OR_4(a, b):
    # a、b 分别是两个长度为 4 的数组,返回一个长度也为 4 的数组
    t = [0] * 4  # 结果数组
    for i in range(4):
        t[i] = a[i] ^ b[i]
    return t

def x_fx(f, a):
    # 进行有限域上的多项式除法运算,用于求解一个元素的逆元
    if a[0] == 0:
        for i in range(3):  # 定义一个长度为4的数组f表示一个3次多项式
            f[i] = a[i + 1]
    else:
        f[1] = a[2]
        f[2] = 0 if a[3] == 1 else 1
        f[3] = 1


def multiply(a, b):
    # 在有限域 GF(2^4) 上的多项式乘法运算
    # 记录下f^n
    f = [0] * 4
    x_fx(f, a)
    f2 = [0] * 4
    x_fx(f2, f)
    f3 = [0] * 4
    x_fx(f3, f2)
    # 现在需要根据多项式a和b开始异或
    result = [0] * 4  # 储存结果的系数
    if b[0] == 1:
        for i in range(4):
            result[i] ^= f3[i]
    if b[1] == 1:
        for i in range(4):
            result[i] ^= f2[i]
    if b[2] == 1:
        for i in range(4):
            result[i] ^= f[i]
    if b[3] == 1:
        for i in range(4):
            result[i] ^= a[i]
    return result

# 列混淆
def MixColumns(mingwen):
    rule = [0, 1, 0, 0]
    m00 = mingwen[0][:4]
    m10 = mingwen[0][4:]
    m01 = mingwen[1][:4]
    m11 = mingwen[1][4:]

    n00 = OR_4(m00, multiply(rule, m10))  # 乘法结果是1011
    n10 = OR_4(multiply(rule, m00), m10)  # 0101
    n01 = OR_4(m01, multiply(rule, m11))  # 0100
    n11 = OR_4(multiply(rule, m01), m11)  # 0010

    mingwen[0][:4] = n00
    mingwen[0][4:] = n10
    mingwen[1][:4] = n01
    mingwen[1][4:] = n11

if __name__ == "__main__":
    mingwen_str = "0110111101101011"
    key_str = "1010011100111011"
    mingwen = [[int(mingwen_str[i * 8 + j]) for j in range(8)] for i in range(2)]
    key = [[int(key_str[i * 8 + j]) for j in range(8)] for i in range(2)]

    # 密钥扩展算法,由于只有三轮加密,第一轮只使用了原始key
    key1 = [[0] * 8 for _ in range(2)]
    key2 = [[0] * 8 for _ in range(2)]
    key1[0] = XR_8(key[0], g(key[1], rcon1))
    key1[1] = XR_8(key1[0], key[1])
    key2[0] = XR_8(key1[0], g(key1[1], rcon2))
    key2[1] = XR_8(key2[0], key1[1])

    # 第零轮
    # 轮密钥加
    AddRoundKey(mingwen, key)

    # 第一轮
    # 明文半字节代替
    SubBytes(mingwen[0])
    SubBytes(mingwen[1])
    # 明文的行移位
    ShiftRows(mingwen)
    # 明文的列混淆
    MixColumns(mingwen)
    # 明文的轮密钥加
    AddRoundKey(mingwen, key1)

    # 第二轮
    # 明文半字节代替
    SubBytes(mingwen[0])
    SubBytes(mingwen[1])
    # 明文的行移位
    ShiftRows(mingwen)
    # 明文的轮密钥加
    AddRoundKey(mingwen, key2)

    # 输出结果
    print("密文为:")
    for i in range(2):
        for j in range(8):
            print(mingwen[i][j], end=' ')

在这里插入图片描述


代码学习来源:S-AES加密实现


  • 以上若有理解错的地方欢迎指正!
Logo

永洪科技,致力于打造全球领先的数据技术厂商,具备从数据应用方案咨询、BI、AIGC智能分析、数字孪生、数据资产、数据治理、数据实施的端到端大数据价值服务能力。

更多推荐