当前位置:   article > 正文

GMSSL sm3代码接口_c++ sm3 gmssl

c++ sm3 gmssl
结合官方文档对sm3算法研究了一下,从GMSSL源码挖出sm3,处理一下word数据存储方式后调试通过
  • 1
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "sm3.h"


//大小端数据转换函数,例:0x00112233转换为0x33221100
uint32_t Lendian_2_Bendian(uint32_t value)
{
	return (value & 0x000000FFU) << 24 | (value & 0x0000FF00U) << 8
		   |(value & 0x00FF0000U) >> 8 | (value & 0xFF000000U) >> 24;
}




void sm3_init(sm3_ctx_t *ctx)
{
	//初始值IV
	ctx->digest[0] = 0x7380166F;
	ctx->digest[1] = 0x4914B2B9;
	ctx->digest[2] = 0x172442D7;
	ctx->digest[3] = 0xDA8A0600;
	ctx->digest[4] = 0xA96F30BC;
	ctx->digest[5] = 0x163138AA;
	ctx->digest[6] = 0xE38DEE4D;
	ctx->digest[7] = 0xB0FB0E4E;

	ctx->nblocks = 0;
	ctx->num = 0;
}

//前n-1个512bit块数据处理
void sm3_update(sm3_ctx_t *ctx, const unsigned char* data, size_t data_len)
{
	if (ctx->num) 
	{
		unsigned int left = SM3_BLOCK_SIZE - ctx->num;
		
		if (data_len < left) 
		{
			memcpy(ctx->block + ctx->num, data, data_len);
			ctx->num += data_len;
			return;
		} 
		else 
		{
			memcpy(ctx->block + ctx->num, data, left);
			sm3_compress(ctx->digest, ctx->block);
			ctx->nblocks++;
			data += left;
			data_len -= left;
		}
	}

	//迭代压缩(处理前n-1个512bit块数据)
	while(data_len >= SM3_BLOCK_SIZE) 
	{
		sm3_compress(ctx->digest, data);
		ctx->nblocks++;
		data += SM3_BLOCK_SIZE;
		data_len -= SM3_BLOCK_SIZE;
	}

	//剩下一组不足512bit的块数据,进行单独处理
	ctx->num = data_len;
	
	if(data_len) 
	{
		memcpy(ctx->block, data, data_len);
	}
}

/************************************************************************
* 函数功能:处理剩余的一组不足512bit的块数据,并输出最终摘要值
* 输入:
*		@*ctx :输入数据
* 输出:
*		@*digest :摘要值
*返回值:NULL
************************************************************************/
void sm3_final(sm3_ctx_t *ctx, unsigned char *digest)
{
	int i;
	uint32_t *pdigest = (uint32_t *)digest;
	uint32_t *count = (uint32_t *)(ctx->block + SM3_BLOCK_SIZE - 8);

	/*****    数据填充       **********/
	//首先在数据末尾填充“1”
	ctx->block[ctx->num] = 0x80;

	//进行“0”填充,根据剩余需要填充数据的长度是否有64bit的空间来决定填充“0”的个数
	if (ctx->num + 9 <= SM3_BLOCK_SIZE) 
	{
		memset(ctx->block + ctx->num + 1, 0, SM3_BLOCK_SIZE - ctx->num - 9);
	} 
	else 
	{
		memset(ctx->block + ctx->num + 1, 0, SM3_BLOCK_SIZE - ctx->num - 1);
		sm3_compress(ctx->digest, ctx->block);
		memset(ctx->block, 0, SM3_BLOCK_SIZE - 8);
	}

	//最后64bit填充数据长度的二进制表示(word型数据需要以大端进行存储)
	count[0] = cpu_to_be32((ctx->nblocks) >> 23);
	count[1] = Lendian_2_Bendian(cpu_to_be32((ctx->nblocks << 9) + (ctx->num << 3)));//本系统用小端模式需要转换

	sm3_compress(ctx->digest, ctx->block);
	
	for (i = 0; i < sizeof(ctx->digest)/sizeof(ctx->digest[0]); i++) 
	{
		pdigest[i] =Lendian_2_Bendian(cpu_to_be32(ctx->digest[i]));
	}
}

#define ROTATELEFT(X,n)  (((X)<<(n)) | ((X)>>(32-(n))))

#define P0(x) ((x) ^  ROTATELEFT((x),9)  ^ ROTATELEFT((x),17))
#define P1(x) ((x) ^  ROTATELEFT((x),15) ^ ROTATELEFT((x),23))

#define FF0(x,y,z) ( (x) ^ (y) ^ (z))
#define FF1(x,y,z) (((x) & (y)) | ( (x) & (z)) | ( (y) & (z)))

