Hi,
i am trying to evaluate the speed of ECDSA and ECDH for the curves defined by
NIST, but i am getting strange results for binary curves. Using my program the
timings are:
ECDSA [K-163] Sign: 503.024 ms
ECDSA [K-163] Verify: 621.819 ms
ECDSA [K-163] Sign w/ Pre-comp.: 123.687 ms
ECDSA [B-163] Sign: 508.369 ms
ECDSA [B-163] Verify: 623.069 ms
ECDSA [B-163] Sign w/ Pre-comp.: 124.553 ms
ECDSA [K-233] Sign: 76.1827 ms
ECDSA [K-233] Verify: 91.9683 ms
ECDSA [K-233] Sign w/ Pre-comp.: 20.6026 ms
ECDSA [B-233] Sign: 75.1749 ms
ECDSA [B-233] Verify: 93.576 ms
ECDSA [B-233] Sign w/ Pre-comp.: 20.8087 ms
ECDSA [K-283] Sign: 2503.01 ms
ECDSA [K-283] Verify: 3067.52 ms
ECDSA [K-283] Sign w/ Pre-comp.: 615.38 ms
ECDSA [B-283] Sign: 2493.62 ms
ECDSA [B-283] Verify: 3075.02 ms
ECDSA [B-283] Sign w/ Pre-comp.: 609.284 ms
ECDSA [K-409] Sign: 301.355 ms
ECDSA [K-409] Verify: 363.599 ms
ECDSA [K-409] Sign w/ Pre-comp.: 78.7774 ms
ECDSA [B-409] Sign: 303.911 ms
ECDSA [B-409] Verify: 364.634 ms
ECDSA [B-409] Sign w/ Pre-comp.: 78.5611 ms
ECDSA [K-571] Sign: 23508.4 ms
ECDSA [K-571] Verify: 27371.1 ms
ECDSA [K-571] Sign w/ Pre-comp.: 5628.62 ms
ECDSA [B-571] Sign: 23472 ms
ECDSA [B-571] Verify: 27395.8 ms
ECDSA [B-571] Sign w/ Pre-comp.: 5533.41 ms
ECDSA [P-192] Sign: 16.2262 ms
ECDSA [P-192] Verify: 36.7545 ms
ECDSA [P-192] Sign w/ Pre-comp.: 9.0122 ms
ECDSA [P-224] Sign: 20.5934 ms
ECDSA [P-224] Verify: 56.5787 ms
ECDSA [P-224] Sign w/ Pre-comp.: 12.9446 ms
ECDSA [P-256] Sign: 24.5977 ms
ECDSA [P-256] Verify: 74.793 ms
ECDSA [P-256] Sign w/ Pre-comp.: 16.811 ms
ECDSA [P-384] Sign: 74.1836 ms
ECDSA [P-384] Verify: 189.479 ms
ECDSA [P-384] Sign w/ Pre-comp.: 39.5372 ms
ECDSA [P-521] Sign: 282.332 ms
ECDSA [P-521] Verify: 633.798 ms
ECDSA [P-521] Sign w/ Pre-comp.: 135.298 ms
ECDSA [P-521] Sign: 283.565 ms
ECDSA [P-521] Verify: 633.566 ms
ECDSA [P-521] Sign w/ Pre-comp.: 136.105 ms
The timings for prime curves seems to be okay, but for binary curves they are
strange. The big difference for signature time between {K,B}-163 and {K,B}-233
(and other fields) ist odd. I tried to find out what causes this, but i could
not. Is this a kown behavior? I hope somebody can help me.
I am running the benchmark program in a celeron 430 MHz, with 384 MB of RAM.
The OS is Fedora Core 3 (kernel 2.6.9-1.667), crypto++ 5.21 (compiled with
"CXXFLAGS = -O2 -DNDEBUG -ffunction-sections -fdata-sections" flags) and
GCC/G++ 3.4.2.
Thanks,
David Jr
The code that i used to measure the timings for binary curves.
-----------------------------------------------------------------------------
#include "pch.h"
#include "osrng.h"
#include "integer.h"
#include "rng.h"
#include "files.h"
#include "hex.h"
#include "eccrypto.h"
#include "ecp.h"
#include "ec2n.h"
#include "asn.h"
#include "dh.h"
#include "mqv.h"
#include "oids.h"
#include <stdlib.h>
#include <sys/time.h>
#include <math.h>
#include <iostream>
#include <iomanip>
USING_NAMESPACE(CryptoPP)
USING_NAMESPACE(std)
#define EC_NUM 16
#define N 10
struct NameToOID
{
const char* pszName;
OID oid;
};
const struct NameToOID Table[EC_NUM] =
{
{"[K-163]", ASN1::sect163k1()},
{"[B-163]", ASN1::sect163r2()},
{"[K-233]", ASN1::sect233k1()},
{"[B-233]", ASN1::sect233r1()},
{"[K-283]", ASN1::sect283k1()},
{"[B-283]", ASN1::sect283r1()},
{"[K-409]", ASN1::sect409k1()},
{"[B-409]", ASN1::sect409r1()},
{"[K-571]", ASN1::sect571k1()},
{"[B-571]", ASN1::sect571r1()},
{"[P-192]", ASN1::secp192k1()},
{"[P-224]", ASN1::secp224k1()},
{"[P-256]", ASN1::secp256r1()},
{"[P-384]", ASN1::secp384r1()},
{"[P-521]", ASN1::secp521r1()},
{"[P-521]", ASN1::secp521r1()}
};
static inline int wtime(double tim[2])
{
struct timeval time1;
if(gettimeofday(&time1, NULL))
return printf("bad return of gettimeofday, ierr\n");
tim[0] = time1.tv_sec;
tim[1] = time1.tv_usec;
}
void time_ecdsa_binary_curves()
{
int count;
unsigned int i,j;
unsigned int len = 256;
LC_RNG rng(time(NULL));
double ti[2],tf[2], elapsed;
byte msg[16][64];
byte sign[16][256];
Integer basePointOrder, d;
EC2N curve; // Elliptic Curve Group
EC2NPoint basePoint;
EC2NPoint Q;
EC2NPoint pubKeyPoint;
ECDSA<EC2N, SHA>::PrivateKey privKey;
ECDSA<EC2N, SHA>::PublicKey pubKey;
srand(1); // Initialize Random Number Generator
for(i=0;i<16;i++) // Initialize Messages
for(j=0;j<64;j++)
msg[i][j]=rand();
for(i=0;i<10;i++) {
privKey.Initialize(rng,Table[i].oid);
privKey.MakePublicKey(pubKey);
basePointOrder=privKey.GetAbstractGroupParameters().GetSubgroupOrder();
basePoint = privKey.GetAbstractGroupParameters().GetSubgroupGenerator();
curve = privKey.AccessGroupParameters().GetCurve();
pubKeyPoint = pubKey.GetPublicElement();
d = privKey.GetPrivateExponent();
ECDSA<EC2N, SHA>::Signer signer(curve, basePoint, basePointOrder, d);
ECDSA<EC2N, SHA>::Verifier verifier(signer);
wtime(ti); // Start
for (count=0; count<10; count++)
signer.SignMessage(rng, msg[count], 64, sign[count]);
wtime(tf); // Stop
elapsed=(tf[0] - ti[0])*1000 + (tf[1] - ti[1])/1000;
cout << "\nECDSA " << Table[i].pszName << " Sign: " << elapsed/count << "
ms";
wtime(ti);
for (count=0; count<10; count++)
if(!verifier.VerifyMessage(msg[count], 64,
sign[count],signer.SignatureLength()))
printf(".");
wtime(tf);
elapsed=(tf[0] - ti[0])*1000 + (tf[1] - ti[1])/1000;
cout << "\nECDSA " << Table[i].pszName << " Verify: " << elapsed/count << "
ms";
signer.AccessMaterial().Precompute(16);
wtime(ti);
for (count=0; count<10; count++)
signer.SignMessage(rng, msg[count], 64, sign[count]);
wtime(tf);
elapsed=(tf[0] - ti[0])*1000 + (tf[1] - ti[1])/1000;
cout << "\nECDSA " << Table[i].pszName << " Sign w/ Pre-comp.: " <<
elapsed/count << " ms";
}
}
int main()
{
time_ecdsa_binary_curves();
return 1;
}