SM3算法 C语言 (从OpenSSL库中分离算法:六)
SM3算法 C語言 (從OpenSSL庫中分離算法:六)
OpenSSL簡介:
OpenSSL 是用于傳輸層安全性 (TLS) 和安全套接字層 (SSL) 協(xié)議的一個強(qiáng)大、商業(yè)級和功能齊全的工具包,它也是一個通用的密碼學(xué)庫。包含有RSA、SM4、DES、AES等諸多加密算法。
OpenSSL GitHub地址如下:
GitHub - openssl/openssl: TLS/SSL and crypto library
在日常的開發(fā)工作中,有時只想用OpenSSL庫中的一種算法,此時調(diào)用整個OpenSSL庫,往往是沒必要的;再或者在嵌入式平臺使用某一算法,那我們只移植這個算法,沒有必要移植整個OpenSSL庫。
SM3簡介
SM3是我國采用的一種密碼散列函數(shù)標(biāo)準(zhǔn),由國家密碼管理局于2010年12月17日發(fā)布。相關(guān)標(biāo)準(zhǔn)為“GM/T 0004-2012 《SM3密碼雜湊算法》”。它可以將任意長度的消息壓縮成固定長度的摘要,主要用于數(shù)字簽名和數(shù)據(jù)完整性保護(hù)等
在商用密碼體系中,SM3主要用于數(shù)字簽名及驗證、消息認(rèn)證碼生成及驗證、隨機(jī)數(shù)生成等,其算法公開。據(jù)國家密碼管理局表示,其安全性及效率與SHA-256相當(dāng)。
移植過程
一、下載代碼
從OpenSSL的Github倉庫下載代碼,可以下載master分支,也可以下載最新的release版本。將下載的文件解壓,得到代碼。
重點關(guān)注紅框目錄:
- crypto目錄內(nèi)是各種加密算法
- include目錄內(nèi)是各加密算法對外接口的頭文件
二、準(zhǔn)備環(huán)境
新建Visual Studio C++ 控制臺項目"sm3test",編譯選項是:x86\Debug
三、準(zhǔn)備文件
刪除目錄內(nèi)的如下本項目中無用文件:
- build.info
- legacy_sm3.c
四、修改代碼
修改調(diào)用文件
在VS工程中含有main函數(shù)的主文件:sm3test.cpp中,增加包含sm3.h頭文件
#include "sm3/sm3.h"在main函數(shù)中添加如下代碼
SM3_CTX SMC;ossl_sm3_init(&SMC);const unsigned char Data[1024] = "Hello World";unsigned char md[SM3_DIGEST_LENGTH] = { 0 };ossl_sm3_update(&SMC, Data, strlen((const char *) Data));ossl_sm3_final(md, &SMC);for (int i = 0; i < SM3_DIGEST_LENGTH; i++) {printf("%02x-", *(md + i));}修改后的sm3test.cpp代碼如下:
#include <iostream> #include "sm3/sm3.h" int main() {SM3_CTX SMC;ossl_sm3_init(&SMC);const unsigned char Data[1024] = "Hello World";unsigned char md[SM3_DIGEST_LENGTH] = { 0 };ossl_sm3_update(&SMC, Data, strlen((const char *) Data));ossl_sm3_final(md, &SMC);for (int i = 0; i < SM3_DIGEST_LENGTH; i++) {printf("%02x-", *(md + i));} }修改sm3.h
刪除條件編譯 OPENSSL_SM3_H
刪除頭文件# include <openssl/opensslconf.h>
刪除條件編譯 OPENSSL_NO_SM3
添加C++調(diào)用時的宏
修改或刪除后的文件如下:
# pragma once # ifdef __cplusplus extern "C" { # endif# define SM3_DIGEST_LENGTH 32 # define SM3_WORD unsigned int# define SM3_CBLOCK 64 # define SM3_LBLOCK (SM3_CBLOCK/4)typedef struct SM3state_st {SM3_WORD A, B, C, D, E, F, G, H;SM3_WORD Nl, Nh;SM3_WORD data[SM3_LBLOCK];unsigned int num; } SM3_CTX;int ossl_sm3_init(SM3_CTX* c); int ossl_sm3_update(SM3_CTX* c, const void* data, size_t len); int ossl_sm3_final(unsigned char* md, SM3_CTX* c);# ifdef __cplusplus } # endif修改sm3_local.h
修改頭文件# include "internal/sm3.h"改為#include "sm3.h"
修改頭文件# include "crypto/md32_common.h"改為#include "md32_common.h"
修改或刪除后的文件如下:
#include <string.h> #include "sm3.h"#define DATA_ORDER_IS_BIG_ENDIAN#define HASH_LONG SM3_WORD #define HASH_CTX SM3_CTX #define HASH_CBLOCK SM3_CBLOCK #define HASH_UPDATE ossl_sm3_update #define HASH_TRANSFORM ossl_sm3_transform #define HASH_FINAL ossl_sm3_final #define HASH_MAKE_STRING(c, s) \do { \unsigned long ll; \ll=(c)->A; (void)HOST_l2c(ll, (s)); \ll=(c)->B; (void)HOST_l2c(ll, (s)); \ll=(c)->C; (void)HOST_l2c(ll, (s)); \ll=(c)->D; (void)HOST_l2c(ll, (s)); \ll=(c)->E; (void)HOST_l2c(ll, (s)); \ll=(c)->F; (void)HOST_l2c(ll, (s)); \ll=(c)->G; (void)HOST_l2c(ll, (s)); \ll=(c)->H; (void)HOST_l2c(ll, (s)); \} while (0) #define HASH_BLOCK_DATA_ORDER ossl_sm3_block_data_ordervoid ossl_sm3_block_data_order(SM3_CTX *c, const void *p, size_t num); void ossl_sm3_transform(SM3_CTX *c, const unsigned char *data);#include "md32_common.h"#define P0(X) (X ^ ROTATE(X, 9) ^ ROTATE(X, 17)) #define P1(X) (X ^ ROTATE(X, 15) ^ ROTATE(X, 23))#define FF0(X,Y,Z) (X ^ Y ^ Z) #define GG0(X,Y,Z) (X ^ Y ^ Z)#define FF1(X,Y,Z) ((X & Y) | ((X | Y) & Z)) #define GG1(X,Y,Z) ((Z ^ (X & (Y ^ Z))))#define EXPAND(W0,W7,W13,W3,W10) \(P1(W0 ^ W7 ^ ROTATE(W13, 15)) ^ ROTATE(W3, 7) ^ W10)#define RND(A, B, C, D, E, F, G, H, TJ, Wi, Wj, FF, GG) \do { \const SM3_WORD A12 = ROTATE(A, 12); \const SM3_WORD A12_SM = A12 + E + TJ; \const SM3_WORD SS1 = ROTATE(A12_SM, 7); \const SM3_WORD TT1 = FF(A, B, C) + D + (SS1 ^ A12) + (Wj); \const SM3_WORD TT2 = GG(E, F, G) + H + SS1 + Wi; \B = ROTATE(B, 9); \D = TT1; \F = ROTATE(F, 19); \H = P0(TT2); \} while(0)#define R1(A,B,C,D,E,F,G,H,TJ,Wi,Wj) \RND(A,B,C,D,E,F,G,H,TJ,Wi,Wj,FF0,GG0)#define R2(A,B,C,D,E,F,G,H,TJ,Wi,Wj) \RND(A,B,C,D,E,F,G,H,TJ,Wi,Wj,FF1,GG1)#define SM3_A 0x7380166fUL #define SM3_B 0x4914b2b9UL #define SM3_C 0x172442d7UL #define SM3_D 0xda8a0600UL #define SM3_E 0xa96f30bcUL #define SM3_F 0x163138aaUL #define SM3_G 0xe38dee4dUL #define SM3_H 0xb0fb0e4eUL修改sm3.c
刪除頭文件#include <openssl/e_os2.h>
修改或刪除后的文件如下:
#include "sm3_local.h"int ossl_sm3_init(SM3_CTX *c) {memset(c, 0, sizeof(*c));c->A = SM3_A;c->B = SM3_B;c->C = SM3_C;c->D = SM3_D;c->E = SM3_E;c->F = SM3_F;c->G = SM3_G;c->H = SM3_H;return 1; }void ossl_sm3_block_data_order(SM3_CTX *ctx, const void *p, size_t num) {const unsigned char *data = p;register unsigned MD32_REG_T A, B, C, D, E, F, G, H;unsigned MD32_REG_T W00, W01, W02, W03, W04, W05, W06, W07,W08, W09, W10, W11, W12, W13, W14, W15;for (; num--;) {A = ctx->A;B = ctx->B;C = ctx->C;D = ctx->D;E = ctx->E;F = ctx->F;G = ctx->G;H = ctx->H;/** We have to load all message bytes immediately since SM3 reads* them slightly out of order.*/(void)HOST_c2l(data, W00);(void)HOST_c2l(data, W01);(void)HOST_c2l(data, W02);(void)HOST_c2l(data, W03);(void)HOST_c2l(data, W04);(void)HOST_c2l(data, W05);(void)HOST_c2l(data, W06);(void)HOST_c2l(data, W07);(void)HOST_c2l(data, W08);(void)HOST_c2l(data, W09);(void)HOST_c2l(data, W10);(void)HOST_c2l(data, W11);(void)HOST_c2l(data, W12);(void)HOST_c2l(data, W13);(void)HOST_c2l(data, W14);(void)HOST_c2l(data, W15);R1(A, B, C, D, E, F, G, H, 0x79CC4519, W00, W00 ^ W04);W00 = EXPAND(W00, W07, W13, W03, W10);R1(D, A, B, C, H, E, F, G, 0xF3988A32, W01, W01 ^ W05);W01 = EXPAND(W01, W08, W14, W04, W11);R1(C, D, A, B, G, H, E, F, 0xE7311465, W02, W02 ^ W06);W02 = EXPAND(W02, W09, W15, W05, W12);R1(B, C, D, A, F, G, H, E, 0xCE6228CB, W03, W03 ^ W07);W03 = EXPAND(W03, W10, W00, W06, W13);R1(A, B, C, D, E, F, G, H, 0x9CC45197, W04, W04 ^ W08);W04 = EXPAND(W04, W11, W01, W07, W14);R1(D, A, B, C, H, E, F, G, 0x3988A32F, W05, W05 ^ W09);W05 = EXPAND(W05, W12, W02, W08, W15);R1(C, D, A, B, G, H, E, F, 0x7311465E, W06, W06 ^ W10);W06 = EXPAND(W06, W13, W03, W09, W00);R1(B, C, D, A, F, G, H, E, 0xE6228CBC, W07, W07 ^ W11);W07 = EXPAND(W07, W14, W04, W10, W01);R1(A, B, C, D, E, F, G, H, 0xCC451979, W08, W08 ^ W12);W08 = EXPAND(W08, W15, W05, W11, W02);R1(D, A, B, C, H, E, F, G, 0x988A32F3, W09, W09 ^ W13);W09 = EXPAND(W09, W00, W06, W12, W03);R1(C, D, A, B, G, H, E, F, 0x311465E7, W10, W10 ^ W14);W10 = EXPAND(W10, W01, W07, W13, W04);R1(B, C, D, A, F, G, H, E, 0x6228CBCE, W11, W11 ^ W15);W11 = EXPAND(W11, W02, W08, W14, W05);R1(A, B, C, D, E, F, G, H, 0xC451979C, W12, W12 ^ W00);W12 = EXPAND(W12, W03, W09, W15, W06);R1(D, A, B, C, H, E, F, G, 0x88A32F39, W13, W13 ^ W01);W13 = EXPAND(W13, W04, W10, W00, W07);R1(C, D, A, B, G, H, E, F, 0x11465E73, W14, W14 ^ W02);W14 = EXPAND(W14, W05, W11, W01, W08);R1(B, C, D, A, F, G, H, E, 0x228CBCE6, W15, W15 ^ W03);W15 = EXPAND(W15, W06, W12, W02, W09);R2(A, B, C, D, E, F, G, H, 0x9D8A7A87, W00, W00 ^ W04);W00 = EXPAND(W00, W07, W13, W03, W10);R2(D, A, B, C, H, E, F, G, 0x3B14F50F, W01, W01 ^ W05);W01 = EXPAND(W01, W08, W14, W04, W11);R2(C, D, A, B, G, H, E, F, 0x7629EA1E, W02, W02 ^ W06);W02 = EXPAND(W02, W09, W15, W05, W12);R2(B, C, D, A, F, G, H, E, 0xEC53D43C, W03, W03 ^ W07);W03 = EXPAND(W03, W10, W00, W06, W13);R2(A, B, C, D, E, F, G, H, 0xD8A7A879, W04, W04 ^ W08);W04 = EXPAND(W04, W11, W01, W07, W14);R2(D, A, B, C, H, E, F, G, 0xB14F50F3, W05, W05 ^ W09);W05 = EXPAND(W05, W12, W02, W08, W15);R2(C, D, A, B, G, H, E, F, 0x629EA1E7, W06, W06 ^ W10);W06 = EXPAND(W06, W13, W03, W09, W00);R2(B, C, D, A, F, G, H, E, 0xC53D43CE, W07, W07 ^ W11);W07 = EXPAND(W07, W14, W04, W10, W01);R2(A, B, C, D, E, F, G, H, 0x8A7A879D, W08, W08 ^ W12);W08 = EXPAND(W08, W15, W05, W11, W02);R2(D, A, B, C, H, E, F, G, 0x14F50F3B, W09, W09 ^ W13);W09 = EXPAND(W09, W00, W06, W12, W03);R2(C, D, A, B, G, H, E, F, 0x29EA1E76, W10, W10 ^ W14);W10 = EXPAND(W10, W01, W07, W13, W04);R2(B, C, D, A, F, G, H, E, 0x53D43CEC, W11, W11 ^ W15);W11 = EXPAND(W11, W02, W08, W14, W05);R2(A, B, C, D, E, F, G, H, 0xA7A879D8, W12, W12 ^ W00);W12 = EXPAND(W12, W03, W09, W15, W06);R2(D, A, B, C, H, E, F, G, 0x4F50F3B1, W13, W13 ^ W01);W13 = EXPAND(W13, W04, W10, W00, W07);R2(C, D, A, B, G, H, E, F, 0x9EA1E762, W14, W14 ^ W02);W14 = EXPAND(W14, W05, W11, W01, W08);R2(B, C, D, A, F, G, H, E, 0x3D43CEC5, W15, W15 ^ W03);W15 = EXPAND(W15, W06, W12, W02, W09);R2(A, B, C, D, E, F, G, H, 0x7A879D8A, W00, W00 ^ W04);W00 = EXPAND(W00, W07, W13, W03, W10);R2(D, A, B, C, H, E, F, G, 0xF50F3B14, W01, W01 ^ W05);W01 = EXPAND(W01, W08, W14, W04, W11);R2(C, D, A, B, G, H, E, F, 0xEA1E7629, W02, W02 ^ W06);W02 = EXPAND(W02, W09, W15, W05, W12);R2(B, C, D, A, F, G, H, E, 0xD43CEC53, W03, W03 ^ W07);W03 = EXPAND(W03, W10, W00, W06, W13);R2(A, B, C, D, E, F, G, H, 0xA879D8A7, W04, W04 ^ W08);W04 = EXPAND(W04, W11, W01, W07, W14);R2(D, A, B, C, H, E, F, G, 0x50F3B14F, W05, W05 ^ W09);W05 = EXPAND(W05, W12, W02, W08, W15);R2(C, D, A, B, G, H, E, F, 0xA1E7629E, W06, W06 ^ W10);W06 = EXPAND(W06, W13, W03, W09, W00);R2(B, C, D, A, F, G, H, E, 0x43CEC53D, W07, W07 ^ W11);W07 = EXPAND(W07, W14, W04, W10, W01);R2(A, B, C, D, E, F, G, H, 0x879D8A7A, W08, W08 ^ W12);W08 = EXPAND(W08, W15, W05, W11, W02);R2(D, A, B, C, H, E, F, G, 0x0F3B14F5, W09, W09 ^ W13);W09 = EXPAND(W09, W00, W06, W12, W03);R2(C, D, A, B, G, H, E, F, 0x1E7629EA, W10, W10 ^ W14);W10 = EXPAND(W10, W01, W07, W13, W04);R2(B, C, D, A, F, G, H, E, 0x3CEC53D4, W11, W11 ^ W15);W11 = EXPAND(W11, W02, W08, W14, W05);R2(A, B, C, D, E, F, G, H, 0x79D8A7A8, W12, W12 ^ W00);W12 = EXPAND(W12, W03, W09, W15, W06);R2(D, A, B, C, H, E, F, G, 0xF3B14F50, W13, W13 ^ W01);W13 = EXPAND(W13, W04, W10, W00, W07);R2(C, D, A, B, G, H, E, F, 0xE7629EA1, W14, W14 ^ W02);W14 = EXPAND(W14, W05, W11, W01, W08);R2(B, C, D, A, F, G, H, E, 0xCEC53D43, W15, W15 ^ W03);W15 = EXPAND(W15, W06, W12, W02, W09);R2(A, B, C, D, E, F, G, H, 0x9D8A7A87, W00, W00 ^ W04);W00 = EXPAND(W00, W07, W13, W03, W10);R2(D, A, B, C, H, E, F, G, 0x3B14F50F, W01, W01 ^ W05);W01 = EXPAND(W01, W08, W14, W04, W11);R2(C, D, A, B, G, H, E, F, 0x7629EA1E, W02, W02 ^ W06);W02 = EXPAND(W02, W09, W15, W05, W12);R2(B, C, D, A, F, G, H, E, 0xEC53D43C, W03, W03 ^ W07);W03 = EXPAND(W03, W10, W00, W06, W13);R2(A, B, C, D, E, F, G, H, 0xD8A7A879, W04, W04 ^ W08);R2(D, A, B, C, H, E, F, G, 0xB14F50F3, W05, W05 ^ W09);R2(C, D, A, B, G, H, E, F, 0x629EA1E7, W06, W06 ^ W10);R2(B, C, D, A, F, G, H, E, 0xC53D43CE, W07, W07 ^ W11);R2(A, B, C, D, E, F, G, H, 0x8A7A879D, W08, W08 ^ W12);R2(D, A, B, C, H, E, F, G, 0x14F50F3B, W09, W09 ^ W13);R2(C, D, A, B, G, H, E, F, 0x29EA1E76, W10, W10 ^ W14);R2(B, C, D, A, F, G, H, E, 0x53D43CEC, W11, W11 ^ W15);R2(A, B, C, D, E, F, G, H, 0xA7A879D8, W12, W12 ^ W00);R2(D, A, B, C, H, E, F, G, 0x4F50F3B1, W13, W13 ^ W01);R2(C, D, A, B, G, H, E, F, 0x9EA1E762, W14, W14 ^ W02);R2(B, C, D, A, F, G, H, E, 0x3D43CEC5, W15, W15 ^ W03);ctx->A ^= A;ctx->B ^= B;ctx->C ^= C;ctx->D ^= D;ctx->E ^= E;ctx->F ^= F;ctx->G ^= G;ctx->H ^= H;} }修改md32_common.h
刪除頭文件# include <openssl/crypto.h>
刪除代碼中全部的OPENSSL_cleanse();
*解釋:經(jīng)查閱openssl代碼中的OPENSSL_cleanse函數(shù)聲明,此函數(shù)作用等同與標(biāo)準(zhǔn)C中的memset(p,0,size)功能,是將參數(shù)一內(nèi)存清0,本文件中調(diào)用該函數(shù)的地方,其參數(shù)1均為棧空間,函數(shù)結(jié)束后將自動回收,因此沒必要手動清0,因此該函數(shù)可以不調(diào)用,若不放心,可以用memset函數(shù)替代。
修改或刪除后的文件如下:
#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN) # error "DATA_ORDER must be defined!" #endif#ifndef HASH_CBLOCK # error "HASH_CBLOCK must be defined!" #endif #ifndef HASH_LONG # error "HASH_LONG must be defined!" #endif #ifndef HASH_CTX # error "HASH_CTX must be defined!" #endif#ifndef HASH_UPDATE # error "HASH_UPDATE must be defined!" #endif #ifndef HASH_TRANSFORM # error "HASH_TRANSFORM must be defined!" #endif #ifndef HASH_FINAL # error "HASH_FINAL must be defined!" #endif#ifndef HASH_BLOCK_DATA_ORDER # error "HASH_BLOCK_DATA_ORDER must be defined!" #endif#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))#if defined(DATA_ORDER_IS_BIG_ENDIAN)# define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \l|=(((unsigned long)(*((c)++)))<<16), \l|=(((unsigned long)(*((c)++)))<< 8), \l|=(((unsigned long)(*((c)++))) ) ) # define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \*((c)++)=(unsigned char)(((l)>>16)&0xff), \*((c)++)=(unsigned char)(((l)>> 8)&0xff), \*((c)++)=(unsigned char)(((l) )&0xff), \l)#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)# define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \l|=(((unsigned long)(*((c)++)))<< 8), \l|=(((unsigned long)(*((c)++)))<<16), \l|=(((unsigned long)(*((c)++)))<<24) ) # define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \*((c)++)=(unsigned char)(((l)>> 8)&0xff), \*((c)++)=(unsigned char)(((l)>>16)&0xff), \*((c)++)=(unsigned char)(((l)>>24)&0xff), \l)#endif/** Time for some action :-)*/int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len) {const unsigned char *data = data_;unsigned char *p;HASH_LONG l;size_t n;if (len == 0)return 1;l = (c->Nl + (((HASH_LONG) len) << 3)) & 0xffffffffUL;if (l < c->Nl) /* overflow */c->Nh++;c->Nh += (HASH_LONG) (len >> 29); /* might cause compiler warning on* 16-bit */c->Nl = l;n = c->num;if (n != 0) {p = (unsigned char *)c->data;if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) {memcpy(p + n, data, HASH_CBLOCK - n);HASH_BLOCK_DATA_ORDER(c, p, 1);n = HASH_CBLOCK - n;data += n;len -= n;c->num = 0;/** We use memset rather than OPENSSL_cleanse() here deliberately.* Using OPENSSL_cleanse() here could be a performance issue. It* will get properly cleansed on finalisation so this isn't a* security problem.*/memset(p, 0, HASH_CBLOCK); /* keep it zeroed */} else {memcpy(p + n, data, len);c->num += (unsigned int)len;return 1;}}n = len / HASH_CBLOCK;if (n > 0) {HASH_BLOCK_DATA_ORDER(c, data, n);n *= HASH_CBLOCK;data += n;len -= n;}if (len != 0) {p = (unsigned char *)c->data;c->num = (unsigned int)len;memcpy(p, data, len);}return 1; }void HASH_TRANSFORM(HASH_CTX *c, const unsigned char *data) {HASH_BLOCK_DATA_ORDER(c, data, 1); }int HASH_FINAL(unsigned char *md, HASH_CTX *c) {unsigned char *p = (unsigned char *)c->data;size_t n = c->num;p[n] = 0x80; /* there is always room for one */n++;if (n > (HASH_CBLOCK - 8)) {memset(p + n, 0, HASH_CBLOCK - n);n = 0;HASH_BLOCK_DATA_ORDER(c, p, 1);}memset(p + n, 0, HASH_CBLOCK - 8 - n);p += HASH_CBLOCK - 8; #if defined(DATA_ORDER_IS_BIG_ENDIAN)(void)HOST_l2c(c->Nh, p);(void)HOST_l2c(c->Nl, p); #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)(void)HOST_l2c(c->Nl, p);(void)HOST_l2c(c->Nh, p); #endifp -= HASH_CBLOCK;HASH_BLOCK_DATA_ORDER(c, p, 1);c->num = 0;#ifndef HASH_MAKE_STRING # error "HASH_MAKE_STRING must be defined!" #elseHASH_MAKE_STRING(c, md); #endifreturn 1; }#ifndef MD32_REG_T # if defined(__alpha) || defined(__sparcv9) || defined(__mips) # define MD32_REG_T long /** This comment was originally written for MD5, which is why it* discusses A-D. But it basically applies to all 32-bit digests,* which is why it was moved to common header file.** In case you wonder why A-D are declared as long and not* as MD5_LONG. Doing so results in slight performance* boost on LP64 architectures. The catch is we don't* really care if 32 MSBs of a 64-bit register get polluted* with eventual overflows as we *save* only 32 LSBs in* *either* case. Now declaring 'em long excuses the compiler* from keeping 32 MSBs zeroed resulting in 13% performance* improvement under SPARC Solaris7/64 and 5% under AlphaLinux.* Well, to be honest it should say that this *prevents** performance degradation.*/ # else /** Above is not absolute and there are LP64 compilers that* generate better code if MD32_REG_T is defined int. The above* pre-processor condition reflects the circumstances under which* the conclusion was made and is subject to further extension.*/ # define MD32_REG_T int # endif #endif五、編譯運(yùn)行
將sm3.h,sm3.c,sm3_local.h,md32_common.h文件,配置添加到VS工程中。
編譯運(yùn)行,輸出sm3結(jié)果如下:
77-01-58-16-14-3e-e6-27-f4-fa-41-0b-6d-ad-2b-db-9f-cb-df-1e-06-1a-45-2a-68-6b-87-11-a4-84-c5-d7上述算法,適用于計算字符串、緩沖區(qū)的SM3值。至于小文件、大文件的SM3如何計算,可以參考本人的另外兩篇關(guān)于MD5的博客,與SM3非常相似。
小文件MD5計算
大文件MD5計算
歡迎大家關(guān)注、留言討論、可分享源碼
總結(jié)
以上是生活随笔為你收集整理的SM3算法 C语言 (从OpenSSL库中分离算法:六)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 新代系统反向间隙参数_新代系统SYNTE
- 下一篇: SM3密码杂凑算法实现及说明