bntest.c 24.0 KB
Newer Older
1
/* crypto/bn/bntest.c */
2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 * 
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 * 
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from 
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 * 
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * 
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
62

63
#include "e_os.h"
64

65 66 67 68 69
#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/rand.h>
#include <openssl/x509.h>
#include <openssl/err.h>
70

71
#ifdef OPENSSL_SYS_WINDOWS
72 73 74
#include "../bio/bss_file.c"
#endif

75 76 77
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 */
78

79 80 81
int test_add(BIO *bp);
int test_sub(BIO *bp);
int test_lshift1(BIO *bp);
B
Ben Laurie 已提交
82
int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_);
83
int test_rshift1(BIO *bp);
B
Ben Laurie 已提交
84
int test_rshift(BIO *bp,BN_CTX *ctx);
85 86 87 88 89 90 91 92
int test_div(BIO *bp,BN_CTX *ctx);
int test_div_recp(BIO *bp,BN_CTX *ctx);
int test_mul(BIO *bp);
int test_sqr(BIO *bp,BN_CTX *ctx);
int test_mont(BIO *bp,BN_CTX *ctx);
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);
93
int test_exp(BIO *bp,BN_CTX *ctx);
94
int test_kron(BIO *bp,BN_CTX *ctx);
B
BN_sqrt  
Bodo Möller 已提交
95
int test_sqrt(BIO *bp,BN_CTX *ctx);
96 97 98
int rand_neg(void);
static int results=0;

99
#ifdef OPENSSL_NO_STDIO
100
#define APPS_WIN16
101
#include "bss_file.c"
102 103
#endif

104
static unsigned char lst[]="\xC6\x4F\x43\x04\x2A\xEA\xCA\x6E\x58\x36\x80\x5B\xE8\xC9"
B
Ben Laurie 已提交
105 106
"\x9B\x04\x5D\x48\x36\xC2\xFD\x16\xC9\x64\xF0";

107 108
static const char rnd_seed[] = "string to make the random number generator think it has entropy";

109
static void message(BIO *out, char *m)
110 111 112 113 114 115 116
	{
	fprintf(stderr, "test %s\n", m);
	BIO_puts(out, "print \"test ");
	BIO_puts(out, m);
	BIO_puts(out, "\\n\"\n");
	}

U
Ulf Möller 已提交
117
int main(int argc, char *argv[])
118 119 120 121 122
	{
	BN_CTX *ctx;
	BIO *out;
	char *outfile=NULL;

123 124
	results = 0;

125
	RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */
126

127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
	argc--;
	argv++;
	while (argc >= 1)
		{
		if (strcmp(*argv,"-results") == 0)
			results=1;
		else if (strcmp(*argv,"-out") == 0)
			{
			if (--argc < 1) break;
			outfile= *(++argv);
			}
		argc--;
		argv++;
		}


	ctx=BN_CTX_new();
	if (ctx == NULL) exit(1);

	out=BIO_new(BIO_s_file());
	if (out == NULL) exit(1);
	if (outfile == NULL)
		{
		BIO_set_fp(out,stdout,BIO_NOCLOSE);
		}
	else
		{
		if (!BIO_write_filename(out,outfile))
			{
			perror(outfile);
			exit(1);
			}
		}

	if (!results)
		BIO_puts(out,"obase=16\nibase=16\n");

164
	message(out,"BN_add");
165
	if (!test_add(out)) goto err;
166
	BIO_flush(out);
167

168
	message(out,"BN_sub");
169
	if (!test_sub(out)) goto err;
170
	BIO_flush(out);
171

172
	message(out,"BN_lshift1");
173
	if (!test_lshift1(out)) goto err;
174
	BIO_flush(out);
175

176
	message(out,"BN_lshift (fixed)");
177
	if (!test_lshift(out,ctx,BN_bin2bn(lst,sizeof(lst)-1,NULL)))
B
Ben Laurie 已提交
178
	    goto err;
179
	BIO_flush(out);
B
Ben Laurie 已提交
180

181
	message(out,"BN_lshift");
B
Ben Laurie 已提交
182
	if (!test_lshift(out,ctx,NULL)) goto err;
183
	BIO_flush(out);
184

185
	message(out,"BN_rshift1");
186
	if (!test_rshift1(out)) goto err;
187
	BIO_flush(out);
188

189
	message(out,"BN_rshift");
B
Ben Laurie 已提交
190
	if (!test_rshift(out,ctx)) goto err;
191
	BIO_flush(out);
192

193
	message(out,"BN_sqr");
194
	if (!test_sqr(out,ctx)) goto err;
195
	BIO_flush(out);
196

197
	message(out,"BN_mul");
198
	if (!test_mul(out)) goto err;
199
	BIO_flush(out);
200

201
	message(out,"BN_div");
202
	if (!test_div(out,ctx)) goto err;
203
	BIO_flush(out);
204

205
	message(out,"BN_div_recp");
206
	if (!test_div_recp(out,ctx)) goto err;
207
	BIO_flush(out);
208

209
	message(out,"BN_mod");
210
	if (!test_mod(out,ctx)) goto err;
211
	BIO_flush(out);
212

213
	message(out,"BN_mod_mul");
214
	if (!test_mod_mul(out,ctx)) goto err;
215
	BIO_flush(out);
216

217
	message(out,"BN_mont");
218
	if (!test_mont(out,ctx)) goto err;
219
	BIO_flush(out);
B
Bodo Möller 已提交
220

221
	message(out,"BN_mod_exp");
222
	if (!test_mod_exp(out,ctx)) goto err;
223
	BIO_flush(out);
224

225
	message(out,"BN_exp");
226
	if (!test_exp(out,ctx)) goto err;
227
	BIO_flush(out);
228

229 230 231 232
	message(out,"BN_kronecker");
	if (!test_kron(out,ctx)) goto err;
	BIO_flush(out);

B
BN_sqrt  
Bodo Möller 已提交
233 234 235 236
	message(out,"BN_mod_sqrt");
	if (!test_sqrt(out,ctx)) goto err;
	BIO_flush(out);

237 238 239
	BN_CTX_free(ctx);
	BIO_free(out);

240 241 242
/**/
	exit(0);
err:
B
Bodo Möller 已提交
243 244
	BIO_puts(out,"1\n"); /* make sure the Perl script fed by bc notices
	                      * the failure, see test_bn in test/Makefile.ssl*/
245
	BIO_flush(out);
246
	ERR_load_crypto_strings();
247
	ERR_print_errors_fp(stderr);
248 249 250 251
	exit(1);
	return(1);
	}

U
Ulf Möller 已提交
252
int test_add(BIO *bp)
253
	{
254
	BIGNUM a,b,c;
255 256
	int i;

257 258 259
	BN_init(&a);
	BN_init(&b);
	BN_init(&c);
260

261
	BN_bntest_rand(&a,512,0,0);
262
	for (i=0; i<num0; i++)
263
		{
264
		BN_bntest_rand(&b,450+i,0,0);
265 266 267
		a.neg=rand_neg();
		b.neg=rand_neg();
		BN_add(&c,&a,&b);
268 269 270 271
		if (bp != NULL)
			{
			if (!results)
				{
272
				BN_print(bp,&a);
273
				BIO_puts(bp," + ");
274
				BN_print(bp,&b);
275 276
				BIO_puts(bp," - ");
				}
277
			BN_print(bp,&c);
278 279
			BIO_puts(bp,"\n");
			}
B
Ben Laurie 已提交
280 281 282 283 284 285
		a.neg=!a.neg;
		b.neg=!b.neg;
		BN_add(&c,&c,&b);
		BN_add(&c,&c,&a);
		if(!BN_is_zero(&c))
		    {
286
		    fprintf(stderr,"Add test failed!\n");
B
Ben Laurie 已提交
287 288
		    return 0;
		    }
289
		}
290 291 292
	BN_free(&a);
	BN_free(&b);
	BN_free(&c);
293 294 295
	return(1);
	}

U
Ulf Möller 已提交
296
int test_sub(BIO *bp)
297
	{
298
	BIGNUM a,b,c;
299 300
	int i;

301 302 303
	BN_init(&a);
	BN_init(&b);
	BN_init(&c);
304

305
	for (i=0; i<num0+num1; i++)
306
		{
307 308
		if (i < num1)
			{
309
			BN_bntest_rand(&a,512,0,0);
310 311 312 313 314 315
			BN_copy(&b,&a);
			if (BN_set_bit(&a,i)==0) return(0);
			BN_add_word(&b,i);
			}
		else
			{
316
			BN_bntest_rand(&b,400+i-num1,0,0);
317 318 319
			a.neg=rand_neg();
			b.neg=rand_neg();
			}
320
		BN_sub(&c,&a,&b);
321 322 323 324
		if (bp != NULL)
			{
			if (!results)
				{
325
				BN_print(bp,&a);
326
				BIO_puts(bp," - ");
327
				BN_print(bp,&b);
328 329
				BIO_puts(bp," - ");
				}
330
			BN_print(bp,&c);
331 332
			BIO_puts(bp,"\n");
			}
B
Ben Laurie 已提交
333 334 335 336
		BN_add(&c,&c,&b);
		BN_sub(&c,&c,&a);
		if(!BN_is_zero(&c))
		    {
337
		    fprintf(stderr,"Subtract test failed!\n");
B
Ben Laurie 已提交
338 339
		    return 0;
		    }
340
		}
341 342 343
	BN_free(&a);
	BN_free(&b);
	BN_free(&c);
344 345 346
	return(1);
	}

