实验二

流密码主要算法实现

姓名:徐慧聪

学号:2023103793


1. 实验环境

  • ubuntu 22.04
  • Python 3.10
  • 文件结构(/dist/StreamCipher为可执行文件)

Untitled

2. 代码实现

2.1 Grain

  • LFSR存key
  • NFSR存全1
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
class Grain128:
def __init__(self, key):
self.LFSR = key & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
self.NFSR = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

def clock(self):
feedback_LFSR = (self.LFSR >> 7) & 1 ^ (self.LFSR >> 38) & 1 ^ (self.LFSR >> 70) & 1 ^ (self.LFSR >> 81) & 1 ^ (self.LFSR >> 96) & 1
feedback_NFSR = self.LFSR & 1 ^ (self.NFSR >> 26) & 1 ^ (self.NFSR >> 56) & 1 ^ (self.NFSR >> 91) & 1 ^ (self.NFSR >> 96) & 1 ^ (self.NFSR >> 3) & (self.NFSR >> 67) & 1 ^ (self.NFSR >> 11) & (self.NFSR >> 13) & 1 ^ (self.NFSR >> 17) & (self.NFSR >> 18) & 1 ^ (self.NFSR >> 27) & (self.NFSR >> 59) & 1 ^ (self.NFSR >> 40) & (self.NFSR >> 48) & 1 ^ (self.NFSR >> 61) & (self.NFSR >> 65) & 1 ^ (self.NFSR >> 68) & (self.NFSR >> 84) & 1 ^ (self.NFSR >> 88) & (self.NFSR >> 92) & (self.NFSR >> 93) & (self.NFSR >> 95) & 1 ^ (self.NFSR >> 22) & (self.NFSR >> 24) & (self.NFSR >> 25) & 1 ^ (self.NFSR >> 70) & (self.NFSR >> 78) & (self.NFSR >> 82) & 1

self.NFSR >>= 1
self.NFSR |= feedback_LFSR << 127
self.LFSR >>= 1
self.LFSR |= feedback_NFSR << 127

return feedback_LFSR, feedback_NFSR

def h(self, s, b):
return (b >> 12) & 1 ^ (s >> 8) & 1 ^ (s >> 13) & (s >> 20) & 1 ^ (b >> 95) & (s >> 42) & 1 ^ (s >> 60) & (s >> 79) & 1 ^ (b >> 12) & (b >> 95) & (s >> 94) & 1

def generate_keystream(self, length):
keystream = []
for _ in range(length):
feedback_LFSR, feedback_NFSR = self.clock()
keystream.append(self.h(self.NFSR, self.LFSR))
return keystream

def encrypt(self, plaintext):
keystream = self.generate_keystream(len(plaintext))
ciphertext = bytes([plaintext[i] ^ keystream[i] for i in range(len(plaintext))])
return ciphertext

def decrypt(self, ciphertext):
return self.encrypt(ciphertext) # XOR 加密和解密是相同的操作

2.2 Trivium

  • 与Grain算法类似
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
class Trivium:
def __init__(self, key, iv):
self.state = [0] * 288

# 将密钥和初始向量放入寄存器
for i in range(80):
self.state[i] = (key >> i) & 1
for i in range(94, 177):
self.state[i] = (iv >> (i - 94)) & 1
for i in range(285, 288):
self.state[i] = 1

def clock(self):
t1 = self.state[65] ^ self.state[92]
t2 = self.state[161] ^ self.state[176]
t3 = self.state[242] ^ self.state[287]

z = t1 ^ t2 ^ t3

t1 ^= self.state[90] & self.state[91] ^ self.state[170]
t2 ^= self.state[174] & self.state[175] ^ self.state[263]
t3 ^= self.state[285] & self.state[286] ^ self.state[68]

self.state = [t3] + self.state[:92] + [t1] + self.state[93:176] + [t2] + self.state[177:287]
# print(len(self.state))
return z

def generate_keystream(self, length):
keystream = []
for _ in range(length):
z = self.clock()
keystream.append(z)
return keystream

def encrypt(self, plaintext):
keystream = self.generate_keystream(len(plaintext))
ciphertext = bytes([plaintext[i] ^ keystream[i] for i in range(len(plaintext))])
return ciphertext

def decrypt(self, ciphertext):
return self.encrypt(ciphertext) # XOR 加密和解密是相同的操作