#define GG0(x,y,z) ( (x) ^ (y) ^ (z))
#define GG1(x,y,z) (((x) & (y)) | ( (~(x)) & (z)) )



/************************************************************************
* 函数功能:压缩函数CF
* 输入:
*		@*digest :256bit初始数据(IV)
*		@*block :经过填充后的数据(512bit对齐)
* 输出:
*		@*digest :迭代压缩结果
*返回值:NULL
************************************************************************/
void sm3_compress(uint32_t digest[8], const unsigned char block[64])
{
	int j;
	uint32_t W[68], W1[64];
	const uint32_t *pblock = (const uint32_t *)block;

	uint32_t A = digest[0];
	uint32_t B = digest[1];
	uint32_t C = digest[2];
	uint32_t D = digest[3];
	uint32_t E = digest[4];
	uint32_t F = digest[5];
	uint32_t G = digest[6];
	uint32_t H = digest[7];
	uint32_t SS1,SS2,TT1,TT2,T[64];

	/*****	  消息扩展		 *******/
	//W0 W1...W67
	for(j = 0; j < 16; j++) 
	{
		//word数据以大端存储,后续计算基于该组数据,无需在进行大小端转换
		W[j] = Lendian_2_Bendian(cpu_to_be32(pblock[j]));
	}
	
	for(j = 16; j < 68; j++) 
	{
		W[j] = P1( W[j-16] ^ W[j-9] ^ ROTATELEFT(W[j-3],15)) ^ ROTATELEFT(W[j - 13],7 ) ^ W[j-6];
	}

	//W'0 W'1 ... W'63
	for( j = 0; j < 64; j++) 
	{
		W1[j] = W[j] ^ W[j+4];
	}

	//压缩函数
	for(j =0; j < 16; j++) {

		T[j] = 0x79CC4519;
		SS1 = ROTATELEFT((ROTATELEFT(A,12) + E + ROTATELEFT(T[j],j)), 7);
		SS2 = SS1 ^ ROTATELEFT(A,12);
		TT1 = FF0(A,B,C) + D + SS2 + W1[j];
		TT2 = GG0(E,F,G) + H + SS1 + W[j];
		D = C;
		C = ROTATELEFT(B,9);
		B = A;
		A = TT1;
		H = G;
		G = ROTATELEFT(F,19);
		F = E;
		E = P0(TT2);
	}

	for(j =16; j < 64; j++) {

		T[j] = 0x7A879D8A;
		SS1 = ROTATELEFT((ROTATELEFT(A,12) + E + ROTATELEFT(T[j],j)), 7);
		SS2 = SS1 ^ ROTATELEFT(A,12);
		TT1 = FF1(A,B,C) + D + SS2 + W1[j];
		TT2 = GG1(E,F,G) + H + SS1 + W[j];
		D = C;
		C = ROTATELEFT(B,9);
		B = A;
		A = TT1;
		H = G;
		G = ROTATELEFT(F,19);
		F = E;
		E = P0(TT2);
	}

	digest[0] ^= A;
	digest[1] ^= B;
	digest[2] ^= C;
	digest[3] ^= D;
	digest[4] ^= E;
	digest[5] ^= F;
	digest[6] ^= G;
	digest[7] ^= H;
}


/************************************************************************
* 函数功能:sm3接口函数
* 输入:
*		@*msg :输入消息
*		@*msglen :消息长度
* 输出:
*		@*dgst :摘要值(256bit对齐)
*返回值:NULL
************************************************************************/
void sm3(const unsigned char *msg, size_t msglen,
	unsigned char dgst[SM3_DIGEST_LENGTH])
{
	sm3_ctx_t ctx;

	sm3_init(&ctx);
	sm3_update(&ctx, msg, msglen);
	sm3_final(&ctx, dgst);

	memset(&ctx, 0, sizeof(sm3_ctx_t));
}

void main(void)
{
	int i = 0;
	unsigned char msg1[] = "abc";
	unsigned char msg[] = "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd";
	unsigned char dgst[32] = "";

	printf("\nmassage : %s\n",msg1);
	sm3(msg1,strlen(msg1),dgst);

	printf("\ndigest : ");
	for(i=0; i<sizeof(dgst); i++)
	{
		printf("%02x",dgst[i]);

		if((i+1) % 4 == 0)
		{
			printf(" ");
		}
	}

	printf("\n\n");
	
	printf("\nmassage : %s\n",msg);
	sm3(msg,strlen(msg),dgst);

	printf("\ndigest : ");
	for(i=0; i<sizeof(dgst); i++)
	{
		printf("%02x",dgst[i]);

		if((i+1) % 4 == 0)
		{
			printf(" ");
		}
	}

	printf("\n\n");
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279

测试结果:
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/139605?site
推荐阅读
相关标签
  

闽ICP备14008679号