![](https://csdnimg.cn/release/download_crawler_static/87904988/bg5.jpg)
- 4 -
密钥扩展与加/解密实现过程大同小异,具体实现过程如下所述。
设,密钥输入为(
0
,
1
,
2
,
3
),轮密钥输出为
, ∈ {0, 1, 2, … 31}。
① 将初始密钥 (
0
,
1
,
2
,
3
) 分别异或固定参数 (
0
,
1
,
2
,
3
)得到用于循环的密钥(
0
,
1
,
2
,
3
),即,
0
=
0
⨁
0
,
1
=
1
⨁
1
,
2
=
2
⨁
2
,
3
=
3
⨁
3
。
② 进入轮密钥
的生成, 当 = 0 时为第一轮密钥扩展,一直进行到
= 31 结束。
③ 将
+1
,
+2
,
+3
和固定参数
异或得到一个 32 比特的数据,
作为盒变换的输入。即, _ =
+1
⊕
+2
⊕
+3
⊕
。
④ 将 _ 拆分成 4 个 8 比特数据,分别进行盒变换,之后再
将 4 个 8 比特输出合并成一个 32 比特的 _。
⑤ 将上一步获得的 _分别循环左移 13,23 位,得到 2 个
32 比特的结果,记移位结果为 13, 23与盒变换输出 _ 和
异或,得到
+4
。即,
+4
= _ ⊕ 13 ⊕ 23 ⊕
。
其中每一个
即为产生的轮密钥。
2.3 具体算法实现
SM4 算法的主体代码包括加解密模块和密钥扩展模块。以下为加解密模块具体实现
代码以及注释。
(1) 加/解密模块
def _do(self, text: bytes, key_r: list):
text_ = [0 for _ in range(4)]
# 将 128bit 转化成 4x32bit
for i in range(4):
text_[i] = int.from_bytes(text[4 * i:4 * i + 4], 'big')
for i in range(32):
box_in = text_[1] ^ text_[2] ^ text_[3] ^ key_r[i]
box_out = self._s_box(box_in)
temp = text_[0] ^ box_out ^ self._rot_left(box_out, 2) ^ self._rot_left(box_out,10)
temp = temp ^ self._rot_left(box_out, 18) ^ self._rot_left(box_out, 24)
text_ = text_[1:] + [temp]
text_ = text_[::-1] # 结果逆序
# 将 4x32bit 合并成 128bit
result = bytearray()
for i in range(4):
result.extend(text_[i].to_bytes(4, 'big'))