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.
 
 
 
 
 

750 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, struct field_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 struct field_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 struct field_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. struct field_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. field_bias(&b,1);
  154. if (!field_is_zero(&b)) {
  155. printf("ISR validation failure!\n");
  156. field_print("a", &a);
  157. field_print("s", &d);
  158. }
  159. }
  160. when = now();
  161. for (i=0; i<nbase; i++) {
  162. elligator_2s_inject(&affine, &a);
  163. }
  164. when = now() - when;
  165. printf("elligator: %5.1fµs\n", when * 1e6 / i);
  166. for (i=0; i<100; i++) {
  167. field_randomize(&crand, &a);
  168. elligator_2s_inject(&affine, &a);
  169. if (!validate_affine(&affine)) {
  170. printf("Elligator validation failure!\n");
  171. field_print("a", &a);
  172. field_print("x", &affine.x);
  173. field_print("y", &affine.y);
  174. }
  175. }
  176. when = now();
  177. for (i=0; i<nbase; i++) {
  178. deserialize_affine(&affine, &a);
  179. }
  180. when = now() - when;
  181. printf("decompress: %5.1fµs\n", when * 1e6 / i);
  182. convert_affine_to_extensible(&exta, &affine);
  183. when = now();
  184. for (i=0; i<nbase; i++) {
  185. serialize_extensible(&a, &exta);
  186. }
  187. when = now() - when;
  188. printf("compress: %5.1fµs\n", when * 1e6 / i);
  189. int goods = 0;
  190. for (i=0; i<100; i++) {
  191. field_randomize(&crand, &a);
  192. mask_t good = deserialize_affine(&affine, &a);
  193. if (good & !validate_affine(&affine)) {
  194. printf("Deserialize validation failure!\n");
  195. field_print("a", &a);
  196. field_print("x", &affine.x);
  197. field_print("y", &affine.y);
  198. } else if (good) {
  199. goods++;
  200. convert_affine_to_extensible(&exta,&affine);
  201. serialize_extensible(&b, &exta);
  202. field_sub(&c,&b,&a);
  203. field_bias(&c,2);
  204. if (!field_is_zero(&c)) {
  205. printf("Reserialize validation failure!\n");
  206. field_print("a", &a);
  207. field_print("x", &affine.x);
  208. field_print("y", &affine.y);
  209. deserialize_affine(&affine, &b);
  210. field_print("b", &b);
  211. field_print("x", &affine.x);
  212. field_print("y", &affine.y);
  213. printf("\n");
  214. }
  215. }
  216. }
  217. if (goods<i/3) {
  218. printf("Deserialization validation failure! Deserialized %d/%d points\n", goods, i);
  219. }
  220. word_t lsk[768/WORD_BITS];
  221. crandom_generate(&crand, (unsigned char *)lsk, sizeof(lsk));
  222. when = now();
  223. for (i=0; i<nbase*100; i++) {
  224. barrett_reduce(lsk,sizeof(lsk)/sizeof(word_t),0,&curve_prime_order);
  225. }
  226. when = now() - when;
  227. printf("barrett red: %5.1fns\n", when * 1e9 / i);
  228. when = now();
  229. for (i=0; i<nbase*10; i++) {
  230. barrett_mac(lsk,SCALAR_WORDS,lsk,SCALAR_WORDS,lsk,SCALAR_WORDS,&curve_prime_order);
  231. }
  232. when = now() - when;
  233. printf("barrett mac: %5.1fns\n", when * 1e9 / i);
  234. memset(&ext,0,sizeof(ext));
  235. memset(&niels,0,sizeof(niels)); /* avoid assertions in p521 even though this isn't a valid ext or niels */
  236. when = now();
  237. for (i=0; i<nbase*100; i++) {
  238. add_tw_niels_to_tw_extensible(&ext, &niels);
  239. }
  240. when = now() - when;
  241. printf("exti+niels: %5.1fns\n", when * 1e9 / i);
  242. convert_tw_extensible_to_tw_pniels(&pniels, &ext);
  243. when = now();
  244. for (i=0; i<nbase*100; i++) {
  245. add_tw_pniels_to_tw_extensible(&ext, &pniels);
  246. }
  247. when = now() - when;
  248. printf("exti+pniels: %5.1fns\n", when * 1e9 / i);
  249. when = now();
  250. for (i=0; i<nbase*100; i++) {
  251. double_tw_extensible(&ext);
  252. }
  253. when = now() - when;
  254. printf("exti dbl: %5.1fns\n", when * 1e9 / i);
  255. when = now();
  256. for (i=0; i<nbase*100; i++) {
  257. untwist_and_double(&exta, &ext);
  258. }
  259. when = now() - when;
  260. printf("i->a isog: %5.1fns\n", when * 1e9 / i);
  261. when = now();
  262. for (i=0; i<nbase*100; i++) {
  263. twist_and_double(&ext, &exta);
  264. }
  265. when = now() - when;
  266. printf("a->i isog: %5.1fns\n", when * 1e9 / i);
  267. memset(&mb,0,sizeof(mb));
  268. when = now();
  269. for (i=0; i<nbase*100; i++) {
  270. montgomery_step(&mb);
  271. }
  272. when = now() - when;
  273. printf("monty step: %5.1fns\n", when * 1e9 / i);
  274. memset(&mba,0,sizeof(mba));
  275. when = now();
  276. for (i=0; i<nbase*100; i++) {
  277. montgomery_aux_step(&mba);
  278. }
  279. when = now() - when;
  280. printf("monty aux: %5.1fns\n", when * 1e9 / i);
  281. when = now();
  282. for (i=0; i<nbase/10; i++) {
  283. ignore_result(montgomery_ladder(&a,&b,sk,FIELD_BITS,0));
  284. }
  285. when = now() - when;
  286. printf("full ladder: %5.1fµs\n", when * 1e6 / i);
  287. when = now();
  288. for (i=0; i<nbase/10; i++) {
  289. scalarmul(&ext,sk);
  290. }
  291. when = now() - when;
  292. printf("edwards smz: %5.1fµs\n", when * 1e6 / i);
  293. when = now();
  294. for (i=0; i<nbase/10; i++) {
  295. scalarmul_vlook(&ext,sk);
  296. }
  297. when = now() - when;
  298. printf("edwards svl: %5.1fµs\n", when * 1e6 / i);
  299. when = now();
  300. for (i=0; i<nbase/10; i++) {
  301. scalarmul(&ext,sk);
  302. untwist_and_double_and_serialize(&a,&ext);
  303. }
  304. when = now() - when;
  305. printf("edwards smc: %5.1fµs\n", when * 1e6 / i);
  306. when = now();
  307. for (i=0; i<nbase/10; i++) {
  308. q448_randomize(&crand, sk);
  309. scalarmul_vt(&ext,sk,SCALAR_BITS);
  310. }
  311. when = now() - when;
  312. printf("edwards vtm: %5.1fµs\n", when * 1e6 / i);
  313. struct tw_niels_t wnaft[1<<6];
  314. when = now();
  315. for (i=0; i<nbase/10; i++) {
  316. ignore_result(precompute_fixed_base_wnaf(wnaft,&ext,6));
  317. }
  318. when = now() - when;
  319. printf("wnaf6 pre: %5.1fµs\n", when * 1e6 / i);
  320. when = now();
  321. for (i=0; i<nbase/10; i++) {
  322. q448_randomize(&crand, sk);
  323. scalarmul_fixed_base_wnaf_vt(&ext,sk,SCALAR_BITS,wnaft,6);
  324. }
  325. when = now() - when;
  326. printf("edwards vt6: %5.1fµs\n", when * 1e6 / i);
  327. when = now();
  328. for (i=0; i<nbase/10; i++) {
  329. ignore_result(precompute_fixed_base_wnaf(wnaft,&ext,4));
  330. }
  331. when = now() - when;
  332. printf("wnaf4 pre: %5.1fµs\n", when * 1e6 / i);
  333. when = now();
  334. for (i=0; i<nbase/10; i++) {
  335. q448_randomize(&crand, sk);
  336. scalarmul_fixed_base_wnaf_vt(&ext,sk,SCALAR_BITS,wnaft,4);
  337. }
  338. when = now() - when;
  339. printf("edwards vt4: %5.1fµs\n", when * 1e6 / i);
  340. when = now();
  341. for (i=0; i<nbase/10; i++) {
  342. ignore_result(precompute_fixed_base_wnaf(wnaft,&ext,5));
  343. }
  344. when = now() - when;
  345. printf("wnaf5 pre: %5.1fµs\n", when * 1e6 / i);
  346. when = now();
  347. for (i=0; i<nbase/10; i++) {
  348. q448_randomize(&crand, sk);
  349. scalarmul_fixed_base_wnaf_vt(&ext,sk,SCALAR_BITS,wnaft,5);
  350. }
  351. when = now() - when;
  352. printf("edwards vt5: %5.1fµs\n", when * 1e6 / i);
  353. when = now();
  354. for (i=0; i<nbase/10; i++) {
  355. q448_randomize(&crand, sk);
  356. q448_randomize(&crand, tk);
  357. linear_combo_var_fixed_vt(&ext,sk,FIELD_BITS,tk,FIELD_BITS,wnaft,5);
  358. }
  359. when = now() - when;
  360. printf("vt vf combo: %5.1fµs\n", when * 1e6 / i);
  361. when = now();
  362. for (i=0; i<nbase/10; i++) {
  363. deserialize_affine(&affine, &a);
  364. convert_affine_to_extensible(&exta,&affine);
  365. twist_and_double(&ext,&exta);
  366. scalarmul(&ext,sk);
  367. untwist_and_double(&exta,&ext);
  368. serialize_extensible(&b, &exta);
  369. }
  370. when = now() - when;
  371. printf("edwards sm: %5.1fµs\n", when * 1e6 / i);
  372. 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;
  373. while (1) {
  374. field_randomize(&crand, &a);
  375. if (deserialize_affine(&affine, &a)) break;
  376. }
  377. convert_affine_to_extensible(&exta,&affine);
  378. twist_and_double(&ext,&exta);
  379. when = now();
  380. for (i=0; i<nbase/10; i++) {
  381. if (i) destroy_fixed_base(&t_5_5_18);
  382. ignore_result(precompute_fixed_base(&t_5_5_18, &ext, 5, 5, 18, NULL));
  383. }
  384. when = now() - when;
  385. printf("pre(5,5,18): %5.1fµs\n", when * 1e6 / i);
  386. when = now();
  387. for (i=0; i<nbase/10; i++) {
  388. if (i) destroy_fixed_base(&t_3_5_30);
  389. ignore_result(precompute_fixed_base(&t_3_5_30, &ext, 3, 5, 30, NULL));
  390. }
  391. when = now() - when;
  392. printf("pre(3,5,30): %5.1fµs\n", when * 1e6 / i);
  393. when = now();
  394. for (i=0; i<nbase/10; i++) {
  395. if (i) destroy_fixed_base(&t_5_3_30);
  396. ignore_result(precompute_fixed_base(&t_5_3_30, &ext, 5, 3, 30, NULL));
  397. }
  398. when = now() - when;
  399. printf("pre(5,3,30): %5.1fµs\n", when * 1e6 / i);
  400. when = now();
  401. for (i=0; i<nbase/10; i++) {
  402. if (i) destroy_fixed_base(&t_15_3_10);
  403. ignore_result(precompute_fixed_base(&t_15_3_10, &ext, 15, 3, 10, NULL));
  404. }
  405. when = now() - when;
  406. printf("pre(15,3,10):%5.1fµs\n", when * 1e6 / i);
  407. when = now();
  408. for (i=0; i<nbase/10; i++) {
  409. if (i) destroy_fixed_base(&t_8_4_14);
  410. ignore_result(precompute_fixed_base(&t_8_4_14, &ext, 8, 4, 14, NULL));
  411. }
  412. when = now() - when;
  413. printf("pre(8,4,14): %5.1fµs\n", when * 1e6 / i);
  414. when = now();
  415. for (i=0; i<nbase; i++) {
  416. scalarmul_fixed_base(&ext, sk, FIELD_BITS, &t_5_5_18);
  417. }
  418. when = now() - when;
  419. printf("com(5,5,18): %5.1fµs\n", when * 1e6 / i);
  420. when = now();
  421. for (i=0; i<nbase; i++) {
  422. scalarmul_fixed_base(&ext, sk, FIELD_BITS, &t_3_5_30);
  423. }
  424. when = now() - when;
  425. printf("com(3,5,30): %5.1fµs\n", when * 1e6 / i);
  426. when = now();
  427. for (i=0; i<nbase; i++) {
  428. scalarmul_fixed_base(&ext, sk, FIELD_BITS, &t_8_4_14);
  429. }
  430. when = now() - when;
  431. printf("com(8,4,14): %5.1fµs\n", when * 1e6 / i);
  432. when = now();
  433. for (i=0; i<nbase; i++) {
  434. scalarmul_fixed_base(&ext, sk, FIELD_BITS, &t_5_3_30);
  435. }
  436. when = now() - when;
  437. printf("com(5,3,30): %5.1fµs\n", when * 1e6 / i);
  438. when = now();
  439. for (i=0; i<nbase; i++) {
  440. scalarmul_fixed_base(&ext, sk, FIELD_BITS, &t_15_3_10);
  441. }
  442. when = now() - when;
  443. printf("com(15,3,10):%5.1fµs\n", when * 1e6 / i);
  444. printf("\nGoldilocks:\n");
  445. int res = goldilocks_init();
  446. assert(!res);
  447. struct goldilocks_public_key_t gpk,hpk;
  448. struct goldilocks_private_key_t gsk,hsk;
  449. when = now();
  450. for (i=0; i<nbase; i++) {
  451. if (i&1) {
  452. res = goldilocks_keygen(&gsk,&gpk);
  453. } else {
  454. res = goldilocks_keygen(&hsk,&hpk);
  455. }
  456. assert(!res);
  457. }
  458. when = now() - when;
  459. printf("keygen: %5.1fµs\n", when * 1e6 / i);
  460. uint8_t ss1[64],ss2[64];
  461. int gres1=0,gres2=0;
  462. when = now();
  463. for (i=0; i<nbase; i++) {
  464. if (i&1) {
  465. gres1 = goldilocks_shared_secret(ss1,&gsk,&hpk);
  466. } else {
  467. gres2 = goldilocks_shared_secret(ss2,&hsk,&gpk);
  468. }
  469. }
  470. when = now() - when;
  471. printf("ecdh: %5.1fµs\n", when * 1e6 / i);
  472. if (gres1 || gres2 || memcmp(ss1,ss2,64)) {
  473. printf("[FAIL] %d %d\n",gres1,gres2);
  474. printf("sk1 = ");
  475. for (i=0; i<SCALAR_BYTES; i++) {
  476. printf("%02x", gsk.opaque[i]);
  477. }
  478. printf("\nsk2 = ");
  479. for (i=0; i<SCALAR_BYTES; i++) {
  480. printf("%02x", hsk.opaque[i]);
  481. }
  482. printf("\nss1 = ");
  483. for (i=0; i<64; i++) {
  484. printf("%02x", ss1[i]);
  485. }
  486. printf("\nss2 = ");
  487. for (i=0; i<64; i++) {
  488. printf("%02x", ss2[i]);
  489. }
  490. printf("\n");
  491. }
  492. uint8_t sout[FIELD_BYTES*2];
  493. const char *message = "hello world";
  494. size_t message_len = strlen(message);
  495. when = now();
  496. for (i=0; i<nbase; i++) {
  497. res = goldilocks_sign(sout,(const unsigned char *)message,message_len,&gsk);
  498. (void)res;
  499. assert(!res);
  500. }
  501. when = now() - when;
  502. printf("sign: %5.1fµs\n", when * 1e6 / i);
  503. when = now();
  504. for (i=0; i<nbase; i++) {
  505. int ver = goldilocks_verify(sout,(const unsigned char *)message,message_len,&gpk);
  506. (void)ver;
  507. assert(!ver);
  508. }
  509. when = now() - when;
  510. printf("verify: %5.1fµs\n", when * 1e6 / i);
  511. struct goldilocks_precomputed_public_key_t *pre = NULL;
  512. when = now();
  513. for (i=0; i<nbase; i++) {
  514. goldilocks_destroy_precomputed_public_key(pre);
  515. pre = goldilocks_precompute_public_key(&gpk);
  516. }
  517. when = now() - when;
  518. printf("precompute: %5.1fµs\n", when * 1e6 / i);
  519. when = now();
  520. for (i=0; i<nbase; i++) {
  521. int ver = goldilocks_verify_precomputed(sout,(const unsigned char *)message,message_len,pre);
  522. (void)ver;
  523. assert(!ver);
  524. }
  525. when = now() - when;
  526. printf("verify pre: %5.1fµs\n", when * 1e6 / i);
  527. when = now();
  528. for (i=0; i<nbase; i++) {
  529. int ret = goldilocks_shared_secret_precomputed(ss1,&gsk,pre);
  530. (void)ret;
  531. assert(!ret);
  532. }
  533. when = now() - when;
  534. printf("ecdh pre: %5.1fµs\n", when * 1e6 / i);
  535. printf("\nTesting...\n");
  536. int failures=0, successes = 0;
  537. for (i=0; i<nbase/10; i++) {
  538. ignore_result(goldilocks_keygen(&gsk,&gpk));
  539. goldilocks_sign(sout,(const unsigned char *)message,message_len,&gsk);
  540. res = goldilocks_verify(sout,(const unsigned char *)message,message_len,&gpk);
  541. if (res) failures++;
  542. }
  543. if (failures) {
  544. printf("FAIL %d/%d signature checks!\n", failures, i);
  545. }
  546. failures=0; successes = 0;
  547. for (i=0; i<nbase/10; i++) {
  548. field_randomize(&crand, &a);
  549. word_t two = 2;
  550. mask_t good = montgomery_ladder(&b,&a,&two,2,0);
  551. if (!good) continue;
  552. word_t x,y;
  553. crandom_generate(&crand, (unsigned char *)&x, sizeof(x));
  554. crandom_generate(&crand, (unsigned char *)&y, sizeof(y));
  555. x = (hword_t)x;
  556. y = (hword_t)y;
  557. word_t z=x*y;
  558. ignore_result(montgomery_ladder(&b,&a,&x,WORD_BITS,0));
  559. ignore_result(montgomery_ladder(&c,&b,&y,WORD_BITS,0));
  560. ignore_result(montgomery_ladder(&b,&a,&z,WORD_BITS,0));
  561. field_sub(&d,&b,&c);
  562. field_bias(&d,2);
  563. if (!field_is_zero(&d)) {
  564. printf("Odd ladder validation failure %d!\n", ++failures);
  565. field_print("a", &a);
  566. printf("x=%"PRIxWORD", y=%"PRIxWORD", z=%"PRIxWORD"\n", x,y,z);
  567. field_print("c", &c);
  568. field_print("b", &b);
  569. printf("\n");
  570. }
  571. }
  572. failures = 0;
  573. for (i=0; i<nbase/10; i++) {
  574. mask_t good;
  575. do {
  576. field_randomize(&crand, &a);
  577. good = deserialize_affine(&affine, &a);
  578. } while (!good);
  579. convert_affine_to_extensible(&exta,&affine);
  580. twist_and_double(&ext,&exta);
  581. untwist_and_double(&exta,&ext);
  582. serialize_extensible(&b, &exta);
  583. untwist_and_double_and_serialize(&c, &ext);
  584. field_sub(&d,&b,&c);
  585. field_bias(&d,2);
  586. if (good && !field_is_zero(&d)){
  587. printf("Iso+serial validation failure %d!\n", ++failures);
  588. field_print("a", &a);
  589. field_print("b", &b);
  590. field_print("c", &c);
  591. printf("\n");
  592. } else if (good) {
  593. successes ++;
  594. }
  595. }
  596. if (successes < i/3) {
  597. printf("Iso+serial variation: only %d/%d successful.\n", successes, i);
  598. }
  599. successes = failures = 0;
  600. for (i=0; i<nbase/10; i++) {
  601. struct field_t aa;
  602. struct tw_extensible_t exu,exv,exw;
  603. mask_t good;
  604. do {
  605. field_randomize(&crand, &a);
  606. good = deserialize_affine(&affine, &a);
  607. convert_affine_to_extensible(&exta,&affine);
  608. twist_and_double(&ext,&exta);
  609. } while (!good);
  610. do {
  611. field_randomize(&crand, &aa);
  612. good = deserialize_affine(&affine, &aa);
  613. convert_affine_to_extensible(&exta,&affine);
  614. twist_and_double(&exu,&exta);
  615. } while (!good);
  616. field_randomize(&crand, &aa);
  617. q448_randomize(&crand, sk);
  618. if (i==0 || i==2) memset(&sk, 0, sizeof(sk));
  619. q448_randomize(&crand, tk);
  620. if (i==0 || i==1) memset(&tk, 0, sizeof(tk));
  621. copy_tw_extensible(&exv, &ext);
  622. copy_tw_extensible(&exw, &exu);
  623. scalarmul(&exv,sk);
  624. scalarmul(&exw,tk);
  625. convert_tw_extensible_to_tw_pniels(&pniels, &exw);
  626. add_tw_pniels_to_tw_extensible(&exv,&pniels);
  627. untwist_and_double(&exta,&exv);
  628. serialize_extensible(&b, &exta);
  629. ignore_result(precompute_fixed_base_wnaf(wnaft,&exu,5));
  630. linear_combo_var_fixed_vt(&ext,sk,FIELD_BITS,tk,FIELD_BITS,wnaft,5);
  631. untwist_and_double(&exta,&exv);
  632. serialize_extensible(&c, &exta);
  633. field_sub(&d,&b,&c);
  634. field_bias(&d,2);
  635. if (!field_is_zero(&d)){
  636. printf("PreWNAF combo validation failure %d!\n", ++failures);
  637. field_print("a", &a);
  638. field_print("A", &aa);
  639. q448_print("s", sk);
  640. q448_print("t", tk);
  641. field_print("c", &c);
  642. field_print("b", &b);
  643. printf("\n\n");
  644. } else if (good) {
  645. successes ++;
  646. }
  647. }
  648. if (successes < i) {
  649. printf("PreWNAF combo variation: only %d/%d successful.\n", successes, i);
  650. }
  651. return 0;
  652. }