• 沒有找到結果。

第五章 加密電路的實現

A. B ENCH . CPP

// bench.cpp

#include "pch.h"

#include "crc.h"

#include "des.h"

#include "blowfish.h"

#include "rc5.h"

#include "tea.h"

#include "bench.h"

#include <time.h>

#include <math.h>

#include <iostream>

#include <iomanip>

USING_NAMESPACE(CryptoPP) USING_NAMESPACE(std)

#ifdef CLOCKS_PER_SEC

static const double CLOCK_TICKS_PER_SECOND = (double)CLOCKS_PER_SEC;

#elif defined(CLK_TCK)

static const double CLOCK_TICKS_PER_SECOND = (double)CLK_TCK;

#else

static const double CLOCK_TICKS_PER_SECOND = 1000000.0;

#endif

static const byte *const key=(byte

*)"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000";

static double logtotal = 0;

static unsigned int logcount = 0;

void OutputResultBytes(const char *name, unsigned long length, double timeTaken) {

double mbs = length / timeTaken / (1024*1024);

cout << "<TR><TH>" << name;

cout << "<TD>" << length;

cout << setiosflags(ios::fixed);

cout << "<TD>" << setprecision(3) << timeTaken;

cout << "<TD>" << setprecision(3) << mbs << endl;

cout << resetiosflags(ios::fixed);

logtotal += log(mbs);

logcount++;

}

void OutputResultOperations(const char *name, const char *operation, bool pc, unsigned long iterations, double timeTaken)

{

cout << "<TR><TH>" << name << " " << operation << (pc ? " with precomputation" : "");

cout << "<TD>" << iterations;

cout << setiosflags(ios::fixed);

cout << "<TD>" << setprecision(3) << timeTaken;

cout << "<TD>" << setprecision(2) << (1000*timeTaken/iterations) << endl;

cout << resetiosflags(ios::fixed);

logtotal += log(iterations/timeTaken);

logcount++;

}

void BenchMark(const char *name, BlockTransformation &cipher, double timeTotal) {

const int BUF_SIZE = RoundDownToMultipleOf(1024U, cipher.OptimalNumberOfParallelBlocks() * cipher.BlockSize());

SecByteBlock buf(BUF_SIZE);

const int nBlocks = BUF_SIZE / cipher.BlockSize();

clock_t start = clock();

unsigned long i=0, length=BUF_SIZE;

double timeTaken;

do {

length *= 2;

for (; i<length; i+=BUF_SIZE)

cipher.ProcessAndXorMultipleBlocks(buf, NULL, buf, nBlocks);

timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND;

}

while (timeTaken < 2.0/3*timeTotal);

OutputResultBytes(name, length, timeTaken);

}

void BenchMark(const char *name, StreamTransformation &cipher, double timeTotal) {

const int BUF_SIZE=1024;

SecByteBlock buf(BUF_SIZE);

clock_t start = clock();

unsigned long i=0, length=BUF_SIZE;

double timeTaken;

do {

length *= 2;

for (; i<length; i+=BUF_SIZE)

cipher.ProcessString(buf, BUF_SIZE);

timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND;

}

while (timeTaken < 2.0/3*timeTotal);

OutputResultBytes(name, length, timeTaken);

}

void BenchMark(const char *name, HashTransformation &hash, double timeTotal) {

const int BUF_SIZE=1024;

SecByteBlock buf(BUF_SIZE);

LC_RNG rng(time(NULL));

rng.GenerateBlock(buf, BUF_SIZE);

clock_t start = clock();

unsigned long i=0, length=BUF_SIZE;

double timeTaken;

do {

length *= 2;

for (; i<length; i+=BUF_SIZE)

hash.Update(buf, BUF_SIZE);

timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND;

}

while (timeTaken < 2.0/3*timeTotal);

OutputResultBytes(name, length, timeTaken);

}

void BenchMark(const char *name, BufferedTransformation &bt, double timeTotal) {

const int BUF_SIZE=1024;

SecByteBlock buf(BUF_SIZE);

LC_RNG rng(time(NULL));

rng.GenerateBlock(buf, BUF_SIZE);

clock_t start = clock();

unsigned long i=0, length=BUF_SIZE;

double timeTaken;

do {

length *= 2;

for (; i<length; i+=BUF_SIZE)

bt.Put(buf, BUF_SIZE);

timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND;

}

while (timeTaken < 2.0/3*timeTotal);

OutputResultBytes(name, length, timeTaken);

}

void BenchMarkEncryption(const char *name, PK_Encryptor &key, double timeTotal, bool pc=false) {

unsigned int len = 16;

LC_RNG rng(time(NULL));

SecByteBlock plaintext(len), ciphertext(key.CiphertextLength(len));

rng.GenerateBlock(plaintext, len);

clock_t start = clock();

unsigned int i;

double timeTaken;

for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)

key.Encrypt(rng, plaintext, len, ciphertext);

OutputResultOperations(name, "Encryption", pc, i, timeTaken);

if (!pc && key.GetMaterial().SupportsPrecomputation()) {

key.AccessMaterial().Precompute(16);

BenchMarkEncryption(name, key, timeTotal, true);

} }

