码迷,mamicode.com
首页 > 编程语言 > 详细

AES SBox的构造(python)

时间:2018-10-20 19:42:53      阅读:151      评论:0      收藏:0      [点我收藏+]

标签:需要   end   bytes   运算   span   矩阵   com   使用   欧几里得   

几点需要注意的,求解逆元的时候使用的是拓展欧几里得,但是那些运算规则需要变一变,模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(\n)
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

AES SBox的构造(python)

标签:需要   end   bytes   运算   span   矩阵   com   使用   欧几里得   

原文地址:https://www.cnblogs.com/Guhongying/p/9822499.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!