root/usr.bin/openssl/speed.c
/* $OpenBSD: speed.c,v 1.52 2026/03/19 20:28:46 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */
/* ====================================================================
 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
 *
 * Portions of the attached software ("Contribution") are developed by
 * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
 *
 * The Contribution is licensed pursuant to the OpenSSL open source
 * license provided above.
 *
 * The ECDH and ECDSA speed test software is originally written by
 * Sumit Gupta of Sun Microsystems Laboratories.
 *
 */

/* most of this code has been pilfered from my libdes speed.c program */

#ifndef OPENSSL_NO_SPEED

#define SECONDS         3
#define RSA_SECONDS     10
#define DSA_SECONDS     10
#define ECDSA_SECONDS   10
#define ECDH_SECONDS    10
#define MLKEM_SECONDS   10

#define MAX_UNALIGN     16

#include <math.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <unistd.h>

#include "apps.h"

#include <openssl/bn.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/mlkem.h>
#include <openssl/modes.h>
#include <openssl/objects.h>
#include <openssl/x509.h>

#ifndef OPENSSL_NO_AES
#include <openssl/aes.h>
#endif
#ifndef OPENSSL_NO_BF
#include <openssl/blowfish.h>
#endif
#ifndef OPENSSL_NO_CAST
#include <openssl/cast.h>
#endif
#ifndef OPENSSL_NO_CAMELLIA
#include <openssl/camellia.h>
#endif
#ifndef OPENSSL_NO_DES
#include <openssl/des.h>
#endif
#include <openssl/dsa.h>
#include <openssl/ecdh.h>
#include <openssl/ecdsa.h>
#ifndef OPENSSL_NO_HMAC
#include <openssl/hmac.h>
#endif
#ifndef OPENSSL_NO_IDEA
#include <openssl/idea.h>
#endif
#ifndef OPENSSL_NO_MD4
#include <openssl/md4.h>
#endif
#ifndef OPENSSL_NO_MD5
#include <openssl/md5.h>
#endif
#ifndef OPENSSL_NO_RC2
#include <openssl/rc2.h>
#endif
#ifndef OPENSSL_NO_RC4
#include <openssl/rc4.h>
#endif
#include <openssl/rsa.h>
#ifndef OPENSSL_NO_RIPEMD
#include <openssl/ripemd.h>
#endif
#ifndef OPENSSL_NO_SHA
#include <openssl/sha.h>
#endif

#define BUFSIZE (1024*8+64)
volatile sig_atomic_t run;

static int mr = 0;
static int usertime = 1;

static void print_message(const char *s, int length);
static void
pkey_print_message(const char *str, const char *str2,
    int bits, int sec);
static void print_result(int alg, int run_no, int count, double time_used);
static int do_multi(int multi);

#define SIZE_NUM        5
#define MAX_ECDH_SIZE   256

enum {
        D_MD4,
        D_MD5,
        D_HMAC,
        D_SHA1,
        D_RMD160,
        D_RC4,
        D_CBC_DES,
        D_EDE3_DES,
        D_CBC_IDEA,
        D_CBC_RC2,
        D_CBC_BF,
        D_CBC_CAST,
        D_CBC_128_AES,
        D_CBC_192_AES,
        D_CBC_256_AES,
        D_CBC_128_CML,
        D_CBC_192_CML,
        D_CBC_256_CML,
        D_EVP,
        D_SHA256,
        D_SHA512,
        D_IGE_128_AES,
        D_IGE_192_AES,
        D_IGE_256_AES,
        D_GHASH,
        D_AES_128_GCM,
        D_AES_256_GCM,
        D_CHACHA20_POLY1305,
        ALGOR_NUM,
};

enum {
        R_DSA_512,
        R_DSA_1024,
        R_DSA_2048,
        DSA_NUM,
};

enum {
        R_RSA_512,
        R_RSA_1024,
        R_RSA_2048,
        R_RSA_4096,
        RSA_NUM,
};

enum {
        R_EC_P224,
        R_EC_P256,
        R_EC_P384,
        R_EC_P521,
        EC_NUM,
};

enum {
        R_MLKEM_768,
        R_MLKEM_1024,
        MLKEM_NUM,
};

static const char *names[ALGOR_NUM] = {
        "md4", "md5", "hmac(sha256)", "sha1", "rmd160",
        "rc4", "des cbc", "des ede3", "idea cbc",
        "rc2 cbc", "blowfish cbc", "cast cbc",
        "aes-128 cbc", "aes-192 cbc", "aes-256 cbc",
        "camellia-128 cbc", "camellia-192 cbc", "camellia-256 cbc",
        "evp", "sha256", "sha512",
        "aes-128 ige", "aes-192 ige", "aes-256 ige", "ghash",
        "aes-128 gcm", "aes-256 gcm", "chacha20 poly1305",
};
static double results[ALGOR_NUM][SIZE_NUM];
static int lengths[SIZE_NUM] = {16, 64, 256, 1024, 8 * 1024};
static double rsa_results[RSA_NUM][2];
static double dsa_results[DSA_NUM][2];
static double ecdsa_results[EC_NUM][2];
static double ecdh_results[EC_NUM][1];
static double mlkem_results[MLKEM_NUM][3];

struct mlkem_speed_param {
        const char      *name;
        int              bits;
        int              rank;
};

static const struct mlkem_speed_param mlkem_params[MLKEM_NUM] = {
        [R_MLKEM_768]  = { "mlkem768",  768,  MLKEM768_RANK  },
        [R_MLKEM_1024] = { "mlkem1024", 1024, MLKEM1024_RANK },
};

static void sig_done(int sig);

static DSA *
get_dsa(const unsigned char *priv, size_t priv_size,
    const unsigned char *pub, size_t pub_size,
    const unsigned char *p_char, size_t p_size,
    const unsigned char *q_char, size_t q_size,
    const unsigned char *g_char, size_t g_size)
{
        DSA *dsa;
        BIGNUM *priv_key = NULL, *pub_key = NULL;
        BIGNUM *p = NULL, *q = NULL, *g = NULL;

        if ((dsa = DSA_new()) == NULL)
                return (NULL);

        priv_key = BN_bin2bn(priv, priv_size, NULL);
        pub_key = BN_bin2bn(pub, pub_size, NULL);
        if (priv_key == NULL || pub_key == NULL)
                goto err;

        if (!DSA_set0_key(dsa, pub_key, priv_key))
                goto err;
        pub_key = NULL;
        priv_key = NULL;

        p = BN_bin2bn(p_char, p_size, NULL);
        q = BN_bin2bn(q_char, q_size, NULL);
        g = BN_bin2bn(g_char, g_size, NULL);
        if (p == NULL || q == NULL || g == NULL)
                goto err;

        if (!DSA_set0_pqg(dsa, p, q, g))
                goto err;
        p = NULL;
        q = NULL;
        g = NULL;

        return dsa;

 err:
        DSA_free(dsa);
        BN_free(priv_key);
        BN_free(pub_key);
        BN_free(p);
        BN_free(q);
        BN_free(g);

        return NULL;
}


static const unsigned char dsa512_priv[] = {
        0x65, 0xe5, 0xc7, 0x38, 0x60, 0x24, 0xb5, 0x89, 0xd4, 0x9c, 0xeb, 0x4c,
        0x9c, 0x1d, 0x7a, 0x22, 0xbd, 0xd1, 0xc2, 0xd2,
};

static const unsigned char dsa512_pub[] = {
        0x00, 0x95, 0xa7, 0x0d, 0xec, 0x93, 0x68, 0xba, 0x5f, 0xf7, 0x5f, 0x07,
        0xf2, 0x3b, 0xad, 0x6b, 0x01, 0xdc, 0xbe, 0xec, 0xde, 0x04, 0x7a, 0x3a,
        0x27, 0xb3, 0xec, 0x49, 0xfd, 0x08, 0x43, 0x3d, 0x7e, 0xa8, 0x2c, 0x5e,
        0x7b, 0xbb, 0xfc, 0xf4, 0x6e, 0xeb, 0x6c, 0xb0, 0x6e, 0xf8, 0x02, 0x12,
        0x8c, 0x38, 0x5d, 0x83, 0x56, 0x7d, 0xee, 0x53, 0x05, 0x3e, 0x24, 0x84,
        0xbe, 0xba, 0x0a, 0x6b, 0xc8,
};

static const unsigned char dsa512_p[] = {
        0x9D, 0x1B, 0x69, 0x8E, 0x26, 0xDB, 0xF2, 0x2B, 0x11, 0x70, 0x19, 0x86,
        0xF6, 0x19, 0xC8, 0xF8, 0x19, 0xF2, 0x18, 0x53, 0x94, 0x46, 0x06, 0xD0,
        0x62, 0x50, 0x33, 0x4B, 0x02, 0x3C, 0x52, 0x30, 0x03, 0x8B, 0x3B, 0xF9,
        0x5F, 0xD1, 0x24, 0x06, 0x4F, 0x7B, 0x4C, 0xBA, 0xAA, 0x40, 0x9B, 0xFD,
        0x96, 0xE4, 0x37, 0x33, 0xBB, 0x2D, 0x5A, 0xD7, 0x5A, 0x11, 0x40, 0x66,
        0xA2, 0x76, 0x7D, 0x31,
};

static const unsigned char dsa512_q[] = {
        0xFB, 0x53, 0xEF, 0x50, 0xB4, 0x40, 0x92, 0x31, 0x56, 0x86, 0x53, 0x7A,
        0xE8, 0x8B, 0x22, 0x9A, 0x49, 0xFB, 0x71, 0x8F,
};

static const unsigned char dsa512_g[] = {
        0x83, 0x3E, 0x88, 0xE5, 0xC5, 0x89, 0x73, 0xCE, 0x3B, 0x6C, 0x01, 0x49,
        0xBF, 0xB3, 0xC7, 0x9F, 0x0A, 0xEA, 0x44, 0x91, 0xE5, 0x30, 0xAA, 0xD9,
        0xBE, 0x5B, 0x5F, 0xB7, 0x10, 0xD7, 0x89, 0xB7, 0x8E, 0x74, 0xFB, 0xCF,
        0x29, 0x1E, 0xEB, 0xA8, 0x2C, 0x54, 0x51, 0xB8, 0x10, 0xDE, 0xA0, 0xCE,
        0x2F, 0xCC, 0x24, 0x6B, 0x90, 0x77, 0xDE, 0xA2, 0x68, 0xA6, 0x52, 0x12,
        0xA2, 0x03, 0x9D, 0x20,
};

static DSA *
get_dsa512(void)
{
        return get_dsa(dsa512_priv, sizeof(dsa512_priv),
            dsa512_pub, sizeof(dsa512_pub), dsa512_p, sizeof(dsa512_p),
            dsa512_q, sizeof(dsa512_q), dsa512_g, sizeof(dsa512_g));
}

static const unsigned char dsa1024_priv[] = {
        0x7d, 0x21, 0xda, 0xbb, 0x62, 0x15, 0x47, 0x36, 0x07, 0x67, 0x12, 0xe8,
        0x8c, 0xaa, 0x1c, 0xcd, 0x38, 0x12, 0x61, 0x18,
};

static const unsigned char dsa1024_pub[] = {
        0x3c, 0x4e, 0x9c, 0x2a, 0x7f, 0x16, 0xc1, 0x25, 0xeb, 0xac, 0x78, 0x63,
        0x90, 0x14, 0x8c, 0x8b, 0xf4, 0x68, 0x43, 0x3c, 0x2d, 0xee, 0x65, 0x50,
        0x7d, 0x9c, 0x8f, 0x8c, 0x8a, 0x51, 0xd6, 0x11, 0x2b, 0x99, 0xaf, 0x1e,
        0x90, 0x97, 0xb5, 0xd3, 0xa6, 0x20, 0x25, 0xd6, 0xfe, 0x43, 0x02, 0xd5,
        0x91, 0x7d, 0xa7, 0x8c, 0xdb, 0xc9, 0x85, 0xa3, 0x36, 0x48, 0xf7, 0x68,
        0xaa, 0x60, 0xb1, 0xf7, 0x05, 0x68, 0x3a, 0xa3, 0x3f, 0xd3, 0x19, 0x82,
        0xd8, 0x82, 0x7a, 0x77, 0xfb, 0xef, 0xf4, 0x15, 0x0a, 0xeb, 0x06, 0x04,
        0x7f, 0x53, 0x07, 0x0c, 0xbc, 0xcb, 0x2d, 0x83, 0xdb, 0x3e, 0xd1, 0x28,
        0xa5, 0xa1, 0x31, 0xe0, 0x67, 0xfa, 0x50, 0xde, 0x9b, 0x07, 0x83, 0x7e,
        0x2c, 0x0b, 0xc3, 0x13, 0x50, 0x61, 0xe5, 0xad, 0xbd, 0x36, 0xb8, 0x97,
        0x4e, 0x40, 0x7d, 0xe8, 0x83, 0x0d, 0xbc, 0x4b
};

static const unsigned char dsa1024_p[] = {
        0xA7, 0x3F, 0x6E, 0x85, 0xBF, 0x41, 0x6A, 0x29, 0x7D, 0xF0, 0x9F, 0x47,
        0x19, 0x30, 0x90, 0x9A, 0x09, 0x1D, 0xDA, 0x6A, 0x33, 0x1E, 0xC5, 0x3D,
        0x86, 0x96, 0xB3, 0x15, 0xE0, 0x53, 0x2E, 0x8F, 0xE0, 0x59, 0x82, 0x73,
        0x90, 0x3E, 0x75, 0x31, 0x99, 0x47, 0x7A, 0x52, 0xFB, 0x85, 0xE4, 0xD9,
        0xA6, 0x7B, 0x38, 0x9B, 0x68, 0x8A, 0x84, 0x9B, 0x87, 0xC6, 0x1E, 0xB5,
        0x7E, 0x86, 0x4B, 0x53, 0x5B, 0x59, 0xCF, 0x71, 0x65, 0x19, 0x88, 0x6E,
        0xCE, 0x66, 0xAE, 0x6B, 0x88, 0x36, 0xFB, 0xEC, 0x28, 0xDC, 0xC2, 0xD7,
        0xA5, 0xBB, 0xE5, 0x2C, 0x39, 0x26, 0x4B, 0xDA, 0x9A, 0x70, 0x18, 0x95,
        0x37, 0x95, 0x10, 0x56, 0x23, 0xF6, 0x15, 0xED, 0xBA, 0x04, 0x5E, 0xDE,
        0x39, 0x4F, 0xFD, 0xB7, 0x43, 0x1F, 0xB5, 0xA4, 0x65, 0x6F, 0xCD, 0x80,
        0x11, 0xE4, 0x70, 0x95, 0x5B, 0x50, 0xCD, 0x49,
};

static const unsigned char dsa1024_q[] = {
        0xF7, 0x07, 0x31, 0xED, 0xFA, 0x6C, 0x06, 0x03, 0xD5, 0x85, 0x8A, 0x1C,
        0xAC, 0x9C, 0x65, 0xE7, 0x50, 0x66, 0x65, 0x6F,
};

static const unsigned char dsa1024_g[] = {
        0x4D, 0xDF, 0x4C, 0x03, 0xA6, 0x91, 0x8A, 0xF5, 0x19, 0x6F, 0x50, 0x46,
        0x25, 0x99, 0xE5, 0x68, 0x6F, 0x30, 0xE3, 0x69, 0xE1, 0xE5, 0xB3, 0x5D,
        0x98, 0xBB, 0x28, 0x86, 0x48, 0xFC, 0xDE, 0x99, 0x04, 0x3F, 0x5F, 0x88,
        0x0C, 0x9C, 0x73, 0x24, 0x0D, 0x20, 0x5D, 0xB9, 0x2A, 0x9A, 0x3F, 0x18,
        0x96, 0x27, 0xE4, 0x62, 0x87, 0xC1, 0x7B, 0x74, 0x62, 0x53, 0xFC, 0x61,
        0x27, 0xA8, 0x7A, 0x91, 0x09, 0x9D, 0xB6, 0xF1, 0x4D, 0x9C, 0x54, 0x0F,
        0x58, 0x06, 0xEE, 0x49, 0x74, 0x07, 0xCE, 0x55, 0x7E, 0x23, 0xCE, 0x16,
        0xF6, 0xCA, 0xDC, 0x5A, 0x61, 0x01, 0x7E, 0xC9, 0x71, 0xB5, 0x4D, 0xF6,
        0xDC, 0x34, 0x29, 0x87, 0x68, 0xF6, 0x5E, 0x20, 0x93, 0xB3, 0xDB, 0xF5,
        0xE4, 0x09, 0x6C, 0x41, 0x17, 0x95, 0x92, 0xEB, 0x01, 0xB5, 0x73, 0xA5,
        0x6A, 0x7E, 0xD8, 0x32, 0xED, 0x0E, 0x02, 0xB8,
};

static DSA *
get_dsa1024(void)
{
        return get_dsa(dsa1024_priv, sizeof(dsa1024_priv),
            dsa1024_pub, sizeof(dsa1024_pub), dsa1024_p, sizeof(dsa1024_p),
            dsa1024_q, sizeof(dsa1024_q), dsa1024_g, sizeof(dsa1024_g));
}

static const unsigned char dsa2048_priv[] = {
        0x32, 0x67, 0x92, 0xf6, 0xc4, 0xe2, 0xe2, 0xe8, 0xa0, 0x8b, 0x6b, 0x45,
        0x0c, 0x8a, 0x76, 0xb0, 0xee, 0xcf, 0x91, 0xa7,
};

static const unsigned char dsa2048_pub[] = {
        0x17, 0x8f, 0xa8, 0x11, 0x84, 0x92, 0xec, 0x83, 0x47, 0xc7, 0x6a, 0xb0,
        0x92, 0xaf, 0x5a, 0x20, 0x37, 0xa3, 0x64, 0x79, 0xd2, 0xd0, 0x3d, 0xcd,
        0xe0, 0x61, 0x88, 0x88, 0x21, 0xcc, 0x74, 0x5d, 0xce, 0x4c, 0x51, 0x47,
        0xf0, 0xc5, 0x5c, 0x4c, 0x82, 0x7a, 0xaf, 0x72, 0xad, 0xb9, 0xe0, 0x53,
        0xf2, 0x78, 0xb7, 0xf0, 0xb5, 0x48, 0x7f, 0x8a, 0x3a, 0x18, 0xd1, 0x9f,
        0x8b, 0x7d, 0xa5, 0x47, 0xb7, 0x95, 0xab, 0x98, 0xf8, 0x7b, 0x74, 0x50,
        0x56, 0x8e, 0x57, 0xf0, 0xee, 0xf5, 0xb7, 0xba, 0xab, 0x85, 0x86, 0xf9,
        0x2b, 0xef, 0x41, 0x56, 0xa0, 0xa4, 0x9f, 0xb7, 0x38, 0x00, 0x46, 0x0a,
        0xa6, 0xf1, 0xfc, 0x1f, 0xd8, 0x4e, 0x85, 0x44, 0x92, 0x43, 0x21, 0x5d,
        0x6e, 0xcc, 0xc2, 0xcb, 0x26, 0x31, 0x0d, 0x21, 0xc4, 0xbd, 0x8d, 0x24,
        0xbc, 0xd9, 0x18, 0x19, 0xd7, 0xdc, 0xf1, 0xe7, 0x93, 0x50, 0x48, 0x03,
        0x2c, 0xae, 0x2e, 0xe7, 0x49, 0x88, 0x5f, 0x93, 0x57, 0x27, 0x99, 0x36,
        0xb4, 0x20, 0xab, 0xfc, 0xa7, 0x2b, 0xf2, 0xd9, 0x98, 0xd7, 0xd4, 0x34,
        0x9d, 0x96, 0x50, 0x58, 0x9a, 0xea, 0x54, 0xf3, 0xee, 0xf5, 0x63, 0x14,
        0xee, 0x85, 0x83, 0x74, 0x76, 0xe1, 0x52, 0x95, 0xc3, 0xf7, 0xeb, 0x04,
        0x04, 0x7b, 0xa7, 0x28, 0x1b, 0xcc, 0xea, 0x4a, 0x4e, 0x84, 0xda, 0xd8,
        0x9c, 0x79, 0xd8, 0x9b, 0x66, 0x89, 0x2f, 0xcf, 0xac, 0xd7, 0x79, 0xf9,
        0xa9, 0xd8, 0x45, 0x13, 0x78, 0xb9, 0x00, 0x14, 0xc9, 0x7e, 0x22, 0x51,
        0x86, 0x67, 0xb0, 0x9f, 0x26, 0x11, 0x23, 0xc8, 0x38, 0xd7, 0x70, 0x1d,
        0x15, 0x8e, 0x4d, 0x4f, 0x95, 0x97, 0x40, 0xa1, 0xc2, 0x7e, 0x01, 0x18,
        0x72, 0xf4, 0x10, 0xe6, 0x8d, 0x52, 0x16, 0x7f, 0xf2, 0xc9, 0xf8, 0x33,
        0x8b, 0x33, 0xb7, 0xce,
};

