SM3算法 C语言 (从OpenSSL库中分离算法:六)
SM3算法 C语言 (从OpenSSL库中分离算法:六)
OpenSSL简介:
OpenSSL 是用于传输层安全性 (TLS) 和安全套接字层 (SSL) 协议的一个强大、商业级和功能齐全的工具包,它也是一个通用的密码学库。包含有RSA、SM4、DES、AES等诸多加密算法。
OpenSSL GitHub地址如下:
GitHub - openssl/openssl: TLS/SSL and crypto library
在日常的开发工作中,有时只想用OpenSSL库中的一种算法,此时调用整个OpenSSL库,往往是没必要的;再或者在嵌入式平台使用某一算法,那我们只移植这个算法,没有必要移植整个OpenSSL库。
SM3简介
SM3是我国采用的一种密码散列函数标准,由国家密码管理局于2010年12月17日发布。相关标准为“GM/T 0004-2012 《SM3密码杂凑算法》”。它可以将任意长度的消息压缩成固定长度的摘要,主要用于数字签名和数据完整性保护等
在商用密码体系中,SM3主要用于数字签名及验证、消息认证码生成及验证、随机数生成等,其算法公开。据国家密码管理局表示,其安全性及效率与SHA-256相当。
移植过程
一、下载代码
从OpenSSL的Github仓库下载代码,可以下载master分支,也可以下载最新的release版本。将下载的文件解压,得到代码。
重点关注红框目录:
- crypto目录内是各种加密算法
- include目录内是各加密算法对外接口的头文件
二、准备环境
新建Visual Studio C++ 控制台项目"sm3test",编译选项是:x86\Debug
三、准备文件
- 复制OpenSSL源码中:/crypto/sm3文件夹到VS工程代码目录下
- 复制OpenSSL源码中:/include/internal/sm3.h文件到VS工程代码目录中sm3文件夹内
- 复制OpenSSL源码中:/include/crypto/md32_common.h文件到VS工程代码目录中sm3文件夹内
- 复制完成后,VS工程代码目录sm3文件夹内文件如下:
删除目录内的如下本项目中无用文件:
- build.info
- legacy_sm3.c
四、修改代码
修改调用文件
在VS工程中含有main函数的主文件:sm3test.cpp中,增加包含sm3.h头文件
#include "sm3/sm3.h"
在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));
}
修改后的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++调用时的宏
修改或删除后的文件如下:
# 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_order
void 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();
*解释:经查阅openssl代码中的OPENSSL_cleanse函数声明,此函数作用等同与标准C中的memset(p,0,size)功能,是将参数一内存清0,本文件中调用该函数的地方,其参数1均为栈空间,函数结束后将自动回收,因此没必要手动清0,因此该函数可以不调用,若不放心,可以用memset函数替代。
修改或删除后的文件如下:
#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);
#endif
p -= HASH_CBLOCK;
HASH_BLOCK_DATA_ORDER(c, p, 1);
c->num = 0;
#ifndef HASH_MAKE_STRING
# error "HASH_MAKE_STRING must be defined!"
#else
HASH_MAKE_STRING(c, md);
#endif
return 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
五、编译运行
将sm3.h,sm3.c,sm3_local.h,md32_common.h文件,配置添加到VS工程中。
编译运行,输出sm3结果如下:
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
上述算法,适用于计算字符串、缓冲区的SM3值。至于小文件、大文件的SM3如何计算,可以参考本人的另外两篇关于MD5的博客,与SM3非常相似。
欢迎大家关注、留言讨论、可分享源码
更多推荐
所有评论(0)