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.
 
 
 
 
 

798 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 "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. #include "decaf.h"
  17. static __inline__ void
  18. ignore_result ( int result ) {
  19. (void)result;
  20. }
  21. static double now(void) {
  22. struct timeval tv;
  23. gettimeofday(&tv, NULL);
  24. return tv.tv_sec + tv.tv_usec/1000000.0;
  25. }
  26. static void field_randomize( struct crandom_state_t *crand, field_a_t a ) {
  27. crandom_generate(crand, (unsigned char *)a, sizeof(*a));
  28. field_strong_reduce(a);
  29. }
  30. static void q448_randomize( struct crandom_state_t *crand, word_t sk[SCALAR_WORDS] ) {
  31. crandom_generate(crand, (unsigned char *)sk, SCALAR_BYTES);
  32. }
  33. static void field_print( const char *descr, const field_a_t a ) {
  34. int j;
  35. unsigned char ser[FIELD_BYTES];
  36. field_serialize(ser,a);
  37. printf("%s = 0x", descr);
  38. for (j=FIELD_BYTES - 1; j>=0; j--) {
  39. printf("%02x", ser[j]);
  40. }
  41. printf("\n");
  42. }
  43. static void __attribute__((unused))
  44. field_print_full (
  45. const char *descr,
  46. const field_a_t a
  47. ) {
  48. int j;
  49. printf("%s = 0x", descr);
  50. for (j=15; j>=0; j--) {
  51. printf("%02" PRIxWORD "_" PRIxWORD56 " ",
  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 montgomery_aux_t mba;
  77. field_a_t a,b,c,d;
  78. double when;
  79. int i;
  80. int nbase = N_TESTS_BASE;
  81. /* Bad randomness so we can debug. */
  82. char initial_seed[32];
  83. for (i=0; i<32; i++) initial_seed[i] = i;
  84. struct crandom_state_t crand;
  85. crandom_init_from_buffer(&crand, initial_seed);
  86. /* For testing the performance drop from the crandom debuffering change.
  87. ignore_result(crandom_init_from_file(&crand, "/dev/urandom", 10000, 1));
  88. */
  89. word_t sk[SCALAR_WORDS],tk[SCALAR_WORDS];
  90. q448_randomize(&crand, sk);
  91. memset(a,0,sizeof(a));
  92. memset(b,0,sizeof(b));
  93. memset(c,0,sizeof(c));
  94. memset(d,0,sizeof(d));
  95. when = now();
  96. for (i=0; i<nbase*5000; i++) {
  97. field_mul(c, b, a);
  98. }
  99. when = now() - when;
  100. printf("mul: %5.1fns\n", when * 1e9 / i);
  101. when = now();
  102. for (i=0; i<nbase*5000; i++) {
  103. field_sqr(c, a);
  104. }
  105. when = now() - when;
  106. printf("sqr: %5.1fns\n", when * 1e9 / i);
  107. when = now();
  108. for (i=0; i<nbase*5000; i++) {
  109. field_mulw(c, b, 1234562);
  110. }
  111. when = now() - when;
  112. printf("mulw: %5.1fns\n", when * 1e9 / i);
  113. when = now();
  114. for (i=0; i<nbase*500; i++) {
  115. field_mul(c, b, a);
  116. field_mul(a, b, c);
  117. }
  118. when = now() - when;
  119. printf("mul dep: %5.1fns\n", when * 1e9 / i / 2);
  120. when = now();
  121. for (i=0; i<nbase*10; i++) {
  122. field_randomize(&crand, a);
  123. }
  124. when = now() - when;
  125. printf("rand448: %5.1fns\n", when * 1e9 / i);
  126. sha512_ctx_a_t sha;
  127. uint8_t hashout[128];
  128. when = now();
  129. for (i=0; i<nbase; i++) {
  130. sha512_init(sha);
  131. sha512_final(sha, hashout);
  132. }
  133. when = now() - when;
  134. printf("sha512 1blk: %5.1fns\n", when * 1e9 / i);
  135. when = now();
  136. for (i=0; i<nbase; i++) {
  137. sha512_update(sha, hashout, 128);
  138. }
  139. when = now() - when;
  140. printf("sha512 blk: %5.1fns (%0.2f MB/s)\n", when * 1e9 / i, 128*i/when/1e6);
  141. when = now();
  142. for (i=0; i<nbase; i++) {
  143. field_isr(c, a);
  144. }
  145. when = now() - when;
  146. printf("isr auto: %5.1fµs\n", when * 1e6 / i);
  147. for (i=0; i<100; i++) {
  148. field_randomize(&crand, a);
  149. field_isr(d,a);
  150. field_sqr(b,d);
  151. field_mul(c,b,a);
  152. field_sqr(b,c);
  153. field_subw(b,1);
  154. if (!field_is_zero(b)) {
  155. printf("ISR validation failure!\n");
  156. field_print("a", a);
  157. field_print("s", d);
  158. }
  159. }
  160. when = now();
  161. for (i=0; i<nbase; i++) {
  162. elligator_2s_inject(&affine, a);
  163. }
  164. when = now() - when;
  165. printf("elligator: %5.1fµs\n", when * 1e6 / i);
  166. for (i=0; i<100; i++) {
  167. field_randomize(&crand, a);
  168. elligator_2s_inject(&affine, a);
  169. if (!validate_affine(&affine)) {
  170. printf("Elligator validation failure!\n");
  171. field_print("a", a);
  172. field_print("x", affine.x);
  173. field_print("y", affine.y);
  174. }
  175. }
  176. when = now();
  177. for (i=0; i<nbase; i++) {
  178. deserialize_affine(&affine, a);
  179. }
  180. when = now() - when;
  181. printf("decompress: %5.1fµs\n", when * 1e6 / i);
  182. convert_affine_to_extensible(&exta, &affine);
  183. when = now();
  184. for (i=0; i<nbase; i++) {
  185. serialize_extensible(a, &exta);
  186. }
  187. when = now() - when;
  188. printf("compress: %5.1fµs\n", when * 1e6 / i);
  189. int goods = 0;
  190. for (i=0; i<100; i++) {
  191. field_randomize(&crand, a);
  192. mask_t good = deserialize_affine(&affine, a);
  193. if (good & !validate_affine(&affine)) {
  194. printf("Deserialize validation failure!\n");
  195. field_print("a", a);
  196. field_print("x", affine.x);
  197. field_print("y", affine.y);
  198. } else if (good) {
  199. goods++;
  200. convert_affine_to_extensible(&exta,&affine);
  201. serialize_extensible(b, &exta);
  202. field_sub(c,b,a);
  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. tw_extended_a_t ed;
  236. convert_tw_extensible_to_tw_extended(ed,&ext);
  237. when = now();
  238. for (i=0; i<nbase*100; i++) {
  239. add_tw_niels_to_tw_extensible(&ext, &niels);
  240. }
  241. when = now() - when;
  242. printf("exti+niels: %5.1fns\n", when * 1e9 / i);
  243. when = now();
  244. for (i=0; i<nbase*100; i++) {
  245. add_tw_extended(ed,ed);
  246. }
  247. when = now() - when;
  248. printf("txt + txt : %5.1fns\n", when * 1e9 / i);
  249. decaf_point_t Da,Db,Dc;
  250. memset(Da,0,sizeof(Da));
  251. memset(Db,0,sizeof(Db));
  252. memset(Dc,0,sizeof(Dc));
  253. when = now();
  254. for (i=0; i<nbase*100; i++) {
  255. decaf_add(Da,Db,Dc);
  256. }
  257. when = now() - when;
  258. printf("dec + dec: %5.1fns\n", when * 1e9 / i);
  259. convert_tw_extensible_to_tw_pniels(&pniels, &ext);
  260. when = now();
  261. for (i=0; i<nbase*100; i++) {
  262. add_tw_pniels_to_tw_extensible(&ext, &pniels);
  263. }
  264. when = now() - when;
  265. printf("exti+pniels: %5.1fns\n", when * 1e9 / i);
  266. when = now();
  267. for (i=0; i<nbase*100; i++) {
  268. double_tw_extensible(&ext);
  269. }
  270. when = now() - when;
  271. printf("exti dbl: %5.1fns\n", when * 1e9 / i);
  272. when = now();
  273. for (i=0; i<nbase*100; i++) {
  274. untwist_and_double(&exta, &ext);
  275. }
  276. when = now() - when;
  277. printf("i->a isog: %5.1fns\n", when * 1e9 / i);
  278. when = now();
  279. for (i=0; i<nbase*100; i++) {
  280. twist_and_double(&ext, &exta);
  281. }
  282. when = now() - when;
  283. printf("a->i isog: %5.1fns\n", when * 1e9 / i);
  284. memset(&mb,0,sizeof(mb));
  285. when = now();
  286. for (i=0; i<nbase*100; i++) {
  287. montgomery_step(&mb);
  288. }
  289. when = now() - when;
  290. printf("monty step: %5.1fns\n", when * 1e9 / i);
  291. memset(&mba,0,sizeof(mba));
  292. when = now();
  293. for (i=0; i<nbase*100; i++) {
  294. montgomery_aux_step(&mba);
  295. }
  296. when = now() - when;
  297. printf("monty aux: %5.1fns\n", when * 1e9 / i);
  298. when = now();
  299. for (i=0; i<nbase/10; i++) {
  300. ignore_result(montgomery_ladder(a,b,sk,FIELD_BITS,0));
  301. }
  302. when = now() - when;
  303. printf("full ladder: %5.1fµs\n", when * 1e6 / i);
  304. when = now();
  305. for (i=0; i<nbase/10; i++) {
  306. ignore_result(decaf_montgomery_ladder(a,b,sk,FIELD_BITS));
  307. }
  308. when = now() - when;
  309. printf("decafladder: %5.1fµs\n", when * 1e6 / i);
  310. when = now();
  311. for (i=0; i<nbase/10; i++) {
  312. decaf_scalarmul(Da,Db,sk,sizeof(sk)/sizeof(word_t));
  313. }
  314. when = now() - when;
  315. printf("decaf slow: %5.1fµs\n", when * 1e6 / i);
  316. when = now();
  317. for (i=0; i<nbase/10; i++) {
  318. scalarmul(&ext,sk);
  319. }
  320. when = now() - when;
  321. printf("edwards smz: %5.1fµs\n", when * 1e6 / i);
  322. when = now();
  323. for (i=0; i<nbase/10; i++) {
  324. scalarmul_vlook(&ext,sk);
  325. }
  326. when = now() - when;
  327. printf("edwards svl: %5.1fµs\n", when * 1e6 / i);
  328. when = now();
  329. for (i=0; i<nbase/10; i++) {
  330. scalarmul_ed(ed,sk);
  331. }
  332. when = now() - when;
  333. printf("edwards txt: %5.1fµs\n", when * 1e6 / i);
  334. field_set_ui(a,0);
  335. when = now();
  336. for (i=0; i<nbase/10; i++) {
  337. ignore_result(decaf_deserialize_tw_extended(ed,a,-1));
  338. scalarmul_ed(ed,sk);
  339. decaf_serialize_tw_extended(a,ed);
  340. }
  341. when = now() - when;
  342. printf("simple ECDH: %5.1fµs\n", when * 1e6 / i);
  343. when = now();
  344. for (i=0; i<nbase/10; i++) {
  345. scalarmul(&ext,sk);
  346. untwist_and_double_and_serialize(a,&ext);
  347. }
  348. when = now() - when;
  349. printf("edwards smc: %5.1fµs\n", when * 1e6 / i);
  350. when = now();
  351. for (i=0; i<nbase/10; i++) {
  352. q448_randomize(&crand, sk);
  353. scalarmul_vt(&ext,sk,SCALAR_BITS);
  354. }
  355. when = now() - when;
  356. printf("edwards vtm: %5.1fµs\n", when * 1e6 / i);
  357. tw_niels_a_t wnaft[1<<6];
  358. when = now();
  359. for (i=0; i<nbase/10; i++) {
  360. ignore_result(precompute_fixed_base_wnaf(wnaft,&ext,6));
  361. }
  362. when = now() - when;
  363. printf("wnaf6 pre: %5.1fµs\n", when * 1e6 / i);
  364. when = now();
  365. for (i=0; i<nbase/10; i++) {
  366. q448_randomize(&crand, sk);
  367. scalarmul_fixed_base_wnaf_vt(&ext,sk,SCALAR_BITS,(const tw_niels_a_t*)wnaft,6);
  368. }
  369. when = now() - when;
  370. printf("edwards vt6: %5.1fµs\n", when * 1e6 / i);
  371. when = now();
  372. for (i=0; i<nbase/10; i++) {
  373. ignore_result(precompute_fixed_base_wnaf(wnaft,&ext,4));
  374. }
  375. when = now() - when;
  376. printf("wnaf4 pre: %5.1fµs\n", when * 1e6 / i);
  377. when = now();
  378. for (i=0; i<nbase/10; i++) {
  379. q448_randomize(&crand, sk);
  380. scalarmul_fixed_base_wnaf_vt(&ext,sk,SCALAR_BITS,(const tw_niels_a_t*)wnaft,4);
  381. }
  382. when = now() - when;
  383. printf("edwards vt4: %5.1fµs\n", when * 1e6 / i);
  384. when = now();
  385. for (i=0; i<nbase/10; i++) {
  386. ignore_result(precompute_fixed_base_wnaf(wnaft,&ext,5));
  387. }
  388. when = now() - when;
  389. printf("wnaf5 pre: %5.1fµs\n", when * 1e6 / i);
  390. when = now();
  391. for (i=0; i<nbase/10; i++) {
  392. q448_randomize(&crand, sk);
  393. scalarmul_fixed_base_wnaf_vt(&ext,sk,SCALAR_BITS,(const tw_niels_a_t*)wnaft,5);
  394. }
  395. when = now() - when;
  396. printf("edwards vt5: %5.1fµs\n", when * 1e6 / i);
  397. when = now();
  398. for (i=0; i<nbase/10; i++) {
  399. q448_randomize(&crand, sk);
  400. q448_randomize(&crand, tk);
  401. linear_combo_var_fixed_vt(&ext,sk,FIELD_BITS,tk,FIELD_BITS,(const tw_niels_a_t*)wnaft,5);
  402. }
  403. when = now() - when;
  404. printf("vt vf combo: %5.1fµs\n", when * 1e6 / i);
  405. when = now();
  406. for (i=0; i<nbase/10; i++) {
  407. deserialize_affine(&affine, a);
  408. convert_affine_to_extensible(&exta,&affine);
  409. twist_and_double(&ext,&exta);
  410. scalarmul(&ext,sk);
  411. untwist_and_double(&exta,&ext);
  412. serialize_extensible(b, &exta);
  413. }
  414. when = now() - when;
  415. printf("edwards sm: %5.1fµs\n", when * 1e6 / i);
  416. 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;
  417. while (1) {
  418. field_randomize(&crand, a);
  419. if (deserialize_affine(&affine, a)) break;
  420. }
  421. convert_affine_to_extensible(&exta,&affine);
  422. twist_and_double(&ext,&exta);
  423. when = now();
  424. for (i=0; i<nbase/10; i++) {
  425. if (i) destroy_fixed_base(&t_5_5_18);
  426. ignore_result(precompute_fixed_base(&t_5_5_18, &ext, 5, 5, 18, NULL));
  427. }
  428. when = now() - when;
  429. printf("pre(5,5,18): %5.1fµs\n", when * 1e6 / i);
  430. when = now();
  431. for (i=0; i<nbase/10; i++) {
  432. if (i) destroy_fixed_base(&t_3_5_30);
  433. ignore_result(precompute_fixed_base(&t_3_5_30, &ext, 3, 5, 30, NULL));
  434. }
  435. when = now() - when;
  436. printf("pre(3,5,30): %5.1fµs\n", when * 1e6 / i);
  437. when = now();
  438. for (i=0; i<nbase/10; i++) {
  439. if (i) destroy_fixed_base(&t_5_3_30);
  440. ignore_result(precompute_fixed_base(&t_5_3_30, &ext, 5, 3, 30, NULL));
  441. }
  442. when = now() - when;
  443. printf("pre(5,3,30): %5.1fµs\n", when * 1e6 / i);
  444. when = now();
  445. for (i=0; i<nbase/10; i++) {
  446. if (i) destroy_fixed_base(&t_15_3_10);
  447. ignore_result(precompute_fixed_base(&t_15_3_10, &ext, 15, 3, 10, NULL));
  448. }
  449. when = now() - when;
  450. printf("pre(15,3,10):%5.1fµs\n", when * 1e6 / i);
  451. when = now();
  452. for (i=0; i<nbase/10; i++) {
  453. if (i) destroy_fixed_base(&t_8_4_14);
  454. ignore_result(precompute_fixed_base(&t_8_4_14, &ext, 8, 4, 14, NULL));
  455. }
  456. when = now() - when;
  457. printf("pre(8,4,14): %5.1fµs\n", when * 1e6 / i);
  458. when = now();
  459. for (i=0; i<nbase; i++) {
  460. scalarmul_fixed_base(&ext, sk, FIELD_BITS, &t_5_5_18);
  461. }
  462. when = now() - when;
  463. printf("com(5,5,18): %5.1fµs\n", when * 1e6 / i);
  464. when = now();
  465. for (i=0; i<nbase; i++) {
  466. scalarmul_fixed_base(&ext, sk, FIELD_BITS, &t_3_5_30);
  467. }
  468. when = now() - when;
  469. printf("com(3,5,30): %5.1fµs\n", when * 1e6 / i);
  470. when = now();
  471. for (i=0; i<nbase; i++) {
  472. scalarmul_fixed_base(&ext, sk, FIELD_BITS, &t_8_4_14);
  473. }
  474. when = now() - when;
  475. printf("com(8,4,14): %5.1fµs\n", when * 1e6 / i);
  476. when = now();
  477. for (i=0; i<nbase; i++) {
  478. scalarmul_fixed_base(&ext, sk, FIELD_BITS, &t_5_3_30);
  479. }
  480. when = now() - when;
  481. printf("com(5,3,30): %5.1fµs\n", when * 1e6 / i);
  482. when = now();
  483. for (i=0; i<nbase; i++) {
  484. scalarmul_fixed_base(&ext, sk, FIELD_BITS, &t_15_3_10);
  485. }
  486. when = now() - when;
  487. printf("com(15,3,10):%5.1fµs\n", when * 1e6 / i);
  488. printf("\nGoldilocks:\n");
  489. int res = goldilocks_init();
  490. assert(!res);
  491. struct goldilocks_public_key_t gpk,hpk;
  492. struct goldilocks_private_key_t gsk,hsk;
  493. when = now();
  494. for (i=0; i<nbase; i++) {
  495. if (i&1) {
  496. res = goldilocks_keygen(&gsk,&gpk);
  497. } else {
  498. res = goldilocks_keygen(&hsk,&hpk);
  499. }
  500. assert(!res);
  501. }
  502. when = now() - when;
  503. printf("keygen: %5.1fµs\n", when * 1e6 / i);
  504. uint8_t ss1[64],ss2[64];
  505. int gres1=0,gres2=0;
  506. when = now();
  507. for (i=0; i<nbase; i++) {
  508. if (i&1) {
  509. gres1 = goldilocks_shared_secret(ss1,&gsk,&hpk);
  510. } else {
  511. gres2 = goldilocks_shared_secret(ss2,&hsk,&gpk);
  512. }
  513. }
  514. when = now() - when;
  515. printf("ecdh: %5.1fµs\n", when * 1e6 / i);
  516. if (gres1 || gres2 || memcmp(ss1,ss2,64)) {
  517. printf("[FAIL] %d %d\n",gres1,gres2);
  518. printf("sk1 = ");
  519. for (i=0; i<SCALAR_BYTES; i++) {
  520. printf("%02x", gsk.opaque[i]);
  521. }
  522. printf("\nsk2 = ");
  523. for (i=0; i<SCALAR_BYTES; i++) {
  524. printf("%02x", hsk.opaque[i]);
  525. }
  526. printf("\nss1 = ");
  527. for (i=0; i<64; i++) {
  528. printf("%02x", ss1[i]);
  529. }
  530. printf("\nss2 = ");
  531. for (i=0; i<64; i++) {
  532. printf("%02x", ss2[i]);
  533. }
  534. printf("\n");
  535. }
  536. uint8_t sout[FIELD_BYTES*2];
  537. const char *message = "hello world";
  538. size_t message_len = strlen(message);
  539. when = now();
  540. for (i=0; i<nbase; i++) {
  541. res = goldilocks_sign(sout,(const unsigned char *)message,message_len,&gsk);
  542. (void)res;
  543. assert(!res);
  544. }
  545. when = now() - when;
  546. printf("sign: %5.1fµs\n", when * 1e6 / i);
  547. when = now();
  548. for (i=0; i<nbase; i++) {
  549. int ver = goldilocks_verify(sout,(const unsigned char *)message,message_len,&gpk);
  550. (void)ver;
  551. assert(!ver);
  552. }
  553. when = now() - when;
  554. printf("verify: %5.1fµs\n", when * 1e6 / i);
  555. struct goldilocks_precomputed_public_key_t *pre = NULL;
  556. when = now();
  557. for (i=0; i<nbase; i++) {
  558. goldilocks_destroy_precomputed_public_key(pre);
  559. pre = goldilocks_precompute_public_key(&gpk);
  560. }
  561. when = now() - when;
  562. printf("precompute: %5.1fµs\n", when * 1e6 / i);
  563. when = now();
  564. for (i=0; i<nbase; i++) {
  565. int ver = goldilocks_verify_precomputed(sout,(const unsigned char *)message,message_len,pre);
  566. (void)ver;
  567. assert(!ver);
  568. }
  569. when = now() - when;
  570. printf("verify pre: %5.1fµs\n", when * 1e6 / i);
  571. when = now();
  572. for (i=0; i<nbase; i++) {
  573. int ret = goldilocks_shared_secret_precomputed(ss1,&gsk,pre);
  574. (void)ret;
  575. assert(!ret);
  576. }
  577. when = now() - when;
  578. printf("ecdh pre: %5.1fµs\n", when * 1e6 / i);
  579. printf("\nTesting...\n");
  580. int failures=0, successes = 0;
  581. for (i=0; i<nbase/10; i++) {
  582. ignore_result(goldilocks_keygen(&gsk,&gpk));
  583. goldilocks_sign(sout,(const unsigned char *)message,message_len,&gsk);
  584. res = goldilocks_verify(sout,(const unsigned char *)message,message_len,&gpk);
  585. if (res) failures++;
  586. }
  587. if (failures) {
  588. printf("FAIL %d/%d signature checks!\n", failures, i);
  589. }
  590. failures=0; successes = 0;
  591. for (i=0; i<nbase/10; i++) {
  592. field_randomize(&crand, a);
  593. word_t two = 2;
  594. mask_t good = montgomery_ladder(b,a,&two,2,0);
  595. if (!good) continue;
  596. word_t x,y;
  597. crandom_generate(&crand, (unsigned char *)&x, sizeof(x));
  598. crandom_generate(&crand, (unsigned char *)&y, sizeof(y));
  599. x = (hword_t)x;
  600. y = (hword_t)y;
  601. word_t z=x*y;
  602. ignore_result(montgomery_ladder(b,a,&x,WORD_BITS,0));
  603. ignore_result(montgomery_ladder(c,b,&y,WORD_BITS,0));
  604. ignore_result(montgomery_ladder(b,a,&z,WORD_BITS,0));
  605. field_sub(d,b,c);
  606. if (!field_is_zero(d)) {
  607. printf("Odd ladder validation failure %d!\n", ++failures);
  608. field_print("a", a);
  609. printf("x=%"PRIxWORD", y=%"PRIxWORD", z=%"PRIxWORD"\n", x,y,z);
  610. field_print("c", c);
  611. field_print("b", b);
  612. printf("\n");
  613. }
  614. }
  615. failures = 0;
  616. for (i=0; i<nbase/10; i++) {
  617. mask_t good;
  618. do {
  619. field_randomize(&crand, a);
  620. good = deserialize_affine(&affine, a);
  621. } while (!good);
  622. convert_affine_to_extensible(&exta,&affine);
  623. twist_and_double(&ext,&exta);
  624. untwist_and_double(&exta,&ext);
  625. serialize_extensible(b, &exta);
  626. untwist_and_double_and_serialize(c, &ext);
  627. field_sub(d,b,c);
  628. if (good && !field_is_zero(d)){
  629. printf("Iso+serial validation failure %d!\n", ++failures);
  630. field_print("a", a);
  631. field_print("b", b);
  632. field_print("c", c);
  633. printf("\n");
  634. } else if (good) {
  635. successes ++;
  636. }
  637. }
  638. if (successes < i/3) {
  639. printf("Iso+serial variation: only %d/%d successful.\n", successes, i);
  640. }
  641. successes = failures = 0;
  642. for (i=0; i<nbase/10; i++) {
  643. field_a_t aa;
  644. struct tw_extensible_t exu,exv,exw;
  645. mask_t good;
  646. do {
  647. field_randomize(&crand, a);
  648. good = deserialize_affine(&affine, a);
  649. convert_affine_to_extensible(&exta,&affine);
  650. twist_and_double(&ext,&exta);
  651. } while (!good);
  652. do {
  653. field_randomize(&crand, aa);
  654. good = deserialize_affine(&affine, aa);
  655. convert_affine_to_extensible(&exta,&affine);
  656. twist_and_double(&exu,&exta);
  657. } while (!good);
  658. field_randomize(&crand, aa);
  659. q448_randomize(&crand, sk);
  660. if (i==0 || i==2) memset(&sk, 0, sizeof(sk));
  661. q448_randomize(&crand, tk);
  662. if (i==0 || i==1) memset(&tk, 0, sizeof(tk));
  663. copy_tw_extensible(&exv, &ext);
  664. copy_tw_extensible(&exw, &exu);
  665. scalarmul(&exv,sk);
  666. scalarmul(&exw,tk);
  667. convert_tw_extensible_to_tw_pniels(&pniels, &exw);
  668. add_tw_pniels_to_tw_extensible(&exv,&pniels);
  669. untwist_and_double(&exta,&exv);
  670. serialize_extensible(b, &exta);
  671. ignore_result(precompute_fixed_base_wnaf(wnaft,&exu,5));
  672. linear_combo_var_fixed_vt(&ext,sk,FIELD_BITS,tk,FIELD_BITS,(const tw_niels_a_t*)wnaft,5);
  673. untwist_and_double(&exta,&exv);
  674. serialize_extensible(c, &exta);
  675. field_sub(d,b,c);
  676. if (!field_is_zero(d)){
  677. printf("PreWNAF combo validation failure %d!\n", ++failures);
  678. field_print("a", a);
  679. field_print("A", aa);
  680. q448_print("s", sk);
  681. q448_print("t", tk);
  682. field_print("c", c);
  683. field_print("b", b);
  684. printf("\n\n");
  685. } else if (good) {
  686. successes ++;
  687. }
  688. }
  689. if (successes < i) {
  690. printf("PreWNAF combo variation: only %d/%d successful.\n", successes, i);
  691. }
  692. return 0;
  693. }