2.3 ZUC

  • 加载密钥
  • LFSR状态重组
  • 计算非线性函数F
  • LFSR的初始化模式和工作模式
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
class ZUC_128:
def __init__(self, key, iv, D):
self.key = key # 128位密钥
self.iv = iv # 128位初始化向量
self.D = D # 240位常量

self.LFSR = [0]*16 # 31bit*16寄存器单元
self.R1 = 0 # 2个32bit记忆单元
self.R2 = 0
self.BRx = [0]*4 # 比特重组后的结果
self.init_zuc()

def load_key(self):
# 将key ,iv,D重组为31bit*16LFSR
# 将key,iv 分为8bit * 16个单元
key_units = [(self.key >> (15 - i) * 8) & 0xFF for i in range(16)]
iv_units = [(self.iv >> (15 - i) * 8) & 0xFF for i in range(16)]

# 将D 分为15位16个单元
D_units = [(self.D >> (15 - i) * 15) & 0x7FFF for i in range(16)]

# 将8+8+15组成新的整数存入LFSR中
for i in range(16):
self.LFSR[i] = (key_units[i] << 23) | (iv_units[i] << 15) | D_units[i]

def BR(self):
# 将LFSR状态重组,生成四个X变量
self.BRx[0] = ((self.LFSR[15] & 0x7fff8000) << 1) | (self.LFSR[14] & 0xffff)
self.BRx[1] = ((self.LFSR[11] & 0xFFFF) << 16) | ((self.LFSR[9] >> 15) & 0x7fff)
self.BRx[2] = ((self.LFSR[7] & 0xFFFF) << 16) | ((self.LFSR[5] >> 15) & 0x7fff)
self.BRx[3] = ((self.LFSR[2] & 0xFFFF) << 16) | ((self.LFSR[0] >> 15) & 0x7fff)

def L1(self, X):
# 计算线性函数L1
return X ^ (X << 2) ^ (X << 10) ^ (X << 18) ^ (X << 24)

def L2(self, X):
# 计算线性函数L2
return X ^ (X << 8) ^ (X << 14) ^ (X << 22) ^ (X << 30)

