bntest.c 20.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 "openssl/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 72 73 74
#ifdef WINDOWS
#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 95 96
int rand_neg(void);
static int results=0;

97
#ifdef NO_STDIO
98
#define APPS_WIN16
99
#include "bss_file.c"
100 101
#endif

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

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

107 108 109
void message(BIO *out, char *m)
	{
	fprintf(stderr, "test %s\n", m);
U
Ulf Möller 已提交
110
#if defined(linux) || defined(FreeBSD) /* can we use GNU bc features? */
111 112 113 114 115 116
	BIO_puts(out, "print \"test ");
	BIO_puts(out, m);
	BIO_puts(out, "\\n\"\n");
#endif
	}

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 126 127 128
	RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_rand may fail, and we don't
	                                       * even check its return value
	                                       * (which we should) */

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 164 165
	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");

166
	message(out,"BN_add");
167 168 169
	if (!test_add(out)) goto err;
	fflush(stdout);

170
	message(out,"BN_sub");
171 172 173
	if (!test_sub(out)) goto err;
	fflush(stdout);

174
	message(out,"BN_lshift1");
175 176 177
	if (!test_lshift1(out)) goto err;
	fflush(stdout);

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

183
	message(out,"BN_lshift");
B
Ben Laurie 已提交
184
	if (!test_lshift(out,ctx,NULL)) goto err;
185 186
	fflush(stdout);

187
	message(out,"BN_rshift1");
188 189 190
	if (!test_rshift1(out)) goto err;
	fflush(stdout);

191
	message(out,"BN_rshift");
B
Ben Laurie 已提交
192
	if (!test_rshift(out,ctx)) goto err;
193 194
	fflush(stdout);

195
	message(out,"BN_sqr");
196
	if (!test_sqr(out,ctx)) goto err;
197 198
	fflush(stdout);

199
	message(out,"BN_mul");
200 201 202
	if (!test_mul(out)) goto err;
	fflush(stdout);

203
	message(out,"BN_div");
204 205 206
	if (!test_div(out,ctx)) goto err;
	fflush(stdout);

207
	message(out,"BN_div_recp");
208 209 210
	if (!test_div_recp(out,ctx)) goto err;
	fflush(stdout);

211
	message(out,"BN_mod");
212
	if (!test_mod(out,ctx)) goto err;
213 214
	fflush(stdout);

215
	message(out,"BN_mod_mul");
216 217 218
	if (!test_mod_mul(out,ctx)) goto err;
	fflush(stdout);

219
	message(out,"BN_mont");
220 221
	if (!test_mont(out,ctx)) goto err;
	fflush(stdout);
B
Bodo Möller 已提交
222

223
	message(out,"BN_mod_exp");
224 225 226
	if (!test_mod_exp(out,ctx)) goto err;
	fflush(stdout);

227
	message(out,"BN_exp");
228 229 230
	if (!test_exp(out,ctx)) goto err;
	fflush(stdout);

231 232 233
	BN_CTX_free(ctx);
	BIO_free(out);

234 235 236
/**/
	exit(0);
err:
237
	BIO_puts(out,"1\n"); /* make sure bc fails if we are piping to it */
238
	ERR_load_crypto_strings();
239
	ERR_print_errors_fp(stderr);
240 241 242 243
	exit(1);
	return(1);
	}

