SM3是一种广泛利用在中国国家尺度中的哈希算法,全称为“中国国家密码算法SM3”。它由中国国家密码管理局制定,主要用于数字签名和消息完备性验证。SM3算法与SHA-256在布局上雷同,但其设计具有特定的改进以增强安全性。
SM3算法天生256位的哈希值,利用了32轮的迭代运算,而且依赖于消息扩展、压缩函数、消息混淆等步调。
1、SM3算法主要步调
- 消息填充:起首对输入的消息进行填充,使其长度变为512的倍数。填充方法是在消息末尾添加一个’1’位,然后添加一定命量的’0’位,最后再添加64位的消息长度。
- 消息扩展:将填充后的消息分为512位的块,然后进行消息扩展,将每个512位的消息块扩展为132个32位的字。
- 压缩函数:将消息块与初始的IV(Initial Vector,初始向量)通过非线性变换进行压缩,32轮迭代,每轮利用扩展后的消息字和常量进行混合运算。
- 迭代运算:将压缩后的结果与前一个结果相加,作为下一次压缩的输入,直到全部消息块都处理完毕。
- 输出哈希值:最后得到的256位数据即为SM3的哈希值。
2、数据示例
假设输入消息为 “abc”。在SM3算法中,这将被转化为字节形式进行处理:b"abc"。
2.1步调 1: 消息填充
SM3算法的第一步是对消息进行填充,使其长度变为512的倍数。
2.1.1 原始消息:
- “abc” 在ASCII中的十六进制表示为:0x61 0x62 0x63,即 b"abc"。
- 长度为3字节,或者24位(二进制)。
2.1.2 附加 ‘1’ 位:
- 在消息末尾添加一个’1’位:0x61 0x62 0x63 0x80,即 b"abc\x80"。
2.1.3 填充 ‘0’ 位:
- 为了使填充后的长度为448位(512位-64位,数据长度需要用64位的),我们需要在’1’位后填充448 - 24 - 8 = 416位的0。
- 填充后的消息为:0x61 0x62 0x63 0x80 加上 52 (64字节-8字节-3字节-1字节)个 0x00,即 b"abc\x80" + b’\x00’*52。
2.1.4 附加消息长度:
- 将原始消息的长度(24位)用64位二进制表示,并附加到消息末尾:0x0000000000000018(64位表示的十六进制)。
- 终极填充后的消息为:
- b"abc\x80" + b'\x00'*52 + b'\x00\x00\x00\x00\x00\x00\x00\x18
复制代码- 0x61 0x62 0x63 0x80 00 00 00 00 00 00 00 00 00 00 00 00 ...
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 18
复制代码 2.2 步调 2: 消息扩展
将填充后的消息块扩展为132个32位字(W[0]到W[67]和W’[0]到W’[63]),以便进行后续的压缩计算。
2.2.1 分块:
- 每个512位的消息块被分成16个32位的字(W[0]到W[15])。
- 对于"abc",原始消息块为:
- W[0] = 0x61626380
- W[1] = 0x00000000
- W[2] = 0x00000000
- ...
- W[15] = 0x00000018
复制代码 2.2.2 消息扩展:
- 扩展为68个字(W[16]-W[67]):
- W[j] = P1(W[j-16] ^ W[j-9] ^ ROTL(W[j-3], 15)) ^ ROTL(W[j-13], 7) ^ W[j-6]
复制代码
- 比方:
- W[16] = P1(W[0] ^ W[7] ^ ROTL(W[13], 15)) ^ ROTL(W[3], 7) ^ W[10]
复制代码 2.2.3 计算W’:
W’共64个字,和W合起来共132个字
2.3 步调 3: 压缩函数
目标:将扩展后的消息块与初始向量(IV)通过32轮迭代压缩,天生新的哈希值。
2.3.1 初始化寄存器:
- 利用8个初始向量IV初始化寄存器(A到H):
- A = 0x7380166F, B = 0x4914B2B9, C = 0x172442D7, D = 0xDA8A0600,
- E = 0xA96F30BC, F = 0x163138AA, G = 0xE38DEE4D, H = 0xB0FB0E4E
复制代码 2.3.1 32轮迭代计算:
- 每轮利用FF、GG、P0、P1等函数,以及常量T[j],更新寄存器的值。
- 比方,第1轮的计算:
- SS1 = ROTL(ROTL(A, 12) + E + ROTL(T[0], 0), 7)
- SS2 = SS1 ^ ROTL(A, 12)
- TT1 = FF(A, B, C, j) + D + SS2 + W'[j]
- TT2 = GG(E, F, G, j) + H + SS1 + W[j]
复制代码
- 更新寄存器的值:
- A = TT1, B = A, C = ROTL(B, 9), D = C, ...
复制代码 2.3.2 压缩结果:
- 每一轮的结果与前一轮的结果相加,作为下一轮的输入。处理完全部消息块后,将终极结果作为哈希值。
2.4 步调4:输出哈希值
目标:将终极压缩后的256位寄存器值作为SM3的哈希值输出。
2.4.1组合寄存器值:
- 将终极的寄存器A到H的值连接起来,形成一个256位(64个十六进制字符)的哈希值。
- 对于消息 “abc”,终极输出的哈希值为:
- 66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0
复制代码 3、python实现
- import struct
- def left_rotate(n, b):
- """左旋转 n by b bits。"""
- return ((n << b)
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |