void ssh_busy_wait_usec(const SshUInt64 time_us)
{
  SshTimeMeasure timer;

  timer = ssh_time_measure_allocate();
  ssh_time_measure_start(timer);
  while (ssh_time_measure_stamp(timer,
                                SSH_TIME_GRANULARITY_MICROSECOND) <
         time_us)
    /*NOTHING*/;
  ssh_time_measure_stop(timer);
  ssh_time_measure_free(timer);
}
/* Test to encrypt with the accelerated public key */
void test_acc_public_key(void *context)
{
  SshExternalKeyTestCtx ctx = context;
  SshEKTestOp test_ctx = ssh_xcalloc(1, sizeof(*test_ctx));
  SshPublicKey key;
  unsigned char *data = ctx->big_buf;
  size_t data_len = ctx->big_buf_len;

  key = accelerator_test ? ctx->acc_pub_key : ctx->pub_key;

  test_ctx->op_id = next_op_id++;
  test_ctx->test_ctx = ctx;

  test_ctx->timer = ssh_time_measure_allocate();
  ssh_time_measure_start(test_ctx->timer);
  ctx->accelerated_encrypts_pending++;
  ctx->accelerated_encrypts_left--;
  ssh_public_key_encrypt_async(key,
                               data,
                               data_len,
                               acc_encrypt_done, test_ctx);
  SSH_DEBUG_HEXDUMP(7, ("Encrypting data of len %d:", data_len),
                    data, data_len);

  if (ctx->accelerated_encrypts_left || continuous_test)
    {
      ssh_xregister_timeout(0, timeout_ms * 1000, test_acc_public_key, ctx);
    }
  else
    {
      SSH_DEBUG(2, ("All the encrypts send"));
    }

  SSH_DEBUG(2, ("Encrypts left %d, pending %d",
                ctx->accelerated_encrypts_left,
                ctx->accelerated_encrypts_pending));
}
Exemple #3
0
/* The main test program. */
int main(int argc, char *argv[])
{
  Boolean verbose = FALSE;
  SshDlList t_list;
  SshTimeMeasure ssh_timer;
  double timer_value;
  int i, k, evens, odds;

  /* Initialize the random number generator and timer */
  srand((unsigned int)ssh_time());
  ssh_timer = ssh_time_measure_allocate();

  printf("Running test for SshDlList");

  /* Check for verbose output option */
  if (argc == 2 && !strcmp("-v", argv[1]))
    {
      verbose = TRUE;
      printf(".\n\n");
    }
  else
    printf(", use -v for verbose output.\n");

  /* Initialize the test data */
  test_data = ssh_xmalloc(TEST_NUMBERS * sizeof(TestData));
  for (i=0; i < TEST_NUMBERS; i++)
    test_data[i].number = i;

  t_list = ssh_dllist_allocate();

  /* List addition tests */
  for (i=TEST_NUMBERS/2; i < TEST_NUMBERS; i++)
    if (ssh_dllist_add_item(t_list, (void *)&test_data[i], SSH_DLLIST_END)
        != SSH_DLLIST_OK)
      ssh_fatal("t-dllist: list addition failed. Test failed.");

  if (verbose)
    print_list(t_list);

  for (i=TEST_NUMBERS/2-1; i >= 0; i--)
    if (ssh_dllist_add_item(t_list, (void *)&test_data[i], SSH_DLLIST_BEGIN)
        != SSH_DLLIST_OK)
      ssh_fatal("t-dllist: list addition failed. Test failed.");

  if (verbose)
    print_list(t_list);

  /* List searching tests */
  if (verbose)
    printf("Testing list searching... ");
  ssh_dllist_rewind(t_list);

  i = 5;
  ssh_dllist_fw(t_list, i);
  if (ssh_dllist_current(t_list) != &test_data[i])
    ssh_fatal("t-dllist: problems with ssh_dllist_fw. Test failed.");

  i = 11;
  ssh_dllist_find(t_list, &test_data[i]);
  if (ssh_dllist_current(t_list) != &test_data[i])
    ssh_fatal("t-dllist: problems with ssh_dllist_find. Test failed.");

  if (verbose)
    printf("OK\n");

  /* List clear test */
  if (verbose)
    printf("Clearing the list... ");
  ssh_dllist_clear(t_list);
  if (verbose)
    printf("checking is the list empty... ");
  if (ssh_dllist_is_empty(t_list) != TRUE)
    ssh_fatal("t-dllist: list NOT empty! Test failed.\n");
  else if (verbose)
    printf("OK\n");

  /* ----------------------- performance testing ----------------------- */

  /* list addition */
  evens = odds = 0;
  ssh_time_measure_start(ssh_timer);
  for (k=0; k < ITEMS_TO_ADD_TO_THE_LIST; k++)
    {
      i = (int)((rand() / 256) % TEST_NUMBERS);

      if (i < 0 || i >= TEST_NUMBERS)
        ssh_fatal("t-dllist: random number calculation produced index out "
                  "of range.");

      if (i % 2 == 0)
        evens++;
      else
        odds++;

      ssh_dllist_add_item(t_list, (void *)&test_data[i], SSH_DLLIST_END);
    }
  ssh_time_measure_stop(ssh_timer);
  timer_value = (double)ssh_time_measure_get(ssh_timer,
                                             SSH_TIME_GRANULARITY_SECOND);
  if (verbose)
    printf("%d item additions took %.2f ms. Added %d evens, %d odds.\n",
           ITEMS_TO_ADD_TO_THE_LIST, timer_value * 1000, evens, odds);
  if (evens + odds != ITEMS_TO_ADD_TO_THE_LIST)
    ssh_fatal("t-dllist: evens + odds does not match. Test failed.");

  /* list length calculation */
  ssh_time_measure_reset(ssh_timer);
  ssh_time_measure_start(ssh_timer);
  i = ssh_dllist_length(t_list);
  ssh_time_measure_stop(ssh_timer);
  timer_value = (double)ssh_time_measure_get(ssh_timer,
                                             SSH_TIME_GRANULARITY_SECOND);
  if (verbose)
    printf("Calculating list length took %.2f ms for %d elements.\n",
           timer_value * 1000, i);
  if (i != ITEMS_TO_ADD_TO_THE_LIST)
    ssh_fatal("t-dllist: number of list elements does not match the expected. Test failed.");

  /* list reverse */
  ssh_time_measure_reset(ssh_timer);
  ssh_time_measure_start(ssh_timer);
  reverse_list(t_list);
  ssh_time_measure_stop(ssh_timer);
  timer_value = (double)ssh_time_measure_get(ssh_timer,
                                             SSH_TIME_GRANULARITY_SECOND);
  if (verbose)
    printf("List reverse took %.2f ms (reverse is user implemented).\n", timer_value * 1000);

  /* mapcar test */
  ssh_time_measure_reset(ssh_timer);
  ssh_time_measure_start(ssh_timer);
  ssh_dllist_mapcar(t_list, remove_evens, NULL);
  ssh_time_measure_stop(ssh_timer);
  timer_value = (double)ssh_time_measure_get(ssh_timer,
                                             SSH_TIME_GRANULARITY_SECOND);
  if (verbose)
    printf("Remove evens with mapcar call, it took %.2f ms, elements left: %d\n",
           timer_value * 1000,
           ssh_dllist_length(t_list));
  if (ssh_dllist_length(t_list) != odds)
    ssh_fatal("t-dllist: invalid number of list elements after mapcar. Test failed.");

  if (verbose)
    printf("Freeing everything... ");
  ssh_time_measure_reset(ssh_timer);
  ssh_time_measure_start(ssh_timer);
  ssh_dllist_free(t_list);
  ssh_time_measure_stop(ssh_timer);
  timer_value = (double)ssh_time_measure_get(ssh_timer,
                                             SSH_TIME_GRANULARITY_SECOND);
  ssh_xfree(test_data);
  if (verbose)
    printf("OK, took %.2f ms (list had %d items).\n", timer_value * 1000, odds);

  return 0;
}
void cipher_speed_test(char *cipher_name,
                       char *passphrase,
                       unsigned char *key, size_t key_len,
                       unsigned char *iv, size_t iv_len,
                       Boolean encrypt_mode)
{
  SshCryptoStatus cs;
  SshCipher cipher;
  SshTimeMeasure timer;
  unsigned char *data;
  unsigned char *data_dest;
  size_t block_len, data_len, tot, n;
  int i, len_mul;
  double sec;

  if (!passphrase && !key)
    {
      passphrase = "This is a test key!";
    }
  if (passphrase)
    {
      SSH_DEBUG(5, ("Allocating %s context with passphrase.", cipher_name));
      cs = ssh_cipher_allocate_with_passphrase(cipher_name,
                                               passphrase,
                                               encrypt_mode,
                                               &cipher);
    }
  else
    {
      SSH_DEBUG(5, ("Allocating %s context with key vector.", cipher_name));
      cs = ssh_cipher_allocate(cipher_name,
                               key,
                               key_len,
                               encrypt_mode,
                               &cipher);
    }
  if (cs != SSH_CRYPTO_OK)
    {
      switch (cs)
        {
        case SSH_CRYPTO_UNSUPPORTED:
          fprintf(stderr, "%s: Unsupported cipher \"%s\".\n", 
                  av0, cipher_name);
          exit(-1);
        case SSH_CRYPTO_KEY_TOO_SHORT:
          fprintf(stderr, "%s: Key too short for \"%s\".\n", av0, cipher_name);
          exit(-1);
        default:
          fprintf(stderr, "%s: Cipher allocate failed.\n", av0);
          exit(-1);
        }
      /*NOTREACHED*/
    }
  if (iv != NULL)
    {
      if (ssh_cipher_get_iv_length(ssh_cipher_name(cipher)) == iv_len)
        ssh_cipher_set_iv(cipher, iv);
      else
        {
          fprintf(stderr, "%s: Weird IV length.\n", av0);
          exit(1);
        }
    }
  block_len = ssh_cipher_get_block_length(ssh_cipher_name(cipher));
  data_len = CIPHER_TEST_DATA_LEN;
  while (data_len % block_len != 0)
    {
      SSH_DEBUG(5, ("Growing test data len to match with cipher block size."));
      data_len++;
    }
  data = ssh_xmalloc(data_len);
  data_dest = ssh_xmalloc(data_len);
  for (i = 0; i < data_len; i++)
    data[i] = (unsigned char)(i % 0x100);
  tot = data_len * 2;
  timer = ssh_time_measure_allocate();
 timer_retry:
  n = tot;
  ssh_time_measure_reset(timer);
  ssh_time_measure_start(timer);
  while (n > 0)
    {
      if (n > CIPHER_TEST_DATA_LEN)
        {
          cs = ssh_cipher_transform(cipher,
                                    data_dest,
                                    data,
                                    CIPHER_TEST_DATA_LEN);
          n -= CIPHER_TEST_DATA_LEN;
        }
      else
        {
          cs = ssh_cipher_transform(cipher,
                                    data_dest,
                                    data,
                                    n);
          n = 0;
        }
      if (cs != SSH_CRYPTO_OK)
          ssh_fatal("%s: ssh_cipher_transform failed (%d).", av0, (int)cs);

    }
  ssh_time_measure_stop(timer);
  sec = (double)ssh_time_measure_get(timer, SSH_TIME_GRANULARITY_SECOND);

  if (sec < CIPHER_TEST_MIN_TIME)
    {
      if (sec < 0.1)
        {
          /* This doesn't directly aim to sufficient length.
             Let's retry with 10 times longer data to get
             hash code into the cache for the `real test'. */
          len_mul = 10;
        }
      else
        {
          /* Let's try to heuristically adjust the next test
             loop so that it takes about CIPHER_TEST_MIN_TIME
             seconds to complete. */
          len_mul = (int)((CIPHER_TEST_MIN_TIME + 1.0) / sec) + 1;
        }
      SSH_DEBUG(5, ("Test completes too fast (%.2f sec).", sec));
      SSH_DEBUG(5, ("Multiply test len by %d.", len_mul));
      tot *= len_mul;
      goto timer_retry;
    }
  else
    {
      SSH_DEBUG(5, ("Test completes OK (%.2f sec).", sec));
    }
  printf("Speed[\"%s\"] = %.2f kB (%.2f megabits) / sec\n",
         cipher_name,
         ((((double)tot) / 1024.0) / sec),
         ((((double)tot) / 131072.0) / sec));
  ssh_time_measure_free(timer);
  ssh_cipher_free(cipher);
  ssh_xfree(data);
  ssh_xfree(data_dest);
  return;
}
int main(int argc, char **argv)
{
  SshExternalKeyTestCtx test_ctx;
  int i;
  SshPrivateKey prv_key;
  SshPublicKey pub_key;
  SshMPInteger n;

  parse_arguments(argc, argv);

  ssh_pk_provider_register(&ssh_pk_if_modn_generator);
  /* Initialize the event loop and the test context. */
  ssh_event_loop_initialize();
  ssh_debug_set_level_string(debug_level_string);

  ssh_global_init();
  /* Initialize the crypto library. */
  if (ssh_crypto_library_initialize() != SSH_CRYPTO_OK)
    ssh_fatal("Cannot initialize the crypto library");

  test_ctx = ssh_xcalloc(1, sizeof(*test_ctx));
  test_ctx->accelerated_encrypts_left = default_accelerated_encrypts;
  test_ctx->timer = ssh_time_measure_allocate();

  SSH_DEBUG(3, ("Reading the test key. Please wait...."));

  prv_key = get_prv_key("accelerator-test.prv");

  if (ssh_private_key_select_scheme(prv_key,
                                    SSH_PKF_ENCRYPT, "rsa-none-none",
                                    SSH_PKF_END) != SSH_CRYPTO_OK)
    ssh_fatal("Could not select the scheme for private key");



  if (ssh_private_key_derive_public_key(prv_key, &pub_key)
      != SSH_CRYPTO_OK)
    {
      ssh_fatal("Can not derive a public key from a "
                "stored private key");
    }

  if (ssh_public_key_select_scheme(pub_key,
                                   SSH_PKF_ENCRYPT, "rsa-none-none",
                                   SSH_PKF_END) != SSH_CRYPTO_OK)
    ssh_fatal("Could not select the scheme for public key");



  n = ssh_mprz_malloc();

  /* Get information about the RSA key. E and N are needed for nFast. */
  if (ssh_public_key_get_info(pub_key,
                              SSH_PKF_MODULO_N, n,
                              SSH_PKF_END)
      != SSH_CRYPTO_OK)
    {
      return FALSE;
    }


#if 0
  n_bytes = (ssh_mprz_get_size(n, 2) + 7) / 8;
  if (n_bytes == 0 || (n_bytes & 3) != 0)
    n_bytes += (4 - (n_bytes & 3));

  test_ctx->big_buf = ssh_xmalloc(n_bytes);
  test_ctx->big_buf_len = n_bytes;

  ssh_mprz_get_buf(test_ctx->big_buf, test_ctx->big_buf_len, n);
  ssh_mprz_free(n);
  test_ctx->big_buf_len = 128;
  test_ctx->big_buf[0] = 1;
#else
#if 0
  n_bytes = ssh_mprz_get_size(n, 8);
  test_ctx->big_buf = ssh_xmalloc(n_bytes);
  test_ctx->big_buf_len = n_bytes;
  ssh_mprz_init(&r);
  ssh_mprz_rand(&r, n_bytes * 8);
  ssh_mprz_mod(&r, &r, n);
  ssh_mprz_get_buf(test_ctx->big_buf, test_ctx->big_buf_len, &r);
  ssh_mprz_free(n);
  ssh_mprz_clear(&r);
#else
  test_ctx->big_buf = ssh_xmalloc(129);
  test_ctx->big_buf_len = 129;
  memcpy(test_ctx->big_buf,
         "\x00\x50\xe7\x85\x86\x40\xf8\x9b"
         "\xb8\xeb\x19\x64\xd8\x51\x33\xd7"
         "\x4f\xac\x32\x5d\x03\x66\x3d\x0c"
         "\xbe\xfd\x40\x29\x82\xb7\x61\x09"
         "\x15\x37\x4f\xe1\xd0\x57\xb0\x6d"
         "\x16\x49\x73\x25\x20\x3d\xa8\xfa"
         "\xf6\xb4\x72\xec\x75\xc8\x42\xc7"
         "\x99\x64\x63\x23\x29\xe0\x65\xa1"
         "\x2a\xc2\xb7\xf1\x5b\xb4\x9b\x30"
         "\xdb\xc7\x22\xb9\xf9\xde\xb5\x09"
         "\xb5\xe0\x0a\xca\xc5\xf9\xaf\x8f"
         "\x54\xf2\x9a\x06\x2b\xc1\xc2\x65"
         "\x87\xb3\xd5\xec\xd3\x8a\x2f\xa7"
         "\x5f\x69\x34\xe7\x7f\xeb\xaf\x56"
         "\x3c\x3d\x71\x3f\x73\xba\x8b\xa7"
         "\xd3\xe5\x6d\x98\xc8\x01\x6b\x18"
         "\x14",
         129);
#endif
#endif

  test_ctx->pub_key = pub_key;
  test_ctx->prv_key = prv_key;

  test_ek_add(test_ctx);
#ifndef WIN32
  ssh_register_signal(SIGUSR1, test_signal_handler, test_ctx);
#endif
  ssh_event_loop_run();

  /* Uninitialize. */
  for (i = 0; i < test_ctx->num_prv_keys; i++)
    ssh_private_key_free(test_ctx->prv_keys[i]);

  for (i = 0; i < test_ctx->num_pub_keys; i++)
    ssh_public_key_free(test_ctx->pub_keys[i]);


  ssh_xfree(test_ctx->prv_keys);
  ssh_xfree(test_ctx->pub_keys);
  ssh_xfree(test_ctx);
  return 0;
}
Exemple #6
0
int main()
{
  SshTimeMeasure total_timer;
  SshTimeMeasure timer_1;
  SshTimeMeasure timer_2;
  SshTimeMeasure timer_3;
  SshTimeMeasure timer_4;
  SshTimeMeasure timer_5;
  static struct SshTimeMeasureRec timer_6_rec = SSH_TIME_MEASURE_INITIALIZER;
  SshTimeMeasure timer_6;
  int i;
  double rv = 0.0;
  int ev = 0;
#ifdef HAVE_GETTIMEOFDAY      
  struct timeval tv;
#endif /* HAVE_GETTIMEOFDAY */
  SshUInt64 seconds;
  SshUInt32 nanoseconds;

  total_timer = ssh_time_measure_allocate();
  timer_1 = ssh_time_measure_allocate();
  timer_2 = ssh_time_measure_allocate();
  timer_3 = ssh_time_measure_allocate();
  timer_4 = ssh_time_measure_allocate();
  timer_5 = ssh_time_measure_allocate();
  timer_6 = &timer_6_rec;

  if (ssh_time_measure_get(timer_5, SSH_TIME_GRANULARITY_NANOSECOND) != 0)
    {
      ssh_warning("Weird initial stamp value.\n");
      ev++;
    }
  if (ssh_time_measure_get(timer_6, SSH_TIME_GRANULARITY_NANOSECOND) != 0)
    {
      ssh_warning("Weird initial (static) stamp value.\n");
      ev++;
    }
  rv = (double)ssh_time_measure_get(total_timer, SSH_TIME_GRANULARITY_SECOND); 
  if ((rv < 0.0) || (rv > 0.0))
    {
      ssh_warning("Weird initial value.\n");
      ev++;
    }

  ssh_time_measure_granularity(&seconds, &nanoseconds);
  if ((seconds == 0) && (nanoseconds == 0))
    {
      ssh_warning("Weird granularity.\n");
      ev++;
    }
  else
    {
      printf("granularity is %lu sec %lu nsec\n", 
             (unsigned long)seconds,
             (unsigned long)nanoseconds);
    }

  START(total_timer);
  START(timer_1);
  START(timer_3);
  START(timer_4);
  START(timer_5);

  STAMP(total_timer);

  printf("testing stamps\n");
  NANOSTAMP(timer_1);
  MICROSTAMP(timer_1);
  MILLISTAMP(timer_1);
  STAMP(timer_1);
  USLEEP(1000000);
  NANOSTAMP(timer_1);
  MICROSTAMP(timer_1);
  MILLISTAMP(timer_1);
  STAMP(timer_1);
  USLEEP(1000000);
  NANOSTAMP(timer_1);
  MICROSTAMP(timer_1);
  MILLISTAMP(timer_1);
  STAMP(timer_1);
  USLEEP(1000000);
  NANOSTAMP(timer_1);
  MICROSTAMP(timer_1);
  MILLISTAMP(timer_1);
  STAMP(timer_1);
  CHECKNANOSTAMP(timer_1);
  USLEEP(1000000);
  NANOSTAMP(timer_1);
  MICROSTAMP(timer_1);
  MILLISTAMP(timer_1);
  STAMP(timer_1);
  CHECKNANOSTAMP(timer_1);
  USLEEP(1000000);
  NANOSTAMP(timer_1);
  MICROSTAMP(timer_1);
  MILLISTAMP(timer_1);
  STAMP(timer_1);
  CHECKNANOSTAMP(timer_1);
  USLEEP(1000000);
  NANOSTAMP(timer_1);
  MICROSTAMP(timer_1);
  MILLISTAMP(timer_1);
  STAMP(timer_1);
  CHECKNANOSTAMP(timer_1);
  
  USLEEP(2000000);
  STAMP(total_timer);

  SET(timer_5, 12345, 12345678);
  INTERMEDIATE(timer_5);
  if ((rv < 12345.0) || (rv > 12350.0))
    {
      ssh_warning("Weird intermediate after running set.\n");
      ev++;
    }

  INTERMEDIATE(timer_1);
  if (rv < 1.0)
    {
      ssh_warning("Weird intermediate.\n");
      ev++;
    }
  STOP(timer_3);
  if (rv < 1.0)
    {
      ssh_warning("Weird stop value.\n");
      ev++;
    }
  START(timer_2);
  RESET(timer_4);

  USLEEP(3000000);
  STAMP(total_timer);

  INTERMEDIATE(timer_2);
  INTERMEDIATE(timer_5);
  START(timer_3);
  if (rv < 1.0)
    {
      ssh_warning("Weird restart value.\n");
      ev++;
    }
  RESET(timer_4);
  STOP(timer_1);


  USLEEP(4000000);
  STAMP(total_timer);


  STOP(timer_5);

#ifdef SSHUINT64_IS_64BITS
  printf("Setting timer_5 to big value.\n");
  ssh_time_measure_set_value(timer_5, 
                             ((SshUInt64)0xffffffff) * ((SshUInt64)30), 
                             987654321);
  INTERMEDIATE(timer_5);
  if ((rv < 128849018000.0) || (rv > 128849019000.0))
    {
      ssh_warning("Weird intermediate after stopped set.\n");
      ev++;
    }
#else
  SET(timer_5, 1234567890, 987654321);
  INTERMEDIATE(timer_5);
  if ((rv < 1234567890.0) || (rv > 1234567900.0))
    {
      ssh_warning("Weird intermediate after stopped set.\n");
      ev++;
    }
#endif

  STOP(timer_4);
  STOP(timer_3);
  STOP(timer_2);
  STOP(timer_1);

#define TIMESTAMPS 1000000

  ssh_time_measure_reset(timer_1);
  ssh_time_measure_reset(timer_2);
  printf("\nGenerating %d timestamps.\n", TIMESTAMPS);
  START(timer_2);
  START(timer_1);
  for (i = 1; i < TIMESTAMPS; i++)
    {
      ssh_time_measure_stamp(timer_2, SSH_TIME_GRANULARITY_MICROSECOND);
    }
  STOP(timer_1);
  STOP(timer_2);
  printf("Time elapsed %.12f seconds (%.12f seconds/timestamp", 
         (double)ssh_time_measure_get(timer_1, SSH_TIME_GRANULARITY_SECOND),
         (double)ssh_time_measure_get(timer_1, SSH_TIME_GRANULARITY_SECOND) / (double)TIMESTAMPS);
  if ((double)ssh_time_measure_get(timer_1, SSH_TIME_GRANULARITY_SECOND) > 0.0)
    printf(", %d timestamps/second",
           (int)((double)TIMESTAMPS / (double)ssh_time_measure_get(timer_1, SSH_TIME_GRANULARITY_SECOND)));
  printf(")\n");

  ssh_time_measure_reset(timer_3);
  ssh_time_measure_reset(timer_4);
  printf("\nFor reference generating %d timestamps with time(3).\n", 
         TIMESTAMPS);
  START(timer_4);
  START(timer_3);
  for (i = 1; i < TIMESTAMPS; i++)
    {
      ssh_time();
    }
  STOP(timer_3);
  STOP(timer_4);
  printf("Time elapsed %.12f seconds (%.12f seconds/timestamp", 
         (double)ssh_time_measure_get(timer_3, SSH_TIME_GRANULARITY_SECOND),
         (double)ssh_time_measure_get(timer_3, SSH_TIME_GRANULARITY_SECOND) / (double)TIMESTAMPS);
  if ((double)ssh_time_measure_get(timer_3, SSH_TIME_GRANULARITY_SECOND) > 0.0)
    printf(", %d timestamps/second",
           (int)((double)TIMESTAMPS / (double)ssh_time_measure_get(timer_3, SSH_TIME_GRANULARITY_SECOND)));
  printf(")\n");

  if (((double)ssh_time_measure_get(timer_1, SSH_TIME_GRANULARITY_SECOND) > 0.0) &&
      ((double)ssh_time_measure_get(timer_3, SSH_TIME_GRANULARITY_SECOND) > 0.0))
    printf("Using time(3) is %2.1f%% faster than ssh_..._stamp.\n", 
           (((double)ssh_time_measure_get(timer_1, SSH_TIME_GRANULARITY_SECOND) - 
             (double)ssh_time_measure_get(timer_3, SSH_TIME_GRANULARITY_SECOND)) /
            (double)ssh_time_measure_get(timer_1, SSH_TIME_GRANULARITY_SECOND)) * 100.0);

#ifdef HAVE_GETTIMEOFDAY
  ssh_time_measure_reset(timer_3);
  ssh_time_measure_reset(timer_4);
  printf("\nFor reference generating %d timestamps with gettimeofday.\n", 
         TIMESTAMPS);
  START(timer_4);
  START(timer_3);
  for (i = 1; i < TIMESTAMPS; i++)
    {
      gettimeofday(&tv, NULL);
    }
  STOP(timer_3);
  STOP(timer_4);
  printf("Time elapsed %.12f seconds (%.12f seconds/timestamp", 
         (double)ssh_time_measure_get(timer_3, SSH_TIME_GRANULARITY_SECOND),
         (double)ssh_time_measure_get(timer_3, SSH_TIME_GRANULARITY_SECOND) / (double)TIMESTAMPS);
  if ((double)ssh_time_measure_get(timer_3, SSH_TIME_GRANULARITY_SECOND) > 0.0)
    printf(", %d timestamps/second",
           (int)((double)TIMESTAMPS / (double)ssh_time_measure_get(timer_3, SSH_TIME_GRANULARITY_SECOND)));
  printf(")\n");

  if (((double)ssh_time_measure_get(timer_1, SSH_TIME_GRANULARITY_SECOND) > 0.0) &&
      ((double)ssh_time_measure_get(timer_3, SSH_TIME_GRANULARITY_SECOND) > 0.0))
    printf("Using gettimeofday(3) is %2.1f%% faster than ssh_..._stamp.\n", 
           (((double)ssh_time_measure_get(timer_1, SSH_TIME_GRANULARITY_SECOND) - 
             (double)ssh_time_measure_get(timer_3, SSH_TIME_GRANULARITY_SECOND)) /
            (double)ssh_time_measure_get(timer_1, SSH_TIME_GRANULARITY_SECOND)) * 100.0);
#endif /* HAVE_GETTIMEOFDAY */

  printf("making start stop test. timers are silently started and stopped.\n");
  printf("timer_3 runs while timer_4 is started and stopped in loop.\n");
  ssh_time_measure_stop(timer_3);
  ssh_time_measure_stop(timer_4);
  ssh_time_measure_reset(timer_3);
  ssh_time_measure_reset(timer_4);
  ssh_time_measure_start(timer_3);
  for (i = 0; i < 1000000; i++)
    {
      ssh_time_measure_start(timer_4);
      ssh_time_measure_stop(timer_4);
    }
  ssh_time_measure_stop(timer_3);
  INTERMEDIATE(timer_4);
  INTERMEDIATE(timer_3);
  

  STOP(total_timer);
  GET_INT(timer_1);
  INTERMEDIATE(timer_1);
  GET_INT(timer_2);
  INTERMEDIATE(timer_2);
  GET_INT(timer_3);
  INTERMEDIATE(timer_3);
  GET_INT(timer_4);
  INTERMEDIATE(timer_4);
  GET_INT(timer_5);
  INTERMEDIATE(timer_5);
  GET_INT(total_timer);
  INTERMEDIATE(total_timer);
  printf("Testing granularities\n");
  GET_NANOSECONDS(total_timer);
  GET_MICROSECONDS(total_timer);
  GET_MILLISECONDS(total_timer);
  GET_SECONDS(total_timer);
  GET_MINUTES(total_timer);
  GET_HOURS(total_timer);
  GET_DAYS(total_timer);
  GET_WEEKS(total_timer);
  GET_MONTHS(total_timer);
  GET_YEARS(total_timer);
  GET_NANOSECONDS(timer_5);
  GET_MICROSECONDS(timer_5);
  GET_MILLISECONDS(timer_5);
  GET_SECONDS(timer_5);
  GET_MINUTES(timer_5);
  GET_HOURS(timer_5);
  GET_DAYS(timer_5);
  GET_WEEKS(timer_5);
  GET_MONTHS(timer_5);
  GET_MONTHS_2(timer_5);
  GET_YEARS(timer_5);
  GET_YEARS_2(timer_5);
  GET_YEARS_3(timer_5);

  ssh_time_measure_free(timer_5);
  ssh_time_measure_free(timer_4);
  ssh_time_measure_free(timer_3);
  ssh_time_measure_free(timer_2);
  ssh_time_measure_free(timer_1);
  ssh_time_measure_free(total_timer);

  exit(ev);
}