bn_lib.c 18.5 KB
Newer Older
1
/* crypto/bn/bn_lib.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
 * 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.]
 */

59 60 61 62 63 64
#ifndef BN_DEBUG
# undef NDEBUG /* avoid conflicting definitions */
# define NDEBUG
#endif

#include <assert.h>
B
Bodo Möller 已提交
65
#include <limits.h>
66 67 68 69
#include <stdio.h>
#include "cryptlib.h"
#include "bn_lcl.h"

B
Ben Laurie 已提交
70
const char *BN_version="Big Number" OPENSSL_VERSION_PTEXT;
71

72 73
/* This stuff appears to be completely unused, so is deprecated */
#ifndef OPENSSL_NO_DEPRECATED
74 75 76 77 78 79 80 81 82
/* For a 32 bit machine
 * 2 -   4 ==  128
 * 3 -   8 ==  256
 * 4 -  16 ==  512
 * 5 -  32 == 1024
 * 6 -  64 == 2048
 * 7 - 128 == 4096
 * 8 - 256 == 8192
 */
83 84 85 86 87 88 89 90
static int bn_limit_bits=0;
static int bn_limit_num=8;        /* (1<<bn_limit_bits) */
static int bn_limit_bits_low=0;
static int bn_limit_num_low=8;    /* (1<<bn_limit_bits_low) */
static int bn_limit_bits_high=0;
static int bn_limit_num_high=8;   /* (1<<bn_limit_bits_high) */
static int bn_limit_bits_mont=0;
static int bn_limit_num_mont=8;   /* (1<<bn_limit_bits_mont) */
91

U
Ulf Möller 已提交
92
void BN_set_params(int mult, int high, int low, int mont)
93 94 95
	{
	if (mult >= 0)
		{
96
		if (mult > (int)(sizeof(int)*8)-1)
97 98 99 100 101 102
			mult=sizeof(int)*8-1;
		bn_limit_bits=mult;
		bn_limit_num=1<<mult;
		}
	if (high >= 0)
		{
103
		if (high > (int)(sizeof(int)*8)-1)
104 105 106 107 108 109
			high=sizeof(int)*8-1;
		bn_limit_bits_high=high;
		bn_limit_num_high=1<<high;
		}
	if (low >= 0)
		{
110
		if (low > (int)(sizeof(int)*8)-1)
111 112 113 114 115 116
			low=sizeof(int)*8-1;
		bn_limit_bits_low=low;
		bn_limit_num_low=1<<low;
		}
	if (mont >= 0)
		{
117
		if (mont > (int)(sizeof(int)*8)-1)
118 119 120 121 122 123
			mont=sizeof(int)*8-1;
		bn_limit_bits_mont=mont;
		bn_limit_num_mont=1<<mont;
		}
	}

U
Ulf Möller 已提交
124
int BN_get_params(int which)
125 126 127 128 129 130 131
	{
	if      (which == 0) return(bn_limit_bits);
	else if (which == 1) return(bn_limit_bits_high);
	else if (which == 2) return(bn_limit_bits_low);
	else if (which == 3) return(bn_limit_bits_mont);
	else return(0);
	}
132
#endif
133

B
Bodo Möller 已提交
134
const BIGNUM *BN_value_one(void)
135 136
	{
	static BN_ULONG data_one=1L;
137
	static BIGNUM const_one={&data_one,1,1,0,BN_FLG_STATIC_DATA};
138 139 140 141

	return(&const_one);
	}

U
Ulf Möller 已提交
142
char *BN_options(void)
143 144 145 146 147 148 149 150
	{
	static int init=0;
	static char data[16];

	if (!init)
		{
		init++;
#ifdef BN_LLONG
151 152
		BIO_snprintf(data,sizeof data,"bn(%d,%d)",
			     (int)sizeof(BN_ULLONG)*8,(int)sizeof(BN_ULONG)*8);
153
#else
154 155
		BIO_snprintf(data,sizeof data,"bn(%d,%d)",
			     (int)sizeof(BN_ULONG)*8,(int)sizeof(BN_ULONG)*8);
156 157 158 159 160
#endif
		}
	return(data);
	}

