1 C
2 C++
3 Windows
4 Linux
5 数据库
- 5.1 SQL
- 5.2 Mysql
- 5.3 Oracle
- 5.5 Sqlite
- 5.6 数据库范式
- 5.7 游标
6 数据结构
7 算法
- 7.1 栈和队列
- 7.2 基本排序算法
- 7.3 合并排序
- 7.4 快速排序
- 7.5 优先级队列与堆排序
- 7.6 符号表及其基本实现
- 7.7 深度优先算法 DFS 和广度优先算法 BFS
- 7.8 桶排序
- 7.9 基数排序
8 Qt
9 AS400
10 Web
- 10.2 JavaScript
- 10.3 简述 cookie 和 session 及 token
- 10.4 Https 双向证书认证
- 10.5 URL 详解
12 C
13 框架
14 协议
15 工具
17 QA
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
2.7 SM3
sm3.h
/*
* 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 / 4];
unsigned char messageBlock[64];
} SM3Context;
/*
* SM3计算函数
*/
unsigned char *SM3Calc(const unsigned char *message,
unsigned int messageLen, unsigned char digest[SM3_HASH_SIZE]);
#endif // _SM3_H_
sm3.c
/*
* sm3.c
*/
#include "stdafx.h"
#include <stdio.h>
#include <memory.h>
#include "sm3.h"
/*
* 判断运行环境是否为小端
*/
static const int endianTest = 1;
#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[0];
byte[0] = byte[3];
byte[3] = temp;
temp = byte[1];
byte[1] = byte[2];
byte[2] = temp;
return word;
}
/*
* T
*/
unsigned int T(int i)
{
if (i >= 0 && i <= 15)
return 0x79CC4519;
else if (i >= 16 && i <= 63)
return 0x7A879D8A;
else
return 0;
}
/*
* FF
*/
unsigned int FF(unsigned int X, unsigned int Y, unsigned int Z, int i)
{
if (i >= 0 && i <= 15)
return X ^ Y ^ Z;
else if (i >= 16 && i <= 63)
return (X & Y) | (X & Z) | (Y & Z);
else
return 0;
}
/*
* GG
*/
unsigned int GG(unsigned int X, unsigned int Y, unsigned int Z, int i)
{
if (i >= 0 && i <= 15)
return X ^ Y ^ Z;
else if (i >= 16 && i <= 63)
return (X & Y) | (~X & Z);
else
return 0;
}
/*
* P0
*/
unsigned int P0(unsigned int X)
{
return X ^ LeftRotate(X, 9) ^ LeftRotate(X, 17);
}
/*
* P1
*/
unsigned int P1(unsigned int X)
{
return X ^ LeftRotate(X, 15) ^ LeftRotate(X, 23);
}
/*
* 初始化函数
*/
void SM3Init(SM3Context *context)
{
context->intermediateHash[0] = 0x7380166F;
context->intermediateHash[1] = 0x4914B2B9;
context->intermediateHash[2] = 0x172442D7;
context->intermediateHash[3] = 0xDA8A0600;
context->intermediateHash[4] = 0xA96F30BC;
context->intermediateHash[5] = 0x163138AA;
context->intermediateHash[6] = 0xE38DEE4D;
context->intermediateHash[7] = 0xB0FB0E4E;
}
/*
* 处理消息块
*/
void SM3ProcessMessageBlock(SM3Context *context)
{
int i;
unsigned int W[68];
unsigned int W_[64];
unsigned int A, B, C, D, E, F, G, H, SS1, SS2, TT1, TT2;
/* 消息扩展 */
for (i = 0; i < 16; i++)
{
W[i] = *(unsigned int *)(context->messageBlock + i * 4);
if (IsLittleEndian())
ReverseWord(W + i);
//printf("%d: %x\n", i, W[i]);
}
for (i = 16; i < 68; i++)
{
W[i] = P1(W[i - 16] ^ W[i - 9] ^ LeftRotate(W[i - 3], 15))
^ LeftRotate(W[i - 13], 7)
^ W[i - 6];
//printf("%d: %x\n", i, W[i]);
}
for (i = 0; i < 64; i++)
{
W_[i] = W[i] ^ W[i + 4];
//printf("%d: %x\n", i, W_[i]);
}
/* 消息压缩 */
A = context->intermediateHash[0];
B = context->intermediateHash[1];
C = context->intermediateHash[2];
D = context->intermediateHash[3];
E = context->intermediateHash[4];
F = context->intermediateHash[5];
G = context->intermediateHash[6];
H = context->intermediateHash[7];
for (i = 0; i < 64; i++)
{
SS1 = LeftRotate((LeftRotate(A, 12) + E + LeftRotate(T(i), i)), 7);
SS2 = SS1 ^ LeftRotate(A, 12);
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, 9);
B = A;
A = TT1;
H = G;
G = LeftRotate(F, 19);
F = E;
E = P0(TT2);
}
context->intermediateHash[0] ^= A;
context->intermediateHash[1] ^= B;
context->intermediateHash[2] ^= C;
context->intermediateHash[3] ^= D;
context->intermediateHash[4] ^= E;
context->intermediateHash[5] ^= F;
context->intermediateHash[6] ^= G;
context->intermediateHash[7] ^= 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 = 0; i < messageLen / 64; i++)
{
memcpy(context.messageBlock, message + i * 64, 64);
SM3ProcessMessageBlock(&context);
}
/* 填充消息分组,并处理 */
bitLen = messageLen * 8;
if (IsLittleEndian())
ReverseWord(&bitLen);
remainder = messageLen % 64;
memcpy(context.messageBlock, message + i * 64, remainder);
context.messageBlock[remainder] = 0x80;
if (remainder <= 55)
{
/* 长度按照大端法占8个字节,该程序只考虑长度在 2**32 - 1(单位:比特)以内的情况,
* 故将高 4 个字节赋为 0 。*/
memset(context.messageBlock + remainder + 1, 0, 64 - remainder - 1 - 8 + 4);
memcpy(context.messageBlock + 64 - 4, &bitLen, 4);
SM3ProcessMessageBlock(&context);
}
else
{
memset(context.messageBlock + remainder + 1, 0, 64 - remainder - 1);
SM3ProcessMessageBlock(&context);
/* 长度按照大端法占8个字节,该程序只考虑长度在 2**32 - 1(单位:比特)以内的情况,
* 故将高 4 个字节赋为 0 。*/
memset(context.messageBlock, 0, 64 - 4);
memcpy(context.messageBlock + 64 - 4, &bitLen, 4);
SM3ProcessMessageBlock(&context);
}
/* 返回结果 */
if (IsLittleEndian())
for (i = 0; i < 8; i++)
ReverseWord(context.intermediateHash + i);
memcpy(digest, context.intermediateHash, SM3_HASH_SIZE);
return digest;
}
sm3Test.cpp
// sm3Test.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <string.h>
#include <stdio.h>
#include "sm3.h"
#include <iostream>
//#pragma comment(lib,"sm3dll2")
//extern "C" void SM3Call(const unsigned char *message,unsigned int messageLen, unsigned char digest[SM3_HASH_SIZE]);
int main( int argc, char *argv[] )
{
unsigned char input[256] = "12345678";
int ilen = 3;
unsigned char output[32];
int i;
// ctx;
printf("Message:\n");
printf("%s\n",input);
SM3Calc(input, 8, output);
printf("Hash:\n ");
for(i=0; i<32; i++)
{
printf("%02x",output[i]);
if (((i+1) % 4 ) == 0) printf(" ");
}
printf("\n");
unsigned char input2[256] = "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd";
int ilen2 = 64;
unsigned char output2[32];
int i2;
// ctx;
printf("Message:\n");
printf("%s\n", input2);
SM3Calc(input2, ilen2, output2);
printf("Hash:\n ");
for (i2 = 0; i2<32; i2++)
{
printf("%02x", output2[i2]);
if (((i2 + 1) % 4) == 0) printf(" ");
}
printf("\n");
system("pause");
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论