security/nss/lib/freebl/mpi/mdxptest.c

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:2a09cc5dbb5a
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <malloc.h>
9 #include <time.h>
10 #include "mpi.h"
11 #include "mpi-priv.h"
12
13 /* #define OLD_WAY 1 */
14
15 /* This key is the 1024-bit test key used for speed testing of RSA private
16 ** key ops.
17 */
18
19 #define CONST const
20
21 static CONST unsigned char default_n[128] = {
22 0xc2,0xae,0x96,0x89,0xaf,0xce,0xd0,0x7b,0x3b,0x35,0xfd,0x0f,0xb1,0xf4,0x7a,0xd1,
23 0x3c,0x7d,0xb5,0x86,0xf2,0x68,0x36,0xc9,0x97,0xe6,0x82,0x94,0x86,0xaa,0x05,0x39,
24 0xec,0x11,0x51,0xcc,0x5c,0xa1,0x59,0xba,0x29,0x18,0xf3,0x28,0xf1,0x9d,0xe3,0xae,
25 0x96,0x5d,0x6d,0x87,0x73,0xf6,0xf6,0x1f,0xd0,0x2d,0xfb,0x2f,0x7a,0x13,0x7f,0xc8,
26 0x0c,0x7a,0xe9,0x85,0xfb,0xce,0x74,0x86,0xf8,0xef,0x2f,0x85,0x37,0x73,0x0f,0x62,
27 0x4e,0x93,0x17,0xb7,0x7e,0x84,0x9a,0x94,0x11,0x05,0xca,0x0d,0x31,0x4b,0x2a,0xc8,
28 0xdf,0xfe,0xe9,0x0c,0x13,0xc7,0xf2,0xad,0x19,0x64,0x28,0x3c,0xb5,0x6a,0xc8,0x4b,
29 0x79,0xea,0x7c,0xce,0x75,0x92,0x45,0x3e,0xa3,0x9d,0x64,0x6f,0x04,0x69,0x19,0x17
30 };
31
32 static CONST unsigned char default_d[128] = {
33 0x13,0xcb,0xbc,0xf2,0xf3,0x35,0x8c,0x6d,0x7b,0x6f,0xd9,0xf3,0xa6,0x9c,0xbd,0x80,
34 0x59,0x2e,0x4f,0x2f,0x11,0xa7,0x17,0x2b,0x18,0x8f,0x0f,0xe8,0x1a,0x69,0x5f,0x6e,
35 0xac,0x5a,0x76,0x7e,0xd9,0x4c,0x6e,0xdb,0x47,0x22,0x8a,0x57,0x37,0x7a,0x5e,0x94,
36 0x7a,0x25,0xb5,0xe5,0x78,0x1d,0x3c,0x99,0xaf,0x89,0x7d,0x69,0x2e,0x78,0x9d,0x1d,
37 0x84,0xc8,0xc1,0xd7,0x1a,0xb2,0x6d,0x2d,0x8a,0xd9,0xab,0x6b,0xce,0xae,0xb0,0xa0,
38 0x58,0x55,0xad,0x5c,0x40,0x8a,0xd6,0x96,0x08,0x8a,0xe8,0x63,0xe6,0x3d,0x6c,0x20,
39 0x49,0xc7,0xaf,0x0f,0x25,0x73,0xd3,0x69,0x43,0x3b,0xf2,0x32,0xf8,0x3d,0x5e,0xee,
40 0x7a,0xca,0xd6,0x94,0x55,0xe5,0xbd,0x25,0x34,0x8d,0x63,0x40,0xb5,0x8a,0xc3,0x01
41 };
42
43
44 #define DEFAULT_ITERS 50
45
46 typedef clock_t timetype;
47 #define gettime(x) *(x) = clock()
48 #define subtime(a, b) a -= b
49 #define msec(x) ((clock_t)((double)x * 1000.0 / CLOCKS_PER_SEC))
50 #define sec(x) (x / CLOCKS_PER_SEC)
51
52 struct TimingContextStr {
53 timetype start;
54 timetype end;
55 timetype interval;
56
57 int minutes;
58 int seconds;
59 int millisecs;
60 };
61
62 typedef struct TimingContextStr TimingContext;
63
64 TimingContext *CreateTimingContext(void)
65 {
66 return (TimingContext *)malloc(sizeof(TimingContext));
67 }
68
69 void DestroyTimingContext(TimingContext *ctx)
70 {
71 free(ctx);
72 }
73
74 void TimingBegin(TimingContext *ctx)
75 {
76 gettime(&ctx->start);
77 }
78
79 static void timingUpdate(TimingContext *ctx)
80 {
81
82 ctx->millisecs = msec(ctx->interval) % 1000;
83 ctx->seconds = sec(ctx->interval);
84 ctx->minutes = ctx->seconds / 60;
85 ctx->seconds %= 60;
86
87 }
88
89 void TimingEnd(TimingContext *ctx)
90 {
91 gettime(&ctx->end);
92 ctx->interval = ctx->end;
93 subtime(ctx->interval, ctx->start);
94 timingUpdate(ctx);
95 }
96
97 char *TimingGenerateString(TimingContext *ctx)
98 {
99 static char sBuf[4096];
100
101 sprintf(sBuf, "%d minutes, %d.%03d seconds", ctx->minutes,
102 ctx->seconds, ctx->millisecs);
103 return sBuf;
104 }
105
106 static void
107 dumpBytes( unsigned char * b, int l)
108 {
109 int i;
110 if (l <= 0)
111 return;
112 for (i = 0; i < l; ++i) {
113 if (i % 16 == 0)
114 printf("\t");
115 printf(" %02x", b[i]);
116 if (i % 16 == 15)
117 printf("\n");
118 }
119 if ((i % 16) != 0)
120 printf("\n");
121 printf("\n");
122 }
123
124 static mp_err
125 testNewFuncs(const unsigned char * modulusBytes, int modulus_len)
126 {
127 mp_err mperr = MP_OKAY;
128 mp_int modulus;
129 unsigned char buf[512];
130
131 mperr = mp_init(&modulus);
132 mperr = mp_read_unsigned_octets(&modulus, modulusBytes, modulus_len );
133 mperr = mp_to_fixlen_octets(&modulus, buf, modulus_len);
134 mperr = mp_to_fixlen_octets(&modulus, buf, modulus_len+1);
135 mperr = mp_to_fixlen_octets(&modulus, buf, modulus_len+4);
136 mperr = mp_to_unsigned_octets(&modulus, buf, modulus_len);
137 mperr = mp_to_signed_octets(&modulus, buf, modulus_len + 1);
138 mp_clear(&modulus);
139 return mperr;
140 }
141
142 int
143 testModExp( const unsigned char * modulusBytes,
144 const unsigned int expo,
145 const unsigned char * input,
146 unsigned char * output,
147 int modulus_len)
148 {
149 mp_err mperr = MP_OKAY;
150 mp_int modulus;
151 mp_int base;
152 mp_int exponent;
153 mp_int result;
154
155 mperr = mp_init(&modulus);
156 mperr += mp_init(&base);
157 mperr += mp_init(&exponent);
158 mperr += mp_init(&result);
159 /* we initialize all mp_ints unconditionally, even if some fail.
160 ** This guarantees that the DIGITS pointer is valid (even if null).
161 ** So, mp_clear will do the right thing below.
162 */
163 if (mperr == MP_OKAY) {
164 mperr = mp_read_unsigned_octets(&modulus,
165 modulusBytes + (sizeof default_n - modulus_len), modulus_len );
166 mperr += mp_read_unsigned_octets(&base, input, modulus_len );
167 mp_set(&exponent, expo);
168 if (mperr == MP_OKAY) {
169 #if OLD_WAY
170 mperr = s_mp_exptmod(&base, &exponent, &modulus, &result);
171 #else
172 mperr = mp_exptmod(&base, &exponent, &modulus, &result);
173 #endif
174 if (mperr == MP_OKAY) {
175 mperr = mp_to_fixlen_octets(&result, output, modulus_len);
176 }
177 }
178 }
179 mp_clear(&base);
180 mp_clear(&result);
181
182 mp_clear(&modulus);
183 mp_clear(&exponent);
184
185 return (int)mperr;
186 }
187
188 int
189 doModExp( const unsigned char * modulusBytes,
190 const unsigned char * exponentBytes,
191 const unsigned char * input,
192 unsigned char * output,
193 int modulus_len)
194 {
195 mp_err mperr = MP_OKAY;
196 mp_int modulus;
197 mp_int base;
198 mp_int exponent;
199 mp_int result;
200
201 mperr = mp_init(&modulus);
202 mperr += mp_init(&base);
203 mperr += mp_init(&exponent);
204 mperr += mp_init(&result);
205 /* we initialize all mp_ints unconditionally, even if some fail.
206 ** This guarantees that the DIGITS pointer is valid (even if null).
207 ** So, mp_clear will do the right thing below.
208 */
209 if (mperr == MP_OKAY) {
210 mperr = mp_read_unsigned_octets(&modulus,
211 modulusBytes + (sizeof default_n - modulus_len), modulus_len );
212 mperr += mp_read_unsigned_octets(&exponent, exponentBytes, modulus_len );
213 mperr += mp_read_unsigned_octets(&base, input, modulus_len );
214 if (mperr == MP_OKAY) {
215 #if OLD_WAY
216 mperr = s_mp_exptmod(&base, &exponent, &modulus, &result);
217 #else
218 mperr = mp_exptmod(&base, &exponent, &modulus, &result);
219 #endif
220 if (mperr == MP_OKAY) {
221 mperr = mp_to_fixlen_octets(&result, output, modulus_len);
222 }
223 }
224 }
225 mp_clear(&base);
226 mp_clear(&result);
227
228 mp_clear(&modulus);
229 mp_clear(&exponent);
230
231 return (int)mperr;
232 }
233
234 int
235 main(int argc, char **argv)
236 {
237 TimingContext * timeCtx;
238 char * progName;
239 long iters = DEFAULT_ITERS;
240 unsigned int modulus_len;
241 int i;
242 int rv;
243 unsigned char buf [1024];
244 unsigned char buf2[1024];
245
246 progName = strrchr(argv[0], '/');
247 if (!progName)
248 progName = strrchr(argv[0], '\\');
249 progName = progName ? progName+1 : argv[0];
250
251 if (argc >= 2) {
252 iters = atol(argv[1]);
253 }
254
255 if (argc >= 3) {
256 modulus_len = atol(argv[2]);
257 } else
258 modulus_len = sizeof default_n;
259
260 /* no library init function !? */
261
262 memset(buf, 0x41, sizeof buf);
263
264 if (iters < 2) {
265 testNewFuncs( default_n, modulus_len);
266 testNewFuncs( default_n+1, modulus_len - 1);
267 testNewFuncs( default_n+2, modulus_len - 2);
268 testNewFuncs( default_n+3, modulus_len - 3);
269
270 printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies);
271 rv = testModExp(default_n, 0, buf, buf2, modulus_len);
272 dumpBytes((unsigned char *)buf2, modulus_len);
273
274 printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies);
275 rv = testModExp(default_n, 1, buf, buf2, modulus_len);
276 dumpBytes((unsigned char *)buf2, modulus_len);
277
278 printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies);
279 rv = testModExp(default_n, 2, buf, buf2, modulus_len);
280 dumpBytes((unsigned char *)buf2, modulus_len);
281
282 printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies);
283 rv = testModExp(default_n, 3, buf, buf2, modulus_len);
284 dumpBytes((unsigned char *)buf2, modulus_len);
285 }
286 printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies);
287 rv = doModExp(default_n, default_d, buf, buf2, modulus_len);
288 if (rv != 0) {
289 fprintf(stderr, "Error in modexp operation:\n");
290 exit(1);
291 }
292 dumpBytes((unsigned char *)buf2, modulus_len);
293 printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies);
294
295 timeCtx = CreateTimingContext();
296 TimingBegin(timeCtx);
297 i = iters;
298 while (i--) {
299 rv = doModExp(default_n, default_d, buf, buf2, modulus_len);
300 if (rv != 0) {
301 fprintf(stderr, "Error in modexp operation\n");
302 exit(1);
303 }
304 }
305 TimingEnd(timeCtx);
306 printf("%ld iterations in %s\n", iters, TimingGenerateString(timeCtx));
307 printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies);
308
309 return 0;
310 }

mercurial