// bench.cpp - written and placed in the public domain by Wei Dai
#include "pch.h"
#include "md2.h"
#include "md5.h"
#include "md5mac.h"
#include "hmac.h"
#include "xormac.h"
#include "sha.h"
#include "haval.h"
#include "tiger.h"
#include "ripemd.h"
#include "idea.h"
#include "des.h"
#include "rc2.h"
#include "rc5.h"
#include "blowfish.h"
#include "diamond.h"
#include "wake.h"
#include "3way.h"
#include "safer.h"
#include "gost.h"
#include "shark.h"
#include "cast.h"
#include "square.h"
#include "seal.h"
#include "rc6.h"
#include "mars.h"
#include "blumshub.h"
#include "rsa.h"
#include "elgamal.h"
#include "nr.h"
#include "dsa.h"
#include "luc.h"
#include "rabin.h"
#include "rw.h"
#include "blumgold.h"
#include "eccrypto.h"
#include "ecp.h"
#include "ec2n.h"
#include "asn.h"
#include "rng.h"
#include "files.h"
#include "hex.h"
#include "modes.h"
#include "mdc.h"
#include "lubyrack.h"
#include "sapphire.h"
#include "tea.h"
#include "dh.h"
#include "mqv.h"
#include "bench.h"
#include <time.h>
#include <iostream>
#include <iomanip>
USING_NAMESPACE(CryptoPP)
USING_NAMESPACE(std)
#ifdef CLOCKS_PER_SEC
static const float CLOCK_TICKS_PER_SECOND = (float)CLOCKS_PER_SEC;
#elif defined(CLK_TCK)
static const float CLOCK_TICKS_PER_SECOND = (float)CLK_TCK;
#else
static const float CLOCK_TICKS_PER_SECOND = 1000000.0;
#endif
static const byte *const key=(byte *)"0123456789abcdef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
void BenchMark(const char *name, BlockTransformation &cipher, float timeTotal)
{
const int BUF_SIZE = cipher.BlockSize();
SecByteBlock buf(BUF_SIZE);
clock_t start = clock();
unsigned long i=0, length=BUF_SIZE;
float timeTaken;
do
{
length *= 2;
for (; i<length; i+=BUF_SIZE)
cipher.ProcessBlock(buf);
timeTaken = float(clock() - start) / CLOCK_TICKS_PER_SECOND;
}
while (timeTaken < 2.0/3*timeTotal);
float kbs = length / timeTaken;
cout << "<TR><TH>" << name;
cout << "<TD>" << length;
cout << "<TD>" << timeTaken;
cout << "<TD>" << (long)kbs << endl;
}
void BenchMark(const char *name, StreamCipher &cipher, float timeTotal)
{
const int BUF_SIZE=128; // encrypt 128 bytes at a time
SecByteBlock buf(BUF_SIZE);
clock_t start = clock();
unsigned long i=0, length=BUF_SIZE;
float timeTaken;
do
{
length *= 2;
for (; i<length; i+=BUF_SIZE)
cipher.ProcessString(buf, BUF_SIZE);
timeTaken = float(clock() - start) / CLOCK_TICKS_PER_SECOND;
}
while (timeTaken < 2.0/3*timeTotal);
float kbs = length / timeTaken;
cout << "<TR><TH>" << name;
cout << "<TD>" << length;
cout << "<TD>" << timeTaken;
cout << "<TD>" << (long)kbs << endl;
}
void BenchMark(const char *name, HashModule &hash, float timeTotal)
{
const int BUF_SIZE=128; // update 128 bytes at a time
SecByteBlock buf(BUF_SIZE);
clock_t start = clock();
unsigned long i=0, length=BUF_SIZE;
float timeTaken;
do
{
length *= 2;
for (; i<length; i+=BUF_SIZE)
hash.Update(buf, BUF_SIZE);
timeTaken = float(clock() - start) / CLOCK_TICKS_PER_SECOND;
}
while (timeTaken < 2.0/3*timeTotal);
float kbs = length / timeTaken;
cout << "<TR><TH>" << name;
cout << "<TD>" << length;
cout << "<TD>" << timeTaken;
cout << "<TD>" << (long)kbs << endl;
}
void BenchMark(const char *name, BufferedTransformation &bt, float timeTotal)
{
const int BUF_SIZE=128; // update 128 bytes at a time
SecByteBlock buf(BUF_SIZE);
clock_t start = clock();
unsigned long i=0, length=BUF_SIZE;
float timeTaken;
do
{
length *= 2;
for (; i<length; i+=BUF_SIZE)
bt.Put(buf, BUF_SIZE);
timeTaken = float(clock() - start) / CLOCK_TICKS_PER_SECOND;
}
while (timeTaken < 2.0/3*timeTotal);
float kbs = length / timeTaken;
cout << "<TR><TH>" << name;
cout << "<TD>" << length;
cout << "<TD>" << timeTaken;
cout << "<TD>" << (long)kbs << endl;
}
void BenchMarkEncryption(const char *name, PK_Encryptor &key, float timeTotal, bool pc=false)
{
unsigned int len = 16;
LC_RNG rng(time(NULL));
SecByteBlock plaintext(len), ciphertext(key.CipherTextLength(len));
rng.GetBlock(plaintext, len);
clock_t start = clock();
unsigned int i;
float timeTaken;
for (timeTaken=(float)0, i=0; timeTaken < timeTotal; timeTaken = float(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)
key.Encrypt(rng, plaintext, len, ciphertext);
cout << "<TR><TH>" << name << " Encryption" << (pc ? " with precomputation" : "");
cout << "<TD>" << i;
cout << "<TD>" << setprecision(3) << timeTaken;
cout << "<TD>" << (unsigned int)(1000*timeTaken/i) << endl;
}
void BenchMarkEncryption(const char *name, PK_WithPrecomputation<PK_FixedLengthEncryptor> &key, float timeTotal)
{
BenchMarkEncryption(name, dynamic_cast<PK_Encryptor &>(key), timeTotal);
key.Precompute(16);
BenchMarkEncryption(name, dynamic_cast<PK_Encryptor &>(key), timeTotal, true);
}
void BenchMarkDecryption(const char *name, PK_Decryptor &priv, PK_Encryptor &pub, float timeTotal)
{
unsigned int len = 16;
LC_RNG rng(time(NULL));
SecByteBlock ciphertext(pub.CipherTextLength(len));
SecByteBlock plaintext(pub.MaxPlainTextLength(ciphertext.size));
rng.GetBlock(plaintext, len);
pub.Encrypt(rng, plaintext, len, ciphertext);
clock_t start = clock();
unsigned int i;
float timeTaken;
for (timeTaken=(float)0, i=0; timeTaken < timeTotal; timeTaken = float(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)
priv.Decrypt(ciphertext, ciphertext.size, plaintext);
cout << "<TR><TH>" << name << " Decryption";
cout << "<TD>" << i;
cout << "<TD>" << setprecision(3) << timeTaken;
cout << "<TD>" << (unsigned int)(1000*timeTaken/i) << endl;
}
void BenchMarkSigning(const char *name, PK_Signer &key, float timeTotal, bool pc=false)
{
unsigned int len = 16;
LC_RNG rng(time(NULL));
SecByteBlock message(len), signature(key.SignatureLength());
rng.GetBlock(message, len);
clock_t start = clock();
unsigned int i;
float timeTaken;
for (timeTaken=(float)0, i=0; timeTaken < timeTotal; timeTaken = float(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)
key.SignMessage(rng, message, len, signature);
cout << "<TR><TH>" << name << " Signature" << (pc ? " with precomputation" : "");
cout << "<TD>" << i;
cout << "<TD>" << setprecision(3) << timeTaken;
cout << "<TD>" << (unsigned int)(1000*timeTaken/i) << endl;
}
void BenchMarkSigning(const char *name, PK_WithPrecomputation<PK_Signer> &key, float timeTotal)
{
BenchMarkSigning(name, dynamic_cast<PK_Signer &>(key), timeTotal);
key.Precompute(16);
BenchMarkSigning(name, dynamic_cast<PK_Signer &>(key), timeTotal, true);
}
void BenchMarkVerification(const char *name, PK_Signer &priv, PK_Verifier &pub, float timeTotal, bool pc=false)
{
unsigned int len = 16;
LC_RNG rng(time(NULL));
SecByteBlock message(len), signature(pub.SignatureLength());
rng.GetBlock(message, len);
priv.SignMessage(rng, message, len, signature);
clock_t start = clock();
unsigned int i;
float timeTaken;
for (timeTaken=(float)0, i=0; timeTaken < timeTotal; timeTaken = float(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)
pub.VerifyMessage(message, len, signature);
cout << "<TR><TH>" << name << " Verification" << (pc ? " with precomputation" : "");
cout << "<TD>" << i;
cout << "<TD>" << setprecision(3) << timeTaken;
cout << "<TD>" << (unsigned int)(1000*timeTaken/i) << endl;
}
void BenchMarkVerification(const char *name, PK_Signer &priv, PK_WithPrecomputation<PK_Verifier> &pub, float timeTotal)
{
BenchMarkVerification(name, priv, dynamic_cast<PK_Verifier &>(pub), timeTotal);
pub.Precompute(16);
BenchMarkVerification(name, priv, dynamic_cast<PK_Verifier &>(pub), timeTotal, true);
}
void BenchMarkKeyGen(const char *name, PK_SimpleKeyAgreementDomain &d, float timeTotal, bool pc=false)
{