国密SM3的C语言代码C51移植到8051

    SM3杂凑算法是我国自主设计的密码杂凑算法

    SM3是中华人民共和国政府采用的一种密码散列函数标准,由国家密码管理局于2010年12月17日发布。相关标准为“GM/T 0004-2012 《SM3密码杂凑算法》”。

    在商用密码体系中,SM3主要用于数字签名及验证、消息认证码生成及验证、随机数生成等,其算法公开。据国家密码管理局表示,其安全性及效率与SHA-256相当。

完整源码下载地址:https://download.csdn.net/download/guoggn/18439171

 一、 处理过程

1、分组

   512bit为一组,

2、填充

  不够512bit进行填充,假设消息m 的长度为l 比特。首先将比特“ 1”添加到消息的末尾,再添加k 个“ 0”, k是满
足l + 1 + k ≡ 448mod512 的最小的非负整数。然后再添加一个64位比特串,该比特串是长度l的二进
制表示。填充后的消息m′ 的比特长度为512的倍数

3、消息扩展

4、迭代压缩

二、c51代码

 

/* 压缩函数 */
void CF(u8 *arr)
{
	u32 j;
	u32 A, B, C, D, E, F, G, H;
	u32 SS1, SS2, TT1, TT2;
	
#ifdef _DEBUG
	printf("message = \n");
	for (j = 0; j < 64; j++)
		printf("%b02x", arr[j]);
	printf("\n\n");
#endif
	
		/* 消息扩展 */
	for (j = 0; j < 16; j++)
	{
		W[j] = (u32)arr[j * 4 + 0] << 24 | (u32)arr[j * 4 + 1] << 16 | (u32)arr[j * 4 + 2] << 8 | (u32)arr[j * 4 + 3];
	}
	for (j = 16; j < 68; j++)
	{
		W[j] = P_1(W[j - 16] ^ W[j - 9] ^ (rotate_left(W[j - 3], 15))) ^ (rotate_left(W[j - 13], 7)) ^ W[j - 6];
	}
#ifdef _DEBUG
	printf("W[] = \n");
	for (j = 0; j < 68; j++)
		printf("%l08x, ", W[j]);
	printf("\n\n");
#endif
	for (j = 0; j < 64; j++)
	{
		W_1[j] = W[j] ^ W[j + 4];
	}
#ifdef _DEBUG
	printf("W_1[] = \n");
	for (j = 0; j < 64; j++)
		printf("%l08x, ", W_1[j]);
	printf("\n\n");
#endif
	
		/* 消息压缩 */
	A = hash[0];
	B = hash[1];
	C = hash[2];
	D = hash[3];
	E = hash[4];
	F = hash[5];
	G = hash[6];
	H = hash[7];
	
	for (j = 0; j < 64; j++)
	{
		#ifdef _DEBUG
		printf("A_[%l02d]  = %l08x, %l08x, %l08x, %l08x, %l08x, %l08x, %l08x, %l08x \n", j, A,B,C,D,E,F,G,H);
		#endif
		
		SS1 = rotate_left((rotate_left(A, 12)) + E + (rotate_left(T[j], j)), 7);
		SS2 = SS1 ^ (rotate_left(A, 12));
		TT1 = FF(A, B, C, j) + D + SS2 + W_1[j];
		TT2 = GG(E, F, G, j) + H + SS1 + W[j];
		D = C;
		C = rotate_left(B, 9);
		B = A;
		A = TT1;
		H = G;
		G = rotate_left(F, 19);
		F = E;
		E = P_0(TT2);
	}
#ifdef _DEBUG
		printf("A_[%l02d]  = %l08x, %l08x, %l08x, %l08x, %l08x, %l08x, %l08x, %l08x \n", j, A,B,C,D,E,F,G,H);
#endif
	
	hash[0] = (A ^ hash[0]);
	hash[1] = (B ^ hash[1]);
	hash[2] = (C ^ hash[2]);
	hash[3] = (D ^ hash[3]);
	hash[4] = (E ^ hash[4]);
	hash[5] = (F ^ hash[5]);
	hash[6] = (G ^ hash[6]);
	hash[7] = (H ^ hash[7]);
}

 

void SM3(u8 *msg, u32 msglen, u8 *out_hash)
{
	u32 i, bitLen, remainder;
	
		/* 初始化上下文 */
	SM3_Init();

		/* 消息分组处理 */
	for(i = 0; i < msglen/64; i++){
		memcpy(message_buffer, msg + i * 64, 64);
		CF(message_buffer);
	}
	
		/* 分组信息部分不够64字节,填充消息,并处理 */
	bitLen  = msglen * 8;
	remainder  = msglen % 64;
	memcpy(message_buffer, msg + i * 64, remainder);
	memset(&message_buffer[remainder], 0, 64 - remainder);	
	message_buffer[remainder] = 0x80;
	
		/* 信息部分小于55字节,填充部分大于8字节 */
	if(remainder <= 55)
	{
		/* 长度按照大端法占8个字节,消息块为64字节,故填充的长度高 4 个字节恒为 0 */
		memcpy(message_buffer + 60, &bitLen, 4);
		CF(message_buffer);
	}
		/* 信息部分大于55字节,填充部分不够8字节 ,将长度串放入下一分组进行压缩*/
	else
	{
		CF(message_buffer);
		memset(message_buffer, 0, 64);
		memcpy(message_buffer + 60, &bitLen, 4);
		CF(message_buffer);
	}
	
		/* 返回结果 */
		memcpy(out_hash, hash, 32);

#ifdef _DEBUG	
		printf("hash[] = \n");
		for (i = 0; i < 32; i++)
			printf("%b02x", out_hash[i]);
		printf("\n");
#endif	
}
void sm3test(void)
{
	s32 i,len;
	u8 Hash[32]={0};
	s8 str[]="abc";
	//66c7f0f4 62eeedd9 d1f2d46b dc10e4e2 4167c487 5cf2f7a2 297da02b 8f4ba8e0
	s8 str2[] = "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd";
	//debe9ff9 2275b8a1 38604889 c18e5a4d 6fdb70e5 387e5765 293dcba3 9c0c5732
	
	
	printf("in = \"%s\"\r\n",str);
	len=strlen(str);
	SM3(str, len, Hash);	
	printf("out = ");
	for (i = 0; i < 32; i++)
		printf("%b02x", Hash[i]);
	printf("\n\n");	
	
	printf("in = \"%s\"\r\n",str2);
	len=strlen(str2);
	SM3(str2, len, Hash);
	printf("out = ");
	for (i = 0; i < 32; i++)
		printf("%b02x", Hash[i]);
	printf("\n");

}

下载全部源码

https://download.csdn.net/download/guoggn/18439171

参考

https://blog.csdn.net/a344288106/article/details/80094878?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1

https://blog.csdn.net/weixin_48203710/article/details/106409587

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值