-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathzuc.py
141 lines (125 loc) · 5.9 KB
/
zuc.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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
from bitarray import bitarray
from bitarray.util import int2ba, ba2int, ba2hex
d = [
0b100010011010111,
0b010011010111100,
0b110001001101011,
0b001001101011110,
0b101011110001001,
0b011010111100010,
0b111000100110101,
0b000100110101111,
0b100110101111000,
0b010111100010011,
0b110101111000100,
0b001101011110001,
0b101111000100110,
0b011110001001101,
0b111100010011010,
0b100011110101100,
]
s0 = [
0x3e,0x72,0x5b,0x47,0xca,0xe0,0x00,0x33,0x04,0xd1,0x54,0x98,0x09,0xb9,0x6d,0xcb,
0x7b,0x1b,0xf9,0x32,0xaf,0x9d,0x6a,0xa5,0xb8,0x2d,0xfc,0x1d,0x08,0x53,0x03,0x90,
0x4d,0x4e,0x84,0x99,0xe4,0xce,0xd9,0x91,0xdd,0xb6,0x85,0x48,0x8b,0x29,0x6e,0xac,
0xcd,0xc1,0xf8,0x1e,0x73,0x43,0x69,0xc6,0xb5,0xbd,0xfd,0x39,0x63,0x20,0xd4,0x38,
0x76,0x7d,0xb2,0xa7,0xcf,0xed,0x57,0xc5,0xf3,0x2c,0xbb,0x14,0x21,0x06,0x55,0x9b,
0xe3,0xef,0x5e,0x31,0x4f,0x7f,0x5a,0xa4,0x0d,0x82,0x51,0x49,0x5f,0xba,0x58,0x1c,
0x4a,0x16,0xd5,0x17,0xa8,0x92,0x24,0x1f,0x8c,0xff,0xd8,0xae,0x2e,0x01,0xd3,0xad,
0x3b,0x4b,0xda,0x46,0xeb,0xc9,0xde,0x9a,0x8f,0x87,0xd7,0x3a,0x80,0x6f,0x2f,0xc8,
0xb1,0xb4,0x37,0xf7,0x0a,0x22,0x13,0x28,0x7c,0xcc,0x3c,0x89,0xc7,0xc3,0x96,0x56,
0x07,0xbf,0x7e,0xf0,0x0b,0x2b,0x97,0x52,0x35,0x41,0x79,0x61,0xa6,0x4c,0x10,0xfe,
0xbc,0x26,0x95,0x88,0x8a,0xb0,0xa3,0xfb,0xc0,0x18,0x94,0xf2,0xe1,0xe5,0xe9,0x5d,
0xd0,0xdc,0x11,0x66,0x64,0x5c,0xec,0x59,0x42,0x75,0x12,0xf5,0x74,0x9c,0xaa,0x23,
0x0e,0x86,0xab,0xbe,0x2a,0x02,0xe7,0x67,0xe6,0x44,0xa2,0x6c,0xc2,0x93,0x9f,0xf1,
0xf6,0xfa,0x36,0xd2,0x50,0x68,0x9e,0x62,0x71,0x15,0x3d,0xd6,0x40,0xc4,0xe2,0x0f,
0x8e,0x83,0x77,0x6b,0x25,0x05,0x3f,0x0c,0x30,0xea,0x70,0xb7,0xa1,0xe8,0xa9,0x65,
0x8d,0x27,0x1a,0xdb,0x81,0xb3,0xa0,0xf4,0x45,0x7a,0x19,0xdf,0xee,0x78,0x34,0x60,
]
s1 = [
0x55,0xc2,0x63,0x71,0x3b,0xc8,0x47,0x86,0x9f,0x3c,0xda,0x5b,0x29,0xaa,0xfd,0x77,
0x8c,0xc5,0x94,0x0c,0xa6,0x1a,0x13,0x00,0xe3,0xa8,0x16,0x72,0x40,0xf9,0xf8,0x42,
0x44,0x26,0x68,0x96,0x81,0xd9,0x45,0x3e,0x10,0x76,0xc6,0xa7,0x8b,0x39,0x43,0xe1,
0x3a,0xb5,0x56,0x2a,0xc0,0x6d,0xb3,0x05,0x22,0x66,0xbf,0xdc,0x0b,0xfa,0x62,0x48,
0xdd,0x20,0x11,0x06,0x36,0xc9,0xc1,0xcf,0xf6,0x27,0x52,0xbb,0x69,0xf5,0xd4,0x87,
0x7f,0x84,0x4c,0xd2,0x9c,0x57,0xa4,0xbc,0x4f,0x9a,0xdf,0xfe,0xd6,0x8d,0x7a,0xeb,
0x2b,0x53,0xd8,0x5c,0xa1,0x14,0x17,0xfb,0x23,0xd5,0x7d,0x30,0x67,0x73,0x08,0x09,
0xee,0xb7,0x70,0x3f,0x61,0xb2,0x19,0x8e,0x4e,0xe5,0x4b,0x93,0x8f,0x5d,0xdb,0xa9,
0xad,0xf1,0xae,0x2e,0xcb,0x0d,0xfc,0xf4,0x2d,0x46,0x6e,0x1d,0x97,0xe8,0xd1,0xe9,
0x4d,0x37,0xa5,0x75,0x5e,0x83,0x9e,0xab,0x82,0x9d,0xb9,0x1c,0xe0,0xcd,0x49,0x89,
0x01,0xb6,0xbd,0x58,0x24,0xa2,0x5f,0x38,0x78,0x99,0x15,0x90,0x50,0xb8,0x95,0xe4,
0xd0,0x91,0xc7,0xce,0xed,0x0f,0xb4,0x6f,0xa0,0xcc,0xf0,0x02,0x4a,0x79,0xc3,0xde,
0xa3,0xef,0xea,0x51,0xe6,0x6b,0x18,0xec,0x1b,0x2c,0x80,0xf7,0x74,0xe7,0xff,0x21,
0x5a,0x6a,0x54,0x1e,0x41,0x31,0x92,0x35,0xc4,0x33,0x07,0x0a,0xba,0x7e,0x0e,0x34,
0x88,0xb1,0x98,0x7c,0xf3,0x3d,0x60,0x6c,0x7b,0xca,0xd3,0x1f,0x32,0x65,0x04,0x28,
0x64,0xbe,0x85,0x9b,0x2f,0x59,0x8a,0xd7,0xb0,0x25,0xac,0xaf,0x12,0x03,0xe2,0xf2,
]
def rol(bits, shift_num):
return bits[shift_num:] + bits[:shift_num]
def L1(bits):
return bits ^ rol(bits, 2) ^ rol(bits, 10) ^ rol(bits, 18) ^ rol(bits, 24)
def L2(bits):
return bits ^ rol(bits, 8) ^ rol(bits, 14) ^ rol(bits, 22) ^ rol(bits, 30)
def S(bits):
result = bitarray('')
result += int2ba(s0[ba2int(bits[0:8])], length=8)
result += int2ba(s1[ba2int(bits[8:16])], length=8)
result += int2ba(s0[ba2int(bits[16:24])], length=8)
result += int2ba(s1[ba2int(bits[24:32])], length=8)
return result
class ZUC:
def __init__(self, key, iv):
self.initialize(key, iv)
self.generate_32bit()
def initialize(self, key, iv):
#将密钥和初始化向量装入线性寄存器
self.s = []
for i in range(16):
self.s.append(key[i*8:i*8+8] + int2ba(d[i], length=15) + iv[i*8:i*8+8])
self.r1 = self.r2 = int2ba(0, length=32)
for i in range(32):
self.BitReconstruction()
self.F()
self.LFSRWithInitializationMode()
def BitReconstruction(self):
self.x0 = self.s[15][:16] + self.s[14][-16:]
self.x1 = self.s[11][-16:] + self.s[9][:16]
self.x2 = self.s[7][-16:] + self.s[5][:16]
self.x3 = self.s[2][-16:] + self.s[0][:16]
def F(self):
self.w = int2ba((ba2int(self.x0 ^ self.r1) + ba2int(self.r2)) % (2**32), length=32)
w1 = int2ba((ba2int(self.r1) + ba2int(self.x1)) % (2**32), length=32)
w2 = self.r2 ^ self.x2
self.r1 = S(L1(w1[-16:] + w2[:16]))
self.r2 = S(L2(w2[-16:] + w1[:16]))
return self.w
def LFSRWithInitializationMode(self):
v = (2**15*ba2int(self.s[15]) + 2**17*ba2int(self.s[13]) + 2**21*ba2int(self.s[10]) \
+ 2**20*ba2int(self.s[4]) + (1+2**8)*ba2int(self.s[0])) % (2**31 - 1)
s16 = int2ba((v + ba2int(self.w[:-1])) % (2**31 - 1), length=31)
for i in range(15):
self.s[i] = self.s[i + 1]
self.s[15] = s16
def LFSRWithWorkMode(self):
s16 = (2**15*ba2int(self.s[15]) + 2**17*ba2int(self.s[13]) + 2**21*ba2int(self.s[10]) \
+ 2**20*ba2int(self.s[4]) + (1+2**8)*ba2int(self.s[0])) % (2**31 - 1)
if s16 == 0:
s16 = 2**31 - 1
s16 = int2ba(s16, length=31)
for i in range(15):
self.s[i] = self.s[i + 1]
self.s[15] = s16
def generate_32bit(self):
self.BitReconstruction()
z = self.F() ^ self.x3
self.LFSRWithWorkMode()
return z
def bit2str(bits):
padBit = (4 - len(bits) % 4) % 4
return ba2hex(bitarray('0'*padBit) + bits).decode()
if __name__ == "__main__":
key = int2ba(0x3d4c4be96a82fdaeb58f641db17b455b, length=128)
iv = int2ba(0x84319aa8de6915ca1f6bda6bfbd8c766, length=128)
zucBlock = ZUC(key, iv)
for i in range(10):
print(bit2str(zucBlock.generate_32bit()))