U
Ulf Möller 已提交
244
int test_add(BIO *bp)
245
	{
246
	BIGNUM a,b,c;
247 248 249
	int i;
	int j;

250 251 252
	BN_init(&a);
	BN_init(&b);
	BN_init(&c);
253

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

U
Ulf Möller 已提交
292
int test_sub(BIO *bp)
293
	{
294
	BIGNUM a,b,c;
295 296 297
	int i;
	int j;

298 299 300
	BN_init(&a);
	BN_init(&b);
	BN_init(&c);
301

302
	for (i=0; i<num0+num1; i++)
303
		{
304 305 306 307 308 309 310 311 312 313 314 315 316
		if (i < num1)
			{
			BN_rand(&a,512,0,0);
			BN_copy(&b,&a);
			if (BN_set_bit(&a,i)==0) return(0);
			BN_add_word(&b,i);
			}
		else
			{
			BN_rand(&b,400+i-num1,0,0);
			a.neg=rand_neg();
			b.neg=rand_neg();
			}
317 318
		if (bp == NULL)
			for (j=0; j<10000; j++)
319 320
				BN_sub(&c,&a,&b);
		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 352
	int i;
	int j;

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

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

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

U
Ulf Möller 已提交
415
int test_div_recp(BIO *bp, BN_CTX *ctx)
416
	{
B
Ben Laurie 已提交
417
	BIGNUM a,b,c,d,e;
418 419 420 421 422 423 424 425 426
	BN_RECP_CTX recp;
	int i;
	int j;

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

429
	for (i=0; i<num0+num1; i++)
430
		{
431 432 433 434 435 436 437 438 439
		if (i < num1)
			{
			BN_rand(&a,400,0,0);
			BN_copy(&b,&a);
			BN_lshift(&a,&a,i);
			BN_add_word(&a,i);
			}
		else
			BN_rand(&b,50+3*(i-num1),0,0);
440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468
		a.neg=rand_neg();
		b.neg=rand_neg();
		BN_RECP_CTX_set(&recp,&b,ctx);
		if (bp == NULL)
			for (j=0; j<100; j++)
				BN_div_recp(&d,&c,&a,&recp,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 已提交
469 470 471 472 473
		BN_mul(&e,&d,&b,ctx);
		BN_add(&d,&e,&c);
		BN_sub(&d,&d,&a);
		if(!BN_is_zero(&d))
		    {
474 475 476 477 478 479
		    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 已提交
480 481
		    return 0;
		    }
482 483 484 485 486
		}
	BN_free(&a);
	BN_free(&b);
	BN_free(&c);
	BN_free(&d);
B
Ben Laurie 已提交
487
	BN_free(&e);
488
	BN_RECP_CTX_free(&recp);
489 490 491
	return(1);
	}

U
Ulf Möller 已提交
492
int test_mul(BIO *bp)
493
	{
B
Ben Laurie 已提交
494
	BIGNUM a,b,c,d,e;
495 496
	int i;
	int j;
497
	BN_CTX ctx;
498

499 500 501 502
	BN_CTX_init(&ctx);
	BN_init(&a);
	BN_init(&b);
	BN_init(&c);
B
Ben Laurie 已提交
503 504
	BN_init(&d);
	BN_init(&e);
505

506
	for (i=0; i<num0+num1; i++)
507
		{
508 509 510 511 512 513 514
		if (i < num1)
			{
			BN_rand(&a,100,0,0);
			BN_rand(&b,100,0,0);
			}
		else
			BN_rand(&b,i-num1,0,0);
515 516
		a.neg=rand_neg();
		b.neg=rand_neg();
517 518
		if (bp == NULL)
			for (j=0; j<100; j++)
519 520
				BN_mul(&c,&a,&b,&ctx);
		BN_mul(&c,&a,&b,&ctx);
521 522 523 524
		if (bp != NULL)
			{
			if (!results)
				{
525
				BN_print(bp,&a);
526
				BIO_puts(bp," * ");
527
				BN_print(bp,&b);
528 529
				BIO_puts(bp," - ");
				}
530
			BN_print(bp,&c);
531 532
			BIO_puts(bp,"\n");
			}
B
Ben Laurie 已提交
533 534 535 536
		BN_div(&d,&e,&c,&a,&ctx);
		BN_sub(&d,&d,&b);
		if(!BN_is_zero(&d) || !BN_is_zero(&e))
		    {
537
		    fprintf(stderr,"Multiplication test failed!\n");
B
Ben Laurie 已提交
538 539
		    return 0;
		    }
540
		}
541 542 543
	BN_free(&a);
	BN_free(&b);
	BN_free(&c);
B
Ben Laurie 已提交
544 545
	BN_free(&d);
	BN_free(&e);
546
	BN_CTX_free(&ctx);
547 548 549
	return(1);
	}

U
Ulf Möller 已提交
550
int test_sqr(BIO *bp, BN_CTX *ctx)
551
	{
B
Ben Laurie 已提交
552
	BIGNUM a,c,d,e;
553 554 555
	int i;
	int j;

556 557
	BN_init(&a);
	BN_init(&c);
B
Ben Laurie 已提交
558 559
	BN_init(&d);
	BN_init(&e);
560

561
	for (i=0; i<num0; i++)
562
		{
563 564
		BN_rand(&a,40+i*10,0,0);
		a.neg=rand_neg();
565 566
		if (bp == NULL)
			for (j=0; j<100; j++)
567 568
				BN_sqr(&c,&a,ctx);
		BN_sqr(&c,&a,ctx);
569 570 571 572
		if (bp != NULL)
			{
			if (!results)
				{
573
				BN_print(bp,&a);
574
				BIO_puts(bp," * ");
575
				BN_print(bp,&a);
576 577
				BIO_puts(bp," - ");
				}
578
			BN_print(bp,&c);
579 580
			BIO_puts(bp,"\n");
			}
B
Ben Laurie 已提交
581 582 583 584
		BN_div(&d,&e,&c,&a,ctx);
		BN_sub(&d,&d,&a);
		if(!BN_is_zero(&d) || !BN_is_zero(&e))
		    {
585
		    fprintf(stderr,"Square test failed!\n");
B
Ben Laurie 已提交
586 587
		    return 0;
		    }
588
		}
589 590
	BN_free(&a);
	BN_free(&c);
B
Ben Laurie 已提交
591 592
	BN_free(&d);
	BN_free(&e);
593 594 595
	return(1);
	}

U
Ulf Möller 已提交
596
int test_mont(BIO *bp, BN_CTX *ctx)
597
	{
B
Ben Laurie 已提交
598
	BIGNUM a,b,c,d,A,B;
599
	BIGNUM n;
600 601 602 603
	int i;
	int j;
	BN_MONT_CTX *mont;

604 605 606
	BN_init(&a);
	BN_init(&b);
	BN_init(&c);
B
Ben Laurie 已提交
607
	BN_init(&d);
608 609 610
	BN_init(&A);
	BN_init(&B);
	BN_init(&n);
611 612 613

	mont=BN_MONT_CTX_new();

614 615
	BN_rand(&a,100,0,0); /**/
	BN_rand(&b,100,0,0); /**/
616
	for (i=0; i<num2; i++)
617
		{
B
Bodo Möller 已提交
618 619 620 621 622
		int bits = (100%BN_BITS2+1)*BN_BITS2*i*BN_BITS2;

		if (bits == 0)
			continue;
		BN_rand(&n,bits,0,1);
623
		BN_MONT_CTX_set(mont,&n,ctx);
624

625 626
		BN_to_montgomery(&A,&a,mont,ctx);
		BN_to_montgomery(&B,&b,mont,ctx);
627 628 629

		if (bp == NULL)
			for (j=0; j<100; j++)
630 631 632
				BN_mod_mul_montgomery(&c,&A,&B,mont,ctx);/**/
		BN_mod_mul_montgomery(&c,&A,&B,mont,ctx);/**/
		BN_from_montgomery(&A,&c,mont,ctx);/**/
633 634 635 636 637 638
		if (bp != NULL)
			{
			if (!results)
				{
#ifdef undef
fprintf(stderr,"%d * %d %% %d\n",
639 640
BN_num_bits(&a),
BN_num_bits(&b),
641 642
BN_num_bits(mont->N));
#endif
643
				BN_print(bp,&a);
644
				BIO_puts(bp," * ");
645
				BN_print(bp,&b);
646
				BIO_puts(bp," % ");
647
				BN_print(bp,&(mont->N));
648 649
				BIO_puts(bp," - ");
				}
650
			BN_print(bp,&A);
651 652
			BIO_puts(bp,"\n");
			}
B
Ben Laurie 已提交
653 654 655 656
		BN_mod_mul(&d,&a,&b,&n,ctx);
		BN_sub(&d,&d,&A);
		if(!BN_is_zero(&d))
		    {
657
		    fprintf(stderr,"Montgomery multiplication test failed!\n");
B
Ben Laurie 已提交
658 659
		    return 0;
		    }
660 661
		}
	BN_MONT_CTX_free(mont);
662 663 664
	BN_free(&a);
	BN_free(&b);
	BN_free(&c);
B
Ben Laurie 已提交
665 666 667 668
	BN_free(&d);
	BN_free(&A);
	BN_free(&B);
	BN_free(&n);
669 670 671
	return(1);
	}

U
Ulf Möller 已提交
672
int test_mod(BIO *bp, BN_CTX *ctx)
673
	{
B
Ben Laurie 已提交
674
	BIGNUM *a,*b,*c,*d,*e;
675 676 677 678 679 680
	int i;
	int j;

	a=BN_new();
	b=BN_new();
	c=BN_new();
B
Ben Laurie 已提交
681 682
	d=BN_new();
	e=BN_new();
683 684

	BN_rand(a,1024,0,0); /**/
685
	for (i=0; i<num0; i++)
686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705
		{
		BN_rand(b,450+i*10,0,0); /**/
		a->neg=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)
			{
			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 已提交
706 707 708 709
		BN_div(d,e,a,b,ctx);
		BN_sub(e,e,c);
		if(!BN_is_zero(e))
		    {
710
		    fprintf(stderr,"Modulo test failed!\n");
B
Ben Laurie 已提交
711 712
		    return 0;
		    }
713 714 715 716
		}
	BN_free(a);
	BN_free(b);
	BN_free(c);
B
Ben Laurie 已提交
717 718
	BN_free(d);
	BN_free(e);
719 720 721
	return(1);
	}

U
Ulf Möller 已提交
722
int test_mod_mul(BIO *bp, BN_CTX *ctx)
723 724 725 726 727 728 729 730 731 732 733
	{
	BIGNUM *a,*b,*c,*d,*e;
	int i;

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

	BN_rand(c,1024,0,0); /**/
734
	for (i=0; i<num0; i++)
735
		{
U
Ulf Möller 已提交
736 737
		BN_rand(a,475+i*10,0,0); /**/
		BN_rand(b,425+i*11,0,0); /**/
738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766
		a->neg=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;

			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);
				BIO_puts(bp," - ");
				}
			BN_print(bp,e);
			BIO_puts(bp,"\n");
			}
B
Ben Laurie 已提交
767 768 769 770 771
		BN_mul(d,a,b,ctx);
		BN_sub(d,d,e);
		BN_div(a,b,d,c,ctx);
		if(!BN_is_zero(b))
		    {
772
		    fprintf(stderr,"Modulo multiply test failed!\n");
B
Ben Laurie 已提交
773 774
		    return 0;
		    }
775 776 777 778 779 780 781 782 783
		}
	BN_free(a);
	BN_free(b);
	BN_free(c);
	BN_free(d);
	BN_free(e);
	return(1);
	}

U
Ulf Möller 已提交
784
int test_mod_exp(BIO *bp, BN_CTX *ctx)
785 786 787 788 789 790 791 792 793 794 795
	{
	BIGNUM *a,*b,*c,*d,*e;
	int i;

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

	BN_rand(c,30,0,1); /* must be odd for montgomery */
796
	for (i=0; i<num2; i++)
797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817
		{
		BN_rand(a,20+i*5,0,0); /**/
		BN_rand(b,2+i,0,0); /**/

		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 已提交
818 819 820 821 822
		BN_exp(e,a,b,ctx);
		BN_sub(e,e,d);
		BN_div(a,b,e,c,ctx);
		if(!BN_is_zero(b))
		    {
823
		    fprintf(stderr,"Modulo exponentiation test failed!\n");
B
Ben Laurie 已提交
824 825
		    return 0;
		    }
826 827 828 829 830 831 832 833 834
		}
	BN_free(a);
	BN_free(b);
	BN_free(c);
	BN_free(d);
	BN_free(e);
	return(1);
	}

U
Ulf Möller 已提交
835
int test_exp(BIO *bp, BN_CTX *ctx)
836
	{
B
Ben Laurie 已提交
837
	BIGNUM *a,*b,*d,*e,*one;
838 839 840 841 842 843
	int i;

	a=BN_new();
	b=BN_new();
	d=BN_new();
	e=BN_new();
B
Ben Laurie 已提交
844 845
	one=BN_new();
	BN_one(one);
846

847
	for (i=0; i<num2; i++)
848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866
		{
		BN_rand(a,20+i*5,0,0); /**/
		BN_rand(b,2+i,0,0); /**/

		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 已提交
867 868 869 870 871 872
		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))
		    {
873
		    fprintf(stderr,"Exponentiation test failed!\n");
B
Ben Laurie 已提交
874 875
		    return 0;
		    }
876 877 878 879 880
		}
	BN_free(a);
	BN_free(b);
	BN_free(d);
	BN_free(e);