U
Ulf Möller 已提交
161
int BN_num_bits_word(BN_ULONG l)
162
	{
163
	static const char bits[256]={
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
		0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,
		5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
		6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
		6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
		7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
		7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
		7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
		7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
		};

182
#if defined(SIXTY_FOUR_BIT_LONG)
183 184 185 186 187 188
	if (l & 0xffffffff00000000L)
		{
		if (l & 0xffff000000000000L)
			{
			if (l & 0xff00000000000000L)
				{
189
				return(bits[(int)(l>>56)]+56);
190
				}
191
			else	return(bits[(int)(l>>48)]+48);
192 193 194 195 196
			}
		else
			{
			if (l & 0x0000ff0000000000L)
				{
197
				return(bits[(int)(l>>40)]+40);
198
				}
199
			else	return(bits[(int)(l>>32)]+32);
200 201 202 203 204 205 206 207 208 209 210
			}
		}
	else
#else
#ifdef SIXTY_FOUR_BIT
	if (l & 0xffffffff00000000LL)
		{
		if (l & 0xffff000000000000LL)
			{
			if (l & 0xff00000000000000LL)
				{
211
				return(bits[(int)(l>>56)]+56);
212
				}
213
			else	return(bits[(int)(l>>48)]+48);
214 215 216 217 218
			}
		else
			{
			if (l & 0x0000ff0000000000LL)
				{
219
				return(bits[(int)(l>>40)]+40);
220
				}
221
			else	return(bits[(int)(l>>32)]+32);
222 223 224 225 226 227 228 229 230 231
			}
		}
	else
#endif
#endif
		{
#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
		if (l & 0xffff0000L)
			{
			if (l & 0xff000000L)
232 233
				return(bits[(int)(l>>24L)]+24);
			else	return(bits[(int)(l>>16L)]+16);
234 235 236 237 238 239
			}
		else
#endif
			{
#if defined(SIXTEEN_BIT) || defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
			if (l & 0xff00L)
240
				return(bits[(int)(l>>8)]+8);
241 242
			else	
#endif
243
				return(bits[(int)(l   )]  );
244 245 246 247
			}
		}
	}

248
int BN_num_bits(const BIGNUM *a)
249
	{
G
Geoff Thorpe 已提交
250
	int i = a->top - 1;
251 252
	bn_check_top(a);

G
Geoff Thorpe 已提交
253 254
	if (BN_is_zero(a)) return 0;
	return ((i*BN_BITS2) + BN_num_bits_word(a->d[i]));
255 256
	}

U
Ulf Möller 已提交
257
void BN_clear_free(BIGNUM *a)
258
	{
259 260
	int i;

261
	if (a == NULL) return;
G
Geoff Thorpe 已提交
262
	bn_check_top(a);
263 264
	if (a->d != NULL)
		{
265
		OPENSSL_cleanse(a->d,a->dmax*sizeof(a->d[0]));
266
		if (!(BN_get_flags(a,BN_FLG_STATIC_DATA)))
267
			OPENSSL_free(a->d);
268
		}
269
	i=BN_get_flags(a,BN_FLG_MALLOCED);
270
	OPENSSL_cleanse(a,sizeof(BIGNUM));
271
	if (i)
272
		OPENSSL_free(a);
273 274
	}

U
Ulf Möller 已提交
275
void BN_free(BIGNUM *a)
276 277
	{
	if (a == NULL) return;
G
Geoff Thorpe 已提交
278
	bn_check_top(a);
279
	if ((a->d != NULL) && !(BN_get_flags(a,BN_FLG_STATIC_DATA)))
280
		OPENSSL_free(a->d);
281
	if (a->flags & BN_FLG_MALLOCED)
282
		OPENSSL_free(a);
283 284 285 286 287 288 289
	else
		{
#ifndef OPENSSL_NO_DEPRECATED
		a->flags|=BN_FLG_FREE;
#endif
		a->d = NULL;
		}
290 291
	}

U
Ulf Möller 已提交
292
void BN_init(BIGNUM *a)
293 294
	{
	memset(a,0,sizeof(BIGNUM));
295
	bn_check_top(a);
296 297
	}

U
Ulf Möller 已提交
298
BIGNUM *BN_new(void)
299 300 301
	{
	BIGNUM *ret;

302
	if ((ret=(BIGNUM *)OPENSSL_malloc(sizeof(BIGNUM))) == NULL)
303 304 305 306 307
		{
		BNerr(BN_F_BN_NEW,ERR_R_MALLOC_FAILURE);
		return(NULL);
		}
	ret->flags=BN_FLG_MALLOCED;
308 309
	ret->top=0;
	ret->neg=0;
310
	ret->dmax=0;
311
	ret->d=NULL;
312
	bn_check_top(ret);
313 314 315
	return(ret);
	}

316 317
/* This is used both by bn_expand2() and bn_dup_expand() */
/* The caller MUST check that words > b->dmax before calling this */
318
static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
319
	{
320
	BN_ULONG *A,*a = NULL;
321 322
	const BN_ULONG *B;
	int i;
323

G
Geoff Thorpe 已提交
324 325
	bn_check_top(b);

326 327
	if (words > (INT_MAX/(4*BN_BITS2)))
		{
328
		BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_BIGNUM_TOO_LONG);
329 330
		return NULL;
		}
331
	if (BN_get_flags(b,BN_FLG_STATIC_DATA))
332
		{
333
		BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
334 335
		return(NULL);
		}
336
	a=A=(BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG)*words);
337 338
	if (A == NULL)
		{
339
		BNerr(BN_F_BN_EXPAND_INTERNAL,ERR_R_MALLOC_FAILURE);
340 341
		return(NULL);
		}
342
#if 1
343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360
	B=b->d;
	/* Check if the previous number needs to be copied */
	if (B != NULL)
		{
		for (i=b->top>>2; i>0; i--,A+=4,B+=4)
			{
			/*
			 * The fact that the loop is unrolled
			 * 4-wise is a tribute to Intel. It's
			 * the one that doesn't have enough
			 * registers to accomodate more data.
			 * I'd unroll it 8-wise otherwise:-)
			 *
			 *		<appro@fy.chalmers.se>
			 */
			BN_ULONG a0,a1,a2,a3;
			a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
			A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
361
			}
362
		switch (b->top&3)
363
			{
364 365 366
		case 3:	A[2]=B[2];
		case 2:	A[1]=B[1];
		case 1:	A[0]=B[0];
367 368 369 370
		case 0: /* workaround for ultrix cc: without 'case 0', the optimizer does
		         * the switch table by doing a=top&3; a--; goto jump_table[a];
		         * which fails for top== 0 */
			;
371
			}
372 373
		}

374
#else
375
	memset(A,0,sizeof(BN_ULONG)*words);
376
	memcpy(A,b->d,sizeof(b->d[0])*b->top);
377 378
#endif
		
379 380
	return(a);
	}
381

382 383 384 385 386 387 388 389 390 391 392
/* This is an internal function that can be used instead of bn_expand2()
 * when there is a need to copy BIGNUMs instead of only expanding the
 * data part, while still expanding them.
 * Especially useful when needing to expand BIGNUMs that are declared
 * 'const' and should therefore not be changed.
 * The reason to use this instead of a BN_dup() followed by a bn_expand2()
 * is memory allocation overhead.  A BN_dup() followed by a bn_expand2()
 * will allocate new memory for the BIGNUM data twice, and free it once,
 * while bn_dup_expand() makes sure allocation is made only once.
 */

