bign_test.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. /*
  2. *******************************************************************************
  3. \file bign_test.c
  4. \brief Tests for STB 34.101.45 (bign)
  5. \project bee2/test
  6. \created 2012.08.27
  7. \version 2023.09.25
  8. \copyright The Bee2 authors
  9. \license Licensed under the Apache License, Version 2.0 (see LICENSE.txt).
  10. *******************************************************************************
  11. */
  12. #include <bee2/core/err.h>
  13. #include <bee2/core/mem.h>
  14. #include <bee2/core/hex.h>
  15. #include <bee2/core/str.h>
  16. #include <bee2/core/util.h>
  17. #include <bee2/math/ww.h>
  18. #include <bee2/math/zz.h>
  19. #include <bee2/crypto/bign.h>
  20. #include <bee2/crypto/belt.h>
  21. #include <bee2/crypto/brng.h>
  22. /*
  23. *******************************************************************************
  24. brngCTRX: Расширение brngCTR
  25. -# При инициализации можно передать дополнительное слово X.
  26. *******************************************************************************
  27. */
  28. typedef struct
  29. {
  30. const octet* X; /*< дополнительное слово */
  31. size_t count; /*< размер X в октетах */
  32. size_t offset; /*< текущее смещение в X */
  33. octet state_ex[]; /*< состояние brngCTR */
  34. } brng_ctrx_st;
  35. static size_t brngCTRX_keep()
  36. {
  37. return sizeof(brng_ctrx_st) + brngCTR_keep();
  38. }
  39. static void brngCTRXStart(const octet key[32], const octet iv[32],
  40. const void* X, size_t count, void* state)
  41. {
  42. brng_ctrx_st* s = (brng_ctrx_st*)state;
  43. ASSERT(memIsValid(s, sizeof(brng_ctrx_st)));
  44. ASSERT(count > 0);
  45. ASSERT(memIsValid(s->state_ex, brngCTR_keep()));
  46. brngCTRStart(s->state_ex, key, iv);
  47. s->X = (const octet*)X;
  48. s->count = count;
  49. s->offset = 0;
  50. }
  51. static void brngCTRXStepR(void* buf, size_t count, void* stack)
  52. {
  53. brng_ctrx_st* s = (brng_ctrx_st*)stack;
  54. octet* buf1 = (octet*)buf;
  55. size_t count1 = count;
  56. ASSERT(memIsValid(s, sizeof(brng_ctrx_st)));
  57. // заполнить buf
  58. while (count1)
  59. if (count1 < s->count - s->offset)
  60. {
  61. memCopy(buf1, s->X + s->offset, count1);
  62. s->offset += count1;
  63. count1 = 0;
  64. }
  65. else
  66. {
  67. memCopy(buf1, s->X + s->offset, s->count - s->offset);
  68. buf1 += s->count - s->offset;
  69. count1 -= s->count - s->offset;
  70. s->offset = 0;
  71. }
  72. // сгенерировать
  73. brngCTRStepR(buf, count, s->state_ex);
  74. }
  75. /*
  76. *******************************************************************************
  77. Функция интерфейса bign_pgen_calc_q
  78. *******************************************************************************
  79. */
  80. static err_t _calc_q(bign_params* params, void* state)
  81. {
  82. err_t code;
  83. bign_params par[1];
  84. code = bignParamsStd(par, "1.2.112.0.2.0.34.101.45.3.1");
  85. ERR_CALL_CHECK(code);
  86. if (params->l != par->l ||
  87. !memEq(params->p, par->p, sizeof(params->p)) ||
  88. !memEq(params->a, par->a, sizeof(params->a)) ||
  89. !memEq(params->seed, par->seed, sizeof(params->seed)))
  90. return ERR_NO_RESULT;
  91. memCopy(params->q, par->q, sizeof(par->q));
  92. return ERR_OK;
  93. }
  94. /*
  95. *******************************************************************************
  96. Самотестирование
  97. -# Выполняются тесты из приложения к СТБ 34.101.45.
  98. -# Номера тестов соответствуют номерам таблиц приложения.
  99. -# Дополнительные тесты покрывают ошибки, выявленные в результате испытаний.
  100. *******************************************************************************
  101. */
  102. bool_t bignTest()
  103. {
  104. bign_params params[1];
  105. bign_params params1[1];
  106. octet der[512];
  107. size_t count;
  108. octet privkey[64];
  109. octet pubkey[128];
  110. octet id_privkey[64];
  111. octet id_pubkey[128];
  112. octet hash[64];
  113. octet id_hash[64];
  114. octet sig[64 + 32];
  115. octet id_sig[64 + 32 + 128];
  116. octet brng_state[1024];
  117. octet zz_stack[512];
  118. octet token[80];
  119. word q[W_OF_O(32)];
  120. word d[W_OF_O(32)];
  121. word H[W_OF_O(32)];
  122. word k[W_OF_O(32)];
  123. word S0[W_OF_O(32)];
  124. word S1[W_OF_O(32)];
  125. char pwd[] = "B194BAC80A08F53B";
  126. size_t iter = 10000;
  127. octet key[32];
  128. // подготовить память
  129. if (sizeof(brng_state) < brngCTRX_keep() ||
  130. sizeof(zz_stack) < zzMulMod_deep(W_OF_O(32)))
  131. return FALSE;
  132. // проверить таблицы Б.1, Б.2, Б.3
  133. count = sizeof(der);
  134. if (bignParamsStd(params, "1.2.112.0.2.0.34.101.45.3.3") != ERR_OK ||
  135. bignParamsVal(params) != ERR_OK ||
  136. bignParamsEnc(der, &count, params) != ERR_OK ||
  137. bignParamsDec(params1, der, count) != ERR_OK ||
  138. !memEq(params, params1, sizeof(bign_params)))
  139. return FALSE;
  140. if (bignParamsStd(params, "1.2.112.0.2.0.34.101.45.3.2") != ERR_OK ||
  141. bignParamsVal(params) != ERR_OK ||
  142. bignParamsEnc(der, &count, params) != ERR_OK ||
  143. bignParamsDec(params1, der, count) != ERR_OK ||
  144. !memEq(params, params1, sizeof(bign_params)))
  145. return FALSE;
  146. if (bignParamsStd(params, "1.2.112.0.2.0.34.101.45.3.1") != ERR_OK ||
  147. bignParamsVal(params) != ERR_OK ||
  148. bignParamsEnc(der, &count, params) != ERR_OK ||
  149. bignParamsDec(params1, der, count) != ERR_OK ||
  150. !memEq(params, params1, sizeof(bign_params)))
  151. return FALSE;
  152. // генерация таблицы Б.1
  153. if (bignParamsStd(params1, "1.2.112.0.2.0.34.101.45.3.1") != ERR_OK)
  154. return FALSE;
  155. params1->seed[0] = 0;
  156. memSetZero(params1->b, sizeof(params1->b));
  157. memSetZero(params1->q, sizeof(params1->q));
  158. memSetZero(params1->yG, sizeof(params1->yG));
  159. if (bignParamsGen(params1, _calc_q, 0, 0) != ERR_OK ||
  160. !memEq(params, params1, sizeof(bign_params)))
  161. return FALSE;
  162. // идентификатор объекта
  163. count = sizeof(der);
  164. if (bignOidToDER(der, &count, "1.2.112.0.2.0.34.101.31.81")
  165. != ERR_OK || count != 11)
  166. return FALSE;
  167. // инициализировать ГПСЧ
  168. brngCTRXStart(beltH() + 128, beltH() + 128 + 64, beltH(), 8 * 32,
  169. brng_state);
  170. // тест Г.1
  171. if (bignKeypairGen(privkey, pubkey, params, brngCTRXStepR, brng_state) !=
  172. ERR_OK)
  173. return FALSE;
  174. if (!hexEq(privkey,
  175. "1F66B5B84B7339674533F0329C74F218"
  176. "34281FED0732429E0C79235FC273E269") ||
  177. !hexEq(pubkey,
  178. "BD1A5650179D79E03FCEE49D4C2BD5DD"
  179. "F54CE46D0CF11E4FF87BF7A890857FD0"
  180. "7AC6A60361E8C8173491686D461B2826"
  181. "190C2EDA5909054A9AB84D2AB9D99A90"))
  182. return FALSE;
  183. if (bignKeypairVal(params, privkey, pubkey) != ERR_OK)
  184. return FALSE;
  185. if (bignPubkeyVal(params, pubkey) != ERR_OK)
  186. return FALSE;
  187. if (bignPubkeyCalc(pubkey, params, privkey) != ERR_OK)
  188. return FALSE;
  189. if (!hexEq(pubkey,
  190. "BD1A5650179D79E03FCEE49D4C2BD5DD"
  191. "F54CE46D0CF11E4FF87BF7A890857FD0"
  192. "7AC6A60361E8C8173491686D461B2826"
  193. "190C2EDA5909054A9AB84D2AB9D99A90"))
  194. return FALSE;
  195. memSetZero(pubkey, 32);
  196. memCopy(pubkey + 32, params->yG, 32);
  197. if (bignDH(pubkey, params, privkey, pubkey, 64) != ERR_OK)
  198. return FALSE;
  199. if (!hexEq(pubkey,
  200. "BD1A5650179D79E03FCEE49D4C2BD5DD"
  201. "F54CE46D0CF11E4FF87BF7A890857FD0"
  202. "7AC6A60361E8C8173491686D461B2826"
  203. "190C2EDA5909054A9AB84D2AB9D99A90"))
  204. return FALSE;
  205. // тест Г.2
  206. if (beltHash(hash, beltH(), 13) != ERR_OK)
  207. return FALSE;
  208. if (bignSign(sig, params, der, count, hash, privkey, brngCTRXStepR,
  209. brng_state) != ERR_OK)
  210. return FALSE;
  211. if (!hexEq(sig,
  212. "E36B7F0377AE4C524027C387FADF1B20"
  213. "CE72F1530B71F2B5FD3A8C584FE2E1AE"
  214. "D20082E30C8AF65011F4FB54649DFD3D"))
  215. return FALSE;
  216. if (bignVerify(params, der, count, hash, sig, pubkey) != ERR_OK)
  217. return FALSE;
  218. sig[0] ^= 1;
  219. if (bignVerify(params, der, count, hash, sig, pubkey) == ERR_OK)
  220. return FALSE;
  221. sig[0] ^= 1, pubkey[0] ^= 1;
  222. if (bignVerify(params, der, count, hash, sig, pubkey) == ERR_OK)
  223. return FALSE;
  224. pubkey[0] ^= 1;
  225. // тест Г.8
  226. memCopy(id_hash, hash, 32);
  227. if (bignIdExtract(id_privkey, id_pubkey, params, der, count,
  228. id_hash, sig, pubkey) != ERR_OK)
  229. return FALSE;
  230. if (!hexEq(id_pubkey,
  231. "CCEEF1A313A406649D15DA0A851D486A"
  232. "695B641B20611776252FFDCE39C71060"
  233. "7C9EA1F33C23D20DFCB8485A88BE6523"
  234. "A28ECC3215B47FA289D6C9BE1CE837C0") ||
  235. !hexEq(id_privkey,
  236. "79628979DF369BEB94DEF3299476AED4"
  237. "14F39148AA69E31A7397E8AA70578AB3"))
  238. return FALSE;
  239. // тест Г.4
  240. if (bignKeyWrap(token, params, beltH(), 18, beltH() + 32, pubkey,
  241. brngCTRXStepR, brng_state) != ERR_OK)
  242. return FALSE;
  243. if (!hexEq(token,
  244. "9B4EA669DABDF100A7D4B6E6EB76EE52"
  245. "51912531F426750AAC8A9DBB51C54D8D"
  246. "EB9289B50A46952D0531861E45A8814B"
  247. "008FDC65DE9FF1FA2A1F16B6A280E957"
  248. "A814"))
  249. return FALSE;
  250. if (bignKeyUnwrap(token, params, token, 18 + 16 + 32, beltH() + 32,
  251. privkey) != ERR_OK)
  252. return FALSE;
  253. if (!memEq(token, beltH(), 18))
  254. return FALSE;
  255. // тест Г.3
  256. if (beltHash(hash, beltH(), 48) != ERR_OK)
  257. return FALSE;
  258. if (bignSign(sig, params, der, count, hash, privkey, brngCTRXStepR,
  259. brng_state) != ERR_OK)
  260. return FALSE;
  261. if (!hexEq(sig,
  262. "47A63C8B9C936E94B5FAB3D9CBD78366"
  263. "290F3210E163EEC8DB4E921E8479D413"
  264. "8F112CC23E6DCE65EC5FF21DF4231C28"))
  265. return FALSE;
  266. if (bignVerify(params, der, count, hash, sig, pubkey) != ERR_OK)
  267. return FALSE;
  268. // тест Г.5
  269. bignKeyWrap(token, params, beltH(), 32, beltH() + 64,
  270. pubkey, brngCTRXStepR, brng_state);
  271. if (!hexEq(token,
  272. "4856093A0F6C13015FC8E15F1B23A762"
  273. "02D2F4BA6E5EC52B78658477F6486DE6"
  274. "87AFAEEA0EF7BC1326A7DCE7A10BA10E"
  275. "3F91C0126044B22267BF30BD6F1DA29E"
  276. "0647CF39C1D59A56BB0194E0F4F8A2BB"))
  277. return FALSE;
  278. bignKeyUnwrap(token, params, token, 32 + 16 + 32, beltH() + 64,
  279. privkey);
  280. if (!memEq(token, beltH(), 32))
  281. return FALSE;
  282. // тест Г.6
  283. if (beltHash(hash, beltH(), 13) != ERR_OK)
  284. return FALSE;
  285. if (bignSign2(sig, params, der, count, hash, privkey, 0, 0)
  286. != ERR_OK)
  287. return FALSE;
  288. wwFrom(q, params->q, 32);
  289. wwFrom(d, privkey, 32);
  290. wwFrom(S0, sig, 16);
  291. wwFrom(S1, sig + 16, 32);
  292. wwFrom(H, hash, 32);
  293. S0[W_OF_O(16)] = 1;
  294. wwSetZero(S0 + W_OF_O(16) + 1, W_OF_O(16) - 1);
  295. zzMulMod(k, S0, d, q, W_OF_O(32), zz_stack);
  296. zzAddMod(k, S1, k, q, W_OF_O(32));
  297. zzAddMod(k, k, H, q, W_OF_O(32));
  298. wwTo(k, 32, k);
  299. if (!hexEq(k,
  300. "829614D8411DBBC4E1F2471A40045864"
  301. "40FD8C9553FAB6A1A45CE417AE97111E"))
  302. return FALSE;
  303. // тест Г.7
  304. if (beltHash(hash, beltH(), 48) != ERR_OK)
  305. return FALSE;
  306. if (bignSign2(sig, params, der, count, hash, privkey,
  307. beltH() + 128 + 64, 23) != ERR_OK)
  308. return FALSE;
  309. wwFrom(q, params->q, 32);
  310. wwFrom(d, privkey, 32);
  311. wwFrom(S0, sig, 16);
  312. wwFrom(S1, sig + 16, 32);
  313. wwFrom(H, hash, 32);
  314. S0[W_OF_O(16)] = 1;
  315. wwSetZero(S0 + W_OF_O(16) + 1, W_OF_O(16) - 1);
  316. zzMulMod(k, S0, d, q, W_OF_O(32), zz_stack);
  317. zzAddMod(k, S1, k, q, W_OF_O(32));
  318. zzAddMod(k, k, H, q, W_OF_O(32));
  319. wwTo(k, 32, k);
  320. if (!hexEq(k,
  321. "7ADC8713283EBFA547A2AD9CDFB245AE"
  322. "0F7B968DF0F91CB785D1F932A3583107"))
  323. return FALSE;
  324. // тест Г.9
  325. if (beltHash(hash, beltH() + 32, 16) != ERR_OK)
  326. return FALSE;
  327. if (bignIdSign(id_sig, params, der, count, id_hash, hash, id_privkey,
  328. brngCTRXStepR, brng_state) != ERR_OK)
  329. return FALSE;
  330. if (!hexEq(id_sig,
  331. "1697FE6A073D3B28C9D0DD832A169D7B"
  332. "8D342FDC47BC8AAEB6226448956E22D6"
  333. "CC73B62CB21B66E5C8DE0A3E234FB0C6"))
  334. return FALSE;
  335. if (bignIdVerify(params, der, count, id_hash, hash, id_sig,
  336. id_pubkey, pubkey) != ERR_OK)
  337. return FALSE;
  338. id_sig[0] ^= 1;
  339. if (bignIdVerify(params, der, count, id_hash, hash, id_sig,
  340. id_pubkey, pubkey) == ERR_OK)
  341. return FALSE;
  342. id_sig[0] ^= 1, id_pubkey[0] ^= 1;
  343. if (bignIdVerify(params, der, count, id_hash, hash, id_sig,
  344. id_pubkey, pubkey) == ERR_OK)
  345. return FALSE;
  346. id_pubkey[0] ^= 1;
  347. // тест Г.10
  348. if (beltHash(hash, beltH() + 32, 23) != ERR_OK)
  349. return FALSE;
  350. if (bignIdSign(id_sig, params, der, count, id_hash, hash, id_privkey,
  351. brngCTRXStepR, brng_state) != ERR_OK)
  352. return FALSE;
  353. if (!hexEq(id_sig,
  354. "31CBA14FC2D79AFCD8F50E29F993FC2C"
  355. "B270BD0A79D534B3B120791400C8BB18"
  356. "50AD6D3C78047FCB46F18608AC7006AA"))
  357. return FALSE;
  358. if (bignIdVerify(params, der, count, id_hash, hash, id_sig,
  359. id_pubkey, pubkey) != ERR_OK)
  360. return FALSE;
  361. id_sig[0] ^= 1;
  362. if (bignIdVerify(params, der, count, id_hash, hash, id_sig,
  363. id_pubkey, pubkey) == ERR_OK)
  364. return FALSE;
  365. id_sig[0] ^= 1, id_pubkey[0] ^= 1;
  366. if (bignIdVerify(params, der, count, id_hash, hash, id_sig,
  367. id_pubkey, pubkey) == ERR_OK)
  368. return FALSE;
  369. id_pubkey[0] ^= 1;
  370. // дополнительный тест для проверки bignIdSign2
  371. if (bignIdSign2(id_sig, params, der, count, id_hash, hash,
  372. id_privkey, 0, 0) != ERR_OK ||
  373. bignIdVerify(params, der, count, id_hash, hash, id_sig,
  374. id_pubkey, pubkey) != ERR_OK)
  375. return FALSE;
  376. id_sig[0] ^= 1;
  377. if (bignIdVerify(params, der, count, id_hash, hash, id_sig,
  378. id_pubkey, pubkey) == ERR_OK)
  379. return FALSE;
  380. id_sig[0] ^= 1, id_pubkey[0] ^= 1;
  381. if (bignIdVerify(params, der, count, id_hash, hash, id_sig,
  382. id_pubkey, pubkey) == ERR_OK)
  383. return FALSE;
  384. id_pubkey[0] ^= 1;
  385. // тест E.5
  386. beltPBKDF2(key, (const octet*)pwd, strLen(pwd), iter,
  387. beltH() + 128 + 64, 8);
  388. if (!hexEq(key,
  389. "3D331BBBB1FBBB40E4BF22F6CB9A689E"
  390. "F13A77DC09ECF93291BFE42439A72E7D"))
  391. return FALSE;
  392. beltKWPWrap(token, privkey, 32, 0, key, 32);
  393. if (!hexEq(token,
  394. "4EA289D5F718087DD8EDB305BA1CE898"
  395. "0E5EC3E0B56C8BF9D5C3E909CF4C14F0"
  396. "7B8204E67841A165E924945CD07F37E7"))
  397. return FALSE;
  398. // дополнительный тест: транспорт ключа из 16 октетов
  399. if (bignKeyWrap(token, params, beltH(), 16, beltH() + 64,
  400. pubkey, brngCTRXStepR, brng_state) != ERR_OK ||
  401. bignKeyUnwrap(token, params, token, 32 + 16 + 16, beltH() + 64,
  402. privkey) != ERR_OK ||
  403. !memEq(token, beltH(), 16))
  404. return FALSE;
  405. // дополнительные тесты (vs OpenSSL)
  406. hexTo(key, "49FEFF8076CD9480");
  407. beltPBKDF2(key, (const octet*)"zed", 3, 2048, key, 8);
  408. if (!hexEq(key,
  409. "7249B4785FE68B1586D189A23E3842E4"
  410. "8705C080A3248D8F0E8C3D63A93B2670"))
  411. return FALSE;
  412. hexTo(key, "C65017E4F108BCF0");
  413. beltPBKDF2(key, (const octet*)"zed", 3, 10000, key, 8);
  414. if (!hexEq(key,
  415. "E48329259BC1211DDAC2EF1DADFFC993"
  416. "2702A92F1DD66C14A9BA1D7300C8713C"))
  417. return FALSE;
  418. // все нормально
  419. return TRUE;
  420. }