B
Ben Laurie 已提交
881
	BN_free(one);
882 883 884
	return(1);
	}

B
Ben Laurie 已提交
885
int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_)
886
	{
B
Ben Laurie 已提交
887
	BIGNUM *a,*b,*c,*d;
888 889 890 891
	int i;

	b=BN_new();
	c=BN_new();
B
Ben Laurie 已提交
892
	d=BN_new();
893 894
	BN_one(c);

B
Ben Laurie 已提交
895 896 897 898 899 900 901 902
	if(a_)
	    a=a_;
	else
	    {
	    a=BN_new();
	    BN_rand(a,200,0,0); /**/
	    a->neg=rand_neg();
	    }
903
	for (i=0; i<num0; i++)
904 905 906 907 908 909 910 911 912 913 914 915 916 917 918
		{
		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 已提交
919 920 921 922
		BN_mul(d,a,c,ctx);
		BN_sub(d,d,b);
		if(!BN_is_zero(d))
		    {
923 924 925 926 927 928 929 930 931 932
		    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 已提交
933 934
		    return 0;
		    }
935 936 937 938
		}
	BN_free(a);
	BN_free(b);
	BN_free(c);
B
Ben Laurie 已提交
939
	BN_free(d);
940 941 942
	return(1);
	}

U
Ulf Möller 已提交
943
int test_lshift1(BIO *bp)
944
	{
B
Ben Laurie 已提交
945
	BIGNUM *a,*b,*c;
946 947 948 949
	int i;

	a=BN_new();
	b=BN_new();
B
Ben Laurie 已提交
950
	c=BN_new();
951 952 953

	BN_rand(a,200,0,0); /**/
	a->neg=rand_neg();
954
	for (i=0; i<num0; i++)
955 956 957 958 959 960 961 962 963 964 965 966 967
		{
		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 已提交
968 969 970 971
		BN_add(c,a,a);
		BN_sub(a,b,c);
		if(!BN_is_zero(a))
		    {
972
		    fprintf(stderr,"Left shift one test failed!\n");
B
Ben Laurie 已提交
973 974 975
		    return 0;
		    }
		
976 977 978 979
		BN_copy(a,b);
		}
	BN_free(a);
	BN_free(b);
B
Ben Laurie 已提交
980
	BN_free(c);
981 982 983
	return(1);
	}

