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.
 
 
 
 
 

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