-/*
- * atomTime.c - measure performance of digital signature primitives (not incluing
- * digest)
- */
-
-#include "ckconfig.h"
-#include "ckutilsPlatform.h"
-#include "CryptKitSA.h"
-#include "curveParams.h"
-#include "falloc.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-
-#define SIGN_LOOPS_DEF 100
-#define VFY_LOOPS_DEF 100
-#define PRIV_KEY_SIZE_BYTES 32
-#define DIGEST_SIZE_BYTES 20 /* e.g., SHA1 */
-#define NUM_KEYS 10
-
-static void usage(char **argv)
-{
- printf("Usage: %s [option...]\n", argv[0]);
- printf("Options:\n");
- printf(" s=signLoops -- default %d\n", SIGN_LOOPS_DEF);
- printf(" v=verifyLoops -- default %d\n", VFY_LOOPS_DEF);
- printf(" D=depth -- default is ALL\n");
- exit(1);
-}
-
-typedef struct {
- unsigned char *data;
- unsigned length;
-} FeeData;
-
-/*
- * Fill numDatas with random data of length bits. Caller has mallocd referents.
- */
-static void genRandData(FeeData *datas,
- unsigned numDatas,
- unsigned numBytes,
- feeRand rand)
-{
- unsigned i;
- FeeData *fd;
- for(i=0; i<numDatas; i++) {
- fd = &datas[i];
- fd->length = numBytes;
- feeRandBytes(rand, fd->data, numBytes);
- }
- return;
-}
-
-static void mallocData(
- FeeData *fd,
- unsigned numBytes)
-{
- fd->data = (unsigned char *)fmalloc(numBytes);
- fd->length = numBytes;
-}
-
-/* common random callback */
-feeReturn randCallback(
- void *ref,
- unsigned char *bytes,
- unsigned numBytes)
-{
- feeRand frand = (feeRand)ref;
- feeRandBytes(frand, bytes, numBytes);
- return FR_Success;
-}
-
-int main(int argc, char **argv)
-{
- int arg;
- char *argp;
- unsigned sigLoops = SIGN_LOOPS_DEF;
- unsigned vfyLoops = VFY_LOOPS_DEF;
- unsigned numKeys = NUM_KEYS; // might be less for very small loops
- unsigned depth;
- feeRand rand;
-
- feePubKey keys[NUM_KEYS];
- /* sigLoops copies of each of {digestData, sigData} */
- FeeData *digestData;
- FeeData *sigData;
-
- unsigned seed;
- unsigned i;
- PLAT_TIME startTime;
- PLAT_TIME endTime;
- double elapsed;
- curveParams *cp;
- unsigned minDepth = 0;
- unsigned maxDepth = FEE_DEPTH_MAX;
- unsigned basePrimeLen;
- char *curveType;
- feeReturn frtn;
-
- for(arg=1; arg<argc; arg++) {
- argp = argv[arg];
- switch(argp[0]) {
- case 's':
- sigLoops = atoi(&argp[2]);
- break;
- case 'v':
- vfyLoops = atoi(&argp[2]);
- break;
- case 'D':
- minDepth = maxDepth = atoi(&argp[2]);
- break;
- default:
- usage(argv);
- break;
- }
- }
-
- /*
- * Common random generator
- */
- time((time_t *)&seed);
- rand = feeRandAllocWithSeed(seed);
-
- if(numKeys > sigLoops) {
- numKeys = sigLoops;
- }
- digestData = (FeeData *)fmalloc(sizeof(FeeData) * sigLoops);
- sigData = (FeeData *)fmalloc(sizeof(FeeData) * sigLoops);
-
- /* alloc the data, once, for largest private key or "digest" we'll use */
- for(i=0; i<sigLoops; i++) {
- mallocData(&digestData[i], PRIV_KEY_SIZE_BYTES);
- }
- for(depth=minDepth; depth<=maxDepth; depth++) {
-
- /*
- * Get curve params for this depth
- */
- cp = curveParamsForDepth(depth);
- if(cp == NULL) {
- printf("malloc failure\n");
- exit(1);
- }
- switch(cp->curveType) {
- case FCT_Montgomery:
- curveType = "FCT_Montgomery";
- break;
- case FCT_Weierstrass:
- curveType = "FCT_Weierstrass";
- break;
- case FCT_General:
- curveType = "FCT_General";
- break;
- default:
- printf("***Unknown curveType!\n");
- exit(1);
- }
-
- switch(cp->primeType) {
- case FPT_General:
- printf("depth=%d; FPT_General, %s; keysize=%d;\n",
- depth, curveType, bitlen(cp->basePrime));
- break;
- case FPT_Mersenne:
- printf("depth=%d; FPT_Mersenne, %s; q=%d\n",
- depth, curveType, cp->q);
- break;
- default:
- printf("depth=%d; FPT_FEE, %s; q=%d k=%d\n",
- depth, curveType, cp->q, cp->k);
- break;
- }
- basePrimeLen = bitlen(cp->basePrime);
-
- /* one set of random data as private keys */
- unsigned privSize = (basePrimeLen + 8) / 8;
- genRandData(digestData, numKeys, privSize, rand);
-
- /* generate the keys (no hash - we've got that covered) */
- for(i=0; i<numKeys; i++) {
- keys[i] = feePubKeyAlloc();
- feePubKeyInitFromPrivDataDepth(keys[i], digestData[i].data, privSize,
- depth, 0);
- }
-
- /* now different data to actually sign */
- genRandData(digestData, sigLoops, DIGEST_SIZE_BYTES, rand);
-
- /*
- * sign
- */
- PLAT_GET_TIME(startTime);
- for(i=0; i<sigLoops; i++) {
- FeeData *digst = &digestData[i];
- FeeData *sig = &sigData[i];
- feePubKey fkey = keys[i % numKeys];
-
- feeSig fs = feeSigNewWithKey(fkey, randCallback, rand);
- frtn = feeSigSign(fs, digst->data, digst->length, fkey);
- if(frtn) {
- printf("***Error %d on feeSigSign\n", (int)frtn);
- break;
- }
- frtn = feeSigData(fs, &sig->data, &sig->length);
- if(frtn) {
- printf("***Error %d on feeSigData\n", (int)frtn);
- break;
- }
- feeSigFree(fs);
- }
- PLAT_GET_TIME(endTime);
- elapsed = PLAT_GET_US(startTime, endTime);
- printf(" sign: %12.2f us per op\n",
- elapsed / sigLoops);
-
- /*
- * verify - might be doing more of these than we have
- * valid signatures.....
- */
- unsigned dex=0;
- PLAT_GET_TIME(startTime);
- for(i=0; i<vfyLoops; i++) {
- FeeData *digst = &digestData[dex];
- FeeData *sig = &sigData[dex];
- feePubKey fkey = keys[dex % numKeys];
-
- feeSig fs;
- frtn = feeSigParse(sig->data, sig->length, &fs);
- if(frtn) {
- printf("***Error %d on feeSigParse\n", (int)frtn);
- break;
- }
- frtn = feeSigVerify(fs, digst->data, digst->length, fkey);
- if(frtn) {
- printf("***Error %d on feeSigVerify\n", (int)frtn);
- break;
- }
- feeSigFree(fs);
- dex++;
- if(dex == sigLoops) {
- /* that's all the data we have, recycle */
- dex = 0;
- }
- }
- PLAT_GET_TIME(endTime);
- elapsed = PLAT_GET_US(startTime, endTime);
- printf(" verify: %12.2f us per op\n",
- elapsed / vfyLoops);
-
- freeCurveParams(cp);
- /* possibly limited number of signatures.... */
- for(i=0; i<sigLoops; i++) {
- ffree(sigData[i].data); // mallocd by feeSigData()
- }
- for(i=0; i<numKeys; i++) {
- feePubKeyFree(keys[i]);
- }
- }
-
- feeRandFree(rand);
- for(i=0; i<sigLoops; i++) {
- ffree(digestData[i].data);
- }
- ffree(digestData);
- ffree(sigData);
-
- return 0;
-}
-