]> git.saurik.com Git - apple/security.git/blobdiff - Security/libsecurity_cryptkit/ckutils/giantBench/giantBench.c
Security-57031.1.35.tar.gz
[apple/security.git] / Security / libsecurity_cryptkit / ckutils / giantBench / giantBench.c
diff --git a/Security/libsecurity_cryptkit/ckutils/giantBench/giantBench.c b/Security/libsecurity_cryptkit/ckutils/giantBench/giantBench.c
new file mode 100644 (file)
index 0000000..989a613
--- /dev/null
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+
+#include "giantIntegers.h"
+#include "ckutilities.h"
+#include "feeFunctions.h"
+#include "feeDebug.h"
+#include <stdlib.h>
+#include "ckutilsPlatform.h"
+#include <stdio.h>
+#include <time.h>
+
+#define LOOPS_DEF      100
+#define MIN_SIZE_DEF   4       /* min giant size in bytes */
+#define MAX_SIZE_DEF   32      /* max in bytes */
+#define LOOP_NOTIFY    100
+
+
+static void usage(char **argv) 
+{
+       printf("usage: %s [options]\n", argv[0]);
+       printf("   Options:\n");
+       printf("   l=loops    (default = %d)\n", LOOPS_DEF); 
+       printf("   n=maxBytes (default = %d\n", MIN_SIZE_DEF);
+       printf("   x=maxBytes (default = %d\n", MAX_SIZE_DEF);
+       printf("   o (use old 16-bit CryptKit\n");
+       printf("   s=seed\n");
+       printf("   h(elp)\n");
+       exit(1);
+}
+
+/*
+ * Fill buffer with random data.
+ */
+static void fillData(unsigned bufSize, 
+       unsigned char *buf)
+{
+       unsigned        *ip;
+       unsigned        intCount;
+       unsigned        residue;
+       unsigned char   *cp;
+       int             i;
+       
+       intCount = bufSize >> 2;
+       ip = (unsigned *)buf;
+       for(i=0; i<intCount; i++) {
+               *ip++ = RAND();
+       }
+       
+       residue = bufSize & 0x3;
+       cp = (unsigned char *)ip;
+       for(i=0; i<residue; i++) {
+               *cp++ = (unsigned char)RAND();
+       }
+}
+
+/*
+ * fill a pre-allocd giant with specified number of bytes of random 
+ * data. *Buf is mallocd and uninitialized and will change here.
+ */
+static void genGiant(giant g, 
+       unsigned numBytes, 
+       unsigned char *buf)
+{
+       int i;
+       
+       fillData(numBytes, buf);
+       deserializeGiant(buf, g, numBytes);
+       
+       /* set random sign; deserializeGiant() is always positive */
+       i = RAND();
+       if(i & 1) {
+               g->sign = -g->sign;
+       }
+       
+       /* avoid zero data - too many pitfalls with mod and div */
+       while(isZero(g)) {
+               g->sign = 1;
+               g->n[0] = RAND();
+       }
+}
+
+/*
+ * Init giant arrays with random data.
+ */
+static void initRandGiants(unsigned numBytes, 
+       unsigned char *buf,
+       unsigned numGiants,
+       giant *g1, 
+       giant *g2)
+{
+       int i;
+       
+       for(i=0; i<numGiants; i++) {
+           genGiant(g1[i], numBytes, buf);
+           genGiant(g2[i], numBytes, buf);
+       }
+}
+
+/*
+ * Individual tests. API is identical for all tests.
+ *
+ * loops  : number of ops to perform.
+ * g1, g2 : arrays of giants with random data and sign. Tests may modify
+ *          these. Size of array = 'loops'. Capacity big enough for all
+ *          conceivable ops.
+ * Return : total microseconds to do 'loops' ops.
+ */
+static int mulgTest(unsigned loops, 
+       giant *g1, 
+       giant *g2)
+{
+       int loop;
+       PLAT_TIME startTime;
+       PLAT_TIME endTime;
+       
+       PLAT_GET_TIME(startTime);
+       for(loop=0; loop<loops; loop++) {
+               mulg(*g1++, *g2++);
+       }
+       PLAT_GET_TIME(endTime);
+       return PLAT_GET_NS(startTime, endTime);
+}
+
+static int squareTest(unsigned loops, 
+       giant *g1, 
+       giant *g2)
+{
+       int loop;
+       PLAT_TIME startTime;
+       PLAT_TIME endTime;
+       
+       PLAT_GET_TIME(startTime);
+       for(loop=0; loop<loops; loop++) {
+               gsquare(*g1++);
+       }
+       PLAT_GET_TIME(endTime);
+       return PLAT_GET_NS(startTime, endTime);
+}
+
+
+int main(int argc, char **argv)
+{
+       int             arg;
+       char            *argp;
+       giant           *g1;
+       giant           *g2;            // ditto
+       unsigned char   *buf;           // random data
+       unsigned        numDigits;
+       unsigned        i;
+       unsigned        numBytes;
+       unsigned        mulgElapsed;
+       unsigned        sqrElapsed;
+       
+       int             loops = LOOPS_DEF;
+       int             seedSpec = 0;
+       unsigned        seed = 0;
+       unsigned        maxSize = MAX_SIZE_DEF;
+       unsigned        minSize = MIN_SIZE_DEF;
+       int             useOld = 0;
+       
+       initCryptKit();
+       
+       #if     macintosh
+       argc = ccommand(&argv);
+       #endif
+       
+       for(arg=1; arg<argc; arg++) {
+               argp = argv[arg];
+               switch(argp[0]) {
+                   case 'x':
+                       maxSize = atoi(&argp[2]);
+                       break;
+                   case 'n':
+                       minSize = atoi(&argp[2]);
+                       break;
+                   case 'l':
+                       loops = atoi(&argp[2]);
+                       break;
+                   case 'o':
+                       useOld = 1;
+                       break;
+                   case 's':
+                       seed = atoi(&argp[2]);
+                       seedSpec = 1;
+                       break;
+                   case 'h':
+                   default:
+                       usage(argv);
+               }
+       }
+       buf = malloc(maxSize);
+
+       if(!seedSpec) {
+               unsigned long   tim;
+               time(&tim);
+               seed = (unsigned)tim;
+       }
+       SRAND(seed);
+
+       /*
+        * Scratch giants, big enough for anything. Malloc here, init with
+        * random data before each test
+        * note these mallocs will be too big in the useOld case...
+        */
+       g1 = malloc(sizeof(giant) * loops);
+       g2 = malloc(sizeof(giant) * loops);
+    if((g1 == NULL) || (g2 == NULL)) {
+       printf("malloc error\n");
+       exit(1);
+    }
+       if(useOld) {
+           numDigits = ((2 * maxSize) + 1) / 2;
+       }
+       else {
+           numDigits = BYTES_TO_GIANT_DIGITS(2 * maxSize);
+       }
+       for(i=0; i<loops; i++) {
+           g1[i] = newGiant(numDigits);
+           g2[i] = newGiant(numDigits);
+           if((g1[i] == NULL) || (g2[i] == NULL)) {
+               printf("malloc error\n");
+               exit(1);
+           }
+       }
+
+       printf("Starting giants test: seed %d\n", seed);
+       for(numBytes=minSize; numBytes<=maxSize; numBytes*=2) {
+                   
+               initRandGiants(numBytes, 
+                       buf,
+                       loops,
+                       g1, 
+                       g2);
+
+               mulgElapsed = mulgTest(loops, g1, g2);
+               initRandGiants(numBytes, 
+                       buf,
+                       loops,
+                       g1, 
+                       g2);
+
+               sqrElapsed = squareTest(loops, g1, g2);
+               printf("  bits : %4d   mulg : %3d ns   gsquare : %3d ns\n", 
+                       numBytes * 8, 
+                       mulgElapsed / loops,
+                       sqrElapsed / loops);
+
+       } /* for numBytes */
+       return 0;
+}