393
#ifndef OPENSSL_NO_DEPRECATED
394 395 396 397
BIGNUM *bn_dup_expand(const BIGNUM *b, int words)
	{
	BIGNUM *r = NULL;

G
Geoff Thorpe 已提交
398 399
	bn_check_top(b);

400 401 402 403 404
	/* This function does not work if
	 *      words <= b->dmax && top < words
	 * because BN_dup() does not preserve 'dmax'!
	 * (But bn_dup_expand() is not used anywhere yet.)
	 */
G
Geoff Thorpe 已提交
405

406 407
	if (words > b->dmax)
		{
408
		BN_ULONG *a = bn_expand_internal(b, words);
409 410 411 412

		if (a)
			{
			r = BN_new();
413 414 415 416 417 418 419 420 421 422 423 424
			if (r)
				{
				r->top = b->top;
				r->dmax = words;
				r->neg = b->neg;
				r->d = a;
				}
			else
				{
				/* r == NULL, BN_new failure */
				OPENSSL_free(a);
				}
425
			}
426
		/* If a == NULL, there was an error in allocation in
427
		   bn_expand_internal(), and NULL should be returned */
428 429 430 431 432 433
		}
	else
		{
		r = BN_dup(b);
		}

434
	bn_check_top(r);
435 436
	return r;
	}
437
#endif
438 439

/* This is an internal function that should not be used in applications.
440
 * It ensures that 'b' has enough room for a 'words' word number
B
Bodo Möller 已提交
441
 * and initialises any unused part of b->d with leading zeros.
442 443 444 445 446
 * It is mostly used by the various BIGNUM routines. If there is an error,
 * NULL is returned. If not, 'b' is returned. */

BIGNUM *bn_expand2(BIGNUM *b, int words)
	{
G
Geoff Thorpe 已提交
447 448
	bn_check_top(b);

449 450
	if (words > b->dmax)
		{
451
		BN_ULONG *a = bn_expand_internal(b, words);
G
Geoff Thorpe 已提交
452 453 454 455
		if(!a) return NULL;
		if(b->d) OPENSSL_free(b->d);
		b->d=a;
		b->dmax=words;
456
		}
G
Geoff Thorpe 已提交
457

458 459
/* None of this should be necessary because of what b->top means! */
#if 0
460
	/* NB: bn_wexpand() calls this only if the BIGNUM really has to grow */
G
Geoff Thorpe 已提交
461
	if (b->top < b->dmax)
462
		{
463 464
		int i;
		BN_ULONG *A = &(b->d[b->top]);
B
Bodo Möller 已提交
465
		for (i=(b->dmax - b->top)>>3; i>0; i--,A+=8)
B
Bodo Möller 已提交
466 467 468 469
			{
			A[0]=0; A[1]=0; A[2]=0; A[3]=0;
			A[4]=0; A[5]=0; A[6]=0; A[7]=0;
			}
B
Bodo Möller 已提交
470
		for (i=(b->dmax - b->top)&7; i>0; i--,A++)
B
Bodo Möller 已提交
471
			A[0]=0;
B
Bodo Möller 已提交
472
		assert(A == &(b->d[b->dmax]));
473
		}
474
#endif
G
Geoff Thorpe 已提交
475
	bn_check_top(b);
476
	return b;
477 478
	}

479
BIGNUM *BN_dup(const BIGNUM *a)
480
	{
G
Geoff Thorpe 已提交
481
	BIGNUM *t;
482

483
	if (a == NULL) return NULL;
484 485
	bn_check_top(a);

486
	t = BN_new();
G
Geoff Thorpe 已提交
487 488 489
	if (t == NULL) return NULL;
	if(!BN_copy(t, a))
		{
490
		BN_free(t);
G
Geoff Thorpe 已提交
491 492 493 494
		return NULL;
		}
	bn_check_top(t);
	return t;
495 496
	}

