#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
#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;
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;
}
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; unsigned depth;
feeRand rand;
feePubKey keys[NUM_KEYS];
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;
}
}
time((time_t *)&seed);
rand = feeRandAllocWithSeed(seed);
if(numKeys > sigLoops) {
numKeys = sigLoops;
}
digestData = (FeeData *)fmalloc(sizeof(FeeData) * sigLoops);
sigData = (FeeData *)fmalloc(sizeof(FeeData) * sigLoops);
for(i=0; i<sigLoops; i++) {
mallocData(&digestData[i], PRIV_KEY_SIZE_BYTES);
}
for(depth=minDepth; depth<=maxDepth; 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);
unsigned privSize = (basePrimeLen + 8) / 8;
genRandData(digestData, numKeys, privSize, rand);
for(i=0; i<numKeys; i++) {
keys[i] = feePubKeyAlloc();
feePubKeyInitFromPrivDataDepth(keys[i], digestData[i].data, privSize,
depth, 0);
}
genRandData(digestData, sigLoops, DIGEST_SIZE_BYTES, rand);
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);
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) {
dex = 0;
}
}
PLAT_GET_TIME(endTime);
elapsed = PLAT_GET_US(startTime, endTime);
printf(" verify: %12.2f us per op\n",
elapsed / vfyLoops);
freeCurveParams(cp);
for(i=0; i<sigLoops; i++) {
ffree(sigData[i].data); }
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;
}