AES字运算 | AES数学基础 | 现代密码学

题目

AES数学基础

详情可参考 现代密码学|AES数学基础|GF(2^8)有限域上的运算问题_哔哩哔哩_bilibili

(25条消息) 关于AES的列混合计算和解密流程问题_aes列混合在线计算_国科大网安二班的博客-CSDN博客

请仔细阅读以上两个参考资料后 再来看本文

这里只涉及编程中基于AES数学基础的算法设计

首先有几个需要注意的问题:

  1. {}里的是一个字节 代表该字节的二进制所代表的那个系数在GF(2)的多项式

  2. 同时每一项相乘的结果要mod(x8+x4+x3+x+1)

  3. 最后的结果要mod(x4+1)

加法很简单:直接对应系数异或即可

def plus():#加法很简单 对应系数异或即可
    A = input("请依次输入a(x)中x^3 x^2 x^1 x^0的系数:\n").split(" ")
    B = input("请依次输入b(x)中x^3 x^2 x^1 x^0的系数:\n").split(" ")
    C=[]
    for i in range(4):
        C.append(hex((int(A[i],16)^int(B[i],16)))[2:].zfill(2))
    print("结果以x^3 x^2 x^1 x^0的次序输出:")
    for i in range(4):
        print(C[i],end=" ")
    return C

乘法比较复杂:

d0,d1,d2,d3是通过类似于矩阵相乘的形式得到的(原因在给出的第2个链接中可以找到)

在这里插入图片描述

在计算每一项例如a0 b0、a3 b1相乘的过程中需要将其中一个多项式分解为x*s(x)的形式 以便于计算

例如:

{12} *{07} 分解为 {12} * {02*02 + 02 + 01} = {12} *{02}*{02} + {12} * {02} + {12}*{01}

(02 在对应二进制的多项式中 代表的就是x;同理,01 代表的就是 1;这里的加法仍然是异或运算)

那么在算法中,以此为例 :

第一次需要进行两次乘x运算 即完成 12*02*02(此处及以下都省略{})

第二次需要进行一次乘x运算 即完成12*02,同时需要与上述结果异或得到新的结果

直到第三次01的出现 (显然 01 乘 任何多项式 都等于该多项式本身) 再将12 与第二次的结果相异或得到新结果,至此结束

我们理清了这个思路后

只需要做到两步即可:

  1. 实现x*s(x)的算法

关于这方面核心:

在这里插入图片描述

具体推导过程可自行查阅 这里不阐述

def times_x(num):#实现x*b(x) 
    num = num<<1
    bitstr = bin(num)[2:].zfill(9)#注意长度包括b7是9
    bitstr_ = bitstr[1:]#取b6到0
    if(bitstr[0] == "0"):#判断b7
        return int(bitstr_,2)
    else:
        return int(bitstr_,2)^ 0b00011011
  1. 以矩阵形式完成乘法算法
 D =[]
    for i in range(4):
        result = 0 # 用于记录d0,d1,d2,d3
        for j in range(4):#min max 用来节约时间

            # 挑选两个之中更小的那个
            min_ = min(coeff_A[i][j],B[3-j])# 3-j是因为 次数递减输入系数

            # 将相乘的数不断分解出x 直到无法分解
            # 例如 12 * 07 = 12 * (02 * 02 + 02 + 01) 
            while(min_ >= 2):

                #进行再一次分解之前要重置max 
                max_ = max(coeff_A[i][j],B[3-j])

                #xnum表示此次分解需要乘x的次数
                xnum = math.floor(math.log(min_,2))#floor向下取整
                min_ = min_ - 2**xnum 
                for t in range(xnum):
                    max_ = times_x(max_)
                result = result ^ max_# 将每次while循环的结果异或
            
            if min_ == 1:
                result = result ^ max(coeff_A[i][j],B[3-j])
            #不用考虑0的情况 因为和0相乘还是等于0 而0和任何数异或还是这个数

        D.append(result)

完整代码

没经过严密的验证 不保证完全正确

import math
def times_x(num):#实现x*b(x) 
    num = num<<1
    bitstr = bin(num)[2:].zfill(9)#注意长度包括b7是9
    bitstr_ = bitstr[1:]#取b6到0
    if(bitstr[0] == "0"):#判断b7
        return int(bitstr_,2)
    else:
        return int(bitstr_,2)^ 0b00011011

def times():#乘法
    A = [int(i,16) for i in input("请依次输入a(x)中x^3 x^2 x^1 x^0的系数:\n").split(" ")]
    B = [int(i,16) for i in input("请依次输入b(x)中x^3 x^2 x^1 x^0的系数:\n").split(" ")]
    coeff_A = [ [A[3],A[0],A[1],A[2]],
                [A[2],A[3],A[0],A[1]],
                [A[1],A[2],A[3],A[0]],
                [A[0],A[1],A[2],A[3]]]#输入的系数是以 x^3 x^2递减的次数输入的
    # print(coeff_A)
    D =[]
    for i in range(4):
        result = 0 # 用于记录d0,d1,d2,d3
        for j in range(4):#min max 用来节约时间

            # 挑选两个之中更小的那个
            min_ = min(coeff_A[i][j],B[3-j])# 3-j是因为 次数递减输入系数

            # 将相乘的数不断分解出x 直到无法分解
            # 例如 12 * 07 = 12 * (02 * 02 + 02 + 01) 
            while(min_ >= 2):

                #进行再一次分解之前要重置max 
                max_ = max(coeff_A[i][j],B[3-j])

                #xnum表示此次分解需要乘x的次数
                xnum = math.floor(math.log(min_,2))#floor向下取整
                min_ = min_ - 2**xnum 
                for t in range(xnum):
                    max_ = times_x(max_)
                result = result ^ max_# 将每次while循环的结果异或
            
            if min_ == 1:
                result = result ^ max(coeff_A[i][j],B[3-j])
            #不用考虑0的情况 因为和0相乘还是等于0 而0和任何数异或还是这个数

        D.append(result)
    print("结果以x^3 x^2 x^1 x^0的次序输出:")
    for i in range(4):
        print(hex(D[3-i])[2:].zfill(2),end=" ")#得到的列表是d0,d1,d2,d3,因此为了顺应输入的次序逆着输出
    return D
def plus():#加法很简单 对应系数异或即可
    A = input("请依次输入a(x)中x^3 x^2 x^1 x^0的系数:\n").split(" ")
    B = input("请依次输入b(x)中x^3 x^2 x^1 x^0的系数:\n").split(" ")
    C=[]
    for i in range(4):
        C.append(hex((int(A[i],16)^int(B[i],16)))[2:].zfill(2))
    print("结果以x^3 x^2 x^1 x^0的次序输出:")
    for i in range(4):
        print(C[i],end=" ")
    return C
delim = int(input("请选择运算符:0.+  1.*\n"))
if delim:
    times()
else :
    plus()

结果如图:

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

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值