static const unsigned char dsa2048_p[] = {
        0xA0, 0x25, 0xFA, 0xAD, 0xF4, 0x8E, 0xB9, 0xE5, 0x99, 0xF3, 0x5D, 0x6F,
        0x4F, 0x83, 0x34, 0xE2, 0x7E, 0xCF, 0x6F, 0xBF, 0x30, 0xAF, 0x6F, 0x81,
        0xEB, 0xF8, 0xC4, 0x13, 0xD9, 0xA0, 0x5D, 0x8B, 0x5C, 0x8E, 0xDC, 0xC2,
        0x1D, 0x0B, 0x41, 0x32, 0xB0, 0x1F, 0xFE, 0xEF, 0x0C, 0xC2, 0xA2, 0x7E,
        0x68, 0x5C, 0x28, 0x21, 0xE9, 0xF5, 0xB1, 0x58, 0x12, 0x63, 0x4C, 0x19,
        0x4E, 0xFF, 0x02, 0x4B, 0x92, 0xED, 0xD2, 0x07, 0x11, 0x4D, 0x8C, 0x58,
        0x16, 0x5C, 0x55, 0x8E, 0xAD, 0xA3, 0x67, 0x7D, 0xB9, 0x86, 0x6E, 0x0B,
        0xE6, 0x54, 0x6F, 0x40, 0xAE, 0x0E, 0x67, 0x4C, 0xF9, 0x12, 0x5B, 0x3C,
        0x08, 0x7A, 0xF7, 0xFC, 0x67, 0x86, 0x69, 0xE7, 0x0A, 0x94, 0x40, 0xBF,
        0x8B, 0x76, 0xFE, 0x26, 0xD1, 0xF2, 0xA1, 0x1A, 0x84, 0xA1, 0x43, 0x56,
        0x28, 0xBC, 0x9A, 0x5F, 0xD7, 0x3B, 0x69, 0x89, 0x8A, 0x36, 0x2C, 0x51,
        0xDF, 0x12, 0x77, 0x2F, 0x57, 0x7B, 0xA0, 0xAA, 0xDD, 0x7F, 0xA1, 0x62,
        0x3B, 0x40, 0x7B, 0x68, 0x1A, 0x8F, 0x0D, 0x38, 0xBB, 0x21, 0x5D, 0x18,
        0xFC, 0x0F, 0x46, 0xF7, 0xA3, 0xB0, 0x1D, 0x23, 0xC3, 0xD2, 0xC7, 0x72,
        0x51, 0x18, 0xDF, 0x46, 0x95, 0x79, 0xD9, 0xBD, 0xB5, 0x19, 0x02, 0x2C,
        0x87, 0xDC, 0xE7, 0x57, 0x82, 0x7E, 0xF1, 0x8B, 0x06, 0x3D, 0x00, 0xA5,
        0x7B, 0x6B, 0x26, 0x27, 0x91, 0x0F, 0x6A, 0x77, 0xE4, 0xD5, 0x04, 0xE4,
        0x12, 0x2C, 0x42, 0xFF, 0xD2, 0x88, 0xBB, 0xD3, 0x92, 0xA0, 0xF9, 0xC8,
        0x51, 0x64, 0x14, 0x5C, 0xD8, 0xF9, 0x6C, 0x47, 0x82, 0xB4, 0x1C, 0x7F,
        0x09, 0xB8, 0xF0, 0x25, 0x83, 0x1D, 0x3F, 0x3F, 0x05, 0xB3, 0x21, 0x0A,
        0x5D, 0xA7, 0xD8, 0x54, 0xC3, 0x65, 0x7D, 0xC3, 0xB0, 0x1D, 0xBF, 0xAE,
        0xF8, 0x68, 0xCF, 0x9B,
};

static const unsigned char dsa2048_q[] = {
        0x97, 0xE7, 0x33, 0x4D, 0xD3, 0x94, 0x3E, 0x0B, 0xDB, 0x62, 0x74, 0xC6,
        0xA1, 0x08, 0xDD, 0x19, 0xA3, 0x75, 0x17, 0x1B,
};

static const unsigned char dsa2048_g[] = {
        0x2C, 0x78, 0x16, 0x59, 0x34, 0x63, 0xF4, 0xF3, 0x92, 0xFC, 0xB5, 0xA5,
        0x4F, 0x13, 0xDE, 0x2F, 0x1C, 0xA4, 0x3C, 0xAE, 0xAD, 0x38, 0x3F, 0x7E,
        0x90, 0xBF, 0x96, 0xA6, 0xAE, 0x25, 0x90, 0x72, 0xF5, 0x8E, 0x80, 0x0C,
        0x39, 0x1C, 0xD9, 0xEC, 0xBA, 0x90, 0x5B, 0x3A, 0xE8, 0x58, 0x6C, 0x9E,
        0x30, 0x42, 0x37, 0x02, 0x31, 0x82, 0xBC, 0x6A, 0xDF, 0x6A, 0x09, 0x29,
        0xE3, 0xC0, 0x46, 0xD1, 0xCB, 0x85, 0xEC, 0x0C, 0x30, 0x5E, 0xEA, 0xC8,
        0x39, 0x8E, 0x22, 0x9F, 0x22, 0x10, 0xD2, 0x34, 0x61, 0x68, 0x37, 0x3D,
        0x2E, 0x4A, 0x5B, 0x9A, 0xF5, 0xC1, 0x48, 0xC6, 0xF6, 0xDC, 0x63, 0x1A,
        0xD3, 0x96, 0x64, 0xBA, 0x34, 0xC9, 0xD1, 0xA0, 0xD1, 0xAE, 0x6C, 0x2F,
        0x48, 0x17, 0x93, 0x14, 0x43, 0xED, 0xF0, 0x21, 0x30, 0x19, 0xC3, 0x1B,
        0x5F, 0xDE, 0xA3, 0xF0, 0x70, 0x78, 0x18, 0xE1, 0xA8, 0xE4, 0xEE, 0x2E,
        0x00, 0xA5, 0xE4, 0xB3, 0x17, 0xC8, 0x0C, 0x7D, 0x6E, 0x42, 0xDC, 0xB7,
        0x46, 0x00, 0x36, 0x4D, 0xD4, 0x46, 0xAA, 0x3D, 0x3C, 0x46, 0x89, 0x40,
        0xBF, 0x1D, 0x84, 0x77, 0x0A, 0x75, 0xF3, 0x87, 0x1D, 0x08, 0x4C, 0xA6,
        0xD1, 0xA9, 0x1C, 0x1E, 0x12, 0x1E, 0xE1, 0xC7, 0x30, 0x28, 0x76, 0xA5,
        0x7F, 0x6C, 0x85, 0x96, 0x2B, 0x6F, 0xDB, 0x80, 0x66, 0x26, 0xAE, 0xF5,
        0x93, 0xC7, 0x8E, 0xAE, 0x9A, 0xED, 0xE4, 0xCA, 0x04, 0xEA, 0x3B, 0x72,
        0xEF, 0xDC, 0x87, 0xED, 0x0D, 0xA5, 0x4C, 0x4A, 0xDD, 0x71, 0x22, 0x64,
        0x59, 0x69, 0x4E, 0x8E, 0xBF, 0x43, 0xDC, 0xAB, 0x8E, 0x66, 0xBB, 0x01,
        0xB6, 0xF4, 0xE7, 0xFD, 0xD2, 0xAD, 0x9F, 0x36, 0xC1, 0xA0, 0x29, 0x99,
        0xD1, 0x96, 0x70, 0x59, 0x06, 0x78, 0x35, 0xBD, 0x65, 0x55, 0x52, 0x9E,
        0xF8, 0xB2, 0xE5, 0x38,
};

static DSA *
get_dsa2048(void)
{
        return get_dsa(dsa2048_priv, sizeof(dsa2048_priv),
            dsa2048_pub, sizeof(dsa2048_pub), dsa2048_p, sizeof(dsa2048_p),
            dsa2048_q, sizeof(dsa2048_q), dsa2048_g, sizeof(dsa2048_g));
}

static const unsigned char test512[] = {
        0x30, 0x82, 0x01, 0x3a, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00,
        0xd6, 0x33, 0xb9, 0xc8, 0xfb, 0x4f, 0x3c, 0x7d, 0xc0, 0x01,
        0x86, 0xd0, 0xe7, 0xa0, 0x55, 0xf2, 0x95, 0x93, 0xcc, 0x4f,
        0xb7, 0x5b, 0x67, 0x5b, 0x94, 0x68, 0xc9, 0x34, 0x15, 0xde,
        0xa5, 0x2e, 0x1c, 0x33, 0xc2, 0x6e, 0xfc, 0x34, 0x5e, 0x71,
        0x13, 0xb7, 0xd6, 0xee, 0xd8, 0xa5, 0x65, 0x05, 0x72, 0x87,
        0xa8, 0xb0, 0x77, 0xfe, 0x57, 0xf5, 0xfc, 0x5f, 0x55, 0x83,
        0x87, 0xdd, 0x57, 0x49, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02,
        0x41, 0x00, 0xa7, 0xf7, 0x91, 0xc5, 0x0f, 0x84, 0x57, 0xdc,
        0x07, 0xf7, 0x6a, 0x7f, 0x60, 0x52, 0xb3, 0x72, 0xf1, 0x66,
        0x1f, 0x7d, 0x97, 0x3b, 0x9e, 0xb6, 0x0a, 0x8f, 0x8c, 0xcf,
        0x42, 0x23, 0x00, 0x04, 0xd4, 0x28, 0x0e, 0x1c, 0x90, 0xc4,
        0x11, 0x25, 0x25, 0xa5, 0x93, 0xa5, 0x2f, 0x70, 0x02, 0xdf,
        0x81, 0x9c, 0x49, 0x03, 0xa0, 0xf8, 0x6d, 0x54, 0x2e, 0x26,
        0xde, 0xaa, 0x85, 0x59, 0xa8, 0x31, 0x02, 0x21, 0x00, 0xeb,
        0x47, 0xd7, 0x3b, 0xf6, 0xc3, 0xdd, 0x5a, 0x46, 0xc5, 0xb9,
        0x2b, 0x9a, 0xa0, 0x09, 0x8f, 0xa6, 0xfb, 0xf3, 0x78, 0x7a,
        0x33, 0x70, 0x9d, 0x0f, 0x42, 0x6b, 0x13, 0x68, 0x24, 0xd3,
        0x15, 0x02, 0x21, 0x00, 0xe9, 0x10, 0xb0, 0xb3, 0x0d, 0xe2,
        0x82, 0x68, 0x77, 0x8a, 0x6e, 0x7c, 0xda, 0xbc, 0x3e, 0x53,
        0x83, 0xfb, 0xd6, 0x22, 0xe7, 0xb5, 0xae, 0x6e, 0x80, 0xda,
        0x00, 0x55, 0x97, 0xc1, 0xd0, 0x65, 0x02, 0x20, 0x4c, 0xf8,
        0x73, 0xb1, 0x6a, 0x49, 0x29, 0x61, 0x1f, 0x46, 0x10, 0x0d,
        0xf3, 0xc7, 0xe7, 0x58, 0xd7, 0x88, 0x15, 0x5e, 0x94, 0x9b,
        0xbf, 0x7b, 0xa2, 0x42, 0x58, 0x45, 0x41, 0x0c, 0xcb, 0x01,
        0x02, 0x20, 0x12, 0x11, 0xba, 0x31, 0x57, 0x9d, 0x3d, 0x11,
        0x0e, 0x5b, 0x8c, 0x2f, 0x5f, 0xe2, 0x02, 0x4f, 0x05, 0x47,
        0x8c, 0x15, 0x8e, 0xb3, 0x56, 0x3f, 0xb8, 0xfb, 0xad, 0xd4,
        0xf4, 0xfc, 0x10, 0xc5, 0x02, 0x20, 0x18, 0xa1, 0x29, 0x99,
        0x5b, 0xd9, 0xc8, 0xd4, 0xfc, 0x49, 0x7a, 0x2a, 0x21, 0x2c,
        0x49, 0xe4, 0x4f, 0xeb, 0xef, 0x51, 0xf1, 0xab, 0x6d, 0xfb,
        0x4b, 0x14, 0xe9, 0x4b, 0x52, 0xb5, 0x82, 0x2c,
};

static const unsigned char test1024[] = {
        0x30, 0x82, 0x02, 0x5c, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81,
        0x00, 0xdc, 0x98, 0x43, 0xe8, 0x3d, 0x43, 0x5b, 0xe4, 0x05,
        0xcd, 0xd0, 0xa9, 0x3e, 0xcb, 0x83, 0x75, 0xf6, 0xb5, 0xa5,
        0x9f, 0x6b, 0xe9, 0x34, 0x41, 0x29, 0x18, 0xfa, 0x6a, 0x55,
        0x4d, 0x70, 0xfc, 0xec, 0xae, 0x87, 0x38, 0x0a, 0x20, 0xa9,
        0xc0, 0x45, 0x77, 0x6e, 0x57, 0x60, 0x57, 0xf4, 0xed, 0x96,
        0x22, 0xcb, 0x8f, 0xe1, 0x33, 0x3a, 0x17, 0x1f, 0xed, 0x37,
        0xa5, 0x6f, 0xeb, 0xa6, 0xbc, 0x12, 0x80, 0x1d, 0x53, 0xbd,
        0x70, 0xeb, 0x21, 0x76, 0x3e, 0xc9, 0x2f, 0x1a, 0x45, 0x24,
        0x82, 0xff, 0xcd, 0x59, 0x32, 0x06, 0x2e, 0x12, 0x3b, 0x23,
        0x78, 0xed, 0x12, 0x3d, 0xe0, 0x8d, 0xf9, 0x67, 0x4f, 0x37,
        0x4e, 0x47, 0x02, 0x4c, 0x2d, 0xc0, 0x4f, 0x1f, 0xb3, 0x94,
        0xe1, 0x41, 0x2e, 0x2d, 0x90, 0x10, 0xfc, 0x82, 0x91, 0x8b,
        0x0f, 0x22, 0xd4, 0xf2, 0xfc, 0x2c, 0xab, 0x53, 0x55, 0x02,
        0x03, 0x01, 0x00, 0x01, 0x02, 0x81, 0x80, 0x2b, 0xcc, 0x3f,
        0x8f, 0x58, 0xba, 0x8b, 0x00, 0x16, 0xf6, 0xea, 0x3a, 0xf0,
        0x30, 0xd0, 0x05, 0x17, 0xda, 0xb0, 0xeb, 0x9a, 0x2d, 0x4f,
        0x26, 0xb0, 0xd6, 0x38, 0xc1, 0xeb, 0xf5, 0xd8, 0x3d, 0x1f,
        0x70, 0xf7, 0x7f, 0xf4, 0xe2, 0xcf, 0x51, 0x51, 0x79, 0x88,
        0xfa, 0xe8, 0x32, 0x0e, 0x7b, 0x2d, 0x97, 0xf2, 0xfa, 0xba,
        0x27, 0xc5, 0x9c, 0xd9, 0xc5, 0xeb, 0x8a, 0x79, 0x52, 0x3c,
        0x64, 0x34, 0x7d, 0xc2, 0xcf, 0x28, 0xc7, 0x4e, 0xd5, 0x43,
        0x0b, 0xd1, 0xa6, 0xca, 0x6d, 0x03, 0x2d, 0x72, 0x23, 0xbc,
        0x6d, 0x05, 0xfa, 0x16, 0x09, 0x2f, 0x2e, 0x5c, 0xb6, 0xee,
        0x74, 0xdd, 0xd2, 0x48, 0x8e, 0x36, 0x0c, 0x06, 0x3d, 0x4d,
        0xe5, 0x10, 0x82, 0xeb, 0x6a, 0xf3, 0x4b, 0x9f, 0xd6, 0xed,
        0x11, 0xb1, 0x6e, 0xec, 0xf4, 0xfe, 0x8e, 0x75, 0x94, 0x20,
        0x2f, 0xcb, 0xac, 0x46, 0xf1, 0x02, 0x41, 0x00, 0xf9, 0x8c,
        0xa3, 0x85, 0xb1, 0xdd, 0x29, 0xaf, 0x65, 0xc1, 0x33, 0xf3,
        0x95, 0xc5, 0x52, 0x68, 0x0b, 0xd4, 0xf1, 0xe5, 0x0e, 0x02,
        0x9f, 0x4f, 0xfa, 0x77, 0xdc, 0x46, 0x9e, 0xc7, 0xa6, 0xe4,
        0x16, 0x29, 0xda, 0xb0, 0x07, 0xcf, 0x5b, 0xa9, 0x12, 0x8a,
        0xdd, 0x63, 0x0a, 0xde, 0x2e, 0x8c, 0x66, 0x8b, 0x8c, 0xdc,
        0x19, 0xa3, 0x7e, 0xf4, 0x3b, 0xd0, 0x1a, 0x8c, 0xa4, 0xc2,
        0xe1, 0xd3, 0x02, 0x41, 0x00, 0xe2, 0x4c, 0x05, 0xf2, 0x04,
        0x86, 0x4e, 0x61, 0x43, 0xdb, 0xb0, 0xb9, 0x96, 0x86, 0x52,
        0x2c, 0xca, 0x8d, 0x7b, 0xab, 0x0b, 0x13, 0x0d, 0x7e, 0x38,
        0x5b, 0xe2, 0x2e, 0x7b, 0x0e, 0xe7, 0x19, 0x99, 0x38, 0xe7,
        0xf2, 0x21, 0xbd, 0x85, 0x85, 0xe3, 0xfd, 0x28, 0x77, 0x20,
        0x31, 0x71, 0x2c, 0xd0, 0xff, 0xfb, 0x2e, 0xaf, 0x85, 0xb4,
        0x86, 0xca, 0xf3, 0xbb, 0xca, 0xaa, 0x0f, 0x95, 0x37, 0x02,
        0x40, 0x0e, 0x41, 0x9a, 0x95, 0xe8, 0xb3, 0x59, 0xce, 0x4b,
        0x61, 0xde, 0x35, 0xec, 0x38, 0x79, 0x9c, 0xb8, 0x10, 0x52,
        0x41, 0x63, 0xab, 0x82, 0xae, 0x6f, 0x00, 0xa9, 0xf4, 0xde,
        0xdd, 0x49, 0x0b, 0x7e, 0xb8, 0xa5, 0x65, 0xa9, 0x0c, 0x8f,
        0x8f, 0xf9, 0x1f, 0x35, 0xc6, 0x92, 0xb8, 0x5e, 0xb0, 0x66,
        0xab, 0x52, 0x40, 0xc0, 0xb6, 0x36, 0x6a, 0x7d, 0x80, 0x46,
        0x04, 0x02, 0xe5, 0x9f, 0x41, 0x02, 0x41, 0x00, 0xc0, 0xad,
        0xcc, 0x4e, 0x21, 0xee, 0x1d, 0x24, 0x91, 0xfb, 0xa7, 0x80,
        0x8d, 0x9a, 0xb6, 0xb3, 0x2e, 0x8f, 0xc2, 0xe1, 0x82, 0xdf,
        0x69, 0x18, 0xb4, 0x71, 0xff, 0xa6, 0x65, 0xde, 0xed, 0x84,
        0x8d, 0x42, 0xb7, 0xb3, 0x21, 0x69, 0x56, 0x1c, 0x07, 0x60,
        0x51, 0x29, 0x04, 0xff, 0x34, 0x06, 0xdd, 0xb9, 0x67, 0x2c,
        0x7c, 0x04, 0x93, 0x0e, 0x46, 0x15, 0xbb, 0x2a, 0xb7, 0x1b,
        0xe7, 0x87, 0x02, 0x40, 0x78, 0xda, 0x5d, 0x07, 0x51, 0x0c,
        0x16, 0x7a, 0x9f, 0x29, 0x20, 0x84, 0x0d, 0x42, 0xfa, 0xd7,
        0x00, 0xd8, 0x77, 0x7e, 0xb0, 0xb0, 0x6b, 0xd6, 0x5b, 0x53,
        0xb8, 0x9b, 0x7a, 0xcd, 0xc7, 0x2b, 0xb8, 0x6a, 0x63, 0xa9,
        0xfb, 0x6f, 0xa4, 0x72, 0xbf, 0x4c, 0x5d, 0x00, 0x14, 0xba,
        0xfa, 0x59, 0x88, 0xed, 0xe4, 0xe0, 0x8c, 0xa2, 0xec, 0x14,
        0x7e, 0x2d, 0xe2, 0xf0, 0x46, 0x49, 0x95, 0x45,
};

