/ test / test_speed.c
test_speed.c
   1  /*
   2   * Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
   3   *
   4   * Permission is hereby granted, free of charge, to any person obtaining 
   5   * a copy of this software and associated documentation files (the
   6   * "Software"), to deal in the Software without restriction, including
   7   * without limitation the rights to use, copy, modify, merge, publish,
   8   * distribute, sublicense, and/or sell copies of the Software, and to
   9   * permit persons to whom the Software is furnished to do so, subject to
  10   * the following conditions:
  11   *
  12   * The above copyright notice and this permission notice shall be 
  13   * included in all copies or substantial portions of the Software.
  14   *
  15   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
  16   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
  18   * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  19   * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  20   * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21   * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22   * SOFTWARE.
  23   */
  24  
  25  #include <stdio.h>
  26  #include <stdlib.h>
  27  #include <string.h>
  28  #include <time.h>
  29  #include "inner.h"
  30  
  31  #define HASH_SIZE(cname)   br_ ## cname ## _SIZE
  32  
  33  #define SPEED_HASH(Name, cname) \
  34  static void \
  35  test_speed_ ## cname(void) \
  36  { \
  37  	unsigned char buf[8192]; \
  38  	unsigned char tmp[HASH_SIZE(cname)]; \
  39  	br_ ## cname ## _context mc; \
  40  	int i; \
  41  	long num; \
  42   \
  43  	memset(buf, 'T', sizeof buf); \
  44  	for (i = 0; i < 10; i ++) { \
  45  		br_ ## cname ## _init(&mc); \
  46  		br_ ## cname ## _update(&mc, buf, sizeof buf); \
  47  		br_ ## cname ## _out(&mc, tmp); \
  48  	} \
  49  	num = 10; \
  50  	for (;;) { \
  51  		clock_t begin, end; \
  52  		double tt; \
  53  		long k; \
  54   \
  55  		br_ ## cname ## _init(&mc); \
  56  		begin = clock(); \
  57  		for (k = num; k > 0; k --) { \
  58  			br_ ## cname ## _update(&mc, buf, sizeof buf); \
  59  		} \
  60  		end = clock(); \
  61  		br_ ## cname ## _out(&mc, tmp); \
  62  		tt = (double)(end - begin) / CLOCKS_PER_SEC; \
  63  		if (tt >= 2.0) { \
  64  			printf("%-30s %8.2f MB/s\n", #Name, \
  65  				((double)sizeof buf) * (double)num \
  66  				/ (tt * 1000000.0)); \
  67  			fflush(stdout); \
  68  			return; \
  69  		} \
  70  		num <<= 1; \
  71  	} \
  72  }
  73  
  74  #define BLOCK_SIZE(cname)   br_ ## cname ## _BLOCK_SIZE
  75  
  76  #define SPEED_BLOCKCIPHER_CBC(Name, fname, cname, klen, dir) \
  77  static void \
  78  test_speed_ ## fname(void) \
  79  { \
  80  	unsigned char key[klen]; \
  81  	unsigned char buf[8192 - (8192 % BLOCK_SIZE(cname))]; \
  82  	unsigned char iv[BLOCK_SIZE(cname)]; \
  83  	const br_block_cbc ## dir ## _class *vt; \
  84  	br_ ## cname ## _cbc ## dir ## _keys ec; \
  85  	int i; \
  86  	long num; \
  87   \
  88  	memset(key, 'T', sizeof key); \
  89  	memset(buf, 'P', sizeof buf); \
  90  	memset(iv, 'X', sizeof iv); \
  91  	vt = br_ ## cname ## _cbc ## dir ## _get_vtable(); \
  92  	if (vt == NULL) { \
  93  		printf("%-30s UNAVAILABLE\n", #Name); \
  94  		fflush(stdout); \
  95  		return; \
  96  	} \
  97  	for (i = 0; i < 10; i ++) { \
  98  		vt->init(&ec.vtable, key, sizeof key); \
  99  		vt->run(&ec.vtable, iv, buf, sizeof buf); \
 100  	} \
 101  	num = 10; \
 102  	for (;;) { \
 103  		clock_t begin, end; \
 104  		double tt; \
 105  		long k; \
 106   \
 107  		vt->init(&ec.vtable, key, sizeof key); \
 108  		begin = clock(); \
 109  		for (k = num; k > 0; k --) { \
 110  			vt->run(&ec.vtable, iv, buf, sizeof buf); \
 111  		} \
 112  		end = clock(); \
 113  		tt = (double)(end - begin) / CLOCKS_PER_SEC; \
 114  		if (tt >= 2.0) { \
 115  			printf("%-30s %8.2f MB/s\n", #Name, \
 116  				((double)sizeof buf) * (double)num \
 117  				/ (tt * 1000000.0)); \
 118  			fflush(stdout); \
 119  			return; \
 120  		} \
 121  		num <<= 1; \
 122  	} \
 123  }
 124  
 125  #define SPEED_BLOCKCIPHER_CTR(Name, fname, cname, klen) \
 126  static void \
 127  test_speed_ ## fname(void) \
 128  { \
 129  	unsigned char key[klen]; \
 130  	unsigned char buf[8192 - (8192 % BLOCK_SIZE(cname))]; \
 131  	unsigned char iv[BLOCK_SIZE(cname) - 4]; \
 132  	const br_block_ctr_class *vt; \
 133  	br_ ## cname ## _ctr_keys ec; \
 134  	int i; \
 135  	long num; \
 136   \
 137  	memset(key, 'T', sizeof key); \
 138  	memset(buf, 'P', sizeof buf); \
 139  	memset(iv, 'X', sizeof iv); \
 140  	vt = br_ ## cname ## _ctr_get_vtable(); \
 141  	if (vt == NULL) { \
 142  		printf("%-30s UNAVAILABLE\n", #Name); \
 143  		fflush(stdout); \
 144  		return; \
 145  	} \
 146  	for (i = 0; i < 10; i ++) { \
 147  		vt->init(&ec.vtable, key, sizeof key); \
 148  		vt->run(&ec.vtable, iv, 1, buf, sizeof buf); \
 149  	} \
 150  	num = 10; \
 151  	for (;;) { \
 152  		clock_t begin, end; \
 153  		double tt; \
 154  		long k; \
 155   \
 156  		vt->init(&ec.vtable, key, sizeof key); \
 157  		begin = clock(); \
 158  		for (k = num; k > 0; k --) { \
 159  			vt->run(&ec.vtable, iv, 1, buf, sizeof buf); \
 160  		} \
 161  		end = clock(); \
 162  		tt = (double)(end - begin) / CLOCKS_PER_SEC; \
 163  		if (tt >= 2.0) { \
 164  			printf("%-30s %8.2f MB/s\n", #Name, \
 165  				((double)sizeof buf) * (double)num \
 166  				/ (tt * 1000000.0)); \
 167  			fflush(stdout); \
 168  			return; \
 169  		} \
 170  		num <<= 1; \
 171  	} \
 172  }
 173  
 174  #define SPEED_CHACHA20(Name, fname) \
 175  static void \
 176  test_speed_ ## fname(void) \
 177  { \
 178  	br_chacha20_run bc; \
 179  	unsigned char key[32]; \
 180  	unsigned char buf[8192]; \
 181  	unsigned char iv[12]; \
 182  	int i; \
 183  	long num; \
 184   \
 185  	bc = br_ ## fname ## _get(); \
 186  	if (bc == 0) { \
 187  		printf("%-30s UNAVAILABLE\n", #Name); \
 188  		fflush(stdout); \
 189  		return; \
 190  	} \
 191  	memset(key, 'T', sizeof key); \
 192  	memset(buf, 'P', sizeof buf); \
 193  	memset(iv, 'X', sizeof iv); \
 194  	for (i = 0; i < 10; i ++) { \
 195  		bc(key, iv, i, buf, sizeof buf); \
 196  	} \
 197  	num = 10; \
 198  	for (;;) { \
 199  		clock_t begin, end; \
 200  		double tt; \
 201  		long k; \
 202   \
 203  		begin = clock(); \
 204  		for (k = num; k > 0; k --) { \
 205  			bc(key, iv, (uint32_t)k, buf, sizeof buf); \
 206  		} \
 207  		end = clock(); \
 208  		tt = (double)(end - begin) / CLOCKS_PER_SEC; \
 209  		if (tt >= 2.0) { \
 210  			printf("%-30s %8.2f MB/s\n", #Name, \
 211  				((double)sizeof buf) * (double)num \
 212  				/ (tt * 1000000.0)); \
 213  			fflush(stdout); \
 214  			return; \
 215  		} \
 216  		num <<= 1; \
 217  	} \
 218  }
 219  
 220  SPEED_HASH(MD5, md5)
 221  SPEED_HASH(SHA-1, sha1)
 222  SPEED_HASH(SHA-256, sha256)
 223  SPEED_HASH(SHA-512, sha512)
 224  
 225  /*
 226   * There are no vtable selection functions for the portable implementations,
 227   * so we define some custom macros.
 228   */
 229  #define br_aes_big_cbcenc_get_vtable()     (&br_aes_big_cbcenc_vtable)
 230  #define br_aes_big_cbcdec_get_vtable()     (&br_aes_big_cbcdec_vtable)
 231  #define br_aes_big_ctr_get_vtable()        (&br_aes_big_ctr_vtable)
 232  #define br_aes_big_ctrcbc_get_vtable()     (&br_aes_big_ctrcbc_vtable)
 233  #define br_aes_small_cbcenc_get_vtable()   (&br_aes_small_cbcenc_vtable)
 234  #define br_aes_small_cbcdec_get_vtable()   (&br_aes_small_cbcdec_vtable)
 235  #define br_aes_small_ctr_get_vtable()      (&br_aes_small_ctr_vtable)
 236  #define br_aes_small_ctrcbc_get_vtable()   (&br_aes_small_ctrcbc_vtable)
 237  #define br_aes_ct_cbcenc_get_vtable()      (&br_aes_ct_cbcenc_vtable)
 238  #define br_aes_ct_cbcdec_get_vtable()      (&br_aes_ct_cbcdec_vtable)
 239  #define br_aes_ct_ctr_get_vtable()         (&br_aes_ct_ctr_vtable)
 240  #define br_aes_ct_ctrcbc_get_vtable()      (&br_aes_ct_ctrcbc_vtable)
 241  #define br_aes_ct64_cbcenc_get_vtable()    (&br_aes_ct64_cbcenc_vtable)
 242  #define br_aes_ct64_cbcdec_get_vtable()    (&br_aes_ct64_cbcdec_vtable)
 243  #define br_aes_ct64_ctr_get_vtable()       (&br_aes_ct64_ctr_vtable)
 244  #define br_aes_ct64_ctrcbc_get_vtable()    (&br_aes_ct64_ctrcbc_vtable)
 245  #define br_chacha20_ct_get()               (&br_chacha20_ct_run)
 246  
 247  #define SPEED_AES(iname) \
 248  SPEED_BLOCKCIPHER_CBC(AES-128 CBC encrypt (iname), aes128_ ## iname ## _cbcenc, aes_ ## iname, 16, enc) \
 249  SPEED_BLOCKCIPHER_CBC(AES-128 CBC decrypt (iname), aes128_ ## iname ## _cbcdec, aes_ ## iname, 16, dec) \
 250  SPEED_BLOCKCIPHER_CBC(AES-192 CBC encrypt (iname), aes192_ ## iname ## _cbcenc, aes_ ## iname, 24, enc) \
 251  SPEED_BLOCKCIPHER_CBC(AES-192 CBC decrypt (iname), aes192_ ## iname ## _cbcdec, aes_ ## iname, 24, dec) \
 252  SPEED_BLOCKCIPHER_CBC(AES-256 CBC encrypt (iname), aes256_ ## iname ## _cbcenc, aes_ ## iname, 32, enc) \
 253  SPEED_BLOCKCIPHER_CBC(AES-256 CBC decrypt (iname), aes256_ ## iname ## _cbcdec, aes_ ## iname, 32, dec) \
 254  SPEED_BLOCKCIPHER_CTR(AES-128 CTR (iname), aes128_ ## iname ## _ctr, aes_ ## iname, 16) \
 255  SPEED_BLOCKCIPHER_CTR(AES-192 CTR (iname), aes192_ ## iname ## _ctr, aes_ ## iname, 24) \
 256  SPEED_BLOCKCIPHER_CTR(AES-256 CTR (iname), aes256_ ## iname ## _ctr, aes_ ## iname, 32)
 257  
 258  SPEED_AES(big)
 259  SPEED_AES(small)
 260  SPEED_AES(ct)
 261  SPEED_AES(ct64)
 262  SPEED_AES(x86ni)
 263  SPEED_AES(pwr8)
 264  
 265  #define br_des_tab_cbcenc_get_vtable()     (&br_des_tab_cbcenc_vtable)
 266  #define br_des_tab_cbcdec_get_vtable()     (&br_des_tab_cbcdec_vtable)
 267  #define br_des_ct_cbcenc_get_vtable()      (&br_des_ct_cbcenc_vtable)
 268  #define br_des_ct_cbcdec_get_vtable()      (&br_des_ct_cbcdec_vtable)
 269  
 270  #define SPEED_DES(iname) \
 271  SPEED_BLOCKCIPHER_CBC(DES CBC encrypt (iname), des_ ## iname ## _cbcenc, des_ ## iname, 8, enc) \
 272  SPEED_BLOCKCIPHER_CBC(DES CBC decrypt (iname), des_ ## iname ## _cbcdec, des_ ## iname, 8, dec) \
 273  SPEED_BLOCKCIPHER_CBC(3DES CBC encrypt (iname), 3des_ ## iname ## _cbcenc, des_ ## iname, 24, enc) \
 274  SPEED_BLOCKCIPHER_CBC(3DES CBC decrypt (iname), 3des_ ## iname ## _cbcdec, des_ ## iname, 24, dec)
 275  
 276  SPEED_DES(tab)
 277  SPEED_DES(ct)
 278  
 279  SPEED_CHACHA20(ChaCha20 (ct), chacha20_ct)
 280  SPEED_CHACHA20(ChaCha20 (sse2), chacha20_sse2)
 281  
 282  static void
 283  test_speed_ghash_inner(char *name, br_ghash gh)
 284  {
 285  	unsigned char buf[8192], h[16], y[16];
 286  	int i;
 287  	long num;
 288  
 289  	memset(buf, 'T', sizeof buf);
 290  	memset(h, 'P', sizeof h);
 291  	memset(y, 0, sizeof y);
 292  	for (i = 0; i < 10; i ++) {
 293  		gh(y, h, buf, sizeof buf);
 294  	}
 295  	num = 10;
 296  	for (;;) {
 297  		clock_t begin, end;
 298  		double tt;
 299  		long k;
 300  
 301  		begin = clock();
 302  		for (k = num; k > 0; k --) {
 303  			gh(y, h, buf, sizeof buf);
 304  		}
 305  		end = clock();
 306  		tt = (double)(end - begin) / CLOCKS_PER_SEC;
 307  		if (tt >= 2.0) {
 308  			printf("%-30s %8.2f MB/s\n", name,
 309  				((double)sizeof buf) * (double)num
 310  				/ (tt * 1000000.0));
 311  			fflush(stdout);
 312  			return;
 313  		}
 314  		num <<= 1;
 315  	}
 316  }
 317  
 318  static void
 319  test_speed_ghash_ctmul(void)
 320  {
 321  	test_speed_ghash_inner("GHASH (ctmul)", &br_ghash_ctmul);
 322  }
 323  
 324  static void
 325  test_speed_ghash_ctmul32(void)
 326  {
 327  	test_speed_ghash_inner("GHASH (ctmul32)", &br_ghash_ctmul32);
 328  }
 329  
 330  static void
 331  test_speed_ghash_ctmul64(void)
 332  {
 333  	test_speed_ghash_inner("GHASH (ctmul64)", &br_ghash_ctmul64);
 334  }
 335  
 336  static void
 337  test_speed_ghash_pclmul(void)
 338  {
 339  	br_ghash gh;
 340  
 341  	gh = br_ghash_pclmul_get();
 342  	if (gh == 0) {
 343  		printf("%-30s UNAVAILABLE\n", "GHASH (pclmul)");
 344  		fflush(stdout);
 345  	} else {
 346  		test_speed_ghash_inner("GHASH (pclmul)", gh);
 347  	}
 348  }
 349  
 350  static void
 351  test_speed_ghash_pwr8(void)
 352  {
 353  	br_ghash gh;
 354  
 355  	gh = br_ghash_pwr8_get();
 356  	if (gh == 0) {
 357  		printf("%-30s UNAVAILABLE\n", "GHASH (pwr8)");
 358  		fflush(stdout);
 359  	} else {
 360  		test_speed_ghash_inner("GHASH (pwr8)", gh);
 361  	}
 362  }
 363  
 364  static uint32_t
 365  fake_chacha20(const void *key, const void *iv,
 366  	uint32_t cc, void *data, size_t len)
 367  {
 368  	(void)key;
 369  	(void)iv;
 370  	(void)data;
 371  	(void)len;
 372  	return cc + (uint32_t)((len + 63) >> 6);
 373  }
 374  
 375  /*
 376   * To speed-test Poly1305, we run it with a do-nothing stub instead of
 377   * ChaCha20.
 378   */
 379  static void
 380  test_speed_poly1305_inner(char *name, br_poly1305_run pl)
 381  {
 382  	unsigned char buf[8192], key[32], iv[12], aad[13], tag[16];
 383  	int i;
 384  	long num;
 385  
 386  	memset(key, 'K', sizeof key);
 387  	memset(iv, 'I', sizeof iv);
 388  	memset(aad, 'A', sizeof aad);
 389  	memset(buf, 'T', sizeof buf);
 390  	for (i = 0; i < 10; i ++) {
 391  		pl(key, iv, buf, sizeof buf,
 392  			aad, sizeof aad, tag, &fake_chacha20, 0);
 393  	}
 394  	num = 10;
 395  	for (;;) {
 396  		clock_t begin, end;
 397  		double tt;
 398  		long k;
 399  
 400  		begin = clock();
 401  		for (k = num; k > 0; k --) {
 402  			pl(key, iv, buf, sizeof buf,
 403  				aad, sizeof aad, tag, &fake_chacha20, 0);
 404  		}
 405  		end = clock();
 406  		tt = (double)(end - begin) / CLOCKS_PER_SEC;
 407  		if (tt >= 2.0) {
 408  			printf("%-30s %8.2f MB/s\n", name,
 409  				((double)sizeof buf) * (double)num
 410  				/ (tt * 1000000.0));
 411  			fflush(stdout);
 412  			return;
 413  		}
 414  		num <<= 1;
 415  	}
 416  }
 417  
 418  static void
 419  test_speed_poly1305_ctmul(void)
 420  {
 421  	test_speed_poly1305_inner("Poly1305 (ctmul)", &br_poly1305_ctmul_run);
 422  }
 423  
 424  static void
 425  test_speed_poly1305_ctmul32(void)
 426  {
 427  	test_speed_poly1305_inner("Poly1305 (ctmul32)",
 428  		&br_poly1305_ctmul32_run);
 429  }
 430  
 431  static void
 432  test_speed_poly1305_ctmulq(void)
 433  {
 434  	br_poly1305_run bp;
 435  
 436  	bp = br_poly1305_ctmulq_get();
 437  	if (bp == 0) {
 438  		printf("%-30s UNAVAILABLE\n", "Poly1305 (ctmulq)");
 439  	} else {
 440  		test_speed_poly1305_inner("Poly1305 (ctmulq)", bp);
 441  	}
 442  }
 443  
 444  static void
 445  test_speed_poly1305_i15(void)
 446  {
 447  	test_speed_poly1305_inner("Poly1305 (i15)", &br_poly1305_i15_run);
 448  }
 449  
 450  static void
 451  test_speed_eax_inner(char *name,
 452  	const br_block_ctrcbc_class *vt, size_t key_len)
 453  {
 454  	unsigned char buf[8192], key[32], nonce[16], aad[16], tag[16];
 455  	int i;
 456  	long num;
 457  	br_aes_gen_ctrcbc_keys ac;
 458  	br_eax_context ec;
 459  
 460  	if (vt == NULL) {
 461  		printf("%-30s UNAVAILABLE\n", name);
 462  		fflush(stdout);
 463  		return;
 464  	}
 465  	memset(key, 'K', key_len);
 466  	memset(nonce, 'N', sizeof nonce);
 467  	memset(aad, 'A', sizeof aad);
 468  	memset(buf, 'T', sizeof buf);
 469  	for (i = 0; i < 10; i ++) {
 470  		vt->init(&ac.vtable, key, key_len);
 471  		br_eax_init(&ec, &ac.vtable);
 472  		br_eax_reset(&ec, nonce, sizeof nonce);
 473  		br_eax_aad_inject(&ec, aad, sizeof aad);
 474  		br_eax_flip(&ec);
 475  		br_eax_run(&ec, 1, buf, sizeof buf);
 476  		br_eax_get_tag(&ec, tag);
 477  	}
 478  	num = 10;
 479  	for (;;) {
 480  		clock_t begin, end;
 481  		double tt;
 482  		long k;
 483  
 484  		begin = clock();
 485  		for (k = num; k > 0; k --) {
 486  			vt->init(&ac.vtable, key, key_len);
 487  			br_eax_init(&ec, &ac.vtable);
 488  			br_eax_reset(&ec, nonce, sizeof nonce);
 489  			br_eax_aad_inject(&ec, aad, sizeof aad);
 490  			br_eax_flip(&ec);
 491  			br_eax_run(&ec, 1, buf, sizeof buf);
 492  			br_eax_get_tag(&ec, tag);
 493  		}
 494  		end = clock();
 495  		tt = (double)(end - begin) / CLOCKS_PER_SEC;
 496  		if (tt >= 2.0) {
 497  			printf("%-30s %8.2f MB/s\n", name,
 498  				((double)sizeof buf) * (double)num
 499  				/ (tt * 1000000.0));
 500  			fflush(stdout);
 501  			return;
 502  		}
 503  		num <<= 1;
 504  	}
 505  }
 506  
 507  #define SPEED_EAX(Algo, algo, keysize, impl) \
 508  static void \
 509  test_speed_eax_ ## algo ## keysize ## _ ## impl(void) \
 510  { \
 511  	test_speed_eax_inner("EAX " #Algo "-" #keysize "(" #impl ")", \
 512  		br_ ## algo ## _ ## impl ##  _ctrcbc_get_vtable() \
 513  		, (keysize) >> 3); \
 514  }
 515  
 516  SPEED_EAX(AES, aes, 128, big)
 517  SPEED_EAX(AES, aes, 128, small)
 518  SPEED_EAX(AES, aes, 128, ct)
 519  SPEED_EAX(AES, aes, 128, ct64)
 520  SPEED_EAX(AES, aes, 128, x86ni)
 521  SPEED_EAX(AES, aes, 128, pwr8)
 522  SPEED_EAX(AES, aes, 192, big)
 523  SPEED_EAX(AES, aes, 192, small)
 524  SPEED_EAX(AES, aes, 192, ct)
 525  SPEED_EAX(AES, aes, 192, ct64)
 526  SPEED_EAX(AES, aes, 192, x86ni)
 527  SPEED_EAX(AES, aes, 192, pwr8)
 528  SPEED_EAX(AES, aes, 256, big)
 529  SPEED_EAX(AES, aes, 256, small)
 530  SPEED_EAX(AES, aes, 256, ct)
 531  SPEED_EAX(AES, aes, 256, ct64)
 532  SPEED_EAX(AES, aes, 256, x86ni)
 533  SPEED_EAX(AES, aes, 256, pwr8)
 534  
 535  static void
 536  test_speed_shake_inner(int security_level)
 537  {
 538  	unsigned char buf[8192];
 539  	br_shake_context sc;
 540  	int i;
 541  	long num;
 542  
 543  	memset(buf, 'D', sizeof buf);
 544  	br_shake_init(&sc, security_level);
 545  	for (i = 0; i < 10; i ++) {
 546  		br_shake_inject(&sc, buf, sizeof buf);
 547  	}
 548  	num = 10;
 549  	for (;;) {
 550  		clock_t begin, end;
 551  		double tt;
 552  		long k;
 553  
 554  		begin = clock();
 555  		for (k = num; k > 0; k --) {
 556  			br_shake_inject(&sc, buf, sizeof buf);
 557  		}
 558  		end = clock();
 559  		tt = (double)(end - begin) / CLOCKS_PER_SEC;
 560  		if (tt >= 2.0) {
 561  			printf("SHAKE%-3d (inject)              %8.2f MB/s\n",
 562  				security_level,
 563  				((double)sizeof buf) * (double)num
 564  				/ (tt * 1000000.0));
 565  			fflush(stdout);
 566  			break;
 567  		}
 568  		num <<= 1;
 569  	}
 570  
 571  	br_shake_flip(&sc);
 572  	for (i = 0; i < 10; i ++) {
 573  		br_shake_produce(&sc, buf, sizeof buf);
 574  	}
 575  
 576  	num = 10;
 577  	for (;;) {
 578  		clock_t begin, end;
 579  		double tt;
 580  		long k;
 581  
 582  		begin = clock();
 583  		for (k = num; k > 0; k --) {
 584  			br_shake_produce(&sc, buf, sizeof buf);
 585  		}
 586  		end = clock();
 587  		tt = (double)(end - begin) / CLOCKS_PER_SEC;
 588  		if (tt >= 2.0) {
 589  			printf("SHAKE%-3d (produce)             %8.2f MB/s\n",
 590  				security_level,
 591  				((double)sizeof buf) * (double)num
 592  				/ (tt * 1000000.0));
 593  			fflush(stdout);
 594  			break;
 595  		}
 596  		num <<= 1;
 597  	}
 598  }
 599  
 600  static void
 601  test_speed_shake128(void)
 602  {
 603  	test_speed_shake_inner(128);
 604  }
 605  
 606  static void
 607  test_speed_shake256(void)
 608  {
 609  	test_speed_shake_inner(256);
 610  }
 611  
 612  static const unsigned char RSA_N[] = {
 613  	0xE9, 0xF2, 0x4A, 0x2F, 0x96, 0xDF, 0x0A, 0x23,
 614  	0x01, 0x85, 0xF1, 0x2C, 0xB2, 0xA8, 0xEF, 0x23,
 615  	0xCE, 0x2E, 0xB0, 0x4E, 0x18, 0x31, 0x95, 0x5B,
 616  	0x98, 0x2D, 0x9B, 0x8C, 0xE3, 0x1A, 0x2B, 0x96,
 617  	0xB5, 0xC7, 0xEE, 0xED, 0x72, 0x43, 0x2D, 0xFE,
 618  	0x7F, 0x61, 0x33, 0xEA, 0x14, 0xFC, 0xDE, 0x80,
 619  	0x17, 0x42, 0xF0, 0xF3, 0xC3, 0xC7, 0x89, 0x47,
 620  	0x76, 0x5B, 0xFA, 0x33, 0xC4, 0x8C, 0x94, 0xDE,
 621  	0x6A, 0x75, 0xD8, 0x1A, 0xF4, 0x49, 0xBC, 0xF3,
 622  	0xB7, 0x9E, 0x2C, 0x8D, 0xEC, 0x5A, 0xEE, 0xBF,
 623  	0x4B, 0x5A, 0x7F, 0xEF, 0x21, 0x39, 0xDB, 0x1D,
 624  	0x83, 0x5E, 0x7E, 0x2F, 0xAA, 0x5E, 0xBA, 0x28,
 625  	0xC3, 0xA2, 0x53, 0x19, 0xFB, 0x2F, 0x78, 0x6B,
 626  	0x14, 0x60, 0x49, 0x3C, 0xCC, 0x1B, 0xE9, 0x1E,
 627  	0x3D, 0x10, 0xA4, 0xEB, 0x7F, 0x66, 0x98, 0xF6,
 628  	0xC3, 0xAC, 0x35, 0xF5, 0x01, 0x84, 0xFF, 0x7D,
 629  	0x1F, 0x72, 0xBE, 0xB4, 0xD1, 0x89, 0xC8, 0xDD,
 630  	0x44, 0xE7, 0xB5, 0x2E, 0x2C, 0xE1, 0x85, 0xF5,
 631  	0x15, 0x50, 0xA9, 0x08, 0xC7, 0x67, 0xD9, 0x2B,
 632  	0x6C, 0x11, 0xB3, 0xEB, 0x28, 0x8D, 0xF4, 0xCC,
 633  	0xE3, 0xC3, 0xC5, 0x04, 0x0E, 0x7C, 0x8D, 0xDB,
 634  	0x39, 0x06, 0x6A, 0x74, 0x75, 0xDF, 0xA8, 0x0F,
 635  	0xDA, 0x67, 0x5A, 0x73, 0x1E, 0xFD, 0x8E, 0x4C,
 636  	0xEE, 0x17, 0xEE, 0x1E, 0x67, 0xDB, 0x98, 0x70,
 637  	0x60, 0xF7, 0xB9, 0xB5, 0x1F, 0x19, 0x93, 0xD6,
 638  	0x3F, 0x2F, 0x1F, 0xB6, 0x5B, 0x59, 0xAA, 0x85,
 639  	0xBB, 0x25, 0xE4, 0x13, 0xEF, 0xE7, 0xB9, 0x87,
 640  	0x9C, 0x3F, 0x5E, 0xE4, 0x08, 0xA3, 0x51, 0xCF,
 641  	0x8B, 0xAD, 0xF4, 0xE6, 0x1A, 0x5F, 0x51, 0xDD,
 642  	0xA8, 0xBE, 0xE8, 0xD1, 0x20, 0x19, 0x61, 0x6C,
 643  	0x18, 0xAB, 0xCA, 0x0A, 0xD9, 0x82, 0xA6, 0x94,
 644  	0xD5, 0x69, 0x2A, 0xF6, 0x43, 0x66, 0x31, 0x09
 645  };
 646  
 647  static const unsigned char RSA_E[] = {
 648  	0x01, 0x00, 0x01
 649  };
 650  
 651  static const unsigned char RSA_P[] = {
 652  	0xFD, 0x39, 0x40, 0x56, 0x20, 0x80, 0xC5, 0x81,
 653  	0x4C, 0x5F, 0x0C, 0x1A, 0x52, 0x84, 0x03, 0x2F,
 654  	0xCE, 0x82, 0xB0, 0xD8, 0x30, 0x23, 0x7F, 0x77,
 655  	0x45, 0xC2, 0x01, 0xC4, 0x68, 0x96, 0x0D, 0xA7,
 656  	0x22, 0xA9, 0x6C, 0xA9, 0x1A, 0x33, 0xE5, 0x2F,
 657  	0xB5, 0x07, 0x9A, 0xF9, 0xEA, 0x33, 0xA5, 0xC8,
 658  	0x96, 0x60, 0x6A, 0xCA, 0xEB, 0xE5, 0x6E, 0x09,
 659  	0x46, 0x7E, 0x2D, 0xEF, 0x93, 0x7D, 0x56, 0xED,
 660  	0x75, 0x70, 0x3B, 0x96, 0xC4, 0xD5, 0xDB, 0x0B,
 661  	0x3F, 0x69, 0xDF, 0x06, 0x18, 0x76, 0xF4, 0xCF,
 662  	0xF8, 0x84, 0x22, 0xDF, 0xBD, 0x71, 0x62, 0x7B,
 663  	0x67, 0x99, 0xBC, 0x09, 0x95, 0x54, 0xA4, 0x98,
 664  	0x83, 0xF5, 0xA9, 0xCF, 0x09, 0xA5, 0x1F, 0x61,
 665  	0x25, 0xB4, 0x70, 0x6C, 0x91, 0xB8, 0xB3, 0xD0,
 666  	0xCE, 0x9C, 0x45, 0x65, 0x9B, 0xEF, 0xD4, 0x70,
 667  	0xBE, 0x86, 0xD2, 0x98, 0x5D, 0xEB, 0xE3, 0xFF
 668  };
 669  
 670  static const unsigned char RSA_Q[] = {
 671  	0xEC, 0x82, 0xEE, 0x63, 0x5F, 0x40, 0x52, 0xDB,
 672  	0x38, 0x7A, 0x37, 0x6A, 0x54, 0x5B, 0xD9, 0xA0,
 673  	0x73, 0xB4, 0xBB, 0x52, 0xB2, 0x84, 0x07, 0xD0,
 674  	0xCC, 0x82, 0x0D, 0x20, 0xB3, 0xFA, 0xD5, 0xB6,
 675  	0x25, 0x92, 0x35, 0x4D, 0xB4, 0xC7, 0x36, 0x48,
 676  	0xCE, 0x5E, 0x21, 0x4A, 0xA6, 0x74, 0x65, 0xF4,
 677  	0x7D, 0x1D, 0xBC, 0x3B, 0xE2, 0xF4, 0x3E, 0x11,
 678  	0x58, 0x10, 0x6C, 0x04, 0x46, 0x9E, 0x8D, 0x57,
 679  	0xE0, 0x04, 0xE2, 0xEC, 0x47, 0xCF, 0xB3, 0x2A,
 680  	0xFD, 0x4C, 0x55, 0x18, 0xDB, 0xDE, 0x3B, 0xDC,
 681  	0xF4, 0x5B, 0xDA, 0xF3, 0x1A, 0xC8, 0x41, 0x6F,
 682  	0x73, 0x3B, 0xFE, 0x3C, 0xA0, 0xDB, 0xBA, 0x6E,
 683  	0x65, 0xA5, 0xE8, 0x02, 0xA5, 0x6C, 0xEA, 0x03,
 684  	0xF6, 0x99, 0xF7, 0xCB, 0x4B, 0xB7, 0x11, 0x51,
 685  	0x93, 0x88, 0x3F, 0xF9, 0x06, 0x85, 0xA9, 0x1E,
 686  	0xCA, 0x64, 0xF8, 0x11, 0xA5, 0x1A, 0xCA, 0xF7
 687  };
 688  
 689  static const unsigned char RSA_DP[] = {
 690  	0x77, 0x95, 0xE0, 0x02, 0x4C, 0x9B, 0x43, 0xAA,
 691  	0xCA, 0x4C, 0x60, 0xC4, 0xD5, 0x8F, 0x2E, 0x8A,
 692  	0x17, 0x36, 0xB5, 0x19, 0x83, 0xB2, 0x5F, 0xF2,
 693  	0x0D, 0xE9, 0x8F, 0x38, 0x18, 0x44, 0x34, 0xF2,
 694  	0x67, 0x76, 0x27, 0xB0, 0xBC, 0x85, 0x21, 0x89,
 695  	0x24, 0x2F, 0x11, 0x4B, 0x51, 0x05, 0x4F, 0x17,
 696  	0xA9, 0x9C, 0xA3, 0x12, 0x6D, 0xD1, 0x0D, 0xE4,
 697  	0x27, 0x7C, 0x53, 0x69, 0x3E, 0xF8, 0x04, 0x63,
 698  	0x64, 0x00, 0xBA, 0xC3, 0x7A, 0xF5, 0x9B, 0xDA,
 699  	0x75, 0xFA, 0x23, 0xAF, 0x17, 0x42, 0xA6, 0x5E,
 700  	0xC8, 0xF8, 0x6E, 0x17, 0xC7, 0xB9, 0x92, 0x4E,
 701  	0xC1, 0x20, 0x63, 0x23, 0x0B, 0x78, 0xCB, 0xBA,
 702  	0x93, 0x27, 0x23, 0x28, 0x79, 0x5F, 0x97, 0xB0,
 703  	0x23, 0x44, 0x51, 0x8B, 0x94, 0x4D, 0xEB, 0xED,
 704  	0x82, 0x85, 0x5E, 0x68, 0x9B, 0xF9, 0xE9, 0x13,
 705  	0xCD, 0x86, 0x92, 0x52, 0x0E, 0x98, 0xE6, 0x35
 706  };
 707  
 708  static const unsigned char RSA_DQ[] = {
 709  	0xD8, 0xDD, 0x71, 0xB3, 0x62, 0xBA, 0xBB, 0x7E,
 710  	0xD1, 0xF9, 0x96, 0xE8, 0x83, 0xB3, 0xB9, 0x08,
 711  	0x9C, 0x30, 0x03, 0x77, 0xDF, 0xC2, 0x9A, 0xDC,
 712  	0x05, 0x39, 0xD6, 0xC9, 0xBE, 0xDE, 0x68, 0xA9,
 713  	0xDD, 0x27, 0x84, 0x82, 0xDD, 0x19, 0xB1, 0x97,
 714  	0xEE, 0xCA, 0x77, 0x22, 0x59, 0x20, 0xEF, 0xFF,
 715  	0xCF, 0xDD, 0xBD, 0x24, 0xF8, 0x84, 0xD6, 0x88,
 716  	0xD6, 0xC4, 0x30, 0x17, 0x77, 0x9D, 0x98, 0xA3,
 717  	0x14, 0x01, 0xC7, 0x05, 0xBB, 0x0F, 0x23, 0x0D,
 718  	0x6F, 0x37, 0x57, 0xEC, 0x34, 0x67, 0x41, 0x62,
 719  	0xE8, 0x19, 0x75, 0xD9, 0x66, 0x1C, 0x6B, 0x8B,
 720  	0xC3, 0x11, 0x26, 0x9C, 0xF7, 0x2E, 0xA3, 0x72,
 721  	0xE8, 0xF7, 0xC8, 0x96, 0xEC, 0x92, 0xC2, 0xBD,
 722  	0xA1, 0x98, 0x2A, 0x93, 0x99, 0xB8, 0xA2, 0x43,
 723  	0xB7, 0xD0, 0xBE, 0x40, 0x1C, 0x8F, 0xE0, 0xB4,
 724  	0x20, 0x07, 0x97, 0x43, 0xAE, 0xAD, 0xB3, 0x9F
 725  };
 726  
 727  static const unsigned char RSA_IQ[] = {
 728  	0xB7, 0xE2, 0x60, 0xA9, 0x62, 0xEC, 0xEC, 0x0B,
 729  	0x57, 0x02, 0x96, 0xF9, 0x36, 0x35, 0x2C, 0x37,
 730  	0xAF, 0xC2, 0xEE, 0x71, 0x49, 0x26, 0x8E, 0x0F,
 731  	0x27, 0xB1, 0xFA, 0x0F, 0xEA, 0xDC, 0xF0, 0x8B,
 732  	0x53, 0x6C, 0xB2, 0x46, 0x27, 0xCD, 0x29, 0xA2,
 733  	0x35, 0x0F, 0x5D, 0x8A, 0x3F, 0x20, 0x8C, 0x13,
 734  	0x3D, 0xA1, 0xFF, 0x85, 0x91, 0x99, 0xE8, 0x50,
 735  	0xED, 0xF1, 0x29, 0x00, 0xEE, 0x24, 0x90, 0xB5,
 736  	0x5F, 0x3A, 0x74, 0x26, 0xD7, 0xA2, 0x24, 0x8D,
 737  	0x89, 0x88, 0xD8, 0x35, 0x22, 0x22, 0x8A, 0x66,
 738  	0x5D, 0x5C, 0xDE, 0x83, 0x8C, 0xFA, 0x27, 0xE6,
 739  	0xB9, 0xEB, 0x72, 0x08, 0xCD, 0x53, 0x4B, 0x93,
 740  	0x0F, 0xAD, 0xC3, 0xF8, 0x7C, 0xFE, 0x84, 0xD7,
 741  	0x08, 0xF3, 0xBE, 0x3D, 0x60, 0x1E, 0x95, 0x8D,
 742  	0x44, 0x5B, 0x65, 0x7E, 0xC1, 0x30, 0xC3, 0x84,
 743  	0xC0, 0xB0, 0xFE, 0xBF, 0x28, 0x54, 0x1E, 0xC4
 744  };
 745  
 746  static const br_rsa_public_key RSA_PK = {
 747  	(void *)RSA_N, sizeof RSA_N,
 748  	(void *)RSA_E, sizeof RSA_E
 749  };
 750  
 751  static const br_rsa_private_key RSA_SK = {
 752  	2048,
 753  	(void *)RSA_P, sizeof RSA_P,
 754  	(void *)RSA_Q, sizeof RSA_Q,
 755  	(void *)RSA_DP, sizeof RSA_DP,
 756  	(void *)RSA_DQ, sizeof RSA_DQ,
 757  	(void *)RSA_IQ, sizeof RSA_IQ
 758  };
 759  
 760  static void
 761  test_speed_rsa_inner(char *name,
 762  	br_rsa_public fpub, br_rsa_private fpriv, br_rsa_keygen kgen)
 763  {
 764  	unsigned char tmp[sizeof RSA_N];
 765  	int i;
 766  	long num;
 767  	/*
 768  	br_hmac_drbg_context rng;
 769  	*/
 770  	br_aesctr_drbg_context rng;
 771  	const br_block_ctr_class *ictr;
 772  
 773  	memset(tmp, 'R', sizeof tmp);
 774  	tmp[0] = 0;
 775  	for (i = 0; i < 10; i ++) {
 776  		if (!fpriv(tmp, &RSA_SK)) {
 777  			abort();
 778  		}
 779  	}
 780  	num = 10;
 781  	for (;;) {
 782  		clock_t begin, end;
 783  		double tt;
 784  		long k;
 785  
 786  		begin = clock();
 787  		for (k = num; k > 0; k --) {
 788  			fpriv(tmp, &RSA_SK);
 789  		}
 790  		end = clock();
 791  		tt = (double)(end - begin) / CLOCKS_PER_SEC;
 792  		if (tt >= 2.0) {
 793  			printf("%-30s %8.2f priv/s\n", name,
 794  				(double)num / tt);
 795  			fflush(stdout);
 796  			break;
 797  		}
 798  		num <<= 1;
 799  	}
 800  	for (i = 0; i < 10; i ++) {
 801  		if (!fpub(tmp, sizeof tmp, &RSA_PK)) {
 802  			abort();
 803  		}
 804  	}
 805  	num = 10;
 806  	for (;;) {
 807  		clock_t begin, end;
 808  		double tt;
 809  		long k;
 810  
 811  		begin = clock();
 812  		for (k = num; k > 0; k --) {
 813  			fpub(tmp, sizeof tmp, &RSA_PK);
 814  		}
 815  		end = clock();
 816  		tt = (double)(end - begin) / CLOCKS_PER_SEC;
 817  		if (tt >= 2.0) {
 818  			printf("%-30s %8.2f pub/s\n", name,
 819  				(double)num / tt);
 820  			fflush(stdout);
 821  			break;
 822  		}
 823  		num <<= 1;
 824  	}
 825  
 826  	if (kgen == 0) {
 827  		printf("%-30s KEYGEN UNAVAILABLE\n", name);
 828  		fflush(stdout);
 829  		return;
 830  	}
 831  	/*
 832  	br_hmac_drbg_init(&rng, &br_sha256_vtable, "RSA keygen seed", 15);
 833  	*/
 834  	ictr = br_aes_x86ni_ctr_get_vtable();
 835  	if (ictr == NULL) {
 836  		ictr = br_aes_pwr8_ctr_get_vtable();
 837  		if (ictr == NULL) {
 838  #if BR_64
 839  			ictr = &br_aes_ct64_ctr_vtable;
 840  #else
 841  			ictr = &br_aes_ct_ctr_vtable;
 842  #endif
 843  		}
 844  	}
 845  	br_aesctr_drbg_init(&rng, ictr, "RSA keygen seed", 15);
 846  
 847  	num = 10;
 848  	for (;;) {
 849  		clock_t begin, end;
 850  		double tt;
 851  		long k;
 852  
 853  		begin = clock();
 854  		for (k = num; k > 0; k --) {
 855  			br_rsa_private_key sk;
 856  			unsigned char kbuf[BR_RSA_KBUF_PRIV_SIZE(1024)];
 857  
 858  			kgen(&rng.vtable, &sk, kbuf, NULL, NULL, 1024, 0);
 859  		}
 860  		end = clock();
 861  		tt = (double)(end - begin) / CLOCKS_PER_SEC;
 862  		if (tt >= 10.0) {
 863  			printf("%-30s %8.2f kgen[1024]/s\n", name,
 864  				(double)num / tt);
 865  			fflush(stdout);
 866  			break;
 867  		}
 868  		num <<= 1;
 869  	}
 870  
 871  	num = 10;
 872  	for (;;) {
 873  		clock_t begin, end;
 874  		double tt;
 875  		long k;
 876  
 877  		begin = clock();
 878  		for (k = num; k > 0; k --) {
 879  			br_rsa_private_key sk;
 880  			unsigned char kbuf[BR_RSA_KBUF_PRIV_SIZE(2048)];
 881  
 882  			kgen(&rng.vtable, &sk, kbuf, NULL, NULL, 2048, 0);
 883  		}
 884  		end = clock();
 885  		tt = (double)(end - begin) / CLOCKS_PER_SEC;
 886  		if (tt >= 10.0) {
 887  			printf("%-30s %8.2f kgen[2048]/s\n", name,
 888  				(double)num / tt);
 889  			fflush(stdout);
 890  			break;
 891  		}
 892  		num <<= 1;
 893  	}
 894  }
 895  
 896  static void
 897  test_speed_rsa_i15(void)
 898  {
 899  	test_speed_rsa_inner("RSA i15",
 900  		&br_rsa_i15_public, &br_rsa_i15_private, &br_rsa_i15_keygen);
 901  }
 902  
 903  static void
 904  test_speed_rsa_i31(void)
 905  {
 906  	test_speed_rsa_inner("RSA i31",
 907  		&br_rsa_i31_public, &br_rsa_i31_private, &br_rsa_i31_keygen);
 908  }
 909  
 910  static void
 911  test_speed_rsa_i32(void)
 912  {
 913  	test_speed_rsa_inner("RSA i32",
 914  		&br_rsa_i32_public, &br_rsa_i32_private, 0);
 915  }
 916  
 917  static void
 918  test_speed_rsa_i62(void)
 919  {
 920  	br_rsa_public pub;
 921  	br_rsa_private priv;
 922  	br_rsa_keygen kgen;
 923  
 924  	pub = br_rsa_i62_public_get();
 925  	priv = br_rsa_i62_private_get();
 926  	kgen = br_rsa_i62_keygen_get();
 927  	if (pub) {
 928  		test_speed_rsa_inner("RSA i62", pub, priv, kgen);
 929  	} else {
 930  		printf("%-30s UNAVAILABLE\n", "RSA i62");
 931  	}
 932  }
 933  
 934  static void
 935  test_speed_ec_inner_1(const char *name,
 936  	const br_ec_impl *impl, const br_ec_curve_def *cd)
 937  {
 938  	unsigned char bx[80], U[160];
 939  	uint32_t x[22], n[22];
 940  	size_t nlen, ulen;
 941  	int i;
 942  	long num;
 943  
 944  	nlen = cd->order_len;
 945  	br_i31_decode(n, cd->order, nlen);
 946  	memset(bx, 'T', sizeof bx);
 947  	br_i31_decode_reduce(x, bx, sizeof bx, n);
 948  	br_i31_encode(bx, nlen, x);
 949  	ulen = cd->generator_len;
 950  	memcpy(U, cd->generator, ulen);
 951  	for (i = 0; i < 10; i ++) {
 952  		impl->mul(U, ulen, bx, nlen, cd->curve);
 953  	}
 954  	num = 10;
 955  	for (;;) {
 956  		clock_t begin, end;
 957  		double tt;
 958  		long k;
 959  
 960  		begin = clock();
 961  		for (k = num; k > 0; k --) {
 962  			impl->mul(U, ulen, bx, nlen, cd->curve);
 963  		}
 964  		end = clock();
 965  		tt = (double)(end - begin) / CLOCKS_PER_SEC;
 966  		if (tt >= 2.0) {
 967  			printf("%-30s %8.2f mul/s\n", name,
 968  				(double)num / tt);
 969  			fflush(stdout);
 970  			break;
 971  		}
 972  		num <<= 1;
 973  	}
 974  }
 975  
 976  static void
 977  test_speed_ec_inner_2(const char *name,
 978  	const br_ec_impl *impl, const br_ec_curve_def *cd)
 979  {
 980  	unsigned char bx[80], U[160];
 981  	uint32_t x[22], n[22];
 982  	size_t nlen;
 983  	int i;
 984  	long num;
 985  
 986  	nlen = cd->order_len;
 987  	br_i31_decode(n, cd->order, nlen);
 988  	memset(bx, 'T', sizeof bx);
 989  	br_i31_decode_reduce(x, bx, sizeof bx, n);
 990  	br_i31_encode(bx, nlen, x);
 991  	for (i = 0; i < 10; i ++) {
 992  		impl->mulgen(U, bx, nlen, cd->curve);
 993  	}
 994  	num = 10;
 995  	for (;;) {
 996  		clock_t begin, end;
 997  		double tt;
 998  		long k;
 999  
1000  		begin = clock();
1001  		for (k = num; k > 0; k --) {
1002  			impl->mulgen(U, bx, nlen, cd->curve);
1003  		}
1004  		end = clock();
1005  		tt = (double)(end - begin) / CLOCKS_PER_SEC;
1006  		if (tt >= 2.0) {
1007  			printf("%-30s %8.2f mul/s\n", name,
1008  				(double)num / tt);
1009  			fflush(stdout);
1010  			break;
1011  		}
1012  		num <<= 1;
1013  	}
1014  }
1015  
1016  static void
1017  test_speed_ec_inner(const char *name,
1018  	const br_ec_impl *impl, const br_ec_curve_def *cd)
1019  {
1020  	char tmp[50];
1021  
1022  	test_speed_ec_inner_1(name, impl, cd);
1023  	sprintf(tmp, "%s (FP)", name);
1024  	test_speed_ec_inner_2(tmp, impl, cd);
1025  }
1026  
1027  static void
1028  test_speed_ec_p256_m15(void)
1029  {
1030  	test_speed_ec_inner("EC p256_m15",
1031  		&br_ec_p256_m15, &br_secp256r1);
1032  }
1033  
1034  static void
1035  test_speed_ec_p256_m31(void)
1036  {
1037  	test_speed_ec_inner("EC p256_m31",
1038  		&br_ec_p256_m31, &br_secp256r1);
1039  }
1040  
1041  static void
1042  test_speed_ec_p256_m62(void)
1043  {
1044  	const br_ec_impl *ec;
1045  
1046  	ec = br_ec_p256_m62_get();
1047  	if (ec != NULL) {
1048  		test_speed_ec_inner("EC p256_m62", ec, &br_secp256r1);
1049  	} else {
1050  		printf("%-30s UNAVAILABLE\n", "EC p256_m62");
1051  	}
1052  }
1053  
1054  static void
1055  test_speed_ec_p256_m64(void)
1056  {
1057  	const br_ec_impl *ec;
1058  
1059  	ec = br_ec_p256_m64_get();
1060  	if (ec != NULL) {
1061  		test_speed_ec_inner("EC p256_m64", ec, &br_secp256r1);
1062  	} else {
1063  		printf("%-30s UNAVAILABLE\n", "EC p256_m64");
1064  	}
1065  }
1066  
1067  static void
1068  test_speed_ec_prime_i15(void)
1069  {
1070  	test_speed_ec_inner("EC prime_i15 P-256",
1071  		&br_ec_prime_i15, &br_secp256r1);
1072  	test_speed_ec_inner("EC prime_i15 P-384",
1073  		&br_ec_prime_i15, &br_secp384r1);
1074  	test_speed_ec_inner("EC prime_i15 P-521",
1075  		&br_ec_prime_i15, &br_secp521r1);
1076  }
1077  
1078  static void
1079  test_speed_ec_prime_i31(void)
1080  {
1081  	test_speed_ec_inner("EC prime_i31 P-256",
1082  		&br_ec_prime_i31, &br_secp256r1);
1083  	test_speed_ec_inner("EC prime_i31 P-384",
1084  		&br_ec_prime_i31, &br_secp384r1);
1085  	test_speed_ec_inner("EC prime_i31 P-521",
1086  		&br_ec_prime_i31, &br_secp521r1);
1087  }
1088  
1089  static void
1090  test_speed_ec_c25519_i15(void)
1091  {
1092  	test_speed_ec_inner("EC c25519_i15",
1093  		&br_ec_c25519_i15, &br_curve25519);
1094  }
1095  
1096  static void
1097  test_speed_ec_c25519_i31(void)
1098  {
1099  	test_speed_ec_inner("EC c25519_i31",
1100  		&br_ec_c25519_i31, &br_curve25519);
1101  }
1102  
1103  static void
1104  test_speed_ec_c25519_m15(void)
1105  {
1106  	test_speed_ec_inner("EC c25519_m15",
1107  		&br_ec_c25519_m15, &br_curve25519);
1108  }
1109  
1110  static void
1111  test_speed_ec_c25519_m31(void)
1112  {
1113  	test_speed_ec_inner("EC c25519_m31",
1114  		&br_ec_c25519_m31, &br_curve25519);
1115  }
1116  
1117  static void
1118  test_speed_ec_c25519_m62(void)
1119  {
1120  	const br_ec_impl *ec;
1121  
1122  	ec = br_ec_c25519_m62_get();
1123  	if (ec != NULL) {
1124  		test_speed_ec_inner("EC c25519_m62", ec, &br_curve25519);
1125  	} else {
1126  		printf("%-30s UNAVAILABLE\n", "EC c25519_m62");
1127  	}
1128  }
1129  
1130  static void
1131  test_speed_ec_c25519_m64(void)
1132  {
1133  	const br_ec_impl *ec;
1134  
1135  	ec = br_ec_c25519_m64_get();
1136  	if (ec != NULL) {
1137  		test_speed_ec_inner("EC c25519_m64", ec, &br_curve25519);
1138  	} else {
1139  		printf("%-30s UNAVAILABLE\n", "EC c25519_m64");
1140  	}
1141  }
1142  
1143  static void
1144  test_speed_ecdsa_inner(const char *name,
1145  	const br_ec_impl *impl, const br_ec_curve_def *cd,
1146  	br_ecdsa_sign sign, br_ecdsa_vrfy vrfy)
1147  {
1148  	unsigned char bx[80], U[160], hv[32], sig[160];
1149  	uint32_t x[22], n[22];
1150  	size_t nlen, ulen, sig_len;
1151  	int i;
1152  	long num;
1153  	br_ec_private_key sk;
1154  	br_ec_public_key pk;
1155  
1156  	nlen = cd->order_len;
1157  	br_i31_decode(n, cd->order, nlen);
1158  	memset(bx, 'T', sizeof bx);
1159  	br_i31_decode_reduce(x, bx, sizeof bx, n);
1160  	br_i31_encode(bx, nlen, x);
1161  	ulen = cd->generator_len;
1162  	memcpy(U, cd->generator, ulen);
1163  	impl->mul(U, ulen, bx, nlen, cd->curve);
1164  	sk.curve = cd->curve;
1165  	sk.x = bx;
1166  	sk.xlen = nlen;
1167  	pk.curve = cd->curve;
1168  	pk.q = U;
1169  	pk.qlen = ulen;
1170  
1171  	memset(hv, 'H', sizeof hv);
1172  	sig_len = sign(impl, &br_sha256_vtable, hv, &sk, sig);
1173  	if (vrfy(impl, hv, sizeof hv, &pk, sig, sig_len) != 1) {
1174  		fprintf(stderr, "self-test sign/verify failed\n");
1175  		exit(EXIT_FAILURE);
1176  	}
1177  
1178  	for (i = 0; i < 10; i ++) {
1179  		hv[1] ++;
1180  		sign(impl, &br_sha256_vtable, hv, &sk, sig);
1181  		vrfy(impl, hv, sizeof hv, &pk, sig, sig_len);
1182  	}
1183  
1184  	num = 10;
1185  	for (;;) {
1186  		clock_t begin, end;
1187  		double tt;
1188  		long k;
1189  
1190  		begin = clock();
1191  		for (k = num; k > 0; k --) {
1192  			hv[1] ++;
1193  			sig_len = sign(impl, &br_sha256_vtable, hv, &sk, sig);
1194  		}
1195  		end = clock();
1196  		tt = (double)(end - begin) / CLOCKS_PER_SEC;
1197  		if (tt >= 2.0) {
1198  			printf("%-30s %8.2f sign/s\n", name,
1199  				(double)num / tt);
1200  			fflush(stdout);
1201  			break;
1202  		}
1203  		num <<= 1;
1204  	}
1205  
1206  	num = 10;
1207  	for (;;) {
1208  		clock_t begin, end;
1209  		double tt;
1210  		long k;
1211  
1212  		begin = clock();
1213  		for (k = num; k > 0; k --) {
1214  			vrfy(impl, hv, sizeof hv, &pk, sig, sig_len);
1215  		}
1216  		end = clock();
1217  		tt = (double)(end - begin) / CLOCKS_PER_SEC;
1218  		if (tt >= 2.0) {
1219  			printf("%-30s %8.2f verify/s\n", name,
1220  				(double)num / tt);
1221  			fflush(stdout);
1222  			break;
1223  		}
1224  		num <<= 1;
1225  	}
1226  }
1227  
1228  static void
1229  test_speed_ecdsa_p256_m15(void)
1230  {
1231  	test_speed_ecdsa_inner("ECDSA m15 P-256",
1232  		&br_ec_p256_m15, &br_secp256r1,
1233  		&br_ecdsa_i15_sign_asn1,
1234  		&br_ecdsa_i15_vrfy_asn1);
1235  }
1236  
1237  static void
1238  test_speed_ecdsa_p256_m31(void)
1239  {
1240  	test_speed_ecdsa_inner("ECDSA m31 P-256",
1241  		&br_ec_p256_m31, &br_secp256r1,
1242  		&br_ecdsa_i31_sign_asn1,
1243  		&br_ecdsa_i31_vrfy_asn1);
1244  }
1245  
1246  static void
1247  test_speed_ecdsa_p256_m62(void)
1248  {
1249  	const br_ec_impl *ec;
1250  
1251  	ec = br_ec_p256_m62_get();
1252  	if (ec != NULL) {
1253  		test_speed_ecdsa_inner("ECDSA m62 P-256",
1254  			ec, &br_secp256r1,
1255  			&br_ecdsa_i31_sign_asn1,
1256  			&br_ecdsa_i31_vrfy_asn1);
1257  	} else {
1258  		printf("%-30s UNAVAILABLE\n", "ECDSA m62 P-256");
1259  	}
1260  }
1261  
1262  static void
1263  test_speed_ecdsa_p256_m64(void)
1264  {
1265  	const br_ec_impl *ec;
1266  
1267  	ec = br_ec_p256_m64_get();
1268  	if (ec != NULL) {
1269  		test_speed_ecdsa_inner("ECDSA m64 P-256",
1270  			ec, &br_secp256r1,
1271  			&br_ecdsa_i31_sign_asn1,
1272  			&br_ecdsa_i31_vrfy_asn1);
1273  	} else {
1274  		printf("%-30s UNAVAILABLE\n", "ECDSA m64 P-256");
1275  	}
1276  }
1277  
1278  static void
1279  test_speed_ecdsa_i15(void)
1280  {
1281  	test_speed_ecdsa_inner("ECDSA i15 P-256",
1282  		&br_ec_prime_i15, &br_secp256r1,
1283  		&br_ecdsa_i15_sign_asn1,
1284  		&br_ecdsa_i15_vrfy_asn1);
1285  	test_speed_ecdsa_inner("ECDSA i15 P-384",
1286  		&br_ec_prime_i15, &br_secp384r1,
1287  		&br_ecdsa_i15_sign_asn1,
1288  		&br_ecdsa_i15_vrfy_asn1);
1289  	test_speed_ecdsa_inner("ECDSA i15 P-521",
1290  		&br_ec_prime_i15, &br_secp521r1,
1291  		&br_ecdsa_i15_sign_asn1,
1292  		&br_ecdsa_i15_vrfy_asn1);
1293  }
1294  
1295  static void
1296  test_speed_ecdsa_i31(void)
1297  {
1298  	test_speed_ecdsa_inner("ECDSA i31 P-256",
1299  		&br_ec_prime_i31, &br_secp256r1,
1300  		&br_ecdsa_i31_sign_asn1,
1301  		&br_ecdsa_i31_vrfy_asn1);
1302  	test_speed_ecdsa_inner("ECDSA i31 P-384",
1303  		&br_ec_prime_i31, &br_secp384r1,
1304  		&br_ecdsa_i31_sign_asn1,
1305  		&br_ecdsa_i31_vrfy_asn1);
1306  	test_speed_ecdsa_inner("ECDSA i31 P-521",
1307  		&br_ec_prime_i31, &br_secp521r1,
1308  		&br_ecdsa_i31_sign_asn1,
1309  		&br_ecdsa_i31_vrfy_asn1);
1310  }
1311  
1312  static void
1313  test_speed_i31(void)
1314  {
1315  	static const unsigned char bp[] = {
1316  		/* A 521-bit prime integer (order of the P-521 curve). */
1317  		0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1318  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1319  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1320  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1321  		0xFF, 0xFA, 0x51, 0x86, 0x87, 0x83, 0xBF, 0x2F,
1322  		0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
1323  		0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C,
1324  		0x47, 0xAE, 0xBB, 0x6F, 0xB7, 0x1E, 0x91, 0x38,
1325  		0x64, 0x09
1326  	};
1327  
1328  	unsigned char tmp[60 + sizeof bp];
1329  	uint32_t p[20], x[20], y[20], z[20], uu[60], p0i;
1330  	int i;
1331  	long num;
1332  
1333  	br_i31_decode(p, bp, sizeof bp);
1334  	p0i = br_i31_ninv31(p[1]);
1335  	memset(tmp, 'T', sizeof tmp);
1336  	br_i31_decode_reduce(x, tmp, sizeof tmp, p);
1337  	memset(tmp, 'U', sizeof tmp);
1338  	br_i31_decode_reduce(y, tmp, sizeof tmp, p);
1339  
1340  	for (i = 0; i < 10; i ++) {
1341  		br_i31_to_monty(x, p);
1342  	}
1343  	num = 10;
1344  	for (;;) {
1345  		clock_t begin, end;
1346  		double tt;
1347  		long k;
1348  
1349  		begin = clock();
1350  		for (k = num; k > 0; k --) {
1351  			br_i31_to_monty(x, p);
1352  		}
1353  		end = clock();
1354  		tt = (double)(end - begin) / CLOCKS_PER_SEC;
1355  		if (tt >= 2.0) {
1356  			printf("%-30s %8.2f ops/s\n", "i31 to_monty",
1357  				(double)num / tt);
1358  			fflush(stdout);
1359  			break;
1360  		}
1361  		num <<= 1;
1362  	}
1363  
1364  	for (i = 0; i < 10; i ++) {
1365  		br_i31_from_monty(x, p, p0i);
1366  	}
1367  	num = 10;
1368  	for (;;) {
1369  		clock_t begin, end;
1370  		double tt;
1371  		long k;
1372  
1373  		begin = clock();
1374  		for (k = num; k > 0; k --) {
1375  			br_i31_from_monty(x, p, p0i);
1376  		}
1377  		end = clock();
1378  		tt = (double)(end - begin) / CLOCKS_PER_SEC;
1379  		if (tt >= 2.0) {
1380  			printf("%-30s %8.2f ops/s\n", "i31 from_monty",
1381  				(double)num / tt);
1382  			fflush(stdout);
1383  			break;
1384  		}
1385  		num <<= 1;
1386  	}
1387  
1388  	for (i = 0; i < 10; i ++) {
1389  		br_i31_montymul(z, x, y, p, p0i);
1390  	}
1391  	num = 10;
1392  	for (;;) {
1393  		clock_t begin, end;
1394  		double tt;
1395  		long k;
1396  
1397  		begin = clock();
1398  		for (k = num; k > 0; k --) {
1399  			br_i31_montymul(z, x, y, p, p0i);
1400  		}
1401  		end = clock();
1402  		tt = (double)(end - begin) / CLOCKS_PER_SEC;
1403  		if (tt >= 2.0) {
1404  			printf("%-30s %8.2f ops/s\n", "i31 montymul",
1405  				(double)num / tt);
1406  			fflush(stdout);
1407  			break;
1408  		}
1409  		num <<= 1;
1410  	}
1411  
1412  	for (i = 0; i < 10; i ++) {
1413  		br_i31_moddiv(x, y, p, p0i, uu);
1414  	}
1415  	num = 10;
1416  	for (;;) {
1417  		clock_t begin, end;
1418  		double tt;
1419  		long k;
1420  
1421  		begin = clock();
1422  		for (k = num; k > 0; k --) {
1423  			br_i31_moddiv(x, y, p, p0i, uu);
1424  		}
1425  		end = clock();
1426  		tt = (double)(end - begin) / CLOCKS_PER_SEC;
1427  		if (tt >= 2.0) {
1428  			printf("%-30s %8.2f ops/s\n", "i31 moddiv",
1429  				(double)num / tt);
1430  			fflush(stdout);
1431  			break;
1432  		}
1433  		num <<= 1;
1434  	}
1435  }
1436  
1437  #if 0
1438  
1439  static unsigned char P2048[] = {
1440  	0xFD, 0xB6, 0xE0, 0x3E, 0x00, 0x49, 0x4C, 0xF0, 0x69, 0x3A, 0xDD, 0x7D,
1441  	0xF8, 0xA2, 0x41, 0xB0, 0x6C, 0x67, 0xC5, 0xBA, 0xB8, 0x46, 0x80, 0xF5,
1442  	0xBF, 0xAB, 0x98, 0xFC, 0x84, 0x73, 0xA5, 0x63, 0xC9, 0x52, 0x12, 0xDA,
1443  	0x4C, 0xC1, 0x5B, 0x9D, 0x8D, 0xDF, 0xCD, 0xFE, 0xC5, 0xAD, 0x5A, 0x6F,
1444  	0xDD, 0x02, 0xD9, 0xEC, 0x71, 0xEF, 0xEB, 0xB6, 0x95, 0xED, 0x94, 0x25,
1445  	0x0E, 0x63, 0xDD, 0x6A, 0x52, 0xC7, 0x93, 0xAF, 0x85, 0x9D, 0x2C, 0xBE,
1446  	0x5C, 0xBE, 0x35, 0xD8, 0xDD, 0x39, 0xEF, 0x1B, 0xB1, 0x49, 0x67, 0xB2,
1447  	0x33, 0xC9, 0x7C, 0xE1, 0x51, 0x79, 0x51, 0x59, 0xCA, 0x6E, 0x2A, 0xDF,
1448  	0x0D, 0x76, 0x1C, 0xE7, 0xA5, 0xC0, 0x1E, 0x6C, 0x56, 0x3A, 0x32, 0xE5,
1449  	0xB5, 0xC5, 0xD4, 0xDB, 0xFE, 0xFF, 0xF8, 0xF2, 0x96, 0xA9, 0xC9, 0x65,
1450  	0x59, 0x9E, 0x01, 0x79, 0x9D, 0x38, 0x68, 0x0F, 0xAD, 0x43, 0x3A, 0xD6,
1451  	0x84, 0x0A, 0xE2, 0xEF, 0x96, 0xC1, 0x6D, 0x89, 0x74, 0x19, 0x63, 0x82,
1452  	0x3B, 0xA0, 0x9C, 0xBA, 0x78, 0xDE, 0xDC, 0xC2, 0xE7, 0xD4, 0xFA, 0xD6,
1453  	0x19, 0x21, 0x29, 0xAE, 0x5E, 0xF4, 0x38, 0x81, 0xC6, 0x9E, 0x0E, 0x3C,
1454  	0xCD, 0xC0, 0xDC, 0x93, 0x5D, 0xFD, 0x9A, 0x5C, 0xAB, 0x54, 0x1F, 0xFF,
1455  	0x9C, 0x12, 0x1B, 0x4C, 0xDF, 0x2D, 0x9C, 0x85, 0xF9, 0x68, 0x15, 0x89,
1456  	0x42, 0x9B, 0x6C, 0x45, 0x89, 0x3A, 0xBC, 0xE9, 0x19, 0x91, 0xBE, 0x0C,
1457  	0xEF, 0x90, 0xCC, 0xF6, 0xD6, 0xF0, 0x3D, 0x5C, 0xF5, 0xE5, 0x0F, 0x2F,
1458  	0x02, 0x8A, 0x83, 0x4B, 0x93, 0x2F, 0x14, 0x12, 0x1F, 0x56, 0x9A, 0x12,
1459  	0x58, 0x88, 0xAE, 0x60, 0xB8, 0x5A, 0xE4, 0xA1, 0xBF, 0x4A, 0x81, 0x84,
1460  	0xAB, 0xBB, 0xE4, 0xD0, 0x1D, 0x41, 0xD9, 0x0A, 0xAB, 0x1E, 0x47, 0x5B,
1461  	0x31, 0xAC, 0x2B, 0x73
1462  };
1463  
1464  static unsigned char G2048[] = {
1465  	0x02
1466  };
1467  
1468  static void
1469  test_speed_modpow(void)
1470  {
1471  	uint32_t mx[65], mp[65], me[65], t1[65], t2[65], len;
1472  	unsigned char e[64];
1473  	int i;
1474  	long num;
1475  
1476  	len = br_int_decode(mp, sizeof mp / sizeof mp[0],
1477  		P2048, sizeof P2048);
1478  	if (len != 65) {
1479  		abort();
1480  	}
1481  	memset(e, 'P', sizeof e);
1482  	if (!br_int_decode(me, sizeof me / sizeof me[0], e, sizeof e)) {
1483  		abort();
1484  	}
1485  	if (!br_modint_decode(mx, mp, G2048, sizeof G2048)) {
1486  		abort();
1487  	}
1488  	for (i = 0; i < 10; i ++) {
1489  		br_modint_to_monty(mx, mp);
1490  		br_modint_montypow(mx, me, mp, t1, t2);
1491  		br_modint_from_monty(mx, mp);
1492  	}
1493  	num = 10;
1494  	for (;;) {
1495  		clock_t begin, end;
1496  		double tt;
1497  		long k;
1498  
1499  		begin = clock();
1500  		for (k = num; k > 0; k --) {
1501  			br_modint_to_monty(mx, mp);
1502  			br_modint_montypow(mx, me, mp, t1, t2);
1503  			br_modint_from_monty(mx, mp);
1504  		}
1505  		end = clock();
1506  		tt = (double)(end - begin) / CLOCKS_PER_SEC;
1507  		if (tt >= 2.0) {
1508  			printf("%-30s %8.2f exp/s\n", "pow[2048:256]",
1509  				(double)num / tt);
1510  			fflush(stdout);
1511  			return;
1512  		}
1513  		num <<= 1;
1514  	}
1515  }
1516  
1517  static void
1518  test_speed_moddiv(void)
1519  {
1520  	uint32_t mx[65], my[65], mp[65], t1[65], t2[65], t3[65], len;
1521  	unsigned char x[255], y[255];
1522  	int i;
1523  	long num;
1524  
1525  	len = br_int_decode(mp, sizeof mp / sizeof mp[0],
1526  		P2048, sizeof P2048);
1527  	if (len != 65) {
1528  		abort();
1529  	}
1530  	memset(x, 'T', sizeof x);
1531  	memset(y, 'P', sizeof y);
1532  	if (!br_modint_decode(mx, mp, x, sizeof x)) {
1533  		abort();
1534  	}
1535  	if (!br_modint_decode(my, mp, y, sizeof y)) {
1536  		abort();
1537  	}
1538  	for (i = 0; i < 10; i ++) {
1539  		br_modint_div(mx, my, mp, t1, t2, t3);
1540  	}
1541  	num = 10;
1542  	for (;;) {
1543  		clock_t begin, end;
1544  		double tt;
1545  		long k;
1546  
1547  		begin = clock();
1548  		for (k = num; k > 0; k --) {
1549  			br_modint_div(mx, my, mp, t1, t2, t3);
1550  		}
1551  		end = clock();
1552  		tt = (double)(end - begin) / CLOCKS_PER_SEC;
1553  		if (tt >= 2.0) {
1554  			printf("%-30s %8.2f div/s\n", "div[2048]",
1555  				(double)num / tt);
1556  			fflush(stdout);
1557  			return;
1558  		}
1559  		num <<= 1;
1560  	}
1561  }
1562  #endif
1563  
1564  #define STU(x)   { test_speed_ ## x, #x }
1565  
1566  static const struct {
1567  	void (*fn)(void);
1568  	char *name;
1569  } tfns[] = {
1570  	STU(md5),
1571  	STU(sha1),
1572  	STU(sha256),
1573  	STU(sha512),
1574  
1575  	STU(aes128_big_cbcenc),
1576  	STU(aes128_big_cbcdec),
1577  	STU(aes192_big_cbcenc),
1578  	STU(aes192_big_cbcdec),
1579  	STU(aes256_big_cbcenc),
1580  	STU(aes256_big_cbcdec),
1581  	STU(aes128_big_ctr),
1582  	STU(aes192_big_ctr),
1583  	STU(aes256_big_ctr),
1584  
1585  	STU(aes128_small_cbcenc),
1586  	STU(aes128_small_cbcdec),
1587  	STU(aes192_small_cbcenc),
1588  	STU(aes192_small_cbcdec),
1589  	STU(aes256_small_cbcenc),
1590  	STU(aes256_small_cbcdec),
1591  	STU(aes128_small_ctr),
1592  	STU(aes192_small_ctr),
1593  	STU(aes256_small_ctr),
1594  
1595  	STU(aes128_ct_cbcenc),
1596  	STU(aes128_ct_cbcdec),
1597  	STU(aes192_ct_cbcenc),
1598  	STU(aes192_ct_cbcdec),
1599  	STU(aes256_ct_cbcenc),
1600  	STU(aes256_ct_cbcdec),
1601  	STU(aes128_ct_ctr),
1602  	STU(aes192_ct_ctr),
1603  	STU(aes256_ct_ctr),
1604  
1605  	STU(aes128_ct64_cbcenc),
1606  	STU(aes128_ct64_cbcdec),
1607  	STU(aes192_ct64_cbcenc),
1608  	STU(aes192_ct64_cbcdec),
1609  	STU(aes256_ct64_cbcenc),
1610  	STU(aes256_ct64_cbcdec),
1611  	STU(aes128_ct64_ctr),
1612  	STU(aes192_ct64_ctr),
1613  	STU(aes256_ct64_ctr),
1614  
1615  	STU(aes128_x86ni_cbcenc),
1616  	STU(aes128_x86ni_cbcdec),
1617  	STU(aes192_x86ni_cbcenc),
1618  	STU(aes192_x86ni_cbcdec),
1619  	STU(aes256_x86ni_cbcenc),
1620  	STU(aes256_x86ni_cbcdec),
1621  	STU(aes128_x86ni_ctr),
1622  	STU(aes192_x86ni_ctr),
1623  	STU(aes256_x86ni_ctr),
1624  
1625  	STU(aes128_pwr8_cbcenc),
1626  	STU(aes128_pwr8_cbcdec),
1627  	STU(aes192_pwr8_cbcenc),
1628  	STU(aes192_pwr8_cbcdec),
1629  	STU(aes256_pwr8_cbcenc),
1630  	STU(aes256_pwr8_cbcdec),
1631  	STU(aes128_pwr8_ctr),
1632  	STU(aes192_pwr8_ctr),
1633  	STU(aes256_pwr8_ctr),
1634  
1635  	STU(des_tab_cbcenc),
1636  	STU(des_tab_cbcdec),
1637  	STU(3des_tab_cbcenc),
1638  	STU(3des_tab_cbcdec),
1639  
1640  	STU(des_ct_cbcenc),
1641  	STU(des_ct_cbcdec),
1642  	STU(3des_ct_cbcenc),
1643  	STU(3des_ct_cbcdec),
1644  
1645  	STU(chacha20_ct),
1646  	STU(chacha20_sse2),
1647  
1648  	STU(ghash_ctmul),
1649  	STU(ghash_ctmul32),
1650  	STU(ghash_ctmul64),
1651  	STU(ghash_pclmul),
1652  	STU(ghash_pwr8),
1653  
1654  	STU(poly1305_ctmul),
1655  	STU(poly1305_ctmul32),
1656  	STU(poly1305_ctmulq),
1657  	STU(poly1305_i15),
1658  
1659  	STU(eax_aes128_big),
1660  	STU(eax_aes192_big),
1661  	STU(eax_aes256_big),
1662  	STU(eax_aes128_small),
1663  	STU(eax_aes192_small),
1664  	STU(eax_aes256_small),
1665  	STU(eax_aes128_ct),
1666  	STU(eax_aes192_ct),
1667  	STU(eax_aes256_ct),
1668  	STU(eax_aes128_ct64),
1669  	STU(eax_aes192_ct64),
1670  	STU(eax_aes256_ct64),
1671  	STU(eax_aes128_x86ni),
1672  	STU(eax_aes192_x86ni),
1673  	STU(eax_aes256_x86ni),
1674  	STU(eax_aes128_pwr8),
1675  	STU(eax_aes192_pwr8),
1676  	STU(eax_aes256_pwr8),
1677  
1678  	STU(shake128),
1679  	STU(shake256),
1680  
1681  	STU(rsa_i15),
1682  	STU(rsa_i31),
1683  	STU(rsa_i32),
1684  	STU(rsa_i62),
1685  	STU(ec_prime_i15),
1686  	STU(ec_prime_i31),
1687  	STU(ec_p256_m15),
1688  	STU(ec_p256_m31),
1689  	STU(ec_p256_m62),
1690  	STU(ec_p256_m64),
1691  	STU(ec_c25519_i15),
1692  	STU(ec_c25519_i31),
1693  	STU(ec_c25519_m15),
1694  	STU(ec_c25519_m31),
1695  	STU(ec_c25519_m62),
1696  	STU(ec_c25519_m64),
1697  	STU(ecdsa_p256_m15),
1698  	STU(ecdsa_p256_m31),
1699  	STU(ecdsa_p256_m62),
1700  	STU(ecdsa_p256_m64),
1701  	STU(ecdsa_i15),
1702  	STU(ecdsa_i31),
1703  
1704  	STU(i31)
1705  };
1706  
1707  static int
1708  eq_name(const char *s1, const char *s2)
1709  {
1710  	for (;;) {
1711  		int c1, c2;
1712  
1713  		for (;;) {
1714  			c1 = *s1 ++;
1715  			if (c1 >= 'A' && c1 <= 'Z') {
1716  				c1 += 'a' - 'A';
1717  			} else {
1718  				switch (c1) {
1719  				case '-': case '_': case '.': case ' ':
1720  					continue;
1721  				}
1722  			}
1723  			break;
1724  		}
1725  		for (;;) {
1726  			c2 = *s2 ++;
1727  			if (c2 >= 'A' && c2 <= 'Z') {
1728  				c2 += 'a' - 'A';
1729  			} else {
1730  				switch (c2) {
1731  				case '-': case '_': case '.': case ' ':
1732  					continue;
1733  				}
1734  			}
1735  			break;
1736  		}
1737  		if (c1 != c2) {
1738  			return 0;
1739  		}
1740  		if (c1 == 0) {
1741  			return 1;
1742  		}
1743  	}
1744  }
1745  
1746  int
1747  main(int argc, char *argv[])
1748  {
1749  	size_t u;
1750  
1751  	if (argc <= 1) {
1752  		printf("usage: testspeed all | name...\n");
1753  		printf("individual test names:\n");
1754  		for (u = 0; u < (sizeof tfns) / (sizeof tfns[0]); u ++) {
1755  			printf("   %s\n", tfns[u].name);
1756  		}
1757  	} else {
1758  		for (u = 0; u < (sizeof tfns) / (sizeof tfns[0]); u ++) {
1759  			int i;
1760  
1761  			for (i = 1; i < argc; i ++) {
1762  				if (eq_name(argv[i], tfns[u].name)
1763  					|| eq_name(argv[i], "all"))
1764  				{
1765  					tfns[u].fn();
1766  					break;
1767  				}
1768  			}
1769  		}
1770  	}
1771  	return 0;
1772  }