497
BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
498
	{
499
	int i;
500 501
	BN_ULONG *A;
	const BN_ULONG *B;
502

503 504
	bn_check_top(b);

505 506 507 508 509 510
	if (a == b) return(a);
	if (bn_wexpand(a,b->top) == NULL) return(NULL);

#if 1
	A=a->d;
	B=b->d;
511
	for (i=b->top>>2; i>0; i--,A+=4,B+=4)
512
		{
513 514 515
		BN_ULONG a0,a1,a2,a3;
		a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
		A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
516
		}
517
	switch (b->top&3)
518
		{
519 520 521
		case 3: A[2]=B[2];
		case 2: A[1]=B[1];
		case 1: A[0]=B[0];
522
		case 0: ; /* ultrix cc workaround, see comments in bn_expand_internal */
523 524
		}
#else
525
	memcpy(a->d,b->d,sizeof(b->d[0])*b->top);
526 527
#endif

528
	a->top=b->top;
G
Geoff Thorpe 已提交
529
#ifndef BN_STRICT
530
	if ((a->top == 0) && (a->d != NULL))
531
		a->d[0]=0;
G
Geoff Thorpe 已提交
532
#endif
533
	a->neg=b->neg;
534
	bn_check_top(a);
535 536 537
	return(a);
	}

B
Bodo Möller 已提交
538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573
BIGNUM *BN_ncopy(BIGNUM *a, const BIGNUM *b, size_t n)
	{
	int i, min;
	BN_ULONG *A;
	const BN_ULONG *B;

	bn_check_top(b);
	if (a == b)
		return a;

	min = (b->top < (int)n)? b->top: (int)n;
	if (!min)
		{
		BN_zero(a);
		return a;
		}
	if (bn_wexpand(a, min) == NULL)
		return NULL;

	A=a->d;
	B=b->d;
	for (i=min>>2; i>0; i--, A+=4, B+=4)
		{
		BN_ULONG a0,a1,a2,a3;
		a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
		A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
		}
	switch (min&3)
		{
		case 3: A[2]=B[2];
		case 2: A[1]=B[1];
		case 1: A[0]=B[0];
		case 0: ;
		}
	a->top = min;
	a->neg = b->neg;
574
	bn_correct_top(a);
B
Bodo Möller 已提交
575 576 577
	return(a);
	}

B
Bodo Möller 已提交
578 579 580 581 582 583
void BN_swap(BIGNUM *a, BIGNUM *b)
	{
	int flags_old_a, flags_old_b;
	BN_ULONG *tmp_d;
	int tmp_top, tmp_dmax, tmp_neg;
	
584 585 586
	bn_check_top(a);
	bn_check_top(b);

B
Bodo Möller 已提交
587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606
	flags_old_a = a->flags;
	flags_old_b = b->flags;

	tmp_d = a->d;
	tmp_top = a->top;
	tmp_dmax = a->dmax;
	tmp_neg = a->neg;
	
	a->d = b->d;
	a->top = b->top;
	a->dmax = b->dmax;
	a->neg = b->neg;
	
	b->d = tmp_d;
	b->top = tmp_top;
	b->dmax = tmp_dmax;
	b->neg = tmp_neg;
	
	a->flags = (flags_old_a & BN_FLG_MALLOCED) | (flags_old_b & BN_FLG_STATIC_DATA);
	b->flags = (flags_old_b & BN_FLG_MALLOCED) | (flags_old_a & BN_FLG_STATIC_DATA);
607 608
	bn_check_top(a);
	bn_check_top(b);
B
Bodo Möller 已提交
609 610
	}

U
Ulf Möller 已提交
611
void BN_clear(BIGNUM *a)
612
	{
613
	bn_check_top(a);
614
	if (a->d != NULL)
615
		memset(a->d,0,a->dmax*sizeof(a->d[0]));
616 617 618 619
	a->top=0;
	a->neg=0;
	}

