SM3杂凑算法

本文详细介绍了SM3密码杂凑算法的背景、原理和步骤,并提供了C代码实现。通过对512比特消息的填充和扩展,经过迭代压缩,最终得到杂凑值debe9ff9 2275b8a1 38604889 c18e5a4d 6fdb70e5 387e5765 293dcba3 9c0c5732。该算法在国密标准中占有重要地位。
摘要由CSDN通过智能技术生成

题目

给出16进制消息m,用SM3密码杂凑算法计算Hash值。

环境

Windows10,MinGW-W64-builds-4.3.5,miracl 7.0.1

方案设计

背景

SM3密码杂凑算法

原理

对长度为 ? (? < ???)比特的消息?,SM3杂凑算法经过填充和迭代压缩,生成杂凑值,杂凑值长度为256比特。

算法步骤

  1. 填充
    假设消息?的长度为?比特。首先将比特“1”添加到消息的末尾,再添加?个“0”, ? 是满足?+?+? ≡ ??? ?????? 的最小的非负整数。然后再添加一个64位比特串,该比特串是长度?的二进制表示。填充后的消息 ?′的比特长度为512的倍数。
  2. 扩展
    将填充后的消息 ?′按512比特进行分组: ?′= ?? ?? ⋯ ??−? 其中 ? = (?+?+??)/???。
    将消息分组??按以下方法扩展生成132个字??,??,⋯,???,?’?,?’?, ⋯,?’??用于压缩函数??:
    a) 将消息分组??划分为16个字??,??,⋯,??5。
    b) ??? ? = ?? ?? ??
    ?? ← ??(??−??⊕??−?⊕(??−? ⋘ ??))⊕(??−??⋘ ?) ⊕??−?
    ??????
    c) ??? ? = ? ?? ??
    ?’j = ?? ⊕ ??+?
    ??????
  3. 迭代压缩
    对?′按下列方式迭代:
    ??? ? = ? ?? ?−?
    ?(?+?) = ??(?(?);?(?))
    ??????
    其中??是压缩函数,?(?)为256比特初始值 IV ,?(?)为填充后的 消息分组,迭代压缩的结果为?(?)。
    压缩函数:
    令A,B,C,D,E,F,G,H为字寄存器,SS1,SS2,TT1,TT2为中间变量,压缩函数V i+1 = CF(V (i),B(i)), 0 ≤ i ≤ n−1。计算过程描述如下:
    ABCDEFGH ← V (i)
    FOR j=0 TO 63
    SS1 ← ((A ≪ 12) + E + (Tj ≪ j)) ≪ 7
    SS2 ← SS1⊕(A ≪ 12)
    TT1 ← FFj(A,B,C) + D + SS2 + W’j
    TT2 ← GGj(E,F,G) + H + SS1 + Wj
    D ← C
    C ← B ≪ 9
    B ← A
    A ← TT1
    H ← G
    G ← F ≪ 19
    F ← E
    E ← P0(TT2)
    ENDFOR
    V (i+1) ← ABCDEFGH⊕V (i)

方案实现

流程图

a

主要函数

  • void sftbit(big x, int n, big z); 将一个大数左移或右移n位,n为正数时左移,负数时右移
  • void incr(big x, int n, big z); 将一个大数加上一个整数, z=x+n
  • int numdig(big x); 返回大数x中数字的个数

C代码

#include <stdio.h>
#include "miracl.h"
#include <stdlib.h>

#define N 3
#define NUM_W 132


mr_small GG(int j, mr_small x, mr_small y, mr_small z);
mr_small FF(int j, mr_small x, mr_small y, mr_small z);
void BtoW(int i, mr_small b[][16], mr_small *W);
void CF(int i, mr_small V[][8], mr_small *W);
mr_small move(mr_small x, int n);
mr_small P0(mr_small x);
mr_small P1(mr_small x);
mr_small Tj(int j);

void str2hex(char *str, char *hex)
{
   
    char *p = hex;
    int i;

    for(i=0;str[i];i++){
   
        sprintf(p, "%02x",str[i]);
        p+=2;
    }
    *p='\0';
    // puts(hex);
}

int main(void)
{
   
    miracl *mip = mirsys(5000,16);
    int     i, j, n; unsigned long long     len;
    mr_small W[NUM_W]={
   0}, b[N][16]={
   0}, v[N+1][8], *p;
    big     m;

    m = mirvar(0);
    v[0][0] = 0x7380166f; v[0][1] = 0x4914b2b9; v[0][2] = 0x172442d7; v[0][3
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值