python中list问题及GF(2^8)上域元素的乘x

最近学习aes算法的时候,在网上看到一份代码感觉写的挺好的。

https://github.com/bozhu/AES-Python/blob/master/aes.py

但是其中有一个点有点小疑问。仔细研究了一下…拾一下以前看过的知识。

def __round_encrypt(self, state_matrix, key_matrix):
    self.__sub_bytes(state_matrix)
    self.__shift_rows(state_matrix)

def __sub_bytes(self, s):
    for i in range(4):
        for j in range(4):
            s[i][j] = Sbox[s[i][j]]

def __shift_rows(self, s):
    s[0][1], s[1][1], s[2][1], s[3][1] = s[1][1], s[2][1], s[3][1], s[0][1]
    s[0][2], s[1][2], s[2][2], s[3][2] = s[2][2], s[3][2], s[0][2], s[1][2]
    s[0][3], s[1][3], s[2][3], s[3][3] = s[3][3], s[0][3], s[1][3], s[2][3]

在进行字节替换和行移位的时候,函数并没有返回值,那么state_matrix,它是如何变化的传入到下一个函数中去?

a = 1
print a
def test(t):
    t = 3
    print t
test(a)
print a

---运行结果---
1
3
1
a = [1,2,3]
print a
def test1(t):
    t.append(4)
    print t
test1(a)
print a

---运行结果---
[1, 2, 3]
[1, 2, 3, 4]
[1, 2, 3, 4]

第一个代码块也是平时所理解的,感觉没啥问题,但是第二个代码块,在经过test1函数的处理后,并没有return 返回与赋值,那么为啥a变成了[1,2,3,4]

看下a、t变量的id,他们都是一样的值,也就是带入函数后,t只是a的一个引用,他们最后指向的内存块还是那个值,在整个列表的操作中,都是对这个内存存储的值进行操作,最后a和t的值都是有变化的。

引用http://blog.csdn.net/xidianliutingting/article/details/51682867的图。

所以这可以解释的通一开始的问题,正是因为列表这种赋值其实只是给了一个引用的id,但是还是指向同一个内存值。
所以在使用的时候可以利用 t=a[:]切片操作,这样新的list就是另外一个空间了。


另外就是list的深拷贝和浅拷贝。
在copy库中有一个copy和一个deepcopy
copy.copy是浅拷贝,只拷贝父对象,子对象并不会被拷贝过去,而copy.deepcopy则是深拷贝,相当于完完全全的复制。

子对象不被拷贝是指,比如

a = [1,2,3,[4,5,6]]

其中[4,5,6]就是子对象。


记录aes编写过程中一个重点,在列混淆的时候需要运算,GF(2^8)上域元素的乘x

xtime = lambda a: (((a << 1) ^ 0x1B) & 0xFF) if (a & 0x80) else (a << 1)
def _mult(byte1, byte2): # returns a(x)b(x) (a byte)
    """
    Multiplies two polynomials a(x), b(x) in GF(28) modulo the irreducible polynomial m(x) = x8+x4+x3+x+1. (i.e. m(x) = 0x11b).
    Parameters:
    a - A polynomial a(x) = a7x7+a6x6+a5x5+a4x4+a3x3+a2x2+a1x+a0 in GF(28).
    b - A polynomial b(x) = b7x7+b6x6+b5x5+b4x4+b3x3+b2x2+b1x+b0 in GF(28).
    Returns:
    a(x)b(x) modulo x8+x4+x3+x+1.
    """
    sum = 0b00000000
    toBeXored = byte2
    for i in range(8):
        if (byte1 & 0b00000001) == 0b00000001:
            sum = sum ^ toBeXored

        toBeXored = xtime(toBeXored)
        byte1 = byte1 >> 1
    return sum
print hex(_mult(0x57,0x13))

其中要注意的是,byte1和byte2都是16进制...当时看成10进制的时候,纠结了超级久。

0x01b=b
0x02
b 只要b小于0x80,b<<1。如果b大于或等于0x80,(b<<1)^0x1b
对于大于0x02可以分解成0x02和0x01的算法。

所以

b * 0x0d 
= b * (0x08 + 0x04 + 0x01) 
= (b * 0x08) + (b * 0x04) + (b * 0x01) 
= (b * 0x02 * 0x02 * 0x02) + (b * 0x02 * 0x02) + (b * 0x01)
posted @ 2016-12-28 15:25  l3m0n  阅读(1595)  评论(0编辑  收藏  举报