-
Notifications
You must be signed in to change notification settings - Fork 1
/
s_des.py
76 lines (68 loc) · 3.03 KB
/
s_des.py
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
import sys
sys.path.append("../..")
from MyCrypto.des.des_utils import DES_base
class S_DES(DES_base):
def __init__(self, raw_key, _round=2):
self._round = _round
self._reset_data()
self._reset_key(raw_key)
def run(self, data, method='encrypt'):
''' do encryption or decryption for binary data '''
data = self.permutation(data, self._ip, 8) # 8bits
left_data, right_data = self.split_bit(data, 8, 2) # 8bits -> 4bits * 2
if method == 'encrypt':
iteration = range(self._round)
if method == 'decrypt':
iteration = range(self._round-1, -1, -1)
for i in iteration:
left_data, right_data = right_data, left_data ^ self._round_function(right_data, self.keys[i])
output = self.merge_bit((right_data, left_data), 4) # 4bits * 2 -> 8bits
output = self.permutation(output, self._ip_inv, 8) # 8bits
return output
def _round_function(self, data, key):
''' the round function '''
right_extended = self.permutation(data, self._extend, 4) # 4ibts -> 8bits
presult = right_extended ^ key
s_box_inputs = self.split_bit(presult, 8, 2) # 8bits -> 4bits * 2
s_box_outputs = [self._sbox_function(s_box_inputs[i], self._s_box[i]) for i in range(2)]
output = self.merge_bit(s_box_outputs, 2) # 2bits * 2 -> 4bits
output = self.permutation(output, self._permute, 4) # 4bits
return output
@staticmethod
def _sbox_function(data, s_box):
''' choose data from sbox '''
row = (S_DES.get_bit(data, 3) << 1) ^ (data & 1) # 2bits
col = (data >> 1) & ((1 << 2) - 1) # 2bits
return s_box[row*4+col]
def _reset_key(self, key):
''' reset keys of S-DES '''
self.keys = list()
key = self.permutation(key, self._pc1, 10) # 10bits
left_key, right_key = self.split_bit(key, 10, 2) # 10bits -> 5bits * 2
for i in range(self._round):
left_key, right_key = self.cyclic_lshift(left_key, 5, self._lshift[i]), self.cyclic_lshift(right_key, 5, self._lshift[i])
key = self.merge_bit((left_key, right_key), 5) # 5bits * 2 -> 10bits
key = self.permutation(key, self._pc2, 10) # 10bits -> 8bits
self.keys.append(key)
def _reset_data(self):
''' reset basic data of S-DES '''
self._ip = [2, 6, 3, 1, 4, 8, 5, 7]
self._ip_inv = [4, 1, 3, 5, 7, 2, 8, 6]
self._extend = [4, 1, 2, 3, 2, 3, 4, 1]
self._permute = [2, 4, 3, 1]
self._s_box = [
[1, 0, 3, 2, 3, 2, 1, 0, 0, 2, 1, 3, 3, 1, 3, 2],
[0, 1, 2, 3, 2, 0, 1, 3, 3, 0, 1, 0, 2, 1, 0, 3]
]
self._pc1 = [3, 5, 2, 7, 4, 10, 1, 9, 8, 6]
self._pc2 = [6, 3, 7, 4, 8, 5, 10, 9]
self._lshift = [1, 2]
if __name__ == '__main__':
key = 0b1010000010
s_des = S_DES(key)
data = 0b10111101
code = s_des.run(data)
text = s_des.run(code, method='decrypt')
print(bin(data))
print(bin(code))
print(bin(text))