SM3算法笔记

1. 简介

SM3:

  • 国家密码管理局于2010年12月发布
  • 国标GB/T 32905-2016
  • 强度大概等同于SHA-256
  • 大端存储
  • 消息长度:<264 bits
  • 字长:4 bytes
  • Hash长度:256 bits == 32 bytes
  • 轮数:64

2. 常数与函数

初始值

static const uint32_t IV[8] = {
	0x7380166f,
	0x4914b2b9,
	0x172442d7,
	0xda8a0600,
	0xa96f30bc,
	0x163138aa,
	0xe38dee4d,
	0xb0fb0e4e
};

常量

// T[ j < 16 ? 0 : 1 ]
static const uint32_t T[2] =
{
	0x79CC4519, 0x7A879D8A
};

布尔函数

static uint32_t FF(uint32_t x, uint32_t y, uint32_t z, uint32_t j)
{
    // 0 <= j <= 15
    if (j < 16) 
    {
        return x ^ y ^ z;
    }
    // 16 <= j <= 63
    else 
    {
        return (x & y) | (x & z) | (y & z);
    }
}

static uint32_t GG(uint32_t x, uint32_t y, uint32_t z, uint32_t j)
{
    // 0 <= j <= 15
    if (j < 16) 
    {
        return x ^ y ^ z;
    }
    // 16 <= j <= 63
    else 
    {
        return (x & y) | (~x & z);
    }
}

置换函数

static uint32_t P0(uint32_t x)
{
    return x ^ ROTL(x, 9) ^ ROTL(x, 17);
}

static uint32_t P1(uint32_t x)
{
    return x ^ ROTL(x, 15) ^ ROTL(x, 23);
}

3. 算法描述

输入:<264 bits

流程:

  1. 填充
  2. 迭代压缩

输出:32 bytes

填充

与SHA1完全相同。

第一步,填充数据,使位长度比512的倍数小64。

bitsLen == 448 mod 512
bytesLen == 56 mod 64

填充方法:

  1. 一个1,后续用0;
  2. 至少填充1 bit,至多512 bits (64 bytes)。

第二步,添加64 bits消息长度。

经过这一步,消息长度就是512 bits (16 words)的倍数了。

迭代

将填充后的数据M分为N个长512 bit的分组(block)。

for(i = 0 ; i < N; ++i)
{
    // V[0] = 256-bit IV
    // CF: Compression Function
    V[i+1] = CF(V[i], M[i]);
}

扩展

已知每个消息分组为512 bits == 64 bytes == 16 words(uint32)。在代码中,正是以16个4字节整型为单位进行处理的。

这一步是将16个字扩展为132个字:W0 W1...W67 W'0 ... W'63

uint32_t W[HASH_ROUND_NUM + 4] = {0};
uint32_t W1[HASH_ROUND_NUM] = {0};

// extend W[16:68]
for (j = 16; j < (HASH_ROUND_NUM + 4); j++)
{
    W[j] = P1(
        W[j - 16]
        ^ W[j - 9]
        ^ ROTL(W[j - 3], 15)
    )
        ^ ROTL(W[j - 13], 7)
        ^ W[j - 6];
}

// extend W[68:132] == W1
for (j = 0; j < HASH_ROUND_NUM; j++)
{
    W1[j] = W[j] ^ W[j + 4];
}

压缩函数

// CF
A = hash[0];
B = hash[1];
C = hash[2];
D = hash[3];
E = hash[4];
F = hash[5];
G = hash[6];
H = hash[7];
for (j = 0; j < 64; j++)
{
    SS1 = ROTL(
        ROTL(A, 12)
        + E
        + ROTL(T[j < 16 ? 0 : 1], j)
        , 7);
    SS2 = SS1 ^ ROTL(A, 12);
    TT1 = FF(A, B, C, j) + D + SS2 + W1[j];
    TT2 = GG(E, F, G, j) + H + SS1 + W[j];
    D = C;
    C = ROTL(B, 9);
    B = A;
    A = TT1;
    H = G;
    G = ROTL(F, 19);
    F = E;
    E = P0(TT2);
}

实现

https://github.com/C0deStarr/CryptoImp/tree/main/Hash/sha

  • sm3.h
  • sm3.c

参考资料

国家密码管理局关于发布《SM3密码杂凑算法》公告(国密局公告第22号)_国家密码管理局 (sca.gov.cn)

国家标准|GB/T 32905-2016 (samr.gov.cn)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值