620
BN_ULONG BN_get_word(const BIGNUM *a)
621
	{
G
Geoff Thorpe 已提交
622 623
	if (a->top > 1)
		return BN_MASK2;
624
	else if (a->top == 1)
G
Geoff Thorpe 已提交
625
		return a->d[0];
626 627
	/* a->top == 0 */
	return 0;
628 629
	}

630 631 632 633 634 635 636 637 638 639
int BN_set_word(BIGNUM *a, BN_ULONG w)
	{
	bn_check_top(a);
	if (bn_expand(a,(int)sizeof(BN_ULONG)*8) == NULL) return(0);
	a->neg = 0;
	a->d[0] = w;
	a->top = (w ? 1 : 0);
	bn_check_top(a);
	return(1);
	}
640

B
Ben Laurie 已提交
641
BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
642 643 644 645 646 647 648
	{
	unsigned int i,m;
	unsigned int n;
	BN_ULONG l;

	if (ret == NULL) ret=BN_new();
	if (ret == NULL) return(NULL);
649
	bn_check_top(ret);
650 651 652 653 654 655 656 657 658 659 660
	l=0;
	n=len;
	if (n == 0)
		{
		ret->top=0;
		return(ret);
		}
	if (bn_expand(ret,(int)(n+2)*8) == NULL)
		return(NULL);
	i=((n-1)/BN_BYTES)+1;
	m=((n-1)%(BN_BYTES));
661 662
	ret->top=i;
	ret->neg=0;
663 664 665 666 667 668 669 670 671 672 673 674
	while (n-- > 0)
		{
		l=(l<<8L)| *(s++);
		if (m-- == 0)
			{
			ret->d[--i]=l;
			l=0;
			m=BN_BYTES-1;
			}
		}
	/* need to call this due to clear byte at top if avoiding
	 * having the top bit set (-ve number) */
675
	bn_correct_top(ret);
676 677 678 679
	return(ret);
	}

