zoukankan      html  css  js  c++  java
  • AES SBox的构造(python)

    几点需要注意的,求解逆元的时候使用的是拓展欧几里得,但是那些运算规则需要变一变,模2的加减乘除(或者可以理解为多项式的运算)

    在进行字节的仿射变换不用进行矩阵的运算。

    一个矩阵和一个列向量进行运算的时候可以视为矩阵的列向量的线性组合

    代码如下:

      1 #使用拓展欧几里得求解乘法矩阵的逆元
      2 #求一个数的二进制位的长度
      3 def length(a):
      4     len=0
      5     while(a):
      6         a=a>>1
      7         len+=1
      8     return len
      9 
     10 #模2的加减都是一样的,异或即可
     11 def addSub(a,b):
     12     return (a^b)
     13     
     14 def gcd(m,n):
     15     while(n!=0):
     16         m,n=n,m%n
     17     return m        
     18 
     19 #乘法
     20 def multi(a,c):
     21     b=0x01
     22     flag=[]                  #flag得到的是c中为1的位(置)
     23     for j in range(8):
     24         if(c&b):
     25             flag.append(j)
     26         b=(b<<1)&0x00ff      #b从最低位开始,不断左移并与c相与,目的是找出c中为1的位
     27     kk=[]
     28     kk.append(a)            #将a本身存放进去
     29     for i in range(7):      #8位,除了1之外(1就是原数的本身),其余的都先算出结果
     30         if (a&0x80):
     31             a=a<<1
     32             a=a&0x00ff    #将高8位清零,保留低8位(如果上述的左移运算的位数超过8位的话),如果没有这个操作的话,不会默认保留低8位
     33             a=a^0x1b
     34         else:
     35             a=a<<1
     36         kk.append(a)
     37     result=0              #任何数与0异或都是其本身
     38     for k in flag:
     39         result=result^kk[k]
     40     return result
     41 
     42 #参考:https://www.cnblogs.com/YKang/p/7663737.html    
     43 #多项式的模2除法运算,函数的返回值是得到的商和余数
     44 def division(a,b):
     45     len1=length(a)
     46     len2=length(b)
     47     len3=len1-len2
     48     
     49     if a<b:                   #被除数小于除数
     50         if len3==0:          #两个数的长度相同,则直接商1,余数是二者异或的结果
     51             return (1,a^b)
     52         else:
     53             return (0,a)      #如果被除数的位数小于除数,则商0,余数为a
     54             
     55     topBit=1
     56     topBit<<=(len1-1)       
     57     b<<=len3                #将b的位数扩充到和a的位数一样的长度
     58     
     59     quotient=0
     60     remainder=0
     61     
     62     for i in range(len3): 
     63         quotient<<=1        #quotient每次左移一位,就是在后面添加0,然后下面再用一个for循环来确定新增的位是0还是1
     64         if (topBit&a):        #a的最高位为0,即意味着a此时的位数按照正常的一位落位可以满足和除数b的运算
     65             quotient^=1     #如果上面的if语句成立,则说明此时的商应该是1,所以0和1异或得1
     66             a^=b
     67         else:
     68             a^=0            
     69         topBit>>=1          #每运算一次,这个就应该右移一位,继续判断a的位数是否满足
     70         b>>=1               #b右移的效果也是一样的
     71     quotient<<=1            #quotient继续右移一位,此时新加的为0
     72     if a<b:
     73         remainder=a         
     74     else:
     75         quotient^=1
     76         remainder=a^b
     77         
     78     return quotient,remainder
     79 
     80 def egcd(a,b):
     81     r0,r1,s0,s1=1,0,0,1
     82     while(b):
     83         qt,rt=division(a,b)
     84         q,a,b=qt,b,rt
     85         r0,r1=r1,addSub(r0,multi(q,r1))
     86         s0,s1=s1,addSub(s0,multi(q,s1))
     87     return s0                    #s0是求得的逆元
     88 
     89 #矩阵乘以列向量
     90 #矩阵乘以列向量,其实可以以矩阵的列向量进行线性组合
     91 #https://www.zhihu.com/question/21351965/answer/103520656
     92 #也就是矩阵中的第i列和列向量的第i个元素相乘(这里就是简单的相乘,所以那些在列向量中为0的元素就可以忽略不计),
     93 #因为所以的列向量的元素非0几1,所以可以直接使用x进行操作,无须再将x转换成二进制的比特位
     94 #异或运算是二进制位的异或,所以在求解res^M[i]的时候就可以直接把res和整个列进行异或
     95 #参考:https://www.jianshu.com/p/9626fcd97a69
     96 def byteSub(inelem):         #传入逆元给函数
     97     M=[0x1F, 0x3E, 0x7C, 0xF8, 0xF1, 0xE3, 0xC7, 0x8F]
     98     res=0x00
     99     i=0
    100     x=inelem
    101     while x>0:
    102         if x%2:
    103             res^=M[i]
    104         i+=1                   
    105         x>>=1                 #位移或者 '//'
    106     return hex(res^0x63)
    107 
    108 def sBox():
    109     box=[]
    110     for i in range(256):
    111         sbox=byteSub(egcd(283,i))
    112         box.append(sbox)
    113     for j in range(256):
    114         print(box[j],end=' ')
    115         if (j+1)%16==0:
    116             print('
    ')
    117             
    118 sBox()
    View Code

    参考:https://www.jianshu.com/p/9626fcd97a69

               https://www.cnblogs.com/YKang/p/7663737.html

          https://www.zhihu.com/question/21351965/answer/103520656

  • 相关阅读:
    如何面试程序员?
    类似猪八戒网的网站
    存储过程
    一个不错的网站(博客制作参考)
    用触发器来实现级联更新级联删除
    用触发器进行级联删除
    数据库触发器详解
    浅谈数据库中的存储过程
    JDBC连接数据库
    Java递归函数
  • 原文地址:https://www.cnblogs.com/Guhongying/p/9822499.html
Copyright © 2011-2022 走看看