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.
 
 
 
 
 

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