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.
 
 
 
 
 

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