U
Ulf Möller 已提交
347
int test_div(BIO *bp, BN_CTX *ctx)
348
	{
B
Ben Laurie 已提交
349
	BIGNUM a,b,c,d,e;
350 351
	int i;

352 353 354 355
	BN_init(&a);
	BN_init(&b);
	BN_init(&c);
	BN_init(&d);
B
Ben Laurie 已提交
356
	BN_init(&e);
357

358
	for (i=0; i<num0+num1; i++)
359
		{
360 361
		if (i < num1)
			{
362
			BN_bntest_rand(&a,400,0,0);
363 364 365 366 367
			BN_copy(&b,&a);
			BN_lshift(&a,&a,i);
			BN_add_word(&a,i);
			}
		else
368
			BN_bntest_rand(&b,50+3*(i-num1),0,0);
369 370 371
		a.neg=rand_neg();
		b.neg=rand_neg();
		BN_div(&d,&c,&a,&b,ctx);
372 373 374 375
		if (bp != NULL)
			{
			if (!results)
				{
376
				BN_print(bp,&a);
377
				BIO_puts(bp," / ");
378
				BN_print(bp,&b);
379 380
				BIO_puts(bp," - ");
				}
381
			BN_print(bp,&d);
382 383 384 385
			BIO_puts(bp,"\n");

			if (!results)
				{
386
				BN_print(bp,&a);
387
				BIO_puts(bp," % ");
388
				BN_print(bp,&b);
389 390
				BIO_puts(bp," - ");
				}
391
			BN_print(bp,&c);
392 393
			BIO_puts(bp,"\n");
			}
B
Ben Laurie 已提交
394 395 396 397 398
		BN_mul(&e,&d,&b,ctx);
		BN_add(&d,&e,&c);
		BN_sub(&d,&d,&a);
		if(!BN_is_zero(&d))
		    {
399
		    fprintf(stderr,"Division test failed!\n");
B
Ben Laurie 已提交
400 401
		    return 0;
		    }
402
		}
403 404 405 406
	BN_free(&a);
	BN_free(&b);
	BN_free(&c);
	BN_free(&d);
B
Ben Laurie 已提交
407
	BN_free(&e);
408 409 410
	return(1);
	}

U
Ulf Möller 已提交
411
int test_div_recp(BIO *bp, BN_CTX *ctx)
412
	{
B
Ben Laurie 已提交
413
	BIGNUM a,b,c,d,e;
414 415 416 417 418 419 420 421
	BN_RECP_CTX recp;
	int i;

	BN_RECP_CTX_init(&recp);
	BN_init(&a);
	BN_init(&b);
	BN_init(&c);
	BN_init(&d);
B
Ben Laurie 已提交
422
	BN_init(&e);
423

424
	for (i=0; i<num0+num1; i++)
425
		{
426 427
		if (i < num1)
			{
428
			BN_bntest_rand(&a,400,0,0);
429 430 431 432 433
			BN_copy(&b,&a);
			BN_lshift(&a,&a,i);
			BN_add_word(&a,i);
			}
		else
434
			BN_bntest_rand(&b,50+3*(i-num1),0,0);
435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460
		a.neg=rand_neg();
		b.neg=rand_neg();
		BN_RECP_CTX_set(&recp,&b,ctx);
		BN_div_recp(&d,&c,&a,&recp,ctx);
		if (bp != NULL)
			{
			if (!results)
				{
				BN_print(bp,&a);
				BIO_puts(bp," / ");
				BN_print(bp,&b);
				BIO_puts(bp," - ");
				}
			BN_print(bp,&d);
			BIO_puts(bp,"\n");

			if (!results)
				{
				BN_print(bp,&a);
				BIO_puts(bp," % ");
				BN_print(bp,&b);
				BIO_puts(bp," - ");
				}
			BN_print(bp,&c);
			BIO_puts(bp,"\n");
			}
B
Ben Laurie 已提交
461 462 463 464 465
		BN_mul(&e,&d,&b,ctx);
		BN_add(&d,&e,&c);
		BN_sub(&d,&d,&a);
		if(!BN_is_zero(&d))
		    {
466 467 468 469 470 471
		    fprintf(stderr,"Reciprocal division test failed!\n");
		    fprintf(stderr,"a=");
		    BN_print_fp(stderr,&a);
		    fprintf(stderr,"\nb=");
		    BN_print_fp(stderr,&b);
		    fprintf(stderr,"\n");
B
Ben Laurie 已提交
472 473
		    return 0;
		    }
474 475 476 477 478
		}
	BN_free(&a);
	BN_free(&b);
	BN_free(&c);
	BN_free(&d);
B
Ben Laurie 已提交
479
	BN_free(&e);
480
	BN_RECP_CTX_free(&recp);
481 482 483
	return(1);
	}

