当前位置:   article > 正文

2017-2018-1 20155202 20155239 实验二 固件程序设计

sm28.cc.

2017-2018-1 20155202 20155202 实验二 固件程序设计

实验1,2,3,5 搭档写,博客链接:20155239

实验四:国密算法

  • 四个算法的用途:
  • SM1对称分组算法
  • 用途:芯片、智能IC卡、智能密码钥匙、加密卡、加密机等安全产品,广泛应用于电子政务、电子商务及国民经济的各个应用领域(包括国家政务通、警务通等重要领域)。
  • 密码学对应算法:DES,AES

  • SM2椭圆曲线公钥密码算法
  • 用途:密钥管理,数字签名,电子商务,PKI,信息及身份认证等信息安全应用领域
  • 密码学对应算法:ECC椭圆曲线算法

    sm2:

  1. // \file:sm2.c
  2. //SM2 Algorithm
  3. //2011-11-10
  4. //author:goldboar
  5. //email:goldboar@163.com
  6. //depending:opnessl library
  7. //SM2 Standards: http://www.oscca.gov.cn/News/201012/News_1197.htm
  8. #include <limits.h>
  9. //#include <openssl/ec.h>
  10. #include <openssl/bn.h>
  11. #include <openssl/rand.h>
  12. #include <openssl/err.h>
  13. #include <openssl/ecdsa.h>
  14. #include <openssl/ecdh.h>
  15. #include "kdf.h"
  16. #define NID_X9_62_prime_field 406
  17. static void BNPrintf(BIGNUM* bn)
  18. {
  19. char *p=NULL;
  20. p=BN_bn2hex(bn);
  21. printf("%s",p);
  22. OPENSSL_free(p);
  23. }
  24. static int sm2_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kp, BIGNUM **rp)
  25. {
  26. BN_CTX *ctx = NULL;
  27. BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL;
  28. EC_POINT *tmp_point=NULL;
  29. const EC_GROUP *group;
  30. int ret = 0;
  31. if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL)
  32. {
  33. ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
  34. return 0;
  35. }
  36. if (ctx_in == NULL)
  37. {
  38. if ((ctx = BN_CTX_new()) == NULL)
  39. {
  40. ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_MALLOC_FAILURE);
  41. return 0;
  42. }
  43. }
  44. else
  45. ctx = ctx_in;
  46. k = BN_new(); /* this value is later returned in *kp */
  47. r = BN_new(); /* this value is later returned in *rp */
  48. order = BN_new();
  49. X = BN_new();
  50. if (!k || !r || !order || !X)
  51. {
  52. ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
  53. goto err;
  54. }
  55. if ((tmp_point = EC_POINT_new(group)) == NULL)
  56. {
  57. ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
  58. goto err;
  59. }
  60. if (!EC_GROUP_get_order(group, order, ctx))
  61. {
  62. ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
  63. goto err;
  64. }
  65. do
  66. {
  67. /* get random k */
  68. do
  69. if (!BN_rand_range(k, order))
  70. {
  71. ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
  72. goto err;
  73. }
  74. while (BN_is_zero(k));
  75. /* compute r the x-coordinate of generator * k */
  76. if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx))
  77. {
  78. ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
  79. goto err;
  80. }
  81. if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
  82. {
  83. if (!EC_POINT_get_affine_coordinates_GFp(group,
  84. tmp_point, X, NULL, ctx))
  85. {
  86. ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB);
  87. goto err;
  88. }
  89. }
  90. else /* NID_X9_62_characteristic_two_field */
  91. {
  92. if (!EC_POINT_get_affine_coordinates_GF2m(group,
  93. tmp_point, X, NULL, ctx))
  94. {
  95. ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB);
  96. goto err;
  97. }
  98. }
  99. if (!BN_nnmod(r, X, order, ctx))
  100. {
  101. ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
  102. goto err;
  103. }
  104. }
  105. while (BN_is_zero(r));
  106. /* compute the inverse of k */
  107. // if (!BN_mod_inverse(k, k, order, ctx))
  108. // {
  109. // ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
  110. // goto err;
  111. // }
  112. /* clear old values if necessary */
  113. if (*rp != NULL)
  114. BN_clear_free(*rp);
  115. if (*kp != NULL)
  116. BN_clear_free(*kp);
  117. /* save the pre-computed values */
  118. *rp = r;
  119. *kp = k;
  120. ret = 1;
  121. err:
  122. if (!ret)
  123. {
  124. if (k != NULL) BN_clear_free(k);
  125. if (r != NULL) BN_clear_free(r);
  126. }
  127. if (ctx_in == NULL)
  128. BN_CTX_free(ctx);
  129. if (order != NULL)
  130. BN_free(order);
  131. if (tmp_point != NULL)
  132. EC_POINT_free(tmp_point);
  133. if (X)
  134. BN_clear_free(X);
  135. return(ret);
  136. }
  137. static ECDSA_SIG *sm2_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *in_k, const BIGNUM *in_r, EC_KEY *eckey)
  138. {
  139. int ok = 0, i;
  140. BIGNUM *k=NULL, *s, *m=NULL,*tmp=NULL,*order=NULL;
  141. const BIGNUM *ck;
  142. BN_CTX *ctx = NULL;
  143. const EC_GROUP *group;
  144. ECDSA_SIG *ret;
  145. //ECDSA_DATA *ecdsa;
  146. const BIGNUM *priv_key;
  147. BIGNUM *r,*x=NULL,*a=NULL; //new added
  148. //ecdsa = ecdsa_check(eckey);
  149. group = EC_KEY_get0_group(eckey);
  150. priv_key = EC_KEY_get0_private_key(eckey);
  151. if (group == NULL || priv_key == NULL /*|| ecdsa == NULL*/)
  152. {
  153. ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
  154. return NULL;
  155. }
  156. ret = ECDSA_SIG_new();
  157. if (!ret)
  158. {
  159. ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
  160. return NULL;
  161. }
  162. s = ret->s;
  163. r = ret->r;
  164. if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL ||
  165. (tmp = BN_new()) == NULL || (m = BN_new()) == NULL ||
  166. (x = BN_new()) == NULL || (a = BN_new()) == NULL)
  167. {
  168. ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
  169. goto err;
  170. }
  171. if (!EC_GROUP_get_order(group, order, ctx))
  172. {
  173. ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
  174. goto err;
  175. }
  176. // for(i=0;i<dgst_len;i++)
  177. // printf("%02X",dgst[i]);
  178. // printf("\n");
  179. i = BN_num_bits(order);
  180. /* Need to truncate digest if it is too long: first truncate whole
  181. * bytes.
  182. */
  183. if (8 * dgst_len > i)
  184. dgst_len = (i + 7)/8;
  185. if (!BN_bin2bn(dgst, dgst_len, m))
  186. {
  187. ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
  188. goto err;
  189. }
  190. /* If still too long truncate remaining bits with a shift */
  191. if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7)))
  192. {
  193. ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
  194. goto err;
  195. }
  196. // fprintf(stdout,"m: ");
  197. // BNPrintf(m);
  198. // fprintf(stdout,"\n");
  199. do
  200. {
  201. if (in_k == NULL || in_r == NULL)
  202. {
  203. if (!sm2_sign_setup(eckey, ctx, &k, &x))
  204. {
  205. ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,ERR_R_ECDSA_LIB);
  206. goto err;
  207. }
  208. ck = k;
  209. }
  210. else
  211. {
  212. ck = in_k;
  213. if (BN_copy(x, in_r) == NULL)
  214. {
  215. ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
  216. goto err;
  217. }
  218. }
  219. //r=(e+x1) mod n
  220. if (!BN_mod_add_quick(r, m, x, order))
  221. {
  222. ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
  223. goto err;
  224. }
  225. // BNPrintf(r);
  226. // fprintf(stdout,"\n");
  227. if(BN_is_zero(r) )
  228. continue;
  229. BN_add(tmp,r,ck);
  230. if(BN_ucmp(tmp,order) == 0)
  231. continue;
  232. if (!BN_mod_mul(tmp, priv_key, r, order, ctx))
  233. {
  234. ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
  235. goto err;
  236. }
  237. if (!BN_mod_sub_quick(s, ck, tmp, order))
  238. {
  239. ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
  240. goto err;
  241. }
  242. BN_one(a);
  243. //BN_set_word((a),1);
  244. if (!BN_mod_add_quick(tmp, priv_key, a, order))
  245. {
  246. ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
  247. goto err;
  248. }
  249. /* compute the inverse of 1+dA */
  250. if (!BN_mod_inverse(tmp, tmp, order, ctx))
  251. {
  252. ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
  253. goto err;
  254. }
  255. // BNPrintf(tmp);
  256. // fprintf(stdout,"\n");
  257. if (!BN_mod_mul(s, s, tmp, order, ctx))
  258. {
  259. ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
  260. goto err;
  261. }
  262. if (BN_is_zero(s))
  263. {
  264. /* if k and r have been supplied by the caller
  265. * don't to generate new k and r values */
  266. if (in_k != NULL && in_r != NULL)
  267. {
  268. ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_NEED_NEW_SETUP_VALUES);
  269. goto err;
  270. }
  271. }
  272. else
  273. /* s != 0 => we have a valid signature */
  274. break;
  275. }
  276. while (1);
  277. ok = 1;
  278. err:
  279. if (!ok)
  280. {
  281. ECDSA_SIG_free(ret);
  282. ret = NULL;
  283. }
  284. if (ctx)
  285. BN_CTX_free(ctx);
  286. if (m)
  287. BN_clear_free(m);
  288. if (tmp)
  289. BN_clear_free(tmp);
  290. if (order)
  291. BN_free(order);
  292. if (k)
  293. BN_clear_free(k);
  294. if (x)
  295. BN_clear_free(x);
  296. if (a)
  297. BN_clear_free(a);
  298. return ret;
  299. }
  300. static int sm2_do_verify(const unsigned char *dgst, int dgst_len,
  301. const ECDSA_SIG *sig, EC_KEY *eckey)
  302. {
  303. int ret = -1, i;
  304. BN_CTX *ctx;
  305. BIGNUM *order, *R, *m, *X,*t;
  306. EC_POINT *point = NULL;
  307. const EC_GROUP *group;
  308. const EC_POINT *pub_key;
  309. /* check input values */
  310. if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL ||
  311. (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL)
  312. {
  313. ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS);
  314. return -1;
  315. }
  316. ctx = BN_CTX_new();
  317. if (!ctx)
  318. {
  319. ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
  320. return -1;
  321. }
  322. BN_CTX_start(ctx);
  323. order = BN_CTX_get(ctx);
  324. R = BN_CTX_get(ctx);
  325. t = BN_CTX_get(ctx);
  326. m = BN_CTX_get(ctx);
  327. X = BN_CTX_get(ctx);
  328. if (!X)
  329. {
  330. ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
  331. goto err;
  332. }
  333. if (!EC_GROUP_get_order(group, order, ctx))
  334. {
  335. ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
  336. goto err;
  337. }
  338. if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
  339. BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) ||
  340. BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0)
  341. {
  342. ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE);
  343. ret = 0; /* signature is invalid */
  344. goto err;
  345. }
  346. //t =(r+s) mod n
  347. if (!BN_mod_add_quick(t, sig->s, sig->r,order))
  348. {
  349. ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
  350. goto err;
  351. }
  352. if (BN_is_zero(t))
  353. {
  354. ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE);
  355. ret = 0; /* signature is invalid */
  356. goto err;
  357. }
  358. //point = s*G+t*PA
  359. if ((point = EC_POINT_new(group)) == NULL)
  360. {
  361. ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
  362. goto err;
  363. }
  364. if (!EC_POINT_mul(group, point, sig->s, pub_key, t, ctx))
  365. {
  366. ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
  367. goto err;
  368. }
  369. if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
  370. {
  371. if (!EC_POINT_get_affine_coordinates_GFp(group,
  372. point, X, NULL, ctx))
  373. {
  374. ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
  375. goto err;
  376. }
  377. }
  378. else /* NID_X9_62_characteristic_two_field */
  379. {
  380. if (!EC_POINT_get_affine_coordinates_GF2m(group,
  381. point, X, NULL, ctx))
  382. {
  383. ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
  384. goto err;
  385. }
  386. }
  387. i = BN_num_bits(order);
  388. /* Need to truncate digest if it is too long: first truncate whole
  389. * bytes.
  390. */
  391. if (8 * dgst_len > i)
  392. dgst_len = (i + 7)/8;
  393. if (!BN_bin2bn(dgst, dgst_len, m))
  394. {
  395. ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
  396. goto err;
  397. }
  398. /* If still too long truncate remaining bits with a shift */
  399. if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7)))
  400. {
  401. ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
  402. goto err;
  403. }
  404. /* R = m + X mod order */
  405. if (!BN_mod_add_quick(R, m, X, order))
  406. {
  407. ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
  408. goto err;
  409. }
  410. /* if the signature is correct R is equal to sig->r */
  411. ret = (BN_ucmp(R, sig->r) == 0);
  412. err:
  413. BN_CTX_end(ctx);
  414. BN_CTX_free(ctx);
  415. if (point)
  416. EC_POINT_free(point);
  417. return ret;
  418. }
  419. EC_POINT *sm2_compute_key(const EC_POINT *b_pub_key_r, const EC_POINT *b_pub_key, const BIGNUM *a_r,EC_KEY *a_eckey)
  420. {
  421. BN_CTX *ctx;
  422. EC_POINT *tmp=NULL;
  423. BIGNUM *x=NULL, *y=NULL, *order=NULL,*z=NULL;
  424. const BIGNUM *priv_key;
  425. const EC_GROUP* group;
  426. EC_POINT *ret= NULL;
  427. /* size_t buflen, len;*/
  428. unsigned char *buf=NULL;
  429. int i, j;
  430. //char *p=NULL;
  431. BIGNUM *x1,*x2,*t,*h;
  432. if ((ctx = BN_CTX_new()) == NULL) goto err;
  433. BN_CTX_start(ctx);
  434. x = BN_CTX_get(ctx);
  435. y = BN_CTX_get(ctx);
  436. order = BN_CTX_get(ctx);
  437. z = BN_CTX_get(ctx);
  438. x1 = BN_CTX_get(ctx);
  439. x2 = BN_CTX_get(ctx);
  440. t = BN_CTX_get(ctx);
  441. h = BN_CTX_get(ctx);
  442. priv_key = EC_KEY_get0_private_key(a_eckey);
  443. if (priv_key == NULL)
  444. {
  445. ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_NO_PRIVATE_VALUE);
  446. goto err;
  447. }
  448. group = EC_KEY_get0_group(a_eckey);
  449. if ((tmp=EC_POINT_new(group)) == NULL)
  450. {
  451. ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
  452. goto err;
  453. }
  454. if (!EC_POINT_mul(group, tmp, a_r, NULL, NULL, ctx))
  455. {
  456. ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
  457. goto err;
  458. }
  459. if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
  460. {
  461. if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, NULL, ctx))
  462. {
  463. ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
  464. goto err;
  465. }
  466. }
  467. else
  468. {
  469. if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp, x, NULL, ctx))
  470. {
  471. ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
  472. goto err;
  473. }
  474. }
  475. if (!EC_GROUP_get_order(group, order, ctx))
  476. {
  477. ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
  478. goto err;
  479. }
  480. i = BN_num_bits(order);
  481. j = i/2 -1;
  482. BN_mask_bits(x,j);
  483. BN_set_word(y,2);
  484. BN_set_word(z,j);
  485. BN_exp(y,y,z,ctx);
  486. BN_add(x1,x,y);
  487. // fprintf(stdout,"X1=: ");
  488. // BNPrintf(x1);
  489. // fprintf(stdout,"\n");
  490. BN_mod_mul(t,x1,a_r,order,ctx);
  491. BN_mod_add_quick(t,t,priv_key,order);
  492. //
  493. // fprintf(stdout,"ta=: ");
  494. // BNPrintf(t);
  495. // fprintf(stdout,"\n");
  496. if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
  497. {
  498. if (!EC_POINT_get_affine_coordinates_GFp(group, b_pub_key_r, x, NULL, ctx))
  499. {
  500. ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
  501. goto err;
  502. }
  503. }
  504. else
  505. {
  506. if (!EC_POINT_get_affine_coordinates_GF2m(group, b_pub_key_r, x, NULL, ctx))
  507. {
  508. ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
  509. goto err;
  510. }
  511. }
  512. i = BN_num_bits(order);
  513. j = i/2 -1;
  514. BN_mask_bits(x,j);
  515. BN_set_word(y,2);
  516. BN_set_word(z,j);
  517. BN_exp(y,y,z,ctx);
  518. BN_add(x2,x,y);
  519. // fprintf(stdout,"X2=: ");
  520. // BNPrintf(x2);
  521. // fprintf(stdout,"\n");
  522. //x2*Rb+Pb;
  523. if (!EC_POINT_mul(group, tmp, NULL,b_pub_key_r,x2,ctx) )
  524. {
  525. ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
  526. goto err;
  527. }
  528. if ((ret=EC_POINT_new(group)) == NULL)
  529. {
  530. ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
  531. goto err;
  532. }
  533. if (!EC_POINT_add(group, ret, b_pub_key, tmp, ctx))
  534. {
  535. ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
  536. goto err;
  537. }
  538. if (!EC_POINT_get_affine_coordinates_GFp(group,ret, x, y, ctx))
  539. {
  540. goto err;
  541. }
  542. // fprintf(stdout, "\nTesting x2*Rb+Pb Key Point\n x = 0x");
  543. // BNPrintf(x);
  544. // fprintf(stdout, "\n y = 0x");
  545. // BNPrintf( y);
  546. // fprintf(stdout, "\n");
  547. //
  548. if(!EC_GROUP_get_cofactor(group, h, ctx))
  549. {
  550. goto err;
  551. }
  552. BN_mul(t,t,h,ctx);
  553. //h*t*(x2*Rb+Pb)
  554. if (!EC_POINT_mul(group, ret, NULL,ret,t,ctx) )
  555. {
  556. goto err;
  557. }
  558. if (!EC_POINT_get_affine_coordinates_GFp(group,ret, x, y, ctx))
  559. {
  560. goto err;
  561. }
  562. // fprintf(stdout, "\nTesting ret Key Point\n x = 0x");
  563. // BNPrintf(x);
  564. // fprintf(stdout, "\n y = 0x");
  565. // BNPrintf( y);
  566. // fprintf(stdout, "\n");
  567. err:
  568. if (tmp) EC_POINT_free(tmp);
  569. if (ctx) BN_CTX_end(ctx);
  570. if (ctx) BN_CTX_free(ctx);
  571. if (buf) OPENSSL_free(buf);
  572. return(ret);
  573. }
  574. /** SM2_sign_setup
  575. * precompute parts of the signing operation.
  576. * \param eckey pointer to the EC_KEY object containing a private EC key
  577. * \param ctx pointer to a BN_CTX object (may be NULL)
  578. * \param k pointer to a BIGNUM pointer for the inverse of k
  579. * \param rp pointer to a BIGNUM pointer for x coordinate of k * generator
  580. * \return 1 on success and 0 otherwise
  581. */
  582. int SM2_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
  583. {
  584. // ECDSA_DATA *ecdsa = ecdsa_check(eckey);
  585. // if (ecdsa == NULL)
  586. // return 0;
  587. return SM2_sign_setup(eckey, ctx_in, kinvp, rp);
  588. }
  589. /** SM2_sign_ex
  590. * computes ECDSA signature of a given hash value using the supplied
  591. * private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
  592. * \param type this parameter is ignored
  593. * \param dgst pointer to the hash value to sign
  594. * \param dgstlen length of the hash value
  595. * \param sig buffer to hold the DER encoded signature
  596. * \param siglen pointer to the length of the returned signature
  597. * \param k optional pointer to a pre-computed inverse k
  598. * \param rp optional pointer to the pre-computed rp value (see
  599. * ECDSA_sign_setup
  600. * \param eckey pointer to the EC_KEY object containing a private EC key
  601. * \return 1 on success and 0 otherwise
  602. */
  603. int SM2_sign_ex(int type, const unsigned char *dgst, int dlen, unsigned char
  604. *sig, unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *r,
  605. EC_KEY *eckey)
  606. {
  607. ECDSA_SIG *s;
  608. RAND_seed(dgst, dlen);
  609. s = sm2_do_sign(dgst, dlen, kinv, r, eckey);
  610. if (s == NULL)
  611. {
  612. *siglen=0;
  613. return 0;
  614. }
  615. *siglen = i2d_ECDSA_SIG(s, &sig);
  616. ECDSA_SIG_free(s);
  617. return 1;
  618. }
  619. /** SM2_sign
  620. * computes ECDSA signature of a given hash value using the supplied
  621. * private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
  622. * \param type this parameter is ignored
  623. * \param dgst pointer to the hash value to sign
  624. * \param dgstlen length of the hash value
  625. * \param sig buffer to hold the DER encoded signature
  626. * \param siglen pointer to the length of the returned signature
  627. * \param eckey pointer to the EC_KEY object containing a private EC key
  628. * \return 1 on success and 0 otherwise
  629. */
  630. int SM2_sign(int type, const unsigned char *dgst, int dlen, unsigned char
  631. *sig, unsigned int *siglen, EC_KEY *eckey)
  632. {
  633. return SM2_sign_ex(type, dgst, dlen, sig, siglen, NULL, NULL, eckey);
  634. }
  635. /** SM2_verify
  636. * verifies that the given signature is valid ECDSA signature
  637. * of the supplied hash value using the specified public key.
  638. * \param type this parameter is ignored
  639. * \param dgst pointer to the hash value
  640. * \param dgstlen length of the hash value
  641. * \param sig pointer to the DER encoded signature
  642. * \param siglen length of the DER encoded signature
  643. * \param eckey pointer to the EC_KEY object containing a public EC key
  644. * \return 1 if the signature is valid, 0 if the signature is invalid and -1 on error
  645. */
  646. int SM2_verify(int type, const unsigned char *dgst, int dgst_len,
  647. const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
  648. {
  649. ECDSA_SIG *s;
  650. int ret=-1;
  651. s = ECDSA_SIG_new();
  652. if (s == NULL) return(ret);
  653. if (d2i_ECDSA_SIG(&s, &sigbuf, sig_len) == NULL) goto err;
  654. ret=sm2_do_verify(dgst, dgst_len, s, eckey);
  655. err:
  656. ECDSA_SIG_free(s);
  657. return(ret);
  658. }
  659. int SM2_DH_key(const EC_GROUP * group, const EC_POINT *b_pub_key_r, const EC_POINT *b_pub_key, const BIGNUM *a_r,EC_KEY *a_eckey,
  660. unsigned char *outkey,size_t keylen)
  661. {
  662. EC_POINT *dhpoint = NULL;
  663. BN_CTX * ctx;
  664. EC_POINT *P;
  665. BIGNUM *x, *y;
  666. int ret = 0;
  667. unsigned char in[128];
  668. int inlen;
  669. int len;
  670. P = EC_POINT_new(group);
  671. if (!P ) goto err;
  672. ctx = BN_CTX_new();
  673. x = BN_new();
  674. y = BN_new();
  675. if (!x || !y ) goto err;
  676. dhpoint = sm2_compute_key(b_pub_key_r,b_pub_key,a_r,a_eckey);
  677. if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
  678. {
  679. if (!EC_POINT_get_affine_coordinates_GFp(group,dhpoint, x, y, ctx))
  680. {
  681. fprintf(stdout, " failed\n");
  682. goto err;
  683. }
  684. }
  685. else
  686. {
  687. if (!EC_POINT_get_affine_coordinates_GF2m(group,dhpoint, x, y, ctx))
  688. {
  689. ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
  690. goto err;
  691. }
  692. }
  693. // if (!EC_POINT_get_affine_coordinates_GFp(group,dhpoint, x, y, ctx))
  694. // {
  695. // fprintf(stdout, " failed\n");
  696. // goto err;
  697. // }
  698. fprintf(stdout, "\nTesting DH Point\n Xv = 0x");
  699. BNPrintf(x);
  700. fprintf(stdout, "\n Yv = 0x");
  701. BNPrintf( y);
  702. fprintf(stdout, "\n");
  703. len = BN_bn2bin(x,in);
  704. inlen =BN_bn2bin(y,in+len);
  705. inlen = inlen + len;
  706. ret = x9_63_kdf(EVP_sha256(),in,inlen,keylen,outkey);
  707. //ret = 1;
  708. err:
  709. EC_POINT_free(P);
  710. EC_POINT_free(dhpoint);
  711. BN_CTX_free(ctx);
  712. return ret;
  713. }

sm2 test:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <time.h>
  5. #include <openssl/bn.h>
  6. #include <openssl/ec.h>
  7. #include <openssl/rand.h>
  8. #include <openssl/err.h>
  9. #include <openssl/ecdsa.h>
  10. #include <openssl/ecdh.h>
  11. #include "sm2.h"
  12. #pragma comment(lib,"libeay32.lib")
  13. #define ABORT do { \
  14. fflush(stdout); \
  15. fprintf(stderr, "%s:%d: ABORT\n", __FILE__, __LINE__); \
  16. ERR_print_errors_fp(stderr); \
  17. exit(1); \
  18. } while (0)
  19. static const char rnd_seed[] = "string to make the random number generator think it has entropy";
  20. void BNPrintf(BIGNUM* bn)
  21. {
  22. char *p=NULL;
  23. p=BN_bn2hex(bn);
  24. printf("%s",p);
  25. OPENSSL_free(p);
  26. }
  27. int SM2_Test_Vecotor()
  28. {
  29. BN_CTX *ctx = NULL;
  30. BIGNUM *p, *a, *b;
  31. EC_GROUP *group;
  32. EC_POINT *P, *Q, *R;
  33. BIGNUM *x, *y, *z;
  34. EC_KEY *eckey = NULL;
  35. unsigned char digest[20];
  36. unsigned char *signature = NULL;
  37. int sig_len;
  38. CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
  39. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
  40. ERR_load_crypto_strings();
  41. RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */
  42. ctx = BN_CTX_new();
  43. if (!ctx) ABORT;
  44. /* Curve SM2 (Chinese National Algorithm) */
  45. //http://www.oscca.gov.cn/News/201012/News_1197.htm
  46. p = BN_new();
  47. a = BN_new();
  48. b = BN_new();
  49. if (!p || !a || !b) ABORT;
  50. group = EC_GROUP_new(EC_GFp_mont_method()); /* applications should use EC_GROUP_new_curve_GFp
  51. * so that the library gets to choose the EC_METHOD */
  52. if (!group) ABORT;
  53. if (!BN_hex2bn(&p, "8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3")) ABORT;
  54. if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
  55. if (!BN_hex2bn(&a, "787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498")) ABORT;
  56. if (!BN_hex2bn(&b, "63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A")) ABORT;
  57. if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
  58. P = EC_POINT_new(group);
  59. Q = EC_POINT_new(group);
  60. R = EC_POINT_new(group);
  61. if (!P || !Q || !R) ABORT;
  62. x = BN_new();
  63. y = BN_new();
  64. z = BN_new();
  65. if (!x || !y || !z) ABORT;
  66. // sm2 testing P256 Vetor
  67. // p£º8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3
  68. // a£º787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498
  69. // b£º63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A
  70. // xG 421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D
  71. // yG 0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2
  72. // n: 8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7
  73. if (!BN_hex2bn(&x, "421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D")) ABORT;
  74. if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;
  75. if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
  76. if (!BN_hex2bn(&z, "8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7")) ABORT;
  77. if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
  78. if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
  79. fprintf(stdout, "\nChinese sm2 algorithm test -- Generator:\n x = 0x");
  80. BNPrintf(x);
  81. fprintf(stdout, "\n y = 0x");
  82. BNPrintf( y);
  83. fprintf(stdout, "\n");
  84. /* G_y value taken from the standard: */
  85. if (!BN_hex2bn(&z, "0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2")) ABORT;
  86. if (0 != BN_cmp(y, z)) ABORT;
  87. fprintf(stdout, "verify degree ...");
  88. if (EC_GROUP_get_degree(group) != 256) ABORT;
  89. fprintf(stdout, " ok\n");
  90. fprintf(stdout, "verify group order ...");
  91. fflush(stdout);
  92. if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
  93. if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
  94. if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
  95. if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
  96. fflush(stdout);
  97. fprintf(stdout, " ok\n");
  98. //testing ECDSA for SM2
  99. /* create new ecdsa key */
  100. if ((eckey = EC_KEY_new()) == NULL)
  101. goto builtin_err;
  102. if (EC_KEY_set_group(eckey, group) == 0)
  103. {
  104. fprintf(stdout," failed\n");
  105. goto builtin_err;
  106. }
  107. /* create key */
  108. if (!EC_KEY_generate_key(eckey))
  109. {
  110. fprintf(stdout," failed\n");
  111. goto builtin_err;
  112. }
  113. /* check key */
  114. if (!EC_KEY_check_key(eckey))
  115. {
  116. fprintf(stdout," failed\n");
  117. goto builtin_err;
  118. }
  119. /* create signature */
  120. sig_len = ECDSA_size(eckey);
  121. fprintf(stdout,"Siglength is: %d \n",sig_len);
  122. if (!RAND_pseudo_bytes(digest, 20))
  123. {
  124. fprintf(stdout," failed\n");
  125. goto builtin_err;
  126. }
  127. if ((signature = OPENSSL_malloc(sig_len)) == NULL)
  128. goto builtin_err;
  129. if (!SM2_sign(0, digest, 20, signature, &sig_len, eckey))
  130. {
  131. fprintf(stdout, " failed\n");
  132. goto builtin_err;
  133. }
  134. fprintf(stdout, "ECSign OK\n");
  135. /* verify signature */
  136. if (SM2_verify(0, digest, 20, signature, sig_len, eckey) != 1)
  137. {
  138. fprintf(stdout, " failed\n");
  139. goto builtin_err;
  140. }
  141. fprintf(stdout, "ECVerify OK\n");
  142. /* cleanup */
  143. OPENSSL_free(signature);
  144. signature = NULL;
  145. EC_KEY_free(eckey);
  146. eckey = NULL;
  147. builtin_err:
  148. EC_POINT_free(P);
  149. EC_POINT_free(Q);
  150. EC_POINT_free(R);
  151. EC_GROUP_free(group);
  152. BN_CTX_free(ctx);
  153. return 0;
  154. }
  155. int SM2_Test_Vecotor2()
  156. {
  157. BN_CTX *ctx = NULL;
  158. BIGNUM *p, *a, *b;
  159. EC_GROUP *group;
  160. EC_POINT *P, *Q, *R;
  161. BIGNUM *x, *y, *z;
  162. EC_KEY *eckey = NULL;
  163. unsigned char *signature;
  164. unsigned char digest[32] = "\xB5\x24\xF5\x52\xCD\x82\xB8\xB0\x28\x47\x6E\x00\x5C\x37\x7F\xB1\x9A\x87\xE6\xFC\x68\x2D\x48\xBB\x5D\x42\xE3\xD9\xB9\xEF\xFE\x76";
  165. int sig_len;
  166. BIGNUM *kinv, *rp,*order;
  167. ECDSA_SIG *ecsig = ECDSA_SIG_new();
  168. EC_POINT * DHPoint = NULL;
  169. // unsigned char *in="123456";
  170. // size_t inlen = 6;
  171. size_t outlen = 256;
  172. unsigned char outkey[256];
  173. size_t keylen = 256;
  174. size_t i;
  175. CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
  176. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
  177. ERR_load_crypto_strings();
  178. RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */
  179. ctx = BN_CTX_new();
  180. if (!ctx) ABORT;
  181. /* Curve SM2 (Chinese National Algorithm) */
  182. //http://www.oscca.gov.cn/News/201012/News_1197.htm
  183. p = BN_new();
  184. a = BN_new();
  185. b = BN_new();
  186. if (!p || !a || !b) ABORT;
  187. group = EC_GROUP_new(EC_GFp_mont_method()); /* applications should use EC_GROUP_new_curve_GFp
  188. * so that the library gets to choose the EC_METHOD */
  189. if (!group) ABORT;
  190. if (!BN_hex2bn(&p, "8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3")) ABORT;
  191. if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
  192. if (!BN_hex2bn(&a, "787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498")) ABORT;
  193. if (!BN_hex2bn(&b, "63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A")) ABORT;
  194. if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
  195. P = EC_POINT_new(group);
  196. Q = EC_POINT_new(group);
  197. R = EC_POINT_new(group);
  198. if (!P || !Q || !R) ABORT;
  199. x = BN_new();
  200. y = BN_new();
  201. z = BN_new();
  202. if (!x || !y || !z) ABORT;
  203. // sm2 testing P256 Vetor
  204. // p£º8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3
  205. // a£º787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498
  206. // b£º63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A
  207. // xG 421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D
  208. // yG 0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2
  209. // n: 8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7
  210. if (!BN_hex2bn(&x, "421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D")) ABORT;
  211. if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;
  212. if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
  213. if (!BN_hex2bn(&z, "8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7")) ABORT;
  214. if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
  215. if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
  216. fprintf(stdout, "\nChinese sm2 algorithm test -- Generator:\n x = 0x");
  217. BNPrintf(x);
  218. fprintf(stdout, "\n y = 0x");
  219. BNPrintf( y);
  220. fprintf(stdout, "\n");
  221. /* G_y value taken from the standard: */
  222. if (!BN_hex2bn(&z, "0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2")) ABORT;
  223. if (0 != BN_cmp(y, z)) ABORT;
  224. fprintf(stdout, "verify degree ...");
  225. if (EC_GROUP_get_degree(group) != 256) ABORT;
  226. fprintf(stdout, " ok\n");
  227. fprintf(stdout, "verify group order ...");
  228. fflush(stdout);
  229. if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
  230. if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
  231. if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
  232. if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
  233. fflush(stdout);
  234. fprintf(stdout, " ok\n");
  235. //testing ECDSA for SM2
  236. /* create new ecdsa key */
  237. if ((eckey = EC_KEY_new()) == NULL)
  238. goto builtin_err;
  239. if (EC_KEY_set_group(eckey, group) == 0)
  240. {
  241. fprintf(stdout," failed\n");
  242. goto builtin_err;
  243. }
  244. /* create key */
  245. if (!BN_hex2bn(&z, "128B2FA8BD433C6C068C8D803DFF79792A519A55171B1B650C23661D15897263")) ABORT;
  246. if (!EC_POINT_mul(group,P, z, NULL, NULL, ctx)) ABORT;
  247. if (!EC_POINT_get_affine_coordinates_GFp(group,P, x, y, ctx)) ABORT;
  248. fprintf(stdout, "\nTesting ECKey Point\n x = 0x");
  249. BNPrintf(x);
  250. fprintf(stdout, "\n y = 0x");
  251. BNPrintf( y);
  252. fprintf(stdout, "\n");
  253. EC_KEY_set_private_key(eckey,z);
  254. EC_KEY_set_public_key(eckey, P);
  255. /* check key */
  256. if (!EC_KEY_check_key(eckey))
  257. {
  258. fprintf(stdout," failed\n");
  259. goto builtin_err;
  260. }
  261. /* create signature */
  262. sig_len = ECDSA_size(eckey);
  263. //fprintf(stdout,"Siglength is: %d \n",sig_len);
  264. if ((signature = OPENSSL_malloc(sig_len)) == NULL)
  265. goto builtin_err;
  266. rp = BN_new();
  267. kinv = BN_new();
  268. order = BN_new();
  269. if (!BN_hex2bn(&z, "6CB28D99385C175C94F94E934817663FC176D925DD72B727260DBAAE1FB2F96F")) ABORT;
  270. if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx))
  271. {
  272. fprintf(stdout, " failed\n");
  273. goto builtin_err;
  274. }
  275. if (!EC_POINT_get_affine_coordinates_GFp(group,Q, x, y, ctx))
  276. {
  277. fprintf(stdout, " failed\n");
  278. goto builtin_err;
  279. }
  280. fprintf(stdout, "\nTesting K Point\n x = 0x");
  281. BNPrintf(x);
  282. fprintf(stdout, "\n y = 0x");
  283. BNPrintf( y);
  284. fprintf(stdout, "\n");
  285. EC_GROUP_get_order(group, order, ctx);
  286. if (!BN_nnmod(rp, x, order, ctx))
  287. {
  288. fprintf(stdout, " failed\n");
  289. goto builtin_err;
  290. }
  291. if (!BN_copy(kinv, z ))
  292. {
  293. fprintf(stdout, " failed\n");
  294. goto builtin_err;
  295. }
  296. // for(i=0;i<32;i++)
  297. // printf("%02X",digest[i]);
  298. // printf("\n");
  299. if (!SM2_sign_ex(1, digest, 32, signature, &sig_len, kinv, rp, eckey))
  300. {
  301. fprintf(stdout, " failed\n");
  302. goto builtin_err;
  303. }
  304. fprintf(stdout, "ECSign OK\n");
  305. /* verify signature */
  306. if (SM2_verify(1, digest, 32, signature, sig_len, eckey) != 1)
  307. {
  308. fprintf(stdout, " failed\n");
  309. goto builtin_err;
  310. }
  311. fprintf(stdout, "ECVerify OK\n r = 0x");
  312. d2i_ECDSA_SIG(&ecsig, &signature, sig_len);
  313. BNPrintf(ecsig->r);
  314. fprintf(stdout,"\n s = 0x");
  315. BNPrintf(ecsig->s);
  316. fprintf(stdout,"\n");
  317. //testing SM2DH vector
  318. /* create key */
  319. if (!BN_hex2bn(&z, "6FCBA2EF9AE0AB902BC3BDE3FF915D44BA4CC78F88E2F8E7F8996D3B8CCEEDEE")) ABORT;
  320. if (!EC_POINT_mul(group,P, z, NULL, NULL, ctx)) ABORT;
  321. if (!EC_POINT_get_affine_coordinates_GFp(group,P, x, y, ctx)) ABORT;
  322. fprintf(stdout, "\nTesting A Key Point\n x = 0x");
  323. BNPrintf(x);
  324. fprintf(stdout, "\n y = 0x");
  325. BNPrintf( y);
  326. fprintf(stdout, "\n");
  327. EC_KEY_set_private_key(eckey,z);
  328. EC_KEY_set_public_key(eckey, P);
  329. if (!BN_hex2bn(&z, "5E35D7D3F3C54DBAC72E61819E730B019A84208CA3A35E4C2E353DFCCB2A3B53")) ABORT;
  330. if (!EC_POINT_mul(group,Q, z, NULL, NULL, ctx)) ABORT;
  331. if (!EC_POINT_get_affine_coordinates_GFp(group,Q, x, y, ctx)) ABORT;
  332. fprintf(stdout, "\nTesting B Key Point\n x = 0x");
  333. BNPrintf(x);
  334. fprintf(stdout, "\n y = 0x");
  335. BNPrintf( y);
  336. fprintf(stdout, "\n");
  337. //EC_KEY_set_private_key(eckey,z);
  338. //EC_KEY_set_public_key(eckey, P);
  339. if (!BN_hex2bn(&z, "33FE21940342161C55619C4A0C060293D543C80AF19748CE176D83477DE71C80")) ABORT;
  340. if (!EC_POINT_mul(group,P, z, NULL, NULL, ctx)) ABORT;
  341. if (!EC_POINT_get_affine_coordinates_GFp(group,P, x, y, ctx)) ABORT;
  342. fprintf(stdout, "\nTesting Rb Key Point\n x = 0x");
  343. BNPrintf(x);
  344. fprintf(stdout, "\n y = 0x");
  345. BNPrintf( y);
  346. fprintf(stdout, "\n");
  347. if (!BN_hex2bn(&z, "83A2C9C8B96E5AF70BD480B472409A9A327257F1EBB73F5B073354B248668563")) ABORT;
  348. if (!EC_POINT_mul(group,R, z, NULL, NULL, ctx)) ABORT;
  349. if (!EC_POINT_get_affine_coordinates_GFp(group,R, x, y, ctx)) ABORT;
  350. fprintf(stdout, "\nTesting Ra Key Point\n x = 0x");
  351. BNPrintf(x);
  352. fprintf(stdout, "\n y = 0x");
  353. BNPrintf( y);
  354. fprintf(stdout, "\n");
  355. SM2_DH_key(group,P, Q, z,eckey,outkey,keylen);
  356. fprintf(stdout,"\nExchange key --KDF(Xv||Yv)-- :");
  357. for(i=0; i<outlen; i++)
  358. printf("%02X",outkey[i]);
  359. printf("\n");
  360. builtin_err:
  361. OPENSSL_free(signature);
  362. signature = NULL;
  363. EC_POINT_free(P);
  364. EC_POINT_free(Q);
  365. EC_POINT_free(R);
  366. EC_POINT_free(DHPoint);
  367. EC_KEY_free(eckey);
  368. eckey = NULL;
  369. EC_GROUP_free(group);
  370. BN_CTX_free(ctx);
  371. return 0;
  372. }
  373. int main()
  374. {
  375. CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
  376. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
  377. ERR_load_crypto_strings();
  378. RAND_seed(rnd_seed, sizeof rnd_seed);
  379. SM2_Test_Vecotor2();
  380. CRYPTO_cleanup_all_ex_data();
  381. ERR_free_strings();
  382. ERR_remove_state(0);
  383. CRYPTO_mem_leaks_fp(stderr);
  384. return 0;
  385. }
  • SM3杂凑算法
  • 用途:商用密码应用中的数字签名和验证,消息认证码的生成与验证以及随机数的生成。
  • 密码学对应算法:SHA-1,SHA-3,MD5

    sm3:

  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. }

