1*0Sstevel@tonic-gate /* crypto/bn/bntest.c */ 2*0Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3*0Sstevel@tonic-gate * All rights reserved. 4*0Sstevel@tonic-gate * 5*0Sstevel@tonic-gate * This package is an SSL implementation written 6*0Sstevel@tonic-gate * by Eric Young (eay@cryptsoft.com). 7*0Sstevel@tonic-gate * The implementation was written so as to conform with Netscapes SSL. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * This library is free for commercial and non-commercial use as long as 10*0Sstevel@tonic-gate * the following conditions are aheared to. The following conditions 11*0Sstevel@tonic-gate * apply to all code found in this distribution, be it the RC4, RSA, 12*0Sstevel@tonic-gate * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13*0Sstevel@tonic-gate * included with this distribution is covered by the same copyright terms 14*0Sstevel@tonic-gate * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15*0Sstevel@tonic-gate * 16*0Sstevel@tonic-gate * Copyright remains Eric Young's, and as such any Copyright notices in 17*0Sstevel@tonic-gate * the code are not to be removed. 18*0Sstevel@tonic-gate * If this package is used in a product, Eric Young should be given attribution 19*0Sstevel@tonic-gate * as the author of the parts of the library used. 20*0Sstevel@tonic-gate * This can be in the form of a textual message at program startup or 21*0Sstevel@tonic-gate * in documentation (online or textual) provided with the package. 22*0Sstevel@tonic-gate * 23*0Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 24*0Sstevel@tonic-gate * modification, are permitted provided that the following conditions 25*0Sstevel@tonic-gate * are met: 26*0Sstevel@tonic-gate * 1. Redistributions of source code must retain the copyright 27*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 28*0Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 29*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the 30*0Sstevel@tonic-gate * documentation and/or other materials provided with the distribution. 31*0Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software 32*0Sstevel@tonic-gate * must display the following acknowledgement: 33*0Sstevel@tonic-gate * "This product includes cryptographic software written by 34*0Sstevel@tonic-gate * Eric Young (eay@cryptsoft.com)" 35*0Sstevel@tonic-gate * The word 'cryptographic' can be left out if the rouines from the library 36*0Sstevel@tonic-gate * being used are not cryptographic related :-). 37*0Sstevel@tonic-gate * 4. If you include any Windows specific code (or a derivative thereof) from 38*0Sstevel@tonic-gate * the apps directory (application code) you must include an acknowledgement: 39*0Sstevel@tonic-gate * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40*0Sstevel@tonic-gate * 41*0Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42*0Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43*0Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44*0Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45*0Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46*0Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47*0Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48*0Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49*0Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50*0Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51*0Sstevel@tonic-gate * SUCH DAMAGE. 52*0Sstevel@tonic-gate * 53*0Sstevel@tonic-gate * The licence and distribution terms for any publically available version or 54*0Sstevel@tonic-gate * derivative of this code cannot be changed. i.e. this code cannot simply be 55*0Sstevel@tonic-gate * copied and put under another distribution licence 56*0Sstevel@tonic-gate * [including the GNU Public Licence.] 57*0Sstevel@tonic-gate */ 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate #include <stdio.h> 60*0Sstevel@tonic-gate #include <stdlib.h> 61*0Sstevel@tonic-gate #include <string.h> 62*0Sstevel@tonic-gate 63*0Sstevel@tonic-gate #include "e_os.h" 64*0Sstevel@tonic-gate 65*0Sstevel@tonic-gate #include <openssl/bio.h> 66*0Sstevel@tonic-gate #include <openssl/bn.h> 67*0Sstevel@tonic-gate #include <openssl/rand.h> 68*0Sstevel@tonic-gate #include <openssl/x509.h> 69*0Sstevel@tonic-gate #include <openssl/err.h> 70*0Sstevel@tonic-gate 71*0Sstevel@tonic-gate const int num0 = 100; /* number of tests */ 72*0Sstevel@tonic-gate const int num1 = 50; /* additional tests for some functions */ 73*0Sstevel@tonic-gate const int num2 = 5; /* number of tests for slow functions */ 74*0Sstevel@tonic-gate 75*0Sstevel@tonic-gate int test_add(BIO *bp); 76*0Sstevel@tonic-gate int test_sub(BIO *bp); 77*0Sstevel@tonic-gate int test_lshift1(BIO *bp); 78*0Sstevel@tonic-gate int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_); 79*0Sstevel@tonic-gate int test_rshift1(BIO *bp); 80*0Sstevel@tonic-gate int test_rshift(BIO *bp,BN_CTX *ctx); 81*0Sstevel@tonic-gate int test_div(BIO *bp,BN_CTX *ctx); 82*0Sstevel@tonic-gate int test_div_recp(BIO *bp,BN_CTX *ctx); 83*0Sstevel@tonic-gate int test_mul(BIO *bp); 84*0Sstevel@tonic-gate int test_sqr(BIO *bp,BN_CTX *ctx); 85*0Sstevel@tonic-gate int test_mont(BIO *bp,BN_CTX *ctx); 86*0Sstevel@tonic-gate int test_mod(BIO *bp,BN_CTX *ctx); 87*0Sstevel@tonic-gate int test_mod_mul(BIO *bp,BN_CTX *ctx); 88*0Sstevel@tonic-gate int test_mod_exp(BIO *bp,BN_CTX *ctx); 89*0Sstevel@tonic-gate int test_exp(BIO *bp,BN_CTX *ctx); 90*0Sstevel@tonic-gate int test_kron(BIO *bp,BN_CTX *ctx); 91*0Sstevel@tonic-gate int test_sqrt(BIO *bp,BN_CTX *ctx); 92*0Sstevel@tonic-gate int rand_neg(void); 93*0Sstevel@tonic-gate static int results=0; 94*0Sstevel@tonic-gate 95*0Sstevel@tonic-gate static unsigned char lst[]="\xC6\x4F\x43\x04\x2A\xEA\xCA\x6E\x58\x36\x80\x5B\xE8\xC9" 96*0Sstevel@tonic-gate "\x9B\x04\x5D\x48\x36\xC2\xFD\x16\xC9\x64\xF0"; 97*0Sstevel@tonic-gate 98*0Sstevel@tonic-gate static const char rnd_seed[] = "string to make the random number generator think it has entropy"; 99*0Sstevel@tonic-gate 100*0Sstevel@tonic-gate static void message(BIO *out, char *m) 101*0Sstevel@tonic-gate { 102*0Sstevel@tonic-gate fprintf(stderr, "test %s\n", m); 103*0Sstevel@tonic-gate BIO_puts(out, "print \"test "); 104*0Sstevel@tonic-gate BIO_puts(out, m); 105*0Sstevel@tonic-gate BIO_puts(out, "\\n\"\n"); 106*0Sstevel@tonic-gate } 107*0Sstevel@tonic-gate 108*0Sstevel@tonic-gate int main(int argc, char *argv[]) 109*0Sstevel@tonic-gate { 110*0Sstevel@tonic-gate BN_CTX *ctx; 111*0Sstevel@tonic-gate BIO *out; 112*0Sstevel@tonic-gate char *outfile=NULL; 113*0Sstevel@tonic-gate 114*0Sstevel@tonic-gate results = 0; 115*0Sstevel@tonic-gate 116*0Sstevel@tonic-gate RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */ 117*0Sstevel@tonic-gate 118*0Sstevel@tonic-gate argc--; 119*0Sstevel@tonic-gate argv++; 120*0Sstevel@tonic-gate while (argc >= 1) 121*0Sstevel@tonic-gate { 122*0Sstevel@tonic-gate if (strcmp(*argv,"-results") == 0) 123*0Sstevel@tonic-gate results=1; 124*0Sstevel@tonic-gate else if (strcmp(*argv,"-out") == 0) 125*0Sstevel@tonic-gate { 126*0Sstevel@tonic-gate if (--argc < 1) break; 127*0Sstevel@tonic-gate outfile= *(++argv); 128*0Sstevel@tonic-gate } 129*0Sstevel@tonic-gate argc--; 130*0Sstevel@tonic-gate argv++; 131*0Sstevel@tonic-gate } 132*0Sstevel@tonic-gate 133*0Sstevel@tonic-gate 134*0Sstevel@tonic-gate ctx=BN_CTX_new(); 135*0Sstevel@tonic-gate if (ctx == NULL) EXIT(1); 136*0Sstevel@tonic-gate 137*0Sstevel@tonic-gate out=BIO_new(BIO_s_file()); 138*0Sstevel@tonic-gate if (out == NULL) EXIT(1); 139*0Sstevel@tonic-gate if (outfile == NULL) 140*0Sstevel@tonic-gate { 141*0Sstevel@tonic-gate BIO_set_fp(out,stdout,BIO_NOCLOSE); 142*0Sstevel@tonic-gate } 143*0Sstevel@tonic-gate else 144*0Sstevel@tonic-gate { 145*0Sstevel@tonic-gate if (!BIO_write_filename(out,outfile)) 146*0Sstevel@tonic-gate { 147*0Sstevel@tonic-gate perror(outfile); 148*0Sstevel@tonic-gate EXIT(1); 149*0Sstevel@tonic-gate } 150*0Sstevel@tonic-gate } 151*0Sstevel@tonic-gate 152*0Sstevel@tonic-gate if (!results) 153*0Sstevel@tonic-gate BIO_puts(out,"obase=16\nibase=16\n"); 154*0Sstevel@tonic-gate 155*0Sstevel@tonic-gate message(out,"BN_add"); 156*0Sstevel@tonic-gate if (!test_add(out)) goto err; 157*0Sstevel@tonic-gate BIO_flush(out); 158*0Sstevel@tonic-gate 159*0Sstevel@tonic-gate message(out,"BN_sub"); 160*0Sstevel@tonic-gate if (!test_sub(out)) goto err; 161*0Sstevel@tonic-gate BIO_flush(out); 162*0Sstevel@tonic-gate 163*0Sstevel@tonic-gate message(out,"BN_lshift1"); 164*0Sstevel@tonic-gate if (!test_lshift1(out)) goto err; 165*0Sstevel@tonic-gate BIO_flush(out); 166*0Sstevel@tonic-gate 167*0Sstevel@tonic-gate message(out,"BN_lshift (fixed)"); 168*0Sstevel@tonic-gate if (!test_lshift(out,ctx,BN_bin2bn(lst,sizeof(lst)-1,NULL))) 169*0Sstevel@tonic-gate goto err; 170*0Sstevel@tonic-gate BIO_flush(out); 171*0Sstevel@tonic-gate 172*0Sstevel@tonic-gate message(out,"BN_lshift"); 173*0Sstevel@tonic-gate if (!test_lshift(out,ctx,NULL)) goto err; 174*0Sstevel@tonic-gate BIO_flush(out); 175*0Sstevel@tonic-gate 176*0Sstevel@tonic-gate message(out,"BN_rshift1"); 177*0Sstevel@tonic-gate if (!test_rshift1(out)) goto err; 178*0Sstevel@tonic-gate BIO_flush(out); 179*0Sstevel@tonic-gate 180*0Sstevel@tonic-gate message(out,"BN_rshift"); 181*0Sstevel@tonic-gate if (!test_rshift(out,ctx)) goto err; 182*0Sstevel@tonic-gate BIO_flush(out); 183*0Sstevel@tonic-gate 184*0Sstevel@tonic-gate message(out,"BN_sqr"); 185*0Sstevel@tonic-gate if (!test_sqr(out,ctx)) goto err; 186*0Sstevel@tonic-gate BIO_flush(out); 187*0Sstevel@tonic-gate 188*0Sstevel@tonic-gate message(out,"BN_mul"); 189*0Sstevel@tonic-gate if (!test_mul(out)) goto err; 190*0Sstevel@tonic-gate BIO_flush(out); 191*0Sstevel@tonic-gate 192*0Sstevel@tonic-gate message(out,"BN_div"); 193*0Sstevel@tonic-gate if (!test_div(out,ctx)) goto err; 194*0Sstevel@tonic-gate BIO_flush(out); 195*0Sstevel@tonic-gate 196*0Sstevel@tonic-gate message(out,"BN_div_recp"); 197*0Sstevel@tonic-gate if (!test_div_recp(out,ctx)) goto err; 198*0Sstevel@tonic-gate BIO_flush(out); 199*0Sstevel@tonic-gate 200*0Sstevel@tonic-gate message(out,"BN_mod"); 201*0Sstevel@tonic-gate if (!test_mod(out,ctx)) goto err; 202*0Sstevel@tonic-gate BIO_flush(out); 203*0Sstevel@tonic-gate 204*0Sstevel@tonic-gate message(out,"BN_mod_mul"); 205*0Sstevel@tonic-gate if (!test_mod_mul(out,ctx)) goto err; 206*0Sstevel@tonic-gate BIO_flush(out); 207*0Sstevel@tonic-gate 208*0Sstevel@tonic-gate message(out,"BN_mont"); 209*0Sstevel@tonic-gate if (!test_mont(out,ctx)) goto err; 210*0Sstevel@tonic-gate BIO_flush(out); 211*0Sstevel@tonic-gate 212*0Sstevel@tonic-gate message(out,"BN_mod_exp"); 213*0Sstevel@tonic-gate if (!test_mod_exp(out,ctx)) goto err; 214*0Sstevel@tonic-gate BIO_flush(out); 215*0Sstevel@tonic-gate 216*0Sstevel@tonic-gate message(out,"BN_exp"); 217*0Sstevel@tonic-gate if (!test_exp(out,ctx)) goto err; 218*0Sstevel@tonic-gate BIO_flush(out); 219*0Sstevel@tonic-gate 220*0Sstevel@tonic-gate message(out,"BN_kronecker"); 221*0Sstevel@tonic-gate if (!test_kron(out,ctx)) goto err; 222*0Sstevel@tonic-gate BIO_flush(out); 223*0Sstevel@tonic-gate 224*0Sstevel@tonic-gate message(out,"BN_mod_sqrt"); 225*0Sstevel@tonic-gate if (!test_sqrt(out,ctx)) goto err; 226*0Sstevel@tonic-gate BIO_flush(out); 227*0Sstevel@tonic-gate 228*0Sstevel@tonic-gate BN_CTX_free(ctx); 229*0Sstevel@tonic-gate BIO_free(out); 230*0Sstevel@tonic-gate 231*0Sstevel@tonic-gate /**/ 232*0Sstevel@tonic-gate EXIT(0); 233*0Sstevel@tonic-gate err: 234*0Sstevel@tonic-gate BIO_puts(out,"1\n"); /* make sure the Perl script fed by bc notices 235*0Sstevel@tonic-gate * the failure, see test_bn in test/Makefile.ssl*/ 236*0Sstevel@tonic-gate BIO_flush(out); 237*0Sstevel@tonic-gate ERR_load_crypto_strings(); 238*0Sstevel@tonic-gate ERR_print_errors_fp(stderr); 239*0Sstevel@tonic-gate EXIT(1); 240*0Sstevel@tonic-gate return(1); 241*0Sstevel@tonic-gate } 242*0Sstevel@tonic-gate 243*0Sstevel@tonic-gate int test_add(BIO *bp) 244*0Sstevel@tonic-gate { 245*0Sstevel@tonic-gate BIGNUM a,b,c; 246*0Sstevel@tonic-gate int i; 247*0Sstevel@tonic-gate 248*0Sstevel@tonic-gate BN_init(&a); 249*0Sstevel@tonic-gate BN_init(&b); 250*0Sstevel@tonic-gate BN_init(&c); 251*0Sstevel@tonic-gate 252*0Sstevel@tonic-gate BN_bntest_rand(&a,512,0,0); 253*0Sstevel@tonic-gate for (i=0; i<num0; i++) 254*0Sstevel@tonic-gate { 255*0Sstevel@tonic-gate BN_bntest_rand(&b,450+i,0,0); 256*0Sstevel@tonic-gate a.neg=rand_neg(); 257*0Sstevel@tonic-gate b.neg=rand_neg(); 258*0Sstevel@tonic-gate BN_add(&c,&a,&b); 259*0Sstevel@tonic-gate if (bp != NULL) 260*0Sstevel@tonic-gate { 261*0Sstevel@tonic-gate if (!results) 262*0Sstevel@tonic-gate { 263*0Sstevel@tonic-gate BN_print(bp,&a); 264*0Sstevel@tonic-gate BIO_puts(bp," + "); 265*0Sstevel@tonic-gate BN_print(bp,&b); 266*0Sstevel@tonic-gate BIO_puts(bp," - "); 267*0Sstevel@tonic-gate } 268*0Sstevel@tonic-gate BN_print(bp,&c); 269*0Sstevel@tonic-gate BIO_puts(bp,"\n"); 270*0Sstevel@tonic-gate } 271*0Sstevel@tonic-gate a.neg=!a.neg; 272*0Sstevel@tonic-gate b.neg=!b.neg; 273*0Sstevel@tonic-gate BN_add(&c,&c,&b); 274*0Sstevel@tonic-gate BN_add(&c,&c,&a); 275*0Sstevel@tonic-gate if(!BN_is_zero(&c)) 276*0Sstevel@tonic-gate { 277*0Sstevel@tonic-gate fprintf(stderr,"Add test failed!\n"); 278*0Sstevel@tonic-gate return 0; 279*0Sstevel@tonic-gate } 280*0Sstevel@tonic-gate } 281*0Sstevel@tonic-gate BN_free(&a); 282*0Sstevel@tonic-gate BN_free(&b); 283*0Sstevel@tonic-gate BN_free(&c); 284*0Sstevel@tonic-gate return(1); 285*0Sstevel@tonic-gate } 286*0Sstevel@tonic-gate 287*0Sstevel@tonic-gate int test_sub(BIO *bp) 288*0Sstevel@tonic-gate { 289*0Sstevel@tonic-gate BIGNUM a,b,c; 290*0Sstevel@tonic-gate int i; 291*0Sstevel@tonic-gate 292*0Sstevel@tonic-gate BN_init(&a); 293*0Sstevel@tonic-gate BN_init(&b); 294*0Sstevel@tonic-gate BN_init(&c); 295*0Sstevel@tonic-gate 296*0Sstevel@tonic-gate for (i=0; i<num0+num1; i++) 297*0Sstevel@tonic-gate { 298*0Sstevel@tonic-gate if (i < num1) 299*0Sstevel@tonic-gate { 300*0Sstevel@tonic-gate BN_bntest_rand(&a,512,0,0); 301*0Sstevel@tonic-gate BN_copy(&b,&a); 302*0Sstevel@tonic-gate if (BN_set_bit(&a,i)==0) return(0); 303*0Sstevel@tonic-gate BN_add_word(&b,i); 304*0Sstevel@tonic-gate } 305*0Sstevel@tonic-gate else 306*0Sstevel@tonic-gate { 307*0Sstevel@tonic-gate BN_bntest_rand(&b,400+i-num1,0,0); 308*0Sstevel@tonic-gate a.neg=rand_neg(); 309*0Sstevel@tonic-gate b.neg=rand_neg(); 310*0Sstevel@tonic-gate } 311*0Sstevel@tonic-gate BN_sub(&c,&a,&b); 312*0Sstevel@tonic-gate if (bp != NULL) 313*0Sstevel@tonic-gate { 314*0Sstevel@tonic-gate if (!results) 315*0Sstevel@tonic-gate { 316*0Sstevel@tonic-gate BN_print(bp,&a); 317*0Sstevel@tonic-gate BIO_puts(bp," - "); 318*0Sstevel@tonic-gate BN_print(bp,&b); 319*0Sstevel@tonic-gate BIO_puts(bp," - "); 320*0Sstevel@tonic-gate } 321*0Sstevel@tonic-gate BN_print(bp,&c); 322*0Sstevel@tonic-gate BIO_puts(bp,"\n"); 323*0Sstevel@tonic-gate } 324*0Sstevel@tonic-gate BN_add(&c,&c,&b); 325*0Sstevel@tonic-gate BN_sub(&c,&c,&a); 326*0Sstevel@tonic-gate if(!BN_is_zero(&c)) 327*0Sstevel@tonic-gate { 328*0Sstevel@tonic-gate fprintf(stderr,"Subtract test failed!\n"); 329*0Sstevel@tonic-gate return 0; 330*0Sstevel@tonic-gate } 331*0Sstevel@tonic-gate } 332*0Sstevel@tonic-gate BN_free(&a); 333*0Sstevel@tonic-gate BN_free(&b); 334*0Sstevel@tonic-gate BN_free(&c); 335*0Sstevel@tonic-gate return(1); 336*0Sstevel@tonic-gate } 337*0Sstevel@tonic-gate 338*0Sstevel@tonic-gate int test_div(BIO *bp, BN_CTX *ctx) 339*0Sstevel@tonic-gate { 340*0Sstevel@tonic-gate BIGNUM a,b,c,d,e; 341*0Sstevel@tonic-gate int i; 342*0Sstevel@tonic-gate 343*0Sstevel@tonic-gate BN_init(&a); 344*0Sstevel@tonic-gate BN_init(&b); 345*0Sstevel@tonic-gate BN_init(&c); 346*0Sstevel@tonic-gate BN_init(&d); 347*0Sstevel@tonic-gate BN_init(&e); 348*0Sstevel@tonic-gate 349*0Sstevel@tonic-gate for (i=0; i<num0+num1; i++) 350*0Sstevel@tonic-gate { 351*0Sstevel@tonic-gate if (i < num1) 352*0Sstevel@tonic-gate { 353*0Sstevel@tonic-gate BN_bntest_rand(&a,400,0,0); 354*0Sstevel@tonic-gate BN_copy(&b,&a); 355*0Sstevel@tonic-gate BN_lshift(&a,&a,i); 356*0Sstevel@tonic-gate BN_add_word(&a,i); 357*0Sstevel@tonic-gate } 358*0Sstevel@tonic-gate else 359*0Sstevel@tonic-gate BN_bntest_rand(&b,50+3*(i-num1),0,0); 360*0Sstevel@tonic-gate a.neg=rand_neg(); 361*0Sstevel@tonic-gate b.neg=rand_neg(); 362*0Sstevel@tonic-gate BN_div(&d,&c,&a,&b,ctx); 363*0Sstevel@tonic-gate if (bp != NULL) 364*0Sstevel@tonic-gate { 365*0Sstevel@tonic-gate if (!results) 366*0Sstevel@tonic-gate { 367*0Sstevel@tonic-gate BN_print(bp,&a); 368*0Sstevel@tonic-gate BIO_puts(bp," / "); 369*0Sstevel@tonic-gate BN_print(bp,&b); 370*0Sstevel@tonic-gate BIO_puts(bp," - "); 371*0Sstevel@tonic-gate } 372*0Sstevel@tonic-gate BN_print(bp,&d); 373*0Sstevel@tonic-gate BIO_puts(bp,"\n"); 374*0Sstevel@tonic-gate 375*0Sstevel@tonic-gate if (!results) 376*0Sstevel@tonic-gate { 377*0Sstevel@tonic-gate BN_print(bp,&a); 378*0Sstevel@tonic-gate BIO_puts(bp," % "); 379*0Sstevel@tonic-gate BN_print(bp,&b); 380*0Sstevel@tonic-gate BIO_puts(bp," - "); 381*0Sstevel@tonic-gate } 382*0Sstevel@tonic-gate BN_print(bp,&c); 383*0Sstevel@tonic-gate BIO_puts(bp,"\n"); 384*0Sstevel@tonic-gate } 385*0Sstevel@tonic-gate BN_mul(&e,&d,&b,ctx); 386*0Sstevel@tonic-gate BN_add(&d,&e,&c); 387*0Sstevel@tonic-gate BN_sub(&d,&d,&a); 388*0Sstevel@tonic-gate if(!BN_is_zero(&d)) 389*0Sstevel@tonic-gate { 390*0Sstevel@tonic-gate fprintf(stderr,"Division test failed!\n"); 391*0Sstevel@tonic-gate return 0; 392*0Sstevel@tonic-gate } 393*0Sstevel@tonic-gate } 394*0Sstevel@tonic-gate BN_free(&a); 395*0Sstevel@tonic-gate BN_free(&b); 396*0Sstevel@tonic-gate BN_free(&c); 397*0Sstevel@tonic-gate BN_free(&d); 398*0Sstevel@tonic-gate BN_free(&e); 399*0Sstevel@tonic-gate return(1); 400*0Sstevel@tonic-gate } 401*0Sstevel@tonic-gate 402*0Sstevel@tonic-gate int test_div_recp(BIO *bp, BN_CTX *ctx) 403*0Sstevel@tonic-gate { 404*0Sstevel@tonic-gate BIGNUM a,b,c,d,e; 405*0Sstevel@tonic-gate BN_RECP_CTX recp; 406*0Sstevel@tonic-gate int i; 407*0Sstevel@tonic-gate 408*0Sstevel@tonic-gate BN_RECP_CTX_init(&recp); 409*0Sstevel@tonic-gate BN_init(&a); 410*0Sstevel@tonic-gate BN_init(&b); 411*0Sstevel@tonic-gate BN_init(&c); 412*0Sstevel@tonic-gate BN_init(&d); 413*0Sstevel@tonic-gate BN_init(&e); 414*0Sstevel@tonic-gate 415*0Sstevel@tonic-gate for (i=0; i<num0+num1; i++) 416*0Sstevel@tonic-gate { 417*0Sstevel@tonic-gate if (i < num1) 418*0Sstevel@tonic-gate { 419*0Sstevel@tonic-gate BN_bntest_rand(&a,400,0,0); 420*0Sstevel@tonic-gate BN_copy(&b,&a); 421*0Sstevel@tonic-gate BN_lshift(&a,&a,i); 422*0Sstevel@tonic-gate BN_add_word(&a,i); 423*0Sstevel@tonic-gate } 424*0Sstevel@tonic-gate else 425*0Sstevel@tonic-gate BN_bntest_rand(&b,50+3*(i-num1),0,0); 426*0Sstevel@tonic-gate a.neg=rand_neg(); 427*0Sstevel@tonic-gate b.neg=rand_neg(); 428*0Sstevel@tonic-gate BN_RECP_CTX_set(&recp,&b,ctx); 429*0Sstevel@tonic-gate BN_div_recp(&d,&c,&a,&recp,ctx); 430*0Sstevel@tonic-gate if (bp != NULL) 431*0Sstevel@tonic-gate { 432*0Sstevel@tonic-gate if (!results) 433*0Sstevel@tonic-gate { 434*0Sstevel@tonic-gate BN_print(bp,&a); 435*0Sstevel@tonic-gate BIO_puts(bp," / "); 436*0Sstevel@tonic-gate BN_print(bp,&b); 437*0Sstevel@tonic-gate BIO_puts(bp," - "); 438*0Sstevel@tonic-gate } 439*0Sstevel@tonic-gate BN_print(bp,&d); 440*0Sstevel@tonic-gate BIO_puts(bp,"\n"); 441*0Sstevel@tonic-gate 442*0Sstevel@tonic-gate if (!results) 443*0Sstevel@tonic-gate { 444*0Sstevel@tonic-gate BN_print(bp,&a); 445*0Sstevel@tonic-gate BIO_puts(bp," % "); 446*0Sstevel@tonic-gate BN_print(bp,&b); 447*0Sstevel@tonic-gate BIO_puts(bp," - "); 448*0Sstevel@tonic-gate } 449*0Sstevel@tonic-gate BN_print(bp,&c); 450*0Sstevel@tonic-gate BIO_puts(bp,"\n"); 451*0Sstevel@tonic-gate } 452*0Sstevel@tonic-gate BN_mul(&e,&d,&b,ctx); 453*0Sstevel@tonic-gate BN_add(&d,&e,&c); 454*0Sstevel@tonic-gate BN_sub(&d,&d,&a); 455*0Sstevel@tonic-gate if(!BN_is_zero(&d)) 456*0Sstevel@tonic-gate { 457*0Sstevel@tonic-gate fprintf(stderr,"Reciprocal division test failed!\n"); 458*0Sstevel@tonic-gate fprintf(stderr,"a="); 459*0Sstevel@tonic-gate BN_print_fp(stderr,&a); 460*0Sstevel@tonic-gate fprintf(stderr,"\nb="); 461*0Sstevel@tonic-gate BN_print_fp(stderr,&b); 462*0Sstevel@tonic-gate fprintf(stderr,"\n"); 463*0Sstevel@tonic-gate return 0; 464*0Sstevel@tonic-gate } 465*0Sstevel@tonic-gate } 466*0Sstevel@tonic-gate BN_free(&a); 467*0Sstevel@tonic-gate BN_free(&b); 468*0Sstevel@tonic-gate BN_free(&c); 469*0Sstevel@tonic-gate BN_free(&d); 470*0Sstevel@tonic-gate BN_free(&e); 471*0Sstevel@tonic-gate BN_RECP_CTX_free(&recp); 472*0Sstevel@tonic-gate return(1); 473*0Sstevel@tonic-gate } 474*0Sstevel@tonic-gate 475*0Sstevel@tonic-gate int test_mul(BIO *bp) 476*0Sstevel@tonic-gate { 477*0Sstevel@tonic-gate BIGNUM a,b,c,d,e; 478*0Sstevel@tonic-gate int i; 479*0Sstevel@tonic-gate BN_CTX *ctx; 480*0Sstevel@tonic-gate 481*0Sstevel@tonic-gate ctx = BN_CTX_new(); 482*0Sstevel@tonic-gate if (ctx == NULL) EXIT(1); 483*0Sstevel@tonic-gate 484*0Sstevel@tonic-gate BN_init(&a); 485*0Sstevel@tonic-gate BN_init(&b); 486*0Sstevel@tonic-gate BN_init(&c); 487*0Sstevel@tonic-gate BN_init(&d); 488*0Sstevel@tonic-gate BN_init(&e); 489*0Sstevel@tonic-gate 490*0Sstevel@tonic-gate for (i=0; i<num0+num1; i++) 491*0Sstevel@tonic-gate { 492*0Sstevel@tonic-gate if (i <= num1) 493*0Sstevel@tonic-gate { 494*0Sstevel@tonic-gate BN_bntest_rand(&a,100,0,0); 495*0Sstevel@tonic-gate BN_bntest_rand(&b,100,0,0); 496*0Sstevel@tonic-gate } 497*0Sstevel@tonic-gate else 498*0Sstevel@tonic-gate BN_bntest_rand(&b,i-num1,0,0); 499*0Sstevel@tonic-gate a.neg=rand_neg(); 500*0Sstevel@tonic-gate b.neg=rand_neg(); 501*0Sstevel@tonic-gate BN_mul(&c,&a,&b,ctx); 502*0Sstevel@tonic-gate if (bp != NULL) 503*0Sstevel@tonic-gate { 504*0Sstevel@tonic-gate if (!results) 505*0Sstevel@tonic-gate { 506*0Sstevel@tonic-gate BN_print(bp,&a); 507*0Sstevel@tonic-gate BIO_puts(bp," * "); 508*0Sstevel@tonic-gate BN_print(bp,&b); 509*0Sstevel@tonic-gate BIO_puts(bp," - "); 510*0Sstevel@tonic-gate } 511*0Sstevel@tonic-gate BN_print(bp,&c); 512*0Sstevel@tonic-gate BIO_puts(bp,"\n"); 513*0Sstevel@tonic-gate } 514*0Sstevel@tonic-gate BN_div(&d,&e,&c,&a,ctx); 515*0Sstevel@tonic-gate BN_sub(&d,&d,&b); 516*0Sstevel@tonic-gate if(!BN_is_zero(&d) || !BN_is_zero(&e)) 517*0Sstevel@tonic-gate { 518*0Sstevel@tonic-gate fprintf(stderr,"Multiplication test failed!\n"); 519*0Sstevel@tonic-gate return 0; 520*0Sstevel@tonic-gate } 521*0Sstevel@tonic-gate } 522*0Sstevel@tonic-gate BN_free(&a); 523*0Sstevel@tonic-gate BN_free(&b); 524*0Sstevel@tonic-gate BN_free(&c); 525*0Sstevel@tonic-gate BN_free(&d); 526*0Sstevel@tonic-gate BN_free(&e); 527*0Sstevel@tonic-gate BN_CTX_free(ctx); 528*0Sstevel@tonic-gate return(1); 529*0Sstevel@tonic-gate } 530*0Sstevel@tonic-gate 531*0Sstevel@tonic-gate int test_sqr(BIO *bp, BN_CTX *ctx) 532*0Sstevel@tonic-gate { 533*0Sstevel@tonic-gate BIGNUM a,c,d,e; 534*0Sstevel@tonic-gate int i; 535*0Sstevel@tonic-gate 536*0Sstevel@tonic-gate BN_init(&a); 537*0Sstevel@tonic-gate BN_init(&c); 538*0Sstevel@tonic-gate BN_init(&d); 539*0Sstevel@tonic-gate BN_init(&e); 540*0Sstevel@tonic-gate 541*0Sstevel@tonic-gate for (i=0; i<num0; i++) 542*0Sstevel@tonic-gate { 543*0Sstevel@tonic-gate BN_bntest_rand(&a,40+i*10,0,0); 544*0Sstevel@tonic-gate a.neg=rand_neg(); 545*0Sstevel@tonic-gate BN_sqr(&c,&a,ctx); 546*0Sstevel@tonic-gate if (bp != NULL) 547*0Sstevel@tonic-gate { 548*0Sstevel@tonic-gate if (!results) 549*0Sstevel@tonic-gate { 550*0Sstevel@tonic-gate BN_print(bp,&a); 551*0Sstevel@tonic-gate BIO_puts(bp," * "); 552*0Sstevel@tonic-gate BN_print(bp,&a); 553*0Sstevel@tonic-gate BIO_puts(bp," - "); 554*0Sstevel@tonic-gate } 555*0Sstevel@tonic-gate BN_print(bp,&c); 556*0Sstevel@tonic-gate BIO_puts(bp,"\n"); 557*0Sstevel@tonic-gate } 558*0Sstevel@tonic-gate BN_div(&d,&e,&c,&a,ctx); 559*0Sstevel@tonic-gate BN_sub(&d,&d,&a); 560*0Sstevel@tonic-gate if(!BN_is_zero(&d) || !BN_is_zero(&e)) 561*0Sstevel@tonic-gate { 562*0Sstevel@tonic-gate fprintf(stderr,"Square test failed!\n"); 563*0Sstevel@tonic-gate return 0; 564*0Sstevel@tonic-gate } 565*0Sstevel@tonic-gate } 566*0Sstevel@tonic-gate BN_free(&a); 567*0Sstevel@tonic-gate BN_free(&c); 568*0Sstevel@tonic-gate BN_free(&d); 569*0Sstevel@tonic-gate BN_free(&e); 570*0Sstevel@tonic-gate return(1); 571*0Sstevel@tonic-gate } 572*0Sstevel@tonic-gate 573*0Sstevel@tonic-gate int test_mont(BIO *bp, BN_CTX *ctx) 574*0Sstevel@tonic-gate { 575*0Sstevel@tonic-gate BIGNUM a,b,c,d,A,B; 576*0Sstevel@tonic-gate BIGNUM n; 577*0Sstevel@tonic-gate int i; 578*0Sstevel@tonic-gate BN_MONT_CTX *mont; 579*0Sstevel@tonic-gate 580*0Sstevel@tonic-gate BN_init(&a); 581*0Sstevel@tonic-gate BN_init(&b); 582*0Sstevel@tonic-gate BN_init(&c); 583*0Sstevel@tonic-gate BN_init(&d); 584*0Sstevel@tonic-gate BN_init(&A); 585*0Sstevel@tonic-gate BN_init(&B); 586*0Sstevel@tonic-gate BN_init(&n); 587*0Sstevel@tonic-gate 588*0Sstevel@tonic-gate mont=BN_MONT_CTX_new(); 589*0Sstevel@tonic-gate 590*0Sstevel@tonic-gate BN_bntest_rand(&a,100,0,0); /**/ 591*0Sstevel@tonic-gate BN_bntest_rand(&b,100,0,0); /**/ 592*0Sstevel@tonic-gate for (i=0; i<num2; i++) 593*0Sstevel@tonic-gate { 594*0Sstevel@tonic-gate int bits = (200*(i+1))/num2; 595*0Sstevel@tonic-gate 596*0Sstevel@tonic-gate if (bits == 0) 597*0Sstevel@tonic-gate continue; 598*0Sstevel@tonic-gate BN_bntest_rand(&n,bits,0,1); 599*0Sstevel@tonic-gate BN_MONT_CTX_set(mont,&n,ctx); 600*0Sstevel@tonic-gate 601*0Sstevel@tonic-gate BN_nnmod(&a,&a,&n,ctx); 602*0Sstevel@tonic-gate BN_nnmod(&b,&b,&n,ctx); 603*0Sstevel@tonic-gate 604*0Sstevel@tonic-gate BN_to_montgomery(&A,&a,mont,ctx); 605*0Sstevel@tonic-gate BN_to_montgomery(&B,&b,mont,ctx); 606*0Sstevel@tonic-gate 607*0Sstevel@tonic-gate BN_mod_mul_montgomery(&c,&A,&B,mont,ctx);/**/ 608*0Sstevel@tonic-gate BN_from_montgomery(&A,&c,mont,ctx);/**/ 609*0Sstevel@tonic-gate if (bp != NULL) 610*0Sstevel@tonic-gate { 611*0Sstevel@tonic-gate if (!results) 612*0Sstevel@tonic-gate { 613*0Sstevel@tonic-gate #ifdef undef 614*0Sstevel@tonic-gate fprintf(stderr,"%d * %d %% %d\n", 615*0Sstevel@tonic-gate BN_num_bits(&a), 616*0Sstevel@tonic-gate BN_num_bits(&b), 617*0Sstevel@tonic-gate BN_num_bits(mont->N)); 618*0Sstevel@tonic-gate #endif 619*0Sstevel@tonic-gate BN_print(bp,&a); 620*0Sstevel@tonic-gate BIO_puts(bp," * "); 621*0Sstevel@tonic-gate BN_print(bp,&b); 622*0Sstevel@tonic-gate BIO_puts(bp," % "); 623*0Sstevel@tonic-gate BN_print(bp,&(mont->N)); 624*0Sstevel@tonic-gate BIO_puts(bp," - "); 625*0Sstevel@tonic-gate } 626*0Sstevel@tonic-gate BN_print(bp,&A); 627*0Sstevel@tonic-gate BIO_puts(bp,"\n"); 628*0Sstevel@tonic-gate } 629*0Sstevel@tonic-gate BN_mod_mul(&d,&a,&b,&n,ctx); 630*0Sstevel@tonic-gate BN_sub(&d,&d,&A); 631*0Sstevel@tonic-gate if(!BN_is_zero(&d)) 632*0Sstevel@tonic-gate { 633*0Sstevel@tonic-gate fprintf(stderr,"Montgomery multiplication test failed!\n"); 634*0Sstevel@tonic-gate return 0; 635*0Sstevel@tonic-gate } 636*0Sstevel@tonic-gate } 637*0Sstevel@tonic-gate BN_MONT_CTX_free(mont); 638*0Sstevel@tonic-gate BN_free(&a); 639*0Sstevel@tonic-gate BN_free(&b); 640*0Sstevel@tonic-gate BN_free(&c); 641*0Sstevel@tonic-gate BN_free(&d); 642*0Sstevel@tonic-gate BN_free(&A); 643*0Sstevel@tonic-gate BN_free(&B); 644*0Sstevel@tonic-gate BN_free(&n); 645*0Sstevel@tonic-gate return(1); 646*0Sstevel@tonic-gate } 647*0Sstevel@tonic-gate 648*0Sstevel@tonic-gate int test_mod(BIO *bp, BN_CTX *ctx) 649*0Sstevel@tonic-gate { 650*0Sstevel@tonic-gate BIGNUM *a,*b,*c,*d,*e; 651*0Sstevel@tonic-gate int i; 652*0Sstevel@tonic-gate 653*0Sstevel@tonic-gate a=BN_new(); 654*0Sstevel@tonic-gate b=BN_new(); 655*0Sstevel@tonic-gate c=BN_new(); 656*0Sstevel@tonic-gate d=BN_new(); 657*0Sstevel@tonic-gate e=BN_new(); 658*0Sstevel@tonic-gate 659*0Sstevel@tonic-gate BN_bntest_rand(a,1024,0,0); /**/ 660*0Sstevel@tonic-gate for (i=0; i<num0; i++) 661*0Sstevel@tonic-gate { 662*0Sstevel@tonic-gate BN_bntest_rand(b,450+i*10,0,0); /**/ 663*0Sstevel@tonic-gate a->neg=rand_neg(); 664*0Sstevel@tonic-gate b->neg=rand_neg(); 665*0Sstevel@tonic-gate BN_mod(c,a,b,ctx);/**/ 666*0Sstevel@tonic-gate if (bp != NULL) 667*0Sstevel@tonic-gate { 668*0Sstevel@tonic-gate if (!results) 669*0Sstevel@tonic-gate { 670*0Sstevel@tonic-gate BN_print(bp,a); 671*0Sstevel@tonic-gate BIO_puts(bp," % "); 672*0Sstevel@tonic-gate BN_print(bp,b); 673*0Sstevel@tonic-gate BIO_puts(bp," - "); 674*0Sstevel@tonic-gate } 675*0Sstevel@tonic-gate BN_print(bp,c); 676*0Sstevel@tonic-gate BIO_puts(bp,"\n"); 677*0Sstevel@tonic-gate } 678*0Sstevel@tonic-gate BN_div(d,e,a,b,ctx); 679*0Sstevel@tonic-gate BN_sub(e,e,c); 680*0Sstevel@tonic-gate if(!BN_is_zero(e)) 681*0Sstevel@tonic-gate { 682*0Sstevel@tonic-gate fprintf(stderr,"Modulo test failed!\n"); 683*0Sstevel@tonic-gate return 0; 684*0Sstevel@tonic-gate } 685*0Sstevel@tonic-gate } 686*0Sstevel@tonic-gate BN_free(a); 687*0Sstevel@tonic-gate BN_free(b); 688*0Sstevel@tonic-gate BN_free(c); 689*0Sstevel@tonic-gate BN_free(d); 690*0Sstevel@tonic-gate BN_free(e); 691*0Sstevel@tonic-gate return(1); 692*0Sstevel@tonic-gate } 693*0Sstevel@tonic-gate 694*0Sstevel@tonic-gate int test_mod_mul(BIO *bp, BN_CTX *ctx) 695*0Sstevel@tonic-gate { 696*0Sstevel@tonic-gate BIGNUM *a,*b,*c,*d,*e; 697*0Sstevel@tonic-gate int i,j; 698*0Sstevel@tonic-gate 699*0Sstevel@tonic-gate a=BN_new(); 700*0Sstevel@tonic-gate b=BN_new(); 701*0Sstevel@tonic-gate c=BN_new(); 702*0Sstevel@tonic-gate d=BN_new(); 703*0Sstevel@tonic-gate e=BN_new(); 704*0Sstevel@tonic-gate 705*0Sstevel@tonic-gate for (j=0; j<3; j++) { 706*0Sstevel@tonic-gate BN_bntest_rand(c,1024,0,0); /**/ 707*0Sstevel@tonic-gate for (i=0; i<num0; i++) 708*0Sstevel@tonic-gate { 709*0Sstevel@tonic-gate BN_bntest_rand(a,475+i*10,0,0); /**/ 710*0Sstevel@tonic-gate BN_bntest_rand(b,425+i*11,0,0); /**/ 711*0Sstevel@tonic-gate a->neg=rand_neg(); 712*0Sstevel@tonic-gate b->neg=rand_neg(); 713*0Sstevel@tonic-gate if (!BN_mod_mul(e,a,b,c,ctx)) 714*0Sstevel@tonic-gate { 715*0Sstevel@tonic-gate unsigned long l; 716*0Sstevel@tonic-gate 717*0Sstevel@tonic-gate while ((l=ERR_get_error())) 718*0Sstevel@tonic-gate fprintf(stderr,"ERROR:%s\n", 719*0Sstevel@tonic-gate ERR_error_string(l,NULL)); 720*0Sstevel@tonic-gate EXIT(1); 721*0Sstevel@tonic-gate } 722*0Sstevel@tonic-gate if (bp != NULL) 723*0Sstevel@tonic-gate { 724*0Sstevel@tonic-gate if (!results) 725*0Sstevel@tonic-gate { 726*0Sstevel@tonic-gate BN_print(bp,a); 727*0Sstevel@tonic-gate BIO_puts(bp," * "); 728*0Sstevel@tonic-gate BN_print(bp,b); 729*0Sstevel@tonic-gate BIO_puts(bp," % "); 730*0Sstevel@tonic-gate BN_print(bp,c); 731*0Sstevel@tonic-gate if ((a->neg ^ b->neg) && !BN_is_zero(e)) 732*0Sstevel@tonic-gate { 733*0Sstevel@tonic-gate /* If (a*b) % c is negative, c must be added 734*0Sstevel@tonic-gate * in order to obtain the normalized remainder 735*0Sstevel@tonic-gate * (new with OpenSSL 0.9.7, previous versions of 736*0Sstevel@tonic-gate * BN_mod_mul could generate negative results) 737*0Sstevel@tonic-gate */ 738*0Sstevel@tonic-gate BIO_puts(bp," + "); 739*0Sstevel@tonic-gate BN_print(bp,c); 740*0Sstevel@tonic-gate } 741*0Sstevel@tonic-gate BIO_puts(bp," - "); 742*0Sstevel@tonic-gate } 743*0Sstevel@tonic-gate BN_print(bp,e); 744*0Sstevel@tonic-gate BIO_puts(bp,"\n"); 745*0Sstevel@tonic-gate } 746*0Sstevel@tonic-gate BN_mul(d,a,b,ctx); 747*0Sstevel@tonic-gate BN_sub(d,d,e); 748*0Sstevel@tonic-gate BN_div(a,b,d,c,ctx); 749*0Sstevel@tonic-gate if(!BN_is_zero(b)) 750*0Sstevel@tonic-gate { 751*0Sstevel@tonic-gate fprintf(stderr,"Modulo multiply test failed!\n"); 752*0Sstevel@tonic-gate ERR_print_errors_fp(stderr); 753*0Sstevel@tonic-gate return 0; 754*0Sstevel@tonic-gate } 755*0Sstevel@tonic-gate } 756*0Sstevel@tonic-gate } 757*0Sstevel@tonic-gate BN_free(a); 758*0Sstevel@tonic-gate BN_free(b); 759*0Sstevel@tonic-gate BN_free(c); 760*0Sstevel@tonic-gate BN_free(d); 761*0Sstevel@tonic-gate BN_free(e); 762*0Sstevel@tonic-gate return(1); 763*0Sstevel@tonic-gate } 764*0Sstevel@tonic-gate 765*0Sstevel@tonic-gate int test_mod_exp(BIO *bp, BN_CTX *ctx) 766*0Sstevel@tonic-gate { 767*0Sstevel@tonic-gate BIGNUM *a,*b,*c,*d,*e; 768*0Sstevel@tonic-gate int i; 769*0Sstevel@tonic-gate 770*0Sstevel@tonic-gate a=BN_new(); 771*0Sstevel@tonic-gate b=BN_new(); 772*0Sstevel@tonic-gate c=BN_new(); 773*0Sstevel@tonic-gate d=BN_new(); 774*0Sstevel@tonic-gate e=BN_new(); 775*0Sstevel@tonic-gate 776*0Sstevel@tonic-gate BN_bntest_rand(c,30,0,1); /* must be odd for montgomery */ 777*0Sstevel@tonic-gate for (i=0; i<num2; i++) 778*0Sstevel@tonic-gate { 779*0Sstevel@tonic-gate BN_bntest_rand(a,20+i*5,0,0); /**/ 780*0Sstevel@tonic-gate BN_bntest_rand(b,2+i,0,0); /**/ 781*0Sstevel@tonic-gate 782*0Sstevel@tonic-gate if (!BN_mod_exp(d,a,b,c,ctx)) 783*0Sstevel@tonic-gate return(00); 784*0Sstevel@tonic-gate 785*0Sstevel@tonic-gate if (bp != NULL) 786*0Sstevel@tonic-gate { 787*0Sstevel@tonic-gate if (!results) 788*0Sstevel@tonic-gate { 789*0Sstevel@tonic-gate BN_print(bp,a); 790*0Sstevel@tonic-gate BIO_puts(bp," ^ "); 791*0Sstevel@tonic-gate BN_print(bp,b); 792*0Sstevel@tonic-gate BIO_puts(bp," % "); 793*0Sstevel@tonic-gate BN_print(bp,c); 794*0Sstevel@tonic-gate BIO_puts(bp," - "); 795*0Sstevel@tonic-gate } 796*0Sstevel@tonic-gate BN_print(bp,d); 797*0Sstevel@tonic-gate BIO_puts(bp,"\n"); 798*0Sstevel@tonic-gate } 799*0Sstevel@tonic-gate BN_exp(e,a,b,ctx); 800*0Sstevel@tonic-gate BN_sub(e,e,d); 801*0Sstevel@tonic-gate BN_div(a,b,e,c,ctx); 802*0Sstevel@tonic-gate if(!BN_is_zero(b)) 803*0Sstevel@tonic-gate { 804*0Sstevel@tonic-gate fprintf(stderr,"Modulo exponentiation test failed!\n"); 805*0Sstevel@tonic-gate return 0; 806*0Sstevel@tonic-gate } 807*0Sstevel@tonic-gate } 808*0Sstevel@tonic-gate BN_free(a); 809*0Sstevel@tonic-gate BN_free(b); 810*0Sstevel@tonic-gate BN_free(c); 811*0Sstevel@tonic-gate BN_free(d); 812*0Sstevel@tonic-gate BN_free(e); 813*0Sstevel@tonic-gate return(1); 814*0Sstevel@tonic-gate } 815*0Sstevel@tonic-gate 816*0Sstevel@tonic-gate int test_exp(BIO *bp, BN_CTX *ctx) 817*0Sstevel@tonic-gate { 818*0Sstevel@tonic-gate BIGNUM *a,*b,*d,*e,*one; 819*0Sstevel@tonic-gate int i; 820*0Sstevel@tonic-gate 821*0Sstevel@tonic-gate a=BN_new(); 822*0Sstevel@tonic-gate b=BN_new(); 823*0Sstevel@tonic-gate d=BN_new(); 824*0Sstevel@tonic-gate e=BN_new(); 825*0Sstevel@tonic-gate one=BN_new(); 826*0Sstevel@tonic-gate BN_one(one); 827*0Sstevel@tonic-gate 828*0Sstevel@tonic-gate for (i=0; i<num2; i++) 829*0Sstevel@tonic-gate { 830*0Sstevel@tonic-gate BN_bntest_rand(a,20+i*5,0,0); /**/ 831*0Sstevel@tonic-gate BN_bntest_rand(b,2+i,0,0); /**/ 832*0Sstevel@tonic-gate 833*0Sstevel@tonic-gate if (!BN_exp(d,a,b,ctx)) 834*0Sstevel@tonic-gate return(00); 835*0Sstevel@tonic-gate 836*0Sstevel@tonic-gate if (bp != NULL) 837*0Sstevel@tonic-gate { 838*0Sstevel@tonic-gate if (!results) 839*0Sstevel@tonic-gate { 840*0Sstevel@tonic-gate BN_print(bp,a); 841*0Sstevel@tonic-gate BIO_puts(bp," ^ "); 842*0Sstevel@tonic-gate BN_print(bp,b); 843*0Sstevel@tonic-gate BIO_puts(bp," - "); 844*0Sstevel@tonic-gate } 845*0Sstevel@tonic-gate BN_print(bp,d); 846*0Sstevel@tonic-gate BIO_puts(bp,"\n"); 847*0Sstevel@tonic-gate } 848*0Sstevel@tonic-gate BN_one(e); 849*0Sstevel@tonic-gate for( ; !BN_is_zero(b) ; BN_sub(b,b,one)) 850*0Sstevel@tonic-gate BN_mul(e,e,a,ctx); 851*0Sstevel@tonic-gate BN_sub(e,e,d); 852*0Sstevel@tonic-gate if(!BN_is_zero(e)) 853*0Sstevel@tonic-gate { 854*0Sstevel@tonic-gate fprintf(stderr,"Exponentiation test failed!\n"); 855*0Sstevel@tonic-gate return 0; 856*0Sstevel@tonic-gate } 857*0Sstevel@tonic-gate } 858*0Sstevel@tonic-gate BN_free(a); 859*0Sstevel@tonic-gate BN_free(b); 860*0Sstevel@tonic-gate BN_free(d); 861*0Sstevel@tonic-gate BN_free(e); 862*0Sstevel@tonic-gate BN_free(one); 863*0Sstevel@tonic-gate return(1); 864*0Sstevel@tonic-gate } 865*0Sstevel@tonic-gate 866*0Sstevel@tonic-gate static void genprime_cb(int p, int n, void *arg) 867*0Sstevel@tonic-gate { 868*0Sstevel@tonic-gate char c='*'; 869*0Sstevel@tonic-gate 870*0Sstevel@tonic-gate if (p == 0) c='.'; 871*0Sstevel@tonic-gate if (p == 1) c='+'; 872*0Sstevel@tonic-gate if (p == 2) c='*'; 873*0Sstevel@tonic-gate if (p == 3) c='\n'; 874*0Sstevel@tonic-gate putc(c, stderr); 875*0Sstevel@tonic-gate fflush(stderr); 876*0Sstevel@tonic-gate (void)n; 877*0Sstevel@tonic-gate (void)arg; 878*0Sstevel@tonic-gate } 879*0Sstevel@tonic-gate 880*0Sstevel@tonic-gate int test_kron(BIO *bp, BN_CTX *ctx) 881*0Sstevel@tonic-gate { 882*0Sstevel@tonic-gate BIGNUM *a,*b,*r,*t; 883*0Sstevel@tonic-gate int i; 884*0Sstevel@tonic-gate int legendre, kronecker; 885*0Sstevel@tonic-gate int ret = 0; 886*0Sstevel@tonic-gate 887*0Sstevel@tonic-gate a = BN_new(); 888*0Sstevel@tonic-gate b = BN_new(); 889*0Sstevel@tonic-gate r = BN_new(); 890*0Sstevel@tonic-gate t = BN_new(); 891*0Sstevel@tonic-gate if (a == NULL || b == NULL || r == NULL || t == NULL) goto err; 892*0Sstevel@tonic-gate 893*0Sstevel@tonic-gate /* We test BN_kronecker(a, b, ctx) just for b odd (Jacobi symbol). 894*0Sstevel@tonic-gate * In this case we know that if b is prime, then BN_kronecker(a, b, ctx) 895*0Sstevel@tonic-gate * is congruent to $a^{(b-1)/2}$, modulo $b$ (Legendre symbol). 896*0Sstevel@tonic-gate * So we generate a random prime b and compare these values 897*0Sstevel@tonic-gate * for a number of random a's. (That is, we run the Solovay-Strassen 898*0Sstevel@tonic-gate * primality test to confirm that b is prime, except that we 899*0Sstevel@tonic-gate * don't want to test whether b is prime but whether BN_kronecker 900*0Sstevel@tonic-gate * works.) */ 901*0Sstevel@tonic-gate 902*0Sstevel@tonic-gate if (!BN_generate_prime(b, 512, 0, NULL, NULL, genprime_cb, NULL)) goto err; 903*0Sstevel@tonic-gate b->neg = rand_neg(); 904*0Sstevel@tonic-gate putc('\n', stderr); 905*0Sstevel@tonic-gate 906*0Sstevel@tonic-gate for (i = 0; i < num0; i++) 907*0Sstevel@tonic-gate { 908*0Sstevel@tonic-gate if (!BN_bntest_rand(a, 512, 0, 0)) goto err; 909*0Sstevel@tonic-gate a->neg = rand_neg(); 910*0Sstevel@tonic-gate 911*0Sstevel@tonic-gate /* t := (|b|-1)/2 (note that b is odd) */ 912*0Sstevel@tonic-gate if (!BN_copy(t, b)) goto err; 913*0Sstevel@tonic-gate t->neg = 0; 914*0Sstevel@tonic-gate if (!BN_sub_word(t, 1)) goto err; 915*0Sstevel@tonic-gate if (!BN_rshift1(t, t)) goto err; 916*0Sstevel@tonic-gate /* r := a^t mod b */ 917*0Sstevel@tonic-gate b->neg=0; 918*0Sstevel@tonic-gate 919*0Sstevel@tonic-gate if (!BN_mod_exp_recp(r, a, t, b, ctx)) goto err; 920*0Sstevel@tonic-gate b->neg=1; 921*0Sstevel@tonic-gate 922*0Sstevel@tonic-gate if (BN_is_word(r, 1)) 923*0Sstevel@tonic-gate legendre = 1; 924*0Sstevel@tonic-gate else if (BN_is_zero(r)) 925*0Sstevel@tonic-gate legendre = 0; 926*0Sstevel@tonic-gate else 927*0Sstevel@tonic-gate { 928*0Sstevel@tonic-gate if (!BN_add_word(r, 1)) goto err; 929*0Sstevel@tonic-gate if (0 != BN_ucmp(r, b)) 930*0Sstevel@tonic-gate { 931*0Sstevel@tonic-gate fprintf(stderr, "Legendre symbol computation failed\n"); 932*0Sstevel@tonic-gate goto err; 933*0Sstevel@tonic-gate } 934*0Sstevel@tonic-gate legendre = -1; 935*0Sstevel@tonic-gate } 936*0Sstevel@tonic-gate 937*0Sstevel@tonic-gate kronecker = BN_kronecker(a, b, ctx); 938*0Sstevel@tonic-gate if (kronecker < -1) goto err; 939*0Sstevel@tonic-gate /* we actually need BN_kronecker(a, |b|) */ 940*0Sstevel@tonic-gate if (a->neg && b->neg) 941*0Sstevel@tonic-gate kronecker = -kronecker; 942*0Sstevel@tonic-gate 943*0Sstevel@tonic-gate if (legendre != kronecker) 944*0Sstevel@tonic-gate { 945*0Sstevel@tonic-gate fprintf(stderr, "legendre != kronecker; a = "); 946*0Sstevel@tonic-gate BN_print_fp(stderr, a); 947*0Sstevel@tonic-gate fprintf(stderr, ", b = "); 948*0Sstevel@tonic-gate BN_print_fp(stderr, b); 949*0Sstevel@tonic-gate fprintf(stderr, "\n"); 950*0Sstevel@tonic-gate goto err; 951*0Sstevel@tonic-gate } 952*0Sstevel@tonic-gate 953*0Sstevel@tonic-gate putc('.', stderr); 954*0Sstevel@tonic-gate fflush(stderr); 955*0Sstevel@tonic-gate } 956*0Sstevel@tonic-gate 957*0Sstevel@tonic-gate putc('\n', stderr); 958*0Sstevel@tonic-gate fflush(stderr); 959*0Sstevel@tonic-gate ret = 1; 960*0Sstevel@tonic-gate err: 961*0Sstevel@tonic-gate if (a != NULL) BN_free(a); 962*0Sstevel@tonic-gate if (b != NULL) BN_free(b); 963*0Sstevel@tonic-gate if (r != NULL) BN_free(r); 964*0Sstevel@tonic-gate if (t != NULL) BN_free(t); 965*0Sstevel@tonic-gate return ret; 966*0Sstevel@tonic-gate } 967*0Sstevel@tonic-gate 968*0Sstevel@tonic-gate int test_sqrt(BIO *bp, BN_CTX *ctx) 969*0Sstevel@tonic-gate { 970*0Sstevel@tonic-gate BIGNUM *a,*p,*r; 971*0Sstevel@tonic-gate int i, j; 972*0Sstevel@tonic-gate int ret = 0; 973*0Sstevel@tonic-gate 974*0Sstevel@tonic-gate a = BN_new(); 975*0Sstevel@tonic-gate p = BN_new(); 976*0Sstevel@tonic-gate r = BN_new(); 977*0Sstevel@tonic-gate if (a == NULL || p == NULL || r == NULL) goto err; 978*0Sstevel@tonic-gate 979*0Sstevel@tonic-gate for (i = 0; i < 16; i++) 980*0Sstevel@tonic-gate { 981*0Sstevel@tonic-gate if (i < 8) 982*0Sstevel@tonic-gate { 983*0Sstevel@tonic-gate unsigned primes[8] = { 2, 3, 5, 7, 11, 13, 17, 19 }; 984*0Sstevel@tonic-gate 985*0Sstevel@tonic-gate if (!BN_set_word(p, primes[i])) goto err; 986*0Sstevel@tonic-gate } 987*0Sstevel@tonic-gate else 988*0Sstevel@tonic-gate { 989*0Sstevel@tonic-gate if (!BN_set_word(a, 32)) goto err; 990*0Sstevel@tonic-gate if (!BN_set_word(r, 2*i + 1)) goto err; 991*0Sstevel@tonic-gate 992*0Sstevel@tonic-gate if (!BN_generate_prime(p, 256, 0, a, r, genprime_cb, NULL)) goto err; 993*0Sstevel@tonic-gate putc('\n', stderr); 994*0Sstevel@tonic-gate } 995*0Sstevel@tonic-gate p->neg = rand_neg(); 996*0Sstevel@tonic-gate 997*0Sstevel@tonic-gate for (j = 0; j < num2; j++) 998*0Sstevel@tonic-gate { 999*0Sstevel@tonic-gate /* construct 'a' such that it is a square modulo p, 1000*0Sstevel@tonic-gate * but in general not a proper square and not reduced modulo p */ 1001*0Sstevel@tonic-gate if (!BN_bntest_rand(r, 256, 0, 3)) goto err; 1002*0Sstevel@tonic-gate if (!BN_nnmod(r, r, p, ctx)) goto err; 1003*0Sstevel@tonic-gate if (!BN_mod_sqr(r, r, p, ctx)) goto err; 1004*0Sstevel@tonic-gate if (!BN_bntest_rand(a, 256, 0, 3)) goto err; 1005*0Sstevel@tonic-gate if (!BN_nnmod(a, a, p, ctx)) goto err; 1006*0Sstevel@tonic-gate if (!BN_mod_sqr(a, a, p, ctx)) goto err; 1007*0Sstevel@tonic-gate if (!BN_mul(a, a, r, ctx)) goto err; 1008*0Sstevel@tonic-gate if (rand_neg()) 1009*0Sstevel@tonic-gate if (!BN_sub(a, a, p)) goto err; 1010*0Sstevel@tonic-gate 1011*0Sstevel@tonic-gate if (!BN_mod_sqrt(r, a, p, ctx)) goto err; 1012*0Sstevel@tonic-gate if (!BN_mod_sqr(r, r, p, ctx)) goto err; 1013*0Sstevel@tonic-gate 1014*0Sstevel@tonic-gate if (!BN_nnmod(a, a, p, ctx)) goto err; 1015*0Sstevel@tonic-gate 1016*0Sstevel@tonic-gate if (BN_cmp(a, r) != 0) 1017*0Sstevel@tonic-gate { 1018*0Sstevel@tonic-gate fprintf(stderr, "BN_mod_sqrt failed: a = "); 1019*0Sstevel@tonic-gate BN_print_fp(stderr, a); 1020*0Sstevel@tonic-gate fprintf(stderr, ", r = "); 1021*0Sstevel@tonic-gate BN_print_fp(stderr, r); 1022*0Sstevel@tonic-gate fprintf(stderr, ", p = "); 1023*0Sstevel@tonic-gate BN_print_fp(stderr, p); 1024*0Sstevel@tonic-gate fprintf(stderr, "\n"); 1025*0Sstevel@tonic-gate goto err; 1026*0Sstevel@tonic-gate } 1027*0Sstevel@tonic-gate 1028*0Sstevel@tonic-gate putc('.', stderr); 1029*0Sstevel@tonic-gate fflush(stderr); 1030*0Sstevel@tonic-gate } 1031*0Sstevel@tonic-gate 1032*0Sstevel@tonic-gate putc('\n', stderr); 1033*0Sstevel@tonic-gate fflush(stderr); 1034*0Sstevel@tonic-gate } 1035*0Sstevel@tonic-gate ret = 1; 1036*0Sstevel@tonic-gate err: 1037*0Sstevel@tonic-gate if (a != NULL) BN_free(a); 1038*0Sstevel@tonic-gate if (p != NULL) BN_free(p); 1039*0Sstevel@tonic-gate if (r != NULL) BN_free(r); 1040*0Sstevel@tonic-gate return ret; 1041*0Sstevel@tonic-gate } 1042*0Sstevel@tonic-gate 1043*0Sstevel@tonic-gate int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_) 1044*0Sstevel@tonic-gate { 1045*0Sstevel@tonic-gate BIGNUM *a,*b,*c,*d; 1046*0Sstevel@tonic-gate int i; 1047*0Sstevel@tonic-gate 1048*0Sstevel@tonic-gate b=BN_new(); 1049*0Sstevel@tonic-gate c=BN_new(); 1050*0Sstevel@tonic-gate d=BN_new(); 1051*0Sstevel@tonic-gate BN_one(c); 1052*0Sstevel@tonic-gate 1053*0Sstevel@tonic-gate if(a_) 1054*0Sstevel@tonic-gate a=a_; 1055*0Sstevel@tonic-gate else 1056*0Sstevel@tonic-gate { 1057*0Sstevel@tonic-gate a=BN_new(); 1058*0Sstevel@tonic-gate BN_bntest_rand(a,200,0,0); /**/ 1059*0Sstevel@tonic-gate a->neg=rand_neg(); 1060*0Sstevel@tonic-gate } 1061*0Sstevel@tonic-gate for (i=0; i<num0; i++) 1062*0Sstevel@tonic-gate { 1063*0Sstevel@tonic-gate BN_lshift(b,a,i+1); 1064*0Sstevel@tonic-gate BN_add(c,c,c); 1065*0Sstevel@tonic-gate if (bp != NULL) 1066*0Sstevel@tonic-gate { 1067*0Sstevel@tonic-gate if (!results) 1068*0Sstevel@tonic-gate { 1069*0Sstevel@tonic-gate BN_print(bp,a); 1070*0Sstevel@tonic-gate BIO_puts(bp," * "); 1071*0Sstevel@tonic-gate BN_print(bp,c); 1072*0Sstevel@tonic-gate BIO_puts(bp," - "); 1073*0Sstevel@tonic-gate } 1074*0Sstevel@tonic-gate BN_print(bp,b); 1075*0Sstevel@tonic-gate BIO_puts(bp,"\n"); 1076*0Sstevel@tonic-gate } 1077*0Sstevel@tonic-gate BN_mul(d,a,c,ctx); 1078*0Sstevel@tonic-gate BN_sub(d,d,b); 1079*0Sstevel@tonic-gate if(!BN_is_zero(d)) 1080*0Sstevel@tonic-gate { 1081*0Sstevel@tonic-gate fprintf(stderr,"Left shift test failed!\n"); 1082*0Sstevel@tonic-gate fprintf(stderr,"a="); 1083*0Sstevel@tonic-gate BN_print_fp(stderr,a); 1084*0Sstevel@tonic-gate fprintf(stderr,"\nb="); 1085*0Sstevel@tonic-gate BN_print_fp(stderr,b); 1086*0Sstevel@tonic-gate fprintf(stderr,"\nc="); 1087*0Sstevel@tonic-gate BN_print_fp(stderr,c); 1088*0Sstevel@tonic-gate fprintf(stderr,"\nd="); 1089*0Sstevel@tonic-gate BN_print_fp(stderr,d); 1090*0Sstevel@tonic-gate fprintf(stderr,"\n"); 1091*0Sstevel@tonic-gate return 0; 1092*0Sstevel@tonic-gate } 1093*0Sstevel@tonic-gate } 1094*0Sstevel@tonic-gate BN_free(a); 1095*0Sstevel@tonic-gate BN_free(b); 1096*0Sstevel@tonic-gate BN_free(c); 1097*0Sstevel@tonic-gate BN_free(d); 1098*0Sstevel@tonic-gate return(1); 1099*0Sstevel@tonic-gate } 1100*0Sstevel@tonic-gate 1101*0Sstevel@tonic-gate int test_lshift1(BIO *bp) 1102*0Sstevel@tonic-gate { 1103*0Sstevel@tonic-gate BIGNUM *a,*b,*c; 1104*0Sstevel@tonic-gate int i; 1105*0Sstevel@tonic-gate 1106*0Sstevel@tonic-gate a=BN_new(); 1107*0Sstevel@tonic-gate b=BN_new(); 1108*0Sstevel@tonic-gate c=BN_new(); 1109*0Sstevel@tonic-gate 1110*0Sstevel@tonic-gate BN_bntest_rand(a,200,0,0); /**/ 1111*0Sstevel@tonic-gate a->neg=rand_neg(); 1112*0Sstevel@tonic-gate for (i=0; i<num0; i++) 1113*0Sstevel@tonic-gate { 1114*0Sstevel@tonic-gate BN_lshift1(b,a); 1115*0Sstevel@tonic-gate if (bp != NULL) 1116*0Sstevel@tonic-gate { 1117*0Sstevel@tonic-gate if (!results) 1118*0Sstevel@tonic-gate { 1119*0Sstevel@tonic-gate BN_print(bp,a); 1120*0Sstevel@tonic-gate BIO_puts(bp," * 2"); 1121*0Sstevel@tonic-gate BIO_puts(bp," - "); 1122*0Sstevel@tonic-gate } 1123*0Sstevel@tonic-gate BN_print(bp,b); 1124*0Sstevel@tonic-gate BIO_puts(bp,"\n"); 1125*0Sstevel@tonic-gate } 1126*0Sstevel@tonic-gate BN_add(c,a,a); 1127*0Sstevel@tonic-gate BN_sub(a,b,c); 1128*0Sstevel@tonic-gate if(!BN_is_zero(a)) 1129*0Sstevel@tonic-gate { 1130*0Sstevel@tonic-gate fprintf(stderr,"Left shift one test failed!\n"); 1131*0Sstevel@tonic-gate return 0; 1132*0Sstevel@tonic-gate } 1133*0Sstevel@tonic-gate 1134*0Sstevel@tonic-gate BN_copy(a,b); 1135*0Sstevel@tonic-gate } 1136*0Sstevel@tonic-gate BN_free(a); 1137*0Sstevel@tonic-gate BN_free(b); 1138*0Sstevel@tonic-gate BN_free(c); 1139*0Sstevel@tonic-gate return(1); 1140*0Sstevel@tonic-gate } 1141*0Sstevel@tonic-gate 1142*0Sstevel@tonic-gate int test_rshift(BIO *bp,BN_CTX *ctx) 1143*0Sstevel@tonic-gate { 1144*0Sstevel@tonic-gate BIGNUM *a,*b,*c,*d,*e; 1145*0Sstevel@tonic-gate int i; 1146*0Sstevel@tonic-gate 1147*0Sstevel@tonic-gate a=BN_new(); 1148*0Sstevel@tonic-gate b=BN_new(); 1149*0Sstevel@tonic-gate c=BN_new(); 1150*0Sstevel@tonic-gate d=BN_new(); 1151*0Sstevel@tonic-gate e=BN_new(); 1152*0Sstevel@tonic-gate BN_one(c); 1153*0Sstevel@tonic-gate 1154*0Sstevel@tonic-gate BN_bntest_rand(a,200,0,0); /**/ 1155*0Sstevel@tonic-gate a->neg=rand_neg(); 1156*0Sstevel@tonic-gate for (i=0; i<num0; i++) 1157*0Sstevel@tonic-gate { 1158*0Sstevel@tonic-gate BN_rshift(b,a,i+1); 1159*0Sstevel@tonic-gate BN_add(c,c,c); 1160*0Sstevel@tonic-gate if (bp != NULL) 1161*0Sstevel@tonic-gate { 1162*0Sstevel@tonic-gate if (!results) 1163*0Sstevel@tonic-gate { 1164*0Sstevel@tonic-gate BN_print(bp,a); 1165*0Sstevel@tonic-gate BIO_puts(bp," / "); 1166*0Sstevel@tonic-gate BN_print(bp,c); 1167*0Sstevel@tonic-gate BIO_puts(bp," - "); 1168*0Sstevel@tonic-gate } 1169*0Sstevel@tonic-gate BN_print(bp,b); 1170*0Sstevel@tonic-gate BIO_puts(bp,"\n"); 1171*0Sstevel@tonic-gate } 1172*0Sstevel@tonic-gate BN_div(d,e,a,c,ctx); 1173*0Sstevel@tonic-gate BN_sub(d,d,b); 1174*0Sstevel@tonic-gate if(!BN_is_zero(d)) 1175*0Sstevel@tonic-gate { 1176*0Sstevel@tonic-gate fprintf(stderr,"Right shift test failed!\n"); 1177*0Sstevel@tonic-gate return 0; 1178*0Sstevel@tonic-gate } 1179*0Sstevel@tonic-gate } 1180*0Sstevel@tonic-gate BN_free(a); 1181*0Sstevel@tonic-gate BN_free(b); 1182*0Sstevel@tonic-gate BN_free(c); 1183*0Sstevel@tonic-gate BN_free(d); 1184*0Sstevel@tonic-gate BN_free(e); 1185*0Sstevel@tonic-gate return(1); 1186*0Sstevel@tonic-gate } 1187*0Sstevel@tonic-gate 1188*0Sstevel@tonic-gate int test_rshift1(BIO *bp) 1189*0Sstevel@tonic-gate { 1190*0Sstevel@tonic-gate BIGNUM *a,*b,*c; 1191*0Sstevel@tonic-gate int i; 1192*0Sstevel@tonic-gate 1193*0Sstevel@tonic-gate a=BN_new(); 1194*0Sstevel@tonic-gate b=BN_new(); 1195*0Sstevel@tonic-gate c=BN_new(); 1196*0Sstevel@tonic-gate 1197*0Sstevel@tonic-gate BN_bntest_rand(a,200,0,0); /**/ 1198*0Sstevel@tonic-gate a->neg=rand_neg(); 1199*0Sstevel@tonic-gate for (i=0; i<num0; i++) 1200*0Sstevel@tonic-gate { 1201*0Sstevel@tonic-gate BN_rshift1(b,a); 1202*0Sstevel@tonic-gate if (bp != NULL) 1203*0Sstevel@tonic-gate { 1204*0Sstevel@tonic-gate if (!results) 1205*0Sstevel@tonic-gate { 1206*0Sstevel@tonic-gate BN_print(bp,a); 1207*0Sstevel@tonic-gate BIO_puts(bp," / 2"); 1208*0Sstevel@tonic-gate BIO_puts(bp," - "); 1209*0Sstevel@tonic-gate } 1210*0Sstevel@tonic-gate BN_print(bp,b); 1211*0Sstevel@tonic-gate BIO_puts(bp,"\n"); 1212*0Sstevel@tonic-gate } 1213*0Sstevel@tonic-gate BN_sub(c,a,b); 1214*0Sstevel@tonic-gate BN_sub(c,c,b); 1215*0Sstevel@tonic-gate if(!BN_is_zero(c) && !BN_abs_is_word(c, 1)) 1216*0Sstevel@tonic-gate { 1217*0Sstevel@tonic-gate fprintf(stderr,"Right shift one test failed!\n"); 1218*0Sstevel@tonic-gate return 0; 1219*0Sstevel@tonic-gate } 1220*0Sstevel@tonic-gate BN_copy(a,b); 1221*0Sstevel@tonic-gate } 1222*0Sstevel@tonic-gate BN_free(a); 1223*0Sstevel@tonic-gate BN_free(b); 1224*0Sstevel@tonic-gate BN_free(c); 1225*0Sstevel@tonic-gate return(1); 1226*0Sstevel@tonic-gate } 1227*0Sstevel@tonic-gate 1228*0Sstevel@tonic-gate int rand_neg(void) 1229*0Sstevel@tonic-gate { 1230*0Sstevel@tonic-gate static unsigned int neg=0; 1231*0Sstevel@tonic-gate static int sign[8]={0,0,0,1,1,0,1,1}; 1232*0Sstevel@tonic-gate 1233*0Sstevel@tonic-gate return(sign[(neg++)%8]); 1234*0Sstevel@tonic-gate } 1235