1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/freebl/mpi/mdxptest.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,310 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#include <stdio.h> 1.9 +#include <stdlib.h> 1.10 +#include <string.h> 1.11 +#include <malloc.h> 1.12 +#include <time.h> 1.13 +#include "mpi.h" 1.14 +#include "mpi-priv.h" 1.15 + 1.16 +/* #define OLD_WAY 1 */ 1.17 + 1.18 +/* This key is the 1024-bit test key used for speed testing of RSA private 1.19 +** key ops. 1.20 +*/ 1.21 + 1.22 +#define CONST const 1.23 + 1.24 +static CONST unsigned char default_n[128] = { 1.25 +0xc2,0xae,0x96,0x89,0xaf,0xce,0xd0,0x7b,0x3b,0x35,0xfd,0x0f,0xb1,0xf4,0x7a,0xd1, 1.26 +0x3c,0x7d,0xb5,0x86,0xf2,0x68,0x36,0xc9,0x97,0xe6,0x82,0x94,0x86,0xaa,0x05,0x39, 1.27 +0xec,0x11,0x51,0xcc,0x5c,0xa1,0x59,0xba,0x29,0x18,0xf3,0x28,0xf1,0x9d,0xe3,0xae, 1.28 +0x96,0x5d,0x6d,0x87,0x73,0xf6,0xf6,0x1f,0xd0,0x2d,0xfb,0x2f,0x7a,0x13,0x7f,0xc8, 1.29 +0x0c,0x7a,0xe9,0x85,0xfb,0xce,0x74,0x86,0xf8,0xef,0x2f,0x85,0x37,0x73,0x0f,0x62, 1.30 +0x4e,0x93,0x17,0xb7,0x7e,0x84,0x9a,0x94,0x11,0x05,0xca,0x0d,0x31,0x4b,0x2a,0xc8, 1.31 +0xdf,0xfe,0xe9,0x0c,0x13,0xc7,0xf2,0xad,0x19,0x64,0x28,0x3c,0xb5,0x6a,0xc8,0x4b, 1.32 +0x79,0xea,0x7c,0xce,0x75,0x92,0x45,0x3e,0xa3,0x9d,0x64,0x6f,0x04,0x69,0x19,0x17 1.33 +}; 1.34 + 1.35 +static CONST unsigned char default_d[128] = { 1.36 +0x13,0xcb,0xbc,0xf2,0xf3,0x35,0x8c,0x6d,0x7b,0x6f,0xd9,0xf3,0xa6,0x9c,0xbd,0x80, 1.37 +0x59,0x2e,0x4f,0x2f,0x11,0xa7,0x17,0x2b,0x18,0x8f,0x0f,0xe8,0x1a,0x69,0x5f,0x6e, 1.38 +0xac,0x5a,0x76,0x7e,0xd9,0x4c,0x6e,0xdb,0x47,0x22,0x8a,0x57,0x37,0x7a,0x5e,0x94, 1.39 +0x7a,0x25,0xb5,0xe5,0x78,0x1d,0x3c,0x99,0xaf,0x89,0x7d,0x69,0x2e,0x78,0x9d,0x1d, 1.40 +0x84,0xc8,0xc1,0xd7,0x1a,0xb2,0x6d,0x2d,0x8a,0xd9,0xab,0x6b,0xce,0xae,0xb0,0xa0, 1.41 +0x58,0x55,0xad,0x5c,0x40,0x8a,0xd6,0x96,0x08,0x8a,0xe8,0x63,0xe6,0x3d,0x6c,0x20, 1.42 +0x49,0xc7,0xaf,0x0f,0x25,0x73,0xd3,0x69,0x43,0x3b,0xf2,0x32,0xf8,0x3d,0x5e,0xee, 1.43 +0x7a,0xca,0xd6,0x94,0x55,0xe5,0xbd,0x25,0x34,0x8d,0x63,0x40,0xb5,0x8a,0xc3,0x01 1.44 +}; 1.45 + 1.46 + 1.47 +#define DEFAULT_ITERS 50 1.48 + 1.49 +typedef clock_t timetype; 1.50 +#define gettime(x) *(x) = clock() 1.51 +#define subtime(a, b) a -= b 1.52 +#define msec(x) ((clock_t)((double)x * 1000.0 / CLOCKS_PER_SEC)) 1.53 +#define sec(x) (x / CLOCKS_PER_SEC) 1.54 + 1.55 +struct TimingContextStr { 1.56 + timetype start; 1.57 + timetype end; 1.58 + timetype interval; 1.59 + 1.60 + int minutes; 1.61 + int seconds; 1.62 + int millisecs; 1.63 +}; 1.64 + 1.65 +typedef struct TimingContextStr TimingContext; 1.66 + 1.67 +TimingContext *CreateTimingContext(void) 1.68 +{ 1.69 + return (TimingContext *)malloc(sizeof(TimingContext)); 1.70 +} 1.71 + 1.72 +void DestroyTimingContext(TimingContext *ctx) 1.73 +{ 1.74 + free(ctx); 1.75 +} 1.76 + 1.77 +void TimingBegin(TimingContext *ctx) 1.78 +{ 1.79 + gettime(&ctx->start); 1.80 +} 1.81 + 1.82 +static void timingUpdate(TimingContext *ctx) 1.83 +{ 1.84 + 1.85 + ctx->millisecs = msec(ctx->interval) % 1000; 1.86 + ctx->seconds = sec(ctx->interval); 1.87 + ctx->minutes = ctx->seconds / 60; 1.88 + ctx->seconds %= 60; 1.89 + 1.90 +} 1.91 + 1.92 +void TimingEnd(TimingContext *ctx) 1.93 +{ 1.94 + gettime(&ctx->end); 1.95 + ctx->interval = ctx->end; 1.96 + subtime(ctx->interval, ctx->start); 1.97 + timingUpdate(ctx); 1.98 +} 1.99 + 1.100 +char *TimingGenerateString(TimingContext *ctx) 1.101 +{ 1.102 + static char sBuf[4096]; 1.103 + 1.104 + sprintf(sBuf, "%d minutes, %d.%03d seconds", ctx->minutes, 1.105 + ctx->seconds, ctx->millisecs); 1.106 + return sBuf; 1.107 +} 1.108 + 1.109 +static void 1.110 +dumpBytes( unsigned char * b, int l) 1.111 +{ 1.112 + int i; 1.113 + if (l <= 0) 1.114 + return; 1.115 + for (i = 0; i < l; ++i) { 1.116 + if (i % 16 == 0) 1.117 + printf("\t"); 1.118 + printf(" %02x", b[i]); 1.119 + if (i % 16 == 15) 1.120 + printf("\n"); 1.121 + } 1.122 + if ((i % 16) != 0) 1.123 + printf("\n"); 1.124 + printf("\n"); 1.125 +} 1.126 + 1.127 +static mp_err 1.128 +testNewFuncs(const unsigned char * modulusBytes, int modulus_len) 1.129 +{ 1.130 + mp_err mperr = MP_OKAY; 1.131 + mp_int modulus; 1.132 + unsigned char buf[512]; 1.133 + 1.134 + mperr = mp_init(&modulus); 1.135 + mperr = mp_read_unsigned_octets(&modulus, modulusBytes, modulus_len ); 1.136 + mperr = mp_to_fixlen_octets(&modulus, buf, modulus_len); 1.137 + mperr = mp_to_fixlen_octets(&modulus, buf, modulus_len+1); 1.138 + mperr = mp_to_fixlen_octets(&modulus, buf, modulus_len+4); 1.139 + mperr = mp_to_unsigned_octets(&modulus, buf, modulus_len); 1.140 + mperr = mp_to_signed_octets(&modulus, buf, modulus_len + 1); 1.141 + mp_clear(&modulus); 1.142 + return mperr; 1.143 +} 1.144 + 1.145 +int 1.146 +testModExp( const unsigned char * modulusBytes, 1.147 + const unsigned int expo, 1.148 + const unsigned char * input, 1.149 + unsigned char * output, 1.150 + int modulus_len) 1.151 +{ 1.152 + mp_err mperr = MP_OKAY; 1.153 + mp_int modulus; 1.154 + mp_int base; 1.155 + mp_int exponent; 1.156 + mp_int result; 1.157 + 1.158 + mperr = mp_init(&modulus); 1.159 + mperr += mp_init(&base); 1.160 + mperr += mp_init(&exponent); 1.161 + mperr += mp_init(&result); 1.162 + /* we initialize all mp_ints unconditionally, even if some fail. 1.163 + ** This guarantees that the DIGITS pointer is valid (even if null). 1.164 + ** So, mp_clear will do the right thing below. 1.165 + */ 1.166 + if (mperr == MP_OKAY) { 1.167 + mperr = mp_read_unsigned_octets(&modulus, 1.168 + modulusBytes + (sizeof default_n - modulus_len), modulus_len ); 1.169 + mperr += mp_read_unsigned_octets(&base, input, modulus_len ); 1.170 + mp_set(&exponent, expo); 1.171 + if (mperr == MP_OKAY) { 1.172 +#if OLD_WAY 1.173 + mperr = s_mp_exptmod(&base, &exponent, &modulus, &result); 1.174 +#else 1.175 + mperr = mp_exptmod(&base, &exponent, &modulus, &result); 1.176 +#endif 1.177 + if (mperr == MP_OKAY) { 1.178 + mperr = mp_to_fixlen_octets(&result, output, modulus_len); 1.179 + } 1.180 + } 1.181 + } 1.182 + mp_clear(&base); 1.183 + mp_clear(&result); 1.184 + 1.185 + mp_clear(&modulus); 1.186 + mp_clear(&exponent); 1.187 + 1.188 + return (int)mperr; 1.189 +} 1.190 + 1.191 +int 1.192 +doModExp( const unsigned char * modulusBytes, 1.193 + const unsigned char * exponentBytes, 1.194 + const unsigned char * input, 1.195 + unsigned char * output, 1.196 + int modulus_len) 1.197 +{ 1.198 + mp_err mperr = MP_OKAY; 1.199 + mp_int modulus; 1.200 + mp_int base; 1.201 + mp_int exponent; 1.202 + mp_int result; 1.203 + 1.204 + mperr = mp_init(&modulus); 1.205 + mperr += mp_init(&base); 1.206 + mperr += mp_init(&exponent); 1.207 + mperr += mp_init(&result); 1.208 + /* we initialize all mp_ints unconditionally, even if some fail. 1.209 + ** This guarantees that the DIGITS pointer is valid (even if null). 1.210 + ** So, mp_clear will do the right thing below. 1.211 + */ 1.212 + if (mperr == MP_OKAY) { 1.213 + mperr = mp_read_unsigned_octets(&modulus, 1.214 + modulusBytes + (sizeof default_n - modulus_len), modulus_len ); 1.215 + mperr += mp_read_unsigned_octets(&exponent, exponentBytes, modulus_len ); 1.216 + mperr += mp_read_unsigned_octets(&base, input, modulus_len ); 1.217 + if (mperr == MP_OKAY) { 1.218 +#if OLD_WAY 1.219 + mperr = s_mp_exptmod(&base, &exponent, &modulus, &result); 1.220 +#else 1.221 + mperr = mp_exptmod(&base, &exponent, &modulus, &result); 1.222 +#endif 1.223 + if (mperr == MP_OKAY) { 1.224 + mperr = mp_to_fixlen_octets(&result, output, modulus_len); 1.225 + } 1.226 + } 1.227 + } 1.228 + mp_clear(&base); 1.229 + mp_clear(&result); 1.230 + 1.231 + mp_clear(&modulus); 1.232 + mp_clear(&exponent); 1.233 + 1.234 + return (int)mperr; 1.235 +} 1.236 + 1.237 +int 1.238 +main(int argc, char **argv) 1.239 +{ 1.240 + TimingContext * timeCtx; 1.241 + char * progName; 1.242 + long iters = DEFAULT_ITERS; 1.243 + unsigned int modulus_len; 1.244 + int i; 1.245 + int rv; 1.246 + unsigned char buf [1024]; 1.247 + unsigned char buf2[1024]; 1.248 + 1.249 + progName = strrchr(argv[0], '/'); 1.250 + if (!progName) 1.251 + progName = strrchr(argv[0], '\\'); 1.252 + progName = progName ? progName+1 : argv[0]; 1.253 + 1.254 + if (argc >= 2) { 1.255 + iters = atol(argv[1]); 1.256 + } 1.257 + 1.258 + if (argc >= 3) { 1.259 + modulus_len = atol(argv[2]); 1.260 + } else 1.261 + modulus_len = sizeof default_n; 1.262 + 1.263 + /* no library init function !? */ 1.264 + 1.265 + memset(buf, 0x41, sizeof buf); 1.266 + 1.267 + if (iters < 2) { 1.268 + testNewFuncs( default_n, modulus_len); 1.269 + testNewFuncs( default_n+1, modulus_len - 1); 1.270 + testNewFuncs( default_n+2, modulus_len - 2); 1.271 + testNewFuncs( default_n+3, modulus_len - 3); 1.272 + 1.273 + printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies); 1.274 + rv = testModExp(default_n, 0, buf, buf2, modulus_len); 1.275 + dumpBytes((unsigned char *)buf2, modulus_len); 1.276 + 1.277 + printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies); 1.278 + rv = testModExp(default_n, 1, buf, buf2, modulus_len); 1.279 + dumpBytes((unsigned char *)buf2, modulus_len); 1.280 + 1.281 + printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies); 1.282 + rv = testModExp(default_n, 2, buf, buf2, modulus_len); 1.283 + dumpBytes((unsigned char *)buf2, modulus_len); 1.284 + 1.285 + printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies); 1.286 + rv = testModExp(default_n, 3, buf, buf2, modulus_len); 1.287 + dumpBytes((unsigned char *)buf2, modulus_len); 1.288 + } 1.289 + printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies); 1.290 + rv = doModExp(default_n, default_d, buf, buf2, modulus_len); 1.291 + if (rv != 0) { 1.292 + fprintf(stderr, "Error in modexp operation:\n"); 1.293 + exit(1); 1.294 + } 1.295 + dumpBytes((unsigned char *)buf2, modulus_len); 1.296 + printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies); 1.297 + 1.298 + timeCtx = CreateTimingContext(); 1.299 + TimingBegin(timeCtx); 1.300 + i = iters; 1.301 + while (i--) { 1.302 + rv = doModExp(default_n, default_d, buf, buf2, modulus_len); 1.303 + if (rv != 0) { 1.304 + fprintf(stderr, "Error in modexp operation\n"); 1.305 + exit(1); 1.306 + } 1.307 + } 1.308 + TimingEnd(timeCtx); 1.309 + printf("%ld iterations in %s\n", iters, TimingGenerateString(timeCtx)); 1.310 + printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies); 1.311 + 1.312 + return 0; 1.313 +}