1/*
2 * Copyright (c) 2000-2001,2011,2014 Apple Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19/* crypto/bn/bn_lib.c */
20/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
21 * All rights reserved.
22 *
23 * This package is an SSL implementation written
24 * by Eric Young (eay@cryptsoft.com).
25 * The implementation was written so as to conform with Netscapes SSL.
26 *
27 * This library is free for commercial and non-commercial use as long as
28 * the following conditions are aheared to.  The following conditions
29 * apply to all code found in this distribution, be it the RC4, RSA,
30 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
31 * included with this distribution is covered by the same copyright terms
32 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
33 *
34 * Copyright remains Eric Young's, and as such any Copyright notices in
35 * the code are not to be removed.
36 * If this package is used in a product, Eric Young should be given attribution
37 * as the author of the parts of the library used.
38 * This can be in the form of a textual message at program startup or
39 * in documentation (online or textual) provided with the package.
40 *
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
43 * are met:
44 * 1. Redistributions of source code must retain the copyright
45 *    notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright
47 *    notice, this list of conditions and the following disclaimer in the
48 *    documentation and/or other materials provided with the distribution.
49 * 3. All advertising materials mentioning features or use of this software
50 *    must display the following acknowledgement:
51 *    "This product includes cryptographic software written by
52 *     Eric Young (eay@cryptsoft.com)"
53 *    The word 'cryptographic' can be left out if the rouines from the library
54 *    being used are not cryptographic related :-).
55 * 4. If you include any Windows specific code (or a derivative thereof) from
56 *    the apps directory (application code) you must include an acknowledgement:
57 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
58 *
59 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
60 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
61 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
62 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
63 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
64 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
65 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
66 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
69 * SUCH DAMAGE.
70 *
71 * The licence and distribution terms for any publically available version or
72 * derivative of this code cannot be changed.  i.e. this code cannot simply be
73 * copied and put under another distribution licence
74 * [including the GNU Public Licence.]
75 */
76
77#include <stdio.h>
78#include "cryptlib.h"
79#include "bn_lcl.h"
80
81const char *BN_version="Big Number" OPENSSL_VERSION_PTEXT;
82
83#if		BN_PARAMS_ENABLE
84
85/* For a 32 bit machine
86 * 2 -   4 ==  128
87 * 3 -   8 ==  256
88 * 4 -  16 ==  512
89 * 5 -  32 == 1024
90 * 6 -  64 == 2048
91 * 7 - 128 == 4096
92 * 8 - 256 == 8192
93 */
94static int bn_limit_bits=0;
95static int bn_limit_num=8;        /* (1<<bn_limit_bits) */
96static int bn_limit_bits_low=0;
97static int bn_limit_num_low=8;    /* (1<<bn_limit_bits_low) */
98static int bn_limit_bits_high=0;
99static int bn_limit_num_high=8;   /* (1<<bn_limit_bits_high) */
100static int bn_limit_bits_mont=0;
101static int bn_limit_num_mont=8;   /* (1<<bn_limit_bits_mont) */
102
103void BN_set_params(int mult, int high, int low, int mont)
104	{
105	if (mult >= 0)
106		{
107		if (mult > (sizeof(int)*8)-1)
108			mult=sizeof(int)*8-1;
109		bn_limit_bits=mult;
110		bn_limit_num=1<<mult;
111		}
112	if (high >= 0)
113		{
114		if (high > (sizeof(int)*8)-1)
115			high=sizeof(int)*8-1;
116		bn_limit_bits_high=high;
117		bn_limit_num_high=1<<high;
118		}
119	if (low >= 0)
120		{
121		if (low > (sizeof(int)*8)-1)
122			low=sizeof(int)*8-1;
123		bn_limit_bits_low=low;
124		bn_limit_num_low=1<<low;
125		}
126	if (mont >= 0)
127		{
128		if (mont > (sizeof(int)*8)-1)
129			mont=sizeof(int)*8-1;
130		bn_limit_bits_mont=mont;
131		bn_limit_num_mont=1<<mont;
132		}
133	}
134
135int BN_get_params(int which)
136	{
137	if      (which == 0) return(bn_limit_bits);
138	else if (which == 1) return(bn_limit_bits_high);
139	else if (which == 2) return(bn_limit_bits_low);
140	else if (which == 3) return(bn_limit_bits_mont);
141	else return(0);
142	}
143#endif	/* BN_PARAMS_ENABLE */
144
145BIGNUM *BN_value_one(void)
146	{
147	static BN_ULONG data_one=1L;
148	static BIGNUM const_one={&data_one,1,1,0};
149
150	return(&const_one);
151	}
152
153char *BN_options(void)
154	{
155	static int init=0;
156	static char data[16];
157
158	if (!init)
159		{
160		init++;
161#ifdef BN_LLONG
162		sprintf(data,"bn(%d,%d)",(int)sizeof(BN_ULLONG)*8,
163			(int)sizeof(BN_ULONG)*8);
164#else
165		sprintf(data,"bn(%d,%d)",(int)sizeof(BN_ULONG)*8,
166			(int)sizeof(BN_ULONG)*8);
167#endif
168		}
169	return(data);
170	}
171
172int BN_num_bits_word(BN_ULONG l)
173	{
174	static const char bits[256]={
175		0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,
176		5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
177		6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
178		6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
179		7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
180		7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
181		7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
182		7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
183		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
184		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
185		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
186		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
187		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
188		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
189		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
190		8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
191		};
192
193#if defined(SIXTY_FOUR_BIT_LONG)
194	if (l & 0xffffffff00000000L)
195		{
196		if (l & 0xffff000000000000L)
197			{
198			if (l & 0xff00000000000000L)
199				{
200				return(bits[(int)(l>>56)]+56);
201				}
202			else	return(bits[(int)(l>>48)]+48);
203			}
204		else
205			{
206			if (l & 0x0000ff0000000000L)
207				{
208				return(bits[(int)(l>>40)]+40);
209				}
210			else	return(bits[(int)(l>>32)]+32);
211			}
212		}
213	else
214#else
215#ifdef SIXTY_FOUR_BIT
216	if (l & 0xffffffff00000000LL)
217		{
218		if (l & 0xffff000000000000LL)
219			{
220			if (l & 0xff00000000000000LL)
221				{
222				return(bits[(int)(l>>56)]+56);
223				}
224			else	return(bits[(int)(l>>48)]+48);
225			}
226		else
227			{
228			if (l & 0x0000ff0000000000LL)
229				{
230				return(bits[(int)(l>>40)]+40);
231				}
232			else	return(bits[(int)(l>>32)]+32);
233			}
234		}
235	else
236#endif
237#endif
238		{
239#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
240		if (l & 0xffff0000L)
241			{
242			if (l & 0xff000000L)
243				return(bits[(int)(l>>24L)]+24);
244			else	return(bits[(int)(l>>16L)]+16);
245			}
246		else
247#endif
248			{
249#if defined(SIXTEEN_BIT) || defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
250			if (l & 0xff00L)
251				return(bits[(int)(l>>8)]+8);
252			else
253#endif
254				return(bits[(int)(l   )]  );
255			}
256		}
257	}
258
259int BN_num_bits(const BIGNUM *a)
260	{
261	BN_ULONG l;
262	int i;
263
264	bn_check_top(a);
265
266	if (a->top == 0) return(0);
267	l=a->d[a->top-1];
268	i=(a->top-1)*BN_BITS2;
269	if (l == 0)
270		{
271#if !defined(NO_STDIO) && !defined(WIN16)
272		fprintf(stderr,"BAD TOP VALUE\n");
273#endif
274		abort();
275		}
276	return(i+BN_num_bits_word(l));
277	}
278
279void BN_clear_free(BIGNUM *a)
280	{
281	int i;
282
283	if (a == NULL) return;
284	if (a->d != NULL)
285		{
286		memset(a->d,0,a->max*sizeof(a->d[0]));
287		if (!(BN_get_flags(a,BN_FLG_STATIC_DATA)))
288			Free(a->d);
289		}
290	i=BN_get_flags(a,BN_FLG_MALLOCED);
291	memset(a,0,sizeof(BIGNUM));
292	if (i)
293		Free(a);
294	}
295
296void BN_free(BIGNUM *a)
297	{
298	if (a == NULL) return;
299	if ((a->d != NULL) && !(BN_get_flags(a,BN_FLG_STATIC_DATA)))
300		Free(a->d);
301	a->flags|=BN_FLG_FREE; /* REMOVE? */
302	if (a->flags & BN_FLG_MALLOCED)
303		Free(a);
304	}
305
306void BN_init(BIGNUM *a)
307	{
308	memset(a,0,sizeof(BIGNUM));
309	}
310
311BIGNUM *BN_new(void)
312	{
313	BIGNUM *ret;
314
315	if ((ret=(BIGNUM *)Malloc(sizeof(BIGNUM))) == NULL)
316		{
317		BNerr(BN_F_BN_NEW,ERR_R_MALLOC_FAILURE);
318		return(NULL);
319		}
320	ret->flags=BN_FLG_MALLOCED;
321	ret->top=0;
322	ret->neg=0;
323	ret->max=0;
324	ret->d=NULL;
325	return(ret);
326	}
327
328/* This is an internal function that should not be used in applications.
329 * It ensures that 'b' has enough room for a 'words' word number number.
330 * It is mostly used by the various BIGNUM routines. If there is an error,
331 * NULL is returned. If not, 'b' is returned. */
332
333BIGNUM *bn_expand2(BIGNUM *b, int words)
334	{
335	BN_ULONG *A,*a;
336	const BN_ULONG *B;
337	int i;
338
339	bn_check_top(b);
340
341	if (words > b->max)
342		{
343		bn_check_top(b);
344		if (BN_get_flags(b,BN_FLG_STATIC_DATA))
345			{
346			BNerr(BN_F_BN_EXPAND2,BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
347			return(NULL);
348			}
349		a=A=(BN_ULONG *)Malloc(sizeof(BN_ULONG)*(words+1));
350		if (A == NULL)
351			{
352			BNerr(BN_F_BN_EXPAND2,ERR_R_MALLOC_FAILURE);
353			return(NULL);
354			}
355#if 1
356		B=b->d;
357		/* Check if the previous number needs to be copied */
358		if (B != NULL)
359			{
360#if 0
361			/* This lot is an unrolled loop to copy b->top
362			 * BN_ULONGs from B to A
363			 */
364/*
365 * I have nothing against unrolling but it's usually done for
366 * several reasons, namely:
367 * - minimize percentage of decision making code, i.e. branches;
368 * - avoid cache trashing;
369 * - make it possible to schedule loads earlier;
370 * Now let's examine the code below. The cornerstone of C is
371 * "programmer is always right" and that's what we love it for:-)
372 * For this very reason C compilers have to be paranoid when it
373 * comes to data aliasing and assume the worst. Yeah, but what
374 * does it mean in real life? This means that loop body below will
375 * be compiled to sequence of loads immediately followed by stores
376 * as compiler assumes the worst, something in A==B+1 style. As a
377 * result CPU pipeline is going to starve for incoming data. Secondly
378 * if A and B happen to share same cache line such code is going to
379 * cause severe cache trashing. Both factors have severe impact on
380 * performance of modern CPUs and this is the reason why this
381 * particular piece of code is #ifdefed away and replaced by more
382 * "friendly" version found in #else section below. This comment
383 * also applies to BN_copy function.
384 *
385 *					<appro@fy.chalmers.se>
386 */
387			for (i=b->top&(~7); i>0; i-=8)
388				{
389				A[0]=B[0]; A[1]=B[1]; A[2]=B[2]; A[3]=B[3];
390				A[4]=B[4]; A[5]=B[5]; A[6]=B[6]; A[7]=B[7];
391				A+=8;
392				B+=8;
393				}
394			switch (b->top&7)
395				{
396			case 7:
397				A[6]=B[6];
398			case 6:
399				A[5]=B[5];
400			case 5:
401				A[4]=B[4];
402			case 4:
403				A[3]=B[3];
404			case 3:
405				A[2]=B[2];
406			case 2:
407				A[1]=B[1];
408			case 1:
409				A[0]=B[0];
410			case 0:
411				/* I need the 'case 0' entry for utrix cc.
412				 * If the optimizer is turned on, it does the
413				 * switch table by doing
414				 * a=top&7
415				 * a--;
416				 * goto jump_table[a];
417				 * If top is 0, this makes us jump to 0xffffffc
418				 * which is rather bad :-(.
419				 * eric 23-Apr-1998
420				 */
421				;
422				}
423#else
424			for (i=b->top>>2; i>0; i--,A+=4,B+=4)
425				{
426				/*
427				 * The fact that the loop is unrolled
428				 * 4-wise is a tribute to Intel. It's
429				 * the one that doesn't have enough
430				 * registers to accomodate more data.
431				 * I'd unroll it 8-wise otherwise:-)
432				 *
433				 *		<appro@fy.chalmers.se>
434				 */
435				BN_ULONG a0,a1,a2,a3;
436				a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
437				A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
438				}
439			switch (b->top&3)
440				{
441				case 3:	A[2]=B[2];
442				case 2:	A[1]=B[1];
443				case 1:	A[0]=B[0];
444				case 0:	; /* ultrix cc workaround, see above */
445				}
446#endif
447			Free(b->d);
448			}
449
450		b->d=a;
451		b->max=words;
452
453		/* Now need to zero any data between b->top and b->max */
454
455		A= &(b->d[b->top]);
456		for (i=(b->max - b->top)>>3; i>0; i--,A+=8)
457			{
458			A[0]=0; A[1]=0; A[2]=0; A[3]=0;
459			A[4]=0; A[5]=0; A[6]=0; A[7]=0;
460			}
461		for (i=(b->max - b->top)&7; i>0; i--,A++)
462			A[0]=0;
463#else
464			memset(A,0,sizeof(BN_ULONG)*(words+1));
465			memcpy(A,b->d,sizeof(b->d[0])*b->top);
466			b->d=a;
467			b->max=words;
468#endif
469
470/*		memset(&(p[b->max]),0,((words+1)-b->max)*sizeof(BN_ULONG)); */
471/*	{ int i; for (i=b->max; i<words+1; i++) p[i]=i;} */
472
473		}
474	return(b);
475	}
476
477BIGNUM *BN_dup(const BIGNUM *a)
478	{
479	BIGNUM *r;
480
481	if (a == NULL) return NULL;
482
483	bn_check_top(a);
484
485	r=BN_new();
486	if (r == NULL) return(NULL);
487	return((BIGNUM *)BN_copy(r,a));
488	}
489
490BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
491	{
492	int i;
493	BN_ULONG *A;
494	const BN_ULONG *B;
495
496	bn_check_top(b);
497
498	if (a == b) return(a);
499	if (bn_wexpand(a,b->top) == NULL) return(NULL);
500
501#if 1
502	A=a->d;
503	B=b->d;
504	for (i=b->top>>2; i>0; i--,A+=4,B+=4)
505		{
506		BN_ULONG a0,a1,a2,a3;
507		a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
508		A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
509		}
510	switch (b->top&3)
511		{
512		case 3: A[2]=B[2];
513		case 2: A[1]=B[1];
514		case 1: A[0]=B[0];
515		case 0: ; /* ultrix cc workaround, see comments in bn_expand2 */
516		}
517#else
518	memcpy(a->d,b->d,sizeof(b->d[0])*b->top);
519#endif
520
521/*	memset(&(a->d[b->top]),0,sizeof(a->d[0])*(a->max-b->top));*/
522	a->top=b->top;
523	if ((a->top == 0) && (a->d != NULL))
524		a->d[0]=0;
525	a->neg=b->neg;
526	return(a);
527	}
528
529void BN_clear(BIGNUM *a)
530	{
531	if (a->d != NULL)
532		memset(a->d,0,a->max*sizeof(a->d[0]));
533	a->top=0;
534	a->neg=0;
535	}
536
537BN_ULONG BN_get_word(BIGNUM *a)
538	{
539	int i;
540	unsigned n;
541	BN_ULONG ret=0;
542
543	n=BN_num_bytes(a);
544	if (n > sizeof(BN_ULONG))
545		return(BN_MASK2);
546	for (i=a->top-1; i>=0; i--)
547		{
548#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
549		ret<<=BN_BITS4; /* stops the compiler complaining */
550		ret<<=BN_BITS4;
551#else
552		ret=0;
553#endif
554		ret|=a->d[i];
555		}
556	return(ret);
557	}
558
559int BN_set_word(BIGNUM *a, BN_ULONG w)
560	{
561	int i,n;
562
563	if (bn_expand(a,(int)(sizeof(BN_ULONG)*8)) == NULL) return(0);
564
565	n=sizeof(BN_ULONG)/BN_BYTES;
566	a->neg=0;
567	a->top=0;
568	a->d[0]=(BN_ULONG)w&BN_MASK2;
569	if (a->d[0] != 0) a->top=1;
570	for (i=1; i<n; i++)
571		{
572		/* the following is done instead of
573		 * w>>=BN_BITS2 so compilers don't complain
574		 * on builds where sizeof(long) == BN_TYPES */
575#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
576		w>>=BN_BITS4;
577		w>>=BN_BITS4;
578#else
579		w=0;
580#endif
581		a->d[i]=(BN_ULONG)w&BN_MASK2;
582		if (a->d[i] != 0) a->top=i+1;
583		}
584	return(1);
585	}
586
587/* ignore negative */
588BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
589	{
590	unsigned int i,m;
591	unsigned int n;
592	BN_ULONG l;
593
594	if (ret == NULL) ret=BN_new();
595	if (ret == NULL) return(NULL);
596	l=0;
597	n=len;
598	if (n == 0)
599		{
600		ret->top=0;
601		return(ret);
602		}
603	if (bn_expand(ret,(int)(n+2)*8) == NULL)
604		return(NULL);
605	i=((n-1)/BN_BYTES)+1;
606	m=((n-1)%(BN_BYTES));
607	ret->top=i;
608	while (n-- > 0)
609		{
610		l=(l<<8L)| *(s++);
611		if (m-- == 0)
612			{
613			ret->d[--i]=l;
614			l=0;
615			m=BN_BYTES-1;
616			}
617		}
618	/* need to call this due to clear byte at top if avoiding
619	 * having the top bit set (-ve number) */
620	bn_fix_top(ret);
621	return(ret);
622	}
623
624/* ignore negative */
625int BN_bn2bin(const BIGNUM *a, unsigned char *to)
626	{
627	int n,i;
628	BN_ULONG l;
629
630	n=i=BN_num_bytes(a);
631	while (i-- > 0)
632		{
633		l=a->d[i/BN_BYTES];
634		*(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff;
635		}
636	return(n);
637	}
638
639int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
640	{
641	int i;
642	BN_ULONG t1,t2,*ap,*bp;
643
644	bn_check_top(a);
645	bn_check_top(b);
646
647	i=a->top-b->top;
648	if (i != 0) return(i);
649	ap=a->d;
650	bp=b->d;
651	for (i=a->top-1; i>=0; i--)
652		{
653		t1= ap[i];
654		t2= bp[i];
655		if (t1 != t2)
656			return(t1 > t2?1:-1);
657		}
658	return(0);
659	}
660
661int BN_cmp(const BIGNUM *a, const BIGNUM *b)
662	{
663	int i;
664	int gt,lt;
665	BN_ULONG t1,t2;
666
667	if ((a == NULL) || (b == NULL))
668		{
669		if (a != NULL)
670			return(-1);
671		else if (b != NULL)
672			return(1);
673		else
674			return(0);
675		}
676
677	bn_check_top(a);
678	bn_check_top(b);
679
680	if (a->neg != b->neg)
681		{
682		if (a->neg)
683			return(-1);
684		else	return(1);
685		}
686	if (a->neg == 0)
687		{ gt=1; lt= -1; }
688	else	{ gt= -1; lt=1; }
689
690	if (a->top > b->top) return(gt);
691	if (a->top < b->top) return(lt);
692	for (i=a->top-1; i>=0; i--)
693		{
694		t1=a->d[i];
695		t2=b->d[i];
696		if (t1 > t2) return(gt);
697		if (t1 < t2) return(lt);
698		}
699	return(0);
700	}
701
702int BN_set_bit(BIGNUM *a, int n)
703	{
704	int i,j,k;
705
706	i=n/BN_BITS2;
707	j=n%BN_BITS2;
708	if (a->top <= i)
709		{
710		if (bn_wexpand(a,i+1) == NULL) return(0);
711		for(k=a->top; k<i+1; k++)
712			a->d[k]=0;
713		a->top=i+1;
714		}
715
716	a->d[i]|=(((BN_ULONG)1)<<j);
717	return(1);
718	}
719
720int BN_clear_bit(BIGNUM *a, int n)
721	{
722	int i,j;
723
724	i=n/BN_BITS2;
725	j=n%BN_BITS2;
726	if (a->top <= i) return(0);
727
728	a->d[i]&=(~(((BN_ULONG)1)<<j));
729	bn_fix_top(a);
730	return(1);
731	}
732
733int BN_is_bit_set(const BIGNUM *a, int n)
734	{
735	int i,j;
736
737	if (n < 0) return(0);
738	i=n/BN_BITS2;
739	j=n%BN_BITS2;
740	if (a->top <= i) return(0);
741	return((a->d[i]&(((BN_ULONG)1)<<j))?1:0);
742	}
743
744int BN_mask_bits(BIGNUM *a, int n)
745	{
746	int b,w;
747
748	w=n/BN_BITS2;
749	b=n%BN_BITS2;
750	if (w >= a->top) return(0);
751	if (b == 0)
752		a->top=w;
753	else
754		{
755		a->top=w+1;
756		a->d[w]&= ~(BN_MASK2<<b);
757		}
758	bn_fix_top(a);
759	return(1);
760	}
761
762int bn_cmp_words(BN_ULONG *a, BN_ULONG *b, int n)
763	{
764	int i;
765	BN_ULONG aa,bb;
766
767	aa=a[n-1];
768	bb=b[n-1];
769	if (aa != bb) return((aa > bb)?1:-1);
770	for (i=n-2; i>=0; i--)
771		{
772		aa=a[i];
773		bb=b[i];
774		if (aa != bb) return((aa > bb)?1:-1);
775		}
776	return(0);
777	}
778
779