static const unsigned char test2048[] = {
        0x30, 0x82, 0x04, 0xa3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01,
        0x01, 0x00, 0xc0, 0xc0, 0xce, 0x3e, 0x3c, 0x53, 0x67, 0x3f,
        0x4f, 0xc5, 0x2f, 0xa4, 0xc2, 0x5a, 0x2f, 0x58, 0xfd, 0x27,
        0x52, 0x6a, 0xe8, 0xcf, 0x4a, 0x73, 0x47, 0x8d, 0x25, 0x0f,
        0x5f, 0x03, 0x26, 0x78, 0xef, 0xf0, 0x22, 0x12, 0xd3, 0xde,
        0x47, 0xb2, 0x1c, 0x0b, 0x38, 0x63, 0x1a, 0x6c, 0x85, 0x7a,
        0x80, 0xc6, 0x8f, 0xa0, 0x41, 0xaf, 0x62, 0xc4, 0x67, 0x32,
        0x88, 0xf8, 0xa6, 0x9c, 0xf5, 0x23, 0x1d, 0xe4, 0xac, 0x3f,
        0x29, 0xf9, 0xec, 0xe1, 0x8b, 0x26, 0x03, 0x2c, 0xb2, 0xab,
        0xf3, 0x7d, 0xb5, 0xca, 0x49, 0xc0, 0x8f, 0x1c, 0xdf, 0x33,
        0x3a, 0x60, 0xda, 0x3c, 0xb0, 0x16, 0xf8, 0xa9, 0x12, 0x8f,
        0x64, 0xac, 0x23, 0x0c, 0x69, 0x64, 0x97, 0x5d, 0x99, 0xd4,
        0x09, 0x83, 0x9b, 0x61, 0xd3, 0xac, 0xf0, 0xde, 0xdd, 0x5e,
        0x9f, 0x44, 0x94, 0xdb, 0x3a, 0x4d, 0x97, 0xe8, 0x52, 0x29,
        0xf7, 0xdb, 0x94, 0x07, 0x45, 0x90, 0x78, 0x1e, 0x31, 0x0b,
        0x80, 0xf7, 0x57, 0xad, 0x1c, 0x79, 0xc5, 0xcb, 0x32, 0xb0,
        0xce, 0xcd, 0x74, 0xb3, 0xe2, 0x94, 0xc5, 0x78, 0x2f, 0x34,
        0x1a, 0x45, 0xf7, 0x8c, 0x52, 0xa5, 0xbc, 0x8d, 0xec, 0xd1,
        0x2f, 0x31, 0x3b, 0xf0, 0x49, 0x59, 0x5e, 0x88, 0x9d, 0x15,
        0x92, 0x35, 0x32, 0xc1, 0xe7, 0x61, 0xec, 0x50, 0x48, 0x7c,
        0xba, 0x05, 0xf9, 0xf8, 0xf8, 0xa7, 0x8c, 0x83, 0xe8, 0x66,
        0x5b, 0xeb, 0xfe, 0xd8, 0x4f, 0xdd, 0x6d, 0x36, 0xc0, 0xb2,
        0x90, 0x0f, 0xb8, 0x52, 0xf9, 0x04, 0x9b, 0x40, 0x2c, 0x27,
        0xd6, 0x36, 0x8e, 0xc2, 0x1b, 0x44, 0xf3, 0x92, 0xd5, 0x15,
        0x9e, 0x9a, 0xbc, 0xf3, 0x7d, 0x03, 0xd7, 0x02, 0x14, 0x20,
        0xe9, 0x10, 0x92, 0xfd, 0xf9, 0xfc, 0x8f, 0xe5, 0x18, 0xe1,
        0x95, 0xcc, 0x9e, 0x60, 0xa6, 0xfa, 0x38, 0x4d, 0x02, 0x03,
        0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x00, 0x00, 0xc3, 0xc3,
        0x0d, 0xb4, 0x27, 0x90, 0x8d, 0x4b, 0xbf, 0xb8, 0x84, 0xaa,
        0xd0, 0xb8, 0xc7, 0x5d, 0x99, 0xbe, 0x55, 0xf6, 0x3e, 0x7c,
        0x49, 0x20, 0xcb, 0x8a, 0x8e, 0x19, 0x0e, 0x66, 0x24, 0xac,
        0xaf, 0x03, 0x33, 0x97, 0xeb, 0x95, 0xd5, 0x3b, 0x0f, 0x40,
        0x56, 0x04, 0x50, 0xd1, 0xe6, 0xbe, 0x84, 0x0b, 0x25, 0xd3,
        0x9c, 0xe2, 0x83, 0x6c, 0xf5, 0x62, 0x5d, 0xba, 0x2b, 0x7d,
        0x3d, 0x7a, 0x6c, 0xe1, 0xd2, 0x0e, 0x54, 0x93, 0x80, 0x01,
        0x91, 0x51, 0x09, 0xe8, 0x5b, 0x8e, 0x47, 0xbd, 0x64, 0xe4,
        0x0e, 0x03, 0x83, 0x55, 0xcf, 0x5a, 0x37, 0xf0, 0x25, 0xb5,
        0x7d, 0x21, 0xd7, 0x69, 0xdf, 0x6f, 0xc2, 0xcf, 0x10, 0xc9,
        0x8a, 0x40, 0x9f, 0x7a, 0x70, 0xc0, 0xe8, 0xe8, 0xc0, 0xe6,
        0x9a, 0x15, 0x0a, 0x8d, 0x4e, 0x46, 0xcb, 0x7a, 0xdb, 0xb3,
        0xcb, 0x83, 0x02, 0xc4, 0xf0, 0xab, 0xeb, 0x02, 0x01, 0x0e,
        0x23, 0xfc, 0x1d, 0xc4, 0xbd, 0xd4, 0xaa, 0x5d, 0x31, 0x46,
        0x99, 0xce, 0x9e, 0xf8, 0x04, 0x75, 0x10, 0x67, 0xc4, 0x53,
        0x47, 0x44, 0xfa, 0xc2, 0x25, 0x73, 0x7e, 0xd0, 0x8e, 0x59,
        0xd1, 0xb2, 0x5a, 0xf4, 0xc7, 0x18, 0x92, 0x2f, 0x39, 0xab,
        0xcd, 0xa3, 0xb5, 0xc2, 0xb9, 0xc7, 0xb9, 0x1b, 0x9f, 0x48,
        0xfa, 0x13, 0xc6, 0x98, 0x4d, 0xca, 0x84, 0x9c, 0x06, 0xca,
        0xe7, 0x89, 0x01, 0x04, 0xc4, 0x6c, 0xfd, 0x29, 0x59, 0x35,
        0xe7, 0xf3, 0xdd, 0xce, 0x64, 0x59, 0xbf, 0x21, 0x13, 0xa9,
        0x9f, 0x0e, 0xc5, 0xff, 0xbd, 0x33, 0x00, 0xec, 0xac, 0x6b,
        0x11, 0xef, 0x51, 0x5e, 0xad, 0x07, 0x15, 0xde, 0xb8, 0x5f,
        0xc6, 0xb9, 0xa3, 0x22, 0x65, 0x46, 0x83, 0x14, 0xdf, 0xd0,
        0xf1, 0x44, 0x8a, 0xe1, 0x9c, 0x23, 0x33, 0xb4, 0x97, 0x33,
        0xe6, 0x6b, 0x81, 0x02, 0x81, 0x81, 0x00, 0xec, 0x12, 0xa7,
        0x59, 0x74, 0x6a, 0xde, 0x3e, 0xad, 0xd8, 0x36, 0x80, 0x50,
        0xa2, 0xd5, 0x21, 0x81, 0x07, 0xf1, 0xd0, 0x91, 0xf2, 0x6c,
        0x12, 0x2f, 0x9d, 0x1a, 0x26, 0xf8, 0x30, 0x65, 0xdf, 0xe8,
        0xc0, 0x9b, 0x6a, 0x30, 0x98, 0x82, 0x87, 0xec, 0xa2, 0x56,
        0x87, 0x62, 0x6f, 0xe7, 0x9f, 0xf6, 0x56, 0xe6, 0x71, 0x8f,
        0x49, 0x86, 0x93, 0x5a, 0x4d, 0x34, 0x58, 0xfe, 0xd9, 0x04,
        0x13, 0xaf, 0x79, 0xb7, 0xad, 0x11, 0xd1, 0x30, 0x9a, 0x14,
        0x06, 0xa0, 0xfa, 0xb7, 0x55, 0xdc, 0x6c, 0x5a, 0x4c, 0x2c,
        0x59, 0x56, 0xf6, 0xe8, 0x9d, 0xaf, 0x0a, 0x78, 0x99, 0x06,
        0x06, 0x9e, 0xe7, 0x9c, 0x51, 0x55, 0x43, 0xfc, 0x3b, 0x6c,
        0x0b, 0xbf, 0x2d, 0x41, 0xa7, 0xaf, 0xb7, 0xe0, 0xe8, 0x28,
        0x18, 0xb4, 0x13, 0xd1, 0xe6, 0x97, 0xd0, 0x9f, 0x6a, 0x80,
        0xca, 0xdd, 0x1a, 0x7e, 0x15, 0x02, 0x81, 0x81, 0x00, 0xd1,
        0x06, 0x0c, 0x1f, 0xe3, 0xd0, 0xab, 0xd6, 0xca, 0x7c, 0xbc,
        0x7d, 0x13, 0x35, 0xce, 0x27, 0xcd, 0xd8, 0x49, 0x51, 0x63,
        0x64, 0x0f, 0xca, 0x06, 0x12, 0xfc, 0x07, 0x3e, 0xaf, 0x61,
        0x6d, 0xe2, 0x53, 0x39, 0x27, 0xae, 0xc3, 0x11, 0x9e, 0x94,
        0x01, 0x4f, 0xe3, 0xf3, 0x67, 0xf9, 0x77, 0xf9, 0xe7, 0x95,
        0x3a, 0x6f, 0xe2, 0x20, 0x73, 0x3e, 0xa4, 0x7a, 0x28, 0xd4,
        0x61, 0x97, 0xf6, 0x17, 0xa0, 0x23, 0x10, 0x2b, 0xce, 0x84,
        0x57, 0x7e, 0x25, 0x1f, 0xf4, 0xa8, 0x54, 0xd2, 0x65, 0x94,
        0xcc, 0x95, 0x0a, 0xab, 0x30, 0xc1, 0x59, 0x1f, 0x61, 0x8e,
        0xb9, 0x6b, 0xd7, 0x4e, 0xb9, 0x83, 0x43, 0x79, 0x85, 0x11,
        0xbc, 0x0f, 0xae, 0x25, 0x20, 0x05, 0xbc, 0xd2, 0x48, 0xa1,
        0x68, 0x09, 0x84, 0xf6, 0x12, 0x9a, 0x66, 0xb9, 0x2b, 0xbb,
        0x76, 0x03, 0x17, 0x46, 0x4e, 0x97, 0x59, 0x02, 0x81, 0x80,
        0x09, 0x4c, 0xfa, 0xd6, 0xe5, 0x65, 0x48, 0x78, 0x43, 0xb5,
        0x1f, 0x00, 0x93, 0x2c, 0xb7, 0x24, 0xe8, 0xc6, 0x7d, 0x5a,
        0x70, 0x45, 0x92, 0xc8, 0x6c, 0xa3, 0xcd, 0xe1, 0xf7, 0x29,
        0x40, 0xfa, 0x3f, 0x5b, 0x47, 0x44, 0x39, 0xc1, 0xe8, 0x72,
        0x9e, 0x7a, 0x0e, 0xda, 0xaa, 0xa0, 0x2a, 0x09, 0xfd, 0x54,
        0x93, 0x23, 0xaa, 0x37, 0x85, 0x5b, 0xcc, 0xd4, 0xf9, 0xd8,
        0xff, 0xc1, 0x61, 0x0d, 0xbd, 0x7e, 0x18, 0x24, 0x73, 0x6d,
        0x40, 0x72, 0xf1, 0x93, 0x09, 0x48, 0x97, 0x6c, 0x84, 0x90,
        0xa8, 0x46, 0x14, 0x01, 0x39, 0x11, 0xe5, 0x3c, 0x41, 0x27,
        0x32, 0x75, 0x24, 0xed, 0xa1, 0xd9, 0x12, 0x29, 0x8a, 0x28,
        0x71, 0x89, 0x8d, 0xca, 0x30, 0xb0, 0x01, 0xc4, 0x2f, 0x82,
        0x19, 0x14, 0x4c, 0x70, 0x1c, 0xb8, 0x23, 0x2e, 0xe8, 0x90,
        0x49, 0x97, 0x92, 0x97, 0x6b, 0x7a, 0x9d, 0xb9, 0x02, 0x81,
        0x80, 0x0f, 0x0e, 0xa1, 0x76, 0xf6, 0xa1, 0x44, 0x8f, 0xaf,
        0x7c, 0x76, 0xd3, 0x87, 0xbb, 0xbb, 0x83, 0x10, 0x88, 0x01,
        0x18, 0x14, 0xd1, 0xd3, 0x75, 0x59, 0x24, 0xaa, 0xf5, 0x16,
        0xa5, 0xe9, 0x9d, 0xd1, 0xcc, 0xee, 0xf4, 0x15, 0xd9, 0xc5,
        0x7e, 0x27, 0xe9, 0x44, 0x49, 0x06, 0x72, 0xb9, 0xfc, 0xd3,
        0x8a, 0xc4, 0x2c, 0x36, 0x7d, 0x12, 0x9b, 0x5a, 0xaa, 0xdc,
        0x85, 0xee, 0x6e, 0xad, 0x54, 0xb3, 0xf4, 0xfc, 0x31, 0xa1,
        0x06, 0x3a, 0x70, 0x57, 0x0c, 0xf3, 0x95, 0x5b, 0x3e, 0xe8,
        0xfd, 0x1a, 0x4f, 0xf6, 0x78, 0x93, 0x46, 0x6a, 0xd7, 0x31,
        0xb4, 0x84, 0x64, 0x85, 0x09, 0x38, 0x89, 0x92, 0x94, 0x1c,
        0xbf, 0xe2, 0x3c, 0x2a, 0xe0, 0xff, 0x99, 0xa3, 0xf0, 0x2b,
        0x31, 0xc2, 0x36, 0xcd, 0x60, 0xbf, 0x9d, 0x2d, 0x74, 0x32,
        0xe8, 0x9c, 0x93, 0x6e, 0xbb, 0x91, 0x7b, 0xfd, 0xd9, 0x02,
        0x81, 0x81, 0x00, 0xa2, 0x71, 0x25, 0x38, 0xeb, 0x2a, 0xe9,
        0x37, 0xcd, 0xfe, 0x44, 0xce, 0x90, 0x3f, 0x52, 0x87, 0x84,
        0x52, 0x1b, 0xae, 0x8d, 0x22, 0x94, 0xce, 0x38, 0xe6, 0x04,
        0x88, 0x76, 0x85, 0x9a, 0xd3, 0x14, 0x09, 0xe5, 0x69, 0x9a,
        0xff, 0x58, 0x92, 0x02, 0x6a, 0x7d, 0x7c, 0x1e, 0x2c, 0xfd,
        0xa8, 0xca, 0x32, 0x14, 0x4f, 0x0d, 0x84, 0x0d, 0x37, 0x43,
        0xbf, 0xe4, 0x5d, 0x12, 0xc8, 0x24, 0x91, 0x27, 0x8d, 0x46,
        0xd9, 0x54, 0x53, 0xe7, 0x62, 0x71, 0xa8, 0x2b, 0x71, 0x41,
        0x8d, 0x75, 0xf8, 0x3a, 0xa0, 0x61, 0x29, 0x46, 0xa6, 0xe5,
        0x82, 0xfa, 0x3a, 0xd9, 0x08, 0xfa, 0xfc, 0x63, 0xfd, 0x6b,
        0x30, 0xbc, 0xf4, 0x4e, 0x9e, 0x8c, 0x25, 0x0c, 0xb6, 0x55,
        0xe7, 0x3c, 0xd4, 0x4e, 0x0b, 0xfd, 0x8b, 0xc3, 0x0e, 0x1d,
        0x9c, 0x44, 0x57, 0x8f, 0x1f, 0x86, 0xf7, 0xd5, 0x1b, 0xe4,
        0x95,
};