def S(self, X):
# 定义S函数,这里假设您已经有了四个8x8的S盒
S_boxes = [
# S0
[
[0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76],
[0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0],
[0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15],
[0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75],
[0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84],
[0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF],
[0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8],
[0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2],
[0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73],
[0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB],
[0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79],
[0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08],
[0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A],
[0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E],
[0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF],
[0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16]
],
# S1
[
[0x51, 0xF4, 0xA7, 0x50, 0x68, 0x6B, 0x8A, 0x42, 0xDB, 0x32, 0xF0, 0xFD, 0x66, 0x03, 0x91, 0x26],
[0x37, 0x6E, 0xD8, 0xCB, 0x1E, 0x09, 0x2C, 0x8F, 0xB5, 0x18, 0x89, 0x14, 0xF3, 0x9A, 0xF5, 0xE9],
[0xC9, 0x4E, 0xD7, 0xE3, 0x5D, 0x50, 0x26, 0x3B, 0x04, 0xB8, 0xA5, 0xE8, 0x0A, 0x56, 0x8D, 0xE7],
[0x60, 0xFC, 0xB1, 0xCC, 0x23, 0x3D, 0x36, 0x0F, 0x6F, 0x7D, 0x9B, 0x9E, 0x95, 0x10, 0x78, 0xA9],
[0x7C, 0xD0, 0xF2, 0x6A, 0x3F, 0x1C, 0x71, 0x4B, 0xAD, 0x4D, 0x0D, 0x22, 0x2A, 0x90, 0x88, 0x46],
[0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2],
[0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D],
[0xB3, 0x8E, 0x67, 0x32, 0xCA, 0x4A, 0x1C, 0xA9, 0x7C, 0x03, 0xB7, 0x7B, 0x2A, 0x11, 0x99, 0x47],
[0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E],
[0xC4, 0xF2, 0xD0, 0x46, 0x71, 0x1D, 0x18, 0xDB, 0x52, 0x9E, 0xE3, 0xB6, 0x36, 0x87, 0x0E, 0x95],
[0x37, 0x6E, 0xD8, 0xCB, 0x1E, 0x09, 0x2C, 0x8F, 0xB5, 0x18, 0x89, 0x14, 0xF3, 0x9A, 0xF5, 0xE9],
[0x5E, 0xFA, 0x64, 0xCB, 0xB4, 0x97, 0xBE, 0x2B, 0xBC, 0x77, 0x2E, 0x03, 0xD3, 0x19, 0x59, 0xCF],
[0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A],
[0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35],
[0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, 0x7C, 0x80, 0x9F, 0x5D, 0x9D, 0x43, 0x59, 0xF9, 0xB9, 0x34],
[0x59, 0xCF, 0x36, 0x09, 0x7D, 0xB8, 0x1E, 0x8F, 0x12, 0x4B, 0xDE, 0x6C, 0x91, 0x9B, 0x8D, 0x92]
],
# S2
[
[0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76],
[0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0],
[0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15],
[0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75],
[0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84],
[0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF],
[0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8],
[0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2],
[0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73],
[0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB],
[0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79],
[0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08],
[0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A],
[0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E],
[0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF],
[0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16]
],
# S3
[
[0x51, 0xF4, 0xA7, 0x50, 0x68, 0x6B, 0x8A, 0x42, 0xDB, 0x32, 0xF0, 0xFD, 0x66, 0x03, 0x91, 0x26],
[0x37, 0x6E, 0xD8, 0xCB, 0x1E, 0x09, 0x2C, 0x8F, 0xB5, 0x18, 0x89, 0x14, 0xF3, 0x9A, 0xF5, 0xE9],
[0xC9, 0x4E, 0xD7, 0xE3, 0x5D, 0x50, 0x26, 0x3B, 0x04, 0xB8, 0xA5, 0xE8, 0x0A, 0x56, 0x8D, 0xE7],
[0x60, 0xFC, 0xB1, 0xCC, 0x23, 0x3D, 0x36, 0x0F, 0x6F, 0x7D, 0x9B, 0x9E, 0x95, 0x10, 0x78, 0xA9],
[0x7C, 0xD0, 0xF2, 0x6A, 0x3F, 0x1C, 0x71, 0x4B, 0xAD, 0x4D, 0x0D, 0x22, 0x2A, 0x90, 0x88, 0x46],
[0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2],
[0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D],
[0xB3, 0x8E, 0x67, 0x32, 0xCA, 0x4A, 0x1C, 0xA9, 0x7C, 0x03, 0xB7, 0x7B, 0x2A, 0x11, 0x99, 0x47],
[0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E],
[0xC4, 0xF2, 0xD0, 0x46, 0x71, 0x1D, 0x18, 0xDB, 0x52, 0x9E, 0xE3, 0xB6, 0x36, 0x87, 0x0E, 0x95],
[0x37, 0x6E, 0xD8, 0xCB, 0x1E, 0x09, 0x2C, 0x8F, 0xB5, 0x18, 0x89, 0x14, 0xF3, 0x9A, 0xF5, 0xE9],
[0x5E, 0xFA, 0x64, 0xCB, 0xB4, 0x97, 0xBE, 0x2B, 0xBC, 0x77, 0x2E, 0x03, 0xD3, 0x19, 0x59, 0xCF],
[0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A],
[0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35],
[0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, 0x7C, 0x80, 0x9F, 0x5D, 0x9D, 0x43, 0x59, 0xF9, 0xB9, 0x34],
[0x59, 0xCF, 0x36, 0x09, 0x7D, 0xB8, 0x1E, 0x8F, 0x12, 0x4B, 0xDE, 0x6C, 0x91, 0x9B, 0x8D, 0x92]
]
]

S = lambda i, x: S_boxes[i][x >> 4][x & 0xF]
x0 = (X >> 24) & 0xFF
x1 = (X >> 16) & 0xFF
x2 = (X >> 8) & 0xFF
x3 = X & 0xFF
y = (S(0,x0) << 24) | (S(1,x1) << 16) | (S(2,x2) << 8) | S(3,x3)
return y

def F(self):
# 计算非线性F函数
self.BR()
w = ((self.BRx[0] ^ self.R1) + self.R2 ) & 0xFFFFFFFF
W1 = (self.R1 + self.BRx[1]) & 0xFFFFFFFF
W2 = self.R2 ^ self.BRx[2]
self.R1 = self.S(self.L1((W1 << 16) | (W2 >> 16)));
self.R2 = self.S(self.L2((W2 << 16) | (W1 >> 16)));
return w

