XOR 函数在特殊情况下失败
XOR function failing in special cases
我想先说明这个问题是 python 相关的,而不是 DES 相关的。
我为我的密码学做了一个 DES 加密程序 class。忽略关键函数,这种加密的一般格式是:明文->(排列)-> L0 R0。 L(i)=R(i-1)。 R(i)=L(i-1) XOR F(E(R(i-1) XOR K(i)))
我的程序目前是用来输出这个过程中的每一步的。在每一步,我的程序都按预期工作,直到我在该轮加密结束之前到达最终的 XOR。我使用的 XOR 方法在此问题之前使用并且按预期工作。
这是我制作的class:
class DES:
def printListInX(self, l, x):
strList=""
for i in range(len(l)):
if i % x ==0:
strList+=" "
strList+=str(l[i])
return strList
def byteArrToInt(self,bits):
#generally only used for turning 3 bits to 1 num
temp=8*bits[0] + 4*bits[1] +2*bits[2]+bits[3]
return temp
def intTo4bits(self, n)->list:
bStr = ''
while n > 0:
bStr = str(n % 2) +bStr
n = n >> 1
while len(bStr)<4:
bStr="0"+bStr
return [int(x) for x in bStr]
def shiftLeft(self, h, num):
for i in range(num):
h=h[1:]+[h[0]]
return h
def xorBytes(self, n=[], m=[])->list:
#assume n m of equal size
temp=[]
for i in range(len(n)):
if n[i] == m[i]:
temp.append(0)
else:
temp.append(1)
return temp
def get2from1(self, L):
temp1=[]
temp2=[]
half=len(L)/2 #len is assumed even so no need to floor
for i in range(len(L)):
if i <half:
temp1.append(L[i])
else:
temp2.append(L[i])
return temp1, temp2
def hexToBinList(self,h):
binDict={
"0":"0000","1":"0001","2":"0010","3":"0011","4":"0100",
"5":"0101","6":"0110","7":"0111","8":"1000","9":"1001",
"A":"1010","a":"1010","b":"1011","B":"1011",
"C":"1100","c":"1100","D":"1101","d":"1101",
"E":"1110","e":"1110","F":"1111","f":"1111"
}
if isinstance(h, str):
strList=list(h)
elif isinstance(h,list):
#assume its a list of hex values
strList=h
ans=[]
for c in strList:
ans+=list(binDict[c])
return ans
def process(self, h):
if isinstance(h, str):
if len(h)==64:
#make into array of those ints
#assuming 64 len string is only 1 or 0
temp=list(h)
return [int(x) for x in temp]
elif len(h)==16:
return self.hexToBinList(h)
elif isinstance(h, list):
if len(h)==64:
#assume binary
return h
elif len(h)==16:
return self.hexToBinList(h)
#else? if int do i convert to hex?
def initialPermutation(self, ptList):
#reorder bits, newList[0]=ptList[57] (58 but indexing starts at 1 not 0)
newList=[]
for i in range(len(ptList)):
newList.append(ptList[self.ipTable[i] - 1])
return newList
def PC1(self,keyList):
pc1Table=[57,49,41,33,25,17,9,
1,58,50,42,34,26,18,
10,2,59,51,43,35,27,
19,11,3,60,52,44,36,
63,55,47,39,31,23,15,
7,62,54,46,38,30,22,
14,6,61,53,45,37,29,
21,13,5,28,20,12,4]
#len(keyList)==64
#len(ans)==56
ans=[]
for i in range(56):
ans.append(keyList[pc1Table[i] - 1])
return ans
def PC2(self, keyList):
pc2Table=[14,17,11,24,1,5,3,28,
15,6,21,10,23,19,12,4,
26,8,16,7,27,20,13,2,
41,52,31,37,47,55,30,40,
51,45,33,48,44,49,39,56,
34,53,46,42,50,36,29,32]
#len(keyList)=56
#len(ans)=48
ans=[]
for i in range(48):
ans.append(keyList[pc2Table[i] - 1])
return ans
def expansion(self, R:list)->list:
eTable=[32,1,2,3,4,5,
4,5,6,7,8,9,
8,9,10,11,12,13,
12,13,14,15,16,17,
16,17,18,19,20,21,
20,21,22,23,24,25,
24,25,26,27,28,29,
28,29,30,31,32,1]
#len(R)=32
#len(ans)=48
ans=[]
for i in range(48):
ans.append(R[eTable[i] - 1])
return ans
def s1box(self, bits)->list:
#bits is R XOR K. will be broken and sent to each box class internally
box=[
[14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7],
[0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8],
[4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0],
[15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13]
]
usable=bits[:6]
bits=bits[6:]
row=int( (str(usable[0]) + str(usable[-1])), 2)
col=self.byteArrToInt(usable[1:-1])
print('bits from s1box: ', self.intTo4bits(box[row][col]))
return self.intTo4bits(box[row][col]) + self.s2box(bits)
def s2box(self, bits)->list:
box=[
[15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10],
[3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5],
[0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15],
[13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9]
]
usable=bits[:6]
bits=bits[6:]
row=int( (str(usable[0]) + str(usable[-1])), 2)
col=self.byteArrToInt(usable[1:-1])
print('bits from s2box: ', self.intTo4bits(box[row][col]))
return self.intTo4bits(box[row][col]) + self.s3box(bits)
def s3box(self, bits)->list:
box=[
[10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8],
[13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1],
[13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7],
[1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12]
]
usable=bits[:6]
bits=bits[6:]
row=int( (str(usable[0]) + str(usable[-1])), 2)
col=self.byteArrToInt(usable[1:-1])
print('bits from s3box: ', self.intTo4bits(box[row][col]))
return self.intTo4bits(box[row][col]) + self.s4box(bits)
def s4box(self, bits)->list:
box=[
[7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15],
[13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9],
[10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4],
[3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14]
]
usable=bits[:6]
bits=bits[6:]
row=int( (str(usable[0]) + str(usable[-1])), 2)
col=self.byteArrToInt(usable[1:-1])
print('bits from s4box: ', self.intTo4bits(box[row][col]))
return self.intTo4bits(box[row][col]) + self.s5box(bits)
def s5box(self, bits)->list:
box=[
[2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9],
[14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6],
[4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14],
[11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3]
]
usable=bits[:6]
bits=bits[6:]
row=int( (str(usable[0]) + str(usable[-1])), 2)
col=self.byteArrToInt(usable[1:-1])
print('bits from s5box: ', self.intTo4bits(box[row][col]))
return self.intTo4bits(box[row][col]) + self.s6box(bits)
def s6box(self, bits)->list:
box=[
[12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11],
[10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8],
[9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6],
[4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13]
]
usable=bits[:6]
bits=bits[6:]
row=int( (str(usable[0]) + str(usable[-1])), 2)
col=self.byteArrToInt(usable[1:-1])
print('bits from s6box: ', self.intTo4bits(box[row][col]))
return self.intTo4bits(box[row][col]) + self.s7box(bits)
def s7box(self, bits)->list:
box=[
[4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1],
[13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6],
[1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2],
[6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12]
]
usable=bits[:6]
bits=bits[6:]
row=int( (str(usable[0]) + str(usable[-1])), 2)
col=self.byteArrToInt(usable[1:-1])
print('bits from s7box: ', self.intTo4bits(box[row][col]))
return self.intTo4bits(box[row][col]) + self.s8box(bits)
def s8box(self, bits)->list:
box=[
[13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7],
[1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2],
[7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8],
[2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11]
]
#bits should not be len 6
row=int( (str(bits[0]) + str(bits[-1])), 2)
col=self.byteArrToInt(bits[1:-1])
print('bits from s8box: ', self.intTo4bits(box[row][col]))
return self.intTo4bits(box[row][col])
def pBox(self, bits)->list:
box=[16,7,20,21,29,12,28,17,
1,15,23,26,5,18,31,10,
2,8,24,14,32,27,3,9,
19,13,30,6,22,11,4,25]
ans=[]
for i in range(32):
ans.append(bits[box[i] - 1])
print('bits from pBox: ',self.printListInX(ans, 4))
return ans
def F(self, R:list, K:list)->list:
#expand R from 32 to 48 bits
expR=self.expansion(R)
print('R after expansion: ', self.printListInX(expR, 6))
#XOR newR with K
rXorK=self.xorBytes(expR,K)
print('R XOR K: ', self.printListInX(rXorK, 6))
#break into 8 sub lists (size 6 each) for S boxes
afterSbox=self.s1box(rXorK) #should now be 32 bits
#P box permutation
ans=self.pBox(afterSbox)
return ans
def finalPermutation(self, bits:list)->list:
newList=[]
for i in range(len(bits)):
newList.append(bits[self.ipTableINV[i] - 1])
return newList
def encrypt(self, pt, key, numRounds):
################# SOMETHIGN WRONG ALGORITHMETICALLY #####################
############ i think its because i get L0 and R0 but never actually use them in F
self.pt=self.process(pt) #will be type list
self.key = self.process(key)#will be type list
self.numRounds=numRounds #should always be 16
#do IP on pt to get L,R
newPtList=self.initialPermutation(self.pt)
print('PT after first permutation: ', self.printListInX(newPtList,4))
L,R=self.get2from1(newPtList)
print("L0: ", self.printListInX(L, 4), "\tR0: ", self.printListInX(R, 4))
#do PC1 on key to get C,D
key56bits=self.PC1(self.key)
print('key after PC1: ', self.printListInX(key56bits, 4))
C,D=self.get2from1(key56bits)
print('initail C: ', self.printListInX(C, 4), '\ninitial D: ', self.printListInX(D, 4))
shift1=[0,1,8,15]
for i in range(numRounds):
print('\n\nstart of round ', (i+1),'\n\n')
newL=R
#newC=C (shifted left x times)
#newD=D (shifted left x times)
#x depends on roundnum
if i in shift1:
C=self.shiftLeft(C,1)
D=self.shiftLeft(D,1)
else:
C=self.shiftLeft(C,2)
D=self.shiftLeft(D,2)
#K=COMPRESS(newC,newD)
print('after shift C: ', self.printListInX(C, 4), '\nafter shift D: ', self.printListInX(D, 4))
K=self.PC2(C+D)
print('K', (i+1), ': ', self.printListInX(K, 6))
#newR=L XOR F(R,K)
fOfRK=self.F(R,K)
print('F of R0,K1: ', self.printListInX(fOfRK, 4))
print('before final XOR')
print('L',i,': ', self.printListInX(L, 4))
print('F',(i+1),': ',self.printListInX(fOfRK,4))
################### start issue ################
newR=self.xorBytes(fOfRK,L)
################### end issue ##################
print('newR: ', self.printListInX(newR, 4))
#L=newL, R=newR, C=newC, D=newD
R=newR
L=newL
print('L', (i+1), ': ', self.printListInX(L, 4))
print('R', (i+1), ': ', self.printListInX(R, 4))
#now that rounds are done, do final permutation (ipTableINV)
self.encryptedBits=self.finalPermutation(L+R)
return self.encryptedBits
def __init__(self):
self.ipTable=[58,50,42,34,26,18,10,2,
60,52,44,36,28,20,12,4,
62,54,46,38,30,22,14,6,
64,56,48,40,32,24,16,8,
57,49,41,33,25,17,9,1,
59,51,43,35,27,19,11,3,
61,53,45,37,29,21,13,5,
63,55,47,39,31,23,15,7]
self.ipTableINV=[40,8,48,16,56,24,64,32,
39,7,47,15,55,23,63,31,
38,6,46,14,54,22,26,30,
37,5,45,13,53,21,61,29,
36,4,44,12,52,20,60,28,
35,3,43,11,51,19,59,27,
34,2,42,10,50,18,58,26,
33,1,41,9,49,17,57,25]
这是用于 运行 和创建输出的驱动程序:
from DES64Bit import DES
cipher=DES()
pt="0123456789ABCDEF"
key="0123456789ABCDEF"
cipher.encrypt(pt=pt, key=key, numRounds=2)
由此产生的输出如下
DES_OUTPUT
这里是第二轮开始前倒数第三轮“newR:”
这一行应该由前两行异或组成。
我这里有一个程序使用内部使用的相同方法以及相同的位串
def xorBytes(n, m):
#assume n m of equal size
temp=[]
for i in range(len(n)):
if n[i] == m[i]:
temp.append(0)
else:
temp.append(1)
return temp
n=[1,1,1,1, 0,0,0,0, 1,0,1,0, 1,0,1,0, 1,1,1,1, 0,0,0,0, 1,0,1,0, 1,0,1,0]
m=[0,0,1,1, 1,0,0,0, 1,1,0,1, 1,0,1,1, 1,1,1,1, 1,0,0,1, 1,1,0,0, 1,0,1,1]
print(xorBytes(n,m))
(抱歉我无法将最后 3 行包含在代码示例中)
这个程序的输出如下:
[1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1]
这是应该与“newR:”一起输出的内容
当 i XOR L(i-1) 与 F(E(R(i-1) XOR K(i)))
我不知道是什么导致了这个错误,但是我用来存储这个结果的变量在创建之前根本没有被使用过。我使用的异或方法前后都用过,只是在每一轮的这个位置是不正确的。每次,在这一点上,结果最终都是一个大小正确的全 1 列表。输入到我的 XOR 方法中的两个列表是先前输出的,因此它们存在并包含正确的元素。
如有任何帮助,我将不胜感激。如开头所述,这可能更像是 python 问题而不是 DES 问题。
问题是您在混合类型...有时您使用字符列表 '0'
和 '1'
,有时使用数字列表 0
和 1
。
在 Python 0 == '0'
中将 return False
因此 X-Or 将全部为 1。
把所有的东西都转换成字符或者把所有的东西都转换成数字,不要混用。
对于其他比较类型(例如<
)Python 3 会给出错误,但对于相等性测试,不同类型只是比较不同,无论值是什么。
我想先说明这个问题是 python 相关的,而不是 DES 相关的。 我为我的密码学做了一个 DES 加密程序 class。忽略关键函数,这种加密的一般格式是:明文->(排列)-> L0 R0。 L(i)=R(i-1)。 R(i)=L(i-1) XOR F(E(R(i-1) XOR K(i))) 我的程序目前是用来输出这个过程中的每一步的。在每一步,我的程序都按预期工作,直到我在该轮加密结束之前到达最终的 XOR。我使用的 XOR 方法在此问题之前使用并且按预期工作。 这是我制作的class:
class DES:
def printListInX(self, l, x):
strList=""
for i in range(len(l)):
if i % x ==0:
strList+=" "
strList+=str(l[i])
return strList
def byteArrToInt(self,bits):
#generally only used for turning 3 bits to 1 num
temp=8*bits[0] + 4*bits[1] +2*bits[2]+bits[3]
return temp
def intTo4bits(self, n)->list:
bStr = ''
while n > 0:
bStr = str(n % 2) +bStr
n = n >> 1
while len(bStr)<4:
bStr="0"+bStr
return [int(x) for x in bStr]
def shiftLeft(self, h, num):
for i in range(num):
h=h[1:]+[h[0]]
return h
def xorBytes(self, n=[], m=[])->list:
#assume n m of equal size
temp=[]
for i in range(len(n)):
if n[i] == m[i]:
temp.append(0)
else:
temp.append(1)
return temp
def get2from1(self, L):
temp1=[]
temp2=[]
half=len(L)/2 #len is assumed even so no need to floor
for i in range(len(L)):
if i <half:
temp1.append(L[i])
else:
temp2.append(L[i])
return temp1, temp2
def hexToBinList(self,h):
binDict={
"0":"0000","1":"0001","2":"0010","3":"0011","4":"0100",
"5":"0101","6":"0110","7":"0111","8":"1000","9":"1001",
"A":"1010","a":"1010","b":"1011","B":"1011",
"C":"1100","c":"1100","D":"1101","d":"1101",
"E":"1110","e":"1110","F":"1111","f":"1111"
}
if isinstance(h, str):
strList=list(h)
elif isinstance(h,list):
#assume its a list of hex values
strList=h
ans=[]
for c in strList:
ans+=list(binDict[c])
return ans
def process(self, h):
if isinstance(h, str):
if len(h)==64:
#make into array of those ints
#assuming 64 len string is only 1 or 0
temp=list(h)
return [int(x) for x in temp]
elif len(h)==16:
return self.hexToBinList(h)
elif isinstance(h, list):
if len(h)==64:
#assume binary
return h
elif len(h)==16:
return self.hexToBinList(h)
#else? if int do i convert to hex?
def initialPermutation(self, ptList):
#reorder bits, newList[0]=ptList[57] (58 but indexing starts at 1 not 0)
newList=[]
for i in range(len(ptList)):
newList.append(ptList[self.ipTable[i] - 1])
return newList
def PC1(self,keyList):
pc1Table=[57,49,41,33,25,17,9,
1,58,50,42,34,26,18,
10,2,59,51,43,35,27,
19,11,3,60,52,44,36,
63,55,47,39,31,23,15,
7,62,54,46,38,30,22,
14,6,61,53,45,37,29,
21,13,5,28,20,12,4]
#len(keyList)==64
#len(ans)==56
ans=[]
for i in range(56):
ans.append(keyList[pc1Table[i] - 1])
return ans
def PC2(self, keyList):
pc2Table=[14,17,11,24,1,5,3,28,
15,6,21,10,23,19,12,4,
26,8,16,7,27,20,13,2,
41,52,31,37,47,55,30,40,
51,45,33,48,44,49,39,56,
34,53,46,42,50,36,29,32]
#len(keyList)=56
#len(ans)=48
ans=[]
for i in range(48):
ans.append(keyList[pc2Table[i] - 1])
return ans
def expansion(self, R:list)->list:
eTable=[32,1,2,3,4,5,
4,5,6,7,8,9,
8,9,10,11,12,13,
12,13,14,15,16,17,
16,17,18,19,20,21,
20,21,22,23,24,25,
24,25,26,27,28,29,
28,29,30,31,32,1]
#len(R)=32
#len(ans)=48
ans=[]
for i in range(48):
ans.append(R[eTable[i] - 1])
return ans
def s1box(self, bits)->list:
#bits is R XOR K. will be broken and sent to each box class internally
box=[
[14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7],
[0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8],
[4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0],
[15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13]
]
usable=bits[:6]
bits=bits[6:]
row=int( (str(usable[0]) + str(usable[-1])), 2)
col=self.byteArrToInt(usable[1:-1])
print('bits from s1box: ', self.intTo4bits(box[row][col]))
return self.intTo4bits(box[row][col]) + self.s2box(bits)
def s2box(self, bits)->list:
box=[
[15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10],
[3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5],
[0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15],
[13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9]
]
usable=bits[:6]
bits=bits[6:]
row=int( (str(usable[0]) + str(usable[-1])), 2)
col=self.byteArrToInt(usable[1:-1])
print('bits from s2box: ', self.intTo4bits(box[row][col]))
return self.intTo4bits(box[row][col]) + self.s3box(bits)
def s3box(self, bits)->list:
box=[
[10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8],
[13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1],
[13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7],
[1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12]
]
usable=bits[:6]
bits=bits[6:]
row=int( (str(usable[0]) + str(usable[-1])), 2)
col=self.byteArrToInt(usable[1:-1])
print('bits from s3box: ', self.intTo4bits(box[row][col]))
return self.intTo4bits(box[row][col]) + self.s4box(bits)
def s4box(self, bits)->list:
box=[
[7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15],
[13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9],
[10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4],
[3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14]
]
usable=bits[:6]
bits=bits[6:]
row=int( (str(usable[0]) + str(usable[-1])), 2)
col=self.byteArrToInt(usable[1:-1])
print('bits from s4box: ', self.intTo4bits(box[row][col]))
return self.intTo4bits(box[row][col]) + self.s5box(bits)
def s5box(self, bits)->list:
box=[
[2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9],
[14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6],
[4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14],
[11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3]
]
usable=bits[:6]
bits=bits[6:]
row=int( (str(usable[0]) + str(usable[-1])), 2)
col=self.byteArrToInt(usable[1:-1])
print('bits from s5box: ', self.intTo4bits(box[row][col]))
return self.intTo4bits(box[row][col]) + self.s6box(bits)
def s6box(self, bits)->list:
box=[
[12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11],
[10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8],
[9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6],
[4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13]
]
usable=bits[:6]
bits=bits[6:]
row=int( (str(usable[0]) + str(usable[-1])), 2)
col=self.byteArrToInt(usable[1:-1])
print('bits from s6box: ', self.intTo4bits(box[row][col]))
return self.intTo4bits(box[row][col]) + self.s7box(bits)
def s7box(self, bits)->list:
box=[
[4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1],
[13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6],
[1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2],
[6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12]
]
usable=bits[:6]
bits=bits[6:]
row=int( (str(usable[0]) + str(usable[-1])), 2)
col=self.byteArrToInt(usable[1:-1])
print('bits from s7box: ', self.intTo4bits(box[row][col]))
return self.intTo4bits(box[row][col]) + self.s8box(bits)
def s8box(self, bits)->list:
box=[
[13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7],
[1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2],
[7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8],
[2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11]
]
#bits should not be len 6
row=int( (str(bits[0]) + str(bits[-1])), 2)
col=self.byteArrToInt(bits[1:-1])
print('bits from s8box: ', self.intTo4bits(box[row][col]))
return self.intTo4bits(box[row][col])
def pBox(self, bits)->list:
box=[16,7,20,21,29,12,28,17,
1,15,23,26,5,18,31,10,
2,8,24,14,32,27,3,9,
19,13,30,6,22,11,4,25]
ans=[]
for i in range(32):
ans.append(bits[box[i] - 1])
print('bits from pBox: ',self.printListInX(ans, 4))
return ans
def F(self, R:list, K:list)->list:
#expand R from 32 to 48 bits
expR=self.expansion(R)
print('R after expansion: ', self.printListInX(expR, 6))
#XOR newR with K
rXorK=self.xorBytes(expR,K)
print('R XOR K: ', self.printListInX(rXorK, 6))
#break into 8 sub lists (size 6 each) for S boxes
afterSbox=self.s1box(rXorK) #should now be 32 bits
#P box permutation
ans=self.pBox(afterSbox)
return ans
def finalPermutation(self, bits:list)->list:
newList=[]
for i in range(len(bits)):
newList.append(bits[self.ipTableINV[i] - 1])
return newList
def encrypt(self, pt, key, numRounds):
################# SOMETHIGN WRONG ALGORITHMETICALLY #####################
############ i think its because i get L0 and R0 but never actually use them in F
self.pt=self.process(pt) #will be type list
self.key = self.process(key)#will be type list
self.numRounds=numRounds #should always be 16
#do IP on pt to get L,R
newPtList=self.initialPermutation(self.pt)
print('PT after first permutation: ', self.printListInX(newPtList,4))
L,R=self.get2from1(newPtList)
print("L0: ", self.printListInX(L, 4), "\tR0: ", self.printListInX(R, 4))
#do PC1 on key to get C,D
key56bits=self.PC1(self.key)
print('key after PC1: ', self.printListInX(key56bits, 4))
C,D=self.get2from1(key56bits)
print('initail C: ', self.printListInX(C, 4), '\ninitial D: ', self.printListInX(D, 4))
shift1=[0,1,8,15]
for i in range(numRounds):
print('\n\nstart of round ', (i+1),'\n\n')
newL=R
#newC=C (shifted left x times)
#newD=D (shifted left x times)
#x depends on roundnum
if i in shift1:
C=self.shiftLeft(C,1)
D=self.shiftLeft(D,1)
else:
C=self.shiftLeft(C,2)
D=self.shiftLeft(D,2)
#K=COMPRESS(newC,newD)
print('after shift C: ', self.printListInX(C, 4), '\nafter shift D: ', self.printListInX(D, 4))
K=self.PC2(C+D)
print('K', (i+1), ': ', self.printListInX(K, 6))
#newR=L XOR F(R,K)
fOfRK=self.F(R,K)
print('F of R0,K1: ', self.printListInX(fOfRK, 4))
print('before final XOR')
print('L',i,': ', self.printListInX(L, 4))
print('F',(i+1),': ',self.printListInX(fOfRK,4))
################### start issue ################
newR=self.xorBytes(fOfRK,L)
################### end issue ##################
print('newR: ', self.printListInX(newR, 4))
#L=newL, R=newR, C=newC, D=newD
R=newR
L=newL
print('L', (i+1), ': ', self.printListInX(L, 4))
print('R', (i+1), ': ', self.printListInX(R, 4))
#now that rounds are done, do final permutation (ipTableINV)
self.encryptedBits=self.finalPermutation(L+R)
return self.encryptedBits
def __init__(self):
self.ipTable=[58,50,42,34,26,18,10,2,
60,52,44,36,28,20,12,4,
62,54,46,38,30,22,14,6,
64,56,48,40,32,24,16,8,
57,49,41,33,25,17,9,1,
59,51,43,35,27,19,11,3,
61,53,45,37,29,21,13,5,
63,55,47,39,31,23,15,7]
self.ipTableINV=[40,8,48,16,56,24,64,32,
39,7,47,15,55,23,63,31,
38,6,46,14,54,22,26,30,
37,5,45,13,53,21,61,29,
36,4,44,12,52,20,60,28,
35,3,43,11,51,19,59,27,
34,2,42,10,50,18,58,26,
33,1,41,9,49,17,57,25]
这是用于 运行 和创建输出的驱动程序:
from DES64Bit import DES
cipher=DES()
pt="0123456789ABCDEF"
key="0123456789ABCDEF"
cipher.encrypt(pt=pt, key=key, numRounds=2)
由此产生的输出如下 DES_OUTPUT
这里是第二轮开始前倒数第三轮“newR:” 这一行应该由前两行异或组成。
我这里有一个程序使用内部使用的相同方法以及相同的位串
def xorBytes(n, m):
#assume n m of equal size
temp=[]
for i in range(len(n)):
if n[i] == m[i]:
temp.append(0)
else:
temp.append(1)
return temp
n=[1,1,1,1, 0,0,0,0, 1,0,1,0, 1,0,1,0, 1,1,1,1, 0,0,0,0, 1,0,1,0, 1,0,1,0]
m=[0,0,1,1, 1,0,0,0, 1,1,0,1, 1,0,1,1, 1,1,1,1, 1,0,0,1, 1,1,0,0, 1,0,1,1]
print(xorBytes(n,m))
(抱歉我无法将最后 3 行包含在代码示例中)
这个程序的输出如下:
[1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1]
这是应该与“newR:”一起输出的内容
当 i XOR L(i-1) 与 F(E(R(i-1) XOR K(i)))
我不知道是什么导致了这个错误,但是我用来存储这个结果的变量在创建之前根本没有被使用过。我使用的异或方法前后都用过,只是在每一轮的这个位置是不正确的。每次,在这一点上,结果最终都是一个大小正确的全 1 列表。输入到我的 XOR 方法中的两个列表是先前输出的,因此它们存在并包含正确的元素。
如有任何帮助,我将不胜感激。如开头所述,这可能更像是 python 问题而不是 DES 问题。
问题是您在混合类型...有时您使用字符列表 '0'
和 '1'
,有时使用数字列表 0
和 1
。
在 Python 0 == '0'
中将 return False
因此 X-Or 将全部为 1。
把所有的东西都转换成字符或者把所有的东西都转换成数字,不要混用。
对于其他比较类型(例如<
)Python 3 会给出错误,但对于相等性测试,不同类型只是比较不同,无论值是什么。