SM3 python代码

问了问文心一言SM3是什么,我觉得它在胡说八道,贴出来给大家看看(放图片是怕污染大家的搜索)

在这里插入图片描述

实际上sm3是一个哈希加密算法,也就是能加密,但是不能解密,不管多长的串扔进去都是64位十六进制数,相同的内容加密后得到的结果必然相同。(所以说看到文心一言说到对称加密就可以判定它在胡说八道了)

# -*- coding:utf-8 -*-


# 初始值

MAX = 2 ** 32


def str2bin(msg):
    """
    字符串转比特串
    :param msg: 字符串
    :return: 转换之后的比特串
    """
    l = len(msg)
    s_dec = 0
    for m in msg:
        s_dec = s_dec << 8
        s_dec += ord(m)

    msg_bin = bin(s_dec)[2:].zfill(l * 8)
    return msg_bin

def int2bin(a, k):
    """
    将整数转化为比特串
    :param a: 待转化的整数
    :param k: 比特串的长度
    :return: 转化后长度为k的比特串
    """
    return bin(a)[2:].zfill(k)


def int2hex(a, k):
    """
    整数转化为16进制的字符串,前补0补齐k位数
    :param a: 整数
    :param k: 补齐后的字符串长度
    :return: 转化后的16进制形式字符串
    """
    return hex(a)[2:].zfill(k)


def bin2hex(a, k):
    """
    比特串转化为16进制的字符串,前补0补齐k位数
    :param a: 待转化的比特串
    :param k: 补齐后的字符串长度
    :return: 长度为k的16进制字符串
    """
    # return hex(int(a, 2))[2:].zfill(k)
    # 对于python2需去除长整型引入的字符L
    return hex(int(a, 2))[2:].replace('L', '').zfill(k)


def msg_fill(msg_bin):
    """
    对消息进行填充。填充后的消息满足:(l+1+k) mod 512 = 448 k取最小值 l比特串长度
    因为要填充64比特
    :param msg_bin: 比特串形式的消息
    :return: 填充后的消息(比特串形式)
    """
    l = len(msg_bin)
    k = 448 - (l + 1) % 512
    if k < 0:
        k += 512

    l_bin = int2bin(l, 64)
    msg_filled = msg_bin + '1' + '0' * k + l_bin

    return msg_filled


def iteration_func(msg):
    """
    迭代压缩
    :param msg: 填充后的比特串消息
    :return: 迭代压缩后的消息,长度为64的字符串
    """
    # 将填充后的消息按512比特进行分组
    n = len(msg) // 512
    b = []
    for i in range(n):
        b.append(msg[512 * i:512 * (i + 1)])

    # 对消息进行迭代压缩
    v = [int2bin(iv, 256)]
    for i in range(n):
        v.append(cf(v[i], b[i]))

    return bin2hex(v[n], 64)


def msg_extension(bi):
    """
    消息扩展, 将消息分组bi扩展生成132个字W0, W1, · · · , W67, W0', W1', · · · , W63',用于压缩函数CF
    :param bi: 填充后的消息分组,长度为512的比特串
    :return: w, w1 扩展后的消息,w为68字的list, w1为64字的list。字以整数存储
    """
    # 将消息分组bi划分为16个字W0, W1, · · · , W15, 每个里边有32位, 存储的是10进制数
    w = []
    for j in range(16):
        w.append(int(bi[j * 32:(j + 1) * 32], 2))

    for j in range(16, 68):
        w_j = p1(w[j - 16] ^ w[j - 9] ^ rotate_left(w[j - 3], 15)) ^ rotate_left(w[j - 13], 7) ^ w[j - 6]
        w.append(w_j)

    w1 = []
    for j in range(64):
        w1.append(w[j] ^ w[j + 4])

    return w, w1


def cf(vi, bi):
    """
    压缩函数
    :param vi: 比特串(256位)
    :param bi: 填充后的消息分组(512位比特串)
    :return: 压缩后的比特串(256位)
    """
    # 对bi进行消息扩展
    w, w1 = msg_extension(bi)

    # 将vi拆分为 a~h 8个字
    t = []
    for i in range(8):
        t.append(int(vi[i * 32:(i + 1) * 32], 2))
    a, b, c, d, e, f, g, h = t

    for j in range(64):
        ss1 = rotate_left((rotate_left(a, 12) + e + rotate_left(t_j(j), j)) % MAX, 7)
        ss2 = ss1 ^ rotate_left(a, 12)
        tt1 = (ff(a, b, c, j) + d + ss2 + w1[j]) % MAX
        tt2 = (gg(e, f, g, j) + h + ss1 + w[j]) % MAX
        d = c
        c = rotate_left(b, 9)
        b = a
        a = tt1
        h = g
        g = rotate_left(f, 19)
        f = e
        e = p0(tt2)

    vi_1 = int2bin(a, 32) + int2bin(b, 32) + int2bin(c, 32) + int2bin(d, 32) \
           + int2bin(e, 32) + int2bin(f, 32) + int2bin(g, 32) + int2bin(h, 32)
    vi_1 = int(vi_1, 2) ^ int(vi, 2)

    return int2bin(vi_1, 256)


