Crypto++ has special optimized code for GF2N computation in trinomial basis. So if the elliptic curve is defined over a field that happens to have a trinomial basis (and only some of the NIST curves are), the benchmarks would be much faster.

----- Original Message ----- From: "David Renato Francisco dos Reis Junior" <[EMAIL PROTECTED]>
To: <[email protected]>
Sent: Saturday, August 27, 2005 3:49 AM
Subject: Performance issue


Hi,

i already sent this message without a subject and got no reply. I still have problem to evaluate Crypto++ ECDSA performance, and would appreciate any help.

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;
}






  • Performance issue David Renato Francisco dos Reis Junior
    • Re: Performance issue Wei Dai

Reply via email to