/* ignore negative */
680
int BN_bn2bin(const BIGNUM *a, unsigned char *to)
681 682 683 684
	{
	int n,i;
	BN_ULONG l;

685
	bn_check_top(a);
686 687 688 689 690 691 692 693 694
	n=i=BN_num_bytes(a);
	while (i-- > 0)
		{
		l=a->d[i/BN_BYTES];
		*(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff;
		}
	return(n);
	}

695
int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
696 697 698 699
	{
	int i;
	BN_ULONG t1,t2,*ap,*bp;

700 701 702
	bn_check_top(a);
	bn_check_top(b);

703 704 705 706 707 708 709 710 711
	i=a->top-b->top;
	if (i != 0) return(i);
	ap=a->d;
	bp=b->d;
	for (i=a->top-1; i>=0; i--)
		{
		t1= ap[i];
		t2= bp[i];
		if (t1 != t2)
G
Geoff Thorpe 已提交
712
			return((t1 > t2) ? 1 : -1);
713 714 715 716
		}
	return(0);
	}

717
int BN_cmp(const BIGNUM *a, const BIGNUM *b)
718 719 720 721 722 723 724 725 726 727 728 729 730 731
	{
	int i;
	int gt,lt;
	BN_ULONG t1,t2;

	if ((a == NULL) || (b == NULL))
		{
		if (a != NULL)
			return(-1);
		else if (b != NULL)
			return(1);
		else
			return(0);
		}
732 733 734 735

	bn_check_top(a);
	bn_check_top(b);

736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757
	if (a->neg != b->neg)
		{
		if (a->neg)
			return(-1);
		else	return(1);
		}
	if (a->neg == 0)
		{ gt=1; lt= -1; }
	else	{ gt= -1; lt=1; }

	if (a->top > b->top) return(gt);
	if (a->top < b->top) return(lt);
	for (i=a->top-1; i>=0; i--)
		{
		t1=a->d[i];
		t2=b->d[i];
		if (t1 > t2) return(gt);
		if (t1 < t2) return(lt);
		}
	return(0);
	}

U
Ulf Möller 已提交
758
int BN_set_bit(BIGNUM *a, int n)
759
	{
760
	int i,j,k;
761

762 763 764
	if (n < 0)
		return 0;

765 766
	i=n/BN_BITS2;
	j=n%BN_BITS2;
767 768
	if (a->top <= i)
		{
769 770 771
		if (bn_wexpand(a,i+1) == NULL) return(0);
		for(k=a->top; k<i+1; k++)
			a->d[k]=0;
772 773
		a->top=i+1;
		}
774

775
	a->d[i]|=(((BN_ULONG)1)<<j);
776
	bn_check_top(a);
777 778 779
	return(1);
	}

U
Ulf Möller 已提交
780
int BN_clear_bit(BIGNUM *a, int n)
781 782 783
	{
	int i,j;

G
Geoff Thorpe 已提交
784 785
	bn_check_top(a);
	if (n < 0) return 0;
786

787 788 789 790
	i=n/BN_BITS2;
	j=n%BN_BITS2;
	if (a->top <= i) return(0);

791
	a->d[i]&=(~(((BN_ULONG)1)<<j));
792
	bn_correct_top(a);
793 794 795
	return(1);
	}

796
int BN_is_bit_set(const BIGNUM *a, int n)
797 798 799
	{
	int i,j;

G
Geoff Thorpe 已提交
800 801
	bn_check_top(a);
	if (n < 0) return 0;
802 803
	i=n/BN_BITS2;
	j=n%BN_BITS2;
G
Geoff Thorpe 已提交
804
	if (a->top <= i) return 0;
805 806 807
	return((a->d[i]&(((BN_ULONG)1)<<j))?1:0);
	}

U
Ulf Möller 已提交
808
int BN_mask_bits(BIGNUM *a, int n)
809 810 811
	{
	int b,w;

G
Geoff Thorpe 已提交
812 813
	bn_check_top(a);
	if (n < 0) return 0;
814

815 816
	w=n/BN_BITS2;
	b=n%BN_BITS2;
G
Geoff Thorpe 已提交
817
	if (w >= a->top) return 0;
818 819 820 821 822 823 824
	if (b == 0)
		a->top=w;
	else
		{
		a->top=w+1;
		a->d[w]&= ~(BN_MASK2<<b);
		}
825
	bn_correct_top(a);
826 827
	return(1);
	}
828

829
int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n)
830 831 832 833 834 835 836 837 838 839 840 841 842 843 844
	{
	int i;
	BN_ULONG aa,bb;

	aa=a[n-1];
	bb=b[n-1];
	if (aa != bb) return((aa > bb)?1:-1);
	for (i=n-2; i>=0; i--)
		{
		aa=a[i];
		bb=b[i];
		if (aa != bb) return((aa > bb)?1:-1);
		}
	return(0);
	}
845

846 847 848 849 850 851 852
/* Here follows a specialised variants of bn_cmp_words().  It has the
   property of performing the operation on arrays of different sizes.
   The sizes of those arrays is expressed through cl, which is the
   common length ( basicall, min(len(a),len(b)) ), and dl, which is the
   delta between the two lengths, calculated as len(a)-len(b).
   All lengths are the number of BN_ULONGs...  */

853 854 855 856 857 858 859 860
int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b,
	int cl, int dl)
	{
	int n,i;
	n = cl-1;

	if (dl < 0)
		{
861
		for (i=dl; i<0; i++)
862
			{
863
			if (b[n-i] != 0)
864 865 866 867 868 869 870 871 872 873 874 875 876
				return -1; /* a < b */
			}
		}
	if (dl > 0)
		{
		for (i=dl; i>0; i--)
			{
			if (a[n+i] != 0)
				return 1; /* a > b */
			}
		}
	return bn_cmp_words(a,b,cl);
	}