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

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial