You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

744 lines
21 KiB

  1. /* Copyright (c) 2014 Cryptography Research, Inc.
  2. * Released under the MIT License. See LICENSE.txt for license information.
  3. */
  4. #include "word.h"
  5. #include <sys/time.h>
  6. #include <sys/types.h>
  7. #include <stdio.h>
  8. #include <memory.h>
  9. #include "field.h"
  10. #include "ec_point.h"
  11. #include "scalarmul.h"
  12. #include "barrett_field.h"
  13. #include "crandom.h"
  14. #include "goldilocks.h"
  15. #include "sha512.h"
  16. static __inline__ void
  17. ignore_result ( int result ) {
  18. (void)result;
  19. }
  20. static double now(void) {
  21. struct timeval tv;
  22. gettimeofday(&tv, NULL);
  23. return tv.tv_sec + tv.tv_usec/1000000.0;
  24. }
  25. static void field_randomize( struct crandom_state_t *crand, field_a_t a ) {
  26. crandom_generate(crand, (unsigned char *)a, sizeof(*a));
  27. field_strong_reduce(a);
  28. }
  29. static void q448_randomize( struct crandom_state_t *crand, word_t sk[SCALAR_WORDS] ) {
  30. crandom_generate(crand, (unsigned char *)sk, SCALAR_BYTES);
  31. }
  32. static void field_print( const char *descr, const field_a_t a ) {
  33. int j;
  34. unsigned char ser[FIELD_BYTES];
  35. field_serialize(ser,a);
  36. printf("%s = 0x", descr);
  37. for (j=FIELD_BYTES - 1; j>=0; j--) {
  38. printf("%02x", ser[j]);
  39. }
  40. printf("\n");
  41. }
  42. static void __attribute__((unused))
  43. field_print_full (
  44. const char *descr,
  45. const field_a_t a
  46. ) {
  47. int j;
  48. printf("%s = 0x", descr);
  49. for (j=15; j>=0; j--) {
  50. printf("%02" PRIxWORD "_" PRIxWORD56 " ",
  51. a->limb[j]>>28, a->limb[j]&((1<<28)-1));
  52. }
  53. printf("\n");
  54. }
  55. static void q448_print( const char *descr, const word_t secret[SCALAR_WORDS] ) {
  56. int j;
  57. printf("%s = 0x", descr);
  58. for (j=SCALAR_WORDS-1; j>=0; j--) {
  59. printf(PRIxWORDfull, secret[j]);
  60. }
  61. printf("\n");
  62. }
  63. #ifndef N_TESTS_BASE
  64. #define N_TESTS_BASE 10000
  65. #endif
  66. int main(int argc, char **argv) {
  67. (void)argc;
  68. (void)argv;
  69. struct tw_extensible_t ext;
  70. struct extensible_t exta;
  71. struct tw_niels_t niels;
  72. struct tw_pniels_t pniels;
  73. struct affine_t affine;
  74. struct montgomery_t mb;
  75. struct montgomery_aux_t mba;
  76. field_a_t a,b,c,d;
  77. double when;
  78. int i;
  79. int nbase = N_TESTS_BASE;
  80. /* Bad randomness so we can debug. */
  81. char initial_seed[32];
  82. for (i=0; i<32; i++) initial_seed[i] = i;
  83. struct crandom_state_t crand;
  84. crandom_init_from_buffer(&crand, initial_seed);
  85. /* For testing the performance drop from the crandom debuffering change.
  86. ignore_result(crandom_init_from_file(&crand, "/dev/urandom", 10000, 1));
  87. */
  88. word_t sk[SCALAR_WORDS],tk[SCALAR_WORDS];
  89. q448_randomize(&crand, sk);
  90. memset(a,0,sizeof(a));
  91. memset(b,0,sizeof(b));
  92. memset(c,0,sizeof(c));
  93. memset(d,0,sizeof(d));
  94. when = now();
  95. for (i=0; i<nbase*5000; i++) {
  96. field_mul(c, b, a);
  97. }
  98. when = now() - when;
  99. printf("mul: %5.1fns\n", when * 1e9 / i);
  100. when = now();
  101. for (i=0; i<nbase*5000; i++) {
  102. field_sqr(c, a);
  103. }
  104. when = now() - when;
  105. printf("sqr: %5.1fns\n", when * 1e9 / i);
  106. when = now();
  107. for (i=0; i<nbase*5000; i++) {
  108. field_mulw(c, b, 1234562);
  109. }
  110. when = now() - when;
  111. printf("mulw: %5.1fns\n", when * 1e9 / i);
  112. when = now();
  113. for (i=0; i<nbase*500; i++) {
  114. field_mul(c, b, a);
  115. field_mul(a, b, c);
  116. }
  117. when = now() - when;
  118. printf("mul dep: %5.1fns\n", when * 1e9 / i / 2);
  119. when = now();
  120. for (i=0; i<nbase*10; i++) {
  121. field_randomize(&crand, a);
  122. }
  123. when = now() - when;
  124. printf("rand448: %5.1fns\n", when * 1e9 / i);
  125. struct sha512_ctx_t sha;
  126. uint8_t hashout[128];
  127. when = now();
  128. for (i=0; i<nbase; i++) {
  129. sha512_init(&sha);
  130. sha512_final(&sha, hashout);
  131. }
  132. when = now() - when;
  133. printf("sha512 1blk: %5.1fns\n", when * 1e9 / i);
  134. when = now();
  135. for (i=0; i<nbase; i++) {
  136. sha512_update(&sha, hashout, 128);
  137. }
  138. when = now() - when;
  139. printf("sha512 blk: %5.1fns (%0.2f MB/s)\n", when * 1e9 / i, 128*i/when/1e6);
  140. when = now();
  141. for (i=0; i<nbase; i++) {
  142. field_isr(c, a);
  143. }
  144. when = now() - when;
  145. printf("isr auto: %5.1fµs\n", when * 1e6 / i);
  146. for (i=0; i<100; i++) {
  147. field_randomize(&crand, a);
  148. field_isr(d,a);
  149. field_sqr(b,d);
  150. field_mul(c,b,a);
  151. field_sqr(b,c);
  152. field_subw(b,1);
  153. if (!field_is_zero(b)) {
  154. printf("ISR validation failure!\n");
  155. field_print("a", a);
  156. field_print("s", d);
  157. }
  158. }
  159. when = now();
  160. for (i=0; i<nbase; i++) {
  161. elligator_2s_inject(&affine, a);
  162. }
  163. when = now() - when;
  164. printf("elligator: %5.1fµs\n", when * 1e6 / i);
  165. for (i=0; i<100; i++) {
  166. field_randomize(&crand, a);
  167. elligator_2s_inject(&affine, a);
  168. if (!validate_affine(&affine)) {
  169. printf("Elligator validation failure!\n");
  170. field_print("a", a);
  171. field_print("x", affine.x);
  172. field_print("y", affine.y);
  173. }
  174. }
  175. when = now();
  176. for (i=0; i<nbase; i++) {
  177. deserialize_affine(&affine, a);
  178. }
  179. when = now() - when;
  180. printf("decompress: %5.1fµs\n", when * 1e6 / i);
  181. convert_affine_to_extensible(&exta, &affine);
  182. when = now();
  183. for (i=0; i<nbase; i++) {
  184. serialize_extensible(a, &exta);
  185. }
  186. when = now() - when;
  187. printf("compress: %5.1fµs\n", when * 1e6 / i);
  188. int goods = 0;
  189. for (i=0; i<100; i++) {
  190. field_randomize(&crand, a);
  191. mask_t good = deserialize_affine(&affine, a);
  192. if (good & !validate_affine(&affine)) {
  193. printf("Deserialize validation failure!\n");
  194. field_print("a", a);
  195. field_print("x", affine.x);
  196. field_print("y", affine.y);
  197. } else if (good) {
  198. goods++;
  199. convert_affine_to_extensible(&exta,&affine);
  200. serialize_extensible(b, &exta);
  201. field_sub(c,b,a);
  202. if (!field_is_zero(c)) {
  203. printf("Reserialize validation failure!\n");
  204. field_print("a", a);
  205. field_print("x", affine.x);
  206. field_print("y", affine.y);
  207. deserialize_affine(&affine, b);
  208. field_print("b", b);
  209. field_print("x", affine.x);
  210. field_print("y", affine.y);
  211. printf("\n");
  212. }
  213. }
  214. }
  215. if (goods<i/3) {
  216. printf("Deserialization validation failure! Deserialized %d/%d points\n", goods, i);
  217. }
  218. word_t lsk[768/WORD_BITS];
  219. crandom_generate(&crand, (unsigned char *)lsk, sizeof(lsk));
  220. when = now();
  221. for (i=0; i<nbase*100; i++) {
  222. barrett_reduce(lsk,sizeof(lsk)/sizeof(word_t),0,&curve_prime_order);
  223. }
  224. when = now() - when;
  225. printf("barrett red: %5.1fns\n", when * 1e9 / i);
  226. when = now();
  227. for (i=0; i<nbase*10; i++) {
  228. barrett_mac(lsk,SCALAR_WORDS,lsk,SCALAR_WORDS,lsk,SCALAR_WORDS,&curve_prime_order);
  229. }
  230. when = now() - when;
  231. printf("barrett mac: %5.1fns\n", when * 1e9 / i);
  232. memset(&ext,0,sizeof(ext));
  233. memset(&niels,0,sizeof(niels)); /* avoid assertions in p521 even though this isn't a valid ext or niels */
  234. when = now();
  235. for (i=0; i<nbase*100; i++) {
  236. add_tw_niels_to_tw_extensible(&ext, &niels);
  237. }
  238. when = now() - when;
  239. printf("exti+niels: %5.1fns\n", when * 1e9 / i);
  240. convert_tw_extensible_to_tw_pniels(&pniels, &ext);
  241. when = now();
  242. for (i=0; i<nbase*100; i++) {
  243. add_tw_pniels_to_tw_extensible(&ext, &pniels);
  244. }
  245. when = now() - when;
  246. printf("exti+pniels: %5.1fns\n", when * 1e9 / i);
  247. when = now();
  248. for (i=0; i<nbase*100; i++) {
  249. double_tw_extensible(&ext);
  250. }
  251. when = now() - when;
  252. printf("exti dbl: %5.1fns\n", when * 1e9 / i);
  253. when = now();
  254. for (i=0; i<nbase*100; i++) {
  255. untwist_and_double(&exta, &ext);
  256. }
  257. when = now() - when;
  258. printf("i->a isog: %5.1fns\n", when * 1e9 / i);
  259. when = now();
  260. for (i=0; i<nbase*100; i++) {
  261. twist_and_double(&ext, &exta);
  262. }
  263. when = now() - when;
  264. printf("a->i isog: %5.1fns\n", when * 1e9 / i);
  265. memset(&mb,0,sizeof(mb));
  266. when = now();
  267. for (i=0; i<nbase*100; i++) {
  268. montgomery_step(&mb);
  269. }
  270. when = now() - when;
  271. printf("monty step: %5.1fns\n", when * 1e9 / i);
  272. memset(&mba,0,sizeof(mba));
  273. when = now();
  274. for (i=0; i<nbase*100; i++) {
  275. montgomery_aux_step(&mba);
  276. }
  277. when = now() - when;
  278. printf("monty aux: %5.1fns\n", when * 1e9 / i);
  279. when = now();
  280. for (i=0; i<nbase/10; i++) {
  281. ignore_result(montgomery_ladder(a,b,sk,FIELD_BITS,0));
  282. }
  283. when = now() - when;
  284. printf("full ladder: %5.1fµs\n", when * 1e6 / i);
  285. when = now();
  286. for (i=0; i<nbase/10; i++) {
  287. scalarmul(&ext,sk);
  288. }
  289. when = now() - when;
  290. printf("edwards smz: %5.1fµs\n", when * 1e6 / i);
  291. when = now();
  292. for (i=0; i<nbase/10; i++) {
  293. scalarmul_vlook(&ext,sk);
  294. }
  295. when = now() - when;
  296. printf("edwards svl: %5.1fµs\n", when * 1e6 / i);
  297. when = now();
  298. for (i=0; i<nbase/10; i++) {
  299. scalarmul(&ext,sk);
  300. untwist_and_double_and_serialize(a,&ext);
  301. }
  302. when = now() - when;
  303. printf("edwards smc: %5.1fµs\n", when * 1e6 / i);
  304. when = now();
  305. for (i=0; i<nbase/10; i++) {
  306. q448_randomize(&crand, sk);
  307. scalarmul_vt(&ext,sk,SCALAR_BITS);
  308. }
  309. when = now() - when;
  310. printf("edwards vtm: %5.1fµs\n", when * 1e6 / i);
  311. struct tw_niels_t wnaft[1<<6];
  312. when = now();
  313. for (i=0; i<nbase/10; i++) {
  314. ignore_result(precompute_fixed_base_wnaf(wnaft,&ext,6));
  315. }
  316. when = now() - when;
  317. printf("wnaf6 pre: %5.1fµs\n", when * 1e6 / i);
  318. when = now();
  319. for (i=0; i<nbase/10; i++) {
  320. q448_randomize(&crand, sk);
  321. scalarmul_fixed_base_wnaf_vt(&ext,sk,SCALAR_BITS,wnaft,6);
  322. }
  323. when = now() - when;
  324. printf("edwards vt6: %5.1fµs\n", when * 1e6 / i);
  325. when = now();
  326. for (i=0; i<nbase/10; i++) {
  327. ignore_result(precompute_fixed_base_wnaf(wnaft,&ext,4));
  328. }
  329. when = now() - when;
  330. printf("wnaf4 pre: %5.1fµs\n", when * 1e6 / i);
  331. when = now();
  332. for (i=0; i<nbase/10; i++) {
  333. q448_randomize(&crand, sk);
  334. scalarmul_fixed_base_wnaf_vt(&ext,sk,SCALAR_BITS,wnaft,4);
  335. }
  336. when = now() - when;
  337. printf("edwards vt4: %5.1fµs\n", when * 1e6 / i);
  338. when = now();
  339. for (i=0; i<nbase/10; i++) {
  340. ignore_result(precompute_fixed_base_wnaf(wnaft,&ext,5));
  341. }
  342. when = now() - when;
  343. printf("wnaf5 pre: %5.1fµs\n", when * 1e6 / i);
  344. when = now();
  345. for (i=0; i<nbase/10; i++) {
  346. q448_randomize(&crand, sk);
  347. scalarmul_fixed_base_wnaf_vt(&ext,sk,SCALAR_BITS,wnaft,5);
  348. }
  349. when = now() - when;
  350. printf("edwards vt5: %5.1fµs\n", when * 1e6 / i);
  351. when = now();
  352. for (i=0; i<nbase/10; i++) {
  353. q448_randomize(&crand, sk);
  354. q448_randomize(&crand, tk);
  355. linear_combo_var_fixed_vt(&ext,sk,FIELD_BITS,tk,FIELD_BITS,wnaft,5);
  356. }
  357. when = now() - when;
  358. printf("vt vf combo: %5.1fµs\n", when * 1e6 / i);
  359. when = now();
  360. for (i=0; i<nbase/10; i++) {
  361. deserialize_affine(&affine, a);
  362. convert_affine_to_extensible(&exta,&affine);
  363. twist_and_double(&ext,&exta);
  364. scalarmul(&ext,sk);
  365. untwist_and_double(&exta,&ext);
  366. serialize_extensible(b, &exta);
  367. }
  368. when = now() - when;
  369. printf("edwards sm: %5.1fµs\n", when * 1e6 / i);
  370. struct fixed_base_table_t t_5_5_18, t_3_5_30, t_8_4_14, t_5_3_30, t_15_3_10;
  371. while (1) {
  372. field_randomize(&crand, a);
  373. if (deserialize_affine(&affine, a)) break;
  374. }
  375. convert_affine_to_extensible(&exta,&affine);
  376. twist_and_double(&ext,&exta);
  377. when = now();
  378. for (i=0; i<nbase/10; i++) {
  379. if (i) destroy_fixed_base(&t_5_5_18);
  380. ignore_result(precompute_fixed_base(&t_5_5_18, &ext, 5, 5, 18, NULL));
  381. }
  382. when = now() - when;
  383. printf("pre(5,5,18): %5.1fµs\n", when * 1e6 / i);
  384. when = now();
  385. for (i=0; i<nbase/10; i++) {
  386. if (i) destroy_fixed_base(&t_3_5_30);
  387. ignore_result(precompute_fixed_base(&t_3_5_30, &ext, 3, 5, 30, NULL));
  388. }
  389. when = now() - when;
  390. printf("pre(3,5,30): %5.1fµs\n", when * 1e6 / i);
  391. when = now();
  392. for (i=0; i<nbase/10; i++) {
  393. if (i) destroy_fixed_base(&t_5_3_30);
  394. ignore_result(precompute_fixed_base(&t_5_3_30, &ext, 5, 3, 30, NULL));
  395. }
  396. when = now() - when;
  397. printf("pre(5,3,30): %5.1fµs\n", when * 1e6 / i);
  398. when = now();
  399. for (i=0; i<nbase/10; i++) {
  400. if (i) destroy_fixed_base(&t_15_3_10);
  401. ignore_result(precompute_fixed_base(&t_15_3_10, &ext, 15, 3, 10, NULL));
  402. }
  403. when = now() - when;
  404. printf("pre(15,3,10):%5.1fµs\n", when * 1e6 / i);
  405. when = now();
  406. for (i=0; i<nbase/10; i++) {
  407. if (i) destroy_fixed_base(&t_8_4_14);
  408. ignore_result(precompute_fixed_base(&t_8_4_14, &ext, 8, 4, 14, NULL));
  409. }
  410. when = now() - when;
  411. printf("pre(8,4,14): %5.1fµs\n", when * 1e6 / i);
  412. when = now();
  413. for (i=0; i<nbase; i++) {
  414. scalarmul_fixed_base(&ext, sk, FIELD_BITS, &t_5_5_18);
  415. }
  416. when = now() - when;
  417. printf("com(5,5,18): %5.1fµs\n", when * 1e6 / i);
  418. when = now();
  419. for (i=0; i<nbase; i++) {
  420. scalarmul_fixed_base(&ext, sk, FIELD_BITS, &t_3_5_30);
  421. }
  422. when = now() - when;
  423. printf("com(3,5,30): %5.1fµs\n", when * 1e6 / i);
  424. when = now();
  425. for (i=0; i<nbase; i++) {
  426. scalarmul_fixed_base(&ext, sk, FIELD_BITS, &t_8_4_14);
  427. }
  428. when = now() - when;
  429. printf("com(8,4,14): %5.1fµs\n", when * 1e6 / i);
  430. when = now();
  431. for (i=0; i<nbase; i++) {
  432. scalarmul_fixed_base(&ext, sk, FIELD_BITS, &t_5_3_30);
  433. }
  434. when = now() - when;
  435. printf("com(5,3,30): %5.1fµs\n", when * 1e6 / i);
  436. when = now();
  437. for (i=0; i<nbase; i++) {
  438. scalarmul_fixed_base(&ext, sk, FIELD_BITS, &t_15_3_10);
  439. }
  440. when = now() - when;
  441. printf("com(15,3,10):%5.1fµs\n", when * 1e6 / i);
  442. printf("\nGoldilocks:\n");
  443. int res = goldilocks_init();
  444. assert(!res);
  445. struct goldilocks_public_key_t gpk,hpk;
  446. struct goldilocks_private_key_t gsk,hsk;
  447. when = now();
  448. for (i=0; i<nbase; i++) {
  449. if (i&1) {
  450. res = goldilocks_keygen(&gsk,&gpk);
  451. } else {
  452. res = goldilocks_keygen(&hsk,&hpk);
  453. }
  454. assert(!res);
  455. }
  456. when = now() - when;
  457. printf("keygen: %5.1fµs\n", when * 1e6 / i);
  458. uint8_t ss1[64],ss2[64];
  459. int gres1=0,gres2=0;
  460. when = now();
  461. for (i=0; i<nbase; i++) {
  462. if (i&1) {
  463. gres1 = goldilocks_shared_secret(ss1,&gsk,&hpk);
  464. } else {
  465. gres2 = goldilocks_shared_secret(ss2,&hsk,&gpk);
  466. }
  467. }
  468. when = now() - when;
  469. printf("ecdh: %5.1fµs\n", when * 1e6 / i);
  470. if (gres1 || gres2 || memcmp(ss1,ss2,64)) {
  471. printf("[FAIL] %d %d\n",gres1,gres2);
  472. printf("sk1 = ");
  473. for (i=0; i<SCALAR_BYTES; i++) {
  474. printf("%02x", gsk.opaque[i]);
  475. }
  476. printf("\nsk2 = ");
  477. for (i=0; i<SCALAR_BYTES; i++) {
  478. printf("%02x", hsk.opaque[i]);
  479. }
  480. printf("\nss1 = ");
  481. for (i=0; i<64; i++) {
  482. printf("%02x", ss1[i]);
  483. }
  484. printf("\nss2 = ");
  485. for (i=0; i<64; i++) {
  486. printf("%02x", ss2[i]);
  487. }
  488. printf("\n");
  489. }
  490. uint8_t sout[FIELD_BYTES*2];
  491. const char *message = "hello world";
  492. size_t message_len = strlen(message);
  493. when = now();
  494. for (i=0; i<nbase; i++) {
  495. res = goldilocks_sign(sout,(const unsigned char *)message,message_len,&gsk);
  496. (void)res;
  497. assert(!res);
  498. }
  499. when = now() - when;
  500. printf("sign: %5.1fµs\n", when * 1e6 / i);
  501. when = now();
  502. for (i=0; i<nbase; i++) {
  503. int ver = goldilocks_verify(sout,(const unsigned char *)message,message_len,&gpk);
  504. (void)ver;
  505. assert(!ver);
  506. }
  507. when = now() - when;
  508. printf("verify: %5.1fµs\n", when * 1e6 / i);
  509. struct goldilocks_precomputed_public_key_t *pre = NULL;
  510. when = now();
  511. for (i=0; i<nbase; i++) {
  512. goldilocks_destroy_precomputed_public_key(pre);
  513. pre = goldilocks_precompute_public_key(&gpk);
  514. }
  515. when = now() - when;
  516. printf("precompute: %5.1fµs\n", when * 1e6 / i);
  517. when = now();
  518. for (i=0; i<nbase; i++) {
  519. int ver = goldilocks_verify_precomputed(sout,(const unsigned char *)message,message_len,pre);
  520. (void)ver;
  521. assert(!ver);
  522. }
  523. when = now() - when;
  524. printf("verify pre: %5.1fµs\n", when * 1e6 / i);
  525. when = now();
  526. for (i=0; i<nbase; i++) {
  527. int ret = goldilocks_shared_secret_precomputed(ss1,&gsk,pre);
  528. (void)ret;
  529. assert(!ret);
  530. }
  531. when = now() - when;
  532. printf("ecdh pre: %5.1fµs\n", when * 1e6 / i);
  533. printf("\nTesting...\n");
  534. int failures=0, successes = 0;
  535. for (i=0; i<nbase/10; i++) {
  536. ignore_result(goldilocks_keygen(&gsk,&gpk));
  537. goldilocks_sign(sout,(const unsigned char *)message,message_len,&gsk);
  538. res = goldilocks_verify(sout,(const unsigned char *)message,message_len,&gpk);
  539. if (res) failures++;
  540. }
  541. if (failures) {
  542. printf("FAIL %d/%d signature checks!\n", failures, i);
  543. }
  544. failures=0; successes = 0;
  545. for (i=0; i<nbase/10; i++) {
  546. field_randomize(&crand, a);
  547. word_t two = 2;
  548. mask_t good = montgomery_ladder(b,a,&two,2,0);
  549. if (!good) continue;
  550. word_t x,y;
  551. crandom_generate(&crand, (unsigned char *)&x, sizeof(x));
  552. crandom_generate(&crand, (unsigned char *)&y, sizeof(y));
  553. x = (hword_t)x;
  554. y = (hword_t)y;
  555. word_t z=x*y;
  556. ignore_result(montgomery_ladder(b,a,&x,WORD_BITS,0));
  557. ignore_result(montgomery_ladder(c,b,&y,WORD_BITS,0));
  558. ignore_result(montgomery_ladder(b,a,&z,WORD_BITS,0));
  559. field_sub(d,b,c);
  560. if (!field_is_zero(d)) {
  561. printf("Odd ladder validation failure %d!\n", ++failures);
  562. field_print("a", a);
  563. printf("x=%"PRIxWORD", y=%"PRIxWORD", z=%"PRIxWORD"\n", x,y,z);
  564. field_print("c", c);
  565. field_print("b", b);
  566. printf("\n");
  567. }
  568. }
  569. failures = 0;
  570. for (i=0; i<nbase/10; i++) {
  571. mask_t good;
  572. do {
  573. field_randomize(&crand, a);
  574. good = deserialize_affine(&affine, a);
  575. } while (!good);
  576. convert_affine_to_extensible(&exta,&affine);
  577. twist_and_double(&ext,&exta);
  578. untwist_and_double(&exta,&ext);
  579. serialize_extensible(b, &exta);
  580. untwist_and_double_and_serialize(c, &ext);
  581. field_sub(d,b,c);
  582. if (good && !field_is_zero(d)){
  583. printf("Iso+serial validation failure %d!\n", ++failures);
  584. field_print("a", a);
  585. field_print("b", b);
  586. field_print("c", c);
  587. printf("\n");
  588. } else if (good) {
  589. successes ++;
  590. }
  591. }
  592. if (successes < i/3) {
  593. printf("Iso+serial variation: only %d/%d successful.\n", successes, i);
  594. }
  595. successes = failures = 0;
  596. for (i=0; i<nbase/10; i++) {
  597. field_a_t aa;
  598. struct tw_extensible_t exu,exv,exw;
  599. mask_t good;
  600. do {
  601. field_randomize(&crand, a);
  602. good = deserialize_affine(&affine, a);
  603. convert_affine_to_extensible(&exta,&affine);
  604. twist_and_double(&ext,&exta);
  605. } while (!good);
  606. do {
  607. field_randomize(&crand, aa);
  608. good = deserialize_affine(&affine, aa);
  609. convert_affine_to_extensible(&exta,&affine);
  610. twist_and_double(&exu,&exta);
  611. } while (!good);
  612. field_randomize(&crand, aa);
  613. q448_randomize(&crand, sk);
  614. if (i==0 || i==2) memset(&sk, 0, sizeof(sk));
  615. q448_randomize(&crand, tk);
  616. if (i==0 || i==1) memset(&tk, 0, sizeof(tk));
  617. copy_tw_extensible(&exv, &ext);
  618. copy_tw_extensible(&exw, &exu);
  619. scalarmul(&exv,sk);
  620. scalarmul(&exw,tk);
  621. convert_tw_extensible_to_tw_pniels(&pniels, &exw);
  622. add_tw_pniels_to_tw_extensible(&exv,&pniels);
  623. untwist_and_double(&exta,&exv);
  624. serialize_extensible(b, &exta);
  625. ignore_result(precompute_fixed_base_wnaf(wnaft,&exu,5));
  626. linear_combo_var_fixed_vt(&ext,sk,FIELD_BITS,tk,FIELD_BITS,wnaft,5);
  627. untwist_and_double(&exta,&exv);
  628. serialize_extensible(c, &exta);
  629. field_sub(d,b,c);
  630. if (!field_is_zero(d)){
  631. printf("PreWNAF combo validation failure %d!\n", ++failures);
  632. field_print("a", a);
  633. field_print("A", aa);
  634. q448_print("s", sk);
  635. q448_print("t", tk);
  636. field_print("c", c);
  637. field_print("b", b);
  638. printf("\n\n");
  639. } else if (good) {
  640. successes ++;
  641. }
  642. }
  643. if (successes < i) {
  644. printf("PreWNAF combo variation: only %d/%d successful.\n", successes, i);
  645. }
  646. return 0;
  647. }