1*0Sstevel@tonic-gate /* unused */ 2*0Sstevel@tonic-gate 3*0Sstevel@tonic-gate /* crypto/bn/expspeed.c */ 4*0Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 5*0Sstevel@tonic-gate * All rights reserved. 6*0Sstevel@tonic-gate * 7*0Sstevel@tonic-gate * This package is an SSL implementation written 8*0Sstevel@tonic-gate * by Eric Young (eay@cryptsoft.com). 9*0Sstevel@tonic-gate * The implementation was written so as to conform with Netscapes SSL. 10*0Sstevel@tonic-gate * 11*0Sstevel@tonic-gate * This library is free for commercial and non-commercial use as long as 12*0Sstevel@tonic-gate * the following conditions are aheared to. The following conditions 13*0Sstevel@tonic-gate * apply to all code found in this distribution, be it the RC4, RSA, 14*0Sstevel@tonic-gate * lhash, DES, etc., code; not just the SSL code. The SSL documentation 15*0Sstevel@tonic-gate * included with this distribution is covered by the same copyright terms 16*0Sstevel@tonic-gate * except that the holder is Tim Hudson (tjh@cryptsoft.com). 17*0Sstevel@tonic-gate * 18*0Sstevel@tonic-gate * Copyright remains Eric Young's, and as such any Copyright notices in 19*0Sstevel@tonic-gate * the code are not to be removed. 20*0Sstevel@tonic-gate * If this package is used in a product, Eric Young should be given attribution 21*0Sstevel@tonic-gate * as the author of the parts of the library used. 22*0Sstevel@tonic-gate * This can be in the form of a textual message at program startup or 23*0Sstevel@tonic-gate * in documentation (online or textual) provided with the package. 24*0Sstevel@tonic-gate * 25*0Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 26*0Sstevel@tonic-gate * modification, are permitted provided that the following conditions 27*0Sstevel@tonic-gate * are met: 28*0Sstevel@tonic-gate * 1. Redistributions of source code must retain the copyright 29*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 30*0Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 31*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the 32*0Sstevel@tonic-gate * documentation and/or other materials provided with the distribution. 33*0Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software 34*0Sstevel@tonic-gate * must display the following acknowledgement: 35*0Sstevel@tonic-gate * "This product includes cryptographic software written by 36*0Sstevel@tonic-gate * Eric Young (eay@cryptsoft.com)" 37*0Sstevel@tonic-gate * The word 'cryptographic' can be left out if the rouines from the library 38*0Sstevel@tonic-gate * being used are not cryptographic related :-). 39*0Sstevel@tonic-gate * 4. If you include any Windows specific code (or a derivative thereof) from 40*0Sstevel@tonic-gate * the apps directory (application code) you must include an acknowledgement: 41*0Sstevel@tonic-gate * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 42*0Sstevel@tonic-gate * 43*0Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 44*0Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 45*0Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 46*0Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 47*0Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 48*0Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 49*0Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 50*0Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 51*0Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 52*0Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 53*0Sstevel@tonic-gate * SUCH DAMAGE. 54*0Sstevel@tonic-gate * 55*0Sstevel@tonic-gate * The licence and distribution terms for any publically available version or 56*0Sstevel@tonic-gate * derivative of this code cannot be changed. i.e. this code cannot simply be 57*0Sstevel@tonic-gate * copied and put under another distribution licence 58*0Sstevel@tonic-gate * [including the GNU Public Licence.] 59*0Sstevel@tonic-gate */ 60*0Sstevel@tonic-gate 61*0Sstevel@tonic-gate /* most of this code has been pilfered from my libdes speed.c program */ 62*0Sstevel@tonic-gate 63*0Sstevel@tonic-gate #define BASENUM 5000 64*0Sstevel@tonic-gate #define NUM_START 0 65*0Sstevel@tonic-gate 66*0Sstevel@tonic-gate 67*0Sstevel@tonic-gate /* determine timings for modexp, modmul, modsqr, gcd, Kronecker symbol, 68*0Sstevel@tonic-gate * modular inverse, or modular square roots */ 69*0Sstevel@tonic-gate #define TEST_EXP 70*0Sstevel@tonic-gate #undef TEST_MUL 71*0Sstevel@tonic-gate #undef TEST_SQR 72*0Sstevel@tonic-gate #undef TEST_GCD 73*0Sstevel@tonic-gate #undef TEST_KRON 74*0Sstevel@tonic-gate #undef TEST_INV 75*0Sstevel@tonic-gate #undef TEST_SQRT 76*0Sstevel@tonic-gate #define P_MOD_64 9 /* least significant 6 bits for prime to be used for BN_sqrt timings */ 77*0Sstevel@tonic-gate 78*0Sstevel@tonic-gate #if defined(TEST_EXP) + defined(TEST_MUL) + defined(TEST_SQR) + defined(TEST_GCD) + defined(TEST_KRON) + defined(TEST_INV) +defined(TEST_SQRT) != 1 79*0Sstevel@tonic-gate # error "choose one test" 80*0Sstevel@tonic-gate #endif 81*0Sstevel@tonic-gate 82*0Sstevel@tonic-gate #if defined(TEST_INV) || defined(TEST_SQRT) 83*0Sstevel@tonic-gate # define C_PRIME 84*0Sstevel@tonic-gate static void genprime_cb(int p, int n, void *arg); 85*0Sstevel@tonic-gate #endif 86*0Sstevel@tonic-gate 87*0Sstevel@tonic-gate 88*0Sstevel@tonic-gate 89*0Sstevel@tonic-gate #undef PROG 90*0Sstevel@tonic-gate #define PROG bnspeed_main 91*0Sstevel@tonic-gate 92*0Sstevel@tonic-gate #include <stdio.h> 93*0Sstevel@tonic-gate #include <stdlib.h> 94*0Sstevel@tonic-gate #include <signal.h> 95*0Sstevel@tonic-gate #include <string.h> 96*0Sstevel@tonic-gate #include <openssl/crypto.h> 97*0Sstevel@tonic-gate #include <openssl/err.h> 98*0Sstevel@tonic-gate #include <openssl/rand.h> 99*0Sstevel@tonic-gate 100*0Sstevel@tonic-gate #if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX) 101*0Sstevel@tonic-gate #define TIMES 102*0Sstevel@tonic-gate #endif 103*0Sstevel@tonic-gate 104*0Sstevel@tonic-gate #ifndef _IRIX 105*0Sstevel@tonic-gate #include <time.h> 106*0Sstevel@tonic-gate #endif 107*0Sstevel@tonic-gate #ifdef TIMES 108*0Sstevel@tonic-gate #include <sys/types.h> 109*0Sstevel@tonic-gate #include <sys/times.h> 110*0Sstevel@tonic-gate #endif 111*0Sstevel@tonic-gate 112*0Sstevel@tonic-gate /* Depending on the VMS version, the tms structure is perhaps defined. 113*0Sstevel@tonic-gate The __TMS macro will show if it was. If it wasn't defined, we should 114*0Sstevel@tonic-gate undefine TIMES, since that tells the rest of the program how things 115*0Sstevel@tonic-gate should be handled. -- Richard Levitte */ 116*0Sstevel@tonic-gate #if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS) 117*0Sstevel@tonic-gate #undef TIMES 118*0Sstevel@tonic-gate #endif 119*0Sstevel@tonic-gate 120*0Sstevel@tonic-gate #ifndef TIMES 121*0Sstevel@tonic-gate #include <sys/timeb.h> 122*0Sstevel@tonic-gate #endif 123*0Sstevel@tonic-gate 124*0Sstevel@tonic-gate #if defined(sun) || defined(__ultrix) 125*0Sstevel@tonic-gate #define _POSIX_SOURCE 126*0Sstevel@tonic-gate #include <limits.h> 127*0Sstevel@tonic-gate #include <sys/param.h> 128*0Sstevel@tonic-gate #endif 129*0Sstevel@tonic-gate 130*0Sstevel@tonic-gate #include <openssl/bn.h> 131*0Sstevel@tonic-gate #include <openssl/x509.h> 132*0Sstevel@tonic-gate 133*0Sstevel@tonic-gate /* The following if from times(3) man page. It may need to be changed */ 134*0Sstevel@tonic-gate #ifndef HZ 135*0Sstevel@tonic-gate # ifndef CLK_TCK 136*0Sstevel@tonic-gate # ifndef _BSD_CLK_TCK_ /* FreeBSD hack */ 137*0Sstevel@tonic-gate # define HZ 100.0 138*0Sstevel@tonic-gate # else /* _BSD_CLK_TCK_ */ 139*0Sstevel@tonic-gate # define HZ ((double)_BSD_CLK_TCK_) 140*0Sstevel@tonic-gate # endif 141*0Sstevel@tonic-gate # else /* CLK_TCK */ 142*0Sstevel@tonic-gate # define HZ ((double)CLK_TCK) 143*0Sstevel@tonic-gate # endif 144*0Sstevel@tonic-gate #endif 145*0Sstevel@tonic-gate 146*0Sstevel@tonic-gate #undef BUFSIZE 147*0Sstevel@tonic-gate #define BUFSIZE ((long)1024*8) 148*0Sstevel@tonic-gate int run=0; 149*0Sstevel@tonic-gate 150*0Sstevel@tonic-gate static double Time_F(int s); 151*0Sstevel@tonic-gate #define START 0 152*0Sstevel@tonic-gate #define STOP 1 153*0Sstevel@tonic-gate 154*0Sstevel@tonic-gate static double Time_F(int s) 155*0Sstevel@tonic-gate { 156*0Sstevel@tonic-gate double ret; 157*0Sstevel@tonic-gate #ifdef TIMES 158*0Sstevel@tonic-gate static struct tms tstart,tend; 159*0Sstevel@tonic-gate 160*0Sstevel@tonic-gate if (s == START) 161*0Sstevel@tonic-gate { 162*0Sstevel@tonic-gate times(&tstart); 163*0Sstevel@tonic-gate return(0); 164*0Sstevel@tonic-gate } 165*0Sstevel@tonic-gate else 166*0Sstevel@tonic-gate { 167*0Sstevel@tonic-gate times(&tend); 168*0Sstevel@tonic-gate ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ; 169*0Sstevel@tonic-gate return((ret < 1e-3)?1e-3:ret); 170*0Sstevel@tonic-gate } 171*0Sstevel@tonic-gate #else /* !times() */ 172*0Sstevel@tonic-gate static struct timeb tstart,tend; 173*0Sstevel@tonic-gate long i; 174*0Sstevel@tonic-gate 175*0Sstevel@tonic-gate if (s == START) 176*0Sstevel@tonic-gate { 177*0Sstevel@tonic-gate ftime(&tstart); 178*0Sstevel@tonic-gate return(0); 179*0Sstevel@tonic-gate } 180*0Sstevel@tonic-gate else 181*0Sstevel@tonic-gate { 182*0Sstevel@tonic-gate ftime(&tend); 183*0Sstevel@tonic-gate i=(long)tend.millitm-(long)tstart.millitm; 184*0Sstevel@tonic-gate ret=((double)(tend.time-tstart.time))+((double)i)/1000.0; 185*0Sstevel@tonic-gate return((ret < 0.001)?0.001:ret); 186*0Sstevel@tonic-gate } 187*0Sstevel@tonic-gate #endif 188*0Sstevel@tonic-gate } 189*0Sstevel@tonic-gate 190*0Sstevel@tonic-gate #define NUM_SIZES 7 191*0Sstevel@tonic-gate #if NUM_START > NUM_SIZES 192*0Sstevel@tonic-gate # error "NUM_START > NUM_SIZES" 193*0Sstevel@tonic-gate #endif 194*0Sstevel@tonic-gate static int sizes[NUM_SIZES]={128,256,512,1024,2048,4096,8192}; 195*0Sstevel@tonic-gate static int mul_c[NUM_SIZES]={8*8*8*8*8*8,8*8*8*8*8,8*8*8*8,8*8*8,8*8,8,1}; 196*0Sstevel@tonic-gate /*static int sizes[NUM_SIZES]={59,179,299,419,539}; */ 197*0Sstevel@tonic-gate 198*0Sstevel@tonic-gate #define RAND_SEED(string) { const char str[] = string; RAND_seed(string, sizeof str); } 199*0Sstevel@tonic-gate 200*0Sstevel@tonic-gate void do_mul_exp(BIGNUM *r,BIGNUM *a,BIGNUM *b,BIGNUM *c,BN_CTX *ctx); 201*0Sstevel@tonic-gate 202*0Sstevel@tonic-gate int main(int argc, char **argv) 203*0Sstevel@tonic-gate { 204*0Sstevel@tonic-gate BN_CTX *ctx; 205*0Sstevel@tonic-gate BIGNUM *a,*b,*c,*r; 206*0Sstevel@tonic-gate 207*0Sstevel@tonic-gate #if 1 208*0Sstevel@tonic-gate if (!CRYPTO_set_mem_debug_functions(0,0,0,0,0)) 209*0Sstevel@tonic-gate abort(); 210*0Sstevel@tonic-gate #endif 211*0Sstevel@tonic-gate 212*0Sstevel@tonic-gate ctx=BN_CTX_new(); 213*0Sstevel@tonic-gate a=BN_new(); 214*0Sstevel@tonic-gate b=BN_new(); 215*0Sstevel@tonic-gate c=BN_new(); 216*0Sstevel@tonic-gate r=BN_new(); 217*0Sstevel@tonic-gate 218*0Sstevel@tonic-gate while (!RAND_status()) 219*0Sstevel@tonic-gate /* not enough bits */ 220*0Sstevel@tonic-gate RAND_SEED("I demand a manual recount!"); 221*0Sstevel@tonic-gate 222*0Sstevel@tonic-gate do_mul_exp(r,a,b,c,ctx); 223*0Sstevel@tonic-gate return 0; 224*0Sstevel@tonic-gate } 225*0Sstevel@tonic-gate 226*0Sstevel@tonic-gate void do_mul_exp(BIGNUM *r, BIGNUM *a, BIGNUM *b, BIGNUM *c, BN_CTX *ctx) 227*0Sstevel@tonic-gate { 228*0Sstevel@tonic-gate int i,k; 229*0Sstevel@tonic-gate double tm; 230*0Sstevel@tonic-gate long num; 231*0Sstevel@tonic-gate 232*0Sstevel@tonic-gate num=BASENUM; 233*0Sstevel@tonic-gate for (i=NUM_START; i<NUM_SIZES; i++) 234*0Sstevel@tonic-gate { 235*0Sstevel@tonic-gate #ifdef C_PRIME 236*0Sstevel@tonic-gate # ifdef TEST_SQRT 237*0Sstevel@tonic-gate if (!BN_set_word(a, 64)) goto err; 238*0Sstevel@tonic-gate if (!BN_set_word(b, P_MOD_64)) goto err; 239*0Sstevel@tonic-gate # define ADD a 240*0Sstevel@tonic-gate # define REM b 241*0Sstevel@tonic-gate # else 242*0Sstevel@tonic-gate # define ADD NULL 243*0Sstevel@tonic-gate # define REM NULL 244*0Sstevel@tonic-gate # endif 245*0Sstevel@tonic-gate if (!BN_generate_prime(c,sizes[i],0,ADD,REM,genprime_cb,NULL)) goto err; 246*0Sstevel@tonic-gate putc('\n', stderr); 247*0Sstevel@tonic-gate fflush(stderr); 248*0Sstevel@tonic-gate #endif 249*0Sstevel@tonic-gate 250*0Sstevel@tonic-gate for (k=0; k<num; k++) 251*0Sstevel@tonic-gate { 252*0Sstevel@tonic-gate if (k%50 == 0) /* Average over num/50 different choices of random numbers. */ 253*0Sstevel@tonic-gate { 254*0Sstevel@tonic-gate if (!BN_pseudo_rand(a,sizes[i],1,0)) goto err; 255*0Sstevel@tonic-gate 256*0Sstevel@tonic-gate if (!BN_pseudo_rand(b,sizes[i],1,0)) goto err; 257*0Sstevel@tonic-gate 258*0Sstevel@tonic-gate #ifndef C_PRIME 259*0Sstevel@tonic-gate if (!BN_pseudo_rand(c,sizes[i],1,1)) goto err; 260*0Sstevel@tonic-gate #endif 261*0Sstevel@tonic-gate 262*0Sstevel@tonic-gate #ifdef TEST_SQRT 263*0Sstevel@tonic-gate if (!BN_mod_sqr(a,a,c,ctx)) goto err; 264*0Sstevel@tonic-gate if (!BN_mod_sqr(b,b,c,ctx)) goto err; 265*0Sstevel@tonic-gate #else 266*0Sstevel@tonic-gate if (!BN_nnmod(a,a,c,ctx)) goto err; 267*0Sstevel@tonic-gate if (!BN_nnmod(b,b,c,ctx)) goto err; 268*0Sstevel@tonic-gate #endif 269*0Sstevel@tonic-gate 270*0Sstevel@tonic-gate if (k == 0) 271*0Sstevel@tonic-gate Time_F(START); 272*0Sstevel@tonic-gate } 273*0Sstevel@tonic-gate 274*0Sstevel@tonic-gate #if defined(TEST_EXP) 275*0Sstevel@tonic-gate if (!BN_mod_exp(r,a,b,c,ctx)) goto err; 276*0Sstevel@tonic-gate #elif defined(TEST_MUL) 277*0Sstevel@tonic-gate { 278*0Sstevel@tonic-gate int i = 0; 279*0Sstevel@tonic-gate for (i = 0; i < 50; i++) 280*0Sstevel@tonic-gate if (!BN_mod_mul(r,a,b,c,ctx)) goto err; 281*0Sstevel@tonic-gate } 282*0Sstevel@tonic-gate #elif defined(TEST_SQR) 283*0Sstevel@tonic-gate { 284*0Sstevel@tonic-gate int i = 0; 285*0Sstevel@tonic-gate for (i = 0; i < 50; i++) 286*0Sstevel@tonic-gate { 287*0Sstevel@tonic-gate if (!BN_mod_sqr(r,a,c,ctx)) goto err; 288*0Sstevel@tonic-gate if (!BN_mod_sqr(r,b,c,ctx)) goto err; 289*0Sstevel@tonic-gate } 290*0Sstevel@tonic-gate } 291*0Sstevel@tonic-gate #elif defined(TEST_GCD) 292*0Sstevel@tonic-gate if (!BN_gcd(r,a,b,ctx)) goto err; 293*0Sstevel@tonic-gate if (!BN_gcd(r,b,c,ctx)) goto err; 294*0Sstevel@tonic-gate if (!BN_gcd(r,c,a,ctx)) goto err; 295*0Sstevel@tonic-gate #elif defined(TEST_KRON) 296*0Sstevel@tonic-gate if (-2 == BN_kronecker(a,b,ctx)) goto err; 297*0Sstevel@tonic-gate if (-2 == BN_kronecker(b,c,ctx)) goto err; 298*0Sstevel@tonic-gate if (-2 == BN_kronecker(c,a,ctx)) goto err; 299*0Sstevel@tonic-gate #elif defined(TEST_INV) 300*0Sstevel@tonic-gate if (!BN_mod_inverse(r,a,c,ctx)) goto err; 301*0Sstevel@tonic-gate if (!BN_mod_inverse(r,b,c,ctx)) goto err; 302*0Sstevel@tonic-gate #else /* TEST_SQRT */ 303*0Sstevel@tonic-gate if (!BN_mod_sqrt(r,a,c,ctx)) goto err; 304*0Sstevel@tonic-gate if (!BN_mod_sqrt(r,b,c,ctx)) goto err; 305*0Sstevel@tonic-gate #endif 306*0Sstevel@tonic-gate } 307*0Sstevel@tonic-gate tm=Time_F(STOP); 308*0Sstevel@tonic-gate printf( 309*0Sstevel@tonic-gate #if defined(TEST_EXP) 310*0Sstevel@tonic-gate "modexp %4d ^ %4d %% %4d" 311*0Sstevel@tonic-gate #elif defined(TEST_MUL) 312*0Sstevel@tonic-gate "50*modmul %4d %4d %4d" 313*0Sstevel@tonic-gate #elif defined(TEST_SQR) 314*0Sstevel@tonic-gate "100*modsqr %4d %4d %4d" 315*0Sstevel@tonic-gate #elif defined(TEST_GCD) 316*0Sstevel@tonic-gate "3*gcd %4d %4d %4d" 317*0Sstevel@tonic-gate #elif defined(TEST_KRON) 318*0Sstevel@tonic-gate "3*kronecker %4d %4d %4d" 319*0Sstevel@tonic-gate #elif defined(TEST_INV) 320*0Sstevel@tonic-gate "2*inv %4d %4d mod %4d" 321*0Sstevel@tonic-gate #else /* TEST_SQRT */ 322*0Sstevel@tonic-gate "2*sqrt [prime == %d (mod 64)] %4d %4d mod %4d" 323*0Sstevel@tonic-gate #endif 324*0Sstevel@tonic-gate " -> %8.3fms %5.1f (%ld)\n", 325*0Sstevel@tonic-gate #ifdef TEST_SQRT 326*0Sstevel@tonic-gate P_MOD_64, 327*0Sstevel@tonic-gate #endif 328*0Sstevel@tonic-gate sizes[i],sizes[i],sizes[i],tm*1000.0/num,tm*mul_c[i]/num, num); 329*0Sstevel@tonic-gate num/=7; 330*0Sstevel@tonic-gate if (num <= 0) num=1; 331*0Sstevel@tonic-gate } 332*0Sstevel@tonic-gate return; 333*0Sstevel@tonic-gate 334*0Sstevel@tonic-gate err: 335*0Sstevel@tonic-gate ERR_print_errors_fp(stderr); 336*0Sstevel@tonic-gate } 337*0Sstevel@tonic-gate 338*0Sstevel@tonic-gate 339*0Sstevel@tonic-gate #ifdef C_PRIME 340*0Sstevel@tonic-gate static void genprime_cb(int p, int n, void *arg) 341*0Sstevel@tonic-gate { 342*0Sstevel@tonic-gate char c='*'; 343*0Sstevel@tonic-gate 344*0Sstevel@tonic-gate if (p == 0) c='.'; 345*0Sstevel@tonic-gate if (p == 1) c='+'; 346*0Sstevel@tonic-gate if (p == 2) c='*'; 347*0Sstevel@tonic-gate if (p == 3) c='\n'; 348*0Sstevel@tonic-gate putc(c, stderr); 349*0Sstevel@tonic-gate fflush(stderr); 350*0Sstevel@tonic-gate (void)n; 351*0Sstevel@tonic-gate (void)arg; 352*0Sstevel@tonic-gate } 353*0Sstevel@tonic-gate #endif 354