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.
 
 
 
 
 

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