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.
 
 
 
 
 

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