sm3test

  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:\n");
  12. printf("%s\n",input);
  13. sm3(input, ilen, output);
  14. printf("Hash:\n ");
  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:\n");
  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:\n ");
  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. }
  • SM4对称分组算法
  • 用途:无线局域网产品。
  • 密码学对应算法:DES,AES

    SM4:

  1. /*
  2. * SM4 Encryption alogrithm (SMS4 algorithm)
  3. * GM/T 0002-2012 Chinese National Standard ref:http://www.oscca.gov.cn/
  4. * thanks to Xyssl
  5. * thnaks and refers to http://hi.baidu.com/numax/blog/item/80addfefddfb93e4cf1b3e61.html
  6. * author:goldboar
  7. * email:goldboar@163.com
  8. * 2012-4-20
  9. */
  10. // Test vector 1
  11. // plain: 01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10
  12. // key: 01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10
  13. // round key and temp computing result:
  14. // rk[ 0] = f12186f9 X[ 0] = 27fad345
  15. // rk[ 1] = 41662b61 X[ 1] = a18b4cb2
  16. // rk[ 2] = 5a6ab19a X[ 2] = 11c1e22a
  17. // rk[ 3] = 7ba92077 X[ 3] = cc13e2ee
  18. // rk[ 4] = 367360f4 X[ 4] = f87c5bd5
  19. // rk[ 5] = 776a0c61 X[ 5] = 33220757
  20. // rk[ 6] = b6bb89b3 X[ 6] = 77f4c297
  21. // rk[ 7] = 24763151 X[ 7] = 7a96f2eb
  22. // rk[ 8] = a520307c X[ 8] = 27dac07f
  23. // rk[ 9] = b7584dbd X[ 9] = 42dd0f19
  24. // rk[10] = c30753ed X[10] = b8a5da02
  25. // rk[11] = 7ee55b57 X[11] = 907127fa
  26. // rk[12] = 6988608c X[12] = 8b952b83
  27. // rk[13] = 30d895b7 X[13] = d42b7c59
  28. // rk[14] = 44ba14af X[14] = 2ffc5831
  29. // rk[15] = 104495a1 X[15] = f69e6888
  30. // rk[16] = d120b428 X[16] = af2432c4
  31. // rk[17] = 73b55fa3 X[17] = ed1ec85e
  32. // rk[18] = cc874966 X[18] = 55a3ba22
  33. // rk[19] = 92244439 X[19] = 124b18aa
  34. // rk[20] = e89e641f X[20] = 6ae7725f
  35. // rk[21] = 98ca015a X[21] = f4cba1f9
  36. // rk[22] = c7159060 X[22] = 1dcdfa10
  37. // rk[23] = 99e1fd2e X[23] = 2ff60603
  38. // rk[24] = b79bd80c X[24] = eff24fdc
  39. // rk[25] = 1d2115b0 X[25] = 6fe46b75
  40. // rk[26] = 0e228aeb X[26] = 893450ad
  41. // rk[27] = f1780c81 X[27] = 7b938f4c
  42. // rk[28] = 428d3654 X[28] = 536e4246
  43. // rk[29] = 62293496 X[29] = 86b3e94f
  44. // rk[30] = 01cf72e5 X[30] = d206965e
  45. // rk[31] = 9124a012 X[31] = 681edf34
  46. // cypher: 68 1e df 34 d2 06 96 5e 86 b3 e9 4f 53 6e 42 46
  47. //
  48. // test vector 2
  49. // the same key and plain 1000000 times coumpting
  50. // plain: 01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10
  51. // key: 01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10
  52. // cypher: 59 52 98 c7 c6 fd 27 1f 04 02 f8 04 c3 3d 3f 66
  53. #include "sm4.h"
  54. #include <string.h>
  55. #include <stdio.h>
  56. /*
  57. * 32-bit integer manipulation macros (big endian)
  58. */
  59. #ifndef GET_ULONG_BE
  60. #define GET_ULONG_BE(n,b,i) \
  61. { \
  62. (n) = ( (unsigned long) (b)[(i) ] << 24 ) \
  63. | ( (unsigned long) (b)[(i) + 1] << 16 ) \
  64. | ( (unsigned long) (b)[(i) + 2] << 8 ) \
  65. | ( (unsigned long) (b)[(i) + 3] ); \
  66. }
  67. #endif
  68. #ifndef PUT_ULONG_BE
  69. #define PUT_ULONG_BE(n,b,i) \
  70. { \
  71. (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
  72. (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
  73. (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
  74. (b)[(i) + 3] = (unsigned char) ( (n) ); \
  75. }
  76. #endif
  77. /*
  78. *rotate shift left marco definition
  79. *
  80. */
  81. #define SHL(x,n) (((x) & 0xFFFFFFFF) << n)
  82. #define ROTL(x,n) (SHL((x),n) | ((x) >> (32 - n)))
  83. #define SWAP(a,b) { unsigned long t = a; a = b; b = t; t = 0; }
  84. /*
  85. * Expanded SM4 S-boxes
  86. /* Sbox table: 8bits input convert to 8 bits output*/
  87. static const unsigned char SboxTable[16][16] =
  88. {
  89. {0xd6,0x90,0xe9,0xfe,0xcc,0xe1,0x3d,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05},
  90. {0x2b,0x67,0x9a,0x76,0x2a,0xbe,0x04,0xc3,0xaa,0x44,0x13,0x26,0x49,0x86,0x06,0x99},
  91. {0x9c,0x42,0x50,0xf4,0x91,0xef,0x98,0x7a,0x33,0x54,0x0b,0x43,0xed,0xcf,0xac,0x62},
  92. {0xe4,0xb3,0x1c,0xa9,0xc9,0x08,0xe8,0x95,0x80,0xdf,0x94,0xfa,0x75,0x8f,0x3f,0xa6},
  93. {0x47,0x07,0xa7,0xfc,0xf3,0x73,0x17,0xba,0x83,0x59,0x3c,0x19,0xe6,0x85,0x4f,0xa8},
  94. {0x68,0x6b,0x81,0xb2,0x71,0x64,0xda,0x8b,0xf8,0xeb,0x0f,0x4b,0x70,0x56,0x9d,0x35},
  95. {0x1e,0x24,0x0e,0x5e,0x63,0x58,0xd1,0xa2,0x25,0x22,0x7c,0x3b,0x01,0x21,0x78,0x87},
  96. {0xd4,0x00,0x46,0x57,0x9f,0xd3,0x27,0x52,0x4c,0x36,0x02,0xe7,0xa0,0xc4,0xc8,0x9e},
  97. {0xea,0xbf,0x8a,0xd2,0x40,0xc7,0x38,0xb5,0xa3,0xf7,0xf2,0xce,0xf9,0x61,0x15,0xa1},
  98. {0xe0,0xae,0x5d,0xa4,0x9b,0x34,0x1a,0x55,0xad,0x93,0x32,0x30,0xf5,0x8c,0xb1,0xe3},
  99. {0x1d,0xf6,0xe2,0x2e,0x82,0x66,0xca,0x60,0xc0,0x29,0x23,0xab,0x0d,0x53,0x4e,0x6f},
  100. {0xd5,0xdb,0x37,0x45,0xde,0xfd,0x8e,0x2f,0x03,0xff,0x6a,0x72,0x6d,0x6c,0x5b,0x51},
  101. {0x8d,0x1b,0xaf,0x92,0xbb,0xdd,0xbc,0x7f,0x11,0xd9,0x5c,0x41,0x1f,0x10,0x5a,0xd8},
  102. {0x0a,0xc1,0x31,0x88,0xa5,0xcd,0x7b,0xbd,0x2d,0x74,0xd0,0x12,0xb8,0xe5,0xb4,0xb0},
  103. {0x89,0x69,0x97,0x4a,0x0c,0x96,0x77,0x7e,0x65,0xb9,0xf1,0x09,0xc5,0x6e,0xc6,0x84},
  104. {0x18,0xf0,0x7d,0xec,0x3a,0xdc,0x4d,0x20,0x79,0xee,0x5f,0x3e,0xd7,0xcb,0x39,0x48}
  105. };
  106. /* System parameter */
  107. static const unsigned long FK[4] = {0xa3b1bac6,0x56aa3350,0x677d9197,0xb27022dc};
  108. /* fixed parameter */
  109. static const unsigned long CK[32] =
  110. {
  111. 0x00070e15,0x1c232a31,0x383f464d,0x545b6269,
  112. 0x70777e85,0x8c939aa1,0xa8afb6bd,0xc4cbd2d9,
  113. 0xe0e7eef5,0xfc030a11,0x181f262d,0x343b4249,
  114. 0x50575e65,0x6c737a81,0x888f969d,0xa4abb2b9,
  115. 0xc0c7ced5,0xdce3eaf1,0xf8ff060d,0x141b2229,
  116. 0x30373e45,0x4c535a61,0x686f767d,0x848b9299,
  117. 0xa0a7aeb5,0xbcc3cad1,0xd8dfe6ed,0xf4fb0209,
  118. 0x10171e25,0x2c333a41,0x484f565d,0x646b7279
  119. };
  120. /*
  121. * private function:
  122. * look up in SboxTable and get the related value.
  123. * args: [in] inch: 0x00~0xFF (8 bits unsigned value).
  124. */
  125. static unsigned char sm4Sbox(unsigned char inch)
  126. {
  127. unsigned char *pTable = (unsigned char *)SboxTable;
  128. unsigned char retVal = (unsigned char)(pTable[inch]);
  129. return retVal;
  130. }
  131. /*
  132. * private F(Lt) function:
  133. * "T algorithm" == "L algorithm" + "t algorithm".
  134. * args: [in] a: a is a 32 bits unsigned value;
  135. * return: c: c is calculated with line algorithm "L" and nonline algorithm "t"
  136. */
  137. static unsigned long sm4Lt(unsigned long ka)
  138. {
  139. unsigned long bb = 0;
  140. unsigned long c = 0;
  141. unsigned char a[4];
  142. unsigned char b[4];
  143. PUT_ULONG_BE(ka,a,0)
  144. b[0] = sm4Sbox(a[0]);
  145. b[1] = sm4Sbox(a[1]);
  146. b[2] = sm4Sbox(a[2]);
  147. b[3] = sm4Sbox(a[3]);
  148. GET_ULONG_BE(bb,b,0)
  149. c =bb^(ROTL(bb, 2))^(ROTL(bb, 10))^(ROTL(bb, 18))^(ROTL(bb, 24));
  150. return c;
  151. }
  152. /*
  153. * private F function:
  154. * Calculating and getting encryption/decryption contents.
  155. * args: [in] x0: original contents;
  156. * args: [in] x1: original contents;
  157. * args: [in] x2: original contents;
  158. * args: [in] x3: original contents;
  159. * args: [in] rk: encryption/decryption key;
  160. * return the contents of encryption/decryption contents.
  161. */
  162. static unsigned long sm4F(unsigned long x0, unsigned long x1, unsigned long x2, unsigned long x3, unsigned long rk)
  163. {
  164. return (x0^sm4Lt(x1^x2^x3^rk));
  165. }
  166. /* private function:
  167. * Calculating round encryption key.
  168. * args: [in] a: a is a 32 bits unsigned value;
  169. * return: sk[i]: i{0,1,2,3,...31}.
  170. */
  171. static unsigned long sm4CalciRK(unsigned long ka)
  172. {
  173. unsigned long bb = 0;
  174. unsigned long rk = 0;
  175. unsigned char a[4];
  176. unsigned char b[4];
  177. PUT_ULONG_BE(ka,a,0)
  178. b[0] = sm4Sbox(a[0]);
  179. b[1] = sm4Sbox(a[1]);
  180. b[2] = sm4Sbox(a[2]);
  181. b[3] = sm4Sbox(a[3]);
  182. GET_ULONG_BE(bb,b,0)
  183. rk = bb^(ROTL(bb, 13))^(ROTL(bb, 23));
  184. return rk;
  185. }
  186. static void sm4_setkey( unsigned long SK[32], unsigned char key[16] )
  187. {
  188. unsigned long MK[4];
  189. unsigned long k[36];
  190. unsigned long i = 0;
  191. GET_ULONG_BE( MK[0], key, 0 );
  192. GET_ULONG_BE( MK[1], key, 4 );
  193. GET_ULONG_BE( MK[2], key, 8 );
  194. GET_ULONG_BE( MK[3], key, 12 );
  195. k[0] = MK[0]^FK[0];
  196. k[1] = MK[1]^FK[1];
  197. k[2] = MK[2]^FK[2];
  198. k[3] = MK[3]^FK[3];
  199. for(; i<32; i++)
  200. {
  201. k[i+4] = k[i] ^ (sm4CalciRK(k[i+1]^k[i+2]^k[i+3]^CK[i]));
  202. SK[i] = k[i+4];
  203. }
  204. }
  205. /*
  206. * SM4 standard one round processing
  207. *
  208. */
  209. static void sm4_one_round( unsigned long sk[32],
  210. unsigned char input[16],
  211. unsigned char output[16] )
  212. {
  213. unsigned long i = 0;
  214. unsigned long ulbuf[36];
  215. memset(ulbuf, 0, sizeof(ulbuf));
  216. GET_ULONG_BE( ulbuf[0], input, 0 )
  217. GET_ULONG_BE( ulbuf[1], input, 4 )
  218. GET_ULONG_BE( ulbuf[2], input, 8 )
  219. GET_ULONG_BE( ulbuf[3], input, 12 )
  220. while(i<32)
  221. {
  222. ulbuf[i+4] = sm4F(ulbuf[i], ulbuf[i+1], ulbuf[i+2], ulbuf[i+3], sk[i]);
  223. // #ifdef _DEBUG
  224. // printf("rk(%02d) = 0x%08x, X(%02d) = 0x%08x \n",i,sk[i], i, ulbuf[i+4] );
  225. // #endif
  226. i++;
  227. }
  228. PUT_ULONG_BE(ulbuf[35],output,0);
  229. PUT_ULONG_BE(ulbuf[34],output,4);
  230. PUT_ULONG_BE(ulbuf[33],output,8);
  231. PUT_ULONG_BE(ulbuf[32],output,12);
  232. }
  233. /*
  234. * SM4 key schedule (128-bit, encryption)
  235. */
  236. void sm4_setkey_enc( sm4_context *ctx, unsigned char key[16] )
  237. {
  238. ctx->mode = SM4_ENCRYPT;
  239. sm4_setkey( ctx->sk, key );
  240. }
  241. /*
  242. * SM4 key schedule (128-bit, decryption)
  243. */
  244. void sm4_setkey_dec( sm4_context *ctx, unsigned char key[16] )
  245. {
  246. int i;
  247. ctx->mode = SM4_ENCRYPT;
  248. sm4_setkey( ctx->sk, key );
  249. for( i = 0; i < 16; i ++ )
  250. {
  251. SWAP( ctx->sk[ i ], ctx->sk[ 31-i] );
  252. }
  253. }
  254. /*
  255. * SM4-ECB block encryption/decryption
  256. */
  257. void sm4_crypt_ecb( sm4_context *ctx,
  258. int mode,
  259. int length,
  260. unsigned char *input,
  261. unsigned char *output)
  262. {
  263. while( length > 0 )
  264. {
  265. sm4_one_round( ctx->sk, input, output );
  266. input += 16;
  267. output += 16;
  268. length -= 16;
  269. }
  270. }
  271. /*
  272. * SM4-CBC buffer encryption/decryption
  273. */
  274. void sm4_crypt_cbc( sm4_context *ctx,
  275. int mode,
  276. int length,
  277. unsigned char iv[16],
  278. unsigned char *input,
  279. unsigned char *output )
  280. {
  281. int i;
  282. unsigned char temp[16];
  283. if( mode == SM4_ENCRYPT )
  284. {
  285. while( length > 0 )
  286. {
  287. for( i = 0; i < 16; i++ )
  288. output[i] = (unsigned char)( input[i] ^ iv[i] );
  289. sm4_one_round( ctx->sk, output, output );
  290. memcpy( iv, output, 16 );
  291. input += 16;
  292. output += 16;
  293. length -= 16;
  294. }
  295. }
  296. else /* SM4_DECRYPT */
  297. {
  298. while( length > 0 )
  299. {
  300. memcpy( temp, input, 16 );
  301. sm4_one_round( ctx->sk, input, output );
  302. for( i = 0; i < 16; i++ )
  303. output[i] = (unsigned char)( output[i] ^ iv[i] );
  304. memcpy( iv, temp, 16 );
  305. input += 16;
  306. output += 16;
  307. length -= 16;
  308. }
  309. }
  310. }

sm4test

  1. /*
  2. * SM4/SMS4 algorithm test programme
  3. * 2012-4-21
  4. */
  5. #include <string.h>
  6. #include <stdio.h>
  7. #include "sm4.h"
  8. int main()
  9. {
  10. unsigned char key[16] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
  11. unsigned char input[16] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
  12. unsigned char output[16];
  13. sm4_context ctx;
  14. unsigned long i;
  15. //encrypt standard testing vector
  16. sm4_setkey_enc(&ctx,key);
  17. sm4_crypt_ecb(&ctx,1,16,input,output);
  18. for(i=0;i<16;i++)
  19. printf("%02x ", output[i]);
  20. printf("\n");
  21. //decrypt testing
  22. sm4_setkey_dec(&ctx,key);
  23. sm4_crypt_ecb(&ctx,0,16,output,output);
  24. for(i=0;i<16;i++)
  25. printf("%02x ", output[i]);
  26. printf("\n");
  27. //decrypt 1M times testing vector based on standards.
  28. i = 0;
  29. sm4_setkey_enc(&ctx,key);
  30. while (i<1000000)
  31. {
  32. sm4_crypt_ecb(&ctx,1,16,input,input);
  33. i++;
  34. }
  35. for(i=0;i<16;i++)
  36. printf("%02x ", input[i]);
  37. printf("\n");
  38. return 0;
  39. }

运行截图:

1072527-20171105230439451-178644644.png

实验感想:

  • 实验比较简单,一步一步走就完成了实验,对此我还是比较满意的。因为这次实验比较容易。

转载于:https://www.cnblogs.com/zx20155202/p/7789917.html

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

闽ICP备14008679号