SM3杂凑算法的C、python和go实现

本文介绍了SM3杂凑算法在C、Python和Go语言中的实现细节。在Python中需要注意非补码非操作、大端数据读取和加法运算的取余处理;Go语言中则需关注大小端转换、ParseInt比特位设置以及迭代过程中的状态重置;C语言实现涉及到头文件和源代码的编写。同时,文章提供了相关的参考资料链接,包括论文、过程测试数据以及各语言的实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Github

https://github.com/Tyrone-Zhao/Algorithm/tree/master/sm3

注意点

Python

1.python中的非为补码非,需要自己编写按位非
2.算法为大端运算,用python编写算法时需要在把输入数据转换成bytes后,从bytes读取大端数据,使用int.from_bytes(data, “big”)方法
3.因为是采用寄存器机制,所以在python中需要使用list类型来实现, 并且设定最大值为2 ** 32,在做加法运算时需要取余

Python代码

python SM3算法

import binascii
import sys
import pysnooper


class SM3:
    MAX = 2 ** 32
    IV = "7380166f4914b2b9172442d7da8a0600a96f30bc163138aae38dee4db0fb0e4e"

    def __init__(self, string):
        self.input = string
        self.b_input = bytes(self.input, "utf-8")
        self.hex_input = hex(int.from_bytes(self.b_input, "big"))[2:]  # 按照大端计算

    @property
    def hash(self):
        """
        获取结果Hash值
        :return: 256位16进制hash值
        """
        return self.iterationCourse(self.fill(self.hexToBin(self.hex_input)))[-1]

    def getT(self, j):
        """
        常量
        :param j:
        :return: 79cc4519 (0 <= j <= 15), 7a879d8a (16 <= j <= 63)
        """
        if 0 <= j <= 15:
            return int("79cc4519", 16)
        elif 16 <= j <= 63:
            return int("7a879d8a", 16)

    def FF(self, X, Y, Z, j):
        """
        布尔函数
        :param X: 16进制string
        :param Y: 16进制string
        :param Z: 16进制string
        :return: X ^ Y ^ Z (0 <= j <= 15), (X & Y) | (X & Z) | (Y & Z) (16 <= j <= 63)
        """
        if 0 <= j <= 15:
            return X ^ Y ^ Z
        elif 16 <= j <= 63:
            return (X & Y) | (X & Z) | (Y & Z)
        else:
            return 0

    def GG(self, X, Y, Z, j):
        """
        布尔函数
        :param X: 16进制string
        :param Y: 16进制string
        :param Z: 16进制string
        :return: X ^ Y ^ Z (0 <= j <= 15), (X & Y) | (~X & Z) (16 <= j <= 63)
        """
        if 0 <= j <= 15:
            return X ^ Y ^ Z
        elif 16 <= j <= 63:
            return (X & Y) | (self.non(X) & Z)
        else:
            return 0

    def P0(self, X):
        """
        置换函数
        :param X: 整数值
        :return: X ^ (X <<< 9) ^ (X <<< 17)
        """
        return X ^ self.leftRotate(X, 9) ^ self.leftRotate(X, 17)

    def P1(self, X):
        """
        置换函数
        :param X: 整数值
        :return: X ^ (X <<< 15) ^ (X <<< 23)
        """
        return X ^ self.leftRotate(X, 15) ^ self.leftRotate(X, 23)

    def leftRotate(self, X, k):
        """
        循环左移
        :param X: 整数值
        :param k: 位移的位数
        :param bit: 整数对应二进制的位数
        :return: 二进制左移k位的整数值
        """
        res = list(self.intToBin(X))
        for i in range(k):
            temp = res.pop(0)
            res.append(temp)
        return int("".join(res), 2)

    def fill(self, bin_string):
        """
        填充二进制消息string
        :param bin_string: 对任意消息使用self.msgToBin()得到的结果
        :return: 填充后的二进制消息m',其比特长度为512的倍数
        """
        tail = "{:064b}".format(len(bin_string))
        bin_string += "1"
        div, mod = divmod(len(bin_string), 512)
        if mod >= 448:
            bin_string += "0" * (512 - mod + 448)
        else:
            bin_string += "0" * (448 - mod)

        return bin_string + tail

    def iterationCourse(self, msg):
        """
        迭代压缩消息
        :param msg: 填充后的二进制消息m', self.fill(msg)
        :return: Hash值(杂凑值)
        """
        # 将填充消息m'按512比特进行分组
        n = len(msg) // 512
        m = [msg[i * 512:(i + 1) * 512] for i in range(n)]
        # 对m[i]进行压缩迭代, msg = self.bigLittleEndianConvert(Vi, "big")  # 小端数据转换为大端
        V = [self.IV]
        for i in range(n):
            V.append(hex(int(self.intToBin(self.CF(V[-1], m[i]), 256), 2))[2:])

        return V

    def CF(self, Vi, mi):
        """
        压缩函数
        :param Vi: 512比特16进制数据
        :param mi: 512比特二进制数据
        :return: 512比特16进制数据
        """
        # 将Vi存储到字寄存器
        msg = Vi
        A = [int(msg[i * 8: (i + 1) * 8], 16) for i in range(len(msg) // 8)]
        # 消息扩展,得到W和W'
        W1, W2 = self.informationExtend(mi)
        # 压缩消息
        for j in range(64):
            factor1 = self.leftRotate(A[0], 12)
            factor2 = self.leftRotate(self.getT(j), j % 32)
            SS1 = self.leftRotate((factor1 + A[4] + factor2) % self.MAX, 7)
            factor3 = self.leftRotate(A[0], 12)
            SS2 = SS1 ^ factor3
            TT1 = (self.FF(A[0], A[1], A[2], j) + A[3] + SS2 + W2[j]) % self.MAX
            TT2 = (self.GG(A[4], A[5], A[6], j) + A[7] + SS1 + W1[j]) % self.MAX
            A[3] = A[2]
            A[2] = self.leftRotate(A[1], 9)
            A[1] = A[0]
            A[0] = TT1
            A[7] = A[6]
            A[6] = self.leftRotate(A[5], 19)
            A[5] = A[4]
            A[4] = self.P0(TT2)
        temp = self.intToBin(A[0], 32) + self.intToBin(A[1], 32) + self.intToBin(A[2], 32) + \
               self.intToBin(A[3], 32) + self.intToBin(A[4], 32) + self.intToBin(A[5], 32) + \
               self.intToBin(A[6], 32) + self.intToBin(A[7], 32)
        temp = int(temp, 2)
        return temp ^ int(Vi, 16)


    def informationExtend(self, mi):
        
好的,我很乐意为您介绍Python实现SM3算法的过程。SM3是中国国家密码管理局发布的密码杂凑算法,以下是Python实现SM3算法的主要步骤: 1. 初始化常量: ```python IV = [0x7380166F, 0x4914B2B9, 0x172442D7, 0xDA8A0600, 0xA96F30BC, 0x163138AA, 0xE38DEE4D, 0xB0FB0E4E] ``` 2. 定义必要的函数: ```python def left_rotate(x, n): return ((x << n) | (x >> (32 - n))) & 0xFFFFFFFF def padding(message): # 填充函数 ... def process_blocks(message): # 处理消息块 ... ``` 3. SM3主函数: ```python def sm3(message): padded_message = padding(message) blocks = [padded_message[i:i+64] for i in range(0, len(padded_message), 64)] A, B, C, D, E, F, G, H = IV for block in blocks: W = [0]*68 W1 = [0]*64 for i in range(16): W[i] = int.from_bytes(block[i*4:(i+1)*4], 'big') for i in range(16, 68): W[i] = P1(W[i-16] ^ W[i-9] ^ left_rotate(W[i-3], 15)) ^ left_rotate(W[i-13], 7) ^ W[i-6] for i in range(64): W1[i] = W[i] ^ W[i+4] a, b, c, d, e, f, g, h = A, B, C, D, E, F, G, H for i in range(64): T1 = (h ^ R1(e)) + R2(e) + S1(a) + W1[i] T2 = S0(a) + Maj(a, b, c) h = g g = f f = e e = (d + T1) & 0xFFFFFFFF d = c c = b b = a a = (T1 + T2) & 0xFFFFFFFF A = (A + a) & 0xFFFFFFFF B = (B + b) & 0xFFFFFFFF C = (C + c) & 0xFFFFFFFF D = (D + d) & 0xFFFFFFFF E = (E + e) & 0xFFFFFFFF F = (F + f) & 0xFFFFFFFF G = (G + g) & 0xFFFFFFFF H = (H + h) & 0xFFFFFFFF return ''.join(f'{x:08x}' for x in [A, B, C, D, E, F, G, H]) ``` 4. 使用示例: ```python message = "Hello, SM3!" hash_value = sm3(message.encode()) print(f"SM3哈希值: {hash_value}") ``` 这个实现包括了SM3算法的主要部分,如初始化常量、填充函数、消息块处理函数以及主函数。其中,`left_rotate`函数用于左循环移位,`padding`函数用于消息填充,`process_blocks`函数用于处理消息块。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值