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

changeset 0
6474c204b198
     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 +}

mercurial