static const unsigned char test4096[] = {
        0x30, 0x82, 0x09, 0x29, 0x02, 0x01, 0x00, 0x02, 0x82, 0x02,
        0x01, 0x00, 0xc0, 0x71, 0xac, 0x1a, 0x13, 0x88, 0x82, 0x43,
        0x3b, 0x51, 0x57, 0x71, 0x8d, 0xb6, 0x2b, 0x82, 0x65, 0x21,
        0x53, 0x5f, 0x28, 0x29, 0x4f, 0x8d, 0x7c, 0x8a, 0xb9, 0x44,
        0xb3, 0x28, 0x41, 0x4f, 0xd3, 0xfa, 0x6a, 0xf8, 0xb9, 0x28,
        0x50, 0x39, 0x67, 0x53, 0x2c, 0x3c, 0xd7, 0xcb, 0x96, 0x41,
        0x40, 0x32, 0xbb, 0xeb, 0x70, 0xae, 0x1f, 0xb0, 0x65, 0xf7,
        0x3a, 0xd9, 0x22, 0xfd, 0x10, 0xae, 0xbd, 0x02, 0xe2, 0xdd,
        0xf3, 0xc2, 0x79, 0x3c, 0xc6, 0xfc, 0x75, 0xbb, 0xaf, 0x4e,
        0x3a, 0x36, 0xc2, 0x4f, 0xea, 0x25, 0xdf, 0x13, 0x16, 0x4b,
        0x20, 0xfe, 0x4b, 0x69, 0x16, 0xc4, 0x7f, 0x1a, 0x43, 0xa6,
        0x17, 0x1b, 0xb9, 0x0a, 0xf3, 0x09, 0x86, 0x28, 0x89, 0xcf,
        0x2c, 0xd0, 0xd4, 0x81, 0xaf, 0xc6, 0x6d, 0xe6, 0x21, 0x8d,
        0xee, 0xef, 0xea, 0xdc, 0xb7, 0xc6, 0x3b, 0x63, 0x9f, 0x0e,
        0xad, 0x89, 0x78, 0x23, 0x18, 0xbf, 0x70, 0x7e, 0x84, 0xe0,
        0x37, 0xec, 0xdb, 0x8e, 0x9c, 0x3e, 0x6a, 0x19, 0xcc, 0x99,
        0x72, 0xe6, 0xb5, 0x7d, 0x6d, 0xfa, 0xe5, 0xd3, 0xe4, 0x90,
        0xb5, 0xb2, 0xb2, 0x12, 0x70, 0x4e, 0xca, 0xf8, 0x10, 0xf8,
        0xa3, 0x14, 0xc2, 0x48, 0x19, 0xeb, 0x60, 0x99, 0xbb, 0x2a,
        0x1f, 0xb1, 0x7a, 0xb1, 0x3d, 0x24, 0xfb, 0xa0, 0x29, 0xda,
        0xbd, 0x1b, 0xd7, 0xa4, 0xbf, 0xef, 0x60, 0x2d, 0x22, 0xca,
        0x65, 0x98, 0xf1, 0xc4, 0xe1, 0xc9, 0x02, 0x6b, 0x16, 0x28,
        0x2f, 0xa1, 0xaa, 0x79, 0x00, 0xda, 0xdc, 0x7c, 0x43, 0xf7,
        0x42, 0x3c, 0xa0, 0xef, 0x68, 0xf7, 0xdf, 0xb9, 0x69, 0xfb,
        0x8e, 0x01, 0xed, 0x01, 0x42, 0xb5, 0x4e, 0x57, 0xa6, 0x26,
        0xb8, 0xd0, 0x7b, 0x56, 0x6d, 0x03, 0xc6, 0x40, 0x8c, 0x8c,
        0x2a, 0x55, 0xd7, 0x9c, 0x35, 0x00, 0x94, 0x93, 0xec, 0x03,
        0xeb, 0x22, 0xef, 0x77, 0xbb, 0x79, 0x13, 0x3f, 0x15, 0xa1,
        0x8f, 0xca, 0xdf, 0xfd, 0xd3, 0xb8, 0xe1, 0xd4, 0xcc, 0x09,
        0x3f, 0x3c, 0x2c, 0xdb, 0xd1, 0x49, 0x7f, 0x38, 0x07, 0x83,
        0x6d, 0xeb, 0x08, 0x66, 0xe9, 0x06, 0x44, 0x12, 0xac, 0x95,
        0x22, 0x90, 0x23, 0x67, 0xd4, 0x08, 0xcc, 0xf4, 0xb7, 0xdc,
        0xcc, 0x87, 0xd4, 0xac, 0x69, 0x35, 0x4c, 0xb5, 0x39, 0x36,
        0xcd, 0xa4, 0xd2, 0x95, 0xca, 0x0d, 0xc5, 0xda, 0xc2, 0xc5,
        0x22, 0x32, 0x28, 0x08, 0xe3, 0xd2, 0x8b, 0x38, 0x30, 0xdc,
        0x8c, 0x75, 0x4f, 0x6a, 0xec, 0x7a, 0xac, 0x16, 0x3e, 0xa8,
        0xd4, 0x6a, 0x45, 0xe1, 0xa8, 0x4f, 0x2e, 0x80, 0x34, 0xaa,
        0x54, 0x1b, 0x02, 0x95, 0x7d, 0x8a, 0x6d, 0xcc, 0x79, 0xca,
        0xf2, 0xa4, 0x2e, 0x8d, 0xfb, 0xfe, 0x15, 0x51, 0x10, 0x0e,
        0x4d, 0x88, 0xb1, 0xc7, 0xf4, 0x79, 0xdb, 0xf0, 0xb4, 0x56,
        0x44, 0x37, 0xca, 0x5a, 0xc1, 0x8c, 0x48, 0xac, 0xae, 0x48,
        0x80, 0x83, 0x01, 0x3f, 0xde, 0xd9, 0xd3, 0x2c, 0x51, 0x46,
        0xb1, 0x41, 0xb6, 0xc6, 0x91, 0x72, 0xf9, 0x83, 0x55, 0x1b,
        0x8c, 0xba, 0xf3, 0x73, 0xe5, 0x2c, 0x74, 0x50, 0x3a, 0xbe,
        0xc5, 0x2f, 0xa7, 0xb2, 0x6d, 0x8c, 0x9e, 0x13, 0x77, 0xa3,
        0x13, 0xcd, 0x6d, 0x8c, 0x45, 0xe1, 0xfc, 0x0b, 0xb7, 0x69,
        0xe9, 0x27, 0xbc, 0x65, 0xc3, 0xfa, 0x9b, 0xd0, 0xef, 0xfe,
        0xe8, 0x1f, 0xb3, 0x5e, 0x34, 0xf4, 0x8c, 0xea, 0xfc, 0xd3,
        0x81, 0xbf, 0x3d, 0x30, 0xb2, 0xb4, 0x01, 0xe8, 0x43, 0x0f,
        0xba, 0x02, 0x23, 0x42, 0x76, 0x82, 0x31, 0x73, 0x91, 0xed,
        0x07, 0x46, 0x61, 0x0d, 0x39, 0x83, 0x40, 0xce, 0x7a, 0xd4,
        0xdb, 0x80, 0x2c, 0x1f, 0x0d, 0xd1, 0x34, 0xd4, 0x92, 0xe3,
        0xd4, 0xf1, 0xc2, 0x01, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02,
        0x82, 0x02, 0x01, 0x00, 0x97, 0x6c, 0xda, 0x6e, 0xea, 0x4f,
        0xcf, 0xaf, 0xf7, 0x4c, 0xd9, 0xf1, 0x90, 0x00, 0x77, 0xdb,
        0xf2, 0x97, 0x76, 0x72, 0xb9, 0xb7, 0x47, 0xd1, 0x9c, 0xdd,
        0xcb, 0x4a, 0x33, 0x6e, 0xc9, 0x75, 0x76, 0xe6, 0xe4, 0xa5,
        0x31, 0x8c, 0x77, 0x13, 0xb4, 0x29, 0xcd, 0xf5, 0x52, 0x17,
        0xef, 0xf3, 0x08, 0x00, 0xe3, 0xbd, 0x2e, 0xbc, 0xd4, 0x52,
        0x88, 0xe9, 0x30, 0x75, 0x0b, 0x02, 0xf5, 0xcd, 0x89, 0x0c,
        0x6c, 0x57, 0x19, 0x27, 0x3d, 0x1e, 0x85, 0xb4, 0xc1, 0x2f,
        0x1d, 0x92, 0x00, 0x5c, 0x76, 0x29, 0x4b, 0xa4, 0xe1, 0x12,
        0xb3, 0xc8, 0x09, 0xfe, 0x0e, 0x78, 0x72, 0x61, 0xcb, 0x61,
        0x6f, 0x39, 0x91, 0x95, 0x4e, 0xd5, 0x3e, 0xc7, 0x8f, 0xb8,
        0xf6, 0x36, 0xfe, 0x9c, 0x93, 0x9a, 0x38, 0x25, 0x7a, 0xf4,
        0x4a, 0x12, 0xd4, 0xa0, 0x13, 0xbd, 0xf9, 0x1d, 0x12, 0x3e,
        0x21, 0x39, 0xfb, 0x72, 0xe0, 0x05, 0x3d, 0xc3, 0xe5, 0x50,
        0xa8, 0x5d, 0x85, 0xa3, 0xea, 0x5f, 0x1c, 0xb2, 0x3f, 0xea,
        0x6d, 0x03, 0x91, 0x55, 0xd8, 0x19, 0x0a, 0x21, 0x12, 0x16,
        0xd9, 0x12, 0xc4, 0xe6, 0x07, 0x18, 0x5b, 0x26, 0xa4, 0xae,
        0xed, 0x2b, 0xb7, 0xa6, 0xed, 0xf8, 0xad, 0xec, 0x77, 0xe6,
        0x7f, 0x4f, 0x76, 0x00, 0xc0, 0xfa, 0x15, 0x92, 0xb4, 0x2c,
        0x22, 0xc2, 0xeb, 0x6a, 0xad, 0x14, 0x05, 0xb2, 0xe5, 0x8a,
        0x9e, 0x85, 0x83, 0xcc, 0x04, 0xf1, 0x56, 0x78, 0x44, 0x5e,
        0xde, 0xe0, 0x60, 0x1a, 0x65, 0x79, 0x31, 0x23, 0x05, 0xbb,
        0x01, 0xff, 0xdd, 0x2e, 0xb7, 0xb3, 0xaa, 0x74, 0xe0, 0xa5,
        0x94, 0xaf, 0x4b, 0xde, 0x58, 0x0f, 0x55, 0xde, 0x33, 0xf6,
        0xe3, 0xd6, 0x34, 0x36, 0x57, 0xd6, 0x79, 0x91, 0x2e, 0xbe,
        0x3b, 0xd9, 0x4e, 0xb6, 0x9d, 0x21, 0x5c, 0xd3, 0x48, 0x14,
        0x7f, 0x4a, 0xc4, 0x60, 0xa9, 0x29, 0xf8, 0x53, 0x7f, 0x88,
        0x11, 0x2d, 0xb5, 0xc5, 0x2d, 0x6f, 0xee, 0x85, 0x0b, 0xf7,
        0x8d, 0x9a, 0xbe, 0xb0, 0x42, 0xf2, 0x2e, 0x71, 0xaf, 0x19,
        0x31, 0x6d, 0xec, 0xcd, 0x6f, 0x2b, 0x23, 0xdf, 0xb4, 0x40,
        0xaf, 0x2c, 0x0a, 0xc3, 0x1b, 0x7d, 0x7d, 0x03, 0x1d, 0x4b,
        0xf3, 0xb5, 0xe0, 0x85, 0xd8, 0xdf, 0x91, 0x6b, 0x0a, 0x69,
        0xf7, 0xf2, 0x69, 0x66, 0x5b, 0xf1, 0xcf, 0x46, 0x7d, 0xe9,
        0x70, 0xfa, 0x6d, 0x7e, 0x75, 0x4e, 0xa9, 0x77, 0xe6, 0x8c,
        0x02, 0xf7, 0x14, 0x4d, 0xa5, 0x41, 0x8f, 0x3f, 0xc1, 0x62,
        0x1e, 0x71, 0x5e, 0x38, 0xb4, 0xd6, 0xe6, 0xe1, 0x4b, 0xc2,
        0x2c, 0x30, 0x83, 0x81, 0x6f, 0x49, 0x2e, 0x96, 0xe6, 0xc9,
        0x9a, 0xf7, 0x5d, 0x09, 0xa0, 0x55, 0x02, 0xa5, 0x3a, 0x25,
        0x23, 0xd0, 0x92, 0xc3, 0xa3, 0xe3, 0x0e, 0x12, 0x2f, 0x4d,
        0xef, 0xf3, 0x55, 0x5a, 0xbe, 0xe6, 0x19, 0x86, 0x31, 0xab,
        0x75, 0x9a, 0xd3, 0xf0, 0x2c, 0xc5, 0x41, 0x92, 0xd9, 0x1f,
        0x5f, 0x11, 0x8c, 0x75, 0x1c, 0x63, 0xd0, 0x02, 0x80, 0x2c,
        0x68, 0xcb, 0x93, 0xfb, 0x51, 0x73, 0x49, 0xb4, 0x60, 0xda,
        0xe2, 0x26, 0xaf, 0xa9, 0x46, 0x12, 0xb8, 0xec, 0x50, 0xdd,
        0x12, 0x06, 0x5f, 0xce, 0x59, 0xe6, 0xf6, 0x1c, 0xe0, 0x54,
        0x10, 0xad, 0xf6, 0xcd, 0x98, 0xcc, 0x0f, 0xfb, 0xcb, 0x41,
        0x14, 0x9d, 0xed, 0xe4, 0xb4, 0x74, 0x5f, 0x09, 0x60, 0xc7,
        0x12, 0xf6, 0x7b, 0x3c, 0x8f, 0xa7, 0x20, 0xbc, 0xe4, 0xb1,
        0xef, 0xeb, 0xa4, 0x93, 0xc5, 0x06, 0xca, 0x9a, 0x27, 0x9d,
        0x87, 0xf3, 0xde, 0xca, 0xe5, 0xe7, 0xf6, 0x1c, 0x01, 0x65,
        0x5b, 0xfb, 0x19, 0x79, 0x6e, 0x08, 0x26, 0xc5, 0xc8, 0x28,
        0x0e, 0xb6, 0x3b, 0x07, 0x08, 0xc1, 0x02, 0x82, 0x01, 0x01,
        0x00, 0xe8, 0x1c, 0x73, 0xa6, 0xb8, 0xe0, 0x0e, 0x6d, 0x8d,
        0x1b, 0xb9, 0x53, 0xed, 0x58, 0x94, 0xe6, 0x1d, 0x60, 0x14,
        0x5c, 0x76, 0x43, 0xc4, 0x58, 0x19, 0xc4, 0x24, 0xe8, 0xbc,
        0x1b, 0x3b, 0x0b, 0x13, 0x24, 0x45, 0x54, 0x0e, 0xcc, 0x37,
        0xf0, 0xe0, 0x63, 0x7d, 0xc3, 0xf7, 0xfb, 0x81, 0x74, 0x81,
        0xc4, 0x0f, 0x1a, 0x21, 0x48, 0xaf, 0xce, 0xc1, 0xc4, 0x94,
        0x18, 0x06, 0x44, 0x8d, 0xd3, 0xd2, 0x22, 0x2d, 0x2d, 0x3e,
        0x5a, 0x31, 0xdc, 0x95, 0x8e, 0xf4, 0x41, 0xfc, 0x58, 0xc9,
        0x40, 0x92, 0x17, 0x5f, 0xe3, 0xda, 0xac, 0x9e, 0x3f, 0x1c,
        0x2a, 0x6b, 0x58, 0x5f, 0x48, 0x78, 0x20, 0xb1, 0xaf, 0x24,
        0x9b, 0x3c, 0x20, 0x8b, 0x93, 0x25, 0x9e, 0xe6, 0x6b, 0xbc,
        0x13, 0x42, 0x14, 0x6c, 0x36, 0x31, 0xff, 0x7a, 0xd1, 0xc1,
        0x1a, 0x26, 0x14, 0x7f, 0xa9, 0x76, 0xa7, 0x0c, 0xf8, 0xcc,
        0xed, 0x07, 0x6a, 0xd2, 0xdf, 0x62, 0xee, 0x0a, 0x7c, 0x84,
        0xcb, 0x49, 0x90, 0xb2, 0x03, 0x0d, 0xa2, 0x82, 0x06, 0x77,
        0xf1, 0xcd, 0x67, 0xf2, 0x47, 0x21, 0x02, 0x3f, 0x43, 0x21,
        0xf0, 0x46, 0x30, 0x62, 0x51, 0x72, 0xb1, 0xe7, 0x48, 0xc6,
        0x67, 0x12, 0xcd, 0x9e, 0xd6, 0x15, 0xe5, 0x21, 0xed, 0xfa,
        0x8f, 0x30, 0xa6, 0x41, 0xfe, 0xb6, 0xfa, 0x8f, 0x34, 0x14,
        0x19, 0xe8, 0x11, 0xf7, 0xa5, 0x77, 0x3e, 0xb7, 0xf9, 0x39,
        0x07, 0x8c, 0x67, 0x2a, 0xab, 0x7b, 0x08, 0xf8, 0xb0, 0x06,
        0xa8, 0xea, 0x2f, 0x8f, 0xfa, 0xcc, 0xcc, 0x40, 0xce, 0xf3,
        0x70, 0x4f, 0x3f, 0x7f, 0xe2, 0x0c, 0xea, 0x76, 0x4a, 0x35,
        0x4e, 0x47, 0xad, 0x2b, 0xa7, 0x97, 0x5d, 0x74, 0x43, 0x97,
        0x90, 0xd2, 0xfb, 0xd9, 0xf9, 0x96, 0x01, 0x33, 0x05, 0xed,
        0x7b, 0x03, 0x05, 0xad, 0xf8, 0x49, 0x03, 0x02, 0x82, 0x01,
        0x01, 0x00, 0xd4, 0x40, 0x17, 0x66, 0x10, 0x92, 0x95, 0xc8,
        0xec, 0x62, 0xa9, 0x7a, 0xcb, 0x93, 0x8e, 0xe6, 0x53, 0xd4,
        0x80, 0x48, 0x27, 0x4b, 0x41, 0xce, 0x61, 0xdf, 0xbf, 0x94,
        0xa4, 0x3d, 0x71, 0x03, 0x0b, 0xed, 0x25, 0x71, 0x98, 0xa4,
        0xd6, 0xd5, 0x4a, 0x57, 0xf5, 0x6c, 0x1b, 0xda, 0x21, 0x7d,
        0x35, 0x45, 0xb3, 0xf3, 0x6a, 0xd9, 0xd3, 0x43, 0xe8, 0x5c,
        0x54, 0x1c, 0x83, 0x1b, 0xb4, 0x5f, 0xf2, 0x97, 0x24, 0x2e,
        0xdc, 0x40, 0xde, 0x92, 0x23, 0x59, 0x8e, 0xbc, 0xd2, 0xa1,
        0xf2, 0xe0, 0x4c, 0xdd, 0x0b, 0xd1, 0xe7, 0xae, 0x65, 0xbc,
        0xb5, 0xf5, 0x5b, 0x98, 0xe9, 0xd7, 0xc2, 0xb7, 0x0e, 0x55,
        0x71, 0x0e, 0x3c, 0x0a, 0x24, 0x6b, 0xa6, 0xe6, 0x14, 0x61,
        0x11, 0xfd, 0x33, 0x42, 0x99, 0x2b, 0x84, 0x77, 0x74, 0x92,
        0x91, 0xf5, 0x79, 0x79, 0xcf, 0xad, 0x8e, 0x04, 0xef, 0x80,
        0x1e, 0x57, 0xf4, 0x14, 0xf5, 0x35, 0x09, 0x74, 0xb2, 0x13,
        0x71, 0x58, 0x6b, 0xea, 0x32, 0x5d, 0xf3, 0xd3, 0x76, 0x48,
        0x39, 0x10, 0x23, 0x84, 0x9d, 0xbe, 0x92, 0x77, 0x4a, 0xed,
        0x70, 0x3e, 0x1a, 0xa2, 0x6c, 0xb3, 0x81, 0x00, 0xc3, 0xc9,
        0xe4, 0x52, 0xc8, 0x24, 0x88, 0x0c, 0x41, 0xad, 0x87, 0x5a,
        0xea, 0xa3, 0x7a, 0x85, 0x1c, 0x5e, 0x31, 0x7f, 0xc3, 0x35,
        0xc6, 0xfa, 0x10, 0xc8, 0x75, 0x10, 0xc4, 0x96, 0x99, 0xe7,
        0xfe, 0x01, 0xb4, 0x74, 0xdb, 0xb4, 0x11, 0xc3, 0xc8, 0x8c,
        0xf6, 0xf7, 0x3b, 0x66, 0x50, 0xfc, 0xdb, 0xeb, 0xca, 0x47,
        0x85, 0x89, 0xe1, 0x65, 0xd9, 0x62, 0x34, 0x3c, 0x70, 0xd8,
        0x2e, 0xb4, 0x2f, 0x65, 0x3c, 0x4a, 0xa6, 0x2a, 0xe7, 0xc7,
        0xd8, 0x41, 0x8f, 0x8a, 0x43, 0xbf, 0x42, 0xf2, 0x4d, 0xbc,
        0xfc, 0x9e, 0x27, 0x95, 0xfb, 0x75, 0xff, 0xab, 0x02, 0x82,
        0x01, 0x00, 0x41, 0x2f, 0x44, 0x57, 0x6d, 0x12, 0x17, 0x5b,
        0x32, 0xc6, 0xb7, 0x6c, 0x57, 0x7a, 0x8a, 0x0e, 0x79, 0xef,
        0x72, 0xa8, 0x68, 0xda, 0x2d, 0x38, 0xe4, 0xbb, 0x8d, 0xf6,
        0x02, 0x65, 0xcf, 0x56, 0x13, 0xe1, 0x1a, 0xcb, 0x39, 0x80,
        0xa6, 0xb1, 0x32, 0x03, 0x1e, 0xdd, 0xbb, 0x35, 0xd9, 0xac,
        0x43, 0x89, 0x31, 0x08, 0x90, 0x92, 0x5e, 0x35, 0x3d, 0x7b,
        0x9c, 0x6f, 0x86, 0xcb, 0x17, 0xdd, 0x85, 0xe4, 0xed, 0x35,
        0x08, 0x8e, 0xc1, 0xf4, 0x05, 0xd8, 0x68, 0xc6, 0x63, 0x3c,
        0xf7, 0xff, 0xf7, 0x47, 0x33, 0x39, 0xc5, 0x3e, 0xb7, 0x0e,
        0x58, 0x35, 0x9d, 0x81, 0xea, 0xf8, 0x6a, 0x2c, 0x1c, 0x5a,
        0x68, 0x78, 0x64, 0x11, 0x6b, 0xc1, 0x3e, 0x4e, 0x7a, 0xbd,
        0x84, 0xcb, 0x0f, 0xc2, 0xb6, 0x85, 0x1d, 0xd3, 0x76, 0xc5,
        0x93, 0x6a, 0x69, 0x89, 0x56, 0x34, 0xdc, 0x4a, 0x9b, 0xbc,
        0xff, 0xa8, 0x0d, 0x6e, 0x35, 0x9c, 0x60, 0xa7, 0x23, 0x30,
        0xc7, 0x06, 0x64, 0x39, 0x8b, 0x94, 0x89, 0xee, 0xba, 0x7f,
        0x60, 0x8d, 0xfa, 0xb6, 0x97, 0x76, 0xdc, 0x51, 0x4a, 0x3c,
        0xeb, 0x3a, 0x14, 0x2c, 0x20, 0x60, 0x69, 0x4a, 0x86, 0xfe,
        0x8c, 0x21, 0x84, 0x49, 0x54, 0xb3, 0x20, 0xe1, 0x01, 0x7f,
        0x58, 0xdf, 0x7f, 0xb5, 0x21, 0x51, 0x8c, 0x47, 0x9f, 0x91,
        0xeb, 0x97, 0x3e, 0xf2, 0x54, 0xcf, 0x16, 0x46, 0xf9, 0xd9,
        0xb6, 0xe7, 0x64, 0xc9, 0xd0, 0x54, 0xea, 0x2f, 0xa1, 0xcf,
        0xa5, 0x7f, 0x28, 0x8d, 0x84, 0xec, 0xd5, 0x39, 0x03, 0x76,
        0x5b, 0x2d, 0x8e, 0x43, 0xf2, 0x01, 0x24, 0xc9, 0x6f, 0xc0,
        0xf5, 0x69, 0x6f, 0x7d, 0xb5, 0x85, 0xd2, 0x5f, 0x7f, 0x78,
        0x40, 0x07, 0x7f, 0x09, 0x15, 0xb5, 0x1f, 0x28, 0x65, 0x10,
        0xe4, 0x19, 0xa8, 0xc6, 0x9e, 0x8d, 0xdc, 0xcb, 0x02, 0x82,
        0x01, 0x00, 0x13, 0x01, 0xee, 0x56, 0x80, 0x93, 0x70, 0x00,
        0x7f, 0x52, 0xd2, 0x94, 0xa1, 0x98, 0x84, 0x4a, 0x92, 0x25,
        0x4c, 0x9b, 0xa9, 0x91, 0x2e, 0xc2, 0x79, 0xb7, 0x5c, 0xe3,
        0xc5, 0xd5, 0x8e, 0xc2, 0x54, 0x16, 0x17, 0xad, 0x55, 0x9b,
        0x25, 0x76, 0x12, 0x63, 0x50, 0x22, 0x2f, 0x58, 0x58, 0x79,
        0x6b, 0x04, 0xe3, 0xf9, 0x9f, 0x8f, 0x04, 0x41, 0x67, 0x94,
        0xa5, 0x1f, 0xac, 0x8a, 0x15, 0x9c, 0x26, 0x10, 0x6c, 0xf8,
        0x19, 0x57, 0x61, 0xd7, 0x3a, 0x7d, 0x31, 0xb0, 0x2d, 0x38,
        0xbd, 0x94, 0x62, 0xad, 0xc4, 0xfa, 0x36, 0x42, 0x42, 0xf0,
        0x24, 0x67, 0x65, 0x9d, 0x8b, 0x0b, 0x7c, 0x6f, 0x82, 0x44,
        0x1a, 0x8c, 0xc8, 0xc9, 0xab, 0xbb, 0x4c, 0x45, 0xfc, 0x7b,
        0x38, 0xee, 0x30, 0xe1, 0xfc, 0xef, 0x8d, 0xbc, 0x58, 0xdf,
        0x2b, 0x5d, 0x0d, 0x54, 0xe0, 0x49, 0x4d, 0x97, 0x99, 0x8f,
        0x22, 0xa8, 0x83, 0xbe, 0x40, 0xbb, 0x50, 0x2e, 0x78, 0x28,
        0x0f, 0x95, 0x78, 0x8c, 0x8f, 0x98, 0x24, 0x56, 0xc2, 0x97,
        0xf3, 0x2c, 0x43, 0xd2, 0x03, 0x82, 0x66, 0x81, 0x72, 0x5f,
        0x53, 0x16, 0xec, 0xb1, 0xb1, 0x04, 0x5e, 0x40, 0x20, 0x48,
        0x7b, 0x3f, 0x02, 0x97, 0x6a, 0xeb, 0x96, 0x12, 0x21, 0x35,
        0xfe, 0x1f, 0x47, 0xc0, 0x95, 0xea, 0xc5, 0x8a, 0x08, 0x84,
        0x4f, 0x5e, 0x63, 0x94, 0x60, 0x0f, 0x71, 0x5b, 0x7f, 0x4a,
        0xec, 0x4f, 0x60, 0xc6, 0xba, 0x4a, 0x24, 0xf1, 0x20, 0x8b,
        0xa7, 0x2e, 0x3a, 0xce, 0x8d, 0xe0, 0x27, 0x1d, 0xb5, 0x8e,
        0xb4, 0x21, 0xc5, 0xe2, 0xa6, 0x16, 0x0a, 0x51, 0x83, 0x55,
        0x88, 0xd1, 0x30, 0x11, 0x63, 0xd5, 0xd7, 0x8d, 0xae, 0x16,
        0x12, 0x82, 0xc4, 0x85, 0x00, 0x4e, 0x27, 0x83, 0xa5, 0x7c,
        0x90, 0x2e, 0xe5, 0xa2, 0xa3, 0xd3, 0x4c, 0x63, 0x02, 0x82,
        0x01, 0x01, 0x00, 0x86, 0x08, 0x98, 0x98, 0xa5, 0x00, 0x05,
        0x39, 0x77, 0xd9, 0x66, 0xb3, 0xcf, 0xca, 0xa0, 0x71, 0xb3,
        0x50, 0xce, 0x3d, 0xb1, 0x93, 0x95, 0x35, 0xc4, 0xd4, 0x2e,
        0x90, 0xdf, 0x0f, 0xfc, 0x60, 0xc1, 0x94, 0x68, 0x61, 0x43,
        0xca, 0x9a, 0x23, 0x4a, 0x1e, 0x45, 0x72, 0x99, 0xb5, 0x1e,
        0x61, 0x8d, 0x77, 0x0f, 0xa0, 0xbb, 0xd7, 0x77, 0xb4, 0x2a,
        0x15, 0x11, 0x88, 0x2d, 0xb3, 0x56, 0x61, 0x5e, 0x6a, 0xed,
        0xa4, 0x46, 0x4a, 0x3f, 0x50, 0x11, 0xd6, 0xba, 0xb6, 0xd7,
        0x95, 0x65, 0x53, 0xc3, 0xa1, 0x8f, 0xe0, 0xa3, 0xf5, 0x1c,
        0xfd, 0xaf, 0x6e, 0x43, 0xd7, 0x17, 0xa7, 0xd3, 0x81, 0x1b,
        0xa4, 0xdf, 0xe0, 0x97, 0x8a, 0x46, 0x03, 0xd3, 0x46, 0x0e,
        0x83, 0x48, 0x4e, 0xd2, 0x02, 0xcb, 0xc0, 0xad, 0x79, 0x95,
        0x8c, 0x96, 0xba, 0x40, 0x34, 0x11, 0x71, 0x5e, 0xe9, 0x11,
        0xf9, 0xc5, 0x4a, 0x5e, 0x91, 0x9d, 0xf5, 0x92, 0x4f, 0xeb,
        0xc6, 0x70, 0x02, 0x2d, 0x3d, 0x04, 0xaa, 0xe9, 0x3a, 0x8e,
        0xd5, 0xa8, 0xad, 0xf7, 0xce, 0x0d, 0x16, 0xb2, 0xec, 0x0a,
        0x9c, 0xf5, 0x94, 0x39, 0xb9, 0x8a, 0xfc, 0x1e, 0xf9, 0xcc,
        0xf2, 0x5f, 0x21, 0x31, 0x74, 0x72, 0x6b, 0x64, 0xae, 0x35,
        0x61, 0x8d, 0x0d, 0xcb, 0xe7, 0xda, 0x39, 0xca, 0xf3, 0x21,
        0x66, 0x0b, 0x95, 0xd7, 0x0a, 0x7c, 0xca, 0xa1, 0xa9, 0x5a,
        0xe8, 0xac, 0xe0, 0x71, 0x54, 0xaf, 0x28, 0xcf, 0xd5, 0x70,
        0x89, 0xe0, 0xf3, 0x9e, 0x43, 0x6c, 0x8d, 0x7b, 0x99, 0x01,
        0x68, 0x4d, 0xa1, 0x45, 0x46, 0x0c, 0x43, 0xbc, 0xcc, 0x2c,
        0xdd, 0xc5, 0x46, 0xc8, 0x4e, 0x0e, 0xbe, 0xed, 0xb9, 0x26,
        0xab, 0x2e, 0xdb, 0xeb, 0x8f, 0xff, 0xdb, 0xb0, 0xc6, 0x55,
        0xaf, 0xf8, 0x2a, 0x91, 0x9d, 0x50, 0x44, 0x21, 0x17,
};