U
Ulf Möller 已提交
484
int test_mul(BIO *bp)
485
	{
B
Ben Laurie 已提交
486
	BIGNUM a,b,c,d,e;
487
	int i;
488
	BN_CTX ctx;
489

490 491 492 493
	BN_CTX_init(&ctx);
	BN_init(&a);
	BN_init(&b);
	BN_init(&c);
B
Ben Laurie 已提交
494 495
	BN_init(&d);
	BN_init(&e);
496

497
	for (i=0; i<num0+num1; i++)
498
		{
499
		if (i <= num1)
500
			{
501 502
			BN_bntest_rand(&a,100,0,0);
			BN_bntest_rand(&b,100,0,0);
503 504
			}
		else
505
			BN_bntest_rand(&b,i-num1,0,0);
506 507 508
		a.neg=rand_neg();
		b.neg=rand_neg();
		BN_mul(&c,&a,&b,&ctx);
509 510 511 512
		if (bp != NULL)
			{
			if (!results)
				{
513
				BN_print(bp,&a);
514
				BIO_puts(bp," * ");
515
				BN_print(bp,&b);
516 517
				BIO_puts(bp," - ");
				}
518
			BN_print(bp,&c);
519 520
			BIO_puts(bp,"\n");
			}
B
Ben Laurie 已提交
521 522 523 524
		BN_div(&d,&e,&c,&a,&ctx);
		BN_sub(&d,&d,&b);
		if(!BN_is_zero(&d) || !BN_is_zero(&e))
		    {
525
		    fprintf(stderr,"Multiplication test failed!\n");
B
Ben Laurie 已提交
526 527
		    return 0;
		    }
528
		}
529 530 531
	BN_free(&a);
	BN_free(&b);
	BN_free(&c);
B
Ben Laurie 已提交
532 533
	BN_free(&d);
	BN_free(&e);
534
	BN_CTX_free(&ctx);
535 536 537
	return(1);
	}

U
Ulf Möller 已提交
538
int test_sqr(BIO *bp, BN_CTX *ctx)
539
	{
B
Ben Laurie 已提交
540
	BIGNUM a,c,d,e;
541 542
	int i;

543 544
	BN_init(&a);
	BN_init(&c);
B
Ben Laurie 已提交
545 546
	BN_init(&d);
	BN_init(&e);
547

548
	for (i=0; i<num0; i++)
549
		{
550
		BN_bntest_rand(&a,40+i*10,0,0);
551 552
		a.neg=rand_neg();
		BN_sqr(&c,&a,ctx);
553 554 555 556
		if (bp != NULL)
			{
			if (!results)
				{
557
				BN_print(bp,&a);
558
				BIO_puts(bp," * ");
559
				BN_print(bp,&a);
560 561
				BIO_puts(bp," - ");
				}
562
			BN_print(bp,&c);
563 564
			BIO_puts(bp,"\n");
			}
B
Ben Laurie 已提交
565 566 567 568
		BN_div(&d,&e,&c,&a,ctx);
		BN_sub(&d,&d,&a);
		if(!BN_is_zero(&d) || !BN_is_zero(&e))
		    {
569
		    fprintf(stderr,"Square test failed!\n");
B
Ben Laurie 已提交
570 571
		    return 0;
		    }
572
		}
573 574
	BN_free(&a);
	BN_free(&c);
B
Ben Laurie 已提交
575 576
	BN_free(&d);
	BN_free(&e);
577 578 579
	return(1);
	}

U
Ulf Möller 已提交
580
int test_mont(BIO *bp, BN_CTX *ctx)
581
	{
B
Ben Laurie 已提交
582
	BIGNUM a,b,c,d,A,B;
583
	BIGNUM n;
584 585 586
	int i;
	BN_MONT_CTX *mont;

587 588 589
	BN_init(&a);
	BN_init(&b);
	BN_init(&c);
B
Ben Laurie 已提交
590
	BN_init(&d);
591 592 593
	BN_init(&A);
	BN_init(&B);
	BN_init(&n);
594 595 596

	mont=BN_MONT_CTX_new();

597 598
	BN_bntest_rand(&a,100,0,0); /**/
	BN_bntest_rand(&b,100,0,0); /**/
599
	for (i=0; i<num2; i++)
600
		{
601
		int bits = (200*(i+1))/num2;
B
Bodo Möller 已提交
602 603 604

		if (bits == 0)
			continue;
605
		BN_bntest_rand(&n,bits,0,1);
606
		BN_MONT_CTX_set(mont,&n,ctx);
607

608 609 610
		BN_nnmod(&a,&a,&n,ctx);
		BN_nnmod(&b,&b,&n,ctx);

611 612
		BN_to_montgomery(&A,&a,mont,ctx);
		BN_to_montgomery(&B,&b,mont,ctx);
613

614 615
		BN_mod_mul_montgomery(&c,&A,&B,mont,ctx);/**/
		BN_from_montgomery(&A,&c,mont,ctx);/**/
616 617 618 619 620 621
		if (bp != NULL)
			{
			if (!results)
				{
#ifdef undef
fprintf(stderr,"%d * %d %% %d\n",
622 623
BN_num_bits(&a),
BN_num_bits(&b),
624 625
BN_num_bits(mont->N));
#endif
626
				BN_print(bp,&a);
627
				BIO_puts(bp," * ");
628
				BN_print(bp,&b);
629
				BIO_puts(bp," % ");
630
				BN_print(bp,&(mont->N));
631 632
				BIO_puts(bp," - ");
				}
633
			BN_print(bp,&A);
634 635
			BIO_puts(bp,"\n");
			}
B
Ben Laurie 已提交
636 637 638 639
		BN_mod_mul(&d,&a,&b,&n,ctx);
		BN_sub(&d,&d,&A);
		if(!BN_is_zero(&d))
		    {
640
		    fprintf(stderr,"Montgomery multiplication test failed!\n");
B
Ben Laurie 已提交
641 642
		    return 0;
		    }
643 644
		}
	BN_MONT_CTX_free(mont);
645 646 647
	BN_free(&a);
	BN_free(&b);
	BN_free(&c);
B
Ben Laurie 已提交
648 649 650 651
	BN_free(&d);
	BN_free(&A);
	BN_free(&B);
	BN_free(&n);
652 653 654
	return(1);
	}

