SM3算法
- /*
- * sm3.h
- *
- * 为使此算法兼容32位、64位下Linux或Windows系统,
- * 选择 int 来表示 32 位整数。
- * 消息长度最大限定为 2**32 - 1(单位:比特),
- * 且为 8 的倍数(消息的最小单元为字节)。
- */
- #ifndef _SM3_H_
- #define _SM3_H_
- /*
- * SM3算法产生的哈希值大小(单位:字节)
- */
- #define SM3_HASH_SIZE 32
- /*
- * SM3上下文
- */
- typedef struct SM3Context
- {
- unsigned int intermediateHash[SM3_HASH_SIZE / ];
- unsigned char messageBlock[];
- } SM3Context;
- /*
- * SM3计算函数
- */
- unsigned char *SM3Calc(const unsigned char *message,
- unsigned int messageLen, unsigned char digest[SM3_HASH_SIZE]);
- #endif // _SM3_H_
- /*
- * sm3.c
- */
- #include <stdio.h>
- #include <memory.h>
- #include "sm3.h"
- /*
- * 判断运行环境是否为小端
- */
- static const int endianTest = ;
- #define IsLittleEndian() (*(char *)&endianTest == 1)
- /*
- * 向左循环移位
- */
- #define LeftRotate(word, bits) ( (word) << (bits) | (word) >> (32 - (bits)) )
- /*
- * 反转四字节整型字节序
- */
- unsigned int *ReverseWord(unsigned int *word)
- {
- unsigned char *byte, temp;
- byte = (unsigned char *)word;
- temp = byte[];
- byte[] = byte[];
- byte[] = temp;
- temp = byte[];
- byte[] = byte[];
- byte[] = temp;
- return word;
- }
- /*
- * T
- */
- unsigned int T(int i)
- {
- if (i >= && i <= )
- return 0x79CC4519;
- else if (i >= && i <= )
- return 0x7A879D8A;
- else
- return ;
- }
- /*
- * FF
- */
- unsigned int FF(unsigned int X, unsigned int Y, unsigned int Z, int i)
- {
- if (i >= && i <= )
- return X ^ Y ^ Z;
- else if (i >= && i <= )
- return (X & Y) | (X & Z) | (Y & Z);
- else
- return ;
- }
- /*
- * GG
- */
- unsigned int GG(unsigned int X, unsigned int Y, unsigned int Z, int i)
- {
- if (i >= && i <= )
- return X ^ Y ^ Z;
- else if (i >= && i <= )
- return (X & Y) | (~X & Z);
- else
- return ;
- }
- /*
- * P0
- */
- unsigned int P0(unsigned int X)
- {
- return X ^ LeftRotate(X, ) ^ LeftRotate(X, );
- }
- /*
- * P1
- */
- unsigned int P1(unsigned int X)
- {
- return X ^ LeftRotate(X, ) ^ LeftRotate(X, );
- }
- /*
- * 初始化函数
- */
- void SM3Init(SM3Context *context)
- {
- context->intermediateHash[] = 0x7380166F;
- context->intermediateHash[] = 0x4914B2B9;
- context->intermediateHash[] = 0x172442D7;
- context->intermediateHash[] = 0xDA8A0600;
- context->intermediateHash[] = 0xA96F30BC;
- context->intermediateHash[] = 0x163138AA;
- context->intermediateHash[] = 0xE38DEE4D;
- context->intermediateHash[] = 0xB0FB0E4E;
- }
- /*
- * 处理消息块
- */
- void SM3ProcessMessageBlock(SM3Context *context)
- {
- int i;
- unsigned int W[];
- unsigned int W_[];
- unsigned int A, B, C, D, E, F, G, H, SS1, SS2, TT1, TT2;
- /* 消息扩展 */
- for (i = ; i < ; i++)
- {
- W[i] = *(unsigned int *)(context->messageBlock + i * );
- if (IsLittleEndian())
- ReverseWord(W + i);
- //printf("%d: %x\n", i, W[i]);
- }
- for (i = ; i < ; i++)
- {
- W[i] = P1(W[i - ] ^ W[i - ] ^ LeftRotate(W[i - ], ))
- ^ LeftRotate(W[i - ], )
- ^ W[i - ];
- //printf("%d: %x\n", i, W[i]);
- }
- for (i = ; i < ; i++)
- {
- W_[i] = W[i] ^ W[i + ];
- //printf("%d: %x\n", i, W_[i]);
- }
- /* 消息压缩 */
- A = context->intermediateHash[];
- B = context->intermediateHash[];
- C = context->intermediateHash[];
- D = context->intermediateHash[];
- E = context->intermediateHash[];
- F = context->intermediateHash[];
- G = context->intermediateHash[];
- H = context->intermediateHash[];
- for (i = ; i < ; i++)
- {
- SS1 = LeftRotate((LeftRotate(A, ) + E + LeftRotate(T(i), i)), );
- SS2 = SS1 ^ LeftRotate(A, );
- TT1 = FF(A, B, C, i) + D + SS2 + W_[i];
- TT2 = GG(E, F, G, i) + H + SS1 + W[i];
- D = C;
- C = LeftRotate(B, );
- B = A;
- A = TT1;
- H = G;
- G = LeftRotate(F, );
- F = E;
- E = P0(TT2);
- }
- context->intermediateHash[] ^= A;
- context->intermediateHash[] ^= B;
- context->intermediateHash[] ^= C;
- context->intermediateHash[] ^= D;
- context->intermediateHash[] ^= E;
- context->intermediateHash[] ^= F;
- context->intermediateHash[] ^= G;
- context->intermediateHash[] ^= H;
- }
- /*
- * SM3算法主函数
- */
- unsigned char *SM3Calc(const unsigned char *message,
- unsigned int messageLen, unsigned char digest[SM3_HASH_SIZE])
- {
- SM3Context context;
- unsigned int i, remainder, bitLen;
- /* 初始化上下文 */
- SM3Init(&context);
- /* 对前面的消息分组进行处理 */
- for (i = ; i < messageLen / ; i++)
- {
- memcpy(context.messageBlock, message + i * , );
- SM3ProcessMessageBlock(&context);
- }
- /* 填充消息分组,并处理 */
- bitLen = messageLen * ;
- if (IsLittleEndian())
- ReverseWord(&bitLen);
- remainder = messageLen % ;
- memcpy(context.messageBlock, message + i * , remainder);
- context.messageBlock[remainder] = 0x80;
- if (remainder <= )
- {
- /* 长度按照大端法占8个字节,该程序只考虑长度在 2**32 - 1(单位:比特)以内的情况,
- * 故将高 4 个字节赋为 0 。*/
- memset(context.messageBlock + remainder + , , - remainder - - + );
- memcpy(context.messageBlock + - , &bitLen, );
- SM3ProcessMessageBlock(&context);
- }
- else
- {
- memset(context.messageBlock + remainder + , , - remainder - );
- SM3ProcessMessageBlock(&context);
- /* 长度按照大端法占8个字节,该程序只考虑长度在 2**32 - 1(单位:比特)以内的情况,
- * 故将高 4 个字节赋为 0 。*/
- memset(context.messageBlock, , - );
- memcpy(context.messageBlock + - , &bitLen, );
- SM3ProcessMessageBlock(&context);
- }
- /* 返回结果 */
- if (IsLittleEndian())
- for (i = ; i < ; i++)
- ReverseWord(context.intermediateHash + i);
- memcpy(digest, context.intermediateHash, SM3_HASH_SIZE);
- return digest;
- }
SM3算法的更多相关文章
- 国密SM3算法在linux和windows平台结果不一致问题
什么是sm3,是一种类似于sha256的哈希算法,是咱们国家的哈希标准算法: 最近在使用sm3算法时,同样的一份数据,调用同样的sm3接口,发现得到的结果是不一样的: 那么在应用过的过程中,如果同样的 ...
- sm3算法的简单介绍
转自:https://blog.csdn.net/hugewaves/article/details/53765063 SM3算法也是一种哈希算法,中国国家密码管理局在2010年发布,其名称是SM3密 ...
- 关于国密算法 SM1,SM2,SM3,SM4 的笔记
国密即国家密码局认定的国产密码算法.主要有SM1,SM2,SM3,SM4.密钥长度和分组长度均为128位. SM1 为对称加密.其加密强度与AES相当.该算法不公开,调用该算法时,需要通过加密芯片的接 ...
- 毕业设计预习:SM3密码杂凑算法基础学习
SM3密码杂凑算法基础学习 术语与定义 1 比特串bit string 由0和1组成的二进制数字序列. 2 大端big-endian 数据在内存中的一种表示格式,规定左边为高有效位,右边为低有效位.数 ...
- 源代码方式向openssl中加入新算法完整具体步骤(演示样例:摘要算法SM3)【非engine方式】
openssl简单介绍 openssl是一个功能丰富且自包括的开源安全工具箱.它提供的主要功能有:SSL协议实现(包括SSLv2.SSLv3和TLSv1).大量软算法(对称/非对称/摘要).大数运算. ...
- AES SHA-1 SM3 MD5
AES是美国国家标准技术研究所NIST旨在代替DES的21世纪的加密标准. 输入:128bit 的消息分组 输出:128bit 的密文分组 密钥长度及圈数 128 10 192 12 256 14 消 ...
- 《基于Arm实验箱的国密算法应用》课程设计 结题报告
<基于Arm实验箱的国密算法应用>课程设计 结题报告 小组成员姓名:20155206赵飞 20155220吴思其 20155234昝昕明 指导教师:娄嘉鹏 设计方案 题目要求:基于Arm实 ...
- java sm3加密算法
java sm3加密算法实现 CreationTime--2018年7月13日09点28分 Author:Marydon 1.准备工作 所需jar包: bcprov-jdk15on-1.59.ja ...
- Java国密相关算法(bouncycastle)
公用类算法: PCIKeyPair.java /** * @Author: dzy * @Date: 2018/9/27 14:18 * @Describe: 公私钥对 */ @Data @AllAr ...
随机推荐
- typescript 接口的新认识
interface 用于接收服务器的数据. eg: interface mmmmm { x: string, y: number, z: number, select: KnockoutObserva ...
- mysql日期函数 和sql语句扩展information_schema show processlist;
SELECT NOW(); SELECT CURDATE(); SELECT YEAR(NOW()) SELECT CONCAT("mysqldump ","-uroot ...
- Web前端都学点儿啥?
Web开发如今是如日中天,热的发烫.但是Web开发相关的技术和知识却像N座大山一样,耸立在我们面前,连绵起伏,漫无边际.那么这些山头那些我们应该占领,那些我们应该绕开,很多人看着就蒙了,这不光是初学者 ...
- POJ3694-Network(Tarjan缩点+LCA)
题目链接 题意:给你一个连通图.然后再给你n个询问,每一个询问给一个点u,v表示加上u,v之后又多少个桥. 思路:用Tarjan缩点后,形成一棵树,所以树边都是桥了.然后增加边以后,查询LCA,LCA ...
- JAVA中BufferedReader设置编码的必要性
实验环境 Myeclipse 默认编码 UTF-8 先看两种读文件的方式: 方式一: InputStreamReader fReader = new InputStreamReader(new Fil ...
- 怎样在asp.net中用一般处理文件ashx实现下载功能
/// <summary> /// 下载文件,支持大文件.续传.速度限制.支持续传的响应头Accept-Ranges.ETag,请求头Range . /// Accept-Ranges:响 ...
- hdu 4681(枚举+dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4681 思路:首先预处理出串C在A,B中的所有的位置,然后从前向后求一次最长公共子序列,从后向前求一次最 ...
- 【BZOJ1976】[BeiJing2010组队]能量魔方 Cube 最小割
[BZOJ1976][BeiJing2010组队]能量魔方 Cube Description 小C 有一个能量魔方,这个魔方可神奇了,只要按照特定方式,放入不同的 能量水晶,就可以产生巨大的能量. 能 ...
- C语言练习题
C语言练习题 1. 以下选项中,合法的一组C语言数值常量是( ) A)028 .5e-3 .0xf B)12. OXa23 4.5e0 C).177 4e1.5 Oabc D) ...
- Architectural Styles and the Design of Network-based Software Architectures
w Architectural Styles and the Design of Network-based Software Architectures http://www.ics.uci.ed ...