void BenchMarkDecryption(const char *name, PK_Decryptor &priv, PK_Encryptor &pub, double timeTotal) {

unsigned int len = 16;

LC_RNG rng(time(NULL));

SecByteBlock ciphertext(pub.CiphertextLength(len));

SecByteBlock plaintext(pub.MaxPlaintextLength(ciphertext.size()));

rng.GenerateBlock(plaintext, len);

pub.Encrypt(rng, plaintext, len, ciphertext);

clock_t start = clock();

unsigned int i;

double timeTaken;

for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)

priv.Decrypt(rng, ciphertext, ciphertext.size(), plaintext);

OutputResultOperations(name, "Decryption", false, i, timeTaken);

}

void BenchMarkSigning(const char *name, PK_Signer &key, double timeTotal, bool pc=false) {

unsigned int len = 16;

LC_RNG rng(time(NULL));

SecByteBlock message(len), signature(key.SignatureLength());

rng.GenerateBlock(message, len);

clock_t start = clock();

unsigned int i;

double timeTaken;

for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)

key.SignMessage(rng, message, len, signature);

OutputResultOperations(name, "Signature", pc, i, timeTaken);

if (!pc && key.GetMaterial().SupportsPrecomputation()) {

key.AccessMaterial().Precompute(16);

BenchMarkSigning(name, key, timeTotal, true);

} }

void BenchMarkVerification(const char *name, const PK_Signer &priv, PK_Verifier &pub, double timeTotal, bool pc=false)

{

unsigned int len = 16;

LC_RNG rng(time(NULL));

SecByteBlock message(len), signature(pub.SignatureLength());

rng.GenerateBlock(message, len);

priv.SignMessage(rng, message, len, signature);

clock_t start = clock();

unsigned int i;

double timeTaken;

for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)

pub.VerifyMessage(message, len, signature, signature.size());

OutputResultOperations(name, "Verification", pc, i, timeTaken);

if (!pc && pub.GetMaterial().SupportsPrecomputation()) {

pub.AccessMaterial().Precompute(16);

BenchMarkVerification(name, priv, pub, timeTotal, true);

} }

void BenchMarkKeyGen(const char *name, SimpleKeyAgreementDomain &d, double timeTotal, bool pc=false) {

LC_RNG rng(time(NULL));

SecByteBlock priv(d.PrivateKeyLength()), pub(d.PublicKeyLength());

clock_t start = clock();

unsigned int i;

double timeTaken;

for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)

d.GenerateKeyPair(rng, priv, pub);

OutputResultOperations(name, "Key-Pair Generation", pc, i, timeTaken);

if (!pc && d.GetMaterial().SupportsPrecomputation()) {

d.AccessMaterial().Precompute(16);

BenchMarkKeyGen(name, d, timeTotal, true);

} }

void BenchMarkKeyGen(const char *name, AuthenticatedKeyAgreementDomain &d, double timeTotal, bool pc=false) {

LC_RNG rng(time(NULL));

SecByteBlock priv(d.EphemeralPrivateKeyLength()), pub(d.EphemeralPublicKeyLength());

clock_t start = clock();

unsigned int i;

double timeTaken;

for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)

d.GenerateEphemeralKeyPair(rng, priv, pub);

OutputResultOperations(name, "Key-Pair Generation", pc, i, timeTaken);

if (!pc && d.GetMaterial().SupportsPrecomputation()) {

d.AccessMaterial().Precompute(16);

BenchMarkKeyGen(name, d, timeTotal, true);

} }

void BenchMarkAgreement(const char *name, SimpleKeyAgreementDomain &d, double timeTotal, bool pc=false) {

LC_RNG rng(time(NULL));

SecByteBlock priv1(d.PrivateKeyLength()), priv2(d.PrivateKeyLength());

SecByteBlock pub1(d.PublicKeyLength()), pub2(d.PublicKeyLength());

d.GenerateKeyPair(rng, priv1, pub1);

d.GenerateKeyPair(rng, priv2, pub2);

SecByteBlock val(d.AgreedValueLength());

clock_t start = clock();

unsigned int i;

double timeTaken;

for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) /

CLOCK_TICKS_PER_SECOND, i+=2) {

d.Agree(val, priv1, pub2);

d.Agree(val, priv2, pub1);

}

OutputResultOperations(name, "Key Agreement", pc, i, timeTaken);

}

void BenchMarkAgreement(const char *name, AuthenticatedKeyAgreementDomain &d, double timeTotal, bool pc=false) {

LC_RNG rng(time(NULL));

SecByteBlock spriv1(d.StaticPrivateKeyLength()), spriv2(d.StaticPrivateKeyLength());

SecByteBlock epriv1(d.EphemeralPrivateKeyLength()), epriv2(d.EphemeralPrivateKeyLength());

SecByteBlock spub1(d.StaticPublicKeyLength()), spub2(d.StaticPublicKeyLength());

SecByteBlock epub1(d.EphemeralPublicKeyLength()), epub2(d.EphemeralPublicKeyLength());

d.GenerateStaticKeyPair(rng, spriv1, spub1);

d.GenerateStaticKeyPair(rng, spriv2, spub2);

d.GenerateEphemeralKeyPair(rng, epriv1, epub1);

d.GenerateEphemeralKeyPair(rng, epriv2, epub2);

SecByteBlock val(d.AgreedValueLength());

clock_t start = clock();

unsigned int i;

double timeTaken;

for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i+=2)

