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 "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 "decaf_crypto.h"
  18. #include "shake.h"
  19. static __inline__ void
  20. ignore_result ( int result ) {
  21. (void)result;
  22. }
  23. static double now(void) {
  24. struct timeval tv;
  25. gettimeofday(&tv, NULL);
  26. return tv.tv_sec + tv.tv_usec/1000000.0;
  27. }
  28. static void field_randomize( struct crandom_state_t *crand, field_a_t a ) {
  29. crandom_generate(crand, (unsigned char *)a, sizeof(*a));
  30. field_strong_reduce(a);
  31. }
  32. static void q448_randomize( struct crandom_state_t *crand, word_t sk[SCALAR_WORDS] ) {
  33. crandom_generate(crand, (unsigned char *)sk, SCALAR_BYTES);
  34. }
  35. static void field_print( const char *descr, const field_a_t a ) {
  36. int j;
  37. unsigned char ser[FIELD_BYTES];
  38. field_serialize(ser,a);
  39. printf("%s = 0x", descr);
  40. for (j=FIELD_BYTES - 1; j>=0; j--) {
  41. printf("%02x", ser[j]);
  42. }
  43. printf("\n");
  44. }
  45. static void __attribute__((unused))
  46. field_print_full (
  47. const char *descr,
  48. const field_a_t a
  49. ) {
  50. int j;
  51. printf("%s = 0x", descr);
  52. for (j=15; j>=0; j--) {
  53. printf("%02" PRIxWORD "_" PRIxWORD56 " ",
  54. a->limb[j]>>28, a->limb[j]&((1<<28)-1));
  55. }
  56. printf("\n");
  57. }
  58. #ifndef N_TESTS_BASE
  59. #define N_TESTS_BASE 10000
  60. #endif
  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 montgomery_aux_t mba;
  71. field_a_t a,b,c,d;
  72. double when;
  73. int i;
  74. int nbase = N_TESTS_BASE;
  75. /* Bad randomness so we can debug. */
  76. char initial_seed[32];
  77. for (i=0; i<32; i++) initial_seed[i] = i;
  78. struct crandom_state_t crand;
  79. crandom_init_from_buffer(&crand, initial_seed);
  80. /* For testing the performance drop from the crandom debuffering change.
  81. ignore_result(crandom_init_from_file(&crand, "/dev/urandom", 10000, 1));
  82. */
  83. word_t sk[SCALAR_WORDS],tk[SCALAR_WORDS];
  84. q448_randomize(&crand, sk);
  85. memset(a,0,sizeof(a));
  86. memset(b,0,sizeof(b));
  87. memset(c,0,sizeof(c));
  88. memset(d,0,sizeof(d));
  89. when = now();
  90. for (i=0; i<nbase*5000; i++) {
  91. field_mul(c, b, a);
  92. }
  93. when = now() - when;
  94. printf("mul: %5.1fns\n", when * 1e9 / i);
  95. when = now();
  96. for (i=0; i<nbase*5000; i++) {
  97. field_sqr(c, a);
  98. }
  99. when = now() - when;
  100. printf("sqr: %5.1fns\n", when * 1e9 / i);
  101. when = now();
  102. for (i=0; i<nbase*5000; i++) {
  103. field_mulw(c, b, 1234562);
  104. }
  105. when = now() - when;
  106. printf("mulw: %5.1fns\n", when * 1e9 / i);
  107. when = now();
  108. for (i=0; i<nbase*500; i++) {
  109. field_mul(c, b, a);
  110. field_mul(a, b, c);
  111. }
  112. when = now() - when;
  113. printf("mul dep: %5.1fns\n", when * 1e9 / i / 2);
  114. when = now();
  115. for (i=0; i<nbase*10; i++) {
  116. field_randomize(&crand, a);
  117. }
  118. when = now() - when;
  119. printf("rand448: %5.1fns\n", when * 1e9 / i);
  120. sha512_ctx_a_t sha;
  121. uint8_t hashout[128];
  122. when = now();
  123. for (i=0; i<nbase; i++) {
  124. sha512_init(sha);
  125. sha512_final(sha, hashout);
  126. }
  127. when = now() - when;
  128. printf("sha512 1blk: %5.1fns\n", when * 1e9 / i);
  129. when = now();
  130. for (i=0; i<nbase; i++) {
  131. sha512_update(sha, hashout, 128);
  132. }
  133. when = now() - when;
  134. printf("sha512 blk: %5.1fns (%0.2f MB/s)\n", when * 1e9 / i, 128*i/when/1e6);
  135. when = now();
  136. for (i=0; i<nbase; i++) {
  137. shake256_hash(hashout,128,hashout,128);
  138. }
  139. when = now() - when;
  140. printf("shake 1blk: %5.1fns\n", when * 1e9 / i);
  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. decaf_448_scalar_t asc,bsc,csc;
  234. memset(asc,0,sizeof(asc));
  235. memset(bsc,0,sizeof(bsc));
  236. when = now();
  237. for (i=0; i<nbase*10; i++) {
  238. decaf_448_scalar_mul(csc,asc,bsc);
  239. }
  240. when = now() - when;
  241. printf("decaf mulsc: %5.1fns\n", when * 1e9 / i);
  242. when = now();
  243. for (i=0; i<nbase/10; i++) {
  244. decaf_448_scalar_invert(csc,bsc);
  245. }
  246. when = now() - when;
  247. printf("decaf invsc: %5.1fµs\n", when * 1e6 / i);
  248. memset(&ext,0,sizeof(ext));
  249. memset(&niels,0,sizeof(niels)); /* avoid assertions in p521 even though this isn't a valid ext or niels */
  250. tw_extended_a_t ed;
  251. convert_tw_extensible_to_tw_extended(ed,&ext);
  252. when = now();
  253. for (i=0; i<nbase*100; i++) {
  254. add_tw_niels_to_tw_extensible(&ext, &niels);
  255. }
  256. when = now() - when;
  257. printf("exti+niels: %5.1fns\n", when * 1e9 / i);
  258. when = now();
  259. for (i=0; i<nbase*100; i++) {
  260. add_tw_extended(ed,ed);
  261. }
  262. when = now() - when;
  263. printf("txt + txt : %5.1fns\n", when * 1e9 / i);
  264. decaf_448_point_t Da,Db,Dc;
  265. memset(Da,0,sizeof(Da));
  266. memset(Db,0,sizeof(Db));
  267. memset(Dc,0,sizeof(Dc));
  268. when = now();
  269. for (i=0; i<nbase*100; i++) {
  270. decaf_448_point_add(Da,Db,Dc);
  271. }
  272. when = now() - when;
  273. printf("dec + dec: %5.1fns\n", when * 1e9 / i);
  274. convert_tw_extensible_to_tw_pniels(&pniels, &ext);
  275. when = now();
  276. for (i=0; i<nbase*100; i++) {
  277. add_tw_pniels_to_tw_extensible(&ext, &pniels);
  278. }
  279. when = now() - when;
  280. printf("exti+pniels: %5.1fns\n", when * 1e9 / i);
  281. when = now();
  282. for (i=0; i<nbase*100; i++) {
  283. double_tw_extensible(&ext);
  284. }
  285. when = now() - when;
  286. printf("exti dbl: %5.1fns\n", when * 1e9 / i);
  287. when = now();
  288. for (i=0; i<nbase*100; i++) {
  289. untwist_and_double(&exta, &ext);
  290. }
  291. when = now() - when;
  292. printf("i->a isog: %5.1fns\n", when * 1e9 / i);
  293. when = now();
  294. for (i=0; i<nbase*100; i++) {
  295. twist_and_double(&ext, &exta);
  296. }
  297. when = now() - when;
  298. printf("a->i isog: %5.1fns\n", when * 1e9 / i);
  299. memset(&mb,0,sizeof(mb));
  300. when = now();
  301. for (i=0; i<nbase*100; i++) {
  302. montgomery_step(&mb);
  303. }
  304. when = now() - when;
  305. printf("monty step: %5.1fns\n", when * 1e9 / i);
  306. memset(&mba,0,sizeof(mba));
  307. when = now();
  308. for (i=0; i<nbase*100; i++) {
  309. montgomery_aux_step(&mba);
  310. }
  311. when = now() - when;
  312. printf("monty aux: %5.1fns\n", when * 1e9 / i);
  313. when = now();
  314. for (i=0; i<nbase/10; i++) {
  315. ignore_result(montgomery_ladder(a,b,sk,FIELD_BITS,0));
  316. }
  317. when = now() - when;
  318. printf("full ladder: %5.1fµs\n", when * 1e6 / i);
  319. when = now();
  320. for (i=0; i<nbase/10; i++) {
  321. ignore_result(decaf_montgomery_ladder(a,b,sk,FIELD_BITS));
  322. }
  323. when = now() - when;
  324. printf("decafladder: %5.1fµs\n", when * 1e6 / i);
  325. when = now();
  326. for (i=0; i<nbase/10; i++) {
  327. decaf_448_point_scalarmul(Da,Db,asc);
  328. }
  329. when = now() - when;
  330. printf("decaf slow: %5.1fµs\n", when * 1e6 / i);
  331. uint8_t enc[DECAF_448_SER_BYTES];
  332. memset(enc,4,sizeof(enc));
  333. when = now();
  334. for (i=0; i<nbase/10; i++) {
  335. ignore_result(decaf_448_direct_scalarmul(enc,enc,asc,-1,0));
  336. }
  337. when = now() - when;
  338. printf("decaf dir: %5.1fµs\n", when * 1e6 / i);
  339. when = now();
  340. for (i=0; i<nbase/10; i++) {
  341. decaf_448_point_double_scalarmul(Da,Db,bsc,Dc,asc);
  342. }
  343. when = now() - when;
  344. printf("decaf slo2: %5.1fµs\n", when * 1e6 / i);
  345. when = now();
  346. for (i=0; i<nbase/10; i++) {
  347. decaf_448_precomputed_scalarmul(Da,decaf_448_precomputed_base,bsc);
  348. }
  349. when = now() - when;
  350. printf("decaf pres: %5.1fµs\n", when * 1e6 / i);
  351. when = now();
  352. for (i=0; i<nbase/10; i++) {
  353. scalarmul(&ext,sk);
  354. }
  355. when = now() - when;
  356. printf("edwards smz: %5.1fµs\n", when * 1e6 / i);
  357. when = now();
  358. for (i=0; i<nbase/10; i++) {
  359. scalarmul_vlook(&ext,sk);
  360. }
  361. when = now() - when;
  362. printf("edwards svl: %5.1fµs\n", when * 1e6 / i);
  363. when = now();
  364. for (i=0; i<nbase/10; i++) {
  365. scalarmul_ed(ed,sk);
  366. }
  367. when = now() - when;
  368. printf("edwards txt: %5.1fµs\n", when * 1e6 / i);
  369. field_set_ui(a,0);
  370. when = now();
  371. for (i=0; i<nbase/10; i++) {
  372. ignore_result(decaf_deserialize_tw_extended(ed,a,-1));
  373. scalarmul_ed(ed,sk);
  374. decaf_serialize_tw_extended(a,ed);
  375. }
  376. when = now() - when;
  377. printf("simple ECDH: %5.1fµs\n", when * 1e6 / i);
  378. when = now();
  379. for (i=0; i<nbase/10; i++) {
  380. scalarmul(&ext,sk);
  381. untwist_and_double_and_serialize(a,&ext);
  382. }
  383. when = now() - when;
  384. printf("edwards smc: %5.1fµs\n", when * 1e6 / i);
  385. when = now();
  386. for (i=0; i<nbase/10; i++) {
  387. q448_randomize(&crand, sk);
  388. scalarmul_vt(&ext,sk,SCALAR_BITS);
  389. }
  390. when = now() - when;
  391. printf("edwards vtm: %5.1fµs\n", when * 1e6 / i);
  392. tw_niels_a_t wnaft[1<<6];
  393. when = now();
  394. for (i=0; i<nbase/10; i++) {
  395. ignore_result(precompute_fixed_base_wnaf(wnaft,&ext,6));
  396. }
  397. when = now() - when;
  398. printf("wnaf6 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,6);
  403. }
  404. when = now() - when;
  405. printf("edwards vt6: %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,4));
  409. }
  410. when = now() - when;
  411. printf("wnaf4 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,4);
  416. }
  417. when = now() - when;
  418. printf("edwards vt4: %5.1fµs\n", when * 1e6 / i);
  419. when = now();
  420. for (i=0; i<nbase/10; i++) {
  421. ignore_result(precompute_fixed_base_wnaf(wnaft,&ext,5));
  422. }
  423. when = now() - when;
  424. printf("wnaf5 pre: %5.1fµs\n", when * 1e6 / i);
  425. when = now();
  426. for (i=0; i<nbase/10; i++) {
  427. q448_randomize(&crand, sk);
  428. scalarmul_fixed_base_wnaf_vt(&ext,sk,SCALAR_BITS,(const tw_niels_a_t*)wnaft,5);
  429. }
  430. when = now() - when;
  431. printf("edwards vt5: %5.1fµs\n", when * 1e6 / i);
  432. when = now();
  433. for (i=0; i<nbase/10; i++) {
  434. q448_randomize(&crand, sk);
  435. q448_randomize(&crand, tk);
  436. linear_combo_var_fixed_vt(&ext,sk,FIELD_BITS,tk,FIELD_BITS,(const tw_niels_a_t*)wnaft,5);
  437. }
  438. when = now() - when;
  439. printf("vt vf combo: %5.1fµs\n", when * 1e6 / i);
  440. when = now();
  441. for (i=0; i<nbase/10; i++) {
  442. deserialize_affine(&affine, a);
  443. convert_affine_to_extensible(&exta,&affine);
  444. twist_and_double(&ext,&exta);
  445. scalarmul(&ext,sk);
  446. untwist_and_double(&exta,&ext);
  447. serialize_extensible(b, &exta);
  448. }
  449. when = now() - when;
  450. printf("edwards sm: %5.1fµs\n", when * 1e6 / i);
  451. 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;
  452. while (1) {
  453. field_randomize(&crand, a);
  454. if (deserialize_affine(&affine, a)) break;
  455. }
  456. convert_affine_to_extensible(&exta,&affine);
  457. twist_and_double(&ext,&exta);
  458. when = now();
  459. for (i=0; i<nbase/10; i++) {
  460. if (i) destroy_fixed_base(&t_5_5_18);
  461. ignore_result(precompute_fixed_base(&t_5_5_18, &ext, 5, 5, 18, NULL));
  462. }
  463. when = now() - when;
  464. printf("pre(5,5,18): %5.1fµs\n", when * 1e6 / i);
  465. when = now();
  466. for (i=0; i<nbase/10; i++) {
  467. if (i) destroy_fixed_base(&t_3_5_30);
  468. ignore_result(precompute_fixed_base(&t_3_5_30, &ext, 3, 5, 30, NULL));
  469. }
  470. when = now() - when;
  471. printf("pre(3,5,30): %5.1fµs\n", when * 1e6 / i);
  472. when = now();
  473. for (i=0; i<nbase/10; i++) {
  474. if (i) destroy_fixed_base(&t_5_3_30);
  475. ignore_result(precompute_fixed_base(&t_5_3_30, &ext, 5, 3, 30, NULL));
  476. }
  477. when = now() - when;
  478. printf("pre(5,3,30): %5.1fµs\n", when * 1e6 / i);
  479. when = now();
  480. for (i=0; i<nbase/10; i++) {
  481. if (i) destroy_fixed_base(&t_15_3_10);
  482. ignore_result(precompute_fixed_base(&t_15_3_10, &ext, 15, 3, 10, NULL));
  483. }
  484. when = now() - when;
  485. printf("pre(15,3,10):%5.1fµs\n", when * 1e6 / i);
  486. when = now();
  487. for (i=0; i<nbase/10; i++) {
  488. if (i) destroy_fixed_base(&t_8_4_14);
  489. ignore_result(precompute_fixed_base(&t_8_4_14, &ext, 8, 4, 14, NULL));
  490. }
  491. when = now() - when;
  492. printf("pre(8,4,14): %5.1fµs\n", when * 1e6 / i);
  493. when = now();
  494. for (i=0; i<nbase; i++) {
  495. scalarmul_fixed_base(&ext, sk, FIELD_BITS, &t_5_5_18);
  496. }
  497. when = now() - when;
  498. printf("com(5,5,18): %5.1fµs\n", when * 1e6 / i);
  499. when = now();
  500. for (i=0; i<nbase; i++) {
  501. scalarmul_fixed_base(&ext, sk, FIELD_BITS, &t_3_5_30);
  502. }
  503. when = now() - when;
  504. printf("com(3,5,30): %5.1fµs\n", when * 1e6 / i);
  505. when = now();
  506. for (i=0; i<nbase; i++) {
  507. scalarmul_fixed_base(&ext, sk, FIELD_BITS, &t_8_4_14);
  508. }
  509. when = now() - when;
  510. printf("com(8,4,14): %5.1fµs\n", when * 1e6 / i);
  511. when = now();
  512. for (i=0; i<nbase; i++) {
  513. scalarmul_fixed_base(&ext, sk, FIELD_BITS, &t_5_3_30);
  514. }
  515. when = now() - when;
  516. printf("com(5,3,30): %5.1fµs\n", when * 1e6 / i);
  517. when = now();
  518. for (i=0; i<nbase; i++) {
  519. scalarmul_fixed_base(&ext, sk, FIELD_BITS, &t_15_3_10);
  520. }
  521. when = now() - when;
  522. printf("com(15,3,10):%5.1fµs\n", when * 1e6 / i);
  523. printf("\nGoldilocks:\n");
  524. int res = goldilocks_init();
  525. assert(!res);
  526. struct goldilocks_public_key_t gpk,hpk;
  527. struct goldilocks_private_key_t gsk,hsk;
  528. when = now();
  529. for (i=0; i<nbase; i++) {
  530. if (i&1) {
  531. res = goldilocks_keygen(&gsk,&gpk);
  532. } else {
  533. res = goldilocks_keygen(&hsk,&hpk);
  534. }
  535. assert(!res);
  536. }
  537. when = now() - when;
  538. printf("keygen: %5.1fµs\n", when * 1e6 / i);
  539. uint8_t ss1[64],ss2[64];
  540. int gres1=0,gres2=0;
  541. when = now();
  542. for (i=0; i<nbase; i++) {
  543. if (i&1) {
  544. gres1 = goldilocks_shared_secret(ss1,&gsk,&hpk);
  545. } else {
  546. gres2 = goldilocks_shared_secret(ss2,&hsk,&gpk);
  547. }
  548. }
  549. when = now() - when;
  550. printf("ecdh: %5.1fµs\n", when * 1e6 / i);
  551. if (gres1 || gres2 || memcmp(ss1,ss2,64)) {
  552. printf("[FAIL] %d %d\n",gres1,gres2);
  553. printf("sk1 = ");
  554. for (i=0; i<SCALAR_BYTES; i++) {
  555. printf("%02x", gsk.opaque[i]);
  556. }
  557. printf("\nsk2 = ");
  558. for (i=0; i<SCALAR_BYTES; i++) {
  559. printf("%02x", hsk.opaque[i]);
  560. }
  561. printf("\nss1 = ");
  562. for (i=0; i<64; i++) {
  563. printf("%02x", ss1[i]);
  564. }
  565. printf("\nss2 = ");
  566. for (i=0; i<64; i++) {
  567. printf("%02x", ss2[i]);
  568. }
  569. printf("\n");
  570. }
  571. uint8_t sout[FIELD_BYTES*2];
  572. const char *message = "hello world";
  573. size_t message_len = strlen(message);
  574. when = now();
  575. for (i=0; i<nbase; i++) {
  576. res = goldilocks_sign(sout,(const unsigned char *)message,message_len,&gsk);
  577. (void)res;
  578. assert(!res);
  579. }
  580. when = now() - when;
  581. printf("sign: %5.1fµs\n", when * 1e6 / i);
  582. when = now();
  583. for (i=0; i<nbase; i++) {
  584. int ver = goldilocks_verify(sout,(const unsigned char *)message,message_len,&gpk);
  585. (void)ver;
  586. assert(!ver);
  587. }
  588. when = now() - when;
  589. printf("verify: %5.1fµs\n", when * 1e6 / i);
  590. struct goldilocks_precomputed_public_key_t *pre = NULL;
  591. when = now();
  592. for (i=0; i<nbase; i++) {
  593. goldilocks_destroy_precomputed_public_key(pre);
  594. pre = goldilocks_precompute_public_key(&gpk);
  595. }
  596. when = now() - when;
  597. printf("precompute: %5.1fµs\n", when * 1e6 / i);
  598. when = now();
  599. for (i=0; i<nbase; i++) {
  600. int ver = goldilocks_verify_precomputed(sout,(const unsigned char *)message,message_len,pre);
  601. (void)ver;
  602. assert(!ver);
  603. }
  604. when = now() - when;
  605. printf("verify pre: %5.1fµs\n", when * 1e6 / i);
  606. when = now();
  607. for (i=0; i<nbase; i++) {
  608. int ret = goldilocks_shared_secret_precomputed(ss1,&gsk,pre);
  609. (void)ret;
  610. assert(!ret);
  611. }
  612. when = now() - when;
  613. printf("ecdh pre: %5.1fµs\n", when * 1e6 / i);
  614. printf("\nDecaf slow:\n");
  615. decaf_448_symmetric_key_t sym[2] = {{0},{1}};
  616. decaf_448_private_key_t dpriv[2];
  617. decaf_448_public_key_t dpub[2];
  618. unsigned char dshared[2][32];
  619. when = now();
  620. for (i=0; i<nbase; i++) {
  621. decaf_448_derive_private_key(dpriv[i&1], sym[i&1]);
  622. }
  623. when = now() - when;
  624. printf("derive priv: %5.1fµs\n", when * 1e6 / i);
  625. decaf_448_private_to_public(dpub[0], dpriv[0]);
  626. decaf_448_private_to_public(dpub[1], dpriv[1]);
  627. when = now();
  628. for (i=0; i<nbase; i++) {
  629. decaf_bool_t ret = decaf_448_shared_secret(dshared[i&1], 32, dpriv[i&1], dpub[(i+1)&1]);
  630. if (ret != DECAF_SUCCESS) {
  631. printf("BUG: shared secret returns failure on %d.\n", i);
  632. break;
  633. }
  634. }
  635. when = now() - when;
  636. printf("ecdh: %5.1fµs\n", when * 1e6 / i);
  637. if (memcmp(dshared[0], dshared[1], 32)) {
  638. printf("BUG: mismatched shared secrets\n");
  639. }
  640. decaf_448_signature_t dsig;
  641. const char *dmessage = "hello world";
  642. const char *dnessage = "Jello world";
  643. when = now();
  644. for (i=0; i<nbase; i++) {
  645. decaf_448_sign(dsig, dpriv[0], (const unsigned char *)dmessage, 11);
  646. }
  647. when = now() - when;
  648. printf("sign: %5.1fµs\n", when * 1e6 / i);
  649. if (memcmp(dshared[0], dshared[1], 32)) {
  650. printf("BUG: mismatched shared secrets\n");
  651. }
  652. when = now();
  653. for (i=0; i<nbase; i++) {
  654. decaf_bool_t ret = decaf_448_verify(dsig, dpub[0],
  655. (const unsigned char *)((i&1) ? dmessage : dnessage), 11);
  656. if ((i&1) && ~ret) {
  657. printf("BUG: verify failed\n");
  658. break;
  659. } else if (!(i&1) && ret) {
  660. printf("BUG: unverify succeeded\n");
  661. break;
  662. }
  663. }
  664. when = now() - when;
  665. printf("verify: %5.1fµs\n", when * 1e6 / i);
  666. decaf_448_precomputed_s *dpre;
  667. ignore_result(posix_memalign((void**)&dpre,
  668. alignof_decaf_448_precomputed_s, sizeof_decaf_448_precomputed_s));
  669. assert(dpre);
  670. when = now();
  671. for (i=0; i<nbase; i++) {
  672. decaf_448_precompute(dpre, Da);
  673. }
  674. when = now() - when;
  675. printf("pre: %5.1fµs\n", when * 1e6 / i);
  676. free(dpre);
  677. return 0;
  678. }