U
Ulf Möller 已提交
655
int test_mod(BIO *bp, BN_CTX *ctx)
656
	{
B
Ben Laurie 已提交
657
	BIGNUM *a,*b,*c,*d,*e;
658 659 660 661 662
	int i;

	a=BN_new();
	b=BN_new();
	c=BN_new();
B
Ben Laurie 已提交
663 664
	d=BN_new();
	e=BN_new();
665

666
	BN_bntest_rand(a,1024,0,0); /**/
667
	for (i=0; i<num0; i++)
668
		{
669
		BN_bntest_rand(b,450+i*10,0,0); /**/
670 671 672 673 674 675 676 677 678 679 680 681 682 683 684
		a->neg=rand_neg();
		b->neg=rand_neg();
		BN_mod(c,a,b,ctx);/**/
		if (bp != NULL)
			{
			if (!results)
				{
				BN_print(bp,a);
				BIO_puts(bp," % ");
				BN_print(bp,b);
				BIO_puts(bp," - ");
				}
			BN_print(bp,c);
			BIO_puts(bp,"\n");
			}
B
Ben Laurie 已提交
685 686 687 688
		BN_div(d,e,a,b,ctx);
		BN_sub(e,e,c);
		if(!BN_is_zero(e))
		    {
689
		    fprintf(stderr,"Modulo test failed!\n");
B
Ben Laurie 已提交
690 691
		    return 0;
		    }
692 693 694 695
		}
	BN_free(a);
	BN_free(b);
	BN_free(c);
B
Ben Laurie 已提交
696 697
	BN_free(d);
	BN_free(e);
698 699 700
	return(1);
	}

U
Ulf Möller 已提交
701
int test_mod_mul(BIO *bp, BN_CTX *ctx)
702 703
	{
	BIGNUM *a,*b,*c,*d,*e;
704
	int i,j;
705 706 707 708 709 710 711

	a=BN_new();
	b=BN_new();
	c=BN_new();
	d=BN_new();
	e=BN_new();

712
	for (j=0; j<3; j++) {
713
	BN_bntest_rand(c,1024,0,0); /**/
714
	for (i=0; i<num0; i++)
715
		{
716 717
		BN_bntest_rand(a,475+i*10,0,0); /**/
		BN_bntest_rand(b,425+i*11,0,0); /**/
718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737
		a->neg=rand_neg();
		b->neg=rand_neg();
		if (!BN_mod_mul(e,a,b,c,ctx))
			{
			unsigned long l;

			while ((l=ERR_get_error()))
				fprintf(stderr,"ERROR:%s\n",
					ERR_error_string(l,NULL));
			exit(1);
			}
		if (bp != NULL)
			{
			if (!results)
				{
				BN_print(bp,a);
				BIO_puts(bp," * ");
				BN_print(bp,b);
				BIO_puts(bp," % ");
				BN_print(bp,c);
B
Bodo Möller 已提交
738 739 740 741 742 743 744 745 746 747
				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);
					}
748 749 750 751 752
				BIO_puts(bp," - ");
				}
			BN_print(bp,e);
			BIO_puts(bp,"\n");
			}
B
Ben Laurie 已提交
753 754 755 756 757
		BN_mul(d,a,b,ctx);
		BN_sub(d,d,e);
		BN_div(a,b,d,c,ctx);
		if(!BN_is_zero(b))
		    {
758
		    fprintf(stderr,"Modulo multiply test failed!\n");
759
		    ERR_print_errors_fp(stderr);
B
Ben Laurie 已提交
760 761
		    return 0;
		    }
762
		}
763
	}
764 765 766 767 768 769 770 771
	BN_free(a);
	BN_free(b);
	BN_free(c);
	BN_free(d);
	BN_free(e);
	return(1);
	}

