SM2算法
更新时间:2024-05-19 12:24:01 阅读量: 综合文库 文档下载
- 世界杯推荐度:
- 相关推荐
SM2算法实现
说明:
1、 纯源码无库实现,编译环境:VC++ 6,建立控制台程序把程序文件加入编译即可
2、 源码文件包括:main.cpp,SM2.cpp,HashSM3.cpp,Random.cpp,VLONG.cpp
头文件: AlgDump.h,AlgUtil.h,SM2.h,cfg_w32.h,cos_type.h,CryptoErr.h,HashSM3.h,Random.h,TypeDef.h,UniError.h,VLONG.h
3、 算法实现功能:
1)、SM2加密 2)、SM2解密 3)、SM2签名 4)、SM2验签
下载后如果有使用问题联系QQ: 1900109344
源码 SM2算法例程(main.cpp,SM2.cpp,HashSM3.cpp,Random.cpp,VLONG.cpp,AlgDump.h,AlgUtil.h,SM2.h,cfg_w32.h,cos_type.h,CryptoErr.h,HashSM3.h,Random.h,TypeDef.h,UniError.h,VLONG.h)
Main.cpp
#include
#define ECC_BITS 256
#define ECC_DATA_BYTES VL_DATA_BYTES(ECC_BITS)
#if ECC_BITS > ECC_DATA_BITS_MAX #error #endif
void PrintError( DWORD ErrCode ) { }
extern \ mem_xor( void *dst, const void *src1, const void *src2, int nBytes ) {
PBYTE pDst = (PBYTE) dst; PCBYTE pSrc1 = (PCBYTE) src1; PCBYTE pSrc2 = (PCBYTE) src2;
while( nBytes-- )
*pDst++ = (*pSrc1++) ^ (*pSrc2++); }
extern \ memchk( void *pBuff, int bByte, int nSize ) {
int i;
PCBYTE pByte = (PCBYTE) pBuff;
for( i = 0; i < nSize; i++, pByte++ ) {
if( *pByte != bByte ) return 0; // false }
return 1; // true }
extern \ HEX_VAL( int c ) {
if( c >= '0' && c <= '9' ) return (c-'0');
if( c >= 'a' && c <= 'f' ) return (c-'a'+10);
if( c >= 'A' && c <= 'F' ) return (c-'A'+10); return -1; }
#define IS_HEX(c) ( ((c)>='0'&&(c)<='9') || ((c)>='a'&&(c)<='f') || ((c)>='A'&&(c)<='F') )
extern \ LoadHex( unsigned char *abBuf, const char *szHex ) {
unsigned char c, v; unsigned long n;
for( n = 0; *szHex != '\\0'; ) { do
{ c = *szHex++; } while( c == ' ' );
if( c == '\\0' || !IS_HEX(c) ) break;
v = HEX_VAL(c) << 4; do
{ c = *szHex++; } while( c == ' ' ); if( IS_HEX(c) )
v |= HEX_VAL(c); abBuf[n++] = v;
if( c == '\\'0' || !IS_HEX(c) )
break; }
return n; }
extern \ memswap( void *ptr, int nBytes ) {
PBYTE pBuf = (PBYTE) ptr; BYTE bTmp; int i;
for( i=0; i bTmp = pBuf[i]; pBuf[i] = pBuf[nBytes-1-i]; pBuf[nBytes-1-i] = bTmp; } } void main( void ) { ECC_PUB_KEY PubKey; ECC_PRV_KEY PrvKey; BYTE abPlain[ECC_PLAIN_BYTES_MAX]; BYTE abCipher[ECC_CIPHER_SIZE(ECC_BITS,ECC_PLAIN_BYTES_MAX)]; BYTE abDecrypted[ECC_PLAIN_BYTES_MAX]; DWORD dwCipherSize, dwDecryptSize; BYTE Za[SM3_DIGESTSIZE]; BYTE E[SM3_DIGESTSIZE]; ECC_SIGN sign; ECC_CNTX cntx; DWORD ErrCode; ECC_Init( &cntx, ECC_BITS ); printf( \ ECC_KeyGenerate( &cntx, &PrvKey, &PubKey ); printf( \ ErrCode = ECC_CheckPubKey( &cntx, &PubKey ); PrintError( ErrCode ); if( ErrCode != ERR_OK ) return; printf( \ RAND_FillRandom( abPlain, sizeof(abPlain) ); memset( abCipher, 0x00, sizeof(abCipher) ); printf( \ ErrCode = ECC_Encrypt( &cntx, abPlain, sizeof(abPlain), &PubKey, abCipher, &dwCipherSize ); //SM2 加密 PrintError( ErrCode ); if( ErrCode != ERR_OK ) return; printf( \ ErrCode = ECC_Decrypt( &cntx, abCipher, dwCipherSize, &PrvKey, abDecrypted, &dwDecryptSize ); //SM2 解密 PrintError( ErrCode ); if( ErrCode != ERR_OK ) return; if( dwDecryptSize == sizeof(abPlain) && memcmp( abDecrypted, abPlain, sizeof(abPlain) ) == 0 ) printf( \ CMP: OK \\r\\n\ else { printf( \ CMP: Failed\\r\\n\ return; } printf( \#if 0 RAND_FillRandom( E, SM3_DIGESTSIZE ); #else ErrCode = ECC_GetZA( &cntx, (PCBYTE)\ PrintError( ErrCode ); if( ErrCode != ERR_OK ) return; ErrCode = ECC_GetE( (PCBYTE) \ PrintError( ErrCode ); if( ErrCode != ERR_OK ) return; #endif ErrCode = ECC_Sign( &cntx, E, &PrvKey, &sign ); //SM2签名 PrintError( ErrCode ); if( ErrCode != ERR_OK ) return; printf( \ ErrCode = ECC_Verify( &cntx, E, &PubKey, &sign ); //SM2验签 PrintError( ErrCode ); if( ErrCode != ERR_OK ) return; } Random.cpp #include /****************************************************************************************/ static DWORD gdwRandomSeed = 0; static WORD gwRemainBits = 0; static DWORD gdwRemain; /****************************************************************************************/ DWORD RANDOMAPI PASCAL RAND_GetRandom(void) { #if (DO_NOT_USE_RANDOM!=0) // LQ return 0x4c232797; // 2010.06.24 17:32 #else DWORD dwTemp; if (gdwRandomSeed == 0) { gdwRandomSeed = (DWORD) time(NULL); gwRemainBits = 0; } gdwRandomSeed = (gdwRandomSeed * 10807L) & 0x7fffffffL; if (gwRemainBits == 0) { dwTemp = gdwRandomSeed << 1; gdwRandomSeed = (gdwRandomSeed * 10807L) & 0x7fffffffL; gwRemainBits = 31; } else { dwTemp = gdwRemain; } gwRemainBits --; dwTemp |= gdwRandomSeed >> (gwRemainBits); if (gwRemainBits) gdwRemain = gdwRandomSeed << (32-gwRemainBits); return dwTemp; #endif } void RANDOMAPI RAND_FillRandom( PBYTE pBuff, int nSize ) { // In some embeded system, memory is word aligned. In this case, converting pointer // from PBYTE to PDWORD is dangerous. The following code is modified to use memcpy() // which is safe. -- Liu Qing, 2012.07.18 DWORD dwTemp; while( nSize > 0 ) { dwTemp = RAND_GetRandom(); memcpy( pBuff, &dwTemp, (nSize > sizeof(DWORD)) ? sizeof(DWORD) : nSize ); pBuff += sizeof(DWORD); nSize -= sizeof(DWORD); } } HashSM3.cpp #include // Sample 1 // Input:\ // Output:66c7f0f4 62eeedd9 d1f2d46b dc10e4e2 4167c487 5cf2f7a2 297da02b 8f4ba8e0 // Sample 2 // Input:\ // Outpuf:debe9ff9 2275b8a1 38604889 c18e5a4d 6fdb70e5 387e5765 293dcba3 9c0c5732 #define FF0(x,y,z) ( (x) ^ (y) ^ (z)) #define FF1(x,y,z) (((x) & (y)) | ( (x) & (z)) | ( (y) & (z))) #define GG0(x,y,z) ( (x) ^ (y) ^ (z)) #define GG1(x,y,z) (((x) & (y)) | ( (~(x)) & (z)) ) #define SHL(x,n) (((x) & 0xFFFFFFFF) << (n)) #define ROTL(x,n) (SHL((x),(n)) | ((x) >> (32 - (n)))) #define P0(x) ((x) ^ ROTL((x),9) ^ ROTL((x),17)) #define P1(x) ((x) ^ ROTL((x),15) ^ ROTL((x),23)) static void SM3_UpdateBlock( SM3_CNTX *ctx, const BYTE data[64] ) { unsigned long SS1, SS2, TT1, TT2, W[68], W1[64]; unsigned long A, B, C, D, E, F, G, H; unsigned long T[64]; unsigned long Temp; int j; for(j = 0; j < 16; j++) T[j] = 0x79CC4519; for(j =16; j < 64; j++) T[j] = 0x7A879D8A; for(j = 0; j < 16; j++) W[j] = mfGetDWord( data+4*j ); for(j = 16; j < 68; j++ ) { #if 0 W[j] = P1( W[j-16] ^ W[j-9] ^ ROTL(W[j-3],15) ) ^ ROTL(W[j-13],7 ) ^ W[j-6]; #else Temp = W[j-16] ^ W[j-9] ^ ROTL(W[j-3],15); W[j] = P1(Temp) ^ ROTL(W[j-13], 7) ^ W[j-6]; #endif } for( j = 0; j < 64; j++ ) W1[j] = W[j] ^ W[j+4]; A = ctx->state[0]; B = ctx->state[1]; C = ctx->state[2]; D = ctx->state[3]; E = ctx->state[4]; F = ctx->state[5]; G = ctx->state[6]; H = ctx->state[7]; for( j=0; j<16; j++ ) { SS1 = ROTL((ROTL(A,12) + E + ROTL(T[j],j)), 7); SS2 = SS1 ^ ROTL(A,12); TT1 = FF0(A,B,C) + D + SS2 + W1[j]; TT2 = GG0(E,F,G) + H + SS1 + W[j]; D = C; C = ROTL(B,9); B = A; A = TT1; H = G; G = ROTL(F,19); F = E; E = P0(TT2); } for( j=16; j<64; j++ ) { SS1 = ROTL((ROTL(A,12) + E + ROTL(T[j],j)), 7); SS2 = SS1 ^ ROTL(A,12); TT1 = FF1(A,B,C) + D + SS2 + W1[j]; TT2 = GG1(E,F,G) + H + SS1 + W[j]; D = C; C = ROTL(B,9); B = A; A = TT1; H = G; G = ROTL(F,19); F = E; E = P0(TT2); } ctx->state[0] ^= A; ctx->state[1] ^= B; ctx->state[2] ^= C; ctx->state[3] ^= D; ctx->state[4] ^= E; ctx->state[5] ^= F; ctx->state[6] ^= G; ctx->state[7] ^= H; } //----------------------------------------------------------------------------- // SM3 context setup //----------------------------------------------------------------------------- void SM3_Init( SM3_CNTX *ctx ) { ctx->total[0] = 0; ctx->total[1] = 0; ctx->state[0] = 0x7380166F; ctx->state[1] = 0x4914B2B9; ctx->state[2] = 0x172442D7; ctx->state[3] = 0xDA8A0600; ctx->state[4] = 0xA96F30BC; ctx->state[5] = 0x163138AA; ctx->state[6] = 0xE38DEE4D; ctx->state[7] = 0xB0FB0E4E; } void SM3_Update( SM3_CNTX *ctx, PCBYTE pbInput, DWORD nInpBytes ) { DWORD fill; DWORD left; if( nInpBytes <= 0 ) return; left = ctx->total[0] & 0x3F; fill = 64 - left; ctx->total[0] += nInpBytes; ctx->total[0] &= 0xFFFFFFFF; if( ctx->total[0] < (unsigned long) nInpBytes ) ctx->total[1]++; if( left && nInpBytes >= fill ) { memcpy( ctx->buffer + left, pbInput, fill ); SM3_UpdateBlock( ctx, ctx->buffer ); pbInput += fill; nInpBytes -= fill; left = 0; } while( nInpBytes >= 64 ) { SM3_UpdateBlock( ctx, pbInput ); pbInput += 64; nInpBytes -= 64; } if( nInpBytes > 0 ) { memcpy( ctx->buffer + left, pbInput, nInpBytes ); } } void SM3_Final( SM3_CNTX *ctx, BYTE abDigest[32] ) { unsigned long last, padn; unsigned long high, low; unsigned char abBuf[8]; int i; unsigned char padding[64]; high = ( ctx->total[0] >> 29 ) | ( ctx->total[1] << 3 ); low = ( ctx->total[0] << 3 ); mfPutDWord( abBuf, high ); mfPutDWord( abBuf+4, low ); last = ctx->total[0] & 0x3F; padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); memset( padding, 0, 64 ); padding[0] = 0x80; SM3_Update( ctx, (unsigned char *) padding, padn ); SM3_Update( ctx, abBuf, 8 ); for( i=0; i<8; i++) { mfPutDWord( abDigest + 4*i, ctx->state[i] ); } } void SM3_HashBinary( BYTE abDigest[32], PCBYTE pcData, DWORD nDataBytes ) { SM3_CNTX ctx; SM3_Init( &ctx ); SM3_Update( &ctx, pcData, nDataBytes ); SM3_Final( &ctx, abDigest ); memset( &ctx, 0, sizeof( SM3_CNTX ) ); } VLONG.cpp #include //--------------------------------------------------------------------------------------- // Prime table for small integer //--------------------------------------------------------------------------------------- static const WORD gawPrimeTable[] = { 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, 1999 }; void VLONG_Init( PVLONG N, long v ) { if( v >= 0 ) VLONG_SetSignDigits(N,0,1); else { VLONG_SetSignDigits(N,DIGIT_MSB,1); v = -v; } N[1] = v; } void VLONG_Copy( PVLONG D, PCVLONG S ) { #define VLONG_ACTUAL_BYTES(n) ( (1+(n)) * DIGIT_SIZE ) memcpy( D, S, VLONG_ACTUAL_BYTES( VLONG_Digits(S) ) ); } void VLONG_Load( PVLONG N, PCBYTE pcbBuf, int dwBufSize ) { DIGIT dwDigits = (dwBufSize+DIGIT_SIZE-1)/DIGIT_SIZE; int i; if( ( dwBufSize % DIGIT_SIZE ) == 0 ) i = dwDigits; else { N[dwDigits] = 0; for( i=0; i < (int)(dwBufSize%DIGIT_SIZE); i++ ) N[dwDigits] = ( N[dwDigits] << 8 ) | *(pcbBuf++); i = dwDigits - 1; } for( ; i>0; i-- ) { N[i] = mfGetDWord( pcbBuf ); pcbBuf += 4; } for( i=dwDigits; i>1 && N[i]==0; i-- ) {}; VLONG_SetSignDigits( N, 0, i ); } void VLONG_Save( PCVLONG N, PBYTE pbBuf, int dwBufSize ) { int dwBytes = VLONG_Digits(N) * 4; int i = 0; if( dwBufSize > dwBytes ) { dwBytes = dwBufSize - dwBytes; memset( pbBuf, 0, dwBytes ); pbBuf += dwBytes; } for( i = VLONG_Digits(N); i > 0; i-- ) { mfPutDWord( pbBuf, N[i] ); pbBuf += 4; } } int VLONG_Bits( PCVLONG N ) { int i, n; n = VLONG_Digits(N); if( n != 0 ) { for( i =DIGIT_BITS-1; i >= 0; i-- ) { if( ( N[n] & (1< n = (n-1) * DIGIT_BITS + i + 1; } return n; } DWORD VLONG_LoadHex( PVLONG N, const char *szHex ) { BYTE abBuf[VLONG_DATA_BYTES_MAX]; int n; memset( abBuf, 0, sizeof(abBuf) ); n = LoadHex( abBuf, szHex ); VLONG_Load( N, abBuf, n ); return n; } DWORD VLONG_LoadHexLE( PVLONG N, const char *szHex ) { // Liitle Endian Version of VLONG_LoadHex() BYTE abBuf[VLONG_DATA_BYTES_MAX]; int n; memset( abBuf, 0, sizeof(abBuf) ); n = LoadHex( abBuf, szHex ); memswap( abBuf, n ); VLONG_Load( N, abBuf, n ); return n; } int VLONG_AbsCmp( PCVLONG N1, PCVLONG N2 ) { int dwDigits1 = VLONG_Digits(N1); int dwDigits2 = VLONG_Digits(N2); int i; if( dwDigits1 < dwDigits2 ) return -1; else if( dwDigits1 > dwDigits2 ) return 1; else { for( i=dwDigits1; i>0; i-- ) { if( N1[i] < N2[i] ) return -1; else if( N1[i] > N2[i] )
正在阅读:
SM2算法05-19
中国科学院翻译硕士考研所有辅导班中哪个辅导机构口碑最好09-24
八年级语文综合性学习复习题01-27
第27课《岳阳楼记》导学案(答案)10-04
南开19春学期(1709、1803、1809、1903)《中国近现代史纲要(2015)(尔雅)》在线作业11-03
上海市家电渠道经销企业名录2018版1299家 - 图文01-09
计算机组成原理第二章数据表示(含答案)04-13
神后古镇走出中国工艺美术大师 - 孔相卿11-13
《机械基础》期末试卷A-答案02-28
无线CP243i快速使用指南09-06
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- 算法
- SM2
- 2018年中国金属刀具市场发展现状调研及投资趋势前景分析(目录)
- 水利检测员基础知识DOC
- 《Java基础入门》_课后习题
- 合肥国际学校排名 - 图文
- 2018年事业单位工会系统招聘考试《工会基础知识》真题库及答案【
- 大跨度空间框架结构设计探索
- 2012年考研思政治理论大纲变析
- 互联网时代解说词
- 五年级下册语文同步拓展-《母校》教学反思1 沪教版(2015秋)
- 福建省2018届高三文综历史部分4月质量检查测试试题
- 奈达功能对等理论
- 2018年的手术室护理工作计划与2018年的编辑工作计划范文汇编 doc
- 贵州茅台外部环境分析PESTG
- 基础中医学习题
- 2018年中考物理总复习实验题型强化训练试题及答案
- 毕业论文-文献综述-杨翔
- 企业核心员工流失现象分析
- 中国投资信息管理及监测系统V4.0
- K_3开发积累
- 互联网时代解说词