
基于AI生成的SM4加密算法
密码学教材的SM4加密算法AI版,AI是kimi和deepseek混着用的
前言
这里是密码学教材的SM4加密算法AI版,AI是kimi和deepseek混着用的
写这一个算法,主要是想熟练一下python脚本的编写,以及调用AI的水平
SM4其实很好理解的(真的很好,不骗你们)
我遇到最复杂的问题就是,,,
16进制hex,2进制bin,和10进制,一下子出现字符串,一下子出现整数值,这到底怎么转换?
后来发现,其实所有的运算都是数值计算,只是结果可视化需要用函数把他当字符串。。。
另外一个很搞的问题就是,,,
kimi算出来到中间第八行开始,几乎是全错的,deepseek也有个别出错了的。所以这个结果一开始是对的,到中间突然全部变掉了,这种真的挺破防的。。。
不管怎么说,能用AI给你写东西,并且运算出正确的结果,那就是本事!
询问指令
以下是我不断调出正确答案的操作(部分),可以学一学这里的思路。
1.现在我需要你帮我写一个python程序,提供指导即可。
我现在要设置一个x,x是装128bit的密文
2.x0取x的前8位,x1取9-16位,以此类推到x3,x0到x3以十六进制显示;我还要以二进制形式显示每个数
3.怎么用python语句叙述以下内容:
ck[4][32]
for i in range(4):
for j in range(32):
ck[i][j]=(4*i+j)%256
print(ck[i][j])
4.CK[i]是ck[i][j]转换为十六进制之后拼起来的值,例如ck[0][0]=0,ck[0][1]=7,ck[0][2]=14,ck[0][3]=21,那么CK[0]=00070e15
5.python中,MK0和FK0都是4字节长度的十六进制数,现在K0是它们异或的结果,请问这个怎么实现?
6.定义一个K数组有36个元素,每个元素都是4个字节的十六进制数,怎么操作
7.从一个4字节长度的十六进制数,提取出1-2位,3-4位,5-6位,7-8位,得出4个新的十六进制数,怎么做
8.我现在有一个16*16的S盒,我现在要定义Sbox函数,输入一个两位的16进制数,输出一个两位的16进制数
9.能否把所有的内容全部转成10进制数,s盒保持不变,只需要你帮我算出结果,不要代码
s = [[d6,90,e9,fe,cc,e1,3d,b7,16,b6,14,c2,28,fb,2c,05], [2b,67,9a,76,2a,be,04,c3,aa,44,13,26,49,86,06,99], [9c,42,50,f4,91,ef,98,7a,33,54,0b,43,ed,cf,ac,62], [e4,b3,1c,a9,c9,08,e8,95,80,df,94,fa,75,8f,3f,a6], [47,07,a7,fc,f3,73,17,ba,83,59,3c,19,e6,85,4f,a8], [68,6b,81,b2,71,64,da,8b,f8,eb,0f,4b,70,56,9d,35], [1e,24,0e,5e,63,58,d1,a2,25,22,7c,3b,01,21,78,87], [d4,00,46,57,9f,d3,27,52,4c,36,02,e7,a0,c4,c8,9e], [ea,bf,8a,d2,40,c7,38,b5,a3,f7,f2,ce,f9,61,15,a1], [e0,ae,5d,a4,9b,34,1a,55,ad,93,32,30,f5,8c,b1,e3], [1d,f6,e2,2e,82,66,ca,60,c0,29,23,ab,0d,53,4e,6f], [d5,db,37,45,de,fd,8e,2f,03,ff,6a,72,6d,6c,5b,51], [8d,1b,af,92,bb,dd,bc,7f,11,d9,5c,41,1f,10,5a,d8], [0a,c1,31,88,a5,cd,7b,bd,2d,74,d0,12,b8,e5,b4,b0], [89,69,97,4a,0c,96,77,7e,65,b9,f1,09,c5,6e,c6,84], [18,f0,7d,ec,3a,dc,4d,20,79,ee,5f,3e,d7,cb,39,48]]
10.K[0] = MK0 ^ FK0 K[1] = MK1 ^ FK1 K[2] = MK2 ^ FK2 K[3] = MK3 ^ FK3 for i in range(32): K[i+4] = K[i] ^ T2(K[i+1], K[i+2], K[i+3], CK[i]) print(f"rk{i + 1} 十六进制: {hex(K[i+4])}") T2传出来的是一个八位16进制数,MK和FK也都是八位16进制数,请问K[i]是否也是十六进制的形式?这样是否会导致输入格式错误?
11.现在整个代码的加密逻辑是正确的,只是还有一些细节优化以及全局变量的设置不太正确,请帮我完善。
12.以下是输出结果,我们发现这显然不正确,因为K和CK都是8位16进制数,输出结果rk0理应也是8位16进制数。K[1] = 0xdf01febf K[2] = 0x99a12b0f K[3] = 0xc42410cc CK[0] = 0x70e15 rk0 十六进制: 0x45787af164fe83
13.我想监测Ki+1 Ki+2 Ki+3 CKi,如何构造print函数?
14.现在有一个问题: result要和B的循环左移进行异或,而不是和B的移位结果本身异或,请问这个怎么办? for shift in shifts: result ^= (B << shift) & 0xFFFFFFFF # 确保结果是32位 print(hex(result))
15.现在K是lunmiyao函数产生的结果,但是在jiamijieguo函数里要使用,能否帮我优化?
16.X[35]X[34]X[33]X[32]是分别是8位16进制数,请拼成一个新数Y
完整代码
我知道你们只想看结果:
# 全局变量
# 设置一个128位的带加密明文
x = 0x0123456789abcdeffedcba9876543210 # 32*4
# 设置一个128位的密钥
key = 0x0123456789abcdeffedcba9876543210 # 32*4
# S盒
s = [[214, 144, 233, 254, 204, 225, 61, 183, 22, 182, 20, 194, 40, 251, 44, 5],
[43, 103, 154, 118, 42, 190, 4, 195, 170, 68, 19, 38, 73, 134, 6, 153],
[156, 66, 80, 244, 145, 239, 152, 122, 51, 84, 11, 67, 237, 207, 172, 98],
[228, 179, 28, 169, 201, 8, 232, 149, 128, 223, 148, 250, 117, 143, 63, 166],
[71, 7, 167, 252, 243, 115, 23, 186, 131, 89, 60, 25, 230, 133, 79, 168],
[104, 107, 129, 178, 113, 100, 218, 139, 248, 235, 15, 75, 112, 86, 157, 53],
[30, 36, 14, 94, 99, 88, 209, 162, 37, 34, 124, 59, 1, 33, 120, 135],
[212, 0, 70, 87, 159, 211, 39, 82, 76, 54, 2, 231, 160, 196, 200, 158],
[234, 191, 138, 210, 64, 199, 56, 181, 163, 247, 242, 206, 249, 97, 21, 161],
[224, 174, 93, 164, 155, 52, 26, 85, 173, 147, 50, 48, 245, 140, 177, 227],
[29, 246, 226, 46, 130, 102, 202, 96, 192, 41, 35, 171, 13, 83, 78, 111],
[213, 219, 55, 69, 222, 253, 142, 47, 3, 255, 106, 114, 109, 108, 91, 81],
[141, 27, 175, 146, 187, 221, 188, 127, 17, 217, 92, 65, 31, 16, 90, 216],
[10, 193, 49, 136, 165, 205, 123, 189, 45, 116, 208, 18, 184, 229, 180, 176],
[137, 105, 151, 74, 12, 150, 119, 126, 101, 185, 241, 9, 197, 110, 198, 132],
[24, 240, 125, 236, 58, 220, 77, 32, 121, 238, 95, 62, 215, 203, 57, 72]]
def Sbox(input_int):
# 将输入的十六进制数转换为整数
row = input_int // 16
col = input_int % 16
output_int = s[row][col]
return output_int
def T(a, b, c, d, shifts):
"""通用的T函数,用于T1和T2"""
temp = a ^ b ^ c ^ d
parts = [(temp >> (24 - 8 * i)) & 0xFF for i in range(4)]
res = [Sbox(part) for part in parts]
# print(parts,res) # 非常重要的检验中间过程的语句,S的机算可能是错的
B = (res[0] << 24) | (res[1] << 16) | (res[2] << 8) | res[3]
result = B
for shift in shifts:
result ^= ((B << shift) | (B >> (32 - shift))) & 0xFFFFFFFF # 确保结果是32位
return result
def T2(K1, K2, K3, CK):
"""T2函数"""
return T(K1, K2, K3, CK, [13, 23])
def T1(Xa, Xb, Xc, Xd):
"""T1函数"""
return T(Xa, Xb, Xc, Xd, [2, 10, 18, 24])
def chushihuamiwen():
# 如果需要将整数转换为二进制字符串
binary_x = bin(x)[2:].zfill(128) # 确保长度为128位
print(f"x 的二进制表示: {binary_x}")
# 定义掩码(32位掩码)
mask = (1 << 32) - 1
# 提取x0, x1, x2, x3
x0 = (x >> 96) & mask # 前32位
x1 = (x >> 64) & mask # 第33到64位
x2 = (x >> 32) & mask # 第65到96位
x3 = x & mask # 第97到128位
# 打印结果(以十六进制和二进制形式显示)
print(f"x0 (前32位): 十六进制: {hex(x0)}, 二进制: {bin(x0)[2:].zfill(32)}")
print(f"x1 (第33-64位): 十六进制: {hex(x1)}, 二进制: {bin(x1)[2:].zfill(32)}")
print(f"x2 (第65-96位): 十六进制: {hex(x2)}, 二进制: {bin(x2)[2:].zfill(32)}")
print(f"x3 (第97-128位): 十六进制: {hex(x3)}, 二进制: {bin(x3)[2:].zfill(32)}")
return x0, x1, x2, x3
def jiamimiyao():
# 如果需要将整数转换为二进制字符串
binary_key = bin(key)[2:].zfill(128) # 确保长度为128位
print(f"key 的二进制表示: {binary_key}")
# 定义掩码(32位掩码)
mask = (1 << 32) - 1
MK0 = (key >> 96) & mask # 前32位
MK1 = (key >> 64) & mask # 第33到64位
MK2 = (key >> 32) & mask # 第65到96位
MK3 = key & mask # 第97到128位
# 打印结果(以十六进制和二进制形式显示)
print(f"MK0 (前32位): 十六进制: {hex(MK0)}, 二进制: {bin(MK0)[2:].zfill(32)}")
print(f"MK1 (第33-64位): 十六进制: {hex(MK1)}, 二进制: {bin(MK1)[2:].zfill(32)}")
print(f"MK2 (第65-96位): 十六进制: {hex(MK2)}, 二进制: {bin(MK2)[2:].zfill(32)}")
print(f"MK3 (第97-128位): 十六进制: {hex(MK3)}, 二进制: {bin(MK3)[2:].zfill(32)}")
return MK0, MK1, MK2, MK3
def fanxubianhuan(a, b, c, d):
# 定义掩码(32位掩码)
mask = (1 << 128) - 1
# 拼接成一个 32 位的数 Y
Y = ((a << 96) | (b << 64) | (c << 32) | d) &mask
print(f"加密结果Y = {hex(Y)}")
binary_y = bin(Y)[2:].zfill(128) # 确保长度为128位
print(f"Y 的二进制表示: {binary_y}")
return Y
def lunmiyao(MK0, MK1, MK2, MK3):
FK0 = 0xa3b1bac6
FK1 = 0x56aa3350
FK2 = 0x677d9197
FK3 = 0xb27022dc
ck = [[0 for _ in range(32)] for _ in range(4)]
CK = [0]*32
for i in range(32): # 遍历每一列
for j in range(4): # 遍历每一行
ck[j][i] = (4*i+j)*7 % 256 # 注意这里填充的是 ck[j][i]
# 将 CK[i] 转换为整数
CK[i] = (ck[0][i] << 24) | (ck[1][i] << 16) | (ck[2][i] << 8) | ck[3][i]
print(f"CK[{i}] = {hex(CK[i])}") # 打印当前列的 CK[i]
K = [0] * 36
# 计算异或结果
K[0] = MK0 ^ FK0
K[1] = MK1 ^ FK1
K[2] = MK2 ^ FK2
K[3] = MK3 ^ FK3
for i in range(32):
K[i+4] = K[i] ^ T2(K[i+1], K[i+2], K[i+3], CK[i])
print(f"rk[{i}] = {hex(K[i+4])}")
return K
def jiamijieguo(x0,x1,x2,x3,K):
x = [0] * 36
x[0] = x0
x[1] = x1
x[2] = x2
x[3] = x3
for i in range(32):
x[i + 4] = x[i] ^ T1(x[i + 1], x[i + 2], x[i + 3], K[i+4])
print(f"x[{i + 4}] = {hex(x[i + 4])}")
return x
if __name__ == "__main__":
x0, x1, x2, x3 = chushihuamiwen()
MK0, MK1, MK2, MK3 = jiamimiyao()
K = lunmiyao(MK0, MK1, MK2, MK3)
X = jiamijieguo(x0, x1, x2, x3, K)
Y = fanxubianhuan(X[35], X[34], X[33], X[32])
结果验证
你们就说对不对吧!
其实我觉得,S盒可能仍然有错的地方,这就需要不断训练改正了,欢迎大家指出来!
更多推荐
所有评论(0)