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.
 
 
 
 
 

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