一、任意给定两个素数p和q,p!= q,记 N = p * q ,构造Zn*,问(编程解决):
1、是否每个元素都有inverse?是否成群? 2、这个集合有多少元素?
利用有关群的理论来解答 : )
# coding=utf-8
# author:tyty
# date :2018/3/23
from __future__ import division
import random
p = 0 #prime 1
q = 0 #prime 2
for j in range(100000):
while(1):
i = random.randint(1, 30)#u can set the random int whatever u want
for num in range(2, i):
if (i % num == 0):
break
else:
p = i
break
while(1):
k = random.randint(1, 30)#u can set the random int whatever u want
for m in range(2, k):
if (k % m == 0):
break
else:
q = k
break
if (q != p): break
print ("random prime p: ", p, ", q: ", q)
#mod N
N = p * q
print (" N : ", N )
#judge if sealed
#!!! set the range[1, N-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):
print ("It's not sealed. Not a Group!")
print ("It's sealed!")
#judge if can be combined arbitrarily
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 )):
print("It's can not be combined. Not a Group!")
print ("It can be combined arbitratily!")
#we can see e is the 1
print ("Obviously, the E is 1 in the mod n* multiply exp")
#judge whether everyone has a inverse or not
inversenum = [199 for i in range(N)]
for i in range(1, N):
for j in range(1, N):
modNum = (i * j) % N
if (modNum == 1): #has inverse
inversenum[i] = 1
ifInverse = 1
#print (len(inversenum))
for i in range(1, len(inversenum)):
#print (inversenum[i])
if (inversenum[i] != 1):#one is not a inverse!
ifInverse = 0
print ("Not everyone has a inverse..., It's not a Group!")
break
if (ifInverse):
print ("Everyone in this set has a inverse! Also it's a Group!")
二、写一个程序,实现AES的S-box的构造。
难,主要难点在于求有限域上的乘法逆元,参考《密码编码学与网络安全-原理与实践(第七版)》P101 5.6.3求乘法逆元章节,没有完全理解。但是还是想尝试使用扩充欧几里得算法求得每个s盒初始化元素在有限域上的乘法逆元,如下博客链接写的很棒,关于扩充欧几里得和怎样求乘法逆元https://blog.csdn.net/Stray_Lambs/article/details/52133141
没写出来嘿嘿,:)
于是就选择《密码编码学与网络安全-原理与实践(第七版)》P104 5.6.5 使用生成元求乘法逆元的,一开始写了个很渣的,后来参考到http://www.docin.com/p-929525675.html 上有个很棒的用C语言实现代码。
另外,github上https://github.com/Skycker/AES 写的步骤也很明确,只是Sbox那儿直接过程黑盒过去,贴表上去就完事,其他步骤棒棒!
下面是整体实现:
# coding=utf-8
# author:tyty
# date :2018/3/23
Sbox = [0 for i in range(256)] #sbox array
l_t = [0 for i in range(256)] #log table
m_t = [0 for i in range(256)] #pow table - decrease dimension
mid_t = [0 for i in range(256)] #inverse table
b = [0xf1, 0xe3, 0xc7, 0x8f, 0x1f, 0x3e, 0x7c, 0xf8] #b vector
#initialize
p = 1
'''
Step1. the inverse of multiply operation in GF(2^8)
'''
for i in range(256):
#2 mapping table
l_t[i] = p
m_t[p] = i
if (p & 0x80): #whether the b7 is 1 or not
p = p ^ (p << 1) ^ (0x11b) #generator p - 1
else :
p = p ^ (p << 1) ^ 0
#print (p)
for i in range(256):
if (i):
mid_t[i] = l_t[255 - m_t[i]] #255-m_t[i] is the location of inverse in table
#mid_t is the val of inverse
else:
mid_t[i] = 0 #{00} to {00}
#print (mid_t[i])
'''
Step2. the operation of matrix
'''
for i in range(256):
t = 0
tab = 0
for j in range(8):
m = mid = (b[j] & mid_t[i])#press b vector
#matrix multiplication
for k in range(8):
n = mid>>1
if (m != (n << 1)):
t+=1 #locate t
mid = n
m = mid
if (t % 2 > 0):
temp = 1
for k in range(j):
temp = temp << 1 # carry
tab += temp # sum
t = 0
Sbox[i] = tab ^ 0x63 #plus 0x63
print("Here is the Sbox!")#print
for i in range(0, 257):
if (i == 0):
continue
else :
print ("%x" % Sbox[i - 1], end = "")
if (i % 16 == 0):
print()
代码质量差,多多见谅 : )