static const unsigned char key16[] = {
        0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
        0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
};
static const unsigned char key24[] = {
        0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
        0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
        0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34,
};
static const unsigned char key32[] = {
        0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
        0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
        0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34,
        0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56,
};

static void
sig_done(int sig)
{
        run = 0;
}

#define START   TM_RESET
#define STOP    TM_GET

static double
time_f(int s)
{
        if (usertime)
                return app_timer_user(s);

        return app_timer_real(s);
}

static const int KDF1_SHA1_len = 20;
static void *
KDF1_SHA1(const void *in, size_t inlen, void *out, size_t * outlen)
{
#ifndef OPENSSL_NO_SHA
        if (*outlen < SHA_DIGEST_LENGTH)
                return NULL;
        else
                *outlen = SHA_DIGEST_LENGTH;
        return SHA1(in, inlen, out);
#else
        return NULL;
#endif                          /* OPENSSL_NO_SHA */
}

int
speed_main(int argc, char **argv)
{
        unsigned char *real_buf = NULL, *real_buf2 = NULL;
        unsigned char *buf = NULL, *buf2 = NULL;
        size_t unaligned = 0;
        int mret = 1;
        long count = 0;
        int i, j, k;
        long rsa_count;
        unsigned rsa_num;
        unsigned char md[EVP_MAX_MD_SIZE];

#ifndef OPENSSL_NO_RC4
        RC4_KEY rc4_ks;
#endif
#ifndef OPENSSL_NO_RC2
        RC2_KEY rc2_ks;
#endif
#ifndef OPENSSL_NO_IDEA
        IDEA_KEY_SCHEDULE idea_ks;
#endif
#ifndef OPENSSL_NO_BF
        BF_KEY bf_ks;
#endif
#ifndef OPENSSL_NO_CAST
        CAST_KEY cast_ks;
#endif
        unsigned char DES_iv[8];
        unsigned char iv[2 * 16];
#ifndef OPENSSL_NO_DES
        static DES_cblock key = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0};
        static DES_cblock key2 = {0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12};
        static DES_cblock key3 = {0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34};
        DES_key_schedule sch;
        DES_key_schedule sch2;
        DES_key_schedule sch3;
#endif
#ifndef OPENSSL_NO_AES
        AES_KEY aes_ks1, aes_ks2, aes_ks3;
#endif
#ifndef OPENSSL_NO_CAMELLIA
        CAMELLIA_KEY camellia_ks1, camellia_ks2, camellia_ks3;
#endif
        double d = 0.0;

        RSA *rsa_key[RSA_NUM];
        static unsigned int rsa_bits[RSA_NUM] = {512, 1024, 2048, 4096};
        static const unsigned char *rsa_data[RSA_NUM] =
        {test512, test1024, test2048, test4096};
        static int rsa_data_length[RSA_NUM] = {
                sizeof(test512), sizeof(test1024),
        sizeof(test2048), sizeof(test4096)};
        DSA *dsa_key[DSA_NUM];
        static unsigned int dsa_bits[DSA_NUM] = {512, 1024, 2048};
#ifndef OPENSSL_NO_EC
        /*
         * We only test over the following curves as they are representative,
         * To add tests over more curves, simply add the curve NID and curve
         * name to the following arrays and increase the EC_NUM value
         * accordingly.
         */
        static unsigned int test_curves[EC_NUM] = {
                NID_secp224r1,
                NID_X9_62_prime256v1,
                NID_secp384r1,
                NID_secp521r1,
        };
        static const char *test_curves_names[EC_NUM] = {
                "nistp224",
                "nistp256",
                "nistp384",
                "nistp521",
        };
        static int test_curves_bits[EC_NUM] = {
                224, 256, 384, 521,
        };

