当前位置:   article > 正文

SM3密码杂凑算法源码解析_c++ sm3

c++ sm3

1.在SM3算法源文件中主要有以下几个函数:

  1. void sm3_starts( sm3_context *ctx );
  2. void sm3_update( sm3_context *ctx, unsigned char *input, int ilen );
  3. void sm3_finish( sm3_context *ctx, unsigned char output[32] );
  4. void sm3( unsigned char *input, int ilen, unsigned char output[32]);
  5. int sm3_file( char *path, unsigned char output[32] );
  6. void sm3_hmac_starts( sm3_context *ctx, unsigned char *key, int keylen);
  7. void sm3_hmac_update( sm3_context *ctx, unsigned char *input, int ilen );
  8. void sm3_hmac_finish( sm3_context *ctx, unsigned char output[32] );
  9. void sm3_hmac( unsigned char *key, int keylen,
  10. unsigned char *input, int ilen,
  11. unsigned char output[32] );

2. 还有一个重要的结构体:

  1. /**
  2. * \brief SM3 context structure
  3. */
  4. typedef struct
  5. {
  6. unsigned long total[2]; /*!< number of bytes processed */
  7. unsigned long state[8]; /*!< intermediate digest state */
  8. unsigned char buffer[64]; /*!< data block being processed */
  9. unsigned char ipad[64]; /*!< HMAC: inner padding */
  10. unsigned char opad[64]; /*!< HMAC: outer padding */
  11. }
  12. sm3_context;

该结构体规定了要处理的字节数、中间摘要状态、数据分组块等等。

3. SM3函数介绍

  1. /**
  2. * \brief Output = SM3( input buffer )
  3. *
  4. * \param input buffer holding the data
  5. * \param ilen length of the input data
  6. * \param output SM3 checksum result
  7. */
  8. void sm3( unsigned char *input, int ilen,
  9. unsigned char output[32]);

字符指针input存储输入数组,ilen参数表示数据长度,字符数组output存储输出结果,在执行sm3函数时内部会调用:sm3_starts()、sm3_update()、sm3_finish()函数。

4. sm3.h源代码

  1. /**
  2. * \file sm3.h
  3. * thanks to Xyssl
  4. * SM3 standards:http://www.oscca.gov.cn/News/201012/News_1199.htm
  5. * author:goldboar
  6. * email:goldboar@163.com
  7. * 2011-10-26
  8. */
  9. #ifndef XYSSL_SM3_H
  10. #define XYSSL_SM3_H
  11. /**
  12. * \brief SM3 context structure
  13. */
  14. typedef struct
  15. {
  16. unsigned long total[2]; /*!< number of bytes processed */
  17. unsigned long state[8]; /*!< intermediate digest state */
  18. unsigned char buffer[64]; /*!< data block being processed */
  19. unsigned char ipad[64]; /*!< HMAC: inner padding */
  20. unsigned char opad[64]; /*!< HMAC: outer padding */
  21. }
  22. sm3_context;
  23. #ifdef __cplusplus
  24. extern "C" {
  25. #endif
  26. /**
  27. * \brief SM3 context setup
  28. *
  29. * \param ctx context to be initialized
  30. */
  31. void sm3_starts( sm3_context *ctx );
  32. /**
  33. * \brief SM3 process buffer
  34. *
  35. * \param ctx SM3 context
  36. * \param input buffer holding the data
  37. * \param ilen length of the input data
  38. */
  39. void sm3_update( sm3_context *ctx, unsigned char *input, int ilen );
  40. /**
  41. * \brief SM3 final digest
  42. *
  43. * \param ctx SM3 context
  44. */
  45. void sm3_finish( sm3_context *ctx, unsigned char output[32] );
  46. /**
  47. * \brief Output = SM3( input buffer )
  48. *
  49. * \param input buffer holding the data
  50. * \param ilen length of the input data
  51. * \param output SM3 checksum result
  52. */
  53. void sm3( unsigned char *input, int ilen,
  54. unsigned char output[32]);
  55. /**
  56. * \brief Output = SM3( file contents )
  57. *
  58. * \param path input file name
  59. * \param output SM3 checksum result
  60. *
  61. * \return 0 if successful, 1 if fopen failed,
  62. * or 2 if fread failed
  63. */
  64. int sm3_file( char *path, unsigned char output[32] );
  65. /**
  66. * \brief SM3 HMAC context setup
  67. *
  68. * \param ctx HMAC context to be initialized
  69. * \param key HMAC secret key
  70. * \param keylen length of the HMAC key
  71. */
  72. void sm3_hmac_starts( sm3_context *ctx, unsigned char *key, int keylen);
  73. /**
  74. * \brief SM3 HMAC process buffer
  75. *
  76. * \param ctx HMAC context
  77. * \param input buffer holding the data
  78. * \param ilen length of the input data
  79. */
  80. void sm3_hmac_update( sm3_context *ctx, unsigned char *input, int ilen );
  81. /**
  82. * \brief SM3 HMAC final digest
  83. *
  84. * \param ctx HMAC context
  85. * \param output SM3 HMAC checksum result
  86. */
  87. void sm3_hmac_finish( sm3_context *ctx, unsigned char output[32] );
  88. /**
  89. * \brief Output = HMAC-SM3( hmac key, input buffer )
  90. *
  91. * \param key HMAC secret key
  92. * \param keylen length of the HMAC key
  93. * \param input buffer holding the data
  94. * \param ilen length of the input data
  95. * \param output HMAC-SM3 result
  96. */
  97. void sm3_hmac( unsigned char *key, int keylen,
  98. unsigned char *input, int ilen,
  99. unsigned char output[32] );
  100. #ifdef __cplusplus
  101. }
  102. #endif
  103. #endif /* sm3.h */

