Path: blob/main/contrib/bearssl/test/test_speed.c
105152 views
/*1* Copyright (c) 2016 Thomas Pornin <[email protected]>2*3* Permission is hereby granted, free of charge, to any person obtaining4* a copy of this software and associated documentation files (the5* "Software"), to deal in the Software without restriction, including6* without limitation the rights to use, copy, modify, merge, publish,7* distribute, sublicense, and/or sell copies of the Software, and to8* permit persons to whom the Software is furnished to do so, subject to9* the following conditions:10*11* The above copyright notice and this permission notice shall be12* included in all copies or substantial portions of the Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,15* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF16* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND17* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS18* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN19* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN20* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE21* SOFTWARE.22*/2324#include <stdio.h>25#include <stdlib.h>26#include <string.h>27#include <time.h>28#include "inner.h"2930#define HASH_SIZE(cname) br_ ## cname ## _SIZE3132#define SPEED_HASH(Name, cname) \33static void \34test_speed_ ## cname(void) \35{ \36unsigned char buf[8192]; \37unsigned char tmp[HASH_SIZE(cname)]; \38br_ ## cname ## _context mc; \39int i; \40long num; \41\42memset(buf, 'T', sizeof buf); \43for (i = 0; i < 10; i ++) { \44br_ ## cname ## _init(&mc); \45br_ ## cname ## _update(&mc, buf, sizeof buf); \46br_ ## cname ## _out(&mc, tmp); \47} \48num = 10; \49for (;;) { \50clock_t begin, end; \51double tt; \52long k; \53\54br_ ## cname ## _init(&mc); \55begin = clock(); \56for (k = num; k > 0; k --) { \57br_ ## cname ## _update(&mc, buf, sizeof buf); \58} \59end = clock(); \60br_ ## cname ## _out(&mc, tmp); \61tt = (double)(end - begin) / CLOCKS_PER_SEC; \62if (tt >= 2.0) { \63printf("%-30s %8.2f MB/s\n", #Name, \64((double)sizeof buf) * (double)num \65/ (tt * 1000000.0)); \66fflush(stdout); \67return; \68} \69num <<= 1; \70} \71}7273#define BLOCK_SIZE(cname) br_ ## cname ## _BLOCK_SIZE7475#define SPEED_BLOCKCIPHER_CBC(Name, fname, cname, klen, dir) \76static void \77test_speed_ ## fname(void) \78{ \79unsigned char key[klen]; \80unsigned char buf[8192 - (8192 % BLOCK_SIZE(cname))]; \81unsigned char iv[BLOCK_SIZE(cname)]; \82const br_block_cbc ## dir ## _class *vt; \83br_ ## cname ## _cbc ## dir ## _keys ec; \84int i; \85long num; \86\87memset(key, 'T', sizeof key); \88memset(buf, 'P', sizeof buf); \89memset(iv, 'X', sizeof iv); \90vt = br_ ## cname ## _cbc ## dir ## _get_vtable(); \91if (vt == NULL) { \92printf("%-30s UNAVAILABLE\n", #Name); \93fflush(stdout); \94return; \95} \96for (i = 0; i < 10; i ++) { \97vt->init(&ec.vtable, key, sizeof key); \98vt->run(&ec.vtable, iv, buf, sizeof buf); \99} \100num = 10; \101for (;;) { \102clock_t begin, end; \103double tt; \104long k; \105\106vt->init(&ec.vtable, key, sizeof key); \107begin = clock(); \108for (k = num; k > 0; k --) { \109vt->run(&ec.vtable, iv, buf, sizeof buf); \110} \111end = clock(); \112tt = (double)(end - begin) / CLOCKS_PER_SEC; \113if (tt >= 2.0) { \114printf("%-30s %8.2f MB/s\n", #Name, \115((double)sizeof buf) * (double)num \116/ (tt * 1000000.0)); \117fflush(stdout); \118return; \119} \120num <<= 1; \121} \122}123124#define SPEED_BLOCKCIPHER_CTR(Name, fname, cname, klen) \125static void \126test_speed_ ## fname(void) \127{ \128unsigned char key[klen]; \129unsigned char buf[8192 - (8192 % BLOCK_SIZE(cname))]; \130unsigned char iv[BLOCK_SIZE(cname) - 4]; \131const br_block_ctr_class *vt; \132br_ ## cname ## _ctr_keys ec; \133int i; \134long num; \135\136memset(key, 'T', sizeof key); \137memset(buf, 'P', sizeof buf); \138memset(iv, 'X', sizeof iv); \139vt = br_ ## cname ## _ctr_get_vtable(); \140if (vt == NULL) { \141printf("%-30s UNAVAILABLE\n", #Name); \142fflush(stdout); \143return; \144} \145for (i = 0; i < 10; i ++) { \146vt->init(&ec.vtable, key, sizeof key); \147vt->run(&ec.vtable, iv, 1, buf, sizeof buf); \148} \149num = 10; \150for (;;) { \151clock_t begin, end; \152double tt; \153long k; \154\155vt->init(&ec.vtable, key, sizeof key); \156begin = clock(); \157for (k = num; k > 0; k --) { \158vt->run(&ec.vtable, iv, 1, buf, sizeof buf); \159} \160end = clock(); \161tt = (double)(end - begin) / CLOCKS_PER_SEC; \162if (tt >= 2.0) { \163printf("%-30s %8.2f MB/s\n", #Name, \164((double)sizeof buf) * (double)num \165/ (tt * 1000000.0)); \166fflush(stdout); \167return; \168} \169num <<= 1; \170} \171}172173#define SPEED_CHACHA20(Name, fname) \174static void \175test_speed_ ## fname(void) \176{ \177br_chacha20_run bc; \178unsigned char key[32]; \179unsigned char buf[8192]; \180unsigned char iv[12]; \181int i; \182long num; \183\184bc = br_ ## fname ## _get(); \185if (bc == 0) { \186printf("%-30s UNAVAILABLE\n", #Name); \187fflush(stdout); \188return; \189} \190memset(key, 'T', sizeof key); \191memset(buf, 'P', sizeof buf); \192memset(iv, 'X', sizeof iv); \193for (i = 0; i < 10; i ++) { \194bc(key, iv, i, buf, sizeof buf); \195} \196num = 10; \197for (;;) { \198clock_t begin, end; \199double tt; \200long k; \201\202begin = clock(); \203for (k = num; k > 0; k --) { \204bc(key, iv, (uint32_t)k, buf, sizeof buf); \205} \206end = clock(); \207tt = (double)(end - begin) / CLOCKS_PER_SEC; \208if (tt >= 2.0) { \209printf("%-30s %8.2f MB/s\n", #Name, \210((double)sizeof buf) * (double)num \211/ (tt * 1000000.0)); \212fflush(stdout); \213return; \214} \215num <<= 1; \216} \217}218219SPEED_HASH(MD5, md5)220SPEED_HASH(SHA-1, sha1)221SPEED_HASH(SHA-256, sha256)222SPEED_HASH(SHA-512, sha512)223224/*225* There are no vtable selection functions for the portable implementations,226* so we define some custom macros.227*/228#define br_aes_big_cbcenc_get_vtable() (&br_aes_big_cbcenc_vtable)229#define br_aes_big_cbcdec_get_vtable() (&br_aes_big_cbcdec_vtable)230#define br_aes_big_ctr_get_vtable() (&br_aes_big_ctr_vtable)231#define br_aes_big_ctrcbc_get_vtable() (&br_aes_big_ctrcbc_vtable)232#define br_aes_small_cbcenc_get_vtable() (&br_aes_small_cbcenc_vtable)233#define br_aes_small_cbcdec_get_vtable() (&br_aes_small_cbcdec_vtable)234#define br_aes_small_ctr_get_vtable() (&br_aes_small_ctr_vtable)235#define br_aes_small_ctrcbc_get_vtable() (&br_aes_small_ctrcbc_vtable)236#define br_aes_ct_cbcenc_get_vtable() (&br_aes_ct_cbcenc_vtable)237#define br_aes_ct_cbcdec_get_vtable() (&br_aes_ct_cbcdec_vtable)238#define br_aes_ct_ctr_get_vtable() (&br_aes_ct_ctr_vtable)239#define br_aes_ct_ctrcbc_get_vtable() (&br_aes_ct_ctrcbc_vtable)240#define br_aes_ct64_cbcenc_get_vtable() (&br_aes_ct64_cbcenc_vtable)241#define br_aes_ct64_cbcdec_get_vtable() (&br_aes_ct64_cbcdec_vtable)242#define br_aes_ct64_ctr_get_vtable() (&br_aes_ct64_ctr_vtable)243#define br_aes_ct64_ctrcbc_get_vtable() (&br_aes_ct64_ctrcbc_vtable)244#define br_chacha20_ct_get() (&br_chacha20_ct_run)245246#define SPEED_AES(iname) \247SPEED_BLOCKCIPHER_CBC(AES-128 CBC encrypt (iname), aes128_ ## iname ## _cbcenc, aes_ ## iname, 16, enc) \248SPEED_BLOCKCIPHER_CBC(AES-128 CBC decrypt (iname), aes128_ ## iname ## _cbcdec, aes_ ## iname, 16, dec) \249SPEED_BLOCKCIPHER_CBC(AES-192 CBC encrypt (iname), aes192_ ## iname ## _cbcenc, aes_ ## iname, 24, enc) \250SPEED_BLOCKCIPHER_CBC(AES-192 CBC decrypt (iname), aes192_ ## iname ## _cbcdec, aes_ ## iname, 24, dec) \251SPEED_BLOCKCIPHER_CBC(AES-256 CBC encrypt (iname), aes256_ ## iname ## _cbcenc, aes_ ## iname, 32, enc) \252SPEED_BLOCKCIPHER_CBC(AES-256 CBC decrypt (iname), aes256_ ## iname ## _cbcdec, aes_ ## iname, 32, dec) \253SPEED_BLOCKCIPHER_CTR(AES-128 CTR (iname), aes128_ ## iname ## _ctr, aes_ ## iname, 16) \254SPEED_BLOCKCIPHER_CTR(AES-192 CTR (iname), aes192_ ## iname ## _ctr, aes_ ## iname, 24) \255SPEED_BLOCKCIPHER_CTR(AES-256 CTR (iname), aes256_ ## iname ## _ctr, aes_ ## iname, 32)256257SPEED_AES(big)258SPEED_AES(small)259SPEED_AES(ct)260SPEED_AES(ct64)261SPEED_AES(x86ni)262SPEED_AES(pwr8)263264#define br_des_tab_cbcenc_get_vtable() (&br_des_tab_cbcenc_vtable)265#define br_des_tab_cbcdec_get_vtable() (&br_des_tab_cbcdec_vtable)266#define br_des_ct_cbcenc_get_vtable() (&br_des_ct_cbcenc_vtable)267#define br_des_ct_cbcdec_get_vtable() (&br_des_ct_cbcdec_vtable)268269#define SPEED_DES(iname) \270SPEED_BLOCKCIPHER_CBC(DES CBC encrypt (iname), des_ ## iname ## _cbcenc, des_ ## iname, 8, enc) \271SPEED_BLOCKCIPHER_CBC(DES CBC decrypt (iname), des_ ## iname ## _cbcdec, des_ ## iname, 8, dec) \272SPEED_BLOCKCIPHER_CBC(3DES CBC encrypt (iname), 3des_ ## iname ## _cbcenc, des_ ## iname, 24, enc) \273SPEED_BLOCKCIPHER_CBC(3DES CBC decrypt (iname), 3des_ ## iname ## _cbcdec, des_ ## iname, 24, dec)274275SPEED_DES(tab)276SPEED_DES(ct)277278SPEED_CHACHA20(ChaCha20 (ct), chacha20_ct)279SPEED_CHACHA20(ChaCha20 (sse2), chacha20_sse2)280281static void282test_speed_ghash_inner(char *name, br_ghash gh)283{284unsigned char buf[8192], h[16], y[16];285int i;286long num;287288memset(buf, 'T', sizeof buf);289memset(h, 'P', sizeof h);290memset(y, 0, sizeof y);291for (i = 0; i < 10; i ++) {292gh(y, h, buf, sizeof buf);293}294num = 10;295for (;;) {296clock_t begin, end;297double tt;298long k;299300begin = clock();301for (k = num; k > 0; k --) {302gh(y, h, buf, sizeof buf);303}304end = clock();305tt = (double)(end - begin) / CLOCKS_PER_SEC;306if (tt >= 2.0) {307printf("%-30s %8.2f MB/s\n", name,308((double)sizeof buf) * (double)num309/ (tt * 1000000.0));310fflush(stdout);311return;312}313num <<= 1;314}315}316317static void318test_speed_ghash_ctmul(void)319{320test_speed_ghash_inner("GHASH (ctmul)", &br_ghash_ctmul);321}322323static void324test_speed_ghash_ctmul32(void)325{326test_speed_ghash_inner("GHASH (ctmul32)", &br_ghash_ctmul32);327}328329static void330test_speed_ghash_ctmul64(void)331{332test_speed_ghash_inner("GHASH (ctmul64)", &br_ghash_ctmul64);333}334335static void336test_speed_ghash_pclmul(void)337{338br_ghash gh;339340gh = br_ghash_pclmul_get();341if (gh == 0) {342printf("%-30s UNAVAILABLE\n", "GHASH (pclmul)");343fflush(stdout);344} else {345test_speed_ghash_inner("GHASH (pclmul)", gh);346}347}348349static void350test_speed_ghash_pwr8(void)351{352br_ghash gh;353354gh = br_ghash_pwr8_get();355if (gh == 0) {356printf("%-30s UNAVAILABLE\n", "GHASH (pwr8)");357fflush(stdout);358} else {359test_speed_ghash_inner("GHASH (pwr8)", gh);360}361}362363static uint32_t364fake_chacha20(const void *key, const void *iv,365uint32_t cc, void *data, size_t len)366{367(void)key;368(void)iv;369(void)data;370(void)len;371return cc + (uint32_t)((len + 63) >> 6);372}373374/*375* To speed-test Poly1305, we run it with a do-nothing stub instead of376* ChaCha20.377*/378static void379test_speed_poly1305_inner(char *name, br_poly1305_run pl)380{381unsigned char buf[8192], key[32], iv[12], aad[13], tag[16];382int i;383long num;384385memset(key, 'K', sizeof key);386memset(iv, 'I', sizeof iv);387memset(aad, 'A', sizeof aad);388memset(buf, 'T', sizeof buf);389for (i = 0; i < 10; i ++) {390pl(key, iv, buf, sizeof buf,391aad, sizeof aad, tag, &fake_chacha20, 0);392}393num = 10;394for (;;) {395clock_t begin, end;396double tt;397long k;398399begin = clock();400for (k = num; k > 0; k --) {401pl(key, iv, buf, sizeof buf,402aad, sizeof aad, tag, &fake_chacha20, 0);403}404end = clock();405tt = (double)(end - begin) / CLOCKS_PER_SEC;406if (tt >= 2.0) {407printf("%-30s %8.2f MB/s\n", name,408((double)sizeof buf) * (double)num409/ (tt * 1000000.0));410fflush(stdout);411return;412}413num <<= 1;414}415}416417static void418test_speed_poly1305_ctmul(void)419{420test_speed_poly1305_inner("Poly1305 (ctmul)", &br_poly1305_ctmul_run);421}422423static void424test_speed_poly1305_ctmul32(void)425{426test_speed_poly1305_inner("Poly1305 (ctmul32)",427&br_poly1305_ctmul32_run);428}429430static void431test_speed_poly1305_ctmulq(void)432{433br_poly1305_run bp;434435bp = br_poly1305_ctmulq_get();436if (bp == 0) {437printf("%-30s UNAVAILABLE\n", "Poly1305 (ctmulq)");438} else {439test_speed_poly1305_inner("Poly1305 (ctmulq)", bp);440}441}442443static void444test_speed_poly1305_i15(void)445{446test_speed_poly1305_inner("Poly1305 (i15)", &br_poly1305_i15_run);447}448449static void450test_speed_eax_inner(char *name,451const br_block_ctrcbc_class *vt, size_t key_len)452{453unsigned char buf[8192], key[32], nonce[16], aad[16], tag[16];454int i;455long num;456br_aes_gen_ctrcbc_keys ac;457br_eax_context ec;458459if (vt == NULL) {460printf("%-30s UNAVAILABLE\n", name);461fflush(stdout);462return;463}464memset(key, 'K', key_len);465memset(nonce, 'N', sizeof nonce);466memset(aad, 'A', sizeof aad);467memset(buf, 'T', sizeof buf);468for (i = 0; i < 10; i ++) {469vt->init(&ac.vtable, key, key_len);470br_eax_init(&ec, &ac.vtable);471br_eax_reset(&ec, nonce, sizeof nonce);472br_eax_aad_inject(&ec, aad, sizeof aad);473br_eax_flip(&ec);474br_eax_run(&ec, 1, buf, sizeof buf);475br_eax_get_tag(&ec, tag);476}477num = 10;478for (;;) {479clock_t begin, end;480double tt;481long k;482483begin = clock();484for (k = num; k > 0; k --) {485vt->init(&ac.vtable, key, key_len);486br_eax_init(&ec, &ac.vtable);487br_eax_reset(&ec, nonce, sizeof nonce);488br_eax_aad_inject(&ec, aad, sizeof aad);489br_eax_flip(&ec);490br_eax_run(&ec, 1, buf, sizeof buf);491br_eax_get_tag(&ec, tag);492}493end = clock();494tt = (double)(end - begin) / CLOCKS_PER_SEC;495if (tt >= 2.0) {496printf("%-30s %8.2f MB/s\n", name,497((double)sizeof buf) * (double)num498/ (tt * 1000000.0));499fflush(stdout);500return;501}502num <<= 1;503}504}505506#define SPEED_EAX(Algo, algo, keysize, impl) \507static void \508test_speed_eax_ ## algo ## keysize ## _ ## impl(void) \509{ \510test_speed_eax_inner("EAX " #Algo "-" #keysize "(" #impl ")", \511br_ ## algo ## _ ## impl ## _ctrcbc_get_vtable() \512, (keysize) >> 3); \513}514515SPEED_EAX(AES, aes, 128, big)516SPEED_EAX(AES, aes, 128, small)517SPEED_EAX(AES, aes, 128, ct)518SPEED_EAX(AES, aes, 128, ct64)519SPEED_EAX(AES, aes, 128, x86ni)520SPEED_EAX(AES, aes, 128, pwr8)521SPEED_EAX(AES, aes, 192, big)522SPEED_EAX(AES, aes, 192, small)523SPEED_EAX(AES, aes, 192, ct)524SPEED_EAX(AES, aes, 192, ct64)525SPEED_EAX(AES, aes, 192, x86ni)526SPEED_EAX(AES, aes, 192, pwr8)527SPEED_EAX(AES, aes, 256, big)528SPEED_EAX(AES, aes, 256, small)529SPEED_EAX(AES, aes, 256, ct)530SPEED_EAX(AES, aes, 256, ct64)531SPEED_EAX(AES, aes, 256, x86ni)532SPEED_EAX(AES, aes, 256, pwr8)533534static void535test_speed_shake_inner(int security_level)536{537unsigned char buf[8192];538br_shake_context sc;539int i;540long num;541542memset(buf, 'D', sizeof buf);543br_shake_init(&sc, security_level);544for (i = 0; i < 10; i ++) {545br_shake_inject(&sc, buf, sizeof buf);546}547num = 10;548for (;;) {549clock_t begin, end;550double tt;551long k;552553begin = clock();554for (k = num; k > 0; k --) {555br_shake_inject(&sc, buf, sizeof buf);556}557end = clock();558tt = (double)(end - begin) / CLOCKS_PER_SEC;559if (tt >= 2.0) {560printf("SHAKE%-3d (inject) %8.2f MB/s\n",561security_level,562((double)sizeof buf) * (double)num563/ (tt * 1000000.0));564fflush(stdout);565break;566}567num <<= 1;568}569570br_shake_flip(&sc);571for (i = 0; i < 10; i ++) {572br_shake_produce(&sc, buf, sizeof buf);573}574575num = 10;576for (;;) {577clock_t begin, end;578double tt;579long k;580581begin = clock();582for (k = num; k > 0; k --) {583br_shake_produce(&sc, buf, sizeof buf);584}585end = clock();586tt = (double)(end - begin) / CLOCKS_PER_SEC;587if (tt >= 2.0) {588printf("SHAKE%-3d (produce) %8.2f MB/s\n",589security_level,590((double)sizeof buf) * (double)num591/ (tt * 1000000.0));592fflush(stdout);593break;594}595num <<= 1;596}597}598599static void600test_speed_shake128(void)601{602test_speed_shake_inner(128);603}604605static void606test_speed_shake256(void)607{608test_speed_shake_inner(256);609}610611static const unsigned char RSA_N[] = {6120xE9, 0xF2, 0x4A, 0x2F, 0x96, 0xDF, 0x0A, 0x23,6130x01, 0x85, 0xF1, 0x2C, 0xB2, 0xA8, 0xEF, 0x23,6140xCE, 0x2E, 0xB0, 0x4E, 0x18, 0x31, 0x95, 0x5B,6150x98, 0x2D, 0x9B, 0x8C, 0xE3, 0x1A, 0x2B, 0x96,6160xB5, 0xC7, 0xEE, 0xED, 0x72, 0x43, 0x2D, 0xFE,6170x7F, 0x61, 0x33, 0xEA, 0x14, 0xFC, 0xDE, 0x80,6180x17, 0x42, 0xF0, 0xF3, 0xC3, 0xC7, 0x89, 0x47,6190x76, 0x5B, 0xFA, 0x33, 0xC4, 0x8C, 0x94, 0xDE,6200x6A, 0x75, 0xD8, 0x1A, 0xF4, 0x49, 0xBC, 0xF3,6210xB7, 0x9E, 0x2C, 0x8D, 0xEC, 0x5A, 0xEE, 0xBF,6220x4B, 0x5A, 0x7F, 0xEF, 0x21, 0x39, 0xDB, 0x1D,6230x83, 0x5E, 0x7E, 0x2F, 0xAA, 0x5E, 0xBA, 0x28,6240xC3, 0xA2, 0x53, 0x19, 0xFB, 0x2F, 0x78, 0x6B,6250x14, 0x60, 0x49, 0x3C, 0xCC, 0x1B, 0xE9, 0x1E,6260x3D, 0x10, 0xA4, 0xEB, 0x7F, 0x66, 0x98, 0xF6,6270xC3, 0xAC, 0x35, 0xF5, 0x01, 0x84, 0xFF, 0x7D,6280x1F, 0x72, 0xBE, 0xB4, 0xD1, 0x89, 0xC8, 0xDD,6290x44, 0xE7, 0xB5, 0x2E, 0x2C, 0xE1, 0x85, 0xF5,6300x15, 0x50, 0xA9, 0x08, 0xC7, 0x67, 0xD9, 0x2B,6310x6C, 0x11, 0xB3, 0xEB, 0x28, 0x8D, 0xF4, 0xCC,6320xE3, 0xC3, 0xC5, 0x04, 0x0E, 0x7C, 0x8D, 0xDB,6330x39, 0x06, 0x6A, 0x74, 0x75, 0xDF, 0xA8, 0x0F,6340xDA, 0x67, 0x5A, 0x73, 0x1E, 0xFD, 0x8E, 0x4C,6350xEE, 0x17, 0xEE, 0x1E, 0x67, 0xDB, 0x98, 0x70,6360x60, 0xF7, 0xB9, 0xB5, 0x1F, 0x19, 0x93, 0xD6,6370x3F, 0x2F, 0x1F, 0xB6, 0x5B, 0x59, 0xAA, 0x85,6380xBB, 0x25, 0xE4, 0x13, 0xEF, 0xE7, 0xB9, 0x87,6390x9C, 0x3F, 0x5E, 0xE4, 0x08, 0xA3, 0x51, 0xCF,6400x8B, 0xAD, 0xF4, 0xE6, 0x1A, 0x5F, 0x51, 0xDD,6410xA8, 0xBE, 0xE8, 0xD1, 0x20, 0x19, 0x61, 0x6C,6420x18, 0xAB, 0xCA, 0x0A, 0xD9, 0x82, 0xA6, 0x94,6430xD5, 0x69, 0x2A, 0xF6, 0x43, 0x66, 0x31, 0x09644};645646static const unsigned char RSA_E[] = {6470x01, 0x00, 0x01648};649650static const unsigned char RSA_P[] = {6510xFD, 0x39, 0x40, 0x56, 0x20, 0x80, 0xC5, 0x81,6520x4C, 0x5F, 0x0C, 0x1A, 0x52, 0x84, 0x03, 0x2F,6530xCE, 0x82, 0xB0, 0xD8, 0x30, 0x23, 0x7F, 0x77,6540x45, 0xC2, 0x01, 0xC4, 0x68, 0x96, 0x0D, 0xA7,6550x22, 0xA9, 0x6C, 0xA9, 0x1A, 0x33, 0xE5, 0x2F,6560xB5, 0x07, 0x9A, 0xF9, 0xEA, 0x33, 0xA5, 0xC8,6570x96, 0x60, 0x6A, 0xCA, 0xEB, 0xE5, 0x6E, 0x09,6580x46, 0x7E, 0x2D, 0xEF, 0x93, 0x7D, 0x56, 0xED,6590x75, 0x70, 0x3B, 0x96, 0xC4, 0xD5, 0xDB, 0x0B,6600x3F, 0x69, 0xDF, 0x06, 0x18, 0x76, 0xF4, 0xCF,6610xF8, 0x84, 0x22, 0xDF, 0xBD, 0x71, 0x62, 0x7B,6620x67, 0x99, 0xBC, 0x09, 0x95, 0x54, 0xA4, 0x98,6630x83, 0xF5, 0xA9, 0xCF, 0x09, 0xA5, 0x1F, 0x61,6640x25, 0xB4, 0x70, 0x6C, 0x91, 0xB8, 0xB3, 0xD0,6650xCE, 0x9C, 0x45, 0x65, 0x9B, 0xEF, 0xD4, 0x70,6660xBE, 0x86, 0xD2, 0x98, 0x5D, 0xEB, 0xE3, 0xFF667};668669static const unsigned char RSA_Q[] = {6700xEC, 0x82, 0xEE, 0x63, 0x5F, 0x40, 0x52, 0xDB,6710x38, 0x7A, 0x37, 0x6A, 0x54, 0x5B, 0xD9, 0xA0,6720x73, 0xB4, 0xBB, 0x52, 0xB2, 0x84, 0x07, 0xD0,6730xCC, 0x82, 0x0D, 0x20, 0xB3, 0xFA, 0xD5, 0xB6,6740x25, 0x92, 0x35, 0x4D, 0xB4, 0xC7, 0x36, 0x48,6750xCE, 0x5E, 0x21, 0x4A, 0xA6, 0x74, 0x65, 0xF4,6760x7D, 0x1D, 0xBC, 0x3B, 0xE2, 0xF4, 0x3E, 0x11,6770x58, 0x10, 0x6C, 0x04, 0x46, 0x9E, 0x8D, 0x57,6780xE0, 0x04, 0xE2, 0xEC, 0x47, 0xCF, 0xB3, 0x2A,6790xFD, 0x4C, 0x55, 0x18, 0xDB, 0xDE, 0x3B, 0xDC,6800xF4, 0x5B, 0xDA, 0xF3, 0x1A, 0xC8, 0x41, 0x6F,6810x73, 0x3B, 0xFE, 0x3C, 0xA0, 0xDB, 0xBA, 0x6E,6820x65, 0xA5, 0xE8, 0x02, 0xA5, 0x6C, 0xEA, 0x03,6830xF6, 0x99, 0xF7, 0xCB, 0x4B, 0xB7, 0x11, 0x51,6840x93, 0x88, 0x3F, 0xF9, 0x06, 0x85, 0xA9, 0x1E,6850xCA, 0x64, 0xF8, 0x11, 0xA5, 0x1A, 0xCA, 0xF7686};687688static const unsigned char RSA_DP[] = {6890x77, 0x95, 0xE0, 0x02, 0x4C, 0x9B, 0x43, 0xAA,6900xCA, 0x4C, 0x60, 0xC4, 0xD5, 0x8F, 0x2E, 0x8A,6910x17, 0x36, 0xB5, 0x19, 0x83, 0xB2, 0x5F, 0xF2,6920x0D, 0xE9, 0x8F, 0x38, 0x18, 0x44, 0x34, 0xF2,6930x67, 0x76, 0x27, 0xB0, 0xBC, 0x85, 0x21, 0x89,6940x24, 0x2F, 0x11, 0x4B, 0x51, 0x05, 0x4F, 0x17,6950xA9, 0x9C, 0xA3, 0x12, 0x6D, 0xD1, 0x0D, 0xE4,6960x27, 0x7C, 0x53, 0x69, 0x3E, 0xF8, 0x04, 0x63,6970x64, 0x00, 0xBA, 0xC3, 0x7A, 0xF5, 0x9B, 0xDA,6980x75, 0xFA, 0x23, 0xAF, 0x17, 0x42, 0xA6, 0x5E,6990xC8, 0xF8, 0x6E, 0x17, 0xC7, 0xB9, 0x92, 0x4E,7000xC1, 0x20, 0x63, 0x23, 0x0B, 0x78, 0xCB, 0xBA,7010x93, 0x27, 0x23, 0x28, 0x79, 0x5F, 0x97, 0xB0,7020x23, 0x44, 0x51, 0x8B, 0x94, 0x4D, 0xEB, 0xED,7030x82, 0x85, 0x5E, 0x68, 0x9B, 0xF9, 0xE9, 0x13,7040xCD, 0x86, 0x92, 0x52, 0x0E, 0x98, 0xE6, 0x35705};706707static const unsigned char RSA_DQ[] = {7080xD8, 0xDD, 0x71, 0xB3, 0x62, 0xBA, 0xBB, 0x7E,7090xD1, 0xF9, 0x96, 0xE8, 0x83, 0xB3, 0xB9, 0x08,7100x9C, 0x30, 0x03, 0x77, 0xDF, 0xC2, 0x9A, 0xDC,7110x05, 0x39, 0xD6, 0xC9, 0xBE, 0xDE, 0x68, 0xA9,7120xDD, 0x27, 0x84, 0x82, 0xDD, 0x19, 0xB1, 0x97,7130xEE, 0xCA, 0x77, 0x22, 0x59, 0x20, 0xEF, 0xFF,7140xCF, 0xDD, 0xBD, 0x24, 0xF8, 0x84, 0xD6, 0x88,7150xD6, 0xC4, 0x30, 0x17, 0x77, 0x9D, 0x98, 0xA3,7160x14, 0x01, 0xC7, 0x05, 0xBB, 0x0F, 0x23, 0x0D,7170x6F, 0x37, 0x57, 0xEC, 0x34, 0x67, 0x41, 0x62,7180xE8, 0x19, 0x75, 0xD9, 0x66, 0x1C, 0x6B, 0x8B,7190xC3, 0x11, 0x26, 0x9C, 0xF7, 0x2E, 0xA3, 0x72,7200xE8, 0xF7, 0xC8, 0x96, 0xEC, 0x92, 0xC2, 0xBD,7210xA1, 0x98, 0x2A, 0x93, 0x99, 0xB8, 0xA2, 0x43,7220xB7, 0xD0, 0xBE, 0x40, 0x1C, 0x8F, 0xE0, 0xB4,7230x20, 0x07, 0x97, 0x43, 0xAE, 0xAD, 0xB3, 0x9F724};725726static const unsigned char RSA_IQ[] = {7270xB7, 0xE2, 0x60, 0xA9, 0x62, 0xEC, 0xEC, 0x0B,7280x57, 0x02, 0x96, 0xF9, 0x36, 0x35, 0x2C, 0x37,7290xAF, 0xC2, 0xEE, 0x71, 0x49, 0x26, 0x8E, 0x0F,7300x27, 0xB1, 0xFA, 0x0F, 0xEA, 0xDC, 0xF0, 0x8B,7310x53, 0x6C, 0xB2, 0x46, 0x27, 0xCD, 0x29, 0xA2,7320x35, 0x0F, 0x5D, 0x8A, 0x3F, 0x20, 0x8C, 0x13,7330x3D, 0xA1, 0xFF, 0x85, 0x91, 0x99, 0xE8, 0x50,7340xED, 0xF1, 0x29, 0x00, 0xEE, 0x24, 0x90, 0xB5,7350x5F, 0x3A, 0x74, 0x26, 0xD7, 0xA2, 0x24, 0x8D,7360x89, 0x88, 0xD8, 0x35, 0x22, 0x22, 0x8A, 0x66,7370x5D, 0x5C, 0xDE, 0x83, 0x8C, 0xFA, 0x27, 0xE6,7380xB9, 0xEB, 0x72, 0x08, 0xCD, 0x53, 0x4B, 0x93,7390x0F, 0xAD, 0xC3, 0xF8, 0x7C, 0xFE, 0x84, 0xD7,7400x08, 0xF3, 0xBE, 0x3D, 0x60, 0x1E, 0x95, 0x8D,7410x44, 0x5B, 0x65, 0x7E, 0xC1, 0x30, 0xC3, 0x84,7420xC0, 0xB0, 0xFE, 0xBF, 0x28, 0x54, 0x1E, 0xC4743};744745static const br_rsa_public_key RSA_PK = {746(void *)RSA_N, sizeof RSA_N,747(void *)RSA_E, sizeof RSA_E748};749750static const br_rsa_private_key RSA_SK = {7512048,752(void *)RSA_P, sizeof RSA_P,753(void *)RSA_Q, sizeof RSA_Q,754(void *)RSA_DP, sizeof RSA_DP,755(void *)RSA_DQ, sizeof RSA_DQ,756(void *)RSA_IQ, sizeof RSA_IQ757};758759static void760test_speed_rsa_inner(char *name,761br_rsa_public fpub, br_rsa_private fpriv, br_rsa_keygen kgen)762{763unsigned char tmp[sizeof RSA_N];764int i;765long num;766/*767br_hmac_drbg_context rng;768*/769br_aesctr_drbg_context rng;770const br_block_ctr_class *ictr;771772memset(tmp, 'R', sizeof tmp);773tmp[0] = 0;774for (i = 0; i < 10; i ++) {775if (!fpriv(tmp, &RSA_SK)) {776abort();777}778}779num = 10;780for (;;) {781clock_t begin, end;782double tt;783long k;784785begin = clock();786for (k = num; k > 0; k --) {787fpriv(tmp, &RSA_SK);788}789end = clock();790tt = (double)(end - begin) / CLOCKS_PER_SEC;791if (tt >= 2.0) {792printf("%-30s %8.2f priv/s\n", name,793(double)num / tt);794fflush(stdout);795break;796}797num <<= 1;798}799for (i = 0; i < 10; i ++) {800if (!fpub(tmp, sizeof tmp, &RSA_PK)) {801abort();802}803}804num = 10;805for (;;) {806clock_t begin, end;807double tt;808long k;809810begin = clock();811for (k = num; k > 0; k --) {812fpub(tmp, sizeof tmp, &RSA_PK);813}814end = clock();815tt = (double)(end - begin) / CLOCKS_PER_SEC;816if (tt >= 2.0) {817printf("%-30s %8.2f pub/s\n", name,818(double)num / tt);819fflush(stdout);820break;821}822num <<= 1;823}824825if (kgen == 0) {826printf("%-30s KEYGEN UNAVAILABLE\n", name);827fflush(stdout);828return;829}830/*831br_hmac_drbg_init(&rng, &br_sha256_vtable, "RSA keygen seed", 15);832*/833ictr = br_aes_x86ni_ctr_get_vtable();834if (ictr == NULL) {835ictr = br_aes_pwr8_ctr_get_vtable();836if (ictr == NULL) {837#if BR_64838ictr = &br_aes_ct64_ctr_vtable;839#else840ictr = &br_aes_ct_ctr_vtable;841#endif842}843}844br_aesctr_drbg_init(&rng, ictr, "RSA keygen seed", 15);845846num = 10;847for (;;) {848clock_t begin, end;849double tt;850long k;851852begin = clock();853for (k = num; k > 0; k --) {854br_rsa_private_key sk;855unsigned char kbuf[BR_RSA_KBUF_PRIV_SIZE(1024)];856857kgen(&rng.vtable, &sk, kbuf, NULL, NULL, 1024, 0);858}859end = clock();860tt = (double)(end - begin) / CLOCKS_PER_SEC;861if (tt >= 10.0) {862printf("%-30s %8.2f kgen[1024]/s\n", name,863(double)num / tt);864fflush(stdout);865break;866}867num <<= 1;868}869870num = 10;871for (;;) {872clock_t begin, end;873double tt;874long k;875876begin = clock();877for (k = num; k > 0; k --) {878br_rsa_private_key sk;879unsigned char kbuf[BR_RSA_KBUF_PRIV_SIZE(2048)];880881kgen(&rng.vtable, &sk, kbuf, NULL, NULL, 2048, 0);882}883end = clock();884tt = (double)(end - begin) / CLOCKS_PER_SEC;885if (tt >= 10.0) {886printf("%-30s %8.2f kgen[2048]/s\n", name,887(double)num / tt);888fflush(stdout);889break;890}891num <<= 1;892}893}894895static void896test_speed_rsa_i15(void)897{898test_speed_rsa_inner("RSA i15",899&br_rsa_i15_public, &br_rsa_i15_private, &br_rsa_i15_keygen);900}901902static void903test_speed_rsa_i31(void)904{905test_speed_rsa_inner("RSA i31",906&br_rsa_i31_public, &br_rsa_i31_private, &br_rsa_i31_keygen);907}908909static void910test_speed_rsa_i32(void)911{912test_speed_rsa_inner("RSA i32",913&br_rsa_i32_public, &br_rsa_i32_private, 0);914}915916static void917test_speed_rsa_i62(void)918{919br_rsa_public pub;920br_rsa_private priv;921br_rsa_keygen kgen;922923pub = br_rsa_i62_public_get();924priv = br_rsa_i62_private_get();925kgen = br_rsa_i62_keygen_get();926if (pub) {927test_speed_rsa_inner("RSA i62", pub, priv, kgen);928} else {929printf("%-30s UNAVAILABLE\n", "RSA i62");930}931}932933static void934test_speed_ec_inner_1(const char *name,935const br_ec_impl *impl, const br_ec_curve_def *cd)936{937unsigned char bx[80], U[160];938uint32_t x[22], n[22];939size_t nlen, ulen;940int i;941long num;942943nlen = cd->order_len;944br_i31_decode(n, cd->order, nlen);945memset(bx, 'T', sizeof bx);946br_i31_decode_reduce(x, bx, sizeof bx, n);947br_i31_encode(bx, nlen, x);948ulen = cd->generator_len;949memcpy(U, cd->generator, ulen);950for (i = 0; i < 10; i ++) {951impl->mul(U, ulen, bx, nlen, cd->curve);952}953num = 10;954for (;;) {955clock_t begin, end;956double tt;957long k;958959begin = clock();960for (k = num; k > 0; k --) {961impl->mul(U, ulen, bx, nlen, cd->curve);962}963end = clock();964tt = (double)(end - begin) / CLOCKS_PER_SEC;965if (tt >= 2.0) {966printf("%-30s %8.2f mul/s\n", name,967(double)num / tt);968fflush(stdout);969break;970}971num <<= 1;972}973}974975static void976test_speed_ec_inner_2(const char *name,977const br_ec_impl *impl, const br_ec_curve_def *cd)978{979unsigned char bx[80], U[160];980uint32_t x[22], n[22];981size_t nlen;982int i;983long num;984985nlen = cd->order_len;986br_i31_decode(n, cd->order, nlen);987memset(bx, 'T', sizeof bx);988br_i31_decode_reduce(x, bx, sizeof bx, n);989br_i31_encode(bx, nlen, x);990for (i = 0; i < 10; i ++) {991impl->mulgen(U, bx, nlen, cd->curve);992}993num = 10;994for (;;) {995clock_t begin, end;996double tt;997long k;998999begin = clock();1000for (k = num; k > 0; k --) {1001impl->mulgen(U, bx, nlen, cd->curve);1002}1003end = clock();1004tt = (double)(end - begin) / CLOCKS_PER_SEC;1005if (tt >= 2.0) {1006printf("%-30s %8.2f mul/s\n", name,1007(double)num / tt);1008fflush(stdout);1009break;1010}1011num <<= 1;1012}1013}10141015static void1016test_speed_ec_inner(const char *name,1017const br_ec_impl *impl, const br_ec_curve_def *cd)1018{1019char tmp[50];10201021test_speed_ec_inner_1(name, impl, cd);1022sprintf(tmp, "%s (FP)", name);1023test_speed_ec_inner_2(tmp, impl, cd);1024}10251026static void1027test_speed_ec_p256_m15(void)1028{1029test_speed_ec_inner("EC p256_m15",1030&br_ec_p256_m15, &br_secp256r1);1031}10321033static void1034test_speed_ec_p256_m31(void)1035{1036test_speed_ec_inner("EC p256_m31",1037&br_ec_p256_m31, &br_secp256r1);1038}10391040static void1041test_speed_ec_p256_m62(void)1042{1043const br_ec_impl *ec;10441045ec = br_ec_p256_m62_get();1046if (ec != NULL) {1047test_speed_ec_inner("EC p256_m62", ec, &br_secp256r1);1048} else {1049printf("%-30s UNAVAILABLE\n", "EC p256_m62");1050}1051}10521053static void1054test_speed_ec_p256_m64(void)1055{1056const br_ec_impl *ec;10571058ec = br_ec_p256_m64_get();1059if (ec != NULL) {1060test_speed_ec_inner("EC p256_m64", ec, &br_secp256r1);1061} else {1062printf("%-30s UNAVAILABLE\n", "EC p256_m64");1063}1064}10651066static void1067test_speed_ec_prime_i15(void)1068{1069test_speed_ec_inner("EC prime_i15 P-256",1070&br_ec_prime_i15, &br_secp256r1);1071test_speed_ec_inner("EC prime_i15 P-384",1072&br_ec_prime_i15, &br_secp384r1);1073test_speed_ec_inner("EC prime_i15 P-521",1074&br_ec_prime_i15, &br_secp521r1);1075}10761077static void1078test_speed_ec_prime_i31(void)1079{1080test_speed_ec_inner("EC prime_i31 P-256",1081&br_ec_prime_i31, &br_secp256r1);1082test_speed_ec_inner("EC prime_i31 P-384",1083&br_ec_prime_i31, &br_secp384r1);1084test_speed_ec_inner("EC prime_i31 P-521",1085&br_ec_prime_i31, &br_secp521r1);1086}10871088static void1089test_speed_ec_c25519_i15(void)1090{1091test_speed_ec_inner("EC c25519_i15",1092&br_ec_c25519_i15, &br_curve25519);1093}10941095static void1096test_speed_ec_c25519_i31(void)1097{1098test_speed_ec_inner("EC c25519_i31",1099&br_ec_c25519_i31, &br_curve25519);1100}11011102static void1103test_speed_ec_c25519_m15(void)1104{1105test_speed_ec_inner("EC c25519_m15",1106&br_ec_c25519_m15, &br_curve25519);1107}11081109static void1110test_speed_ec_c25519_m31(void)1111{1112test_speed_ec_inner("EC c25519_m31",1113&br_ec_c25519_m31, &br_curve25519);1114}11151116static void1117test_speed_ec_c25519_m62(void)1118{1119const br_ec_impl *ec;11201121ec = br_ec_c25519_m62_get();1122if (ec != NULL) {1123test_speed_ec_inner("EC c25519_m62", ec, &br_curve25519);1124} else {1125printf("%-30s UNAVAILABLE\n", "EC c25519_m62");1126}1127}11281129static void1130test_speed_ec_c25519_m64(void)1131{1132const br_ec_impl *ec;11331134ec = br_ec_c25519_m64_get();1135if (ec != NULL) {1136test_speed_ec_inner("EC c25519_m64", ec, &br_curve25519);1137} else {1138printf("%-30s UNAVAILABLE\n", "EC c25519_m64");1139}1140}11411142static void1143test_speed_ecdsa_inner(const char *name,1144const br_ec_impl *impl, const br_ec_curve_def *cd,1145br_ecdsa_sign sign, br_ecdsa_vrfy vrfy)1146{1147unsigned char bx[80], U[160], hv[32], sig[160];1148uint32_t x[22], n[22];1149size_t nlen, ulen, sig_len;1150int i;1151long num;1152br_ec_private_key sk;1153br_ec_public_key pk;11541155nlen = cd->order_len;1156br_i31_decode(n, cd->order, nlen);1157memset(bx, 'T', sizeof bx);1158br_i31_decode_reduce(x, bx, sizeof bx, n);1159br_i31_encode(bx, nlen, x);1160ulen = cd->generator_len;1161memcpy(U, cd->generator, ulen);1162impl->mul(U, ulen, bx, nlen, cd->curve);1163sk.curve = cd->curve;1164sk.x = bx;1165sk.xlen = nlen;1166pk.curve = cd->curve;1167pk.q = U;1168pk.qlen = ulen;11691170memset(hv, 'H', sizeof hv);1171sig_len = sign(impl, &br_sha256_vtable, hv, &sk, sig);1172if (vrfy(impl, hv, sizeof hv, &pk, sig, sig_len) != 1) {1173fprintf(stderr, "self-test sign/verify failed\n");1174exit(EXIT_FAILURE);1175}11761177for (i = 0; i < 10; i ++) {1178hv[1] ++;1179sign(impl, &br_sha256_vtable, hv, &sk, sig);1180vrfy(impl, hv, sizeof hv, &pk, sig, sig_len);1181}11821183num = 10;1184for (;;) {1185clock_t begin, end;1186double tt;1187long k;11881189begin = clock();1190for (k = num; k > 0; k --) {1191hv[1] ++;1192sig_len = sign(impl, &br_sha256_vtable, hv, &sk, sig);1193}1194end = clock();1195tt = (double)(end - begin) / CLOCKS_PER_SEC;1196if (tt >= 2.0) {1197printf("%-30s %8.2f sign/s\n", name,1198(double)num / tt);1199fflush(stdout);1200break;1201}1202num <<= 1;1203}12041205num = 10;1206for (;;) {1207clock_t begin, end;1208double tt;1209long k;12101211begin = clock();1212for (k = num; k > 0; k --) {1213vrfy(impl, hv, sizeof hv, &pk, sig, sig_len);1214}1215end = clock();1216tt = (double)(end - begin) / CLOCKS_PER_SEC;1217if (tt >= 2.0) {1218printf("%-30s %8.2f verify/s\n", name,1219(double)num / tt);1220fflush(stdout);1221break;1222}1223num <<= 1;1224}1225}12261227static void1228test_speed_ecdsa_p256_m15(void)1229{1230test_speed_ecdsa_inner("ECDSA m15 P-256",1231&br_ec_p256_m15, &br_secp256r1,1232&br_ecdsa_i15_sign_asn1,1233&br_ecdsa_i15_vrfy_asn1);1234}12351236static void1237test_speed_ecdsa_p256_m31(void)1238{1239test_speed_ecdsa_inner("ECDSA m31 P-256",1240&br_ec_p256_m31, &br_secp256r1,1241&br_ecdsa_i31_sign_asn1,1242&br_ecdsa_i31_vrfy_asn1);1243}12441245static void1246test_speed_ecdsa_p256_m62(void)1247{1248const br_ec_impl *ec;12491250ec = br_ec_p256_m62_get();1251if (ec != NULL) {1252test_speed_ecdsa_inner("ECDSA m62 P-256",1253ec, &br_secp256r1,1254&br_ecdsa_i31_sign_asn1,1255&br_ecdsa_i31_vrfy_asn1);1256} else {1257printf("%-30s UNAVAILABLE\n", "ECDSA m62 P-256");1258}1259}12601261static void1262test_speed_ecdsa_p256_m64(void)1263{1264const br_ec_impl *ec;12651266ec = br_ec_p256_m64_get();1267if (ec != NULL) {1268test_speed_ecdsa_inner("ECDSA m64 P-256",1269ec, &br_secp256r1,1270&br_ecdsa_i31_sign_asn1,1271&br_ecdsa_i31_vrfy_asn1);1272} else {1273printf("%-30s UNAVAILABLE\n", "ECDSA m64 P-256");1274}1275}12761277static void1278test_speed_ecdsa_i15(void)1279{1280test_speed_ecdsa_inner("ECDSA i15 P-256",1281&br_ec_prime_i15, &br_secp256r1,1282&br_ecdsa_i15_sign_asn1,1283&br_ecdsa_i15_vrfy_asn1);1284test_speed_ecdsa_inner("ECDSA i15 P-384",1285&br_ec_prime_i15, &br_secp384r1,1286&br_ecdsa_i15_sign_asn1,1287&br_ecdsa_i15_vrfy_asn1);1288test_speed_ecdsa_inner("ECDSA i15 P-521",1289&br_ec_prime_i15, &br_secp521r1,1290&br_ecdsa_i15_sign_asn1,1291&br_ecdsa_i15_vrfy_asn1);1292}12931294static void1295test_speed_ecdsa_i31(void)1296{1297test_speed_ecdsa_inner("ECDSA i31 P-256",1298&br_ec_prime_i31, &br_secp256r1,1299&br_ecdsa_i31_sign_asn1,1300&br_ecdsa_i31_vrfy_asn1);1301test_speed_ecdsa_inner("ECDSA i31 P-384",1302&br_ec_prime_i31, &br_secp384r1,1303&br_ecdsa_i31_sign_asn1,1304&br_ecdsa_i31_vrfy_asn1);1305test_speed_ecdsa_inner("ECDSA i31 P-521",1306&br_ec_prime_i31, &br_secp521r1,1307&br_ecdsa_i31_sign_asn1,1308&br_ecdsa_i31_vrfy_asn1);1309}13101311static void1312test_speed_i31(void)1313{1314static const unsigned char bp[] = {1315/* A 521-bit prime integer (order of the P-521 curve). */13160x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,13170xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,13180xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,13190xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,13200xFF, 0xFA, 0x51, 0x86, 0x87, 0x83, 0xBF, 0x2F,13210x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,13220xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C,13230x47, 0xAE, 0xBB, 0x6F, 0xB7, 0x1E, 0x91, 0x38,13240x64, 0x091325};13261327unsigned char tmp[60 + sizeof bp];1328uint32_t p[20], x[20], y[20], z[20], uu[60], p0i;1329int i;1330long num;13311332br_i31_decode(p, bp, sizeof bp);1333p0i = br_i31_ninv31(p[1]);1334memset(tmp, 'T', sizeof tmp);1335br_i31_decode_reduce(x, tmp, sizeof tmp, p);1336memset(tmp, 'U', sizeof tmp);1337br_i31_decode_reduce(y, tmp, sizeof tmp, p);13381339for (i = 0; i < 10; i ++) {1340br_i31_to_monty(x, p);1341}1342num = 10;1343for (;;) {1344clock_t begin, end;1345double tt;1346long k;13471348begin = clock();1349for (k = num; k > 0; k --) {1350br_i31_to_monty(x, p);1351}1352end = clock();1353tt = (double)(end - begin) / CLOCKS_PER_SEC;1354if (tt >= 2.0) {1355printf("%-30s %8.2f ops/s\n", "i31 to_monty",1356(double)num / tt);1357fflush(stdout);1358break;1359}1360num <<= 1;1361}13621363for (i = 0; i < 10; i ++) {1364br_i31_from_monty(x, p, p0i);1365}1366num = 10;1367for (;;) {1368clock_t begin, end;1369double tt;1370long k;13711372begin = clock();1373for (k = num; k > 0; k --) {1374br_i31_from_monty(x, p, p0i);1375}1376end = clock();1377tt = (double)(end - begin) / CLOCKS_PER_SEC;1378if (tt >= 2.0) {1379printf("%-30s %8.2f ops/s\n", "i31 from_monty",1380(double)num / tt);1381fflush(stdout);1382break;1383}1384num <<= 1;1385}13861387for (i = 0; i < 10; i ++) {1388br_i31_montymul(z, x, y, p, p0i);1389}1390num = 10;1391for (;;) {1392clock_t begin, end;1393double tt;1394long k;13951396begin = clock();1397for (k = num; k > 0; k --) {1398br_i31_montymul(z, x, y, p, p0i);1399}1400end = clock();1401tt = (double)(end - begin) / CLOCKS_PER_SEC;1402if (tt >= 2.0) {1403printf("%-30s %8.2f ops/s\n", "i31 montymul",1404(double)num / tt);1405fflush(stdout);1406break;1407}1408num <<= 1;1409}14101411for (i = 0; i < 10; i ++) {1412br_i31_moddiv(x, y, p, p0i, uu);1413}1414num = 10;1415for (;;) {1416clock_t begin, end;1417double tt;1418long k;14191420begin = clock();1421for (k = num; k > 0; k --) {1422br_i31_moddiv(x, y, p, p0i, uu);1423}1424end = clock();1425tt = (double)(end - begin) / CLOCKS_PER_SEC;1426if (tt >= 2.0) {1427printf("%-30s %8.2f ops/s\n", "i31 moddiv",1428(double)num / tt);1429fflush(stdout);1430break;1431}1432num <<= 1;1433}1434}14351436#if 014371438static unsigned char P2048[] = {14390xFD, 0xB6, 0xE0, 0x3E, 0x00, 0x49, 0x4C, 0xF0, 0x69, 0x3A, 0xDD, 0x7D,14400xF8, 0xA2, 0x41, 0xB0, 0x6C, 0x67, 0xC5, 0xBA, 0xB8, 0x46, 0x80, 0xF5,14410xBF, 0xAB, 0x98, 0xFC, 0x84, 0x73, 0xA5, 0x63, 0xC9, 0x52, 0x12, 0xDA,14420x4C, 0xC1, 0x5B, 0x9D, 0x8D, 0xDF, 0xCD, 0xFE, 0xC5, 0xAD, 0x5A, 0x6F,14430xDD, 0x02, 0xD9, 0xEC, 0x71, 0xEF, 0xEB, 0xB6, 0x95, 0xED, 0x94, 0x25,14440x0E, 0x63, 0xDD, 0x6A, 0x52, 0xC7, 0x93, 0xAF, 0x85, 0x9D, 0x2C, 0xBE,14450x5C, 0xBE, 0x35, 0xD8, 0xDD, 0x39, 0xEF, 0x1B, 0xB1, 0x49, 0x67, 0xB2,14460x33, 0xC9, 0x7C, 0xE1, 0x51, 0x79, 0x51, 0x59, 0xCA, 0x6E, 0x2A, 0xDF,14470x0D, 0x76, 0x1C, 0xE7, 0xA5, 0xC0, 0x1E, 0x6C, 0x56, 0x3A, 0x32, 0xE5,14480xB5, 0xC5, 0xD4, 0xDB, 0xFE, 0xFF, 0xF8, 0xF2, 0x96, 0xA9, 0xC9, 0x65,14490x59, 0x9E, 0x01, 0x79, 0x9D, 0x38, 0x68, 0x0F, 0xAD, 0x43, 0x3A, 0xD6,14500x84, 0x0A, 0xE2, 0xEF, 0x96, 0xC1, 0x6D, 0x89, 0x74, 0x19, 0x63, 0x82,14510x3B, 0xA0, 0x9C, 0xBA, 0x78, 0xDE, 0xDC, 0xC2, 0xE7, 0xD4, 0xFA, 0xD6,14520x19, 0x21, 0x29, 0xAE, 0x5E, 0xF4, 0x38, 0x81, 0xC6, 0x9E, 0x0E, 0x3C,14530xCD, 0xC0, 0xDC, 0x93, 0x5D, 0xFD, 0x9A, 0x5C, 0xAB, 0x54, 0x1F, 0xFF,14540x9C, 0x12, 0x1B, 0x4C, 0xDF, 0x2D, 0x9C, 0x85, 0xF9, 0x68, 0x15, 0x89,14550x42, 0x9B, 0x6C, 0x45, 0x89, 0x3A, 0xBC, 0xE9, 0x19, 0x91, 0xBE, 0x0C,14560xEF, 0x90, 0xCC, 0xF6, 0xD6, 0xF0, 0x3D, 0x5C, 0xF5, 0xE5, 0x0F, 0x2F,14570x02, 0x8A, 0x83, 0x4B, 0x93, 0x2F, 0x14, 0x12, 0x1F, 0x56, 0x9A, 0x12,14580x58, 0x88, 0xAE, 0x60, 0xB8, 0x5A, 0xE4, 0xA1, 0xBF, 0x4A, 0x81, 0x84,14590xAB, 0xBB, 0xE4, 0xD0, 0x1D, 0x41, 0xD9, 0x0A, 0xAB, 0x1E, 0x47, 0x5B,14600x31, 0xAC, 0x2B, 0x731461};14621463static unsigned char G2048[] = {14640x021465};14661467static void1468test_speed_modpow(void)1469{1470uint32_t mx[65], mp[65], me[65], t1[65], t2[65], len;1471unsigned char e[64];1472int i;1473long num;14741475len = br_int_decode(mp, sizeof mp / sizeof mp[0],1476P2048, sizeof P2048);1477if (len != 65) {1478abort();1479}1480memset(e, 'P', sizeof e);1481if (!br_int_decode(me, sizeof me / sizeof me[0], e, sizeof e)) {1482abort();1483}1484if (!br_modint_decode(mx, mp, G2048, sizeof G2048)) {1485abort();1486}1487for (i = 0; i < 10; i ++) {1488br_modint_to_monty(mx, mp);1489br_modint_montypow(mx, me, mp, t1, t2);1490br_modint_from_monty(mx, mp);1491}1492num = 10;1493for (;;) {1494clock_t begin, end;1495double tt;1496long k;14971498begin = clock();1499for (k = num; k > 0; k --) {1500br_modint_to_monty(mx, mp);1501br_modint_montypow(mx, me, mp, t1, t2);1502br_modint_from_monty(mx, mp);1503}1504end = clock();1505tt = (double)(end - begin) / CLOCKS_PER_SEC;1506if (tt >= 2.0) {1507printf("%-30s %8.2f exp/s\n", "pow[2048:256]",1508(double)num / tt);1509fflush(stdout);1510return;1511}1512num <<= 1;1513}1514}15151516static void1517test_speed_moddiv(void)1518{1519uint32_t mx[65], my[65], mp[65], t1[65], t2[65], t3[65], len;1520unsigned char x[255], y[255];1521int i;1522long num;15231524len = br_int_decode(mp, sizeof mp / sizeof mp[0],1525P2048, sizeof P2048);1526if (len != 65) {1527abort();1528}1529memset(x, 'T', sizeof x);1530memset(y, 'P', sizeof y);1531if (!br_modint_decode(mx, mp, x, sizeof x)) {1532abort();1533}1534if (!br_modint_decode(my, mp, y, sizeof y)) {1535abort();1536}1537for (i = 0; i < 10; i ++) {1538br_modint_div(mx, my, mp, t1, t2, t3);1539}1540num = 10;1541for (;;) {1542clock_t begin, end;1543double tt;1544long k;15451546begin = clock();1547for (k = num; k > 0; k --) {1548br_modint_div(mx, my, mp, t1, t2, t3);1549}1550end = clock();1551tt = (double)(end - begin) / CLOCKS_PER_SEC;1552if (tt >= 2.0) {1553printf("%-30s %8.2f div/s\n", "div[2048]",1554(double)num / tt);1555fflush(stdout);1556return;1557}1558num <<= 1;1559}1560}1561#endif15621563#define STU(x) { test_speed_ ## x, #x }15641565static const struct {1566void (*fn)(void);1567char *name;1568} tfns[] = {1569STU(md5),1570STU(sha1),1571STU(sha256),1572STU(sha512),15731574STU(aes128_big_cbcenc),1575STU(aes128_big_cbcdec),1576STU(aes192_big_cbcenc),1577STU(aes192_big_cbcdec),1578STU(aes256_big_cbcenc),1579STU(aes256_big_cbcdec),1580STU(aes128_big_ctr),1581STU(aes192_big_ctr),1582STU(aes256_big_ctr),15831584STU(aes128_small_cbcenc),1585STU(aes128_small_cbcdec),1586STU(aes192_small_cbcenc),1587STU(aes192_small_cbcdec),1588STU(aes256_small_cbcenc),1589STU(aes256_small_cbcdec),1590STU(aes128_small_ctr),1591STU(aes192_small_ctr),1592STU(aes256_small_ctr),15931594STU(aes128_ct_cbcenc),1595STU(aes128_ct_cbcdec),1596STU(aes192_ct_cbcenc),1597STU(aes192_ct_cbcdec),1598STU(aes256_ct_cbcenc),1599STU(aes256_ct_cbcdec),1600STU(aes128_ct_ctr),1601STU(aes192_ct_ctr),1602STU(aes256_ct_ctr),16031604STU(aes128_ct64_cbcenc),1605STU(aes128_ct64_cbcdec),1606STU(aes192_ct64_cbcenc),1607STU(aes192_ct64_cbcdec),1608STU(aes256_ct64_cbcenc),1609STU(aes256_ct64_cbcdec),1610STU(aes128_ct64_ctr),1611STU(aes192_ct64_ctr),1612STU(aes256_ct64_ctr),16131614STU(aes128_x86ni_cbcenc),1615STU(aes128_x86ni_cbcdec),1616STU(aes192_x86ni_cbcenc),1617STU(aes192_x86ni_cbcdec),1618STU(aes256_x86ni_cbcenc),1619STU(aes256_x86ni_cbcdec),1620STU(aes128_x86ni_ctr),1621STU(aes192_x86ni_ctr),1622STU(aes256_x86ni_ctr),16231624STU(aes128_pwr8_cbcenc),1625STU(aes128_pwr8_cbcdec),1626STU(aes192_pwr8_cbcenc),1627STU(aes192_pwr8_cbcdec),1628STU(aes256_pwr8_cbcenc),1629STU(aes256_pwr8_cbcdec),1630STU(aes128_pwr8_ctr),1631STU(aes192_pwr8_ctr),1632STU(aes256_pwr8_ctr),16331634STU(des_tab_cbcenc),1635STU(des_tab_cbcdec),1636STU(3des_tab_cbcenc),1637STU(3des_tab_cbcdec),16381639STU(des_ct_cbcenc),1640STU(des_ct_cbcdec),1641STU(3des_ct_cbcenc),1642STU(3des_ct_cbcdec),16431644STU(chacha20_ct),1645STU(chacha20_sse2),16461647STU(ghash_ctmul),1648STU(ghash_ctmul32),1649STU(ghash_ctmul64),1650STU(ghash_pclmul),1651STU(ghash_pwr8),16521653STU(poly1305_ctmul),1654STU(poly1305_ctmul32),1655STU(poly1305_ctmulq),1656STU(poly1305_i15),16571658STU(eax_aes128_big),1659STU(eax_aes192_big),1660STU(eax_aes256_big),1661STU(eax_aes128_small),1662STU(eax_aes192_small),1663STU(eax_aes256_small),1664STU(eax_aes128_ct),1665STU(eax_aes192_ct),1666STU(eax_aes256_ct),1667STU(eax_aes128_ct64),1668STU(eax_aes192_ct64),1669STU(eax_aes256_ct64),1670STU(eax_aes128_x86ni),1671STU(eax_aes192_x86ni),1672STU(eax_aes256_x86ni),1673STU(eax_aes128_pwr8),1674STU(eax_aes192_pwr8),1675STU(eax_aes256_pwr8),16761677STU(shake128),1678STU(shake256),16791680STU(rsa_i15),1681STU(rsa_i31),1682STU(rsa_i32),1683STU(rsa_i62),1684STU(ec_prime_i15),1685STU(ec_prime_i31),1686STU(ec_p256_m15),1687STU(ec_p256_m31),1688STU(ec_p256_m62),1689STU(ec_p256_m64),1690STU(ec_c25519_i15),1691STU(ec_c25519_i31),1692STU(ec_c25519_m15),1693STU(ec_c25519_m31),1694STU(ec_c25519_m62),1695STU(ec_c25519_m64),1696STU(ecdsa_p256_m15),1697STU(ecdsa_p256_m31),1698STU(ecdsa_p256_m62),1699STU(ecdsa_p256_m64),1700STU(ecdsa_i15),1701STU(ecdsa_i31),17021703STU(i31)1704};17051706static int1707eq_name(const char *s1, const char *s2)1708{1709for (;;) {1710int c1, c2;17111712for (;;) {1713c1 = *s1 ++;1714if (c1 >= 'A' && c1 <= 'Z') {1715c1 += 'a' - 'A';1716} else {1717switch (c1) {1718case '-': case '_': case '.': case ' ':1719continue;1720}1721}1722break;1723}1724for (;;) {1725c2 = *s2 ++;1726if (c2 >= 'A' && c2 <= 'Z') {1727c2 += 'a' - 'A';1728} else {1729switch (c2) {1730case '-': case '_': case '.': case ' ':1731continue;1732}1733}1734break;1735}1736if (c1 != c2) {1737return 0;1738}1739if (c1 == 0) {1740return 1;1741}1742}1743}17441745int1746main(int argc, char *argv[])1747{1748size_t u;17491750if (argc <= 1) {1751printf("usage: testspeed all | name...\n");1752printf("individual test names:\n");1753for (u = 0; u < (sizeof tfns) / (sizeof tfns[0]); u ++) {1754printf(" %s\n", tfns[u].name);1755}1756} else {1757for (u = 0; u < (sizeof tfns) / (sizeof tfns[0]); u ++) {1758int i;17591760for (i = 1; i < argc; i ++) {1761if (eq_name(argv[i], tfns[u].name)1762|| eq_name(argv[i], "all"))1763{1764tfns[u].fn();1765break;1766}1767}1768}1769}1770return 0;1771}177217731774