{

d.Agree(val, spriv1, epriv1, spub2, epub2);

d.Agree(val, spriv2, epriv2, spub1, epub1);

}

OutputResultOperations(name, "Key Agreement", pc, i, timeTaken);

}

//VC60 workaround: compiler bug triggered without the extra dummy parameters template <class T>

void BenchMarkKeyed(const char *name, double timeTotal, T *x=NULL) {

T c;

c.SetKeyWithIV(key, c.DefaultKeyLength(), key);

BenchMark(name, c, timeTotal);

}

//VC60 workaround: compiler bug triggered without the extra dummy parameters template <class T>

void BenchMarkKeyedVariable(const char *name, double timeTotal, unsigned int keyLength, T *x=NULL) {

T c;

c.SetKeyWithIV(key, keyLength, key);

BenchMark(name, c, timeTotal);

}

//VC60 workaround: compiler bug triggered without the extra dummy parameters template <class T>

void BenchMarkKeyless(const char *name, double timeTotal, T *x=NULL) {

T c;

BenchMark(name, c, timeTotal);

}

//VC60 workaround: compiler bug triggered without the extra dummy parameters template <class SCHEME>

void BenchMarkCrypto(const char *filename, const char *name, double timeTotal, SCHEME *x=NULL) {

FileSource f(filename, true, new HexDecoder());

typename SCHEME::Decryptor priv(f);

typename SCHEME::Encryptor pub(priv);

BenchMarkEncryption(name, pub, timeTotal);

BenchMarkDecryption(name, priv, pub, timeTotal);

}

//VC60 workaround: compiler bug triggered without the extra dummy parameters template <class SCHEME>

void BenchMarkSignature(const char *filename, const char *name, double timeTotal, SCHEME *x=NULL)

{

FileSource f(filename, true, new HexDecoder());

typename SCHEME::Signer priv(f);

typename SCHEME::Verifier pub(priv);

BenchMarkSigning(name, priv, timeTotal);

BenchMarkVerification(name, priv, pub, timeTotal);

}

//VC60 workaround: compiler bug triggered without the extra dummy parameters template <class D>

void BenchMarkKeyAgreement(const char *filename, const char *name, double timeTotal, D *x=NULL) {

FileSource f(filename, true, new HexDecoder());

D d(f);

BenchMarkKeyGen(name, d, timeTotal);

BenchMarkAgreement(name, d, timeTotal);

}

void BenchMarkAll(double t) {

#if 1

logtotal = 0;

logcount = 0;

cout << "<TABLE border=1><COLGROUP><COL align=left><COL align=right><COL align=right><COL align=right>" << endl;

cout << "<THEAD><TR><TH>Algorithm<TH>Bytes Processed<TH>Time Taken<TH>Megabytes(2^20 bytes)/Second\n<TBODY>" << endl;

BenchMarkKeyless<CRC32>("CRC-32", t);

BenchMarkKeyed<DES::Encryption>("DES", t);

BenchMarkKeyed<RC5::Encryption>("RC5 (r=16)", t);

BenchMarkKeyed<Blowfish::Encryption>("Blowfish", t);

BenchMarkKeyed<TEA::Encryption>("TEA", t);

cout << "</TABLE>" << endl;

cout << "<TABLE border=1><COLGROUP><COL align=left><COL align=right><COL align=right><COL align=right>" << endl;

cout << "<THEAD><TR><TH>Operation<TH>Iterations<TH>Total Time<TH>Milliseconds/Operation" << endl;

cout << "<TBODY style=\"background: yellow\">" << endl;

BenchMarkKeyAgreement<XTR_DH>("xtrdh171.dat", "XTR-DH 171", t);

BenchMarkKeyAgreement<XTR_DH>("xtrdh342.dat", "XTR-DH 342", t);

BenchMarkKeyAgreement<DH>("dh1024.dat", "DH 1024", t);

BenchMarkKeyAgreement<DH>("dh2048.dat", "DH 2048", t);

BenchMarkKeyAgreement<LUC_DH>("lucd512.dat", "LUCDIF 512", t);

BenchMarkKeyAgreement<LUC_DH>("lucd1024.dat", "LUCDIF 1024", t);

BenchMarkKeyAgreement<MQV>("mqv1024.dat", "MQV 1024", t);

BenchMarkKeyAgreement<MQV>("mqv2048.dat", "MQV 2048", t);

cout << "</TABLE>" << endl;

cout << "Throughput Geometric Average: " << setiosflags(ios::fixed) << exp(logtotal/logcount) << endl;

time_t endTime = time(NULL);

cout << "\nTest ended at " << asctime(localtime(&endTime));

#endif

}

相關文件