U
Ulf Möller 已提交
772
int test_mod_exp(BIO *bp, BN_CTX *ctx)
773 774 775 776 777 778 779 780 781 782
	{
	BIGNUM *a,*b,*c,*d,*e;
	int i;

	a=BN_new();
	b=BN_new();
	c=BN_new();
	d=BN_new();
	e=BN_new();

783
	BN_bntest_rand(c,30,0,1); /* must be odd for montgomery */
784
	for (i=0; i<num2; i++)
785
		{
786 787
		BN_bntest_rand(a,20+i*5,0,0); /**/
		BN_bntest_rand(b,2+i,0,0); /**/
788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805

		if (!BN_mod_exp(d,a,b,c,ctx))
			return(00);

		if (bp != NULL)
			{
			if (!results)
				{
				BN_print(bp,a);
				BIO_puts(bp," ^ ");
				BN_print(bp,b);
				BIO_puts(bp," % ");
				BN_print(bp,c);
				BIO_puts(bp," - ");
				}
			BN_print(bp,d);
			BIO_puts(bp,"\n");
			}
B
Ben Laurie 已提交
806 807 808 809 810
		BN_exp(e,a,b,ctx);
		BN_sub(e,e,d);
		BN_div(a,b,e,c,ctx);
		if(!BN_is_zero(b))
		    {
811
		    fprintf(stderr,"Modulo exponentiation test failed!\n");
B
Ben Laurie 已提交
812 813
		    return 0;
		    }
814 815 816 817 818 819 820 821 822
		}
	BN_free(a);
	BN_free(b);
	BN_free(c);
	BN_free(d);
	BN_free(e);
	return(1);
	}

U
Ulf Möller 已提交
823
int test_exp(BIO *bp, BN_CTX *ctx)
824
	{
B
Ben Laurie 已提交
825
	BIGNUM *a,*b,*d,*e,*one;
826 827 828 829 830 831
	int i;

	a=BN_new();
	b=BN_new();
	d=BN_new();
	e=BN_new();
B
Ben Laurie 已提交
832 833
	one=BN_new();
	BN_one(one);
834

835
	for (i=0; i<num2; i++)
836
		{
837 838
		BN_bntest_rand(a,20+i*5,0,0); /**/
		BN_bntest_rand(b,2+i,0,0); /**/
839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854

		if (!BN_exp(d,a,b,ctx))
			return(00);

		if (bp != NULL)
			{
			if (!results)
				{
				BN_print(bp,a);
				BIO_puts(bp," ^ ");
				BN_print(bp,b);
				BIO_puts(bp," - ");
				}
			BN_print(bp,d);
			BIO_puts(bp,"\n");
			}
B
Ben Laurie 已提交
855 856 857 858 859 860
		BN_one(e);
		for( ; !BN_is_zero(b) ; BN_sub(b,b,one))
		    BN_mul(e,e,a,ctx);
		BN_sub(e,e,d);
		if(!BN_is_zero(e))
		    {
861
		    fprintf(stderr,"Exponentiation test failed!\n");
B
Ben Laurie 已提交
862 863
		    return 0;
		    }
864 865 866 867 868
		}
	BN_free(a);
	BN_free(b);
	BN_free(d);
	BN_free(e);
B
Ben Laurie 已提交
869
	BN_free(one);
870 871 872
	return(1);
	}

B
Bodo Möller 已提交
873 874 875 876 877 878 879 880 881 882 883 884 885 886
static void genprime_cb(int p, int n, void *arg)
	{
	char c='*';

	if (p == 0) c='.';
	if (p == 1) c='+';
	if (p == 2) c='*';
	if (p == 3) c='\n';
	putc(c, stderr);
	fflush(stderr);
	(void)n;
	(void)arg;
	}

