前言

这里是密码学教材的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盒可能仍然有错的地方,这就需要不断训练改正了,欢迎大家指出来!

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