日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

SM3杂凑算法

發布時間:2023/12/31 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SM3杂凑算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 題目
  • 環境
  • 方案設計
    • 背景
    • 原理
    • 算法步驟
  • 方案實現
    • 流程圖
    • 主要函數
    • C代碼
    • 測試
      • 數據
      • 結果
    • 注意問題
  • 說明

題目

給出16進制消息m,用SM3密碼雜湊算法計算Hash值。

環境

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

方案設計

背景

SM3密碼雜湊算法

原理

對長度為 ? (? < ???)比特的消息?,SM3雜湊算法經過填充和迭代壓縮,生成雜湊值,雜湊值長度為256比特。

算法步驟

  • 填充
    假設消息?的長度為?比特。首先將比特“1”添加到消息的末尾,再添加?個“0”, ? 是滿足?+?+? ≡ ??? ?????? 的最小的非負整數。然后再添加一個64位比特串,該比特串是長度?的二進制表示。填充后的消息 ?′的比特長度為512的倍數。
  • 擴展
    將填充后的消息 ?′按512比特進行分組: ?′= ?? ?? ? ???? 其中 ? = (?+?+??)/???。
    將消息分組??按以下方法擴展生成132個字??,??,?,???,?’?,?’?, ?,?’??用于壓縮函數??:
    a) 將消息分組??劃分為16個字??,??,?,??5。
    b) ??? ? = ?? ?? ??
    ?? ← ??(?????⊕????⊕(???? ? ??))⊕(?????? ?) ⊕????
    ??????
    c) ??? ? = ? ?? ??
    ?’j = ?? ⊕ ??+?
    ??????
  • 迭代壓縮
    對?′按下列方式迭代:
    ??? ? = ? ?? ???
    ?(?+?) = ??(?(?);?(?))
    ??????
    其中??是壓縮函數,?(?)為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)
  • 方案實現

    流程圖

    主要函數

    • 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 132mr_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] = 0xda8a0600;v[0][4] = 0xa96f30bc; v[0][5] = 0x163138aa; v[0][6] = 0xe38dee4d; v[0][7] = 0xb0fb0e4e;FILE *fp;fp = fopen("data.txt", "r");mip->IOBASE = 16;cinnum(m, fp);fclose(fp);printf("m = ");cotnum(m, stdout);// 填充len = numdig(m)*4; sftbit(m, 1, m);incr(m, 1, m);if (len % 512 < 448){n = len/512 + 1; sftbit(m, 511-(len%512), m); }else {n = len/512 + 2; sftbit(m, 1023-(len%512), m);} incr(m, len, m);printf("m'= ");cotnum(m, stdout); printf("n=%d, len=%d\n",n,len); // 將m按字分割存入數組bp = m->w;for (i = n-1; i >=0; i--){for (j = 15; j >= 0; j--){b[i][j] = *p++;} }puts("\nB(i)=");for (i = 0; i < n; i++){for (j = 0; j < 16; j++){printf("%08x ", b[i][j]);if ((j+1)%8 == 0) putchar('\n');} }for (i = 0; i < n; i++) {BtoW(i, b, W); // 將消息分組??擴展生成132個字CF(i, v, W); // 迭代壓縮}printf("\ny= ");for (j = 0; j < 8; j++) {printf("%08x ", v[n][j]);}mirexit();return 0; }void BtoW(int i, mr_small b[][16], mr_small *W) {int j;for (j = 0; j < 16; j++) {W[j] = b[i][j];}for (j = 16; j < 68; j++) {W[j] = P1(W[j-16]^W[j-9]^move(W[j-3], 15))^move(W[j-13], 7)^W[j-6];}for (j = 0; j < 64; j++) {W[j+68] = W[j]^W[j+4];}printf("\nW(%d)= \n", i+1);for (j = 0; j < NUM_W; j++) {printf("%08x ",W[j]);if ((j+1)%8==0 && j<68 || j==67 || (j-67)%8==0 && j>67 ){putchar('\n');}}} void CF(int i, mr_small V[][8], mr_small *W) {mr_small R[8], ST[4];int j; int t; printf("\n j A B C D E F G H\n ");for (j = 0; j < 8; j++) {R[j] = V[i][j];printf("%08x ",R[j]); }putchar('\n');for (j = 0; j < 64; j++) { ST[0] = move(move(R[0], 12)+R[4]+move(Tj(j), j), 7);ST[1] = ST[0] ^ move(R[0], 12); ST[2] = FF(j, R[0], R[1], R[2]) + R[3] + ST[1] + W[j+68];ST[3] = GG(j, R[4], R[5], R[6]) + R[7] + ST[0] + W[j];R[3] = R[2]; R[2] = move(R[1], 9);R[1] = R[0];R[0] = ST[2];R[7] = R[6];R[6] = move(R[5], 19);R[5] = R[4];R[4] = P0(ST[3]); printf("%2d ",j);for(t=0;t<8;t++) printf("%08x ",R[t]);putchar('\n');}for (j = 0; j < 8; j++) {V[i+1][j] = V[i][j] ^ R[j];}}mr_small FF(int j, mr_small x, mr_small y, mr_small z) {if (j < 16 && j >= 0) {return x^y^z;} if(j >=16 && j < 64) {return (x&y)|(x&z)|(y&z);}return -1; } mr_small GG(int j, mr_small x, mr_small y, mr_small z) {if (j < 16 && j >= 0) {return x^y^z;} if(j >=16 && j < 64) {return (x&y)|(~x&z);}return -1; } mr_small move(mr_small x, int n) {mr_small y , z; y = x << n;z = x >> (sizeof(x)*8-n);z = y | z;return z; } mr_small P0(mr_small x) {return x^move(x, 9)^move(x, 17); } mr_small P1(mr_small x) {return x^move(x, 15)^move(x, 23); } mr_small Tj(int j) {if (j >=0 && j <16){return 0x79cc4519;}if (j >=16 && j <64){return 0x7a879d8a;}return -1; }

    測試

    數據

    512比特消息

    61626364 61626364 61626364 61626364 61626364 61626364 61626364 61626364
    61626364 61626364 61626364 61626364 61626364 61626364 61626364 61626364

    填充后的消息

    61626364 61626364 61626364 61626364 61626364 61626364 61626364 61626364
    61626364 61626364 61626364 61626364 61626364 61626364 61626364 61626364
    80000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    80000000 00000000 00000000 00000000 00000000 00000000 00000000 00000200

    雜湊值

    debe9ff9 2275b8a1 38604889 c18e5a4d 6fdb70e5 387e5765 293dcba3 9c0c5732

    結果


    注意問題

    因為一個字的長度為32 bits,可以用無符號整型unsigned int表示。所以把大數分割成無符號整型數組便于運算,大數結構體內有兩個成員,分別為長度和數組/指針(小端存儲),通過unsigned int指針可以很方便的訪問該數組,按字取出并放入用于運算的數組B。

    說明

    課程作業,僅作記錄

    總結

    以上是生活随笔為你收集整理的SM3杂凑算法的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。