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.
 
 
 
 
 

781 lines
22 KiB

  1. /* Copyright (c) 2014 Cryptography Research, Inc.
  2. * Released under the MIT License. See LICENSE.txt for license information.
  3. */
  4. #include <sys/time.h>
  5. #include <sys/types.h>
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <memory.h>
  9. #include "p448.h"
  10. #include "ec_point.h"
  11. #include "scalarmul.h"
  12. #include "barrett_field.h"
  13. #include "crandom.h"
  14. #include "goldilocks.h"
  15. word_t q448_lo[4] = {
  16. 0xdc873d6d54a7bb0dull,
  17. 0xde933d8d723a70aaull,
  18. 0x3bb124b65129c96full,
  19. 0x000000008335dc16ull
  20. };
  21. double now() {
  22. struct timeval tv;
  23. gettimeofday(&tv, NULL);
  24. return tv.tv_sec + tv.tv_usec/1000000.0;
  25. }
  26. void p448_randomize( struct crandom_state_t *crand, struct p448_t *a ) {
  27. crandom_generate(crand, (unsigned char *)a, sizeof(*a));
  28. p448_strong_reduce(a);
  29. }
  30. void q448_randomize( struct crandom_state_t *crand, uint64_t sk[7] ) {
  31. crandom_generate(crand, (unsigned char *)sk, sizeof(uint64_t)*7);
  32. }
  33. void p448_print( const char *descr, const struct p448_t *a ) {
  34. p448_t b;
  35. p448_copy(&b, a);
  36. p448_strong_reduce(&b);
  37. int j;
  38. printf("%s = 0x", descr);
  39. for (j=7; j>=0; j--) {
  40. printf("%014llx", (unsigned long long)b.limb[j]);
  41. }
  42. printf("\n");
  43. }
  44. void p448_print_full( const char *descr, const struct p448_t *a ) {
  45. int j;
  46. printf("%s = 0x", descr);
  47. for (j=7; j>=0; j--) {
  48. printf("%02llx_%014llx ", a->limb[j]>>56, (unsigned long long)a->limb[j]&(1ull<<56)-1);
  49. }
  50. printf("\n");
  51. }
  52. void q448_print( const char *descr, const uint64_t secret[7] ) {
  53. int j;
  54. printf("%s = 0x", descr);
  55. for (j=6; j>=0; j--) {
  56. printf("%016llx", (unsigned long long)secret[j]);
  57. }
  58. printf("\n");
  59. }
  60. int main(int argc, char **argv) {
  61. (void)argc;
  62. (void)argv;
  63. struct tw_extensible_t ext;
  64. struct extensible_t exta;
  65. struct tw_niels_t niels;
  66. struct tw_pniels_t pniels;
  67. struct affine_t affine;
  68. struct montgomery_t mb;
  69. struct p448_t a,b,c,d;
  70. double when;
  71. int i,j;
  72. /* Bad randomness so we can debug. */
  73. char initial_seed[32];
  74. for (i=0; i<32; i++) initial_seed[i] = i;
  75. struct crandom_state_t crand;
  76. crandom_init_from_buffer(&crand, initial_seed);
  77. uint64_t sk[7],tk[7];
  78. q448_randomize(&crand, sk);
  79. when = now();
  80. for (i=0; i<10000000; i++) {
  81. p448_mul(&c, &b, &a);
  82. }
  83. when = now() - when;
  84. printf("mul: %5.1fns\n", when * 1e9 / i);
  85. when = now();
  86. for (i=0; i<10000000; i++) {
  87. p448_sqr(&c, &a);
  88. }
  89. when = now() - when;
  90. printf("sqr: %5.1fns\n", when * 1e9 / i);
  91. when = now();
  92. for (i=0; i<5000000; i++) {
  93. p448_mul(&c, &b, &a);
  94. p448_mul(&a, &b, &c);
  95. }
  96. when = now() - when;
  97. printf("mul dep: %5.1fns\n", when * 1e9 / i / 2);
  98. when = now();
  99. for (i=0; i<10000000; i++) {
  100. p448_mulw(&c, &b, 1234562);
  101. }
  102. when = now() - when;
  103. printf("mulw: %5.1fns\n", when * 1e9 / i);
  104. when = now();
  105. for (i=0; i<100000; i++) {
  106. p448_randomize(&crand, &a);
  107. }
  108. when = now() - when;
  109. printf("rand448: %5.1fns\n", when * 1e9 / i);
  110. when = now();
  111. for (i=0; i<10000; i++) {
  112. p448_isr(&c, &a);
  113. }
  114. when = now() - when;
  115. printf("isr auto: %5.1fµs\n", when * 1e6 / i);
  116. for (i=0; i<100; i++) {
  117. p448_randomize(&crand, &a);
  118. p448_isr(&d,&a);
  119. p448_sqr(&b,&d);
  120. p448_mul(&c,&b,&a);
  121. p448_sqr(&b,&c);
  122. p448_subw(&b,1);
  123. p448_bias(&b,1);
  124. if (!p448_is_zero(&b)) {
  125. printf("ISR validation failure!\n");
  126. p448_print("a", &a);
  127. p448_print("s", &d);
  128. }
  129. }
  130. when = now();
  131. for (i=0; i<10000; i++) {
  132. elligator_2s_inject(&affine, &a);
  133. }
  134. when = now() - when;
  135. printf("elligator: %5.1fµs\n", when * 1e6 / i);
  136. for (i=0; i<100; i++) {
  137. p448_randomize(&crand, &a);
  138. elligator_2s_inject(&affine, &a);
  139. if (!p448_affine_validate(&affine)) {
  140. printf("Elligator validation failure!\n");
  141. p448_print("a", &a);
  142. p448_print("x", &affine.x);
  143. p448_print("y", &affine.y);
  144. }
  145. }
  146. when = now();
  147. for (i=0; i<10000; i++) {
  148. affine_deserialize(&affine, &a);
  149. }
  150. when = now() - when;
  151. printf("decompress: %5.1fµs\n", when * 1e6 / i);
  152. when = now();
  153. for (i=0; i<10000; i++) {
  154. extensible_serialize(&a, &exta);
  155. }
  156. when = now() - when;
  157. printf("compress: %5.1fµs\n", when * 1e6 / i);
  158. int goods = 0;
  159. for (i=0; i<100; i++) {
  160. p448_randomize(&crand, &a);
  161. mask_t good = affine_deserialize(&affine, &a);
  162. if (good & !p448_affine_validate(&affine)) {
  163. printf("Deserialize validation failure!\n");
  164. p448_print("a", &a);
  165. p448_print("x", &affine.x);
  166. p448_print("y", &affine.y);
  167. } else if (good) {
  168. goods++;
  169. convert_affine_to_extensible(&exta,&affine);
  170. extensible_serialize(&b, &exta);
  171. p448_sub(&c,&b,&a);
  172. p448_bias(&c,2);
  173. if (!p448_is_zero(&c)) {
  174. printf("Reserialize validation failure!\n");
  175. p448_print("a", &a);
  176. p448_print("x", &affine.x);
  177. p448_print("y", &affine.y);
  178. affine_deserialize(&affine, &b);
  179. p448_print("b", &b);
  180. p448_print("x", &affine.x);
  181. p448_print("y", &affine.y);
  182. printf("\n");
  183. }
  184. }
  185. }
  186. if (goods<i/3) {
  187. printf("Deserialization validation failure! Deserialized %d/%d points\n", goods, i);
  188. }
  189. uint64_t lsk[12];
  190. for (i=0;i<10; i++) {
  191. for (j=11; j>=0; j--) {
  192. lsk[j] = random();
  193. lsk[j] = lsk[j]<<22 ^ random();
  194. lsk[j] = lsk[j]<<22 ^ random();
  195. }
  196. }
  197. when = now();
  198. for (i=0; i<1000000; i++) {
  199. barrett_reduce(lsk,12,0,q448_lo,7,4,62);
  200. }
  201. when = now() - when;
  202. printf("barrett red: %5.1fns\n", when * 1e9 / i);
  203. when = now();
  204. for (i=0; i<100000; i++) {
  205. barrett_mac(lsk,7,lsk,7,lsk,7,q448_lo,7,4,62);
  206. }
  207. when = now() - when;
  208. printf("barrett mac: %5.1fns\n", when * 1e9 / i);
  209. when = now();
  210. for (i=0; i<1000000; i++) {
  211. p448_tw_extensible_add_niels(&ext, &niels);
  212. }
  213. when = now() - when;
  214. printf("exti+niels: %5.1fns\n", when * 1e9 / i);
  215. when = now();
  216. for (i=0; i<1000000; i++) {
  217. p448_tw_extensible_add_pniels(&ext, &pniels);
  218. }
  219. when = now() - when;
  220. printf("exti+pniels: %5.1fns\n", when * 1e9 / i);
  221. when = now();
  222. for (i=0; i<1000000; i++) {
  223. p448_tw_extensible_double(&ext);
  224. }
  225. when = now() - when;
  226. printf("exti dbl: %5.1fns\n", when * 1e9 / i);
  227. when = now();
  228. for (i=0; i<1000000; i++) {
  229. p448_isogeny_tw_to_un(&exta, &ext);
  230. }
  231. when = now() - when;
  232. printf("i->a isog: %5.1fns\n", when * 1e9 / i);
  233. when = now();
  234. for (i=0; i<1000000; i++) {
  235. p448_isogeny_un_to_tw(&ext, &exta);
  236. }
  237. when = now() - when;
  238. printf("a->i isog: %5.1fns\n", when * 1e9 / i);
  239. when = now();
  240. for (i=0; i<1000000; i++) {
  241. p448_montgomery_step(&mb);
  242. }
  243. when = now() - when;
  244. printf("monty step: %5.1fns\n", when * 1e9 / i);
  245. when = now();
  246. for (i=0; i<1000; i++) {
  247. p448_montgomery_ladder(&a,&b,sk,448,0);
  248. }
  249. when = now() - when;
  250. printf("full ladder: %5.1fµs\n", when * 1e6 / i);
  251. when = now();
  252. for (i=0; i<1000; i++) {
  253. edwards_scalar_multiply(&ext,sk);
  254. }
  255. when = now() - when;
  256. printf("edwards smz: %5.1fµs\n", when * 1e6 / i);
  257. when = now();
  258. int sum = 0;
  259. for (i=0; i<1000; i++) {
  260. q448_randomize(&crand, sk);
  261. sum += edwards_scalar_multiply_vt(&ext,sk);
  262. }
  263. when = now() - when;
  264. printf("edwards vtm: %5.1fµs (%0.2f avg bits = 1.5 + 448/%0.2f)\n",
  265. when * 1e6 / i, 1.0*sum/i, 448.0*i/(sum-1.5*i));
  266. struct tw_niels_t wnaft[1<<6];
  267. when = now();
  268. for (i=0; i<1000; i++) {
  269. precompute_for_wnaf(wnaft,&ext,6);
  270. }
  271. when = now() - when;
  272. printf("wnaf6 pre: %5.1fµs\n", when * 1e6 / i);
  273. when = now();
  274. for (i=0; i<1000; i++) {
  275. q448_randomize(&crand, sk);
  276. edwards_scalar_multiply_vt_pre(&ext,sk,wnaft,6);
  277. }
  278. when = now() - when;
  279. printf("edwards vt6: %5.1fµs\n", when * 1e6 / i);
  280. when = now();
  281. for (i=0; i<1000; i++) {
  282. precompute_for_wnaf(wnaft,&ext,4);
  283. }
  284. when = now() - when;
  285. printf("wnaf4 pre: %5.1fµs\n", when * 1e6 / i);
  286. when = now();
  287. for (i=0; i<1000; i++) {
  288. q448_randomize(&crand, sk);
  289. edwards_scalar_multiply_vt_pre(&ext,sk,wnaft,4);
  290. }
  291. when = now() - when;
  292. printf("edwards vt4: %5.1fµs\n", when * 1e6 / i);
  293. when = now();
  294. for (i=0; i<1000; i++) {
  295. precompute_for_wnaf(wnaft,&ext,5);
  296. }
  297. when = now() - when;
  298. printf("wnaf5 pre: %5.1fµs\n", when * 1e6 / i);
  299. when = now();
  300. for (i=0; i<1000; i++) {
  301. q448_randomize(&crand, sk);
  302. edwards_scalar_multiply_vt_pre(&ext,sk,wnaft,5);
  303. }
  304. when = now() - when;
  305. printf("edwards vt5: %5.1fµs\n", when * 1e6 / i);
  306. when = now();
  307. sum = 0;
  308. for (i=0; i<1000; i++) {
  309. q448_randomize(&crand, sk);
  310. q448_randomize(&crand, tk);
  311. sum += edwards_combo_var_fixed_vt(&ext,sk,tk,wnaft,5);
  312. }
  313. when = now() - when;
  314. printf("vt vf combo: %5.1fµs (avg = %0.3f)\n", when * 1e6 / i, 1.0*sum/i);
  315. when = now();
  316. for (i=0; i<1000; i++) {
  317. affine_deserialize(&affine, &a);
  318. convert_affine_to_extensible(&exta,&affine);
  319. p448_isogeny_un_to_tw(&ext,&exta);
  320. edwards_scalar_multiply(&ext,sk);
  321. p448_isogeny_tw_to_un(&exta,&ext);
  322. extensible_serialize(&b, &exta);
  323. }
  324. when = now() - when;
  325. printf("edwards sm: %5.1fµs\n", when * 1e6 / i);
  326. struct tw_niels_t table[80] __attribute__((aligned(32)));
  327. while (1) {
  328. p448_randomize(&crand, &a);
  329. if (affine_deserialize(&affine, &a)) break;
  330. }
  331. convert_affine_to_extensible(&exta,&affine);
  332. p448_isogeny_un_to_tw(&ext,&exta);
  333. when = now();
  334. for (i=0; i<1000; i++) {
  335. precompute_for_combs(table, &ext, 5, 5, 18);
  336. }
  337. when = now() - when;
  338. printf("pre(5,5,18): %5.1fµs\n", when * 1e6 / i);
  339. when = now();
  340. for (i=0; i<10000; i++) {
  341. edwards_comb(&ext, sk, table, 5, 5, 18);
  342. }
  343. when = now() - when;
  344. printf("com(5,5,18): %5.1fµs\n", when * 1e6 / i);
  345. when = now();
  346. for (i=0; i<10000; i++) {
  347. edwards_comb(&ext, sk, table, 3, 5, 30);
  348. }
  349. when = now() - when;
  350. printf("com(3,5,30): %5.1fµs\n", when * 1e6 / i);
  351. when = now();
  352. for (i=0; i<10000; i++) {
  353. edwards_comb(&ext, sk, table, 2, 5, 45);
  354. }
  355. when = now() - when;
  356. printf("com(2,5,45): %5.1fµs\n", when * 1e6 / i);
  357. when = now();
  358. for (i=0; i<10000; i++) {
  359. edwards_comb(&ext, sk, table, 8, 4, 14);
  360. }
  361. when = now() - when;
  362. printf("com(4,4,28): %5.1fµs\n", when * 1e6 / i);
  363. when = now();
  364. for (i=0; i<10000; i++) {
  365. q448_randomize(&crand, sk);
  366. edwards_comb(&ext, sk, table, 5, 5, 18);
  367. p448_isogeny_tw_to_un(&exta,&ext);
  368. extensible_serialize(&b, &exta);
  369. }
  370. when = now() - when;
  371. printf("keygen: %5.1fµs\n", when * 1e6 / i);
  372. printf("\nGoldilocks:\n");
  373. int res = goldilocks_init();
  374. assert(!res);
  375. uint8_t gpk[56],gsk[56],hsk[56],hpk[56];
  376. when = now();
  377. for (i=0; i<10000; i++) {
  378. if (i&1) {
  379. res = goldilocks_keygen(gsk,gpk);
  380. } else {
  381. res = goldilocks_keygen(hsk,hpk);
  382. }
  383. assert(!res);
  384. }
  385. when = now() - when;
  386. printf("keygen: %5.1fµs\n", when * 1e6 / i);
  387. uint8_t ss1[64],ss2[64];
  388. int gres1,gres2;
  389. when = now();
  390. for (i=0; i<10000; i++) {
  391. if (i&1) {
  392. gres1 = goldilocks_shared_secret(ss1,gsk,hpk);
  393. } else {
  394. gres2 = goldilocks_shared_secret(ss2,hsk,gpk);
  395. }
  396. }
  397. when = now() - when;
  398. printf("ecdh: %5.1fµs\n", when * 1e6 / i);
  399. if (gres1 || gres2 || memcmp(ss1,ss2,56)) {
  400. printf("[FAIL] %d %d\n",gres1,gres2);
  401. printf("ss1 = ");
  402. for (i=0; i<56; i++) {
  403. printf("%02x", ss1[i]);
  404. }
  405. printf("\nss2 = ");
  406. for (i=0; i<56; i++) {
  407. printf("%02x", ss2[i]);
  408. }
  409. printf("\n");
  410. }
  411. printf("\nTesting...\n");
  412. int failures=0, successes = 0;
  413. for (i=0; i<1000; i++) {
  414. p448_randomize(&crand, &a);
  415. uint64_t two = 2;
  416. mask_t good = p448_montgomery_ladder(&b,&a,&two,2,0);
  417. if (!good) continue;
  418. uint64_t x = rand(), y=rand(), z=x*y;
  419. p448_montgomery_ladder(&b,&a,&x,64,0);
  420. p448_montgomery_ladder(&c,&b,&y,64,0);
  421. p448_montgomery_ladder(&b,&a,&z,64,0);
  422. p448_sub(&d,&b,&c);
  423. p448_bias(&d,2);
  424. if (!p448_is_zero(&d)) {
  425. printf("Odd ladder validation failure %d!\n", ++failures);
  426. p448_print("a", &a);
  427. printf("x=%llx, y=%llx, z=%llx\n", x,y,z);
  428. p448_print("c", &c);
  429. p448_print("b", &b);
  430. printf("\n");
  431. }
  432. }
  433. failures = 0;
  434. for (i=0; i<1000; i++) {
  435. mask_t good;
  436. do {
  437. p448_randomize(&crand, &a);
  438. good = affine_deserialize(&affine, &a);
  439. } while (!good);
  440. convert_affine_to_extensible(&exta,&affine);
  441. p448_isogeny_un_to_tw(&ext,&exta);
  442. p448_isogeny_tw_to_un(&exta,&ext);
  443. extensible_serialize(&b, &exta);
  444. isogeny_and_serialize(&c, &ext);
  445. p448_sub(&d,&b,&c);
  446. p448_bias(&d,2);
  447. if (good && !p448_is_zero(&d)){
  448. printf("Iso+serial validation failure %d!\n", ++failures);
  449. p448_print("a", &a);
  450. p448_print("b", &b);
  451. p448_print("c", &c);
  452. printf("\n");
  453. } else if (good) {
  454. successes ++;
  455. }
  456. }
  457. if (successes < i/3) {
  458. printf("Iso+serial variation: only %d/%d successful.\n", successes, i);
  459. }
  460. failures = 0;
  461. uint64_t four = 4;
  462. for (i=0; i<1000; i++) {
  463. p448_randomize(&crand, &a);
  464. q448_randomize(&crand, sk);
  465. mask_t good = p448_montgomery_ladder(&b,&a,&four,3,0);
  466. good &= p448_montgomery_ladder(&c,&b,sk,448,0);
  467. mask_t goodb = affine_deserialize(&affine, &a);
  468. convert_affine_to_extensible(&exta,&affine);
  469. p448_isogeny_un_to_tw(&ext,&exta);
  470. edwards_scalar_multiply(&ext,sk);
  471. p448_isogeny_tw_to_un(&exta,&ext);
  472. extensible_serialize(&b, &exta);
  473. p448_sub(&d,&b,&c);
  474. p448_bias(&d,2);
  475. if (good != goodb) {
  476. printf("Compatibility validation failure %d: good: %d != %d\n", ++failures, (int)(-good), (int)(-goodb));
  477. } else if (good && !p448_is_zero(&d)){
  478. printf("Compatibility validation failure %d!\n", ++failures);
  479. p448_print("a", &a);
  480. q448_print("s", sk);
  481. p448_print("c", &c);
  482. p448_print("b", &b);
  483. printf("\n");
  484. } else if (good) {
  485. successes ++;
  486. }
  487. }
  488. if (successes < i/3) {
  489. printf("Compatibility variation: only %d/%d successful.\n", successes, i);
  490. }
  491. successes = failures = 0;
  492. for (i=0; i<1000; i++) {
  493. p448_randomize(&crand, &a);
  494. q448_randomize(&crand, sk);
  495. if (!i) bzero(&sk, sizeof(sk));
  496. mask_t good = p448_montgomery_ladder(&b,&a,&four,3,0);
  497. good &= p448_montgomery_ladder(&c,&b,sk,448,0);
  498. if (!good) continue;
  499. affine_deserialize(&affine, &a);
  500. convert_affine_to_extensible(&exta,&affine);
  501. p448_isogeny_un_to_tw(&ext,&exta);
  502. precompute_for_combs(table, &ext, 5, 5, 18);
  503. edwards_comb(&ext, sk, table, 5, 5, 18);
  504. p448_isogeny_tw_to_un(&exta,&ext);
  505. extensible_serialize(&b, &exta);
  506. p448_sub(&d,&b,&c);
  507. p448_bias(&d,2);
  508. if (!p448_is_zero(&d)){
  509. printf("Comb validation failure %d!\n", ++failures);
  510. p448_print("a", &a);
  511. q448_print("s", sk);
  512. p448_print("c", &c);
  513. p448_print("b", &b);
  514. printf("\n");
  515. } else if (good) {
  516. successes ++;
  517. }
  518. }
  519. if (successes < i/3) {
  520. printf("Comb variation: only %d/%d successful.\n", successes, i);
  521. }
  522. successes = failures = 0;
  523. for (i=0; i<1000; i++) {
  524. p448_randomize(&crand, &a);
  525. q448_randomize(&crand, sk);
  526. if (!i) bzero(&sk, sizeof(sk));
  527. mask_t good = affine_deserialize(&affine, &a);
  528. if (!good) continue;
  529. convert_affine_to_extensible(&exta,&affine);
  530. p448_isogeny_un_to_tw(&ext,&exta);
  531. struct tw_extensible_t exu;
  532. copy_tw_extensible(&exu, &ext);
  533. edwards_scalar_multiply(&ext,sk);
  534. p448_isogeny_tw_to_un(&exta,&ext);
  535. extensible_serialize(&b, &exta);
  536. edwards_scalar_multiply_vt(&exu,sk);
  537. p448_isogeny_tw_to_un(&exta,&exu);
  538. extensible_serialize(&c, &exta);
  539. p448_sub(&d,&b,&c);
  540. p448_bias(&d,2);
  541. if (!p448_is_zero(&d)){
  542. printf("WNAF validation failure %d!\n", ++failures);
  543. p448_print("a", &a);
  544. q448_print("s", sk);
  545. p448_print("c", &c);
  546. p448_print("b", &b);
  547. printf("\n");
  548. } else if (good) {
  549. successes ++;
  550. }
  551. }
  552. if (successes < i/3) {
  553. printf("WNAF variation: only %d/%d successful.\n", successes, i);
  554. }
  555. successes = failures = 0;
  556. for (i=0; i<1000; i++) {
  557. p448_randomize(&crand, &a);
  558. q448_randomize(&crand, sk);
  559. if (!i) bzero(&sk, sizeof(sk));
  560. mask_t good = affine_deserialize(&affine, &a);
  561. if (!good) continue;
  562. convert_affine_to_extensible(&exta,&affine);
  563. p448_isogeny_un_to_tw(&ext,&exta);
  564. struct tw_extensible_t exu;
  565. copy_tw_extensible(&exu, &ext);
  566. edwards_scalar_multiply(&ext,sk);
  567. p448_isogeny_tw_to_un(&exta,&ext);
  568. extensible_serialize(&b, &exta);
  569. precompute_for_wnaf(wnaft,&exu,5);
  570. edwards_scalar_multiply_vt_pre(&exu,sk,wnaft,5);
  571. p448_isogeny_tw_to_un(&exta,&exu);
  572. extensible_serialize(&c, &exta);
  573. p448_sub(&d,&b,&c);
  574. p448_bias(&d,2);
  575. if (!p448_is_zero(&d)){
  576. printf("PreWNAF validation failure %d!\n", ++failures);
  577. p448_print("a", &a);
  578. q448_print("s", sk);
  579. p448_print("c", &c);
  580. p448_print("b", &b);
  581. for (j=0; j<1<<5; j++) {
  582. printf("WNAFT %d\n", j);
  583. p448_print(" a",&wnaft[j].a);
  584. p448_print(" b",&wnaft[j].b);
  585. p448_print(" c",&wnaft[j].c);
  586. }
  587. printf("\n\n");
  588. } else if (good) {
  589. successes ++;
  590. }
  591. }
  592. if (successes < i/3) {
  593. printf("PreWNAF variation: only %d/%d successful.\n", successes, i);
  594. }
  595. successes = failures = 0;
  596. for (i=0; i<1000; i++) {
  597. struct p448_t aa;
  598. struct tw_extensible_t exu,exv,exw;
  599. mask_t good;
  600. do {
  601. p448_randomize(&crand, &a);
  602. good = affine_deserialize(&affine, &a);
  603. convert_affine_to_extensible(&exta,&affine);
  604. p448_isogeny_un_to_tw(&ext,&exta);
  605. } while (!good);
  606. do {
  607. p448_randomize(&crand, &aa);
  608. good = affine_deserialize(&affine, &aa);
  609. convert_affine_to_extensible(&exta,&affine);
  610. p448_isogeny_un_to_tw(&exu,&exta);
  611. } while (!good);
  612. p448_randomize(&crand, &aa);
  613. q448_randomize(&crand, sk);
  614. if (i==0 || i==2) bzero(&sk, sizeof(sk));
  615. q448_randomize(&crand, tk);
  616. if (i==0 || i==1) bzero(&tk, sizeof(tk));
  617. copy_tw_extensible(&exv, &ext);
  618. copy_tw_extensible(&exw, &exu);
  619. edwards_scalar_multiply(&exv,sk);
  620. edwards_scalar_multiply(&exw,tk);
  621. convert_tw_extensible_to_tw_pniels(&pniels, &exw);
  622. p448_tw_extensible_add_pniels(&exv,&pniels);
  623. p448_isogeny_tw_to_un(&exta,&exv);
  624. extensible_serialize(&b, &exta);
  625. precompute_for_wnaf(wnaft,&exu,5);
  626. edwards_combo_var_fixed_vt(&ext,sk,tk,wnaft,5);
  627. p448_isogeny_tw_to_un(&exta,&exv);
  628. extensible_serialize(&c, &exta);
  629. p448_sub(&d,&b,&c);
  630. p448_bias(&d,2);
  631. if (!p448_is_zero(&d)){
  632. printf("PreWNAF combo validation failure %d!\n", ++failures);
  633. p448_print("a", &a);
  634. p448_print("A", &aa);
  635. q448_print("s", sk);
  636. q448_print("t", tk);
  637. p448_print("c", &c);
  638. p448_print("b", &b);
  639. printf("\n\n");
  640. } else if (good) {
  641. successes ++;
  642. }
  643. }
  644. if (successes < i) {
  645. printf("PreWNAF combo variation: only %d/%d successful.\n", successes, i);
  646. }
  647. successes = failures = 0;
  648. for (i=0; i<1000; i++) {
  649. p448_randomize(&crand, &a);
  650. q448_randomize(&crand, sk);
  651. q448_randomize(&crand, tk);
  652. uint64_t two = 2;
  653. mask_t good = p448_montgomery_ladder(&b,&a,&two,2,0);
  654. p448_montgomery_ladder(&b,&a,sk,448,0);
  655. p448_montgomery_ladder(&d,&b,tk,448,0);
  656. p448_montgomery_ladder(&b,&a,tk,448,0);
  657. p448_montgomery_ladder(&c,&b,sk,448,0);
  658. p448_sub(&b,&c,&d);
  659. p448_bias(&b,2);
  660. mask_t success = p448_is_zero(&b) | ~good;
  661. if (!success) {
  662. printf("Ladder validation failure %d!\n", ++failures);
  663. p448_print("a", &a);
  664. q448_print("s", sk);
  665. q448_print("t", tk);
  666. p448_print("c", &c);
  667. p448_print("d", &d);
  668. printf("\n");
  669. }
  670. }
  671. return 0;
  672. }