bign_test.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. /*
  2. *******************************************************************************
  3. \file bign_test.c
  4. \brief Tests for STB 34.101.45 (bign)
  5. \project bee2/test
  6. \author Sergey Agievich [agievich@{bsu.by|gmail.com}]
  7. \created 2012.08.27
  8. \version 2020.11.25
  9. \license This program is released under the GNU General Public License
  10. version 3. See Copyright Notices in bee2/info.h.
  11. *******************************************************************************
  12. */
  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. Самотестирование
  78. -# Выполняются тесты из приложения к СТБ 34.101.45.
  79. -# Номера тестов соответствуют номерам таблиц приложения.
  80. -# Дополнительные тесты покрывают ошибки, выявленные в результате испытаний.
  81. *******************************************************************************
  82. */
  83. bool_t bignTest()
  84. {
  85. bign_params params[1];
  86. octet oid_der[128];
  87. size_t oid_len;
  88. octet privkey[64];
  89. octet pubkey[128];
  90. octet id_privkey[64];
  91. octet id_pubkey[128];
  92. octet hash[64];
  93. octet id_hash[64];
  94. octet sig[64 + 32];
  95. octet id_sig[64 + 32 + 128];
  96. octet brng_state[1024];
  97. octet zz_stack[512];
  98. octet token[80];
  99. word q[W_OF_O(32)];
  100. word d[W_OF_O(32)];
  101. word H[W_OF_O(32)];
  102. word k[W_OF_O(32)];
  103. word S0[W_OF_O(32)];
  104. word S1[W_OF_O(32)];
  105. char pwd[] = "B194BAC80A08F53B";
  106. size_t iter = 10000;
  107. octet key[32];
  108. // создать стек
  109. ASSERT(sizeof(brng_state) >= brngCTRX_keep());
  110. ASSERT(sizeof(zz_stack) >= zzMulMod_deep(W_OF_O(32)));
  111. // проверить таблицы Б.1, Б.2, Б.3
  112. if (bignStdParams(params, "1.2.112.0.2.0.34.101.45.3.3") != ERR_OK ||
  113. bignValParams(params) != ERR_OK)
  114. return FALSE;
  115. if (bignStdParams(params, "1.2.112.0.2.0.34.101.45.3.2") != ERR_OK ||
  116. bignValParams(params) != ERR_OK)
  117. return FALSE;
  118. if (bignStdParams(params, "1.2.112.0.2.0.34.101.45.3.1") != ERR_OK ||
  119. bignValParams(params) != ERR_OK)
  120. return FALSE;
  121. // идентификатор объекта
  122. oid_len = sizeof(oid_der);
  123. if (bignOidToDER(oid_der, &oid_len, "1.2.112.0.2.0.34.101.31.81")
  124. != ERR_OK || oid_len != 11)
  125. return FALSE;
  126. // инициализировать ГПСЧ
  127. brngCTRXStart(beltH() + 128, beltH() + 128 + 64,
  128. beltH(), 8 * 32, brng_state);
  129. // тест Г.1
  130. if (bignGenKeypair(privkey, pubkey, params, brngCTRXStepR, brng_state) !=
  131. ERR_OK)
  132. return FALSE;
  133. if (!hexEq(privkey,
  134. "1F66B5B84B7339674533F0329C74F218"
  135. "34281FED0732429E0C79235FC273E269") ||
  136. !hexEq(pubkey,
  137. "BD1A5650179D79E03FCEE49D4C2BD5DD"
  138. "F54CE46D0CF11E4FF87BF7A890857FD0"
  139. "7AC6A60361E8C8173491686D461B2826"
  140. "190C2EDA5909054A9AB84D2AB9D99A90"))
  141. return FALSE;
  142. if (bignValKeypair(params, privkey, pubkey) != ERR_OK)
  143. return FALSE;
  144. if (bignValPubkey(params, pubkey) != ERR_OK)
  145. return FALSE;
  146. if (bignCalcPubkey(pubkey, params, privkey) != ERR_OK)
  147. return FALSE;
  148. if (!hexEq(pubkey,
  149. "BD1A5650179D79E03FCEE49D4C2BD5DD"
  150. "F54CE46D0CF11E4FF87BF7A890857FD0"
  151. "7AC6A60361E8C8173491686D461B2826"
  152. "190C2EDA5909054A9AB84D2AB9D99A90"))
  153. return FALSE;
  154. memSetZero(pubkey, 32);
  155. memCopy(pubkey + 32, params->yG, 32);
  156. if (bignDH(pubkey, params, privkey, pubkey, 64) != ERR_OK)
  157. return FALSE;
  158. if (!hexEq(pubkey,
  159. "BD1A5650179D79E03FCEE49D4C2BD5DD"
  160. "F54CE46D0CF11E4FF87BF7A890857FD0"
  161. "7AC6A60361E8C8173491686D461B2826"
  162. "190C2EDA5909054A9AB84D2AB9D99A90"))
  163. return FALSE;
  164. // тест Г.2
  165. if (beltHash(hash, beltH(), 13) != ERR_OK)
  166. return FALSE;
  167. if (bignSign(sig, params, oid_der, oid_len, hash, privkey, brngCTRXStepR,
  168. brng_state) != ERR_OK)
  169. return FALSE;
  170. if (!hexEq(sig,
  171. "E36B7F0377AE4C524027C387FADF1B20"
  172. "CE72F1530B71F2B5FD3A8C584FE2E1AE"
  173. "D20082E30C8AF65011F4FB54649DFD3D"))
  174. return FALSE;
  175. if (bignVerify(params, oid_der, oid_len, hash, sig, pubkey) != ERR_OK)
  176. return FALSE;
  177. sig[0] ^= 1;
  178. if (bignVerify(params, oid_der, oid_len, hash, sig, pubkey) == ERR_OK)
  179. return FALSE;
  180. sig[0] ^= 1, pubkey[0] ^= 1;
  181. if (bignVerify(params, oid_der, oid_len, hash, sig, pubkey) == ERR_OK)
  182. return FALSE;
  183. pubkey[0] ^= 1;
  184. // тест Г.8
  185. memCopy(id_hash, hash, 32);
  186. if (bignIdExtract(id_privkey, id_pubkey, params, oid_der, oid_len,
  187. id_hash, sig, pubkey) != ERR_OK)
  188. return FALSE;
  189. if (!hexEq(id_pubkey,
  190. "CCEEF1A313A406649D15DA0A851D486A"
  191. "695B641B20611776252FFDCE39C71060"
  192. "7C9EA1F33C23D20DFCB8485A88BE6523"
  193. "A28ECC3215B47FA289D6C9BE1CE837C0") ||
  194. !hexEq(id_privkey,
  195. "79628979DF369BEB94DEF3299476AED4"
  196. "14F39148AA69E31A7397E8AA70578AB3"))
  197. return FALSE;
  198. // тест Г.4
  199. if (bignKeyWrap(token, params, beltH(), 18, beltH() + 32, pubkey,
  200. brngCTRXStepR, brng_state) != ERR_OK)
  201. return FALSE;
  202. if (!hexEq(token,
  203. "9B4EA669DABDF100A7D4B6E6EB76EE52"
  204. "51912531F426750AAC8A9DBB51C54D8D"
  205. "EB9289B50A46952D0531861E45A8814B"
  206. "008FDC65DE9FF1FA2A1F16B6A280E957"
  207. "A814"))
  208. return FALSE;
  209. if (bignKeyUnwrap(token, params, token, 18 + 16 + 32, beltH() + 32,
  210. privkey) != ERR_OK)
  211. return FALSE;
  212. if (!memEq(token, beltH(), 18))
  213. return FALSE;
  214. // тест Г.3
  215. if (beltHash(hash, beltH(), 48) != ERR_OK)
  216. return FALSE;
  217. if (bignSign(sig, params, oid_der, oid_len, hash, privkey, brngCTRXStepR,
  218. brng_state) != ERR_OK)
  219. return FALSE;
  220. if (!hexEq(sig,
  221. "47A63C8B9C936E94B5FAB3D9CBD78366"
  222. "290F3210E163EEC8DB4E921E8479D413"
  223. "8F112CC23E6DCE65EC5FF21DF4231C28"))
  224. return FALSE;
  225. if (bignVerify(params, oid_der, oid_len, hash, sig, pubkey) != ERR_OK)
  226. return FALSE;
  227. // тест Г.5
  228. bignKeyWrap(token, params, beltH(), 32, beltH() + 64,
  229. pubkey, brngCTRXStepR, brng_state);
  230. if (!hexEq(token,
  231. "4856093A0F6C13015FC8E15F1B23A762"
  232. "02D2F4BA6E5EC52B78658477F6486DE6"
  233. "87AFAEEA0EF7BC1326A7DCE7A10BA10E"
  234. "3F91C0126044B22267BF30BD6F1DA29E"
  235. "0647CF39C1D59A56BB0194E0F4F8A2BB"))
  236. return FALSE;
  237. bignKeyUnwrap(token, params, token, 32 + 16 + 32, beltH() + 64,
  238. privkey);
  239. if (!memEq(token, beltH(), 32))
  240. return FALSE;
  241. // тест Г.6
  242. if (beltHash(hash, beltH(), 13) != ERR_OK)
  243. return FALSE;
  244. if (bignSign2(sig, params, oid_der, oid_len, hash, privkey, 0, 0)
  245. != ERR_OK)
  246. return FALSE;
  247. wwFrom(q, params->q, 32);
  248. wwFrom(d, privkey, 32);
  249. wwFrom(S0, sig, 16);
  250. wwFrom(S1, sig + 16, 32);
  251. wwFrom(H, hash, 32);
  252. S0[W_OF_O(16)] = 1;
  253. wwSetZero(S0 + W_OF_O(16) + 1, W_OF_O(16) - 1);
  254. zzMulMod(k, S0, d, q, W_OF_O(32), zz_stack);
  255. zzAddMod(k, S1, k, q, W_OF_O(32));
  256. zzAddMod(k, k, H, q, W_OF_O(32));
  257. wwTo(k, 32, k);
  258. if (!hexEq(k,
  259. "829614D8411DBBC4E1F2471A40045864"
  260. "40FD8C9553FAB6A1A45CE417AE97111E"))
  261. return FALSE;
  262. // тест Г.7
  263. if (beltHash(hash, beltH(), 48) != ERR_OK)
  264. return FALSE;
  265. if (bignSign2(sig, params, oid_der, oid_len, hash, privkey,
  266. beltH() + 128 + 64, 23) != ERR_OK)
  267. return FALSE;
  268. wwFrom(q, params->q, 32);
  269. wwFrom(d, privkey, 32);
  270. wwFrom(S0, sig, 16);
  271. wwFrom(S1, sig + 16, 32);
  272. wwFrom(H, hash, 32);
  273. S0[W_OF_O(16)] = 1;
  274. wwSetZero(S0 + W_OF_O(16) + 1, W_OF_O(16) - 1);
  275. zzMulMod(k, S0, d, q, W_OF_O(32), zz_stack);
  276. zzAddMod(k, S1, k, q, W_OF_O(32));
  277. zzAddMod(k, k, H, q, W_OF_O(32));
  278. wwTo(k, 32, k);
  279. if (!hexEq(k,
  280. "7ADC8713283EBFA547A2AD9CDFB245AE"
  281. "0F7B968DF0F91CB785D1F932A3583107"))
  282. return FALSE;
  283. // тест Г.9
  284. if (beltHash(hash, beltH() + 32, 16) != ERR_OK)
  285. return FALSE;
  286. if (bignIdSign(id_sig, params, oid_der, oid_len, id_hash, hash, id_privkey,
  287. brngCTRXStepR, brng_state) != ERR_OK)
  288. return FALSE;
  289. if (!hexEq(id_sig,
  290. "1697FE6A073D3B28C9D0DD832A169D7B"
  291. "8D342FDC47BC8AAEB6226448956E22D6"
  292. "CC73B62CB21B66E5C8DE0A3E234FB0C6"))
  293. return FALSE;
  294. if (bignIdVerify(params, oid_der, oid_len, id_hash, hash, id_sig,
  295. id_pubkey, pubkey) != ERR_OK)
  296. return FALSE;
  297. id_sig[0] ^= 1;
  298. if (bignIdVerify(params, oid_der, oid_len, id_hash, hash, id_sig,
  299. id_pubkey, pubkey) == ERR_OK)
  300. return FALSE;
  301. id_sig[0] ^= 1, id_pubkey[0] ^= 1;
  302. if (bignIdVerify(params, oid_der, oid_len, id_hash, hash, id_sig,
  303. id_pubkey, pubkey) == ERR_OK)
  304. return FALSE;
  305. id_pubkey[0] ^= 1;
  306. // тест Г.10
  307. if (beltHash(hash, beltH() + 32, 23) != ERR_OK)
  308. return FALSE;
  309. if (bignIdSign(id_sig, params, oid_der, oid_len, id_hash, hash, id_privkey,
  310. brngCTRXStepR, brng_state) != ERR_OK)
  311. return FALSE;
  312. if (!hexEq(id_sig,
  313. "31CBA14FC2D79AFCD8F50E29F993FC2C"
  314. "B270BD0A79D534B3B120791400C8BB18"
  315. "50AD6D3C78047FCB46F18608AC7006AA"))
  316. return FALSE;
  317. if (bignIdVerify(params, oid_der, oid_len, id_hash, hash, id_sig,
  318. id_pubkey, pubkey) != ERR_OK)
  319. return FALSE;
  320. id_sig[0] ^= 1;
  321. if (bignIdVerify(params, oid_der, oid_len, id_hash, hash, id_sig,
  322. id_pubkey, pubkey) == ERR_OK)
  323. return FALSE;
  324. id_sig[0] ^= 1, id_pubkey[0] ^= 1;
  325. if (bignIdVerify(params, oid_der, oid_len, id_hash, hash, id_sig,
  326. id_pubkey, pubkey) == ERR_OK)
  327. return FALSE;
  328. id_pubkey[0] ^= 1;
  329. // дополнительный тест для проверки bignIdSign2
  330. if (bignIdSign2(id_sig, params, oid_der, oid_len, id_hash, hash,
  331. id_privkey, 0, 0) != ERR_OK ||
  332. bignIdVerify(params, oid_der, oid_len, id_hash, hash, id_sig,
  333. id_pubkey, pubkey) != ERR_OK)
  334. return FALSE;
  335. id_sig[0] ^= 1;
  336. if (bignIdVerify(params, oid_der, oid_len, id_hash, hash, id_sig,
  337. id_pubkey, pubkey) == ERR_OK)
  338. return FALSE;
  339. id_sig[0] ^= 1, id_pubkey[0] ^= 1;
  340. if (bignIdVerify(params, oid_der, oid_len, id_hash, hash, id_sig,
  341. id_pubkey, pubkey) == ERR_OK)
  342. return FALSE;
  343. id_pubkey[0] ^= 1;
  344. // тест E.5
  345. beltPBKDF2(key, (const octet*)pwd, strLen(pwd), iter,
  346. beltH() + 128 + 64, 8);
  347. if (!hexEq(key,
  348. "3D331BBBB1FBBB40E4BF22F6CB9A689E"
  349. "F13A77DC09ECF93291BFE42439A72E7D"))
  350. return FALSE;
  351. beltKWPWrap(token, privkey, 32, 0, key, 32);
  352. if (!hexEq(token,
  353. "4EA289D5F718087DD8EDB305BA1CE898"
  354. "0E5EC3E0B56C8BF9D5C3E909CF4C14F0"
  355. "7B8204E67841A165E924945CD07F37E7"))
  356. return FALSE;
  357. // дополнительный тест: транспорт ключа из 16 октетов
  358. if (bignKeyWrap(token, params, beltH(), 16, beltH() + 64,
  359. pubkey, brngCTRXStepR, brng_state) != ERR_OK ||
  360. bignKeyUnwrap(token, params, token, 32 + 16 + 16, beltH() + 64,
  361. privkey) != ERR_OK ||
  362. !memEq(token, beltH(), 16))
  363. return FALSE;
  364. // дополнительные тесты (vs OpenSSL)
  365. hexTo(key, "49FEFF8076CD9480");
  366. beltPBKDF2(key, (const octet*)"zed", 3, 2048, key, 8);
  367. if (!hexEq(key,
  368. "7249B4785FE68B1586D189A23E3842E4"
  369. "8705C080A3248D8F0E8C3D63A93B2670"))
  370. return FALSE;
  371. hexTo(key, "C65017E4F108BCF0");
  372. beltPBKDF2(key, (const octet*)"zed", 3, 10000, key, 8);
  373. if (!hexEq(key,
  374. "E48329259BC1211DDAC2EF1DADFFC993"
  375. "2702A92F1DD66C14A9BA1D7300C8713C"))
  376. return FALSE;
  377. // все нормально
  378. return TRUE;
  379. }