根据国家密码管理局官网发布的规范文档里的算法描述,对SM3密码杂凑算法进行了原汁原味的实现。代码里的函数、变量名称都尽量使用算法描述中的名称,尽量遵循算法描述的原始步骤,不使用算法技巧进行处理。
算法描述里的“位”的存储在程序中用字节来存储,因此代码里会有这样的写法:unsigned char Vi[256/8],表示Vi为256位(存储为256/8字节)的意思,而对等的 unsigned char Vi[32] 则表示Vi为32字节。
算法描述里的“字”是32字节,用 unsigned long 表示。
最后的函数 void SM3Hash(unsigned char* m, int ml, unsigned char r[32]) 为算法主体,参数 m 是原始数据,ml 是数据长度,r 是返回值。
本算法通过了官方文档附录里的示例验证。
#include <memory>
unsigned char IV[256 / 8] = { 0x73,0x80,0x16,0x6f,0x49,0x14,0xb2,0xb9,0x17,0x24,0x42,0xd7,0xda,0x8a,0x06,0x00,0xa9,0x6f,0x30,0xbc,0x16,0x31,0x38,0xaa,0xe3,0x8d,0xee,0x4d,0xb0,0xfb,0x0e,0x4e };
// 循环左移
unsigned long SL(unsigned long X, int n)
{
unsigned __int64 x = X;
x = x << (n % 32);
unsigned long l = (unsigned long)(x >> 32);
return x | l;
}
unsigned long Tj(int j)
{
if (j <= 15)
{
return 0x79cc4519;
}
else
{
return 0x7a879d8a;
}
}
unsigned long FFj(int j, unsigned long X, unsigned long Y, unsigned long Z)
{
if (j <= 15)