#endif

        unsigned char ecdsasig[256];
        unsigned int ecdsasiglen;
        EC_KEY *ecdsa[EC_NUM];

        EC_KEY *ecdh_a[EC_NUM], *ecdh_b[EC_NUM];
        unsigned char secret_a[MAX_ECDH_SIZE], secret_b[MAX_ECDH_SIZE];
        int secret_size_a, secret_size_b;
        int ecdh_checks = 0;
        int secret_idx = 0;

        int rsa_doit[RSA_NUM];
        int dsa_doit[DSA_NUM];
        int ecdsa_doit[EC_NUM];
        int ecdh_doit[EC_NUM];
        int mlkem_doit[MLKEM_NUM];
        int doit[ALGOR_NUM];
        int pr_header = 0;
        const EVP_CIPHER *evp_cipher = NULL;
        const EVP_MD *evp_md = NULL;
        int decrypt = 0;
        int multi = 0;
        struct sigaction sa;
        const char *errstr = NULL;

        if (pledge("stdio proc", NULL) == -1) {
                perror("pledge");
                exit(1);
        }

        usertime = -1;

        memset(results, 0, sizeof(results));
        memset(dsa_key, 0, sizeof(dsa_key));
        for (i = 0; i < EC_NUM; i++)
                ecdsa[i] = NULL;
        for (i = 0; i < EC_NUM; i++) {
                ecdh_a[i] = NULL;
                ecdh_b[i] = NULL;
        }

        memset(rsa_key, 0, sizeof(rsa_key));
        for (i = 0; i < RSA_NUM; i++)
                rsa_key[i] = NULL;

        if ((buf = real_buf = malloc(BUFSIZE + MAX_UNALIGN)) == NULL) {
                BIO_printf(bio_err, "out of memory\n");
                goto end;
        }
        if ((buf2 = real_buf2 = malloc(BUFSIZE + MAX_UNALIGN)) == NULL) {
                BIO_printf(bio_err, "out of memory\n");
                goto end;
        }
        memset(DES_iv, 0, sizeof(DES_iv));
        memset(iv, 0, sizeof(iv));

        for (i = 0; i < ALGOR_NUM; i++)
                doit[i] = 0;
        for (i = 0; i < RSA_NUM; i++)
                rsa_doit[i] = 0;
        for (i = 0; i < DSA_NUM; i++)
                dsa_doit[i] = 0;
        for (i = 0; i < EC_NUM; i++)
                ecdsa_doit[i] = 0;
        for (i = 0; i < EC_NUM; i++)
                ecdh_doit[i] = 0;
        for (i = 0; i < MLKEM_NUM; i++)
                mlkem_doit[i] = 0;


        j = 0;
        argc--;
        argv++;
        while (argc) {
                if (argc > 0 && strcmp(*argv, "-elapsed") == 0) {
                        usertime = 0;
                        j--;    /* Otherwise, -elapsed gets confused with an
                                 * algorithm. */
                } else if (argc > 0 && strcmp(*argv, "-evp") == 0) {
                        argc--;
                        argv++;
                        if (argc == 0) {
                                BIO_printf(bio_err, "no EVP given\n");
                                goto end;
                        }
                        evp_cipher = EVP_get_cipherbyname(*argv);
                        if (!evp_cipher) {
                                evp_md = EVP_get_digestbyname(*argv);
                        }
                        if (!evp_cipher && !evp_md) {
                                BIO_printf(bio_err, "%s is an unknown cipher or digest\n", *argv);
                                goto end;
                        }
                        doit[D_EVP] = 1;
                } else if (argc > 0 && strcmp(*argv, "-decrypt") == 0) {
                        decrypt = 1;
                        j--;    /* Otherwise, -decrypt gets confused with an
                                 * algorithm. */
                } else if (argc > 0 && strcmp(*argv, "-multi") == 0) {
                        argc--;
                        argv++;
                        if (argc == 0) {
                                BIO_printf(bio_err, "no multi count given\n");
                                goto end;
                        }
                        multi = strtonum(argv[0], 1, INT_MAX, &errstr);
                        if (errstr) {
                                BIO_printf(bio_err, "bad multi count: %s", errstr);
                                goto end;
                        }
                        j--;    /* Otherwise, -multi gets confused with an
                                 * algorithm. */
                } else if (argc > 0 && strcmp(*argv, "-unaligned") == 0) {
                        argc--;
                        argv++;
                        if (argc == 0) {
                                BIO_printf(bio_err, "no alignment offset given\n");
                                goto end;
                        }
                        unaligned = strtonum(argv[0], 0, MAX_UNALIGN, &errstr);
                        if (errstr) {
                                BIO_printf(bio_err, "bad alignment offset: %s",
                                    errstr);
                                goto end;
                        }
                        buf = real_buf + unaligned;
                        buf2 = real_buf2 + unaligned;
                        j--;    /* Otherwise, -unaligned gets confused with an
                                 * algorithm. */
                } else if (argc > 0 && strcmp(*argv, "-mr") == 0) {
                        mr = 1;
                        j--;    /* Otherwise, -mr gets confused with an
                                 * algorithm. */
                } else
#ifndef OPENSSL_NO_MD4
                if (strcmp(*argv, "md4") == 0)
                        doit[D_MD4] = 1;
                else
#endif
#ifndef OPENSSL_NO_MD5
                if (strcmp(*argv, "md5") == 0)
                        doit[D_MD5] = 1;
                else
#endif
#ifndef OPENSSL_NO_MD5
                if (strcmp(*argv, "hmac") == 0)
                        doit[D_HMAC] = 1;
                else
#endif
#ifndef OPENSSL_NO_SHA
                if (strcmp(*argv, "sha1") == 0)
                        doit[D_SHA1] = 1;
                else if (strcmp(*argv, "sha") == 0)
                        doit[D_SHA1] = 1,
                            doit[D_SHA256] = 1,
                            doit[D_SHA512] = 1;
                else
#ifndef OPENSSL_NO_SHA256
                if (strcmp(*argv, "sha256") == 0)
                        doit[D_SHA256] = 1;
                else
#endif
#ifndef OPENSSL_NO_SHA512
                if (strcmp(*argv, "sha512") == 0)
                        doit[D_SHA512] = 1;
                else
#endif
#endif
#ifndef OPENSSL_NO_RIPEMD
                if (strcmp(*argv, "ripemd") == 0)
                        doit[D_RMD160] = 1;
                else if (strcmp(*argv, "rmd160") == 0)
                        doit[D_RMD160] = 1;
                else if (strcmp(*argv, "ripemd160") == 0)
                        doit[D_RMD160] = 1;
                else
#endif
#ifndef OPENSSL_NO_RC4
                if (strcmp(*argv, "rc4") == 0)
                        doit[D_RC4] = 1;
                else
#endif
#ifndef OPENSSL_NO_DES
                if (strcmp(*argv, "des-cbc") == 0)
                        doit[D_CBC_DES] = 1;
                else if (strcmp(*argv, "des-ede3") == 0)
                        doit[D_EDE3_DES] = 1;
                else
#endif
#ifndef OPENSSL_NO_AES
                if (strcmp(*argv, "aes-128-cbc") == 0)
                        doit[D_CBC_128_AES] = 1;
                else if (strcmp(*argv, "aes-192-cbc") == 0)
                        doit[D_CBC_192_AES] = 1;
                else if (strcmp(*argv, "aes-256-cbc") == 0)
                        doit[D_CBC_256_AES] = 1;
                else if (strcmp(*argv, "aes-128-ige") == 0)
                        doit[D_IGE_128_AES] = 1;
                else if (strcmp(*argv, "aes-192-ige") == 0)
                        doit[D_IGE_192_AES] = 1;
                else if (strcmp(*argv, "aes-256-ige") == 0)
                        doit[D_IGE_256_AES] = 1;
                else
#endif
#ifndef OPENSSL_NO_CAMELLIA
                if (strcmp(*argv, "camellia-128-cbc") == 0)
                        doit[D_CBC_128_CML] = 1;
                else if (strcmp(*argv, "camellia-192-cbc") == 0)
                        doit[D_CBC_192_CML] = 1;
                else if (strcmp(*argv, "camellia-256-cbc") == 0)
                        doit[D_CBC_256_CML] = 1;
                else
#endif
#ifndef RSA_NULL
                if (strcmp(*argv, "openssl") == 0) {
                        RSA_set_default_method(RSA_PKCS1_SSLeay());
                        j--;
                } else
#endif
                if (strcmp(*argv, "dsa512") == 0)
                        dsa_doit[R_DSA_512] = 2;
                else if (strcmp(*argv, "dsa1024") == 0)
                        dsa_doit[R_DSA_1024] = 2;
                else if (strcmp(*argv, "dsa2048") == 0)
                        dsa_doit[R_DSA_2048] = 2;
                else if (strcmp(*argv, "rsa512") == 0)
                        rsa_doit[R_RSA_512] = 2;
                else if (strcmp(*argv, "rsa1024") == 0)
                        rsa_doit[R_RSA_1024] = 2;
                else if (strcmp(*argv, "rsa2048") == 0)
                        rsa_doit[R_RSA_2048] = 2;
                else if (strcmp(*argv, "rsa4096") == 0)
                        rsa_doit[R_RSA_4096] = 2;
                else
#ifndef OPENSSL_NO_RC2
                if (strcmp(*argv, "rc2-cbc") == 0)
                        doit[D_CBC_RC2] = 1;
                else if (strcmp(*argv, "rc2") == 0)
                        doit[D_CBC_RC2] = 1;
                else
#endif
#ifndef OPENSSL_NO_IDEA
                if (strcmp(*argv, "idea-cbc") == 0)
                        doit[D_CBC_IDEA] = 1;
                else if (strcmp(*argv, "idea") == 0)
                        doit[D_CBC_IDEA] = 1;
                else
#endif
#ifndef OPENSSL_NO_BF
                if (strcmp(*argv, "bf-cbc") == 0)
                        doit[D_CBC_BF] = 1;
                else if (strcmp(*argv, "blowfish") == 0)
                        doit[D_CBC_BF] = 1;
                else if (strcmp(*argv, "bf") == 0)
                        doit[D_CBC_BF] = 1;
                else
#endif
#ifndef OPENSSL_NO_CAST
                if (strcmp(*argv, "cast-cbc") == 0)
                        doit[D_CBC_CAST] = 1;
                else if (strcmp(*argv, "cast") == 0)
                        doit[D_CBC_CAST] = 1;
                else if (strcmp(*argv, "cast5") == 0)
                        doit[D_CBC_CAST] = 1;
                else
#endif
#ifndef OPENSSL_NO_DES
                if (strcmp(*argv, "des") == 0) {
                        doit[D_CBC_DES] = 1;
                        doit[D_EDE3_DES] = 1;
                } else
#endif
#ifndef OPENSSL_NO_AES
                if (strcmp(*argv, "aes") == 0) {
                        doit[D_CBC_128_AES] = 1;
                        doit[D_CBC_192_AES] = 1;
                        doit[D_CBC_256_AES] = 1;
                } else if (strcmp(*argv, "ghash") == 0)
                        doit[D_GHASH] = 1;
                else if (strcmp(*argv,"aes-128-gcm") == 0)
                        doit[D_AES_128_GCM]=1;
                else if (strcmp(*argv,"aes-256-gcm") == 0)
                        doit[D_AES_256_GCM]=1;
                else
#endif
#ifndef OPENSSL_NO_CAMELLIA
                if (strcmp(*argv, "camellia") == 0) {
                        doit[D_CBC_128_CML] = 1;
                        doit[D_CBC_192_CML] = 1;
                        doit[D_CBC_256_CML] = 1;
                } else
#endif
#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
                if (strcmp(*argv,"chacha20-poly1305") == 0)
                        doit[D_CHACHA20_POLY1305]=1;
                else
#endif
                if (strcmp(*argv, "rsa") == 0) {
                        rsa_doit[R_RSA_512] = 1;
                        rsa_doit[R_RSA_1024] = 1;
                        rsa_doit[R_RSA_2048] = 1;
                        rsa_doit[R_RSA_4096] = 1;
                } else if (strcmp(*argv, "dsa") == 0) {
                        dsa_doit[R_DSA_512] = 1;
                        dsa_doit[R_DSA_1024] = 1;
                        dsa_doit[R_DSA_2048] = 1;
                } else if (strcmp(*argv, "ecdsap224") == 0)
                        ecdsa_doit[R_EC_P224] = 2;
                else if (strcmp(*argv, "ecdsap256") == 0)
                        ecdsa_doit[R_EC_P256] = 2;
                else if (strcmp(*argv, "ecdsap384") == 0)
                        ecdsa_doit[R_EC_P384] = 2;
                else if (strcmp(*argv, "ecdsap521") == 0)
                        ecdsa_doit[R_EC_P521] = 2;
                else if (strcmp(*argv, "ecdsa") == 0) {
                        for (i = 0; i < EC_NUM; i++)
                                ecdsa_doit[i] = 1;
                } else if (strcmp(*argv, "ecdhp224") == 0)
                        ecdh_doit[R_EC_P224] = 2;
                else if (strcmp(*argv, "ecdhp256") == 0)
                        ecdh_doit[R_EC_P256] = 2;
                else if (strcmp(*argv, "ecdhp384") == 0)
                        ecdh_doit[R_EC_P384] = 2;
                else if (strcmp(*argv, "ecdhp521") == 0)
                        ecdh_doit[R_EC_P521] = 2;
                else if (strcmp(*argv, "ecdh") == 0) {
                        for (i = 0; i < EC_NUM; i++)
                                ecdh_doit[i] = 1;
                } else if (strcmp(*argv, "mlkem") == 0) {
                        mlkem_doit[R_MLKEM_768] = 1;
                        mlkem_doit[R_MLKEM_1024] = 1;
                } else if (strcmp(*argv, "mlkem768") == 0) {
                        mlkem_doit[R_MLKEM_768] = 2;
                } else if (strcmp(*argv, "mlkem1024") == 0) {
                        mlkem_doit[R_MLKEM_1024] = 2;
                } else {
                        BIO_printf(bio_err, "Error: bad option or value\n");
                        BIO_printf(bio_err, "\n");
                        BIO_printf(bio_err, "Available values:\n");
#ifndef OPENSSL_NO_MD4
                        BIO_printf(bio_err, "md4      ");
#endif
#ifndef OPENSSL_NO_MD5
                        BIO_printf(bio_err, "md5      ");
#ifndef OPENSSL_NO_HMAC
                        BIO_printf(bio_err, "hmac     ");
#endif
#endif
#ifndef OPENSSL_NO_SHA1
                        BIO_printf(bio_err, "sha1     ");
#endif
#ifndef OPENSSL_NO_SHA256
                        BIO_printf(bio_err, "sha256   ");
#endif
#ifndef OPENSSL_NO_SHA512
                        BIO_printf(bio_err, "sha512   ");
#endif
#ifndef OPENSSL_NO_RIPEMD160
                        BIO_printf(bio_err, "rmd160");
#endif
#if !defined(OPENSSL_NO_MD2) || \
    !defined(OPENSSL_NO_MD4) || !defined(OPENSSL_NO_MD5) || \
    !defined(OPENSSL_NO_SHA1) || !defined(OPENSSL_NO_RIPEMD160)
                        BIO_printf(bio_err, "\n");
#endif

#ifndef OPENSSL_NO_IDEA
                        BIO_printf(bio_err, "idea-cbc ");
#endif
#ifndef OPENSSL_NO_RC2
                        BIO_printf(bio_err, "rc2-cbc  ");
#endif
#ifndef OPENSSL_NO_BF
                        BIO_printf(bio_err, "bf-cbc   ");
#endif
#ifndef OPENSSL_NO_DES
                        BIO_printf(bio_err, "des-cbc  des-ede3\n");
#endif
#ifndef OPENSSL_NO_AES
                        BIO_printf(bio_err, "aes-128-cbc aes-192-cbc aes-256-cbc ");
                        BIO_printf(bio_err, "aes-128-ige aes-192-ige aes-256-ige\n");
                        BIO_printf(bio_err, "aes-128-gcm aes-256-gcm ");
#endif
#ifndef OPENSSL_NO_CAMELLIA
                        BIO_printf(bio_err, "\n");
                        BIO_printf(bio_err, "camellia-128-cbc camellia-192-cbc camellia-256-cbc ");
#endif
#ifndef OPENSSL_NO_RC4
                        BIO_printf(bio_err, "rc4");
#endif
#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
                        BIO_printf(bio_err," chacha20-poly1305");
#endif
                        BIO_printf(bio_err, "\n");

                        BIO_printf(bio_err, "rsa512   rsa1024  rsa2048  rsa4096\n");

                        BIO_printf(bio_err, "dsa512   dsa1024  dsa2048\n");
                        BIO_printf(bio_err, "ecdsap224 ecdsap256 ecdsap384 ecdsap521\n");
                        BIO_printf(bio_err, "ecdhp224  ecdhp256  ecdhp384  ecdhp521\n");
                        BIO_printf(bio_err, "mlkem768  mlkem1024\n");

#ifndef OPENSSL_NO_IDEA
                        BIO_printf(bio_err, "idea     ");
#endif
#ifndef OPENSSL_NO_RC2
                        BIO_printf(bio_err, "rc2      ");
#endif
#ifndef OPENSSL_NO_DES
                        BIO_printf(bio_err, "des      ");
#endif
#ifndef OPENSSL_NO_AES
                        BIO_printf(bio_err, "aes      ");
#endif
#ifndef OPENSSL_NO_CAMELLIA
                        BIO_printf(bio_err, "camellia ");
#endif
                        BIO_printf(bio_err, "rsa      ");
                        BIO_printf(bio_err, "mlkem    ");
#ifndef OPENSSL_NO_BF
                        BIO_printf(bio_err, "blowfish");
#endif
#if !defined(OPENSSL_NO_IDEA) || !defined(OPENSSL_NO_SEED) || \
    !defined(OPENSSL_NO_RC2) || !defined(OPENSSL_NO_DES) || \
    !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_BF) || \
    !defined(OPENSSL_NO_AES) || !defined(OPENSSL_NO_CAMELLIA)
                        BIO_printf(bio_err, "\n");
#endif

                        BIO_printf(bio_err, "\n");
                        BIO_printf(bio_err, "Available options:\n");
                        BIO_printf(bio_err, "-elapsed        measure time in real time instead of CPU user time.\n");
                        BIO_printf(bio_err, "-evp e          use EVP e.\n");
                        BIO_printf(bio_err, "-decrypt        time decryption instead of encryption (only EVP).\n");
                        BIO_printf(bio_err, "-mr             produce machine readable output.\n");
                        BIO_printf(bio_err, "-multi n        run n benchmarks in parallel.\n");
                        BIO_printf(bio_err, "-unaligned n    use buffers with offset n from proper alignment.\n");
                        goto end;
                }
                argc--;
                argv++;
                j++;
        }

        if (multi && do_multi(multi))
                goto show_res;

        if (j == 0) {
                for (i = 0; i < ALGOR_NUM; i++) {
                        if (i != D_EVP)
                                doit[i] = 1;
                }
                for (i = 0; i < RSA_NUM; i++)
                        rsa_doit[i] = 1;
                for (i = 0; i < DSA_NUM; i++)
                        dsa_doit[i] = 1;
                for (i = 0; i < EC_NUM; i++)
                        ecdsa_doit[i] = 1;
                for (i = 0; i < EC_NUM; i++)
                        ecdh_doit[i] = 1;
                for (i = 0; i < MLKEM_NUM; i++)
                        mlkem_doit[i] = 1;
        }
        for (i = 0; i < ALGOR_NUM; i++)
                if (doit[i])
                        pr_header++;

        if (usertime == 0 && !mr)
                BIO_printf(bio_err, "You have chosen to measure elapsed time instead of user CPU time.\n");

        for (i = 0; i < RSA_NUM; i++) {
                const unsigned char *p;

                p = rsa_data[i];
                rsa_key[i] = d2i_RSAPrivateKey(NULL, &p, rsa_data_length[i]);
                if (rsa_key[i] == NULL) {
                        BIO_printf(bio_err, "internal error loading RSA key number %d\n", i);
                        goto end;
                }
        }

        dsa_key[0] = get_dsa512();
        dsa_key[1] = get_dsa1024();
        dsa_key[2] = get_dsa2048();

#ifndef OPENSSL_NO_DES
        DES_set_key_unchecked(&key, &sch);
        DES_set_key_unchecked(&key2, &sch2);
        DES_set_key_unchecked(&key3, &sch3);
#endif
#ifndef OPENSSL_NO_AES
        AES_set_encrypt_key(key16, 128, &aes_ks1);
        AES_set_encrypt_key(key24, 192, &aes_ks2);
        AES_set_encrypt_key(key32, 256, &aes_ks3);
#endif
#ifndef OPENSSL_NO_CAMELLIA
        Camellia_set_key(key16, 128, &camellia_ks1);
        Camellia_set_key(key24, 192, &camellia_ks2);
        Camellia_set_key(key32, 256, &camellia_ks3);
#endif
#ifndef OPENSSL_NO_IDEA
        idea_set_encrypt_key(key16, &idea_ks);
#endif
#ifndef OPENSSL_NO_RC4
        RC4_set_key(&rc4_ks, 16, key16);
#endif
#ifndef OPENSSL_NO_RC2
        RC2_set_key(&rc2_ks, 16, key16, 128);
#endif
#ifndef OPENSSL_NO_BF
        BF_set_key(&bf_ks, 16, key16);
#endif
#ifndef OPENSSL_NO_CAST
        CAST_set_key(&cast_ks, 16, key16);
#endif
#define COND    (run && count<0x7fffffff)
#define COUNT(d) (count)

        memset(&sa, 0, sizeof(sa));
        sigemptyset(&sa.sa_mask);
        sa.sa_flags = SA_RESTART;
        sa.sa_handler = sig_done;
        sigaction(SIGALRM, &sa, NULL);

#ifndef OPENSSL_NO_MD4
        if (doit[D_MD4]) {
                for (j = 0; j < SIZE_NUM; j++) {
                        print_message(names[D_MD4], lengths[j]);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++)
                                EVP_Digest(&(buf[0]), (unsigned long) lengths[j], md, NULL, EVP_md4(), NULL);
                        d = time_f(STOP);
                        print_result(D_MD4, j, count, d);
                }
        }
#endif

#ifndef OPENSSL_NO_MD5
        if (doit[D_MD5]) {
                for (j = 0; j < SIZE_NUM; j++) {
                        print_message(names[D_MD5], lengths[j]);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++)
                                EVP_Digest(&(buf[0]), (unsigned long) lengths[j], md, NULL, EVP_get_digestbyname("md5"), NULL);
                        d = time_f(STOP);
                        print_result(D_MD5, j, count, d);
                }
        }
#endif

#if !defined(OPENSSL_NO_SHA256) && !defined(OPENSSL_NO_HMAC)
        if (doit[D_HMAC]) {
                HMAC_CTX *hctx;

                if ((hctx = HMAC_CTX_new()) == NULL) {
                        BIO_printf(bio_err, "Failed to allocate HMAC context.\n");
                        goto end;
                }

                HMAC_Init_ex(hctx, (unsigned char *) "This is a key...",
                    16, EVP_sha256(), NULL);

                for (j = 0; j < SIZE_NUM; j++) {
                        print_message(names[D_HMAC], lengths[j]);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++) {
                                if (!HMAC_Init_ex(hctx, NULL, 0, NULL, NULL)) {
                                        HMAC_CTX_free(hctx);
                                        goto end;
                                }
                                if (!HMAC_Update(hctx, buf, lengths[j])) {
                                        HMAC_CTX_free(hctx);
                                        goto end;
                                }
                                if (!HMAC_Final(hctx, md, NULL)) {
                                        HMAC_CTX_free(hctx);
                                        goto end;
                                }
                        }
                        d = time_f(STOP);
                        print_result(D_HMAC, j, count, d);
                }
                HMAC_CTX_free(hctx);
        }
#endif
#ifndef OPENSSL_NO_SHA
        if (doit[D_SHA1]) {
                for (j = 0; j < SIZE_NUM; j++) {
                        print_message(names[D_SHA1], lengths[j]);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++)
                                EVP_Digest(buf, (unsigned long) lengths[j], md, NULL, EVP_sha1(), NULL);
                        d = time_f(STOP);
                        print_result(D_SHA1, j, count, d);
                }
        }
#ifndef OPENSSL_NO_SHA256
        if (doit[D_SHA256]) {
                for (j = 0; j < SIZE_NUM; j++) {
                        print_message(names[D_SHA256], lengths[j]);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++)
                                SHA256(buf, lengths[j], md);
                        d = time_f(STOP);
                        print_result(D_SHA256, j, count, d);
                }
        }
#endif

#ifndef OPENSSL_NO_SHA512
        if (doit[D_SHA512]) {
                for (j = 0; j < SIZE_NUM; j++) {
                        print_message(names[D_SHA512], lengths[j]);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++)
                                SHA512(buf, lengths[j], md);
                        d = time_f(STOP);
                        print_result(D_SHA512, j, count, d);
                }
        }
#endif
#endif

#ifndef OPENSSL_NO_RIPEMD
        if (doit[D_RMD160]) {
                for (j = 0; j < SIZE_NUM; j++) {
                        print_message(names[D_RMD160], lengths[j]);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++)
                                EVP_Digest(buf, (unsigned long) lengths[j], md, NULL, EVP_ripemd160(), NULL);
                        d = time_f(STOP);
                        print_result(D_RMD160, j, count, d);
                }
        }
#endif
#ifndef OPENSSL_NO_RC4
        if (doit[D_RC4]) {
                for (j = 0; j < SIZE_NUM; j++) {
                        print_message(names[D_RC4], lengths[j]);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++)
                                RC4(&rc4_ks, (unsigned int) lengths[j],
                                    buf, buf);
                        d = time_f(STOP);
                        print_result(D_RC4, j, count, d);
                }
        }
#endif
#ifndef OPENSSL_NO_DES
        if (doit[D_CBC_DES]) {
                for (j = 0; j < SIZE_NUM; j++) {
                        print_message(names[D_CBC_DES], lengths[j]);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++)
                                DES_ncbc_encrypt(buf, buf, lengths[j], &sch,
                                    &DES_iv, DES_ENCRYPT);
                        d = time_f(STOP);
                        print_result(D_CBC_DES, j, count, d);
                }
        }
        if (doit[D_EDE3_DES]) {
                for (j = 0; j < SIZE_NUM; j++) {
                        print_message(names[D_EDE3_DES], lengths[j]);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++)
                                DES_ede3_cbc_encrypt(buf, buf, lengths[j],
                                    &sch, &sch2, &sch3,
                                    &DES_iv, DES_ENCRYPT);
                        d = time_f(STOP);
                        print_result(D_EDE3_DES, j, count, d);
                }
        }
