/*
* sequence.c
*/
#include <stdio.h>
#include <memory.h> /*
* SM3算法产生的哈希值大小(单位:字节)
*/
#define SM3_HASH_SIZE 32 /*
* SM3上下文
*/
typedef struct SM3Context
{
unsigned int intermediateHash[SM3_HASH_SIZE / ];
unsigned char messageBlock[];
} SM3Context; /*
* 判断运行环境是否为小端
*/
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 <= )
{
memset(context.messageBlock + remainder + , , - remainder - - + );
memcpy(context.messageBlock + - , &bitLen, );
SM3ProcessMessageBlock(&context);
}
else
{
memset(context.messageBlock + remainder + , , - remainder - );
SM3ProcessMessageBlock(&context);
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,并将结果以无符号整数形式返回
*/
unsigned int SM3CalcAndReturnUInt(const unsigned char *message, unsigned int messageLen)
{
int i;
unsigned int s;
unsigned char digest[SM3_HASH_SIZE]; SM3Calc(message, messageLen, digest);
for (i = , s = ; i < SM3_HASH_SIZE; i += )
{
s += digest[i + ] << |
digest[i + ] << |
digest[i + ] << |
digest[i + ] << ;
} return s;
} int main(void)
{
printf("%x\n", SM3CalcAndReturnUInt("\x1\x2\x3\x4\x5\x6", strlen("\x1\x2\x3\x4\x5\x6")));
return ;
}

sequence.c的更多相关文章

  1. oracle SEQUENCE 创建, 修改,删除

    oracle创建序列化: CREATE SEQUENCE seq_itv_collection            INCREMENT BY 1  -- 每次加几个              STA ...

  2. Oracle数据库自动备份SQL文本:Procedure存储过程,View视图,Function函数,Trigger触发器,Sequence序列号等

    功能:备份存储过程,视图,函数触发器,Sequence序列号等准备工作:--1.创建文件夹 :'E:/OracleBackUp/ProcBack';--文本存放的路径--2.执行:create or ...

  3. DG gap sequence修复一例

    环境:Oracle 11.2.0.4 DG 故障现象: 客户在备库告警日志中发现GAP sequence提示信息: Mon Nov 21 09:53:29 2016 Media Recovery Wa ...

  4. Permutation Sequence

    The set [1,2,3,-,n] contains a total of n! unique permutations. By listing and labeling all of the p ...

  5. [LeetCode] Sequence Reconstruction 序列重建

    Check whether the original sequence org can be uniquely reconstructed from the sequences in seqs. Th ...

  6. [LeetCode] Binary Tree Longest Consecutive Sequence 二叉树最长连续序列

    Given a binary tree, find the length of the longest consecutive sequence path. The path refers to an ...

  7. [LeetCode] Verify Preorder Sequence in Binary Search Tree 验证二叉搜索树的先序序列

    Given an array of numbers, verify whether it is the correct preorder traversal sequence of a binary ...

  8. [LeetCode] Longest Consecutive Sequence 求最长连续序列

    Given an unsorted array of integers, find the length of the longest consecutive elements sequence. F ...

  9. [LeetCode] Permutation Sequence 序列排序

    The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and labeling all of the p ...

  10. Leetcode 60. Permutation Sequence

    The set [1,2,3,-,n] contains a total of n! unique permutations. By listing and labeling all of the p ...

随机推荐

  1. iOS 学习笔记六 【APP中的文字和APP名字的国际化多语言处理】

    今天为新手解决下APP中的文字和APP名字的国际化多语言处理, 不多说了,直接上步骤: 1.打开你的项目,单机project名字,选中project,直接看图吧: 2.创建Localizable.st ...

  2. Qt5 CMake cross compile

    cmake_minimum_required(VERSION 2.8) if (${ARM}) set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCES ...

  3. django 类通用视图详解

    view() :     该类为所有类视图的父类,处于最底层,仅仅只对请求参数做校验后,给特定请求方法做特定调用. 用法: url中定位到类方法:Aa.as_view() ——> View.as ...

  4. 更改系统环境设置,让alias永远生效

        alias(中文称为“别名”)允许使用更加简短的名称来重新定义 Linux 中的 Shell 命令,从而简化命令行的输入.如果经常与 CLI 打交道,那么使用 alias 不仅会节省时间,而且 ...

  5. go的sync.Map

    sync.Map这个数据结构是线程安全的(基本类型Map结构体在并发读写时会panic严重错误),它填补了Map线程不安全的缺陷,不过最好只在需要的情况下使用.它一般用于并发模型中对同一类map结构体 ...

  6. js或jquery实现页面打印(局部打印)

    首先定义css样式:  复制代码代码如下: @media print { .noprint { display: none;color:green } }  对于不想打印的内容只用在标签中加上 cla ...

  7. rem的使用方法

    首先写入一下代码 <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" cont ...

  8. 微信 oauth4

    4.最后 4. 使用access_token获取用户信息 请求方法: https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN& ...

  9. Redis 安装成windows服务- 一主二从三哨兵,sentinel安装为Windows服务

    这里只做记录说明 Redis的主从配置网上很多文章,百度一大堆,安装流程应该都可以配置通.我使用的这篇文章 https://blog.csdn.net/u010648555/article/detai ...

  10. ChemDraw破解版真的不大好用

    一直以来都有很多的用户朋友在网上找ChemDraw破解版使用,但是现在厂商清理的厉害,还有国家对知识产权的保护越来越严格,破解版ChemDraw越来越难找了.大家与其花那么多的时候找破解版的,不如买个 ...