4. sm3.c源代码

  1. /*
  2. * SM3 Hash alogrith
  3. * thanks to Xyssl
  4. * author:goldboar
  5. * email:goldboar@163.com
  6. * 2011-10-26
  7. */
  8. //Testing data from SM3 Standards
  9. //http://www.oscca.gov.cn/News/201012/News_1199.htm
  10. // Sample 1
  11. // Input:"abc"
  12. // Output:66c7f0f4 62eeedd9 d1f2d46b dc10e4e2 4167c487 5cf2f7a2 297da02b 8f4ba8e0
  13. // Sample 2
  14. // Input:"abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"
  15. // Outpuf:debe9ff9 2275b8a1 38604889 c18e5a4d 6fdb70e5 387e5765 293dcba3 9c0c5732
  16. #include "sm3.h"
  17. #include <string.h>
  18. #include <stdio.h>
  19. /*
  20. * 32-bit integer manipulation macros (big endian)
  21. */
  22. #ifndef GET_ULONG_BE
  23. #define GET_ULONG_BE(n,b,i) \
  24. { \
  25. (n) = ( (unsigned long) (b)[(i) ] << 24 ) \
  26. | ( (unsigned long) (b)[(i) + 1] << 16 ) \
  27. | ( (unsigned long) (b)[(i) + 2] << 8 ) \
  28. | ( (unsigned long) (b)[(i) + 3] ); \
  29. }
  30. #endif
  31. #ifndef PUT_ULONG_BE
  32. #define PUT_ULONG_BE(n,b,i) \
  33. { \
  34. (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
  35. (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
  36. (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
  37. (b)[(i) + 3] = (unsigned char) ( (n) ); \
  38. }
  39. #endif
  40. /*
  41. * SM3 context setup
  42. */
  43. void sm3_starts( sm3_context *ctx )
  44. {
  45. ctx->total[0] = 0;
  46. ctx->total[1] = 0;
  47. ctx->state[0] = 0x7380166F;
  48. ctx->state[1] = 0x4914B2B9;
  49. ctx->state[2] = 0x172442D7;
  50. ctx->state[3] = 0xDA8A0600;
  51. ctx->state[4] = 0xA96F30BC;
  52. ctx->state[5] = 0x163138AA;
  53. ctx->state[6] = 0xE38DEE4D;
  54. ctx->state[7] = 0xB0FB0E4E;
  55. }
  56. static void sm3_process( sm3_context *ctx, unsigned char data[64] )
  57. {
  58. unsigned long SS1, SS2, TT1, TT2, W[68],W1[64];
  59. unsigned long A, B, C, D, E, F, G, H;
  60. unsigned long T[64];
  61. unsigned long Temp1,Temp2,Temp3,Temp4,Temp5;
  62. int j;
  63. #ifdef _DEBUG
  64. int i;
  65. #endif
  66. // for(j=0; j < 68; j++)
  67. // W[j] = 0;
  68. // for(j=0; j < 64; j++)
  69. // W1[j] = 0;
  70. for(j = 0; j < 16; j++)
  71. T[j] = 0x79CC4519;
  72. for(j =16; j < 64; j++)
  73. T[j] = 0x7A879D8A;
  74. GET_ULONG_BE( W[ 0], data, 0 );
  75. GET_ULONG_BE( W[ 1], data, 4 );
  76. GET_ULONG_BE( W[ 2], data, 8 );
  77. GET_ULONG_BE( W[ 3], data, 12 );
  78. GET_ULONG_BE( W[ 4], data, 16 );
  79. GET_ULONG_BE( W[ 5], data, 20 );
  80. GET_ULONG_BE( W[ 6], data, 24 );
  81. GET_ULONG_BE( W[ 7], data, 28 );
  82. GET_ULONG_BE( W[ 8], data, 32 );
  83. GET_ULONG_BE( W[ 9], data, 36 );
  84. GET_ULONG_BE( W[10], data, 40 );
  85. GET_ULONG_BE( W[11], data, 44 );
  86. GET_ULONG_BE( W[12], data, 48 );
  87. GET_ULONG_BE( W[13], data, 52 );
  88. GET_ULONG_BE( W[14], data, 56 );
  89. GET_ULONG_BE( W[15], data, 60 );
  90. #ifdef _DEBUG
  91. printf("Message with padding:\n");
  92. for(i=0; i< 8; i++)
  93. printf("%08x ",W[i]);
  94. printf("\n");
  95. for(i=8; i< 16; i++)
  96. printf("%08x ",W[i]);
  97. printf("\n");
  98. #endif
  99. #define FF0(x,y,z) ( (x) ^ (y) ^ (z))
  100. #define FF1(x,y,z) (((x) & (y)) | ( (x) & (z)) | ( (y) & (z)))
  101. #define GG0(x,y,z) ( (x) ^ (y) ^ (z))
  102. #define GG1(x,y,z) (((x) & (y)) | ( (~(x)) & (z)) )
  103. #define SHL(x,n) (((x) & 0xFFFFFFFF) << n)
  104. #define ROTL(x,n) (SHL((x),n) | ((x) >> (32 - n)))
  105. #define P0(x) ((x) ^ ROTL((x),9) ^ ROTL((x),17))
  106. #define P1(x) ((x) ^ ROTL((x),15) ^ ROTL((x),23))
  107. for(j = 16; j < 68; j++ )
  108. {
  109. //W[j] = P1( W[j-16] ^ W[j-9] ^ ROTL(W[j-3],15)) ^ ROTL(W[j - 13],7 ) ^ W[j-6];
  110. //Why thd release's result is different with the debug's ?
  111. //Below is okay. Interesting, Perhaps VC6 has a bug of Optimizaiton.
  112. Temp1 = W[j-16] ^ W[j-9];
  113. Temp2 = ROTL(W[j-3],15);
  114. Temp3 = Temp1 ^ Temp2;
  115. Temp4 = P1(Temp3);
  116. Temp5 = ROTL(W[j - 13],7 ) ^ W[j-6];
  117. W[j] = Temp4 ^ Temp5;
  118. }
  119. #ifdef _DEBUG
  120. printf("Expanding message W0-67:\n");
  121. for(i=0; i<68; i++)
  122. {
  123. printf("%08x ",W[i]);
  124. if(((i+1) % 8) == 0) printf("\n");
  125. }
  126. printf("\n");
  127. #endif
  128. for(j = 0; j < 64; j++)
  129. {
  130. W1[j] = W[j] ^ W[j+4];
  131. }
  132. #ifdef _DEBUG
  133. printf("Expanding message W'0-63:\n");
  134. for(i=0; i<64; i++)
  135. {
  136. printf("%08x ",W1[i]);
  137. if(((i+1) % 8) == 0) printf("\n");
  138. }
  139. printf("\n");
  140. #endif
  141. A = ctx->state[0];
  142. B = ctx->state[1];
  143. C = ctx->state[2];
  144. D = ctx->state[3];
  145. E = ctx->state[4];
  146. F = ctx->state[5];
  147. G = ctx->state[6];
  148. H = ctx->state[7];
  149. #ifdef _DEBUG
  150. printf("j A B C D E F G H\n");
  151. printf(" %08x %08x %08x %08x %08x %08x %08x %08x\n",A,B,C,D,E,F,G,H);
  152. #endif
  153. for(j =0; j < 16; j++)
  154. {
  155. SS1 = ROTL((ROTL(A,12) + E + ROTL(T[j],j)), 7);
  156. SS2 = SS1 ^ ROTL(A,12);
  157. TT1 = FF0(A,B,C) + D + SS2 + W1[j];
  158. TT2 = GG0(E,F,G) + H + SS1 + W[j];
  159. D = C;
  160. C = ROTL(B,9);
  161. B = A;
  162. A = TT1;
  163. H = G;
  164. G = ROTL(F,19);
  165. F = E;
  166. E = P0(TT2);
  167. #ifdef _DEBUG
  168. printf("%02d %08x %08x %08x %08x %08x %08x %08x %08x\n",j,A,B,C,D,E,F,G,H);
  169. #endif
  170. }
  171. for(j =16; j < 64; j++)
  172. {
  173. SS1 = ROTL((ROTL(A,12) + E + ROTL(T[j],j)), 7);
  174. SS2 = SS1 ^ ROTL(A,12);
  175. TT1 = FF1(A,B,C) + D + SS2 + W1[j];
  176. TT2 = GG1(E,F,G) + H + SS1 + W[j];
  177. D = C;
  178. C = ROTL(B,9);
  179. B = A;
  180. A = TT1;
  181. H = G;
  182. G = ROTL(F,19);
  183. F = E;
  184. E = P0(TT2);
  185. #ifdef _DEBUG
  186. printf("%02d %08x %08x %08x %08x %08x %08x %08x %08x\n",j,A,B,C,D,E,F,G,H);
  187. #endif
  188. }
  189. ctx->state[0] ^= A;
  190. ctx->state[1] ^= B;
  191. ctx->state[2] ^= C;
  192. ctx->state[3] ^= D;
  193. ctx->state[4] ^= E;
  194. ctx->state[5] ^= F;
  195. ctx->state[6] ^= G;
  196. ctx->state[7] ^= H;
  197. #ifdef _DEBUG
  198. printf(" %08x %08x %08x %08x %08x %08x %08x %08x\n",ctx->state[0],ctx->state[1],ctx->state[2],
  199. ctx->state[3],ctx->state[4],ctx->state[5],ctx->state[6],ctx->state[7]);
  200. #endif
  201. }
  202. /*
  203. * SM3 process buffer
  204. */
  205. void sm3_update( sm3_context *ctx, unsigned char *input, int ilen )
  206. {
  207. int fill;
  208. unsigned long left;
  209. if( ilen <= 0 )
  210. return;
  211. left = ctx->total[0] & 0x3F;
  212. fill = 64 - left;
  213. ctx->total[0] += ilen;
  214. ctx->total[0] &= 0xFFFFFFFF;
  215. if( ctx->total[0] < (unsigned long) ilen )
  216. ctx->total[1]++;
  217. if( left && ilen >= fill )
  218. {
  219. memcpy( (void *) (ctx->buffer + left),
  220. (void *) input, fill );
  221. sm3_process( ctx, ctx->buffer );
  222. input += fill;
  223. ilen -= fill;
  224. left = 0;
  225. }
  226. while( ilen >= 64 )
  227. {
  228. sm3_process( ctx, input );
  229. input += 64;
  230. ilen -= 64;
  231. }
  232. if( ilen > 0 )
  233. {
  234. memcpy( (void *) (ctx->buffer + left),
  235. (void *) input, ilen );
  236. }
  237. }
  238. static const unsigned char sm3_padding[64] =
  239. {
  240. 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  241. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  242. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  243. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  244. };
  245. /*
  246. * SM3 final digest
  247. */
  248. void sm3_finish( sm3_context *ctx, unsigned char output[32] )
  249. {
  250. unsigned long last, padn;
  251. unsigned long high, low;
  252. unsigned char msglen[8];
  253. high = ( ctx->total[0] >> 29 )
  254. | ( ctx->total[1] << 3 );
  255. low = ( ctx->total[0] << 3 );
  256. PUT_ULONG_BE( high, msglen, 0 );
  257. PUT_ULONG_BE( low, msglen, 4 );
  258. last = ctx->total[0] & 0x3F;
  259. padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
  260. sm3_update( ctx, (unsigned char *) sm3_padding, padn );
  261. sm3_update( ctx, msglen, 8 );
  262. PUT_ULONG_BE( ctx->state[0], output, 0 );
  263. PUT_ULONG_BE( ctx->state[1], output, 4 );
  264. PUT_ULONG_BE( ctx->state[2], output, 8 );
  265. PUT_ULONG_BE( ctx->state[3], output, 12 );
  266. PUT_ULONG_BE( ctx->state[4], output, 16 );
  267. PUT_ULONG_BE( ctx->state[5], output, 20 );
  268. PUT_ULONG_BE( ctx->state[6], output, 24 );
  269. PUT_ULONG_BE( ctx->state[7], output, 28 );
  270. }
  271. /*
  272. * output = SM3( input buffer )
  273. */
  274. void sm3( unsigned char *input, int ilen,
  275. unsigned char output[32] )
  276. {
  277. sm3_context ctx;
  278. sm3_starts( &ctx );
  279. sm3_update( &ctx, input, ilen );
  280. sm3_finish( &ctx, output );
  281. memset( &ctx, 0, sizeof( sm3_context ) );
  282. }
  283. /*
  284. * output = SM3( file contents )
  285. */
  286. int sm3_file( char *path, unsigned char output[32] )
  287. {
  288. FILE *f;
  289. size_t n;
  290. sm3_context ctx;
  291. unsigned char buf[1024];
  292. if( ( f = fopen( path, "rb" ) ) == NULL )
  293. return( 1 );
  294. sm3_starts( &ctx );
  295. while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
  296. sm3_update( &ctx, buf, (int) n );
  297. sm3_finish( &ctx, output );
  298. memset( &ctx, 0, sizeof( sm3_context ) );
  299. if( ferror( f ) != 0 )
  300. {
  301. fclose( f );
  302. return( 2 );
  303. }
  304. fclose( f );
  305. return( 0 );
  306. }
  307. /*
  308. * SM3 HMAC context setup
  309. */
  310. void sm3_hmac_starts( sm3_context *ctx, unsigned char *key, int keylen )
  311. {
  312. int i;
  313. unsigned char sum[32];
  314. if( keylen > 64 )
  315. {
  316. sm3( key, keylen, sum );
  317. keylen = 32;
  318. //keylen = ( is224 ) ? 28 : 32;
  319. key = sum;
  320. }
  321. memset( ctx->ipad, 0x36, 64 );
  322. memset( ctx->opad, 0x5C, 64 );
  323. for( i = 0; i < keylen; i++ )
  324. {
  325. ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
  326. ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
  327. }
  328. sm3_starts( ctx);
  329. sm3_update( ctx, ctx->ipad, 64 );
  330. memset( sum, 0, sizeof( sum ) );
  331. }
  332. /*
  333. * SM3 HMAC process buffer
  334. */
  335. void sm3_hmac_update( sm3_context *ctx, unsigned char *input, int ilen )
  336. {
  337. sm3_update( ctx, input, ilen );
  338. }
  339. /*
  340. * SM3 HMAC final digest
  341. */
  342. void sm3_hmac_finish( sm3_context *ctx, unsigned char output[32] )
  343. {
  344. int hlen;
  345. unsigned char tmpbuf[32];
  346. //is224 = ctx->is224;
  347. hlen = 32;
  348. sm3_finish( ctx, tmpbuf );
  349. sm3_starts( ctx );
  350. sm3_update( ctx, ctx->opad, 64 );
  351. sm3_update( ctx, tmpbuf, hlen );
  352. sm3_finish( ctx, output );
  353. memset( tmpbuf, 0, sizeof( tmpbuf ) );
  354. }
  355. /*
  356. * output = HMAC-SM#( hmac key, input buffer )
  357. */
  358. void sm3_hmac( unsigned char *key, int keylen,
  359. unsigned char *input, int ilen,
  360. unsigned char output[32] )
  361. {
  362. sm3_context ctx;
  363. sm3_hmac_starts( &ctx, key, keylen);
  364. sm3_hmac_update( &ctx, input, ilen );
  365. sm3_hmac_finish( &ctx, output );
  366. memset( &ctx, 0, sizeof( sm3_context ) );
  367. }

5 sm3test.c 源代码

  1. #include <string.h>
  2. #include <stdio.h>
  3. #include "sm3.h"
  4. int main( int argc, char *argv[] )
  5. {
  6. unsigned char *input = "abc";
  7. int ilen = 3;
  8. unsigned char output[32];
  9. int i;
  10. sm3_context ctx;
  11. printf("Message: ");
  12. printf("%s\n",input);
  13. sm3(input, ilen, output);
  14. printf("Hash: ");
  15. for(i=0; i<32; i++)
  16. {
  17. printf("%02x",output[i]);
  18. if (((i+1) % 4 ) == 0) printf(" ");
  19. }
  20. printf("\n");
  21. printf("Message: ");
  22. for(i=0; i < 16; i++)
  23. printf("abcd");
  24. printf("\n");
  25. sm3_starts( &ctx );
  26. for(i=0; i < 16; i++)
  27. sm3_update( &ctx, "abcd", 4 );
  28. sm3_finish( &ctx, output );
  29. memset( &ctx, 0, sizeof( sm3_context ) );
  30. printf("Hash: ");
  31. for(i=0; i<32; i++)
  32. {
  33. printf("%02x",output[i]);
  34. if (((i+1) % 4 ) == 0) printf(" ");
  35. }
  36. printf("\n");
  37. //getch(); //VS2008
  38. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/139559?site
推荐阅读
相关标签
  

闽ICP备14008679号