-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdes.py
More file actions
119 lines (73 loc) · 2.1 KB
/
des.py
File metadata and controls
119 lines (73 loc) · 2.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
from tables import IP
def permute(block, table):
permuted = ""
for position in table:
permuted += block[position - 1]
return permuted
def shift_left(block, shifts):
return block[shifts:] + block[:shifts]
def xor(a, b):
result = ""
for i in range(len(a)):
if a[i] == b[i]:
result += "0"
else:
result += "1"
return result
from tables import S_BOXES
def sbox_substitution(bits):
output = ""
# Split into 8 groups of 6 bits
for i in range(8):
block = bits[i*6:(i+1)*6]
row = int(block[0] + block[5], 2)
column = int(block[1:5], 2)
value = S_BOXES[i][row][column]
output += format(value, '04b')
return output
from tables import PC1, PC2, SHIFT_SCHEDULE
def generate_round_keys(key):
round_keys = []
# Apply PC1
permuted_key = permute(key, PC1)
# Split into halves
left = permuted_key[:28]
right = permuted_key[28:]
# Generate 16 keys
for shift in SHIFT_SCHEDULE:
left = shift_left(left, shift)
right = shift_left(right, shift)
combined = left + right
round_key = permute(combined, PC2)
round_keys.append(round_key)
return round_keys
from tables import E, P
def des_round(left, right, round_key):
# Expansion
expanded = permute(right, E)
# XOR with round key
xored = xor(expanded, round_key)
# S-box substitution
sbox_output = sbox_substitution(xored)
# P permutation
p_output = permute(sbox_output, P)
# Generate new right
new_right = xor(left, p_output)
# New left becomes old right
new_left = right
return new_left, new_right
from tables import IP, FP
def encrypt_block(block, round_keys):
# Initial Permutation
block = permute(block, IP)
# Split into halves
left = block[:32]
right = block[32:]
# 16 rounds
for i in range(16):
left, right = des_round(left, right, round_keys[i])
# Final swap
combined = right + left
# Final Permutation
ciphertext = permute(combined, FP)
return ciphertext