X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fbn%2Fbntest.c;h=b83d0ba30d420e96ac70adde2c2eedd157130ca1;hp=c60cee7388e2bc7c6b959ec4b06152f93221fb0f;hb=e102a3dcfdff8f3dbe81286926525318611fc23a;hpb=a9be3af5ad4836f7e50f0546311ca90c717b861e diff --git a/crypto/bn/bntest.c b/crypto/bn/bntest.c index c60cee7388..b83d0ba30d 100644 --- a/crypto/bn/bntest.c +++ b/crypto/bn/bntest.c @@ -59,7 +59,9 @@ #include #include #include -#include + +#include "openssl/e_os.h" + #include #include #include @@ -70,12 +72,16 @@ #include "../bio/bss_file.c" #endif +const int num0 = 100; /* number of tests */ +const int num1 = 50; /* additional tests for some functions */ +const int num2 = 5; /* number of tests for slow functions */ + int test_add(BIO *bp); int test_sub(BIO *bp); int test_lshift1(BIO *bp); -int test_lshift(BIO *bp); +int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_); int test_rshift1(BIO *bp); -int test_rshift(BIO *bp); +int test_rshift(BIO *bp,BN_CTX *ctx); int test_div(BIO *bp,BN_CTX *ctx); int test_div_recp(BIO *bp,BN_CTX *ctx); int test_mul(BIO *bp); @@ -85,6 +91,8 @@ int test_mod(BIO *bp,BN_CTX *ctx); int test_mod_mul(BIO *bp,BN_CTX *ctx); int test_mod_exp(BIO *bp,BN_CTX *ctx); int test_exp(BIO *bp,BN_CTX *ctx); +int test_kron(BIO *bp,BN_CTX *ctx); +int test_sqrt(BIO *bp,BN_CTX *ctx); int rand_neg(void); static int results=0; @@ -93,13 +101,28 @@ static int results=0; #include "bss_file.c" #endif +static unsigned char lst[]="\xC6\x4F\x43\x04\x2A\xEA\xCA\x6E\x58\x36\x80\x5B\xE8\xC9" +"\x9B\x04\x5D\x48\x36\xC2\xFD\x16\xC9\x64\xF0"; + +static const char rnd_seed[] = "string to make the random number generator think it has entropy"; + +static void message(BIO *out, char *m) + { + fprintf(stderr, "test %s\n", m); + BIO_puts(out, "print \"test "); + BIO_puts(out, m); + BIO_puts(out, "\\n\"\n"); + } + int main(int argc, char *argv[]) { BN_CTX *ctx; BIO *out; char *outfile=NULL; - srand((unsigned int)time(NULL)); + results = 0; + + RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */ argc--; argv++; @@ -138,72 +161,90 @@ int main(int argc, char *argv[]) if (!results) BIO_puts(out,"obase=16\nibase=16\n"); - fprintf(stderr,"test BN_add\n"); + message(out,"BN_add"); if (!test_add(out)) goto err; - fflush(stdout); + BIO_flush(out); - fprintf(stderr,"test BN_sub\n"); + message(out,"BN_sub"); if (!test_sub(out)) goto err; - fflush(stdout); + BIO_flush(out); - fprintf(stderr,"test BN_lshift1\n"); + message(out,"BN_lshift1"); if (!test_lshift1(out)) goto err; - fflush(stdout); + BIO_flush(out); - fprintf(stderr,"test BN_lshift\n"); - if (!test_lshift(out)) goto err; - fflush(stdout); + message(out,"BN_lshift (fixed)"); + if (!test_lshift(out,ctx,BN_bin2bn(lst,sizeof(lst)-1,NULL))) + goto err; + BIO_flush(out); - fprintf(stderr,"test BN_rshift1\n"); + message(out,"BN_lshift"); + if (!test_lshift(out,ctx,NULL)) goto err; + BIO_flush(out); + + message(out,"BN_rshift1"); if (!test_rshift1(out)) goto err; - fflush(stdout); + BIO_flush(out); - fprintf(stderr,"test BN_rshift\n"); - if (!test_rshift(out)) goto err; - fflush(stdout); + message(out,"BN_rshift"); + if (!test_rshift(out,ctx)) goto err; + BIO_flush(out); - fprintf(stderr,"test BN_sqr\n"); + message(out,"BN_sqr"); if (!test_sqr(out,ctx)) goto err; - fflush(stdout); + BIO_flush(out); - fprintf(stderr,"test BN_mul\n"); + message(out,"BN_mul"); if (!test_mul(out)) goto err; - fflush(stdout); + BIO_flush(out); - fprintf(stderr,"test BN_div\n"); + message(out,"BN_div"); if (!test_div(out,ctx)) goto err; - fflush(stdout); + BIO_flush(out); - fprintf(stderr,"test BN_div_recp\n"); + message(out,"BN_div_recp"); if (!test_div_recp(out,ctx)) goto err; - fflush(stdout); + BIO_flush(out); - fprintf(stderr,"test BN_mod\n"); + message(out,"BN_mod"); if (!test_mod(out,ctx)) goto err; - fflush(stdout); + BIO_flush(out); - fprintf(stderr,"test BN_mod_mul\n"); + message(out,"BN_mod_mul"); if (!test_mod_mul(out,ctx)) goto err; - fflush(stdout); + BIO_flush(out); -/* - fprintf(stderr,"test BN_mont\n"); + message(out,"BN_mont"); if (!test_mont(out,ctx)) goto err; - fflush(stdout); -*/ - fprintf(stderr,"test BN_mod_exp\n"); + BIO_flush(out); + + message(out,"BN_mod_exp"); if (!test_mod_exp(out,ctx)) goto err; - fflush(stdout); + BIO_flush(out); - fprintf(stderr,"test BN_exp\n"); + message(out,"BN_exp"); if (!test_exp(out,ctx)) goto err; - fflush(stdout); + BIO_flush(out); + + message(out,"BN_kronecker"); + if (!test_kron(out,ctx)) goto err; + BIO_flush(out); + + message(out,"BN_mod_sqrt"); + if (!test_sqrt(out,ctx)) goto err; + BIO_flush(out); + + BN_CTX_free(ctx); + BIO_free(out); /**/ exit(0); err: + BIO_puts(out,"1\n"); /* make sure the Perl script fed by bc notices + * the failure, see test_bn in test/Makefile.ssl*/ + BIO_flush(out); ERR_load_crypto_strings(); - ERR_print_errors(out); + ERR_print_errors_fp(stderr); exit(1); return(1); } @@ -212,21 +253,17 @@ int test_add(BIO *bp) { BIGNUM a,b,c; int i; - int j; BN_init(&a); BN_init(&b); BN_init(&c); - BN_rand(&a,512,0,0); - for (i=0; i<100; i++) + BN_bntest_rand(&a,512,0,0); + for (i=0; iN)); BN_print(bp,&A); BIO_puts(bp,"\n"); } + BN_mod_mul(&d,&a,&b,&n,ctx); + BN_sub(&d,&d,&A); + if(!BN_is_zero(&d)) + { + fprintf(stderr,"Montgomery multiplication test failed!\n"); + return 0; + } } BN_MONT_CTX_free(mont); BN_free(&a); BN_free(&b); BN_free(&c); + BN_free(&d); + BN_free(&A); + BN_free(&B); + BN_free(&n); return(1); } int test_mod(BIO *bp, BN_CTX *ctx) { - BIGNUM *a,*b,*c; + BIGNUM *a,*b,*c,*d,*e; int i; - int j; a=BN_new(); b=BN_new(); c=BN_new(); + d=BN_new(); + e=BN_new(); - BN_rand(a,1024,0,0); /**/ - for (i=0; i<20; i++) + BN_bntest_rand(a,1024,0,0); /**/ + for (i=0; ineg=rand_neg(); b->neg=rand_neg(); - if (bp == NULL) - for (j=0; j<100; j++) - BN_mod(c,a,b,ctx);/**/ BN_mod(c,a,b,ctx);/**/ if (bp != NULL) { @@ -563,17 +682,26 @@ int test_mod(BIO *bp, BN_CTX *ctx) BN_print(bp,c); BIO_puts(bp,"\n"); } + BN_div(d,e,a,b,ctx); + BN_sub(e,e,c); + if(!BN_is_zero(e)) + { + fprintf(stderr,"Modulo test failed!\n"); + return 0; + } } BN_free(a); BN_free(b); BN_free(c); + BN_free(d); + BN_free(e); return(1); } int test_mod_mul(BIO *bp, BN_CTX *ctx) { BIGNUM *a,*b,*c,*d,*e; - int i; + int i,j; a=BN_new(); b=BN_new(); @@ -581,17 +709,14 @@ int test_mod_mul(BIO *bp, BN_CTX *ctx) d=BN_new(); e=BN_new(); - BN_rand(c,1024,0,0); /**/ - for (i=0; i<10; i++) + for (j=0; j<3; j++) { + BN_bntest_rand(c,1024,0,0); /**/ + for (i=0; ineg=rand_neg(); b->neg=rand_neg(); - /* if (bp == NULL) - for (j=0; j<100; j++) - BN_mod_mul(d,a,b,c,ctx);*/ /**/ - if (!BN_mod_mul(e,a,b,c,ctx)) { unsigned long l; @@ -610,12 +735,32 @@ int test_mod_mul(BIO *bp, BN_CTX *ctx) BN_print(bp,b); BIO_puts(bp," % "); BN_print(bp,c); + if ((a->neg ^ b->neg) && !BN_is_zero(e)) + { + /* If (a*b) % c is negative, c must be added + * in order to obtain the normalized remainder + * (new with OpenSSL 0.9.7, previous versions of + * BN_mod_mul could generate negative results) + */ + BIO_puts(bp," + "); + BN_print(bp,c); + } BIO_puts(bp," - "); } BN_print(bp,e); BIO_puts(bp,"\n"); } + BN_mul(d,a,b,ctx); + BN_sub(d,d,e); + BN_div(a,b,d,c,ctx); + if(!BN_is_zero(b)) + { + fprintf(stderr,"Modulo multiply test failed!\n"); + ERR_print_errors_fp(stderr); + return 0; + } } + } BN_free(a); BN_free(b); BN_free(c); @@ -635,11 +780,11 @@ int test_mod_exp(BIO *bp, BN_CTX *ctx) d=BN_new(); e=BN_new(); - BN_rand(c,30,0,1); /* must be odd for montgomery */ - for (i=0; i<6; i++) + BN_bntest_rand(c,30,0,1); /* must be odd for montgomery */ + for (i=0; ineg = rand_neg(); + putc('\n', stderr); + + for (i = 0; i < num0; i++) + { + if (!BN_bntest_rand(a, 512, 0, 0)) goto err; + a->neg = rand_neg(); + + /* t := (|b|-1)/2 (note that b is odd) */ + if (!BN_copy(t, b)) goto err; + t->neg = 0; + if (!BN_sub_word(t, 1)) goto err; + if (!BN_rshift1(t, t)) goto err; + /* r := a^t mod b */ + b->neg=0; + + if (!BN_mod_exp_recp(r, a, t, b, ctx)) goto err; /* XXX should be BN_mod_exp_recp, but ..._recp triggers a bug that must be fixed */ + b->neg=1; + + if (BN_is_word(r, 1)) + legendre = 1; + else if (BN_is_zero(r)) + legendre = 0; + else + { + if (!BN_add_word(r, 1)) goto err; + if (0 != BN_ucmp(r, b)) + { + fprintf(stderr, "Legendre symbol computation failed\n"); + goto err; + } + legendre = -1; + } + + kronecker = BN_kronecker(a, b, ctx); + if (kronecker < -1) goto err; + /* we actually need BN_kronecker(a, |b|) */ + if (a->neg && b->neg) + kronecker = -kronecker; + + if (legendre != kronecker) + { + fprintf(stderr, "legendre != kronecker; a = "); + BN_print_fp(stderr, a); + fprintf(stderr, ", b = "); + BN_print_fp(stderr, b); + fprintf(stderr, "\n"); + goto err; + } + + putc('.', stderr); + fflush(stderr); + } + + putc('\n', stderr); + fflush(stderr); + ret = 1; + err: + if (a != NULL) BN_free(a); + if (b != NULL) BN_free(b); + if (r != NULL) BN_free(r); + if (t != NULL) BN_free(t); + return ret; + } + +int test_sqrt(BIO *bp, BN_CTX *ctx) + { + BIGNUM *a,*p,*r; + int i, j; + int ret = 0; + + a = BN_new(); + p = BN_new(); + r = BN_new(); + if (a == NULL || p == NULL || r == NULL) goto err; + + for (i = 0; i < 16; i++) + { + if (i < 8) + { + unsigned primes[8] = { 2, 3, 5, 7, 11, 13, 17, 19 }; + + if (!BN_set_word(p, primes[i])) goto err; + } + else + { + if (!BN_set_word(a, 32)) goto err; + if (!BN_set_word(r, 2*i + 1)) goto err; + + if (!BN_generate_prime(p, 256, 0, a, r, genprime_cb, NULL)) goto err; + putc('\n', stderr); + } + p->neg = rand_neg(); + + for (j = 0; j < num2; j++) + { + /* construct 'a' such that it is a square modulo p, + * but in general not a proper square and not reduced modulo p */ + if (!BN_bntest_rand(r, 256, 0, 3)) goto err; + if (!BN_nnmod(r, r, p, ctx)) goto err; + if (!BN_mod_sqr(r, r, p, ctx)) goto err; + if (!BN_bntest_rand(a, 256, 0, 3)) goto err; + if (!BN_nnmod(a, a, p, ctx)) goto err; + if (!BN_mod_sqr(a, a, p, ctx)) goto err; + if (!BN_mul(a, a, r, ctx)) goto err; + if (rand_neg()) + if (!BN_sub(a, a, p)) goto err; + + if (!BN_mod_sqrt(r, a, p, ctx)) goto err; + if (!BN_mod_sqr(r, r, p, ctx)) goto err; + + if (!BN_nnmod(a, a, p, ctx)) goto err; + + if (BN_cmp(a, r) != 0) + { + fprintf(stderr, "BN_mod_sqrt failed: a = "); + BN_print_fp(stderr, a); + fprintf(stderr, ", r = "); + BN_print_fp(stderr, r); + fprintf(stderr, ", p = "); + BN_print_fp(stderr, p); + fprintf(stderr, "\n"); + goto err; + } + + putc('.', stderr); + fflush(stderr); + } + + putc('\n', stderr); + fflush(stderr); + } + ret = 1; + err: + if (a != NULL) BN_free(a); + if (p != NULL) BN_free(p); + if (r != NULL) BN_free(r); + return ret; + } + +int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_) + { + BIGNUM *a,*b,*c,*d; int i; - a=BN_new(); b=BN_new(); c=BN_new(); + d=BN_new(); BN_one(c); - BN_rand(a,200,0,0); /**/ - a->neg=rand_neg(); - for (i=0; i<70; i++) + if(a_) + a=a_; + else + { + a=BN_new(); + BN_bntest_rand(a,200,0,0); /**/ + a->neg=rand_neg(); + } + for (i=0; ineg=rand_neg(); - for (i=0; i<70; i++) + for (i=0; ineg=rand_neg(); - for (i=0; i<70; i++) + for (i=0; ineg=rand_neg(); - for (i=0; i<70; i++) + for (i=0; i