def rotate_left(a, k):
    """
    (字)循环左移k比特运算(对字内32位比特进行循环左移)
    :param a: 待按位左移的比特串
    :param k: 左移位数
    :return:
    """
    k = k % 32
    # &全真为真 |全假为假
    return ((a << k) & 0xFFFFFFFF) | ((a & 0xFFFFFFFF) >> (32 - k))


def p0(x):
    """
    置换函数P0
    :param x: 待置换的消息(字)
    :return: 置换后的消息(字)
    """
    return x ^ rotate_left(x, 9) ^ rotate_left(x, 17)


def p1(x):
    """
    置换函数P1
    :param x: 待置换的消息(字)
    :return: 置换后的消息(字)
    """
    return x ^ rotate_left(x, 15) ^ rotate_left(x, 23)


def t_j(j):
    """
    常量
    """
    if j <= 15:
        return 0x79cc4519
    else:
        return 0x7a879d8a


def ff(x, y, z, j):
    """
    布尔函数ff
    """
    if j <= 15:
        return x ^ y ^ z
    else:
        return (x & y) | (x & z) | (y & z)


def gg(x, y, z, j):
    """
    布尔函数gg
    """
    if j <= 15:
        return x ^ y ^ z
    else:
        return (x & y) | ((x ^ 0xFFFFFFFF) & z)


def sm3(msg):
    """
    sm3加密主函数
    :param msg: 待加密的字符串
    :return: sm3加密后的字符串
    """
    # 字符串转化为比特串
    s_bin = str2bin(msg)

    # 对消息进行填充
    s_fill = msg_fill(s_bin)

    # 对填充后的消息进行迭代压缩
    s_sm3 = iteration_func(s_fill)

    # 对于python2需要删除因长整型而引入的末尾的L字符,python3不存在该问题
    return s_sm3.upper().replace("L", "")


if __name__ == "__main__":
    iv = 0x7380166f4914b2b9172442d7da8a0600a96f30bc163138aae38dee4db0fb0e4e
    s1 = 'Abdullah Gul'
    s1_sm3 = sm3(s1)
    print("{} ==> {}".format(s1, s1_sm3))

### SM9算法的Python实现 SM9是中国国家密码管理局发布的基于身份的加密标准之一。下面提供了一个简化版的SM9签名验证机制的Python代码示例: ```python from gmssl import sm3, func import random class SM9IdentityBasedSignature: def __init__(self): self.p = int('FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF', 16) self.a = int('FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC', 16) self.b = int('28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93', 16) @staticmethod def hash_message(message): """Hashes a message using SM3""" h = sm3.Sm3Hash() h.update(bytes(message.encode())) return h.hexdigest() def generate_key_pair(self): private_key = random.randint(1, self.p - 1) public_key = pow(private_key, 3, self.p) return private_key, public_key def sign(self, private_key, message): hashed_msg = int(SM9IdentityBasedSignature.hash_message(message), 16) signature = pow(hashed_msg, private_key, self.p) return signature def verify_signature(self, public_key, message, signature): hashed_msg = int(SM9IdentityBasedSignature.hash_message(message), 16) verification_result = pow(signature, public_key, self.p) == hashed_msg % self.p return verification_result if __name__ == "__main__": signer = SM9IdentityBasedSignature() priv_key, pub_key = signer.generate_key_pair() # Generate key pair msg_to_sign = "This is an example message." sig = signer.sign(priv_key, msg_to_sign) # Sign the message with private key valid = signer.verify_signature(pub_key, msg_to_sign, sig) # Verify the signed message against public key print(f'Signature Validity: {valid}') ``` 此段代码展示了如何创建一个简单的SM9身份基签名方案,包括密钥对生成、消息哈希处理以及签名和验签过程[^1]。 需要注意的是上述例子仅用于教学目的,并未完全遵循官方文档中的所有细节规定,在实际应用中应当参照最新的国家标准和技术指南来构建安全可靠的系统。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值