#endif
#ifndef OPENSSL_NO_AES
        if (doit[D_CBC_128_AES]) {
                for (j = 0; j < SIZE_NUM; j++) {
                        print_message(names[D_CBC_128_AES], lengths[j]);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++)
                                AES_cbc_encrypt(buf, buf,
                                    (unsigned long) lengths[j], &aes_ks1,
                                    iv, AES_ENCRYPT);
                        d = time_f(STOP);
                        print_result(D_CBC_128_AES, j, count, d);
                }
        }
        if (doit[D_CBC_192_AES]) {
                for (j = 0; j < SIZE_NUM; j++) {
                        print_message(names[D_CBC_192_AES], lengths[j]);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++)
                                AES_cbc_encrypt(buf, buf,
                                    (unsigned long) lengths[j], &aes_ks2,
                                    iv, AES_ENCRYPT);
                        d = time_f(STOP);
                        print_result(D_CBC_192_AES, j, count, d);
                }
        }
        if (doit[D_CBC_256_AES]) {
                for (j = 0; j < SIZE_NUM; j++) {
                        print_message(names[D_CBC_256_AES], lengths[j]);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++)
                                AES_cbc_encrypt(buf, buf,
                                    (unsigned long) lengths[j], &aes_ks3,
                                    iv, AES_ENCRYPT);
                        d = time_f(STOP);
                        print_result(D_CBC_256_AES, j, count, d);
                }
        }
        if (doit[D_IGE_128_AES]) {
                for (j = 0; j < SIZE_NUM; j++) {
                        print_message(names[D_IGE_128_AES], lengths[j]);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++)
                                AES_ige_encrypt(buf, buf2,
                                    (unsigned long) lengths[j], &aes_ks1,
                                    iv, AES_ENCRYPT);
                        d = time_f(STOP);
                        print_result(D_IGE_128_AES, j, count, d);
                }
        }
        if (doit[D_IGE_192_AES]) {
                for (j = 0; j < SIZE_NUM; j++) {
                        print_message(names[D_IGE_192_AES], lengths[j]);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++)
                                AES_ige_encrypt(buf, buf2,
                                    (unsigned long) lengths[j], &aes_ks2,
                                    iv, AES_ENCRYPT);
                        d = time_f(STOP);
                        print_result(D_IGE_192_AES, j, count, d);
                }
        }
        if (doit[D_IGE_256_AES]) {
                for (j = 0; j < SIZE_NUM; j++) {
                        print_message(names[D_IGE_256_AES], lengths[j]);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++)
                                AES_ige_encrypt(buf, buf2,
                                    (unsigned long) lengths[j], &aes_ks3,
                                    iv, AES_ENCRYPT);
                        d = time_f(STOP);
                        print_result(D_IGE_256_AES, j, count, d);
                }
        }
        if (doit[D_GHASH]) {
                GCM128_CONTEXT *ctx = CRYPTO_gcm128_new(&aes_ks1, (block128_f) AES_encrypt);
                CRYPTO_gcm128_setiv(ctx, (unsigned char *) "0123456789ab", 12);

                for (j = 0; j < SIZE_NUM; j++) {
                        print_message(names[D_GHASH], lengths[j]);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++)
                                CRYPTO_gcm128_aad(ctx, buf, lengths[j]);
                        d = time_f(STOP);
                        print_result(D_GHASH, j, count, d);
                }
                CRYPTO_gcm128_release(ctx);
        }
        if (doit[D_AES_128_GCM]) {
                const EVP_AEAD *aead = EVP_aead_aes_128_gcm();
                static const unsigned char nonce[32] = {0};
                size_t buf_len, nonce_len;
                EVP_AEAD_CTX *ctx;

                if ((ctx = EVP_AEAD_CTX_new()) == NULL) {
                        BIO_printf(bio_err,
                            "Failed to allocate aead context.\n");
                        goto end;
                }

                EVP_AEAD_CTX_init(ctx, aead, key32, EVP_AEAD_key_length(aead),
                    EVP_AEAD_DEFAULT_TAG_LENGTH, NULL);
                nonce_len = EVP_AEAD_nonce_length(aead);

                for (j = 0; j < SIZE_NUM; j++) {
                        print_message(names[D_AES_128_GCM], lengths[j]);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++)
                                EVP_AEAD_CTX_seal(ctx, buf, &buf_len, BUFSIZE, nonce,
                                    nonce_len, buf, lengths[j], NULL, 0);
                        d = time_f(STOP);
                        print_result(D_AES_128_GCM,j,count,d);
                }
                EVP_AEAD_CTX_free(ctx);
        }

        if (doit[D_AES_256_GCM]) {
                const EVP_AEAD *aead = EVP_aead_aes_256_gcm();
                static const unsigned char nonce[32] = {0};
                size_t buf_len, nonce_len;
                EVP_AEAD_CTX *ctx;

                if ((ctx = EVP_AEAD_CTX_new()) == NULL) {
                        BIO_printf(bio_err,
                            "Failed to allocate aead context.\n");
                        goto end;
                }

                EVP_AEAD_CTX_init(ctx, aead, key32, EVP_AEAD_key_length(aead),
                EVP_AEAD_DEFAULT_TAG_LENGTH, NULL);
                nonce_len = EVP_AEAD_nonce_length(aead);

                for (j = 0; j < SIZE_NUM; j++) {
                        print_message(names[D_AES_256_GCM], lengths[j]);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++)
                                EVP_AEAD_CTX_seal(ctx, buf, &buf_len, BUFSIZE, nonce,
                                    nonce_len, buf, lengths[j], NULL, 0);
                        d = time_f(STOP);
                        print_result(D_AES_256_GCM, j, count, d);
                }
                EVP_AEAD_CTX_free(ctx);
        }
#endif
#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
        if (doit[D_CHACHA20_POLY1305]) {
                const EVP_AEAD *aead = EVP_aead_chacha20_poly1305();
                static const unsigned char nonce[32] = {0};
                size_t buf_len, nonce_len;
                EVP_AEAD_CTX *ctx;

                if ((ctx = EVP_AEAD_CTX_new()) == NULL) {
                        BIO_printf(bio_err,
                            "Failed to allocate aead context.\n");
                        goto end;
                }

                EVP_AEAD_CTX_init(ctx, aead, key32, EVP_AEAD_key_length(aead),
                    EVP_AEAD_DEFAULT_TAG_LENGTH, NULL);
                nonce_len = EVP_AEAD_nonce_length(aead);

                for (j = 0; j < SIZE_NUM; j++) {
                        print_message(names[D_CHACHA20_POLY1305], lengths[j]);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++)
                                EVP_AEAD_CTX_seal(ctx, buf, &buf_len, BUFSIZE, nonce,
                                    nonce_len, buf, lengths[j], NULL, 0);
                        d = time_f(STOP);
                        print_result(D_CHACHA20_POLY1305, j, count, d);
                }
                EVP_AEAD_CTX_free(ctx);
        }
#endif
#ifndef OPENSSL_NO_CAMELLIA
        if (doit[D_CBC_128_CML]) {
                for (j = 0; j < SIZE_NUM; j++) {
                        print_message(names[D_CBC_128_CML], lengths[j]);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++)
                                Camellia_cbc_encrypt(buf, buf,
                                    (unsigned long) lengths[j], &camellia_ks1,
                                    iv, CAMELLIA_ENCRYPT);
                        d = time_f(STOP);
                        print_result(D_CBC_128_CML, j, count, d);
                }
        }
        if (doit[D_CBC_192_CML]) {
                for (j = 0; j < SIZE_NUM; j++) {
                        print_message(names[D_CBC_192_CML], lengths[j]);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++)
                                Camellia_cbc_encrypt(buf, buf,
                                    (unsigned long) lengths[j], &camellia_ks2,
                                    iv, CAMELLIA_ENCRYPT);
                        d = time_f(STOP);
                        print_result(D_CBC_192_CML, j, count, d);
                }
        }
        if (doit[D_CBC_256_CML]) {
                for (j = 0; j < SIZE_NUM; j++) {
                        print_message(names[D_CBC_256_CML], lengths[j]);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++)
                                Camellia_cbc_encrypt(buf, buf,
                                    (unsigned long) lengths[j], &camellia_ks3,
                                    iv, CAMELLIA_ENCRYPT);
                        d = time_f(STOP);
                        print_result(D_CBC_256_CML, j, count, d);
                }
        }
#endif
#ifndef OPENSSL_NO_IDEA
        if (doit[D_CBC_IDEA]) {
                for (j = 0; j < SIZE_NUM; j++) {
                        print_message(names[D_CBC_IDEA], lengths[j]);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++)
                                idea_cbc_encrypt(buf, buf,
                                    (unsigned long) lengths[j], &idea_ks,
                                    iv, IDEA_ENCRYPT);
                        d = time_f(STOP);
                        print_result(D_CBC_IDEA, j, count, d);
                }
        }
#endif
#ifndef OPENSSL_NO_RC2
        if (doit[D_CBC_RC2]) {
                for (j = 0; j < SIZE_NUM; j++) {
                        print_message(names[D_CBC_RC2], lengths[j]);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++)
                                RC2_cbc_encrypt(buf, buf,
                                    (unsigned long) lengths[j], &rc2_ks,
                                    iv, RC2_ENCRYPT);
                        d = time_f(STOP);
                        print_result(D_CBC_RC2, j, count, d);
                }
        }
#endif
#ifndef OPENSSL_NO_BF
        if (doit[D_CBC_BF]) {
                for (j = 0; j < SIZE_NUM; j++) {
                        print_message(names[D_CBC_BF], lengths[j]);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++)
                                BF_cbc_encrypt(buf, buf,
                                    (unsigned long) lengths[j], &bf_ks,
                                    iv, BF_ENCRYPT);
                        d = time_f(STOP);
                        print_result(D_CBC_BF, j, count, d);
                }
        }
#endif
#ifndef OPENSSL_NO_CAST
        if (doit[D_CBC_CAST]) {
                for (j = 0; j < SIZE_NUM; j++) {
                        print_message(names[D_CBC_CAST], lengths[j]);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++)
                                CAST_cbc_encrypt(buf, buf,
                                    (unsigned long) lengths[j], &cast_ks,
                                    iv, CAST_ENCRYPT);
                        d = time_f(STOP);
                        print_result(D_CBC_CAST, j, count, d);
                }
        }