887 888
int test_kron(BIO *bp, BN_CTX *ctx)
	{
889
	BIGNUM *a,*b,*r,*t;
B
Bodo Möller 已提交
890 891 892 893 894 895 896
	int i;
	int legendre, kronecker;
	int ret = 0;

	a = BN_new();
	b = BN_new();
	r = BN_new();
897 898
	t = BN_new();
	if (a == NULL || b == NULL || r == NULL || t == NULL) goto err;
B
Bodo Möller 已提交
899
	
B
Bodo Möller 已提交
900 901 902 903 904 905 906 907 908
	/* We test BN_kronecker(a, b, ctx) just for  b  odd (Jacobi symbol).
	 * In this case we know that if  b  is prime, then BN_kronecker(a, b, ctx)
	 * is congruent to $a^{(b-1)/2}$, modulo $b$ (Legendre symbol).
	 * So we generate a random prime  b  and compare these values
	 * for a number of random  a's.  (That is, we run the Solovay-Strassen
	 * primality test to confirm that  b  is prime, except that we
	 * don't want to test whether  b  is prime but whether BN_kronecker
	 * works.) */

B
Bodo Möller 已提交
909
	if (!BN_generate_prime(b, 512, 0, NULL, NULL, genprime_cb, NULL)) goto err;
B
Bodo Möller 已提交
910
	b->neg = rand_neg();
B
Bodo Möller 已提交
911
	putc('\n', stderr);
B
Bodo Möller 已提交
912

B
Bodo Möller 已提交
913 914
	for (i = 0; i < num0; i++)
		{
915
		if (!BN_bntest_rand(a, 512, 0, 0)) goto err;
916 917
		a->neg = rand_neg();

B
Bodo Möller 已提交
918
		/* t := (|b|-1)/2  (note that b is odd) */
919
		if (!BN_copy(t, b)) goto err;
B
Bodo Möller 已提交
920
		t->neg = 0;
921 922 923
		if (!BN_sub_word(t, 1)) goto err;
		if (!BN_rshift1(t, t)) goto err;
		/* r := a^t mod b */
924 925 926 927
		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;
B
Bodo Möller 已提交
928 929 930

		if (BN_is_word(r, 1))
			legendre = 1;
931 932
		else if (BN_is_zero(r))
			legendre = 0;
B
Bodo Möller 已提交
933 934 935
		else
			{
			if (!BN_add_word(r, 1)) goto err;
936
			if (0 != BN_ucmp(r, b))
B
Bodo Möller 已提交
937 938 939 940 941 942
				{
				fprintf(stderr, "Legendre symbol computation failed\n");
				goto err;
				}
			legendre = -1;
			}
943
		
B
Bodo Möller 已提交
944 945
		kronecker = BN_kronecker(a, b, ctx);
		if (kronecker < -1) goto err;
B
Bodo Möller 已提交
946 947 948
		/* we actually need BN_kronecker(a, |b|) */
		if (a->neg && b->neg)
			kronecker = -kronecker;
B
Bodo Möller 已提交
949 950 951 952 953
		
		if (legendre != kronecker)
			{
			fprintf(stderr, "legendre != kronecker; a = ");
			BN_print_fp(stderr, a);
954
			fprintf(stderr, ", b = ");
B
Bodo Möller 已提交
955 956 957 958 959
			BN_print_fp(stderr, b);
			fprintf(stderr, "\n");
			goto err;
			}

960 961
		putc('.', stderr);
		fflush(stderr);
B
Bodo Möller 已提交
962 963
		}

964 965
	putc('\n', stderr);
	fflush(stderr);
B
Bodo Möller 已提交
966 967 968 969 970
	ret = 1;
 err:
	if (a != NULL) BN_free(a);
	if (b != NULL) BN_free(b);
	if (r != NULL) BN_free(r);
971
	if (t != NULL) BN_free(t);
B
Bodo Möller 已提交
972
	return ret;
973 974
	}

B
BN_sqrt  
Bodo Möller 已提交
975 976 977 978 979 980 981 982 983 984 985 986 987 988 989
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)
			{
990
			unsigned primes[8] = { 2, 3, 5, 7, 11, 13, 17, 19 };
B
BN_sqrt  
Bodo Möller 已提交
991 992 993 994 995 996 997 998 999 1000 1001
			
			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);
			}
B
Bodo Möller 已提交
1002
		p->neg = rand_neg();
B
BN_sqrt  
Bodo Möller 已提交
1003 1004 1005 1006 1007

		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 */
1008
			if (!BN_bntest_rand(r, 256, 0, 3)) goto err;
B
BN_sqrt  
Bodo Möller 已提交
1009 1010
			if (!BN_nnmod(r, r, p, ctx)) goto err;
			if (!BN_mod_sqr(r, r, p, ctx)) goto err;
1011
			if (!BN_bntest_rand(a, 256, 0, 3)) goto err;
B
BN_sqrt  
Bodo Möller 已提交
1012 1013 1014
			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;
B
Bodo Möller 已提交
1015 1016
			if (rand_neg())
				if (!BN_sub(a, a, p)) goto err;
B
BN_sqrt  
Bodo Möller 已提交
1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049

			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;
	}

B
Ben Laurie 已提交
1050
int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_)
1051
	{
B
Ben Laurie 已提交
1052
	BIGNUM *a,*b,*c,*d;
1053 1054 1055 1056
	int i;

	b=BN_new();
	c=BN_new();
B
Ben Laurie 已提交
1057
	d=BN_new();
1058 1059
	BN_one(c);

B
Ben Laurie 已提交
1060 1061 1062 1063 1064
	if(a_)
	    a=a_;
	else
	    {
	    a=BN_new();
1065
	    BN_bntest_rand(a,200,0,0); /**/
B
Ben Laurie 已提交
1066 1067
	    a->neg=rand_neg();
	    }
1068
	for (i=0; i<num0; i++)
1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083
		{
		BN_lshift(b,a,i+1);
		BN_add(c,c,c);
		if (bp != NULL)
			{
			if (!results)
				{
				BN_print(bp,a);
				BIO_puts(bp," * ");
				BN_print(bp,c);
				BIO_puts(bp," - ");
				}
			BN_print(bp,b);
			BIO_puts(bp,"\n");
			}
B
Ben Laurie 已提交
1084 1085 1086 1087
		BN_mul(d,a,c,ctx);
		BN_sub(d,d,b);
		if(!BN_is_zero(d))
		    {
1088 1089 1090 1091 1092 1093 1094 1095 1096 1097
		    fprintf(stderr,"Left shift test failed!\n");
		    fprintf(stderr,"a=");
		    BN_print_fp(stderr,a);
		    fprintf(stderr,"\nb=");
		    BN_print_fp(stderr,b);
		    fprintf(stderr,"\nc=");
		    BN_print_fp(stderr,c);
		    fprintf(stderr,"\nd=");
		    BN_print_fp(stderr,d);
		    fprintf(stderr,"\n");
B
Ben Laurie 已提交
1098 1099
		    return 0;
		    }
1100 1101 1102 1103
		}
	BN_free(a);
	BN_free(b);
	BN_free(c);
B
Ben Laurie 已提交
1104
	BN_free(d);
1105 1106 1107
	return(1);
	}