def LFSRWithInitMode(self,u):
v = 0
tmp = 0

v = self.LFSR[0]
tmp = mod_2exp_mul(self.LFSR[0], 8)
v = mod_add(v, tmp)

tmp = mod_2exp_mul(self.LFSR[4], 20)
v = mod_add(v, tmp)

tmp = mod_2exp_mul(self.LFSR[10], 21)
v = mod_add(v, tmp)

tmp = mod_2exp_mul(self.LFSR[13], 17)
v = mod_add(v, tmp)

tmp = mod_2exp_mul(self.LFSR[15], 15)
v = mod_add(v, tmp)

v = mod_add(v, u)
if v == 0:
v = 0x7fffffff

self.LFSR = self.LFSR[1:] + [v]

def LFSRWithWorkMode(self):
v = 0
tmp = 0

v = self.LFSR[0]
tmp = mod_2exp_mul(self.LFSR[0], 8)
v = mod_add(v, tmp)

tmp = mod_2exp_mul(self.LFSR[4], 20)
v = mod_add(v, tmp)

tmp = mod_2exp_mul(self.LFSR[10], 21)
v = mod_add(v, tmp)

tmp = mod_2exp_mul(self.LFSR[13], 17)
v = mod_add(v, tmp)

tmp = mod_2exp_mul(self.LFSR[15], 15)
v = mod_add(v, tmp)

if v == 0:
v = 0x7fffffff

self.LFSR = self.LFSR[1:] + [v]

def init_zuc(self):
self.load_key()
self.R1 = 0
self.R2 = 0
for i in range(32):
self.BR()
w = self.F()
self.LFSRWithInitMode(w>>1)

def clock(self):
self.BR()
w = self.F()
z = w ^ self.BRx[3]
self.LFSRWithWorkMode()
return z

def generate_keystream(self, length):
keystream = []
self.BR()
self.F()
self.LFSRWithWorkMode()
for _ in range(length):
z = self.clock()
# print(z)
keystream.extend(z.to_bytes(4, byteorder='big'))
return keystream

def encrypt(self, plaintext):
keystream = self.generate_keystream(len(plaintext))
# print(len(plaintext))
ciphertext = bytes([plaintext[i] ^ keystream[i] for i in range(len(plaintext))])
return ciphertext

def decrypt(self, ciphertext):
return self.encrypt(ciphertext) # XOR 加密和解密是相同的操作

3. 实验

3.1 main

  • 根据输入参数,选择加密算法
  • 根据输入参数,选择终端读入还是文件读入
    • 输入-:终端读入
    • 输入文件名:文件读入
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
def main():
if len(sys.argv) < 2:
print("Usage: python cipher.py <algorithm> <input>")
print("Supported algorithms: Grain, Trivium, ZUC")
return

algorithm = sys.argv[1].lower()
input_file = sys.argv[2]

if algorithm == "grain":
key = 0x01234567 # 128 位密钥
encryption = Grain128(key)
decryption = Grain128(key)
elif algorithm == "trivium":
key = 0x01234
iv = 0xabcde
encryption = Trivium(key, iv)
decryption = Trivium(key, iv)
elif algorithm == "zuc":
key = 0x01234567
iv = 0x89abcdef
D = 0x0123456789abcdef
encryption = ZUC_128(key, iv,D)
decryption = ZUC_128(key, iv,D)
else:
print("Unknown algorithm:", algorithm)
return

# 从终端输入读取
if input_file == "-":
plaintext = input("Enter plaintext: ")
plaintext_bytes = plaintext.encode()
ciphertext = encryption.encrypt(plaintext_bytes)
print("Ciphertext:", ciphertext)

# 从文件输入读取
else:
with open(input_file, "rb") as file:
plaintext_bytes = file.read()
ciphertext = encryption.encrypt(plaintext_bytes)
with open("encrypted_output.bin", "wb") as file:
print("Ciphertext:", ciphertext)
file.write(ciphertext)
print("Encryption complete. Output saved to encrypted_output.bin")

# 解密
decrypted_text = decryption.decrypt(ciphertext)
print("Decrypted text:", decrypted_text.decode())

3.2 实验结果

  • Grain

Untitled

  • Trivium

Untitled

  • Zuc

Untitled

总结

  • 使用Python实现三类加密方法
  • 支持文件读入和终端读入
  • 利用PyInstaller实现Python文件打包成可执行文件