如何解决特殊情况下XOR函数失败
我想通过说这个问题与python有关而不与DES有关来开头。 我为我的密码学课程编写了一个DES加密程序。忽略密钥功能,此加密的一般格式为:明文->(排列)-> L0 R0。 L(i)= R(i-1)。 R(i)= L(i-1)XOR F(E(R(i-1)XOR K(i))) 目前,我的程序已输出此过程的每个步骤。在每一步中,我的程序都会按预期工作,直到我在该轮加密结束之前到达最终的XOR为止。我在此问题之前使用了XOR方法,并且可以按预期工作。 这是我上的课:
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,24,4,8,16,40,48,56,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,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,7],[0,8],[4,0],[15,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,10],[3,5],15],[13,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,1],[1,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,9],[10,4],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,[14,6],14],[11,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,11],[9,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,2],[6,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,[7,[2,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,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,'\ninitial D: ',self.printListInX(D,4))
shift1=[0,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: ','\nafter shift D: ',4))
K=self.PC2(C+D)
print('K',': ',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,4))
print('F',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',4))
print('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,64,57,7]
self.ipTableINV=[40,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,0]
m=[0,1]
print(xorBytes(n,m))
(抱歉,我无法获得代码示例中的最后3行)
该程序的输出如下:
[1,1]
这应该与“ newR:”一起输出
当i XOR L(i-1)与F(E(R(i-1)XOR K(i)))时,此错误在每一轮都发生
我不知道是什么导致了此错误,但是在此创建之前,根本没有使用过用于存储此结果的变量。我之前和之后使用的XOR方法是错误的,只是在每个回合中的此位置。每次此时,结果最终都是正确大小的全1列表。输入到我的XOR方法中的两个列表是先前输出的,因此它们存在并且包含正确的元素。
对此我将不胜感激。如开头所述,这可能是python问题,而不是DES问题。
解决方法
问题是您正在混合类型...有时使用字符列表'0'
和'1'
,有时使用数字列表0
和1
。
在Python中,0 == '0'
将返回False
,因此X-Or均为全。
只需将所有内容转换为使用字符或将所有内容转换为使用数字,请勿将它们混合使用。
对于其他比较类型(例如<
),Python 3会给出一个错误,但是对于相等性测试,无论值是多少,不同类型都只是比较不同。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。