U
Ulf Möller 已提交
1108
int test_lshift1(BIO *bp)
1109
	{
B
Ben Laurie 已提交
1110
	BIGNUM *a,*b,*c;
1111 1112 1113 1114
	int i;

	a=BN_new();
	b=BN_new();
B
Ben Laurie 已提交
1115
	c=BN_new();
1116

1117
	BN_bntest_rand(a,200,0,0); /**/
1118
	a->neg=rand_neg();
1119
	for (i=0; i<num0; i++)
1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132
		{
		BN_lshift1(b,a);
		if (bp != NULL)
			{
			if (!results)
				{
				BN_print(bp,a);
				BIO_puts(bp," * 2");
				BIO_puts(bp," - ");
				}
			BN_print(bp,b);
			BIO_puts(bp,"\n");
			}
B
Ben Laurie 已提交
1133 1134 1135 1136
		BN_add(c,a,a);
		BN_sub(a,b,c);
		if(!BN_is_zero(a))
		    {
1137
		    fprintf(stderr,"Left shift one test failed!\n");
B
Ben Laurie 已提交
1138 1139 1140
		    return 0;
		    }
		
1141 1142 1143 1144
		BN_copy(a,b);
		}
	BN_free(a);
	BN_free(b);
B
Ben Laurie 已提交
1145
	BN_free(c);
1146 1147 1148
	return(1);
	}

B
Ben Laurie 已提交
1149
int test_rshift(BIO *bp,BN_CTX *ctx)
1150
	{
B
Ben Laurie 已提交
1151
	BIGNUM *a,*b,*c,*d,*e;
1152 1153 1154 1155 1156
	int i;

	a=BN_new();
	b=BN_new();
	c=BN_new();
B
Ben Laurie 已提交
1157 1158
	d=BN_new();
	e=BN_new();
1159 1160
	BN_one(c);

1161
	BN_bntest_rand(a,200,0,0); /**/
1162
	a->neg=rand_neg();
1163
	for (i=0; i<num0; i++)
1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178
		{
		BN_rshift(b,a,i+1);
		BN_add(c,c,c);
		if (bp != NULL)
			{
			if (!results)
				{
				BN_print(bp,a);
				BIO_puts(bp," / ");
				BN_print(bp,c);
				BIO_puts(bp," - ");
				}
			BN_print(bp,b);
			BIO_puts(bp,"\n");
			}
B
Ben Laurie 已提交
1179 1180 1181 1182
		BN_div(d,e,a,c,ctx);
		BN_sub(d,d,b);
		if(!BN_is_zero(d))
		    {
1183
		    fprintf(stderr,"Right shift test failed!\n");
B
Ben Laurie 已提交
1184 1185
		    return 0;
		    }
1186 1187 1188 1189
		}
	BN_free(a);
	BN_free(b);
	BN_free(c);
B
Ben Laurie 已提交
1190 1191
	BN_free(d);
	BN_free(e);
1192 1193 1194
	return(1);
	}

U
Ulf Möller 已提交
1195
int test_rshift1(BIO *bp)
1196
	{
B
Ben Laurie 已提交
1197
	BIGNUM *a,*b,*c;
1198 1199 1200 1201
	int i;

	a=BN_new();
	b=BN_new();
B
Ben Laurie 已提交
1202
	c=BN_new();
1203

1204
	BN_bntest_rand(a,200,0,0); /**/
1205
	a->neg=rand_neg();
1206
	for (i=0; i<num0; i++)
1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219
		{
		BN_rshift1(b,a);
		if (bp != NULL)
			{
			if (!results)
				{
				BN_print(bp,a);
				BIO_puts(bp," / 2");
				BIO_puts(bp," - ");
				}
			BN_print(bp,b);
			BIO_puts(bp,"\n");
			}
B
Ben Laurie 已提交
1220 1221
		BN_sub(c,a,b);
		BN_sub(c,c,b);
1222
		if(!BN_is_zero(c) && !BN_abs_is_word(c, 1))
B
Ben Laurie 已提交
1223
		    {
1224
		    fprintf(stderr,"Right shift one test failed!\n");
B
Ben Laurie 已提交
1225 1226
		    return 0;
		    }
1227 1228 1229 1230
		BN_copy(a,b);
		}
	BN_free(a);
	BN_free(b);
B
Ben Laurie 已提交
1231
	BN_free(c);
1232 1233 1234
	return(1);
	}

U
Ulf Möller 已提交
1235
int rand_neg(void)
1236 1237 1238 1239 1240 1241
	{
	static unsigned int neg=0;
	static int sign[8]={0,0,0,1,1,0,1,1};

	return(sign[(neg++)%8]);
	}