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



Reply via email to