-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprince64.py
114 lines (84 loc) · 4.75 KB
/
prince64.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
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
class prince:
def __init__(self, inL: list, inK: list):
self.SBox = [0x0B, 0x0F, 0x03, 0x02, 0x0A, 0x0C, 0x09, 0x01, 0x06, 0x07, 0x08, 0x00, 0x0E, 0x05, 0x0D, 0x04]
self.InvSBox = [0x0B, 0x07, 0x03, 0x02, 0x0F, 0x0D, 0x08, 0x09, 0x0A, 0x06, 0x04, 0x00, 0x05, 0x0E, 0x0C, 0x01]
self.RC = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x31, 0x91, 0xa8, 0xe2, 0x30, 0x07, 0x37, 0x44,
0x4a, 0x90, 0x83, 0x22, 0x92, 0xf9, 0x13, 0x0d,
0x80, 0xe2, 0xaf, 0x89, 0xce, 0xe4, 0xc6, 0x98
]
self._plaintext = inL
self.Key = inK
def cipher(self, ExKey):
self._plaintext = [self._plaintext[i] ^ ExKey[i] for i in range(8)]
self._AddKey(ExKey)
self._RCLayer(0)
self._SLayer()
self._MLayer()
self._RCLayer(1)
self._AddKey(ExKey)
self._SLayer()
self._MPrimeLayer()
self._InvSLayer()
self._AddKey(ExKey)
self._RCLayer(2)
self._InvMLayer()
self._InvSLayer()
self._RCLayer(3)
self._AddKey(ExKey)
self._plaintext = [self._plaintext[i] ^ ExKey[i+8] for i in range(8)]
def ExtendKey(self, Key):
newKey = [0x00] * 24
for i in range(8):
newKey[i] = Key[i]
newKey[i + 8] = (Key[i] >> 1) | (Key[(i + 1) % 8] << 7 & 0x80)
newKey[i + 16] = Key[i + 8]
newKey[15] ^= (Key[7] & 0x10)
return newKey
def _SR(self):
temp = self._plaintext[:]
perm = [0, 5, 2, 7, 4, 1, 6, 3]
self._plaintext = [ (temp[perm[i]] & 0x0F) | (self._plaintext[perm[(i+2)%8]] & 0xF0) for i in range(8)]
def _InvSR(self):
temp = self._plaintext[:]
perm = [0, 5, 2, 7, 4, 1, 6, 3]
self._plaintext = [ (temp[perm[i]] & 0x0F) | (self._plaintext[perm[(i+6)%8]] & 0xF0) for i in range(8)]
def _SLayer(self):
self._plaintext = [ (self.SBox[self._plaintext[i] >> 4] << 4) | self.SBox[self._plaintext[i] & 0x0F] for i in range(8) ]
def _InvSLayer(self):
self._plaintext = [ (self.InvSBox[self._plaintext[i] >> 4] << 4) | self.InvSBox[self._plaintext[i] & 0x0F] for i in range(8) ]
def _MPrimeLayer(self):
temp = self._plaintext[0]
self._plaintext[0] = (temp & 0xD7) ^ (self._plaintext[1] & 0x7D) ^ (temp >> 4 & 0x0B) ^ (self._plaintext[1] >> 4 & 0x0E) ^ (temp << 4 & 0xB0) ^ (self._plaintext[1] << 4 & 0xE0)
self._plaintext[1] = (temp & 0x7D) ^ (self._plaintext[1] & 0xD7) ^ (temp >> 4 & 0x0E) ^ (self._plaintext[1] >> 4 & 0x0B) ^ (temp << 4 & 0xE0) ^ (self._plaintext[1] << 4 & 0xB0)
temp = self._plaintext[2]
self._plaintext[2] = (temp & 0xEB) ^ (self._plaintext[3] & 0xBE) ^ (temp >> 4 & 0x0D) ^ (self._plaintext[3] >> 4 & 0x07) ^ (temp << 4 & 0xD0) ^ (self._plaintext[3] << 4 & 0x70)
self._plaintext[3] = (temp & 0xBE) ^ (self._plaintext[3] & 0xEB) ^ (temp >> 4 & 0x07) ^ (self._plaintext[3] >> 4 & 0x0D) ^ (temp << 4 & 0x70) ^ (self._plaintext[3] << 4 & 0xD0)
temp = self._plaintext[4]
self._plaintext[4] = (temp & 0xEB) ^ (self._plaintext[5] & 0xBE) ^ (temp >> 4 & 0x0D) ^ (self._plaintext[5] >> 4 & 0x07) ^ (temp << 4 & 0xD0) ^ (self._plaintext[5] << 4 & 0x70)
self._plaintext[5] = (temp & 0xBE) ^ (self._plaintext[5] & 0xEB) ^ (temp >> 4 & 0x07) ^ (self._plaintext[5] >> 4 & 0x0D) ^ (temp << 4 & 0x70) ^ (self._plaintext[5] << 4 & 0xD0)
temp = self._plaintext[6]
self._plaintext[6] = (temp & 0xD7) ^ (self._plaintext[7] & 0x7D) ^ (temp >> 4 & 0x0B) ^ (self._plaintext[7] >> 4 & 0x0E) ^ (temp << 4 & 0xB0) ^ (self._plaintext[7] << 4 & 0xE0)
self._plaintext[7] = (temp & 0x7D) ^ (self._plaintext[7] & 0xD7) ^ (temp >> 4 & 0x0E) ^ (self._plaintext[7] >> 4 & 0x0B) ^ (temp << 4 & 0xE0) ^ (self._plaintext[7] << 4 & 0xB0)
def _MLayer(self):
self._MPrimeLayer()
self._SR()
def _InvMLayer(self):
self._InvSR()
self._MPrimeLayer()
def _RCLayer(self, round):
self._plaintext = [ self._plaintext[i] ^ self.RC[8 * round + i] for i in range(8)]
def _AddKey(self, ExKey):
self._plaintext = [ self._plaintext[i] ^ ExKey[i + 16] for i in range(8) ]
def prince(self):
ExKey = self.ExtendKey(self.Key)
self.cipher(ExKey)
return [nibble >> 4 | (nibble << 4 & 0xF0) for nibble in self._plaintext]
def start(self):
ExKey = self.ExtendKey(self.Key)
self.cipher(ExKey)
print('0x', end='')
for i in range(8):
print(format(self._plaintext[i] >> 4 | (self._plaintext[i] << 4 & 0xF0), '02x'), end='')
print()