B
Ben Laurie 已提交
984
int test_rshift(BIO *bp,BN_CTX *ctx)
985
	{
B
Ben Laurie 已提交
986
	BIGNUM *a,*b,*c,*d,*e;
987 988 989 990 991
	int i;

	a=BN_new();
	b=BN_new();
	c=BN_new();
B
Ben Laurie 已提交
992 993
	d=BN_new();
	e=BN_new();
994 995 996 997
	BN_one(c);

	BN_rand(a,200,0,0); /**/
	a->neg=rand_neg();
998
	for (i=0; i<num0; i++)
999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013
		{
		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 已提交
1014 1015 1016 1017
		BN_div(d,e,a,c,ctx);
		BN_sub(d,d,b);
		if(!BN_is_zero(d))
		    {
1018
		    fprintf(stderr,"Right shift test failed!\n");
B
Ben Laurie 已提交
1019 1020
		    return 0;
		    }
1021 1022 1023 1024
		}
	BN_free(a);
	BN_free(b);
	BN_free(c);
B
Ben Laurie 已提交
1025 1026
	BN_free(d);
	BN_free(e);
1027 1028 1029
	return(1);
	}

U
Ulf Möller 已提交
1030
int test_rshift1(BIO *bp)
1031
	{
B
Ben Laurie 已提交
1032
	BIGNUM *a,*b,*c;
1033 1034 1035 1036
	int i;

	a=BN_new();
	b=BN_new();
B
Ben Laurie 已提交
1037
	c=BN_new();
1038 1039 1040

	BN_rand(a,200,0,0); /**/
	a->neg=rand_neg();
1041
	for (i=0; i<num0; i++)
1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054
		{
		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 已提交
1055 1056 1057 1058
		BN_sub(c,a,b);
		BN_sub(c,c,b);
		if(!BN_is_zero(c) && !BN_is_one(c))
		    {
1059
		    fprintf(stderr,"Right shift one test failed!\n");
B
Ben Laurie 已提交
1060 1061
		    return 0;
		    }
1062 1063 1064 1065
		BN_copy(a,b);
		}
	BN_free(a);
	BN_free(b);
B
Ben Laurie 已提交
1066
	BN_free(c);
1067 1068 1069
	return(1);
	}

U
Ulf Möller 已提交
1070
int rand_neg(void)
1071 1072 1073 1074 1075 1076
	{
	static unsigned int neg=0;
	static int sign[8]={0,0,0,1,1,0,1,1};

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