]> git.saurik.com Git - apple/security.git/blobdiff - OSX/libsecurity_cryptkit/ckutils/sigTime/sigTime.cpp
Security-57336.1.9.tar.gz
[apple/security.git] / OSX / libsecurity_cryptkit / ckutils / sigTime / sigTime.cpp
diff --git a/OSX/libsecurity_cryptkit/ckutils/sigTime/sigTime.cpp b/OSX/libsecurity_cryptkit/ckutils/sigTime/sigTime.cpp
new file mode 100644 (file)
index 0000000..d3f81c1
--- /dev/null
@@ -0,0 +1,269 @@
+/*
+ * 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;
+}