]> git.saurik.com Git - apple/security.git/blame - libsecurity_cryptkit/ckutils/giantBench/giantBench.c
Security-55471.14.18.tar.gz
[apple/security.git] / libsecurity_cryptkit / ckutils / giantBench / giantBench.c
CommitLineData
b1ab9ed8
A
1/* Copyright (c) 1998 Apple Computer, Inc. All rights reserved.
2 *
3 * giantBench.c - Benchmark of NSGiantInteger primitives.
4 *
5 * Revision History
6 * ----------------
7 * 13 Apr 98 Doug Mitchell at Apple
8 * Created.
9 */
10
11#include "giantIntegers.h"
12#include "ckutilities.h"
13#include "feeFunctions.h"
14#include "feeDebug.h"
15#include <stdlib.h>
16#include "ckutilsPlatform.h"
17#include <stdio.h>
18#include <time.h>
19
20#define LOOPS_DEF 100
21#define MIN_SIZE_DEF 4 /* min giant size in bytes */
22#define MAX_SIZE_DEF 32 /* max in bytes */
23#define LOOP_NOTIFY 100
24
25
26static void usage(char **argv)
27{
28 printf("usage: %s [options]\n", argv[0]);
29 printf(" Options:\n");
30 printf(" l=loops (default = %d)\n", LOOPS_DEF);
31 printf(" n=maxBytes (default = %d\n", MIN_SIZE_DEF);
32 printf(" x=maxBytes (default = %d\n", MAX_SIZE_DEF);
33 printf(" o (use old 16-bit CryptKit\n");
34 printf(" s=seed\n");
35 printf(" h(elp)\n");
36 exit(1);
37}
38
39/*
40 * Fill buffer with random data.
41 */
42static void fillData(unsigned bufSize,
43 unsigned char *buf)
44{
45 unsigned *ip;
46 unsigned intCount;
47 unsigned residue;
48 unsigned char *cp;
49 int i;
50
51 intCount = bufSize >> 2;
52 ip = (unsigned *)buf;
53 for(i=0; i<intCount; i++) {
54 *ip++ = RAND();
55 }
56
57 residue = bufSize & 0x3;
58 cp = (unsigned char *)ip;
59 for(i=0; i<residue; i++) {
60 *cp++ = (unsigned char)RAND();
61 }
62}
63
64/*
65 * fill a pre-allocd giant with specified number of bytes of random
66 * data. *Buf is mallocd and uninitialized and will change here.
67 */
68static void genGiant(giant g,
69 unsigned numBytes,
70 unsigned char *buf)
71{
72 int i;
73
74 fillData(numBytes, buf);
75 deserializeGiant(buf, g, numBytes);
76
77 /* set random sign; deserializeGiant() is always positive */
78 i = RAND();
79 if(i & 1) {
80 g->sign = -g->sign;
81 }
82
83 /* avoid zero data - too many pitfalls with mod and div */
84 while(isZero(g)) {
85 g->sign = 1;
86 g->n[0] = RAND();
87 }
88}
89
90/*
91 * Init giant arrays with random data.
92 */
93static void initRandGiants(unsigned numBytes,
94 unsigned char *buf,
95 unsigned numGiants,
96 giant *g1,
97 giant *g2)
98{
99 int i;
100
101 for(i=0; i<numGiants; i++) {
102 genGiant(g1[i], numBytes, buf);
103 genGiant(g2[i], numBytes, buf);
104 }
105}
106
107/*
108 * Individual tests. API is identical for all tests.
109 *
110 * loops : number of ops to perform.
111 * g1, g2 : arrays of giants with random data and sign. Tests may modify
112 * these. Size of array = 'loops'. Capacity big enough for all
113 * conceivable ops.
114 * Return : total microseconds to do 'loops' ops.
115 */
116
117static int mulgTest(unsigned loops,
118 giant *g1,
119 giant *g2)
120{
121 int loop;
122 PLAT_TIME startTime;
123 PLAT_TIME endTime;
124
125 PLAT_GET_TIME(startTime);
126 for(loop=0; loop<loops; loop++) {
127 mulg(*g1++, *g2++);
128 }
129 PLAT_GET_TIME(endTime);
130 return PLAT_GET_NS(startTime, endTime);
131}
132
133static int squareTest(unsigned loops,
134 giant *g1,
135 giant *g2)
136{
137 int loop;
138 PLAT_TIME startTime;
139 PLAT_TIME endTime;
140
141 PLAT_GET_TIME(startTime);
142 for(loop=0; loop<loops; loop++) {
143 gsquare(*g1++);
144 }
145 PLAT_GET_TIME(endTime);
146 return PLAT_GET_NS(startTime, endTime);
147}
148
149
150int main(int argc, char **argv)
151{
152 int arg;
153 char *argp;
154 giant *g1;
155 giant *g2; // ditto
156 unsigned char *buf; // random data
157 unsigned numDigits;
158 unsigned i;
159 unsigned numBytes;
160 unsigned mulgElapsed;
161 unsigned sqrElapsed;
162
163 int loops = LOOPS_DEF;
164 int seedSpec = 0;
165 unsigned seed = 0;
166 unsigned maxSize = MAX_SIZE_DEF;
167 unsigned minSize = MIN_SIZE_DEF;
168 int useOld = 0;
169
170 initCryptKit();
171
172 #if macintosh
173 argc = ccommand(&argv);
174 #endif
175
176 for(arg=1; arg<argc; arg++) {
177 argp = argv[arg];
178 switch(argp[0]) {
179 case 'x':
180 maxSize = atoi(&argp[2]);
181 break;
182 case 'n':
183 minSize = atoi(&argp[2]);
184 break;
185 case 'l':
186 loops = atoi(&argp[2]);
187 break;
188 case 'o':
189 useOld = 1;
190 break;
191 case 's':
192 seed = atoi(&argp[2]);
193 seedSpec = 1;
194 break;
195 case 'h':
196 default:
197 usage(argv);
198 }
199 }
200 buf = malloc(maxSize);
201
202 if(!seedSpec) {
203 unsigned long tim;
204 time(&tim);
205 seed = (unsigned)tim;
206 }
207 SRAND(seed);
208
209 /*
210 * Scratch giants, big enough for anything. Malloc here, init with
211 * random data before each test
212 * note these mallocs will be too big in the useOld case...
213 */
214 g1 = malloc(sizeof(giant) * loops);
215 g2 = malloc(sizeof(giant) * loops);
216 if((g1 == NULL) || (g2 == NULL)) {
217 printf("malloc error\n");
218 exit(1);
219 }
220 if(useOld) {
221 numDigits = ((2 * maxSize) + 1) / 2;
222 }
223 else {
224 numDigits = BYTES_TO_GIANT_DIGITS(2 * maxSize);
225 }
226 for(i=0; i<loops; i++) {
227 g1[i] = newGiant(numDigits);
228 g2[i] = newGiant(numDigits);
229 if((g1[i] == NULL) || (g2[i] == NULL)) {
230 printf("malloc error\n");
231 exit(1);
232 }
233 }
234
235 printf("Starting giants test: seed %d\n", seed);
236 for(numBytes=minSize; numBytes<=maxSize; numBytes*=2) {
237
238 initRandGiants(numBytes,
239 buf,
240 loops,
241 g1,
242 g2);
243
244 mulgElapsed = mulgTest(loops, g1, g2);
245 initRandGiants(numBytes,
246 buf,
247 loops,
248 g1,
249 g2);
250
251 sqrElapsed = squareTest(loops, g1, g2);
252 printf(" bits : %4d mulg : %3d ns gsquare : %3d ns\n",
253 numBytes * 8,
254 mulgElapsed / loops,
255 sqrElapsed / loops);
256
257 } /* for numBytes */
258 return 0;
259}