一、任意给定两个素数p和q,p!= q,记 N = p * q ,构造Zn*,问(编程解决):
1、是否每个元素都有inverse?是否成群? 2、这个集合有多少元素?
这题主要是要理解群的定义,一个二元运算的集合如果符合:1.封闭性;2.结合律;3.有单位元;4.对任意元素都存在逆元。则这个集合称为群。以下为编程实现的内容:
from __future__ import division
import random
p = 0
q = 0
for j in range(100000):
while (1):
i = random.randint(1, 20)
for num in range(2, i):
if (i % num == 0):
break
else:
p = i
break
while (1):
k = random.randint(1, 20)
for m in range(2, k):
if (k % m == 0):
break
else:
q = k
break
if (q != p): break
print("随机生成的两个素数分别为 p: ", p, ", q: ", q)
N = p * q
print(" N : ", N, "生成的集合元素总数即为", N)
#下面根据群的判定条件判断是否成群
b = 0#用来判断是否符合群
#1.是否封闭
for i in range(1, N):
for j in range(1, N):
modNum = (i * j) % N
#print (modNum)
if ( modNum >= N and modNum < 0):
b = 1
if (b == 1):
print("这个集合并不是封闭的,不成群")
else:
print("这个集合是封闭的")
#是否符合结合律
for i in range(1, N):
for j in range(1, N):
for k in range(1, N):
if (((((i * j) % N) * k) % N ) != ((((j * k) % N) * i) % N )):
b = 1
if (b == 1):
print("这个集合并不符合结合律,不成群")
else:
print("这个集合符合结合律")
#模N乘法单位元为1
for i in range(1, N):
for j in range(1, N):
if(i * j == j * i == i):
b = 1
c = j#存下单位元
if (b == 1):
print("这个集合存在单位元,该单位元为", c)
else:
print("这个集合不存在单位元,不成群")
#是否对任意元素都存在逆元
inversenum = [100 for i in range(N)]
for i in range(1, N):
for j in range(1, N):
modNum = (i * j) % N
if (modNum == 1):
inversenum[i] = c
ifInverse = 1
for i in range(1, len(inversenum)):
if (inversenum[i] != 1):
ifInverse = 0
print("这个集合中存在一个元素不含逆元,该元素为", i)
print("所以这个集合不成群")
break
if (ifInverse):
print("这个集合中每个元素都存在逆元")
print("经检测该集合符合所有群的定义要求,故该集合成群")
理解了群的定义后再使用python编程总体上难度中等。
二、写一个程序,实现AES的S-box的构造。
这一题相比于上一题难度要高出许多,基本上在编写的过程中都是在百度。
要实现S盒的构造首先要解决在有限域内求出乘法逆元的值。之后再对逆元进行变换,这里需要用到一个矩阵,用16进制表示。其中还需要与{63}这个字节进行异或。在看了下面这个网址之后
http://www.docin.com/p-929525675.html
再一定程度上进行些许修改为python语言得出了以下编程。
#首先构造S盒,8位共能表示256个数
l_t = [0 for i in range(256)]
m_t = [0 for i in range(256)]
Sbox = [0 for i in range(256)]
mid_t = [0 for i in range(256)]
b = [0xf1, 0xe3, 0xc7, 0x8f, 0x1f, 0x3e, 0x7c, 0xf8]#输入字节后变换所需的矩阵用16进制表示
#求出0-255的逆元
p = 1
for i in range(256):
l_t[i] = p
m_t[p] = i
if (p & 0x80):
p = p ^ (p << 1) ^ (0x11b)#8次不可约多项式16进制表示为11B
else:
p = p ^ (p << 1) ^ 0
#求出逆元后存放在mid_t中
for i in range(256):
if (i):
mid_t[i] = l_t[255 - m_t[i]]
else:
mid_t[i] = 0
#对逆元进行变换,用上构造的b矩阵以及{63}这个值
for i in range(256):
t = 0
m = 0
mid = 0
tab = 0
for j in range(8):
m = mid = (b[j] & mid_t[i])
for k in range(8):
n = mid>>1
if (m != (n << 1)):
t+=1
mid = n
m = mid
if (t % 2 > 0):
temp = 1
for k in range(j):
temp = temp << 1
tab += temp
t = 0
Sbox[i] = tab ^ 0x63
#输出S盒
print("S盒如下")
for i in range(0, 257):
print("%x" % Sbox[i - 1], end=" ")
if (i % 16 == 0):
print()