• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /macosx-10.10.1/Security-57031.1.35/Security/libsecurity_cryptkit/ckutils/giantBench/
1/*
2 * Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25#include "giantIntegers.h"
26#include "ckutilities.h"
27#include "feeFunctions.h"
28#include "feeDebug.h"
29#include <stdlib.h>
30#include "ckutilsPlatform.h"
31#include <stdio.h>
32#include <time.h>
33
34#define LOOPS_DEF	100
35#define MIN_SIZE_DEF	4	/* min giant size in bytes */
36#define MAX_SIZE_DEF	32	/* max in bytes */
37#define LOOP_NOTIFY	100
38
39
40static void usage(char **argv)
41{
42	printf("usage: %s [options]\n", argv[0]);
43	printf("   Options:\n");
44	printf("   l=loops    (default = %d)\n", LOOPS_DEF);
45	printf("   n=maxBytes (default = %d\n", MIN_SIZE_DEF);
46	printf("   x=maxBytes (default = %d\n", MAX_SIZE_DEF);
47	printf("   o (use old 16-bit CryptKit\n");
48	printf("   s=seed\n");
49	printf("   h(elp)\n");
50	exit(1);
51}
52
53/*
54 * Fill buffer with random data.
55 */
56static void fillData(unsigned bufSize,
57	unsigned char *buf)
58{
59	unsigned 	*ip;
60	unsigned 	intCount;
61	unsigned 	residue;
62	unsigned char	*cp;
63	int 		i;
64
65	intCount = bufSize >> 2;
66	ip = (unsigned *)buf;
67	for(i=0; i<intCount; i++) {
68		*ip++ = RAND();
69	}
70
71	residue = bufSize & 0x3;
72	cp = (unsigned char *)ip;
73	for(i=0; i<residue; i++) {
74		*cp++ = (unsigned char)RAND();
75	}
76}
77
78/*
79 * fill a pre-allocd giant with specified number of bytes of random
80 * data. *Buf is mallocd and uninitialized and will change here.
81 */
82static void genGiant(giant g,
83	unsigned numBytes,
84	unsigned char *buf)
85{
86	int i;
87
88	fillData(numBytes, buf);
89	deserializeGiant(buf, g, numBytes);
90
91	/* set random sign; deserializeGiant() is always positive */
92	i = RAND();
93	if(i & 1) {
94		g->sign = -g->sign;
95	}
96
97	/* avoid zero data - too many pitfalls with mod and div */
98	while(isZero(g)) {
99		g->sign = 1;
100		g->n[0] = RAND();
101	}
102}
103
104/*
105 * Init giant arrays with random data.
106 */
107static void initRandGiants(unsigned numBytes,
108	unsigned char *buf,
109	unsigned numGiants,
110	giant *g1,
111	giant *g2)
112{
113	int i;
114
115	for(i=0; i<numGiants; i++) {
116	    genGiant(g1[i], numBytes, buf);
117	    genGiant(g2[i], numBytes, buf);
118	}
119}
120
121/*
122 * Individual tests. API is identical for all tests.
123 *
124 * loops  : number of ops to perform.
125 * g1, g2 : arrays of giants with random data and sign. Tests may modify
126 *          these. Size of array = 'loops'. Capacity big enough for all
127 *          conceivable ops.
128 * Return : total microseconds to do 'loops' ops.
129 */
130
131static int mulgTest(unsigned loops,
132	giant *g1,
133	giant *g2)
134{
135	int loop;
136	PLAT_TIME startTime;
137	PLAT_TIME endTime;
138
139	PLAT_GET_TIME(startTime);
140	for(loop=0; loop<loops; loop++) {
141		mulg(*g1++, *g2++);
142	}
143	PLAT_GET_TIME(endTime);
144	return PLAT_GET_NS(startTime, endTime);
145}
146
147static int squareTest(unsigned loops,
148	giant *g1,
149	giant *g2)
150{
151	int loop;
152	PLAT_TIME startTime;
153	PLAT_TIME endTime;
154
155	PLAT_GET_TIME(startTime);
156	for(loop=0; loop<loops; loop++) {
157		gsquare(*g1++);
158	}
159	PLAT_GET_TIME(endTime);
160	return PLAT_GET_NS(startTime, endTime);
161}
162
163
164int main(int argc, char **argv)
165{
166	int		arg;
167	char		*argp;
168	giant		*g1;
169	giant		*g2;		// ditto
170	unsigned char	*buf;		// random data
171	unsigned	numDigits;
172	unsigned	i;
173	unsigned	numBytes;
174	unsigned	mulgElapsed;
175	unsigned	sqrElapsed;
176
177	int 		loops = LOOPS_DEF;
178	int		seedSpec = 0;
179	unsigned	seed = 0;
180	unsigned	maxSize = MAX_SIZE_DEF;
181	unsigned	minSize = MIN_SIZE_DEF;
182	int 		useOld = 0;
183
184	initCryptKit();
185
186	#if	macintosh
187	argc = ccommand(&argv);
188	#endif
189
190	for(arg=1; arg<argc; arg++) {
191		argp = argv[arg];
192		switch(argp[0]) {
193		    case 'x':
194		    	maxSize = atoi(&argp[2]);
195			break;
196		    case 'n':
197		    	minSize = atoi(&argp[2]);
198			break;
199		    case 'l':
200		    	loops = atoi(&argp[2]);
201			break;
202		    case 'o':
203		    	useOld = 1;
204			break;
205		    case 's':
206			seed = atoi(&argp[2]);
207			seedSpec = 1;
208			break;
209		    case 'h':
210		    default:
211		    	usage(argv);
212		}
213	}
214	buf = malloc(maxSize);
215
216	if(!seedSpec) {
217		unsigned long	tim;
218		time(&tim);
219		seed = (unsigned)tim;
220	}
221	SRAND(seed);
222
223	/*
224	 * Scratch giants, big enough for anything. Malloc here, init with
225	 * random data before each test
226	 * note these mallocs will be too big in the useOld case...
227	 */
228	g1 = malloc(sizeof(giant) * loops);
229	g2 = malloc(sizeof(giant) * loops);
230    if((g1 == NULL) || (g2 == NULL)) {
231    	printf("malloc error\n");
232    	exit(1);
233    }
234	if(useOld) {
235	    numDigits = ((2 * maxSize) + 1) / 2;
236	}
237	else {
238	    numDigits = BYTES_TO_GIANT_DIGITS(2 * maxSize);
239	}
240	for(i=0; i<loops; i++) {
241	    g1[i] = newGiant(numDigits);
242	    g2[i] = newGiant(numDigits);
243	    if((g1[i] == NULL) || (g2[i] == NULL)) {
244	    	printf("malloc error\n");
245	    	exit(1);
246	    }
247	}
248
249	printf("Starting giants test: seed %d\n", seed);
250	for(numBytes=minSize; numBytes<=maxSize; numBytes*=2) {
251
252		initRandGiants(numBytes,
253			buf,
254			loops,
255			g1,
256			g2);
257
258		mulgElapsed = mulgTest(loops, g1, g2);
259		initRandGiants(numBytes,
260			buf,
261			loops,
262			g1,
263			g2);
264
265		sqrElapsed = squareTest(loops, g1, g2);
266		printf("  bits : %4d   mulg : %3d ns   gsquare : %3d ns\n",
267			numBytes * 8,
268			mulgElapsed / loops,
269			sqrElapsed / loops);
270
271	} /* for numBytes */
272	return 0;
273}
274