#endif

        if (doit[D_EVP]) {
                for (j = 0; j < SIZE_NUM; j++) {
                        if (evp_cipher) {
                                EVP_CIPHER_CTX *ctx;
                                int outl;

                                names[D_EVP] =
                                    OBJ_nid2ln(EVP_CIPHER_nid(evp_cipher));
                                /*
                                 * -O3 -fschedule-insns messes up an
                                 * optimization here!  names[D_EVP] somehow
                                 * becomes NULL
                                 */
                                print_message(names[D_EVP], lengths[j]);

                                if ((ctx = EVP_CIPHER_CTX_new()) == NULL) {
                                        BIO_printf(bio_err, "Failed to "
                                            "allocate cipher context.\n");
                                        goto end;
                                }
                                if (decrypt)
                                        EVP_DecryptInit_ex(ctx, evp_cipher, NULL, key16, iv);
                                else
                                        EVP_EncryptInit_ex(ctx, evp_cipher, NULL, key16, iv);
                                EVP_CIPHER_CTX_set_padding(ctx, 0);

                                time_f(START);
                                if (decrypt)
                                        for (count = 0, run = 1; COND; count++)
                                                EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[j]);
                                else
                                        for (count = 0, run = 1; COND; count++)
                                                EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[j]);
                                if (decrypt)
                                        EVP_DecryptFinal_ex(ctx, buf, &outl);
                                else
                                        EVP_EncryptFinal_ex(ctx, buf, &outl);
                                d = time_f(STOP);
                                EVP_CIPHER_CTX_free(ctx);
                        }
                        if (evp_md) {
                                names[D_EVP] = OBJ_nid2ln(EVP_MD_type(evp_md));
                                print_message(names[D_EVP], lengths[j]);

                                time_f(START);
                                for (count = 0, run = 1; COND; count++)
                                        EVP_Digest(buf, lengths[j], &(md[0]), NULL, evp_md, NULL);

                                d = time_f(STOP);
                        }
                        print_result(D_EVP, j, count, d);
                }
        }
        arc4random_buf(buf, 36);
        for (j = 0; j < RSA_NUM; j++) {
                int ret;
                if (!rsa_doit[j])
                        continue;
                ret = RSA_sign(NID_md5_sha1, buf, 36, buf2, &rsa_num, rsa_key[j]);
                if (ret == 0) {
                        BIO_printf(bio_err, "RSA sign failure.  No RSA sign will be done.\n");
                        ERR_print_errors(bio_err);
                        rsa_count = 1;
                } else {
                        pkey_print_message("private", "rsa",
                            rsa_bits[j],
                            RSA_SECONDS);
/*                      RSA_blinding_on(rsa_key[j],NULL); */
                        time_f(START);
                        for (count = 0, run = 1; COND; count++) {
                                ret = RSA_sign(NID_md5_sha1, buf, 36, buf2,
                                    &rsa_num, rsa_key[j]);
                                if (ret == 0) {
                                        BIO_printf(bio_err,
                                            "RSA sign failure\n");
                                        ERR_print_errors(bio_err);
                                        count = 1;
                                        break;
                                }
                        }
                        d = time_f(STOP);
                        BIO_printf(bio_err, mr ? "+R1:%ld:%d:%.2f\n"
                            : "%ld %d bit private RSA in %.2fs\n",
                            count, rsa_bits[j], d);
                        rsa_results[j][0] = d / (double) count;
                        rsa_count = count;
                }

                ret = RSA_verify(NID_md5_sha1, buf, 36, buf2, rsa_num, rsa_key[j]);
                if (ret <= 0) {
                        BIO_printf(bio_err, "RSA verify failure.  No RSA verify will be done.\n");
                        ERR_print_errors(bio_err);
                        rsa_doit[j] = 0;
                } else {
                        pkey_print_message("public", "rsa",
                            rsa_bits[j],
                            RSA_SECONDS);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++) {
                                ret = RSA_verify(NID_md5_sha1, buf, 36, buf2,
                                    rsa_num, rsa_key[j]);
                                if (ret <= 0) {
                                        BIO_printf(bio_err,
                                            "RSA verify failure\n");
                                        ERR_print_errors(bio_err);
                                        count = 1;
                                        break;
                                }
                        }
                        d = time_f(STOP);
                        BIO_printf(bio_err, mr ? "+R2:%ld:%d:%.2f\n"
                            : "%ld %d bit public RSA in %.2fs\n",
                            count, rsa_bits[j], d);
                        rsa_results[j][1] = d / (double) count;
                }

                if (rsa_count <= 1) {
                        /* if longer than 10s, don't do any more */
                        for (j++; j < RSA_NUM; j++)
                                rsa_doit[j] = 0;
                }
        }

        arc4random_buf(buf, 20);
        for (j = 0; j < DSA_NUM; j++) {
                unsigned int kk;
                int ret;

                if (!dsa_doit[j])
                        continue;
/*              DSA_generate_key(dsa_key[j]); */
/*              DSA_sign_setup(dsa_key[j],NULL); */
                ret = DSA_sign(EVP_PKEY_DSA, buf, 20, buf2,
                    &kk, dsa_key[j]);
                if (ret == 0) {
                        BIO_printf(bio_err, "DSA sign failure.  No DSA sign will be done.\n");
                        ERR_print_errors(bio_err);
                        rsa_count = 1;
                } else {
                        pkey_print_message("sign", "dsa",
                            dsa_bits[j],
                            DSA_SECONDS);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++) {
                                ret = DSA_sign(EVP_PKEY_DSA, buf, 20, buf2,
                                    &kk, dsa_key[j]);
                                if (ret == 0) {
                                        BIO_printf(bio_err,
                                            "DSA sign failure\n");
                                        ERR_print_errors(bio_err);
                                        count = 1;
                                        break;
                                }
                        }
                        d = time_f(STOP);
                        BIO_printf(bio_err, mr ? "+R3:%ld:%d:%.2f\n"
                            : "%ld %d bit DSA signs in %.2fs\n",
                            count, dsa_bits[j], d);
                        dsa_results[j][0] = d / (double) count;
                        rsa_count = count;
                }

                ret = DSA_verify(EVP_PKEY_DSA, buf, 20, buf2,
                    kk, dsa_key[j]);
                if (ret <= 0) {
                        BIO_printf(bio_err, "DSA verify failure.  No DSA verify will be done.\n");
                        ERR_print_errors(bio_err);
                        dsa_doit[j] = 0;
                } else {
                        pkey_print_message("verify", "dsa",
                            dsa_bits[j],
                            DSA_SECONDS);
                        time_f(START);
                        for (count = 0, run = 1; COND; count++) {
                                ret = DSA_verify(EVP_PKEY_DSA, buf, 20, buf2,
                                    kk, dsa_key[j]);
                                if (ret <= 0) {
                                        BIO_printf(bio_err,
                                            "DSA verify failure\n");
                                        ERR_print_errors(bio_err);
                                        count = 1;
                                        break;
                                }
                        }
                        d = time_f(STOP);
                        BIO_printf(bio_err, mr ? "+R4:%ld:%d:%.2f\n"
                            : "%ld %d bit DSA verify in %.2fs\n",
                            count, dsa_bits[j], d);
                        dsa_results[j][1] = d / (double) count;
                }

                if (rsa_count <= 1) {
                        /* if longer than 10s, don't do any more */
                        for (j++; j < DSA_NUM; j++)
                                dsa_doit[j] = 0;
                }
        }

        for (j = 0; j < EC_NUM; j++) {
                int ret;

                if (!ecdsa_doit[j])
                        continue;       /* Ignore Curve */
                ecdsa[j] = EC_KEY_new_by_curve_name(test_curves[j]);
                if (ecdsa[j] == NULL) {
                        BIO_printf(bio_err, "ECDSA failure.\n");
                        ERR_print_errors(bio_err);
                        rsa_count = 1;
                } else {
                        EC_KEY_precompute_mult(ecdsa[j], NULL);

                        /* Perform ECDSA signature test */
                        EC_KEY_generate_key(ecdsa[j]);
                        ret = ECDSA_sign(0, buf, 20, ecdsasig,
                            &ecdsasiglen, ecdsa[j]);
                        if (ret == 0) {
                                BIO_printf(bio_err, "ECDSA sign failure.  No ECDSA sign will be done.\n");
                                ERR_print_errors(bio_err);
                                rsa_count = 1;
                        } else {
                                pkey_print_message("sign", "ecdsa",
                                    test_curves_bits[j],
                                    ECDSA_SECONDS);

                                time_f(START);
                                for (count = 0, run = 1; COND; count++) {
                                        ret = ECDSA_sign(0, buf, 20,
                                            ecdsasig, &ecdsasiglen,
                                            ecdsa[j]);
                                        if (ret == 0) {
                                                BIO_printf(bio_err, "ECDSA sign failure\n");
                                                ERR_print_errors(bio_err);
                                                count = 1;
                                                break;
                                        }
                                }
                                d = time_f(STOP);

                                BIO_printf(bio_err, mr ? "+R5:%ld:%d:%.2f\n" :
                                    "%ld %d bit ECDSA signs in %.2fs \n",
                                    count, test_curves_bits[j], d);
                                ecdsa_results[j][0] = d / (double) count;
                                rsa_count = count;
                        }

                        /* Perform ECDSA verification test */
                        ret = ECDSA_verify(0, buf, 20, ecdsasig,
                            ecdsasiglen, ecdsa[j]);
                        if (ret != 1) {
                                BIO_printf(bio_err, "ECDSA verify failure.  No ECDSA verify will be done.\n");
                                ERR_print_errors(bio_err);
                                ecdsa_doit[j] = 0;
                        } else {
                                pkey_print_message("verify", "ecdsa",
                                    test_curves_bits[j],
                                    ECDSA_SECONDS);
                                time_f(START);
                                for (count = 0, run = 1; COND; count++) {
                                        ret = ECDSA_verify(0, buf, 20, ecdsasig, ecdsasiglen, ecdsa[j]);
                                        if (ret != 1) {
                                                BIO_printf(bio_err, "ECDSA verify failure\n");
                                                ERR_print_errors(bio_err);
                                                count = 1;
                                                break;
                                        }
                                }
                                d = time_f(STOP);
                                BIO_printf(bio_err, mr ? "+R6:%ld:%d:%.2f\n"
                                    : "%ld %d bit ECDSA verify in %.2fs\n",
                                    count, test_curves_bits[j], d);
                                ecdsa_results[j][1] = d / (double) count;
                        }

                        if (rsa_count <= 1) {
                                /* if longer than 10s, don't do any more */
                                for (j++; j < EC_NUM; j++)
                                        ecdsa_doit[j] = 0;
                        }
                }
        }

        for (j = 0; j < EC_NUM; j++) {
                if (!ecdh_doit[j])
                        continue;
                ecdh_a[j] = EC_KEY_new_by_curve_name(test_curves[j]);
                ecdh_b[j] = EC_KEY_new_by_curve_name(test_curves[j]);
                if ((ecdh_a[j] == NULL) || (ecdh_b[j] == NULL)) {
                        BIO_printf(bio_err, "ECDH failure.\n");
                        ERR_print_errors(bio_err);
                        rsa_count = 1;
                } else {
                        /* generate two ECDH key pairs */
                        if (!EC_KEY_generate_key(ecdh_a[j]) ||
                            !EC_KEY_generate_key(ecdh_b[j])) {
                                BIO_printf(bio_err, "ECDH key generation failure.\n");
                                ERR_print_errors(bio_err);
                                rsa_count = 1;
                        } else {
                                /*
                                 * If field size is not more than 24 octets,
                                 * then use SHA-1 hash of result; otherwise,
                                 * use result (see section 4.8 of
                                 * draft-ietf-tls-ecc-03.txt).
                                 */
                                int field_size, outlen;
                                void *(*kdf) (const void *in, size_t inlen, void *out, size_t * xoutlen);
                                field_size = EC_GROUP_get_degree(EC_KEY_get0_group(ecdh_a[j]));
                                if (field_size <= 24 * 8) {
                                        outlen = KDF1_SHA1_len;
                                        kdf = KDF1_SHA1;
                                } else {
                                        outlen = (field_size + 7) / 8;
                                        kdf = NULL;
                                }
                                secret_size_a = ECDH_compute_key(secret_a, outlen,
                                    EC_KEY_get0_public_key(ecdh_b[j]),
                                    ecdh_a[j], kdf);
                                secret_size_b = ECDH_compute_key(secret_b, outlen,
                                    EC_KEY_get0_public_key(ecdh_a[j]),
                                    ecdh_b[j], kdf);
                                if (secret_size_a != secret_size_b)
                                        ecdh_checks = 0;
                                else
                                        ecdh_checks = 1;

                                for (secret_idx = 0;
                                    (secret_idx < secret_size_a)
                                    && (ecdh_checks == 1);
                                    secret_idx++) {
                                        if (secret_a[secret_idx] != secret_b[secret_idx])
                                                ecdh_checks = 0;
                                }

                                if (ecdh_checks == 0) {
                                        BIO_printf(bio_err,
                                            "ECDH computations don't match.\n");
                                        ERR_print_errors(bio_err);
                                        rsa_count = 1;
                                } else {
                                        pkey_print_message("", "ecdh",
                                            test_curves_bits[j],
                                            ECDH_SECONDS);
                                        time_f(START);
                                        for (count = 0, run = 1; COND; count++) {
                                                ECDH_compute_key(secret_a,
                                                    outlen,
                                                    EC_KEY_get0_public_key(ecdh_b[j]),
                                                    ecdh_a[j], kdf);
                                        }
                                        d = time_f(STOP);
                                        BIO_printf(bio_err, mr
                                            ? "+R7:%ld:%d:%.2f\n"
                                            : "%ld %d-bit ECDH ops in %.2fs\n",
                                            count, test_curves_bits[j], d);
                                        ecdh_results[j][0] = d / (double) count;
                                        rsa_count = count;
                                }
                        }
                }


                if (rsa_count <= 1) {
                        /* if longer than 10s, don't do any more */
                        for (j++; j < EC_NUM; j++)
                                ecdh_doit[j] = 0;
                }
        }

        for (j = 0; j < MLKEM_NUM; j++) {
                const struct mlkem_speed_param *p = &mlkem_params[j];
                int rank = p->rank;
                int bits = p->bits;
                MLKEM_private_key *priv = NULL;
                MLKEM_public_key *pub = NULL;
                uint8_t *encoded_pub = NULL;
                size_t encoded_pub_len = 0;
                uint8_t *ct = NULL, *ss = NULL;
                size_t ct_len = 0, ss_len = 0;

                if (!mlkem_doit[j])
                        continue;

                pkey_print_message("keygen", "mlkem", bits, MLKEM_SECONDS);
                time_f(START);
                for (count = 0, run = 1; COND; count++) {
                        /*
                         * MLKEM_generate_key requires an uninitialized key
                         * object, so allocate and free on every iteration.
                         */
                        if ((priv = MLKEM_private_key_new(rank)) == NULL)
                                break;
                        if (!MLKEM_generate_key(priv, &encoded_pub,
                            &encoded_pub_len, NULL, NULL)) {
                                MLKEM_private_key_free(priv);
                                priv = NULL;
                                break;
                        }
                        MLKEM_private_key_free(priv);
                        priv = NULL;
                        free(encoded_pub);
                        encoded_pub = NULL;
                }
                d = time_f(STOP);
                if (run)
                        goto mlkem_err;
                BIO_printf(bio_err, mr ? "+R8:%ld:%d:%.2f\n"
                    : "%ld %d-bit ML-KEM keygen in %.2fs\n", count, bits, d);
                mlkem_results[j][2] = d / (double)count;
                rsa_count = count;

                if ((priv = MLKEM_private_key_new(rank)) == NULL ||
                    (pub = MLKEM_public_key_new(rank)) == NULL)
                        goto mlkem_err;
                if (!MLKEM_generate_key(priv, &encoded_pub, &encoded_pub_len,
                    NULL, NULL) ||
                    !MLKEM_parse_public_key(pub, encoded_pub, encoded_pub_len))
                        goto mlkem_err;
                free(encoded_pub);
                encoded_pub = NULL;

                pkey_print_message("encap", "mlkem", bits, MLKEM_SECONDS);
                time_f(START);
                for (count = 0, run = 1; COND; count++) {
                        if (!MLKEM_encap(pub, &ct, &ct_len, &ss,
                            &ss_len))
                                break;
                        free(ct);
                        ct = NULL;
                        free(ss);
                        ss = NULL;
                }
                d = time_f(STOP);
                if (run)
                        goto mlkem_err;
                BIO_printf(bio_err, mr ? "+R9:%ld:%d:%.2f\n"
                    : "%ld %d-bit ML-KEM encap in %.2fs\n", count, bits, d);
                mlkem_results[j][0] = d / (double)count;
                rsa_count = count;

                if (!MLKEM_encap(pub, &ct, &ct_len, &ss, &ss_len))
                        goto mlkem_err;
                free(ss);
                ss = NULL;

                pkey_print_message("decap", "mlkem", bits, MLKEM_SECONDS);
                time_f(START);
                for (count = 0, run = 1; COND; count++) {
                        if (!MLKEM_decap(priv, ct, ct_len, &ss, &ss_len))
                                break;
                        free(ss);
                        ss = NULL;
                }
                d = time_f(STOP);
                if (run)
                        goto mlkem_err;
                BIO_printf(bio_err, mr ? "+R10:%ld:%d:%.2f\n"
                    : "%ld %d-bit ML-KEM decap in %.2fs\n", count, bits, d);
                mlkem_results[j][1] = d / (double)count;
                rsa_count = count;

                free(ct);
                ct = NULL;
                MLKEM_private_key_free(priv);
                priv = NULL;
                MLKEM_public_key_free(pub);
                pub = NULL;

                if (rsa_count <= 1) {
                        /* if longer than 10s, don't do any more */
                        for (j++; j < MLKEM_NUM; j++)
                                mlkem_doit[j] = 0;
                }
                continue;

 mlkem_err:
                BIO_printf(bio_err, "MLKEM failure\n");
                ERR_print_errors(bio_err);
                MLKEM_private_key_free(priv);
                MLKEM_public_key_free(pub);
                free(encoded_pub);
                free(ct);
                free(ss);
        }

 show_res:
        if (!mr) {
                fprintf(stdout, "%s\n", SSLeay_version(SSLEAY_VERSION));
                fprintf(stdout, "%s\n", SSLeay_version(SSLEAY_BUILT_ON));
                fprintf(stdout, "%s\n", SSLeay_version(SSLEAY_CFLAGS));
        }
        if (pr_header) {
                if (mr)
                        fprintf(stdout, "+H");
                else {
                        fprintf(stdout, "The 'numbers' are in 1000s of bytes per second processed.\n");
                        fprintf(stdout, "type        ");
                }
                for (j = 0; j < SIZE_NUM; j++)
                        fprintf(stdout, mr ? ":%d" : "%7d bytes", lengths[j]);
                fprintf(stdout, "\n");
        }
        for (k = 0; k < ALGOR_NUM; k++) {
                if (!doit[k])
                        continue;
                if (mr)
                        fprintf(stdout, "+F:%d:%s", k, names[k]);
                else
                        fprintf(stdout, "%-13s", names[k]);
                for (j = 0; j < SIZE_NUM; j++) {
                        if (results[k][j] > 10000 && !mr)
                                fprintf(stdout, " %11.2fk", results[k][j] / 1e3);
                        else
                                fprintf(stdout, mr ? ":%.2f" : " %11.2f ", results[k][j]);
                }
                fprintf(stdout, "\n");
        }
        j = 1;
        for (k = 0; k < RSA_NUM; k++) {
                if (!rsa_doit[k])
                        continue;
                if (j && !mr) {
                        printf("%18ssign    verify    sign/s verify/s\n", " ");
                        j = 0;
                }
                if (mr)
                        fprintf(stdout, "+F2:%u:%u:%f:%f\n",
                            k, rsa_bits[k], rsa_results[k][0],
                            rsa_results[k][1]);
                else
                        fprintf(stdout, "rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
                            rsa_bits[k], rsa_results[k][0], rsa_results[k][1],
                            1.0 / rsa_results[k][0], 1.0 / rsa_results[k][1]);
        }
        j = 1;
        for (k = 0; k < DSA_NUM; k++) {
                if (!dsa_doit[k])
                        continue;
                if (j && !mr) {
                        printf("%18ssign    verify    sign/s verify/s\n", " ");
                        j = 0;
                }
                if (mr)
                        fprintf(stdout, "+F3:%u:%u:%f:%f\n",
                            k, dsa_bits[k], dsa_results[k][0], dsa_results[k][1]);
                else
                        fprintf(stdout, "dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
                            dsa_bits[k], dsa_results[k][0], dsa_results[k][1],
                            1.0 / dsa_results[k][0], 1.0 / dsa_results[k][1]);
        }
        j = 1;
        for (k = 0; k < EC_NUM; k++) {
                if (!ecdsa_doit[k])
                        continue;
                if (j && !mr) {
                        printf("%30ssign    verify    sign/s verify/s\n", " ");
                        j = 0;
                }
                if (mr)
                        fprintf(stdout, "+F4:%u:%u:%f:%f\n",
                            k, test_curves_bits[k],
                            ecdsa_results[k][0], ecdsa_results[k][1]);
                else
                        fprintf(stdout,
                            "%4u bit ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
                            test_curves_bits[k],
                            test_curves_names[k],
                            ecdsa_results[k][0], ecdsa_results[k][1],
                            1.0 / ecdsa_results[k][0], 1.0 / ecdsa_results[k][1]);
        }


        j = 1;
        for (k = 0; k < EC_NUM; k++) {
                if (!ecdh_doit[k])
                        continue;
                if (j && !mr) {
                        printf("%30sop      op/s\n", " ");
                        j = 0;
                }
                if (mr)
                        fprintf(stdout, "+F5:%u:%u:%f:%f\n",
                            k, test_curves_bits[k],
                            ecdh_results[k][0], 1.0 / ecdh_results[k][0]);

                else
                        fprintf(stdout, "%4u bit ecdh (%s) %8.4fs %8.1f\n",
                            test_curves_bits[k],
                            test_curves_names[k],
                            ecdh_results[k][0], 1.0 / ecdh_results[k][0]);
        }

        j = 1;
        for (k = 0; k < MLKEM_NUM; k++) {
                if (!mlkem_doit[k])
                        continue;
                if (j && !mr) {
                        printf("%-9s%12s%9s%12s%9s%12s%9s\n",
                            "", "keygen", "keygen/s",
                            "encap", "encap/s",
                            "decap", "decap/s");
                        j = 0;
                }
                if (mr)
                        fprintf(stdout, "+F6:%u:%f:%f:%f:%f:%f:%f\n",
                            mlkem_params[k].bits,
                            mlkem_results[k][2], 1.0 / mlkem_results[k][2],
                            mlkem_results[k][0], 1.0 / mlkem_results[k][0],
                            mlkem_results[k][1], 1.0 / mlkem_results[k][1]);
                else
                        fprintf(stdout,
                            "mlkem%4d %10.6fs %8.1f %10.6fs %8.1f %10.6fs %8.1f\n",
                            mlkem_params[k].bits,
                            mlkem_results[k][2], 1.0 / mlkem_results[k][2],
                            mlkem_results[k][0], 1.0 / mlkem_results[k][0],
                            mlkem_results[k][1], 1.0 / mlkem_results[k][1]);
        }

        mret = 0;

 end:
        ERR_print_errors(bio_err);
        free(real_buf);
        free(real_buf2);
        for (i = 0; i < RSA_NUM; i++)
                if (rsa_key[i] != NULL)
                        RSA_free(rsa_key[i]);
        for (i = 0; i < DSA_NUM; i++)
                if (dsa_key[i] != NULL)
                        DSA_free(dsa_key[i]);

        for (i = 0; i < EC_NUM; i++)
                if (ecdsa[i] != NULL)
                        EC_KEY_free(ecdsa[i]);
        for (i = 0; i < EC_NUM; i++) {
                if (ecdh_a[i] != NULL)
                        EC_KEY_free(ecdh_a[i]);
                if (ecdh_b[i] != NULL)
                        EC_KEY_free(ecdh_b[i]);
        }


        return (mret);
}

static void
print_message(const char *s, int length)
{
        BIO_printf(bio_err, mr ? "+DT:%s:%d:%d\n"
            : "Doing %s for %ds on %d size blocks: ", s, SECONDS, length);
        (void) BIO_flush(bio_err);
        alarm(SECONDS);
}

static void
pkey_print_message(const char *str, const char *str2,
    int bits, int tm)
{
        BIO_printf(bio_err, mr ? "+DTP:%d:%s:%s:%d\n"
            : "Doing %d bit %s %s for %ds: ", bits, str, str2, tm);
        (void) BIO_flush(bio_err);
        alarm(tm);
}

static void
print_result(int alg, int run_no, int count, double time_used)
{
        BIO_printf(bio_err, mr ? "+R:%d:%s:%f\n"
            : "%d %s in %.2fs\n", count, names[alg], time_used);
        results[alg][run_no] = ((double) count) / time_used * lengths[run_no];
}

static char *
sstrsep(char **string, const char *delim)
{
        char isdelim[256];
        char *token = *string;

        if (**string == 0)
                return NULL;

        memset(isdelim, 0, sizeof isdelim);
        isdelim[0] = 1;

        while (*delim) {
                isdelim[(unsigned char) (*delim)] = 1;
                delim++;
        }

        while (!isdelim[(unsigned char) (**string)]) {
                (*string)++;
        }

        if (**string) {
                **string = 0;
                (*string)++;
        }
        return token;
}

static int
do_multi(int multi)
{
        int n;
        int fd[2];
        int *fds;
        static char sep[] = ":";
        const char *errstr = NULL;

        fds = reallocarray(NULL, multi, sizeof *fds);
        if (fds == NULL) {
                fprintf(stderr, "reallocarray failure\n");
                exit(1);
        }
        for (n = 0; n < multi; ++n) {
                if (pipe(fd) == -1) {
                        fprintf(stderr, "pipe failure\n");
                        exit(1);
                }
                fflush(stdout);
                fflush(stderr);
                if (fork()) {
                        close(fd[1]);
                        fds[n] = fd[0];
                } else {
                        close(fd[0]);
                        close(1);
                        if (dup(fd[1]) == -1) {
                                fprintf(stderr, "dup failed\n");
                                exit(1);
                        }
                        close(fd[1]);
                        mr = 1;
                        usertime = 0;
                        free(fds);
                        return 0;
                }
                printf("Forked child %d\n", n);
        }

        /* for now, assume the pipe is long enough to take all the output */
        for (n = 0; n < multi; ++n) {
                FILE *f;
                char buf[1024];
                char *p;

                f = fdopen(fds[n], "r");
                while (fgets(buf, sizeof buf, f)) {
                        p = strchr(buf, '\n');
                        if (p)
                                *p = '\0';
                        if (buf[0] != '+') {
                                fprintf(stderr, "Don't understand line '%s' from child %d\n",
                                    buf, n);
                                continue;
                        }
                        printf("Got: %s from %d\n", buf, n);
                        if (!strncmp(buf, "+F:", 3)) {
                                int alg;
                                int j;

                                p = buf + 3;
                                alg = strtonum(sstrsep(&p, sep),
                                    0, ALGOR_NUM - 1, &errstr);
                                sstrsep(&p, sep);
                                for (j = 0; j < SIZE_NUM; ++j)
                                        results[alg][j] += atof(sstrsep(&p, sep));
                        } else if (!strncmp(buf, "+F2:", 4)) {
                                int k;
                                double d;

                                p = buf + 4;
                                k = strtonum(sstrsep(&p, sep),
                                    0, ALGOR_NUM - 1, &errstr);
                                sstrsep(&p, sep);

                                d = atof(sstrsep(&p, sep));
                                if (n)
                                        rsa_results[k][0] = 1 / (1 / rsa_results[k][0] + 1 / d);
                                else
                                        rsa_results[k][0] = d;

                                d = atof(sstrsep(&p, sep));
                                if (n)
                                        rsa_results[k][1] = 1 / (1 / rsa_results[k][1] + 1 / d);
                                else
                                        rsa_results[k][1] = d;
                        } else if (!strncmp(buf, "+F2:", 4)) {
                                int k;
                                double d;

                                p = buf + 4;
                                k = strtonum(sstrsep(&p, sep),
                                    0, ALGOR_NUM - 1, &errstr);
                                sstrsep(&p, sep);

                                d = atof(sstrsep(&p, sep));
                                if (n)
                                        rsa_results[k][0] = 1 / (1 / rsa_results[k][0] + 1 / d);
                                else
                                        rsa_results[k][0] = d;

                                d = atof(sstrsep(&p, sep));
                                if (n)
                                        rsa_results[k][1] = 1 / (1 / rsa_results[k][1] + 1 / d);
                                else
                                        rsa_results[k][1] = d;
                        } else if (!strncmp(buf, "+F3:", 4)) {
                                int k;
                                double d;

                                p = buf + 4;
                                k = strtonum(sstrsep(&p, sep),
                                    0, ALGOR_NUM - 1, &errstr);
                                sstrsep(&p, sep);

                                d = atof(sstrsep(&p, sep));
                                if (n)
                                        dsa_results[k][0] = 1 / (1 / dsa_results[k][0] + 1 / d);
                                else
                                        dsa_results[k][0] = d;

                                d = atof(sstrsep(&p, sep));
                                if (n)
                                        dsa_results[k][1] = 1 / (1 / dsa_results[k][1] + 1 / d);
                                else
                                        dsa_results[k][1] = d;
                        } else if (!strncmp(buf, "+F4:", 4)) {
                                int k;
                                double d;

                                p = buf + 4;
                                k = strtonum(sstrsep(&p, sep),
                                    0, ALGOR_NUM - 1, &errstr);
                                sstrsep(&p, sep);

                                d = atof(sstrsep(&p, sep));
                                if (n)
                                        ecdsa_results[k][0] = 1 / (1 / ecdsa_results[k][0] + 1 / d);
                                else
                                        ecdsa_results[k][0] = d;

                                d = atof(sstrsep(&p, sep));
                                if (n)
                                        ecdsa_results[k][1] = 1 / (1 / ecdsa_results[k][1] + 1 / d);
                                else
                                        ecdsa_results[k][1] = d;
                        } else if (!strncmp(buf, "+F5:", 4)) {
                                int k;
                                double d;

                                p = buf + 4;
                                k = strtonum(sstrsep(&p, sep),
                                    0, ALGOR_NUM - 1, &errstr);
                                sstrsep(&p, sep);

                                d = atof(sstrsep(&p, sep));
                                if (n)
                                        ecdh_results[k][0] = 1 / (1 / ecdh_results[k][0] + 1 / d);
                                else
                                        ecdh_results[k][0] = d;

                        } else if (!strncmp(buf, "+H:", 3)) {
                        } else
                                fprintf(stderr, "Unknown type '%s' from child %d\n", buf, n);
                }

                fclose(f);
        }
        free(fds);
        return 1;
}

#endif /* OPENSSL_NO_SPEED */