协助第一轮DES算法 - Python

问题描述 投票:0回答:1

对于某些上下文,我必须经历一轮 DES 算法。我已经成功做到了,除了我现在得到的输出(这是一个 64 位字符串)与我期望得到的输出不同。

与预期输出相比,我的输出的前 48 位相同,而后 16 位不同。整个过程分为 9 个步骤。表数据和异或运算作为这个问题的示例代码提供给我。

我希望在创建第一个子项时使用“k”。

k = '0011000100110010001100110011010000110101001101100011011100111000'

我的最终目标是获得这个64位字符串:0000000011111111010000000011010100101000001100110101010110010101

1:确定 8 位代码的 ASCII 编码给出的 64 位二进制字符串。将该字符串赋给变量 m。这是您要加密的消息。

m = '21346281'

m = [bin(ord(x))[2:].zfill(8) for x in m]

m = ''.join(m)

print("m = ", m)

这给了我输出:m = 0011001000110001001100110011010000110110001100100011100000110001

2:确定将初始排列应用于消息 m 的结果。将生成的 64 位二进制字符串存储在变量 IPm 中。

m = '0011001000110001001100110011010000110110001100100011100000110001'

# Initial Permutation
IP=[
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]

# Applying the first permutation to m 
IPm = ''.join(m[ip - 1] for ip in IP)

print("IPm = ",IPm)

这给了我输出 IPm = 0000000011111111000110001000011000000000111111110100000000110101

3:确定作为第一轮输入的左半部分和右半部分。将这些32位二进制串分别存储在变量L0和R0中。

IPm = '0000000011111111000110001000011000000000111111110100000000110101'

# Split the 64-bit result from the Initial Permutation into two 32-bit halves
halfLength = len(IPm) // 2
L0 = IPm[:halfLength]
R0 = IPm[halfLength:]

# Print the results
print("L0:", L0)
print("R0:", R0)

这给了我输出:

L0:00000000111111110001100010000110

R0:00000000111111110100000000110101

4:确定R0的扩展/排列并将结果的48位二进制字符串存储在变量ER0中。

R0 = '00000000111111110100000000110101'

# Turn expansion permutation into list 
E = [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]

# Apply Expansion/Permutation to the right half R0
ER0 = ''.join(R0[position - 1] for position in E)

# Print the result
print("ER0 = ",ER0)

这给了我输出:ER0 = 100000000001011111111110101000000000000110101010

5:确定第一个子密钥K1,并将48位二进制串存储在变量K1中。

# Original 64-bit key
K = '0011000100110010001100110011010000110101001101100011011100111000'

# Permuted choice 1, used in key generation
PC1 = [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]

# Apply PC-1
KPC1 = ''.join(K[position - 1] for position in PC1)

# Split into two halves
halfLength = len(KPC1) // 2
c0 = KPC1[:halfLength]
d0 = KPC1[halfLength:]

# Define the shift schedule for each round
Schedule = [1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1]

# Perform left circular shifts and apply PC-2 to obtain K1
c = c0
d = d0
for i in range(Schedule[0]):
    c = c[1:] + c[0]
    d = d[1:] + d[0]

# Permuted choice 2, used in key generation
PC2 = [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]

K1 = ''.join((c + d)[position - 1] for position in PC2)[:48]

print("K1 = ",K1)

这给了我输出:K1 = 010100000010110010101100010101110010101011000010

6:确定输入ER0和K1的异或运算。将生成的 48 位二进制字符串存储到变量 A。

# Python function for carrying out the xor of two binary strings

ER0 = '100000000001011111111110101000000000000110101010'
K1 = '010100000010110010101100010101110010101011000010'

def XOR(ER0,K1):
    # ER0 and K1 should be binary strings of equal length
    A = ''.join(str((int(x) + int(y))%2) for x,y in zip(ER0,K1))
    return A

A = XOR(ER0,K1)
print("A = ",A)

这给了我输出:A = 110100000011101101010010111101110010101101101000

7:确定对位串 A 应用 S 盒替换/选择操作的结果。将生成的 32 位二进制串存储在变量 SA 中。

A = '110100000011101101010010111101110010101101101000'

#S-boxes
SBOX = [
# Box-1
[
[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]
],
# Box-2

[
[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]
],

# Box-3

[
[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]

],

# Box-4
[
[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]
],

# Box-5
[
[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]
],
# Box-6

[
[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]

],
# Box-7
[
[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]
],
# Box-8

[
[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]
]

]


# Split A into eight 6-bit blocks
splitA = [A[i:i+6] for i in range(0, len(A), 6)]


# Perform S-box substitution/choice operation on each 6-bit block
SA_blocks = []
for i, block in enumerate(splitA):
    row = int(block[0] + block[5], 2)  # Row is formed by the first and last bits
    col = int(block[1:5], 2)           # Column is formed by the middle four bits

    # Get the value from the corresponding S-box
    value = SBOX[i][row][col]

    # Convert the value to a 4-bit binary string
    binary_value = format(value, '04b')

    # Append the result to the list of SA_blocks
    SA_blocks.append(binary_value)

# Concatenate the results from each S-box to get the final 32-bit binary string
SA = ''.join(SA_blocks)

print("SA = ",SA)

这给了我输出:SA = 10011101100000100101000010101001

8:确定对SA应用置换函数的结果,并将所得的32位二进制串存储到变量PSA中。

SA = '10011101100000100101000010101001'

# Permutation P
P = [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]

# Apply permutation to SA
PSA = ''.join(SA[position - 1] for position in P)

print("PSA = ",PSA)

这给了我输出:PSA = 00101000110011000100110100010011

9:确定两个32位二进制输出串L1和R1,并将它们分别存储在变量L1和R1中。

# Previous values of L0 and R0
L0 = '00000000111111110001100010000110'
R0 = '00000000111111110100000000110101'

# Output from permutation P
PSA = '00101000110011000100110100010011'

def XOR(PSA,R0):
    # ER0 and K1 should be binary strings of equal length
    A = ''.join(str((int(x) + int(y))%2) for x,y in zip(PSA,R0))
    return A

A = XOR(PSA,R0)

# Swap the left and right halves correctly
L1 = R0
R1 = A

# Concatenate L1 and R1 to form a 64-bit string
result = L1 + R1

print("L1:", L1)
print("R1:", R1)
print("Concatenated Result:", result)

这给了我输出:

L1:00000000111111110100000000110101

R1:00101000001100110000110100100110

连接结果:0000000011111111010000000011010100101000001100110000110100100110

如您所见,连接结果与预期结果几乎相同:

0000000011111111010000000011010100101000001100110101010110010101

但是,我的结果的最后16位与预期的结果不同。如果这个问题很冗长,我很抱歉我只是想提供尽可能多的背景信息。感谢任何和所有的帮助。

python des
1个回答
0
投票

我已经成功解决了这个问题。在最后一步中,当执行 XOR 运算时,我不得不使用“L0”而不是使用“R0”。

def XOR(PSA,L0):
# ER0 and K1 should be binary strings of equal length
A = ''.join(str((int(x) + int(y))%2) for x,y in zip(PSA,L0))
return A

A = 异或(PSA,L0)

© www.soinside.com 2019 - 2024. All rights reserved.