首页 > 代码库 > sequence.c
sequence.c
/* * sequence.c */#include <stdio.h>#include <memory.h>/* * SM3算法产生的哈希值大小(单位:字节) */#define SM3_HASH_SIZE 32 /* * SM3上下文 */typedef struct SM3Context{ unsigned int intermediateHash[SM3_HASH_SIZE / 4]; unsigned char messageBlock[64];} SM3Context;/* * 判断运行环境是否为小端 */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) { 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); 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;}/* * 计算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 = 0, s = 0; i < SM3_HASH_SIZE; i += 4) { s += digest[i + 0] << 24 | digest[i + 1] << 16 | digest[i + 2] << 8 | digest[i + 3] << 0; } return s;}int main(void){ printf("%x\n", SM3CalcAndReturnUInt("\x1\x2\x3\x4\x5\x6", strlen("\x1\x2\x3\x4\x5\x6"))); return 0;}
sequence.c
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。